rpcd: iwinfo plugin fixes
[openwrt.git] / package / kernel / mac80211 / patches / 351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch
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
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.
15
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
20    current channel.
21 Solve this by adding a separated field for control channel.
22
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>
26 ---
27
28 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
29 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
30 @@ -2705,7 +2705,7 @@ static s32 brcmf_inform_single_bss(struc
31         if (!bi->ctl_ch) {
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;
36         }
37         channel = bi->ctl_ch;
38  
39 @@ -2823,7 +2823,7 @@ static s32 brcmf_inform_ibss(struct brcm
40         else
41                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
42  
43 -       freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
44 +       freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
45         cfg->channel = freq;
46         notify_channel = ieee80211_get_channel(wiphy, freq);
47  
48 @@ -2833,7 +2833,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;
51  
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 @@ -5251,7 +5251,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg8
58         else
59                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
60  
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);
64  
65  done:
66 @@ -5773,14 +5773,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) {
72                                 index = j;
73                                 break;
74                         }
75                 }
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,
80 +                                                      band->band);
81 +               channel[index].hw_value = ch.control_ch_num;
82  
83                 /* assuming the chanspecs order is HT20,
84                  * HT40 upper, HT40 lower, and VHT80.
85 @@ -5882,7 +5883,7 @@ static int brcmf_enable_bw40_2g(struct b
86                         if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
87                                 continue;
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)
91                                         break;
92                         }
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
97                 if (!bi->ctl_ch) {
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;
102                 }
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,
107                                      &p2p->status) &&
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",
112                                           afx_hdl->peer_chan);
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);
117  
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
124  
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",
130                           afx_hdl->peer_chan);
131                 complete(&afx_hdl->act_frm_scan);
132 @@ -1898,7 +1898,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere
133  
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
144         u16 val;
145  
146         ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK);
147 +       ch->control_ch_num = ch->chnum;
148  
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;
157                 } else {
158                         ch->sb = BRCMU_CHAN_SB_U;
159 -                       ch->chnum += CH_10MHZ_APART;
160 +                       ch->control_ch_num += CH_10MHZ_APART;
161                 }
162                 break;
163         default:
164 @@ -147,6 +148,7 @@ static void brcmu_d11ac_decchspec(struct
165         u16 val;
166  
167         ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK);
168 +       ch->control_ch_num = ch->chnum;
169  
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;
182                 } else {
183                         WARN_ON_ONCE(1);
184                 }
185 @@ -172,16 +174,16 @@ static void brcmu_d11ac_decchspec(struct
186                                          BRCMU_CHSPEC_D11AC_SB_SHIFT);
187                 switch (ch->sb) {
188                 case BRCMU_CHAN_SB_LL:
189 -                       ch->chnum -= CH_30MHZ_APART;
190 +                       ch->control_ch_num -= CH_30MHZ_APART;
191                         break;
192                 case BRCMU_CHAN_SB_LU:
193 -                       ch->chnum -= CH_10MHZ_APART;
194 +                       ch->control_ch_num -= CH_10MHZ_APART;
195                         break;
196                 case BRCMU_CHAN_SB_UL:
197 -                       ch->chnum += CH_10MHZ_APART;
198 +                       ch->control_ch_num += CH_10MHZ_APART;
199                         break;
200                 case BRCMU_CHAN_SB_UU:
201 -                       ch->chnum += CH_30MHZ_APART;
202 +                       ch->control_ch_num += CH_30MHZ_APART;
203                         break;
204                 default:
205                         WARN_ON_ONCE(1);
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,
210  };
211  
212 +/**
213 + * struct brcmu_chan - stores channel formats
214 + *
215 + * This structure can be used with functions translating chanspec into generic
216 + * channel info and the other way.
217 + *
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)
224 + */
225  struct brcmu_chan {
226         u16 chspec;
227         u8 chnum;
228 +       u8 control_ch_num;
229         u8 band;
230         enum brcmu_chan_bw bw;
231         enum brcmu_chan_sb sb;
232  };
233  
234 +/**
235 + * struct brcmu_d11inf - provides functions translating channel format
236 + *
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
241 + */
242  struct brcmu_d11inf {
243         u8 io_type;
244