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