diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index c78b8bf80282..e29a422fe57f 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -2513,60 +2513,25 @@ static bool wlan_hdd_check_dfs_channel_for_adapter(hdd_context_t *hdd_ctx, } /** - * __wlan_hdd_cfg80211_disable_dfs_chan_scan() - DFS channel configuration - * @wiphy: corestack handler - * @wdev: wireless device - * @data: data - * @data_len: data length - * Return: success(0) or reason code for failure + * wlan_hdd_disable_dfs_chan_scan() - disable/enable DFS channels + * @hdd_ctx: HDD context within host driver + * @adapter: Adapter pointer + * @no_dfs_flag: If TRUE, DFS channels cannot be used for scanning + * + * Loops through devices to see who is operating on DFS channels + * and then disables/enables DFS channels by calling SME API. + * Fails the disable request if any device is active on a DFS channel. + * + * Return: 0 or other error codes. */ -static int __wlan_hdd_cfg80211_disable_dfs_chan_scan(struct wiphy *wiphy, - struct wireless_dev *wdev, - const void *data, - int data_len) + +int wlan_hdd_disable_dfs_chan_scan(hdd_context_t *hdd_ctx, + hdd_adapter_t *adapter, + uint32_t no_dfs_flag) { - struct net_device *dev = wdev->netdev; - hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); tHalHandle h_hal = WLAN_HDD_GET_HAL_CTX(adapter); - hdd_context_t *hdd_ctx = wiphy_priv(wiphy); - struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1]; CDF_STATUS status; int ret_val = -EPERM; - uint32_t no_dfs_flag = 0; - - if (CDF_FTM_MODE == hdd_get_conparam()) { - hdd_err("Command not allowed in FTM mode"); - return -EPERM; - } - - if (wlan_hdd_validate_context(hdd_ctx)) { - hddLog(CDF_TRACE_LEVEL_ERROR, - FL("HDD context is not valid")); - return -EINVAL; - } - - if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX, - data, data_len, - wlan_hdd_set_no_dfs_flag_config_policy)) { - hddLog(CDF_TRACE_LEVEL_ERROR, FL("invalid attr")); - return -EINVAL; - } - - if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) { - hddLog(CDF_TRACE_LEVEL_ERROR, FL("attr dfs flag failed")); - return -EINVAL; - } - - no_dfs_flag = nla_get_u32( - tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]); - - hddLog(CDF_TRACE_LEVEL_INFO, FL(" DFS flag = %d"), - no_dfs_flag); - - if (no_dfs_flag > 1) { - hddLog(CDF_TRACE_LEVEL_ERROR, FL("invalid value of dfs flag")); - return -EINVAL; - } if (no_dfs_flag == hdd_ctx->config->enableDFSChnlScan) { if (no_dfs_flag) { @@ -2613,7 +2578,61 @@ static int __wlan_hdd_cfg80211_disable_dfs_chan_scan(struct wiphy *wiphy, FL(" the DFS flag has not changed")); ret_val = 0; } + return ret_val; +} +/** + * __wlan_hdd_cfg80211_disable_dfs_chan_scan() - DFS channel configuration + * @wiphy: corestack handler + * @wdev: wireless device + * @data: data + * @data_len: data length + * Return: success(0) or reason code for failure + */ +static int __wlan_hdd_cfg80211_disable_dfs_chan_scan(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct net_device *dev = wdev->netdev; + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1]; + int ret_val; + uint32_t no_dfs_flag = 0; + + ENTER(); + ret_val = wlan_hdd_validate_context(hdd_ctx); + + if (ret_val) { + hdd_err("HDD context is not valid"); + return ret_val; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX, + data, data_len, + wlan_hdd_set_no_dfs_flag_config_policy)) { + hdd_err("invalid attr"); + return -EINVAL; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) { + hdd_err("attr dfs flag failed"); + return -EINVAL; + } + + no_dfs_flag = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]); + + hddLog(LOG1, FL(" DFS flag = %d"), no_dfs_flag); + + if (no_dfs_flag > 1) { + hddLog(LOGE, FL("invalid value of dfs flag")); + return -EINVAL; + } + + ret_val = wlan_hdd_disable_dfs_chan_scan(hdd_ctx, adapter, + no_dfs_flag); return ret_val; } diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index 7357451f4ca1..f8cdd9001751 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -2275,5 +2275,9 @@ int wlan_hdd_sap_cfg_dfs_override(hdd_adapter_t *adapter); enum cds_con_mode wlan_hdd_convert_nl_iftype_to_hdd_type( enum nl80211_iftype type); -#endif +int wlan_hdd_disable_dfs_chan_scan(hdd_context_t *hdd_ctx, + hdd_adapter_t *adapter, + uint32_t no_dfs_flag); + +#endif diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c index 43c213ffa348..53afb626ddc2 100644 --- a/core/hdd/src/wlan_hdd_ioctl.c +++ b/core/hdd/src/wlan_hdd_ioctl.c @@ -5080,6 +5080,18 @@ static int drv_cmd_set_dfs_scan_mode(hdd_adapter_t *adapter, "%s: Received Command to Set DFS Scan Mode = %d", __func__, dfsScanMode); + /* When DFS scanning is disabled, the DFS channels need to be + * removed from the operation of device. + */ + ret = wlan_hdd_disable_dfs_chan_scan(hdd_ctx, adapter, + (dfsScanMode == CFG_ROAMING_DFS_CHANNEL_DISABLED)); + if (ret < 0) { + /* Some conditions prevented it from disabling DFS channels */ + hddLog(LOGE, + FL("disable/enable DFS channel request was denied")); + goto exit; + } + hdd_ctx->config->allowDFSChannelRoam = dfsScanMode; sme_update_dfs_scan_mode(hdd_ctx->hHal, adapter->sessionId, dfsScanMode);