diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 4ad30387828a..9c3d3523f016 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -23058,6 +23058,9 @@ static int __wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy, uint8_t sec_ch = 0; int ret; uint16_t chan_num = cds_freq_to_chan(chandef->chan->center_freq); + enum channel_state chan_freq_state; + uint8_t max_fw_bw; + enum phy_ch_width ch_width; hdd_enter(); @@ -23074,19 +23077,42 @@ static int __wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy, hdd_debug("%s: set monitor mode Channel %d and freq %d", adapter->dev->name, chan_num, chandef->chan->center_freq); + /* Verify channel state before accepting this request */ + chan_freq_state = + wlan_reg_get_channel_state_for_freq(hdd_ctx->pdev, + chandef->chan->center_freq); + if (chan_freq_state == CHANNEL_STATE_DISABLE || + chan_freq_state == CHANNEL_STATE_INVALID) { + hdd_err("Invalid chan freq received for monitor mode aborting"); + return -EINVAL; + } + + /* Verify the BW before accepting this request */ + ch_width = hdd_map_nl_chan_width(chandef->width); + + max_fw_bw = sme_get_vht_ch_width(); + + if ((ch_width == CH_WIDTH_160MHZ && + max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) || + (ch_width == CH_WIDTH_80P80MHZ && + max_fw_bw <= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)) { + hdd_err("FW does not support this BW %d max BW supported %d", + ch_width, max_fw_bw); + return -EINVAL; + } sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); ch_info = &sta_ctx->ch_info; roam_profile.ChannelInfo.freq_list = &ch_info->freq; roam_profile.ChannelInfo.numOfChannels = 1; roam_profile.phyMode = ch_info->phy_mode; - roam_profile.ch_params.ch_width = hdd_map_nl_chan_width(chandef->width); + roam_profile.ch_params.ch_width = ch_width; hdd_select_cbmode(adapter, chandef->chan->center_freq, &roam_profile.ch_params); qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes, QDF_MAC_ADDR_SIZE); - ch_params.ch_width = hdd_map_nl_chan_width(chandef->width); + ch_params.ch_width = ch_width; /* * CDS api expects secondary channel for calculating * the channel params diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 72e0bf1e8563..61d0cc369a10 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1532,6 +1532,14 @@ QDF_STATUS sme_ext_scan_register_callback(mac_handle_t mac_handle, } #endif /* FEATURE_WLAN_EXTSCAN */ QDF_STATUS sme_abort_roam_scan(mac_handle_t mac_handle, uint8_t sessionId); + +/** + * sme_get_vht_ch_width() - SME API to get the max supported FW chan width + * + * Return: Max channel width supported by FW (eg. 20, 40, 80, 160, 80+80) + */ +uint32_t sme_get_vht_ch_width(void); + #ifdef WLAN_FEATURE_LINK_LAYER_STATS QDF_STATUS sme_ll_stats_clear_req(mac_handle_t mac_handle, tSirLLStatsClearReq * pclearStatsReq); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 995f6e54f365..fc62844c56c9 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -3239,6 +3239,11 @@ QDF_STATUS sme_get_config_param(mac_handle_t mac_handle, return status; } +uint32_t sme_get_vht_ch_width(void) +{ + return wma_get_vht_ch_width(); +} + /* * sme_get_modify_profile_fields() - * HDD or SME - QOS calls this function to get the current values of