Parcourir la source

qcacld-3.0: modifications to SETDFSSCANMODE command

This is qcacld-2.0 to qcacld-3.0 propagation
When SETDFSSCANMODE is set to 0, it should now avoid DFS channels
altogether. Original implementation avoided DFS channel in roaming.
Now host code will first disable DFS channels and then follow
the original path.
Modifications to wlan_hdd_cfg80211_disable_dfs_chan_scan()
    - Keep validation of vendor command from NL.
    - Moved the DFS channel manipulation code to
      wlan_hdd_disable_dfs_chan_scan()
Call wlan_hdd_disable_dfs_chan_scan() in SETDFSSCANMODE processing.

CRs-Fixed: 778613
Change-Id: Ia2c00a6eb8d50e7962224375562a5b6417ba8bb2
Deepak Dhamdhere il y a 10 ans
Parent
commit
29b3b2fd0c

+ 68 - 49
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;
 }
 

+ 5 - 1
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

+ 12 - 0
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);