Prechádzať zdrojové kódy

qcacmn: Unmap nbuf of pending mgmt frames

As part of wlan_mgmt_txrx_pdev_close only nbuf is freed
in case of cleanup path due to SSR or drive unload and
dma unmap is not done.

In this change:
1) Register a callback to mgmt_txrx component tx ops which
   does dma unmap of nbuf as part of pdev close.
2) Revert change id I6a7f5efa665a1da009e594248e88002df35ae9ff
   as there are potential race conditions using the APIs added
   as part of the change.

Change-Id: Id65388a5f4fcb989659bb2088a5e67a4e4e3d265
CRs-Fixed: 2313073
Sravan Kumar Kairam 6 rokov pred
rodič
commit
516330bf2e

+ 0 - 27
umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h

@@ -745,19 +745,6 @@ typedef QDF_STATUS (*mgmt_frame_fill_peer_cb)(
 			struct wlan_objmgr_peer *peer,
 			qdf_nbuf_t buf);
 
-/**
- * mgmt_frame_nbuf_op - Function pointer for any nbuf ops
- * @peer: peer
- * @buf: buffer
- *
- * This is the function pointer to be called during drain at peer
- * peer deletion
- *
- * Return: None
- */
-typedef void (*mgmt_frame_nbuf_op)(struct wlan_objmgr_peer *peer,
-				   qdf_nbuf_t buf);
-
 /**
  * struct mgmt_txrx_mgmt_frame_cb_info - frm and corresponding rx cb info
  * @frm_type:    mgmt frm type
@@ -860,20 +847,6 @@ QDF_STATUS wlan_mgmt_txrx_register_rx_cb(
 			struct mgmt_txrx_mgmt_frame_cb_info *frm_cb_info,
 			uint8_t num_entries);
 
-/**
- * wlan_mgmt_txrx_peer_drain() - Function to drain all mgmt packets
- * specific to a peer
- * @peer: peer context
- * @mgmt_nbuf_op: callback func to UMAC for nbuf related operation
- *
- * This function drains all mgmt packets of a peer at the time of
- * peer deletion.
- *
- * Return: QDF_STATUS_SUCCESS - in case of success
- */
-QDF_STATUS wlan_mgmt_txrx_peer_drain(struct wlan_objmgr_peer *peer,
-				     mgmt_frame_nbuf_op mgmt_nbuf_op);
-
 /**
  * wlan_mgmt_txrx_vdev_drain() - Function to drain all mgmt packets
  * specific to a vdev

+ 11 - 52
umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c

@@ -729,6 +729,7 @@ QDF_STATUS wlan_mgmt_txrx_pdev_open(struct wlan_objmgr_pdev *pdev)
 
 QDF_STATUS wlan_mgmt_txrx_pdev_close(struct wlan_objmgr_pdev *pdev)
 {
+	struct wlan_objmgr_psoc *psoc;
 	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
 	struct mgmt_txrx_desc_elem_t *mgmt_desc;
 	uint32_t pool_size;
@@ -739,6 +740,12 @@ QDF_STATUS wlan_mgmt_txrx_pdev_close(struct wlan_objmgr_pdev *pdev)
 		return QDF_STATUS_E_INVAL;
 	}
 
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc) {
+		mgmt_txrx_err("psoc unavailable for pdev %pK", pdev);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
 	mgmt_txrx_pdev_ctx = (struct mgmt_txrx_priv_pdev_context *)
 		wlan_objmgr_pdev_get_comp_private_obj(pdev,
 		WLAN_UMAC_COMP_MGMT_TXRX);
@@ -760,6 +767,10 @@ QDF_STATUS wlan_mgmt_txrx_pdev_close(struct wlan_objmgr_pdev *pdev)
 				"mgmt descriptor with desc id: %d not in freelist",
 				index);
 			mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[index];
+			if (psoc->soc_cb.tx_ops.mgmt_txrx_tx_ops.
+					tx_drain_nbuf_op)
+				psoc->soc_cb.tx_ops.mgmt_txrx_tx_ops.
+					tx_drain_nbuf_op(pdev, mgmt_desc->nbuf);
 			qdf_nbuf_free(mgmt_desc->nbuf);
 			wlan_objmgr_peer_release_ref(mgmt_desc->peer,
 				WLAN_MGMT_NB_ID);
@@ -770,58 +781,6 @@ QDF_STATUS wlan_mgmt_txrx_pdev_close(struct wlan_objmgr_pdev *pdev)
 	return QDF_STATUS_SUCCESS;
 }
 
-QDF_STATUS wlan_mgmt_txrx_peer_drain(struct wlan_objmgr_peer *peer,
-				     mgmt_frame_nbuf_op mgmt_nbuf_op)
-{
-	struct wlan_objmgr_pdev *pdev;
-	struct wlan_objmgr_vdev *vdev;
-	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_ctx;
-	struct mgmt_txrx_desc_elem_t *mgmt_desc;
-	struct wlan_objmgr_peer *des_peer;
-	uint32_t pool_size;
-	int i;
-
-	vdev = wlan_peer_get_vdev(peer);
-	if (!vdev) {
-		mgmt_txrx_err("vdev context is NULL");
-		return QDF_STATUS_E_INVAL;
-	}
-
-	pdev = wlan_vdev_get_pdev(vdev);
-	if (!pdev) {
-		mgmt_txrx_err("pdev context is NULL");
-		return QDF_STATUS_E_INVAL;
-	}
-
-	mgmt_txrx_ctx = wlan_objmgr_pdev_get_comp_private_obj(pdev,
-						WLAN_UMAC_COMP_MGMT_TXRX);
-	if (!mgmt_txrx_ctx) {
-		mgmt_txrx_err("mgmt txrx context is NULL");
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	pool_size = mgmt_txrx_ctx->mgmt_desc_pool.free_list.max_size;
-	if (!pool_size) {
-		mgmt_txrx_err("pool size is 0");
-		return QDF_STATUS_E_FAILURE;
-	}
-
-	for (i = 0; i < pool_size; i++) {
-		if (mgmt_txrx_ctx->mgmt_desc_pool.pool[i].in_use) {
-			mgmt_desc = &mgmt_txrx_ctx->mgmt_desc_pool.pool[i];
-			des_peer = mgmt_txrx_get_peer(pdev, mgmt_desc->desc_id);
-			if (peer == des_peer) {
-				if (mgmt_nbuf_op)
-					mgmt_nbuf_op(peer, mgmt_desc->nbuf);
-				mgmt_txrx_tx_completion_handler(pdev,
-						mgmt_desc->desc_id, 0, 0);
-			}
-		}
-	}
-
-	return QDF_STATUS_SUCCESS;
-}
-
 QDF_STATUS wlan_mgmt_txrx_vdev_drain(struct wlan_objmgr_vdev *vdev,
 				mgmt_frame_fill_peer_cb mgmt_fill_peer_cb,
 				void *status)

+ 4 - 0
umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h

@@ -116,6 +116,8 @@ struct wlan_lmac_if_cp_stats_rx_ops {
  * @mgmt_tx_send: function pointer to transmit mgmt tx frame
  * @beacon_send:  function pointer to transmit beacon frame
  * @fd_action_frame_send: function pointer to transmit FD action frame
+ * @tx_drain_nbuf_op: function pointer for any umac nbuf realted ops for
+ *                    pending mgmt frames cleanup
  */
 struct wlan_lmac_if_mgmt_txrx_tx_ops {
 	QDF_STATUS (*mgmt_tx_send)(struct wlan_objmgr_vdev *vdev,
@@ -125,6 +127,8 @@ struct wlan_lmac_if_mgmt_txrx_tx_ops {
 			qdf_nbuf_t nbuf);
 	QDF_STATUS (*fd_action_frame_send)(struct wlan_objmgr_vdev *vdev,
 					   qdf_nbuf_t nbuf);
+	void (*tx_drain_nbuf_op)(struct wlan_objmgr_pdev *pdev,
+				 qdf_nbuf_t nbuf);
 };
 
 /**