Jelajahi Sumber

qcacmn: Enable three new 5.9 ghz channels for US

Add new channel bonding pairs as well as frequency
pairs for 40, 80 and 160 MHz with the support of
three new 5.9 GHz channels 169, 173 and 177.
Add new API reg_modify_chan_list_for_5dot9_ghz_channels
to enable/disable these new channels based on
INI value and service bit.

Change-Id: I8598e705ba4047e96e7167661ba70d4236cde251
CRs-Fixed: 2696211
Gururaj Pandurangi 5 tahun lalu
induk
melakukan
b1f6686944

+ 1 - 0
target_if/init_deinit/src/init_event_handler.c

@@ -198,6 +198,7 @@ static int init_deinit_service_ready_event_handler(ol_scn_t scn_handle,
 
 	target_if_reg_set_offloaded_info(psoc);
 	target_if_reg_set_6ghz_info(psoc);
+	target_if_reg_set_5dot9_ghz_info(psoc);
 
 	/* Send num_msdu_desc to DP layer */
 	cdp_soc_set_param(wlan_psoc_get_dp_handle(psoc),

+ 8 - 1
target_if/regulatory/inc/target_if_reg.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
@@ -57,6 +57,13 @@ QDF_STATUS target_if_reg_set_offloaded_info(struct wlan_objmgr_psoc *psoc);
  */
 QDF_STATUS target_if_reg_set_6ghz_info(struct wlan_objmgr_psoc *psoc);
 
+/**
+ * target_if_reg_set_5dot9_ghz_info() - populate 5.9ghz enablement info
+ * @psoc: psoc pointer
+ * Return: Success or Failure
+ */
+QDF_STATUS target_if_reg_set_5dot9_ghz_info(struct wlan_objmgr_psoc *psoc);
+
 /**
  * target_if_regulatory_get_rx_ops() - Get regdb rx ops
  * @psoc: pointer to psoc object

+ 35 - 0
target_if/regulatory/src/target_if_reg.c

@@ -89,6 +89,23 @@ static bool tgt_if_regulatory_is_6ghz_supported(struct wlan_objmgr_psoc *psoc)
 	return wmi_service_enabled(wmi_handle, wmi_service_6ghz_support);
 }
 
+/**
+ * tgt_if_regulatory_is_5dot9_ghz_supported() - Check if 5.9ghz is supported
+ * @psoc: Pointer to psoc
+ *
+ * Return: true if regdb if offloaded, else false
+ */
+static bool
+tgt_if_regulatory_is_5dot9_ghz_supported(struct wlan_objmgr_psoc *psoc)
+{
+	wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+
+	if (!wmi_handle)
+		return false;
+
+	return wmi_service_enabled(wmi_handle, wmi_service_5dot9_ghz_support);
+}
+
 /**
  * tgt_if_regulatory_is_there_serv_ready_extn() - Check for service ready
  * extension
@@ -167,6 +184,24 @@ QDF_STATUS target_if_reg_set_6ghz_info(struct wlan_objmgr_psoc *psoc)
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS target_if_reg_set_5dot9_ghz_info(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_lmac_if_reg_rx_ops *reg_rx_ops;
+
+	reg_rx_ops = target_if_regulatory_get_rx_ops(psoc);
+	if (!reg_rx_ops) {
+		target_if_err("reg_rx_ops is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (reg_rx_ops->reg_set_5dot9_ghz_supported)
+		reg_rx_ops->reg_set_5dot9_ghz_supported(
+			psoc,
+			tgt_if_regulatory_is_5dot9_ghz_supported(psoc));
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * tgt_reg_chan_list_update_handler() - Channel list update handler
  * @handle: scn handle

+ 2 - 0
umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h

@@ -1156,6 +1156,8 @@ struct wlan_lmac_if_reg_rx_ops {
 			bool val);
 	QDF_STATUS (*reg_set_6ghz_supported)(struct wlan_objmgr_psoc *psoc,
 					     bool val);
+	QDF_STATUS (*reg_set_5dot9_ghz_supported)(struct wlan_objmgr_psoc
+						  *psoc, bool val);
 	QDF_STATUS (*get_dfs_region)(struct wlan_objmgr_pdev *pdev,
 			enum dfs_reg *dfs_reg);
 	QDF_STATUS (*reg_ch_avoid_event_handler)(struct wlan_objmgr_psoc *psoc,

+ 3 - 0
umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c

@@ -316,6 +316,9 @@ static void wlan_lmac_if_umac_reg_rx_ops_register(
 	rx_ops->reg_rx_ops.reg_set_6ghz_supported =
 		tgt_reg_set_6ghz_supported;
 
+	rx_ops->reg_rx_ops.reg_set_5dot9_ghz_supported =
+		tgt_reg_set_5dot9_ghz_supported;
+
 	rx_ops->reg_rx_ops.get_dfs_region =
 		wlan_reg_get_dfs_region;
 

+ 60 - 0
umac/regulatory/core/src/reg_build_chan_list.c

@@ -628,6 +628,62 @@ reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev,
 }
 #endif
 
+/**
+ * reg_modify_chan_list_for_5dot9_ghz_channels() - Modify 5.9 GHz channels
+ * in FCC
+ * @pdev: Pointer to pdev object
+ * @chan_list: Current channel list
+ *
+ * This function disables 5.9 GHz channels if service bit
+ * wmi_service_5dot9_ghz_support is not set or the reg db is not offloaded
+ * to FW. If service bit is set but ini enable_5dot9_ghz_chan_in_master_mode
+ * is not set, it converts these channels to passive in FCC regulatory domain.
+ * If both service bit and ini are set, the channels remain enabled.
+ */
+static void
+reg_modify_chan_list_for_5dot9_ghz_channels(struct wlan_objmgr_pdev *pdev,
+					    struct regulatory_channel
+					    *chan_list)
+{
+	enum channel_enum chan_enum;
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+
+	if (!reg_is_fcc_regdmn(pdev))
+		return;
+
+	if (!reg_is_5dot9_ghz_supported(psoc) ||
+	    !reg_is_regdb_offloaded(psoc)) {
+		for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
+			if (reg_is_5dot9_ghz_freq(pdev, chan_list[chan_enum].
+						  center_freq)) {
+				chan_list[chan_enum].state =
+					CHANNEL_STATE_DISABLE;
+				chan_list[chan_enum].chan_flags =
+					REGULATORY_CHAN_DISABLED;
+			}
+		}
+		return;
+	}
+
+	if (reg_is_5dot9_ghz_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_5dot9_ghz_freq(pdev,
+					  chan_list[chan_enum].center_freq)) {
+			chan_list[chan_enum].state =
+				CHANNEL_STATE_DFS;
+			chan_list[chan_enum].chan_flags |=
+				REGULATORY_CHAN_NO_IR;
+		}
+	}
+}
+
 #ifdef DISABLE_UNII_SHARED_BANDS
 /**
  * reg_is_reg_unii_band_1_set() - Check UNII bitmap
@@ -790,6 +846,10 @@ void reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj
 
 	reg_modify_chan_list_for_srd_channels(pdev_priv_obj->pdev_ptr,
 					      pdev_priv_obj->cur_chan_list);
+
+	reg_modify_chan_list_for_5dot9_ghz_channels(pdev_priv_obj->pdev_ptr,
+						    pdev_priv_obj->
+						    cur_chan_list);
 }
 
 void reg_reset_reg_rules(struct reg_rule_info *reg_rules)

+ 15 - 0
umac/regulatory/core/src/reg_db.c

@@ -1686,6 +1686,21 @@ bool reg_etsi13_regdmn(uint8_t reg_dmn)
 	return reg_dmn == ETSI13;
 }
 
+#ifdef CONFIG_BAND_6GHZ
+bool reg_fcc_regdmn(uint8_t reg_dmn)
+{
+	return ((reg_dmn == FCC3) ||
+		(reg_dmn == FCC8) ||
+		(reg_dmn == FCC15) ||
+		(reg_dmn == FCC16));
+}
+#else
+bool reg_fcc_regdmn(uint8_t reg_dmn)
+{
+	return (reg_dmn == FCC3 || reg_dmn == FCC8);
+}
+#endif
+
 bool reg_en302_502_regdmn(uint16_t regdmn)
 {
 	return ((regdmn == ETSI11_WORLD) ||

+ 8 - 0
umac/regulatory/core/src/reg_db.h

@@ -107,6 +107,14 @@ QDF_STATUS reg_get_default_country(uint16_t *default_country);
  */
 bool reg_etsi13_regdmn(uint8_t reg_dmn);
 
