Browse Source

qcacmn: Set default country code

When a country code is not available from inside the device
(from EEPROM), a default country needs to be set. Also get
the regdomains from the default country code and build the
master channel list.

Change-Id: If307ad18318b2aea3fcdd149c01b39a678163bb5
CRs-Fixed: 2002892
Baila, Shashikala Prabhu 8 years ago
parent
commit
9e63cb7b00

+ 2 - 9
umac/regulatory/core/src/reg_db.c

@@ -872,16 +872,9 @@ QDF_STATUS get_num_reg_dmn_pairs(int *num_reg_dmn)
 	return QDF_STATUS_SUCCESS;
 }
 
-QDF_STATUS get_default_country_2g(int *default_country)
+QDF_STATUS get_default_country(uint16_t *default_country)
 {
-	*default_country = WORLD_2G_3;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS get_default_country_5g(int *default_country)
-{
-	*default_country = WORLD_5G_2;
+	*default_country = CTRY_UNITED_STATES;
 
 	return QDF_STATUS_SUCCESS;
 }

+ 1 - 2
umac/regulatory/core/src/reg_db.h

@@ -149,7 +149,6 @@ QDF_STATUS get_num_countries(int *num_countries);
 
 QDF_STATUS get_num_reg_dmn_pairs(int *num_reg_dmn);
 
-QDF_STATUS get_default_country_2g(int *default_country);
+QDF_STATUS get_default_country(uint16_t *default_country);
 
-QDF_STATUS get_default_country_5g(int *default_country);
 #endif

+ 71 - 104
umac/regulatory/core/src/reg_db_parser.c

@@ -118,6 +118,29 @@ QDF_STATUS reg_get_rdpair_from_country_iso(uint8_t *alpha,
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS reg_get_rdpair_from_regdmn_id(uint16_t regdmn_id,
+		uint16_t *regdmn_pair)
+{
+	uint16_t j;
+	int num_reg_dmn;
+
+	get_num_reg_dmn_pairs(&num_reg_dmn);
+
+	for (j = 0; j < num_reg_dmn; j++) {
+		if (g_reg_dmn_pairs[j].reg_dmn_pair_id == regdmn_id)
+			break;
+	}
+
+	if (j == num_reg_dmn) {
+		*regdmn_pair = -1;
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	*regdmn_pair = j;
+
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS reg_get_rdpair_from_country_code(uint16_t cc,
 		uint16_t *country_index,
 		uint16_t *regdmn_pair)
@@ -141,7 +164,7 @@ QDF_STATUS reg_get_rdpair_from_country_code(uint16_t cc,
 
 	for (j = 0; j < num_reg_dmn; j++) {
 		if (g_reg_dmn_pairs[j].reg_dmn_pair_id ==
-			g_all_countries[i].reg_dmn_pair_id)
+				g_all_countries[i].reg_dmn_pair_id)
 			break;
 	}
 
@@ -163,47 +186,46 @@ static inline QDF_STATUS reg_get_reginfo_form_country_code_and_regdmn_pair(
 {
 	uint16_t i, j;
 	uint8_t rule_size_2g, rule_size_5g;
+	uint8_t dmn_id_5g, dmn_id_2g;
 
 	i = country_index;
 	j = regdmn_pair;
 
-	rule_size_2g = QDF_ARRAY_SIZE(
-		regdomains_2g[g_reg_dmn_pairs[j].dmn_id_2g].reg_rule_id);
-	rule_size_5g = QDF_ARRAY_SIZE(
-		regdomains_5g[g_reg_dmn_pairs[j].dmn_id_5g].reg_rule_id);
+	dmn_id_5g = g_reg_dmn_pairs[j].dmn_id_5g;
+	dmn_id_2g = g_reg_dmn_pairs[j].dmn_id_2g;
+
+	rule_size_2g = QDF_ARRAY_SIZE(regdomains_2g[dmn_id_2g].reg_rule_id);
+	rule_size_5g = QDF_ARRAY_SIZE(regdomains_5g[dmn_id_5g].reg_rule_id);
 
 	if (((rule_size_2g + rule_size_5g) >=
-		    regdomains_2g[g_reg_dmn_pairs[j].dmn_id_2g].num_reg_rules +
-		    regdomains_5g[g_reg_dmn_pairs[j].dmn_id_5g].num_reg_rules)
-		) {
-		reg_info->dfs_region =
-		    regdomains_5g[g_reg_dmn_pairs[j].dmn_id_5g].dfs_region;
+				regdomains_2g[dmn_id_2g].num_reg_rules +
+				regdomains_5g[dmn_id_5g].num_reg_rules)) {
+		reg_info->dfs_region = regdomains_5g[dmn_id_5g].dfs_region;
 		reg_info->phybitmap = g_all_countries[i].phymode_bitmap;
 		reg_info->max_bw_2g = g_all_countries[i].max_bw_2g;
 		reg_info->max_bw_5g = g_all_countries[i].max_bw_5g;
-		reg_info->min_bw_2g =
-		    regdomains_2g[g_reg_dmn_pairs[j].dmn_id_2g].min_bw;
-		reg_info->min_bw_5g =
-		    regdomains_5g[g_reg_dmn_pairs[j].dmn_id_5g].min_bw;
+
+		reg_info->min_bw_2g = regdomains_2g[dmn_id_2g].min_bw;
+		reg_info->min_bw_5g = regdomains_5g[dmn_id_5g].min_bw;
+
 		reg_info->num_2g_reg_rules =
-		    regdomains_2g[g_reg_dmn_pairs[j].dmn_id_2g].num_reg_rules;
+			regdomains_2g[dmn_id_2g].num_reg_rules;
 		reg_info->num_5g_reg_rules =
-		    regdomains_5g[g_reg_dmn_pairs[j].dmn_id_5g].num_reg_rules;
+			regdomains_5g[dmn_id_5g].num_reg_rules;
 
 		reg_info->reg_rules_2g_ptr = (struct cur_reg_rule *)
-		    qdf_mem_malloc((reg_info->num_2g_reg_rules) *
-			    sizeof(struct cur_reg_rule));
+			qdf_mem_malloc((reg_info->num_2g_reg_rules) *
+					sizeof(struct cur_reg_rule));
 		reg_info->reg_rules_5g_ptr = (struct cur_reg_rule *)
-		    qdf_mem_malloc((reg_info->num_5g_reg_rules) *
-			    sizeof(struct cur_reg_rule));
+			qdf_mem_malloc((reg_info->num_5g_reg_rules) *
+					sizeof(struct cur_reg_rule));
 
-		reg_regrules_assign(g_reg_dmn_pairs[j].dmn_id_2g,
-				g_reg_dmn_pairs[j].dmn_id_5g, reg_info);
+		reg_regrules_assign(dmn_id_2g, dmn_id_5g, reg_info);
 
 		return QDF_STATUS_SUCCESS;
 	} else if (!(((rule_size_2g + rule_size_5g) >=
-		regdomains_2g[g_reg_dmn_pairs[j].dmn_id_2g].num_reg_rules +
-		regdomains_5g[g_reg_dmn_pairs[j].dmn_id_5g].num_reg_rules)))
+				regdomains_2g[dmn_id_2g].num_reg_rules +
+				regdomains_5g[dmn_id_5g].num_reg_rules)))
 	    return QDF_STATUS_E_NOMEM;
 
 	return QDF_STATUS_SUCCESS;
@@ -215,98 +237,46 @@ static inline QDF_STATUS reg_get_reginfo_form_regdmn_pair(
 {
 	uint16_t j;
 	uint8_t rule_size_2g, rule_size_5g;
+	uint8_t dmn_id_5g, dmn_id_2g;
 
 	j = regdmn_pair;
-	rule_size_2g = QDF_ARRAY_SIZE(
-		regdomains_2g[g_reg_dmn_pairs[j].dmn_id_2g].reg_rule_id);
-	rule_size_5g = QDF_ARRAY_SIZE(
-		regdomains_5g[g_reg_dmn_pairs[j].dmn_id_5g].reg_rule_id);
+	dmn_id_5g = g_reg_dmn_pairs[j].dmn_id_5g;
+	dmn_id_2g = g_reg_dmn_pairs[j].dmn_id_2g;
 
-	if (((rule_size_2g + rule_size_5g) >=
-		    regdomains_2g[g_reg_dmn_pairs[j].dmn_id_2g].num_reg_rules +
-		    regdomains_5g[g_reg_dmn_pairs[j].dmn_id_5g].num_reg_rules)
-		) {
-
-		reg_info->dfs_region =
-		    regdomains_5g[g_reg_dmn_pairs[j].dmn_id_5g].dfs_region;
-		reg_info->phybitmap = 0;
-		reg_info->max_bw_2g = 40;
-		reg_info->max_bw_5g = 160;
-		reg_info->min_bw_2g =
-		    regdomains_2g[g_reg_dmn_pairs[j].dmn_id_2g].min_bw;
-		reg_info->min_bw_5g =
-		    regdomains_5g[g_reg_dmn_pairs[j].dmn_id_5g].min_bw;
-		reg_info->num_2g_reg_rules =
-		    regdomains_2g[g_reg_dmn_pairs[j].dmn_id_2g].num_reg_rules;
-		reg_info->num_5g_reg_rules =
-		    regdomains_5g[g_reg_dmn_pairs[j].dmn_id_5g].num_reg_rules;
-
-		reg_info->reg_rules_2g_ptr = (struct cur_reg_rule *)
-		    qdf_mem_malloc((reg_info->num_2g_reg_rules) *
-			    sizeof(struct cur_reg_rule));
-		reg_info->reg_rules_5g_ptr = (struct cur_reg_rule *)
-		    qdf_mem_malloc((reg_info->num_5g_reg_rules) *
-			    sizeof(struct cur_reg_rule));
-
-		reg_regrules_assign(g_reg_dmn_pairs[j].dmn_id_2g,
-				g_reg_dmn_pairs[j].dmn_id_5g, reg_info);
-
-		return QDF_STATUS_SUCCESS;
-	} else if (!(((rule_size_2g + rule_size_5g) >= regdomains_2g[
-			g_reg_dmn_pairs[j].dmn_id_2g].num_reg_rules +
-			regdomains_5g[
-			g_reg_dmn_pairs[j].dmn_id_5g].num_reg_rules)))
-		return QDF_STATUS_E_NOMEM;
-
-	return QDF_STATUS_SUCCESS;
-}
-
-static inline QDF_STATUS reg_get_reginfo_for_default_regdmn_pair(
-		struct cur_regulatory_info *reg_info,
-		uint16_t regdmn_pair)
-{
-	int default_country_2g;
-	int default_country_5g;
-	uint8_t rule_size_2g, rule_size_5g;
-
-	get_default_country_2g(&default_country_2g);
-	get_default_country_5g(&default_country_5g);
-
-	rule_size_2g =
-		QDF_ARRAY_SIZE(regdomains_2g[default_country_2g].reg_rule_id);
-	rule_size_5g =
-		QDF_ARRAY_SIZE(regdomains_5g[default_country_5g].reg_rule_id);
+	rule_size_2g = QDF_ARRAY_SIZE(regdomains_2g[dmn_id_2g].reg_rule_id);
+	rule_size_5g = QDF_ARRAY_SIZE(regdomains_5g[dmn_id_5g].reg_rule_id);
 
 	if (((rule_size_2g + rule_size_5g) >=
-			regdomains_2g[default_country_2g].num_reg_rules +
-		    regdomains_5g[default_country_5g].num_reg_rules)) {
+		    regdomains_2g[dmn_id_2g].num_reg_rules +
+		    regdomains_5g[dmn_id_5g].num_reg_rules)) {
 
-		reg_info->dfs_region =
-		    regdomains_5g[default_country_5g].dfs_region;
+		reg_info->dfs_region = regdomains_5g[dmn_id_5g].dfs_region;
 		reg_info->phybitmap = 0;
 		reg_info->max_bw_2g = 40;
 		reg_info->max_bw_5g = 160;
-		reg_info->min_bw_2g = regdomains_2g[default_country_2g].min_bw;
-		reg_info->min_bw_5g = regdomains_5g[default_country_5g].min_bw;
+		reg_info->min_bw_2g = regdomains_2g[dmn_id_2g].min_bw;
+		reg_info->min_bw_5g = regdomains_5g[dmn_id_5g].min_bw;
+
 		reg_info->num_2g_reg_rules =
-		    regdomains_2g[default_country_2g].num_reg_rules;
+			regdomains_2g[dmn_id_2g].num_reg_rules;
 		reg_info->num_5g_reg_rules =
-		    regdomains_5g[default_country_5g].num_reg_rules;
+			regdomains_5g[dmn_id_5g].num_reg_rules;
+
 		reg_info->reg_rules_2g_ptr = (struct cur_reg_rule *)
-		    qdf_mem_malloc((reg_info->num_2g_reg_rules) *
-			    sizeof(struct cur_reg_rule));
+			qdf_mem_malloc((reg_info->num_2g_reg_rules) *
+					sizeof(struct cur_reg_rule));
 		reg_info->reg_rules_5g_ptr = (struct cur_reg_rule *)
-		    qdf_mem_malloc((reg_info->num_5g_reg_rules) *
-			    sizeof(struct cur_reg_rule));
+			qdf_mem_malloc((reg_info->num_5g_reg_rules) *
+					sizeof(struct cur_reg_rule));
 
-		reg_regrules_assign(default_country_2g,
-				default_country_5g, reg_info);
+		reg_regrules_assign(dmn_id_2g, dmn_id_5g, reg_info);
 
 		return QDF_STATUS_SUCCESS;
 	} else if (!(((rule_size_2g + rule_size_5g) >=
-			regdomains_2g[default_country_2g].num_reg_rules +
-			regdomains_5g[default_country_5g].num_reg_rules)))
+			regdomains_2g[dmn_id_2g].num_reg_rules +
+			regdomains_5g[dmn_id_5g].num_reg_rules)))
 		return QDF_STATUS_E_NOMEM;
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -321,15 +291,12 @@ QDF_STATUS reg_get_cur_reginfo(struct cur_regulatory_info *reg_info,
 				reg_info,
 				country_index,
 				regdmn_pair);
