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
Tento commit je obsažen v:
Paul Zhang
2019-06-23 22:07:31 +08:00
odevzdal nshrivas
rodič d681a1def1
revize c9dbaeea18
19 změnil soubory, kde provedl 1644 přidání a 5 odebrání

32
Kbuild
Zobrazit soubor

@@ -929,12 +929,25 @@ IPA_OBJS := $(IPA_DIR)/dispatcher/src/wlan_ipa_ucfg_api.o \
endif
######## FWOL ##########
FWOL_DIR := components/fw_offload
FWOL_INC := -I$(WLAN_ROOT)/$(FWOL_DIR)/core/inc \
-I$(WLAN_ROOT)/$(FWOL_DIR)/dispatcher/inc
FWOL_CORE_INC := components/fw_offload/core/inc
FWOL_CORE_SRC := components/fw_offload/core/src
FWOL_DISPATCHER_INC := components/fw_offload/dispatcher/inc
FWOL_DISPATCHER_SRC := components/fw_offload/dispatcher/src
FWOL_TARGET_IF_INC := components/target_if/fw_offload/inc
FWOL_TARGET_IF_SRC := components/target_if/fw_offload/src
FWOL_OS_IF_INC := os_if/fw_offload/inc
FWOL_OS_IF_SRC := os_if/fw_offload/src
FWOL_OBJS := $(FWOL_DIR)/core/src/wlan_fw_offload_main.o \
$(FWOL_DIR)/dispatcher/src/wlan_fwol_ucfg_api.o
FWOL_INC := -I$(WLAN_ROOT)/$(FWOL_CORE_INC) \
-I$(WLAN_ROOT)/$(FWOL_DISPATCHER_INC) \
-I$(WLAN_ROOT)/$(FWOL_TARGET_IF_INC) \
-I$(WLAN_ROOT)/$(FWOL_OS_IF_INC)
FWOL_OBJS := $(FWOL_CORE_SRC)/wlan_fw_offload_main.o \
$(FWOL_DISPATCHER_SRC)/wlan_fwol_ucfg_api.o \
$(FWOL_DISPATCHER_SRC)/wlan_fwol_tgt_api.o \
$(FWOL_TARGET_IF_SRC)/target_if_fwol.o \
$(FWOL_OS_IF_SRC)/os_if_fwol.o
######## SM FRAMEWORK ##############
UMAC_SM_DIR := umac/cmn_services/sm_engine
@@ -1244,6 +1257,11 @@ WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_bcn_api.o
WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_bcn_tlv.o
endif
ifeq ($(CONFIG_WLAN_FW_OFFLOAD), y)
WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_fwol_api.o
WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_fwol_tlv.o
endif
########### FWLOG ###########
FWLOG_DIR := $(WLAN_COMMON_ROOT)/utils/fwlog
@@ -1980,7 +1998,9 @@ OBJS += $(PLD_OBJS)
OBJS += $(UMAC_SM_OBJS)
OBJS += $(UMAC_MLME_OBJS)
OBJS += $(MLME_OBJS)
ifeq ($(CONFIG_WLAN_FW_OFFLOAD), y)
OBJS += $(FWOL_OBJS)
endif
OBJS += $(BLM_OBJS)
ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
@@ -2080,6 +2100,8 @@ cppflags-$(CONFIG_FEATURE_MEMDUMP_ENABLE) += -DWLAN_FEATURE_MEMDUMP_ENABLE
cppflags-$(CONFIG_FEATURE_FW_LOG_PARSING) += -DFEATURE_FW_LOG_PARSING
cppflags-$(CONFIG_FEATURE_OEM_DATA) += -DFEATURE_OEM_DATA
cppflags-$(CONFIG_FEATURE_MOTION_DETECTION) += -DWLAN_FEATURE_MOTION_DETECTION
cppflags-$(CONFIG_WLAN_FW_OFFLOAD) += -DWLAN_FW_OFFLOAD
cppflags-$(CONFIG_WLAN_FEATURE_ELNA) += -DWLAN_FEATURE_ELNA
cppflags-$(CONFIG_PLD_SDIO_CNSS_FLAG) += -DCONFIG_PLD_SDIO_CNSS
cppflags-$(CONFIG_PLD_PCIE_CNSS_FLAG) += -DCONFIG_PLD_PCIE_CNSS

Zobrazit soubor

@@ -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

Zobrazit soubor

@@ -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);
}

Zobrazit soubor

@@ -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 */

Zobrazit soubor

@@ -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_ */

Zobrazit soubor

@@ -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 */

Zobrazit soubor

@@ -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_ */

Zobrazit soubor

@@ -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;
}

Zobrazit soubor

@@ -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 */

Zobrazit soubor

@@ -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__ */

Zobrazit soubor

@@ -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;
}

Zobrazit soubor

