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

@@ -2102,7 +2102,7 @@ static void
wmi_fill_data_synch_frame_event(struct rso_config *rso_cfg,
struct roam_offload_synch_ind *roam_sync_ind)
{
uint8_t *bcn_probersp_ptr;
uint8_t *bcn_probersp_ptr, *link_bcn_probersp_ptr;
uint8_t *reassoc_rsp_ptr;
uint8_t *reassoc_req_ptr;
@@ -2119,10 +2119,29 @@ wmi_fill_data_synch_frame_event(struct rso_config *rso_cfg,
qdf_mem_free(rso_cfg->roam_sync_frame_ind.bcn_probe_rsp);
rso_cfg->roam_sync_frame_ind.bcn_probe_rsp = NULL;
/* Link beacon/probe rsp data */
if (rso_cfg->roam_sync_frame_ind.link_bcn_probe_rsp) {
roam_sync_ind->link_beacon_probe_resp_offset =
sizeof(struct roam_offload_synch_ind) +
roam_sync_ind->beaconProbeRespLength;
roam_sync_ind->link_beacon_probe_resp_length =
rso_cfg->roam_sync_frame_ind.link_bcn_probe_rsp_len;
roam_sync_ind->is_link_beacon =
rso_cfg->roam_sync_frame_ind.is_link_beacon;
link_bcn_probersp_ptr = (uint8_t *)roam_sync_ind +
roam_sync_ind->link_beacon_probe_resp_offset;
qdf_mem_copy(link_bcn_probersp_ptr,
rso_cfg->roam_sync_frame_ind.link_bcn_probe_rsp,
roam_sync_ind->link_beacon_probe_resp_length);
qdf_mem_free(rso_cfg->roam_sync_frame_ind.link_bcn_probe_rsp);
rso_cfg->roam_sync_frame_ind.link_bcn_probe_rsp = NULL;
}
/* ReAssoc Rsp data */
roam_sync_ind->reassocRespOffset =
sizeof(struct roam_offload_synch_ind) +
roam_sync_ind->beaconProbeRespLength;
roam_sync_ind->beaconProbeRespLength +
roam_sync_ind->link_beacon_probe_resp_length;
roam_sync_ind->reassocRespLength =
rso_cfg->roam_sync_frame_ind.reassoc_rsp_len;
reassoc_rsp_ptr = (uint8_t *)roam_sync_ind +
@@ -2137,6 +2156,7 @@ wmi_fill_data_synch_frame_event(struct rso_config *rso_cfg,
roam_sync_ind->reassoc_req_offset =
sizeof(struct roam_offload_synch_ind) +
roam_sync_ind->beaconProbeRespLength +
roam_sync_ind->link_beacon_probe_resp_length +
roam_sync_ind->reassocRespLength;
roam_sync_ind->reassoc_req_length =
rso_cfg->roam_sync_frame_ind.reassoc_req_len;
@@ -2183,6 +2203,10 @@ wmi_fill_data_synch_event(struct roam_offload_synch_ind *roam_sync_ind,
synch_event->bcn_probe_rsp_len;
qdf_mem_copy(bcn_probersp_ptr, param_buf->bcn_probe_rsp_frame,
roam_sync_ind->beaconProbeRespLength);
/*
* Firmware doesn't support link beacon/Probe Rsp data in roam sync
* event. It's always sent in sync_frame event
*/
/* ReAssoc Rsp data */
roam_sync_ind->reassocRespOffset =
sizeof(struct roam_offload_synch_ind) +
@@ -2208,7 +2232,8 @@ wmi_fill_data_synch_event(struct roam_offload_synch_ind *roam_sync_ind,
#ifdef WLAN_FEATURE_11BE_MLO
static QDF_STATUS
wmi_fill_roam_mlo_info(WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf,
wmi_fill_roam_mlo_info(wmi_unified_t wmi_handle,
WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf,
struct roam_offload_synch_ind *roam_sync_ind)
{
uint8_t i;
@@ -2262,7 +2287,8 @@ wmi_fill_roam_mlo_info(WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf,
}
#else
static QDF_STATUS
wmi_fill_roam_mlo_info(WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf,
wmi_fill_roam_mlo_info(wmi_unified_t wmi_handle,
WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf,
struct roam_offload_synch_ind *roam_sync_ind)
{
return QDF_STATUS_SUCCESS;
@@ -2270,7 +2296,8 @@ wmi_fill_roam_mlo_info(WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf,
#endif
static QDF_STATUS
wmi_fill_roam_sync_buffer(struct wlan_objmgr_vdev *vdev,
wmi_fill_roam_sync_buffer(wmi_unified_t wmi_handle,
struct wlan_objmgr_vdev *vdev,
struct rso_config *rso_cfg,
struct roam_offload_synch_ind *roam_sync_ind,
WMI_ROAM_SYNCH_EVENTID_param_tlvs *param_buf)
@@ -2318,6 +2345,7 @@ wmi_fill_roam_sync_buffer(struct wlan_objmgr_vdev *vdev,
wlan_cm_free_roam_synch_frame_ind(rso_cfg);
return status;
}
if (!rso_cfg->roam_sync_frame_ind.reassoc_rsp) {
wmi_err("LFR3: reassoc_rsp is NULL");
QDF_ASSERT(rso_cfg->roam_sync_frame_ind.reassoc_rsp);
@@ -2439,7 +2467,7 @@ wmi_fill_roam_sync_buffer(struct wlan_objmgr_vdev *vdev,
pmk_cache_info->pmkid, PMKID_LEN);
}
status = wmi_fill_roam_mlo_info(param_buf, roam_sync_ind);
status = wmi_fill_roam_mlo_info(wmi_handle, param_buf, roam_sync_ind);
if (QDF_IS_STATUS_ERROR(status)) {
wmi_err("Failed to fill roam mlo info");
return status;
@@ -2469,7 +2497,7 @@ extract_roam_sync_event_tlv(wmi_unified_t wmi_handle, void *evt_buf,
struct wlan_objmgr_psoc *psoc = NULL;
struct rso_config *rso_cfg;
uint32_t roam_synch_data_len;
uint32_t bcn_probe_rsp_len;
uint32_t bcn_probe_rsp_len, link_bcn_probe_rsp_len;
uint32_t reassoc_rsp_len;
uint32_t reassoc_req_len;
wmi_pdev_hw_mode_transition_event_fixed_param *hw_mode_trans_param;
@@ -2554,15 +2582,21 @@ extract_roam_sync_event_tlv(wmi_unified_t wmi_handle, void *evt_buf,
if ((!synch_event->bcn_probe_rsp_len) &&
(!synch_event->reassoc_req_len) &&
(!synch_event->reassoc_rsp_len)) {
bcn_probe_rsp_len = rso_cfg->roam_sync_frame_ind.bcn_probe_rsp_len;
bcn_probe_rsp_len =
rso_cfg->roam_sync_frame_ind.bcn_probe_rsp_len;
link_bcn_probe_rsp_len =
rso_cfg->roam_sync_frame_ind.link_bcn_probe_rsp_len;
reassoc_req_len = rso_cfg->roam_sync_frame_ind.reassoc_req_len;
reassoc_rsp_len = rso_cfg->roam_sync_frame_ind.reassoc_rsp_len;
roam_synch_data_len = bcn_probe_rsp_len + reassoc_rsp_len +
reassoc_req_len + sizeof(struct roam_offload_synch_ind);
roam_synch_data_len =
bcn_probe_rsp_len + link_bcn_probe_rsp_len +
reassoc_rsp_len + reassoc_req_len +
sizeof(struct roam_offload_synch_ind);
wmi_debug("Updated synch payload: LEN bcn:%d, req:%d, rsp:%d",
wmi_debug("Updated synch payload: LEN bcn:%d, link bcn: %d req:%d, rsp:%d",
bcn_probe_rsp_len,
link_bcn_probe_rsp_len,
reassoc_req_len,
reassoc_rsp_len);
} else {
@@ -2609,7 +2643,7 @@ extract_roam_sync_event_tlv(wmi_unified_t wmi_handle, void *evt_buf,
}
*roam_sync_ind = roam_sync;
status = wmi_fill_roam_sync_buffer(vdev, rso_cfg,
status = wmi_fill_roam_sync_buffer(wmi_handle, vdev, rso_cfg,
roam_sync, param_buf);
end:
@@ -2638,8 +2672,8 @@ extract_roam_sync_frame_event_tlv(wmi_unified_t wmi_handle, void *event,
struct roam_synch_frame_ind *frame_ptr)
{
WMI_ROAM_SYNCH_FRAME_EVENTID_param_tlvs *param_buf = NULL;
struct roam_synch_frame_ind *roam_sync_frame_ind;
wmi_roam_synch_frame_event_fixed_param *synch_frame_event;
struct roam_synch_frame_ind *frame_ind;
wmi_roam_synch_frame_event_fixed_param *frame_evt;
if (!event) {
wmi_err("Event param null");
@@ -2652,16 +2686,14 @@ extract_roam_sync_frame_event_tlv(wmi_unified_t wmi_handle, void *event,
return QDF_STATUS_E_NULL_VALUE;
}
synch_frame_event = param_buf->fixed_param;
if (!synch_frame_event) {
frame_evt = param_buf->fixed_param;
if (!frame_evt) {
wmi_err("received null event data from target");
return QDF_STATUS_E_NULL_VALUE;
}
if (synch_frame_event->vdev_id >= WLAN_MAX_VDEVS) {
wmi_err("received invalid vdev_id %d",
synch_frame_event->vdev_id);
if (frame_evt->vdev_id >= WLAN_MAX_VDEVS) {
wmi_err("received invalid vdev_id %d", frame_evt->vdev_id);
return QDF_STATUS_E_FAILURE;
}
@@ -2670,82 +2702,95 @@ extract_roam_sync_frame_event_tlv(wmi_unified_t wmi_handle, void *event,
* driver. So Bcn_prb_rsp_len/reassoc_req_len/reassoc_rsp_len can be 0
* in some of the events.
*/
if (synch_frame_event->bcn_probe_rsp_len >
param_buf->num_bcn_probe_rsp_frame ||
synch_frame_event->reassoc_req_len >
param_buf->num_reassoc_req_frame ||
synch_frame_event->reassoc_rsp_len >
param_buf->num_reassoc_rsp_frame ||
(synch_frame_event->bcn_probe_rsp_len &&
synch_frame_event->bcn_probe_rsp_len < sizeof(struct wlan_frame_hdr)) ||
(synch_frame_event->reassoc_req_len &&
synch_frame_event->reassoc_req_len < sizeof(struct wlan_frame_hdr)) ||
(synch_frame_event->reassoc_rsp_len &&
synch_frame_event->reassoc_rsp_len < sizeof(struct wlan_frame_hdr))) {
if (frame_evt->bcn_probe_rsp_len > param_buf->num_bcn_probe_rsp_frame ||
frame_evt->reassoc_req_len > param_buf->num_reassoc_req_frame ||
frame_evt->reassoc_rsp_len > param_buf->num_reassoc_rsp_frame ||
(frame_evt->bcn_probe_rsp_len &&
frame_evt->bcn_probe_rsp_len < sizeof(struct wlan_frame_hdr)) ||
(frame_evt->reassoc_req_len &&
frame_evt->reassoc_req_len < sizeof(struct wlan_frame_hdr)) ||
(frame_evt->reassoc_rsp_len &&
frame_evt->reassoc_rsp_len < sizeof(struct wlan_frame_hdr))) {
wmi_err("fixed/actual len err: bcn:%d/%d req:%d/%d rsp:%d/%d",
synch_frame_event->bcn_probe_rsp_len,
frame_evt->bcn_probe_rsp_len,
param_buf->num_bcn_probe_rsp_frame,
synch_frame_event->reassoc_req_len,
frame_evt->reassoc_req_len,
param_buf->num_reassoc_req_frame,
synch_frame_event->reassoc_rsp_len,
frame_evt->reassoc_rsp_len,
param_buf->num_reassoc_rsp_frame);
return QDF_STATUS_E_FAILURE;
}
roam_sync_frame_ind = frame_ptr;
roam_sync_frame_ind->vdev_id = synch_frame_event->vdev_id;
frame_ind = frame_ptr;
frame_ind->vdev_id = frame_evt->vdev_id;
wmi_debug("synch frame payload: LEN bcn:%d, req:%d, rsp:%d",
synch_frame_event->bcn_probe_rsp_len,
synch_frame_event->reassoc_req_len,
synch_frame_event->reassoc_rsp_len);
wmi_debug("synch frame payload: LEN %s bcn:%d, req:%d, rsp:%d",
frame_evt->reassoc_rsp_len ? "Assoc" : "Link",
frame_evt->bcn_probe_rsp_len,
frame_evt->reassoc_req_len,
frame_evt->reassoc_rsp_len);
if (synch_frame_event->bcn_probe_rsp_len) {
roam_sync_frame_ind->bcn_probe_rsp_len =
synch_frame_event->bcn_probe_rsp_len;
if (frame_evt->bcn_probe_rsp_len &&
frame_evt->reassoc_rsp_len) {
frame_ind->bcn_probe_rsp_len = frame_evt->bcn_probe_rsp_len;
roam_sync_frame_ind->is_beacon =
synch_frame_event->is_beacon;
frame_ind->is_beacon = frame_evt->is_beacon;
roam_sync_frame_ind->bcn_probe_rsp =
qdf_mem_malloc(roam_sync_frame_ind->bcn_probe_rsp_len);
if (!roam_sync_frame_ind->bcn_probe_rsp) {
QDF_ASSERT(roam_sync_frame_ind->bcn_probe_rsp);
frame_ind->bcn_probe_rsp =
qdf_mem_malloc(frame_ind->bcn_probe_rsp_len);
if (!frame_ind->bcn_probe_rsp) {
QDF_ASSERT(frame_ind->bcn_probe_rsp);
return QDF_STATUS_E_NOMEM;
}
qdf_mem_copy(roam_sync_frame_ind->bcn_probe_rsp,
qdf_mem_copy(frame_ind->bcn_probe_rsp,
param_buf->bcn_probe_rsp_frame,
roam_sync_frame_ind->bcn_probe_rsp_len);
}
frame_ind->bcn_probe_rsp_len);
} else if (frame_evt->bcn_probe_rsp_len) {
frame_ind->link_bcn_probe_rsp_len =
frame_evt->bcn_probe_rsp_len;
if (synch_frame_event->reassoc_req_len) {
roam_sync_frame_ind->reassoc_req_len =
synch_frame_event->reassoc_req_len;
frame_ind->is_link_beacon = frame_evt->is_beacon;
roam_sync_frame_ind->reassoc_req =
qdf_mem_malloc(roam_sync_frame_ind->reassoc_req_len);
if (!roam_sync_frame_ind->reassoc_req) {
QDF_ASSERT(roam_sync_frame_ind->reassoc_req);
if (frame_ind->link_bcn_probe_rsp)
qdf_mem_free(frame_ind->bcn_probe_rsp);
frame_ind->link_bcn_probe_rsp =
qdf_mem_malloc(frame_ind->link_bcn_probe_rsp_len);
if (!frame_ind->link_bcn_probe_rsp) {
QDF_ASSERT(frame_ind->link_bcn_probe_rsp);
return QDF_STATUS_E_NOMEM;
}
qdf_mem_copy(roam_sync_frame_ind->reassoc_req,
qdf_mem_copy(frame_ind->link_bcn_probe_rsp,
param_buf->bcn_probe_rsp_frame,
frame_ind->link_bcn_probe_rsp_len);
}
if (frame_evt->reassoc_req_len) {
frame_ind->reassoc_req_len = frame_evt->reassoc_req_len;
frame_ind->reassoc_req =
qdf_mem_malloc(frame_ind->reassoc_req_len);
if (!frame_ind->reassoc_req) {
QDF_ASSERT(frame_ind->reassoc_req);
return QDF_STATUS_E_NOMEM;
}
qdf_mem_copy(frame_ind->reassoc_req,
param_buf->reassoc_req_frame,
roam_sync_frame_ind->reassoc_req_len);
frame_ind->reassoc_req_len);
}
if (synch_frame_event->reassoc_rsp_len) {
roam_sync_frame_ind->reassoc_rsp_len =
synch_frame_event->reassoc_rsp_len;
if (frame_evt->reassoc_rsp_len) {
frame_ind->reassoc_rsp_len = frame_evt->reassoc_rsp_len;
roam_sync_frame_ind->reassoc_rsp =
qdf_mem_malloc(roam_sync_frame_ind->reassoc_rsp_len);
if (!roam_sync_frame_ind->reassoc_rsp) {
QDF_ASSERT(roam_sync_frame_ind->reassoc_rsp);
frame_ind->reassoc_rsp =
qdf_mem_malloc(frame_ind->reassoc_rsp_len);
if (!frame_ind->reassoc_rsp) {
QDF_ASSERT(frame_ind->reassoc_rsp);
return QDF_STATUS_E_NOMEM;
}
qdf_mem_copy(roam_sync_frame_ind->reassoc_rsp,
qdf_mem_copy(frame_ind->reassoc_rsp,
param_buf->reassoc_rsp_frame,
roam_sync_frame_ind->reassoc_rsp_len);
frame_ind->reassoc_rsp_len);
}
return QDF_STATUS_SUCCESS;