-	else {
-		if (regdmn_pair != (uint16_t)(-1))
+	else if (regdmn_pair != (uint16_t)(-1))
 			reg_get_reginfo_form_regdmn_pair(
 					reg_info,
 					regdmn_pair);
-		else
-			reg_get_reginfo_for_default_regdmn_pair(
-					reg_info);
-	}
+	else
+		return QDF_STATUS_E_FAILURE;
 
 	return QDF_STATUS_SUCCESS;
 }

+ 2 - 0
umac/regulatory/core/src/reg_db_parser.h

@@ -49,3 +49,5 @@ QDF_STATUS reg_get_rdpair_from_country_code(uint16_t cc,
 		uint16_t *country_index,
 		uint16_t *regdmn_pair);
 
+QDF_STATUS reg_get_rdpair_from_regdmn_id(uint16_t regdmn_id,
+		uint16_t *regdmn_pair);

+ 69 - 0
umac/regulatory/core/src/reg_services.c

@@ -2016,3 +2016,72 @@ void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc,
 				     NULL, 1, WLAN_REGULATORY_SB_ID);
 
 }
+
+QDF_STATUS reg_program_default_cc(struct wlan_objmgr_psoc *psoc,
+		uint16_t regdmn)
+{
+	struct wlan_regulatory_psoc_priv_obj *soc_reg;
+	struct cur_regulatory_info *reg_info;
+	uint16_t cc = -1;
+	uint16_t country_index = -1, regdmn_pair = -1;
+	QDF_STATUS err;
+
+	soc_reg = (struct wlan_regulatory_psoc_priv_obj *)
+		wlan_objmgr_psoc_get_comp_private_obj(psoc,
+				WLAN_UMAC_COMP_REGULATORY);
+
+	if (NULL == soc_reg) {
+		reg_err("reg soc is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (soc_reg->offload_enabled)
+		return QDF_STATUS_E_FAILURE;
+
+	reg_info = (struct cur_regulatory_info *)qdf_mem_malloc
+		(sizeof(struct cur_regulatory_info));
+	if (reg_info == NULL) {
+		reg_err("reg info is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	reg_info->psoc = psoc;
+
+	if (regdmn == 0) {
+		get_default_country(&regdmn);
+		regdmn |= COUNTRY_ERD_FLAG;
+	}
+
+	if (regdmn & COUNTRY_ERD_FLAG) {
+		cc = regdmn & ~COUNTRY_ERD_FLAG;
+
+		reg_get_rdpair_from_country_code(cc,
+				&country_index,
+				&regdmn_pair);
+
+		err = reg_get_cur_reginfo(reg_info, country_index, regdmn_pair);
+		if (err == QDF_STATUS_E_FAILURE) {
+			reg_err("%s : Unable to set country code\n", __func__);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		soc_reg->ctry_code = cc;
+
+	} else {
+		reg_get_rdpair_from_regdmn_id(regdmn,
+				&regdmn_pair);
+
+		err = reg_get_cur_reginfo(reg_info, country_index, regdmn_pair);
+		if (err == QDF_STATUS_E_FAILURE) {
+			reg_err("%s : Unable to set country code\n", __func__);
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		soc_reg->reg_dmn_pair = regdmn;
+	}
+
+	reg_info->offload_enabled = false;
+	reg_process_master_chan_list(reg_info);
+
+	return QDF_STATUS_SUCCESS;
+}

+ 28 - 0
umac/regulatory/core/src/reg_services.h

@@ -66,6 +66,31 @@
 	 - REG_CH_TO_FREQ(reg_get_chan_enum(curchan))	\
 	 > REG_SBS_SEPARATION_THRESHOLD)
 
+/* EEPROM setting is a country code */
+#define    COUNTRY_ERD_FLAG     0x8000
+
+/**
+ * enum cc_regdmn_flag: Regdomain flags
+ * @INVALID:       Invalid flag
+ * @CC_IS_SET:     Country code is set
+ * @REGDMN_IS_SET: Regdomain ID is set
+ * @ALPHA_IS_SET:  Country ISO is set
+ */
+enum cc_regdmn_flag {
+	INVALID,
+	CC_IS_SET,
+	REGDMN_IS_SET,
+	ALPHA_IS_SET,
+};
+
+struct cc_regdmn_s {
+	union {
+		uint16_t country_code;
+		uint16_t regdmn_id;
+		uint8_t alpha[REG_ALPHA2_LEN + 1];
+	} cc;
+	uint8_t flags;
+};
 
 extern const struct chan_map channel_map[NUM_CHANNELS];
 
@@ -199,4 +224,7 @@ void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc,
 			       struct regulatory_channel *reg_channels,
 			       uint8_t *alpha2,
 			       enum dfs_reg dfs_region);
+
+QDF_STATUS reg_program_default_cc(struct wlan_objmgr_psoc *psoc,
+		uint16_t regdmn);
 #endif

+ 3 - 0
umac/regulatory/dispatcher/inc/wlan_reg_ucfg_api.h

@@ -46,6 +46,9 @@ QDF_STATUS ucfg_reg_unregister_event_handler(uint8_t vdev_id, reg_event_cb cb,
 		void *arg);
 QDF_STATUS ucfg_reg_init_handler(uint8_t pdev_id);
 
+QDF_STATUS ucfg_reg_program_default_cc(struct wlan_objmgr_psoc *psoc,
+		uint16_t regdmn);
+
 /**
  * ucfg_reg_set_config_vars () - Set the config vars in reg component
  * @psoc: psoc ptr

+ 6 - 0
umac/regulatory/dispatcher/src/wlan_reg_ucfg_api.c

@@ -113,3 +113,9 @@ void ucfg_reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc,
 {
 	reg_program_mas_chan_list(psoc, reg_channels, alpha2, dfs_region);
 }
+
+QDF_STATUS ucfg_reg_program_default_cc(struct wlan_objmgr_psoc *psoc,
+		uint16_t regdmn)
+{
+	return reg_program_default_cc(psoc, regdmn);
+}