@@ -905,6 +905,14 @@ CONFIG_SM_ENG_HIST := n
#Enable OEM DATA feature
CONFIG_FEATURE_OEM_DATA := y
#Enable FW Offload
CONFIG_WLAN_FW_OFFLOAD := y
#Enable eLNA bypass feature
ifeq ($(CONFIG_WLAN_FW_OFFLOAD), y)
CONFIG_WLAN_FEATURE_ELNA := y
endif
ifeq (y,$(findstring y,$(CONFIG_ARCH_MSM) $(CONFIG_ARCH_QCOM)))
CONFIG_WLAN_FEATURE_DP_BUS_BANDWIDTH := y
endif

Zobrazit soubor

@@ -221,4 +221,8 @@ CONFIG_WLAN_FEATURE_DP_BUS_BANDWIDTH := y
endif
CONFIG_SAP_DHCP_FW_IND := n
#Enable FW Offload
CONFIG_WLAN_FW_OFFLOAD := y
###################################

Zobrazit soubor

@@ -716,3 +716,7 @@ CONFIG_WLAN_FEATURE_DP_BUS_BANDWIDTH := y
endif
CONFIG_SAP_DHCP_FW_IND := y
#Enable FW Offload
CONFIG_WLAN_FW_OFFLOAD := y

Zobrazit soubor

@@ -750,3 +750,7 @@ endif
CONFIG_FOURTH_CONNECTION := y
CONFIG_SAP_DHCP_FW_IND := y
#Enable FW Offload
CONFIG_WLAN_FW_OFFLOAD := y

Zobrazit soubor

@@ -172,6 +172,9 @@ CONFIG_BUILD_TAG := y
endif
endif
#Enable FW Offload
CONFIG_WLAN_FW_OFFLOAD := y
CONFIG_ENABLE_SIZE_OPTIMIZE := y
# configure log buffer size

Zobrazit soubor

