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