From 4f0c0c1c50574f1ebf505bd631b25ff67a43cb61 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Tue, 7 Feb 2017 15:21:15 +0530 Subject: [PATCH] qcacld-3.0: Report more information in survey dump qcacld-2.0 to qcacld-3.0 propagation Currently host only report connected frequency and noise in survey dump. Add changes to report all supported frequencies, active time, TX time, busy time and noise. CRs-Fixed: 1061040 Change-Id: I2fa509f53b47d65ba0f4abbc438834b85b9c21f6 --- core/hdd/inc/wlan_hdd_main.h | 21 +++- core/hdd/src/wlan_hdd_cfg.c | 2 + core/hdd/src/wlan_hdd_cfg80211.c | 139 ++++++++++++++++++++++ core/hdd/src/wlan_hdd_main.c | 3 + core/hdd/src/wlan_hdd_stats.c | 193 ++++++++++++++++++++----------- core/mac/inc/ani_global.h | 2 + core/mac/inc/sir_api.h | 19 +++ core/sme/inc/sme_api.h | 12 ++ core/sme/src/common/sme_api.c | 16 +++ core/wma/inc/wma.h | 13 +++ core/wma/src/wma_features.c | 46 ++++++++ core/wma/src/wma_main.c | 4 + core/wma/src/wma_scan_roam.c | 4 + 13 files changed, 406 insertions(+), 68 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index a5bbb70b8cbe..8fa94aa8d760 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1611,6 +1611,8 @@ struct hdd_context_s { struct suspend_resume_stats suspend_resume_stats; struct hdd_runtime_pm_context runtime_context; bool roaming_in_progress; + struct scan_chan_info *chan_info; + struct mutex chan_info_lock; /* bit map to set/reset TDLS by different sources */ unsigned long tdls_source_bitmap; /* tdls source timer to enable/disable TDLS on p2p listen */ @@ -2192,5 +2194,22 @@ void hdd_set_roaming_in_progress(bool value); int wlan_hdd_sap_get_valid_channellist(hdd_adapter_t *adapter, uint32_t *channel_count, uint8_t *channel_list); - +/** + * wlan_hdd_init_chan_info() - initialize channel info variables + * @hdd_ctx: hdd ctx + * + * This API initialize channel info variables + * + * Return: None + */ +void wlan_hdd_init_chan_info(hdd_context_t *hdd_ctx); +/** + * wlan_hdd_deinit_chan_info() - deinitialize channel info variables + * @hdd_ctx: hdd ctx + * + * This API deinitialize channel info variables + * + * Return: None + */ +void wlan_hdd_deinit_chan_info(hdd_context_t *hdd_ctx); #endif /* end #if !defined(WLAN_HDD_MAIN_H) */ diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index 21738a7bb76c..c1326666a32d 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -7088,6 +7088,8 @@ QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx) CSR_STA_ROAM_POLICY_DFS_ENABLED; smeConfig->csrConfig.sta_roam_policy_params.skip_unsafe_channels = 0; + smeConfig->snr_monitor_enabled = pHddCtx->config->fEnableSNRMonitoring; + smeConfig->csrConfig.tx_aggregation_size = pHddCtx->config->tx_aggregation_size; smeConfig->csrConfig.rx_aggregation_size = diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index d592cf900892..effb12f2eb4f 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -16505,6 +16505,145 @@ void wlan_hdd_clear_link_layer_stats(hdd_adapter_t *adapter) return; } +#define CNT_DIFF(cur, prev) \ + ((cur >= prev) ? (cur - prev) : (cur + (MAX_COUNT - (prev) + 1))) +#define MAX_COUNT 0xffffffff +static void hdd_update_chan_info(hdd_context_t *hdd_ctx, + struct scan_chan_info *chan, + struct scan_chan_info *info, uint32_t cmd_flag) +{ + if ((info->cmd_flag != WMI_CHAN_InFO_START_RESP) && + (info->cmd_flag != WMI_CHAN_InFO_END_RESP)) + hdd_err("cmd flag is invalid: %d", info->cmd_flag); + + mutex_lock(&hdd_ctx->chan_info_lock); + + if (info->cmd_flag == WMI_CHAN_InFO_START_RESP) + qdf_mem_zero(chan, sizeof(*chan)); + + chan->freq = info->freq; + chan->noise_floor = info->noise_floor; + chan->clock_freq = info->clock_freq; + chan->cmd_flag = info->cmd_flag; + chan->cycle_count = CNT_DIFF(info->cycle_count, chan->cycle_count); + + chan->rx_clear_count = + CNT_DIFF(info->rx_clear_count, chan->rx_clear_count); + + chan->tx_frame_count = + CNT_DIFF(info->tx_frame_count, chan->tx_frame_count); + + mutex_unlock(&hdd_ctx->chan_info_lock); + +} +#undef CNT_DIFF +#undef MAX_COUNT + +/** + * wlan_hdd_chan_info_cb() - channel info callback + * @chan_info: struct scan_chan_info + * + * Store channel info into HDD context + * + * Return: None. + */ +static void wlan_hdd_chan_info_cb(struct scan_chan_info *info) +{ + hdd_context_t *hdd_ctx; + struct scan_chan_info *chan; + uint8_t idx; + + ENTER(); + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (wlan_hdd_validate_context(hdd_ctx) != 0) { + hdd_err("hdd_ctx is invalid"); + return; + } + + if (!hdd_ctx->chan_info) { + hdd_err("chan_info is NULL"); + return; + } + + chan = hdd_ctx->chan_info; + for (idx = 0; idx < SIR_MAX_NUM_CHANNELS; idx++) { + if (chan[idx].freq == info->freq) { + hdd_update_chan_info(hdd_ctx, &chan[idx], info, + info->cmd_flag); + hdd_info("cmd:%d freq:%u nf:%d cc:%u rcc:%u clk:%u cmd:%d tfc:%d index:%d", + chan[idx].cmd_flag, chan[idx].freq, + chan[idx].noise_floor, + chan[idx].cycle_count, chan[idx].rx_clear_count, + chan[idx].clock_freq, chan[idx].cmd_flag, + chan[idx].tx_frame_count, idx); + if (chan[idx].freq == 0) + break; + + } + } + + EXIT(); +} + +/** + * wlan_hdd_init_chan_info() - init chan info in hdd context + * @hdd_ctx: HDD context pointer + * + * Return: none + */ +void wlan_hdd_init_chan_info(hdd_context_t *hdd_ctx) +{ + uint8_t num_2g, num_5g, index = 0; + + if (!hdd_ctx->config->fEnableSNRMonitoring) { + hdd_info("SNR monitoring is disabled"); + return; + } + + hdd_ctx->chan_info = + qdf_mem_malloc(sizeof(struct scan_chan_info) + * QDF_MAX_NUM_CHAN); + if (hdd_ctx->chan_info == NULL) { + hdd_err("Failed to malloc for chan info"); + return; + } + mutex_init(&hdd_ctx->chan_info_lock); + + num_2g = QDF_ARRAY_SIZE(hdd_channels_2_4_ghz); + for (; index < num_2g; index++) { + hdd_ctx->chan_info[index].freq = + hdd_channels_2_4_ghz[index].center_freq; + } + + num_5g = QDF_ARRAY_SIZE(hdd_channels_5_ghz); + for (; (index - num_2g) < num_5g; index++) { + if (cds_is_dsrc_channel( + hdd_channels_5_ghz[index - num_2g].center_freq)) + continue; + hdd_ctx->chan_info[index].freq = + hdd_channels_5_ghz[index - num_2g].center_freq; + } + sme_set_chan_info_callback(hdd_ctx->hHal, + &wlan_hdd_chan_info_cb); +} + +/** + * wlan_hdd_deinit_chan_info() - deinit chan info in hdd context + * @hdd_ctx: hdd context pointer + * + * Return: none + */ +void wlan_hdd_deinit_chan_info(hdd_context_t *hdd_ctx) +{ + struct scan_chan_info *chan; + + chan = hdd_ctx->chan_info; + hdd_ctx->chan_info = NULL; + if (chan) + qdf_mem_free(chan); +} + /** * struct cfg80211_ops - cfg80211_ops * diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 85401ac893d4..1c56a0707978 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -4940,6 +4940,7 @@ static void hdd_wlan_exit(hdd_context_t *hdd_ctx) cds_flush_work(&hdd_ctx->roc_req_work); wlansap_global_deinit(); + wlan_hdd_deinit_chan_info(hdd_ctx); wiphy_unregister(wiphy); wlan_hdd_cfg80211_deinit(wiphy); @@ -8406,6 +8407,8 @@ int hdd_wlan_startup(struct device *dev) if (hdd_ipa_init(hdd_ctx) == QDF_STATUS_E_FAILURE) goto err_wiphy_unregister; + wlan_hdd_init_chan_info(hdd_ctx); + hdd_initialize_mac_address(hdd_ctx); rtnl_held = hdd_hold_rtnl_lock(); diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c index 5664c1188c0c..f159c76268fe 100644 --- a/core/hdd/src/wlan_hdd_stats.c +++ b/core/hdd/src/wlan_hdd_stats.c @@ -2401,6 +2401,106 @@ struct net_device_stats *hdd_get_stats(struct net_device *dev) ENTER_DEV(dev); return &adapter->stats; } + + +/* + * time = cycle_count * cycle + * cycle = 1 / clock_freq + * Since the unit of clock_freq reported from + * FW is MHZ, and we want to calculate time in + * ms level, the result is + * time = cycle / (clock_freq * 1000) + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) +static bool wlan_fill_survey_result(struct survey_info *survey, int opfreq, + struct scan_chan_info *chan_info, + struct ieee80211_channel *channels) +{ + uint64_t clock_freq = chan_info->clock_freq * 1000; + + if (channels->center_freq != (uint16_t)chan_info->freq) + return false; + + survey->channel = channels; + survey->noise = chan_info->noise_floor; + survey->filled = SURVEY_INFO_NOISE_DBM; + + if (opfreq == chan_info->freq) + survey->filled |= SURVEY_INFO_IN_USE; + + if (clock_freq == 0) + return true; + + survey->time = chan_info->cycle_count / clock_freq; + survey->time_busy = chan_info->rx_clear_count / clock_freq; + survey->time_tx = chan_info->tx_frame_count / clock_freq; + + survey->filled |= SURVEY_INFO_TIME | + SURVEY_INFO_TIME_BUSY | + SURVEY_INFO_TIME_TX; + return true; +} +#else +static bool wlan_fill_survey_result(struct survey_info *survey, int opfreq, + struct scan_chan_info *chan_info, + struct ieee80211_channel *channels) +{ + uint64_t clock_freq = chan_info->clock_freq * 1000; + + if (channels->center_freq != (uint16_t)chan_info->freq) + return false; + + survey->channel = channels; + survey->noise = chan_info->noise_floor; + survey->filled = SURVEY_INFO_NOISE_DBM; + + if (opfreq == chan_info->freq) + survey->filled |= SURVEY_INFO_IN_USE; + + if (clock_freq == 0) + return true; + + survey->channel_time = chan_info->cycle_count / clock_freq; + survey->channel_time_busy = chan_info->rx_clear_count / clock_freq; + survey->channel_time_tx = chan_info->tx_frame_count / clock_freq; + + survey->filled |= SURVEY_INFO_CHANNEL_TIME | + SURVEY_INFO_CHANNEL_TIME_BUSY | + SURVEY_INFO_CHANNEL_TIME_TX; + return true; +} +#endif + +static bool wlan_hdd_update_survey_info(struct wiphy *wiphy, + hdd_adapter_t *pAdapter, struct survey_info *survey, int idx) +{ + bool filled = false; + int i, j = 0; + uint32_t channel = 0, opfreq; /* Initialization Required */ + hdd_context_t *pHddCtx; + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + sme_get_operation_channel(pHddCtx->hHal, &channel, pAdapter->sessionId); + hdd_wlan_get_freq(channel, &opfreq); + + mutex_lock(&pHddCtx->chan_info_lock); + + for (i = 0; i < IEEE80211_NUM_BANDS && !filled; i++) { + if (wiphy->bands[i] == NULL) + continue; + + for (j = 0; j < wiphy->bands[i]->n_channels && !filled; j++) { + struct ieee80211_supported_band *band = wiphy->bands[i]; + filled = wlan_fill_survey_result(survey, opfreq, + &pHddCtx->chan_info[idx], + &band->channels[j]); + } + } + mutex_unlock(&pHddCtx->chan_info_lock); + + return filled; +} + /** * __wlan_hdd_cfg80211_dump_survey() - get survey related info * @wiphy: Pointer to wiphy @@ -2417,86 +2517,45 @@ static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy, hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); hdd_context_t *pHddCtx; hdd_station_ctx_t *pHddStaCtx; - tHalHandle halHandle; - uint32_t channel = 0, freq = 0; /* Initialization Required */ - int8_t snr, rssi; - int status, i, j, filled = 0; + int status; + bool filled = false; ENTER_DEV(dev); - if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { + hdd_info("dump survey index:%d", idx); + if (idx > QDF_MAX_NUM_CHAN - 1) + return -EINVAL; + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + return status; + + if (pHddCtx->chan_info == NULL) { + hdd_err("chan_info is NULL"); + return -EINVAL; + } + + if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { hdd_err("Command not allowed in FTM mode"); return -EINVAL; } - pHddCtx = WLAN_HDD_GET_CTX(pAdapter); - status = wlan_hdd_validate_context(pHddCtx); - - if (0 != status) - return status; - pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); - if (0 == pHddCtx->config->fEnableSNRMonitoring || - 0 != pAdapter->survey_idx || - eConnectionState_Associated != pHddStaCtx->conn_info.connState) { - /* The survey dump ops when implemented completely is expected - * to return a survey of all channels and the ops is called by - * the kernel with incremental values of the argument 'idx' - * till it returns -ENONET. But we can only support the survey - * for the operating channel for now. survey_idx is used to - * track that the ops is called only once and then return - * -ENONET for the next iteration - */ - pAdapter->survey_idx = 0; + if (pHddCtx->config->fEnableSNRMonitoring == 0) + return -ENONET; + + + if (pHddStaCtx->hdd_ReassocScenario) { + hdd_info("Roaming in progress, hence return"); return -ENONET; } - if (!pHddStaCtx->hdd_ReassocScenario) { - hdd_err("Roaming in progress, hence return"); + filled = wlan_hdd_update_survey_info(wiphy, pAdapter, survey, idx); + + if (!filled) return -ENONET; - } - - halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter); - - wlan_hdd_get_snr(pAdapter, &snr); - wlan_hdd_get_rssi(pAdapter, &rssi); - - MTRACE(qdf_trace(QDF_MODULE_ID_HDD, - TRACE_CODE_HDD_CFG80211_DUMP_SURVEY, - pAdapter->sessionId, pAdapter->device_mode)); - - sme_get_operation_channel(halHandle, &channel, pAdapter->sessionId); - hdd_wlan_get_freq(channel, &freq); - - for (i = 0; i < NUM_NL80211_BANDS; i++) { - if (NULL == wiphy->bands[i]) - continue; - - for (j = 0; j < wiphy->bands[i]->n_channels; j++) { - struct ieee80211_supported_band *band = wiphy->bands[i]; - - if (band->channels[j].center_freq == (uint16_t) freq) { - survey->channel = &band->channels[j]; - /* The Rx BDs contain SNR values in dB for the - * received frames while the supplicant expects - * noise. So we calculate and return the value - * of noise (dBm) - * SNR (dB) = RSSI (dBm) - NOISE (dBm) - */ - survey->noise = rssi - snr; - survey->filled = SURVEY_INFO_NOISE_DBM; - filled = 1; - } - } - } - - if (filled) - pAdapter->survey_idx = 1; - else { - pAdapter->survey_idx = 0; - return -ENONET; - } EXIT(); return 0; } diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h index 6e277a0c453d..a1f45d6b113e 100644 --- a/core/mac/inc/ani_global.h +++ b/core/mac/inc/ani_global.h @@ -969,6 +969,8 @@ typedef struct sAniSirGlobal { bool sta_prefer_80MHz_over_160MHz; struct wlan_objmgr_psoc *psoc; enum country_src reg_hint_src; + bool snr_monitor_enabled; + void (*chan_info_cb)(struct scan_chan_info *chan_info); } tAniSirGlobal; typedef enum { diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 5a417c9351ca..90bec792a9b6 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -6889,4 +6889,23 @@ struct wow_pulse_mode { */ QDF_STATUS umac_send_mb_message_to_mac(void *msg); +/** + * struct scan_chan_info - channel info + * @freq: radio frequence + * @cmd flag: cmd flag + * @noise_floor: noise floor + * @cycle_count: cycle count + * @rx_clear_count: rx clear count + * @tx_frame_count: TX frame count + * @clock_freq: clock frequence MHZ + */ +struct scan_chan_info { + uint32_t freq; + uint32_t cmd_flag; + uint32_t noise_floor; + uint32_t cycle_count; + uint32_t rx_clear_count; + uint32_t tx_frame_count; + uint32_t clock_freq; +}; #endif /* __SIR_API_H */ diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index f1ad25e066e0..1ac6ce855bf8 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -91,6 +91,7 @@ typedef void (*hdd_ftm_msg_processor)(void *); typedef struct _smeConfigParams { tCsrConfigParam csrConfig; struct rrm_config_param rrmConfig; + bool snr_monitor_enabled; } tSmeConfigParams, *tpSmeConfigParams; #ifdef FEATURE_WLAN_TDLS @@ -1386,4 +1387,15 @@ void sme_set_cc_src(tHalHandle hal_handle, enum country_src); QDF_STATUS sme_set_wow_pulse(struct wow_pulse_mode *wow_pulse_set_info); #endif +/** + * sme_set_chan_info_callback() - Register chan info callback + * @hal - MAC global handle + * @callback_routine - callback routine from HDD + * + * This API is invoked by HDD to register its callback to mac + * + * Return: QDF_STATUS + */ +void sme_set_chan_info_callback(tHalHandle hal_handle, + void (*callback)(struct scan_chan_info *chan_info)); #endif /* #if !defined( __SME_API_H ) */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 798b942b5fac..3150a0dd5ba9 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -1456,6 +1456,9 @@ QDF_STATUS sme_update_config(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "Could not pass on WNI_CFG_SCAN_IN_POWERSAVE to CFG"); } + + pMac->snr_monitor_enabled = pSmeConfigParams->snr_monitor_enabled; + return status; } @@ -16439,6 +16442,19 @@ QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, tSirMacAddr bss_id) return status; } +void sme_set_chan_info_callback(tHalHandle hal_handle, + void (*callback)(struct scan_chan_info *chan_info)) +{ + tpAniSirGlobal mac; + + if (hal_handle == NULL) { + QDF_ASSERT(0); + return; + } + mac = PMAC_STRUCT(hal_handle); + mac->chan_info_cb = callback; +} + /** * sme_set_adaptive_dwelltime_config() - Update Adaptive dwelltime configuration * @hal: The handle returned by macOpen diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 508c4e452b79..6b129ccb66bd 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -2358,4 +2358,17 @@ int wma_form_rx_packet(qdf_nbuf_t buf, QDF_STATUS wma_mgmt_unified_cmd_send(struct wlan_objmgr_vdev *vdev, qdf_nbuf_t buf, uint32_t desc_id, void *mgmt_tx_params); + +/** + * wma_chan_info_event_handler() - chan info event handler + * @handle: wma handle + * @event_buf: event handler data + * @len: length of @event_buf + * + * this function will handle the WMI_CHAN_INFO_EVENTID + * + * Return: int + */ +int wma_chan_info_event_handler(void *handle, uint8_t *event_buf, + uint32_t len); #endif diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index e08f65f59918..41087462c253 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -8671,3 +8671,49 @@ int wma_unified_power_debug_stats_event_handler(void *handle, return 0; } #endif + +int wma_chan_info_event_handler(void *handle, uint8_t *event_buf, + uint32_t len) +{ + tp_wma_handle wma = (tp_wma_handle)handle; + WMI_CHAN_INFO_EVENTID_param_tlvs *param_buf; + wmi_chan_info_event_fixed_param *event; + struct scan_chan_info buf; + tpAniSirGlobal mac = NULL; + + WMA_LOGD("%s: Enter", __func__); + + if (wma != NULL && wma->cds_context != NULL) + mac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE); + + if (!mac) { + WMA_LOGE("%s: Invalid mac context", __func__); + return -EINVAL; + } + + WMA_LOGD("%s: monitor:%d", __func__, mac->snr_monitor_enabled); + if (mac->snr_monitor_enabled && mac->chan_info_cb) { + param_buf = + (WMI_CHAN_INFO_EVENTID_param_tlvs *)event_buf; + if (!param_buf) { + WMA_LOGA("%s: Invalid chan info event", __func__); + return -EINVAL; + } + + event = param_buf->fixed_param; + if (!event) { + WMA_LOGA("%s: Invalid fixed param", __func__); + return -EINVAL; + } + buf.tx_frame_count = event->tx_frame_cnt; + buf.clock_freq = event->mac_clk_mhz; + buf.cmd_flag = event->cmd_flags; + buf.freq = event->freq; + buf.noise_floor = event->noise_floor; + buf.cycle_count = event->cycle_count; + buf.rx_clear_count = event->rx_clear_count; + mac->chan_info_cb(&buf); + } + + return 0; +} diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index c52000a4ee74..06113969daaf 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -2338,6 +2338,10 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, void *cds_context, WMI_VDEV_ENCRYPT_DECRYPT_DATA_RESP_EVENTID, wma_encrypt_decrypt_msg_handler, WMA_RX_SERIALIZER_CTX); + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_CHAN_INFO_EVENTID, + wma_chan_info_event_handler, + WMA_RX_SERIALIZER_CTX); wma_ndp_register_all_event_handlers(wma_handle); wma_target_if_open(wma_handle); target_if_open(wma_get_psoc_from_scn_handle); diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 2a0086c30b30..cb1ceeddc14a 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -260,6 +260,10 @@ QDF_STATUS wma_get_buf_start_scan_cmd(tp_wma_handle wma_handle, /* add DS param IE in probe req frame */ cmd->scan_ctrl_flags |= WMI_SCAN_ADD_DS_IE_IN_PROBE_REQ; + /* set flag to get chan stats */ + if (pMac->snr_monitor_enabled) + cmd->scan_ctrl_flags |= WMI_SCAN_CHAN_STAT_EVENT; + /* do not add OFDM rates in 11B mode */ if (scan_req->dot11mode != WNI_CFG_DOT11_MODE_11B) cmd->scan_ctrl_flags |= WMI_SCAN_ADD_OFDM_RATES;