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; }