Commit 29696e0a authored by Bryan O'Donoghue's avatar Bryan O'Donoghue Committed by Kalle Valo

wcn36xx: Track SNR and RSSI for each RX frame

The BDs for each RX frame contain both the RSSI and SNR for the received
frame. If we track and store this information it can be useful to us in
get_survey() and potentially elsewhere.
Reported-by: default avatarkernel test robot <lkp@intel.com>
Signed-off-by: default avatarBryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/20220115001646.3981501-4-bryan.odonoghue@linaro.org
parent d6f27466
......@@ -331,6 +331,7 @@ static int wcn36xx_start(struct ieee80211_hw *hw)
INIT_LIST_HEAD(&wcn->vif_list);
spin_lock_init(&wcn->dxe_lock);
spin_lock_init(&wcn->survey_lock);
return 0;
......@@ -394,6 +395,7 @@ static void wcn36xx_change_opchannel(struct wcn36xx *wcn, int ch)
struct wcn36xx_vif *tmp;
struct ieee80211_supported_band *band;
struct ieee80211_channel *channel;
unsigned long flags;
int i, j;
for (i = 0; i < ARRAY_SIZE(wcn->hw->wiphy->bands); i++) {
......@@ -415,8 +417,10 @@ static void wcn36xx_change_opchannel(struct wcn36xx *wcn, int ch)
return;
}
spin_lock_irqsave(&wcn->survey_lock, flags);
wcn->band = band;
wcn->channel = channel;
spin_unlock_irqrestore(&wcn->survey_lock, flags);
list_for_each_entry(tmp, &wcn->vif_list, list) {
vif = wcn36xx_priv_to_vif(tmp);
......@@ -1557,6 +1561,7 @@ static int wcn36xx_probe(struct platform_device *pdev)
void *wcnss;
int ret;
const u8 *addr;
int n_channels;
wcn36xx_dbg(WCN36XX_DBG_MAC, "platform probe\n");
......@@ -1584,6 +1589,13 @@ static int wcn36xx_probe(struct platform_device *pdev)
goto out_wq;
}
n_channels = wcn_band_2ghz.n_channels + wcn_band_5ghz.n_channels;
wcn->chan_survey = devm_kmalloc(wcn->dev, n_channels, GFP_KERNEL);
if (!wcn->chan_survey) {
ret = -ENOMEM;
goto out_wq;
}
ret = dma_set_mask_and_coherent(wcn->dev, DMA_BIT_MASK(32));
if (ret < 0) {
wcn36xx_err("failed to set DMA mask: %d\n", ret);
......
......@@ -271,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;
......@@ -348,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;
......
......@@ -194,7 +194,14 @@ struct wcn36xx_sta {
enum wcn36xx_ampdu_state ampdu_state[16];
int non_agg_frame_ct;
};
struct wcn36xx_dxe_ch;
struct wcn36xx_chan_survey {
s8 rssi;
u8 snr;
};
struct wcn36xx {
struct ieee80211_hw *hw;
struct device *dev;
......@@ -284,6 +291,9 @@ struct wcn36xx {
struct ieee80211_supported_band *band;
struct ieee80211_channel *channel;
spinlock_t survey_lock; /* protects chan_survey */
struct wcn36xx_chan_survey *chan_survey;
};
static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment