mac80211: update to latest version, fix tx gain patch
[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 @@ -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 @@ -325,6 +325,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 @@ -1254,6 +1254,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 @@ -1298,6 +1299,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 @@ -254,6 +254,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 @@ -546,6 +546,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 @@ -569,6 +571,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 @@ -652,6 +656,9 @@ struct sta_bss_parameters {
100   *     For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
101   * @signal_avg: Average signal strength, type depends on the wiphy's signal_type.
102   *     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 @@ -684,6 +691,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 @@ -955,6 +955,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 @@ -980,6 +981,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 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
170 +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
171 @@ -458,12 +458,12 @@ int ath9k_hw_process_rxdesc_edma(struct 
172  
173         /* XXX: Keycache */
174         rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
175 -       rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00);
176 -       rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01);
177 -       rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02);
178 -       rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10);
179 -       rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11);
180 -       rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12);
181 +       rxs->rs_rssi_ctl[0] = MS(rxsp->status1, AR_RxRSSIAnt00);
182 +       rxs->rs_rssi_ctl[1] = MS(rxsp->status1, AR_RxRSSIAnt01);
183 +       rxs->rs_rssi_ctl[2] = MS(rxsp->status1, AR_RxRSSIAnt02);
184 +       rxs->rs_rssi_ext[0] = MS(rxsp->status5, AR_RxRSSIAnt10);
185 +       rxs->rs_rssi_ext[1] = MS(rxsp->status5, AR_RxRSSIAnt11);
186 +       rxs->rs_rssi_ext[2] = MS(rxsp->status5, AR_RxRSSIAnt12);
187  
188         if (rxsp->status11 & AR_RxKeyIdxValid)
189                 rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
190 --- a/drivers/net/wireless/ath/ath9k/mac.c
191 +++ b/drivers/net/wireless/ath/ath9k/mac.c
192 @@ -553,25 +553,25 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
193  
194         if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
195                 rs->rs_rssi = ATH9K_RSSI_BAD;
196 -               rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD;
197 -               rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD;
198 -               rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD;
199 -               rs->rs_rssi_ext0 = ATH9K_RSSI_BAD;
200 -               rs->rs_rssi_ext1 = ATH9K_RSSI_BAD;
201 -               rs->rs_rssi_ext2 = ATH9K_RSSI_BAD;
202 +               rs->rs_rssi_ctl[0] = ATH9K_RSSI_BAD;
203 +               rs->rs_rssi_ctl[1] = ATH9K_RSSI_BAD;
204 +               rs->rs_rssi_ctl[2] = ATH9K_RSSI_BAD;
205 +               rs->rs_rssi_ext[0] = ATH9K_RSSI_BAD;
206 +               rs->rs_rssi_ext[1] = ATH9K_RSSI_BAD;
207 +               rs->rs_rssi_ext[2] = ATH9K_RSSI_BAD;
208         } else {
209                 rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
210 -               rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
211 +               rs->rs_rssi_ctl[0] = MS(ads.ds_rxstatus0,
212                                                 AR_RxRSSIAnt00);
213 -               rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
214 +               rs->rs_rssi_ctl[1] = MS(ads.ds_rxstatus0,
215                                                 AR_RxRSSIAnt01);
216 -               rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
217 +               rs->rs_rssi_ctl[2] = MS(ads.ds_rxstatus0,
218                                                 AR_RxRSSIAnt02);
219 -               rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4,
220 +               rs->rs_rssi_ext[0] = MS(ads.ds_rxstatus4,
221                                                 AR_RxRSSIAnt10);
222 -               rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4,
223 +               rs->rs_rssi_ext[1] = MS(ads.ds_rxstatus4,
224                                                 AR_RxRSSIAnt11);
225 -               rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4,
226 +               rs->rs_rssi_ext[2] = MS(ads.ds_rxstatus4,
227                                                 AR_RxRSSIAnt12);
228         }
229         if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
230 --- a/drivers/net/wireless/ath/ath9k/debug.c
231 +++ b/drivers/net/wireless/ath/ath9k/debug.c
232 @@ -997,12 +997,12 @@ void ath_debug_stat_rx(struct ath_softc 
233  #ifdef CONFIG_ATH9K_MAC_DEBUG
234         spin_lock(&sc->debug.samp_lock);
235         RX_SAMP_DBG(jiffies) = jiffies;
236 -       RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0;
237 -       RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl1;
238 -       RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl2;
239 -       RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext0;
240 -       RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext1;
241 -       RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext2;
242 +       RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl[0];
243 +       RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl[1];
244 +       RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl[2];
245 +       RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext[0];
246 +       RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext[1];
247 +       RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext[2];
248         RX_SAMP_DBG(antenna) = rs->rs_antenna;
249         RX_SAMP_DBG(rssi) = rs->rs_rssi;
250         RX_SAMP_DBG(rate) = rs->rs_rate;
251 --- a/include/linux/nl80211.h
252 +++ b/include/linux/nl80211.h
253 @@ -1729,6 +1729,8 @@ enum nl80211_sta_bss_param {
254   * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update.
255   * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32)
256   * @NL80211_STA_INFO_T_OFFSET: timing offset with respect to this STA (s64)
257 + * @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU
258 + * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
259   * @__NL80211_STA_INFO_AFTER_LAST: internal
260   * @NL80211_STA_INFO_MAX: highest possible station info attribute
261   */
262 @@ -1753,6 +1755,8 @@ enum nl80211_sta_info {
263         NL80211_STA_INFO_STA_FLAGS,
264         NL80211_STA_INFO_BEACON_LOSS,
265         NL80211_STA_INFO_T_OFFSET,
266 +       NL80211_STA_INFO_CHAIN_SIGNAL,
267 +       NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
268  
269         /* keep last */
270         __NL80211_STA_INFO_AFTER_LAST,
271 --- a/net/wireless/nl80211.c
272 +++ b/net/wireless/nl80211.c
273 @@ -2648,6 +2648,32 @@ nla_put_failure:
274         return false;
275  }
276  
277 +static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
278 +                              int id)
279 +{
280 +       void *attr;
281 +       int i = 0;
282 +
283 +       if (!mask)
284 +               return true;
285 +
286 +       attr = nla_nest_start(msg, id);
287 +       if (!attr)
288 +               return false;
289 +
290 +       for (i = 0; i < 4; i++) {
291 +               if (!(mask & BIT(i)))
292 +                       continue;
293 +
294 +               if (nla_put_u8(msg, i, signal[i]))
295 +                       return false;
296 +       }
297 +
298 +       nla_nest_end(msg, attr);
299 +
300 +       return true;
301 +}
302 +
303  static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
304                                 int flags,
305                                 struct cfg80211_registered_device *rdev,
306 @@ -2709,6 +2735,18 @@ static int nl80211_send_station(struct s
307         default:
308                 break;
309         }
310 +       if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) {
311 +               if (!nl80211_put_signal(msg, sinfo->chains,
312 +                                       sinfo->chain_signal,
313 +                                       NL80211_STA_INFO_CHAIN_SIGNAL))
314 +                       goto nla_put_failure;
315 +       }
316 +       if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) {
317 +               if (!nl80211_put_signal(msg, sinfo->chains,
318 +                                       sinfo->chain_signal_avg,
319 +                                       NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
320 +                       goto nla_put_failure;
321 +       }
322         if (sinfo->filled & STATION_INFO_TX_BITRATE) {
323                 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
324                                           NL80211_STA_INFO_TX_BITRATE))
325 --- a/net/mac80211/cfg.c
326 +++ b/net/mac80211/cfg.c
327 @@ -355,6 +355,7 @@ static void sta_set_sinfo(struct sta_inf
328         struct ieee80211_sub_if_data *sdata = sta->sdata;
329         struct ieee80211_local *local = sdata->local;
330         struct timespec uptime;
331 +       int i;
332  
333         sinfo->generation = sdata->local->sta_generation;
334  
335 @@ -394,6 +395,17 @@ static void sta_set_sinfo(struct sta_inf
336                         sinfo->signal = (s8)sta->last_signal;
337                 sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
338         }
339 +       if (sta->chains) {
340 +               sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
341 +                                STATION_INFO_CHAIN_SIGNAL_AVG;
342 +
343 +               sinfo->chains = sta->chains;
344 +               for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
345 +                       sinfo->chain_signal[i] = sta->chain_signal_last[i];
346 +                       sinfo->chain_signal_avg[i] =
347 +                               (s8) -ewma_read(&sta->chain_signal_avg[i]);
348 +               }
349 +       }
350  
351         sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
352  
353 --- a/drivers/net/wireless/ath/ath9k/dfs.c
354 +++ b/drivers/net/wireless/ath/ath9k/dfs.c
355 @@ -164,8 +164,8 @@ void ath9k_dfs_process_phyerr(struct ath
356                 return;
357         }
358  
359 -       ard.rssi = rs->rs_rssi_ctl0;
360 -       ard.ext_rssi = rs->rs_rssi_ext0;
361 +       ard.rssi = rs->rs_rssi_ctl[0];
362 +       ard.ext_rssi = rs->rs_rssi_ext[0];
363  
364         /*
365          * hardware stores this as 8 bit signed value.
366 --- a/drivers/net/wireless/ath/ath9k/antenna.c
367 +++ b/drivers/net/wireless/ath/ath9k/antenna.c
368 @@ -529,14 +529,14 @@ void ath_ant_comb_scan(struct ath_softc 
369         struct ath_ant_comb *antcomb = &sc->ant_comb;
370         int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
371         int curr_main_set;
372 -       int main_rssi = rs->rs_rssi_ctl0;
373 -       int alt_rssi = rs->rs_rssi_ctl1;
374 +       int main_rssi = rs->rs_rssi_ctl[0];
375 +       int alt_rssi = rs->rs_rssi_ctl[1];
376         int rx_ant_conf,  main_ant_conf;
377         bool short_scan = false;
378  
379 -       rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) &
380 +       rx_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_CURRENT_SHIFT) &
381                        ATH_ANT_RX_MASK;
382 -       main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
383 +       main_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_MAIN_SHIFT) &
384                          ATH_ANT_RX_MASK;
385  
386         /* Record packet only when both main_rssi and  alt_rssi is positive */