mac80211: merge some more minstrel_ht performance improvements
[openwrt.git] / package / mac80211 / patches / 522-ath9k_per_chain_signal_strength.patch
1 --- a/include/net/mac80211.h
2 +++ b/include/net/mac80211.h
3 @@ -839,6 +839,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 or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
13 @@ -870,6 +873,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         u8 vendor_radiotap_align;
21         u8 vendor_radiotap_oui[3];
22 --- a/net/mac80211/sta_info.h
23 +++ b/net/mac80211/sta_info.h
24 @@ -342,6 +342,11 @@ struct sta_info {
25         int last_signal;
26         struct ewma avg_signal;
27         int last_ack_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[IEEE80211_NUM_TIDS + 1];
35  
36 --- a/net/mac80211/rx.c
37 +++ b/net/mac80211/rx.c
38 @@ -1383,6 +1383,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 @@ -1433,6 +1434,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 @@ -353,6 +353,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 @@ -721,6 +721,8 @@ struct station_parameters {
80   * @STATION_INFO_LOCAL_PM: @local_pm filled
81   * @STATION_INFO_PEER_PM: @peer_pm filled
82   * @STATION_INFO_NONPEER_PM: @nonpeer_pm 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 @@ -749,6 +751,8 @@ enum station_info_flags {
89         STATION_INFO_NONPEER_PM         = 1<<23,
90         STATION_INFO_RX_BYTES64         = 1<<24,
91         STATION_INFO_TX_BYTES64         = 1<<25,
92 +       STATION_INFO_CHAIN_SIGNAL       = 1<<26,
93 +       STATION_INFO_CHAIN_SIGNAL_AVG   = 1<<27,
94  };
95  
96  /**
97 @@ -842,6 +846,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 @@ -877,6 +884,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 @@ -937,6 +937,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 @@ -962,6 +963,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 @@ -1070,7 +1085,7 @@ static int ath_process_fft(struct ath_so
168         fft_sample.tlv.length = __cpu_to_be16(length);
169  
170         fft_sample.freq = __cpu_to_be16(ah->curchan->chan->center_freq);
171 -       fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0);
172 +       fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl[0]);
173         fft_sample.noise = ah->noise;
174  
175         switch (len - SPECTRAL_HT20_TOTAL_DATA_LEN) {
176 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
177 +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
178 @@ -475,12 +475,12 @@ int ath9k_hw_process_rxdesc_edma(struct 
179  
180         /* XXX: Keycache */
181         rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
182 -       rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00);
183 -       rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01);
184 -       rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02);
185 -       rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10);
186 -       rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11);
187 -       rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12);
188 +       rxs->rs_rssi_ctl[0] = MS(rxsp->status1, AR_RxRSSIAnt00);
189 +       rxs->rs_rssi_ctl[1] = MS(rxsp->status1, AR_RxRSSIAnt01);
190 +       rxs->rs_rssi_ctl[2] = MS(rxsp->status1, AR_RxRSSIAnt02);
191 +       rxs->rs_rssi_ext[0] = MS(rxsp->status5, AR_RxRSSIAnt10);
192 +       rxs->rs_rssi_ext[1] = MS(rxsp->status5, AR_RxRSSIAnt11);
193 +       rxs->rs_rssi_ext[2] = MS(rxsp->status5, AR_RxRSSIAnt12);
194  
195         if (rxsp->status11 & AR_RxKeyIdxValid)
196                 rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
197 --- a/drivers/net/wireless/ath/ath9k/mac.c
198 +++ b/drivers/net/wireless/ath/ath9k/mac.c
199 @@ -553,25 +553,25 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
200  
201         if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
202                 rs->rs_rssi = ATH9K_RSSI_BAD;
203 -               rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD;
204 -               rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD;
205 -               rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD;
206 -               rs->rs_rssi_ext0 = ATH9K_RSSI_BAD;
207 -               rs->rs_rssi_ext1 = ATH9K_RSSI_BAD;
208 -               rs->rs_rssi_ext2 = ATH9K_RSSI_BAD;
209 +               rs->rs_rssi_ctl[0] = ATH9K_RSSI_BAD;
210 +               rs->rs_rssi_ctl[1] = ATH9K_RSSI_BAD;
211 +               rs->rs_rssi_ctl[2] = ATH9K_RSSI_BAD;
212 +               rs->rs_rssi_ext[0] = ATH9K_RSSI_BAD;
213 +               rs->rs_rssi_ext[1] = ATH9K_RSSI_BAD;
214 +               rs->rs_rssi_ext[2] = ATH9K_RSSI_BAD;
215         } else {
216                 rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
217 -               rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
218 +               rs->rs_rssi_ctl[0] = MS(ads.ds_rxstatus0,
219                                                 AR_RxRSSIAnt00);
220 -               rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
221 +               rs->rs_rssi_ctl[1] = MS(ads.ds_rxstatus0,
222                                                 AR_RxRSSIAnt01);
223 -               rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
224 +               rs->rs_rssi_ctl[2] = MS(ads.ds_rxstatus0,
225                                                 AR_RxRSSIAnt02);
226 -               rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4,
227 +               rs->rs_rssi_ext[0] = MS(ads.ds_rxstatus4,
228                                                 AR_RxRSSIAnt10);
229 -               rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4,
230 +               rs->rs_rssi_ext[1] = MS(ads.ds_rxstatus4,
231                                                 AR_RxRSSIAnt11);
232 -               rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4,
233 +               rs->rs_rssi_ext[2] = MS(ads.ds_rxstatus4,
234                                                 AR_RxRSSIAnt12);
235         }
236         if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
237 --- a/drivers/net/wireless/ath/ath9k/debug.c
238 +++ b/drivers/net/wireless/ath/ath9k/debug.c
239 @@ -940,12 +940,12 @@ void ath_debug_stat_rx(struct ath_softc 
240  #ifdef CONFIG_ATH9K_MAC_DEBUG
241         spin_lock(&sc->debug.samp_lock);
242         RX_SAMP_DBG(jiffies) = jiffies;
243 -       RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0;
244 -       RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl1;
245 -       RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl2;
246 -       RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext0;
247 -       RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext1;
248 -       RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext2;
249 +       RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl[0];
250 +       RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl[1];
251 +       RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl[2];
252 +       RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext[0];
253 +       RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext[1];
254 +       RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext[2];
255         RX_SAMP_DBG(antenna) = rs->rs_antenna;
256         RX_SAMP_DBG(rssi) = rs->rs_rssi;
257         RX_SAMP_DBG(rate) = rs->rs_rate;
258 --- a/include/uapi/linux/nl80211.h
259 +++ b/include/uapi/linux/nl80211.h
260 @@ -1918,6 +1918,8 @@ enum nl80211_sta_bss_param {
261   * @NL80211_STA_INFO_PEER_PM: peer mesh STA link-specific power mode
262   * @NL80211_STA_INFO_NONPEER_PM: neighbor mesh STA power save mode towards
263   *     non-peer STA
264 + * @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU
265 + * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
266   * @__NL80211_STA_INFO_AFTER_LAST: internal
267   * @NL80211_STA_INFO_MAX: highest possible station info attribute
268   */
269 @@ -1947,6 +1949,8 @@ enum nl80211_sta_info {
270         NL80211_STA_INFO_NONPEER_PM,
271         NL80211_STA_INFO_RX_BYTES64,
272         NL80211_STA_INFO_TX_BYTES64,
273 +       NL80211_STA_INFO_CHAIN_SIGNAL,
274 +       NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
275  
276         /* keep last */
277         __NL80211_STA_INFO_AFTER_LAST,
278 --- a/net/wireless/nl80211.c
279 +++ b/net/wireless/nl80211.c
280 @@ -3082,6 +3082,32 @@ static bool nl80211_put_sta_rate(struct 
281         return true;
282  }
283  
284 +static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
285 +                              int id)
286 +{
287 +       void *attr;
288 +       int i = 0;
289 +
290 +       if (!mask)
291 +               return true;
292 +
293 +       attr = nla_nest_start(msg, id);
294 +       if (!attr)
295 +               return false;
296 +
297 +       for (i = 0; i < 4; i++) {
298 +               if (!(mask & BIT(i)))
299 +                       continue;
300 +
301 +               if (nla_put_u8(msg, i, signal[i]))
302 +                       return false;
303 +       }
304 +
305 +       nla_nest_end(msg, attr);
306 +
307 +       return true;
308 +}
309 +
310  static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
311                                 int flags,
312                                 struct cfg80211_registered_device *rdev,
313 @@ -3153,6 +3179,18 @@ static int nl80211_send_station(struct s
314         default:
315                 break;
316         }
317 +       if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) {
318 +               if (!nl80211_put_signal(msg, sinfo->chains,
319 +                                       sinfo->chain_signal,
320 +                                       NL80211_STA_INFO_CHAIN_SIGNAL))
321 +                       goto nla_put_failure;
322 +       }
323 +       if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) {
324 +               if (!nl80211_put_signal(msg, sinfo->chains,
325 +                                       sinfo->chain_signal_avg,
326 +                                       NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
327 +                       goto nla_put_failure;
328 +       }
329         if (sinfo->filled & STATION_INFO_TX_BITRATE) {
330                 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
331                                           NL80211_STA_INFO_TX_BITRATE))
332 --- a/net/mac80211/cfg.c
333 +++ b/net/mac80211/cfg.c
334 @@ -445,6 +445,7 @@ static void sta_set_sinfo(struct sta_inf
335         struct ieee80211_sub_if_data *sdata = sta->sdata;
336         struct ieee80211_local *local = sdata->local;
337         struct timespec uptime;
338 +       int i;
339  
340         sinfo->generation = sdata->local->sta_generation;
341  
342 @@ -484,6 +485,17 @@ static void sta_set_sinfo(struct sta_inf
343                         sinfo->signal = (s8)sta->last_signal;
344                 sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
345         }
346 +       if (sta->chains) {
347 +               sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
348 +                                STATION_INFO_CHAIN_SIGNAL_AVG;
349 +
350 +               sinfo->chains = sta->chains;
351 +               for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
352 +                       sinfo->chain_signal[i] = sta->chain_signal_last[i];
353 +                       sinfo->chain_signal_avg[i] =
354 +                               (s8) -ewma_read(&sta->chain_signal_avg[i]);
355 +               }
356 +       }
357  
358         sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
359         sta_set_rate_info_rx(sta, &sinfo->rxrate);
360 --- a/drivers/net/wireless/ath/ath9k/dfs.c
361 +++ b/drivers/net/wireless/ath/ath9k/dfs.c
362 @@ -164,8 +164,8 @@ void ath9k_dfs_process_phyerr(struct ath
363                 return;
364         }
365  
366 -       ard.rssi = rs->rs_rssi_ctl0;
367 -       ard.ext_rssi = rs->rs_rssi_ext0;
368 +       ard.rssi = rs->rs_rssi_ctl[0];
369 +       ard.ext_rssi = rs->rs_rssi_ext[0];
370  
371         /*
372          * hardware stores this as 8 bit signed value.
373 --- a/drivers/net/wireless/ath/ath9k/antenna.c
374 +++ b/drivers/net/wireless/ath/ath9k/antenna.c
375 @@ -546,14 +546,14 @@ void ath_ant_comb_scan(struct ath_softc 
376         struct ath_ant_comb *antcomb = &sc->ant_comb;
377         int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
378         int curr_main_set;
379 -       int main_rssi = rs->rs_rssi_ctl0;
380 -       int alt_rssi = rs->rs_rssi_ctl1;
381 +       int main_rssi = rs->rs_rssi_ctl[0];
382 +       int alt_rssi = rs->rs_rssi_ctl[1];
383         int rx_ant_conf,  main_ant_conf;
384         bool short_scan = false;
385  
386 -       rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) &
387 +       rx_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_CURRENT_SHIFT) &
388                        ATH_ANT_RX_MASK;
389 -       main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
390 +       main_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_MAIN_SHIFT) &
391                          ATH_ANT_RX_MASK;
392  
393         /* Record packet only when both main_rssi and  alt_rssi is positive */