Browse Source

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
Pragaspathi Thilagaraj 5 years ago
parent
commit
d7b4332cb5

+ 2 - 1
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;
 };
 

+ 6 - 2
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;
 }

+ 13 - 4
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;
 }

+ 2 - 1
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;

+ 4 - 2
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))
 {

+ 2 - 1
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))
 {

+ 2 - 1
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;