diff --git a/target_if/core/inc/target_if.h b/target_if/core/inc/target_if.h index 84fdfc31454c..dd650b35e8a6 100644 --- a/target_if/core/inc/target_if.h +++ b/target_if/core/inc/target_if.h @@ -2549,4 +2549,40 @@ static inline void target_psoc_get_mu_max_users( */ void target_if_set_reg_cc_ext_supp(struct target_psoc_info *tgt_hdl, struct wlan_objmgr_psoc *psoc); + +/** + * target_psoc_set_twt_ack_cap() - Set twt ack capability + * + * @psoc_info: Pointer to struct target_psoc_info. + * @val: twt ack cap value + * + * Return: None + * + */ +static inline +void target_psoc_set_twt_ack_cap(struct target_psoc_info *psoc_info, bool val) +{ + if (!psoc_info) + return; + + psoc_info->info.service_ext2_param.twt_ack_support_cap = val; +} + +/** + * target_psoc_get_twt_ack_cap() - Get twt ack capability + * + * @psoc_info: Pointer to struct target_psoc_info. + * @val: twt ack cap value + * + * Return: None + * + */ +static inline +void target_psoc_get_twt_ack_cap(struct target_psoc_info *psoc_info, bool *val) +{ + if (!psoc_info) + return; + + *val = psoc_info->info.service_ext2_param.twt_ack_support_cap; +} #endif diff --git a/target_if/init_deinit/inc/service_ready_param.h b/target_if/init_deinit/inc/service_ready_param.h index 641f8160427a..b964a0199455 100644 --- a/target_if/init_deinit/inc/service_ready_param.h +++ b/target_if/init_deinit/inc/service_ready_param.h @@ -404,6 +404,7 @@ struct wlan_psoc_host_service_ext_param { * @max_users_ul_ofdma: Max number of users per-PPDU for Uplink OFDMA * @max_users_dl_mumimo: Max number of users per-PPDU for Downlink MU-MIMO * @max_users_ul_mumimo: Max number of users per-PPDU for Uplink MU-MIMO + * @twt_ack_support_cap: TWT ack capability support */ struct wlan_psoc_host_service_ext2_param { uint8_t reg_db_version_major; @@ -419,6 +420,7 @@ struct wlan_psoc_host_service_ext2_param { uint16_t max_users_ul_ofdma; uint16_t max_users_dl_mumimo; uint16_t max_users_ul_mumimo; + uint32_t twt_ack_support_cap:1; }; #endif /* _SERVICE_READY_PARAM_H_*/ diff --git a/target_if/init_deinit/inc/service_ready_util.h b/target_if/init_deinit/inc/service_ready_util.h index 62970a147927..7aa16254ffa7 100644 --- a/target_if/init_deinit/inc/service_ready_util.h +++ b/target_if/init_deinit/inc/service_ready_util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021 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 @@ -304,6 +304,31 @@ int init_deinit_populate_scan_radio_cap_ext2(wmi_unified_t handle, uint8_t *event, struct tgt_info *info); +#ifdef WLAN_SUPPORT_TWT +/** + * init_deinit_populate_twt_cap_ext2() - populate twt capabilities from service + * ready ext2 event + * @psoc: PSOC object + * @handle: WMI handle pointer + * @event: event buffer received from FW + * @info: tgt_info object + * + * API to populate twt capability from service ready ext2 event. + * Return: zero on successful population of twt capability or failure + */ +int init_deinit_populate_twt_cap_ext2(struct wlan_objmgr_psoc *psoc, + wmi_unified_t handle, uint8_t *event, + struct tgt_info *info); +#else +static inline +int init_deinit_populate_twt_cap_ext2(struct wlan_objmgr_psoc *psoc, + wmi_unified_t handle, uint8_t *event, + struct tgt_info *info) +{ + return 0; +} +#endif + /** * init_deinit_validate_160_80p80_fw_caps() - validate 160 80p80 fw caps * @psoc: PSOC object diff --git a/target_if/init_deinit/src/init_event_handler.c b/target_if/init_deinit/src/init_event_handler.c index ffc67bb0599f..0f5b9b45683c 100644 --- a/target_if/init_deinit/src/init_event_handler.c +++ b/target_if/init_deinit/src/init_event_handler.c @@ -312,6 +312,12 @@ static int init_deinit_service_ext2_ready_event_handler(ol_scn_t scn_handle, goto exit; } + err_code = init_deinit_populate_twt_cap_ext2(psoc, wmi_handle, event, + info); + + if (err_code) + target_if_debug("failed to populate twt cap ext2"); + target_if_regulatory_set_ext_tpc(psoc); target_if_reg_set_lower_6g_edge_ch_info(psoc); diff --git a/target_if/init_deinit/src/service_ready_util.c b/target_if/init_deinit/src/service_ready_util.c index d5579ecb77f8..8ce3ca43f142 100644 --- a/target_if/init_deinit/src/service_ready_util.c +++ b/target_if/init_deinit/src/service_ready_util.c @@ -535,6 +535,31 @@ free_and_return: return qdf_status_to_os_return(status); } +#ifdef WLAN_SUPPORT_TWT +int init_deinit_populate_twt_cap_ext2(struct wlan_objmgr_psoc *psoc, + wmi_unified_t handle, uint8_t *event, + struct tgt_info *info) +{ + struct wmi_twt_cap_bitmap_params param; + struct target_psoc_info *psoc_info; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + status = wmi_extract_twt_cap_service_ready_ext2(handle, event, + ¶m); + if (QDF_IS_STATUS_ERROR(status)) { + target_if_err("Extraction of twt capability failed"); + goto exit; + } + + psoc_info = wlan_psoc_get_tgt_if_handle(psoc); + + target_psoc_set_twt_ack_cap(psoc_info, param.twt_ack_support_cap); + +exit: + return qdf_status_to_os_return(status); +} +#endif + QDF_STATUS init_deinit_dbr_ring_cap_free( struct target_psoc_info *tgt_psoc_info) { diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 011e48e961a1..589ab5d5e81a 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -1941,6 +1941,13 @@ QDF_STATUS (*extract_sar_cap_service_ready_ext)( uint8_t *evt_buf, struct wlan_psoc_host_service_ext_param *ext_param); +#ifdef WLAN_SUPPORT_TWT +QDF_STATUS (*extract_twt_cap_service_ready_ext2)( + wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_twt_cap_bitmap_params *var); +#endif + #ifdef WMI_DBR_SUPPORT QDF_STATUS (*send_dbr_cfg_cmd)(wmi_unified_t wmi_handle, struct direct_buf_rx_cfg_req *cfg); diff --git a/wmi/inc/wmi_unified_twt_api.h b/wmi/inc/wmi_unified_twt_api.h index 7a2ab5307aa1..f443718b0d82 100644 --- a/wmi/inc/wmi_unified_twt_api.h +++ b/wmi/inc/wmi_unified_twt_api.h @@ -326,4 +326,19 @@ static void wmi_twt_attach_tlv(struct wmi_unified *wmi_handle) } #endif +/** + * wmi_extract_twt_cap_service_ready_ext2: Extract TWT bitmap value + * received through extended + * service ready2 event + * @wmi_handle: WMI handle + * @evt_buf: Event buffer + * @param: Pointer to TWT bitmap param + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +QDF_STATUS wmi_extract_twt_cap_service_ready_ext2( + wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_twt_cap_bitmap_params *params); + #endif /* _WMI_UNIFIED_TWT_API_H_ */ diff --git a/wmi/inc/wmi_unified_twt_param.h b/wmi/inc/wmi_unified_twt_param.h index e5518b1958f5..f3ded0c4df47 100644 --- a/wmi/inc/wmi_unified_twt_param.h +++ b/wmi/inc/wmi_unified_twt_param.h @@ -394,6 +394,15 @@ struct wmi_twt_add_dialog_complete_event_param { uint32_t num_additional_twt_params; }; +/** + * struct wmi_twt_cap_bitmap_params - + * twt_cap_bitmap: TWT capability bitmap + * + */ +struct wmi_twt_cap_bitmap_params { + uint32_t twt_ack_support_cap:1; +}; + /** * struct wmi_twt_del_dialog_param - * @vdev_id: VDEV identifier diff --git a/wmi/src/wmi_unified_twt_api.c b/wmi/src/wmi_unified_twt_api.c index fb53feca9765..40370ceb931b 100644 --- a/wmi/src/wmi_unified_twt_api.c +++ b/wmi/src/wmi_unified_twt_api.c @@ -286,3 +286,15 @@ QDF_STATUS wmi_extract_twt_session_stats_data( return QDF_STATUS_E_FAILURE; } + +QDF_STATUS wmi_extract_twt_cap_service_ready_ext2( + wmi_unified_t wmi_handle, + uint8_t *evt_buf, + struct wmi_twt_cap_bitmap_params *params) +{ + if (wmi_handle->ops->extract_twt_cap_service_ready_ext2) + return wmi_handle->ops->extract_twt_cap_service_ready_ext2( + wmi_handle, evt_buf, params); + + return QDF_STATUS_E_FAILURE; +} diff --git a/wmi/src/wmi_unified_twt_tlv.c b/wmi/src/wmi_unified_twt_tlv.c index fbfe37f7314f..ec27e8eb8e8a 100644 --- a/wmi/src/wmi_unified_twt_tlv.c +++ b/wmi/src/wmi_unified_twt_tlv.c @@ -1028,6 +1028,27 @@ extract_twt_session_stats_event_data(wmi_unified_t wmi_handle, return QDF_STATUS_SUCCESS; } +static QDF_STATUS extract_twt_cap_service_ready_ext2_tlv( + wmi_unified_t wmi_handle, uint8_t *event, + struct wmi_twt_cap_bitmap_params *var) +{ + WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf; + wmi_twt_caps_params *twt_caps; + + param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event; + if (!param_buf) + return QDF_STATUS_E_INVAL; + + twt_caps = param_buf->twt_caps; + if (!twt_caps) + return QDF_STATUS_E_INVAL; + + var->twt_ack_support_cap = WMI_GET_BITS(twt_caps->twt_capability_bitmap, + 0, 1); + + return QDF_STATUS_SUCCESS; +} + void wmi_twt_attach_tlv(wmi_unified_t wmi_handle) { struct wmi_ops *ops = wmi_handle->ops; @@ -1060,5 +1081,8 @@ void wmi_twt_attach_tlv(wmi_unified_t wmi_handle) extract_twt_session_stats_event_data; ops->extract_twt_notify_event = extract_twt_notify_event_tlv; + ops->extract_twt_cap_service_ready_ext2 = + extract_twt_cap_service_ready_ext2_tlv, + wmi_twt_attach_bcast_twt_tlv(ops); }