qcacld-3.0: Update preauth candidate entry to scan table

During SAE roam auth offload, update the beacon/probe response
frame coming from the FW via WMI_ROAM_FRAME_EVENTID into the
scan db.

When the bss info of the preauth candidate is unavailable in
the host/kernel scan entry, supplicant fails to determine the
proper SAE PWE config of the peer and the commit request fails.

Change-Id: Ia782ece7bebf8274f949fe9fb3b2a2882bf47597
CRs-Fixed: 3075458
Цей коміт міститься в:
Surya Prakash Sivaraj
2021-11-15 22:56:01 +05:30
зафіксовано Madan Koyyalamudi
джерело bc99e6e4ef
коміт 6ae47b3e0b
8 змінених файлів з 291 додано та 0 видалено

Переглянути файл

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -142,6 +143,19 @@ target_if_pmkid_request_event_handler(ol_scn_t scn, uint8_t *event,
*/
void
target_if_cm_roam_register_rx_ops(struct wlan_cm_roam_rx_ops *rx_ops);
/**
* target_if_roam_frame_event_handler - Target IF API to receive
* Beacon/probe for the roaming candidate.
* @scn: target handle
* @event: event buffer
* @len: event buffer length
*
* Return: int for success or error code
*/
int
target_if_roam_frame_event_handler(ol_scn_t scn, uint8_t *event,
uint32_t len);
#else /* WLAN_FEATURE_ROAM_OFFLOAD */
static inline
void
@@ -182,5 +196,12 @@ target_if_pmkid_request_event_handler(ol_scn_t scn, uint8_t *event,
{
return 0;
}
static inline int
target_if_roam_frame_event_handler(ol_scn_t scn, uint8_t *event,
uint32_t len)
{
return 0;
}
#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
#endif

Переглянути файл

@@ -63,6 +63,7 @@ target_if_cm_roam_register_rx_ops(struct wlan_cm_roam_rx_ops *rx_ops)
rx_ops->roam_stats_event_rx = cm_roam_stats_event_handler;
rx_ops->roam_auth_offload_event = cm_roam_auth_offload_event_handler;
rx_ops->roam_pmkid_request_event_rx = cm_roam_pmkid_request_handler;
rx_ops->roam_candidate_frame_event = cm_roam_candidate_event_handler;
}
int
@@ -519,6 +520,49 @@ done:
return qdf_status_to_os_return(qdf_status);
}
int
target_if_roam_frame_event_handler(ol_scn_t scn, uint8_t *event,
uint32_t len)
{
struct wlan_objmgr_psoc *psoc;
struct wmi_unified *wmi_handle;
struct roam_scan_candidate_frame frame = {0};
struct wlan_cm_roam_rx_ops *roam_rx_ops;
QDF_STATUS qdf_status;
psoc = target_if_get_psoc_from_scn_hdl(scn);
if (!psoc) {
target_if_err("psoc is null");
return -EINVAL;
}
wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
if (!wmi_handle) {
target_if_err("wmi_handle is null");
return -EINVAL;
}
qdf_status = wmi_extract_roam_candidate_frame_event(wmi_handle, event,
len, &frame);
if (QDF_IS_STATUS_ERROR(qdf_status)) {
target_if_err("parsing of event failed, %d", qdf_status);
return -EINVAL;
}
roam_rx_ops = target_if_cm_get_roam_rx_ops(psoc);
if (!roam_rx_ops || !roam_rx_ops->roam_candidate_frame_event) {
target_if_err("No valid roam rx ops");
return -EINVAL;
}
qdf_status = roam_rx_ops->roam_candidate_frame_event(psoc,
&frame);
if (QDF_IS_STATUS_ERROR(qdf_status))
return -EINVAL;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
target_if_roam_offload_register_events(struct wlan_objmgr_psoc *psoc)
{
@@ -616,5 +660,15 @@ target_if_roam_offload_register_events(struct wlan_objmgr_psoc *psoc)
return QDF_STATUS_E_FAILURE;
}
ret = wmi_unified_register_event_handler(handle,
wmi_roam_frame_event_id,
target_if_roam_frame_event_handler,
WMI_RX_SERIALIZER_CTX);
if (QDF_IS_STATUS_ERROR(ret)) {
target_if_err("wmi event(%u) registration failed, ret: %d",
wmi_roam_frame_event_id, ret);
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS;
}

Переглянути файл

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -546,3 +547,109 @@ 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;
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;
/* 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("Primary channel was not found in the candidate scan entry");
goto err;
update_beacon:
op_freq = wlan_reg_chan_band_to_freq(pdev, primary_channel, band);
mlme_debug("Roaming candidate frequency : %d", op_freq);
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;
}

Переглянути файл

@@ -1128,6 +1128,17 @@ void cm_report_roam_rt_stats(struct wlan_objmgr_psoc *psoc,
enum roam_rt_stats_type events,
struct roam_stats_event *roam_info,
uint32_t value, uint8_t idx);
/**
* cm_roam_candidate_event_handler() - CM callback to save roam
* candidate entry in scan db
*
* @psoc - psoc objmgr ptr
* @frame - roam scan candidate info
*/
QDF_STATUS
cm_roam_candidate_event_handler(struct wlan_objmgr_psoc *psoc,
struct roam_scan_candidate_frame *candidate);
#else
static inline
void wlan_cm_roam_activate_pcl_per_vdev(struct wlan_objmgr_psoc *psoc,
@@ -1294,6 +1305,13 @@ cm_report_roam_rt_stats(struct wlan_objmgr_psoc *psoc,
struct roam_stats_event *roam_info,
uint32_t value, uint8_t idx)
{}
static inline QDF_STATUS
cm_roam_candidate_event_handler(struct wlan_objmgr_psoc *psoc,
struct roam_scan_candidate_frame *candidate)
{
return QDF_STATUS_SUCCESS;
}
#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
#ifdef WLAN_FEATURE_FIPS

Переглянути файл

@@ -2433,6 +2433,18 @@ struct roam_offload_synch_ind {
#endif
};
/*
* struct roam_scan_candidate_frame Roam candidate scan entry
* vdev_id : vdev id
* frame_len : Length of the beacon/probe rsp frame
* frame : Pointer to the frame
*/
struct roam_scan_candidate_frame {
uint8_t vdev_id;
uint32_t frame_length;
uint8_t *frame;
};
/**
* wlan_cm_roam_rx_ops - structure of rx function pointers for
* roaming related commands
@@ -2445,6 +2457,7 @@ struct roam_offload_synch_ind {
* @roam_stats_event_rx: Rx ops function pointer for roam stats event
* @roam_auth_offload_event: Rx ops function pointer for auth offload event
* @roam_pmkid_request_event_rx: Rx ops function pointer for roam pmkid event
* @roam_candidate_frame_event : Rx ops function pointer for roam frame event
*/
struct wlan_cm_roam_rx_ops {
QDF_STATUS (*roam_sync_event)(struct wlan_objmgr_psoc *psoc,
@@ -2467,5 +2480,8 @@ struct wlan_cm_roam_rx_ops {
(*roam_auth_offload_event)(struct auth_offload_event *auth_event);
QDF_STATUS
(*roam_pmkid_request_event_rx)(struct roam_pmkid_req_event *list);
QDF_STATUS
(*roam_candidate_frame_event)(struct wlan_objmgr_psoc *psoc,
struct roam_scan_candidate_frame *frame);
};
#endif

Переглянути файл

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -408,6 +409,19 @@ QDF_STATUS
wmi_extract_roam_pmkid_request(wmi_unified_t wmi_handle,
uint8_t *event, uint32_t data_len,
struct roam_pmkid_req_event **data);
/**
* wmi_extract_roam_candidate_frame_event() - Extract the roam candidate
* scan entry and update the scan db
* @wmi_handle: wmi handle
* @event: Event data received from firmware
* @len: Event data length received from firmware
* @data: Extract the event and fill in data
*/
QDF_STATUS
wmi_extract_roam_candidate_frame_event(wmi_unified_t wmi_handle, uint8_t *event,
uint32_t len,
struct roam_scan_candidate_frame *data);
#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
/**

Переглянути файл

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -487,4 +488,17 @@ wmi_extract_roam_pmkid_request(wmi_unified_t wmi_handle,
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS
wmi_extract_roam_candidate_frame_event(wmi_unified_t wmi_handle, uint8_t *event,
uint32_t len,
struct roam_scan_candidate_frame *data)
{
if (wmi_handle->ops->extract_roam_candidate_frame)
return wmi_handle->ops->extract_roam_candidate_frame(
wmi_handle,
event,
len, data);
return QDF_STATUS_E_FAILURE;
}
#endif

Переглянути файл

@@ -3234,6 +3234,52 @@ extract_roam_pmkid_request_tlv(wmi_unified_t wmi_handle, uint8_t *evt_buf,
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS
extract_roam_candidate_frame_tlv(wmi_unified_t wmi_handle, uint8_t *event,
uint32_t len,
struct roam_scan_candidate_frame *data)
{
WMI_ROAM_FRAME_EVENTID_param_tlvs *param_buf = NULL;
wmi_roam_frame_event_fixed_param *frame_params = NULL;
if (!event || !len) {
wmi_debug("Empty roam candidate frame event");
return QDF_STATUS_E_FAILURE;
}
param_buf = (WMI_ROAM_FRAME_EVENTID_param_tlvs *)event;
if (!param_buf) {
wmi_err("received null buf from target");
return -EINVAL;
}
frame_params =
(wmi_roam_frame_event_fixed_param *)param_buf->fixed_param;
if (frame_params->vdev_id >= WLAN_MAX_VDEVS) {
wmi_debug("Invalid VDEV id %d", frame_params->vdev_id);
return QDF_STATUS_E_FAILURE;
}
if (frame_params->frame_length > param_buf->num_frame) {
wmi_debug("Invalid frame length %d expected : %d",
frame_params->frame_length,
param_buf->num_frame);
return QDF_STATUS_E_FAILURE;
}
if (!param_buf->frame) {
wmi_debug("Frame pointer is Null");
return QDF_STATUS_E_FAILURE;
}
data->vdev_id = frame_params->vdev_id;
data->frame_length = frame_params->frame_length;
data->frame = (uint8_t *)param_buf->frame;
return QDF_STATUS_SUCCESS;
}
void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
{
struct wmi_ops *ops = wmi_handle->ops;
@@ -3258,6 +3304,7 @@ void wmi_roam_offload_attach_tlv(wmi_unified_t wmi_handle)
ops->send_roam_invoke_cmd = send_roam_invoke_cmd_tlv;
ops->send_vdev_set_pcl_cmd = send_vdev_set_pcl_cmd_tlv;
ops->send_set_roam_trigger_cmd = send_set_roam_trigger_cmd_tlv;
ops->extract_roam_candidate_frame = extract_roam_candidate_frame_tlv;
}
#else
static inline QDF_STATUS