From d7b4332cb53e7a152dc6ff60eed22d02d7e87416 Mon Sep 17 00:00:00 2001 From: Pragaspathi Thilagaraj Date: Thu, 6 Feb 2020 16:46:46 +0530 Subject: [PATCH] qcacld-3.0: Fill correct reason code after deauth roaming failure After deauth/disassoc, roaming is triggered by the firmware and if roaming failure occurs before handoff is started, then firmware sends the WMI_ROAM_EVENTID event with deauth reason. Currently unspecified reason is sent to the upper layers for every emergency deauth roaming failure. Extract the reason code from the deauth/disassoc frame sent by the AP, received in WMI_ROAM_EVENTID. Change-Id: I461a38e8a8e60fa26b2ace3f54a6f8208f00838d CRs-Fixed: 2611473 --- core/mac/inc/sir_api.h | 3 ++- core/mac/src/pe/include/lim_api.h | 8 ++++++-- core/mac/src/pe/lim/lim_api.c | 17 +++++++++++++---- core/wma/inc/wma.h | 3 ++- core/wma/inc/wma_types.h | 6 ++++-- core/wma/src/wma_mgmt.c | 3 ++- core/wma/src/wma_scan_roam.c | 3 ++- 7 files changed, 31 insertions(+), 12 deletions(-) diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 81b78a69c26e..3a2d1fe5ec7a 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -390,7 +390,8 @@ struct sme_ready_req { QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac, uint8_t vdev_id, uint8_t *deauth_disassoc_frame, - uint16_t deauth_disassoc_frame_len); + uint16_t deauth_disassoc_frame_len, + uint16_t reason_code); void *csr_roam_pmkid_req_cb; }; diff --git a/core/mac/src/pe/include/lim_api.h b/core/mac/src/pe/include/lim_api.h index 961d50fb430d..2aaf2a84c59b 100644 --- a/core/mac/src/pe/include/lim_api.h +++ b/core/mac/src/pe/include/lim_api.h @@ -335,13 +335,16 @@ pe_roam_synch_callback(struct mac_context *mac_ctx, * @vdev_id: VDEV in which the event was received * @deauth_disassoc_frame: Deauth/disassoc frame received from firmware * @deauth_disassoc_frame_len: Length of @deauth_disassoc_frame + * @reason_code: Fw sent reason code if disassoc/deauth frame is not + * available * * Return: QDF_STATUS */ QDF_STATUS pe_disconnect_callback(struct mac_context *mac, uint8_t vdev_id, uint8_t *deauth_disassoc_frame, - uint16_t deauth_disassoc_frame_len); + uint16_t deauth_disassoc_frame_len, + uint16_t reason_code); #else static inline QDF_STATUS @@ -356,7 +359,8 @@ pe_roam_synch_callback(struct mac_context *mac_ctx, static inline QDF_STATUS pe_disconnect_callback(struct mac_context *mac, uint8_t vdev_id, uint8_t *deauth_disassoc_frame, - uint16_t deauth_disassoc_frame_len) + uint16_t deauth_disassoc_frame_len, + uint16_t reason_code) { return QDF_STATUS_E_NOSUPPORT; } diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index 3a5e5f3ce97e..42ac285a4fa5 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -2219,7 +2219,8 @@ lim_copy_and_free_hlp_data_from_session(struct pe_session *session_ptr, QDF_STATUS pe_disconnect_callback(struct mac_context *mac, uint8_t vdev_id, uint8_t *deauth_disassoc_frame, - uint16_t deauth_disassoc_frame_len) + uint16_t deauth_disassoc_frame_len, + uint16_t reason_code) { struct pe_session *session; @@ -2229,10 +2230,18 @@ pe_disconnect_callback(struct mac_context *mac, uint8_t vdev_id, return QDF_STATUS_E_FAILURE; } - lim_extract_ies_from_deauth_disassoc(session, deauth_disassoc_frame, - deauth_disassoc_frame_len); + if (deauth_disassoc_frame && + deauth_disassoc_frame_len > SIR_MAC_MIN_IE_LEN) { + lim_extract_ies_from_deauth_disassoc(session, + deauth_disassoc_frame, + deauth_disassoc_frame_len); + + reason_code = sir_read_u16(deauth_disassoc_frame + + sizeof(struct wlan_frame_hdr)); + } + lim_tear_down_link_with_ap(mac, session->peSessionId, - eSIR_MAC_UNSPEC_FAILURE_REASON); + reason_code); return QDF_STATUS_SUCCESS; } diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 1955dd659ad3..50d00fc5d011 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1087,7 +1087,8 @@ typedef struct { QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac, uint8_t vdev_id, uint8_t *deauth_disassoc_frame, - uint16_t deauth_disassoc_frame_len); + uint16_t deauth_disassoc_frame_len, + uint16_t reason_code); QDF_STATUS (*csr_roam_pmkid_req_cb)(uint8_t vdev_id, struct roam_pmkid_req_event *bss_list); qdf_wake_lock_t wmi_cmd_rsp_wake_lock; diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index bd177b4e9d80..37a957fcbf0b 100644 --- a/core/wma/inc/wma_types.h +++ b/core/wma/inc/wma_types.h @@ -730,7 +730,8 @@ QDF_STATUS wma_register_roaming_callbacks( QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac, uint8_t vdev_id, uint8_t *deauth_disassoc_frame, - uint16_t deauth_disassoc_frame_len), + uint16_t deauth_disassoc_frame_len, + uint16_t reason_code), QDF_STATUS (*csr_roam_pmkid_req_cb)(uint8_t vdev_id, struct roam_pmkid_req_event *bss_list)); #else @@ -750,7 +751,8 @@ static inline QDF_STATUS wma_register_roaming_callbacks( QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac, uint8_t vdev_id, uint8_t *deauth_disassoc_frame, - uint16_t deauth_disassoc_frame_len), + uint16_t deauth_disassoc_frame_len, + uint16_t reason_code), QDF_STATUS (*csr_roam_pmkid_req_cb)(uint8_t vdev_id, struct roam_pmkid_req_event *bss_list)) { diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index e5d318753d99..1476a8712402 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -3812,7 +3812,8 @@ QDF_STATUS wma_register_roaming_callbacks( QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac, uint8_t vdev_id, uint8_t *deauth_disassoc_frame, - uint16_t deauth_disassoc_frame_len), + uint16_t deauth_disassoc_frame_len, + uint16_t reason_code), QDF_STATUS (*csr_roam_pmkid_req_cb)(uint8_t vdev_id, struct roam_pmkid_req_event *bss_list)) { diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 4968bfd5f5ec..64e13ae5a278 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -5944,7 +5944,8 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf, frame = param_buf->deauth_disassoc_frame; wma_handle->pe_disconnect_cb(wma_handle->mac_context, wmi_event->vdev_id, - frame, wmi_event->notif_params1); + frame, wmi_event->notif_params1, + wmi_event->notif); roam_synch_data = qdf_mem_malloc(sizeof(*roam_synch_data)); if (!roam_synch_data) return -ENOMEM;