瀏覽代碼

qcacmn: Mark SRD channels conditionally passive

--Treat SRD channels as PASSIVE if INI enable_srd_chan_in_master_mode
is 0. Add API reg_modify_chan_list_for_srd_channels for this purpose.
Mark channels as PASSIVE in both driver and kernel. Do not add this API
for WIN use-cases.
--Make default value of enable_srd_chan_in_master_mode as 1. WIN needs
default value as 1. MCC can over-ride with INI.
--When pdev is added, compute pdev current channel list only after pdev
private object is attached to the pdev. Computation of current channel
list accesses the private object via the pdev.
--When a pdev is added and deleted, set and reset def_pdev_id
correctly. Currently reset is not being done when pdev is destroyed.
--When programming current country to the firmware, do not use
def_pdev_id, since def_pdev_id can be -1. Ask for response for all phys.
Program pending reply for every phy, since the reg-domain for all phys
need to be re-programmed.
--Remove reg_reset_reg_rules when pdev is processed, after addition of
master channel list. The psoc copy of master reg rules need not be
cleaned up.

Change-Id: I5eaa457b8819d7a22d2e592d1b79fff15b364f40
CRs-Fixed: 2491045
Amar Singhal 5 年之前
父節點
當前提交
28374e3ff1

+ 47 - 3
umac/regulatory/core/src/reg_build_chan_list.c

@@ -542,8 +542,50 @@ static void reg_modify_chan_list_for_cached_channels(
 }
 #endif
 
-void reg_compute_pdev_current_chan_list(
-		struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
+#ifdef CONFIG_REG_CLIENT
+/**
+ * reg_modify_chan_list_for_srd_channels() - Modify SRD channels in ETSI13
+ * @pdev: Pointer to pdev object
+ * @chan_list: Current channel list
+ *
+ * This function converts SRD channels to passive in ETSI13 regulatory domain
+ * when enable_srd_chan_in_master_mode is not set.
+ */
+static void
+reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev,
+				      struct regulatory_channel *chan_list)
+{
+	enum channel_enum chan_enum;
+
+	if (!reg_is_etsi13_regdmn(pdev))
+		return;
+
+	if (reg_is_etsi13_srd_chan_allowed_master_mode(pdev))
+		return;
+
+	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
+		if (chan_list[chan_enum].chan_flags & REGULATORY_CHAN_DISABLED)
+			continue;
+
+		if (reg_is_etsi13_srd_chan(pdev,
+					   chan_list[chan_enum].chan_num)) {
+			chan_list[chan_enum].state =
+				CHANNEL_STATE_DFS;
+			chan_list[chan_enum].chan_flags |=
+				REGULATORY_CHAN_NO_IR;
+		}
+	}
+}
+#else
+static inline void
+reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev,
+				      struct regulatory_channel *chan_list)
+{
+}
+#endif
+
+void reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj
+					*pdev_priv_obj)
 {
 	qdf_mem_copy(pdev_priv_obj->cur_chan_list, pdev_priv_obj->mas_chan_list,
 		     NUM_CHANNELS * sizeof(struct regulatory_channel));
@@ -571,6 +613,9 @@ void reg_compute_pdev_current_chan_list(
 					  pdev_priv_obj->en_chan_144);
 
 	reg_modify_chan_list_for_cached_channels(pdev_priv_obj);
+
+	reg_modify_chan_list_for_srd_channels(pdev_priv_obj->pdev_ptr,
+					      pdev_priv_obj->cur_chan_list);
 }
 
 void reg_reset_reg_rules(struct reg_rule_info *reg_rules)
@@ -907,7 +952,6 @@ QDF_STATUS reg_process_master_chan_list(
 	if (pdev) {
 		reg_propagate_mas_chan_list_to_pdev(psoc, pdev, &dir);
 		wlan_objmgr_pdev_release_ref(pdev, dbg_id);
-		reg_reset_reg_rules(reg_rules);
 	}
 
 	return QDF_STATUS_SUCCESS;

+ 19 - 6
umac/regulatory/core/src/reg_priv_objs.c

@@ -91,7 +91,7 @@ QDF_STATUS wlan_regulatory_psoc_obj_created_notification(
 	soc_reg_obj->vdev_cnt_11d = 0;
 	soc_reg_obj->vdev_id_for_11d_scan = INVALID_VDEV_ID;
 	soc_reg_obj->restart_beaconing = CH_AVOID_RULE_RESTART;
-	soc_reg_obj->enable_srd_chan_in_master_mode = false;
+	soc_reg_obj->enable_srd_chan_in_master_mode = true;
 	soc_reg_obj->enable_11d_in_world_mode = false;
 	soc_reg_obj->def_pdev_id = -1;
 
@@ -185,10 +185,12 @@ QDF_STATUS wlan_regulatory_pdev_obj_created_notification(
 		return QDF_STATUS_E_FAULT;
 	}
 
-	if (psoc_priv_obj->def_pdev_id == -1)
+	if (psoc_priv_obj->def_pdev_id == -1) {
+		reg_debug("marking pdev with id %d", pdev_id);
 		psoc_priv_obj->def_pdev_id = pdev_id;
-	else
-		reg_err("reg cannot handle more than one pdev");
+	} else {
+		reg_debug("not marking this pdev");
+	}
 
 	pdev_priv_obj->pdev_ptr = pdev;
 	pdev_priv_obj->dfs_enabled = psoc_priv_obj->dfs_enabled;
@@ -236,8 +238,6 @@ QDF_STATUS wlan_regulatory_pdev_obj_created_notification(
 	reg_init_pdev_mas_chan_list(pdev_priv_obj,
 				    &psoc_priv_obj->mas_chan_params[pdev_id]);
 
-	reg_compute_pdev_current_chan_list(pdev_priv_obj);
-
 	psoc_reg_rules = &psoc_priv_obj->mas_chan_params[pdev_id].reg_rules;
 	reg_save_reg_rules_to_pdev(psoc_reg_rules, pdev_priv_obj);
 
@@ -249,6 +249,9 @@ QDF_STATUS wlan_regulatory_pdev_obj_created_notification(
 		qdf_mem_free(pdev_priv_obj);
 		return status;
 	}
+
+	reg_compute_pdev_current_chan_list(pdev_priv_obj);
+
 	if (!psoc_priv_obj->is_11d_offloaded)
 		reg_11d_host_scan_init(parent_psoc);
 
@@ -263,9 +266,12 @@ QDF_STATUS wlan_regulatory_pdev_obj_destroyed_notification(
 	QDF_STATUS status;
 	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
 	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
+	uint32_t pdev_id;
 
 	pdev_priv_obj = reg_get_pdev_obj(pdev);
 
+	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
+
 	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
 		reg_err("reg pdev private obj is NULL");
 		return QDF_STATUS_E_FAILURE;
@@ -282,6 +288,13 @@ QDF_STATUS wlan_regulatory_pdev_obj_destroyed_notification(
 
 	pdev_priv_obj->pdev_ptr = NULL;
 
+	if (psoc_priv_obj->def_pdev_id == pdev_id) {
+		reg_debug("deleting marked pdev");
+		psoc_priv_obj->def_pdev_id = -1;
+	} else {
+		reg_debug("deleting unmarked pdev");
+	}
+
 	status = wlan_objmgr_pdev_component_obj_detach(
 			pdev, WLAN_UMAC_COMP_REGULATORY, pdev_priv_obj);
 

+ 23 - 18
umac/regulatory/core/src/reg_utils.c

@@ -953,13 +953,13 @@ void reg_reset_ctry_pending_hints(struct wlan_regulatory_psoc_priv_obj
 	}
 }
 
-QDF_STATUS reg_set_curr_country(
-		struct wlan_regulatory_psoc_priv_obj *soc_reg,
-		struct cur_regulatory_info *regulat_info,
-		struct wlan_lmac_if_reg_tx_ops *tx_ops)
+QDF_STATUS reg_set_curr_country(struct wlan_regulatory_psoc_priv_obj *soc_reg,
+				struct cur_regulatory_info *regulat_info,
+				struct wlan_lmac_if_reg_tx_ops *tx_ops)
 {
 	struct wlan_objmgr_psoc *psoc = regulat_info->psoc;
 	uint8_t pdev_id;
+	uint8_t phy_num;
 	struct set_country country_code;
 	QDF_STATUS status;
 
@@ -974,13 +974,19 @@ QDF_STATUS reg_set_curr_country(
 			  REG_ALPHA2_LEN)))
 		return QDF_STATUS_SUCCESS;
 
-	pdev_id = soc_reg->def_pdev_id;
-	if (soc_reg->cc_src == SOURCE_USERSPACE)
-		soc_reg->new_user_ctry_pending[pdev_id] = true;
-	else if (soc_reg->cc_src == SOURCE_11D)
-		soc_reg->new_11d_ctry_pending[pdev_id] = true;
-	else
-		soc_reg->world_country_pending[pdev_id] = true;
+	/*
+	 * Need firmware to send channel list event
+	 * for all phys. Therefore set pdev_id to 0xFF
+	 */
+	pdev_id = 0xFF;
+	for (phy_num = 0; phy_num < regulat_info->num_phy; phy_num++) {
+		if (soc_reg->cc_src == SOURCE_USERSPACE)
+			soc_reg->new_user_ctry_pending[phy_num] = true;
+		else if (soc_reg->cc_src == SOURCE_11D)
+			soc_reg->new_11d_ctry_pending[phy_num] = true;
+		else
+			soc_reg->world_country_pending[phy_num] = true;
+	}
 
 	qdf_mem_zero(&country_code, sizeof(country_code));
 	qdf_mem_copy(country_code.country, soc_reg->cur_country,
@@ -1013,7 +1019,7 @@ error:
 bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg,
 				struct cur_regulatory_info *regulat_info)
 {
-	uint8_t pdev_id;
+	uint8_t phy_num;
 
 	if (!soc_reg->offload_enabled)
 		return false;
@@ -1021,12 +1027,11 @@ bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg,
 	if (soc_reg->cc_src == SOURCE_UNKNOWN)
 		return false;
 
-	pdev_id = regulat_info->phy_id;
-
-	if (soc_reg->new_user_ctry_pending[pdev_id] ||
-	    soc_reg->new_init_ctry_pending[pdev_id] ||
-	    soc_reg->new_11d_ctry_pending[pdev_id] ||
-	    soc_reg->world_country_pending[pdev_id])
+	phy_num = regulat_info->phy_id;
+	if (soc_reg->new_user_ctry_pending[phy_num] ||
+	    soc_reg->new_init_ctry_pending[phy_num] ||
+	    soc_reg->new_11d_ctry_pending[phy_num] ||
+	    soc_reg->world_country_pending[phy_num])
 		return false;
 
 	return true;