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 a8ee1c2f98..a4205e1b56 100644 --- a/target_if/mlo_mgr/src/target_if_mlo_mgr.c +++ b/target_if/mlo_mgr/src/target_if_mlo_mgr.c @@ -177,6 +177,67 @@ target_if_mlo_link_set_active(struct wlan_objmgr_psoc *psoc, return ret; } +static int target_if_mlo_vdev_tid_to_link_map_event_handler( + ol_scn_t scn, uint8_t *event_buff, uint32_t len) +{ + struct wlan_objmgr_psoc *psoc; + struct mlo_vdev_host_tid_to_link_map_resp event = {0}; + struct wmi_unified *wmi_handle; + struct wlan_lmac_if_mlo_rx_ops *rx_ops; + QDF_STATUS status; + + if (!event_buff) { + mlme_err("Received NULL event ptr from FW"); + return -EINVAL; + } + + psoc = target_if_get_psoc_from_scn_hdl(scn); + if (!psoc) { + mlme_err("PSOC is NULL"); + return -EINVAL; + } + + rx_ops = target_if_mlo_get_rx_ops(psoc); + if (!rx_ops || !rx_ops->process_mlo_vdev_tid_to_link_map_event) { + target_if_err("callback not registered"); + return -EINVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + mlme_err("wmi_handle is null"); + return -EINVAL; + } + + if (wmi_extract_mlo_vdev_tid_to_link_map_event(wmi_handle, event_buff, + &event)) { + mlme_err("Failed to extract TID-to-link mapping event"); + return -EINVAL; + } + + status = rx_ops->process_mlo_vdev_tid_to_link_map_event(psoc, &event); + + return qdf_status_to_os_return(status); +} + +static inline void +target_if_mlo_register_vdev_tid_to_link_map_event( + struct wmi_unified *wmi_handle) +{ + wmi_unified_register_event_handler( + wmi_handle, wmi_mlo_ap_vdev_tid_to_link_map_eventid, + target_if_mlo_vdev_tid_to_link_map_event_handler, + WMI_RX_EXECUTION_CTX); +} + +static inline void +target_if_mlo_unregister_vdev_tid_to_link_map_event( + struct wmi_unified *wmi_handle) +{ + wmi_unified_unregister_event_handler( + wmi_handle, wmi_mlo_ap_vdev_tid_to_link_map_eventid); +} + /** * target_if_mlo_register_tx_ops() - lmac handler to register mlo tx ops * callback functions 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 9c091f7937..4f2d2e3689 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 @@ -1401,11 +1401,15 @@ struct wlan_lmac_if_mlo_tx_ops { /** * struct wlan_lmac_if_mlo_rx_ops - defines southbound rx callbacks for mlo * @process_link_set_active_resp: function pointer to rx FW events + * @process_mlo_vdev_tid_to_link_map_event: function pointer to rx T2LM event */ struct wlan_lmac_if_mlo_rx_ops { QDF_STATUS (*process_link_set_active_resp)(struct wlan_objmgr_psoc *psoc, struct mlo_link_set_active_resp *event); + QDF_STATUS (*process_mlo_vdev_tid_to_link_map_event)( + struct wlan_objmgr_psoc *psoc, + struct mlo_vdev_host_tid_to_link_map_resp *event); }; #endif 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 8162dd2866..8bcd538128 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 @@ -81,6 +81,7 @@ #ifdef WLAN_FEATURE_11BE_MLO #include "wlan_mlo_mgr_cmn.h" +#include #endif #include @@ -966,6 +967,8 @@ wlan_lmac_if_mlo_mgr_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops) /* register handler for received mlo related events */ rx_ops->mlo_rx_ops.process_link_set_active_resp = mlo_process_link_set_active_resp; + rx_ops->mlo_rx_ops.process_mlo_vdev_tid_to_link_map_event = + wlan_mlo_vdev_tid_to_link_map_event; } #else static void 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 575c1a70b5..96fff796c8 100644 --- a/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h +++ b/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h @@ -969,4 +969,31 @@ enum mlo_chip_recovery_type { /* Add new types above */ MLO_RECOVERY_MODE_MAX = 0xf }; + +/** + * enum wlan_t2lm_status - Target status codes in event of t2lm + * @WLAN_MAP_SWITCH_TIMER_TSF: Mapping switch time value in TSF to be included + * in probe response frames + * @WLAN_MAP_SWITCH_TIMER_EXPIRED: Indication that the new proposed T2LM has + * been applied, Update the required data structures and other modules. + * @WLAN_EXPECTED_DUR_EXPIRED: Indication that the proposed T2LM ineffective + * after this duration and all TIDs fall back to default mode. + */ +enum wlan_t2lm_status { + WLAN_MAP_SWITCH_TIMER_TSF, + WLAN_MAP_SWITCH_TIMER_EXPIRED, + WLAN_EXPECTED_DUR_EXPIRED, +}; + +/** + * struct mlo_vdev_host_tid_to_link_map_resp - TID-to-link mapping response + * @vdev_id: Vdev id + * @wlan_t2lm_status: Target status for t2lm ie info + * @mapping_switch_tsf: Mapping switch time in tsf for probe response frames + */ +struct mlo_vdev_host_tid_to_link_map_resp { + uint8_t vdev_id; + enum wlan_t2lm_status status; + uint8_t mapping_switch_tsf; +}; #endif diff --git a/umac/mlo_mgr/inc/wlan_mlo_t2lm.h b/umac/mlo_mgr/inc/wlan_mlo_t2lm.h index ad6ca85b8b..fd24911c77 100644 --- a/umac/mlo_mgr/inc/wlan_mlo_t2lm.h +++ b/umac/mlo_mgr/inc/wlan_mlo_t2lm.h @@ -65,6 +65,18 @@ QDF_STATUS wlan_mlo_parse_t2lm_ie( uint8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm, struct wlan_t2lm_onging_negotiation_info *t2lm); +/** + * wlan_mlo_vdev_tid_to_link_map_event() - API to process the revceived T2LM + * event. + * @psoc: psoc object + * @event: Pointer to received T2LM info + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_mlo_vdev_tid_to_link_map_event( + struct wlan_objmgr_psoc *psoc, + struct mlo_vdev_host_tid_to_link_map_resp *event); + /** * wlan_mlo_parse_t2lm_action_frame() - API to parse T2LM action frame * @t2lm: Pointer to T2LM structure diff --git a/umac/mlo_mgr/src/wlan_mlo_t2lm.c b/umac/mlo_mgr/src/wlan_mlo_t2lm.c index a0be5d612a..d65c5a4440 100644 --- a/umac/mlo_mgr/src/wlan_mlo_t2lm.c +++ b/umac/mlo_mgr/src/wlan_mlo_t2lm.c @@ -567,3 +567,114 @@ uint8_t *wlan_mlo_add_t2lm_action_frame( return frm; } + +/** + * wlan_mlo_t2lm_handle_mapping_switch_time_expiry() - API to handle the mapping + * switch timer expiry. + * @t2lm_ctx: Pointer to T2LM context + * @vdev: Pointer to vdev structure + * + * Return: None + */ +static void wlan_mlo_t2lm_handle_mapping_switch_time_expiry( + struct wlan_t2lm_context *t2lm_ctx, + struct wlan_objmgr_vdev *vdev) +{ + uint8_t vdev_id = wlan_vdev_get_id(vdev); + int i = 0; + + for (i = 0; i < t2lm_ctx->num_of_t2lm_ie; i++) { + if (!t2lm_ctx->t2lm_ie[i].t2lm.mapping_switch_time_present) + continue; + + /* Mapping switch time will always present at index 1. Hence, + * skip the index 0. + */ + if (i != 1) + continue; + + qdf_mem_copy(&t2lm_ctx->t2lm_ie[0], &t2lm_ctx->t2lm_ie[1], + sizeof(struct wlan_mlo_t2lm_ie)); + t2lm_ctx->t2lm_ie[0].t2lm.mapping_switch_time_present = false; + t2lm_ctx->t2lm_ie[0].t2lm.mapping_switch_time = 0; + t2lm_debug("vdev_id:%d mark the advertised T2LM as established", + vdev_id); + } +} + +/** + * wlan_mlo_t2lm_handle_expected_duration_expiry() - API to handle the expected + * duration timer expiry. + * @t2lm_ctx: Pointer to T2LM context + * @vdev: Pointer to vdev structure + * + * Return: none + */ +static void wlan_mlo_t2lm_handle_expected_duration_expiry( + struct wlan_t2lm_context *t2lm_ctx, + struct wlan_objmgr_vdev *vdev) +{ + uint8_t vdev_id = wlan_vdev_get_id(vdev); + int i = 0; + + for (i = 0; i < t2lm_ctx->num_of_t2lm_ie; i++) { + if (!t2lm_ctx->t2lm_ie[i].t2lm.expected_duration_present) + continue; + + qdf_mem_zero(&t2lm_ctx->t2lm_ie[i], + sizeof(struct wlan_mlo_t2lm_ie)); + t2lm_ctx->t2lm_ie[i].t2lm.direction = WLAN_T2LM_BIDI_DIRECTION; + t2lm_ctx->t2lm_ie[i].t2lm.default_link_mapping = 1; + t2lm_debug("vdev_id:%d Expected duration is expired", + vdev_id); + } +} + +QDF_STATUS wlan_mlo_vdev_tid_to_link_map_event( + struct wlan_objmgr_psoc *psoc, + struct mlo_vdev_host_tid_to_link_map_resp *event) +{ + struct wlan_objmgr_vdev *vdev; + struct wlan_t2lm_context *t2lm_ctx; + int i = 0; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, event->vdev_id, + WLAN_MLO_MGR_ID); + if (!vdev) { + t2lm_err("null vdev"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (!vdev->mlo_dev_ctx) { + t2lm_err("null mlo_dev_ctx"); + return QDF_STATUS_E_NULL_VALUE; + } + + t2lm_ctx = &vdev->mlo_dev_ctx->t2lm_ctx; + + switch (event->status) { + case WLAN_MAP_SWITCH_TIMER_TSF: + for (i = 0; i < t2lm_ctx->num_of_t2lm_ie; i++) { + if (!t2lm_ctx->t2lm_ie[i].t2lm.mapping_switch_time_present) + continue; + + t2lm_ctx->t2lm_ie[i].t2lm.mapping_switch_time = + event->mapping_switch_tsf; + t2lm_debug("vdev_id:%d updated mapping switch time:%d", + event->vdev_id, event->mapping_switch_tsf); + } + break; + case WLAN_MAP_SWITCH_TIMER_EXPIRED: + wlan_mlo_t2lm_handle_mapping_switch_time_expiry(t2lm_ctx, vdev); + break; + case WLAN_EXPECTED_DUR_EXPIRED: + wlan_mlo_t2lm_handle_expected_duration_expiry(t2lm_ctx, vdev); + break; + default: + t2lm_err("Invalid status"); + } + + mlo_release_vdev_ref(vdev); + + return QDF_STATUS_SUCCESS; +} diff --git a/wmi/inc/wmi_unified_11be_api.h b/wmi/inc/wmi_unified_11be_api.h index 96fd8b69d3..a5afddb0be 100644 --- a/wmi/inc/wmi_unified_11be_api.h +++ b/wmi/inc/wmi_unified_11be_api.h @@ -90,7 +90,7 @@ QDF_STATUS wmi_send_mlo_vdev_tid_to_link_map_cmd( * wmi_extract_mlo_vdev_tid_to_link_map_event() - extract mlo t2lm info for vdev * @wmi: wmi handle * @evt_buf: pointer to event buffer - * @evt: Pointer to host structure to get the t2lm info + * @resp: Pointer to host structure to get the t2lm info * * This function gets called to extract mlo t2lm info for particular pdev * @@ -98,9 +98,8 @@ QDF_STATUS wmi_send_mlo_vdev_tid_to_link_map_cmd( */ QDF_STATUS wmi_extract_mlo_vdev_tid_to_link_map_event( - wmi_unified_t wmi, - void *evt_buf, - struct wmi_host_tid_to_link_map_resp *params); + wmi_unified_t wmi, void *evt_buf, + struct mlo_vdev_host_tid_to_link_map_resp *resp); /** * wmi_extract_mlo_vdev_bcast_tid_to_link_map_event() - extract bcast mlo t2lm diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 9c7ce782ff..8269a7b423 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -1090,21 +1090,6 @@ typedef struct { } wmi_host_mac_addr; #ifdef WLAN_FEATURE_11BE -/** - * enum wlan_t2lm_status - Target status codes in event of t2lm - * @WLAN_MAP_SWITCH_TIMER_TSF: Mapping switch time value in TSF to be included - * in probe response frames - * @WLAN_MAP_SWITCH_TIMER_EXPIRED: Indication that the new proposed T2LM has - * been applied, Update the required data structures and other modules. - * @WLAN_EXPECTED_DUR_EXPIRED: Indication that the proposed T2LM ineffective - * after this duration and all TIDs fall back to default mode. - */ -enum wlan_t2lm_status { - WLAN_MAP_SWITCH_TIMER_TSF, - WLAN_MAP_SWITCH_TIMER_EXPIRED, - WLAN_EXPECTED_DUR_EXPIRED, -}; - /** * struct wlan_host_t2lm_of_tids - TID-to-link mapping info * @direction: 0 - Downlink, 1 - uplink 2 - Both uplink and downlink @@ -1151,18 +1136,6 @@ struct wmi_host_tid_to_link_map_ap_params { struct wlan_t2lm_info info[WLAN_MAX_T2LM_IE]; }; -/** - * struct wmi_host_tid_to_link_map_resp - TID-to-link mapping response - * @vdev_id: Vdev id - * @wlan_t2lm_status: Target status for t2lm ie info - * @mapping_switch_tsf: Mapping switch time in tsf for probe response frames - */ -struct wmi_host_tid_to_link_map_resp { - uint8_t vdev_id; - enum wlan_t2lm_status status; - uint8_t mapping_switch_tsf; -}; - /** * struct wmi_host_bcast_t2lm_info - TID-to-link mapping broadcast info * @vdev_id: Vdev id @@ -5202,6 +5175,9 @@ typedef enum { #ifdef HEALTH_MON_SUPPORT wmi_extract_health_mon_init_done_info_eventid, #endif /* HEALTH_MON_SUPPORT */ +#ifdef WLAN_FEATURE_11BE_MLO + wmi_mlo_ap_vdev_tid_to_link_map_eventid, +#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 28c38092e2..8774098435 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -3100,9 +3100,9 @@ QDF_STATUS (*send_mlo_vdev_tid_to_link_map)( struct wmi_host_tid_to_link_map_ap_params *params); QDF_STATUS (*extract_mlo_vdev_tid_to_link_map_event)( - struct wmi_unified *wmi_handle, - uint8_t *buf, - struct wmi_host_tid_to_link_map_resp *params); + struct wmi_unified *wmi_handle, + uint8_t *buf, + struct mlo_vdev_host_tid_to_link_map_resp *params); QDF_STATUS (*extract_mlo_vdev_bcast_tid_to_link_map_event)( struct wmi_unified *wmi_handle, diff --git a/wmi/src/wmi_unified_11be_api.c b/wmi/src/wmi_unified_11be_api.c index 6bb9fe87b0..ea8bb5bacd 100644 --- a/wmi/src/wmi_unified_11be_api.c +++ b/wmi/src/wmi_unified_11be_api.c @@ -82,9 +82,8 @@ QDF_STATUS wmi_send_mlo_vdev_tid_to_link_map_cmd( QDF_STATUS wmi_extract_mlo_vdev_tid_to_link_map_event( - wmi_unified_t wmi, - void *evt_buf, - struct wmi_host_tid_to_link_map_resp *resp) + wmi_unified_t wmi, void *evt_buf, + struct mlo_vdev_host_tid_to_link_map_resp *resp) { if (wmi->ops->extract_mlo_vdev_tid_to_link_map_event) { return wmi->ops->extract_mlo_vdev_tid_to_link_map_event(wmi, diff --git a/wmi/src/wmi_unified_11be_tlv.c b/wmi/src/wmi_unified_11be_tlv.c index 6eab60f94a..86fd1bdcdc 100644 --- a/wmi/src/wmi_unified_11be_tlv.c +++ b/wmi/src/wmi_unified_11be_tlv.c @@ -953,9 +953,9 @@ static QDF_STATUS send_mlo_vdev_tid_to_link_map_cmd_tlv( static QDF_STATUS extract_mlo_vdev_tid_to_link_map_event_tlv( - struct wmi_unified *wmi_handle, - uint8_t *buf, - struct wmi_host_tid_to_link_map_resp *params) + struct wmi_unified *wmi_handle, + uint8_t *buf, + struct mlo_vdev_host_tid_to_link_map_resp *params) { WMI_MLO_AP_VDEV_TID_TO_LINK_MAP_EVENTID_param_tlvs *param_buf; wmi_mlo_ap_vdev_tid_to_link_map_evt_fixed_param *ev; diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 806dc05188..d670b25a7e 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -20143,6 +20143,8 @@ static void populate_tlv_events_id_mlo(uint32_t *event_ids) WMI_MLO_LINK_SET_ACTIVE_RESP_EVENTID; event_ids[wmi_vdev_quiet_offload_eventid] = WMI_QUIET_HANDLING_EVENTID; + event_ids[wmi_mlo_ap_vdev_tid_to_link_map_eventid] = + WMI_MLO_AP_VDEV_TID_TO_LINK_MAP_EVENTID; } #else /* WLAN_FEATURE_11BE_MLO */ static inline void populate_tlv_events_id_mlo(uint32_t *event_ids)