From 2c14fae3d5ceb135d742c6a503b6c3a83bde94fe Mon Sep 17 00:00:00 2001 From: Min Liu Date: Wed, 3 Jul 2019 17:57:58 +0800 Subject: [PATCH] qcacmn: Add interface to get / set eLNA bypass Add interface to get / set eLNA bypass from / to firmware via WMI. Change-Id: I2ed78aece6703c18999fdfbfdfa159a2abd477a6 CRs-Fixed: 2498526 --- .../obj_mgr/inc/wlan_objmgr_cmn.h | 6 + wmi/inc/wmi_unified_api.h | 4 + wmi/inc/wmi_unified_fwol_api.h | 68 ++++++++ wmi/inc/wmi_unified_param.h | 1 + wmi/inc/wmi_unified_priv.h | 28 +++ wmi/src/wmi_unified_fwol_api.c | 60 +++++++ wmi/src/wmi_unified_fwol_tlv.c | 160 ++++++++++++++++++ wmi/src/wmi_unified_tlv.c | 2 + 8 files changed, 329 insertions(+) create mode 100644 wmi/inc/wmi_unified_fwol_api.h create mode 100644 wmi/src/wmi_unified_fwol_api.c create mode 100644 wmi/src/wmi_unified_fwol_tlv.c diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h index 81128cdfd8..cf0d2d4d33 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h @@ -254,6 +254,8 @@ typedef void (*wlan_objmgr_peer_status_handler)( * @WLAN_MLME_OBJMGR_ID: MLME object manager operations VAP, Node * @WLAN_OFFCHAN_TX_ID: Offchannel Tx operations * @WLAN_MISC_ID: power manager, PAPI, rate set, etc. + * @WLAN_FWOL_NB_ID: fw offload northbound operations + * @WLAN_FWOL_SB_ID: fw offload southbound operations * @WLAN_REF_ID_MAX: Max id used to generate ref count tracking array */ /* New value added to the enum must also be reflected in function @@ -330,6 +332,8 @@ typedef enum { WLAN_MLME_OBJMGR_ID = 67, WLAN_OFFCHAN_TX_ID = 68, WLAN_MISC_ID = 69, + WLAN_FWOL_NB_ID = 70, + WLAN_FWOL_SB_ID = 71, WLAN_REF_ID_MAX, } wlan_objmgr_ref_dbgid; @@ -413,6 +417,8 @@ static inline char *string_from_dbgid(wlan_objmgr_ref_dbgid id) "WLAN_MLME_OBJMGR_ID", "WLAN_OFFCHAN_TX_ID", "WLAN_MISC_ID", + "WLAN_FWOL_NB_ID", + "WLAN_FWOL_SB_ID", "WLAN_REF_ID_MAX"}; return (char *)strings[id]; diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index af5ceee7c7..eef3c56dd2 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -96,6 +96,10 @@ #include "wmi_unified_sta_api.h" #endif +#ifdef WLAN_FW_OFFLOAD +#include "wmi_unified_fwol_api.h" +#endif + typedef qdf_nbuf_t wmi_buf_t; #define wmi_buf_data(_buf) qdf_nbuf_data(_buf) diff --git a/wmi/inc/wmi_unified_fwol_api.h b/wmi/inc/wmi_unified_fwol_api.h new file mode 100644 index 0000000000..dcc77fa0b1 --- /dev/null +++ b/wmi/inc/wmi_unified_fwol_api.h @@ -0,0 +1,68 @@ +/* + * 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: Implement API's specific to fw offload component. + */ + +#ifndef _WMI_UNIFIED_FWOL_API_H_ +#define _WMI_UNIFIED_FWOL_API_H_ +#include "wlan_fwol_public_structs.h" + +#ifdef WLAN_FEATURE_ELNA +/** + * wmi_unified_send_set_elna_bypass_cmd() - Send WMI set eLNA bypass cmd + * @wmi_handle: wmi handle + * @req: set eLNA bypass request + * + * Send WMI set eLNA bypass command to firmware. + * + * Return: QDF_STATUS + */ +QDF_STATUS +wmi_unified_send_set_elna_bypass_cmd(struct wmi_unified *wmi_handle, + struct set_elna_bypass_request *req); + +/** + * wmi_unified_send_get_elna_bypass_cmd() - Send WMI get eLNA bypass cmd + * @wmi_handle: wmi handle + * @req: get eLNA bypass request + * + * Send WMI get eLNA bypass command to firmware. + * + * Return: QDF_STATUS + */ +QDF_STATUS +wmi_unified_send_get_elna_bypass_cmd(struct wmi_unified *wmi_handle, + struct get_elna_bypass_request *req); + +/** + * wmi_extract_get_elna_bypass_resp() - Extract WMI get eLNA bypass response + * @wmi_handle: wmi handle + * @resp_buf: response buffer + * @resp: get eLNA bypass response + * + * Extract WMI get eLNA bypass response from firmware. + * + * Return: QDF_STATUS + */ +QDF_STATUS +wmi_extract_get_elna_bypass_resp(struct wmi_unified *wmi_handle, void *resp_buf, + struct get_elna_bypass_response *resp); +#endif /* WLAN_FEATURE_ELNA */ + +#endif /* _WMI_UNIFIED_FWOL_API_H_ */ diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 209c5386b9..10a7121726 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -4521,6 +4521,7 @@ typedef enum { wmi_chan_rf_characterization_info_event_id, wmi_roam_auth_offload_event_id, wmi_service_ready_ext2_event_id, + wmi_get_elna_bypass_event_id, wmi_events_max, } wmi_conv_event_id; diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 11249a3e30..86096255bb 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -29,6 +29,10 @@ #include "qdf_atomic.h" #include +#ifdef WLAN_FW_OFFLOAD +#include "wlan_fwol_public_structs.h" +#endif + #ifdef DFS_COMPONENT_ENABLE #include #endif @@ -2021,6 +2025,16 @@ QDF_STATUS (*extract_hw_mode_resp_event)(wmi_unified_t wmi_handle, QDF_STATUS (*send_set_roam_trigger_cmd)(wmi_unified_t wmi_handle, uint32_t vdev_id, uint32_t trigger_bitmap); + +#ifdef WLAN_FEATURE_ELNA +QDF_STATUS (*send_set_elna_bypass_cmd)(wmi_unified_t wmi_handle, + struct set_elna_bypass_request *req); +QDF_STATUS (*send_get_elna_bypass_cmd)(wmi_unified_t wmi_handle, + struct get_elna_bypass_request *req); +QDF_STATUS (*extract_get_elna_bypass_resp)(wmi_unified_t wmi_handle, + void *resp_buf, + struct get_elna_bypass_response *resp); +#endif /* WLAN_FEATURE_ELNA */ }; /* Forward declartion for psoc*/ @@ -2404,6 +2418,20 @@ static inline void wmi_bcn_attach_tlv(wmi_unified_t wmi_handle) } #endif +/** + * wmi_fwol_attach_tlv() - attach fw offload tlv handlers + * @wmi_handle: wmi handle + * + * Return: void + */ +#ifdef WLAN_FW_OFFLOAD +void wmi_fwol_attach_tlv(wmi_unified_t wmi_handle); +#else +static inline void wmi_fwol_attach_tlv(wmi_unified_t wmi_handle) +{ +} +#endif + /** * wmi_align() - provides word aligned parameter * @param: parameter to be aligned diff --git a/wmi/src/wmi_unified_fwol_api.c b/wmi/src/wmi_unified_fwol_api.c new file mode 100644 index 0000000000..7ccb46cade --- /dev/null +++ b/wmi/src/wmi_unified_fwol_api.c @@ -0,0 +1,60 @@ +/* + * 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: Implement API's specific to fw offload component. + */ + +#include "wmi_unified_priv.h" +#include "wlan_fwol_public_structs.h" +#include "wmi_unified_fwol_api.h" + +#ifdef WLAN_FEATURE_ELNA +QDF_STATUS +wmi_unified_send_set_elna_bypass_cmd(struct wmi_unified *wmi_handle, + struct set_elna_bypass_request *req) +{ + if (wmi_handle->ops->send_set_elna_bypass_cmd) + return wmi_handle->ops->send_set_elna_bypass_cmd(wmi_handle, + req); + + return QDF_STATUS_E_FAILURE; +} + +QDF_STATUS +wmi_unified_send_get_elna_bypass_cmd(struct wmi_unified *wmi_handle, + struct get_elna_bypass_request *req) +{ + if (wmi_handle->ops->send_get_elna_bypass_cmd) + return wmi_handle->ops->send_get_elna_bypass_cmd(wmi_handle, + req); + + return QDF_STATUS_E_FAILURE; +} + +QDF_STATUS +wmi_extract_get_elna_bypass_resp(struct wmi_unified *wmi_handle, void *resp_buf, + struct get_elna_bypass_response *resp) +{ + if (wmi_handle->ops->extract_get_elna_bypass_resp) + return wmi_handle->ops->extract_get_elna_bypass_resp(wmi_handle, + resp_buf, + resp); + + return QDF_STATUS_E_FAILURE; +} +#endif /* WLAN_FEATURE_ELNA */ diff --git a/wmi/src/wmi_unified_fwol_tlv.c b/wmi/src/wmi_unified_fwol_tlv.c new file mode 100644 index 0000000000..13663bc572 --- /dev/null +++ b/wmi/src/wmi_unified_fwol_tlv.c @@ -0,0 +1,160 @@ +/* + * 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. + */ + +#include "osdep.h" +#include "wmi.h" +#include "wmi_unified_priv.h" +#include "wlan_fwol_public_structs.h" +#include "wmi_unified_fwol_api.h" + +#ifdef WLAN_FEATURE_ELNA +/** + * send_set_elna_bypass_cmd_tlv() - send set elna bypass cmd to fw + * @wmi_handle: wmi handle + * @req: set eLNA bypass request + * + * Send WMI_SET_ELNA_BYPASS_CMDID to fw. + * + * Return: QDF_STATUS + */ +static QDF_STATUS +send_set_elna_bypass_cmd_tlv(wmi_unified_t wmi_handle, + struct set_elna_bypass_request *req) +{ + wmi_buf_t buf; + wmi_set_elna_bypass_cmd_fixed_param *cmd; + uint16_t len = sizeof(*cmd); + QDF_STATUS ret; + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); + return QDF_STATUS_E_NOMEM; + } + + cmd = (wmi_set_elna_bypass_cmd_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_set_elna_bypass_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN + (wmi_set_elna_bypass_cmd_fixed_param)); + cmd->vdev_id = req->vdev_id; + cmd->en_dis = req->en_dis; + wmi_mtrace(WMI_SET_ELNA_BYPASS_CMDID, req->vdev_id, req->en_dis); + ret = wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_SET_ELNA_BYPASS_CMDID); + if (QDF_IS_STATUS_ERROR(ret)) { + WMI_LOGE("Failed to send set param command ret = %d", ret); + wmi_buf_free(buf); + } + + return ret; +} + +/** + * send_get_elna_bypass_cmd_tlv() - send get elna bypass cmd to fw + * @wmi_handle: wmi handle + * @req: get eLNA bypass request + * + * Send WMI_GET_ELNA_BYPASS_CMDID to fw. + * + * Return: QDF_STATUS + */ +static QDF_STATUS +send_get_elna_bypass_cmd_tlv(wmi_unified_t wmi_handle, + struct get_elna_bypass_request *req) +{ + wmi_buf_t buf; + wmi_get_elna_bypass_cmd_fixed_param *cmd; + uint16_t len = sizeof(*cmd); + QDF_STATUS ret; + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + WMI_LOGE("%s: Failed to allocate wmi buffer", __func__); + return QDF_STATUS_E_NOMEM; + } + + cmd = (wmi_get_elna_bypass_cmd_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_get_elna_bypass_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN + (wmi_get_elna_bypass_cmd_fixed_param)); + cmd->vdev_id = req->vdev_id; + wmi_mtrace(WMI_GET_ELNA_BYPASS_CMDID, req->vdev_id, 0); + ret = wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_GET_ELNA_BYPASS_CMDID); + if (QDF_IS_STATUS_ERROR(ret)) { + WMI_LOGE("Failed to send set param command ret = %d", ret); + wmi_buf_free(buf); + } + + return ret; +} + +/** + * extract_get_elna_bypass_resp_tlv() - Extract WMI get eLNA bypass response + * @wmi_handle: wmi handle + * @resp_buf: response buffer + * @resp: get eLNA bypass response + * + * Extract WMI get eLNA bypass response from firmware. + * + * Return: QDF_STATUS + */ +static QDF_STATUS +extract_get_elna_bypass_resp_tlv(struct wmi_unified *wmi_handle, void *resp_buf, + struct get_elna_bypass_response *resp) +{ + WMI_GET_ELNA_BYPASS_EVENTID_param_tlvs *param_buf; + wmi_get_elna_bypass_event_fixed_param *evt; + + param_buf = resp_buf; + evt = param_buf->fixed_param; + if (!evt) { + WMI_LOGE("Invalid get elna bypass event"); + return QDF_STATUS_E_INVAL; + } + + WMI_LOGD("Get elna bypass %d from vdev %d", evt->en_dis, evt->vdev_id); + + resp->vdev_id = evt->vdev_id; + resp->en_dis = evt->en_dis; + + return QDF_STATUS_SUCCESS; +} +#endif /* WLAN_FEATURE_ELNA */ + +#ifdef WLAN_FEATURE_ELNA +static void wmi_fwol_attach_elna_tlv(struct wmi_ops *ops) +{ + ops->send_set_elna_bypass_cmd = send_set_elna_bypass_cmd_tlv; + ops->send_get_elna_bypass_cmd = send_get_elna_bypass_cmd_tlv; + ops->extract_get_elna_bypass_resp = extract_get_elna_bypass_resp_tlv; +} +#else +static void wmi_fwol_attach_elna_tlv(struct wmi_ops *ops) +{ +} +#endif /* WLAN_FEATURE_ELNA */ + +void wmi_fwol_attach_tlv(wmi_unified_t wmi_handle) +{ + struct wmi_ops *ops = wmi_handle->ops; + + wmi_fwol_attach_elna_tlv(ops); +} diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 122257f8ec..c77f6988f6 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -12560,6 +12560,7 @@ static void populate_tlv_events_id(uint32_t *event_ids) WMI_CHAN_RF_CHARACTERIZATION_INFO_EVENTID; event_ids[wmi_roam_auth_offload_event_id] = WMI_ROAM_PREAUTH_START_EVENTID; + event_ids[wmi_get_elna_bypass_event_id] = WMI_GET_ELNA_BYPASS_EVENTID; } /** @@ -12885,6 +12886,7 @@ void wmi_tlv_attach(wmi_unified_t wmi_handle) wmi_pmo_attach_tlv(wmi_handle); wmi_sta_attach_tlv(wmi_handle); wmi_11ax_bss_color_attach_tlv(wmi_handle); + wmi_fwol_attach_tlv(wmi_handle); } qdf_export_symbol(wmi_tlv_attach);