qcacld-3.0: Add logic in host to detect msdu_id duplication
Add logic in host to detect if host is using
musdu_id which is already in use.
CRs-Fixed: 929428
Change-Id: I10413ed4b5b76e16211aa0cbb9012cfb8f26cae0
diff --git a/Kbuild b/Kbuild
index f2764c9..1503d74 100755
--- a/Kbuild
+++ b/Kbuild
@@ -1117,6 +1117,10 @@
CDEFINES += -DWLAN_FEATURE_LPSS
endif
+ifneq ($(TARGET_BUILD_VARIANT),user)
+CDEFINES += -DDESC_DUP_DETECT_DEBUG
+endif
+
ifeq ($(PANIC_ON_BUG),1)
CDEFINES += -DPANIC_ON_BUG
endif
diff --git a/core/dp/txrx/ol_tx_desc.c b/core/dp/txrx/ol_tx_desc.c
index 4708461..152beec 100644
--- a/core/dp/txrx/ol_tx_desc.c
+++ b/core/dp/txrx/ol_tx_desc.c
@@ -122,6 +122,7 @@
qdf_spin_lock_bh(&pdev->tx_mutex);
if (pdev->tx_desc.freelist) {
tx_desc = ol_tx_get_desc_global_pool(pdev);
+ ol_tx_desc_dup_detect_set(pdev, tx_desc);
ol_tx_desc_sanity_checks(pdev, tx_desc);
ol_tx_desc_compute_delay(tx_desc);
}
@@ -165,6 +166,7 @@
qdf_spin_lock_bh(&pool->flow_pool_lock);
if (pool->avail_desc) {
tx_desc = ol_tx_get_desc_flow_pool(pool);
+ ol_tx_desc_dup_detect_set(pdev, tx_desc);
if (qdf_unlikely(pool->avail_desc < pool->stop_th)) {
pool->status = FLOW_POOL_ACTIVE_PAUSED;
qdf_spin_unlock_bh(&pool->flow_pool_lock);
@@ -239,6 +241,7 @@
ol_tso_free_segment(pdev, tx_desc->tso_desc);
}
}
+ ol_tx_desc_dup_detect_reset(pdev, tx_desc);
ol_tx_desc_reset_pkt_type(tx_desc);
ol_tx_desc_reset_timestamp(tx_desc);
@@ -271,6 +274,7 @@
ol_tx_desc_reset_timestamp(tx_desc);
qdf_spin_lock_bh(&pool->flow_pool_lock);
+ ol_tx_desc_dup_detect_reset(pdev, tx_desc);
ol_tx_put_desc_flow_pool(pool, tx_desc);
switch (pool->status) {
case FLOW_POOL_ACTIVE_PAUSED:
@@ -366,7 +370,6 @@
}
/* initialize the HW tx descriptor */
-
htt_tx_desc_init(pdev->htt_pdev, tx_desc->htt_tx_desc,
tx_desc->htt_tx_desc_paddr,
ol_tx_desc_id(pdev, tx_desc), netbuf, &msdu_info->htt,
diff --git a/core/dp/txrx/ol_tx_desc.h b/core/dp/txrx/ol_tx_desc.h
index 9b0cf42..ed72650 100644
--- a/core/dp/txrx/ol_tx_desc.h
+++ b/core/dp/txrx/ol_tx_desc.h
@@ -37,6 +37,11 @@
#include <cdp_txrx_cmn.h> /* ol_txrx_vdev_t, etc. */
#include <ol_txrx_internal.h> /*TXRX_ASSERT2 */
+#define DIV_BY_8 3
+#define DIV_BY_32 5
+#define MOD_BY_8 0x7
+#define MOD_BY_32 0x1F
+
struct ol_tx_desc_t *
ol_tx_desc_alloc_wrapper(struct ol_txrx_pdev_t *pdev,
struct ol_txrx_vdev_t *vdev,
@@ -253,4 +258,120 @@
}
#endif
+#ifdef DESC_DUP_DETECT_DEBUG
+/**
+ * ol_tx_desc_dup_detect_init() - initialize descriptor duplication logic
+ * @pdev: pdev handle
+ * @pool_size: global pool size
+ *
+ * Return: none
+ */
+static inline
+void ol_tx_desc_dup_detect_init(struct ol_txrx_pdev_t *pdev, uint16_t pool_size)
+{
+ uint16_t size = (pool_size >> DIV_BY_8) +
+ ((pool_size & MOD_BY_8) ? 1 : 0);
+ pdev->tx_desc.free_list_bitmap = qdf_mem_malloc(size);
+ if (!pdev->tx_desc.free_list_bitmap)
+ qdf_print("%s: malloc failed", __func__);
+}
+
+/**
+ * ol_tx_desc_dup_detect_deinit() - deinit descriptor duplication logic
+ * @pdev: pdev handle
+ *
+ * Return: none
+ */
+static inline
+void ol_tx_desc_dup_detect_deinit(struct ol_txrx_pdev_t *pdev)
+{
+ qdf_print("%s: pool_size %d num_free %d\n", __func__,
+ pdev->tx_desc.pool_size, pdev->tx_desc.num_free);
+ if (pdev->tx_desc.free_list_bitmap)
+ qdf_mem_free(pdev->tx_desc.free_list_bitmap);
+}
+
+/**
+ * ol_tx_desc_dup_detect_set() - set bit for msdu_id
+ * @pdev: pdev handle
+ * @tx_desc: tx descriptor
+ *
+ * Return: none
+ */
+static inline
+void ol_tx_desc_dup_detect_set(struct ol_txrx_pdev_t *pdev,
+ struct ol_tx_desc_t *tx_desc)
+{
+ uint16_t msdu_id = ol_tx_desc_id(pdev, tx_desc);
+ uint16_t index = msdu_id >> DIV_BY_32;
+ uint8_t pos = msdu_id & MOD_BY_32;
+
+ if (!pdev->tx_desc.free_list_bitmap)
+ return;
+
+ if (qdf_unlikely(pdev->tx_desc.free_list_bitmap[index] & (1 << pos))) {
+ uint16_t size = (pdev->tx_desc.pool_size >> DIV_BY_8) +
+ ((pdev->tx_desc.pool_size & MOD_BY_8) ? 1 : 0);
+ qdf_print("duplicate msdu_id %d detected !!\n", msdu_id);
+ qdf_trace_hex_dump(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+ (void *)pdev->tx_desc.free_list_bitmap, size);
+ QDF_BUG(0);
+ }
+ pdev->tx_desc.free_list_bitmap[index] |= (1 << pos);
+}
+
+/**
+ * ol_tx_desc_dup_detect_reset() - reset bit for msdu_id
+ * @pdev: pdev handle
+ * @tx_desc: tx descriptor
+ *
+ * Return: none
+ */
+static inline
+void ol_tx_desc_dup_detect_reset(struct ol_txrx_pdev_t *pdev,
+ struct ol_tx_desc_t *tx_desc)
+{
+ uint16_t msdu_id = ol_tx_desc_id(pdev, tx_desc);
+ uint16_t index = msdu_id >> DIV_BY_32;
+ uint8_t pos = msdu_id & MOD_BY_32;
+
+ if (!pdev->tx_desc.free_list_bitmap)
+ return;
+
+ if (qdf_unlikely(!
+ (pdev->tx_desc.free_list_bitmap[index] & (1 << pos)))) {
+ uint16_t size = (pdev->tx_desc.pool_size >> DIV_BY_8) +
+ ((pdev->tx_desc.pool_size & MOD_BY_8) ? 1 : 0);
+ qdf_print("duplicate free msg received for msdu_id %d!!\n",
+ msdu_id);
+ qdf_trace_hex_dump(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+ (void *)pdev->tx_desc.free_list_bitmap, size);
+ QDF_BUG(0);
+ }
+ pdev->tx_desc.free_list_bitmap[index] &= ~(1 << pos);
+}
+#else
+static inline
+void ol_tx_desc_dup_detect_init(struct ol_txrx_pdev_t *pdev, uint16_t size)
+{
+}
+
+static inline
+void ol_tx_desc_dup_detect_deinit(struct ol_txrx_pdev_t *pdev)
+{
+}
+
+static inline
+void ol_tx_desc_dup_detect_set(struct ol_txrx_pdev_t *pdev,
+ struct ol_tx_desc_t *tx_desc)
+{
+}
+
+static inline
+void ol_tx_desc_dup_detect_reset(struct ol_txrx_pdev_t *pdev,
+ struct ol_tx_desc_t *tx_desc)
+{
+}
+#endif
+
#endif /* _OL_TX_DESC__H_ */
diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c
index 7c9c94c..a3bd7be 100644
--- a/core/dp/txrx/ol_txrx.c
+++ b/core/dp/txrx/ol_txrx.c
@@ -548,6 +548,8 @@
desc_pool_size = ol_tx_get_desc_global_pool_size(pdev);
+ ol_tx_desc_dup_detect_init(pdev, desc_pool_size);
+
setup_fastpath_ce_handles(osc, pdev);
ret = htt_attach(pdev->htt_pdev, desc_pool_size);
@@ -1081,6 +1083,8 @@
htt_detach(pdev->htt_pdev);
htt_pdev_free(pdev->htt_pdev);
+ ol_tx_desc_dup_detect_deinit(pdev);
+
ol_txrx_peer_find_detach(pdev);
qdf_spinlock_destroy(&pdev->tx_mutex);
diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h
index 87e4ac8..ff36e19 100644
--- a/core/dp/txrx/ol_txrx_types.h
+++ b/core/dp/txrx/ol_txrx_types.h
@@ -564,6 +564,9 @@
uint8_t page_divider;
uint32_t offset_filter;
struct qdf_mem_multi_page_t desc_pages;
+#ifdef DESC_DUP_DETECT_DEBUG
+ uint32_t *free_list_bitmap;
+#endif
} tx_desc;
uint8_t is_mgmt_over_wmi_enabled;