@@ -141,6 +141,7 @@
#include "wlan_blm_ucfg_api.h"
#include "wlan_hdd_hw_capability.h"
#include "wlan_hdd_oemdata.h"
#include "os_if_fwol.h"
#define g_mode_rates_size (12)
#define a_mode_rates_size (8)
@@ -6108,6 +6109,7 @@ wlan_hdd_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE] = {.type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] = {.type = NLA_U8},
[QCA_WLAN_VENDOR_ATTR_CONFIG_GTX] = {.type = NLA_U8},
[QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS] = {.type = NLA_U8},
[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY] = {.type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE_LIST] = {
.type = NLA_BINARY,
@@ -7270,6 +7272,32 @@ static int hdd_config_disconnect_ies(struct hdd_adapter *adapter,
return qdf_status_to_os_return(status);
}
#ifdef WLAN_FEATURE_ELNA
/**
* hdd_set_elna_bypass() - Set eLNA bypass
* @adapter: Pointer to HDD adapter
* @attr: Pointer to struct nlattr
*
* Return: 0 on success; error number otherwise
*/
static int hdd_set_elna_bypass(struct hdd_adapter *adapter,
const struct nlattr *attr)
{
int ret;
struct wlan_objmgr_vdev *vdev;
vdev = hdd_objmgr_get_vdev(adapter);
if (!vdev)
return -EINVAL;
ret = os_if_fwol_set_elna_bypass(vdev, attr);
hdd_objmgr_put_vdev(vdev);
return ret;
}
#endif
/**
* typedef independent_setter_fn - independent attribute handler
* @adapter: The adapter being configured
@@ -7356,8 +7384,135 @@ static const struct independent_setters independent_setters[] = {
hdd_config_gtx},
{QCA_WLAN_VENDOR_ATTR_DISCONNECT_IES,
hdd_config_disconnect_ies},
#ifdef WLAN_FEATURE_ELNA
{QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS,
hdd_set_elna_bypass},
#endif
};
#ifdef WLAN_FEATURE_ELNA
/**
* hdd_get_elna_bypass() - Get eLNA bypass
* @adapter: Pointer to HDD adapter
* @skb: sk buffer to hold nl80211 attributes
* @attr: Pointer to struct nlattr
*
* Return: 0 on success; error number otherwise
*/
static int hdd_get_elna_bypass(struct hdd_adapter *adapter,
struct sk_buff *skb,
const struct nlattr *attr)
{
int ret;
struct wlan_objmgr_vdev *vdev;
vdev = hdd_objmgr_get_vdev(adapter);
if (!vdev)
return -EINVAL;
ret = os_if_fwol_get_elna_bypass(vdev, skb, attr);
hdd_objmgr_put_vdev(vdev);
return ret;
}
#endif
/**
* typedef config_getter_fn - get configuration handler
* @adapter: The adapter being configured
* @skb: sk buffer to hold nl80211 attributes
* @attr: The nl80211 attribute being applied
*
* Defines the signature of functions in the attribute vtable
*
* Return: 0 if the attribute was handled successfully, otherwise an errno
*/
typedef int (*config_getter_fn)(struct hdd_adapter *adapter,
struct sk_buff *skb,
const struct nlattr *attr);
/**
* struct config_getters
* @id: vendor attribute which this entry handles
* @cb: callback function to invoke to process the attribute when present
*/
struct config_getters {
uint32_t id;
size_t max_attr_len;
config_getter_fn cb;
};
/* vtable for config getters */
static const struct config_getters config_getters[] = {
#ifdef WLAN_FEATURE_ELNA
{QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS,
sizeof(uint8_t),
hdd_get_elna_bypass},
#endif
};
/**
* hdd_get_configuration() - Handle get configuration
* @adapter: adapter upon which the vendor command was received
* @tb: parsed attribute array
*
* This is a table-driven function which dispatches attributes
* in a QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION
* vendor command.
*
* Return: 0 if there were no issues, otherwise errno of the last issue
*/
static int hdd_get_configuration(struct hdd_adapter *adapter,
struct nlattr **tb)
{
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
uint32_t i, id;
unsigned long nl_buf_len = NLMSG_HDRLEN;
struct sk_buff *skb;
struct nlattr *attr;
config_getter_fn cb;
int errno = 0;
for (i = 0; i < QDF_ARRAY_SIZE(config_getters); i++) {
id = config_getters[i].id;
attr = tb[id];
if (!attr)
continue;
nl_buf_len += NLA_HDRLEN +
NLA_ALIGN(config_getters[i].max_attr_len);
}
skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
if (!skb) {
hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
return -ENOMEM;
}
for (i = 0; i < QDF_ARRAY_SIZE(config_getters); i++) {
id = config_getters[i].id;
attr = tb[id];
if (!attr)
continue;
cb = config_getters[i].cb;
errno = cb(adapter, skb, attr);
if (errno)
break;
}
if (errno) {
hdd_err("Failed to get wifi configuration, errno = %d", errno);
kfree_skb(skb);
return -EINVAL;
}
cfg80211_vendor_cmd_reply(skb);
return errno;
}
/**
* hdd_set_independent_configuration() - Handle independent attributes
* @adapter: adapter upon which the vendor command was received
@@ -7536,6 +7691,88 @@ static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
return errno;
}
/**
* __wlan_hdd_cfg80211_wifi_configuration_get() - Wifi configuration
* vendor command
* @wiphy: wiphy device pointer
* @wdev: wireless device pointer
* @data: Vendor command data buffer
* @data_len: Buffer length
*
* Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
*
* Return: Error code.
*/
static int
__wlan_hdd_cfg80211_wifi_configuration_get(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
struct net_device *dev = wdev->netdev;
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1];
int errno;
int ret;
hdd_enter_dev(dev);
if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
hdd_err("Command not allowed in FTM mode");
return -EPERM;
}
errno = wlan_hdd_validate_context(hdd_ctx);
if (errno)
return errno;
if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_CONFIG_MAX, data,
data_len, wlan_hdd_wifi_config_policy)) {
hdd_err("invalid attr");
return -EINVAL;
}
ret = hdd_get_configuration(adapter, tb);
if (ret)
errno = ret;
return errno;
}
/**
* wlan_hdd_cfg80211_wifi_configuration_get() - Wifi configuration
* vendor command
*
* @wiphy: wiphy device pointer
* @wdev: wireless device pointer
* @data: Vendor command data buffer
* @data_len: Buffer length
*
* Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
*
* Return: EOK or other error codes.
*/
static int wlan_hdd_cfg80211_wifi_configuration_get(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data,
int data_len)
{
int errno;
struct osif_vdev_sync *vdev_sync;
errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
if (errno)
return errno;
errno = __wlan_hdd_cfg80211_wifi_configuration_get(wiphy, wdev,
data, data_len);
osif_vdev_sync_op_stop(vdev_sync);
return errno;
}
/**
* __wlan_hdd_cfg80211_set_wifi_test_config() - Wifi test configuration
* vendor command
@@ -13498,6 +13735,14 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = wlan_hdd_cfg80211_wifi_configuration_set
},
{
.info.vendor_id = QCA_NL80211_VENDOR_ID,
.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION,
.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
WIPHY_VENDOR_CMD_NEED_NETDEV |
WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = wlan_hdd_cfg80211_wifi_configuration_get
},
{
.info.vendor_id = QCA_NL80211_VENDOR_ID,
.info.subcmd =

67
os_if/fw_offload/inc/os_if_fwol.h Normální soubor
Zobrazit soubor

@@ -0,0 +1,67 @@
/*
* 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: os_if_fwol.h
*
* This Header file provide declaration for OS interface API
*/
#ifndef __OS_IF_FWOL_H__
#define __OS_IF_FWOL_H__
#include "wlan_objmgr_vdev_obj.h"
#ifdef WLAN_FEATURE_ELNA
/**
* os_if_fwol_set_elna_bypass() - Set eLNA bypass
* @vdev: Pointer to vdev
* @attr: Pointer to struct nlattr
*
* Return: 0 on success; error number otherwise
*/
int os_if_fwol_set_elna_bypass(struct wlan_objmgr_vdev *vdev,
const struct nlattr *attr);
/**
* os_if_fwol_get_elna_bypass() - Get eLNA bypass
* @vdev: Pointer to vdev
* @skb: sk buffer to hold nl80211 attributes
* @attr: Pointer to struct nlattr
*
* Return: 0 on success; error number otherwise
*/
int os_if_fwol_get_elna_bypass(struct wlan_objmgr_vdev *vdev,
struct sk_buff *skb,
const struct nlattr *attr);
#else
static inline int os_if_fwol_set_elna_bypass(struct wlan_objmgr_vdev *vdev,
const struct nlattr *attr)
{
return 0;
}
static inline int os_if_fwol_get_elna_bypass(struct wlan_objmgr_vdev *vdev,
struct sk_buff *skb,
const struct nlattr *attr)
{
return 0;
}
#endif /* WLAN_FEATURE_ELNA */
#endif /* __OS_IF_FWOL_H__ */

