qcacmn: Regulatory component registration

Register the regulatory component with obj mgr. Regulatory
component only needs to listen to psoc level messages.

Change-Id: I3d060d66cb7bac2912afb1301ef1960f8bd9c0ef
CRs-Fixed: 2002892
diff --git a/qdf/inc/qdf_types.h b/qdf/inc/qdf_types.h
index a616126..4128968 100644
--- a/qdf/inc/qdf_types.h
+++ b/qdf/inc/qdf_types.h
@@ -289,6 +289,7 @@
  * @QDF_MODULE_ID_P2P: P2P module ID
  * @QDF_MODULE_ID_POLICY_MGR: Policy Manager module ID
  * @QDF_MODULE_ID_CONFIG: CONFIG module ID
+ * @QDF_MODULE_ID_REGULATORY    : REGULATORY module ID
  * @QDF_MODULE_ID_ANY: anything
  * @QDF_MODULE_ID_MAX: Max place holder module ID
  */
@@ -373,6 +374,7 @@
 	QDF_MODULE_ID_P2P,
 	QDF_MODULE_ID_POLICY_MGR,
 	QDF_MODULE_ID_CONFIG,
+	QDF_MODULE_ID_REGULATORY,
 	QDF_MODULE_ID_ANY,
 	QDF_MODULE_ID_MAX,
 } QDF_MODULE_ID;
