Эх сурвалжийг харах

qcacld-3.0: Set start and end channel configuration option

Add changes to enforce start and end channel limit in do_acs
if driver force acs and vendor based acs are enabled.

Also add changes to fix memory leak in set vendor channel API

Change-Id: Id45aaf3eb3c3dc1606a249136d3801a63ee854c4
CRs-Fixed: 2088567
Nachiket Kukade 7 жил өмнө
parent
commit
c3f92f7f44

+ 84 - 9
core/hdd/src/wlan_hdd_cfg80211.c

@@ -1506,6 +1506,59 @@ int wlan_hdd_sap_cfg_dfs_override(hdd_adapter_t *adapter)
 	return con_ch;
 }
 
+/**
+ * wlan_hdd_reset_force_acs_chan_range: Set acs channel ranges as per force ACS
+ * configuration.
+ * @hdd_ctx: pointer to hdd context
+ * @sap_config: pointer to SAP config struct
+ *
+ * Return: 0 if success else error code
+ */
+static int wlan_hdd_reset_force_acs_chan_range(hdd_context_t *hdd_ctx,
+						tsap_Config_t *sap_config)
+{
+	bool is_dfs_mode_enabled = false;
+	uint32_t i, num_channels = 0;
+	uint8_t channels[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
+
+	if (hdd_ctx->config->force_sap_acs_st_ch >
+			hdd_ctx->config->force_sap_acs_end_ch) {
+		hdd_err("invalid configuration for start and end channel");
+		return -EINVAL;
+	}
+	if (hdd_ctx->config->enableDFSMasterCap)
+		is_dfs_mode_enabled = true;
+
+	sap_config->acs_cfg.start_ch =
+			hdd_ctx->config->force_sap_acs_st_ch;
+	sap_config->acs_cfg.end_ch =
+			hdd_ctx->config->force_sap_acs_end_ch;
+
+	for (i = sap_config->acs_cfg.start_ch;
+			i <= sap_config->acs_cfg.end_ch; i++) {
+		if ((CHANNEL_STATE_ENABLE ==
+		     wlan_reg_get_channel_state(hdd_ctx->hdd_pdev, i)) ||
+		    (is_dfs_mode_enabled &&
+		     CHANNEL_STATE_DFS ==
+		     wlan_reg_get_channel_state(hdd_ctx->hdd_pdev, i))) {
+			channels[num_channels] = i;
+			num_channels++;
+		}
+	}
+	if (sap_config->acs_cfg.ch_list)
+		qdf_mem_free(sap_config->acs_cfg.ch_list);
+
+	sap_config->acs_cfg.ch_list = qdf_mem_malloc(num_channels);
+	if (!sap_config->acs_cfg.ch_list) {
+		hdd_err("ACS config alloc fail");
+		return -ENOMEM;
+	}
+	qdf_mem_copy(sap_config->acs_cfg.ch_list, channels, num_channels);
+	sap_config->acs_cfg.ch_list_count = num_channels;
+
+	return 0;
+}
+
 /**
  * wlan_hdd_set_acs_ch_range : Start ACS channel range values
  * @sap_cfg: pointer to SAP config struct
@@ -1515,7 +1568,6 @@ int wlan_hdd_sap_cfg_dfs_override(hdd_adapter_t *adapter)
  *
  * Return: None
  */
-
 static void wlan_hdd_set_acs_ch_range(tsap_Config_t *sap_cfg, bool ht_enabled,
 							bool vht_enabled)
 {
@@ -1545,7 +1597,6 @@ static void wlan_hdd_set_acs_ch_range(tsap_Config_t *sap_cfg, bool ht_enabled,
 	if (vht_enabled)
 		sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11ac;
 
-
 	/* Parse ACS Chan list from hostapd */
 	if (!sap_cfg->acs_cfg.ch_list)
 		return;
@@ -2177,6 +2228,7 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1];
 	bool ht_enabled, ht40_enabled, vht_enabled;
 	uint8_t ch_width, hw_mode;
+	QDF_STATUS qdf_status;
 
 	/* ***Note*** Donot set SME config related to ACS operation here because
 	 * ACS operation is not synchronouse and ACS for Second AP may come when
@@ -2325,12 +2377,12 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
 	hdd_debug("get pcl for DO_ACS vendor command");
 
 	/* consult policy manager to get PCL */
-	status = policy_mgr_get_pcl(hdd_ctx->hdd_psoc, PM_SAP_MODE,
+	qdf_status = policy_mgr_get_pcl(hdd_ctx->hdd_psoc, PM_SAP_MODE,
 				sap_config->acs_cfg.pcl_channels,
 				&sap_config->acs_cfg.pcl_ch_count,
 				sap_config->acs_cfg.pcl_channels_weight_list,
 				QDF_MAX_NUM_CHAN);
-	if (QDF_STATUS_SUCCESS != status)
+	if (QDF_STATUS_SUCCESS != qdf_status)
 		hdd_err("Get PCL failed");
 
 	if (sap_config->acs_cfg.pcl_ch_count) {
@@ -2342,12 +2394,20 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
 				  pcl_channels[i],
 				  sap_config->acs_cfg.
 				  pcl_channels_weight_list[i]);
-		}
+	}
 
 	wlan_hdd_set_acs_ch_range(sap_config, ht_enabled, vht_enabled);
-	/* ACS override for android */
+
+	if (hdd_ctx->config->force_sap_acs) {
+		hdd_debug("forcing SAP acs start and end channel");
+		status = wlan_hdd_reset_force_acs_chan_range(hdd_ctx,
+						sap_config);
+		if (status != 0)
+			goto out;
+	}
 
 	sap_config->acs_cfg.band = hw_mode;
+	/* ACS override for android */
 	if (hdd_ctx->config->sap_p2p_11ac_override && ht_enabled &&
 	    !hdd_ctx->config->sap_force_11n_for_11ac) {
 		hdd_debug("ACS Config override for 11AC vhtChannelWidth %d",
@@ -2366,7 +2426,6 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
 		}
 	}
 
-
 	hdd_debug("ACS Config for %s: HW_MODE: %d ACS_BW: %d HT: %d VHT: %d START_CH: %d END_CH: %d band %d",
 		adapter->dev->name, sap_config->acs_cfg.hw_mode,
 		ch_width, ht_enabled, vht_enabled,
@@ -9878,7 +9937,6 @@ static int hdd_update_acs_channel(hdd_adapter_t *adapter, uint8_t reason,
 	default:
 		hdd_info("invalid reason for timer invoke");
 	}
-	qdf_mem_free(channel_list);
 	EXIT();
 	return status;
 }
@@ -9939,6 +9997,10 @@ static int hdd_parse_vendor_acs_chan_config(struct hdd_vendor_chan_info
 
 	channel_list = qdf_mem_malloc(sizeof(struct hdd_vendor_chan_info) *
 					(*channel_cnt));
+	if (NULL == channel_list) {
+		hdd_err("Could not allocate for channel_list");
+		return -ENOMEM;
+	}
 
 	i = 0;
 	nla_for_each_nested(curr_attr, tb[SET_CHAN_CHAN_LIST], rem) {
@@ -10020,6 +10082,7 @@ static int __wlan_hdd_cfg80211_update_vendor_channel(struct wiphy *wiphy,
 	struct hdd_vendor_chan_info *channel_list = NULL;
 	hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
 	hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+	struct hdd_vendor_chan_info *channel_list_ptr;
 
 	ENTER();
 
@@ -10041,6 +10104,7 @@ static int __wlan_hdd_cfg80211_update_vendor_channel(struct wiphy *wiphy,
 
 	ret_val = hdd_parse_vendor_acs_chan_config(&channel_list, &reason,
 					&channel_cnt, data, data_len);
+	channel_list_ptr = channel_list;
 	if (ret_val)
 		return ret_val;
 
@@ -10051,16 +10115,27 @@ static int __wlan_hdd_cfg80211_update_vendor_channel(struct wiphy *wiphy,
 					channel_list->chan_width);
 		if (qdf_status == QDF_STATUS_SUCCESS)
 			break;
+		else if (channel_cnt == 1) {
+			hdd_err("invalid channel %d received from app",
+				channel_list->pri_ch);
+			channel_list->pri_ch = 0;
+			break;
+		}
+
 		channel_cnt--;
 		channel_list++;
 	}
+	hdd_debug("received primary channel as %d", channel_list->pri_ch);
 	if ((channel_cnt <= 0) || !channel_list) {
-		hdd_err("no available channel/chanlist %p", channel_list);
+		hdd_err("no available channel/chanlist %d/%p", channel_cnt,
+			channel_list);
+		qdf_mem_free(channel_list_ptr);
 		return -EINVAL;
 	}
 
 	qdf_status = hdd_update_acs_channel(adapter, reason,
 				      channel_cnt, channel_list);
+	qdf_mem_free(channel_list_ptr);
 	return qdf_status_to_os_return(qdf_status);
 }
 

+ 2 - 1
core/hdd/src/wlan_hdd_hostapd.c

@@ -7307,7 +7307,8 @@ static int wlan_hdd_setup_driver_overrides(hdd_adapter_t *ap_adapter)
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
 
 	if (ap_adapter->device_mode == QDF_SAP_MODE &&
-				hdd_ctx->config->force_sap_acs)
+				hdd_ctx->config->force_sap_acs &&
+				!hdd_ctx->config->vendor_acs_support)
 		goto setup_acs_overrides;
 
 	/* Fixed channel 11AC override: