ソースを参照

qcacmn: Move mgmt descriptors per pdev for probe response throttling

Mgmt tx rx descriptors are now used instead of WMI descriptors
for management Tx/Rx.
Since WMI descriptors were per radio to support probe response throttling
the mgmt descriptors should also be moved from per psoc to per pdev.

The reason for this is probe response throttling should happen per radio
and not per psoc since if the mgmt frames peding counter is
maintained per psoc, it could affect other radios of the same psoc also.

The maximum number of mgmt descriptors per psoc was 50.
This is also changed to 512 mgmt descriptors per pdev which is the
same as WMI descriptors per radio as used earlier to support
probe response throttling.

Change-Id: Ibb46082e0acf340800418a7e9689a29cd688bdab
CRs-Fixed: 2146177
Vivek 7 年 前
コミット
5747b78091

+ 5 - 1
umac/cmn_services/inc/wlan_cmn.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -49,6 +49,10 @@
 /* Invalid pdev_id */
 #define WLAN_INVALID_PDEV_ID 0xFFFFFFFF
 
+/* Invalid free descriptor count */
+#define WLAN_INVALID_MGMT_DESC_COUNT 0xFFFFFFFF
+
+/* 802.11 cap info */
 /* 802.11 cap info */
 #define WLAN_CAPINFO_ESS               0x0001
 #define WLAN_CAPINFO_IBSS              0x0002

