소스 검색

qcacmn: Fixes for master channel list

When a new master channel list is created, populate master chan list to all
pdevs. Do not make any assumption on availability of pdevs. Make other
stability and initialization fixes. Also add extra fields to data
structures.

Change-Id: I0a59c41e9425435f6069807a3c5de0b389d8fa5e
CRs-Fixed: 2002892
Amar Singhal 8 년 전
부모
커밋
c2d4953235
4개의 변경된 파일263개의 추가작업 그리고 221개의 파일을 삭제
  1. 3 0
      umac/regulatory/core/src/reg_priv.h
  2. 245 221
      umac/regulatory/core/src/reg_services.c
  3. 14 0
      umac/regulatory/dispatcher/inc/reg_services_public_struct.h
  4. 1 0
      wmi/src/wmi_unified_tlv.c

+ 3 - 0
umac/regulatory/core/src/reg_priv.h

@@ -48,6 +48,9 @@
 struct wlan_regulatory_psoc_priv_obj {
 	struct regulatory_channel mas_chan_list[NUM_CHANNELS];
 	bool offload_enabled;
+	uint8_t num_phy;
+	uint16_t reg_dmn_pair;
+	uint16_t ctry_code;
 	bool nol_chan[NUM_CHANNELS];
 	char default_country[REG_ALPHA2_LEN + 1];
 	char current_country[REG_ALPHA2_LEN + 1];

+ 245 - 221
umac/regulatory/core/src/reg_services.c

@@ -1042,7 +1042,7 @@ static void reg_fill_channel_info(enum channel_enum chan_enum,
 			REGULATORY_CHAN_NO_IR;
 
 		master_list[chan_enum].state =
-			CHANNEL_STATE_PASSIVE;
+			CHANNEL_STATE_DFS;
 	}
 
 	if (reg_rule->flags & REGULATORY_CHAN_RADAR) {
@@ -1143,166 +1143,6 @@ static void do_auto_bw_correction(uint32_t num_reg_rules,
 }
 
 
-QDF_STATUS reg_process_master_chan_list(struct cur_regulatory_info
-					*regulat_info)
-{
-	struct wlan_regulatory_psoc_priv_obj *soc_reg;
-	uint32_t num_2g_reg_rules, num_5g_reg_rules;
-	struct cur_reg_rule *reg_rule_2g, *reg_rule_5g;
-	uint16_t min_bw_2g, max_bw_2g, min_bw_5g, max_bw_5g;
-	struct regulatory_channel *mas_chan_list;
-
-	reg_debug("process reg master chan list");
-
-	wlan_psoc_obj_lock(regulat_info->psoc);
-	soc_reg = (struct wlan_regulatory_psoc_priv_obj *)
-		wlan_objmgr_psoc_get_comp_private_obj(regulat_info->psoc,
-						  WLAN_UMAC_COMP_REGULATORY);
-	wlan_psoc_obj_unlock(regulat_info->psoc);
-
-	if (NULL == soc_reg) {
-		reg_err("soc_reg is NULL");
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	soc_reg->offload_enabled = true;
-
-	soc_reg->phybitmap = regulat_info->phybitmap;
-	soc_reg->dfs_region = regulat_info->dfs_region;
-	qdf_mem_copy(soc_reg->default_country, regulat_info->alpha2,
-		     REG_ALPHA2_LEN);
-	qdf_mem_copy(soc_reg->current_country, regulat_info->alpha2,
-		     REG_ALPHA2_LEN);
-
-	mas_chan_list = soc_reg->mas_chan_list;
-
-	min_bw_2g = regulat_info->min_bw_2g;
-	max_bw_2g = regulat_info->max_bw_2g;
-	reg_rule_2g = regulat_info->reg_rules_2g_ptr;
-	num_2g_reg_rules = regulat_info->num_2g_reg_rules;
-	update_max_bw_per_rule(num_2g_reg_rules,
-			       reg_rule_2g, max_bw_2g);
-
-	min_bw_5g = regulat_info->min_bw_5g;
-	max_bw_5g = regulat_info->max_bw_5g;
-	reg_rule_5g = regulat_info->reg_rules_5g_ptr;
-	num_5g_reg_rules = regulat_info->num_5g_reg_rules;
-	update_max_bw_per_rule(num_5g_reg_rules,
-			       reg_rule_5g, max_bw_5g);
-
-	do_auto_bw_correction(num_5g_reg_rules, reg_rule_5g, max_bw_5g);
-
-	populate_band_channels(CHAN_ENUM_1, CHAN_ENUM_14,
-			       reg_rule_2g, num_2g_reg_rules,
-			       min_bw_2g, mas_chan_list);
-
-	populate_band_channels(CHAN_ENUM_36, CHAN_ENUM_165,
-			       reg_rule_5g,
-			       num_5g_reg_rules,
-			       min_bw_5g, mas_chan_list);
-
-	return QDF_STATUS_SUCCESS;
-}
-
-/**
- * wlan_regulatory_psoc_obj_created_notification() - PSOC obj create callback
- * @psoc: PSOC object
- * @arg_list: Variable argument list
- *
- * This callback is registered with object manager during initialization to
- * get notified when the object is created.
- *
- * Return: Success or Failure
- */
-QDF_STATUS wlan_regulatory_psoc_obj_created_notification(
-		struct wlan_objmgr_psoc *psoc, void *arg_list)
-{
-	struct wlan_regulatory_psoc_priv_obj *soc_reg_obj;
-	struct regulatory_channel *mas_chan_list;
-	enum channel_enum chan_enum;
-	QDF_STATUS status;
-
-	soc_reg_obj = qdf_mem_malloc(sizeof(*soc_reg_obj));
-
-	if (NULL == soc_reg_obj) {
-		reg_alert("Mem alloc failed for reg psoc priv obj");
-		return QDF_STATUS_E_NOMEM;
-	}
-
-	soc_reg_obj->offload_enabled = false;
-	soc_reg_obj->psoc_ptr = psoc;
-	soc_reg_obj->dfs_enabled = true;
-	soc_reg_obj->set_fcc_channel = false;
-	soc_reg_obj->band_capability = BAND_ALL;
-	soc_reg_obj->indoor_chan_enabled = true;
-
-
-	mas_chan_list = soc_reg_obj->mas_chan_list;
-
-	for (chan_enum = 0; chan_enum < NUM_CHANNELS;
-	     chan_enum++) {
-		mas_chan_list[chan_enum].chan_num =
-			channel_map[chan_enum].chan_num;
-		mas_chan_list[chan_enum].center_freq =
-			channel_map[chan_enum].center_freq;
-		mas_chan_list[chan_enum].chan_flags |=
-			REGULATORY_CHAN_DISABLED;
-		mas_chan_list[chan_enum].state =
-			CHANNEL_STATE_DISABLE;
-		mas_chan_list[chan_enum].nol_chan = false;
-		soc_reg_obj->nol_chan[chan_enum] = false;
-	}
-
-	status = wlan_objmgr_psoc_component_obj_attach(psoc,
-			WLAN_UMAC_COMP_REGULATORY, soc_reg_obj,
-			QDF_STATUS_SUCCESS);
-
-	reg_debug("reg psoc obj created with status %d", status);
-
-	return status;
-}
-
-/**
- * wlan_regulatory_psoc_obj_destroyed_notification() - PSOC obj delete callback
- * @psoc: PSOC object
- * @arg_list: Variable argument list
- *
- * This callback is registered with object manager during initialization to
- * get notified when the object is deleted.
- *
- * Return: Success or Failure
- */
-QDF_STATUS wlan_regulatory_psoc_obj_destroyed_notification(
-		struct wlan_objmgr_psoc *psoc, void *arg_list)
-{
-	QDF_STATUS status;
-	struct wlan_regulatory_psoc_priv_obj *soc_reg;
-
-	wlan_psoc_obj_lock(psoc);
-	soc_reg = wlan_objmgr_psoc_get_comp_private_obj(psoc,
-					    WLAN_UMAC_COMP_REGULATORY);
-	wlan_psoc_obj_unlock(psoc);
-
-	if (NULL == soc_reg) {
-		reg_err("reg psoc private obj is NULL");
-		return QDF_STATUS_E_FAULT;
-	}
-
-	soc_reg->psoc_ptr = NULL;
-
-	status = wlan_objmgr_psoc_component_obj_detach(psoc,
-			WLAN_UMAC_COMP_REGULATORY,
-			soc_reg);
-	if (status != QDF_STATUS_SUCCESS)
-		reg_err("soc_reg private obj detach failed");
-
-	reg_debug("reg psoc obj detached with status %d", status);
-
-	qdf_mem_free(soc_reg);
-
-	return status;
-}
-
 static void
 modify_chan_list_for_dfs_channels(struct regulatory_channel *chan_list,
 				  bool dfs_enabled)
@@ -1470,6 +1310,250 @@ modify_chan_list_for_freq_range(struct regulatory_channel
 	}
 }
 
+static void reg_change_pdev_for_new_mas_chan_list(struct wlan_objmgr_psoc *psoc,
+						  void *object, void *arg)
+{
+	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object;
+	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
+	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
+	enum channel_enum chan_enum;
+
+	wlan_psoc_obj_lock(psoc);
+	psoc_priv_obj = (struct wlan_regulatory_psoc_priv_obj *)
+		wlan_objmgr_psoc_get_comp_private_obj(psoc,
+				       WLAN_UMAC_COMP_REGULATORY);
+	wlan_psoc_obj_unlock(psoc);
+
+	if (NULL == psoc_priv_obj) {
+		reg_err("psoc priv obj is NULL");
+		return;
+	}
+
+	wlan_pdev_obj_lock(pdev);
+	pdev_priv_obj = (struct wlan_regulatory_pdev_priv_obj *)
+		wlan_objmgr_pdev_get_comp_private_obj(pdev,
+					       WLAN_UMAC_COMP_REGULATORY);
+	wlan_pdev_obj_unlock(pdev);
+
+	if (NULL == pdev_priv_obj) {
+		reg_err("pdev priv obj is NULL");
+		return;
+	}
+
+	qdf_mem_copy(pdev_priv_obj->cur_chan_list,
+		     psoc_priv_obj->mas_chan_list,
+		     NUM_CHANNELS * sizeof(struct regulatory_channel));
+
+	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++)
+		pdev_priv_obj->cur_chan_list[chan_enum].nol_chan =
+			psoc_priv_obj->nol_chan[chan_enum];
+
+	modify_chan_list_for_freq_range(pdev_priv_obj->cur_chan_list,
+					pdev_priv_obj->range_2g_low,
+					pdev_priv_obj->range_2g_high,
+					pdev_priv_obj->range_5g_low,
+					pdev_priv_obj->range_5g_high);
+
+	modify_chan_list_for_dfs_channels(pdev_priv_obj->cur_chan_list,
+					  pdev_priv_obj->dfs_enabled);
+
+	modify_chan_list_for_indoor_channels(pdev_priv_obj->cur_chan_list,
+					 pdev_priv_obj->indoor_chan_enabled);
+
+	modify_chan_list_for_band(pdev_priv_obj->cur_chan_list,
+				  pdev_priv_obj->band_capability);
+
+	modify_chan_list_for_nol_list(pdev_priv_obj->cur_chan_list);
+
+	modify_chan_list_for_fcc_channel(pdev_priv_obj->cur_chan_list,
+					 pdev_priv_obj->set_fcc_channel);
+
+}
+
+
+QDF_STATUS reg_process_master_chan_list(struct cur_regulatory_info
+					*regulat_info)
+{
+	struct wlan_regulatory_psoc_priv_obj *soc_reg;
+	uint32_t num_2g_reg_rules, num_5g_reg_rules;
+	struct cur_reg_rule *reg_rule_2g, *reg_rule_5g;
+	uint16_t min_bw_2g, max_bw_2g, min_bw_5g, max_bw_5g;
+	struct regulatory_channel *mas_chan_list;
+	QDF_STATUS status;
+	enum channel_enum chan_enum;
+
+	reg_debug("process reg master chan list");
+
+	wlan_psoc_obj_lock(regulat_info->psoc);
+	soc_reg = (struct wlan_regulatory_psoc_priv_obj *)
+		wlan_objmgr_psoc_get_comp_private_obj(regulat_info->psoc,
+						  WLAN_UMAC_COMP_REGULATORY);
+	wlan_psoc_obj_unlock(regulat_info->psoc);
+
+	if (NULL == soc_reg) {
+		reg_err("soc_reg is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mas_chan_list = soc_reg->mas_chan_list;
+
+	for (chan_enum = 0; chan_enum < NUM_CHANNELS;
+	     chan_enum++) {
+		mas_chan_list[chan_enum].chan_num =
+			channel_map[chan_enum].chan_num;
+		mas_chan_list[chan_enum].center_freq =
+			channel_map[chan_enum].center_freq;
+		mas_chan_list[chan_enum].chan_flags |=
+			REGULATORY_CHAN_DISABLED;
+		mas_chan_list[chan_enum].state =
+			CHANNEL_STATE_DISABLE;
+		mas_chan_list[chan_enum].nol_chan = false;
+		soc_reg->nol_chan[chan_enum] = false;
+	}
+
+	soc_reg->offload_enabled = regulat_info->offload_enabled;
+	soc_reg->phybitmap = regulat_info->phybitmap;
+	soc_reg->dfs_region = regulat_info->dfs_region;
+	qdf_mem_copy(soc_reg->default_country, regulat_info->alpha2,
+		     REG_ALPHA2_LEN);
+	qdf_mem_copy(soc_reg->current_country, regulat_info->alpha2,
+		     REG_ALPHA2_LEN);
+
+	min_bw_2g = regulat_info->min_bw_2g;
+	max_bw_2g = regulat_info->max_bw_2g;
+	reg_rule_2g = regulat_info->reg_rules_2g_ptr;
+	num_2g_reg_rules = regulat_info->num_2g_reg_rules;
+	update_max_bw_per_rule(num_2g_reg_rules,
+			       reg_rule_2g, max_bw_2g);
+
+	min_bw_5g = regulat_info->min_bw_5g;
+	max_bw_5g = regulat_info->max_bw_5g;
+	reg_rule_5g = regulat_info->reg_rules_5g_ptr;
+	num_5g_reg_rules = regulat_info->num_5g_reg_rules;
+	update_max_bw_per_rule(num_5g_reg_rules,
+			       reg_rule_5g, max_bw_5g);
+
+	if (num_5g_reg_rules != 0)
+		do_auto_bw_correction(num_5g_reg_rules, reg_rule_5g,
+				      max_bw_5g);
+
+	if (num_2g_reg_rules != 0)
+		populate_band_channels(CHAN_ENUM_1, CHAN_ENUM_14,
+				       reg_rule_2g, num_2g_reg_rules,
+				       min_bw_2g, mas_chan_list);
+
+	if (num_5g_reg_rules != 0)
+		populate_band_channels(CHAN_ENUM_36, CHAN_ENUM_165,
+				       reg_rule_5g,
+				       num_5g_reg_rules,
+				       min_bw_5g, mas_chan_list);
+
+	status = wlan_objmgr_iterate_obj_list(regulat_info->psoc, WLAN_PDEV_OP,
+					      reg_change_pdev_for_new_mas_chan_list,
+					      NULL, 1, WLAN_REGULATORY_SB_ID);
+
+	return status;
+}
+
+/**
+ * wlan_regulatory_psoc_obj_created_notification() - PSOC obj create callback
+ * @psoc: PSOC object
+ * @arg_list: Variable argument list
+ *
+ * This callback is registered with object manager during initialization to
+ * get notified when the object is created.
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS wlan_regulatory_psoc_obj_created_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg_list)
+{
+	struct wlan_regulatory_psoc_priv_obj *soc_reg_obj;
+	struct regulatory_channel *mas_chan_list;
+	enum channel_enum chan_enum;
+	QDF_STATUS status;
+
+	soc_reg_obj = qdf_mem_malloc(sizeof(*soc_reg_obj));
+
+	if (NULL == soc_reg_obj) {
+		reg_alert("Mem alloc failed for reg psoc priv obj");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	soc_reg_obj->offload_enabled = false;
+	soc_reg_obj->psoc_ptr = psoc;
+	soc_reg_obj->dfs_enabled = true;
+	soc_reg_obj->set_fcc_channel = false;
+	soc_reg_obj->band_capability = BAND_ALL;
+	soc_reg_obj->indoor_chan_enabled = true;
+
+
+	mas_chan_list = soc_reg_obj->mas_chan_list;
+
+	for (chan_enum = 0; chan_enum < NUM_CHANNELS;
+	     chan_enum++) {
+		mas_chan_list[chan_enum].chan_num =
+			channel_map[chan_enum].chan_num;
+		mas_chan_list[chan_enum].center_freq =
+			channel_map[chan_enum].center_freq;
+		mas_chan_list[chan_enum].chan_flags |=
+			REGULATORY_CHAN_DISABLED;
+		mas_chan_list[chan_enum].state =
+			CHANNEL_STATE_DISABLE;
+		mas_chan_list[chan_enum].nol_chan = false;
+		soc_reg_obj->nol_chan[chan_enum] = false;
+	}
+
+	status = wlan_objmgr_psoc_component_obj_attach(psoc,
+			WLAN_UMAC_COMP_REGULATORY, soc_reg_obj,
+			QDF_STATUS_SUCCESS);
+
+	reg_debug("reg psoc obj created with status %d", status);
+
+	return status;
+}
+
+/**
+ * wlan_regulatory_psoc_obj_destroyed_notification() - PSOC obj delete callback
+ * @psoc: PSOC object
+ * @arg_list: Variable argument list
+ *
+ * This callback is registered with object manager during initialization to
+ * get notified when the object is deleted.
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS wlan_regulatory_psoc_obj_destroyed_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg_list)
+{
+	QDF_STATUS status;
+	struct wlan_regulatory_psoc_priv_obj *soc_reg;
+
+	wlan_psoc_obj_lock(psoc);
+	soc_reg = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+					    WLAN_UMAC_COMP_REGULATORY);
+	wlan_psoc_obj_unlock(psoc);
+
+	if (NULL == soc_reg) {
+		reg_err("reg psoc private obj is NULL");
+		return QDF_STATUS_E_FAULT;
+	}
+
+	soc_reg->psoc_ptr = NULL;
+
+	status = wlan_objmgr_psoc_component_obj_detach(psoc,
+			WLAN_UMAC_COMP_REGULATORY,
+			soc_reg);
+	if (status != QDF_STATUS_SUCCESS)
+		reg_err("soc_reg private obj detach failed");
+
+	reg_debug("reg psoc obj detached with status %d", status);
+
+	qdf_mem_free(soc_reg);
+
+	return status;
+}
+
 /**
  * wlan_regulatory_pdev_obj_created_notification() - PDEV obj create callback
  * @pdev: pdev object
@@ -1891,66 +1975,6 @@ bool reg_is_regdb_offloaded(struct wlan_objmgr_psoc *psoc)
 }
 
 
-static void reg_change_pdev_for_new_mas_chan_list(struct wlan_objmgr_psoc *psoc,
-						  void *object, void *arg)
-{
-	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object;
-	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
-	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
-	enum channel_enum chan_enum;
-
-	wlan_psoc_obj_lock(psoc);
-	psoc_priv_obj = (struct wlan_regulatory_psoc_priv_obj *)
-		wlan_objmgr_psoc_get_comp_private_obj(psoc,
-				       WLAN_UMAC_COMP_REGULATORY);
-	wlan_psoc_obj_unlock(psoc);
-
-	if (NULL == psoc_priv_obj) {
-		reg_err("psoc priv obj is NULL");
-		return;
-	}
-
-	wlan_pdev_obj_lock(pdev);
-	pdev_priv_obj = (struct wlan_regulatory_pdev_priv_obj *)
-		wlan_objmgr_pdev_get_comp_private_obj(pdev,
-					       WLAN_UMAC_COMP_REGULATORY);
-	wlan_pdev_obj_unlock(pdev);
-
-	if (NULL == pdev_priv_obj) {
-		reg_err("pdev priv obj is NULL");
-		return;
-	}
-
-	qdf_mem_copy(pdev_priv_obj->cur_chan_list,
-		     psoc_priv_obj->mas_chan_list,
-		     NUM_CHANNELS * sizeof(struct regulatory_channel));
-
-	for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++)
-		pdev_priv_obj->cur_chan_list[chan_enum].nol_chan =
-			psoc_priv_obj->nol_chan[chan_enum];
-
-	modify_chan_list_for_freq_range(pdev_priv_obj->cur_chan_list,
-					pdev_priv_obj->range_2g_low,
-					pdev_priv_obj->range_2g_high,
-					pdev_priv_obj->range_5g_low,
-					pdev_priv_obj->range_5g_high);
-
-	modify_chan_list_for_dfs_channels(pdev_priv_obj->cur_chan_list,
-					  pdev_priv_obj->dfs_enabled);
-
-	modify_chan_list_for_indoor_channels(pdev_priv_obj->cur_chan_list,
-					 pdev_priv_obj->indoor_chan_enabled);
-
-	modify_chan_list_for_band(pdev_priv_obj->cur_chan_list,
-				  pdev_priv_obj->band_capability);
-
-	modify_chan_list_for_nol_list(pdev_priv_obj->cur_chan_list);
-
-	modify_chan_list_for_fcc_channel(pdev_priv_obj->cur_chan_list,
-					 pdev_priv_obj->set_fcc_channel);
-
-}
-
 void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc,
 				    struct regulatory_channel *reg_channels,
 				    uint8_t *alpha2,

+ 14 - 0
umac/regulatory/dispatcher/inc/reg_services_public_struct.h

@@ -393,6 +393,14 @@ enum ht_sec_ch_offset {
 	HIGH_PRIMARY_CH = 3,
 };
 
+enum cc_setting_code {
+	REG_SET_CC_STATUS_PASS = 0,
+	REG_CURRENT_ALPHA2_NOT_FOUND = 1,
+	REG_INIT_ALPHA2_NOT_FOUND = 2,
+	REG_SET_CC_CHANGE_NOT_ALLOWED = 3,
+	REG_SET_CC_STATUS_NO_MEMORY = 4,
+	REG_SET_CC_STATUS_FAIL = 5,
+};
 
 /**
  * struct cur_reg_rule
@@ -415,6 +423,7 @@ struct cur_reg_rule {
 /**
  * struct cur_regulatory_info
  * @psoc: psoc ptr
+ * @cc_setting_code: cc setting regdb value
  * @alpha2: country alpha2
  * @dfs_reg: dfs region
  * @phybitmap: phy bit map
@@ -429,7 +438,12 @@ struct cur_reg_rule {
  */
 struct cur_regulatory_info {
 	struct wlan_objmgr_psoc *psoc;
+	enum cc_setting_code status_code;
+	uint8_t num_phy;
+	uint16_t reg_dmn_pair;
+	uint16_t ctry_code;
 	uint8_t alpha2[REG_ALPHA2_LEN + 1];
+	bool offload_enabled;
 	enum dfs_reg dfs_region;
 	uint32_t phybitmap;
 	uint32_t min_bw_2g;

+ 1 - 0
wmi/src/wmi_unified_tlv.c

@@ -17174,6 +17174,7 @@ static QDF_STATUS extract_reg_chan_list_update_event_tlv(
 			REG_ALPHA2_LEN);
 	reg_info->dfs_region = chan_list_event_hdr->dfs_region;
 	reg_info->phybitmap = chan_list_event_hdr->phybitmap;
+	reg_info->offload_enabled = true;
 	reg_info->min_bw_2g = chan_list_event_hdr->min_bw_2g;
 	reg_info->max_bw_2g = chan_list_event_hdr->max_bw_2g;
 	reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g;