qcacld-3.0: Extract all link probe rsps from ML probe rsp
Firmware sends beacon/probe response of the roam candidate to host through roam_frame_event when it chooses a candidate which needs SAE authentication to be performed. This is needed as the host checks if corresponding scan entry is present in the scan db before starting SAE authentication trigger. But in MLO roaming case, firmware might send ML probe response and the scan entry corresponds to re-assoc link might be present in the per STA profile of the ML probe response. So, extract all per-STA profiles and add them to scan db. Also, use this API to extract and add the link specific ML probe responses for the ML probe response received in roam sync indication if extraction via roam info fails due to some reason(currently it may fail if fw roams to a link but got ML probe rsp from other link as link_info is not present roam info). Change-Id: I6c67927732a54568dfe618bdecaca8f37515e203 CRs-Fixed: 3454834
This commit is contained in:

committato da
Madan Koyyalamudi

parent
983a90bcfb
commit
a87a7cde2a
@@ -890,12 +890,21 @@ cm_update_scan_db_on_roam_success(struct wlan_objmgr_vdev *vdev,
|
||||
roam_synch_ind,
|
||||
wlan_mlme_get_src_addr_from_frame(
|
||||
&ies->bcn_probe_rsp));
|
||||
cm_inform_bcn_probe(cm_ctx,
|
||||
ies->bcn_probe_rsp.ptr,
|
||||
ies->bcn_probe_rsp.len,
|
||||
frame_freq,
|
||||
roam_synch_ind->rssi,
|
||||
cm_id);
|
||||
/*
|
||||
* Firmware might have roamed to a link but got ML probe
|
||||
* response from the other link. Then the link freq is not
|
||||
* present in roam link info and it returns 0. No need to add
|
||||
* the original probe rsp in such cases as roam sync indication
|
||||
* handling would add it to scan db. Add the entry to scan
|
||||
* db only if valid link freq is found.
|
||||
*/
|
||||
if (frame_freq)
|
||||
cm_inform_bcn_probe(cm_ctx,
|
||||
ies->bcn_probe_rsp.ptr,
|
||||
ies->bcn_probe_rsp.len,
|
||||
frame_freq,
|
||||
roam_synch_ind->rssi,
|
||||
cm_id);
|
||||
|
||||
cm_update_scan_mlme_on_roam(vdev, &resp->bssid,
|
||||
SCAN_ENTRY_CON_STATE_ASSOC);
|
||||
|
@@ -591,124 +591,3 @@ QDF_STATUS cm_roam_sync_event_handler_cb(struct wlan_objmgr_vdev *vdev,
|
||||
err:
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
cm_roam_candidate_event_handler(struct wlan_objmgr_psoc *psoc,
|
||||
struct roam_scan_candidate_frame *candidate)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct wlan_objmgr_pdev *pdev;
|
||||
struct cnx_mgr *cm_ctx;
|
||||
uint32_t ie_offset, ie_len;
|
||||
uint8_t *ie_ptr = NULL;
|
||||
uint8_t *extracted_ie = NULL;
|
||||
uint8_t primary_channel, band;
|
||||
qdf_freq_t op_freq;
|
||||
struct wlan_frame_hdr *wh;
|
||||
struct qdf_mac_addr bssid;
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, candidate->vdev_id,
|
||||
WLAN_MLME_CM_ID);
|
||||
if (!vdev) {
|
||||
mlme_err("vdev object is NULL");
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
pdev = wlan_vdev_get_pdev(vdev);
|
||||
if (!pdev) {
|
||||
mlme_err("pdev object is NULL");
|
||||
goto err;
|
||||
}
|
||||
|
||||
cm_ctx = cm_get_cm_ctx(vdev);
|
||||
if (!cm_ctx) {
|
||||
mlme_err("cm ctx is NULL");
|
||||
goto err;
|
||||
}
|
||||
|
||||
QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_MLME, QDF_TRACE_LEVEL_DEBUG,
|
||||
candidate->frame, candidate->frame_length);
|
||||
/* Fixed parameters offset */
|
||||
ie_offset = sizeof(struct wlan_frame_hdr) + MAC_B_PR_SSID_OFFSET;
|
||||
|
||||
if (candidate->frame_length <= ie_offset) {
|
||||
mlme_err("Invalid frame length");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ie_ptr = candidate->frame + ie_offset;
|
||||
ie_len = candidate->frame_length - ie_offset;
|
||||
|
||||
extracted_ie = (uint8_t *)wlan_get_ie_ptr_from_eid(WLAN_ELEMID_SSID,
|
||||
ie_ptr, ie_len);
|
||||
if (extracted_ie && extracted_ie[0] == WLAN_ELEMID_SSID &&
|
||||
extracted_ie[1] > MIN_IE_LEN) {
|
||||
wh = (struct wlan_frame_hdr *)candidate->frame;
|
||||
WLAN_ADDR_COPY(&bssid.bytes[0], wh->i_addr2);
|
||||
|
||||
mlme_debug("SSID of the candidate is " QDF_SSID_FMT,
|
||||
QDF_SSID_REF(extracted_ie[1], &extracted_ie[2]));
|
||||
wlan_cm_set_roam_offload_ssid(vdev, &extracted_ie[2],
|
||||
extracted_ie[1]);
|
||||
wlan_cm_set_roam_offload_bssid(vdev, &bssid);
|
||||
}
|
||||
|
||||
/* For 2.4GHz,5GHz get channel from DS IE */
|
||||
extracted_ie = (uint8_t *)wlan_get_ie_ptr_from_eid(WLAN_ELEMID_DSPARMS,
|
||||
ie_ptr, ie_len);
|
||||
if (extracted_ie && extracted_ie[0] == WLAN_ELEMID_DSPARMS &&
|
||||
extracted_ie[1] == WLAN_DS_PARAM_IE_MAX_LEN) {
|
||||
band = BIT(REG_BAND_2G) | BIT(REG_BAND_5G);
|
||||
primary_channel = *(extracted_ie + 2);
|
||||
mlme_debug("Extracted primary channel from DS : %d",
|
||||
primary_channel);
|
||||
goto update_beacon;
|
||||
}
|
||||
|
||||
/* For HT, VHT and non-6GHz HE, get channel from HTINFO IE */
|
||||
extracted_ie = (uint8_t *)
|
||||
wlan_get_ie_ptr_from_eid(WLAN_ELEMID_HTINFO_ANA,
|
||||
ie_ptr, ie_len);
|
||||
if (extracted_ie && extracted_ie[0] == WLAN_ELEMID_HTINFO_ANA &&
|
||||
extracted_ie[1] == sizeof(struct wlan_ie_htinfo_cmn)) {
|
||||
band = BIT(REG_BAND_2G) | BIT(REG_BAND_5G);
|
||||
primary_channel =
|
||||
((struct wlan_ie_htinfo *)extracted_ie)->
|
||||
hi_ie.hi_ctrlchannel;
|
||||
mlme_debug("Extracted primary channel from HT INFO : %d",
|
||||
primary_channel);
|
||||
goto update_beacon;
|
||||
}
|
||||
/* For 6GHz, get channel from HE OP IE */
|
||||
extracted_ie = (uint8_t *)
|
||||
wlan_get_ext_ie_ptr_from_ext_id(WLAN_HEOP_OUI_TYPE,
|
||||
(uint8_t)
|
||||
WLAN_HEOP_OUI_SIZE,
|
||||
ie_ptr, ie_len);
|
||||
if (extracted_ie && !qdf_mem_cmp(&extracted_ie[2], WLAN_HEOP_OUI_TYPE,
|
||||
WLAN_HEOP_OUI_SIZE) &&
|
||||
extracted_ie[1] <= WLAN_MAX_HEOP_IE_LEN) {
|
||||
band = BIT(REG_BAND_6G);
|
||||
primary_channel = util_scan_get_6g_oper_channel(extracted_ie);
|
||||
mlme_debug("Extracted primary channel from HE OP : %d",
|
||||
primary_channel);
|
||||
if (primary_channel)
|
||||
goto update_beacon;
|
||||
}
|
||||
|
||||
mlme_err("Ignore beacon, Primary channel was not found in the candidate frame");
|
||||
goto err;
|
||||
|
||||
update_beacon:
|
||||
op_freq = wlan_reg_chan_band_to_freq(pdev, primary_channel, band);
|
||||
cm_inform_bcn_probe(cm_ctx, candidate->frame, candidate->frame_length,
|
||||
op_freq,
|
||||
0, /* Real RSSI will be updated by Roam synch ind */
|
||||
cm_ctx->active_cm_id);
|
||||
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
err:
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
@@ -1300,6 +1300,20 @@ QDF_STATUS
|
||||
wlan_cm_update_offload_ssid_from_candidate(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t vdev_id,
|
||||
struct qdf_mac_addr *ap_bssid);
|
||||
|
||||
/**
|
||||
* wlan_cm_add_frame_to_scan_db() - Add the frame to scan db
|
||||
*
|
||||
* @psoc: PSOC pointer
|
||||
* @frame: frame to be added to scan db
|
||||
*
|
||||
* Fetch the channel from frame and add the frame to scan db
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS
|
||||
wlan_cm_add_frame_to_scan_db(struct wlan_objmgr_psoc *psoc,
|
||||
struct roam_scan_candidate_frame *frame);
|
||||
#else
|
||||
static inline
|
||||
void wlan_cm_roam_activate_pcl_per_vdev(struct wlan_objmgr_psoc *psoc,
|
||||
@@ -1549,6 +1563,12 @@ wlan_cm_update_offload_ssid_from_candidate(struct wlan_objmgr_pdev *pdev,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
wlan_cm_add_frame_to_scan_db(struct wlan_objmgr_psoc *psoc,
|
||||
struct roam_scan_candidate_frame *frame)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
|
||||
|
||||
#ifdef WLAN_FEATURE_FIPS
|
||||
|
@@ -2859,11 +2859,13 @@ struct roam_offload_synch_ind {
|
||||
* @vdev_id : vdev id
|
||||
* @frame_length : Length of the beacon/probe rsp frame
|
||||
* @frame : Pointer to the frame
|
||||
* @rssi: RSSI of the received frame, 0 if not available
|
||||
*/
|
||||
struct roam_scan_candidate_frame {
|
||||
uint8_t vdev_id;
|
||||
uint32_t frame_length;
|
||||
uint8_t *frame;
|
||||
int32_t rssi;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include "wlan_reg_ucfg_api.h"
|
||||
#include "wlan_connectivity_logging.h"
|
||||
#include "target_if.h"
|
||||
#include "wlan_mlo_mgr_roam.h"
|
||||
|
||||
/* Support for "Fast roaming" (i.e., ESE, LFR, or 802.11r.) */
|
||||
#define BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN 15
|
||||
@@ -4678,6 +4679,125 @@ end:
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
wlan_cm_add_frame_to_scan_db(struct wlan_objmgr_psoc *psoc,
|
||||
struct roam_scan_candidate_frame *frame)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct wlan_objmgr_pdev *pdev;
|
||||
struct cnx_mgr *cm_ctx;
|
||||
uint32_t ie_offset, ie_len;
|
||||
uint8_t *ie_ptr = NULL;
|
||||
uint8_t *extracted_ie = NULL;
|
||||
uint8_t primary_channel, band;
|
||||
qdf_freq_t op_freq;
|
||||
struct wlan_frame_hdr *wh;
|
||||
struct qdf_mac_addr bssid;
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, frame->vdev_id,
|
||||
WLAN_MLME_CM_ID);
|
||||
if (!vdev) {
|
||||
mlme_err("vdev object is NULL");
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
pdev = wlan_vdev_get_pdev(vdev);
|
||||
if (!pdev) {
|
||||
mlme_err("pdev object is NULL");
|
||||
goto err;
|
||||
}
|
||||
|
||||
cm_ctx = cm_get_cm_ctx(vdev);
|
||||
if (!cm_ctx) {
|
||||
mlme_err("cm ctx is NULL");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Fixed parameters offset */
|
||||
ie_offset = sizeof(struct wlan_frame_hdr) + MAC_B_PR_SSID_OFFSET;
|
||||
|
||||
if (frame->frame_length <= ie_offset) {
|
||||
mlme_err("Invalid frame length");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ie_ptr = frame->frame + ie_offset;
|
||||
ie_len = frame->frame_length - ie_offset;
|
||||
|
||||
extracted_ie = (uint8_t *)wlan_get_ie_ptr_from_eid(WLAN_ELEMID_SSID,
|
||||
ie_ptr, ie_len);
|
||||
if (extracted_ie && extracted_ie[0] == WLAN_ELEMID_SSID &&
|
||||
extracted_ie[1] > MIN_IE_LEN) {
|
||||
wh = (struct wlan_frame_hdr *)frame->frame;
|
||||
WLAN_ADDR_COPY(&bssid.bytes[0], wh->i_addr2);
|
||||
|
||||
mlme_debug("SSID of the candidate is " QDF_SSID_FMT,
|
||||
QDF_SSID_REF(extracted_ie[1], &extracted_ie[2]));
|
||||
wlan_cm_set_roam_offload_ssid(vdev, &extracted_ie[2],
|
||||
extracted_ie[1]);
|
||||
wlan_cm_set_roam_offload_bssid(vdev, &bssid);
|
||||
}
|
||||
|
||||
/* For 2.4GHz,5GHz get channel from DS IE */
|
||||
extracted_ie = (uint8_t *)wlan_get_ie_ptr_from_eid(WLAN_ELEMID_DSPARMS,
|
||||
ie_ptr, ie_len);
|
||||
if (extracted_ie && extracted_ie[0] == WLAN_ELEMID_DSPARMS &&
|
||||
extracted_ie[1] == WLAN_DS_PARAM_IE_MAX_LEN) {
|
||||
band = BIT(REG_BAND_2G) | BIT(REG_BAND_5G);
|
||||
primary_channel = *(extracted_ie + 2);
|
||||
mlme_debug("Extracted primary channel from DS : %d",
|
||||
primary_channel);
|
||||
goto update_beacon;
|
||||
}
|
||||
|
||||
/* For HT, VHT and non-6GHz HE, get channel from HTINFO IE */
|
||||
extracted_ie = (uint8_t *)
|
||||
wlan_get_ie_ptr_from_eid(WLAN_ELEMID_HTINFO_ANA,
|
||||
ie_ptr, ie_len);
|
||||
if (extracted_ie && extracted_ie[0] == WLAN_ELEMID_HTINFO_ANA &&
|
||||
extracted_ie[1] == sizeof(struct wlan_ie_htinfo_cmn)) {
|
||||
band = BIT(REG_BAND_2G) | BIT(REG_BAND_5G);
|
||||
primary_channel =
|
||||
((struct wlan_ie_htinfo *)extracted_ie)->
|
||||
hi_ie.hi_ctrlchannel;
|
||||
mlme_debug("Extracted primary channel from HT INFO : %d",
|
||||
primary_channel);
|
||||
goto update_beacon;
|
||||
}
|
||||
/* For 6GHz, get channel from HE OP IE */
|
||||
extracted_ie = (uint8_t *)
|
||||
wlan_get_ext_ie_ptr_from_ext_id(WLAN_HEOP_OUI_TYPE,
|
||||
(uint8_t)
|
||||
WLAN_HEOP_OUI_SIZE,
|
||||
ie_ptr, ie_len);
|
||||
if (extracted_ie && !qdf_mem_cmp(&extracted_ie[2], WLAN_HEOP_OUI_TYPE,
|
||||
WLAN_HEOP_OUI_SIZE) &&
|
||||
extracted_ie[1] <= WLAN_MAX_HEOP_IE_LEN) {
|
||||
band = BIT(REG_BAND_6G);
|
||||
primary_channel = util_scan_get_6g_oper_channel(extracted_ie);
|
||||
mlme_debug("Extracted primary channel from HE OP : %d",
|
||||
primary_channel);
|
||||
if (primary_channel)
|
||||
goto update_beacon;
|
||||
}
|
||||
|
||||
mlme_err("Ignore beacon, Primary channel was not found in the candidate frame");
|
||||
goto err;
|
||||
|
||||
update_beacon:
|
||||
op_freq = wlan_reg_chan_band_to_freq(pdev, primary_channel, band);
|
||||
cm_inform_bcn_probe(cm_ctx, frame->frame, frame->frame_length,
|
||||
op_freq,
|
||||
frame->rssi,
|
||||
cm_ctx->active_cm_id);
|
||||
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
err:
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
@@ -4812,4 +4932,18 @@ bool wlan_cm_roam_is_mlo_ap(struct wlan_objmgr_vdev *vdev)
|
||||
|
||||
return rso_config->sae_roam_auth.is_mlo_ap;
|
||||
}
|
||||
#endif /* WLAN_FEATURE_ROAM_OFFLOAD && WLAN_FEATURE_11BE_MLO */
|
||||
|
||||
QDF_STATUS
|
||||
cm_roam_candidate_event_handler(struct wlan_objmgr_psoc *psoc,
|
||||
struct roam_scan_candidate_frame *candidate)
|
||||
{
|
||||
return mlo_add_all_link_probe_rsp_to_scan_db(psoc, candidate);
|
||||
}
|
||||
#elif defined(WLAN_FEATURE_ROAM_OFFLOAD) /* end WLAN_FEATURE_11BE_MLO */
|
||||
QDF_STATUS
|
||||
cm_roam_candidate_event_handler(struct wlan_objmgr_psoc *psoc,
|
||||
struct roam_scan_candidate_frame *candidate)
|
||||
{
|
||||
return wlan_cm_add_frame_to_scan_db(psoc, candidate);
|
||||
}
|
||||
#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
|
||||
|
Fai riferimento in un nuovo problema
Block a user