Root/package/mac80211/patches/522-ath9k_per_chain_signal_strength.patch

1--- a/include/net/mac80211.h
2+++ b/include/net/mac80211.h
3@@ -816,6 +816,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@@ -847,6 +850,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@@ -329,6 +329,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@@ -1375,6 +1375,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@@ -1425,6 +1426,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@@ -324,6 +324,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@@ -653,6 +653,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@@ -676,6 +678,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@@ -769,6 +773,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@@ -801,6 +808,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@@ -475,12 +475,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@@ -939,12 +939,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/uapi/linux/nl80211.h
250+++ b/include/uapi/linux/nl80211.h
251@@ -1834,6 +1834,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@@ -1858,6 +1860,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@@ -2910,6 +2910,32 @@ static bool nl80211_put_sta_rate(struct
272     return true;
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 portid, u32 seq,
302                 int flags,
303                 struct cfg80211_registered_device *rdev,
304@@ -2971,6 +2997,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@@ -435,6 +435,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@@ -474,6 +475,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     sta_set_rate_info_rx(sta, &sinfo->rxrate);
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@@ -546,14 +546,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 */
385

Archive Download this file



interactive