+/**
+ * reg_fcc_regdmn () - Checks if the reg domain is FCC3/FCC8/FCC15/FCC16 or not
+ * @reg_dmn: reg domain
+ *
+ * Return: true or false
+ */
+bool reg_fcc_regdmn(uint8_t reg_dmn);
+
 /**
  * reg_en302_502_regdmn() - Check if the reg domain is en302_502 applicable.
  * @reg_dmn: Regulatory domain pair ID.

+ 2 - 0
umac/regulatory/core/src/reg_priv_objs.c

@@ -93,6 +93,8 @@ QDF_STATUS wlan_regulatory_psoc_obj_created_notification(
 	soc_reg_obj->restart_beaconing = CH_AVOID_RULE_RESTART;
 	soc_reg_obj->enable_srd_chan_in_master_mode = true;
 	soc_reg_obj->enable_11d_in_world_mode = false;
+	soc_reg_obj->five_dot_nine_ghz_supported = false;
+	soc_reg_obj->enable_5dot9_ghz_chan_in_master_mode = false;
 
 	for (i = 0; i < MAX_STA_VDEV_CNT; i++)
 		soc_reg_obj->vdev_ids_11d[i] = INVALID_VDEV_ID;

+ 6 - 0
umac/regulatory/core/src/reg_priv_objs.h

@@ -95,12 +95,17 @@ struct chan_change_cbk_entry {
  *	bit position value
  * @ignore_fw_reg_offload_ind: Ignore FW reg offload indication
  * @six_ghz_supported: whether 6ghz is supported
+ * @five_dot_nine_ghz_supported: whether 5.9ghz is supported
+ *	(service bit WMI_SERVICE_5_DOT_9GHZ_SUPPORT)
+ * @enable_5dot9_ghz_chan_in_master_mode: 5.9 GHz channel support in
+ *	master mode (ini fcc_5dot9_ghz_chan_in_master_mode)
  */
 struct wlan_regulatory_psoc_priv_obj {
 	struct mas_chan_params mas_chan_params[PSOC_MAX_PHY_REG_CAP];
 	bool chan_list_recvd[PSOC_MAX_PHY_REG_CAP];
 	bool offload_enabled;
 	bool six_ghz_supported;
+	bool five_dot_nine_ghz_supported;
 	uint8_t num_phy;
 	char cur_country[REG_ALPHA2_LEN + 1];
 	char def_country[REG_ALPHA2_LEN + 1];
@@ -143,6 +148,7 @@ struct wlan_regulatory_psoc_priv_obj {
 	bool force_ssc_disable_indoor_channel;
 	bool enable_srd_chan_in_master_mode;
 	bool enable_11d_in_world_mode;
+	bool enable_5dot9_ghz_chan_in_master_mode;
 	qdf_spinlock_t cbk_list_lock;
 };
 

+ 116 - 10
umac/regulatory/core/src/reg_services_common.c

@@ -51,7 +51,8 @@ static const struct bonded_channel bonded_chan_40mhz_list[] = {
 	{140, 144},
 	{149, 153},
 	{157, 161},
-	{165, 169}
+	{165, 169},
+	{173, 177}
 };
 
 static const struct bonded_channel bonded_chan_80mhz_list[] = {
@@ -60,12 +61,14 @@ static const struct bonded_channel bonded_chan_80mhz_list[] = {
 	{100, 112},
 	{116, 128},
 	{132, 144},
-	{149, 161}
+	{149, 161},
+	{165, 177}
 };
 
 static const struct bonded_channel bonded_chan_160mhz_list[] = {
 	{36, 64},
-	{100, 128}
+	{100, 128},
+	{149, 177}
 };
 #endif /* CONFIG_CHAN_NUM_API */
 
@@ -85,6 +88,7 @@ static const struct bonded_channel_freq bonded_chan_40mhz_list_freq[] = {
 	{5745, 5765},
 	{5785, 5805},
 	{5825, 5845},
+	{5865, 5885},
 #ifdef CONFIG_BAND_6GHZ
 	{5955, 5975},
 	{5995, 6015},
@@ -126,6 +130,7 @@ static const struct bonded_channel_freq bonded_chan_80mhz_list_freq[] = {
 	{5580, 5640},
 	{5660, 5720},
 	{5745, 5805},
+	{5825, 5885},
 #ifdef CONFIG_BAND_6GHZ
 	{5955, 6015},
 	{6035, 6095},
@@ -148,6 +153,7 @@ static const struct bonded_channel_freq bonded_chan_80mhz_list_freq[] = {
 static const struct bonded_channel_freq bonded_chan_160mhz_list_freq[] = {
 	{5180, 5320},
 	{5500, 5640},
+	{5745, 5885},
 #ifdef CONFIG_BAND_6GHZ
 	{5955, 6095},
 	{6115, 6255},
@@ -259,20 +265,15 @@ const struct chan_map channel_map_us[NUM_CHANNELS] = {
 	[CHAN_ENUM_5850] = {5850, 170, 2, 160},
 	[CHAN_ENUM_5855] = {5855, 171, 2, 160},
 	[CHAN_ENUM_5860] = {5860, 172, 2, 160},
-#else
-	[CHAN_ENUM_5850] = {5850, INVALID_CHANNEL_NUM, 2, 160},
-	[CHAN_ENUM_5855] = {5855, INVALID_CHANNEL_NUM, 2, 160},
-	[CHAN_ENUM_5860] = {5860, INVALID_CHANNEL_NUM, 2, 160},
 #endif
 	[CHAN_ENUM_5865] = {5865, 173, 2, 160},
 #ifdef WLAN_FEATURE_DSRC
 	[CHAN_ENUM_5870] = {5870, 174, 2, 160},
-#else
-	[CHAN_ENUM_5870] = {5870, INVALID_CHANNEL_NUM, 2, 160},
-#endif
 	[CHAN_ENUM_5875] = {5875, 175, 2, 160},
 	[CHAN_ENUM_5880] = {5880, 176, 2, 160},
+#endif
 	[CHAN_ENUM_5885] = {5885, 177, 2, 160},
+#ifdef WLAN_FEATURE_DSRC
 	[CHAN_ENUM_5890] = {5890, 178, 2, 160},
 	[CHAN_ENUM_5895] = {5895, 179, 2, 160},
 	[CHAN_ENUM_5900] = {5900, 180, 2, 160},
@@ -280,6 +281,7 @@ const struct chan_map channel_map_us[NUM_CHANNELS] = {
 	[CHAN_ENUM_5910] = {5910, 182, 2, 160},
 	[CHAN_ENUM_5915] = {5915, 183, 2, 160},
 	[CHAN_ENUM_5920] = {5920, 184, 2, 160},
+#endif /* WLAN_FEATURE_DSRC */
 #ifdef CONFIG_BAND_6GHZ
 	[CHAN_ENUM_5935] = {5935, 2, 2, 20},
 	[CHAN_ENUM_5955] = {5955, 1, 2, 160},
@@ -429,14 +431,19 @@ const struct chan_map channel_map_eu[NUM_CHANNELS] = {
 	[CHAN_ENUM_5805] = {5805, 161, 2, 160},
 	[CHAN_ENUM_5825] = {5825, 165, 2, 160},
 	[CHAN_ENUM_5845] = {5845, 169, 2, 160},
+#ifdef WLAN_FEATURE_DSRC
 	[CHAN_ENUM_5850] = {5850, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5855] = {5855, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5860] = {5860, INVALID_CHANNEL_NUM, 2, 160},
+#endif
 	[CHAN_ENUM_5865] = {5865, 173, 2, 160},
+#ifdef WLAN_FEATURE_DSRC
 	[CHAN_ENUM_5870] = {5870, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5875] = {5875, 175, 2, 160},
 	[CHAN_ENUM_5880] = {5880, 176, 2, 160},
+#endif
 	[CHAN_ENUM_5885] = {5885, 177, 2, 160},
+#ifdef WLAN_FEATURE_DSRC
 	[CHAN_ENUM_5890] = {5890, 178, 2, 160},
 	[CHAN_ENUM_5895] = {5895, 179, 2, 160},
 	[CHAN_ENUM_5900] = {5900, 180, 2, 160},
@@ -444,6 +451,7 @@ const struct chan_map channel_map_eu[NUM_CHANNELS] = {
 	[CHAN_ENUM_5910] = {5910, 182, 2, 160},
 	[CHAN_ENUM_5915] = {5915, 183, 2, 160},
 	[CHAN_ENUM_5920] = {5920, 184, 2, 160},
+#endif /* WLAN_FEATURE_DSRC */
 #ifdef CONFIG_BAND_6GHZ
 	[CHAN_ENUM_5935] = {5935, 2, 2, 20},
 	[CHAN_ENUM_5955] = {5955, 1, 2, 160},
@@ -593,14 +601,19 @@ const struct chan_map channel_map_jp[NUM_CHANNELS] = {
 	[CHAN_ENUM_5805] = {5805, 161, 2, 160},
 	[CHAN_ENUM_5825] = {5825, 165, 2, 160},
 	[CHAN_ENUM_5845] = {5845, 169, 2, 160},
+#ifdef WLAN_FEATURE_DSRC
 	[CHAN_ENUM_5850] = {5850, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5855] = {5855, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5860] = {5860, INVALID_CHANNEL_NUM, 2, 160},
+#endif
 	[CHAN_ENUM_5865] = {5865, INVALID_CHANNEL_NUM, 2, 160},
+#ifdef WLAN_FEATURE_DSRC
 	[CHAN_ENUM_5870] = {5870, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5875] = {5875, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5880] = {5880, INVALID_CHANNEL_NUM, 2, 160},
+#endif
 	[CHAN_ENUM_5885] = {5885, INVALID_CHANNEL_NUM, 2, 160},
+#ifdef WLAN_FEATURE_DSRC
 	[CHAN_ENUM_5890] = {5890, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5895] = {5895, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5900] = {5900, INVALID_CHANNEL_NUM, 2, 160},
@@ -608,6 +621,7 @@ const struct chan_map channel_map_jp[NUM_CHANNELS] = {
 	[CHAN_ENUM_5910] = {5910, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5915] = {5915, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5920] = {5920, INVALID_CHANNEL_NUM, 2, 160},
+#endif /* WLAN_FEATURE_DSRC */
 #ifdef CONFIG_BAND_6GHZ
 	[CHAN_ENUM_5935] = {5935, 2, 2, 20},
 	[CHAN_ENUM_5955] = {5955, 1, 2, 160},
@@ -757,14 +771,19 @@ const struct chan_map channel_map_global[NUM_CHANNELS] = {
 	[CHAN_ENUM_5805] = {5805, 161, 2, 160},
 	[CHAN_ENUM_5825] = {5825, 165, 2, 160},
 	[CHAN_ENUM_5845] = {5845, 169, 2, 160},
+#ifdef WLAN_FEATURE_DSRC
 	[CHAN_ENUM_5850] = {5850, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5855] = {5855, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5860] = {5860, INVALID_CHANNEL_NUM, 2, 160},
+#endif
 	[CHAN_ENUM_5865] = {5865, 173, 2, 160},
+#ifdef WLAN_FEATURE_DSRC
 	[CHAN_ENUM_5870] = {5870, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5875] = {5875, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5880] = {5880, INVALID_CHANNEL_NUM, 2, 160},
+#endif
 	[CHAN_ENUM_5885] = {5885, INVALID_CHANNEL_NUM, 2, 160},
+#ifdef WLAN_FEATURE_DSRC
 	[CHAN_ENUM_5890] = {5890, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5895] = {5895, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5900] = {5900, INVALID_CHANNEL_NUM, 2, 160},
@@ -772,6 +791,7 @@ const struct chan_map channel_map_global[NUM_CHANNELS] = {
 	[CHAN_ENUM_5910] = {5910, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5915] = {5915, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5920] = {5920, INVALID_CHANNEL_NUM, 2, 160},
+#endif /* WLAN_FEATURE_DSRC */
 #ifdef CONFIG_BAND_6GHZ
 	[CHAN_ENUM_5935] = {5935, 2, 2, 20},
 	[CHAN_ENUM_5955] = {5955, 1, 2, 160},
@@ -921,14 +941,19 @@ const struct chan_map channel_map_china[NUM_CHANNELS] = {
 	[CHAN_ENUM_5805] = {5805, 161, 2, 160},
 	[CHAN_ENUM_5825] = {5825, 165, 2, 160},
 	[CHAN_ENUM_5845] = {5845, 169, 2, 160},
+#ifdef WLAN_FEATURE_DSRC
 	[CHAN_ENUM_5850] = {5850, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5855] = {5855, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5860] = {5860, INVALID_CHANNEL_NUM, 2, 160},
+#endif
 	[CHAN_ENUM_5865] = {5865, INVALID_CHANNEL_NUM, 2, 160},
+#ifdef WLAN_FEATURE_DSRC
 	[CHAN_ENUM_5870] = {5870, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5875] = {5875, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5880] = {5880, INVALID_CHANNEL_NUM, 2, 160},
+#endif
 	[CHAN_ENUM_5885] = {5885, INVALID_CHANNEL_NUM, 2, 160},
+#ifdef WLAN_FEATURE_DSRC
 	[CHAN_ENUM_5890] = {5890, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5895] = {5895, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5900] = {5900, INVALID_CHANNEL_NUM, 2, 160},
@@ -936,6 +961,7 @@ const struct chan_map channel_map_china[NUM_CHANNELS] = {
 	[CHAN_ENUM_5910] = {5910, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5915] = {5915, INVALID_CHANNEL_NUM, 2, 160},
 	[CHAN_ENUM_5920] = {5920, INVALID_CHANNEL_NUM, 2, 160},
+#endif /* WLAN_FEATURE_DSRC */
 #ifdef CONFIG_BAND_6GHZ
 	[CHAN_ENUM_5935] = {5935, 2, 2, 20},
 	[CHAN_ENUM_5955] = {5955, 1, 2, 160},
@@ -3799,6 +3825,23 @@ QDF_STATUS reg_set_6ghz_supported(struct wlan_objmgr_psoc *psoc, bool val)
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS
+reg_set_5dot9_ghz_supported(struct wlan_objmgr_psoc *psoc, bool val)
+{
+	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
+
+	psoc_priv_obj = reg_get_psoc_obj(psoc);
+
+	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
+		reg_err("psoc reg component is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	psoc_priv_obj->five_dot_nine_ghz_supported = val;
+
+	return QDF_STATUS_SUCCESS;
+}
+
 bool reg_is_6ghz_op_class(struct wlan_objmgr_pdev *pdev, uint8_t op_class)
 {
 	return ((op_class >= MIN_6GHZ_OPER_CLASS) &&
@@ -3821,6 +3864,69 @@ bool reg_is_6ghz_supported(struct wlan_objmgr_psoc *psoc)
 }
 #endif
 
+bool reg_is_5dot9_ghz_supported(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
+
+	psoc_priv_obj = reg_get_psoc_obj(psoc);
+
+	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
+		reg_err("psoc reg component is NULL");
+		return  false;
+	}
+
+	return psoc_priv_obj->five_dot_nine_ghz_supported;
+}
+
+bool reg_is_fcc_regdmn(struct wlan_objmgr_pdev *pdev)
+{
+	struct cur_regdmn_info cur_reg_dmn;
+	QDF_STATUS status;
+
+	status = reg_get_curr_regdomain(pdev, &cur_reg_dmn);
+	if (status != QDF_STATUS_SUCCESS) {
+		reg_err_rl("Failed to get reg domain");
+		return false;
+	}
+
+	return reg_fcc_regdmn(cur_reg_dmn.dmn_id_5g);
+}
+
+bool reg_is_5dot9_ghz_freq(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq)
+{
+	struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
+
+	pdev_priv_obj = reg_get_pdev_obj(pdev);
+
+	if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
+		reg_err("reg pdev priv obj is NULL");
+		return false;
+	}
+
+	return (freq >= channel_map_us[MIN_5DOT9_CHANNEL].center_freq &&
+		freq <= channel_map_us[MAX_5DOT9_CHANNEL].center_freq);
+}
+
+bool reg_is_5dot9_ghz_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
+
+	if (!pdev) {
+		reg_alert("pdev is NULL");
+		return true;
+	}
+	psoc = wlan_pdev_get_psoc(pdev);
+
+	psoc_priv_obj = reg_get_psoc_obj(psoc);
+	if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
+		reg_alert("psoc reg component is NULL");
+		return true;
+	}
+
+	return psoc_priv_obj->enable_5dot9_ghz_chan_in_master_mode;
+}
+
 #ifdef DISABLE_UNII_SHARED_BANDS
 QDF_STATUS
 reg_get_unii_5g_bitmap(struct wlan_objmgr_pdev *pdev, uint8_t *bitmap)

+ 44 - 0
umac/regulatory/core/src/reg_services_common.h

@@ -1093,6 +1093,15 @@ bool reg_get_ignore_fw_reg_offload_ind(struct wlan_objmgr_psoc *psoc);
 QDF_STATUS reg_set_6ghz_supported(struct wlan_objmgr_psoc *psoc,
 				  bool val);
 
+/**
+ * reg_set_5dot9_ghz_supported() - Set if 5.9ghz is supported
+ *
+ * @psoc: Pointer to psoc
+ * @val: value
+ */
+QDF_STATUS reg_set_5dot9_ghz_supported(struct wlan_objmgr_psoc *psoc,
+				       bool val);
+
 /**
  * reg_is_6ghz_op_class() - Check whether 6ghz oper class
  *
@@ -1111,6 +1120,41 @@ bool reg_is_6ghz_op_class(struct wlan_objmgr_pdev *pdev,
 bool reg_is_6ghz_supported(struct wlan_objmgr_psoc *psoc);
 #endif
 
+/**
+ * reg_is_5dot9_ghz_supported() - Whether 5.9ghz is supported
+ *
+ * @psoc: pointer to psoc
+ */
+bool reg_is_5dot9_ghz_supported(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * reg_is_fcc_regdmn () - Checks if the current reg domain is FCC3/FCC8/FCC15/
+ * FCC16 or not
+ * @pdev: pdev ptr
+ *
+ * Return: true or false
+ */
+bool reg_is_fcc_regdmn(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * reg_is_5dot9_ghz_freq () - Checks if the frequency is 5.9 GHz freq or not
+ * @freq: frequency
+ * @pdev: pdev ptr
+ *
+ * Return: true or false
+ */
+bool reg_is_5dot9_ghz_freq(struct wlan_objmgr_pdev *pdev, qdf_freq_t freq);
+
+/**
+ * reg_is_5dot9_ghz_chan_allowed_master_mode () - Checks if 5.9 GHz channels
+ * are allowed in master mode or not.
+ *
+ * @pdev: pdev ptr
+ *
+ * Return: true or false
+ */
+bool reg_is_5dot9_ghz_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev);
+
 /**
  * reg_get_unii_5g_bitmap() - get unii_5g_bitmap value
  * @pdev: pdev pointer

+ 2 - 0
umac/regulatory/core/src/reg_utils.c

@@ -794,6 +794,8 @@ QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc,
 		config_vars.enable_srd_chan_in_master_mode;
 	psoc_priv_obj->enable_11d_in_world_mode =
 		config_vars.enable_11d_in_world_mode;
+	psoc_priv_obj->enable_5dot9_ghz_chan_in_master_mode =
+		config_vars.enable_5dot9_ghz_chan_in_master_mode;
 
 	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID);
 	if (QDF_IS_STATUS_ERROR(status)) {

+ 19 - 1
umac/regulatory/dispatcher/inc/reg_services_public_struct.h

@@ -357,15 +357,19 @@ enum channel_enum {
 	CHAN_ENUM_5805,
 	CHAN_ENUM_5825,
 	CHAN_ENUM_5845,
-
+#ifdef WLAN_FEATURE_DSRC
 	CHAN_ENUM_5850,
 	CHAN_ENUM_5855,
 	CHAN_ENUM_5860,
+#endif
 	CHAN_ENUM_5865,
+#ifdef WLAN_FEATURE_DSRC
 	CHAN_ENUM_5870,
 	CHAN_ENUM_5875,
 	CHAN_ENUM_5880,
+#endif
 	CHAN_ENUM_5885,
+#ifdef WLAN_FEATURE_DSRC
 	CHAN_ENUM_5890,
 	CHAN_ENUM_5895,
 	CHAN_ENUM_5900,
@@ -373,6 +377,7 @@ enum channel_enum {
 	CHAN_ENUM_5910,
 	CHAN_ENUM_5915,
 	CHAN_ENUM_5920,
+#endif /* WLAN_FEATURE_DSRC */
 #ifdef CONFIG_BAND_6GHZ
 	CHAN_ENUM_5935,
 	CHAN_ENUM_5955,
@@ -449,6 +454,11 @@ enum channel_enum {
 	MAX_49GHZ_CHANNEL = CHAN_ENUM_5080,
 	NUM_49GHZ_CHANNELS = (MAX_49GHZ_CHANNEL - MIN_49GHZ_CHANNEL + 1),
 
+	MIN_5GHZ_CHANNEL = CHAN_ENUM_5180,
+	MAX_5GHZ_CHANNEL = CHAN_ENUM_5885,
+	NUM_5GHZ_CHANNELS = (MAX_5GHZ_CHANNEL - MIN_5GHZ_CHANNEL + 1),
+
+#ifdef WLAN_FEATURE_DSRC
 	MIN_5GHZ_CHANNEL = CHAN_ENUM_5180,
 	MAX_5GHZ_CHANNEL = CHAN_ENUM_5920,
 	NUM_5GHZ_CHANNELS = (MAX_5GHZ_CHANNEL - MIN_5GHZ_CHANNEL + 1),
@@ -456,6 +466,11 @@ enum channel_enum {
 	MIN_DSRC_CHANNEL = CHAN_ENUM_5850,
 	MAX_DSRC_CHANNEL = CHAN_ENUM_5920,
 	NUM_DSRC_CHANNELS = (MAX_DSRC_CHANNEL - MIN_DSRC_CHANNEL + 1),
+#endif
+
+	MIN_5DOT9_CHANNEL = CHAN_ENUM_5845,
+	MAX_5DOT9_CHANNEL = CHAN_ENUM_5885,
+	NUM_5DOT9_CHANNELS = (MAX_5DOT9_CHANNEL - MIN_5DOT9_CHANNEL + 1),
 
 	INVALID_CHANNEL = 0xBAD,
 
@@ -963,6 +978,8 @@ enum restart_beaconing_on_ch_avoid_rule {
  * away from active LTE channels
  * @enable_srd_chan_in_master_mode: SRD channel support in master mode
  * @enable_11d_in_world_mode: enable 11d in world mode
+ * @enable_5dot9_ghz_chan_in_master_mode: 5.9 GHz channel support in
+ * master mode
  */
 struct reg_config_vars {
 	uint32_t enable_11d_support;
@@ -975,6 +992,7 @@ struct reg_config_vars {
 	enum restart_beaconing_on_ch_avoid_rule restart_beaconing;
 	bool enable_srd_chan_in_master_mode;
 	bool enable_11d_in_world_mode;
+	bool enable_5dot9_ghz_chan_in_master_mode;
 };
 
 /**

+ 9 - 1
umac/regulatory/dispatcher/inc/wlan_reg_tgt_api.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
@@ -81,4 +81,12 @@ bool tgt_reg_ignore_fw_reg_offload_ind(struct wlan_objmgr_psoc *psoc);
 QDF_STATUS tgt_reg_set_6ghz_supported(struct wlan_objmgr_psoc *psoc,
 				      bool val);
 
+/**
+ * tgt_reg_set_5dot9_ghz_supported() - Whether 5.9ghz is supported by the chip
+ * @psoc: Pointer to psoc
+ * @val: value
+ */
+QDF_STATUS tgt_reg_set_5dot9_ghz_supported(struct wlan_objmgr_psoc *psoc,
+					   bool val);
+
 #endif

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

@@ -95,3 +95,9 @@ QDF_STATUS tgt_reg_set_6ghz_supported(struct wlan_objmgr_psoc *psoc,
 {
 	return reg_set_6ghz_supported(psoc, val);
 }
+
+QDF_STATUS tgt_reg_set_5dot9_ghz_supported(struct wlan_objmgr_psoc *psoc,
+					   bool val)
+{
+	return reg_set_5dot9_ghz_supported(psoc, val);
+}

+ 1 - 0
wmi/inc/wmi_unified_param.h

@@ -5202,6 +5202,7 @@ typedef enum {
 	wmi_service_dual_sta_roam_support,
 	wmi_service_peer_create_conf,
 	wmi_service_configure_roam_trigger_param_support,
+	wmi_service_5dot9_ghz_support,
 	wmi_services_max,
 } wmi_conv_service_ids;
 #define WMI_SERVICE_UNAVAILABLE 0xFFFF

+ 2 - 0
wmi/src/wmi_unified_tlv.c

@@ -15262,6 +15262,8 @@ static void populate_tlv_service(uint32_t *wmi_service)
 			WMI_SERVICE_PEER_CREATE_CONF;
 	wmi_service[wmi_service_configure_roam_trigger_param_support] =
 			WMI_SERVICE_CONFIGURE_ROAM_TRIGGER_PARAM_SUPPORT;
+	wmi_service[wmi_service_5dot9_ghz_support] =
+			WMI_SERVICE_5_DOT_9GHZ_SUPPORT;
 }
 
 /**