Procházet zdrojové kódy

qcacld-3.0: Process eWNI_SME_DISCONNECT_DONE_IND even after stop bss

If LIM initiate disconnect for a peer (eSmeCommandWmStatusChange) and
at same time bss is stopped, disconnect may get processed after stop
bss and thus will return from LIM as AP has already stopped.

LIM will post eWNI_SME_DISCONNECT_DONE_IND to sme to remove
the eSmeCommandWmStatusChange command from serialization active queue.
But eWNI_SME_DISCONNECT_DONE_IND is not processed in CSR sub state
eCSR_ROAM_SUBSTATE_STOP_BSS_REQ the command is not removed.

Fix is to handle the eWNI_SME_DISCONNECT_DONE_IND in
eCSR_ROAM_SUBSTATE_STOP_BSS_REQ state.Also allow
hdd_cfg80211_del_station call during unload.

Change-Id: I79cd1f413f2f9f12e6da6702098b782b6c156d24
CRs-Fixed: 2425724
Abhishek Singh před 6 roky
rodič
revize
97e8a71156
2 změnil soubory, kde provedl 66 přidání a 64 odebrání
  1. 4 5
      core/hdd/src/wlan_hdd_cfg80211.c
  2. 62 59
      core/sme/src/csr/csr_api_roam.c

+ 4 - 5
core/hdd/src/wlan_hdd_cfg80211.c

@@ -19423,7 +19423,6 @@ int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
 	struct hdd_context *hdd_ctx;
 	QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
 	struct hdd_hostapd_state *hapd_state;
-	int status;
 	uint8_t sta_id;
 	uint8_t *mac;
 	mac_handle_t mac_handle;
@@ -19443,10 +19442,10 @@ int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
 		   adapter->vdev_id, adapter->device_mode);
 
 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-	status = wlan_hdd_validate_context(hdd_ctx);
-
-	if (0 != status)
-		return status;
+	if (!hdd_ctx) {
+		hdd_err("hdd_ctx is NULL");
+		return -EINVAL;
+	}
 
 	mac = (uint8_t *) param->peerMacAddr.bytes;
 	mac_handle = hdd_ctx->mac_handle;

+ 62 - 59
core/sme/src/csr/csr_api_roam.c

@@ -9645,6 +9645,64 @@ csr_roam_roaming_state_start_bss_rsp_processor(struct mac_context *mac,
 				pSmeStartBssRsp->sessionId);
 }
 