+ 50 - 44
umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -26,7 +26,7 @@
 #include "qdf_nbuf.h"
 
 QDF_STATUS wlan_mgmt_txrx_desc_pool_init(
-			struct mgmt_txrx_priv_context *mgmt_txrx_ctx,
+			struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx,
 			uint32_t pool_size)
 {
 	uint32_t i;
@@ -37,88 +37,93 @@ QDF_STATUS wlan_mgmt_txrx_desc_pool_init(
 		return QDF_STATUS_E_INVAL;
 	}
 
-	mgmt_txrx_info("mgmt_txrx ctx: %pK psoc: %pK, initialize mgmt desc pool of size %d",
-				mgmt_txrx_ctx, mgmt_txrx_ctx->psoc, pool_size);
-	mgmt_txrx_ctx->mgmt_desc_pool.pool = qdf_mem_malloc(pool_size *
-					sizeof(struct mgmt_txrx_desc_elem_t));
+	mgmt_txrx_info(
+			"mgmt_txrx ctx: %pK pdev: %pK"
+			"initialize mgmt desc pool of size %d",
+			mgmt_txrx_pdev_ctx, mgmt_txrx_pdev_ctx->pdev, pool_size);
+	mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool = qdf_mem_malloc(pool_size *
+			sizeof(struct mgmt_txrx_desc_elem_t));
 
-	if (!mgmt_txrx_ctx->mgmt_desc_pool.pool) {
+	if (!mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool) {
 		mgmt_txrx_err("Failed to allocate desc pool");
 		return QDF_STATUS_E_NOMEM;
 	}
-	qdf_list_create(&mgmt_txrx_ctx->mgmt_desc_pool.free_list, pool_size);
+	qdf_list_create(&mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list,
+					pool_size);
 
 	for (i = 0; i < pool_size; i++) {
-		mgmt_txrx_ctx->mgmt_desc_pool.pool[i].desc_id = i;
-		mgmt_txrx_ctx->mgmt_desc_pool.pool[i].in_use = false;
-		qdf_list_insert_front(&mgmt_txrx_ctx->mgmt_desc_pool.free_list,
-				&mgmt_txrx_ctx->mgmt_desc_pool.pool[i].entry);
+		mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[i].desc_id = i;
+		mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[i].in_use = false;
+		qdf_list_insert_front(
+				&mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list,
+				&mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[i].entry);
 	}
 
 	qdf_spinlock_create(
-		&mgmt_txrx_ctx->mgmt_desc_pool.desc_pool_lock);
+		&mgmt_txrx_pdev_ctx->mgmt_desc_pool.desc_pool_lock);
 
 	return QDF_STATUS_SUCCESS;
 }
 
 void wlan_mgmt_txrx_desc_pool_deinit(
-			struct mgmt_txrx_priv_context *mgmt_txrx_ctx)
+			struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx)
 {
-	uint8_t i;
+	uint32_t i;
 	uint32_t pool_size;
 	QDF_STATUS status;
 
-	if (!mgmt_txrx_ctx->mgmt_desc_pool.pool) {
+	if (!mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool) {
 		mgmt_txrx_err("Empty mgmt descriptor pool");
 		qdf_assert_always(0);
 		return;
 	}
 
-	pool_size = mgmt_txrx_ctx->mgmt_desc_pool.free_list.max_size;
+	pool_size = mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list.max_size;
 	for (i = 0; i < pool_size; i++) {
 		status = qdf_list_remove_node(
-				&mgmt_txrx_ctx->mgmt_desc_pool.free_list,
-				&mgmt_txrx_ctx->mgmt_desc_pool.pool[i].entry);
+				&mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list,
+				&mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[i].entry);
 		if (status != QDF_STATUS_SUCCESS)
-			mgmt_txrx_err("Failed to get mgmt descriptor from freelist, desc id: %d with status %d",
-					i, status);
+			mgmt_txrx_err(
+				"Failed to get mgmt desc from freelist, desc id: %d: status %d",
+				i, status);
 	}
 
-	qdf_list_destroy(&mgmt_txrx_ctx->mgmt_desc_pool.free_list);
-	qdf_mem_free(mgmt_txrx_ctx->mgmt_desc_pool.pool);
-	mgmt_txrx_ctx->mgmt_desc_pool.pool = NULL;
+	qdf_list_destroy(&mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list);
+	qdf_mem_free(mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool);
+	mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool = NULL;
 
 	qdf_spinlock_destroy(
-		&mgmt_txrx_ctx->mgmt_desc_pool.desc_pool_lock);
+		&mgmt_txrx_pdev_ctx->mgmt_desc_pool.desc_pool_lock);
 }
 
 struct mgmt_txrx_desc_elem_t *wlan_mgmt_txrx_desc_get(
-			struct mgmt_txrx_priv_context *mgmt_txrx_ctx)
+			struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx)
 {
 	QDF_STATUS status;
 	qdf_list_node_t *desc_node;
 	struct mgmt_txrx_desc_elem_t *mgmt_txrx_desc;
 
-	qdf_spin_lock_bh(&mgmt_txrx_ctx->mgmt_desc_pool.desc_pool_lock);
-	if (qdf_list_peek_front(&mgmt_txrx_ctx->mgmt_desc_pool.free_list,
+	qdf_spin_lock_bh(&mgmt_txrx_pdev_ctx->mgmt_desc_pool.desc_pool_lock);
+	if (qdf_list_peek_front(&mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list,
 			    &desc_node)
 			!= QDF_STATUS_SUCCESS) {
 		qdf_spin_unlock_bh(
-			&mgmt_txrx_ctx->mgmt_desc_pool.desc_pool_lock);
+			&mgmt_txrx_pdev_ctx->mgmt_desc_pool.desc_pool_lock);
 		mgmt_txrx_err("Descriptor freelist empty for mgmt_txrx_ctx %pK",
-				mgmt_txrx_ctx);
+				mgmt_txrx_pdev_ctx);
 		return NULL;
 	}
 
-	status = qdf_list_remove_node(&mgmt_txrx_ctx->mgmt_desc_pool.free_list,
-			     desc_node);
+	status = qdf_list_remove_node(
+				&mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list,
+				desc_node);
 	if (status != QDF_STATUS_SUCCESS) {
 		qdf_spin_unlock_bh(
-			&mgmt_txrx_ctx->mgmt_desc_pool.desc_pool_lock);
+			&mgmt_txrx_pdev_ctx->mgmt_desc_pool.desc_pool_lock);
 		mgmt_txrx_err("Failed to get descriptor from list: status %d",
 					status);
 		qdf_assert_always(0);
-		return NULL;
 	}
 
 	mgmt_txrx_desc = qdf_container_of(desc_node,
@@ -127,34 +132,35 @@ struct mgmt_txrx_desc_elem_t *wlan_mgmt_txrx_desc_get(
 	mgmt_txrx_desc->in_use = true;
 
 	/* acquire the wakelock when there are pending mgmt tx frames */
-	qdf_wake_lock_timeout_acquire(&mgmt_txrx_ctx->wakelock_tx_cmp,
+	qdf_wake_lock_timeout_acquire(&mgmt_txrx_pdev_ctx->wakelock_tx_cmp,
 				      MGMT_TXRX_WAKELOCK_TIMEOUT_TX_CMP);
 
-	qdf_spin_unlock_bh(&mgmt_txrx_ctx->mgmt_desc_pool.desc_pool_lock);
+	qdf_spin_unlock_bh(&mgmt_txrx_pdev_ctx->mgmt_desc_pool.desc_pool_lock);
 
 	mgmt_txrx_info("retrieved mgmt desc: %pK with desc id: %d",
 			mgmt_txrx_desc, mgmt_txrx_desc->desc_id);
 	return mgmt_txrx_desc;
 }
 
-void wlan_mgmt_txrx_desc_put(struct mgmt_txrx_priv_context *mgmt_txrx_ctx,
+void wlan_mgmt_txrx_desc_put(
+			struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx,
 			uint32_t desc_id)
 {
 	struct mgmt_txrx_desc_elem_t *desc;
 
-	desc = &mgmt_txrx_ctx->mgmt_desc_pool.pool[desc_id];
-	qdf_spin_lock_bh(&mgmt_txrx_ctx->mgmt_desc_pool.desc_pool_lock);
+	desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[desc_id];
+	qdf_spin_lock_bh(&mgmt_txrx_pdev_ctx->mgmt_desc_pool.desc_pool_lock);
 	desc->in_use = false;
-	qdf_list_insert_front(&mgmt_txrx_ctx->mgmt_desc_pool.free_list,
+	qdf_list_insert_front(&mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list,
 			      &desc->entry);
 
 	/* release the wakelock if there are no pending mgmt tx frames */
-	if (mgmt_txrx_ctx->mgmt_desc_pool.free_list.count ==
-	    mgmt_txrx_ctx->mgmt_desc_pool.free_list.max_size)
-		qdf_wake_lock_release(&mgmt_txrx_ctx->wakelock_tx_cmp,
+	if (mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list.count ==
+	    mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list.max_size)
+		qdf_wake_lock_release(&mgmt_txrx_pdev_ctx->wakelock_tx_cmp,
 				      MGMT_TXRX_WAKELOCK_REASON_TX_CMP);
 
-	qdf_spin_unlock_bh(&mgmt_txrx_ctx->mgmt_desc_pool.desc_pool_lock);
+	qdf_spin_unlock_bh(&mgmt_txrx_pdev_ctx->mgmt_desc_pool.desc_pool_lock);
 
 	mgmt_txrx_info("put mgmt desc: %pK with desc id: %d into freelist",
 			desc, desc->desc_id);

+ 27 - 17
umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main_i.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -170,26 +170,35 @@ struct mgmt_txrx_stats_t {
 };
 
 /**
- * struct mgmt_txrx_priv_context - mgmt txrx private context
- * @psoc_context:     psoc context
- * @mgmt_rx_comp_cb:  array of pointers of mgmt rx cbs
+ * struct mgmt_txrx_priv_psoc_context - mgmt txrx private psoc context
+ * @psoc:                psoc context
+ * @mgmt_rx_comp_cb:     array of pointers of mgmt rx cbs
+ * @mgmt_txrx_psoc_ctx_lock:  mgmt txrx psoc ctx lock
+ */
+struct mgmt_txrx_priv_psoc_context {
+	struct wlan_objmgr_psoc *psoc;
+	struct mgmt_rx_handler *mgmt_rx_comp_cb[MGMT_MAX_FRAME_TYPE];
+	qdf_spinlock_t mgmt_txrx_psoc_ctx_lock;
+};
+
+/**
+ * struct mgmt_txrx_priv_context_dev - mgmt txrx private context
+ * @pdev:     pdev context
  * @mgmt_desc_pool:   pointer to mgmt desc. pool
  * @mgmt_txrx_stats:  pointer to mgmt txrx stats
  * @wakelock_tx_cmp:  mgmt tx complete wake lock
  */
-struct mgmt_txrx_priv_context {
-	struct wlan_objmgr_psoc *psoc;
-	struct mgmt_rx_handler *mgmt_rx_comp_cb[MGMT_MAX_FRAME_TYPE];
+struct mgmt_txrx_priv_pdev_context {
+	struct wlan_objmgr_pdev *pdev;
 	struct mgmt_desc_pool_t mgmt_desc_pool;
 	struct mgmt_txrx_stats_t *mgmt_txrx_stats;
-	qdf_spinlock_t mgmt_txrx_ctx_lock;
 	qdf_wake_lock_t wakelock_tx_cmp;
 };
 
 
 /**
  * wlan_mgmt_txrx_desc_pool_init() - initializes mgmt. desc. pool
- * @mgmt_txrx_ctx: mgmt txrx context
+ * @mgmt_txrx_pdev_ctx: mgmt txrx pdev context
  * @pool_size: desc. pool size
  *
  * This function initializes the mgmt descriptor pool.
@@ -197,23 +206,23 @@ struct mgmt_txrx_priv_context {
  * Return: QDF_STATUS_SUCCESS - in case of success
  */
 QDF_STATUS wlan_mgmt_txrx_desc_pool_init(
-			struct mgmt_txrx_priv_context *mgmt_txrx_ctx,
+			struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx,
 			uint32_t pool_size);
 
 /**
  * wlan_mgmt_txrx_desc_pool_deinit() - deinitializes mgmt. desc. pool
- * @mgmt_txrx_ctx: mgmt txrx context
+ * @mgmt_txrx_pdev_ctx: mgmt txrx pdev context
  *
  * This function deinitializes the mgmt descriptor pool.
  *
  * Return: void
  */
 void wlan_mgmt_txrx_desc_pool_deinit(
-			struct mgmt_txrx_priv_context *mgmt_txrx_ctx);
+			struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx);
 
 /**
  * wlan_mgmt_txrx_desc_get() - gets mgmt. descriptor from freelist
- * @mgmt_txrx_ctx: mgmt txrx context
+ * @mgmt_txrx_pdev_ctx: mgmt txrx pdev context
  *
  * This function retrieves the mgmt. descriptor for mgmt. tx frames
  * from the mgmt. descriptor freelist.
@@ -221,18 +230,19 @@ void wlan_mgmt_txrx_desc_pool_deinit(
  * Return: mgmt. descriptor retrieved.
  */
 struct mgmt_txrx_desc_elem_t *wlan_mgmt_txrx_desc_get(
-			struct mgmt_txrx_priv_context *mgmt_txrx_ctx);
+			struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx);
 
 /**
  * wlan_mgmt_txrx_desc_put() - puts mgmt. descriptor back in freelist
- * @mgmt_txrx_ctx: mgmt txrx context
+ * @mgmt_txrx_pdev_ctx: mgmt txrx pdev context
  * @desc_id: mgmt txrx descriptor id
  *
  * This function puts the mgmt. descriptor back in to the freelist.
  *
  * Return: void
  */
-void wlan_mgmt_txrx_desc_put(struct mgmt_txrx_priv_context *mgmt_txrx_ctx,
-			     uint32_t desc_id);
+void wlan_mgmt_txrx_desc_put(
+			struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx,
+			uint32_t desc_id);
 
 #endif

+ 20 - 9
umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_tgt_api.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -50,7 +50,7 @@ QDF_STATUS tgt_mgmt_txrx_rx_frame_handler(
 
 /**
  * tgt_mgmt_txrx_tx_completion_handler() - handles mgmt. tx completions
- * @psoc: psoc context
+ * @pdev: pdev context
  * @desc_id: mgmt desc. id
  * @status: status of download of tx packet
  * @tx_compl_params: tx completion params
@@ -62,13 +62,13 @@ QDF_STATUS tgt_mgmt_txrx_rx_frame_handler(
  * Return: QDF_STATUS_SUCCESS - in case of success
  */
 QDF_STATUS tgt_mgmt_txrx_tx_completion_handler(
-			struct wlan_objmgr_psoc *psoc,
+			struct wlan_objmgr_pdev *pdev,
 			uint32_t desc_id, uint32_t status,
 			void *tx_compl_params);
 
 /**
  * tgt_mgmt_txrx_get_nbuf_from_desc_id() - extracts nbuf from mgmt desc
- * @psoc: psoc context
+ * @pdev: pdev context
  * @desc_id: desc_id
  *
  * This function extracts nbuf from mgmt desc extracted from desc id.
@@ -77,12 +77,12 @@ QDF_STATUS tgt_mgmt_txrx_tx_completion_handler(
  *         NULL - in case of failure
  */
 qdf_nbuf_t tgt_mgmt_txrx_get_nbuf_from_desc_id(
-			struct wlan_objmgr_psoc *psoc,
+			struct wlan_objmgr_pdev *pdev,
 			uint32_t desc_id);
 
 /**
  * tgt_mgmt_txrx_get_peer_from_desc_id() - extracts peer from mgmt desc
- * @psoc: psoc context
+ * @pdev: pdev context
  * @desc_id: desc_id
  *
  * This function extracts peer from mgmt desc extracted from desc id.
@@ -92,12 +92,12 @@ qdf_nbuf_t tgt_mgmt_txrx_get_nbuf_from_desc_id(
  */
 struct wlan_objmgr_peer *
 tgt_mgmt_txrx_get_peer_from_desc_id(
-			struct wlan_objmgr_psoc *psoc,
+			struct wlan_objmgr_pdev *pdev,
 			uint32_t desc_id);
 
 /**
  * tgt_mgmt_txrx_get_vdev_id_from_desc_id() - extracts vdev id from mgmt desc
- * @psoc: psoc context
+ * @pdev: pdev context
  * @desc_id: desc_id
  *
  * This function extracts vdev id from mgmt desc extracted from desc id.
@@ -106,7 +106,18 @@ tgt_mgmt_txrx_get_peer_from_desc_id(
  *         WLAN_UMAC_VDEV_ID_MAX - in case of failure
  */
 uint8_t tgt_mgmt_txrx_get_vdev_id_from_desc_id(
-			struct wlan_objmgr_psoc *psoc,
+			struct wlan_objmgr_pdev *pdev,
 			uint32_t desc_id);
 
+/**
+ * tgt_mgmt_txrx_get_free_desc_pool_count() - get free mgmt desc count
+ * @pdev: pdev context
+ *
+ * This function returns the count of free mgmt descriptors.
+ *
+ * Return:  free descpriptor count
+ */
+uint32_t tgt_mgmt_txrx_get_free_desc_pool_count(
+			struct wlan_objmgr_pdev *pdev);
+
 #endif

+ 2 - 6
umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -30,11 +30,7 @@
 #include "wlan_objmgr_cmn.h"
 #include "qdf_nbuf.h"
 
-/**
- * Current HTC credit is 2 so pool size of 50 is sufficient as non
- * converged code will still be using similar implementation from WMA path
- */
-#define MGMT_DESC_POOL_MAX 50
+#define MGMT_DESC_POOL_MAX 512
 
 #define mgmt_txrx_log(level, args...) \
 			QDF_TRACE(QDF_MODULE_ID_MGMT_TXRX, level, ## args)

+ 71 - 48
umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -27,6 +27,7 @@
 #include "../../core/src/wlan_mgmt_txrx_main_i.h"
 #include "wlan_objmgr_psoc_obj.h"
 #include "wlan_objmgr_peer_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
 
 
 /**
@@ -809,7 +810,7 @@ QDF_STATUS tgt_mgmt_txrx_rx_frame_handler(
 			qdf_nbuf_t buf,
 			struct mgmt_rx_event_params *mgmt_rx_params)
 {
-	struct mgmt_txrx_priv_context *mgmt_txrx_ctx;
+	struct mgmt_txrx_priv_psoc_context *mgmt_txrx_psoc_ctx;
 	struct ieee80211_frame *wh;
 	qdf_nbuf_t copy_buf;
 	struct wlan_objmgr_peer *peer = NULL;
@@ -876,45 +877,46 @@ QDF_STATUS tgt_mgmt_txrx_rx_frame_handler(
 		goto dec_peer_ref_cnt;
 	}
 
-	mgmt_txrx_info("Rcvd mgmt frame, mgmt txrx frm type: %u, seq. no.: %u, peer: %pK",
+	mgmt_txrx_info("Rcvd mgmt frame, mgmt txrx frm type: %u"
+			"seq. no.: %u, peer: %pK",
 			frm_type, *(uint16_t *)wh->i_seq, peer);
 
-	mgmt_txrx_ctx = (struct mgmt_txrx_priv_context *)
+	mgmt_txrx_psoc_ctx = (struct mgmt_txrx_priv_psoc_context *)
 			wlan_objmgr_psoc_get_comp_private_obj(psoc,
 				WLAN_UMAC_COMP_MGMT_TXRX);
 
-	qdf_spin_lock_bh(&mgmt_txrx_ctx->mgmt_txrx_ctx_lock);
-	rx_handler = mgmt_txrx_ctx->mgmt_rx_comp_cb[frm_type];
+	qdf_spin_lock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
+	rx_handler = mgmt_txrx_psoc_ctx->mgmt_rx_comp_cb[frm_type];
 	if (rx_handler) {
 		status = wlan_mgmt_txrx_rx_handler_list_copy(rx_handler,
 				&rx_handler_head, &rx_handler_tail);
 		if (status != QDF_STATUS_SUCCESS) {
-			qdf_spin_unlock_bh(&mgmt_txrx_ctx->mgmt_txrx_ctx_lock);
+			qdf_spin_unlock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
 			qdf_nbuf_free(buf);
 			goto rx_handler_mem_free;
 		}
 	}
 
-	rx_handler = mgmt_txrx_ctx->mgmt_rx_comp_cb[MGMT_FRAME_TYPE_ALL];
+	rx_handler = mgmt_txrx_psoc_ctx->mgmt_rx_comp_cb[MGMT_FRAME_TYPE_ALL];
 	if (rx_handler) {
 		status = wlan_mgmt_txrx_rx_handler_list_copy(rx_handler,
 				&rx_handler_head, &rx_handler_tail);
 		if (status != QDF_STATUS_SUCCESS) {
-			qdf_spin_unlock_bh(&mgmt_txrx_ctx->mgmt_txrx_ctx_lock);
+			qdf_spin_unlock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
 			qdf_nbuf_free(buf);
 			goto rx_handler_mem_free;
 		}
 	}
 
 	if (!rx_handler_head) {
-		qdf_spin_unlock_bh(&mgmt_txrx_ctx->mgmt_txrx_ctx_lock);
+		qdf_spin_unlock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
 		mgmt_txrx_info("No rx callback registered for frm_type: %d",
 			frm_type);
 		qdf_nbuf_free(buf);
 		status = QDF_STATUS_E_FAILURE;
 		goto dec_peer_ref_cnt;
 	}
-	qdf_spin_unlock_bh(&mgmt_txrx_ctx->mgmt_txrx_ctx_lock);
+	qdf_spin_unlock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
 
 	rx_handler = rx_handler_head;
 	while (rx_handler->next) {
@@ -940,28 +942,28 @@ dec_peer_ref_cnt:
 }
 
 QDF_STATUS tgt_mgmt_txrx_tx_completion_handler(
-			struct wlan_objmgr_psoc *psoc,
+			struct wlan_objmgr_pdev *pdev,
 			uint32_t desc_id, uint32_t status,
 			void *tx_compl_params)
 {
-	struct mgmt_txrx_priv_context *mgmt_txrx_ctx;
+	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
 	struct mgmt_txrx_desc_elem_t *mgmt_desc;
 	void *cb_context;
 	mgmt_tx_download_comp_cb tx_compl_cb;
 	mgmt_ota_comp_cb  ota_comp_cb;
 	qdf_nbuf_t nbuf;
 
-	mgmt_txrx_ctx = (struct mgmt_txrx_priv_context *)
-			wlan_objmgr_psoc_get_comp_private_obj(psoc,
+	mgmt_txrx_pdev_ctx = (struct mgmt_txrx_priv_pdev_context *)
+			wlan_objmgr_pdev_get_comp_private_obj(pdev,
 				WLAN_UMAC_COMP_MGMT_TXRX);
-	if (!mgmt_txrx_ctx) {
-		mgmt_txrx_err("Mgmt txrx context empty for psoc %pK", psoc);
+	if (!mgmt_txrx_pdev_ctx) {
+		mgmt_txrx_err("Mgmt txrx context empty for pdev %pK", pdev);
 		return QDF_STATUS_E_NULL_VALUE;
 	}
-	mgmt_desc = &mgmt_txrx_ctx->mgmt_desc_pool.pool[desc_id];
+	mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[desc_id];
 	if (!mgmt_desc) {
-		mgmt_txrx_err("Mgmt desc empty for id %d psoc %pK ",
-				desc_id, psoc);
+		mgmt_txrx_err("Mgmt desc empty for id %d pdev %pK ",
+				desc_id, pdev);
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 	tx_compl_cb = mgmt_desc->tx_dwnld_cmpl_cb;
@@ -1006,29 +1008,29 @@ no_registered_cb:
 	 * accessing peer in wlan_mgmt_txrx_mgmt_frame_tx
 	 */
 	wlan_objmgr_peer_release_ref(mgmt_desc->peer, WLAN_MGMT_SB_ID);
-	wlan_mgmt_txrx_desc_put(mgmt_txrx_ctx, desc_id);
+	wlan_mgmt_txrx_desc_put(mgmt_txrx_pdev_ctx, desc_id);
 	return QDF_STATUS_SUCCESS;
 }
 
 qdf_nbuf_t tgt_mgmt_txrx_get_nbuf_from_desc_id(
-			struct wlan_objmgr_psoc *psoc,
+			struct wlan_objmgr_pdev *pdev,
 			uint32_t desc_id)
 {
-	struct mgmt_txrx_priv_context *mgmt_txrx_ctx;
+	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
 	struct mgmt_txrx_desc_elem_t *mgmt_desc;
 	qdf_nbuf_t buf;
 
-	mgmt_txrx_ctx = (struct mgmt_txrx_priv_context *)
-			wlan_objmgr_psoc_get_comp_private_obj(psoc,
+	mgmt_txrx_pdev_ctx = (struct mgmt_txrx_priv_pdev_context *)
+			wlan_objmgr_pdev_get_comp_private_obj(pdev,
 				WLAN_UMAC_COMP_MGMT_TXRX);
-	if (!mgmt_txrx_ctx) {
-		mgmt_txrx_err("Mgmt txrx context empty for psoc %pK", psoc);
+	if (!mgmt_txrx_pdev_ctx) {
+		mgmt_txrx_err("Mgmt txrx context empty for pdev %pK", pdev);
 		goto fail;
 	}
-	mgmt_desc = &mgmt_txrx_ctx->mgmt_desc_pool.pool[desc_id];
+	mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[desc_id];
 	if (!mgmt_desc) {
-		mgmt_txrx_err("Mgmt descriptor unavailable for id %d psoc %pK",
-				desc_id, psoc);
+		mgmt_txrx_err("Mgmt descriptor unavailable for id %d pdev %pK",
+				desc_id, pdev);
 		goto fail;
 	}
 	buf = mgmt_desc->nbuf;
@@ -1040,25 +1042,25 @@ fail:
 
 struct wlan_objmgr_peer *
 tgt_mgmt_txrx_get_peer_from_desc_id(
-			struct wlan_objmgr_psoc *psoc,
+			struct wlan_objmgr_pdev *pdev,
 			uint32_t desc_id)
 {
-	struct mgmt_txrx_priv_context *mgmt_txrx_ctx;
+	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
 	struct mgmt_txrx_desc_elem_t *mgmt_desc;
 	struct wlan_objmgr_peer *peer;
 
-	mgmt_txrx_ctx = (struct mgmt_txrx_priv_context *)
-			wlan_objmgr_psoc_get_comp_private_obj(psoc,
+	mgmt_txrx_pdev_ctx = (struct mgmt_txrx_priv_pdev_context *)
+			wlan_objmgr_pdev_get_comp_private_obj(pdev,
 				WLAN_UMAC_COMP_MGMT_TXRX);
-	if (!mgmt_txrx_ctx) {
-		mgmt_txrx_err("Mgmt txrx context empty for psoc %pK", psoc);
+	if (!mgmt_txrx_pdev_ctx) {
+		mgmt_txrx_err("Mgmt txrx context empty for pdev %pK", pdev);
 		goto fail;
 	}
 
-	mgmt_desc = &mgmt_txrx_ctx->mgmt_desc_pool.pool[desc_id];
+	mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[desc_id];
 	if (!mgmt_desc) {
-		mgmt_txrx_err("Mgmt descriptor unavailable for id %d psoc %pK",
-				desc_id, psoc);
+		mgmt_txrx_err("Mgmt descriptor unavailable for id %d pdev %pK",
+				desc_id, pdev);
 		goto fail;
 	}
 
@@ -1070,25 +1072,25 @@ fail:
 }
 
 uint8_t tgt_mgmt_txrx_get_vdev_id_from_desc_id(
-			struct wlan_objmgr_psoc *psoc,
+			struct wlan_objmgr_pdev *pdev,
 			uint32_t desc_id)
 {
-	struct mgmt_txrx_priv_context *mgmt_txrx_ctx;
+	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
 	struct mgmt_txrx_desc_elem_t *mgmt_desc;
 	uint8_t vdev_id;
 
-	mgmt_txrx_ctx = (struct mgmt_txrx_priv_context *)
-			wlan_objmgr_psoc_get_comp_private_obj(psoc,
+	mgmt_txrx_pdev_ctx = (struct mgmt_txrx_priv_pdev_context *)
+			wlan_objmgr_pdev_get_comp_private_obj(pdev,
 				WLAN_UMAC_COMP_MGMT_TXRX);
-	if (!mgmt_txrx_ctx) {
-		mgmt_txrx_err("Mgmt txrx context empty for psoc %pK", psoc);
+	if (!mgmt_txrx_pdev_ctx) {
+		mgmt_txrx_err("Mgmt txrx context empty for pdev %pK", pdev);
 		goto fail;
 	}
 
-	mgmt_desc = &mgmt_txrx_ctx->mgmt_desc_pool.pool[desc_id];
+	mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[desc_id];
 	if (!mgmt_desc) {
-		mgmt_txrx_err("Mgmt descriptor unavailable for id %d psoc %pK",
-				desc_id, psoc);
+		mgmt_txrx_err("Mgmt descriptor unavailable for id %d pdev %pK",
+				desc_id, pdev);
 		goto fail;
 	}
 
@@ -1098,3 +1100,24 @@ uint8_t tgt_mgmt_txrx_get_vdev_id_from_desc_id(
 fail:
 	return WLAN_UMAC_VDEV_ID_MAX;
 }
+
+uint32_t tgt_mgmt_txrx_get_free_desc_pool_count(
+			struct wlan_objmgr_pdev *pdev)
+{
+	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
+	uint32_t free_desc_count = WLAN_INVALID_MGMT_DESC_COUNT;
+
+	mgmt_txrx_pdev_ctx = (struct mgmt_txrx_priv_pdev_context *)
+			wlan_objmgr_pdev_get_comp_private_obj(pdev,
+			WLAN_UMAC_COMP_MGMT_TXRX);
+	if (!mgmt_txrx_pdev_ctx) {
+		mgmt_txrx_err("Mgmt txrx context empty for pdev %pK", pdev);
+		goto fail;
+	}
+
+	free_desc_count = qdf_list_size(
+		&(mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list));
+
+fail:
+	return free_desc_count;
+}

+ 271 - 102
umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -46,46 +46,29 @@ static QDF_STATUS wlan_mgmt_txrx_psoc_obj_create_notification(
 			struct wlan_objmgr_psoc *psoc,
 			void *arg)
 {
-	struct mgmt_txrx_priv_context *mgmt_txrx_ctx;
-	struct mgmt_txrx_stats_t *mgmt_txrx_stats;
+	struct mgmt_txrx_priv_psoc_context *mgmt_txrx_psoc_ctx;
 	QDF_STATUS status;
 
 	if (!psoc) {
 		mgmt_txrx_err("psoc context passed is NULL");
-		return QDF_STATUS_E_INVAL;
+		status = QDF_STATUS_E_INVAL;
+		goto err_return;
 	}
 
-	mgmt_txrx_ctx = qdf_mem_malloc(sizeof(*mgmt_txrx_ctx));
-	if (!mgmt_txrx_ctx) {
+	mgmt_txrx_psoc_ctx = qdf_mem_malloc(sizeof(*mgmt_txrx_psoc_ctx));
+	if (!mgmt_txrx_psoc_ctx) {
 		mgmt_txrx_err("Failed to allocate mgmt txrx context");
-		return QDF_STATUS_E_NOMEM;
-	}
-
-	mgmt_txrx_ctx->psoc = psoc;
-
-	status = wlan_mgmt_txrx_desc_pool_init(mgmt_txrx_ctx,
-					       MGMT_DESC_POOL_MAX);
-	if (status != QDF_STATUS_SUCCESS) {
-		mgmt_txrx_err("Failed to initialize mgmt desc. pool with status: %u",
-				status);
-		goto err_desc_pool_init;
-	}
-
-	mgmt_txrx_stats = qdf_mem_malloc(sizeof(*mgmt_txrx_stats));
-	if (!mgmt_txrx_stats) {
-		mgmt_txrx_err("Failed to allocate memory for mgmt txrx stats structure");
 		status = QDF_STATUS_E_NOMEM;
-		goto err_mgmt_txrx_stats;
+		goto err_return;
 	}
-	mgmt_txrx_ctx->mgmt_txrx_stats = mgmt_txrx_stats;
 
-	qdf_spinlock_create(&mgmt_txrx_ctx->mgmt_txrx_ctx_lock);
-	qdf_wake_lock_create(&mgmt_txrx_ctx->wakelock_tx_cmp,
-			     "mgmt_txrx tx_cmp");
+	mgmt_txrx_psoc_ctx->psoc = psoc;
+
+	qdf_spinlock_create(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
 
 	if (wlan_objmgr_psoc_component_obj_attach(psoc,
 				WLAN_UMAC_COMP_MGMT_TXRX,
-				mgmt_txrx_ctx, QDF_STATUS_SUCCESS)
+				mgmt_txrx_psoc_ctx, QDF_STATUS_SUCCESS)
 			!= QDF_STATUS_SUCCESS) {
 		mgmt_txrx_err("Failed to attach mgmt txrx ctx in psoc ctx");
 		status = QDF_STATUS_E_FAILURE;
@@ -93,18 +76,14 @@ static QDF_STATUS wlan_mgmt_txrx_psoc_obj_create_notification(
 	}
 
 	mgmt_txrx_info("Mgmt txrx creation successful, mgmt txrx ctx: %pK, psoc: %pK",
-			mgmt_txrx_ctx, psoc);
+			mgmt_txrx_psoc_ctx, psoc);
 
 	return QDF_STATUS_SUCCESS;
 
 err_psoc_attach:
-	qdf_spinlock_destroy(&mgmt_txrx_ctx->mgmt_txrx_ctx_lock);
-	qdf_wake_lock_destroy(&mgmt_txrx_ctx->wakelock_tx_cmp);
-	qdf_mem_free(mgmt_txrx_stats);
-err_mgmt_txrx_stats:
-	wlan_mgmt_txrx_desc_pool_deinit(mgmt_txrx_ctx);
-err_desc_pool_init:
-	qdf_mem_free(mgmt_txrx_ctx);
+	qdf_spinlock_destroy(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
+	qdf_mem_free(mgmt_txrx_psoc_ctx);
+err_return:
 	return status;
 }
 
@@ -123,40 +102,168 @@ static QDF_STATUS wlan_mgmt_txrx_psoc_obj_destroy_notification(
 			struct wlan_objmgr_psoc *psoc,
 			void *arg)
 {
-	struct mgmt_txrx_priv_context *mgmt_txrx_ctx;
+	struct mgmt_txrx_priv_psoc_context *mgmt_txrx_psoc_ctx;
 
 	if (!psoc) {
 		mgmt_txrx_err("psoc context passed is NULL");
 		return QDF_STATUS_E_INVAL;
 	}
 
-	mgmt_txrx_ctx = wlan_objmgr_psoc_get_comp_private_obj(
+	mgmt_txrx_psoc_ctx = wlan_objmgr_psoc_get_comp_private_obj(
 			psoc, WLAN_UMAC_COMP_MGMT_TXRX);
-	if (!mgmt_txrx_ctx) {
+	if (!mgmt_txrx_psoc_ctx) {
 		mgmt_txrx_err("mgmt txrx context is already NULL");
 		return QDF_STATUS_E_FAILURE;
 	}
 
 	mgmt_txrx_info("deleting mgmt txrx psoc obj, mgmt txrx ctx: %pK, psoc: %pK",
-			mgmt_txrx_ctx, psoc);
+			mgmt_txrx_psoc_ctx, psoc);
 	if (wlan_objmgr_psoc_component_obj_detach(psoc,
-				WLAN_UMAC_COMP_MGMT_TXRX, mgmt_txrx_ctx)
+				WLAN_UMAC_COMP_MGMT_TXRX, mgmt_txrx_psoc_ctx)
 			!= QDF_STATUS_SUCCESS) {
 		mgmt_txrx_err("Failed to detach mgmt txrx ctx in psoc ctx");
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	wlan_mgmt_txrx_desc_pool_deinit(mgmt_txrx_ctx);
-	qdf_mem_free(mgmt_txrx_ctx->mgmt_txrx_stats);
-	qdf_spinlock_destroy(&mgmt_txrx_ctx->mgmt_txrx_ctx_lock);
-	qdf_wake_lock_destroy(&mgmt_txrx_ctx->wakelock_tx_cmp);
-	qdf_mem_free(mgmt_txrx_ctx);
+	qdf_spinlock_destroy(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
+	qdf_mem_free(mgmt_txrx_psoc_ctx);
 
 	mgmt_txrx_info("mgmt txrx deletion successful, psoc: %pK", psoc);
 
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * wlan_mgmt_txrx_pdev_obj_create_notification() - called from objmgr when pdev
+ *                                                 is created
+ * @pdev: pdev context
+ * @arg: argument
+ *
+ * This function gets called from object manager when pdev is being created and
+ * creates mgmt_txrx context, mgmt desc pool.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+static QDF_STATUS wlan_mgmt_txrx_pdev_obj_create_notification(
+			struct wlan_objmgr_pdev *pdev,
+			void *arg)
+{
+	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
+	struct mgmt_txrx_stats_t *mgmt_txrx_stats;
+	QDF_STATUS status;
+
+	if (!pdev) {
+		mgmt_txrx_err("pdev context passed is NULL");
+		status = QDF_STATUS_E_INVAL;
+		goto err_return;
+
+	}
+
+	mgmt_txrx_pdev_ctx = qdf_mem_malloc(sizeof(*mgmt_txrx_pdev_ctx));
+	if (!mgmt_txrx_pdev_ctx) {
+		mgmt_txrx_err("Failed to allocate mgmt txrx context");
+		status = QDF_STATUS_E_NOMEM;
+		goto err_return;
+	}
+
+	mgmt_txrx_pdev_ctx->pdev = pdev;
+
+	status = wlan_mgmt_txrx_desc_pool_init(mgmt_txrx_pdev_ctx,
+					       MGMT_DESC_POOL_MAX);
+	if (status != QDF_STATUS_SUCCESS) {
+		mgmt_txrx_err(
+			"Failed to initialize mgmt desc. pool with status: %u",
+			status);
+		goto err_desc_pool_init;
+	}
+
+	mgmt_txrx_stats = qdf_mem_malloc(sizeof(*mgmt_txrx_stats));
+	if (!mgmt_txrx_stats) {
+		mgmt_txrx_err(
+			"Failed to allocate memory for mgmt txrx stats structure");
+		status = QDF_STATUS_E_NOMEM;
+		goto err_mgmt_txrx_stats;
+	}
+	mgmt_txrx_pdev_ctx->mgmt_txrx_stats = mgmt_txrx_stats;
+
+	qdf_wake_lock_create(&mgmt_txrx_pdev_ctx->wakelock_tx_cmp,
+			     "mgmt_txrx tx_cmp");
+
+	if (wlan_objmgr_pdev_component_obj_attach(pdev,
+			WLAN_UMAC_COMP_MGMT_TXRX,
+			mgmt_txrx_pdev_ctx, QDF_STATUS_SUCCESS)
+			!= QDF_STATUS_SUCCESS) {
+		mgmt_txrx_err("Failed to attach mgmt txrx ctx in pdev ctx");
+		status = QDF_STATUS_E_FAILURE;
+		goto err_pdev_attach;
+	}
+
+	mgmt_txrx_info(
+		"Mgmt txrx creation successful, mgmt txrx ctx: %pK, pdev: %pK",
+		mgmt_txrx_pdev_ctx, pdev);
+
+	return QDF_STATUS_SUCCESS;
+
+err_pdev_attach:
+	qdf_wake_lock_destroy(&mgmt_txrx_pdev_ctx->wakelock_tx_cmp);
+	qdf_mem_free(mgmt_txrx_stats);
+err_mgmt_txrx_stats:
+	wlan_mgmt_txrx_desc_pool_deinit(mgmt_txrx_pdev_ctx);
+err_desc_pool_init:
+	qdf_mem_free(mgmt_txrx_pdev_ctx);
+err_return:
+	return status;
+}
+
+/**
+ * wlan_mgmt_txrx_pdev_obj_destroy_notification() - called from objmgr when
+ *                                                  pdev is destroyed
+ * @pdev: pdev context
+ * @arg: argument
+ *
+ * This function gets called from object manager when pdev is being destroyed
+ * pdev deletes mgmt_txrx context, mgmt desc pool.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+static QDF_STATUS wlan_mgmt_txrx_pdev_obj_destroy_notification(
+			struct wlan_objmgr_pdev *pdev,
+			void *arg)
+{
+	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
+
+	if (!pdev) {
+		mgmt_txrx_err("pdev context passed is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	mgmt_txrx_pdev_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_MGMT_TXRX);
+	if (!mgmt_txrx_pdev_ctx) {
+		mgmt_txrx_err("mgmt txrx context is already NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	mgmt_txrx_info("deleting mgmt txrx pdev obj, mgmt txrx ctx: %pK, pdev: %pK",
+			mgmt_txrx_pdev_ctx, pdev);
+	if (wlan_objmgr_pdev_component_obj_detach(pdev,
+				WLAN_UMAC_COMP_MGMT_TXRX, mgmt_txrx_pdev_ctx)
+			!= QDF_STATUS_SUCCESS) {
+		mgmt_txrx_err("Failed to detach mgmt txrx ctx in pdev ctx");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wlan_mgmt_txrx_desc_pool_deinit(mgmt_txrx_pdev_ctx);
+	qdf_mem_free(mgmt_txrx_pdev_ctx->mgmt_txrx_stats);
+	qdf_wake_lock_destroy(&mgmt_txrx_pdev_ctx->wakelock_tx_cmp);
+	qdf_mem_free(mgmt_txrx_pdev_ctx);
+
+	mgmt_txrx_info("mgmt txrx deletion successful, pdev: %pK", pdev);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+
 QDF_STATUS wlan_mgmt_txrx_init(void)
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
@@ -166,7 +273,7 @@ QDF_STATUS wlan_mgmt_txrx_init(void)
 				wlan_mgmt_txrx_psoc_obj_create_notification,
 				NULL);
 	if (status != QDF_STATUS_SUCCESS) {
-		mgmt_txrx_err("Failed to register mgmt txrx obj create handler");
+		mgmt_txrx_err("Failed to register mgmt txrx psoc create handler");
 		goto err_psoc_create;
 	}
 
@@ -175,13 +282,37 @@ QDF_STATUS wlan_mgmt_txrx_init(void)
 				wlan_mgmt_txrx_psoc_obj_destroy_notification,
 				NULL);
 	if (status != QDF_STATUS_SUCCESS) {
-		mgmt_txrx_err("Failed to register mgmt txrx obj destroy handler");
+		mgmt_txrx_err("Failed to register mgmt txrx psoc destroy handler");
 		goto err_psoc_delete;
 	}
 
+	status = wlan_objmgr_register_pdev_create_handler(
+				WLAN_UMAC_COMP_MGMT_TXRX,
+				wlan_mgmt_txrx_pdev_obj_create_notification,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		mgmt_txrx_err("Failed to register mgmt txrx pdev obj create handler");
+		goto err_pdev_create;
+	}
+
+	status = wlan_objmgr_register_pdev_destroy_handler(
+				WLAN_UMAC_COMP_MGMT_TXRX,
+				wlan_mgmt_txrx_pdev_obj_destroy_notification,
+				NULL);
+	if (status != QDF_STATUS_SUCCESS) {
+		mgmt_txrx_err("Failed to register mgmt txrx obj destroy handler");
+		goto err_pdev_delete;
+	}
+
 	mgmt_txrx_info("Successfully registered create and destroy handlers with objmgr");
 	return QDF_STATUS_SUCCESS;
 
+err_pdev_delete:
+	wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_MGMT_TXRX,
+			wlan_mgmt_txrx_pdev_obj_create_notification, NULL);
+err_pdev_create:
+	wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_MGMT_TXRX,
+			wlan_mgmt_txrx_psoc_obj_destroy_notification, NULL);
 err_psoc_delete:
 	wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_MGMT_TXRX,
 			wlan_mgmt_txrx_psoc_obj_create_notification, NULL);
@@ -206,6 +337,22 @@ QDF_STATUS wlan_mgmt_txrx_deinit(void)
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	if (wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_MGMT_TXRX,
+				wlan_mgmt_txrx_pdev_obj_create_notification,
+				NULL)
+			!= QDF_STATUS_SUCCESS) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (wlan_objmgr_unregister_pdev_destroy_handler(
+				WLAN_UMAC_COMP_MGMT_TXRX,
+				wlan_mgmt_txrx_pdev_obj_destroy_notification,
+				NULL)
+			!= QDF_STATUS_SUCCESS) {
+		return QDF_STATUS_E_FAILURE;
+	}
+
+
 	mgmt_txrx_info("Successfully unregistered create and destroy handlers with objmgr");
 	return QDF_STATUS_SUCCESS;
 }
@@ -220,7 +367,8 @@ QDF_STATUS wlan_mgmt_txrx_mgmt_frame_tx(struct wlan_objmgr_peer *peer,
 {
 	struct mgmt_txrx_desc_elem_t *desc;
 	struct wlan_objmgr_psoc *psoc;
-	struct mgmt_txrx_priv_context *txrx_ctx;
+	struct wlan_objmgr_pdev *pdev;
+	struct mgmt_txrx_priv_pdev_context *txrx_ctx;
 	struct wlan_objmgr_vdev *vdev;
 
 	if (!peer) {
@@ -245,12 +393,20 @@ QDF_STATUS wlan_mgmt_txrx_mgmt_frame_tx(struct wlan_objmgr_peer *peer,
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 
-	txrx_ctx = (struct mgmt_txrx_priv_context *)
-			wlan_objmgr_psoc_get_comp_private_obj(psoc,
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		mgmt_txrx_err("pdev unavailable for peer %pK vdev %pK",
+				peer, vdev);
+		wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_SB_ID);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	txrx_ctx = (struct mgmt_txrx_priv_pdev_context *)
+			wlan_objmgr_pdev_get_comp_private_obj(pdev,
 				WLAN_UMAC_COMP_MGMT_TXRX);
 	if (!txrx_ctx) {
-		mgmt_txrx_err("No txrx context for peer %pK psoc %pK",
-				peer, psoc);
+		mgmt_txrx_err("No txrx context for peer %pK pdev %pK",
+				peer, pdev);
 		wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_SB_ID);
 		return QDF_STATUS_E_NULL_VALUE;
 	}
@@ -269,7 +425,8 @@ QDF_STATUS wlan_mgmt_txrx_mgmt_frame_tx(struct wlan_objmgr_peer *peer,
 	desc->context = context;
 
 	if (!psoc->soc_cb.tx_ops.mgmt_txrx_tx_ops.mgmt_tx_send) {
-		mgmt_txrx_err("mgmt txrx tx op to send mgmt frame is NULL for psoc: %pK",
+		mgmt_txrx_err(
+				"mgmt txrx txop to send mgmt frame is NULL for psoc: %pK",
 				psoc);
 		wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_SB_ID);
 		desc->nbuf = NULL;
@@ -279,8 +436,8 @@ QDF_STATUS wlan_mgmt_txrx_mgmt_frame_tx(struct wlan_objmgr_peer *peer,
 
 	if (psoc->soc_cb.tx_ops.mgmt_txrx_tx_ops.mgmt_tx_send(
 			vdev, buf, desc->desc_id, mgmt_tx_params)) {
-		mgmt_txrx_err("Mgmt send fail for peer %pK psoc %pK",
-				peer, psoc);
+		mgmt_txrx_err("Mgmt send fail for peer %pK psoc %pK pdev: %pK",
+				peer, psoc, pdev);
 		wlan_objmgr_peer_release_ref(peer, WLAN_MGMT_SB_ID);
 		desc->nbuf = NULL;
 		wlan_mgmt_txrx_desc_put(txrx_ctx, desc->desc_id);
@@ -324,7 +481,7 @@ QDF_STATUS wlan_mgmt_txrx_beacon_frame_tx(struct wlan_objmgr_peer *peer,
 
 /**
  * wlan_mgmt_txrx_create_rx_handler() - creates rx handler node for umac comp.
- * @mgmt_txrx_ctx: mgmt txrx context
+ * @mgmt_txrx_psoc_ctx: mgmt txrx context
  * @mgmt_rx_cb: mgmt rx callback to be registered
  * @comp_id: umac component id
  * @frm_type: mgmt. frame for which cb to be registered.
@@ -335,7 +492,7 @@ QDF_STATUS wlan_mgmt_txrx_beacon_frame_tx(struct wlan_objmgr_peer *peer,
  * Return: QDF_STATUS_SUCCESS - in case of success
  */
 static QDF_STATUS wlan_mgmt_txrx_create_rx_handler(
-				struct mgmt_txrx_priv_context *mgmt_txrx_ctx,
+				struct mgmt_txrx_priv_psoc_context *mgmt_txrx_psoc_ctx,
 				mgmt_frame_rx_callback mgmt_rx_cb,
 				enum wlan_umac_comp_id comp_id,
 				enum mgmt_frame_type frm_type)
@@ -351,10 +508,10 @@ static QDF_STATUS wlan_mgmt_txrx_create_rx_handler(
 	rx_handler->comp_id = comp_id;
 	rx_handler->rx_cb = mgmt_rx_cb;
 
-	qdf_spin_lock_bh(&mgmt_txrx_ctx->mgmt_txrx_ctx_lock);
-	rx_handler->next = mgmt_txrx_ctx->mgmt_rx_comp_cb[frm_type];
-	mgmt_txrx_ctx->mgmt_rx_comp_cb[frm_type] = rx_handler;
-	qdf_spin_unlock_bh(&mgmt_txrx_ctx->mgmt_txrx_ctx_lock);
+	qdf_spin_lock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
+	rx_handler->next = mgmt_txrx_psoc_ctx->mgmt_rx_comp_cb[frm_type];
+	mgmt_txrx_psoc_ctx->mgmt_rx_comp_cb[frm_type] = rx_handler;
+	qdf_spin_unlock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
 
 	mgmt_txrx_info("Callback registered for comp_id: %d, frm_type: %d",
 			comp_id, frm_type);
@@ -363,7 +520,7 @@ static QDF_STATUS wlan_mgmt_txrx_create_rx_handler(
 
 /**
  * wlan_mgmt_txrx_delete_rx_handler() - deletes rx handler node for umac comp.
- * @mgmt_txrx_ctx: mgmt txrx context
+ * @mgmt_txrx_psoc_ctx: mgmt txrx context
  * @mgmt_rx_cb: mgmt rx callback to be deregistered
  * @comp_id: umac component id
  * @frm_type: mgmt. frame for which cb to be registered.
@@ -374,16 +531,16 @@ static QDF_STATUS wlan_mgmt_txrx_create_rx_handler(
  * Return: QDF_STATUS_SUCCESS - in case of success
  */
 static QDF_STATUS wlan_mgmt_txrx_delete_rx_handler(
-				struct mgmt_txrx_priv_context *mgmt_txrx_ctx,
-				mgmt_frame_rx_callback mgmt_rx_cb,
-				enum wlan_umac_comp_id comp_id,
-				enum mgmt_frame_type frm_type)
+		struct mgmt_txrx_priv_psoc_context *mgmt_txrx_psoc_ctx,
+		mgmt_frame_rx_callback mgmt_rx_cb,
+		enum wlan_umac_comp_id comp_id,
+		enum mgmt_frame_type frm_type)
 {
-	struct mgmt_rx_handler *rx_handler, *rx_handler_prev = NULL;
+	struct mgmt_rx_handler *rx_handler = NULL, *rx_handler_prev = NULL;
 	bool delete = false;
 
-	qdf_spin_lock_bh(&mgmt_txrx_ctx->mgmt_txrx_ctx_lock);
-	rx_handler = mgmt_txrx_ctx->mgmt_rx_comp_cb[frm_type];
+	qdf_spin_lock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
+	rx_handler = mgmt_txrx_psoc_ctx->mgmt_rx_comp_cb[frm_type];
 	while (rx_handler) {
 		if (rx_handler->comp_id == comp_id &&
 				rx_handler->rx_cb == mgmt_rx_cb) {
@@ -391,7 +548,7 @@ static QDF_STATUS wlan_mgmt_txrx_delete_rx_handler(
 				rx_handler_prev->next =
 					rx_handler->next;
 			else
-				mgmt_txrx_ctx->mgmt_rx_comp_cb[frm_type] =
+				mgmt_txrx_psoc_ctx->mgmt_rx_comp_cb[frm_type] =
 					rx_handler->next;
 
 			qdf_mem_free(rx_handler);
@@ -402,7 +559,7 @@ static QDF_STATUS wlan_mgmt_txrx_delete_rx_handler(
 		rx_handler_prev = rx_handler;
 		rx_handler = rx_handler->next;
 	}
-	qdf_spin_unlock_bh(&mgmt_txrx_ctx->mgmt_txrx_ctx_lock);
+	qdf_spin_unlock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
 
 	if (!delete) {
 		mgmt_txrx_err("No callback registered for comp_id: %d, frm_type: %d",
@@ -421,7 +578,7 @@ QDF_STATUS wlan_mgmt_txrx_register_rx_cb(
 			struct mgmt_txrx_mgmt_frame_cb_info *frm_cb_info,
 			uint8_t num_entries)
 {
-	struct mgmt_txrx_priv_context *mgmt_txrx_ctx;
+	struct mgmt_txrx_priv_psoc_context *mgmt_txrx_psoc_ctx;
 	QDF_STATUS status;
 	uint8_t i, j;
 
@@ -446,22 +603,22 @@ QDF_STATUS wlan_mgmt_txrx_register_rx_cb(
 		return QDF_STATUS_E_INVAL;
 	}
 
-	mgmt_txrx_ctx = (struct mgmt_txrx_priv_context *)
+	mgmt_txrx_psoc_ctx = (struct mgmt_txrx_priv_psoc_context *)
 			wlan_objmgr_psoc_get_comp_private_obj(psoc,
 				WLAN_UMAC_COMP_MGMT_TXRX);
-	if (!mgmt_txrx_ctx) {
+	if (!mgmt_txrx_psoc_ctx) {
 		mgmt_txrx_err("mgmt txrx context is NULL");
 		return QDF_STATUS_E_FAILURE;
 	}
 
 	for (i = 0; i < num_entries; i++) {
-		status = wlan_mgmt_txrx_create_rx_handler(mgmt_txrx_ctx,
+		status = wlan_mgmt_txrx_create_rx_handler(mgmt_txrx_psoc_ctx,
 				frm_cb_info[i].mgmt_rx_cb, comp_id,
 				frm_cb_info[i].frm_type);
 		if (status != QDF_STATUS_SUCCESS) {
 			for (j = 0; j < i; j++) {
 				wlan_mgmt_txrx_delete_rx_handler(
-					mgmt_txrx_ctx,
+					mgmt_txrx_psoc_ctx,
 					frm_cb_info[j].mgmt_rx_cb,
 					comp_id, frm_cb_info[j].frm_type);
 			}
@@ -478,7 +635,7 @@ QDF_STATUS wlan_mgmt_txrx_deregister_rx_cb(
 			struct mgmt_txrx_mgmt_frame_cb_info *frm_cb_info,
 			uint8_t num_entries)
 {
-	struct mgmt_txrx_priv_context *mgmt_txrx_ctx;
+	struct mgmt_txrx_priv_psoc_context *mgmt_txrx_psoc_ctx;
 	uint8_t i;
 
 	if (!psoc) {
@@ -502,16 +659,16 @@ QDF_STATUS wlan_mgmt_txrx_deregister_rx_cb(
 		return QDF_STATUS_E_INVAL;
 	}
 
-	mgmt_txrx_ctx = (struct mgmt_txrx_priv_context *)
+	mgmt_txrx_psoc_ctx = (struct mgmt_txrx_priv_psoc_context *)
 			wlan_objmgr_psoc_get_comp_private_obj(psoc,
 				WLAN_UMAC_COMP_MGMT_TXRX);
-	if (!mgmt_txrx_ctx) {
+	if (!mgmt_txrx_psoc_ctx) {
 		mgmt_txrx_err("mgmt txrx context is NULL");
 		return QDF_STATUS_E_FAILURE;
 	}
 
 	for (i = 0; i < num_entries; i++) {
-		wlan_mgmt_txrx_delete_rx_handler(mgmt_txrx_ctx,
+		wlan_mgmt_txrx_delete_rx_handler(mgmt_txrx_psoc_ctx,
 				frm_cb_info[i].mgmt_rx_cb, comp_id,
 				frm_cb_info[i].frm_type);
 	}
@@ -526,41 +683,53 @@ QDF_STATUS wlan_mgmt_txrx_psoc_open(struct wlan_objmgr_psoc *psoc)
 
 QDF_STATUS wlan_mgmt_txrx_psoc_close(struct wlan_objmgr_psoc *psoc)
 {
-	struct mgmt_txrx_priv_context *mgmt_txrx_ctx;
+	struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx;
 	struct mgmt_txrx_desc_elem_t *mgmt_desc;
-	uint8_t i;
+	uint16_t i;
 	uint32_t pool_size;
+	uint8_t pdev_count, index;
+	struct wlan_objmgr_pdev *pdev;
 
 	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,
+	pdev_count = wlan_psoc_get_pdev_count(psoc);
+
+	for (index = 0; index < pdev_count; index++) {
+		pdev = psoc->soc_objmgr.wlan_pdev_list[index];
+
+		if (!pdev) {
+			mgmt_txrx_err("pdev context is NULL");
+			return QDF_STATUS_E_INVAL;
+		}
+		mgmt_txrx_pdev_ctx = (struct mgmt_txrx_priv_pdev_context *)
+			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");
+		if (!mgmt_txrx_pdev_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;
-	}
+		pool_size = mgmt_txrx_pdev_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,
+		for (i = 0; i < pool_size; i++) {
+			if (mgmt_txrx_pdev_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_pdev_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);
+				wlan_mgmt_txrx_desc_put(mgmt_txrx_pdev_ctx, i);
+			}
 		}
 	}
-
 	return QDF_STATUS_SUCCESS;
 }

+ 2 - 2
umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -1724,7 +1724,7 @@ void wlan_objmgr_psoc_release_ref(struct wlan_objmgr_psoc *psoc,
 						wlan_objmgr_ref_dbgid id)
 {
 	if (psoc == NULL) {
-		obj_mgr_err("psoc obj is NULLi for id:%d", id);
+		obj_mgr_err("psoc obj is NULL for id:%d", id);
 		QDF_ASSERT(0);
 		return;
 	}

+ 67 - 24
umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_api.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
@@ -22,6 +22,7 @@
 
 #include "wlan_objmgr_cmn.h"
 #include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
 
 /**
  * wlan_lmac_if_umac_rx_ops_register() - UMAC rx handler register
@@ -102,7 +103,7 @@ wlan_lmac_if_get_reg_rx_ops(struct wlan_objmgr_psoc *psoc)
 
 /**
  * mgmt_txrx_get_nbuf() - retrieve nbuf from mgmt desc_id
- * @psoc: psoc context
+ * @pdev: pdev context
  * @desc_id: mgmt desc_id
  *
  * API to retrieve the nbuf from mgmt desc_id
@@ -110,12 +111,16 @@ wlan_lmac_if_get_reg_rx_ops(struct wlan_objmgr_psoc *psoc)
  * Return: nbuf
  */
 static inline qdf_nbuf_t
-mgmt_txrx_get_nbuf(struct wlan_objmgr_psoc *psoc, uint32_t desc_id)
+mgmt_txrx_get_nbuf(struct wlan_objmgr_pdev *pdev, uint32_t desc_id)
 {
-	struct wlan_lmac_if_mgmt_txrx_rx_ops *mgmt_rx_ops =
-				wlan_lmac_if_get_mgmt_txrx_rx_ops(psoc);
+	struct wlan_lmac_if_mgmt_txrx_rx_ops *mgmt_rx_ops;
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	mgmt_rx_ops = wlan_lmac_if_get_mgmt_txrx_rx_ops(psoc);
+
 	if (mgmt_rx_ops && mgmt_rx_ops->mgmt_txrx_get_nbuf_from_desc_id)
-		return mgmt_rx_ops->mgmt_txrx_get_nbuf_from_desc_id(psoc,
+		return mgmt_rx_ops->mgmt_txrx_get_nbuf_from_desc_id(pdev,
 								     desc_id);
 
 	return NULL;
@@ -123,7 +128,7 @@ mgmt_txrx_get_nbuf(struct wlan_objmgr_psoc *psoc, uint32_t desc_id)
 
 /**
  * mgmt_txrx_tx_completion_handler() - mgmt tx completion handler
- * @psoc: psoc context
+ * @pdev: pdev context
  * @desc_id: mgmt desc_id
  * @status: tx status
  * @params: tx params
@@ -133,18 +138,22 @@ mgmt_txrx_get_nbuf(struct wlan_objmgr_psoc *psoc, uint32_t desc_id)
  * Return: QDF_STATUS_SUCCESS - in case of success
  */
 static inline QDF_STATUS
-mgmt_txrx_tx_completion_handler(struct wlan_objmgr_psoc *psoc,
+mgmt_txrx_tx_completion_handler(struct wlan_objmgr_pdev *pdev,
 				uint32_t desc_id, uint32_t status,
 				void *params)
 {
+	struct wlan_lmac_if_mgmt_txrx_rx_ops *mgmt_rx_ops;
+	struct wlan_objmgr_psoc *psoc;
 	qdf_nbuf_t nbuf;
-	struct wlan_lmac_if_mgmt_txrx_rx_ops *mgmt_rx_ops =
-				wlan_lmac_if_get_mgmt_txrx_rx_ops(psoc);
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	mgmt_rx_ops = wlan_lmac_if_get_mgmt_txrx_rx_ops(psoc);
+
 	if (mgmt_rx_ops && mgmt_rx_ops->mgmt_tx_completion_handler)
-		return mgmt_rx_ops->mgmt_tx_completion_handler(psoc, desc_id,
+		return mgmt_rx_ops->mgmt_tx_completion_handler(pdev, desc_id,
 							status, params);
 
-	nbuf = mgmt_txrx_get_nbuf(psoc, desc_id);
+	nbuf = mgmt_txrx_get_nbuf(pdev, desc_id);
 	if (nbuf)
 		qdf_nbuf_free(nbuf);
 
@@ -165,8 +174,10 @@ static inline QDF_STATUS
 mgmt_txrx_rx_handler(struct wlan_objmgr_psoc *psoc, qdf_nbuf_t nbuf,
 			void *params)
 {
-	struct wlan_lmac_if_mgmt_txrx_rx_ops *mgmt_rx_ops =
-				wlan_lmac_if_get_mgmt_txrx_rx_ops(psoc);
+	struct wlan_lmac_if_mgmt_txrx_rx_ops *mgmt_rx_ops;
+
+	mgmt_rx_ops = wlan_lmac_if_get_mgmt_txrx_rx_ops(psoc);
+
 	if (mgmt_rx_ops && mgmt_rx_ops->mgmt_rx_frame_handler)
 		return mgmt_rx_ops->mgmt_rx_frame_handler(psoc, nbuf, params);
 
@@ -178,7 +189,7 @@ mgmt_txrx_rx_handler(struct wlan_objmgr_psoc *psoc, qdf_nbuf_t nbuf,
 
 /**
  * mgmt_txrx_get_peer() - retrieve peer from mgmt desc_id
- * @psoc: psoc context
+ * @pdev: pdev context
  * @desc_id: mgmt desc_id
  *
  * API to retrieve the peer from mgmt desc_id
@@ -186,12 +197,16 @@ mgmt_txrx_rx_handler(struct wlan_objmgr_psoc *psoc, qdf_nbuf_t nbuf,
  * Return: objmgr peer pointer
  */
 static inline struct wlan_objmgr_peer *
-mgmt_txrx_get_peer(struct wlan_objmgr_psoc *psoc, uint32_t desc_id)
+mgmt_txrx_get_peer(struct wlan_objmgr_pdev *pdev, uint32_t desc_id)
 {
-	struct wlan_lmac_if_mgmt_txrx_rx_ops *mgmt_rx_ops =
-				wlan_lmac_if_get_mgmt_txrx_rx_ops(psoc);
+	struct wlan_lmac_if_mgmt_txrx_rx_ops *mgmt_rx_ops;
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	mgmt_rx_ops = wlan_lmac_if_get_mgmt_txrx_rx_ops(psoc);
+
 	if (mgmt_rx_ops && mgmt_rx_ops->mgmt_txrx_get_peer_from_desc_id)
-		return mgmt_rx_ops->mgmt_txrx_get_peer_from_desc_id(psoc,
+		return mgmt_rx_ops->mgmt_txrx_get_peer_from_desc_id(pdev,
 								     desc_id);
 
 	return NULL;
@@ -199,7 +214,7 @@ mgmt_txrx_get_peer(struct wlan_objmgr_psoc *psoc, uint32_t desc_id)
 
 /**
  * mgmt_txrx_get_vdev_id() - retrieve vdev_id from mgmt desc_id
- * @psoc: psoc context
+ * @pdev: pdev context
  * @desc_id: mgmt desc_id
  *
  * API to retrieve the vdev_id from mgmt desc_id
@@ -207,14 +222,42 @@ mgmt_txrx_get_peer(struct wlan_objmgr_psoc *psoc, uint32_t desc_id)
  * Return: vdev_id
  */
 static inline uint8_t
-mgmt_txrx_get_vdev_id(struct wlan_objmgr_psoc *psoc, uint32_t desc_id)
+mgmt_txrx_get_vdev_id(struct wlan_objmgr_pdev *pdev, uint32_t desc_id)
 {
-	struct wlan_lmac_if_mgmt_txrx_rx_ops *mgmt_rx_ops =
-				wlan_lmac_if_get_mgmt_txrx_rx_ops(psoc);
+	struct wlan_lmac_if_mgmt_txrx_rx_ops *mgmt_rx_ops;
+	struct wlan_objmgr_psoc *psoc;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	mgmt_rx_ops = wlan_lmac_if_get_mgmt_txrx_rx_ops(psoc);
+
 	if (mgmt_rx_ops && mgmt_rx_ops->mgmt_txrx_get_vdev_id_from_desc_id)
-		return mgmt_rx_ops->mgmt_txrx_get_vdev_id_from_desc_id(psoc,
+		return mgmt_rx_ops->mgmt_txrx_get_vdev_id_from_desc_id(pdev,
 								   desc_id);
 
 	return WLAN_UMAC_VDEV_ID_MAX;
 }
+/**
+ * mgmt_txrx_get_free_desc_count() - retrieve vdev_id from mgmt desc_id
+ * @pdev: pdev context
+ *
+ * API to get the free desc count mgmt desc pool
+ *
+ * Return: free_desc_count
+ */
+static inline uint32_t
+mgmt_txrx_get_free_desc_count(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_lmac_if_mgmt_txrx_rx_ops *mgmt_rx_ops;
+	struct wlan_objmgr_psoc *psoc;
+	uint32_t free_desc_count = WLAN_INVALID_MGMT_DESC_COUNT;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	mgmt_rx_ops = wlan_lmac_if_get_mgmt_txrx_rx_ops(psoc);
+
+	if (mgmt_rx_ops && mgmt_rx_ops->mgmt_txrx_get_free_desc_pool_count)
+		free_desc_count = mgmt_rx_ops->mgmt_txrx_get_free_desc_pool_count(
+						pdev);
+
+	return free_desc_count;
+}
 #endif /* _WLAN_LMAC_IF_API_H */

+ 7 - 5
umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
@@ -606,7 +606,7 @@ struct wlan_lmac_if_tx_ops {
  */
 struct wlan_lmac_if_mgmt_txrx_rx_ops {
 	QDF_STATUS (*mgmt_tx_completion_handler)(
-			struct wlan_objmgr_psoc *psoc,
+			struct wlan_objmgr_pdev *pdev,
 			uint32_t desc_id, uint32_t status,
 			void *tx_compl_params);
 	QDF_STATUS (*mgmt_rx_frame_handler)(
@@ -614,13 +614,15 @@ struct wlan_lmac_if_mgmt_txrx_rx_ops {
 			qdf_nbuf_t buf,
 			struct mgmt_rx_event_params *mgmt_rx_params);
 	qdf_nbuf_t (*mgmt_txrx_get_nbuf_from_desc_id)(
-			struct wlan_objmgr_psoc *psoc,
+			struct wlan_objmgr_pdev *pdev,
 			uint32_t desc_id);
 	struct wlan_objmgr_peer * (*mgmt_txrx_get_peer_from_desc_id)(
-			struct wlan_objmgr_psoc *psoc, uint32_t desc_id);
+			struct wlan_objmgr_pdev *pdev, uint32_t desc_id);
 	uint8_t (*mgmt_txrx_get_vdev_id_from_desc_id)(
-			struct wlan_objmgr_psoc *psoc,
+			struct wlan_objmgr_pdev *pdev,
 			uint32_t desc_id);
+	uint32_t (*mgmt_txrx_get_free_desc_pool_count)(
+			struct wlan_objmgr_pdev *pdev);
 };
 
 struct wlan_lmac_if_reg_rx_ops {

+ 3 - 1
umac/global_umac_dispatcher/lmac_if/src/wlan_lmac_if.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
@@ -321,6 +321,8 @@ wlan_lmac_if_umac_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops)
 			tgt_mgmt_txrx_get_peer_from_desc_id;
 	mgmt_txrx_rx_ops->mgmt_txrx_get_vdev_id_from_desc_id =
 			tgt_mgmt_txrx_get_vdev_id_from_desc_id;
+	mgmt_txrx_rx_ops->mgmt_txrx_get_free_desc_pool_count =
+			tgt_mgmt_txrx_get_free_desc_pool_count;
 
 	/* scan rx ops */
 	rx_ops->scan.scan_ev_handler = tgt_scan_event_handler;