diff --git a/umac/cmn_services/inc/wlan_cmn.h b/umac/cmn_services/inc/wlan_cmn.h
index 9d022c3..4fb14b9 100644
--- a/umac/cmn_services/inc/wlan_cmn.h
+++ b/umac/cmn_services/inc/wlan_cmn.h
@@ -92,6 +92,7 @@
 /**
  * enum wlan_umac_comp_id - UMAC component id
  * @WLAN_UMAC_COMP_MLME:     MLME
+ * @WLAN_UMAC_COMP_REGULATORY: REGULATORY
  * @WLAN_UMAC_COMP_MGMT_TXRX:   MGMT Tx/Rx
  * @WLAN_UMAC_COMP_SERIALIZATION: Serialization
  * @WLAN_UMAC_COMP_SCAN: SCAN - as scan module uses services provided by
@@ -121,6 +122,7 @@
 	WLAN_UMAC_COMP_WIFI_POS       = 8,
 	WLAN_UMAC_COMP_TDLS           = 9,
 	WLAN_UMAC_COMP_ATF            = 10,
+	WLAN_UMAC_COMP_REGULATORY     = 11,
 	WLAN_UMAC_COMP_ID_MAX,
 };
 
diff --git a/umac/regulatory/core/inc/reg_main.h b/umac/regulatory/core/inc/reg_main.h
index 4c497c9..0652b50 100644
--- a/umac/regulatory/core/inc/reg_main.h
+++ b/umac/regulatory/core/inc/reg_main.h
@@ -23,18 +23,5 @@
  * 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"
-
-
-/**
- * reg_init() - Regulatory component initialization
- * @psoc: pointer to psoc object
- *
- * Return: QDF_STATUS
- */
-QDF_STATUS reg_init(struct wlan_objmgr_psoc *psoc);
+QDF_STATUS wlan_regulatory_init(void);
+QDF_STATUS wlan_regulatory_deinit(void);
diff --git a/umac/regulatory/core/inc/reg_priv.h b/umac/regulatory/core/inc/reg_priv.h
new file mode 100644
index 0000000..f57128d
--- /dev/null
+++ b/umac/regulatory/core/inc/reg_priv.h
@@ -0,0 +1,58 @@
+/*
+ * 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
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: reg_priv.h
+ * This file contains regulatory component private data structures.
+ */
+
+#define reg_log(level, args...) \
+	QDF_TRACE(QDF_MODULE_ID_REGULATORY, level, ## args)
+#define reg_logfl(level, format, args...) reg_log(level, FL(format), ## args)
+
+#define reg_alert(format, args...) \
+		reg_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args)
+#define reg_err(format, args...) \
+		reg_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args)
+#define reg_warn(format, args...) \
+		reg_logfl(QDF_TRACE_LEVEL_WARN, format, ## args)
+#define reg_notice(format, args...) \
+		reg_logfl(QDF_TRACE_LEVEL_INFO, format, ## args)
+#define reg_info(format, args...) \
+		reg_logfl(QDF_TRACE_LEVEL_INFO_HIGH, format, ## args)
+#define reg_debug(format, args...) \
+		reg_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args)
+
+struct wlan_regulatory_psoc_priv_obj {
+	struct regulatory_channel master_ch_list[NUM_CHANNELS];
+	struct regulatory_channel current_ch_list[NUM_CHANNELS];
+	bool offload_enabled;
+	enum channel_enum nol_list[NUM_CHANNELS];
+	char default_country[REG_ALPHA2_LEN + 1];
+	char current_country[REG_ALPHA2_LEN + 1];
+	uint32_t phybitmap;
+	enum dfs_region dfs_region;
+	char country_11d[REG_ALPHA2_LEN + 1];
+	bool dfs_disable;
+	bool set_fcc_channel;
+	enum band_info band_capability;
+	bool indoor_ch_enabled;
+	bool enable_11d_supp_original;
+	bool enable_11d_supp_current;
+	bool userspace_country_priority;
+};
diff --git a/umac/regulatory/core/inc/reg_services.h b/umac/regulatory/core/inc/reg_services.h
index 16fa08b..dcb4d64 100644
--- a/umac/regulatory/core/inc/reg_services.h
+++ b/umac/regulatory/core/inc/reg_services.h
@@ -25,7 +25,162 @@
 
 #include "qdf_types.h"
 #include "qdf_trace.h"
-#include "wlan_reg_services_api.h"
+
+enum channel_state {
+	CHANNEL_STATE_DISABLE,
+	CHANNEL_STATE_PASSIVE,
+	CHANNEL_STATE_DFS,
+	CHANNEL_STATE_ENABLE,
+	CHANNEL_STATE_INVALID,
+};
+
+enum phy_ch_width {
+	CH_WIDTH_20MHZ = 0,
+	CH_WIDTH_40MHZ,
+	CH_WIDTH_80MHZ,
+	CH_WIDTH_160MHZ,
+	CH_WIDTH_80P80MHZ,
+	CH_WIDTH_5MHZ,
+	CH_WIDTH_10MHZ,
+	CH_WIDTH_INVALID,
+	CH_WIDTH_MAX
+};
+
+/**
+ * struct ch_params
+ * @ch_width: channel width
+ * @sec_ch_offset: secondary channel offset
+ * @center_freq_seg0: center freq for segment 0
+ * @center_freq_seg1: center freq for segment 1
+ */
+struct ch_params {
+	enum phy_ch_width ch_width;
+	uint8_t sec_ch_offset;
+	uint8_t center_freq_seg0;
+	uint8_t center_freq_seg1;
+};
+
+struct regulatory_channel {
+	enum channel_state state;
+	uint32_t chan_flags;
+	uint32_t tx_power;
+};
+
+struct channel_power {
+	uint32_t chan_num;
+	uint32_t tx_power;
+};
+
+struct chan_map {
+	uint32_t center_freq;
+	uint32_t chan_num;
+};
+
+enum channel_enum {
+	CHAN_ENUM_1 = 1,
+	CHAN_ENUM_2,
+	CHAN_ENUM_3,
+	CHAN_ENUM_4,
+	CHAN_ENUM_5,
+	CHAN_ENUM_6,
+	CHAN_ENUM_7,
+	CHAN_ENUM_8,
+	CHAN_ENUM_9,
+	CHAN_ENUM_10,
+	CHAN_ENUM_11,
+	CHAN_ENUM_12,
+	CHAN_ENUM_13,
+	CHAN_ENUM_14,
+
+	CHAN_ENUM_36,
+	CHAN_ENUM_40,
+	CHAN_ENUM_44,
+	CHAN_ENUM_48,
+	CHAN_ENUM_52,
+	CHAN_ENUM_56,
+	CHAN_ENUM_60,
+	CHAN_ENUM_64,
+
+	CHAN_ENUM_100,
+	CHAN_ENUM_104,
+	CHAN_ENUM_108,
+	CHAN_ENUM_112,
+	CHAN_ENUM_116,
+	CHAN_ENUM_120,
+	CHAN_ENUM_124,
+	CHAN_ENUM_128,
+	CHAN_ENUM_132,
+	CHAN_ENUM_136,
+	CHAN_ENUM_140,
+	CHAN_ENUM_144,
+
+	CHAN_ENUM_149,
+	CHAN_ENUM_153,
+	CHAN_ENUM_157,
+	CHAN_ENUM_161,
+	CHAN_ENUM_165,
+
+	CHAN_ENUM_183,
+	CHAN_ENUM_184,
+	CHAN_ENUM_185,
+	CHAN_ENUM_186,
+	CHAN_ENUM_187,
+	CHAN_ENUM_188,
+	CHAN_ENUM_189,
+	CHAN_ENUM_190,
+	CHAN_ENUM_191,
+	CHAN_ENUM_192,
+	CHAN_ENUM_193,
+	CHAN_ENUM_194,
+	CHAN_ENUM_195,
+	CHAN_ENUM_196,
+
+	NUM_CHANNELS,
+
+	MIN_24GHZ_CHANNEL = CHAN_ENUM_1,
+	MAX_24GHZ_CHANNEL = CHAN_ENUM_14,
+	NUM_24GHZ_CHANNELS = (MAX_24GHZ_CHANNEL - MIN_24GHZ_CHANNEL + 1),
+
+	MIN_5GHZ_CHANNEL = CHAN_ENUM_36,
+	MAX_5GHZ_CHANNEL = CHAN_ENUM_184,
+	NUM_5GHZ_CHANNELS = (MAX_5GHZ_CHANNEL - MIN_5GHZ_CHANNEL + 1),
+
+	MIN_49GHZ_CHANNEL = CHAN_ENUM_183,
+	MAX_49GHZ_CHANNEL = CHAN_ENUM_196,
+
+	INVALID_CHANNEL = 0xBAD,
+};
+
+enum band_info {
+	band_2g = 0x1,
+	band_49g = 0x2,
+	band_5g_36_48 = 0x4,
+	band_5g_52_64 = 0x8,
+	band_5g_100_144 = 0x10,
+	band_5g_149_165 = 0x20
+};
+
+struct reg_ini_vars {
+	uint32_t enable_11d_support;
+	uint32_t userspace_ctry_priority;
+	enum band_info band_capability;
+	uint32_t dfs_enable;
+	uint32_t indoor_channel_support;
+};
+
+struct set_band_req {
+	enum band_info band;
+	uint32_t pdev_id;
+};
+
+struct country_info {
+	uint8_t country_code[3];
+};
+
+struct reg_country_update {
+	uint8_t country_code[3];
+};
+
 
 QDF_STATUS reg_get_channel_list_with_power(struct regulatory_channel *ch_list);
 void reg_read_default_country(uint8_t *country);
diff --git a/umac/regulatory/core/src/reg_main.c b/umac/regulatory/core/src/reg_main.c
index 71386d1..095df44 100644
--- a/umac/regulatory/core/src/reg_main.c
+++ b/umac/regulatory/core/src/reg_main.c
@@ -22,26 +22,145 @@
  * This file provides the regulatory component initialization and
  * registration 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"
 #include "reg_main.h"
 
 /**
- * reg_init() - Regulatory component initialization
- * @psoc: pointer to psoc object
+ * wlan_regulatory_psoc_obj_created_notification() - PSOC obj create callback
+ * @psoc: PSOC object
+ * @arg_list: Variable argument list
  *
- * Return: QDF_STATUS
+ * This callback is registered with object manager during initialization to
+ * get notified when the object is created.
+ *
+ * Return: Success or Failure
  */
-QDF_STATUS reg_init(struct wlan_objmgr_psoc *psoc)
+static QDF_STATUS wlan_regulatory_psoc_obj_created_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg_list)
 {
-	/*
-	 * Regulatory component initialization
-	 */
-	struct wlan_objmgr_psoc_regulatory *psoc_reg = NULL;
+	struct wlan_regulatory_psoc_priv_obj *soc_reg_obj;
+	QDF_STATUS status;
 
-	psoc_reg = &psoc->soc_reg;
+	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;
+	}
 
-	psoc_reg->country_code = 0;
-	psoc_reg->reg_dmn = 0;
-	psoc_reg->reg_flags = 0;
-	return 0;
+	soc_reg_obj->offload_enabled  = false;
+	status = wlan_objmgr_psoc_component_obj_attach(psoc,
+			WLAN_UMAC_COMP_REGULATORY, soc_reg_obj,
+			QDF_STATUS_SUCCESS);
+	reg_info("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
+ */
+static 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_objmgr_psoc_get_comp_private_obj(psoc,
+				WLAN_UMAC_COMP_REGULATORY);
+	if (NULL == soc_reg) {
+		reg_err("reg psoc private obj is NULL");
+		return QDF_STATUS_E_FAULT;
+	}
+	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_info("reg psoc obj deleted with status %d", status);
+	qdf_mem_free(soc_reg);
+
+	return status;
+}
+
+/**
+ * wlan_regulatory_init() - init regulatory component
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS wlan_regulatory_init(void)
+{
+	QDF_STATUS status;
+
+	status = wlan_objmgr_register_psoc_create_handler(
+			WLAN_UMAC_COMP_REGULATORY,
+			wlan_regulatory_psoc_obj_created_notification, NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		reg_err("Failed to register reg obj create handler");
+		return status;
+	}
+
+	status = wlan_objmgr_register_psoc_destroy_handler(
+			WLAN_UMAC_COMP_REGULATORY,
+			wlan_regulatory_psoc_obj_destroyed_notification, NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		reg_err("Failed to register reg obj delete handler");
+		wlan_objmgr_unregister_psoc_create_handler(
+				WLAN_UMAC_COMP_REGULATORY,
+				wlan_regulatory_psoc_obj_created_notification,
+				NULL);
+		return status;
+	}
+
+	reg_info("regulatory handlers registered with obj mgr");
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_regulatory_deinit() - deinit regulatory component
+ *
+ * Return: Success or Failure
+ */
+QDF_STATUS wlan_regulatory_deinit(void)
+{
+	QDF_STATUS status;
+
+	status = wlan_objmgr_unregister_psoc_create_handler(
+			WLAN_UMAC_COMP_REGULATORY,
+			wlan_regulatory_psoc_obj_created_notification,
+			NULL);
+	if (status != QDF_STATUS_SUCCESS)
+		reg_err("deregister fail for psoc create notif:%d",
+				status);
+	status = wlan_objmgr_unregister_psoc_destroy_handler(
+			WLAN_UMAC_COMP_REGULATORY,
+			wlan_regulatory_psoc_obj_destroyed_notification,
+			NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		reg_err("deregister fail for psoc delete notif:%d",
+				status);
+		return status;
+	}
+	reg_alert("deregistered callbacks with obj mgr successfully");
+
+	return QDF_STATUS_SUCCESS;
+}
+
diff --git a/umac/regulatory/core/src/reg_services.c b/umac/regulatory/core/src/reg_services.c
index b428f65..140ddec 100644
--- a/umac/regulatory/core/src/reg_services.c
+++ b/umac/regulatory/core/src/reg_services.c
@@ -33,6 +33,7 @@
 
 #include "qdf_types.h"
 #include "qdf_trace.h"
+#include "reg_db.h"
 #include "reg_services.h"
 /**
  * reg_get_channel_list_with_power() - Provides the channel list with power
diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h
index 3b96988..ed612c0 100644
--- a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h
+++ b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h
@@ -23,82 +23,6 @@
  * regulatory component.
  */
 
-#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"
-
-enum channel_state {
-	CHANNEL_STATE_DISABLE,
-	CHANNEL_STATE_PASSIVE,
-	CHANNEL_STATE_DFS,
-	CHANNEL_STATE_ENABLE,
-	CHANNEL_STATE_INVALID,
-};
-
-enum phy_ch_width {
-	CH_WIDTH_20MHZ = 0,
-	CH_WIDTH_40MHZ,
-	CH_WIDTH_80MHZ,
-	CH_WIDTH_160MHZ,
-	CH_WIDTH_80P80MHZ,
-	CH_WIDTH_5MHZ,
-	CH_WIDTH_10MHZ,
-	CH_WIDTH_INVALID,
-	CH_WIDTH_MAX
-};
-
-/**
- * struct ch_params
- * @ch_width: channel width
- * @sec_ch_offset: secondary channel offset
- * @center_freq_seg0: center freq for segment 0
- * @center_freq_seg1: center freq for segment 1
- */
-struct ch_params {
-	enum phy_ch_width ch_width;
-	uint8_t sec_ch_offset;
-	uint8_t center_freq_seg0;
-	uint8_t center_freq_seg1;
-};
-
-struct regulatory_channel {
-	enum channel_state state;
-	uint32_t chan_flags;
-	uint32_t tx_power;
-};
-
-struct channel_power {
-	uint32_t chan_num;
-	uint32_t tx_power;
-};
-
-struct chan_map {
-	uint32_t center_freq;
-	uint32_t chan_num;
-};
-
-/**
- * enum dfs_region - DFS region
- * @DFS_UNINIT_REGION: un-initialized region
- * @DFS_FCC_REGION: FCC region
- * @DFS_ETSI_REGION: ETSI region
- * @DFS_MKK_REGION: MKK region
- * @DFS_CN_REGION: China region
- * @DFS_KR_REGION: Korea region
- * @DFS_UNDEF_REGION: Undefined region
- */
-enum dfs_region {
-	DFS_UNINIT_REGION = 0,
-	DFS_FCC_REGION = 1,
-	DFS_ETSI_REGION = 2,
-	DFS_MKK_REGION = 3,
-	DFS_CN_REGION = 4,
-	DFS_KR_REGION = 5,
-	DFS_UNDEF_REGION
-};
-
 /**
  * wlan_reg_get_channel_list_with_power() - Provide the channel list with power
  * @ch_list: pointer to the channel list.
diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_ucfg_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_ucfg_api.h
index a6e6cfc..10c5705 100644
--- a/umac/regulatory/dispatcher/inc/wlan_reg_ucfg_api.h
+++ b/umac/regulatory/dispatcher/inc/wlan_reg_ucfg_api.h
@@ -26,36 +26,6 @@
  * config interface routines
  */
 
-enum band_info {
-	band_2g = 0x1,
-	band_49g = 0x2,
-	band_5g_36_48 = 0x4,
-	band_5g_52_64 = 0x8,
-	band_5g_100_144 = 0x10,
-	band_5g_149_165 = 0x20
-};
-
-struct reg_ini_vars {
-	uint32_t enable_11d_support;
-	uint32_t userspace_ctry_priority;
-	enum band_info band_capability;
-	uint32_t dfs_enable;
-	uint32_t indoor_channel_support;
-};
-
-struct set_band_req {
-	enum band_info band;
-	uint32_t pdev_id;
-};
-
-struct country_info {
-	uint8_t country_code[3];
-};
-
-struct reg_country_update {
-	uint8_t country_code[3];
-};
-
 typedef QDF_STATUS (*reg_event_cb)(void *status_struct);
 
 QDF_STATUS ucfg_reg_set_band(uint8_t vdev_id, uint8_t pdev_id,
diff --git a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c
index 528fe71..d6becde 100644
--- a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c
+++ b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c
@@ -24,7 +24,9 @@
 
 #include "qdf_types.h"
 #include "qdf_trace.h"
+#include "reg_db.h"
 #include "reg_services.h"
+#include "wlan_reg_services_api.h"
 
 /**
  * wlan_reg_get_channel_list_with_power() - Provide the channel list with power
diff --git a/umac/regulatory/dispatcher/src/wlan_reg_ucfg_api.c b/umac/regulatory/dispatcher/src/wlan_reg_ucfg_api.c
index 3be87b9..152b85a 100644
--- a/umac/regulatory/dispatcher/src/wlan_reg_ucfg_api.c
+++ b/umac/regulatory/dispatcher/src/wlan_reg_ucfg_api.c
@@ -22,6 +22,8 @@
  * @brief contains regulatory user config interface definations
  */
 
+#include "reg_db.h"
+#include "reg_services.h"
 #include "wlan_reg_ucfg_api.h"
 
 /**