351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
  2. Date: Fri, 20 May 2016 13:38:57 +0200
  3. Subject: [PATCH] brcmutil: add field storing control channel to the struct
  4. brcmu_chan
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. Our d11 code supports encoding/decoding channel info into/from chanspec
  9. format used by firmware. Current implementation is quite misleading
  10. because of the way "chnum" field is used.
  11. When encoding channel info, "chnum" has to be filled by a caller with
  12. *center* channel number. However when decoding chanspec the same field
  13. is filled with a *control* channel number.
  14. 1) This can be confusing. It's expected for information to be the same
  15. after encoding and decoding.
  16. 2) It doesn't allow accessing all info when decoding. Some functions may
  17. need to know both channel numbers, e.g. cfg80211 callback getting
  18. current channel.
  19. Solve this by adding a separated field for control channel.
  20. Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
  21. Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
  22. Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
  23. ---
  24. --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
  25. +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
  26. @@ -2765,7 +2765,7 @@ static s32 brcmf_inform_single_bss(struc
  27. if (!bi->ctl_ch) {
  28. ch.chspec = le16_to_cpu(bi->chanspec);
  29. cfg->d11inf.decchspec(&ch);
  30. - bi->ctl_ch = ch.chnum;
  31. + bi->ctl_ch = ch.control_ch_num;
  32. }
  33. channel = bi->ctl_ch;
  34. @@ -2883,7 +2883,7 @@ static s32 brcmf_inform_ibss(struct brcm
  35. else
  36. band = wiphy->bands[NL80211_BAND_5GHZ];
  37. - freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
  38. + freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
  39. cfg->channel = freq;
  40. notify_channel = ieee80211_get_channel(wiphy, freq);
  41. @@ -2893,7 +2893,7 @@ static s32 brcmf_inform_ibss(struct brcm
  42. notify_ielen = le32_to_cpu(bi->ie_length);
  43. notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
  44. - brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
  45. + brcmf_dbg(CONN, "channel: %d(%d)\n", ch.control_ch_num, freq);
  46. brcmf_dbg(CONN, "capability: %X\n", notify_capability);
  47. brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
  48. brcmf_dbg(CONN, "signal: %d\n", notify_signal);
  49. @@ -5311,7 +5311,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg8
  50. else
  51. band = wiphy->bands[NL80211_BAND_5GHZ];
  52. - freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
  53. + freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
  54. notify_channel = ieee80211_get_channel(wiphy, freq);
  55. done:
  56. @@ -5833,14 +5833,15 @@ static int brcmf_construct_chaninfo(stru
  57. channel = band->channels;
  58. index = band->n_channels;
  59. for (j = 0; j < band->n_channels; j++) {
  60. - if (channel[j].hw_value == ch.chnum) {
  61. + if (channel[j].hw_value == ch.control_ch_num) {
  62. index = j;
  63. break;
  64. }
  65. }
  66. channel[index].center_freq =
  67. - ieee80211_channel_to_frequency(ch.chnum, band->band);
  68. - channel[index].hw_value = ch.chnum;
  69. + ieee80211_channel_to_frequency(ch.control_ch_num,
  70. + band->band);
  71. + channel[index].hw_value = ch.control_ch_num;
  72. /* assuming the chanspecs order is HT20,
  73. * HT40 upper, HT40 lower, and VHT80.
  74. @@ -5942,7 +5943,7 @@ static int brcmf_enable_bw40_2g(struct b
  75. if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
  76. continue;
  77. for (j = 0; j < band->n_channels; j++) {
  78. - if (band->channels[j].hw_value == ch.chnum)
  79. + if (band->channels[j].hw_value == ch.control_ch_num)
  80. break;
  81. }
  82. if (WARN_ON(j == band->n_channels))
  83. --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
  84. +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
  85. @@ -1246,7 +1246,7 @@ bool brcmf_p2p_scan_finding_common_chann
  86. if (!bi->ctl_ch) {
  87. ch.chspec = le16_to_cpu(bi->chanspec);
  88. cfg->d11inf.decchspec(&ch);
  89. - bi->ctl_ch = ch.chnum;
  90. + bi->ctl_ch = ch.control_ch_num;
  91. }
  92. afx_hdl->peer_chan = bi->ctl_ch;
  93. brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, channel : %d\n",
  94. @@ -1385,7 +1385,7 @@ int brcmf_p2p_notify_action_frame_rx(str
  95. if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
  96. &p2p->status) &&
  97. (ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) {
  98. - afx_hdl->peer_chan = ch.chnum;
  99. + afx_hdl->peer_chan = ch.control_ch_num;
  100. brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n",
  101. afx_hdl->peer_chan);
  102. complete(&afx_hdl->act_frm_scan);
  103. @@ -1428,7 +1428,7 @@ int brcmf_p2p_notify_action_frame_rx(str
  104. memcpy(&mgmt_frame->u, frame, mgmt_frame_len);
  105. mgmt_frame_len += offsetof(struct ieee80211_mgmt, u);
  106. - freq = ieee80211_channel_to_frequency(ch.chnum,
  107. + freq = ieee80211_channel_to_frequency(ch.control_ch_num,
  108. ch.band == BRCMU_CHAN_BAND_2G ?
  109. NL80211_BAND_2GHZ :
  110. NL80211_BAND_5GHZ);
  111. @@ -1873,7 +1873,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere
  112. if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) &&
  113. (ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) {
  114. - afx_hdl->peer_chan = ch.chnum;
  115. + afx_hdl->peer_chan = ch.control_ch_num;
  116. brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n",
  117. afx_hdl->peer_chan);
  118. complete(&afx_hdl->act_frm_scan);
  119. @@ -1898,7 +1898,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere
  120. mgmt_frame = (u8 *)(rxframe + 1);
  121. mgmt_frame_len = e->datalen - sizeof(*rxframe);
  122. - freq = ieee80211_channel_to_frequency(ch.chnum,
  123. + freq = ieee80211_channel_to_frequency(ch.control_ch_num,
  124. ch.band == BRCMU_CHAN_BAND_2G ?
  125. NL80211_BAND_2GHZ :
  126. NL80211_BAND_5GHZ);
  127. --- a/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c
  128. +++ b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c
  129. @@ -107,6 +107,7 @@ static void brcmu_d11n_decchspec(struct
  130. u16 val;
  131. ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK);
  132. + ch->control_ch_num = ch->chnum;
  133. switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) {
  134. case BRCMU_CHSPEC_D11N_BW_20:
  135. @@ -118,10 +119,10 @@ static void brcmu_d11n_decchspec(struct
  136. val = ch->chspec & BRCMU_CHSPEC_D11N_SB_MASK;
  137. if (val == BRCMU_CHSPEC_D11N_SB_L) {
  138. ch->sb = BRCMU_CHAN_SB_L;
  139. - ch->chnum -= CH_10MHZ_APART;
  140. + ch->control_ch_num -= CH_10MHZ_APART;
  141. } else {
  142. ch->sb = BRCMU_CHAN_SB_U;
  143. - ch->chnum += CH_10MHZ_APART;
  144. + ch->control_ch_num += CH_10MHZ_APART;
  145. }
  146. break;
  147. default:
  148. @@ -147,6 +148,7 @@ static void brcmu_d11ac_decchspec(struct
  149. u16 val;
  150. ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK);
  151. + ch->control_ch_num = ch->chnum;
  152. switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) {
  153. case BRCMU_CHSPEC_D11AC_BW_20:
  154. @@ -158,10 +160,10 @@ static void brcmu_d11ac_decchspec(struct
  155. val = ch->chspec & BRCMU_CHSPEC_D11AC_SB_MASK;
  156. if (val == BRCMU_CHSPEC_D11AC_SB_L) {
  157. ch->sb = BRCMU_CHAN_SB_L;
  158. - ch->chnum -= CH_10MHZ_APART;
  159. + ch->control_ch_num -= CH_10MHZ_APART;
  160. } else if (val == BRCMU_CHSPEC_D11AC_SB_U) {
  161. ch->sb = BRCMU_CHAN_SB_U;
  162. - ch->chnum += CH_10MHZ_APART;
  163. + ch->control_ch_num += CH_10MHZ_APART;
  164. } else {
  165. WARN_ON_ONCE(1);
  166. }
  167. @@ -172,16 +174,16 @@ static void brcmu_d11ac_decchspec(struct
  168. BRCMU_CHSPEC_D11AC_SB_SHIFT);
  169. switch (ch->sb) {
  170. case BRCMU_CHAN_SB_LL:
  171. - ch->chnum -= CH_30MHZ_APART;
  172. + ch->control_ch_num -= CH_30MHZ_APART;
  173. break;
  174. case BRCMU_CHAN_SB_LU:
  175. - ch->chnum -= CH_10MHZ_APART;
  176. + ch->control_ch_num -= CH_10MHZ_APART;
  177. break;
  178. case BRCMU_CHAN_SB_UL:
  179. - ch->chnum += CH_10MHZ_APART;
  180. + ch->control_ch_num += CH_10MHZ_APART;
  181. break;
  182. case BRCMU_CHAN_SB_UU:
  183. - ch->chnum += CH_30MHZ_APART;
  184. + ch->control_ch_num += CH_30MHZ_APART;
  185. break;
  186. default:
  187. WARN_ON_ONCE(1);
  188. --- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_d11.h
  189. +++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_d11.h
  190. @@ -125,14 +125,36 @@ enum brcmu_chan_sb {
  191. BRCMU_CHAN_SB_UU = BRCMU_CHAN_SB_LUU,
  192. };
  193. +/**
  194. + * struct brcmu_chan - stores channel formats
  195. + *
  196. + * This structure can be used with functions translating chanspec into generic
  197. + * channel info and the other way.
  198. + *
  199. + * @chspec: firmware specific format
  200. + * @chnum: center channel number
  201. + * @control_ch_num: control channel number
  202. + * @band: frequency band
  203. + * @bw: channel width
  204. + * @sb: control sideband (location of control channel against the center one)
  205. + */
  206. struct brcmu_chan {
  207. u16 chspec;
  208. u8 chnum;
  209. + u8 control_ch_num;
  210. u8 band;
  211. enum brcmu_chan_bw bw;
  212. enum brcmu_chan_sb sb;
  213. };
  214. +/**
  215. + * struct brcmu_d11inf - provides functions translating channel format
  216. + *
  217. + * @io_type: determines version of channel format used by firmware
  218. + * @encchspec: encodes channel info into a chanspec, requires center channel
  219. + * number, ignores control one
  220. + * @decchspec: decodes chanspec into generic info
  221. + */
  222. struct brcmu_d11inf {
  223. u8 io_type;