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
Цей коміт міститься в:

зафіксовано
Madan Koyyalamudi

джерело
bc99e6e4ef
коміт
6ae47b3e0b
@@ -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
|
||||
|
Посилання в новій задачі
Заблокувати користувача