mac80211: update to 2012-09-07, adds ath9k beacon fixes, mesh/adhoc fixes, and more
[openwrt/svn-archive/archive.git] / package / mac80211 / patches / 522-ath9k_per_chain_signal_strength.patch
1 --- a/include/net/mac80211.h
2 +++ b/include/net/mac80211.h
3 @@ -729,6 +729,9 @@ enum mac80211_rx_flags {
4 * @signal: signal strength when receiving this frame, either in dBm, in dB or
5 * unspecified depending on the hardware capabilities flags
6 * @IEEE80211_HW_SIGNAL_*
7 + * @chains: bitmask of receive chains for which separate signal strength
8 + * values were filled.
9 + * @chain_signal: per-chain signal strength, same format as @signal
10 * @antenna: antenna used
11 * @rate_idx: index of data rate into band's supported rates or MCS index if
12 * HT rates are use (RX_FLAG_HT)
13 @@ -749,6 +752,8 @@ struct ieee80211_rx_status {
14 u8 band;
15 u8 antenna;
16 s8 signal;
17 + u8 chains;
18 + s8 chain_signal[4];
19 u8 ampdu_delimiter_crc;
20 };
21
22 --- a/net/mac80211/sta_info.h
23 +++ b/net/mac80211/sta_info.h
24 @@ -325,6 +325,11 @@ struct sta_info {
25 unsigned long rx_dropped;
26 int last_signal;
27 struct ewma avg_signal;
28 +
29 + u8 chains;
30 + s8 chain_signal_last[4];
31 + struct ewma chain_signal_avg[4];
32 +
33 /* Plus 1 for non-QoS frames */
34 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES + 1];
35
36 --- a/net/mac80211/rx.c
37 +++ b/net/mac80211/rx.c
38 @@ -1271,6 +1271,7 @@ ieee80211_rx_h_sta_process(struct ieee80
39 struct sk_buff *skb = rx->skb;
40 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
41 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
42 + int i;
43
44 if (!sta)
45 return RX_CONTINUE;
46 @@ -1315,6 +1316,19 @@ ieee80211_rx_h_sta_process(struct ieee80
47 ewma_add(&sta->avg_signal, -status->signal);
48 }
49
50 + if (status->chains) {
51 + sta->chains = status->chains;
52 + for (i = 0; i < 4; i++) {
53 + int signal = status->chain_signal[i];
54 +
55 + if (!(status->chains & BIT(i)))
56 + continue;
57 +
58 + sta->chain_signal_last[i] = signal;
59 + ewma_add(&sta->chain_signal_avg[i], -signal);
60 + }
61 + }
62 +
63 /*
64 * Change STA power saving mode only at the end of a frame
65 * exchange sequence.
66 --- a/net/mac80211/sta_info.c
67 +++ b/net/mac80211/sta_info.c
68 @@ -254,6 +254,8 @@ struct sta_info *sta_info_alloc(struct i
69 do_posix_clock_monotonic_gettime(&uptime);
70 sta->last_connected = uptime.tv_sec;
71 ewma_init(&sta->avg_signal, 1024, 8);
72 + for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++)
73 + ewma_init(&sta->chain_signal_avg[i], 1024, 8);
74
75 if (sta_prepare_rate_control(local, sta, gfp)) {
76 kfree(sta);
77 --- a/include/net/cfg80211.h
78 +++ b/include/net/cfg80211.h
79 @@ -549,6 +549,8 @@ struct station_parameters {
80 * @STATION_INFO_STA_FLAGS: @sta_flags filled
81 * @STATION_INFO_BEACON_LOSS_COUNT: @beacon_loss_count filled
82 * @STATION_INFO_T_OFFSET: @t_offset filled
83 + * @STATION_INFO_CHAIN_SIGNAL: @chain_signal filled
84 + * @STATION_INFO_CHAIN_SIGNAL_AVG: @chain_signal_avg filled
85 */
86 enum station_info_flags {
87 STATION_INFO_INACTIVE_TIME = 1<<0,
88 @@ -572,6 +574,8 @@ enum station_info_flags {
89 STATION_INFO_STA_FLAGS = 1<<18,
90 STATION_INFO_BEACON_LOSS_COUNT = 1<<19,
91 STATION_INFO_T_OFFSET = 1<<20,
92 + STATION_INFO_CHAIN_SIGNAL = 1<<21,
93 + STATION_INFO_CHAIN_SIGNAL_AVG = 1<<22,
94 };
95
96 /**
97 @@ -655,6 +659,9 @@ struct sta_bss_parameters {
98 * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
99 * @signal_avg: Average signal strength, type depends on the wiphy's signal_type.
100 * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
101 + * @chains: bitmask for filled values in @chain_signal, @chain_signal_avg
102 + * @chain_signal: per-chain signal strength of last received packet in dBm
103 + * @chain_signal_avg: per-chain signal strength average in dBm
104 * @txrate: current unicast bitrate from this station
105 * @rxrate: current unicast bitrate to this station
106 * @rx_packets: packets received from this station
107 @@ -687,6 +694,11 @@ struct station_info {
108 u8 plink_state;
109 s8 signal;
110 s8 signal_avg;
111 +
112 + u8 chains;
113 + s8 chain_signal[4];
114 + s8 chain_signal_avg[4];
115 +
116 struct rate_info txrate;
117 struct rate_info rxrate;
118 u32 rx_packets;
119 --- a/drivers/net/wireless/ath/ath9k/mac.h
120 +++ b/drivers/net/wireless/ath/ath9k/mac.h
121 @@ -133,12 +133,8 @@ struct ath_rx_status {
122 u8 rs_rate;
123 u8 rs_antenna;
124 u8 rs_more;
125 - int8_t rs_rssi_ctl0;
126 - int8_t rs_rssi_ctl1;
127 - int8_t rs_rssi_ctl2;
128 - int8_t rs_rssi_ext0;
129 - int8_t rs_rssi_ext1;
130 - int8_t rs_rssi_ext2;
131 + int8_t rs_rssi_ctl[3];
132 + int8_t rs_rssi_ext[3];
133 u8 rs_isaggr;
134 u8 rs_moreaggr;
135 u8 rs_num_delims;
136 --- a/drivers/net/wireless/ath/ath9k/recv.c
137 +++ b/drivers/net/wireless/ath/ath9k/recv.c
138 @@ -955,6 +955,7 @@ static int ath9k_rx_skb_preprocess(struc
139 bool *decrypt_error)
140 {
141 struct ath_hw *ah = common->ah;
142 + int i, j;
143
144 /*
145 * everything but the rate is checked here, the rate check is done
146 @@ -980,6 +981,20 @@ static int ath9k_rx_skb_preprocess(struc
147 if (rx_stats->rs_moreaggr)
148 rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
149
150 + for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) {
151 + s8 rssi;
152 +
153 + if (!(ah->rxchainmask & BIT(i)))
154 + continue;
155 +
156 + rssi = rx_stats->rs_rssi_ctl[i];
157 + if (rssi != ATH9K_RSSI_BAD) {
158 + rx_status->chains |= BIT(j);
159 + rx_status->chain_signal[j] = ah->noise + rssi;
160 + }
161 + j++;
162 + }
163 +
164 return 0;
165 }
166
167 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
168 +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
169 @@ -458,12 +458,12 @@ int ath9k_hw_process_rxdesc_edma(struct
170
171 /* XXX: Keycache */
172 rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
173 - rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00);
174 - rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01);
175 - rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02);
176 - rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10);
177 - rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11);
178 - rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12);
179 + rxs->rs_rssi_ctl[0] = MS(rxsp->status1, AR_RxRSSIAnt00);
180 + rxs->rs_rssi_ctl[1] = MS(rxsp->status1, AR_RxRSSIAnt01);
181 + rxs->rs_rssi_ctl[2] = MS(rxsp->status1, AR_RxRSSIAnt02);
182 + rxs->rs_rssi_ext[0] = MS(rxsp->status5, AR_RxRSSIAnt10);
183 + rxs->rs_rssi_ext[1] = MS(rxsp->status5, AR_RxRSSIAnt11);
184 + rxs->rs_rssi_ext[2] = MS(rxsp->status5, AR_RxRSSIAnt12);
185
186 if (rxsp->status11 & AR_RxKeyIdxValid)
187 rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
188 --- a/drivers/net/wireless/ath/ath9k/mac.c
189 +++ b/drivers/net/wireless/ath/ath9k/mac.c
190 @@ -553,25 +553,25 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
191
192 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
193 rs->rs_rssi = ATH9K_RSSI_BAD;
194 - rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD;
195 - rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD;
196 - rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD;
197 - rs->rs_rssi_ext0 = ATH9K_RSSI_BAD;
198 - rs->rs_rssi_ext1 = ATH9K_RSSI_BAD;
199 - rs->rs_rssi_ext2 = ATH9K_RSSI_BAD;
200 + rs->rs_rssi_ctl[0] = ATH9K_RSSI_BAD;
201 + rs->rs_rssi_ctl[1] = ATH9K_RSSI_BAD;
202 + rs->rs_rssi_ctl[2] = ATH9K_RSSI_BAD;
203 + rs->rs_rssi_ext[0] = ATH9K_RSSI_BAD;
204 + rs->rs_rssi_ext[1] = ATH9K_RSSI_BAD;
205 + rs->rs_rssi_ext[2] = ATH9K_RSSI_BAD;
206 } else {
207 rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
208 - rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
209 + rs->rs_rssi_ctl[0] = MS(ads.ds_rxstatus0,
210 AR_RxRSSIAnt00);
211 - rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
212 + rs->rs_rssi_ctl[1] = MS(ads.ds_rxstatus0,
213 AR_RxRSSIAnt01);
214 - rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
215 + rs->rs_rssi_ctl[2] = MS(ads.ds_rxstatus0,
216 AR_RxRSSIAnt02);
217 - rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4,
218 + rs->rs_rssi_ext[0] = MS(ads.ds_rxstatus4,
219 AR_RxRSSIAnt10);
220 - rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4,
221 + rs->rs_rssi_ext[1] = MS(ads.ds_rxstatus4,
222 AR_RxRSSIAnt11);
223 - rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4,
224 + rs->rs_rssi_ext[2] = MS(ads.ds_rxstatus4,
225 AR_RxRSSIAnt12);
226 }
227 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
228 --- a/drivers/net/wireless/ath/ath9k/debug.c
229 +++ b/drivers/net/wireless/ath/ath9k/debug.c
230 @@ -997,12 +997,12 @@ void ath_debug_stat_rx(struct ath_softc
231 #ifdef CONFIG_ATH9K_MAC_DEBUG
232 spin_lock(&sc->debug.samp_lock);
233 RX_SAMP_DBG(jiffies) = jiffies;
234 - RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0;
235 - RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl1;
236 - RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl2;
237 - RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext0;
238 - RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext1;
239 - RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext2;
240 + RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl[0];
241 + RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl[1];
242 + RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl[2];
243 + RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext[0];
244 + RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext[1];
245 + RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext[2];
246 RX_SAMP_DBG(antenna) = rs->rs_antenna;
247 RX_SAMP_DBG(rssi) = rs->rs_rssi;
248 RX_SAMP_DBG(rate) = rs->rs_rate;
249 --- a/include/linux/nl80211.h
250 +++ b/include/linux/nl80211.h
251 @@ -1760,6 +1760,8 @@ enum nl80211_sta_bss_param {
252 * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update.
253 * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32)
254 * @NL80211_STA_INFO_T_OFFSET: timing offset with respect to this STA (s64)
255 + * @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU
256 + * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
257 * @__NL80211_STA_INFO_AFTER_LAST: internal
258 * @NL80211_STA_INFO_MAX: highest possible station info attribute
259 */
260 @@ -1784,6 +1786,8 @@ enum nl80211_sta_info {
261 NL80211_STA_INFO_STA_FLAGS,
262 NL80211_STA_INFO_BEACON_LOSS,
263 NL80211_STA_INFO_T_OFFSET,
264 + NL80211_STA_INFO_CHAIN_SIGNAL,
265 + NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
266
267 /* keep last */
268 __NL80211_STA_INFO_AFTER_LAST,
269 --- a/net/wireless/nl80211.c
270 +++ b/net/wireless/nl80211.c
271 @@ -2769,6 +2769,32 @@ nla_put_failure:
272 return false;
273 }
274
275 +static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
276 + int id)
277 +{
278 + void *attr;
279 + int i = 0;
280 +
281 + if (!mask)
282 + return true;
283 +
284 + attr = nla_nest_start(msg, id);
285 + if (!attr)
286 + return false;
287 +
288 + for (i = 0; i < 4; i++) {
289 + if (!(mask & BIT(i)))
290 + continue;
291 +
292 + if (nla_put_u8(msg, i, signal[i]))
293 + return false;
294 + }
295 +
296 + nla_nest_end(msg, attr);
297 +
298 + return true;
299 +}
300 +
301 static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
302 int flags,
303 struct cfg80211_registered_device *rdev,
304 @@ -2830,6 +2856,18 @@ static int nl80211_send_station(struct s
305 default:
306 break;
307 }
308 + if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) {
309 + if (!nl80211_put_signal(msg, sinfo->chains,
310 + sinfo->chain_signal,
311 + NL80211_STA_INFO_CHAIN_SIGNAL))
312 + goto nla_put_failure;
313 + }
314 + if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) {
315 + if (!nl80211_put_signal(msg, sinfo->chains,
316 + sinfo->chain_signal_avg,
317 + NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
318 + goto nla_put_failure;
319 + }
320 if (sinfo->filled & STATION_INFO_TX_BITRATE) {
321 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
322 NL80211_STA_INFO_TX_BITRATE))
323 --- a/net/mac80211/cfg.c
324 +++ b/net/mac80211/cfg.c
325 @@ -367,6 +367,7 @@ static void sta_set_sinfo(struct sta_inf
326 struct ieee80211_sub_if_data *sdata = sta->sdata;
327 struct ieee80211_local *local = sdata->local;
328 struct timespec uptime;
329 + int i;
330
331 sinfo->generation = sdata->local->sta_generation;
332
333 @@ -406,6 +407,17 @@ static void sta_set_sinfo(struct sta_inf
334 sinfo->signal = (s8)sta->last_signal;
335 sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
336 }
337 + if (sta->chains) {
338 + sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
339 + STATION_INFO_CHAIN_SIGNAL_AVG;
340 +
341 + sinfo->chains = sta->chains;
342 + for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
343 + sinfo->chain_signal[i] = sta->chain_signal_last[i];
344 + sinfo->chain_signal_avg[i] =
345 + (s8) -ewma_read(&sta->chain_signal_avg[i]);
346 + }
347 + }
348
349 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
350
351 --- a/drivers/net/wireless/ath/ath9k/dfs.c
352 +++ b/drivers/net/wireless/ath/ath9k/dfs.c
353 @@ -164,8 +164,8 @@ void ath9k_dfs_process_phyerr(struct ath
354 return;
355 }
356
357 - ard.rssi = rs->rs_rssi_ctl0;
358 - ard.ext_rssi = rs->rs_rssi_ext0;
359 + ard.rssi = rs->rs_rssi_ctl[0];
360 + ard.ext_rssi = rs->rs_rssi_ext[0];
361
362 /*
363 * hardware stores this as 8 bit signed value.
364 --- a/drivers/net/wireless/ath/ath9k/antenna.c
365 +++ b/drivers/net/wireless/ath/ath9k/antenna.c
366 @@ -529,14 +529,14 @@ void ath_ant_comb_scan(struct ath_softc
367 struct ath_ant_comb *antcomb = &sc->ant_comb;
368 int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
369 int curr_main_set;
370 - int main_rssi = rs->rs_rssi_ctl0;
371 - int alt_rssi = rs->rs_rssi_ctl1;
372 + int main_rssi = rs->rs_rssi_ctl[0];
373 + int alt_rssi = rs->rs_rssi_ctl[1];
374 int rx_ant_conf, main_ant_conf;
375 bool short_scan = false;
376
377 - rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) &
378 + rx_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_CURRENT_SHIFT) &
379 ATH_ANT_RX_MASK;
380 - main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
381 + main_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_MAIN_SHIFT) &
382 ATH_ANT_RX_MASK;
383
384 /* Record packet only when both main_rssi and alt_rssi is positive */