Browse Source

qcacld-3.0: Handle WMI_ROAM_EVENTID with deauth/disassoc reason

When AP sends deauthentication/disassociation frame, host will
handle the deauth/disassoc frame. If the ini
"enable_disconnect_roam_offload" is enabled, firmware will
trigger a roam scan immediately after deauth/disassoc is
received and roam to a new AP. If roam failure happens after
this roam scan, firmware will send  WMI_ROAM_EVENTID with reason
WMI_ROAM_REASON_DEAUTH.

Register a WMA callback to call the PE disconnect handler
function. This will call lim_tear_down_link_with_ap() to
handle the deauth state machine changes and posts message to
sme to inform the link lost info.

Change-Id: I404b019595b96c0710d09cb9218e3a1d28924fc7
CRs-Fixed: 2443219
Pragaspathi Thilagaraj 6 years ago
parent
commit
b017650fc7

+ 2 - 0
core/mac/inc/sir_api.h

@@ -358,6 +358,8 @@ struct sme_ready_req {
 	void *stop_roaming_cb;
 	QDF_STATUS (*sme_msg_cb)(struct mac_context *mac,
 				 struct scheduler_msg *msg);
+	QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac,
+					uint8_t vdev_id);
 };
 
 /**

+ 18 - 0
core/mac/src/pe/include/lim_api.h

@@ -283,6 +283,18 @@ pe_roam_synch_callback(struct mac_context *mac_ctx,
 		       struct roam_offload_synch_ind *roam_sync_ind_ptr,
 		       struct bss_description *bss_desc_ptr,
 		       enum sir_roam_op_code reason);
+
+/**
+ * pe_disconnect_callback() - Callback to handle deauth event is received
+ * from firmware
+ * @mac: pointer to global mac context
+ * @vdev_id: VDEV in which the event was received
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+pe_disconnect_callback(struct mac_context *mac, uint8_t vdev_id);
+
 #else
 static inline QDF_STATUS
 pe_roam_synch_callback(struct mac_context *mac_ctx,
@@ -292,6 +304,12 @@ pe_roam_synch_callback(struct mac_context *mac_ctx,
 {
 	return QDF_STATUS_E_NOSUPPORT;
 }
+
+static inline QDF_STATUS
+pe_disconnect_callback(struct mac_context *mac, uint8_t vdev_id)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
 #endif
 
 /**

+ 19 - 1
core/mac/src/pe/lim/lim_api.c

@@ -1316,7 +1316,8 @@ void pe_register_callbacks_with_wma(struct mac_context *mac,
 
 	status = wma_register_roaming_callbacks(
 			ready_req->csr_roam_synch_cb,
-			ready_req->pe_roam_synch_cb);
+			ready_req->pe_roam_synch_cb,
+			ready_req->pe_disconnect_cb);
 	if (status != QDF_STATUS_SUCCESS)
 		pe_err("Registering roaming callbacks with WMA failed");
 }
@@ -2082,6 +2083,23 @@ lim_copy_and_free_hlp_data_from_session(struct pe_session *session_ptr,
 {}
 #endif
 
+QDF_STATUS
+pe_disconnect_callback(struct mac_context *mac, uint8_t vdev_id)
+{
+	struct pe_session *session;
+
+	session = pe_find_session_by_sme_session_id(mac, vdev_id);
+	if (!session) {
+		pe_err("LFR3: Vdev %d doesn't exist", vdev_id);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	lim_tear_down_link_with_ap(mac, vdev_id,
+				   eSIR_MAC_UNSPEC_FAILURE_REASON);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS
 pe_roam_synch_callback(struct mac_context *mac_ctx,
 		       struct roam_offload_synch_ind *roam_sync_ind_ptr,

+ 1 - 0
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -373,6 +373,7 @@ static bool __lim_process_sme_sys_ready_ind(struct mac_context *mac,
 
 	if (ANI_DRIVER_TYPE(mac) != QDF_DRIVER_TYPE_MFG) {
 		ready_req->pe_roam_synch_cb = pe_roam_synch_callback;
+		ready_req->pe_disconnect_cb = pe_disconnect_callback;
 		pe_register_mgmt_rx_frm_callback(mac);
 		pe_register_callbacks_with_wma(mac, ready_req);
 		mac->lim.sme_msg_callback = ready_req->sme_msg_cb;

+ 2 - 0
core/wma/inc/wma.h

@@ -1159,6 +1159,8 @@ typedef struct {
 		struct roam_offload_synch_ind *roam_synch_data,
 		struct bss_description *bss_desc_ptr,
 		enum sir_roam_op_code reason);
+	QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac,
+					uint8_t vdev_id);
 	qdf_wake_lock_t wmi_cmd_rsp_wake_lock;
 	qdf_runtime_lock_t wmi_cmd_rsp_runtime_lock;
 	enum active_apf_mode active_uc_apf_mode;

+ 6 - 2
core/wma/inc/wma_types.h

@@ -726,7 +726,9 @@ QDF_STATUS wma_register_roaming_callbacks(
 		QDF_STATUS (*pe_roam_synch_cb)(struct mac_context *mac,
 			struct roam_offload_synch_ind *roam_synch_data,
 			struct bss_description *bss_desc_ptr,
-			enum sir_roam_op_code reason));
+			enum sir_roam_op_code reason),
+		QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac,
+						uint8_t vdev_id));
 #else
 static inline QDF_STATUS wma_register_roaming_callbacks(
 		QDF_STATUS (*csr_roam_synch_cb)(struct mac_context *mac,
@@ -736,7 +738,9 @@ static inline QDF_STATUS wma_register_roaming_callbacks(
 		QDF_STATUS (*pe_roam_synch_cb)(struct mac_context *mac,
 			struct roam_offload_synch_ind *roam_synch_data,
 			struct bss_description *bss_desc_ptr,
-			enum sir_roam_op_code reason))
+			enum sir_roam_op_code reason),
+		QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac,
+						uint8_t vdev_id))
 {
 	return QDF_STATUS_E_NOSUPPORT;
 }

+ 4 - 1
core/wma/src/wma_mgmt.c

@@ -4449,7 +4449,9 @@ QDF_STATUS wma_register_roaming_callbacks(
 	QDF_STATUS (*pe_roam_synch_cb)(struct mac_context *mac,
 		struct roam_offload_synch_ind *roam_synch_data,
 		struct bss_description *bss_desc_ptr,
-		enum sir_roam_op_code reason))
+		enum sir_roam_op_code reason),
+	QDF_STATUS (*pe_disconnect_cb) (struct mac_context *mac,
+					uint8_t vdev_id))
 {
 
 	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
@@ -4460,6 +4462,7 @@ QDF_STATUS wma_register_roaming_callbacks(
 	}
 	wma->csr_roam_synch_cb = csr_roam_synch_cb;
 	wma->pe_roam_synch_cb = pe_roam_synch_cb;
+	wma->pe_disconnect_cb = pe_disconnect_cb;
 	WMA_LOGD("Registered roam synch callbacks with WMA successfully");
 	return QDF_STATUS_SUCCESS;
 }

+ 8 - 0
core/wma/src/wma_scan_roam.c

@@ -1573,6 +1573,7 @@ wma_send_disconnect_roam_params(tp_wma_handle wma_handle,
 	case ROAM_SCAN_OFFLOAD_UPDATE_CFG:
 		if (!params->enable)
 			return;
+		break;
 	case ROAM_SCAN_OFFLOAD_STOP:
 		params->enable = false;
 		break;
@@ -1609,6 +1610,7 @@ wma_send_idle_roam_params(tp_wma_handle wma_handle,
 	case ROAM_SCAN_OFFLOAD_UPDATE_CFG:
 		if (!roam_req->idle_roam_params.enable)
 			return;
+		break;
 	case ROAM_SCAN_OFFLOAD_STOP:
 		roam_req->idle_roam_params.enable = false;
 		break;
@@ -5231,6 +5233,12 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf,
 				roam_synch_data, NULL, SIR_ROAMING_INVOKE_FAIL);
 		qdf_mem_free(roam_synch_data);
 		break;
+	case WMI_ROAM_REASON_DEAUTH:
+		WMA_LOGD("%s: Received disconnect roam event reason:%d",
+			 __func__, wmi_event->notif);
+		wma_handle->pe_disconnect_cb(wma_handle->mac_context,
+					     wmi_event->vdev_id);
+		break;
 	default:
 		WMA_LOGD("%s:Unhandled Roam Event %x for vdevid %x", __func__,
 			 wmi_event->reason, wmi_event->vdev_id);