Bladeren bron

qcacmn: Free netbuf and release peer ref at driver unload time

Free netbuf and release peer ref for tx frames for which tx completions
are not received from fw during driver unload time in
wlan_mgmt_txrx_psoc_close().

Change-Id: I8d5fb2e79f14a978473ab3754d9e495eb09eddaa
CRs-Fixed: 2122505
Himanshu Agarwal 7 jaren geleden
bovenliggende
commit
2afd447999

+ 8 - 1
init_deinit/dispatcher/src/dispatcher_init_deinit.c

@@ -782,9 +782,12 @@ EXPORT_SYMBOL(dispatcher_deinit);
 
 QDF_STATUS dispatcher_psoc_open(struct wlan_objmgr_psoc *psoc)
 {
-	if (QDF_STATUS_SUCCESS != ucfg_scan_psoc_open(psoc))
+	if (QDF_STATUS_SUCCESS != wlan_mgmt_txrx_psoc_open(psoc))
 		goto out;
 
+	if (QDF_STATUS_SUCCESS != ucfg_scan_psoc_open(psoc))
+		goto scan_psoc_open_fail;
+
 	if (QDF_STATUS_SUCCESS != p2p_psoc_open(psoc))
 		goto p2p_psoc_open_fail;
 
@@ -821,6 +824,8 @@ tdls_psoc_open_fail:
 	p2p_psoc_close(psoc);
 p2p_psoc_open_fail:
 	ucfg_scan_psoc_close(psoc);
+scan_psoc_open_fail:
+	wlan_mgmt_txrx_psoc_close(psoc);
 
 out:
 	return QDF_STATUS_E_FAILURE;
@@ -845,6 +850,8 @@ QDF_STATUS dispatcher_psoc_close(struct wlan_objmgr_psoc *psoc)
 
 	QDF_BUG(QDF_STATUS_SUCCESS == ucfg_scan_psoc_close(psoc));
 
+	QDF_BUG(QDF_STATUS_SUCCESS == wlan_mgmt_txrx_psoc_close(psoc));
+
 	return QDF_STATUS_SUCCESS;
 }
 EXPORT_SYMBOL(dispatcher_psoc_close);

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

@@ -777,4 +777,19 @@ QDF_STATUS wlan_mgmt_txrx_deregister_rx_cb(
 			struct mgmt_txrx_mgmt_frame_cb_info *frm_cb_info,
 			uint8_t num_entries);
 
+/**
+ * wlan_mgmt_txrx_psoc_open() - mgmt txrx module psoc open API
+ * @psoc: psoc context
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS wlan_mgmt_txrx_psoc_open(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_mgmt_txrx_psoc_close() - mgmt txrx module psoc close API
+ * @psoc: psoc context
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS wlan_mgmt_txrx_psoc_close(struct wlan_objmgr_psoc *psoc);
 #endif

+ 46 - 0
umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c

@@ -518,3 +518,49 @@ QDF_STATUS wlan_mgmt_txrx_deregister_rx_cb(
 
 	return QDF_STATUS_SUCCESS;
 }
+
+QDF_STATUS wlan_mgmt_txrx_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_mgmt_txrx_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	struct mgmt_txrx_priv_context *mgmt_txrx_ctx;
+	struct mgmt_txrx_desc_elem_t *mgmt_desc;
+	uint8_t i;
+	uint32_t pool_size;
+
+	if (!psoc) {
+		mgmt_txrx_err("psoc context is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	mgmt_txrx_ctx = (struct mgmt_txrx_priv_context *)
+			wlan_objmgr_psoc_get_comp_private_obj(psoc,
+				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_txrx_info("mgmt descriptor with desc id: %d not in freelist",
+				       i);
+			mgmt_desc = &mgmt_txrx_ctx->mgmt_desc_pool.pool[i];
+			qdf_nbuf_free(mgmt_desc->nbuf);
+			wlan_objmgr_peer_release_ref(mgmt_desc->peer,
+						     WLAN_MGMT_SB_ID);
+			wlan_mgmt_txrx_desc_put(mgmt_txrx_ctx, i);
+		}
+	}
+
+	return QDF_STATUS_SUCCESS;
+}