qcacld-3.0: Enhance logic to support mlo 2+ links
Enhance the code logic to support mlo 2+ links. Change-Id: I618d789a502f0577d62d62243a25e7324e685315 CRs-Fixed: 3193628
Cette révision appartient à :

révisé par
Madan Koyyalamudi

Parent
595f20d1f4
révision
708b3542a3
@@ -1122,7 +1122,7 @@ cm_get_ml_partner_info(struct scan_cache_entry *scan_entry,
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
mlo_support_link_num = wlan_mlme_get_sta_mlo_conn_max_num(psoc);
|
||||
mlme_debug("mlo support link num: %d", mlo_support_link_num);
|
||||
mlme_debug("sta mlo support link num: %d", mlo_support_link_num);
|
||||
|
||||
/* TODO: Make sure that scan_entry->ml_info->link_info is a sorted
|
||||
* list.
|
||||
@@ -1132,9 +1132,10 @@ cm_get_ml_partner_info(struct scan_cache_entry *scan_entry,
|
||||
* entry should be cleared to not affect next connect request.
|
||||
*/
|
||||
for (i = 0; i < scan_entry->ml_info.num_links; i++) {
|
||||
mlme_debug("freq: %d, link id: %d "QDF_MAC_ADDR_FMT,
|
||||
mlme_debug("freq: %d, link id: %d is valid %d "QDF_MAC_ADDR_FMT,
|
||||
scan_entry->ml_info.link_info[i].freq,
|
||||
scan_entry->ml_info.link_info[i].link_id,
|
||||
scan_entry->ml_info.link_info[i].is_valid_link,
|
||||
QDF_MAC_ADDR_REF(
|
||||
scan_entry->ml_info.link_info[i].link_addr.bytes));
|
||||
if (j >= mlo_support_link_num - 1)
|
||||
@@ -1152,7 +1153,7 @@ cm_get_ml_partner_info(struct scan_cache_entry *scan_entry,
|
||||
}
|
||||
}
|
||||
partner_info->num_partner_links = j;
|
||||
mlme_debug("partner link num: %d", j);
|
||||
mlme_debug("sta and ap integrate link num: %d", j);
|
||||
|
||||
wlan_objmgr_psoc_release_ref(psoc, WLAN_MLME_CM_ID);
|
||||
|
||||
|
@@ -172,13 +172,15 @@ void hdd_wlan_register_mlo_interfaces(struct hdd_context *hdd_ctx)
|
||||
/* if target supports MLO create a new dev */
|
||||
params.only_wdev_register = true;
|
||||
params.associate_with_ml_adapter = false;
|
||||
status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
|
||||
"null", mac_addr, ¶ms);
|
||||
status = hdd_open_adapter_no_trans(hdd_ctx,
|
||||
QDF_STA_MODE,
|
||||
"null", mac_addr,
|
||||
¶ms);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
hdd_err("Failed to register link adapter:%d", status);
|
||||
}
|
||||
|
||||
qdf_mem_zero(¶ms, sizeof(struct hdd_adapter_create_param));
|
||||
qdf_mem_zero(¶ms, sizeof(params));
|
||||
params.only_wdev_register = true;
|
||||
params.associate_with_ml_adapter = true;
|
||||
mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
|
||||
|
@@ -1435,6 +1435,16 @@ QDF_STATUS populate_dot11f_assoc_rsp_mlo_ie(struct mac_context *mac_ctx,
|
||||
QDF_STATUS populate_dot11f_bcn_mlo_ie(struct mac_context *mac_ctx,
|
||||
struct pe_session *session);
|
||||
|
||||
/**
|
||||
* populate_dot11f_probe_req_mlo_ie() - populate mlo ie for probe req
|
||||
* @mac_ctx: Global MAC context
|
||||
* @session: PE session
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS of no error
|
||||
*/
|
||||
QDF_STATUS populate_dot11f_probe_req_mlo_ie(struct mac_context *mac_ctx,
|
||||
struct pe_session *session);
|
||||
|
||||
/**
|
||||
* populate_dot11f_mlo_rnr() - populate rnr for mlo
|
||||
* @mac_ctx: Global MAC context
|
||||
|
@@ -2648,6 +2648,29 @@ lim_check_ft_initial_im_association(struct roam_offload_synch_ind *roam_synch,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
static void
|
||||
lim_mlo_roam_copy_partner_info_to_session(struct pe_session *session,
|
||||
struct roam_offload_synch_ind *sync_ind)
|
||||
{
|
||||
uint8_t i;
|
||||
struct mlo_partner_info partner_info;
|
||||
|
||||
if (!sync_ind)
|
||||
return;
|
||||
|
||||
for (i = 0; i < sync_ind->num_setup_links; i++) {
|
||||
partner_info.partner_link_info[i].link_id =
|
||||
sync_ind->ml_link[i].link_id;
|
||||
qdf_copy_macaddr(
|
||||
&partner_info.partner_link_info[i].link_addr,
|
||||
&sync_ind->ml_link[i].link_addr);
|
||||
}
|
||||
|
||||
session->ml_partner_info = partner_info;
|
||||
session->ml_partner_info.num_partner_links = sync_ind->num_setup_links;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
lim_gen_link_specific_assoc_rsp(struct mac_context *mac_ctx,
|
||||
struct pe_session *session_entry,
|
||||
@@ -2657,6 +2680,8 @@ lim_gen_link_specific_assoc_rsp(struct mac_context *mac_ctx,
|
||||
struct element_info link_reassoc_rsp;
|
||||
struct qdf_mac_addr sta_link_addr;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
uint8_t idx = 0;
|
||||
uint8_t link_id;
|
||||
|
||||
link_reassoc_rsp.ptr = qdf_mem_malloc(reassoc_rsp_len);
|
||||
if (!link_reassoc_rsp.ptr)
|
||||
@@ -2667,28 +2692,53 @@ lim_gen_link_specific_assoc_rsp(struct mac_context *mac_ctx,
|
||||
|
||||
link_reassoc_rsp.len = reassoc_rsp_len;
|
||||
|
||||
status = util_gen_link_assoc_rsp(reassoc_rsp + WLAN_MAC_HDR_LEN_3A,
|
||||
for (idx = 0;
|
||||
idx < session_entry->ml_partner_info.num_partner_links;
|
||||
idx++) {
|
||||
link_id =
|
||||
session_entry->ml_partner_info.partner_link_info[idx].link_id;
|
||||
status =
|
||||
util_gen_link_assoc_rsp(reassoc_rsp + WLAN_MAC_HDR_LEN_3A,
|
||||
reassoc_rsp_len - WLAN_MAC_HDR_LEN_3A,
|
||||
true,
|
||||
link_id,
|
||||
sta_link_addr,
|
||||
link_reassoc_rsp.ptr,
|
||||
reassoc_rsp_len,
|
||||
(qdf_size_t *)&link_reassoc_rsp.len);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
pe_err("MLO ROAM: Link reassoc generation failed %d", status);
|
||||
goto end;
|
||||
}
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
pe_err("MLO ROAM: Link reassoc generation failed %d",
|
||||
status);
|
||||
goto end;
|
||||
}
|
||||
|
||||
lim_process_assoc_rsp_frame(mac_ctx, link_reassoc_rsp.ptr,
|
||||
lim_process_assoc_rsp_frame(mac_ctx, link_reassoc_rsp.ptr,
|
||||
link_reassoc_rsp.len - SIR_MAC_HDR_LEN_3A,
|
||||
LIM_REASSOC, session_entry);
|
||||
}
|
||||
end:
|
||||
qdf_mem_free(link_reassoc_rsp.ptr);
|
||||
link_reassoc_rsp.len = 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void
|
||||
lim_mlo_roam_copy_partner_info_to_session(struct pe_session *session,
|
||||
struct roam_offload_synch_ind *sync_ind)
|
||||
{}
|
||||
|
||||
static QDF_STATUS
|
||||
lim_gen_link_specific_assoc_rsp(struct mac_context *mac_ctx,
|
||||
struct pe_session *session_entry,
|
||||
uint8_t *reassoc_rsp,
|
||||
uint32_t reassoc_rsp_len)
|
||||
{
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_11AX
|
||||
static void pe_roam_fill_obss_scan_param(struct pe_session *src_session,
|
||||
struct pe_session *dst_session)
|
||||
@@ -2991,6 +3041,9 @@ pe_roam_synch_callback(struct mac_context *mac_ctx,
|
||||
if (roam_sync_ind_ptr->auth_status == ROAM_AUTH_STATUS_AUTHENTICATED)
|
||||
curr_sta_ds->is_key_installed = true;
|
||||
|
||||
lim_mlo_roam_copy_partner_info_to_session(ft_session_ptr,
|
||||
roam_sync_ind_ptr);
|
||||
|
||||
reassoc_resp = (uint8_t *)roam_sync_ind_ptr +
|
||||
roam_sync_ind_ptr->reassoc_resp_offset;
|
||||
|
||||
@@ -3779,24 +3832,6 @@ lim_validate_probe_rsp_link_info(struct pe_session *session_entry,
|
||||
}
|
||||
}
|
||||
|
||||
/* WAR: currently util_gen_link_reqrsp_cmn generates only the first
|
||||
* partner link and DUT only 2 mlo link is supported, so let's just
|
||||
* comparing the first partner info to check whether mlo is possible.
|
||||
*/
|
||||
if (ml_partner_info.num_partner_links == 1) {
|
||||
if (partner_info.partner_link_info[0].link_id ==
|
||||
ml_partner_info.partner_link_info[0].link_id &&
|
||||
(qdf_is_macaddr_equal(&ml_partner_info.partner_link_info[0].link_addr,
|
||||
&partner_info.partner_link_info[0].link_addr)))
|
||||
status = QDF_STATUS_SUCCESS;
|
||||
else
|
||||
status = QDF_STATUS_E_PROTO;
|
||||
|
||||
pe_debug("DUT num partner: %d, AP num partner: %d, status: %d",
|
||||
ml_partner_info.num_partner_links,
|
||||
partner_info.num_partner_links, status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -3984,6 +4019,8 @@ lim_gen_link_specific_probe_rsp(struct mac_context *mac_ctx,
|
||||
uint8_t chan;
|
||||
uint8_t op_class;
|
||||
uint16_t chan_freq, gen_frame_len;
|
||||
uint8_t idx;
|
||||
uint8_t req_link_id;
|
||||
|
||||
if (!session_entry)
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
@@ -3999,13 +4036,17 @@ lim_gen_link_specific_probe_rsp(struct mac_context *mac_ctx,
|
||||
|
||||
if (session_entry->lim_join_req->is_ml_probe_req_sent &&
|
||||
rcvd_probe_resp->mlo_ie.mlo_ie_present) {
|
||||
|
||||
session_entry->lim_join_req->is_ml_probe_req_sent = false;
|
||||
|
||||
partner_info = &session_entry->lim_join_req->partner_info;
|
||||
if (!partner_info->num_partner_links) {
|
||||
pe_err("STA doesn't have any partner link information");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
status = lim_validate_probe_rsp_link_info(session_entry,
|
||||
probe_rsp,
|
||||
probe_rsp_len);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
if(QDF_IS_STATUS_ERROR(
|
||||
lim_check_scan_db_for_join_req_partner_info(
|
||||
@@ -4040,77 +4081,84 @@ lim_gen_link_specific_probe_rsp(struct mac_context *mac_ctx,
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
link_probe_rsp.len = gen_frame_len;
|
||||
qdf_mem_copy(&sta_link_addr, session_entry->self_mac_addr,
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
|
||||
link_probe_rsp.len = gen_frame_len;
|
||||
status = util_gen_link_probe_rsp(probe_rsp,
|
||||
probe_rsp_len, sta_link_addr,
|
||||
link_probe_rsp.ptr, gen_frame_len,
|
||||
(qdf_size_t *)&link_probe_rsp.len);
|
||||
for (idx = 0; idx < partner_info->num_partner_links; idx++) {
|
||||
req_link_id =
|
||||
partner_info->partner_link_info[idx].link_id;
|
||||
status = util_gen_link_probe_rsp(probe_rsp,
|
||||
probe_rsp_len, req_link_id,
|
||||
sta_link_addr, link_probe_rsp.ptr,
|
||||
gen_frame_len,
|
||||
(qdf_size_t *)&link_probe_rsp.len);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
pe_err("MLO: Link probe response generation failed %d",
|
||||
status);
|
||||
if(QDF_IS_STATUS_ERROR(
|
||||
lim_check_scan_db_for_join_req_partner_info(
|
||||
session_entry,
|
||||
mac_ctx)))
|
||||
lim_clear_ml_partner_info(session_entry);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
pe_err("MLO: Link %d probe resp gen failed %d",
|
||||
req_link_id, status);
|
||||
status =
|
||||
lim_check_scan_db_for_join_req_partner_info(
|
||||
session_entry, mac_ctx);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
lim_clear_ml_partner_info(session_entry);
|
||||
|
||||
goto end;
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
|
||||
pe_debug("MLO: link probe rsp size:%u original probe rsp :%u",
|
||||
link_probe_rsp.len, probe_rsp_len);
|
||||
pe_debug("MLO:link probe rsp size:%u orig probe rsp:%u",
|
||||
link_probe_rsp.len, probe_rsp_len);
|
||||
|
||||
/* Currently only 2 link mlo is supported */
|
||||
link_info = &partner_info->partner_link_info[0];
|
||||
wlan_get_chan_by_bssid_from_rnr(session_entry->vdev,
|
||||
session_entry->cm_id,
|
||||
&link_info->link_addr,
|
||||
&chan, &op_class);
|
||||
if (!chan)
|
||||
wlan_get_chan_by_link_id_from_rnr(session_entry->vdev,
|
||||
session_entry->cm_id,
|
||||
link_info->link_id,
|
||||
&chan, &op_class);
|
||||
if (!chan) {
|
||||
pe_err("Invalid link id %d link mac: " QDF_MAC_ADDR_FMT,
|
||||
link_info->link_id,
|
||||
QDF_MAC_ADDR_REF(link_info->link_addr.bytes));
|
||||
if(QDF_IS_STATUS_ERROR(
|
||||
lim_check_scan_db_for_join_req_partner_info(
|
||||
session_entry,
|
||||
mac_ctx)))
|
||||
lim_clear_ml_partner_info(session_entry);
|
||||
link_info = &partner_info->partner_link_info[idx];
|
||||
wlan_get_chan_by_bssid_from_rnr(session_entry->vdev,
|
||||
session_entry->cm_id,
|
||||
&link_info->link_addr,
|
||||
&chan, &op_class);
|
||||
if (!chan)
|
||||
wlan_get_chan_by_link_id_from_rnr(
|
||||
session_entry->vdev,
|
||||
session_entry->cm_id,
|
||||
link_info->link_id,
|
||||
&chan, &op_class);
|
||||
if (!chan) {
|
||||
pe_err("Invalid link id %d link mac: " QDF_MAC_ADDR_FMT,
|
||||
link_info->link_id,
|
||||
QDF_MAC_ADDR_REF(link_info->link_addr.bytes));
|
||||
status =
|
||||
lim_check_scan_db_for_join_req_partner_info(
|
||||
session_entry, mac_ctx);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
lim_clear_ml_partner_info(session_entry);
|
||||
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
goto end;
|
||||
}
|
||||
chan_freq = wlan_reg_chan_opclass_to_freq(chan, op_class,
|
||||
true);
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
goto end;
|
||||
}
|
||||
chan_freq =
|
||||
wlan_reg_chan_opclass_to_freq(chan, op_class,
|
||||
true);
|
||||
|
||||
status = lim_add_bcn_probe(session_entry->vdev,
|
||||
link_probe_rsp.ptr,
|
||||
link_probe_rsp.len,
|
||||
chan_freq, rssi);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
pe_err("failed to add bcn probe %d", status);
|
||||
if(QDF_IS_STATUS_ERROR(
|
||||
lim_check_scan_db_for_join_req_partner_info(
|
||||
session_entry,
|
||||
mac_ctx)))
|
||||
lim_clear_ml_partner_info(session_entry);
|
||||
status = lim_add_bcn_probe(session_entry->vdev,
|
||||
link_probe_rsp.ptr,
|
||||
link_probe_rsp.len,
|
||||
chan_freq, rssi);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
pe_err("failed to add bcn probe %d", status);
|
||||
status =
|
||||
lim_check_scan_db_for_join_req_partner_info(
|
||||
session_entry, mac_ctx);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
lim_clear_ml_partner_info(session_entry);
|
||||
|
||||
goto end;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
} else if (session_entry->lim_join_req->is_ml_probe_req_sent &&
|
||||
!rcvd_probe_resp->mlo_ie.mlo_ie_present) {
|
||||
if(QDF_IS_STATUS_ERROR(lim_check_scan_db_for_join_req_partner_info(
|
||||
session_entry,
|
||||
mac_ctx)))
|
||||
lim_clear_ml_partner_info(session_entry);
|
||||
!rcvd_probe_resp->mlo_ie.mlo_ie_present) {
|
||||
status =
|
||||
lim_check_scan_db_for_join_req_partner_info(
|
||||
session_entry, mac_ctx);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
lim_clear_ml_partner_info(session_entry);
|
||||
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
return status;
|
||||
@@ -4120,6 +4168,7 @@ lim_gen_link_specific_probe_rsp(struct mac_context *mac_ctx,
|
||||
end:
|
||||
if (link_probe_rsp.ptr)
|
||||
qdf_mem_free(link_probe_rsp.ptr);
|
||||
link_probe_rsp.ptr = NULL;
|
||||
link_probe_rsp.len = 0;
|
||||
return status;
|
||||
}
|
||||
@@ -4137,6 +4186,7 @@ lim_gen_link_probe_rsp_roam(struct mac_context *mac_ctx,
|
||||
uint32_t frame_len;
|
||||
struct wlan_frame_hdr *hdr;
|
||||
uint16_t gen_frame_len;
|
||||
uint32_t idx, link_id;
|
||||
|
||||
if (!session || !roam_sync_ind)
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
@@ -4201,37 +4251,41 @@ lim_gen_link_probe_rsp_roam(struct mac_context *mac_ctx,
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
|
||||
link_probe_rsp.len = gen_frame_len;
|
||||
status = util_gen_link_probe_rsp(frame, frame_len,
|
||||
sta_link_addr, link_probe_rsp.ptr,
|
||||
gen_frame_len,
|
||||
(qdf_size_t *)&link_probe_rsp.len);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
pe_err("MLO: Link probe response generation failed %d",
|
||||
status);
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
goto end;
|
||||
}
|
||||
pe_debug("MLO: link probe rsp size:%u original probe rsp :%u",
|
||||
link_probe_rsp.len, frame_len);
|
||||
for (idx = 0; idx < roam_sync_ind->num_setup_links; idx++) {
|
||||
link_id = roam_sync_ind->ml_link[idx].link_id;
|
||||
status = util_gen_link_probe_rsp(frame, frame_len,
|
||||
link_id, sta_link_addr,
|
||||
link_probe_rsp.ptr, gen_frame_len,
|
||||
(qdf_size_t *)&link_probe_rsp.len);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
pe_err("MLO: Link %d probe resp gen failed %d",
|
||||
link_id, status);
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
continue;
|
||||
}
|
||||
pe_debug("MLO: link probe rsp size:%u orig probe rsp :%u",
|
||||
link_probe_rsp.len, frame_len);
|
||||
|
||||
src_addr = lim_get_src_addr_from_frame(&link_probe_rsp);
|
||||
if (!src_addr) {
|
||||
pe_err("MLO: Failed to fetch src address");
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
goto end;
|
||||
src_addr = lim_get_src_addr_from_frame(&link_probe_rsp);
|
||||
if (!src_addr) {
|
||||
pe_err("MLO: Failed to fetch src address");
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
continue;
|
||||
}
|
||||
lim_add_bcn_probe(session->vdev, link_probe_rsp.ptr,
|
||||
link_probe_rsp.len,
|
||||
mlo_roam_get_link_freq_from_mac_addr(
|
||||
roam_sync_ind, src_addr),
|
||||
roam_sync_ind->rssi);
|
||||
}
|
||||
lim_add_bcn_probe(session->vdev, link_probe_rsp.ptr,
|
||||
link_probe_rsp.len,
|
||||
mlo_roam_get_link_freq_from_mac_addr(
|
||||
roam_sync_ind, src_addr),
|
||||
roam_sync_ind->rssi);
|
||||
} else {
|
||||
qdf_mem_free(probe_rsp);
|
||||
return status;
|
||||
}
|
||||
end:
|
||||
|
||||
if (link_probe_rsp.ptr)
|
||||
qdf_mem_free(link_probe_rsp.ptr);
|
||||
link_probe_rsp.ptr = NULL;
|
||||
link_probe_rsp.len = 0;
|
||||
qdf_mem_free(probe_rsp);
|
||||
return status;
|
||||
@@ -4329,7 +4383,7 @@ lim_process_cu_for_probe_rsp(struct mac_context *mac_ctx,
|
||||
* updated.
|
||||
*/
|
||||
status =
|
||||
util_gen_link_probe_rsp(probe_rsp, probe_rsp_len,
|
||||
util_gen_link_probe_rsp(probe_rsp, probe_rsp_len, link_id,
|
||||
sta_link_addr, link_probe_rsp.ptr,
|
||||
probe_rsp_len,
|
||||
(qdf_size_t *)&link_probe_rsp.len);
|
||||
|
@@ -626,6 +626,7 @@ QDF_STATUS lim_mlo_proc_assoc_req_frm(struct wlan_objmgr_vdev *vdev,
|
||||
qdf_copy_macaddr(&link_bssid, (struct qdf_mac_addr *)session->bssId);
|
||||
status = util_gen_link_assoc_req(
|
||||
frm_body, frame_len, sub_type == LIM_REASSOC,
|
||||
0,
|
||||
link_bssid,
|
||||
qdf_nbuf_data(assoc_req->assoc_req_buf),
|
||||
qdf_nbuf_len(assoc_req->assoc_req_buf),
|
||||
@@ -1264,6 +1265,22 @@ lim_send_bcn_frame_mlo(struct mac_context *mac_ctx,
|
||||
return session->mlo_ie_total_len;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
lim_send_probe_req_frame_mlo(struct mac_context *mac_ctx,
|
||||
struct pe_session *session)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
|
||||
session->mlo_ie_total_len = 0;
|
||||
qdf_mem_zero(&session->mlo_ie, sizeof(session->mlo_ie));
|
||||
status = populate_dot11f_probe_req_mlo_ie(mac_ctx, session);
|
||||
if (QDF_IS_STATUS_SUCCESS(status))
|
||||
session->mlo_ie_total_len =
|
||||
lim_caculate_mlo_ie_length(&session->mlo_ie);
|
||||
|
||||
return session->mlo_ie_total_len;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
lim_get_frame_mlo_ie_len(struct pe_session *session)
|
||||
{
|
||||
|
@@ -302,6 +302,17 @@ lim_send_assoc_rsp_mgmt_frame_mlo(struct mac_context *mac_ctx,
|
||||
uint16_t
|
||||
lim_send_bcn_frame_mlo(struct mac_context *mac_ctx, struct pe_session *session);
|
||||
|
||||
/**
|
||||
* lim_send_probe_req_frame_mlo() - Prepare ML IE for probe req frame
|
||||
* @mac_ctx: pointer to mac_context
|
||||
* @session: pointer to pe_session
|
||||
*
|
||||
* Return: the actual ML IE length
|
||||
*/
|
||||
uint16_t
|
||||
lim_send_probe_req_frame_mlo(struct mac_context *mac_ctx,
|
||||
struct pe_session *session);
|
||||
|
||||
/**
|
||||
* lim_get_frame_mlo_ie_len() - get ML IE length
|
||||
* @session: pointer to pe_session
|
||||
@@ -470,6 +481,13 @@ lim_send_assoc_rsp_mgmt_frame_mlo(struct mac_context *mac_ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
lim_send_probe_req_frame_mlo(struct mac_context *mac_ctx,
|
||||
struct pe_session *session)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
lim_send_bcn_frame_mlo(struct mac_context *mac_ctx, struct pe_session *session)
|
||||
{
|
||||
|
@@ -2770,18 +2770,21 @@ static QDF_STATUS
|
||||
lim_process_switch_channel_join_mlo(struct pe_session *session_entry,
|
||||
struct mac_context *mac_ctx)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
struct mlo_partner_info *partner_info;
|
||||
struct element_info assoc_rsp;
|
||||
struct qdf_mac_addr sta_link_addr;
|
||||
uint8_t link_id = 0;
|
||||
|
||||
assoc_rsp.len = 0;
|
||||
mlo_get_assoc_rsp(session_entry->vdev, &assoc_rsp);
|
||||
|
||||
if (!session_entry->lim_join_req->partner_info.num_partner_links) {
|
||||
partner_info = &session_entry->lim_join_req->partner_info;
|
||||
if (!partner_info->num_partner_links) {
|
||||
pe_debug("MLO: num_partner_links is 0");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
/* Todo: update the sta addr by matching link id */
|
||||
qdf_mem_copy(&sta_link_addr, session_entry->self_mac_addr,
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
@@ -2808,23 +2811,23 @@ lim_process_switch_channel_join_mlo(struct pe_session *session_entry,
|
||||
|
||||
link_assoc_rsp.len = assoc_rsp.len + 24;
|
||||
session_entry->limMlmState = eLIM_MLM_WT_ASSOC_RSP_STATE;
|
||||
pe_debug("MLO: Generate and process assoc rsp for link vdev");
|
||||
|
||||
link_id = wlan_vdev_get_link_id(session_entry->vdev);
|
||||
pe_debug("MLO: Generate and process assoc rsp for link vdev %d",
|
||||
link_id);
|
||||
status = util_gen_link_assoc_rsp(assoc_rsp.ptr,
|
||||
assoc_rsp.len - 24,
|
||||
false, sta_link_addr,
|
||||
false, link_id, sta_link_addr,
|
||||
link_assoc_rsp.ptr,
|
||||
assoc_rsp.len,
|
||||
(qdf_size_t *)&link_assoc_rsp.len);
|
||||
|
||||
if (QDF_IS_STATUS_SUCCESS(status)) {
|
||||
pe_debug("MLO: process assoc rsp for link vdev");
|
||||
lim_process_assoc_rsp_frame(mac_ctx,
|
||||
link_assoc_rsp.ptr,
|
||||
(link_assoc_rsp.len - SIR_MAC_HDR_LEN_3A),
|
||||
LIM_ASSOC,
|
||||
session_entry);
|
||||
qdf_mem_free(link_assoc_rsp.ptr);
|
||||
link_assoc_rsp.ptr,
|
||||
(link_assoc_rsp.len - SIR_MAC_HDR_LEN_3A),
|
||||
LIM_ASSOC,
|
||||
session_entry);
|
||||
} else {
|
||||
pe_debug("MLO: link vdev assoc rsp generation failed");
|
||||
assoc_cnf.resultCode = eSIR_SME_INVALID_PARAMETERS;
|
||||
@@ -2833,11 +2836,14 @@ lim_process_switch_channel_join_mlo(struct pe_session *session_entry,
|
||||
assoc_cnf.sessionId = session_entry->peSessionId;
|
||||
lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
|
||||
(uint32_t *)&assoc_cnf);
|
||||
qdf_mem_free(link_assoc_rsp.ptr);
|
||||
}
|
||||
|
||||
qdf_mem_free(link_assoc_rsp.ptr);
|
||||
link_assoc_rsp.ptr = NULL;
|
||||
link_assoc_rsp.len = 0;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
return status;
|
||||
}
|
||||
|
||||
#else /* WLAN_FEATURE_11BE_MLO */
|
||||
@@ -2857,6 +2863,7 @@ lim_process_switch_channel_join_mlo_roam(struct pe_session *session_entry,
|
||||
QDF_STATUS status;
|
||||
struct element_info assoc_rsp = {};
|
||||
struct qdf_mac_addr sta_link_addr;
|
||||
uint8_t link_id = 0;
|
||||
|
||||
assoc_rsp.len = 0;
|
||||
mlo_get_assoc_rsp(session_entry->vdev, &assoc_rsp);
|
||||
@@ -2896,11 +2903,13 @@ lim_process_switch_channel_join_mlo_roam(struct pe_session *session_entry,
|
||||
session_entry->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE;
|
||||
mlo_get_link_mac_addr_from_reassoc_rsp(session_entry->vdev, &bssid);
|
||||
sir_copy_mac_addr(session_entry->limReAssocbssId, bssid.bytes);
|
||||
pe_debug("MLO_ROAM: Generate and process reassoc rsp for link vdev");
|
||||
link_id = wlan_vdev_get_link_id(session_entry->vdev);
|
||||
pe_debug("MLO ROAM: Generate and process assoc rsp for link vdev %d",
|
||||
link_id);
|
||||
|
||||
status = util_gen_link_assoc_rsp(assoc_rsp.ptr,
|
||||
assoc_rsp.len,
|
||||
true, sta_link_addr,
|
||||
true, link_id, sta_link_addr,
|
||||
link_assoc_rsp.ptr,
|
||||
assoc_rsp.len,
|
||||
(qdf_size_t *)&link_assoc_rsp.len);
|
||||
|
@@ -144,111 +144,6 @@ void lim_populate_mac_header(struct mac_context *mac_ctx, uint8_t *buf,
|
||||
mac_hdr->seqControl.seqNumHi, mac_ctx->mgmtSeqNum);
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
static QDF_STATUS
|
||||
lim_populate_ml_probe_req(struct mac_context *mac,
|
||||
struct pe_session *session,
|
||||
uint8_t **ml_prb_req_ie,
|
||||
uint16_t *ml_probe_req_len)
|
||||
{
|
||||
qdf_size_t ml_probe_len = 0;
|
||||
struct wlan_ml_probe_req *ml_prb_req = NULL;
|
||||
uint8_t *ml_probe = NULL;
|
||||
uint8_t link = 0;
|
||||
uint16_t stacontrol = 0;
|
||||
struct mlo_partner_info partner_info;
|
||||
|
||||
if (!session || !session->vdev || !session->vdev->mlo_dev_ctx) {
|
||||
pe_err("Null value");
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
ml_prb_req = qdf_mem_malloc(sizeof(struct wlan_ml_probe_req));
|
||||
if (!ml_prb_req)
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
|
||||
qdf_mem_zero(ml_prb_req, sizeof(struct wlan_ml_probe_req));
|
||||
|
||||
ml_probe = (uint8_t *)ml_prb_req;
|
||||
*ml_prb_req_ie = (uint8_t *)ml_prb_req;
|
||||
/* Fill the Element ID IE Type (0xFF) */
|
||||
ml_prb_req->ml_ie_ff.elem_id = WLAN_ELEMID_EXTN_ELEM;
|
||||
/* Fill the Multi link extn Element ID IE Type (0x6B) */
|
||||
ml_prb_req->ml_ie_ff.elem_id_ext = WLAN_EXTN_ELEMID_MULTI_LINK;
|
||||
ml_probe_len++;
|
||||
|
||||
/* Set ML IE multi link control bitmap:
|
||||
* ML probe variant type = 1
|
||||
* In presence bitmap, set MLD ID presence bit = 1
|
||||
*/
|
||||
QDF_SET_BITS(ml_prb_req->ml_ie_ff.mlcontrol,
|
||||
WLAN_ML_CTRL_TYPE_IDX,
|
||||
WLAN_ML_CTRL_TYPE_BITS,
|
||||
WLAN_ML_VARIANT_PROBEREQ);
|
||||
|
||||
QDF_SET_BITS(ml_prb_req->ml_ie_ff.mlcontrol,
|
||||
WLAN_ML_CTRL_PBM_IDX,
|
||||
WLAN_ML_CTRL_PBM_BITS,
|
||||
1);
|
||||
ml_probe_len += WLAN_ML_CTRL_SIZE;
|
||||
ml_prb_req->common_info_len = 2;
|
||||
ml_probe_len += ml_prb_req->common_info_len;
|
||||
/* mld id is always 0 for tx link for SAP or AP */
|
||||
ml_prb_req->mld_id = 0;
|
||||
|
||||
if (wlan_vdev_mlme_cap_get(session->vdev,
|
||||
WLAN_VDEV_C_EXCL_STA_PROF_PRB_REQ)) {
|
||||
pe_debug("Do not populate sta profile in MLO IE");
|
||||
goto no_sta_prof;
|
||||
}
|
||||
pe_debug("Populate sta profile in MLO IE");
|
||||
|
||||
stacontrol = htole16(stacontrol);
|
||||
partner_info = session->lim_join_req->partner_info;
|
||||
|
||||
for (link = 0;
|
||||
link < partner_info.num_partner_links;
|
||||
link++) {
|
||||
ml_prb_req->sta_profile[link].sub_elem_id = 0;
|
||||
ml_prb_req->sta_profile[link].per_sta_len =
|
||||
WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_SIZE;
|
||||
ml_probe_len += 2;
|
||||
|
||||
QDF_SET_BITS(stacontrol,
|
||||
WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_IDX,
|
||||
WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_BITS,
|
||||
partner_info.partner_link_info[link].link_id);
|
||||
|
||||
QDF_SET_BITS(stacontrol,
|
||||
WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_CMPLTPROF_IDX,
|
||||
WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_CMPLTPROF_BITS,
|
||||
1);
|
||||
ml_prb_req->sta_profile[link].sta_control = stacontrol;
|
||||
ml_probe_len += WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_SIZE;
|
||||
}
|
||||
no_sta_prof:
|
||||
ml_prb_req->ml_ie_ff.elem_len = ml_probe_len;
|
||||
*ml_probe_req_len = ml_probe_len + MIN_IE_LEN;
|
||||
|
||||
pe_nofl_debug("Send ML probe req %zu", ml_probe_len);
|
||||
QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
|
||||
ml_probe, ml_probe_len + MIN_IE_LEN);
|
||||
|
||||
session->lim_join_req->is_ml_probe_req_sent = true;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#else
|
||||
static QDF_STATUS
|
||||
lim_populate_ml_probe_req(struct mac_context *mac,
|
||||
struct pe_session *session,
|
||||
uint8_t **ml_prb_req_ie,
|
||||
uint16_t *ml_probe_req_len)
|
||||
{
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* lim_send_probe_req_mgmt_frame() - send probe request management frame
|
||||
* @mac_ctx: Pointer to Global MAC structure
|
||||
@@ -301,12 +196,10 @@ lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx,
|
||||
QDF_STATUS sir_status;
|
||||
const uint8_t *qcn_ie = NULL;
|
||||
uint8_t channel;
|
||||
uint8_t *ml_probe_req_ie = NULL;
|
||||
uint16_t ml_probe_req_ie_len = 0;
|
||||
int ret;
|
||||
uint8_t *eht_cap_ie = NULL, eht_cap_ie_len = 0;
|
||||
bool is_band_2g;
|
||||
uint16_t ie_buf_size;
|
||||
uint16_t mlo_ie_len = 0;
|
||||
|
||||
if (additional_ielen)
|
||||
addn_ielen = *additional_ielen;
|
||||
@@ -446,10 +339,9 @@ lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx,
|
||||
if (IS_DOT11_MODE_EHT(dot11mode) && pesession &&
|
||||
pesession->lim_join_req) {
|
||||
lim_update_session_eht_capable(mac_ctx, pesession);
|
||||
lim_populate_ml_probe_req(mac_ctx, pesession,
|
||||
&ml_probe_req_ie,
|
||||
&ml_probe_req_ie_len);
|
||||
mlo_ie_len = lim_send_probe_req_frame_mlo(mac_ctx, pesession);
|
||||
}
|
||||
|
||||
populate_dot11f_eht_caps(mac_ctx, pesession, &pr->eht_cap);
|
||||
|
||||
if (addn_ielen && additional_ie) {
|
||||
@@ -500,20 +392,6 @@ lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx,
|
||||
if (extracted_ext_cap_flag)
|
||||
lim_merge_extcap_struct(&pr->ExtCap, &extracted_ext_cap, true);
|
||||
|
||||
/*
|
||||
* Do unpack to populate the add_ie buffer to frm structure
|
||||
* before packing the frm structure. In this way, the IE ordering
|
||||
* which the latest 802.11 spec mandates is maintained.
|
||||
*/
|
||||
if (ml_probe_req_ie_len) {
|
||||
ret = dot11f_unpack_probe_request(mac_ctx, ml_probe_req_ie,
|
||||
ml_probe_req_ie_len,
|
||||
pr, true);
|
||||
if (DOT11F_FAILED(ret)) {
|
||||
pe_err("unpack failed, ret: 0x%x", ret);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/* That's it-- now we pack it. First, how much space are we going to */
|
||||
status = dot11f_get_packed_probe_request_size(mac_ctx, pr, &payload);
|
||||
@@ -527,8 +405,7 @@ lim_send_probe_req_mgmt_frame(struct mac_context *mac_ctx,
|
||||
status);
|
||||
}
|
||||
|
||||
bytes = payload + sizeof(tSirMacMgmtHdr) + addn_ielen +
|
||||
ml_probe_req_ie_len;
|
||||
bytes = payload + sizeof(tSirMacMgmtHdr) + addn_ielen + mlo_ie_len;
|
||||
|
||||
/* Ok-- try to allocate some memory: */
|
||||
qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
|
||||
@@ -600,10 +477,15 @@ skip_eht_ie_update:
|
||||
payload += addn_ielen;
|
||||
}
|
||||
|
||||
if (ml_probe_req_ie_len) {
|
||||
qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
|
||||
ml_probe_req_ie, ml_probe_req_ie_len);
|
||||
payload += ml_probe_req_ie_len;
|
||||
if (mlo_ie_len) {
|
||||
qdf_status = lim_fill_complete_mlo_ie(pesession, mlo_ie_len,
|
||||
frame + sizeof(tSirMacMgmtHdr) + payload);
|
||||
if (QDF_IS_STATUS_ERROR(qdf_status)) {
|
||||
pe_debug("assemble ml ie error, status %d", qdf_status);
|
||||
mlo_ie_len = 0;
|
||||
}
|
||||
|
||||
payload += mlo_ie_len;
|
||||
}
|
||||
|
||||
pe_nofl_debug("Probe req TX: vdev %d seq num %d to " QDF_MAC_ADDR_FMT " len %d",
|
||||
@@ -637,8 +519,6 @@ skip_eht_ie_update:
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
end:
|
||||
qdf_mem_free(ml_probe_req_ie);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
} /* End lim_send_probe_req_mgmt_frame. */
|
||||
|
||||
|
@@ -9279,6 +9279,104 @@ QDF_STATUS populate_dot11f_eht_operation(struct mac_context *mac_ctx,
|
||||
#endif /* WLAN_FEATURE_11BE */
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
QDF_STATUS
|
||||
populate_dot11f_probe_req_mlo_ie(struct mac_context *mac,
|
||||
struct pe_session *session)
|
||||
{
|
||||
struct wlan_mlo_ie *mlo_ie;
|
||||
uint8_t *p_ml_ie, *sta_data;
|
||||
uint16_t len_remaining, sta_len_left;
|
||||
struct wlan_mlo_sta_profile *sta_pro;
|
||||
int num_sta_pro = 0;
|
||||
struct mlo_partner_info partner_info;
|
||||
uint8_t link;
|
||||
|
||||
if (!session || !session->vdev || !session->vdev->mlo_dev_ctx) {
|
||||
pe_err("Null value");
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
mlo_ie = &session->mlo_ie;
|
||||
p_ml_ie = mlo_ie->data;
|
||||
len_remaining = sizeof(mlo_ie->data);
|
||||
|
||||
*p_ml_ie++ = WLAN_ELEMID_EXTN_ELEM;
|
||||
len_remaining--;
|
||||
|
||||
/* set length later */
|
||||
*p_ml_ie++ = 0;
|
||||
len_remaining--;
|
||||
|
||||
*p_ml_ie++ = WLAN_EXTN_ELEMID_MULTI_LINK;
|
||||
len_remaining--;
|
||||
|
||||
/* Set ML IE multi link control bitmap:
|
||||
* ML probe variant type = 1
|
||||
* In presence bitmap, set MLD ID presence bit = 1
|
||||
*/
|
||||
mlo_ie->type = WLAN_ML_VARIANT_PROBEREQ;
|
||||
QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_TYPE_IDX,
|
||||
WLAN_ML_CTRL_TYPE_BITS, mlo_ie->type);
|
||||
QDF_SET_BITS(*(uint16_t *)p_ml_ie, WLAN_ML_CTRL_PBM_IDX,
|
||||
WLAN_ML_CTRL_PBM_BITS, 1);
|
||||
|
||||
p_ml_ie += WLAN_ML_CTRL_SIZE;
|
||||
len_remaining -= WLAN_ML_CTRL_SIZE;
|
||||
|
||||
/* common info length is 2 */
|
||||
*p_ml_ie++ = 2;
|
||||
len_remaining--;
|
||||
|
||||
/* mld id is always 0 for tx link for SAP or AP */
|
||||
*p_ml_ie++ = 0;
|
||||
len_remaining--;
|
||||
|
||||
mlo_ie->num_data = p_ml_ie - mlo_ie->data;
|
||||
|
||||
if (wlan_vdev_mlme_cap_get(session->vdev,
|
||||
WLAN_VDEV_C_EXCL_STA_PROF_PRB_REQ)) {
|
||||
pe_debug("Do not populate sta profile in MLO IE");
|
||||
goto no_sta_prof;
|
||||
}
|
||||
pe_debug("Populate sta profile in MLO IE");
|
||||
|
||||
partner_info = session->lim_join_req->partner_info;
|
||||
for (link = 0; link < partner_info.num_partner_links; link++) {
|
||||
sta_pro = &mlo_ie->sta_profile[num_sta_pro];
|
||||
sta_data = sta_pro->data;
|
||||
sta_len_left = sizeof(sta_pro->data);
|
||||
|
||||
*sta_data++ = WLAN_ML_LINFO_SUBELEMID_PERSTAPROFILE;
|
||||
sta_len_left--;
|
||||
/* length of subelement, filled at last */
|
||||
*sta_data++ = 0;
|
||||
sta_len_left--;
|
||||
|
||||
QDF_SET_BITS(*(uint16_t *)sta_data,
|
||||
WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_IDX,
|
||||
WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_LINKID_BITS,
|
||||
partner_info.partner_link_info[link].link_id);
|
||||
|
||||
QDF_SET_BITS(*(uint16_t *)sta_data,
|
||||
WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_CMPLTPROF_IDX,
|
||||
WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_CMPLTPROF_BITS,
|
||||
1);
|
||||
sta_data += WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_SIZE;
|
||||
sta_len_left -= WLAN_ML_BV_LINFO_PERSTAPROF_STACTRL_SIZE;
|
||||
|
||||
sta_pro->num_data = sta_data - sta_pro->data;
|
||||
sta_pro->data[TAG_LEN_POS] = sta_pro->num_data - MIN_IE_LEN;
|
||||
|
||||
num_sta_pro++;
|
||||
}
|
||||
|
||||
no_sta_prof:
|
||||
mlo_ie->num_sta_profile = num_sta_pro;
|
||||
session->lim_join_req->is_ml_probe_req_sent = true;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS populate_dot11f_assoc_rsp_mlo_ie(struct mac_context *mac_ctx,
|
||||
struct pe_session *session,
|
||||
tpDphHashNode sta,
|
||||
|
Référencer dans un nouveau ticket
Bloquer un utilisateur