Преглед изворни кода

qcacmn: Regulatory component public APIs

Add regulatory component public APIs

Change-Id: Idc8afaf1952e831a3a9917aeef796cb7dc466152
CRs-Fixed: 2002892
Amar Singhal пре 8 година
родитељ
комит
7b56f8d67a

+ 2 - 0
umac/regulatory/core/inc/reg_priv.h

@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2017 The Linux Foundation. All rights reserved.
  *
+ *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * above copyright notice and this permission notice appear in all
@@ -45,6 +46,7 @@ struct wlan_regulatory_psoc_priv_obj {
 	enum channel_enum nol_list[NUM_CHANNELS];
 	char default_country[REG_ALPHA2_LEN + 1];
 	char current_country[REG_ALPHA2_LEN + 1];
+	struct wlan_objmgr_psoc psoc_ptr;
 	uint32_t phybitmap;
 	enum dfs_region dfs_region;
 	char country_11d[REG_ALPHA2_LEN + 1];

+ 39 - 13
umac/regulatory/core/inc/reg_services.h

@@ -23,9 +23,6 @@
  * service functions
  */
 
-#include "qdf_types.h"
-#include "qdf_trace.h"
-
 enum channel_state {
 	CHANNEL_STATE_DISABLE,
 	CHANNEL_STATE_PASSIVE,
@@ -76,6 +73,7 @@ struct chan_map {
 	uint32_t chan_num;
 };
 
+
 enum channel_enum {
 	CHAN_ENUM_1 = 1,
 	CHAN_ENUM_2,
@@ -160,6 +158,22 @@ enum band_info {
 	band_5g_149_165 = 0x20
 };
 
+/**
+ * struct bonded_channel
+ * @start_ch: start channel
+ * @end_ch: end channel
+ */
+struct bonded_channel {
+	uint16_t start_ch;
+	uint16_t end_ch;
+};
+
+enum ht_sec_ch_offset {
+	NO_SEC_CH = 0,
+	LOW_PRIMARY_CH = 1,
+	HIGH_PRIMARY_CH = 3,
+};
+
 struct reg_ini_vars {
 	uint32_t enable_11d_support;
 	uint32_t userspace_ctry_priority;
@@ -174,19 +188,31 @@ struct set_band_req {
 };
 
 struct country_info {
-	uint8_t country_code[3];
+	uint8_t country_code[REG_ALPHA2_LEN + 1];
 };
 
 struct reg_country_update {
-	uint8_t country_code[3];
+	uint8_t country_code[REG_ALPHA2_LEN + 1];
 };
 
 
-QDF_STATUS reg_get_channel_list_with_power(struct regulatory_channel *ch_list);
-void reg_read_default_country(uint8_t *country);
-enum channel_state reg_get_channel_state(uint8_t ch);
-enum channel_state reg_get_5g_bonded_channel_state(uint8_t ch, uint8_t bw);
-enum channel_state reg_get_2g_bonded_channel_state(uint8_t ch, uint8_t bw);
-void reg_set_channel_params(uint8_t ch, struct ch_params *ch_params);
-void reg_get_dfs_region(enum dfs_region *dfs_reg);
-bool reg_is_dfs_ch(uint8_t ch);
+QDF_STATUS reg_get_channel_list_with_power(struct wlan_objmgr_psoc *psoc,
+					   struct channel_power *ch_list,
+					   uint8_t *num_chan);
+
+void reg_read_default_country(struct wlan_objmgr_psoc *psoc,
+		uint8_t *country);
+enum channel_state reg_get_channel_state(struct wlan_objmgr_psoc *psoc,
+		uint32_t ch);
+enum channel_state reg_get_5g_bonded_channel_state(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t ch, enum phy_ch_width bw);
+enum channel_state reg_get_2g_bonded_channel_state(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t oper_ch, uint8_t sec_ch,
+		enum phy_ch_width bw);
+void reg_set_channel_params(struct wlan_objmgr_psoc *psoc,
+		uint8_t ch, struct ch_params *ch_params);
+void reg_get_dfs_region(struct wlan_objmgr_psoc *psoc,
+		enum dfs_region *dfs_reg);
+bool reg_is_dfs_ch(struct wlan_objmgr_psoc *psoc, uint8_t ch);

+ 3 - 0
umac/regulatory/core/src/reg_main.c

@@ -54,12 +54,15 @@ static QDF_STATUS wlan_regulatory_psoc_obj_created_notification(
 
 	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;
+
 	status = wlan_objmgr_psoc_component_obj_attach(psoc,
 			WLAN_UMAC_COMP_REGULATORY, soc_reg_obj,
 			QDF_STATUS_SUCCESS);

+ 478 - 32
umac/regulatory/core/src/reg_services.c

@@ -30,52 +30,301 @@
  * This file defines regulatory component service functions
  */
 
-
+#include "qdf_status.h"
 #include "qdf_types.h"
-#include "qdf_trace.h"
+#include "wlan_objmgr_cmn.h"
+#include "wlan_objmgr_global_obj.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "scheduler_api.h"
 #include "reg_db.h"
 #include "reg_services.h"
+#include "reg_priv.h"
+
+const struct bonded_channel bonded_chan_40mhz_list[] = {
+	{36, 40},
+	{44, 48},
+	{52, 56},
+	{60, 64},
+	{100, 104},
+	{108, 112},
+	{116, 120},
+	{124, 128},
+	{132, 136},
+	{140, 144},
+	{149, 153},
+	{157, 161}
+};
+
+const struct bonded_channel bonded_chan_80mhz_list[] = {
+	{36, 48},
+	{52, 64},
+	{100, 112},
+	{116, 128},
+	{132, 144},
+	{149, 161}
+};
+
+const struct bonded_channel bonded_chan_160mhz_list[] = {
+	{36, 64},
+	{100, 128}
+};
+
+const enum phy_ch_width get_next_lower_bw[] = {
+	[CH_WIDTH_80P80MHZ] = CH_WIDTH_160MHZ,
+	[CH_WIDTH_160MHZ] = CH_WIDTH_80MHZ,
+	[CH_WIDTH_80MHZ] = CH_WIDTH_40MHZ,
+	[CH_WIDTH_40MHZ] = CH_WIDTH_20MHZ,
+	[CH_WIDTH_20MHZ] = CH_WIDTH_10MHZ,
+	[CH_WIDTH_10MHZ] = CH_WIDTH_5MHZ,
+	[CH_WIDTH_5MHZ] = CH_WIDTH_INVALID
+};
+
+const struct chan_map channel_map[NUM_CHANNELS] = {
+	[CHAN_ENUM_1] = {2412, 1},
+	[CHAN_ENUM_2] = {2417, 2},
+	[CHAN_ENUM_3] = {2422, 3},
+	[CHAN_ENUM_4] = {2427, 4},
+	[CHAN_ENUM_5] = {2432, 5},
+	[CHAN_ENUM_6] = {2437, 6},
+	[CHAN_ENUM_7] = {2442, 7},
+	[CHAN_ENUM_8] = {2447, 8},
+	[CHAN_ENUM_9] = {2452, 9},
+	[CHAN_ENUM_10] = {2457, 10},
+	[CHAN_ENUM_11] = {2462, 11},
+	[CHAN_ENUM_12] = {2467, 12},
+	[CHAN_ENUM_13] = {2472, 13},
+	[CHAN_ENUM_14] = {2484, 14},
+
+	[CHAN_ENUM_36] = {5180, 36},
+	[CHAN_ENUM_40] = {5200, 40},
+	[CHAN_ENUM_44] = {5220, 44},
+	[CHAN_ENUM_48] = {5240, 48},
+	[CHAN_ENUM_52] = {5260, 52},
+	[CHAN_ENUM_56] = {5280, 56},
+	[CHAN_ENUM_60] = {5300, 60},
+	[CHAN_ENUM_64] = {5320, 64},
+
+	[CHAN_ENUM_100] = {5500, 100},
+	[CHAN_ENUM_104] = {5520, 104},
+	[CHAN_ENUM_108] = {5540, 108},
+	[CHAN_ENUM_112] = {5560, 112},
+	[CHAN_ENUM_116] = {5580, 116},
+	[CHAN_ENUM_120] = {5600, 120},
+	[CHAN_ENUM_124] = {5620, 124},
+	[CHAN_ENUM_128] = {5640, 128},
+	[CHAN_ENUM_132] = {5660, 132},
+	[CHAN_ENUM_136] = {5680, 136},
+	[CHAN_ENUM_140] = {5700, 140},
+	[CHAN_ENUM_144] = {5720, 144},
+
+	[CHAN_ENUM_149] = {5745, 149},
+	[CHAN_ENUM_153] = {5765, 153},
+	[CHAN_ENUM_157] = {5785, 157},
+	[CHAN_ENUM_161] = {5805, 161},
+	[CHAN_ENUM_165] = {5825, 165},
+
+	[CHAN_ENUM_183] = {4915, 183},
+	[CHAN_ENUM_184] = {4920, 184},
+	[CHAN_ENUM_185] = {4925, 185},
+	[CHAN_ENUM_187] = {4935, 187},
+	[CHAN_ENUM_188] = {4940, 188},
+	[CHAN_ENUM_189] = {4945, 189},
+	[CHAN_ENUM_192] = {4960, 192},
+	[CHAN_ENUM_196] = {4980, 196},
+};
+
 /**
  * reg_get_channel_list_with_power() - Provides the channel list with power
  * @ch_list: pointer to the channel list.
  *
  * Return: QDF_STATUS
  */
-QDF_STATUS reg_get_channel_list_with_power(struct regulatory_channel *ch_list)
+QDF_STATUS reg_get_channel_list_with_power(struct wlan_objmgr_psoc *psoc,
+					   struct channel_power *ch_list,
+					   uint8_t *num_chan)
 {
-	/*
-	 * Update the channel list with channel information with power.
-	 */
+	int i, count;
+	struct regulatory_channel *reg_channels;
+	struct wlan_regulatory_psoc_priv_obj *soc_reg;
+
+	if (!num_chan || !ch_list) {
+		reg_err("chan_list or num_ch is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+	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("soc_reg is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* set the current channel list */
+	reg_channels = &soc_reg->current_ch_list[0];
+	for (i = 0, count = 0; i < NUM_CHANNELS; i++) {
+		if (reg_channels[i].state) {
+			ch_list[count].chan_num =
+				channel_map[i].chan_num;
+			ch_list[count++].tx_power =
+				reg_channels[i].tx_power;
+		}
+	}
+	*num_chan = count;
+
 	return QDF_STATUS_SUCCESS;
 }
-
 /**
  * reg_read_default_country() - Read the default country for the regdomain
  * @country: pointer to the country code.
  *
  * Return: QDF_STATUS
  */
-void reg_read_default_country(uint8_t *country)
+void reg_read_default_country(struct wlan_objmgr_psoc *psoc, uint8_t *country)
 {
-	/*
-	 * Get the default country information
-	 */
+	struct wlan_regulatory_psoc_priv_obj *soc_reg;
+
+	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("soc_reg is NULL");
+		return;
+	}
+
+	if (NULL == country) {
+		reg_err("country is NULL");
+		return;
+	}
+
+	qdf_mem_copy(country, soc_reg->default_country,
+			sizeof(soc_reg->default_country));
 }
 
+static enum channel_enum get_reg_ch_idx(uint32_t chan_num)
+{
+	uint32_t indx;
+
+	for (indx = 0; indx < NUM_CHANNELS; indx++)
+		if (channel_map[indx].chan_num == chan_num)
+			return indx;
+
+	QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
+		  "invalid channel number %d", chan_num);
+
+	return INVALID_CHANNEL;
+}
 /**
  * reg_get_channel_state() - Get channel state from regulatory
  * @ch: channel number.
  *
  * Return: channel state
  */
-enum channel_state reg_get_channel_state(uint8_t ch)
+enum channel_state reg_get_channel_state(struct wlan_objmgr_psoc *psoc,
+		uint32_t ch)
 {
-	/*
-	 * Get channel state from regulatory
-	 */
-	return CHANNEL_STATE_ENABLE;
+	enum channel_enum ch_idx;
+	struct wlan_regulatory_psoc_priv_obj *soc_reg;
+
+	ch_idx = get_reg_ch_idx(ch);
+
+	if (INVALID_CHANNEL == ch_idx)
+		return CHANNEL_STATE_INVALID;
+
+	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("soc_reg is NULL");
+		return CHANNEL_STATE_INVALID;
+	}
+
+	return soc_reg->current_ch_list[ch_idx].state;
 }
 
+/**
+ * reg_get_5g_bonded_chan_array() - get ptr to bonded channel
+ * @oper_ch: operating channel number
+ * @bonded_chan_ar: bonded channel array
+ * @bonded_chan_ptr_ptr: bonded channel ptr ptr
+ *
+ * Return: bonded channel state
+ */
+static enum channel_state reg_get_5g_bonded_chan_array(
+		struct wlan_objmgr_psoc *psoc,
+		uint32_t oper_chan,
+		const struct bonded_channel bonded_chan_ar[],
+		uint16_t array_size,
+		const struct bonded_channel **bonded_chan_ptr_ptr)
+{
+	int i;
+	uint8_t chan_num;
+	const struct bonded_channel *bonded_chan_ptr = NULL;
+	enum channel_state chan_state = CHANNEL_STATE_INVALID;
+	enum channel_state temp_chan_state;
+
+	for (i = 0; i < array_size; i++) {
+		if ((oper_chan >= bonded_chan_ar[i].start_ch) &&
+		    (oper_chan <= bonded_chan_ar[i].end_ch)) {
+			bonded_chan_ptr =  &(bonded_chan_ar[i]);
+			break;
+		}
+	}
+
+	if (NULL == bonded_chan_ptr)
+		return chan_state;
+
+	*bonded_chan_ptr_ptr = bonded_chan_ptr;
+	chan_num =  bonded_chan_ptr->start_ch;
+	while (chan_num <= bonded_chan_ptr->end_ch) {
+		temp_chan_state = reg_get_channel_state(psoc, chan_num);
+		if (temp_chan_state < chan_state)
+			chan_state = temp_chan_state;
+		chan_num = chan_num + 4;
+	}
+
+	return chan_state;
+}
+
+/**
+ * reg_get_5g_bonded_channel() - get the 5G bonded channel state
+ * @chan_num: channel number
+ * @ch_width: channel width
+ * @bonded_chan_ptr_ptr: bonded channel ptr ptr
+ *
+ * Return: channel state
+ */
+static enum channel_state reg_get_5g_bonded_channel(
+		struct wlan_objmgr_psoc *psoc, uint32_t chan_num,
+		enum phy_ch_width ch_width,
+		const struct bonded_channel **bonded_chan_ptr_ptr)
+{
+	if (CH_WIDTH_80P80MHZ == ch_width)
+		return reg_get_5g_bonded_chan_array(psoc, chan_num,
+				bonded_chan_80mhz_list,
+				QDF_ARRAY_SIZE(bonded_chan_80mhz_list),
+				bonded_chan_ptr_ptr);
+	else if (CH_WIDTH_160MHZ == ch_width)
+		return reg_get_5g_bonded_chan_array(psoc, chan_num,
+				bonded_chan_160mhz_list,
+				QDF_ARRAY_SIZE(bonded_chan_160mhz_list),
+				bonded_chan_ptr_ptr);
+	else if (CH_WIDTH_80MHZ == ch_width)
+		return reg_get_5g_bonded_chan_array(psoc, chan_num,
+				bonded_chan_80mhz_list,
+				QDF_ARRAY_SIZE(bonded_chan_80mhz_list),
+				bonded_chan_ptr_ptr);
+	else if (CH_WIDTH_40MHZ == ch_width)
+		return reg_get_5g_bonded_chan_array(psoc, chan_num,
+				bonded_chan_40mhz_list,
+				QDF_ARRAY_SIZE(bonded_chan_40mhz_list),
+				bonded_chan_ptr_ptr);
+	else
+		return reg_get_channel_state(psoc, chan_num);
+}
 /**
  * reg_get_5g_bonded_channel_state() - Get channel state for 5G bonded channel
  * @ch: channel number.
@@ -83,12 +332,64 @@ enum channel_state reg_get_channel_state(uint8_t ch)
  *
  * Return: channel state
  */
-enum channel_state reg_get_5g_bonded_channel_state(uint8_t ch, uint8_t bw)
+enum channel_state reg_get_5g_bonded_channel_state(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t ch, enum phy_ch_width bw)
 {
-	/*
-	 * Get channel state from regulatory
-	 */
-	return CHANNEL_STATE_ENABLE;
+	enum channel_enum ch_indx;
+	enum channel_state chan_state;
+	struct regulatory_channel *reg_channels;
+	struct wlan_regulatory_psoc_priv_obj *soc_reg;
+	bool bw_enabled = false;
+	const struct bonded_channel *bonded_chan_ptr = NULL;
+
+	if (CH_WIDTH_80P80MHZ < bw) {
+		reg_err("bw passed is not good");
+		return CHANNEL_STATE_INVALID;
+	}
+
+	chan_state = reg_get_5g_bonded_channel(psoc, ch, bw, &bonded_chan_ptr);
+
+	if ((CHANNEL_STATE_INVALID == chan_state) ||
+			(CHANNEL_STATE_DISABLE == chan_state))
+		return chan_state;
+
+	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("soc_reg is NULL");
+		return CHANNEL_STATE_INVALID;
+	}
+
+	reg_channels = &soc_reg->current_ch_list[0];
+	ch_indx = get_reg_ch_idx(ch);
+	if (CH_WIDTH_5MHZ == bw)
+		bw_enabled = true;
+	else if (CH_WIDTH_10MHZ == bw)
+		bw_enabled = !(reg_channels[ch_indx].chan_flags &
+				REGULATORY_CHAN_NO_10MHZ);
+	else if (CH_WIDTH_20MHZ == bw)
+		bw_enabled = !(reg_channels[ch_indx].chan_flags &
+				REGULATORY_CHAN_NO_20MHZ);
+	else if (CH_WIDTH_40MHZ == bw)
+		bw_enabled = !((reg_channels[ch_indx].chan_flags &
+			REGULATORY_CHAN_NO_HT40) == REGULATORY_CHAN_NO_HT40);
+	else if (CH_WIDTH_80MHZ == bw)
+		bw_enabled = !(reg_channels[ch_indx].chan_flags &
+				REGULATORY_CHAN_NO_80MHZ);
+	else if (CH_WIDTH_160MHZ == bw)
+		bw_enabled = !(reg_channels[ch_indx].chan_flags &
+				REGULATORY_CHAN_NO_160MHZ);
+	else if (CH_WIDTH_80P80MHZ == bw)
+		bw_enabled = !(reg_channels[ch_indx].chan_flags &
+				REGULATORY_CHAN_NO_80MHZ);
+
+	if (bw_enabled)
+		return chan_state;
+	else
+		return CHANNEL_STATE_DISABLE;
 }
 
 /**
@@ -98,14 +399,81 @@ enum channel_state reg_get_5g_bonded_channel_state(uint8_t ch, uint8_t bw)
  *
  * Return: channel state
  */
-enum channel_state reg_get_2g_bonded_channel_state(uint8_t ch, uint8_t bw)
+enum channel_state reg_get_2g_bonded_channel_state(
+		struct wlan_objmgr_psoc *psoc,
+		uint8_t oper_ch, uint8_t sec_ch,
+		enum phy_ch_width bw)
 {
-	/*
-	 * Get channel state from regulatory
-	 */
+	enum channel_enum chan_idx;
+	enum channel_state chan_state;
+	struct regulatory_channel *reg_channels;
+	struct wlan_regulatory_psoc_priv_obj *soc_reg;
+	bool bw_enabled = false;
+	enum channel_state chan_state2 = CHANNEL_STATE_INVALID;
+
+	if (CH_WIDTH_40MHZ < bw)
+		return CHANNEL_STATE_INVALID;
+
+	if (CH_WIDTH_40MHZ == bw) {
+		if ((sec_ch + 4 != oper_ch) &&
+		    (oper_ch + 4 != sec_ch))
+			return CHANNEL_STATE_INVALID;
+		chan_state2 = reg_get_channel_state(psoc, sec_ch);
+		if (CHANNEL_STATE_INVALID == chan_state2)
+			return chan_state2;
+	}
+
+	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("soc_reg is NULL");
+		return CHANNEL_STATE_INVALID;
+	}
+
+	reg_channels = &soc_reg->current_ch_list[0];
+
+	chan_state = reg_get_channel_state(psoc, oper_ch);
+	if (chan_state2 < chan_state)
+		chan_state = chan_state2;
+
+	if ((CHANNEL_STATE_INVALID == chan_state) ||
+	    (CHANNEL_STATE_DISABLE == chan_state))
+		return chan_state;
+
+	chan_idx = get_reg_ch_idx(oper_ch);
+	if (CH_WIDTH_5MHZ == bw)
+		bw_enabled = true;
+	else if (CH_WIDTH_10MHZ == bw)
+		bw_enabled = !(reg_channels[chan_idx].chan_flags &
+			       REGULATORY_CHAN_NO_10MHZ);
+	else if (CH_WIDTH_20MHZ == bw)
+		bw_enabled = !(reg_channels[chan_idx].chan_flags &
+			       REGULATORY_CHAN_NO_20MHZ);
+	else if (CH_WIDTH_40MHZ == bw)
+		bw_enabled = !((reg_channels[chan_idx].chan_flags &
+				REGULATORY_CHAN_NO_HT40) ==
+				REGULATORY_CHAN_NO_HT40);
+
+	if (bw_enabled)
+		return chan_state;
+	else
+		return CHANNEL_STATE_DISABLE;
+
 	return CHANNEL_STATE_ENABLE;
 }
 
+static enum channel_state reg_combine_channel_states(
+	enum channel_state chan_state1,
+	enum channel_state chan_state2)
+{
+	if ((CHANNEL_STATE_INVALID == chan_state1) ||
+	    (CHANNEL_STATE_INVALID == chan_state2))
+		return CHANNEL_STATE_INVALID;
+	else
+		return min(chan_state1, chan_state2);
+}
 /**
  * reg_set_channel_params () - Sets channel parameteres for given bandwidth
  * @ch: channel number.
@@ -113,12 +481,88 @@ enum channel_state reg_get_2g_bonded_channel_state(uint8_t ch, uint8_t bw)
  *
  * Return: None
  */
-void reg_set_channel_params(uint8_t ch, struct ch_params *ch_params)
+void reg_set_channel_params(struct wlan_objmgr_psoc *psoc,
+		uint8_t ch, struct ch_params *ch_params)
 {
 	/*
 	 * Set channel parameters like center frequency for a bonded channel
 	 * state. Also return the maximum bandwidth supported by the channel.
 	 */
+	enum phy_ch_width next_lower_bw;
+	enum channel_state chan_state = CHANNEL_STATE_ENABLE;
+	enum channel_state chan_state2 = CHANNEL_STATE_ENABLE;
+	const struct bonded_channel *bonded_chan_ptr = NULL;
+	const struct bonded_channel *bonded_chan_ptr2 = NULL;
+
+	if (NULL == ch_params) {
+		reg_err("ch_params is NULL");
+		return;
+	}
+
+	if (CH_WIDTH_MAX <= ch_params->ch_width) {
+		if (0 != ch_params->center_freq_seg1)
+			ch_params->ch_width = CH_WIDTH_80P80MHZ;
+		else
+			ch_params->ch_width = CH_WIDTH_160MHZ;
+	}
+	next_lower_bw = ch_params->ch_width;
+	while (ch_params->ch_width != CH_WIDTH_INVALID) {
+		ch_params->ch_width = next_lower_bw;
+		next_lower_bw = get_next_lower_bw[ch_params->ch_width];
+		bonded_chan_ptr = NULL;
+		bonded_chan_ptr2 = NULL;
+		chan_state = reg_get_5g_bonded_channel(psoc, ch,
+				ch_params->ch_width, &bonded_chan_ptr);
+
+		chan_state = reg_get_5g_bonded_channel_state(psoc, ch,
+				ch_params->ch_width);
+
+		if (CH_WIDTH_80P80MHZ == ch_params->ch_width) {
+			chan_state2 = reg_get_5g_bonded_channel_state(psoc,
+				ch_params->center_freq_seg1 - 2,
+				CH_WIDTH_80MHZ);
+
+			chan_state = reg_combine_channel_states(chan_state,
+					chan_state2);
+		}
+
+		if ((CHANNEL_STATE_ENABLE != chan_state) &&
+		    (CHANNEL_STATE_DFS != chan_state))
+			continue;
+		if (CH_WIDTH_20MHZ >= ch_params->ch_width) {
+			ch_params->sec_ch_offset = NO_SEC_CH;
+			ch_params->center_freq_seg0 = ch;
+			break;
+		} else if (CH_WIDTH_40MHZ <= ch_params->ch_width) {
+			reg_get_5g_bonded_chan_array(psoc, ch,
+					bonded_chan_40mhz_list,
+					QDF_ARRAY_SIZE(bonded_chan_40mhz_list),
+					&bonded_chan_ptr2);
+			if (!bonded_chan_ptr || !bonded_chan_ptr2)
+				continue;
+			if (ch == bonded_chan_ptr2->start_ch)
+				ch_params->sec_ch_offset = LOW_PRIMARY_CH;
+			else
+				ch_params->sec_ch_offset = HIGH_PRIMARY_CH;
+
+			ch_params->center_freq_seg0 =
+				(bonded_chan_ptr->start_ch +
+				 bonded_chan_ptr->end_ch)/2;
+			break;
+		}
+	}
+	if (CH_WIDTH_160MHZ == ch_params->ch_width) {
+		ch_params->center_freq_seg1 = ch_params->center_freq_seg0;
+		chan_state = reg_get_5g_bonded_channel(psoc, ch,
+				CH_WIDTH_80MHZ, &bonded_chan_ptr);
+		if (bonded_chan_ptr)
+			ch_params->center_freq_seg0 =
+				(bonded_chan_ptr->start_ch +
+				 bonded_chan_ptr->end_ch)/2;
+	}
+	reg_info("ch %d ch_wd %d freq0 %d freq1 %d", ch,
+			ch_params->ch_width, ch_params->center_freq_seg0,
+			ch_params->center_freq_seg1);
 }
 
 /**
@@ -127,7 +571,8 @@ void reg_set_channel_params(uint8_t ch, struct ch_params *ch_params)
  *
  * Return: None
  */
-void reg_get_dfs_region(enum dfs_region *dfs_reg)
+void reg_get_dfs_region(struct wlan_objmgr_psoc *psoc,
+		enum dfs_region *dfs_reg)
 {
 	/*
 	 * Get the current dfs region
@@ -140,10 +585,11 @@ void reg_get_dfs_region(enum dfs_region *dfs_reg)
  *
  * Return: true or false
  */
-bool reg_is_dfs_ch(uint8_t ch)
+bool reg_is_dfs_ch(struct wlan_objmgr_psoc *psoc, uint8_t ch)
 {
-	/*
-	 * Get the current dfs region
-	 */
-	return false;
+	enum channel_state ch_state;
+
+	ch_state = reg_get_channel_state(psoc, ch);
+
+	return ch_state == CHANNEL_STATE_DFS;
 }

+ 18 - 11
umac/regulatory/dispatcher/inc/wlan_reg_services_api.h

@@ -29,8 +29,9 @@
  *
  * Return: QDF_STATUS
  */
-QDF_STATUS wlan_reg_get_channel_list_with_power(
-		struct regulatory_channel *ch_list);
+QDF_STATUS wlan_reg_get_channel_list_with_power(struct wlan_objmgr_psoc *psoc,
+						struct channel_power *ch_list,
+						uint8_t *num_chan);
 
 /**
  * wlan_reg_read_default_country() - Read the default country for the regdomain
@@ -38,7 +39,8 @@ QDF_STATUS wlan_reg_get_channel_list_with_power(
  *
  * Return: None
  */
-void wlan_reg_read_default_country(uint8_t *country);
+void wlan_reg_read_default_country(struct wlan_objmgr_psoc *psoc,
+		uint8_t *country);
 
 /**
  * wlan_reg_get_channel_state() - Get channel state from regulatory
@@ -46,7 +48,8 @@ void wlan_reg_read_default_country(uint8_t *country);
  *
  * Return: channel state
  */
-enum channel_state wlan_reg_get_channel_state(uint8_t ch);
+enum channel_state wlan_reg_get_channel_state(struct wlan_objmgr_psoc *psoc,
+		uint32_t ch);
 
 /**
  * wlan_reg_get_5g_bonded_channel_state() - Get 5G bonded channel state
@@ -55,8 +58,9 @@ enum channel_state wlan_reg_get_channel_state(uint8_t ch);
  *
  * Return: channel state
  */
-enum channel_state wlan_reg_get_5g_bonded_channel_state(uint8_t ch,
-		uint8_t bw);
+enum channel_state wlan_reg_get_5g_bonded_channel_state(
+		struct wlan_objmgr_psoc *psoc, uint8_t ch,
+		enum phy_ch_width bw);
 
 /**
  * wlan_reg_get_2g_bonded_channel_state() - Get 2G bonded channel state
@@ -65,8 +69,9 @@ enum channel_state wlan_reg_get_5g_bonded_channel_state(uint8_t ch,
  *
  * Return: channel state
  */
-enum channel_state wlan_reg_get_2g_bonded_channel_state(uint8_t ch,
-		uint8_t bw);
+enum channel_state wlan_reg_get_2g_bonded_channel_state(
+		struct wlan_objmgr_psoc *psoc, uint8_t ch, uint8_t sec_ch,
+		enum phy_ch_width bw);
 
 /**
  * wlan_reg_set_channel_params () - Sets channel parameteres for given bandwidth
@@ -75,7 +80,8 @@ enum channel_state wlan_reg_get_2g_bonded_channel_state(uint8_t ch,
  *
  * Return: None
  */
-void wlan_reg_set_channel_params(uint8_t ch, struct ch_params *ch_params);
+void wlan_reg_set_channel_params(struct wlan_objmgr_psoc *psoc, uint8_t ch,
+		struct ch_params *ch_params);
 
 /**
  * wlan_reg_get_dfs_region () - Get the current dfs region
@@ -83,7 +89,8 @@ void wlan_reg_set_channel_params(uint8_t ch, struct ch_params *ch_params);
  *
  * Return: None
  */
-void wlan_reg_get_dfs_region(enum dfs_region *dfs_reg);
+void wlan_reg_get_dfs_region(struct wlan_objmgr_psoc *psoc,
+		enum dfs_region *dfs_reg);
 
 /**
  * wlan_reg_is_dfs_ch () - Checks the channel state for DFS
@@ -91,4 +98,4 @@ void wlan_reg_get_dfs_region(enum dfs_region *dfs_reg);
  *
  * Return: true or false
  */
-bool wlan_reg_is_dfs_ch(uint8_t ch);
+bool wlan_reg_is_dfs_ch(struct wlan_objmgr_psoc *psoc, uint8_t ch);

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

@@ -2,7 +2,6 @@
  * Copyright (c) 2017 The Linux Foundation. All rights reserved.
  *
  *
- *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * above copyright notice and this permission notice appear in all

+ 32 - 20
umac/regulatory/dispatcher/src/wlan_reg_services_api.c

@@ -23,7 +23,12 @@
  */
 
 #include "qdf_types.h"
-#include "qdf_trace.h"
+#include "qdf_status.h"
+#include "wlan_objmgr_cmn.h"
+#include "wlan_objmgr_global_obj.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "scheduler_api.h"
 #include "reg_db.h"
 #include "reg_services.h"
 #include "wlan_reg_services_api.h"
@@ -34,13 +39,14 @@
  *
  * Return: QDF_STATUS
  */
-QDF_STATUS wlan_reg_get_channel_list_with_power(
-		struct regulatory_channel *ch_list)
+QDF_STATUS wlan_reg_get_channel_list_with_power(struct wlan_objmgr_psoc *psoc,
+						struct channel_power *ch_list,
+						uint8_t *num_chan)
 {
 	/*
 	 * Update the channel list with channel information with power.
 	 */
-	return reg_get_channel_list_with_power(ch_list);
+	return reg_get_channel_list_with_power(psoc, ch_list, num_chan);
 }
 
 /**
@@ -49,12 +55,13 @@ QDF_STATUS wlan_reg_get_channel_list_with_power(
  *
  * Return: None
  */
-void wlan_reg_read_default_country(uint8_t *country)
+void wlan_reg_read_default_country(struct wlan_objmgr_psoc *psoc,
+		uint8_t *country)
 {
 	/*
 	 * Get the default country information
 	 */
-	reg_read_default_country(country);
+	reg_read_default_country(psoc, country);
 }
 
 /**
@@ -63,12 +70,13 @@ void wlan_reg_read_default_country(uint8_t *country)
  *
  * Return: channel state
  */
-enum channel_state wlan_reg_get_channel_state(uint8_t ch)
+enum channel_state wlan_reg_get_channel_state(struct wlan_objmgr_psoc *psoc,
+		uint32_t ch)
 {
 	/*
 	 * Get channel state from regulatory
 	 */
-	return reg_get_channel_state(ch);
+	return reg_get_channel_state(psoc, ch);
 }
 
 /**
@@ -78,13 +86,14 @@ enum channel_state wlan_reg_get_channel_state(uint8_t ch)
  *
  * Return: channel state
  */
-enum channel_state wlan_reg_get_5g_bonded_channel_state(uint8_t ch,
-		uint8_t bw)
+enum channel_state wlan_reg_get_5g_bonded_channel_state(
+		struct wlan_objmgr_psoc *psoc, uint8_t ch,
+		enum phy_ch_width bw)
 {
 	/*
 	 * Get channel state from regulatory
 	 */
-	return reg_get_5g_bonded_channel_state(ch, bw);
+	return reg_get_5g_bonded_channel_state(psoc, ch, bw);
 }
 
 /**
@@ -94,13 +103,14 @@ enum channel_state wlan_reg_get_5g_bonded_channel_state(uint8_t ch,
  *
  * Return: channel state
  */
-enum channel_state wlan_reg_get_2g_bonded_channel_state(uint8_t ch,
-		uint8_t bw)
+enum channel_state wlan_reg_get_2g_bonded_channel_state(
+		struct wlan_objmgr_psoc *psoc, uint8_t ch, uint8_t sec_ch,
+		enum phy_ch_width bw)
 {
 	/*
 	 * Get channel state from regulatory
 	 */
-	return reg_get_2g_bonded_channel_state(ch, bw);
+	return reg_get_2g_bonded_channel_state(psoc, ch, sec_ch, bw);
 }
 
 /**
@@ -110,13 +120,14 @@ enum channel_state wlan_reg_get_2g_bonded_channel_state(uint8_t ch,
  *
  * Return: None
  */
-void wlan_reg_set_channel_params(uint8_t ch, struct ch_params *ch_params)
+void wlan_reg_set_channel_params(struct wlan_objmgr_psoc *psoc, uint8_t ch,
+		struct ch_params *ch_params)
 {
 	/*
 	 * Set channel parameters like center frequency for a bonded channel
 	 * state. Also return the maximum bandwidth supported by the channel.
 	 */
-	reg_set_channel_params(ch, ch_params);
+	reg_set_channel_params(psoc, ch, ch_params);
 }
 
 /**
@@ -125,12 +136,13 @@ void wlan_reg_set_channel_params(uint8_t ch, struct ch_params *ch_params)
  *
  * Return: None
  */
-void wlan_reg_get_dfs_region(enum dfs_region *dfs_reg)
+void wlan_reg_get_dfs_region(struct wlan_objmgr_psoc *psoc,
+		enum dfs_region *dfs_reg)
 {
 	/*
 	 * Get the current dfs region
 	 */
-	reg_get_dfs_region(dfs_reg);
+	reg_get_dfs_region(psoc, dfs_reg);
 }
 
 /**
@@ -139,10 +151,10 @@ void wlan_reg_get_dfs_region(enum dfs_region *dfs_reg)
  *
  * Return: true or false
  */
-bool wlan_reg_is_dfs_ch(uint8_t ch)
+bool wlan_reg_is_dfs_ch(struct wlan_objmgr_psoc *psoc, uint8_t ch)
 {
 	/*
 	 * Get the current dfs region
 	 */
-	return reg_is_dfs_ch(ch);
+	return reg_is_dfs_ch(psoc, ch);
 }

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

@@ -22,6 +22,13 @@
  * @brief contains regulatory user config interface definations
  */
 
+#include "qdf_types.h"
+#include "qdf_status.h"
+#include "wlan_objmgr_cmn.h"
+#include "wlan_objmgr_global_obj.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "scheduler_api.h"
 #include "reg_db.h"
 #include "reg_services.h"
 #include "wlan_reg_ucfg_api.h"