From 800dddec5560a17615a8b11821b44fdc78c437a5 Mon Sep 17 00:00:00 2001 From: Nidhi Jain Date: Tue, 13 Dec 2022 10:22:39 +0530 Subject: [PATCH] qcacmn: Registration function for link disablement This change is to allow other modules to register for link disablement. It includes below functions: 1- Notify link update 2- Register to handler to get link update notification 3- Unregister T2LM handlers Added the below changes as well, - Move T2LM related data structures to wlan_mlo_t2lm.h file - Host receives the expected duration from FW for multiple vdevs. Hence, add support to extract the expected duration for multiple vdevs. Change-Id: Ie8e77d5d3b4351a8551ecd7da50786b58dad3b2e CRs-Fixed: 3346432 --- .../dispatcher/inc/wlan_mgmt_txrx_utils_api.h | 14 + .../mlo_mgr/inc/wlan_mlo_mgr_public_structs.h | 235 +------------ umac/mlo_mgr/inc/wlan_mlo_t2lm.h | 312 ++++++++++++++++++ umac/mlo_mgr/src/wlan_mlo_t2lm.c | 64 +++- wmi/inc/wmi_unified_11be_api.h | 2 +- wmi/inc/wmi_unified_param.h | 10 - wmi/inc/wmi_unified_priv.h | 2 +- wmi/src/wmi_unified_11be_api.c | 2 +- wmi/src/wmi_unified_11be_tlv.c | 34 +- 9 files changed, 418 insertions(+), 257 deletions(-) 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 110222c4c1..2d0834dc03 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 @@ -856,6 +856,18 @@ struct mlo_mgmt_ml_info { uint16_t cu_vdev_map[CU_MAX_MLO_LINKS]; uint8_t vdev_bpcc[MAX_AP_MLDS_PER_LINK * CU_MAX_MLO_LINKS]; }; + +/** + * struct mlo_bcast_t2lm_info - TID-to-link mapping broadcast info + * @num_vdevs: Number of vdevs for which FW populated the expected duration + * @vdev_id: Array of vdev ids + * @expected_duration: Array of expected duration for vdev ids + */ +struct mlo_bcast_t2lm_info { + uint8_t num_vdevs; + uint8_t vdev_id[MAX_AP_MLDS_PER_LINK]; + uint32_t expected_duration[MAX_AP_MLDS_PER_LINK]; +}; #endif /** @@ -886,6 +898,7 @@ struct mlo_mgmt_ml_info { * @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 + * @t2lm_params: T2LM related info received from FW */ struct mgmt_rx_event_params { uint32_t chan_freq; @@ -912,6 +925,7 @@ struct mgmt_rx_event_params { struct mlo_mgmt_ml_info cu_params; struct mgmt_rx_mlo_link_removal_info *link_removal_info; int num_link_removal_info; + struct mlo_bcast_t2lm_info t2lm_params; #endif }; 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 09d8db576e..01dac735b8 100644 --- a/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h +++ b/umac/mlo_mgr/inc/wlan_mlo_mgr_public_structs.h @@ -31,6 +31,7 @@ #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) #include #endif +#include /* MAX MLO dev support */ #ifndef WLAN_UMAC_MLO_MAX_VDEVS @@ -47,6 +48,7 @@ struct mlo_mlme_ext_ops; struct vdev_mlme_obj; +struct wlan_t2lm_context; /* Max LINK PEER support */ #define MAX_MLO_LINK_PEERS WLAN_UMAC_MLO_MAX_VDEVS @@ -278,119 +280,6 @@ struct wlan_mlo_peer_list { #endif }; -#define T2LM_MAX_NUM_TIDS 8 - -/** - * enum wlan_t2lm_direction - Indicates the direction for which TID-to-link - * mapping is available. - * - * @WLAN_T2LM_DL_DIRECTION: Downlink - * @WLAN_T2LM_UL_DIRECTION: Uplink - * @WLAN_T2LM_BIDI_DIRECTION: Both downlink and uplink - * @WLAN_T2LM_MAX_DIRECTION: Max direction, this is used only internally - * @WLAN_T2LM_INVALID_DIRECTION: Invalid, this is used only internally to check - * if the mapping present in wlan_t2lm_info - * structure is valid or not. - */ -enum wlan_t2lm_direction { - WLAN_T2LM_DL_DIRECTION, - WLAN_T2LM_UL_DIRECTION, - WLAN_T2LM_BIDI_DIRECTION, - WLAN_T2LM_MAX_DIRECTION, - WLAN_T2LM_INVALID_DIRECTION, -}; - -#define T2LM_EXPECTED_DURATION_MAX_VALUE 0xFFFFFF -/** - * struct wlan_t2lm_info - TID-to-Link mapping information for the frames - * transmitted on the uplink, downlink and bidirectional. - * - * @direction: 0 - Downlink, 1 - uplink 2 - Both uplink and downlink - * @default_link_mapping: value 1 indicates the default T2LM, where all the TIDs - * are mapped to all the links. - * value 0 indicates the preferred T2LM mapping - * @mapping_switch_time_present: Indicates if mapping switch time field present - * in the T2LM IE - * @expected_duration_present: Indicates if expected duration present in the - * T2LM IE - * @mapping_switch_time: Mapping switch time of this T2LM IE - * @expected_duration: Expected duration of this T2LM IE - * @ieee_link_map_tid: Indicates ieee link id mapping of all the TIDS - * @hw_link_map_tid: Indicates hw link id mapping of all the TIDS - * @timer_started: flag to check if T2LM timer is started for this T2LM IE - */ -struct wlan_t2lm_info { - enum wlan_t2lm_direction direction; - bool default_link_mapping; - bool mapping_switch_time_present; - bool expected_duration_present; - uint16_t mapping_switch_time; - uint32_t expected_duration; - uint16_t ieee_link_map_tid[T2LM_MAX_NUM_TIDS]; - uint16_t hw_link_map_tid[T2LM_MAX_NUM_TIDS]; - bool timer_started; -}; - -/** - * struct wlan_mlo_t2lm_ie - T2LM information - * - * @disabled_link_bitmap: Bitmap of disabled links. This is used to update the - * disabled link field of RNR IE - * @t2lm: T2LM info structure - */ -struct wlan_mlo_t2lm_ie { - uint16_t disabled_link_bitmap; - struct wlan_t2lm_info t2lm; -}; - -/* - * In a beacon or probe response frame, at max two T2LM IEs can be present - * first one to represent the already existing mapping and the other one - * represents the new T2LM mapping that is yet to establish. - */ -#define WLAN_MAX_T2LM_IE 2 -/** - * struct wlan_t2lm_timer - T2LM timer information - * - * @t2lm_timer: T2LM timer - * @timer_interval: T2LM Timer value - * @timer_started: T2LM timer started or not - * @t2lm_ie_index: T2LM IE index value - * @t2lm_dev_lock: lock to access struct - */ -struct wlan_t2lm_timer { - qdf_timer_t t2lm_timer; - uint32_t timer_interval; - bool timer_started; - uint8_t t2lm_ie_index; -#ifdef WLAN_MLO_USE_SPINLOCK - qdf_spinlock_t t2lm_dev_lock; -#else - qdf_mutex_t t2lm_dev_lock; -#endif -}; - -/** - * struct wlan_t2lm_context - T2LM IE information - * - * @num_of_t2lm_ie: Number of T2LM IE - * @t2lm_ie: T2LM IE information - * @t2lm_timer: T2LM timer information - * @t2lm_dev_lock: t2lm dev context lock - * @tsf: time sync func value received via beacon - */ -struct wlan_t2lm_context { - uint8_t num_of_t2lm_ie; - struct wlan_mlo_t2lm_ie t2lm_ie[WLAN_MAX_T2LM_IE]; - struct wlan_t2lm_timer t2lm_timer; -#ifdef WLAN_MLO_USE_SPINLOCK - qdf_spinlock_t t2lm_dev_lock; -#else - qdf_mutex_t t2lm_dev_lock; -#endif - uint64_t tsf; -}; - /* * struct wlan_mlo_dev_context - MLO device context * @node: QDF list node member @@ -503,126 +392,6 @@ struct mlpeer_auth_params { void *rs; }; -/** - * enum wlan_t2lm_category - T2LM category - * - * @WLAN_T2LM_CATEGORY_NONE: none - * @WLAN_T2LM_CATEGORY_REQUEST: T2LM request - * @WLAN_T2LM_CATEGORY_RESPONSE: T2LM response - * @WLAN_T2LM_CATEGORY_TEARDOWN: T2LM teardown - * @WLAN_T2LM_CATEGORY_INVALID: Invalid - */ -enum wlan_t2lm_category { - WLAN_T2LM_CATEGORY_NONE = 0, - WLAN_T2LM_CATEGORY_REQUEST = 1, - WLAN_T2LM_CATEGORY_RESPONSE = 2, - WLAN_T2LM_CATEGORY_TEARDOWN = 3, - WLAN_T2LM_CATEGORY_INVALID, -}; - -/** - * enum wlan_t2lm_tx_status - Status code applicable for the T2LM frames - * transmitted by the current peer. - * - * @WLAN_T2LM_TX_STATUS_NONE: Status code is not applicable - * @WLAN_T2LM_TX_STATUS_SUCCESS: AP/STA successfully transmitted the T2LM frame - * @WLAN_T2LM_TX_STATUS_FAILURE: Tx failure received from the FW. - * @WLAN_T2LM_TX_STATUS_RX_TIMEOUT: T2LM response frame not received from the - * peer for the transmitted T2LM request frame. - * @WLAN_T2LM_TX_STATUS_INVALID: Invalid status code - */ -enum wlan_t2lm_tx_status { - WLAN_T2LM_TX_STATUS_NONE = 0, - WLAN_T2LM_TX_STATUS_SUCCESS = 1, - WLAN_T2LM_TX_STATUS_FAILURE = 2, - WLAN_T2LM_TX_STATUS_RX_TIMEOUT = 3, - WLAN_T2LM_TX_STATUS_INVALID, -}; - -/** - * enum wlan_t2lm_resp_frm_type - T2LM status corresponds to T2LM response frame - * - * @WLAN_T2LM_RESP_TYPE_SUCCESS: T2LM mapping provided in the T2LM request is - * accepted either by the AP or STA - * @WLAN_T2LM_RESP_TYPE_DENIED_TID_TO_LINK_MAPPING: T2LM Request denied because - * the requested TID-to-link mapping is unacceptable. - * @WLAN_T2LM_RESP_TYPE_PREFERRED_TID_TO_LINK_MAPPING: T2LM Request rejected and - * preferred TID-to-link mapping is suggested. - * @WLAN_T2LM_RESP_TYPE_INVALID: Status code is not applicable. - */ -enum wlan_t2lm_resp_frm_type { - WLAN_T2LM_RESP_TYPE_SUCCESS = 0, - WLAN_T2LM_RESP_TYPE_DENIED_TID_TO_LINK_MAPPING = 133, - WLAN_T2LM_RESP_TYPE_PREFERRED_TID_TO_LINK_MAPPING = 134, - WLAN_T2LM_RESP_TYPE_INVALID, -}; - -/** - * enum wlan_t2lm_enable - TID-to-link negotiation supported by the mlo peer - * - * @WLAN_T2LM_NOT_SUPPORTED: T2LM is not supported by the MLD - * @WLAN_T2LM_MAP_ALL_TIDS_TO_SAME_LINK_SET: MLD only supports the mapping of - * all TIDs to the same link set. - * @WLAN_T2LM_MAP_RESERVED: reserved value - * @WLAN_T2LM_MAP_EACH_TID_TO_SAME_OR_DIFFERENET_LINK_SET: MLD supports the - * mapping of each TID to the same or different link set (Disjoint mapping). - * @WLAN_T2LM_ENABLE_INVALID: invalid - */ -enum wlan_t2lm_enable { - WLAN_T2LM_NOT_SUPPORTED = 0, - WLAN_T2LM_MAP_ALL_TIDS_TO_SAME_LINK_SET = 1, - WLAN_T2LM_MAP_RESERVED = 2, - WLAN_T2LM_MAP_EACH_TID_TO_SAME_OR_DIFFERENET_LINK_SET = 3, - WLAN_T2LM_ENABLE_INVALID, -}; - -/** - * struct wlan_prev_t2lm_negotiated_info - Previous successful T2LM negotiation - * is saved here. - * - * @dialog_token: Save the dialog token used in T2LM request and response frame. - * @t2lm_info: Provides the TID to LINK mapping information - */ -struct wlan_prev_t2lm_negotiated_info { - uint16_t dialog_token; - struct wlan_t2lm_info t2lm_info[WLAN_T2LM_MAX_DIRECTION]; -}; - -/** - * struct wlan_t2lm_onging_negotiation_info - Current ongoing T2LM negotiation - * (information about transmitted T2LM request/response frame) - * - * @category: T2LM category as T2LM request frame - * @dialog_token: Save the dialog token used in T2LM request and response frame. - * @t2lm_info: Provides the TID-to-link mapping info for UL/DL/BiDi - * @t2lm_tx_status: Status code corresponds to the transmitted T2LM frames - * @t2lm_resp_type: T2LM status corresponds to T2LM response frame. - */ -struct wlan_t2lm_onging_negotiation_info { - enum wlan_t2lm_category category; - uint8_t dialog_token; - struct wlan_t2lm_info t2lm_info[WLAN_T2LM_MAX_DIRECTION]; - enum wlan_t2lm_tx_status t2lm_tx_status; - enum wlan_t2lm_resp_frm_type t2lm_resp_type; -}; - -/** - * struct wlan_mlo_peer_t2lm_policy - TID-to-link mapping information - * - * @self_gen_dialog_token: self generated dialog token used to send T2LM request - * frame; - * @t2lm_enable_val: TID-to-link enable value supported by this peer. - * @t2lm_negotiated_info: Previous successful T2LM negotiation is saved here. - * @ongoing_tid_to_link_mapping: This has the ongoing TID-to-link mapping info - * transmitted by this peer to the connected peer. - */ -struct wlan_mlo_peer_t2lm_policy { - uint8_t self_gen_dialog_token; - enum wlan_t2lm_enable t2lm_enable_val; - struct wlan_prev_t2lm_negotiated_info t2lm_negotiated_info; - struct wlan_t2lm_onging_negotiation_info ongoing_tid_to_link_mapping; -}; - /** * struct wlan_mlo_eml_cap - EML capabilities of MLD * @emlsr_supp: eMLSR Support diff --git a/umac/mlo_mgr/inc/wlan_mlo_t2lm.h b/umac/mlo_mgr/inc/wlan_mlo_t2lm.h index dfe09afa5a..f22ba46d81 100644 --- a/umac/mlo_mgr/inc/wlan_mlo_t2lm.h +++ b/umac/mlo_mgr/inc/wlan_mlo_t2lm.h @@ -22,6 +22,265 @@ #define _WLAN_MLO_T2LM_H_ #include +#include + +struct mlo_vdev_host_tid_to_link_map_resp; +struct wlan_mlo_dev_context; + +/* Max T2LM TIDS count */ +#define T2LM_MAX_NUM_TIDS 8 + +/* Max T2LM callback handlers */ +#define MAX_T2LM_HANDLERS 50 + +#define T2LM_EXPECTED_DURATION_MAX_VALUE 0xFFFFFF +/** + * enum wlan_t2lm_direction - Indicates the direction for which TID-to-link + * mapping is available. + * + * @WLAN_T2LM_DL_DIRECTION: Downlink + * @WLAN_T2LM_UL_DIRECTION: Uplink + * @WLAN_T2LM_BIDI_DIRECTION: Both downlink and uplink + * @WLAN_T2LM_MAX_DIRECTION: Max direction, this is used only internally + * @WLAN_T2LM_INVALID_DIRECTION: Invalid, this is used only internally to check + * if the mapping present in wlan_t2lm_info + * structure is valid or not. + */ +enum wlan_t2lm_direction { + WLAN_T2LM_DL_DIRECTION, + WLAN_T2LM_UL_DIRECTION, + WLAN_T2LM_BIDI_DIRECTION, + WLAN_T2LM_MAX_DIRECTION, + WLAN_T2LM_INVALID_DIRECTION, +}; + +/** + * struct wlan_t2lm_info - TID-to-Link mapping information for the frames + * transmitted on the uplink, downlink and bidirectional. + * + * @direction: 0 - Downlink, 1 - uplink 2 - Both uplink and downlink + * @default_link_mapping: value 1 indicates the default T2LM, where all the TIDs + * are mapped to all the links. + * value 0 indicates the preferred T2LM mapping + * @mapping_switch_time_present: Indicates if mapping switch time field present + * in the T2LM IE + * @expected_duration_present: Indicates if expected duration present in the + * T2LM IE + * @mapping_switch_time: Mapping switch time of this T2LM IE + * @expected_duration: Expected duration of this T2LM IE + * @ieee_link_map_tid: Indicates ieee link id mapping of all the TIDS + * @hw_link_map_tid: Indicates hw link id mapping of all the TIDS + * @timer_started: flag to check if T2LM timer is started for this T2LM IE + */ +struct wlan_t2lm_info { + enum wlan_t2lm_direction direction; + bool default_link_mapping; + bool mapping_switch_time_present; + bool expected_duration_present; + uint16_t mapping_switch_time; + uint32_t expected_duration; + uint16_t ieee_link_map_tid[T2LM_MAX_NUM_TIDS]; + uint16_t hw_link_map_tid[T2LM_MAX_NUM_TIDS]; + bool timer_started; +}; + +/** + * enum wlan_t2lm_category - T2LM category + * + * @WLAN_T2LM_CATEGORY_NONE: none + * @WLAN_T2LM_CATEGORY_REQUEST: T2LM request + * @WLAN_T2LM_CATEGORY_RESPONSE: T2LM response + * @WLAN_T2LM_CATEGORY_TEARDOWN: T2LM teardown + * @WLAN_T2LM_CATEGORY_INVALID: Invalid + */ +enum wlan_t2lm_category { + WLAN_T2LM_CATEGORY_NONE = 0, + WLAN_T2LM_CATEGORY_REQUEST = 1, + WLAN_T2LM_CATEGORY_RESPONSE = 2, + WLAN_T2LM_CATEGORY_TEARDOWN = 3, + WLAN_T2LM_CATEGORY_INVALID, +}; + +/** + * enum wlan_t2lm_tx_status - Status code applicable for the T2LM frames + * transmitted by the current peer. + * + * @WLAN_T2LM_TX_STATUS_NONE: Status code is not applicable + * @WLAN_T2LM_TX_STATUS_SUCCESS: AP/STA successfully transmitted the T2LM frame + * @WLAN_T2LM_TX_STATUS_FAILURE: Tx failure received from the FW. + * @WLAN_T2LM_TX_STATUS_RX_TIMEOUT: T2LM response frame not received from the + * peer for the transmitted T2LM request frame. + * @WLAN_T2LM_TX_STATUS_INVALID: Invalid status code + */ +enum wlan_t2lm_tx_status { + WLAN_T2LM_TX_STATUS_NONE = 0, + WLAN_T2LM_TX_STATUS_SUCCESS = 1, + WLAN_T2LM_TX_STATUS_FAILURE = 2, + WLAN_T2LM_TX_STATUS_RX_TIMEOUT = 3, + WLAN_T2LM_TX_STATUS_INVALID, +}; + +/** + * enum wlan_t2lm_resp_frm_type - T2LM status corresponds to T2LM response frame + * + * @WLAN_T2LM_RESP_TYPE_SUCCESS: T2LM mapping provided in the T2LM request is + * accepted either by the AP or STA + * @WLAN_T2LM_RESP_TYPE_DENIED_TID_TO_LINK_MAPPING: T2LM Request denied because + * the requested TID-to-link mapping is unacceptable. + * @WLAN_T2LM_RESP_TYPE_PREFERRED_TID_TO_LINK_MAPPING: T2LM Request rejected and + * preferred TID-to-link mapping is suggested. + * @WLAN_T2LM_RESP_TYPE_INVALID: Status code is not applicable. + */ +enum wlan_t2lm_resp_frm_type { + WLAN_T2LM_RESP_TYPE_SUCCESS = 0, + WLAN_T2LM_RESP_TYPE_DENIED_TID_TO_LINK_MAPPING = 133, + WLAN_T2LM_RESP_TYPE_PREFERRED_TID_TO_LINK_MAPPING = 134, + WLAN_T2LM_RESP_TYPE_INVALID, +}; + +/** + * enum wlan_t2lm_enable - TID-to-link negotiation supported by the mlo peer + * + * @WLAN_T2LM_NOT_SUPPORTED: T2LM is not supported by the MLD + * @WLAN_T2LM_MAP_ALL_TIDS_TO_SAME_LINK_SET: MLD only supports the mapping of + * all TIDs to the same link set. + * @WLAN_T2LM_MAP_RESERVED: reserved value + * @WLAN_T2LM_MAP_EACH_TID_TO_SAME_OR_DIFFERENET_LINK_SET: MLD supports the + * mapping of each TID to the same or different link set (Disjoint mapping). + * @WLAN_T2LM_ENABLE_INVALID: invalid + */ +enum wlan_t2lm_enable { + WLAN_T2LM_NOT_SUPPORTED = 0, + WLAN_T2LM_MAP_ALL_TIDS_TO_SAME_LINK_SET = 1, + WLAN_T2LM_MAP_RESERVED = 2, + WLAN_T2LM_MAP_EACH_TID_TO_SAME_OR_DIFFERENET_LINK_SET = 3, + WLAN_T2LM_ENABLE_INVALID, +}; + +/** + * struct wlan_prev_t2lm_negotiated_info - Previous successful T2LM negotiation + * is saved here. + * + * @dialog_token: Save the dialog token used in T2LM request and response frame. + * @t2lm_info: Provides the TID to LINK mapping information + */ +struct wlan_prev_t2lm_negotiated_info { + uint16_t dialog_token; + struct wlan_t2lm_info t2lm_info[WLAN_T2LM_MAX_DIRECTION]; +}; + +/** + * struct wlan_t2lm_onging_negotiation_info - Current ongoing T2LM negotiation + * (information about transmitted T2LM request/response frame) + * + * @category: T2LM category as T2LM request frame + * @dialog_token: Save the dialog token used in T2LM request and response frame. + * @t2lm_info: Provides the TID-to-link mapping info for UL/DL/BiDi + * @t2lm_tx_status: Status code corresponds to the transmitted T2LM frames + * @t2lm_resp_type: T2LM status corresponds to T2LM response frame. + */ +struct wlan_t2lm_onging_negotiation_info { + enum wlan_t2lm_category category; + uint8_t dialog_token; + struct wlan_t2lm_info t2lm_info[WLAN_T2LM_MAX_DIRECTION]; + enum wlan_t2lm_tx_status t2lm_tx_status; + enum wlan_t2lm_resp_frm_type t2lm_resp_type; +}; + +/** + * struct wlan_mlo_peer_t2lm_policy - TID-to-link mapping information + * + * @self_gen_dialog_token: self generated dialog token used to send T2LM request + * frame; + * @t2lm_enable_val: TID-to-link enable value supported by this peer. + * @t2lm_negotiated_info: Previous successful T2LM negotiation is saved here. + * @ongoing_tid_to_link_mapping: This has the ongoing TID-to-link mapping info + * transmitted by this peer to the connected peer. + */ +struct wlan_mlo_peer_t2lm_policy { + uint8_t self_gen_dialog_token; + enum wlan_t2lm_enable t2lm_enable_val; + struct wlan_prev_t2lm_negotiated_info t2lm_negotiated_info; + struct wlan_t2lm_onging_negotiation_info ongoing_tid_to_link_mapping; +}; + +/** + * struct wlan_mlo_t2lm_ie - T2LM information + * + * @disabled_link_bitmap: Bitmap of disabled links. This is used to update the + * disabled link field of RNR IE + * @t2lm: T2LM info structure + */ +struct wlan_mlo_t2lm_ie { + uint16_t disabled_link_bitmap; + struct wlan_t2lm_info t2lm; +}; + +/* + * In a beacon or probe response frame, at max two T2LM IEs can be present + * first one to represent the already existing mapping and the other one + * represents the new T2LM mapping that is yet to establish. + */ +#define WLAN_MAX_T2LM_IE 2 +/** + * struct wlan_t2lm_timer - T2LM timer information + * + * @t2lm_timer: T2LM timer + * @timer_interval: T2LM Timer value + * @timer_started: T2LM timer started or not + * @t2lm_ie_index: T2LM IE index value + * @t2lm_dev_lock: lock to access struct + */ +struct wlan_t2lm_timer { + qdf_timer_t t2lm_timer; + uint32_t timer_interval; + bool timer_started; + uint8_t t2lm_ie_index; +#ifdef WLAN_MLO_USE_SPINLOCK + qdf_spinlock_t t2lm_dev_lock; +#else + qdf_mutex_t t2lm_dev_lock; +#endif +}; + +struct wlan_mlo_dev_context; + +/** + * typedef wlan_mlo_t2lm_link_update_handler - T2LM handler API to notify the + * link update. + * @mldev: Pointer to mlo_dev_context + * @arg: ieee_link_map + * + * Return: QDF_STATUS + */ +typedef QDF_STATUS (*wlan_mlo_t2lm_link_update_handler)( + struct wlan_mlo_dev_context *mldev, void *arg); + +/** + * struct wlan_t2lm_context - T2LM IE information + * + * @num_of_t2lm_ie: Number of T2LM IE + * @t2lm_ie: T2LM IE information + * @t2lm_timer: T2LM timer information + * @t2lm_dev_lock: t2lm dev context lock + * @tsf: time sync func value received via beacon + * @link_update_handler: handler to update T2LM link + * @is_valid_handler: T2LM handler is valid or not + */ +struct wlan_t2lm_context { + uint8_t num_of_t2lm_ie; + struct wlan_mlo_t2lm_ie t2lm_ie[WLAN_MAX_T2LM_IE]; + struct wlan_t2lm_timer t2lm_timer; +#ifdef WLAN_MLO_USE_SPINLOCK + qdf_spinlock_t t2lm_dev_lock; +#else + qdf_mutex_t t2lm_dev_lock; +#endif + uint64_t tsf; + wlan_mlo_t2lm_link_update_handler + link_update_handler[MAX_T2LM_HANDLERS]; + bool is_valid_handler[MAX_T2LM_HANDLERS]; +}; #ifdef WLAN_FEATURE_11BE @@ -125,6 +384,39 @@ static inline void t2lm_dev_lock_release(struct wlan_t2lm_context *t2lm_ctx) } #endif +/** + * wlan_register_t2lm_link_update_notify_handler() - API to register the + * handlers to receive link update notification + * @handler: handler for T2LM link update + * @mldev: Pointer to mlo context + * + * Return: Index on which handler is registered + */ +int wlan_register_t2lm_link_update_notify_handler( + wlan_mlo_t2lm_link_update_handler handler, + struct wlan_mlo_dev_context *mldev); + +/** + * wlan_unregister_t2lm_link_update_notify_handler() - API to unregister the + * T2LM related handlers + * @mldev: Pointer to mlo context + * @index: Index on which the handler was registered + * + * Return: None + */ +void wlan_unregister_t2lm_link_update_notify_handler( + struct wlan_mlo_dev_context *mldev, uint8_t index); + +/** + * wlan_mlo_dev_t2lm_notify_link_update() - API to call the registered handlers + * when there is a link update happens using T2LM + * @mldev: Pointer to mlo context + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_mlo_dev_t2lm_notify_link_update( + struct wlan_mlo_dev_context *mldev); + /** * wlan_mlo_parse_t2lm_ie() - API to parse the T2LM IE * @t2lm: Pointer to T2LM structure @@ -345,5 +637,25 @@ wlan_process_bcn_prbrsp_t2lm_ie(struct wlan_objmgr_vdev *vdev, { return QDF_STATUS_SUCCESS; } + +static inline +int wlan_register_t2lm_link_update_notify_handler( + wlan_mlo_t2lm_link_update_handler handler, + struct wlan_mlo_dev_context *mldev) +{ + return 0; +} + +static inline +void wlan_unregister_t2lm_link_update_notify_handler( + struct wlan_mlo_dev_context *mldev, uint8_t index) +{ +} + +static inline QDF_STATUS wlan_mlo_dev_t2lm_notify_link_update( + struct wlan_mlo_dev_context *mldev) +{ + return QDF_STATUS_SUCCESS; +} #endif /* WLAN_FEATURE_11BE */ #endif /* _WLAN_MLO_T2LM_H_ */ diff --git a/umac/mlo_mgr/src/wlan_mlo_t2lm.c b/umac/mlo_mgr/src/wlan_mlo_t2lm.c index 07ba4bdc19..e9066b10ed 100644 --- a/umac/mlo_mgr/src/wlan_mlo_t2lm.c +++ b/umac/mlo_mgr/src/wlan_mlo_t2lm.c @@ -591,7 +591,7 @@ static void wlan_mlo_t2lm_handle_mapping_switch_time_expiry( /* Mapping switch time will always present at index 1. Hence, * skip the index 0. */ - if (i != 1) + if (i == 0) continue; qdf_mem_copy(&t2lm_ctx->t2lm_ie[0], &t2lm_ctx->t2lm_ie[1], @@ -601,6 +601,9 @@ static void wlan_mlo_t2lm_handle_mapping_switch_time_expiry( t2lm_debug("vdev_id:%d mark the advertised T2LM as established", vdev_id); } + + /* Notify the registered caller about the link update*/ + wlan_mlo_dev_t2lm_notify_link_update(vdev->mlo_dev_ctx); } /** @@ -648,6 +651,9 @@ static void wlan_mlo_t2lm_handle_expected_duration_expiry( vdev_id); } } + + /* Notify the registered caller about the link update*/ + wlan_mlo_dev_t2lm_notify_link_update(vdev->mlo_dev_ctx); } QDF_STATUS wlan_mlo_vdev_tid_to_link_map_event( @@ -1008,3 +1014,59 @@ QDF_STATUS wlan_process_bcn_prbrsp_t2lm_ie( return QDF_STATUS_SUCCESS; } + +int wlan_register_t2lm_link_update_notify_handler( + wlan_mlo_t2lm_link_update_handler handler, + struct wlan_mlo_dev_context *mldev) +{ + struct wlan_t2lm_context *t2lm_ctx = &mldev->t2lm_ctx; + int i; + + for (i = 0; i < MAX_T2LM_HANDLERS; i++) { + if (t2lm_ctx->is_valid_handler[i]) + continue; + + t2lm_ctx->link_update_handler[i] = handler; + t2lm_ctx->is_valid_handler[i] = true; + break; + } + + if (i == MAX_T2LM_HANDLERS) { + t2lm_err("Failed to register the link disablement callback"); + return -EINVAL; + } + + return i; +} + +void wlan_unregister_t2lm_link_update_notify_handler( + struct wlan_mlo_dev_context *mldev, + uint8_t index) +{ + if (index >= MAX_T2LM_HANDLERS) + return; + + mldev->t2lm_ctx.link_update_handler[index] = NULL; + mldev->t2lm_ctx.is_valid_handler[index] = false; +} + +QDF_STATUS wlan_mlo_dev_t2lm_notify_link_update( + struct wlan_mlo_dev_context *mldev) +{ + struct wlan_t2lm_context *t2lm_ctx = &mldev->t2lm_ctx; + wlan_mlo_t2lm_link_update_handler handler; + int i; + + for (i = 0; i < MAX_T2LM_HANDLERS; i++) { + if (!t2lm_ctx->is_valid_handler[i]) + continue; + + handler = t2lm_ctx->link_update_handler[i]; + if (!(handler && t2lm_ctx->num_of_t2lm_ie)) + continue; + + handler(mldev, &t2lm_ctx->t2lm_ie[0].t2lm.ieee_link_map_tid[0]); + } + + return QDF_STATUS_SUCCESS; +} diff --git a/wmi/inc/wmi_unified_11be_api.h b/wmi/inc/wmi_unified_11be_api.h index 0b7773640f..7821cd4191 100644 --- a/wmi/inc/wmi_unified_11be_api.h +++ b/wmi/inc/wmi_unified_11be_api.h @@ -171,7 +171,7 @@ QDF_STATUS wmi_extract_mlo_vdev_bcast_tid_to_link_map_event( wmi_unified_t wmi, void *evt_buf, - struct wmi_host_bcast_t2lm_info *bcast); + struct mlo_bcast_t2lm_info *bcast); #endif /* WLAN_FEATURE_11BE */ #endif /*_WMI_UNIFIED_11BE_API_H_*/ diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index a92c1bfbb7..dc097fcc16 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -1153,16 +1153,6 @@ struct wmi_host_tid_to_link_map_resp { 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 - * @expected_duration: Expected duration for vdev t2lm ie - */ -struct wmi_host_bcast_t2lm_info { - uint8_t vdev_id; - uint32_t expected_duration; -}; #endif /* WLAN_FEATURE_11BE */ #ifdef WLAN_FEATURE_11BE_MLO diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 10ff6f7c62..d2b41b25be 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -3127,7 +3127,7 @@ QDF_STATUS (*extract_mlo_vdev_tid_to_link_map_event)( QDF_STATUS (*extract_mlo_vdev_bcast_tid_to_link_map_event)( struct wmi_unified *wmi_handle, void *buf, - struct wmi_host_bcast_t2lm_info *bcast_info); + struct mlo_bcast_t2lm_info *bcast_info); #endif /* WLAN_FEATURE_11BE */ QDF_STATUS diff --git a/wmi/src/wmi_unified_11be_api.c b/wmi/src/wmi_unified_11be_api.c index 8a17ed2dc2..efd566bf8e 100644 --- a/wmi/src/wmi_unified_11be_api.c +++ b/wmi/src/wmi_unified_11be_api.c @@ -97,7 +97,7 @@ QDF_STATUS wmi_extract_mlo_vdev_bcast_tid_to_link_map_event( wmi_unified_t wmi, void *evt_buf, - struct wmi_host_bcast_t2lm_info *bcast) + struct mlo_bcast_t2lm_info *bcast) { if (wmi->ops->extract_mlo_vdev_bcast_tid_to_link_map_event) { return wmi->ops->extract_mlo_vdev_bcast_tid_to_link_map_event( diff --git a/wmi/src/wmi_unified_11be_tlv.c b/wmi/src/wmi_unified_11be_tlv.c index f1f972dcaf..8dfb488e51 100644 --- a/wmi/src/wmi_unified_11be_tlv.c +++ b/wmi/src/wmi_unified_11be_tlv.c @@ -1180,10 +1180,11 @@ static QDF_STATUS extract_mlo_vdev_bcast_tid_to_link_map_event_tlv( struct wmi_unified *wmi_handle, void *buf, - struct wmi_host_bcast_t2lm_info *bcast_info) + struct mlo_bcast_t2lm_info *bcast_info) { WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs; wmi_mlo_bcast_t2lm_info *info; + int i; param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *)buf; if (!param_tlvs) { @@ -1191,19 +1192,32 @@ extract_mlo_vdev_bcast_tid_to_link_map_event_tlv( return QDF_STATUS_E_INVAL; } - info = param_tlvs->mlo_bcast_t2lm_info; - if (!info) { - wmi_debug("mgmt_ml_info TLV is not sent by FW"); + if (param_tlvs->num_mlo_bcast_t2lm_info > MAX_AP_MLDS_PER_LINK) { + wmi_err("num_mlo_bcast_t2lm_info is greater than %d", + MAX_AP_MLDS_PER_LINK); return QDF_STATUS_E_INVAL; } - bcast_info->vdev_id = - WMI_MLO_BROADCAST_TID_TO_LINK_MAP_INFO_VDEV_ID_GET( - info->vdev_id_expec_dur); + info = param_tlvs->mlo_bcast_t2lm_info; + if (!info) { + wmi_debug("mlo_bcast_t2lm_info is not applicable"); + return QDF_STATUS_SUCCESS; + } - bcast_info->expected_duration = - WMI_MLO_BROADCAST_TID_TO_LINK_MAP_INFO_EXP_DUR_GET( - info->vdev_id_expec_dur); + bcast_info->num_vdevs = param_tlvs->num_mlo_bcast_t2lm_info; + wmi_debug("num_vdevs:%d", bcast_info->num_vdevs); + for (i = 0; i < param_tlvs->num_mlo_bcast_t2lm_info; i++) { + bcast_info->vdev_id[i] = + WMI_MLO_BROADCAST_TID_TO_LINK_MAP_INFO_VDEV_ID_GET( + info->vdev_id_expec_dur); + + bcast_info->expected_duration[i] = + WMI_MLO_BROADCAST_TID_TO_LINK_MAP_INFO_EXP_DUR_GET( + info->vdev_id_expec_dur); + wmi_debug("vdev_id:%d expected_duration:%d", + bcast_info->vdev_id[i], + bcast_info->expected_duration[i]); + } return QDF_STATUS_SUCCESS; }