Selaa lähdekoodia

qcacld-3.0: Add interface to get / set eLNA bypass

Add interface to get / set eLNA bypass from / to firmware

Change-Id: Idf5d6a838d2596767a1fb00040457af721fba69d
CRs-Fixed: 2498525
Paul Zhang 6 vuotta sitten
vanhempi
sitoutus
e0115480ae

+ 51 - 0
fw_offload/core/inc/wlan_fw_offload_main.h

@@ -26,8 +26,10 @@
 #include <wlan_objmgr_psoc_obj.h>
 #include <wlan_objmgr_global_obj.h>
 #include <wlan_cmn.h>
+#include <scheduler_api.h>
 
 #include "cfg_ucfg_api.h"
+#include "wlan_fwol_public_structs.h"
 
 #define fwol_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_FWOL, params)
 #define fwol_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_FWOL, params)
@@ -46,6 +48,17 @@
 #define fwol_nofl_debug(params...) \
 	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_FWOL, params)
 
+/**
+ * enum wlan_fwol_southbound_event - fw offload south bound event type
+ * @WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE: get eLNA bypass response
+ */
+enum wlan_fwol_southbound_event {
+	WLAN_FWOL_EVT_INVALID = 0,
+	WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE,
+	WLAN_FWOL_EVT_LAST,
+	WLAN_FWOL_EVT_MAX = WLAN_FWOL_EVT_LAST - 1
+};
+
 /**
  * struct wlan_fwol_three_antenna_btc - Three antenna BTC config items
  * @btc_mode: Config BTC mode
@@ -244,9 +257,31 @@ struct wlan_fwol_cfg {
 /**
  * struct wlan_fwol_psoc_obj - FW offload psoc priv object
  * @cfg:     cfg items
+ * @cbs:     callback functions
+ * @tx_ops: tx operations for target interface
+ * @rx_ops: rx operations for target interface
  */
 struct wlan_fwol_psoc_obj {
 	struct wlan_fwol_cfg cfg;
+	struct wlan_fwol_callbacks cbs;
+	struct wlan_fwol_tx_ops tx_ops;
+	struct wlan_fwol_rx_ops rx_ops;
+};
+
+/**
+ * struct wlan_fwol_rx_event - event from south bound
+ * @psoc: psoc handle
+ * @event_id: event ID
+ * @get_elna_bypass_response: get eLNA bypass response
+ */
+struct wlan_fwol_rx_event {
+	struct wlan_objmgr_psoc *psoc;
+	enum wlan_fwol_southbound_event event_id;
+	union {
+#ifdef WLAN_FEATURE_ELNA
+		struct get_elna_bypass_response get_elna_bypass_response;
+#endif
+	};
 };
 
 /**
@@ -277,6 +312,22 @@ QDF_STATUS fwol_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc);
  */
 QDF_STATUS fwol_cfg_on_psoc_disable(struct wlan_objmgr_psoc *psoc);
 
+/**
+ * fwol_process_event() - API to process event from south bound
+ * @msg: south bound message
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS fwol_process_event(struct scheduler_msg *msg);
+
+/*
+ * fwol_release_rx_event() - Release fw offload RX event
+ * @event: fw offload RX event
+ *
+ * Return: none
+ */
+void fwol_release_rx_event(struct wlan_fwol_rx_event *event);
+
 /*
  * fwol_init_neighbor_report_cfg() - Populate default neighbor report CFG values
  * @psoc: pointer to the psoc object

+ 94 - 0
fw_offload/core/src/wlan_fw_offload_main.c

@@ -543,3 +543,97 @@ QDF_STATUS fwol_cfg_on_psoc_disable(struct wlan_objmgr_psoc *psoc)
 	/* Clear the CFG structure */
 	return QDF_STATUS_SUCCESS;
 }
