diff --git a/target_if/core/inc/target_if.h b/target_if/core/inc/target_if.h index 5c7857a307..78388babaf 100644 --- a/target_if/core/inc/target_if.h +++ b/target_if/core/inc/target_if.h @@ -2652,4 +2652,40 @@ static inline enum QDF_GLOBAL_MODE target_psoc_get_device_mode */ 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 54d262d0a6..54ab709a31 100644 --- a/target_if/init_deinit/inc/service_ready_param.h +++ b/target_if/init_deinit/inc/service_ready_param.h @@ -427,6 +427,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; @@ -442,6 +443,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 62970a1479..7aa16254ff 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 22f3f1aa24..4e5f043123 100644 --- a/target_if/init_deinit/src/init_event_handler.c +++ b/target_if/init_deinit/src/init_event_handler.c @@ -320,6 +320,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 b393073eb8..9aec012d0a 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 ef83a485d8..ed54bb230d 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -1999,6 +1999,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 7a2ab5307a..f443718b0d 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 e5518b1958..f3ded0c4df 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 fb53feca97..40370ceb93 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 fbfe37f731..ec27e8eb8e 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); }