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

1--- a/include/net/mac80211.h
2+++ b/include/net/mac80211.h
3@@ -684,6 +684,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@@ -697,6 +700,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@@ -313,6 +313,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@@ -1270,6 +1270,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@@ -1312,6 +1313,19 @@ ieee80211_rx_h_sta_process(struct ieee80
49     sta->last_signal = status->signal;
50     ewma_add(&sta->avg_signal, -status->signal);
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@@ -518,6 +518,8 @@ struct station_parameters {
82  * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
83  * @STATION_INFO_STA_FLAGS: @sta_flags filled
84  * @STATION_INFO_BEACON_LOSS_COUNT: @beacon_loss_count 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@@ -539,7 +541,9 @@ enum station_info_flags {
91     STATION_INFO_CONNECTED_TIME = 1<<16,
92     STATION_INFO_ASSOC_REQ_IES = 1<<17,
93     STATION_INFO_STA_FLAGS = 1<<18,
94- STATION_INFO_BEACON_LOSS_COUNT = 1<<19
95+ STATION_INFO_BEACON_LOSS_COUNT = 1<<19,
96+ STATION_INFO_CHAIN_SIGNAL = 1<<20,
97+ STATION_INFO_CHAIN_SIGNAL_AVG = 1<<21,
98 };
99 
100 /**
101@@ -619,6 +623,9 @@ struct sta_bss_parameters {
102  * @plink_state: mesh peer link state
103  * @signal: signal strength of last received packet in dBm
104  * @signal_avg: signal strength average in dBm
105+ * @chains: bitmask for filled values in @chain_signal, @chain_signal_avg
106+ * @chain_signal: per-chain signal strength of last received packet in dBm
107+ * @chain_signal_avg: per-chain signal strength average in dBm
108  * @txrate: current unicast bitrate from this station
109  * @rxrate: current unicast bitrate to this station
110  * @rx_packets: packets received from this station
111@@ -650,6 +657,11 @@ struct station_info {
112     u8 plink_state;
113     s8 signal;
114     s8 signal_avg;
115+
116+ u8 chains;
117+ s8 chain_signal[4];
118+ s8 chain_signal_avg[4];
119+
120     struct rate_info txrate;
121     struct rate_info rxrate;
122     u32 rx_packets;
123--- a/drivers/net/wireless/ath/ath9k/mac.h
124+++ b/drivers/net/wireless/ath/ath9k/mac.h
125@@ -133,12 +133,8 @@ struct ath_rx_status {
126     u8 rs_rate;
127     u8 rs_antenna;
128     u8 rs_more;
129- int8_t rs_rssi_ctl0;
130- int8_t rs_rssi_ctl1;
131- int8_t rs_rssi_ctl2;
132- int8_t rs_rssi_ext0;
133- int8_t rs_rssi_ext1;
134- int8_t rs_rssi_ext2;
135+ int8_t rs_rssi_ctl[3];
136+ int8_t rs_rssi_ext[3];
137     u8 rs_isaggr;
138     u8 rs_moreaggr;
139     u8 rs_num_delims;
140--- a/drivers/net/wireless/ath/ath9k/recv.c
141+++ b/drivers/net/wireless/ath/ath9k/recv.c
142@@ -987,6 +987,7 @@ static int ath9k_rx_skb_preprocess(struc
143                    bool *decrypt_error)
144 {
145     struct ath_hw *ah = common->ah;
146+ int i, j;
147 
148     memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
149 
150@@ -1012,6 +1013,20 @@ static int ath9k_rx_skb_preprocess(struc
151     rx_status->antenna = rx_stats->rs_antenna;
152     rx_status->flag |= RX_FLAG_MACTIME_MPDU;
153 
154+ for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) {
155+ s8 rssi;
156+
157+ if (!(ah->rxchainmask & BIT(i)))
158+ continue;
159+
160+ rssi = rx_stats->rs_rssi_ctl[i];
161+ if (rssi != ATH9K_RSSI_BAD) {
162+ rx_status->chains |= BIT(j);
163+ rx_status->chain_signal[j] = ah->noise + rssi;
164+ }
165+ j++;
166+ }
167+
168     return 0;
169 }
170 
171@@ -1542,14 +1557,14 @@ static void ath_ant_comb_scan(struct ath
172     struct ath_ant_comb *antcomb = &sc->ant_comb;
173     int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
174     int curr_main_set;
175- int main_rssi = rs->rs_rssi_ctl0;
176- int alt_rssi = rs->rs_rssi_ctl1;
177+ int main_rssi = rs->rs_rssi_ctl[0];
178+ int alt_rssi = rs->rs_rssi_ctl[1];
179     int rx_ant_conf, main_ant_conf;
180     bool short_scan = false;
181 
182- rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) &
183+ rx_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_CURRENT_SHIFT) &
184                ATH_ANT_RX_MASK;
185- main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
186+ main_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_MAIN_SHIFT) &
187              ATH_ANT_RX_MASK;
188 
189     /* Record packet only when both main_rssi and alt_rssi is positive */
190--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
191+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
192@@ -463,12 +463,12 @@ int ath9k_hw_process_rxdesc_edma(struct
193 
194     /* XXX: Keycache */
195     rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
196- rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00);
197- rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01);
198- rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02);
199- rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10);
200- rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11);
201- rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12);
202+ rxs->rs_rssi_ctl[0] = MS(rxsp->status1, AR_RxRSSIAnt00);
203+ rxs->rs_rssi_ctl[1] = MS(rxsp->status1, AR_RxRSSIAnt01);
204+ rxs->rs_rssi_ctl[2] = MS(rxsp->status1, AR_RxRSSIAnt02);
205+ rxs->rs_rssi_ext[0] = MS(rxsp->status5, AR_RxRSSIAnt10);
206+ rxs->rs_rssi_ext[1] = MS(rxsp->status5, AR_RxRSSIAnt11);
207+ rxs->rs_rssi_ext[2] = MS(rxsp->status5, AR_RxRSSIAnt12);
208 
209     if (rxsp->status11 & AR_RxKeyIdxValid)
210         rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
211--- a/drivers/net/wireless/ath/ath9k/mac.c
212+++ b/drivers/net/wireless/ath/ath9k/mac.c
213@@ -556,25 +556,25 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
214 
215     if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
216         rs->rs_rssi = ATH9K_RSSI_BAD;
217- rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD;
218- rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD;
219- rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD;
220- rs->rs_rssi_ext0 = ATH9K_RSSI_BAD;
221- rs->rs_rssi_ext1 = ATH9K_RSSI_BAD;
222- rs->rs_rssi_ext2 = ATH9K_RSSI_BAD;
223+ rs->rs_rssi_ctl[0] = ATH9K_RSSI_BAD;
224+ rs->rs_rssi_ctl[1] = ATH9K_RSSI_BAD;
225+ rs->rs_rssi_ctl[2] = ATH9K_RSSI_BAD;
226+ rs->rs_rssi_ext[0] = ATH9K_RSSI_BAD;
227+ rs->rs_rssi_ext[1] = ATH9K_RSSI_BAD;
228+ rs->rs_rssi_ext[2] = ATH9K_RSSI_BAD;
229     } else {
230         rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
231- rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
232+ rs->rs_rssi_ctl[0] = MS(ads.ds_rxstatus0,
233                         AR_RxRSSIAnt00);
234- rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
235+ rs->rs_rssi_ctl[1] = MS(ads.ds_rxstatus0,
236                         AR_RxRSSIAnt01);
237- rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
238+ rs->rs_rssi_ctl[2] = MS(ads.ds_rxstatus0,
239                         AR_RxRSSIAnt02);
240- rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4,
241+ rs->rs_rssi_ext[0] = MS(ads.ds_rxstatus4,
242                         AR_RxRSSIAnt10);
243- rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4,
244+ rs->rs_rssi_ext[1] = MS(ads.ds_rxstatus4,
245                         AR_RxRSSIAnt11);
246- rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4,
247+ rs->rs_rssi_ext[2] = MS(ads.ds_rxstatus4,
248                         AR_RxRSSIAnt12);
249     }
250     if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
251--- a/drivers/net/wireless/ath/ath9k/debug.c
252+++ b/drivers/net/wireless/ath/ath9k/debug.c
253@@ -993,12 +993,12 @@ void ath_debug_stat_rx(struct ath_softc
254 #ifdef CONFIG_ATH9K_MAC_DEBUG
255     spin_lock(&sc->debug.samp_lock);
256     RX_SAMP_DBG(jiffies) = jiffies;
257- RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0;
258- RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl1;
259- RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl2;
260- RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext0;
261- RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext1;
262- RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext2;
263+ RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl[0];
264+ RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl[1];
265+ RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl[2];
266+ RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext[0];
267+ RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext[1];
268+ RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext[2];
269     RX_SAMP_DBG(antenna) = rs->rs_antenna;
270     RX_SAMP_DBG(rssi) = rs->rs_rssi;
271     RX_SAMP_DBG(rate) = rs->rs_rate;
272--- a/include/linux/nl80211.h
273+++ b/include/linux/nl80211.h
274@@ -1661,6 +1661,8 @@ enum nl80211_sta_bss_param {
275  * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected
276  * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update.
277  * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32)
278+ * @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU
279+ * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
280  * @__NL80211_STA_INFO_AFTER_LAST: internal
281  * @NL80211_STA_INFO_MAX: highest possible station info attribute
282  */
283@@ -1684,6 +1686,8 @@ enum nl80211_sta_info {
284     NL80211_STA_INFO_CONNECTED_TIME,
285     NL80211_STA_INFO_STA_FLAGS,
286     NL80211_STA_INFO_BEACON_LOSS,
287+ NL80211_STA_INFO_CHAIN_SIGNAL,
288+ NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
289 
290     /* keep last */
291     __NL80211_STA_INFO_AFTER_LAST,
292--- a/net/wireless/nl80211.c
293+++ b/net/wireless/nl80211.c
294@@ -2376,6 +2376,33 @@ nla_put_failure:
295     return false;
296 }
297 
298+static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
299+ int id)
300+{
301+ void *attr;
302+ int i = 0;
303+
304+ if (!mask)
305+ return true;
306+
307+ attr = nla_nest_start(msg, id);
308+ if (!attr)
309+ goto nla_put_failure;
310+
311+ for (i = 0; i < 4; i++) {
312+ if (!(mask & BIT(i)))
313+ continue;
314+
315+ NLA_PUT_U8(msg, i, signal[i]);
316+ }
317+
318+ nla_nest_end(msg, attr);
319+
320+ return true;
321+nla_put_failure:
322+ return false;
323+}
324+
325 static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
326                 int flags, struct net_device *dev,
327                 const u8 *mac_addr, struct station_info *sinfo)
328@@ -2422,6 +2449,18 @@ static int nl80211_send_station(struct s
329     if (sinfo->filled & STATION_INFO_SIGNAL_AVG)
330         NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG,
331                sinfo->signal_avg);
332+ if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) {
333+ if (!nl80211_put_signal(msg, sinfo->chains,
334+ sinfo->chain_signal,
335+ NL80211_STA_INFO_CHAIN_SIGNAL))
336+ goto nla_put_failure;
337+ }
338+ if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) {
339+ if (!nl80211_put_signal(msg, sinfo->chains,
340+ sinfo->chain_signal_avg,
341+ NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
342+ goto nla_put_failure;
343+ }
344     if (sinfo->filled & STATION_INFO_TX_BITRATE) {
345         if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
346                       NL80211_STA_INFO_TX_BITRATE))
347--- a/net/mac80211/cfg.c
348+++ b/net/mac80211/cfg.c
349@@ -340,6 +340,7 @@ static void sta_set_sinfo(struct sta_inf
350 {
351     struct ieee80211_sub_if_data *sdata = sta->sdata;
352     struct timespec uptime;
353+ int i;
354 
355     sinfo->generation = sdata->local->sta_generation;
356 
357@@ -377,6 +378,17 @@ static void sta_set_sinfo(struct sta_inf
358         sinfo->signal = (s8)sta->last_signal;
359         sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
360     }
361+ if (sta->chains) {
362+ sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
363+ STATION_INFO_CHAIN_SIGNAL_AVG;
364+
365+ sinfo->chains = sta->chains;
366+ for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
367+ sinfo->chain_signal[i] = sta->chain_signal_last[i];
368+ sinfo->chain_signal_avg[i] =
369+ (s8) -ewma_read(&sta->chain_signal_avg[i]);
370+ }
371+ }
372 
373     sinfo->txrate.flags = 0;
374     if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
375

Archive Download this file



interactive