Jelajahi Sumber

qcacld-3.0: Detach peer deletion from vdev deletion

Self-peer holds a reference to the vdev object. As part
of new changes to send vdev delete to firmware as part
of vdev delete notification, the self peer reference needs
to be released 1st before sending the vdev delete to firmware.

Hence detach the peer deletion from the vdev deletion.

Change-Id: I8169fdd6cc6acadea9a89baf38bd273797e8bc9b
CRs-Fixed: 2565315
Arun Kumar Khandavalli 5 tahun lalu
induk
melakukan
c1d2b4f520
1 mengubah file dengan 153 tambahan dan 119 penghapusan
  1. 153 119
      core/wma/src/wma_dev_if.c

+ 153 - 119
core/wma/src/wma_dev_if.c

@@ -483,83 +483,6 @@ QDF_STATUS wma_vdev_detach_callback(
 	return param->status;
 }
 
-/**
- * wma_self_peer_remove() - Self peer remove handler
- * @wma: wma handle
- * @del_vdev_req_param: vdev id
- * @generate_vdev_rsp: request type
- *
- * Return: success if peer delete command sent to firmware, else failure.
- */
-static QDF_STATUS wma_self_peer_remove(tp_wma_handle wma_handle,
-			struct del_vdev_params *del_vdev_req_param)
-{
-	void *peer;
-	struct cdp_pdev *pdev;
-	QDF_STATUS qdf_status;
-	uint8_t peer_id;
-	uint8_t vdev_id = del_vdev_req_param->vdev_id;
-	struct wma_target_req *msg = NULL;
-	struct del_sta_self_rsp_params *sta_self_wmi_rsp;
-	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
-
-	WMA_LOGD("P2P Device: removing self peer %pM",
-		 del_vdev_req_param->self_mac_addr);
-
-	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
-	if (!pdev) {
-		WMA_LOGE("%s: Failed to get pdev", __func__);
-		qdf_status = QDF_STATUS_E_FAULT;
-		goto error;
-	}
-
-	peer = cdp_peer_find_by_addr(soc, pdev,
-			del_vdev_req_param->self_mac_addr,
-			&peer_id);
-	if (!peer) {
-		WMA_LOGE("%s Failed to find peer %pM", __func__,
-			 del_vdev_req_param->self_mac_addr);
-		qdf_status = QDF_STATUS_E_FAULT;
-		goto error;
-	}
-
-	qdf_status = wma_remove_peer(wma_handle,
-				     del_vdev_req_param->self_mac_addr,
-				     vdev_id, peer, false);
-	if (QDF_IS_STATUS_ERROR(qdf_status)) {
-		WMA_LOGE(FL("wma_remove_peer is failed"));
-		goto error;
-	}
-
-	if (wmi_service_enabled(wma_handle->wmi_handle,
-				wmi_service_sync_delete_cmds)) {
-		sta_self_wmi_rsp =
-			qdf_mem_malloc(sizeof(struct del_sta_self_rsp_params));
-		if (!sta_self_wmi_rsp) {
-			qdf_status = QDF_STATUS_E_NOMEM;
-			goto error;
-		}
-		sta_self_wmi_rsp->self_sta_param = del_vdev_req_param;
-		msg = wma_fill_hold_req(wma_handle, vdev_id,
-				   WMA_DELETE_STA_REQ,
-				   WMA_DEL_P2P_SELF_STA_RSP_START,
-				   sta_self_wmi_rsp,
-				   WMA_DELETE_STA_TIMEOUT);
-		if (!msg) {
-			WMA_LOGE(FL("Failed to allocate request for vdev_id %d"),
-				 vdev_id);
-			wma_remove_req(wma_handle, vdev_id,
-				WMA_DEL_P2P_SELF_STA_RSP_START);
-			qdf_mem_free(sta_self_wmi_rsp);
-			qdf_status = QDF_STATUS_E_FAILURE;
-			goto error;
-		}
-	}
-	return QDF_STATUS_SUCCESS;
-error:
-	return qdf_status;
-}
-
 static void
 wma_cdp_vdev_detach(ol_txrx_soc_handle soc, tp_wma_handle wma_handle,
 		    uint8_t vdev_id)
@@ -678,6 +601,80 @@ out:
 	return status;
 }
 
