| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- --- a/include/net/mac80211.h
- +++ b/include/net/mac80211.h
- @@ -816,6 +816,9 @@ enum mac80211_rx_flags {
- * @signal: signal strength when receiving this frame, either in dBm, in dB or
- * unspecified depending on the hardware capabilities flags
- * @IEEE80211_HW_SIGNAL_*
- + * @chains: bitmask of receive chains for which separate signal strength
- + * values were filled.
- + * @chain_signal: per-chain signal strength, same format as @signal
- * @antenna: antenna used
- * @rate_idx: index of data rate into band's supported rates or MCS index if
- * HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
- @@ -847,6 +850,8 @@ struct ieee80211_rx_status {
- u8 band;
- u8 antenna;
- s8 signal;
- + u8 chains;
- + s8 chain_signal[4];
- u8 ampdu_delimiter_crc;
- u8 vendor_radiotap_align;
- u8 vendor_radiotap_oui[3];
- --- a/net/mac80211/sta_info.h
- +++ b/net/mac80211/sta_info.h
- @@ -329,6 +329,11 @@ struct sta_info {
- int last_signal;
- struct ewma avg_signal;
- int last_ack_signal;
- +
- + u8 chains;
- + s8 chain_signal_last[4];
- + struct ewma chain_signal_avg[4];
- +
- /* Plus 1 for non-QoS frames */
- __le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1];
-
- --- a/net/mac80211/rx.c
- +++ b/net/mac80211/rx.c
- @@ -1375,6 +1375,7 @@ ieee80211_rx_h_sta_process(struct ieee80
- struct sk_buff *skb = rx->skb;
- struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- + int i;
-
- if (!sta)
- return RX_CONTINUE;
- @@ -1425,6 +1426,19 @@ ieee80211_rx_h_sta_process(struct ieee80
- ewma_add(&sta->avg_signal, -status->signal);
- }
-
- + if (status->chains) {
- + sta->chains = status->chains;
- + for (i = 0; i < 4; i++) {
- + int signal = status->chain_signal[i];
- +
- + if (!(status->chains & BIT(i)))
- + continue;
- +
- + sta->chain_signal_last[i] = signal;
- + ewma_add(&sta->chain_signal_avg[i], -signal);
- + }
- + }
- +
- /*
- * Change STA power saving mode only at the end of a frame
- * exchange sequence.
- --- a/net/mac80211/sta_info.c
- +++ b/net/mac80211/sta_info.c
- @@ -324,6 +324,8 @@ struct sta_info *sta_info_alloc(struct i
- do_posix_clock_monotonic_gettime(&uptime);
- sta->last_connected = uptime.tv_sec;
- ewma_init(&sta->avg_signal, 1024, 8);
- + for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++)
- + ewma_init(&sta->chain_signal_avg[i], 1024, 8);
-
- if (sta_prepare_rate_control(local, sta, gfp)) {
- kfree(sta);
- --- a/include/net/cfg80211.h
- +++ b/include/net/cfg80211.h
- @@ -653,6 +653,8 @@ struct station_parameters {
- * @STATION_INFO_STA_FLAGS: @sta_flags filled
- * @STATION_INFO_BEACON_LOSS_COUNT: @beacon_loss_count filled
- * @STATION_INFO_T_OFFSET: @t_offset filled
- + * @STATION_INFO_CHAIN_SIGNAL: @chain_signal filled
- + * @STATION_INFO_CHAIN_SIGNAL_AVG: @chain_signal_avg filled
- */
- enum station_info_flags {
- STATION_INFO_INACTIVE_TIME = 1<<0,
- @@ -676,6 +678,8 @@ enum station_info_flags {
- STATION_INFO_STA_FLAGS = 1<<18,
- STATION_INFO_BEACON_LOSS_COUNT = 1<<19,
- STATION_INFO_T_OFFSET = 1<<20,
- + STATION_INFO_CHAIN_SIGNAL = 1<<21,
- + STATION_INFO_CHAIN_SIGNAL_AVG = 1<<22,
- };
-
- /**
- @@ -769,6 +773,9 @@ struct sta_bss_parameters {
- * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
- * @signal_avg: Average signal strength, type depends on the wiphy's signal_type.
- * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
- + * @chains: bitmask for filled values in @chain_signal, @chain_signal_avg
- + * @chain_signal: per-chain signal strength of last received packet in dBm
- + * @chain_signal_avg: per-chain signal strength average in dBm
- * @txrate: current unicast bitrate from this station
- * @rxrate: current unicast bitrate to this station
- * @rx_packets: packets received from this station
- @@ -801,6 +808,11 @@ struct station_info {
- u8 plink_state;
- s8 signal;
- s8 signal_avg;
- +
- + u8 chains;
- + s8 chain_signal[4];
- + s8 chain_signal_avg[4];
- +
- struct rate_info txrate;
- struct rate_info rxrate;
- u32 rx_packets;
- --- a/drivers/net/wireless/ath/ath9k/mac.h
- +++ b/drivers/net/wireless/ath/ath9k/mac.h
- @@ -133,12 +133,8 @@ struct ath_rx_status {
- u8 rs_rate;
- u8 rs_antenna;
- u8 rs_more;
- - int8_t rs_rssi_ctl0;
- - int8_t rs_rssi_ctl1;
- - int8_t rs_rssi_ctl2;
- - int8_t rs_rssi_ext0;
- - int8_t rs_rssi_ext1;
- - int8_t rs_rssi_ext2;
- + int8_t rs_rssi_ctl[3];
- + int8_t rs_rssi_ext[3];
- u8 rs_isaggr;
- u8 rs_moreaggr;
- u8 rs_num_delims;
- --- a/drivers/net/wireless/ath/ath9k/recv.c
- +++ b/drivers/net/wireless/ath/ath9k/recv.c
- @@ -955,6 +955,7 @@ static int ath9k_rx_skb_preprocess(struc
- bool *decrypt_error)
- {
- struct ath_hw *ah = common->ah;
- + int i, j;
-
- /*
- * everything but the rate is checked here, the rate check is done
- @@ -980,6 +981,20 @@ static int ath9k_rx_skb_preprocess(struc
- if (rx_stats->rs_moreaggr)
- rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
-
- + for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) {
- + s8 rssi;
- +
- + if (!(ah->rxchainmask & BIT(i)))
- + continue;
- +
- + rssi = rx_stats->rs_rssi_ctl[i];
- + if (rssi != ATH9K_RSSI_BAD) {
- + rx_status->chains |= BIT(j);
- + rx_status->chain_signal[j] = ah->noise + rssi;
- + }
- + j++;
- + }
- +
- return 0;
- }
-
- --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
- +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
- @@ -475,12 +475,12 @@ int ath9k_hw_process_rxdesc_edma(struct
-
- /* XXX: Keycache */
- rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
- - rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00);
- - rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01);
- - rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02);
- - rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10);
- - rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11);
- - rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12);
- + rxs->rs_rssi_ctl[0] = MS(rxsp->status1, AR_RxRSSIAnt00);
- + rxs->rs_rssi_ctl[1] = MS(rxsp->status1, AR_RxRSSIAnt01);
- + rxs->rs_rssi_ctl[2] = MS(rxsp->status1, AR_RxRSSIAnt02);
- + rxs->rs_rssi_ext[0] = MS(rxsp->status5, AR_RxRSSIAnt10);
- + rxs->rs_rssi_ext[1] = MS(rxsp->status5, AR_RxRSSIAnt11);
- + rxs->rs_rssi_ext[2] = MS(rxsp->status5, AR_RxRSSIAnt12);
-
- if (rxsp->status11 & AR_RxKeyIdxValid)
- rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
- --- a/drivers/net/wireless/ath/ath9k/mac.c
- +++ b/drivers/net/wireless/ath/ath9k/mac.c
- @@ -553,25 +553,25 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a
-
- if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
- rs->rs_rssi = ATH9K_RSSI_BAD;
- - rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD;
- - rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD;
- - rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD;
- - rs->rs_rssi_ext0 = ATH9K_RSSI_BAD;
- - rs->rs_rssi_ext1 = ATH9K_RSSI_BAD;
- - rs->rs_rssi_ext2 = ATH9K_RSSI_BAD;
- + rs->rs_rssi_ctl[0] = ATH9K_RSSI_BAD;
- + rs->rs_rssi_ctl[1] = ATH9K_RSSI_BAD;
- + rs->rs_rssi_ctl[2] = ATH9K_RSSI_BAD;
- + rs->rs_rssi_ext[0] = ATH9K_RSSI_BAD;
- + rs->rs_rssi_ext[1] = ATH9K_RSSI_BAD;
- + rs->rs_rssi_ext[2] = ATH9K_RSSI_BAD;
- } else {
- rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
- - rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
- + rs->rs_rssi_ctl[0] = MS(ads.ds_rxstatus0,
- AR_RxRSSIAnt00);
- - rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
- + rs->rs_rssi_ctl[1] = MS(ads.ds_rxstatus0,
- AR_RxRSSIAnt01);
- - rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
- + rs->rs_rssi_ctl[2] = MS(ads.ds_rxstatus0,
- AR_RxRSSIAnt02);
- - rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4,
- + rs->rs_rssi_ext[0] = MS(ads.ds_rxstatus4,
- AR_RxRSSIAnt10);
- - rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4,
- + rs->rs_rssi_ext[1] = MS(ads.ds_rxstatus4,
- AR_RxRSSIAnt11);
- - rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4,
- + rs->rs_rssi_ext[2] = MS(ads.ds_rxstatus4,
- AR_RxRSSIAnt12);
- }
- if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
- --- a/drivers/net/wireless/ath/ath9k/debug.c
- +++ b/drivers/net/wireless/ath/ath9k/debug.c
- @@ -939,12 +939,12 @@ void ath_debug_stat_rx(struct ath_softc
- #ifdef CONFIG_ATH9K_MAC_DEBUG
- spin_lock(&sc->debug.samp_lock);
- RX_SAMP_DBG(jiffies) = jiffies;
- - RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0;
- - RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl1;
- - RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl2;
- - RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext0;
- - RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext1;
- - RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext2;
- + RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl[0];
- + RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl[1];
- + RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl[2];
- + RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext[0];
- + RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext[1];
- + RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext[2];
- RX_SAMP_DBG(antenna) = rs->rs_antenna;
- RX_SAMP_DBG(rssi) = rs->rs_rssi;
- RX_SAMP_DBG(rate) = rs->rs_rate;
- --- a/include/uapi/linux/nl80211.h
- +++ b/include/uapi/linux/nl80211.h
- @@ -1834,6 +1834,8 @@ enum nl80211_sta_bss_param {
- * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update.
- * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32)
- * @NL80211_STA_INFO_T_OFFSET: timing offset with respect to this STA (s64)
- + * @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU
- + * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
- * @__NL80211_STA_INFO_AFTER_LAST: internal
- * @NL80211_STA_INFO_MAX: highest possible station info attribute
- */
- @@ -1858,6 +1860,8 @@ enum nl80211_sta_info {
- NL80211_STA_INFO_STA_FLAGS,
- NL80211_STA_INFO_BEACON_LOSS,
- NL80211_STA_INFO_T_OFFSET,
- + NL80211_STA_INFO_CHAIN_SIGNAL,
- + NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
-
- /* keep last */
- __NL80211_STA_INFO_AFTER_LAST,
- --- a/net/wireless/nl80211.c
- +++ b/net/wireless/nl80211.c
- @@ -2910,6 +2910,32 @@ static bool nl80211_put_sta_rate(struct
- return true;
- }
-
- +static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
- + int id)
- +{
- + void *attr;
- + int i = 0;
- +
- + if (!mask)
- + return true;
- +
- + attr = nla_nest_start(msg, id);
- + if (!attr)
- + return false;
- +
- + for (i = 0; i < 4; i++) {
- + if (!(mask & BIT(i)))
- + continue;
- +
- + if (nla_put_u8(msg, i, signal[i]))
- + return false;
- + }
- +
- + nla_nest_end(msg, attr);
- +
- + return true;
- +}
- +
- static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
- int flags,
- struct cfg80211_registered_device *rdev,
- @@ -2971,6 +2997,18 @@ static int nl80211_send_station(struct s
- default:
- break;
- }
- + if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) {
- + if (!nl80211_put_signal(msg, sinfo->chains,
- + sinfo->chain_signal,
- + NL80211_STA_INFO_CHAIN_SIGNAL))
- + goto nla_put_failure;
- + }
- + if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) {
- + if (!nl80211_put_signal(msg, sinfo->chains,
- + sinfo->chain_signal_avg,
- + NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
- + goto nla_put_failure;
- + }
- if (sinfo->filled & STATION_INFO_TX_BITRATE) {
- if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
- NL80211_STA_INFO_TX_BITRATE))
- --- a/net/mac80211/cfg.c
- +++ b/net/mac80211/cfg.c
- @@ -435,6 +435,7 @@ static void sta_set_sinfo(struct sta_inf
- struct ieee80211_sub_if_data *sdata = sta->sdata;
- struct ieee80211_local *local = sdata->local;
- struct timespec uptime;
- + int i;
-
- sinfo->generation = sdata->local->sta_generation;
-
- @@ -474,6 +475,17 @@ static void sta_set_sinfo(struct sta_inf
- sinfo->signal = (s8)sta->last_signal;
- sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
- }
- + if (sta->chains) {
- + sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
- + STATION_INFO_CHAIN_SIGNAL_AVG;
- +
- + sinfo->chains = sta->chains;
- + for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
- + sinfo->chain_signal[i] = sta->chain_signal_last[i];
- + sinfo->chain_signal_avg[i] =
- + (s8) -ewma_read(&sta->chain_signal_avg[i]);
- + }
- + }
-
- sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
- sta_set_rate_info_rx(sta, &sinfo->rxrate);
- --- a/drivers/net/wireless/ath/ath9k/dfs.c
- +++ b/drivers/net/wireless/ath/ath9k/dfs.c
- @@ -164,8 +164,8 @@ void ath9k_dfs_process_phyerr(struct ath
- return;
- }
-
- - ard.rssi = rs->rs_rssi_ctl0;
- - ard.ext_rssi = rs->rs_rssi_ext0;
- + ard.rssi = rs->rs_rssi_ctl[0];
- + ard.ext_rssi = rs->rs_rssi_ext[0];
-
- /*
- * hardware stores this as 8 bit signed value.
- --- a/drivers/net/wireless/ath/ath9k/antenna.c
- +++ b/drivers/net/wireless/ath/ath9k/antenna.c
- @@ -546,14 +546,14 @@ void ath_ant_comb_scan(struct ath_softc
- struct ath_ant_comb *antcomb = &sc->ant_comb;
- int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
- int curr_main_set;
- - int main_rssi = rs->rs_rssi_ctl0;
- - int alt_rssi = rs->rs_rssi_ctl1;
- + int main_rssi = rs->rs_rssi_ctl[0];
- + int alt_rssi = rs->rs_rssi_ctl[1];
- int rx_ant_conf, main_ant_conf;
- bool short_scan = false;
-
- - rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) &
- + rx_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_CURRENT_SHIFT) &
- ATH_ANT_RX_MASK;
- - main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
- + main_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_MAIN_SHIFT) &
- ATH_ANT_RX_MASK;
-
- /* Record packet only when both main_rssi and alt_rssi is positive */
|