|
@@ -4798,8 +4798,11 @@ static int ath10k_wmi_event_pdev_bss_chan_info(struct ath10k *ar,
|
|
|
struct sk_buff *skb)
|
|
|
{
|
|
|
struct wmi_pdev_bss_chan_info_event *ev;
|
|
|
+ struct survey_info *survey;
|
|
|
u64 busy, total, tx, rx, rx_bss;
|
|
|
u32 freq, noise_floor;
|
|
|
+ u32 cc_freq_hz = ar->hw_params.channel_counters_freq_hz;
|
|
|
+ int idx;
|
|
|
|
|
|
ev = (struct wmi_pdev_bss_chan_info_event *)skb->data;
|
|
|
if (WARN_ON(skb->len < sizeof(*ev)))
|
|
@@ -4817,6 +4820,29 @@ static int ath10k_wmi_event_pdev_bss_chan_info(struct ath10k *ar,
|
|
|
"wmi event pdev bss chan info:\n freq: %d noise: %d cycle: busy %llu total %llu tx %llu rx %llu rx_bss %llu\n",
|
|
|
freq, noise_floor, busy, total, tx, rx, rx_bss);
|
|
|
|
|
|
+ spin_lock_bh(&ar->data_lock);
|
|
|
+ idx = freq_to_idx(ar, freq);
|
|
|
+ if (idx >= ARRAY_SIZE(ar->survey)) {
|
|
|
+ ath10k_warn(ar, "bss chan info: invalid frequency %d (idx %d out of bounds)\n",
|
|
|
+ freq, idx);
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ survey = &ar->survey[idx];
|
|
|
+
|
|
|
+ survey->noise = noise_floor;
|
|
|
+ survey->time = div_u64(total, cc_freq_hz);
|
|
|
+ survey->time_busy = div_u64(busy, cc_freq_hz);
|
|
|
+ survey->time_rx = div_u64(rx_bss, cc_freq_hz);
|
|
|
+ survey->time_tx = div_u64(tx, cc_freq_hz);
|
|
|
+ survey->filled |= (SURVEY_INFO_NOISE_DBM |
|
|
|
+ SURVEY_INFO_TIME |
|
|
|
+ SURVEY_INFO_TIME_BUSY |
|
|
|
+ SURVEY_INFO_TIME_RX |
|
|
|
+ SURVEY_INFO_TIME_TX);
|
|
|
+exit:
|
|
|
+ spin_unlock_bh(&ar->data_lock);
|
|
|
+ complete(&ar->bss_survey_done);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -5640,6 +5666,9 @@ static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar)
|
|
|
if (ath10k_peer_stats_enabled(ar))
|
|
|
features |= WMI_10_2_PEER_STATS;
|
|
|
|
|
|
+ if (test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map))
|
|
|
+ features |= WMI_10_2_BSS_CHAN_INFO;
|
|
|
+
|
|
|
cmd->resource_config.feature_mask = __cpu_to_le32(features);
|
|
|
|
|
|
memcpy(&cmd->resource_config.common, &config, sizeof(config));
|