qcacld-3.0: Support southbound interface

Attach southbound interface. Each individual component is supposed
to define tx_ops and rx_ops function to attach with southbound.

Change-Id: I622a53ab76bc3bab3774e90569af53ad49b95053
CRs-Fixed: 1096553
diff --git a/Kbuild b/Kbuild
index f8ace11..23c14ce 100644
--- a/Kbuild
+++ b/Kbuild
@@ -717,6 +717,16 @@
 		$(QDF_OBJ_DIR)/qdf_threads.o \
 		$(QDF_OBJ_DIR)/qdf_trace.o
 
+############ UMAC_DISP ############
+UMAC_DISP_DIR := umac/global_umac_dispatcher/lmac_if
+UMAC_DISP_INC_DIR := $(UMAC_DISP_DIR)/inc
+UMAC_DISP_SRC_DIR := $(UMAC_DISP_DIR)/src
+UMAC_DISP_OBJ_DIR := $(WLAN_COMMON_ROOT)/$(UMAC_DISP_SRC_DIR)
+
+UMAC_DISP_INC := -I$(WLAN_COMMON_INC)/$(UMAC_DISP_INC_DIR)
+
+UMAC_DISP_OBJS := $(UMAC_DISP_OBJ_DIR)/wlan_lmac_if.o
+
 ############ CDS (Connectivity driver services) ############
 CDS_DIR :=	core/cds
 CDS_INC_DIR :=	$(CDS_DIR)/inc
@@ -1096,6 +1106,10 @@
 INCS +=		$(HOST_DIAG_LOG_INC)
 endif
 
+ifeq ($(CONFIG_WLAN_CONVERGED_INTERFACE), y)
+INCS +=		$(UMAC_DISP_INC)
+endif
+
 OBJS :=		$(HDD_OBJS) \
 		$(EPPING_OBJS) \
 		$(MAC_OBJS) \
@@ -1134,6 +1148,10 @@
 OBJS +=		$(HOST_DIAG_LOG_OBJS)
 endif
 
+ifeq ($(CONFIG_WLAN_CONVERGED_INTERFACE), y)
+OBJS +=		$(UMAC_DISP_OBJS)
+endif
+
 OBJS +=		$(DP_OBJS) \
 		$(WCFG_OBJS)
 
@@ -1407,6 +1425,10 @@
 CDEFINES += -DWLAN_FEATURE_DSRC
 endif
 
+ifeq ($(CONFIG_WLAN_CONVERGED_INTERFACE), y)
+CDEFINES += -DWLAN_CONVERGED_INTERFACE
+endif
+
 #Enable USB specific APIS
 ifeq ($(CONFIG_HIF_USB), 1)
 CDEFINES += -DHIF_USB \
diff --git a/Kconfig b/Kconfig
index 3798808..aa359f9 100644
--- a/Kconfig
+++ b/Kconfig
@@ -132,4 +132,8 @@
 	bool "Enable DISA certification feature"
 	default n
 
+config WLAN_CONVERGED_INTERFACE
+	bool "Enable WLAN UMAC converged interface"
+	default n
+
 endif # QCA_CLD_WLAN
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index 60aff35..9d6f6e0 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -80,6 +80,11 @@
 #include "cdp_txrx_misc.h"
 #include "wma_nan_datapath.h"
 
+#ifdef WLAN_CONVERGED_INTERFACE
+#include "wlan_lmac_if_def.h"
+#include "wlan_lmac_if_api.h"
+#endif
+
 #define WMA_LOG_COMPLETION_TIMER 10000 /* 10 seconds */
 
 #define WMI_TLV_HEADROOM 128
@@ -1844,6 +1849,75 @@
 	qdf_register_debug_callback(QDF_MODULE_ID_WMA, &wma_state_info_dump);
 }
 
+#ifdef WLAN_CONVERGED_INTERFACE
+/**
+ * wma_register_tx_ops_handler() - register tx_ops of southbound
+ * @tx_ops:  tx_ops pointer in southbound
+ *
+ * Return: 0 on success, errno on failure
+ */
+static QDF_STATUS
+wma_register_tx_ops_handler(struct wlan_lmac_if_tx_ops *tx_ops)
+{
+	/*
+	 * Assign tx_ops, it's up to UMAC modules to declare and define these
+	 * functions which are used to send wmi command to target.
+	 */
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wma_target_if_open() - Attach UMAC modules' interface with wmi layer
+ * @wma_handle: wma handle
+ *
+ * Separate module defines below functions:
+ * 1. tgt_wmi_<module>_<action> api sends wmi command, assigned to south bound
+ *    tx_ops function pointers;
+ * 2. module's south dispatcher handles information from lower layer, assigned
+ *    to south bound rx_ops function pointers;
+ * 3. wmi event handler deals with wmi event, extracts umac needed information,
+ *    and call rx_ops(module's dispatcher). It executes in tasklet context and
+ *    is up to dispatcher to decide the context to reside in tasklet or in
+ *    thread context.
+ *
+ * Return: None
+ */
+static void wma_target_if_open(tp_wma_handle wma_handle)
+{
+	struct wlan_objmgr_psoc *psoc = cds_get_psoc_by_id(0);
+
+	if (!psoc)
+		return;
+
+	wlan_lmac_if_assign_tx_registration_cb(WLAN_DEV_OL,
+					       wma_register_tx_ops_handler);
+
+	wlan_lmac_if_open(psoc);
+
+	/* Register WMI event handler */
+}
+
+/**
+ * wma_target_if_close() - Detach UMAC modules' interface with wmi layer
+ * @wma_handle: wma handle
+ *
+ * Return: None
+ */
+static void wma_target_if_close(tp_wma_handle wma_handle)
+{
+	struct wlan_objmgr_psoc *psoc = cds_get_psoc_by_id(0);
+
+	if (!psoc)
+		return;
+
+	wlan_lmac_if_close(psoc);
+}
+#else
+static void wma_target_if_open(tp_wma_handle wma_handle) {};
+static void wma_target_if_close(tp_wma_handle wma_handle) {};
+#endif
+
 /**
  * wma_open() - Allocate wma context and initialize it.
  * @cds_context:  cds context
@@ -2289,6 +2363,8 @@
 				wma_encrypt_decrypt_msg_handler,
 				WMA_RX_SERIALIZER_CTX);
 	wma_ndp_register_all_event_handlers(wma_handle);
+	wma_target_if_open(wma_handle);
+
 	wma_register_debug_callback();
 
 	return QDF_STATUS_SUCCESS;
@@ -3498,6 +3574,8 @@
 		wmi_desc_pool_deinit(wma_handle);
 	}
 
+	wma_target_if_close(wma_handle);
+
 	WMA_LOGD("%s: Exit", __func__);
 	return QDF_STATUS_SUCCESS;
 }