+
+#ifdef WLAN_FEATURE_ELNA
+/**
+ * fwol_process_get_elna_bypass_resp() - Process get eLNA bypass response
+ * @event: response event
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+fwol_process_get_elna_bypass_resp(struct wlan_fwol_rx_event *event)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	struct wlan_fwol_callbacks *cbs;
+	struct get_elna_bypass_response *resp;
+
+	if (!event) {
+		fwol_err("Event buffer is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	psoc = event->psoc;
+	if (!psoc) {
+		fwol_err("psoc is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL Obj");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	cbs = &fwol_obj->cbs;
+	if (cbs->get_elna_bypass_callback) {
+		resp = &event->get_elna_bypass_response;
+		cbs->get_elna_bypass_callback(cbs->get_elna_bypass_context,
+					      resp);
+	} else {
+		fwol_err("NULL pointer for callback");
+		status = QDF_STATUS_E_IO;
+	}
+
+	return status;
+}
+#else
+static QDF_STATUS
+fwol_process_get_elna_bypass_resp(struct wlan_fwol_rx_event *event)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* WLAN_FEATURE_ELNA */
+
+QDF_STATUS fwol_process_event(struct scheduler_msg *msg)
+{
+	QDF_STATUS status;
+	struct wlan_fwol_rx_event *event;
+
+	fwol_debug("msg type %d", msg->type);
+
+	if (!(msg->bodyptr)) {
+		fwol_err("Invalid message body");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	event = msg->bodyptr;
+	msg->bodyptr = NULL;
+
+	switch (msg->type) {
+	case WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE:
+		status = fwol_process_get_elna_bypass_resp(event);
+		break;
+	default:
+		status = QDF_STATUS_E_INVAL;
+		break;
+	}
+
+	fwol_release_rx_event(event);
+
+	return status;
+}
+
+void fwol_release_rx_event(struct wlan_fwol_rx_event *event)
+{
+	if (!event) {
+		fwol_err("event is NULL");
+		return;
+	}
+
+	if (event->psoc)
+		wlan_objmgr_psoc_release_ref(event->psoc, WLAN_FWOL_SB_ID);
+	qdf_mem_free(event);
+}

+ 4 - 0
fw_offload/dispatcher/inc/cfg_fwol.h

@@ -29,6 +29,7 @@
 #include "cfg_neighbor_roam.h"
 #include "cfg_adaptive_dwelltime.h"
 
+#ifdef WLAN_FW_OFFLOAD
 #define CFG_FWOL_ALL \
 	CFG_ADAPTIVE_DWELLTIME_ALL \
 	CFG_11K_ALL \
@@ -36,6 +37,9 @@
 	CFG_FWOL_GENERIC_ALL \
 	CFG_IE_WHITELIST \
 	CFG_THERMAL_TEMP_ALL
+#else
+#define CFG_FWOL_ALL
+#endif
 
 #endif /* __CFG_FWOL_H */
 

+ 105 - 0
fw_offload/dispatcher/inc/wlan_fwol_public_structs.h

@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2019 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: contains fw offload structure definations
+ */
+
+#ifndef _WLAN_FWOL_PUBLIC_STRUCTS_H_
+#define _WLAN_FWOL_PUBLIC_STRUCTS_H_
+
+#include "wlan_objmgr_psoc_obj.h"
+
+#ifdef WLAN_FEATURE_ELNA
+/**
+ * struct set_elna_bypass_request - set eLNA bypass request
+ * @vdev_id: vdev id
+ * @en_dis: 0 - disable eLNA bypass
+ *          1 - enable eLNA bypass
+ */
+struct set_elna_bypass_request {
+	uint8_t vdev_id;
+	uint8_t en_dis;
+};
+
+/**
+ * struct get_elna_bypass_request - get eLNA bypass request
+ * @vdev_id: vdev id
+ */
+struct get_elna_bypass_request {
+	uint8_t vdev_id;
+};
+
+/**
+ * struct get_elna_bypass_response - get eLNA bypass response
+ * @vdev_id: vdev id
+ * @en_dis: 0 - disable eLNA bypass
+ *          1 - enable eLNA bypass
+ */
+struct get_elna_bypass_response {
+	uint8_t vdev_id;
+	uint8_t en_dis;
+};
+#endif
+
+/**
+ * struct wlan_fwol_callbacks - fw offload callbacks
+ * @get_elna_bypass_callback: callback for get eLNA bypass
+ * @get_elna_bypass_context: context for get eLNA bypass
+ */
+struct wlan_fwol_callbacks {
+#ifdef WLAN_FEATURE_ELNA
+	void (*get_elna_bypass_callback)(void *context,
+				     struct get_elna_bypass_response *response);
+	void *get_elna_bypass_context;
+#endif
+};
+
+/**
+ * struct wlan_fwol_tx_ops - structure of tx func pointers
+ * @set_elna_bypass: set eLNA bypass
+ * @get_elna_bypass: get eLNA bypass
+ * @reg_evt_handler: register event handler
+ * @unreg_evt_handler: unregister event handler
+ */
+struct wlan_fwol_tx_ops {
+#ifdef WLAN_FEATURE_ELNA
+	QDF_STATUS (*set_elna_bypass)(struct wlan_objmgr_psoc *psoc,
+				      struct set_elna_bypass_request *req);
+	QDF_STATUS (*get_elna_bypass)(struct wlan_objmgr_psoc *psoc,
+				      struct get_elna_bypass_request *req);
+#endif
+	QDF_STATUS (*reg_evt_handler)(struct wlan_objmgr_psoc *psoc,
+				      void *arg);
+	QDF_STATUS (*unreg_evt_handler)(struct wlan_objmgr_psoc *psoc,
+					void *arg);
+};
+
+/**
+ * struct wlan_fwol_rx_ops - structure of rx func pointers
+ * @get_elna_bypass_resp: get eLNA bypass response
+ */
+struct wlan_fwol_rx_ops {
+#ifdef WLAN_FEATURE_ELNA
+	QDF_STATUS (*get_elna_bypass_resp)(struct wlan_objmgr_psoc *psoc,
+					 struct get_elna_bypass_response *resp);
+#endif
+};
+
+#endif /* _WLAN_FWOL_PUBLIC_STRUCTS_H_ */
+

+ 50 - 0
fw_offload/dispatcher/inc/wlan_fwol_tgt_api.h

@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019 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: fw offload south bound interface declaration
+ */
+#ifndef _WLAN_FWOL_TGT_API_H
+#define _WLAN_FWOL_TGT_API_H
+
+#include "wlan_fwol_public_structs.h"
+
+/**
+ * tgt_fwol_register_ev_handler() - register south bound event handler
+ * @psoc: psoc handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS tgt_fwol_register_ev_handler(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * tgt_fwol_unregister_ev_handler() - unregister south bound event handler
+ * @psoc: psoc handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS tgt_fwol_unregister_ev_handler(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * tgt_fwol_register_rx_ops() - register fw offload rx operations
+ * @rx_ops: fps to rx operations
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS tgt_fwol_register_rx_ops(struct wlan_fwol_rx_ops *rx_ops);
+#endif /* _WLAN_FWOL_TGT_API_H */

+ 319 - 0
fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h

@@ -26,7 +26,9 @@
 #include <wlan_objmgr_global_obj.h>
 #include <wlan_cmn.h>
 #include "wlan_fw_offload_main.h"
+#include "wlan_fwol_public_structs.h"
 
+#ifdef WLAN_FW_OFFLOAD
 /**
  * ucfg_fwol_psoc_open() - FWOL component Open
  * @psoc: pointer to psoc object
@@ -523,4 +525,321 @@ ucfg_fwol_set_adaptive_dwelltime_config(
 {
 	return fwol_set_adaptive_dwelltime_config(dwelltime_params);
 }
+
+#ifdef WLAN_FEATURE_ELNA
+/**
+ * ucfg_fwol_set_elna_bypass() - send set eLNA bypass request
+ * @vdev: vdev handle
+ * @req: set eLNA bypass request
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_fwol_set_elna_bypass(struct wlan_objmgr_vdev *vdev,
+				     struct set_elna_bypass_request *req);
+
+/**
+ * ucfg_fwol_get_elna_bypass() - send get eLNA bypass request
+ * @vdev: vdev handle
+ * @req: get eLNA bypass request
+ * @callback: get eLNA bypass response callback
+ * @context: request manager context
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS ucfg_fwol_get_elna_bypass(struct wlan_objmgr_vdev *vdev,
+				     struct get_elna_bypass_request *req,
+				     void (*callback)(void *context,
+				     struct get_elna_bypass_response *response),
+				     void *context);
+#endif /* WLAN_FEATURE_ELNA */
+#else
+static inline QDF_STATUS ucfg_fwol_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void ucfg_fwol_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+}
+
+static inline QDF_STATUS ucfg_fwol_init(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void ucfg_fwol_deinit(void)
+{
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_coex_config_params(struct wlan_objmgr_psoc *psoc,
+				 struct wlan_fwol_coex_config *coex_config)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_thermal_temp(struct wlan_objmgr_psoc *psoc,
+			   struct wlan_fwol_thermal_temp *thermal_temp)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_neighbor_report_cfg(struct wlan_objmgr_psoc *psoc,
+				  struct wlan_fwol_neighbor_report_cfg
+				  *fwol_neighbor_report_cfg)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_is_neighbor_report_req_supported(struct wlan_objmgr_psoc *psoc,
+					   bool *neighbor_report_req)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_ie_whitelist(struct wlan_objmgr_psoc *psoc, bool *ie_whitelist)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_set_ie_whitelist(struct wlan_objmgr_psoc *psoc, bool ie_whitelist)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_all_whitelist_params(struct wlan_objmgr_psoc *psoc,
+				   struct wlan_fwol_ie_whitelist *whitelist)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_ani_enabled(struct wlan_objmgr_psoc *psoc,
+			  bool *ani_enabled)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_enable_rts_sifsbursting(struct wlan_objmgr_psoc *psoc,
+				 bool *enable_rts_sifsbursting)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_max_mpdus_inampdu(struct wlan_objmgr_psoc *psoc,
+			   uint8_t *max_mpdus_inampdu)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_arp_ac_category(struct wlan_objmgr_psoc *psoc,
+			 uint32_t *arp_ac_category)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_enable_phy_reg_retention(struct wlan_objmgr_psoc *psoc,
+				  uint8_t *enable_phy_reg_retention)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_upper_brssi_thresh(struct wlan_objmgr_psoc *psoc,
+			    uint16_t *upper_brssi_thresh)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_lower_brssi_thresh(struct wlan_objmgr_psoc *psoc,
+			    uint16_t *lower_brssi_thresh)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_enable_dtim_1chrx(struct wlan_objmgr_psoc *psoc,
+			   bool *enable_dtim_1chrx)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_alternative_chainmask_enabled(struct wlan_objmgr_psoc *psoc,
+				       bool *alternative_chainmask_enabled)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_get_smart_chainmask_enabled(struct wlan_objmgr_psoc *psoc,
+				 bool *smart_chainmask_enabled)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_rts_profile(struct wlan_objmgr_psoc *psoc,
+			  uint16_t *get_rts_profile)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_enable_fw_log_level(struct wlan_objmgr_psoc *psoc,
+				  uint16_t *enable_fw_log_level)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_enable_fw_log_type(struct wlan_objmgr_psoc *psoc,
+				 uint16_t *enable_fw_log_type)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_enable_fw_module_log_level(
+				struct wlan_objmgr_psoc *psoc,
+				uint8_t **enable_fw_module_log_level,
+				uint8_t *enable_fw_module_log_level_num)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_tsf_gpio_pin(struct wlan_objmgr_psoc *psoc,
+			   uint32_t *tsf_gpio_pin)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_tsf_ptp_options(struct wlan_objmgr_psoc *psoc,
+			      uint32_t *tsf_ptp_options)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_lprx_enable(struct wlan_objmgr_psoc *psoc,
+			  bool *lprx_enable)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline bool ucfg_fwol_get_sae_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline bool ucfg_fwol_get_gcmp_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_enable_tx_sch_delay(struct wlan_objmgr_psoc *psoc,
+				  uint8_t *enable_tx_sch_delay)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_enable_secondary_rate(struct wlan_objmgr_psoc *psoc,
+				    uint32_t *enable_secondary_rate)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_all_adaptive_dwelltime_params(
+			struct wlan_objmgr_psoc *psoc,
+			struct adaptive_dwelltime_params *dwelltime_params)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_adaptive_dwell_mode_enabled(struct wlan_objmgr_psoc *psoc,
+					  bool *adaptive_dwell_mode_enabled)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_global_adapt_dwelltime_mode(struct wlan_objmgr_psoc *psoc,
+					  uint8_t *global_adapt_dwelltime_mode)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_adapt_dwell_lpf_weight(struct wlan_objmgr_psoc *psoc,
+				     uint8_t *adapt_dwell_lpf_weight)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_adapt_dwell_passive_mon_intval(
+				struct wlan_objmgr_psoc *psoc,
+				uint8_t *adapt_dwell_passive_mon_intval)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_adapt_dwell_wifi_act_threshold(
+				struct wlan_objmgr_psoc *psoc,
+				uint8_t *adapt_dwell_wifi_act_threshold)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_init_adapt_dwelltime_in_cfg(
+			struct wlan_objmgr_psoc *psoc,
+			struct adaptive_dwelltime_params *dwelltime_params)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_set_adaptive_dwelltime_config(
+			struct adaptive_dwelltime_params *dwelltime_params)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+#ifdef FEATURE_WLAN_RA_FILTERING
+static inline QDF_STATUS
+ucfg_fwol_set_is_rate_limit_enabled(struct wlan_objmgr_psoc *psoc,
+				    bool is_rate_limit_enabled)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS
+ucfg_fwol_get_is_rate_limit_enabled(struct wlan_objmgr_psoc *psoc,
+				    bool *is_rate_limit_enabled)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+#endif /* FEATURE_WLAN_RA_FILTERING */
+
+#endif /* WLAN_FW_OFFLOAD */
+
 #endif /* _WLAN_FWOL_UCFG_API_H_ */

+ 173 - 0
fw_offload/dispatcher/src/wlan_fwol_tgt_api.c

@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2019 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: This file contains fw offload south bound interface definitions
+ */
+
+#include "scheduler_api.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_global_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "wlan_fwol_public_structs.h"
+#include "wlan_fwol_ucfg_api.h"
+#include "wlan_fwol_tgt_api.h"
+#include "wlan_fw_offload_main.h"
+
+QDF_STATUS tgt_fwol_register_ev_handler(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	struct wlan_fwol_tx_ops *tx_ops;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (!psoc) {
+		fwol_err("NULL psoc handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL Obj");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	tx_ops = &fwol_obj->tx_ops;
+	if (tx_ops->reg_evt_handler) {
+		status = tx_ops->reg_evt_handler(psoc, NULL);
+		fwol_debug("reg_evt_handler, status:%d", status);
+	} else {
+		fwol_alert("No reg_evt_handler");
+	}
+
+	return status;
+}
+
+QDF_STATUS tgt_fwol_unregister_ev_handler(struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	struct wlan_fwol_tx_ops *tx_ops;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (!psoc) {
+		fwol_err("NNULL psoc handle");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL Obj");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	tx_ops = &fwol_obj->tx_ops;
+	if (tx_ops->unreg_evt_handler) {
+		status = tx_ops->unreg_evt_handler(psoc, NULL);
+		fwol_debug("unreg_evt_handler, status:%d", status);
+	} else {
+		fwol_alert("No unreg_evt_handler");
+	}
+
+	return status;
+}
+
+/**
+ * fwol_flush_callback() - fw offload message flush callback
+ * @msg: fw offload message
+ *
+ * Return: QDF_STATUS_SUCCESS on success.
+ */
+__attribute__((unused))
+static QDF_STATUS fwol_flush_callback(struct scheduler_msg *msg)
+{
+	struct wlan_fwol_rx_event *event;
+
+	if (!msg) {
+		fwol_err("NULL pointer for eLNA message");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	event = msg->bodyptr;
+	msg->bodyptr = NULL;
+	fwol_release_rx_event(event);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+#ifdef WLAN_FEATURE_ELNA
+/**
+ * tgt_fwol_get_elna_bypass_resp() - handler for get eLNA bypass response
+ * @psoc: psoc handle
+ * @resp: status for last channel config
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+tgt_fwol_get_elna_bypass_resp(struct wlan_objmgr_psoc *psoc,
+			      struct get_elna_bypass_response *resp)
+{
+	QDF_STATUS status;
+	struct scheduler_msg msg = {0};
+	struct wlan_fwol_rx_event *event;
+
+	event = qdf_mem_malloc(sizeof(*event));
+	if (!event)
+		return QDF_STATUS_E_NOMEM;
+
+	status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_FWOL_SB_ID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		fwol_err("Failed to get psoc ref");
+		fwol_release_rx_event(event);
+		return status;
+	}
+
+	event->psoc = psoc;
+	event->event_id = WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE;
+	event->get_elna_bypass_response = *resp;
+	msg.type = WLAN_FWOL_EVT_GET_ELNA_BYPASS_RESPONSE;
+	msg.bodyptr = event;
+	msg.callback = fwol_process_event;
+	msg.flush_callback = fwol_flush_callback;
+	status = scheduler_post_message(QDF_MODULE_ID_FWOL,
+					QDF_MODULE_ID_FWOL,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+
+	if (QDF_IS_STATUS_SUCCESS(status))
+		return QDF_STATUS_SUCCESS;
+
+	fwol_err("failed to send WLAN_FWOL_GET_ELNA_BYPASS_RESPONSE msg");
+	fwol_flush_callback(&msg);
+
+	return status;
+}
+
+static void tgt_fwol_register_elna_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
+{
+	rx_ops->get_elna_bypass_resp = tgt_fwol_get_elna_bypass_resp;
+}
+#else
+static void tgt_fwol_register_elna_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
+{
+}
+#endif /* WLAN_FEATURE_ELNA */
+
+QDF_STATUS tgt_fwol_register_rx_ops(struct wlan_fwol_rx_ops *rx_ops)
+{
+	tgt_fwol_register_elna_rx_ops(rx_ops);
+
+	return QDF_STATUS_SUCCESS;
+}

+ 79 - 0
fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c

@@ -20,7 +20,11 @@
  */
 
 #include "wlan_fw_offload_main.h"
+#include "wlan_fwol_public_structs.h"
 #include "wlan_fwol_ucfg_api.h"
+#include "wlan_fwol_tgt_api.h"
+#include "target_if_fwol.h"
+#include "wlan_objmgr_vdev_obj.h"
 
 QDF_STATUS ucfg_fwol_psoc_open(struct wlan_objmgr_psoc *psoc)
 {
@@ -30,12 +34,16 @@ QDF_STATUS ucfg_fwol_psoc_open(struct wlan_objmgr_psoc *psoc)
 	if (QDF_IS_STATUS_ERROR(status))
 		fwol_err("Failed to initialize FWOL CFG");
 
+	tgt_fwol_register_ev_handler(psoc);
+
 	return status;
 }
 
 void ucfg_fwol_psoc_close(struct wlan_objmgr_psoc *psoc)
 {
 	/* Clear the FWOL CFG Structure */
+
+	tgt_fwol_unregister_ev_handler(psoc);
 }
 
 /**
@@ -66,6 +74,9 @@ fwol_psoc_object_created_notification(struct wlan_objmgr_psoc *psoc, void *arg)
 		qdf_mem_free(fwol_obj);
 	}
 
+	tgt_fwol_register_rx_ops(&fwol_obj->rx_ops);
+	target_if_fwol_register_tx_ops(&fwol_obj->tx_ops);
+
 	return status;
 }
 
@@ -832,3 +843,71 @@ QDF_STATUS ucfg_fwol_get_adapt_dwell_wifi_act_threshold(
 			fwol_obj->cfg.dwelltime_params.wifi_act_threshold;
 	return QDF_STATUS_SUCCESS;
 }
+
+#ifdef WLAN_FEATURE_ELNA
+QDF_STATUS ucfg_fwol_set_elna_bypass(struct wlan_objmgr_vdev *vdev,
+				     struct set_elna_bypass_request *req)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	struct wlan_fwol_tx_ops *tx_ops;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		fwol_err("NULL pointer for psoc");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL Obj");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	tx_ops = &fwol_obj->tx_ops;
+	if (tx_ops->set_elna_bypass)
+		status = tx_ops->set_elna_bypass(psoc, req);
+	else
+		status = QDF_STATUS_E_IO;
+
+	return status;
+}
+
+QDF_STATUS ucfg_fwol_get_elna_bypass(struct wlan_objmgr_vdev *vdev,
+				     struct get_elna_bypass_request *req,
+				     void (*callback)(void *context,
+				     struct get_elna_bypass_response *response),
+				     void *context)
+{
+	QDF_STATUS status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	struct wlan_fwol_tx_ops *tx_ops;
+	struct wlan_fwol_callbacks *cbs;
+
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (!psoc) {
+		fwol_err("NULL pointer for psoc");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL Obj");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	cbs = &fwol_obj->cbs;
+	cbs->get_elna_bypass_callback = callback;
+	cbs->get_elna_bypass_context = context;
+
+	tx_ops = &fwol_obj->tx_ops;
+	if (tx_ops->get_elna_bypass)
+		status = tx_ops->get_elna_bypass(psoc, req);
+	else
+		status = QDF_STATUS_E_IO;
+
+	return status;
+}
+#endif /* WLAN_FEATURE_ELNA */

+ 58 - 0
target_if/fw_offload/inc/target_if_fwol.h

@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2019 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: target interface APIs for fw offload
+ *
+ */
+
+#ifndef __TARGET_IF_FWOL_H__
+#define __TARGET_IF_FWOL_H__
+
+/**
+ * target_if_fwol_register_event_handler() - register fw offload event handler
+ * @psoc: psoc object
+ * @arg: argument passed to lmac
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS target_if_fwol_register_event_handler(struct wlan_objmgr_psoc *psoc,
+						 void *arg);
+
+/**
+ * target_if_fwol_unregister_event_handler() - unregister fw offload event
+ * handler
+ * @psoc: psoc object
+ * @arg: argument passed to lmac
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+target_if_fwol_unregister_event_handler(struct wlan_objmgr_psoc *psoc,
+					void *arg);
+
+/**
+ * target_if_fwol_register_tx_ops() - register fw offload tx ops callback
+ * functions
+ * @tx_ops: fw offload tx operations
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS target_if_fwol_register_tx_ops(struct wlan_fwol_tx_ops *tx_ops);
+
+#endif /* __TARGET_IF_FWOL_H__ */

+ 216 - 0
target_if/fw_offload/src/target_if_fwol.c

@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2019 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: target interface APIs for fw offload
+ *
+ */
+
+#include "qdf_mem.h"
+#include "target_if.h"
+#include "qdf_status.h"
+#include "wmi_unified_api.h"
+#include "wmi_unified_priv.h"
+#include "wmi_unified_param.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_utility.h"
+#include "wlan_defs.h"
+#include "wlan_fwol_public_structs.h"
+#include "wlan_fw_offload_main.h"
+#include "target_if_fwol.h"
+
+#ifdef WLAN_FEATURE_ELNA
+/**
+ * target_if_fwol_set_elna_bypass() - send set eLNA bypass request to FW
+ * @psoc: pointer to PSOC object
+ * @req: set eLNA bypass request
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+target_if_fwol_set_elna_bypass(struct wlan_objmgr_psoc *psoc,
+			       struct set_elna_bypass_request *req)
+{
+	QDF_STATUS status;
+
+	status = wmi_unified_send_set_elna_bypass_cmd(
+					    get_wmi_unified_hdl_from_psoc(psoc),
+					    req);
+	if (status)
+		target_if_err("Failed to set eLNA bypass %d", status);
+
+	return status;
+}
+
+/**
+ * target_if_fwol_get_elna_bypass() - send get eLNA bypass request to FW
+ * @psoc: pointer to PSOC object
+ * @req: get eLNA bypass request
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+static QDF_STATUS
+target_if_fwol_get_elna_bypass(struct wlan_objmgr_psoc *psoc,
+			       struct get_elna_bypass_request *req)
+{
+	QDF_STATUS status;
+
+	status = wmi_unified_send_get_elna_bypass_cmd(
+					    get_wmi_unified_hdl_from_psoc(psoc),
+					    req);
+	if (status)
+		target_if_err("Failed to set eLNA bypass %d", status);
+
+	return status;
+}
+
+/**
+ * target_if_fwol_get_elna_bypass_resp() - handler for get eLNA bypass response
+ * @scn: scn handle
+ * @event_buf: pointer to the event buffer
+ * @len: length of the buffer
+ *
+ * Return: 0 on success
+ */
+static int target_if_fwol_get_elna_bypass_resp(ol_scn_t scn, uint8_t *event_buf,
+					       uint32_t len)
+{
+	QDF_STATUS status;
+	struct get_elna_bypass_response resp;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	struct wlan_fwol_rx_ops *rx_ops;
+
+	target_if_debug("scn:%pK, data:%pK, datalen:%d", scn, event_buf, len);
+	if (!scn || !event_buf) {
+		target_if_err("scn: 0x%pK, data: 0x%pK", scn, event_buf);
+		return -EINVAL;
+	}
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		target_if_err("null psoc");
+		return -EINVAL;
+	}
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		target_if_err("Failed to get FWOL Obj");
+		return -EINVAL;
+	}
+
+	rx_ops = &fwol_obj->rx_ops;
+	if (rx_ops->get_elna_bypass_resp) {
+		status = wmi_extract_get_elna_bypass_resp(
+					    get_wmi_unified_hdl_from_psoc(psoc),
+					    event_buf, &resp);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			target_if_err("Failed to extract eLNA bypass");
+			return -EINVAL;
+		}
+		status = rx_ops->get_elna_bypass_resp(psoc, &resp);
+		if (status != QDF_STATUS_SUCCESS) {
+			target_if_err("get_elna_bypass_resp failed.");
+			return -EINVAL;
+		}
+	} else {
+		target_if_fatal("No get_elna_bypass_resp callback");
+		return -EINVAL;
+	}
+
+	return 0;
+};
+
+static void
+target_if_fwol_register_elna_event_handler(struct wlan_objmgr_psoc *psoc,
+					   void *arg)
+{
+	int rc;
+
+	rc = wmi_unified_register_event(get_wmi_unified_hdl_from_psoc(psoc),
+					wmi_get_elna_bypass_event_id,
+					target_if_fwol_get_elna_bypass_resp);
+	if (rc)
+		target_if_err("Failed to register get eLNA bypass event cb");
+}
+
+static void
+target_if_fwol_unregister_elna_event_handler(struct wlan_objmgr_psoc *psoc,
+					     void *arg)
+{
+	int rc;
+
+	rc = wmi_unified_unregister_event_handler(
+					    get_wmi_unified_hdl_from_psoc(psoc),
+					    wmi_get_elna_bypass_event_id);
+	if (rc)
+		target_if_err("Failed to unregister get eLNA bypass event cb");
+}
+
+static void
+target_if_fwol_register_elna_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
+{
+	tx_ops->set_elna_bypass = target_if_fwol_set_elna_bypass;
+	tx_ops->get_elna_bypass = target_if_fwol_get_elna_bypass;
+}
+#else
+static void
+target_if_fwol_register_elna_event_handler(struct wlan_objmgr_psoc *psoc,
+					   void *arg)
+{
+}
+
+static void
+target_if_fwol_unregister_elna_event_handler(struct wlan_objmgr_psoc *psoc,
+					     void *arg)
+{
+}
+
+static void
+target_if_fwol_register_elna_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
+{
+}
+#endif /* WLAN_FEATURE_ELNA */
+
+QDF_STATUS target_if_fwol_register_event_handler(struct wlan_objmgr_psoc *psoc,
+						 void *arg)
+{
+	target_if_fwol_register_elna_event_handler(psoc, arg);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+target_if_fwol_unregister_event_handler(struct wlan_objmgr_psoc *psoc,
+					void *arg)
+{
+	target_if_fwol_unregister_elna_event_handler(psoc, arg);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS target_if_fwol_register_tx_ops(struct wlan_fwol_tx_ops *tx_ops)
+{
+	target_if_fwol_register_elna_tx_ops(tx_ops);
+
+	tx_ops->reg_evt_handler = target_if_fwol_register_event_handler;
+	tx_ops->unreg_evt_handler = target_if_fwol_unregister_event_handler;
+
+	return QDF_STATUS_SUCCESS;
+}
+