351-0025-brcmfmac-support-removing-AP-interfaces-with-interfa.patch 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
  2. Date: Wed, 29 Jun 2016 21:54:27 +0200
  3. Subject: [PATCH] brcmfmac: support removing AP interfaces with
  4. "interface_remove"
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. New firmwares (e.g. 10.10.69.36 for BCM4366) support "interface_remove"
  9. for removing interfaces. Try to use this method on cfg80211 request. In
  10. case of older firmwares (e.g. 7.35.177.56 for BCM43602 as I tested) this
  11. will just result in firmware rejecting command and this won't change any
  12. behavior.
  13. Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
  14. Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
  15. ---
  16. --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
  17. +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
  18. @@ -771,12 +771,48 @@ s32 brcmf_notify_escan_complete(struct b
  19. return err;
  20. }
  21. +static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
  22. + struct wireless_dev *wdev)
  23. +{
  24. + struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
  25. + struct net_device *ndev = wdev->netdev;
  26. + struct brcmf_if *ifp = netdev_priv(ndev);
  27. + int ret;
  28. + int err;
  29. +
  30. + brcmf_cfg80211_arm_vif_event(cfg, ifp->vif);
  31. +
  32. + err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
  33. + if (err) {
  34. + brcmf_err("interface_remove failed %d\n", err);
  35. + goto err_unarm;
  36. + }
  37. +
  38. + /* wait for firmware event */
  39. + ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
  40. + BRCMF_VIF_EVENT_TIMEOUT);
  41. + if (!ret) {
  42. + brcmf_err("timeout occurred\n");
  43. + err = -EIO;
  44. + goto err_unarm;
  45. + }
  46. +
  47. + brcmf_remove_interface(ifp, true);
  48. +
  49. +err_unarm:
  50. + brcmf_cfg80211_arm_vif_event(cfg, NULL);
  51. + return err;
  52. +}
  53. +
  54. static
  55. int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
  56. {
  57. struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
  58. struct net_device *ndev = wdev->netdev;
  59. + if (ndev && ndev == cfg_to_ndev(cfg))
  60. + return -ENOTSUPP;
  61. +
  62. /* vif event pending in firmware */
  63. if (brcmf_cfg80211_vif_event_armed(cfg))
  64. return -EBUSY;
  65. @@ -793,12 +829,13 @@ int brcmf_cfg80211_del_iface(struct wiph
  66. switch (wdev->iftype) {
  67. case NL80211_IFTYPE_ADHOC:
  68. case NL80211_IFTYPE_STATION:
  69. - case NL80211_IFTYPE_AP:
  70. case NL80211_IFTYPE_AP_VLAN:
  71. case NL80211_IFTYPE_WDS:
  72. case NL80211_IFTYPE_MONITOR:
  73. case NL80211_IFTYPE_MESH_POINT:
  74. return -EOPNOTSUPP;
  75. + case NL80211_IFTYPE_AP:
  76. + return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
  77. case NL80211_IFTYPE_P2P_CLIENT:
  78. case NL80211_IFTYPE_P2P_GO:
  79. case NL80211_IFTYPE_P2P_DEVICE: