From 11fa724d8a783e45e0da8093b8b003d28c5c914c Mon Sep 17 00:00:00 2001 From: Shiva Krishna Pittala Date: Sun, 13 Nov 2022 04:36:35 +0530 Subject: [PATCH] qcacmn: Add support to extract link removal TLVs from MGMT Rx event To assist the Host in ML reconfiguration element construction for probe responses, FW sends MLO link removal information as part of the MGMT Rx event containing the corresponding probe request. This information is an array of TLVs, one TLV for each link that is undergoing link removal from the MLD for which this probe request is intended. The TLV carries the link removal TBTT countdown value maintained by the FW for that link. Add support to extract the same. CRs-Fixed: 3335361 Change-Id: I16c6791a443ddb166da596d404a52ff2a38da291 --- target_if/core/src/target_if_main.c | 2 - target_if/mlo_mgr/inc/target_if_mlo_mgr.h | 30 +++++++++- target_if/mlo_mgr/src/target_if_mlo_mgr.c | 49 ++++++++++++++++ .../dispatcher/inc/wlan_mgmt_txrx_utils_api.h | 16 +++++- .../mlo_mgr/inc/wlan_mlo_mgr_public_structs.h | 13 +++++ wmi/inc/wmi_unified_11be_api.h | 16 ++++++ wmi/inc/wmi_unified_11be_tlv.h | 23 ++++++++ wmi/inc/wmi_unified_priv.h | 6 ++ wmi/src/wmi_unified_11be_api.c | 15 +++++ wmi/src/wmi_unified_11be_tlv.c | 57 +++++++++++++++++++ wmi/src/wmi_unified_tlv.c | 3 + 11 files changed, 224 insertions(+), 6 deletions(-) diff --git a/target_if/core/src/target_if_main.c b/target_if/core/src/target_if_main.c index 07e5fa64cb..d6d4990c3e 100644 --- a/target_if/core/src/target_if_main.c +++ b/target_if/core/src/target_if_main.c @@ -111,9 +111,7 @@ #include "wmi_unified_api.h" #include -#ifdef WLAN_FEATURE_11BE_MLO #include -#endif #ifdef WLAN_FEATURE_COAP #include diff --git a/target_if/mlo_mgr/inc/target_if_mlo_mgr.h b/target_if/mlo_mgr/inc/target_if_mlo_mgr.h index 61715b8cf9..898d0a85c0 100644 --- a/target_if/mlo_mgr/inc/target_if_mlo_mgr.h +++ b/target_if/mlo_mgr/inc/target_if_mlo_mgr.h @@ -27,9 +27,10 @@ #include #include +#ifdef WLAN_FEATURE_11BE_MLO /** * target_if_mlo_get_rx_ops() - get rx ops - * @tx_ops: pointer to target_if tx ops + * @psoc: pointer to soc object * * API to retrieve the MLO rx ops from the psoc context * @@ -51,7 +52,7 @@ target_if_mlo_get_rx_ops(struct wlan_objmgr_psoc *psoc) /** * target_if_mlo_get_tx_ops() - get tx ops - * @tx_ops: pointer to target_if tx ops + * @psoc: pointer to soc object * * API to retrieve the MLO tx ops from the psoc context * @@ -92,5 +93,28 @@ QDF_STATUS target_if_mlo_send_link_removal_cmd( struct wlan_objmgr_psoc *psoc, const struct mlo_link_removal_cmd_params *param); +/** + * target_if_extract_mlo_link_removal_info_mgmt_rx() - Extract MLO link removal + * information from MGMT Rx event + * @wmi_handle: WMI handle + * @evt_buf: Event buffer + * @rx_event: MGMT Rx event parameters + * + * Return: QDF_STATUS of operation + */ +QDF_STATUS +target_if_extract_mlo_link_removal_info_mgmt_rx( + wmi_unified_t wmi_handle, + void *evt_buf, + struct mgmt_rx_event_params *rx_event); +#else +static inline QDF_STATUS +target_if_extract_mlo_link_removal_info_mgmt_rx( + wmi_unified_t wmi_handle, + void *evt_buf, + struct mgmt_rx_event_params *rx_event) +{ + return QDF_STATUS_SUCCESS; +} +#endif #endif /* __TARGET_IF_MLO_MGR_H__ */ - diff --git a/target_if/mlo_mgr/src/target_if_mlo_mgr.c b/target_if/mlo_mgr/src/target_if_mlo_mgr.c index 12e9350361..87bd99de47 100644 --- a/target_if/mlo_mgr/src/target_if_mlo_mgr.c +++ b/target_if/mlo_mgr/src/target_if_mlo_mgr.c @@ -142,6 +142,55 @@ exit: return qdf_status_to_os_return(status); } +QDF_STATUS +target_if_extract_mlo_link_removal_info_mgmt_rx( + wmi_unified_t wmi_handle, + void *evt_buf, + struct mgmt_rx_event_params *rx_event) +{ + QDF_STATUS status; + struct mgmt_rx_mlo_link_removal_info *link_removal_info; + + if (!rx_event) { + target_if_err("Invalid rx_event"); + return QDF_STATUS_E_NULL_VALUE; + } + + rx_event->link_removal_info = NULL; + if (!rx_event->num_link_removal_info) { + /** + * This is not an error. Only probe request frames will contain + * Link removal TLVs, that too only till the link removal TBTT + * countdown completion. + */ + target_if_debug("Link removal TLVs are not present"); + return QDF_STATUS_SUCCESS; + } + + link_removal_info = qdf_mem_malloc(rx_event->num_link_removal_info * + sizeof(*link_removal_info)); + if (!link_removal_info) { + target_if_err("Couldn't allocate memory for link_removal_info"); + rx_event->num_link_removal_info = 0; + return QDF_STATUS_E_NOMEM; + } + + status = wmi_extract_mgmt_rx_mlo_link_removal_info( + wmi_handle, evt_buf, + link_removal_info, + rx_event->num_link_removal_info); + if (QDF_IS_STATUS_ERROR(status)) { + target_if_err("Unable to extract link removal TLVs"); + rx_event->num_link_removal_info = 0; + qdf_mem_free(link_removal_info); + return status; + } + + rx_event->link_removal_info = link_removal_info; + + return QDF_STATUS_SUCCESS; +} + /** * target_if_mlo_register_event_handler() - function to register handler for * mlo related wmi event from firmware. diff --git a/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h b/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h index daae27a7d6..110222c4c1 100644 --- a/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h +++ b/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h @@ -884,6 +884,8 @@ struct mlo_mgmt_ml_info { * @pn_params: Frame PN params * @ext_params: Extended params * @frm_con_ap: Frame is from connected ap + * @link_removal_info: MLO link removal information array + * @num_link_removal_info: Number of elements in @link_removal_info */ struct mgmt_rx_event_params { uint32_t chan_freq; @@ -908,9 +910,18 @@ struct mgmt_rx_event_params { struct frm_conn_ap is_conn_ap; #ifdef WLAN_FEATURE_11BE_MLO struct mlo_mgmt_ml_info cu_params; + struct mgmt_rx_mlo_link_removal_info *link_removal_info; + int num_link_removal_info; #endif }; +#ifdef WLAN_FEATURE_11BE_MLO +#define free_mgmt_rx_mlo_link_removal_info(rx_params) \ + qdf_mem_free((rx_params)->link_removal_info) +#else +#define free_mgmt_rx_mlo_link_removal_info(rx_params) +#endif + #ifdef WLAN_MGMT_RX_REO_SUPPORT static inline struct mgmt_rx_event_params *alloc_mgmt_rx_event_params(void) @@ -947,6 +958,7 @@ free_mgmt_rx_event_params(struct mgmt_rx_event_params *rx_params) if (rx_params) { qdf_mem_free(rx_params->ext_params); qdf_mem_free(rx_params->reo_params); + free_mgmt_rx_mlo_link_removal_info(rx_params); } qdf_mem_free(rx_params); @@ -975,8 +987,10 @@ struct mgmt_rx_event_params *alloc_mgmt_rx_event_params(void) static inline void free_mgmt_rx_event_params(struct mgmt_rx_event_params *rx_params) { - if (rx_params) + if (rx_params) { qdf_mem_free(rx_params->ext_params); + free_mgmt_rx_mlo_link_removal_info(rx_params); + } qdf_mem_free(rx_params); } diff --git a/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h b/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h index 45ec13bf0c..878f173a1d 100644 --- a/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h +++ b/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h @@ -1042,4 +1042,17 @@ struct mlo_link_removal_evt_params { uint8_t vdev_id; struct mlo_link_removal_tbtt_info tbtt_info; }; + +/* + * struct mgmt_rx_mlo_link_removal_info - Information, sent in MGMT Rx event, of + * a link undergoing removal from its MLD + * @vdev_id: Vdev ID of the link undergoing removal + * @hw_link_id: HW link ID of the link undergoing removal + * @tbtt_count: Delete timer TBTT count of the link undergoing removal + */ +struct mgmt_rx_mlo_link_removal_info { + uint8_t vdev_id; + uint8_t hw_link_id; + uint16_t tbtt_count; +}; #endif diff --git a/wmi/inc/wmi_unified_11be_api.h b/wmi/inc/wmi_unified_11be_api.h index daa7dc0d06..0b7773640f 100644 --- a/wmi/inc/wmi_unified_11be_api.h +++ b/wmi/inc/wmi_unified_11be_api.h @@ -103,6 +103,22 @@ QDF_STATUS wmi_extract_mlo_link_removal_tbtt_update( struct wmi_unified *wmi_handle, void *buf, struct mlo_link_removal_tbtt_info *tbtt_info); + +/** + * wmi_extract_mgmt_rx_mlo_link_removal_info() - Extract MLO link removal info + * from MGMT Rx event + * @wmi: wmi handle + * @buf: event buffer + * @link_removal_info: link removal information array to be populated + * @num_link_removal_info: Number of elements in @link_removal_info + * + * Return: QDF_STATUS of operation + */ +QDF_STATUS wmi_extract_mgmt_rx_mlo_link_removal_info( + struct wmi_unified *wmi, + void *buf, + struct mgmt_rx_mlo_link_removal_info *link_removal_info, + int num_link_removal_info); #endif /*WLAN_FEATURE_11BE_MLO*/ #ifdef WLAN_FEATURE_11BE diff --git a/wmi/inc/wmi_unified_11be_tlv.h b/wmi/inc/wmi_unified_11be_tlv.h index 8f84ba5d12..0485a10531 100644 --- a/wmi/inc/wmi_unified_11be_tlv.h +++ b/wmi/inc/wmi_unified_11be_tlv.h @@ -194,6 +194,22 @@ uint8_t *peer_delete_add_mlo_params(uint8_t *buf_ptr, * @wmi_handle: WMI handle */ void wmi_11be_attach_tlv(wmi_unified_t wmi_handle); + +/** + * extract_mgmt_rx_mlo_link_removal_tlv_count() - Extract the number of link + * removal TLVs from MGMT Rx event + * @num_link_removal_tlvs: Number of link removal TLVs + * @hdr: MGMT Rx event parameters to be populated + * + * Return: None + */ +static inline void +extract_mgmt_rx_mlo_link_removal_tlv_count( + int num_link_removal_tlvs, + struct mgmt_rx_event_params *hdr) +{ + hdr->num_link_removal_info = num_link_removal_tlvs; +} #else static uint8_t *vdev_create_add_mlo_params(uint8_t *buf_ptr, struct vdev_create_params *param) @@ -323,5 +339,12 @@ static uint8_t *peer_delete_add_mlo_params(uint8_t *buf_ptr, static void wmi_11be_attach_tlv(wmi_unified_t wmi_handle) { } + +static inline void +extract_mgmt_rx_mlo_link_removal_tlv_count( + int num_link_removal_tlvs, + struct mgmt_rx_event_params *hdr) +{ +} #endif /*WLAN_FEATURE_11BE_MLO*/ #endif /*_WMI_UNIFIED_11BE_TLV_H_*/ diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 804524fa6e..6df8bdd00a 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -3049,6 +3049,12 @@ QDF_STATUS (*extract_mlo_link_removal_tbtt_update)( struct wmi_unified *wmi_handle, void *buf, struct mlo_link_removal_tbtt_info *tbtt_info); + +QDF_STATUS (*extract_mgmt_rx_mlo_link_removal_info)( + struct wmi_unified *wmi_handle, + void *buf, + struct mgmt_rx_mlo_link_removal_info *link_removal_info, + int num_link_removal_info); #endif #ifdef WLAN_FEATURE_SON diff --git a/wmi/src/wmi_unified_11be_api.c b/wmi/src/wmi_unified_11be_api.c index aeb1d9d3b7..8a17ed2dc2 100644 --- a/wmi/src/wmi_unified_11be_api.c +++ b/wmi/src/wmi_unified_11be_api.c @@ -153,3 +153,18 @@ QDF_STATUS wmi_extract_mlo_link_removal_tbtt_update( return QDF_STATUS_E_FAILURE; } + +QDF_STATUS wmi_extract_mgmt_rx_mlo_link_removal_info( + struct wmi_unified *wmi, + void *buf, + struct mgmt_rx_mlo_link_removal_info *link_removal_info, + int num_link_removal_info) +{ + if (wmi->ops->extract_mgmt_rx_mlo_link_removal_info) + return wmi->ops->extract_mgmt_rx_mlo_link_removal_info( + wmi, buf, + link_removal_info, + num_link_removal_info); + + return QDF_STATUS_E_FAILURE; +} diff --git a/wmi/src/wmi_unified_11be_tlv.c b/wmi/src/wmi_unified_11be_tlv.c index 9972be6ab7..8340cc3eff 100644 --- a/wmi/src/wmi_unified_11be_tlv.c +++ b/wmi/src/wmi_unified_11be_tlv.c @@ -740,6 +740,61 @@ extract_mlo_link_removal_tbtt_update_tlv( return QDF_STATUS_SUCCESS; } +/** + * extract_mgmt_rx_mlo_link_removal_info_tlv() - Extract MLO link removal info + * from MGMT Rx event + * @wmi_handle: wmi handle + * @buf: event buffer + * @link_removal_info: link removal information array to be populated + * @num_link_removal_info: Number of elements in @link_removal_info + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS +extract_mgmt_rx_mlo_link_removal_info_tlv( + struct wmi_unified *wmi_handle, + void *buf, + struct mgmt_rx_mlo_link_removal_info *link_removal_info, + int num_link_removal_info) +{ + WMI_MGMT_RX_EVENTID_param_tlvs *param_buf = buf; + wmi_mlo_link_removal_tbtt_count *tlv_arr; + int tlv_idx = 0; + struct mgmt_rx_mlo_link_removal_info *info; + + if (!param_buf) { + wmi_err_rl("Param_buf is NULL"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (!link_removal_info) { + wmi_err_rl("Writable argument is NULL"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (num_link_removal_info != param_buf->num_link_removal_tbtt_count) { + wmi_err_rl("link_removal_info array size (%d) is not equal to" + "number of corresponding TLVs(%d) present in event", + num_link_removal_info, + param_buf->num_link_removal_tbtt_count); + return QDF_STATUS_E_RANGE; + } + + tlv_arr = param_buf->link_removal_tbtt_count; + for (; tlv_idx < param_buf->num_link_removal_tbtt_count; tlv_idx++) { + info = &link_removal_info[tlv_idx]; + + info->hw_link_id = WMI_MLO_LINK_REMOVAL_GET_LINKID( + tlv_arr[tlv_idx].tbtt_info); + info->vdev_id = WMI_MLO_LINK_REMOVAL_GET_VDEVID( + tlv_arr[tlv_idx].tbtt_info); + info->tbtt_count = WMI_MLO_LINK_REMOVAL_GET_TBTT_COUNT( + tlv_arr[tlv_idx].tbtt_info); + } + + return QDF_STATUS_SUCCESS; +} + #ifdef WLAN_FEATURE_11BE size_t peer_assoc_t2lm_params_size(struct peer_assoc_params *req) { @@ -1459,4 +1514,6 @@ void wmi_11be_attach_tlv(wmi_unified_t wmi_handle) extract_mlo_link_removal_evt_fixed_param_tlv; ops->extract_mlo_link_removal_tbtt_update = extract_mlo_link_removal_tbtt_update_tlv; + ops->extract_mgmt_rx_mlo_link_removal_info = + extract_mgmt_rx_mlo_link_removal_info_tlv; } diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 7d26b97c26..43ba4c56f0 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -12757,6 +12757,9 @@ static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, *bufp = param_tlvs->bufp; + extract_mgmt_rx_mlo_link_removal_tlv_count( + param_tlvs->num_link_removal_tbtt_count, hdr); + return QDF_STATUS_SUCCESS; }