diff options
Diffstat (limited to 'drivers/net/wireless/ath/wcn36xx/txrx.c')
-rw-r--r-- | drivers/net/wireless/ath/wcn36xx/txrx.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c index dd58dde8c836..df749b114568 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c @@ -23,6 +23,11 @@ static inline int get_rssi0(struct wcn36xx_rx_bd *bd) return 100 - ((bd->phy_stat0 >> 24) & 0xff); } +static inline int get_snr(struct wcn36xx_rx_bd *bd) +{ + return ((bd->phy_stat1 >> 24) & 0xff); +} + struct wcn36xx_rate { u16 bitrate; u16 mcs_or_legacy_index; @@ -266,6 +271,34 @@ static void __skb_queue_purge_irq(struct sk_buff_head *list) dev_kfree_skb_irq(skb); } +static void wcn36xx_update_survey(struct wcn36xx *wcn, int rssi, int snr, + int band, int freq) +{ + static struct ieee80211_channel *channel; + struct ieee80211_supported_band *sband; + int idx; + int i; + + idx = 0; + if (band == NL80211_BAND_5GHZ) + idx = wcn->hw->wiphy->bands[NL80211_BAND_2GHZ]->n_channels; + + sband = wcn->hw->wiphy->bands[band]; + channel = sband->channels; + + for (i = 0; i < sband->n_channels; i++, channel++) { + if (channel->center_freq == freq) { + idx += i; + break; + } + } + + spin_lock(&wcn->survey_lock); + wcn->chan_survey[idx].rssi = rssi; + wcn->chan_survey[idx].snr = snr; + spin_unlock(&wcn->survey_lock); +} + int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) { struct ieee80211_rx_status status; @@ -343,6 +376,9 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) status.freq = WCN36XX_CENTER_FREQ(wcn); } + wcn36xx_update_survey(wcn, status.signal, get_snr(bd), + status.band, status.freq); + if (bd->rate_id < ARRAY_SIZE(wcn36xx_rate_table)) { rate = &wcn36xx_rate_table[bd->rate_id]; status.encoding = rate->encoding; |