diff --git a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h index 4f07e10116..58592ee264 100644 --- a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h +++ b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h @@ -2595,6 +2595,9 @@ struct wlan_ml_rv_linfo_perstaprof { /* All Updates Included */ #define WLAN_RNR_NBRAPINFO_TBTTINFO_MLDPARAMS_ALLUPDATESINC_IDX 20 #define WLAN_RNR_NBRAPINFO_TBTTINFO_MLDPARAMS_ALLUPDATESINC_BITS 1 +/* Disabled link indication */ +#define WLAN_RNR_NBRAPINFO_TBTTINFO_MLDPARAMS_DISABLEDLINKIND_IDX 21 +#define WLAN_RNR_NBRAPINFO_TBTTINFO_MLDPARAMS_DISABLEDLINKIND_BITS 1 /* * End of definitions related to MLO specific aspects of Reduced Neighbor Report diff --git a/umac/mlo_mgr/inc/wlan_mlo_t2lm.h b/umac/mlo_mgr/inc/wlan_mlo_t2lm.h index 483b51b408..ad6ca85b8b 100644 --- a/umac/mlo_mgr/inc/wlan_mlo_t2lm.h +++ b/umac/mlo_mgr/inc/wlan_mlo_t2lm.h @@ -40,34 +40,33 @@ #define t2lm_debug(format, args...) \ QDF_TRACE_DEBUG(QDF_MODULE_ID_T2LM, format, ## args) +#define t2lm_rl_debug(format, args...) \ + QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_T2LM, format, ## args) + #define WLAN_T2LM_MAX_NUM_LINKS 16 /** * wlan_mlo_parse_t2lm_ie() - API to parse the T2LM IE - * @peer: Pointer to peer structure * @t2lm: Pointer to T2LM structure * @ie: Pointer to T2LM IE * * Return: QDF_STATUS */ QDF_STATUS wlan_mlo_parse_t2lm_ie( - struct wlan_objmgr_peer *peer, struct wlan_t2lm_onging_negotiation_info *t2lm, uint8_t *ie); /** * wlan_mlo_add_t2lm_ie() - API to add TID-to-link mapping IE * @frm: Pointer to buffer - * @peer: Pointer to peer structure * @t2lm: Pointer to t2lm mapping structure * * Return: Updated frame pointer */ -uint8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm, struct wlan_objmgr_peer *peer, +uint8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm, struct wlan_t2lm_onging_negotiation_info *t2lm); /** * wlan_mlo_parse_t2lm_action_frame() - API to parse T2LM action frame - * @peer: Pointer to peer structure * @t2lm: Pointer to T2LM structure * @action_frm: Pointer to action frame * @category: T2LM action frame category @@ -75,14 +74,12 @@ uint8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm, struct wlan_objmgr_peer *peer, * Return: 0 - success, else failure */ int wlan_mlo_parse_t2lm_action_frame( - struct wlan_objmgr_peer *peer, struct wlan_t2lm_onging_negotiation_info *t2lm, struct wlan_action_frame *action_frm, enum wlan_t2lm_category category); /** * wlan_mlo_add_t2lm_action_frame() - API to add T2LM action frame - * @peer: Pointer to peer structure * @frm: Pointer to a frame to add T2LM IE * @args: T2LM action frame related info * @buf: Pointer to T2LM IE values @@ -91,19 +88,37 @@ int wlan_mlo_parse_t2lm_action_frame( * Return: Pointer to the updated frame buffer */ uint8_t *wlan_mlo_add_t2lm_action_frame( - struct wlan_objmgr_peer *peer, uint8_t *frm, struct wlan_action_frame_args *args, uint8_t *buf, enum wlan_t2lm_category category); + +/** + * wlan_mlo_parse_bcn_prbresp_t2lm_ie() - API to parse the T2LM IE from beacon/ + * probe response frame + * @t2lm_ctx: T2LM context + * @ie: Pointer to T2LM IE + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_mlo_parse_bcn_prbresp_t2lm_ie( + struct wlan_t2lm_context *t2lm_ctx, uint8_t *ie); + +/** + * wlan_mlo_add_t2lm_info_ie() - Add T2LM IE for UL/DL/Bidirection + * @frm: Pointer to buffer + * @t2lm: Pointer to t2lm mapping structure + * + * Return: Updated frame pointer + */ +uint8_t *wlan_mlo_add_t2lm_info_ie(uint8_t *frm, struct wlan_t2lm_info *t2lm); #else static inline QDF_STATUS wlan_mlo_parse_t2lm_ie( - struct wlan_objmgr_peer *peer, struct wlan_t2lm_onging_negotiation_info *t2lm, uint8_t *ie) { return QDF_STATUS_E_FAILURE; } static inline -int8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm, struct wlan_objmgr_peer *peer, +int8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm, struct wlan_t2lm_onging_negotiation_info *t2lm) { return frm; @@ -111,7 +126,6 @@ int8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm, struct wlan_objmgr_peer *peer, static inline int wlan_mlo_parse_t2lm_action_frame( - struct wlan_objmgr_peer *peer, struct wlan_t2lm_onging_negotiation_info *t2lm, struct wlan_action_frame *action_frm, enum wlan_t2lm_category category) @@ -121,11 +135,23 @@ int wlan_mlo_parse_t2lm_action_frame( static inline uint8_t *wlan_mlo_add_t2lm_action_frame( - struct wlan_objmgr_peer *peer, uint8_t *frm, struct wlan_action_frame_args *args, uint8_t *buf, enum wlan_t2lm_category category) { return frm; } + +static inline +QDF_STATUS wlan_mlo_parse_bcn_prbresp_t2lm_ie( + struct wlan_t2lm_context *t2lm_ctx, uint8_t *ie) +{ + return QDF_STATUS_E_FAILURE; +} + +static inline +uint8_t *wlan_mlo_add_t2lm_info_ie(uint8_t *frm, struct wlan_t2lm_info *t2lm) +{ + return frm; +} #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 ddfe873dd3..a0be5d612a 100644 --- a/umac/mlo_mgr/src/wlan_mlo_t2lm.c +++ b/umac/mlo_mgr/src/wlan_mlo_t2lm.c @@ -26,138 +26,34 @@ #include #include -/** - * wlan_mlo_get_hw_link_id_mask() - Return hw_link_id mask for a given - * ieee_link_id_mask. - * @wlan_vdev_list: vdev list - * @vdev_count: vdev count - * @ieee_link_id_mask: IEEE link id mask - * - * Return: hw_link_id mask - */ -static uint8_t wlan_mlo_get_hw_link_id_mask( - struct wlan_objmgr_vdev **wlan_vdev_list, - uint16_t vdev_count, uint16_t ieee_link_id_mask) -{ - struct wlan_objmgr_pdev *pdev; - struct wlan_objmgr_vdev *vdev; - uint8_t link_id; - uint16_t ieee_link_id; - uint16_t hw_link_id_mask = 0; - int i; - - for (link_id = 0; link_id < WLAN_T2LM_MAX_NUM_LINKS; link_id++) { - ieee_link_id = ieee_link_id_mask & BIT(link_id); - if (!ieee_link_id) - continue; - - for (i = 0; i < vdev_count; i++) { - vdev = wlan_vdev_list[i]; - if (!vdev) { - t2lm_err("vdev is null"); - continue; - } - - if (ieee_link_id != BIT(vdev->vdev_mlme.mlo_link_id)) - continue; - - pdev = wlan_vdev_get_pdev(vdev); - if (!pdev) { - t2lm_err("pdev is null"); - continue; - } - - hw_link_id_mask |= - BIT(wlan_mlo_get_pdev_hw_link_id(pdev)); - break; - } - } - - return hw_link_id_mask; -} - -/** - * wlan_mlo_parse_t2lm_provisioned_links() - Parse the T2LM provisioned links - * from the T2LM IE. - * @peer: Pointer to peer structure - * @link_mapping_presence_ind: This indicates whether the link mapping of TIDs - * present in the T2LM IE. - * @link_mapping_of_tids: Link mapping of each TID - * @t2lm: Pointer to a T2LM structure - * @dir: DL/UL/BIDI direction - * - * Return: QDF_STATUS - */ -static QDF_STATUS wlan_mlo_parse_t2lm_provisioned_links( - struct wlan_objmgr_peer *peer, - uint8_t link_mapping_presence_ind, - uint8_t *link_mapping_of_tids, - struct wlan_t2lm_onging_negotiation_info *t2lm, - enum wlan_t2lm_direction dir) -{ - struct wlan_objmgr_vdev *vdev; - struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS] = {0}; - uint16_t vdev_count = 0; - uint16_t hw_link_id_mask; - uint8_t tid_num; - uint16_t i; - - vdev = wlan_peer_get_vdev(peer); - if (!vdev) { - t2lm_err("vdev is null"); - return QDF_STATUS_E_NULL_VALUE; - } - - mlo_get_ml_vdev_list(vdev, &vdev_count, wlan_vdev_list); - if (!vdev_count) { - t2lm_err("Number of VDEVs under MLD is reported as 0"); - return QDF_STATUS_E_NULL_VALUE; - } - - for (tid_num = 0; tid_num < T2LM_MAX_NUM_TIDS; tid_num++) { - if (link_mapping_presence_ind & BIT(tid_num)) { - hw_link_id_mask = wlan_mlo_get_hw_link_id_mask( - wlan_vdev_list, vdev_count, - *(uint16_t *)link_mapping_of_tids); - t2lm->t2lm_info[dir].hw_link_map_tid[tid_num] = - hw_link_id_mask; - link_mapping_of_tids += sizeof(uint16_t); - } - } - - for (i = 0; i < vdev_count; i++) - mlo_release_vdev_ref(wlan_vdev_list[i]); - - return QDF_STATUS_SUCCESS; -} - /** * wlan_mlo_parse_t2lm_info() - Parse T2LM IE fields - * @peer: Pointer to peer structure * @ie: Pointer to T2LM IE * @t2lm: Pointer to T2LM structure * * Return: QDF_STATUS */ -static QDF_STATUS wlan_mlo_parse_t2lm_info( - struct wlan_objmgr_peer *peer, uint8_t *ie, - struct wlan_t2lm_onging_negotiation_info *t2lm) +static QDF_STATUS wlan_mlo_parse_t2lm_info(uint8_t *ie, + struct wlan_t2lm_info *t2lm) { + struct wlan_ie_tid_to_link_mapping *t2lm_ie; enum wlan_t2lm_direction dir; uint8_t *t2lm_control_field; uint16_t t2lm_control; uint8_t link_mapping_presence_ind; uint8_t *link_mapping_of_tids; uint8_t tid_num; - QDF_STATUS ret; + uint8_t *ie_ptr = NULL; - t2lm_control_field = ie + sizeof(struct wlan_ie_tid_to_link_mapping); + t2lm_ie = (struct wlan_ie_tid_to_link_mapping *)ie; + + t2lm_control_field = t2lm_ie->data; if (!t2lm_control_field) { t2lm_err("t2lm_control_field is null"); return QDF_STATUS_E_NULL_VALUE; } - t2lm_control = *(uint16_t *)t2lm_control_field; + t2lm_control = qdf_le16_to_cpu(*(uint16_t *)t2lm_control_field); dir = QDF_GET_BITS(t2lm_control, WLAN_T2LM_CONTROL_DIRECTION_IDX, WLAN_T2LM_CONTROL_DIRECTION_BITS); @@ -166,57 +62,124 @@ static QDF_STATUS wlan_mlo_parse_t2lm_info( return QDF_STATUS_E_NULL_VALUE; } - t2lm->t2lm_info[dir].direction = dir; - t2lm->t2lm_info[dir].default_link_mapping = + t2lm->direction = dir; + t2lm->default_link_mapping = QDF_GET_BITS(t2lm_control, WLAN_T2LM_CONTROL_DEFAULT_LINK_MAPPING_IDX, WLAN_T2LM_CONTROL_DEFAULT_LINK_MAPPING_BITS); - t2lm_debug("direction:%d default_link_mapping:%d", - t2lm->t2lm_info[dir].direction, - t2lm->t2lm_info[dir].default_link_mapping); + t2lm->mapping_switch_time_present = + QDF_GET_BITS(t2lm_control, + WLAN_T2LM_CONTROL_MAPPING_SWITCH_TIME_PRESENT_IDX, + WLAN_T2LM_CONTROL_MAPPING_SWITCH_TIME_PRESENT_BITS); - /* Link mapping of TIDs are not present when default mapping is set */ - if (t2lm->t2lm_info[dir].default_link_mapping) + t2lm->expected_duration_present = + QDF_GET_BITS(t2lm_control, + WLAN_T2LM_CONTROL_EXPECTED_DURATION_PRESENT_IDX, + WLAN_T2LM_CONTROL_EXPECTED_DURATION_PRESENT_BITS); + + t2lm_debug("direction:%d default_link_mapping:%d mapping_switch_time_present:%d expected_duration_present:%d", + t2lm->direction, t2lm->default_link_mapping, + t2lm->mapping_switch_time_present, + t2lm->expected_duration_present); + + if (t2lm->default_link_mapping) { + ie_ptr = t2lm_control_field + sizeof(uint8_t); + } else { + link_mapping_presence_ind = + QDF_GET_BITS(t2lm_control, + WLAN_T2LM_CONTROL_LINK_MAPPING_PRESENCE_INDICATOR_IDX, + WLAN_T2LM_CONTROL_LINK_MAPPING_PRESENCE_INDICATOR_BITS); + ie_ptr = t2lm_control_field + sizeof(t2lm_control); + } + + if (t2lm->mapping_switch_time_present) { + t2lm->mapping_switch_time = + qdf_le16_to_cpu(*(uint16_t *)ie_ptr); + ie_ptr += sizeof(uint16_t); + } + + if (t2lm->expected_duration_present) { + qdf_mem_copy(&t2lm->expected_duration, ie_ptr, + WLAN_T2LM_EXPECTED_DURATION_SIZE * + (sizeof(uint8_t))); + ie_ptr += WLAN_T2LM_EXPECTED_DURATION_SIZE * (sizeof(uint8_t)); + } + + t2lm_debug("direction:%d default_link_mapping:%d mapping_switch_time:%d expected_duration:%d", + t2lm->direction, t2lm->default_link_mapping, + t2lm->mapping_switch_time, t2lm->expected_duration); + + if (t2lm->default_link_mapping) return QDF_STATUS_SUCCESS; - link_mapping_presence_ind = QDF_GET_BITS( - t2lm_control, - WLAN_T2LM_CONTROL_LINK_MAPPING_PRESENCE_INDICATOR_IDX, - WLAN_T2LM_CONTROL_LINK_MAPPING_PRESENCE_INDICATOR_BITS); - - link_mapping_of_tids = t2lm_control_field + sizeof(t2lm_control); - - ret = wlan_mlo_parse_t2lm_provisioned_links(peer, - link_mapping_presence_ind, - link_mapping_of_tids, t2lm, - dir); - if (ret) { - t2lm_err("failed to populate provisioned links"); - return ret; - } + link_mapping_of_tids = ie_ptr; for (tid_num = 0; tid_num < T2LM_MAX_NUM_TIDS; tid_num++) { - if (link_mapping_presence_ind & BIT(tid_num)) - t2lm_debug("link mapping of TID%d is %x", tid_num, - t2lm->t2lm_info[dir].hw_link_map_tid[tid_num]); + if (!(link_mapping_presence_ind & BIT(tid_num))) + continue; + + t2lm->ieee_link_map_tid[tid_num] = + qdf_le16_to_cpu(*(uint16_t *)link_mapping_of_tids); + + t2lm_debug("link mapping of TID%d is %x", tid_num, + t2lm->ieee_link_map_tid[tid_num]); + + link_mapping_of_tids += sizeof(uint16_t); } - return ret; + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_mlo_parse_bcn_prbresp_t2lm_ie( + struct wlan_t2lm_context *t2lm_ctx, uint8_t *ie) +{ + struct extn_ie_header *ext_ie_hdr; + QDF_STATUS retval; + int i = 0; + + for (i = 0; i < t2lm_ctx->num_of_t2lm_ie; i++) { + qdf_mem_zero(&t2lm_ctx->t2lm_ie[i].t2lm, + sizeof(struct wlan_t2lm_info)); + t2lm_ctx->t2lm_ie[i].t2lm.direction = + WLAN_T2LM_INVALID_DIRECTION; + } + + t2lm_ctx->num_of_t2lm_ie = 0; + + for (i = 0; i < WLAN_MAX_T2LM_IE; i++) { + if (!ie) { + t2lm_err("ie is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + ext_ie_hdr = (struct extn_ie_header *)ie; + + if (ext_ie_hdr->ie_id == WLAN_ELEMID_EXTN_ELEM && + ext_ie_hdr->ie_extn_id == WLAN_EXTN_ELEMID_T2LM) { + retval = wlan_mlo_parse_t2lm_info( + ie, &t2lm_ctx->t2lm_ie[i].t2lm); + if (retval) { + t2lm_err("Failed to parse the T2LM IE"); + return retval; + } + + t2lm_ctx->num_of_t2lm_ie++; + + ie += ext_ie_hdr->ie_len + sizeof(struct ie_header); + } + } + + return QDF_STATUS_SUCCESS; } QDF_STATUS wlan_mlo_parse_t2lm_ie( - struct wlan_objmgr_peer *peer, struct wlan_t2lm_onging_negotiation_info *t2lm, uint8_t *ie) { - struct extn_ie_header *ext_ie_hdr; - enum wlan_t2lm_direction dir; + struct extn_ie_header *ext_ie_hdr = NULL; QDF_STATUS retval; - - if (!peer) { - t2lm_err("null peer"); - return QDF_STATUS_E_NULL_VALUE; - } + enum wlan_t2lm_direction dir; + struct wlan_t2lm_info t2lm_info; for (dir = 0; dir < WLAN_T2LM_MAX_DIRECTION; dir++) t2lm->t2lm_info[dir].direction = WLAN_T2LM_INVALID_DIRECTION; @@ -231,8 +194,14 @@ QDF_STATUS wlan_mlo_parse_t2lm_ie( if (ext_ie_hdr->ie_id == WLAN_ELEMID_EXTN_ELEM && ext_ie_hdr->ie_extn_id == WLAN_EXTN_ELEMID_T2LM) { - retval = wlan_mlo_parse_t2lm_info(peer, ie, t2lm); - if (retval) { + qdf_mem_zero(&t2lm_info, sizeof(t2lm_info)); + retval = wlan_mlo_parse_t2lm_info(ie, &t2lm_info); + if (!retval && + t2lm_info.direction < WLAN_T2LM_MAX_DIRECTION) { + qdf_mem_copy(&t2lm->t2lm_info[t2lm_info.direction], + &t2lm_info, + sizeof(struct wlan_t2lm_info)); + } else { t2lm_err("Failed to parse the T2LM IE"); return retval; } @@ -261,125 +230,13 @@ QDF_STATUS wlan_mlo_parse_t2lm_ie( } /** - * wlan_get_ieee_link_id_mask() - Get ieee_link_id mask from hw_link_id mask - * @wlan_vdev_list: Pointer to vdev list - * @vdev_count: vdev count - * @hw_link_id_mask: hw_link_id mask - * - * Return: IEEE link ID mask - */ -static uint8_t wlan_get_ieee_link_id_mask( - struct wlan_objmgr_vdev **wlan_vdev_list, - uint16_t vdev_count, uint16_t hw_link_id_mask) -{ - struct wlan_objmgr_pdev *pdev; - struct wlan_objmgr_vdev *vdev; - uint8_t link_id; - uint16_t hw_link_id; - uint16_t ieee_link_id_mask = 0; - int i; - - for (link_id = 0; link_id < WLAN_T2LM_MAX_NUM_LINKS; link_id++) { - hw_link_id = hw_link_id_mask & BIT(link_id); - if (!hw_link_id) - continue; - - for (i = 0; i < vdev_count; i++) { - vdev = wlan_vdev_list[i]; - if (!vdev) { - t2lm_err("vdev is null"); - continue; - } - - pdev = wlan_vdev_get_pdev(vdev); - if (!pdev) { - t2lm_err("pdev is null"); - continue; - } - - if (hw_link_id != BIT(wlan_mlo_get_pdev_hw_link_id(pdev))) - continue; - - ieee_link_id_mask |= BIT(vdev->vdev_mlme.mlo_link_id); - break; - } - } - - return ieee_link_id_mask; -} - -/** - * wlan_mlo_add_t2lm_provisioned_links() - API to add provisioned links in the - * T2LM IE - * @peer: Pointer to peer structure - * @link_mapping_presence_indicator: This indicates whether the link mapping of - * TIDs present in the T2LM IE. - * @link_mapping_of_tids: Link mapping of each TID - * @t2lm: Pointer to a T2LM structure - * @num_tids: Pointer to save num TIDs - * - * Return: QDF_STATUS - */ -static QDF_STATUS wlan_mlo_add_t2lm_provisioned_links( - struct wlan_objmgr_peer *peer, - uint8_t link_mapping_presence_indicator, - uint8_t *link_mapping_of_tids, struct wlan_t2lm_info *t2lm, - uint8_t *num_tids) -{ - struct wlan_objmgr_vdev *vdev; - struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS] = {0}; - uint16_t vdev_count = 0; - uint16_t hw_link_id_mask; - uint16_t ieee_link_id_mask; - uint8_t tid_num; - uint16_t i; - - vdev = wlan_peer_get_vdev(peer); - if (!vdev) { - t2lm_err("vdev is null"); - return QDF_STATUS_E_NULL_VALUE; - } - - mlo_get_ml_vdev_list(vdev, &vdev_count, wlan_vdev_list); - if (!vdev_count) { - t2lm_err("Number of VDEVs under MLD is reported as 0"); - return QDF_STATUS_E_NULL_VALUE; - } - - for (tid_num = 0; tid_num < T2LM_MAX_NUM_TIDS; tid_num++) { - ieee_link_id_mask = 0; - - if (t2lm->hw_link_map_tid[tid_num]) { - hw_link_id_mask = t2lm->hw_link_map_tid[tid_num]; - ieee_link_id_mask = wlan_get_ieee_link_id_mask( - wlan_vdev_list, vdev_count, - hw_link_id_mask); - } - - *(uint16_t *)link_mapping_of_tids = ieee_link_id_mask; - t2lm_info("link mapping of TID%d is %x", tid_num, - ieee_link_id_mask); - link_mapping_of_tids += sizeof(uint16_t); - (*num_tids)++; - } - - for (i = 0; i < vdev_count; i++) - mlo_release_vdev_ref(wlan_vdev_list[i]); - - return QDF_STATUS_SUCCESS; -} - -/** - * wlan_add_t2lm_info_ie() - Add T2LM IE for UL/DL/Bidirection + * wlan_mlo_add_t2lm_info_ie() - Add T2LM IE for UL/DL/Bidirection * @frm: Pointer to buffer - * @peer: Pointer to peer structure * @t2lm: Pointer to t2lm mapping structure * * Return: Updated frame pointer */ -static uint8_t *wlan_add_t2lm_info_ie(uint8_t *frm, - struct wlan_objmgr_peer *peer, - struct wlan_t2lm_info *t2lm) +uint8_t *wlan_mlo_add_t2lm_info_ie(uint8_t *frm, struct wlan_t2lm_info *t2lm) { struct wlan_ie_tid_to_link_mapping *t2lm_ie; uint16_t t2lm_control = 0; @@ -388,8 +245,6 @@ static uint8_t *wlan_add_t2lm_info_ie(uint8_t *frm, uint8_t tid_num; uint8_t num_tids = 0; uint8_t link_mapping_presence_indicator = 0; - uint8_t *efrm = frm; - int ret; t2lm_ie = (struct wlan_ie_tid_to_link_mapping *)frm; t2lm_ie->elem_id = WLAN_ELEMID_EXTN_ELEM; @@ -406,6 +261,16 @@ static uint8_t *wlan_add_t2lm_info_ie(uint8_t *frm, WLAN_T2LM_CONTROL_DEFAULT_LINK_MAPPING_BITS, t2lm->default_link_mapping); + QDF_SET_BITS(t2lm_control, + WLAN_T2LM_CONTROL_MAPPING_SWITCH_TIME_PRESENT_IDX, + WLAN_T2LM_CONTROL_MAPPING_SWITCH_TIME_PRESENT_BITS, + t2lm->mapping_switch_time_present); + + QDF_SET_BITS(t2lm_control, + WLAN_T2LM_CONTROL_EXPECTED_DURATION_PRESENT_IDX, + WLAN_T2LM_CONTROL_EXPECTED_DURATION_PRESENT_BITS, + t2lm->expected_duration_present); + if (t2lm->default_link_mapping) { /* Link mapping of TIDs are not present when default mapping is * set. Hence, the size of TID-To-Link mapping control is one @@ -415,8 +280,8 @@ static uint8_t *wlan_add_t2lm_info_ie(uint8_t *frm, t2lm_ie->elem_len += sizeof(uint8_t); - t2lm_info("T2LM IE added, default_link_mapping: %d dir:%d", - t2lm->default_link_mapping, t2lm->direction); + t2lm_rl_debug("T2LM IE added, default_link_mapping: %d dir:%d", + t2lm->default_link_mapping, t2lm->direction); frm += sizeof(*t2lm_ie) + sizeof(uint8_t); } else { @@ -428,35 +293,59 @@ static uint8_t *wlan_add_t2lm_info_ie(uint8_t *frm, WLAN_T2LM_CONTROL_LINK_MAPPING_PRESENCE_INDICATOR_IDX, WLAN_T2LM_CONTROL_LINK_MAPPING_PRESENCE_INDICATOR_BITS, link_mapping_presence_indicator); - t2lm_info("T2LM IE added, direction:%d link_mapping_presence_indicator:%x", - t2lm->direction, link_mapping_presence_indicator); + t2lm_rl_debug("T2LM IE added, direction:%d link_mapping_presence_indicator:%x", + t2lm->direction, link_mapping_presence_indicator); /* The size of TID-To-Link mapping control is two octets when * default link mapping is not set. */ *(uint16_t *)t2lm_control_field = htole16(t2lm_control); - - link_mapping_of_tids = t2lm_control_field + sizeof(uint16_t); - - ret = wlan_mlo_add_t2lm_provisioned_links( - peer, link_mapping_presence_indicator, - link_mapping_of_tids, t2lm, &num_tids); - if (ret) { - t2lm_err("Failed to add t2lm provisioned links"); - return efrm; - } - - t2lm_ie->elem_len += sizeof(uint16_t) + - (num_tids * sizeof(uint16_t)); - - frm += sizeof(*t2lm_ie) + sizeof(uint16_t) + - (num_tids * sizeof(uint16_t)); + frm += sizeof(*t2lm_ie) + sizeof(uint16_t); + t2lm_ie->elem_len += sizeof(uint16_t); } + if (t2lm->mapping_switch_time_present) { + *frm = htole16(t2lm->mapping_switch_time); + frm += sizeof(uint16_t); + t2lm_ie->elem_len += sizeof(uint16_t); + } + + if (t2lm->expected_duration_present) { + qdf_mem_copy(frm, &t2lm->expected_duration, + WLAN_T2LM_EXPECTED_DURATION_SIZE * + sizeof(uint8_t)); + frm += WLAN_T2LM_EXPECTED_DURATION_SIZE; + t2lm_ie->elem_len += + WLAN_T2LM_EXPECTED_DURATION_SIZE * sizeof(uint8_t); + } + + t2lm_rl_debug("mapping_switch_time:%d expected_duration:%u", + t2lm->mapping_switch_time, t2lm->expected_duration); + + if (t2lm->default_link_mapping) + return frm; + + link_mapping_of_tids = frm; + + for (tid_num = 0; tid_num < T2LM_MAX_NUM_TIDS; tid_num++) { + if (!t2lm->ieee_link_map_tid[tid_num]) + continue; + + *(uint16_t *)link_mapping_of_tids = + htole16(t2lm->ieee_link_map_tid[tid_num]); + t2lm_rl_debug("link mapping of TID%d is %x", tid_num, + htole16(t2lm->ieee_link_map_tid[tid_num])); + link_mapping_of_tids += sizeof(uint16_t); + num_tids++; + } + + frm += num_tids * sizeof(uint16_t); + t2lm_ie->elem_len += (num_tids * sizeof(uint16_t)); + return frm; } -uint8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm, struct wlan_objmgr_peer *peer, +uint8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm, struct wlan_t2lm_onging_negotiation_info *t2lm) { uint8_t dir; @@ -487,8 +376,8 @@ uint8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm, struct wlan_objmgr_peer *peer, for (dir = 0; dir < WLAN_T2LM_MAX_DIRECTION; dir++) { if (t2lm->t2lm_info[dir].direction != WLAN_T2LM_INVALID_DIRECTION) - frm = wlan_add_t2lm_info_ie(frm, peer, - &t2lm->t2lm_info[dir]); + frm = wlan_mlo_add_t2lm_info_ie(frm, + &t2lm->t2lm_info[dir]); } return frm; @@ -497,7 +386,6 @@ uint8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm, struct wlan_objmgr_peer *peer, /** * wlan_mlo_parse_t2lm_request_action_frame() - API to parse T2LM request action * frame. - * @peer: Pointer to peer structure * @t2lm: Pointer to T2LM structure * @action_frm: Pointer to action frame * @category: T2LM action frame category @@ -505,7 +393,6 @@ uint8_t *wlan_mlo_add_t2lm_ie(uint8_t *frm, struct wlan_objmgr_peer *peer, * Return: QDF_STATUS */ static QDF_STATUS wlan_mlo_parse_t2lm_request_action_frame( - struct wlan_objmgr_peer *peer, struct wlan_t2lm_onging_negotiation_info *t2lm, struct wlan_action_frame *action_frm, enum wlan_t2lm_category category) @@ -530,14 +417,13 @@ static QDF_STATUS wlan_mlo_parse_t2lm_request_action_frame( t2lm->dialog_token = *t2lm_action_frm; - return wlan_mlo_parse_t2lm_ie(peer, t2lm, + return wlan_mlo_parse_t2lm_ie(t2lm, t2lm_action_frm + sizeof(uint8_t)); } /** * wlan_mlo_parse_t2lm_response_action_frame() - API to parse T2LM response * action frame. - * @peer: Pointer to peer structure * @t2lm: Pointer to T2LM structure * @action_frm: Pointer to action frame * @category: T2LM action frame category @@ -545,7 +431,6 @@ static QDF_STATUS wlan_mlo_parse_t2lm_request_action_frame( * Return: QDF_STATUS */ static QDF_STATUS wlan_mlo_parse_t2lm_response_action_frame( - struct wlan_objmgr_peer *peer, struct wlan_t2lm_onging_negotiation_info *t2lm, struct wlan_action_frame *action_frm, enum wlan_t2lm_category category) @@ -574,14 +459,13 @@ static QDF_STATUS wlan_mlo_parse_t2lm_response_action_frame( if (t2lm->t2lm_resp_type == WLAN_T2LM_RESP_TYPE_PREFERRED_TID_TO_LINK_MAPPING) { t2lm_action_frm += sizeof(uint8_t) + sizeof(uint8_t); - ret_val = wlan_mlo_parse_t2lm_ie(peer, t2lm, t2lm_action_frm); + ret_val = wlan_mlo_parse_t2lm_ie(t2lm, t2lm_action_frm); } return ret_val; } int wlan_mlo_parse_t2lm_action_frame( - struct wlan_objmgr_peer *peer, struct wlan_t2lm_onging_negotiation_info *t2lm, struct wlan_action_frame *action_frm, enum wlan_t2lm_category category) @@ -592,13 +476,13 @@ int wlan_mlo_parse_t2lm_action_frame( case WLAN_T2LM_CATEGORY_REQUEST: { ret_val = wlan_mlo_parse_t2lm_request_action_frame( - peer, t2lm, action_frm, category); + t2lm, action_frm, category); return qdf_status_to_os_return(ret_val); } case WLAN_T2LM_CATEGORY_RESPONSE: { ret_val = wlan_mlo_parse_t2lm_response_action_frame( - peer, t2lm, action_frm, category); + t2lm, action_frm, category); return qdf_status_to_os_return(ret_val); } @@ -625,7 +509,7 @@ int wlan_mlo_parse_t2lm_action_frame( } static uint8_t *wlan_mlo_add_t2lm_request_action_frame( - struct wlan_objmgr_peer *peer, uint8_t *frm, + uint8_t *frm, struct wlan_action_frame_args *args, uint8_t *buf, enum wlan_t2lm_category category) { @@ -636,11 +520,11 @@ static uint8_t *wlan_mlo_add_t2lm_request_action_frame( t2lm_info("T2LM request frame: category:%d action:%d dialog_token:%d", args->category, args->action, args->arg1); - return wlan_mlo_add_t2lm_ie(frm, peer, (void *)buf); + return wlan_mlo_add_t2lm_ie(frm, (void *)buf); } static uint8_t *wlan_mlo_add_t2lm_response_action_frame( - struct wlan_objmgr_peer *peer, uint8_t *frm, + uint8_t *frm, struct wlan_action_frame_args *args, uint8_t *buf, enum wlan_t2lm_category category) { @@ -655,27 +539,23 @@ static uint8_t *wlan_mlo_add_t2lm_response_action_frame( args->category, args->action, args->arg1, args->arg2); if (args->arg2 == WLAN_T2LM_RESP_TYPE_PREFERRED_TID_TO_LINK_MAPPING) - frm = wlan_mlo_add_t2lm_ie(frm, peer, (void *)buf); + frm = wlan_mlo_add_t2lm_ie(frm, (void *)buf); return frm; } uint8_t *wlan_mlo_add_t2lm_action_frame( - struct wlan_objmgr_peer *peer, uint8_t *frm, + uint8_t *frm, struct wlan_action_frame_args *args, uint8_t *buf, enum wlan_t2lm_category category) { - if (!peer) { - t2lm_err("null peer"); - return NULL; - } switch (category) { case WLAN_T2LM_CATEGORY_REQUEST: - return wlan_mlo_add_t2lm_request_action_frame(peer, frm, args, + return wlan_mlo_add_t2lm_request_action_frame(frm, args, buf, category); case WLAN_T2LM_CATEGORY_RESPONSE: - return wlan_mlo_add_t2lm_response_action_frame(peer, frm, args, + return wlan_mlo_add_t2lm_response_action_frame(frm, args, buf, category); case WLAN_T2LM_CATEGORY_TEARDOWN: *frm++ = args->category;