133
os_if/fw_offload/src/os_if_fwol.c Normální soubor
Zobrazit soubor

@@ -0,0 +1,133 @@
/*
* 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: defines driver functions interfacing with linux kernel
*/
#include "wlan_cfg80211.h"
#include "wlan_osif_request_manager.h"
#include "wlan_fwol_public_structs.h"
#include "wlan_fwol_ucfg_api.h"
#include "os_if_fwol.h"
#ifdef WLAN_FEATURE_ELNA
#define WLAN_WAIT_TIME_GET_ELNA_BYPASS 1500
int os_if_fwol_set_elna_bypass(struct wlan_objmgr_vdev *vdev,
const struct nlattr *attr)
{
struct set_elna_bypass_request req;
QDF_STATUS status;
req.vdev_id = vdev->vdev_objmgr.vdev_id;
req.en_dis = nla_get_u8(attr);
if (req.en_dis > 1) {
osif_err("Invalid elna_bypass value %d", req.en_dis);
return -EINVAL;
}
status = ucfg_fwol_set_elna_bypass(vdev, &req);
if (!QDF_IS_STATUS_SUCCESS(status))
osif_err("Failed to set ELNA BYPASS, %d", status);
return qdf_status_to_os_return(status);
}
struct osif_get_elna_bypass_priv {
uint8_t en_dis;
};
/**
* os_if_fwol_get_elna_bypass_callback() - Get eLNA bypass callback
* @context: Call context
* @response: Pointer to response structure
*
* Return: void
*/
static void
os_if_fwol_get_elna_bypass_callback(void *context,
struct get_elna_bypass_response *response)
{
struct osif_request *request;
struct osif_get_elna_bypass_priv *priv;
request = osif_request_get(context);
if (!request) {
osif_err("Obsolete request");
return;
}
priv = osif_request_priv(request);
priv->en_dis = response->en_dis;
osif_request_complete(request);
osif_request_put(request);
}
int os_if_fwol_get_elna_bypass(struct wlan_objmgr_vdev *vdev,
struct sk_buff *skb,
const struct nlattr *attr)
{
struct get_elna_bypass_request req;
void *cookie;
struct osif_request *request;
struct osif_get_elna_bypass_priv *priv;
static const struct osif_request_params params = {
.priv_size = sizeof(*priv),
.timeout_ms = WLAN_WAIT_TIME_GET_ELNA_BYPASS,
};
QDF_STATUS status;
int ret = 0;
req.vdev_id = vdev->vdev_objmgr.vdev_id;
request = osif_request_alloc(&params);
if (!request) {
osif_err("Request allocation failure");
return -ENOMEM;
}
cookie = osif_request_cookie(request);
status = ucfg_fwol_get_elna_bypass(vdev, &req,
os_if_fwol_get_elna_bypass_callback,
cookie);
if (!QDF_IS_STATUS_SUCCESS(status)) {
osif_err("Failed to get ELNA BYPASS, %d", status);
ret = qdf_status_to_os_return(status);
goto end;
}
ret = osif_request_wait_for_response(request);
if (ret) {
osif_err("Operation timed out");
goto end;
}
priv = osif_request_priv(request);
if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS,
priv->en_dis)) {
osif_err("put fail");
ret = -EINVAL;
}
end:
osif_request_put(request);
return ret;
}
#endif /* #ifdef WLAN_FEATURE_ELNA */