Skip to content

Commit fa7937e

Browse files
Rajkumar Manoharankvalo
authored andcommitted
ath10k: update bss channel survey information
During hw scan, firmware sends two channel information events (pre- complete, complete) to host for each channel change. The snap shot of cycle counters (rx_clear and total) between these two events are given for survey dump. In order to get latest survey statistics of all channels, a scan request has to be issued. In general, an AP DUT is brought up, it won't leave BSS channel except few cases like overlapping bss or radar detection. So survey statistics of bss channel is always referring to older data that are collected before starting AP (either ACS/OBSS scan). To collect latest survey information from target, firmware provides WMI interface to read cycle counters from hardware. For each survey dump request, BSS channel cycle counters are read and cleared in hardware. This makes sure that behavior is in align with ath9k survey report. So survey dump always gives snap shot of cycle counters b/w two survey requests. Signed-off-by: Yanbo Li <[email protected]> Signed-off-by: Rajkumar Manoharan <[email protected]> Signed-off-by: Kalle Valo <[email protected]>
1 parent 89d2d18 commit fa7937e

File tree

4 files changed

+70
-0
lines changed

4 files changed

+70
-0
lines changed

drivers/net/wireless/ath/ath10k/core.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,6 +1392,7 @@ static void ath10k_core_restart(struct work_struct *work)
13921392
complete_all(&ar->install_key_done);
13931393
complete_all(&ar->vdev_setup_done);
13941394
complete_all(&ar->thermal.wmi_sync);
1395+
complete_all(&ar->bss_survey_done);
13951396
wake_up(&ar->htt.empty_tx_wq);
13961397
wake_up(&ar->wmi.tx_credits_wq);
13971398
wake_up(&ar->peer_mapping_wq);
@@ -1724,6 +1725,9 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
17241725
if (ath10k_peer_stats_enabled(ar))
17251726
val = WMI_10_4_PEER_STATS;
17261727

1728+
if (test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map))
1729+
val |= WMI_10_4_BSS_CHANNEL_INFO_64;
1730+
17271731
status = ath10k_mac_ext_resource_config(ar, val);
17281732
if (status) {
17291733
ath10k_err(ar,
@@ -2085,6 +2089,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
20852089
init_completion(&ar->install_key_done);
20862090
init_completion(&ar->vdev_setup_done);
20872091
init_completion(&ar->thermal.wmi_sync);
2092+
init_completion(&ar->bss_survey_done);
20882093

20892094
INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work);
20902095

drivers/net/wireless/ath/ath10k/core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,7 @@ struct ath10k {
876876
* avoid reporting garbage data.
877877
*/
878878
bool ch_info_can_report_survey;
879+
struct completion bss_survey_done;
879880

880881
struct dfs_pattern_detector *dfs_detector;
881882

drivers/net/wireless/ath/ath10k/mac.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6404,6 +6404,39 @@ static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
64046404
mutex_unlock(&ar->conf_mutex);
64056405
}
64066406

6407+
static void
6408+
ath10k_mac_update_bss_chan_survey(struct ath10k *ar,
6409+
struct ieee80211_channel *channel)
6410+
{
6411+
int ret;
6412+
enum wmi_bss_survey_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR;
6413+
6414+
lockdep_assert_held(&ar->conf_mutex);
6415+
6416+
if (!test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map) ||
6417+
(ar->rx_channel != channel))
6418+
return;
6419+
6420+
if (ar->scan.state != ATH10K_SCAN_IDLE) {
6421+
ath10k_dbg(ar, ATH10K_DBG_MAC, "ignoring bss chan info request while scanning..\n");
6422+
return;
6423+
}
6424+
6425+
reinit_completion(&ar->bss_survey_done);
6426+
6427+
ret = ath10k_wmi_pdev_bss_chan_info_request(ar, type);
6428+
if (ret) {
6429+
ath10k_warn(ar, "failed to send pdev bss chan info request\n");
6430+
return;
6431+
}
6432+
6433+
ret = wait_for_completion_timeout(&ar->bss_survey_done, 3 * HZ);
6434+
if (!ret) {
6435+
ath10k_warn(ar, "bss channel survey timed out\n");
6436+
return;
6437+
}
6438+
}
6439+
64076440
static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
64086441
struct survey_info *survey)
64096442
{
@@ -6428,6 +6461,8 @@ static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
64286461
goto exit;
64296462
}
64306463

6464+
ath10k_mac_update_bss_chan_survey(ar, survey->channel);
6465+
64316466
spin_lock_bh(&ar->data_lock);
64326467
memcpy(survey, ar_survey, sizeof(*survey));
64336468
spin_unlock_bh(&ar->data_lock);

drivers/net/wireless/ath/ath10k/wmi.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4798,8 +4798,11 @@ static int ath10k_wmi_event_pdev_bss_chan_info(struct ath10k *ar,
47984798
struct sk_buff *skb)
47994799
{
48004800
struct wmi_pdev_bss_chan_info_event *ev;
4801+
struct survey_info *survey;
48014802
u64 busy, total, tx, rx, rx_bss;
48024803
u32 freq, noise_floor;
4804+
u32 cc_freq_hz = ar->hw_params.channel_counters_freq_hz;
4805+
int idx;
48034806

48044807
ev = (struct wmi_pdev_bss_chan_info_event *)skb->data;
48054808
if (WARN_ON(skb->len < sizeof(*ev)))
@@ -4817,6 +4820,29 @@ static int ath10k_wmi_event_pdev_bss_chan_info(struct ath10k *ar,
48174820
"wmi event pdev bss chan info:\n freq: %d noise: %d cycle: busy %llu total %llu tx %llu rx %llu rx_bss %llu\n",
48184821
freq, noise_floor, busy, total, tx, rx, rx_bss);
48194822

4823+
spin_lock_bh(&ar->data_lock);
4824+
idx = freq_to_idx(ar, freq);
4825+
if (idx >= ARRAY_SIZE(ar->survey)) {
4826+
ath10k_warn(ar, "bss chan info: invalid frequency %d (idx %d out of bounds)\n",
4827+
freq, idx);
4828+
goto exit;
4829+
}
4830+
4831+
survey = &ar->survey[idx];
4832+
4833+
survey->noise = noise_floor;
4834+
survey->time = div_u64(total, cc_freq_hz);
4835+
survey->time_busy = div_u64(busy, cc_freq_hz);
4836+
survey->time_rx = div_u64(rx_bss, cc_freq_hz);
4837+
survey->time_tx = div_u64(tx, cc_freq_hz);
4838+
survey->filled |= (SURVEY_INFO_NOISE_DBM |
4839+
SURVEY_INFO_TIME |
4840+
SURVEY_INFO_TIME_BUSY |
4841+
SURVEY_INFO_TIME_RX |
4842+
SURVEY_INFO_TIME_TX);
4843+
exit:
4844+
spin_unlock_bh(&ar->data_lock);
4845+
complete(&ar->bss_survey_done);
48204846
return 0;
48214847
}
48224848

@@ -5640,6 +5666,9 @@ static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar)
56405666
if (ath10k_peer_stats_enabled(ar))
56415667
features |= WMI_10_2_PEER_STATS;
56425668

5669+
if (test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map))
5670+
features |= WMI_10_2_BSS_CHAN_INFO;
5671+
56435672
cmd->resource_config.feature_mask = __cpu_to_le32(features);
56445673

56455674
memcpy(&cmd->resource_config.common, &config, sizeof(config));

0 commit comments

Comments
 (0)