+/**
+ * wma_self_peer_remove() - Self peer remove handler
+ * @wma: wma handle
+ * @del_vdev_req_param: vdev id
+ * @generate_vdev_rsp: request type
+ *
+ * Return: success if peer delete command sent to firmware, else failure.
+ */
+static QDF_STATUS wma_self_peer_remove(tp_wma_handle wma_handle,
+				       struct del_vdev_params *del_vdev_req)
+{
+	void *peer;
+	struct cdp_pdev *pdev;
+	QDF_STATUS qdf_status;
+	uint8_t peer_id;
+	uint8_t vdev_id = del_vdev_req->vdev_id;
+	struct wma_target_req *msg = NULL;
+	struct del_sta_self_rsp_params *sta_self_wmi_rsp;
+	void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+
+	wma_debug("P2P Device: removing self peer %pM",
+		  del_vdev_req->self_mac_addr);
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		wma_err("Failed to get pdev");
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto error;
+	}
+
+	peer = cdp_peer_find_by_addr(soc, pdev, del_vdev_req->self_mac_addr,
+				     &peer_id);
+	if (!peer) {
+		wma_err("Failed to find peer %pM", del_vdev_req->self_mac_addr);
+		qdf_status = QDF_STATUS_E_FAULT;
+		goto error;
+	}
+
+	qdf_status = wma_remove_peer(wma_handle, del_vdev_req->self_mac_addr,
+				     vdev_id, peer, false);
+	if (QDF_IS_STATUS_ERROR(qdf_status)) {
+		wma_err("wma_remove_peer is failed");
+		goto error;
+	}
+
+	if (wmi_service_enabled(wma_handle->wmi_handle,
+				wmi_service_sync_delete_cmds)) {
+		sta_self_wmi_rsp =
+			qdf_mem_malloc(sizeof(struct del_sta_self_rsp_params));
+		if (!sta_self_wmi_rsp) {
+			qdf_status = QDF_STATUS_E_NOMEM;
+			goto error;
+		}
+		sta_self_wmi_rsp->self_sta_param = del_vdev_req;
+		msg = wma_fill_hold_req(wma_handle, vdev_id,
+					WMA_DELETE_STA_REQ,
+					WMA_DEL_P2P_SELF_STA_RSP_START,
+					sta_self_wmi_rsp,
+					WMA_DELETE_STA_TIMEOUT);
+		if (!msg) {
+			wma_err("Failed to allocate request for vdev_id %d",
+				vdev_id);
+			wma_remove_req(wma_handle, vdev_id,
+				       WMA_DEL_P2P_SELF_STA_RSP_START);
+			qdf_mem_free(sta_self_wmi_rsp);
+			qdf_status = QDF_STATUS_E_FAILURE;
+			goto error;
+		}
+	}
+
+error:
+	return qdf_status;
+}
+
 /**
  * wma_force_objmgr_vdev_peer_cleanup() - Cleanup ObjMgr Vdev peers during SSR
  * @wma_handle: WMA handle
@@ -827,13 +824,74 @@ static void wma_remove_objmgr_peer(tp_wma_handle wma, uint8_t vdev_id,
 	wlan_objmgr_vdev_release_ref(obj_vdev, WLAN_LEGACY_WMA_ID);
 }
 
+static QDF_STATUS wma_check_for_deffered_peer_delete(tp_wma_handle wma_handle,
+						     struct del_vdev_params
+						     *pdel_vdev_req_param)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t vdev_id = pdel_vdev_req_param->vdev_id;
+	struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
+	uint32_t vdev_stop_type;
+
+	if (qdf_atomic_read(&iface->bss_status) == WMA_BSS_STATUS_STARTED) {
+		status = mlme_get_vdev_stop_type(iface->vdev, &vdev_stop_type);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			wma_err("Failed to get wma req msg_type for vdev_id: %d",
+				vdev_id);
+			status = QDF_STATUS_E_INVAL;
+			return status;
+		}
+
+		if (vdev_stop_type != WMA_DELETE_BSS_REQ) {
+			status = QDF_STATUS_E_INVAL;
+			return status;
+		}
+
+		wma_debug("BSS is not yet stopped. Defering vdev(vdev id %x) deletion",
+			  vdev_id);
+		iface->del_staself_req = pdel_vdev_req_param;
+		iface->is_del_sta_defered = true;
+	}
+
+	return status;
+}
+
+static QDF_STATUS wma_vdev_self_peer_delete(tp_wma_handle wma_handle,
+					    struct del_vdev_params
+					    *pdel_vdev_req_param)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	uint8_t vdev_id = pdel_vdev_req_param->vdev_id;
+	struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
+
+	if (wma_vdev_uses_self_peer(iface->type, iface->sub_type)) {
+		status = wma_self_peer_remove(wma_handle, pdel_vdev_req_param);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			wma_err("can't remove selfpeer, send rsp session: %d",
+				vdev_id);
+			status = wma_handle_vdev_detach(wma_handle,
+							pdel_vdev_req_param);
+			if (QDF_IS_STATUS_ERROR(status)) {
+				wma_err("Trigger recovery for vdev %d",
+					vdev_id);
+				cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
+			}
+			return status;
+		}
+	} else if (iface->type == WMI_VDEV_TYPE_STA) {
+		wma_remove_objmgr_peer(wma_handle, vdev_id,
+				       pdel_vdev_req_param->self_mac_addr);
+	}
+
+	return status;
+}
+
 QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle,
 			struct del_vdev_params *pdel_vdev_req_param)
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	uint8_t vdev_id = pdel_vdev_req_param->vdev_id;
 	struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id];
-	uint32_t vdev_stop_type;
 
 	if (!iface->vdev) {
 		WMA_LOGE("vdev %d is NULL", vdev_id);
@@ -858,57 +916,33 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle,
 		goto send_rsp;
 	}
 
-	if (qdf_atomic_read(&iface->bss_status) == WMA_BSS_STATUS_STARTED) {
-		status = mlme_get_vdev_stop_type(iface->vdev, &vdev_stop_type);
-		if (QDF_IS_STATUS_ERROR(status)) {
-			WMA_LOGE("Failed to get wma req msg_type for vdev_id: %d",
-				 vdev_id);
-			goto send_fail_rsp;
-		}
+	status = wma_check_for_deffered_peer_delete(wma_handle,
+						    pdel_vdev_req_param);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto  send_fail_rsp;
 
-		if (vdev_stop_type != WMA_DELETE_BSS_REQ)
-			goto send_fail_rsp;
+	if (iface->is_del_sta_defered)
+		return status;
 
-		WMA_LOGA("BSS is not yet stopped. Defering vdev(vdev id %x) deletion",
-			vdev_id);
-		iface->del_staself_req = pdel_vdev_req_param;
-		iface->is_del_sta_defered = true;
+	iface->is_del_sta_defered = false;
+
+	status = wma_vdev_self_peer_delete(wma_handle, pdel_vdev_req_param);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wma_err("Failed to send self peer delete:%d", status);
 		return status;
 	}
-	iface->is_del_sta_defered = false;
 
-	if (wma_vdev_uses_self_peer(iface->type, iface->sub_type)) {
-		status = wma_self_peer_remove(wma_handle, pdel_vdev_req_param);
-		if (QDF_IS_STATUS_ERROR(status)) {
-			WMA_LOGE("can't remove selfpeer, send rsp session: %d",
-				 vdev_id);
-			status = wma_handle_vdev_detach(wma_handle,
-							pdel_vdev_req_param);
-			if (QDF_IS_STATUS_ERROR(status)) {
-				WMA_LOGE("Trigger recovery for vdev %d",
-					 vdev_id);
-				cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
-			}
-			return status;
-		}
+	if (iface->type != WMI_VDEV_TYPE_MONITOR)
+		iface->vdev_active = false;
 
-		if (!wmi_service_enabled(wma_handle->wmi_handle,
-				wmi_service_sync_delete_cmds))
-			status = wma_handle_vdev_detach(wma_handle,
-							pdel_vdev_req_param);
-	} else {
-		if (iface->type == WMI_VDEV_TYPE_STA) {
-			wma_remove_objmgr_peer(wma_handle, vdev_id,
-				pdel_vdev_req_param->self_mac_addr);
-		}
+	if (!wma_vdev_uses_self_peer(iface->type, iface->sub_type) ||
+	    !wmi_service_enabled(wma_handle->wmi_handle,
+	    wmi_service_sync_delete_cmds)) {
 		status = wma_handle_vdev_detach(wma_handle,
 						pdel_vdev_req_param);
 	}
 
-	if (QDF_IS_STATUS_SUCCESS(status) &&
-	    iface->type != WMI_VDEV_TYPE_MONITOR)
-		iface->vdev_active = false;
-
 	return status;
 
 send_fail_rsp: