qcacld-3.0: Copy link beacon from sync frame event to roam_sync_ind

When firmware attempts roaming to an MLO AP, it tries to find
the complete ML info(all links info) either through ML probe
response or beacons from all the links. It forwards all link
beacons(or ML probe response) to host as part of roam sync
indication through roam sync frame event.
Add support to fetch both link beacons and add them to scan db.
If firmware sends ML probe response, generate link probe response
as well and add it to the scan db.
The link scan result can be used in link connect in case of
hybrid roaming like OWE, 1x,..

Change-Id: Ic8457a5630441d6fd3faeb4791c79422db787f94
CRs-Fixed: 3335225
This commit is contained in:
Srinivas Dasari
2022-11-20 10:06:25 -08:00
committed by Madan Koyyalamudi
parent 833afe5c71
commit 7324535b01
11 changed files with 449 additions and 125 deletions

View File

@@ -298,6 +298,22 @@ cm_populate_connect_ies(struct roam_offload_synch_ind *roam_synch_data,
connect_ies->bcn_probe_rsp.len);
}
/* Beacon/Probe Rsp frame */
if (roam_synch_data->link_beacon_probe_resp_length) {
connect_ies->link_bcn_probe_rsp.len =
roam_synch_data->link_beacon_probe_resp_length;
bcn_probe_rsp_ptr = (uint8_t *)roam_synch_data +
roam_synch_data->link_beacon_probe_resp_offset;
connect_ies->link_bcn_probe_rsp.ptr =
qdf_mem_malloc(connect_ies->link_bcn_probe_rsp.len);
if (!connect_ies->link_bcn_probe_rsp.ptr)
return QDF_STATUS_E_NOMEM;
qdf_mem_copy(connect_ies->link_bcn_probe_rsp.ptr,
bcn_probe_rsp_ptr,
connect_ies->link_bcn_probe_rsp.len);
}
/* ReAssoc Rsp IE data */
if (roam_synch_data->reassocRespLength >
sizeof(struct wlan_frame_hdr)) {
@@ -792,21 +808,49 @@ end:
static void
cm_update_scan_db_on_roam_success(struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_resp *resp,
struct roam_offload_synch_ind *roam_synch_data,
struct roam_offload_synch_ind *roam_synch_ind,
wlan_cm_id cm_id)
{
struct cnx_mgr *cm_ctx;
qdf_freq_t link_freq;
struct wlan_connect_rsp_ies *ies = &resp->connect_ies;
cm_ctx = cm_get_cm_ctx(vdev);
if (!cm_ctx)
return;
cm_inform_bcn_probe(cm_ctx,
resp->connect_ies.bcn_probe_rsp.ptr,
resp->connect_ies.bcn_probe_rsp.len,
resp->freq,
roam_synch_data->rssi,
cm_id);
link_freq = mlo_roam_get_chan_freq(wlan_vdev_get_id(vdev),
roam_synch_ind);
if (roam_synch_ind->auth_status == ROAM_AUTH_STATUS_CONNECTED) {
if (ies->link_bcn_probe_rsp.len)
cm_inform_bcn_probe(cm_ctx,
ies->link_bcn_probe_rsp.ptr,
ies->link_bcn_probe_rsp.len,
link_freq,
roam_synch_ind->rssi,
cm_id);
cm_inform_bcn_probe(cm_ctx,
ies->bcn_probe_rsp.ptr,
ies->bcn_probe_rsp.len,
resp->freq,
roam_synch_ind->rssi,
cm_id);
} else if (wlan_vdev_mlme_is_mlo_link_vdev(vdev)) {
if (ies->link_bcn_probe_rsp.len)
cm_inform_bcn_probe(cm_ctx,
ies->link_bcn_probe_rsp.ptr,
ies->link_bcn_probe_rsp.len,
link_freq,
roam_synch_ind->rssi,
cm_id);
} else {
cm_inform_bcn_probe(cm_ctx,
ies->bcn_probe_rsp.ptr,
ies->bcn_probe_rsp.len,
resp->freq,
roam_synch_ind->rssi,
cm_id);
}
cm_update_scan_mlme_on_roam(vdev, &resp->bssid,
SCAN_ENTRY_CON_STATE_ASSOC);
@@ -1306,6 +1350,11 @@ QDF_STATUS wlan_cm_free_roam_synch_frame_ind(struct rso_config *rso_cfg)
frame_ind->bcn_probe_rsp_len = 0;
frame_ind->bcn_probe_rsp = NULL;
}
if (frame_ind->link_bcn_probe_rsp) {
qdf_mem_free(frame_ind->link_bcn_probe_rsp);
frame_ind->link_bcn_probe_rsp_len = 0;
frame_ind->link_bcn_probe_rsp = NULL;
}
if (frame_ind->reassoc_req) {
qdf_mem_free(frame_ind->reassoc_req);
frame_ind->reassoc_req_len = 0;

View File

@@ -422,6 +422,17 @@ cm_roam_sync_frame_event_handler(struct wlan_objmgr_psoc *psoc,
sync_frame_ind->bcn_probe_rsp;
}
if (sync_frame_ind->link_bcn_probe_rsp_len) {
roam_synch_frame_ind->link_bcn_probe_rsp_len =
sync_frame_ind->link_bcn_probe_rsp_len;
roam_synch_frame_ind->is_link_beacon =
sync_frame_ind->is_link_beacon;
if (roam_synch_frame_ind->link_bcn_probe_rsp)
qdf_mem_free(roam_synch_frame_ind->link_bcn_probe_rsp);
roam_synch_frame_ind->link_bcn_probe_rsp =
sync_frame_ind->link_bcn_probe_rsp;
}
if (sync_frame_ind->reassoc_req_len) {
roam_synch_frame_ind->reassoc_req_len =
sync_frame_ind->reassoc_req_len;
@@ -504,7 +515,18 @@ QDF_STATUS cm_roam_sync_event_handler_cb(struct wlan_objmgr_vdev *vdev,
}
/* 24 byte MAC header and 12 byte to ssid IE */
if (sync_ind->beaconProbeRespLength >
if (wlan_vdev_mlme_is_mlo_link_vdev(vdev) &&
sync_ind->link_beacon_probe_resp_length) {
if (sync_ind->link_beacon_probe_resp_length >
(QDF_IEEE80211_3ADDR_HDR_LEN + MAC_B_PR_SSID_OFFSET)) {
ie_len = sync_ind->link_beacon_probe_resp_length -
(QDF_IEEE80211_3ADDR_HDR_LEN +
MAC_B_PR_SSID_OFFSET);
} else {
mlme_err("LFR3: MLO: Invalid link Beacon Length");
goto err;
}
} else if (sync_ind->beaconProbeRespLength >
(QDF_IEEE80211_3ADDR_HDR_LEN + MAC_B_PR_SSID_OFFSET)) {
ie_len = sync_ind->beaconProbeRespLength -
(QDF_IEEE80211_3ADDR_HDR_LEN + MAC_B_PR_SSID_OFFSET);

View File

@@ -1671,6 +1671,7 @@ void wlan_cm_free_connect_rsp(struct cm_vdev_join_rsp *rsp)
qdf_mem_free(connect_ie->assoc_req.ptr);
qdf_mem_free(connect_ie->bcn_probe_rsp.ptr);
qdf_mem_free(connect_ie->link_bcn_probe_rsp.ptr);
qdf_mem_free(connect_ie->assoc_rsp.ptr);
cm_free_fils_ie(connect_ie);
cm_free_tspec_ie(rsp);

View File

@@ -440,6 +440,9 @@ struct roam_synch_frame_ind {
uint32_t bcn_probe_rsp_len;
uint8_t *bcn_probe_rsp;
uint8_t is_beacon;
uint32_t link_bcn_probe_rsp_len;
uint8_t *link_bcn_probe_rsp;
uint8_t is_link_beacon;
uint32_t reassoc_req_len;
uint8_t *reassoc_req;
uint32_t reassoc_rsp_len;
@@ -2588,6 +2591,9 @@ struct roam_offload_synch_ind {
uint8_t is_assoc;
enum wlan_phymode phy_mode; /*phy mode sent by fw */
wmi_channel chan;
uint16_t link_beacon_probe_resp_offset;
uint16_t link_beacon_probe_resp_length;
uint8_t is_link_beacon;
#ifdef WLAN_FEATURE_11BE_MLO
uint8_t num_setup_links;
struct ml_setup_link_param ml_link[WLAN_UMAC_MLO_MAX_VDEVS];

View File

@@ -91,6 +91,20 @@ uint32_t
mlo_roam_get_chan_freq(uint8_t vdev_id,
struct roam_offload_synch_ind *sync_ind);
/**
* mlo_roam_get_link_freq - get given link frequency
*
* @vdev_id: vdev id
* @sync_ind: roam sync ind pointer
*
* This api will be called to get the link frequency.
*
* Return: channel frequency
*/
uint32_t
mlo_roam_get_link_freq(uint8_t vdev_id,
struct roam_offload_synch_ind *sync_ind);
/**
* mlo_roam_get_link_id - get link id
*

View File

@@ -396,6 +396,23 @@ bool is_multi_link_roam(struct roam_offload_synch_ind *sync_ind)
return false;
}
uint32_t
mlo_roam_get_link_freq(uint8_t vdev_id,
struct roam_offload_synch_ind *sync_ind)
{
uint8_t i;
if (!sync_ind || !sync_ind->num_setup_links)
return 0;
for (i = 0; i < sync_ind->num_setup_links; i++) {
if (sync_ind->ml_link[i].vdev_id != vdev_id)
return sync_ind->ml_link[i].channel.mhz;
}
return 0;
}
QDF_STATUS mlo_enable_rso(struct wlan_objmgr_pdev *pdev,
struct wlan_objmgr_vdev *vdev,
struct wlan_cm_connect_resp *rsp)
@@ -440,7 +457,7 @@ mlo_roam_copy_partner_info(struct wlan_cm_connect_resp *connect_rsp,
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;
partner_info->partner_link_info[i].vdev_id =
partner_info->partner_link_info[i].vdev_id =
sync_ind->ml_link[i].vdev_id;
qdf_copy_macaddr(