diff --git a/init_deinit/dispatcher/src/dispatcher_init_deinit.c b/init_deinit/dispatcher/src/dispatcher_init_deinit.c index cc82036705..ff3f0da2e1 100644 --- a/init_deinit/dispatcher/src/dispatcher_init_deinit.c +++ b/init_deinit/dispatcher/src/dispatcher_init_deinit.c @@ -1007,6 +1007,28 @@ dispatcher_coex_psoc_close(struct wlan_objmgr_psoc *psoc) } #endif /* FEATURE_COEX */ +#ifdef WLAN_FEATURE_DBAM_CONFIG +static QDF_STATUS dbam_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + return wlan_dbam_psoc_enable(psoc); +} + +static QDF_STATUS dbam_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + return wlan_dbam_psoc_disable(psoc); +} +#else +static QDF_STATUS dbam_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS dbam_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* WLAN_FEATURE_DBAM_CONFIG */ + #ifdef WLAN_FEATURE_11BE_MLO static QDF_STATUS mlo_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc) { @@ -1423,8 +1445,13 @@ QDF_STATUS dispatcher_psoc_enable(struct wlan_objmgr_psoc *psoc) if (QDF_STATUS_SUCCESS != dispatcher_twt_psoc_enable(psoc)) goto twt_psoc_enable_fail; + if (QDF_STATUS_SUCCESS != dbam_psoc_enable(psoc)) + goto dbam_psoc_enable_fail; + return QDF_STATUS_SUCCESS; +dbam_psoc_enable_fail: + dispatcher_twt_psoc_disable(psoc); twt_psoc_enable_fail: mlo_mgr_psoc_disable(psoc); mlo_mgr_psoc_enable_fail: @@ -1464,6 +1491,8 @@ QDF_STATUS dispatcher_psoc_disable(struct wlan_objmgr_psoc *psoc) { QDF_STATUS status; + QDF_BUG(QDF_STATUS_SUCCESS == dbam_psoc_disable(psoc)); + QDF_BUG(QDF_STATUS_SUCCESS == dispatcher_twt_psoc_disable(psoc)); QDF_BUG(QDF_STATUS_SUCCESS == mlo_mgr_psoc_disable(psoc)); diff --git a/target_if/core/src/target_if_main.c b/target_if/core/src/target_if_main.c index 446d3791b2..e6d6c79b43 100644 --- a/target_if/core/src/target_if_main.c +++ b/target_if/core/src/target_if_main.c @@ -416,6 +416,20 @@ target_if_coex_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) } #endif +#ifdef WLAN_FEATURE_DBAM_CONFIG +static QDF_STATUS +target_if_dbam_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) +{ + return target_if_dbam_register_tx_ops(tx_ops); +} +#else +static inline QDF_STATUS +target_if_dbam_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops) +{ + return QDF_STATUS_SUCCESS; +} +#endif + static void target_if_target_tx_ops_register( struct wlan_lmac_if_tx_ops *tx_ops) { @@ -619,6 +633,8 @@ QDF_STATUS target_if_register_umac_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) target_if_twt_tx_ops_register(tx_ops); + target_if_dbam_tx_ops_register(tx_ops); + /* Converged UMAC components to register their TX-ops here */ return QDF_STATUS_SUCCESS; } diff --git a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h index 8c65ca55df..db0e5be127 100644 --- a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h +++ b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h @@ -98,6 +98,10 @@ struct dbr_module_config; #ifdef QCA_SUPPORT_CP_STATS #include +#ifdef WLAN_FEATURE_DBAM_CONFIG +#include "wlan_coex_public_structs.h" +#endif + /** * typedef cp_stats_event - Definition of cp stats event * Define stats_event from external cp stats component to cp_stats_event @@ -1263,6 +1267,28 @@ struct wlan_lmac_if_coex_tx_ops { }; #endif +#ifdef WLAN_FEATURE_DBAM_CONFIG +/** + * struct wlan_lmac_if_dbam_tx_ops - south bound tx function pointers for dbam + * @set_dbam_config: function pointer to send dbam config to fw + */ +struct wlan_lmac_if_dbam_tx_ops { + QDF_STATUS (*set_dbam_config)(struct wlan_objmgr_psoc *psoc, + struct coex_dbam_config_params *param); + QDF_STATUS (*dbam_event_attach)(struct wlan_objmgr_psoc *psoc); + QDF_STATUS (*dbam_event_detach)(struct wlan_objmgr_psoc *psoc); +}; + +/** + * struct wlan_lmac_if_dbam_rx_ops - defines southbound rx callback for dbam + * @dbam_resp_event: function pointer to rx dbam response event from FW + */ +struct wlan_lmac_if_dbam_rx_ops { + QDF_STATUS (*dbam_resp_event)(struct wlan_objmgr_psoc *psoc, + enum coex_dbam_comp_status dbam_resp); +}; +#endif + #ifdef WLAN_FEATURE_GPIO_CFG struct gpio_config_params; struct gpio_output_params; @@ -1455,6 +1481,7 @@ struct wlan_lmac_if_spatial_reuse_tx_ops { * @cp_stats_tx_ops: cp stats tx_ops * @coex_ops: coex tx_ops * @gpio_ops: gpio tx_ops + * @dbam_tx_ops: coex dbam tx_ops * * Callback function tabled to be registered with umac. * umac will use the functional table to send events/frames to wmi @@ -1534,6 +1561,10 @@ struct wlan_lmac_if_tx_ops { struct wlan_lmac_if_coex_tx_ops coex_ops; #endif +#ifdef WLAN_FEATURE_DBAM_CONFIG + struct wlan_lmac_if_dbam_tx_ops dbam_tx_ops; +#endif + #ifdef WLAN_FEATURE_GPIO_CFG struct wlan_lmac_if_gpio_tx_ops gpio_ops; #endif @@ -2288,6 +2319,7 @@ struct wlan_lmac_if_green_ap_rx_ops { * @green_ap_rx_ops: green ap rx ops * @ftm_rx_ops: ftm rx ops * @mlo_rx_ops: mlo rx ops + * @dbam_rx_ops: dbam rx ops * * Callback function tabled to be registered with lmac/wmi. * lmac will use the functional table to send events/frames to umac @@ -2357,6 +2389,9 @@ struct wlan_lmac_if_rx_ops { #if defined(WLAN_SUPPORT_TWT) && defined(WLAN_TWT_CONV_SUPPORTED) struct wlan_lmac_if_twt_rx_ops twt_rx_ops; #endif +#ifdef WLAN_FEATURE_DBAM_CONFIG + struct wlan_lmac_if_dbam_rx_ops dbam_rx_ops; +#endif }; /* Function pointer to call legacy tx_ops registration in OL/WMA. diff --git a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c b/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c index 6588434a74..8baa01e1d2 100644 --- a/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c +++ b/umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c @@ -88,6 +88,10 @@ #include #endif +#ifdef WLAN_FEATURE_DBAM_CONFIG +#include "target_if_coex.h" +#endif + #include "target_if.h" /* Function pointer for OL/WMA specific UMAC tx_ops @@ -930,6 +934,19 @@ void wlan_lmac_if_twt_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) } #endif /* WLAN_SUPPORT_TWT && WLAN_TWT_CONV_SUPPORTED */ +#ifdef WLAN_FEATURE_DBAM_CONFIG +static void +wlan_lmac_if_dbam_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) +{ + rx_ops->dbam_rx_ops.dbam_resp_event = target_if_dbam_process_event; +} +#else +static void +wlan_lmac_if_dbam_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) +{ +} +#endif /* WLAN_FEATURE_DBAM_CONFIG */ + /** * wlan_lmac_if_umac_rx_ops_register() - UMAC rx handler register * @rx_ops: Pointer to rx_ops structure to be populated @@ -997,6 +1014,8 @@ wlan_lmac_if_umac_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) wlan_lmac_if_twt_rx_ops_register(rx_ops); + wlan_lmac_if_dbam_rx_ops_register(rx_ops); + return QDF_STATUS_SUCCESS; } diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index f868e8a1dc..fffbf16b9a 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -123,6 +123,10 @@ #include "wmi_unified_11be_setup_api.h" #endif +#ifdef WLAN_FEATURE_DBAM_CONFIG +#include "wlan_coex_public_structs.h" +#endif + typedef qdf_nbuf_t wmi_buf_t; #define wmi_buf_data(_buf) qdf_nbuf_data(_buf) @@ -1993,6 +1997,32 @@ wmi_unified_send_coex_ver_cfg_cmd(wmi_unified_t wmi_handle, QDF_STATUS wmi_unified_send_coex_config_cmd(wmi_unified_t wmi_handle, struct coex_config_params *param); +#ifdef WLAN_FEATURE_DBAM_CONFIG +/** + * wmi_unified_send_dbam_config_cmd() - send dbam config command + * @wmi_handle: wmi handle + * @mode: dbam config mode param + * + * Send WMI_COEX_DBAM_CMD param to fw. + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS +wmi_unified_send_dbam_config_cmd(wmi_unified_t wmi_handle, + struct coex_dbam_config_params *param); + +/** + * wmi_extract_dbam_config_response() - extract dbam config resp sent by FW + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @resp: struct containing dbam config response sent by FW + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +QDF_STATUS +wmi_extract_dbam_config_response(wmi_unified_t wmi_handle, void *evt_buf, + struct coex_dbam_config_resp *resp); +#endif /** * wmi_unified_pdev_fips_cmd_send() - WMI pdev fips cmd function diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 1f94525aa4..4431bb5db3 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -5071,6 +5071,9 @@ typedef enum { #endif #ifdef WLAN_VENDOR_HANDOFF_CONTROL wmi_get_roam_vendor_control_param_event_id, +#endif +#ifdef WLAN_FEATURE_DBAM_CONFIG + wmi_coex_dbam_complete_event_id, #endif wmi_events_max, } wmi_conv_event_id; diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index eb0ef6c444..aaed5da999 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -103,6 +103,10 @@ #include #endif +#ifdef WLAN_FEATURE_DBAM_CONFIG +#include "wlan_coex_public_structs.h" +#endif + #define WMI_UNIFIED_MAX_EVENT 0x100 #ifdef WMI_EXT_DBG @@ -1796,6 +1800,15 @@ QDF_STATUS (*send_coex_config_cmd)(wmi_unified_t wmi_handle, struct coex_config_params *param); +#ifdef WLAN_FEATURE_DBAM_CONFIG +QDF_STATUS +(*send_dbam_config_cmd)(wmi_unified_t wmi_handle, + struct coex_dbam_config_params *param); +QDF_STATUS +(*extract_dbam_config_resp_event)(wmi_unified_t wmi_handle, void *evt_buf, + struct coex_dbam_config_resp *resp); +#endif + #ifdef OL_ATH_SMART_LOGGING QDF_STATUS (*send_smart_logging_enable_cmd)(wmi_unified_t wmi_handle, uint32_t param); diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index 1be14961ec..38098527d2 100644 --- a/wmi/src/wmi_unified_api.c +++ b/wmi/src/wmi_unified_api.c @@ -2864,6 +2864,30 @@ wmi_unified_send_coex_config_cmd(wmi_unified_t wmi_handle, return QDF_STATUS_E_FAILURE; } +#ifdef WLAN_FEATURE_DBAM_CONFIG +QDF_STATUS +wmi_unified_send_dbam_config_cmd(wmi_unified_t wmi_handle, + struct coex_dbam_config_params *param) +{ + if (wmi_handle->ops->send_dbam_config_cmd) + return wmi_handle->ops->send_dbam_config_cmd(wmi_handle, + param); + + return QDF_STATUS_E_FAILURE; +} + +QDF_STATUS +wmi_extract_dbam_config_response(wmi_unified_t wmi_handle, void *evt_buf, + struct coex_dbam_config_resp *resp) +{ + if (wmi_handle->ops->extract_dbam_config_resp_event) + return wmi_handle->ops->extract_dbam_config_resp_event( + wmi_handle, evt_buf, resp); + + return QDF_STATUS_E_FAILURE; +} +#endif + QDF_STATUS wmi_unified_send_request_get_rcpi_cmd(wmi_unified_t wmi_handle, struct rcpi_req *get_rcpi_param) diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 6d65a3ffa5..53b9f82078 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -8037,6 +8037,111 @@ send_coex_config_cmd_tlv(wmi_unified_t wmi_handle, return ret; } +#ifdef WLAN_FEATURE_DBAM_CONFIG + +static enum wmi_coex_dbam_mode_type +map_to_wmi_coex_dbam_mode_type(enum coex_dbam_config_mode mode) +{ + switch (mode) { + case COEX_DBAM_ENABLE: + return WMI_COEX_DBAM_ENABLE; + case COEX_DBAM_FORCE_ENABLE: + return WMI_COEX_DBAM_FORCED; + case COEX_DBAM_DISABLE: + default: + return WMI_COEX_DBAM_DISABLE; + } +} + +/** + * send_dbam_config_cmd_tlv() - send coex DBAM config command to fw + * @wmi_handle: wmi handle + * @param: pointer to coex dbam config param + * + * Return: 0 for success or error code + */ +static QDF_STATUS +send_dbam_config_cmd_tlv(wmi_unified_t wmi_handle, + struct coex_dbam_config_params *param) +{ + wmi_coex_dbam_cmd_fixed_param *cmd; + wmi_buf_t buf; + void *buf_ptr; + QDF_STATUS ret; + int32_t len; + + len = sizeof(*cmd); + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + wmi_err_rl("Failed to allocate wmi buffer"); + return QDF_STATUS_E_NOMEM; + } + + buf_ptr = wmi_buf_data(buf); + cmd = buf_ptr; + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_coex_dbam_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_coex_dbam_cmd_fixed_param)); + + cmd->vdev_id = param->vdev_id; + cmd->dbam_mode = map_to_wmi_coex_dbam_mode_type(param->dbam_mode); + + wmi_mtrace(WMI_COEX_DBAM_CMDID, cmd->vdev_id, 0); + ret = wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_COEX_DBAM_CMDID); + + if (QDF_IS_STATUS_ERROR(ret)) { + wmi_err("Sending DBAM CONFIG CMD failed"); + wmi_buf_free(buf); + return QDF_STATUS_E_FAILURE; + } + + return ret; +} + +static enum coex_dbam_comp_status +wmi_convert_dbam_comp_status(wmi_coex_dbam_comp_status status) +{ + switch (status) { + case WMI_COEX_DBAM_COMP_SUCCESS: + case WMI_COEX_DBAM_COMP_ONGOING: + case WMI_COEX_DBAM_COMP_DELAYED: + return COEX_DBAM_COMP_SUCCESS; + case WMI_COEX_DBAM_COMP_NOT_SUPPORT: + return COEX_DBAM_COMP_NOT_SUPPORT; + case WMI_COEX_DBAM_COMP_INVALID_PARAM: + case WMI_COEX_DBAM_COMP_FAIL: + default: + return COEX_DBAM_COMP_FAIL; + } +} + +/** + * extract_dbam_comp_status_event_tlv() - extract dbam complete status event + * @wmi_handle: WMI handle + * @evt_buf: event buffer + * @resp: pointer to coex dbam config response + * + * Return: QDF_STATUS + */ +static QDF_STATUS +extract_dbam_config_resp_event_tlv(wmi_unified_t wmi_handle, void *evt_buf, + struct coex_dbam_config_resp *resp) +{ + WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *param_buf; + wmi_coex_dbam_complete_event_fixed_param *event; + + param_buf = (WMI_COEX_DBAM_COMPLETE_EVENTID_param_tlvs *)evt_buf; + + event = param_buf->fixed_param; + + resp->dbam_resp = wmi_convert_dbam_comp_status(event->comp_status); + + return QDF_STATUS_SUCCESS; +} +#endif + #ifdef WLAN_SUPPORT_TWT static void wmi_copy_twt_resource_config(wmi_resource_config *resource_cfg, target_resource_config *tgt_res_cfg) @@ -18688,6 +18793,10 @@ struct wmi_ops tlv_ops = { #ifdef WLAN_FEATURE_PEER_TXQ_FLUSH_CONF .send_peer_txq_flush_config_cmd = send_peer_txq_flush_config_cmd_tlv, #endif +#ifdef WLAN_FEATURE_DBAM_CONFIG + .send_dbam_config_cmd = send_dbam_config_cmd_tlv, + .extract_dbam_config_resp_event = extract_dbam_config_resp_event_tlv, +#endif }; #ifdef WLAN_FEATURE_11BE_MLO @@ -19166,6 +19275,10 @@ static void populate_tlv_events_id(uint32_t *event_ids) event_ids[wmi_get_roam_vendor_control_param_event_id] = WMI_ROAM_GET_VENDOR_CONTROL_PARAM_EVENTID; #endif +#ifdef WLAN_FEATURE_DBAM_CONFIG + event_ids[wmi_coex_dbam_complete_event_id] = + WMI_COEX_DBAM_COMPLETE_EVENTID; +#endif } #ifdef WLAN_FEATURE_LINK_LAYER_STATS