+/**
+ * csr_roam_send_disconnect_done_indication() - Send disconnect ind to HDD.
+ *
+ * @mac_ctx: mac global context
+ * @msg_ptr: incoming message
+ *
+ * This function gives final disconnect event to HDD after all cleanup in
+ * lower layers is done.
+ *
+ * Return: None
+ */
+static void
+csr_roam_send_disconnect_done_indication(struct mac_context *mac_ctx,
+					 tSirSmeRsp *msg_ptr)
+{
+	struct sir_sme_discon_done_ind *discon_ind =
+				(struct sir_sme_discon_done_ind *)(msg_ptr);
+	struct csr_roam_info *roam_info;
+	struct csr_roam_session *session;
+
+	roam_info = qdf_mem_malloc(sizeof(*roam_info));
+	if (!roam_info)
+		return;
+
+	sme_debug("DISCONNECT_DONE_IND RC:%d", discon_ind->reason_code);
+
+	if (CSR_IS_SESSION_VALID(mac_ctx, discon_ind->session_id)) {
+		roam_info->reasonCode = discon_ind->reason_code;
+		roam_info->statusCode = eSIR_SME_STA_NOT_ASSOCIATED;
+		qdf_mem_copy(roam_info->peerMac.bytes, discon_ind->peer_mac,
+			     ETH_ALEN);
+
+		roam_info->rssi = mac_ctx->peer_rssi;
+		roam_info->tx_rate = mac_ctx->peer_txrate;
+		roam_info->rx_rate = mac_ctx->peer_rxrate;
+		roam_info->disassoc_reason = discon_ind->reason_code;
+
+		csr_roam_call_callback(mac_ctx, discon_ind->session_id,
+				       roam_info, 0, eCSR_ROAM_LOSTLINK,
+				       eCSR_ROAM_RESULT_DISASSOC_IND);
+		session = CSR_GET_SESSION(mac_ctx, discon_ind->session_id);
+		if (session &&
+		   !CSR_IS_INFRA_AP(&session->connectedProfile))
+			csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE,
+				discon_ind->session_id);
+
+	} else {
+		sme_err("Inactive session %d", discon_ind->session_id);
+	}
+
+	/*
+	 * Release WM status change command as eWNI_SME_DISCONNECT_DONE_IND
+	 * has been sent to HDD and there is nothing else left to do.
+	 */
+	csr_roam_wm_status_change_complete(mac_ctx, discon_ind->session_id);
+	qdf_mem_free(roam_info);
+}
+
 /**
  * csr_roaming_state_msg_processor() - process roaming messages
  * @mac:       mac global context
@@ -9766,6 +9824,10 @@ void csr_roaming_state_msg_processor(struct mac_context *mac, void *pMsgBuf)
 		csr_roam_check_for_link_status_change(mac, pSmeRsp);
 		break;
 
+	case eWNI_SME_DISCONNECT_DONE_IND:
+		csr_roam_send_disconnect_done_indication(mac, pSmeRsp);
+		break;
+
 	case eWNI_SME_UPPER_LAYER_ASSOC_CNF:
 	{
 		tSirSmeAssocIndToUpperLayerCnf *upper_layer_assoc_cnf =
@@ -11296,65 +11358,6 @@ csr_roam_chk_lnk_disassoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
 	qdf_mem_free(cmd);
 }
 
-/**
- * csr_roam_send_disconnect_done_indication() - Send disconnect ind to HDD.
- *
- * @mac_ctx: mac global context
- * @msg_ptr: incoming message
- *
- * This function gives final disconnect event to HDD after all cleanup in
- * lower layers is done.
- *
- * Return: None
- */
-static void
-csr_roam_send_disconnect_done_indication(struct mac_context *mac_ctx, tSirSmeRsp
-				     *msg_ptr)
-{
-	struct sir_sme_discon_done_ind *discon_ind =
-				(struct sir_sme_discon_done_ind *)(msg_ptr);
-	struct csr_roam_info *roam_info;
-	struct csr_roam_session *session;
-
-	roam_info = qdf_mem_malloc(sizeof(*roam_info));
-	if (!roam_info)
-		return;
-
-	sme_debug("eWNI_SME_DISCONNECT_DONE_IND RC:%d",
-		discon_ind->reason_code);
-
-	if (CSR_IS_SESSION_VALID(mac_ctx, discon_ind->session_id)) {
-		roam_info->reasonCode = discon_ind->reason_code;
-		roam_info->statusCode = eSIR_SME_STA_NOT_ASSOCIATED;
-		qdf_mem_copy(roam_info->peerMac.bytes, discon_ind->peer_mac,
-			     ETH_ALEN);
-
-		roam_info->rssi = mac_ctx->peer_rssi;
-		roam_info->tx_rate = mac_ctx->peer_txrate;
-		roam_info->rx_rate = mac_ctx->peer_rxrate;
-		roam_info->disassoc_reason = discon_ind->reason_code;
-
-		csr_roam_call_callback(mac_ctx, discon_ind->session_id,
-				       roam_info, 0, eCSR_ROAM_LOSTLINK,
-				       eCSR_ROAM_RESULT_DISASSOC_IND);
-		session = CSR_GET_SESSION(mac_ctx, discon_ind->session_id);
-		if (session &&
-		   !CSR_IS_INFRA_AP(&session->connectedProfile))
-			csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_IDLE,
-				discon_ind->session_id);
-
-	} else
-		sme_err("Inactive session %d",
-			discon_ind->session_id);
-
-	/*
-	 * Release WM status change command as eWNI_SME_DISCONNECT_DONE_IND
-	 * has been sent to HDD and there is nothing else left to do.
-	 */
-	csr_roam_wm_status_change_complete(mac_ctx, discon_ind->session_id);
-	qdf_mem_free(roam_info);
-}
-
 static void
 csr_roam_chk_lnk_deauth_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
 {