351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
  2. Date: Fri, 27 May 2016 21:07:19 +0200
  3. Subject: [PATCH] brcmfmac: fix setting AP channel with new firmwares
  4. MIME-Version: 1.0
  5. Content-Type: text/plain; charset=UTF-8
  6. Content-Transfer-Encoding: 8bit
  7. Firmware for new chipsets is based on a new major version of code
  8. internally maintained at Broadcom. E.g. brcmfmac4366b-pcie.bin (used for
  9. BCM4366B1) is based on 10.10.69.3309 while brcmfmac43602-pcie.ap.bin was
  10. based on 7.35.177.56.
  11. Currently setting AP 5 GHz channel doesn't work reliably with BCM4366B1.
  12. When setting e.g. 36 control channel with VHT80 (center channel 42)
  13. firmware may randomly pick one of:
  14. 1) 52 control channel with 58 as center one
  15. 2) 100 control channel with 106 as center one
  16. 3) 116 control channel with 122 as center one
  17. 4) 149 control channel with 155 as center one
  18. It seems new firmwares require setting AP mode (BRCMF_C_SET_AP) before
  19. specifying a channel. Changing an order of firmware calls fixes the
  20. problem. This requirement resulted in two separated "chanspec" calls,
  21. one in AP code path and one in P2P path.
  22. This fix was verified with BCM4366B1 and tested for regressions on
  23. BCM43602.
  24. Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
  25. Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
  26. ---
  27. --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
  28. +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
  29. @@ -4458,7 +4458,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
  30. struct brcmf_join_params join_params;
  31. enum nl80211_iftype dev_role;
  32. struct brcmf_fil_bss_enable_le bss_enable;
  33. - u16 chanspec;
  34. + u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
  35. bool mbss;
  36. int is_11d;
  37. @@ -4534,16 +4534,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
  38. brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
  39. + /* Parameters shared by all radio interfaces */
  40. if (!mbss) {
  41. - chanspec = chandef_to_chanspec(&cfg->d11inf,
  42. - &settings->chandef);
  43. - err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
  44. - if (err < 0) {
  45. - brcmf_err("Set Channel failed: chspec=%d, %d\n",
  46. - chanspec, err);
  47. - goto exit;
  48. - }
  49. -
  50. if (is_11d != ifp->vif->is_11d) {
  51. err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
  52. is_11d);
  53. @@ -4591,6 +4583,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
  54. err = -EINVAL;
  55. goto exit;
  56. }
  57. +
  58. + /* Interface specific setup */
  59. if (dev_role == NL80211_IFTYPE_AP) {
  60. if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
  61. brcmf_fil_iovar_int_set(ifp, "mbss", 1);
  62. @@ -4600,6 +4594,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
  63. brcmf_err("setting AP mode failed %d\n", err);
  64. goto exit;
  65. }
  66. + if (!mbss) {
  67. + /* Firmware 10.x requires setting channel after enabling
  68. + * AP and before bringing interface up.
  69. + */
  70. + err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
  71. + if (err < 0) {
  72. + brcmf_err("Set Channel failed: chspec=%d, %d\n",
  73. + chanspec, err);
  74. + goto exit;
  75. + }
  76. + }
  77. err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
  78. if (err < 0) {
  79. brcmf_err("BRCMF_C_UP error (%d)\n", err);
  80. @@ -4621,7 +4626,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
  81. goto exit;
  82. }
  83. brcmf_dbg(TRACE, "AP mode configuration complete\n");
  84. - } else {
  85. + } else if (dev_role == NL80211_IFTYPE_P2P_GO) {
  86. + err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
  87. + if (err < 0) {
  88. + brcmf_err("Set Channel failed: chspec=%d, %d\n",
  89. + chanspec, err);
  90. + goto exit;
  91. + }
  92. err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
  93. sizeof(ssid_le));
  94. if (err < 0) {
  95. @@ -4638,7 +4649,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
  96. }
  97. brcmf_dbg(TRACE, "GO mode configuration complete\n");
  98. + } else {
  99. + WARN_ON(1);
  100. }
  101. +
  102. set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
  103. brcmf_net_setcarrier(ifp, true);