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
Цей коміт міститься в:
Nirav Shah
2016-04-25 10:50:37 +05:30
зафіксовано Gerrit - the friendly Code Review server
джерело 617cff9d7f
коміт 76291969a5
5 змінених файлів з 136 додано та 1 видалено

Переглянути файл

@@ -122,6 +122,7 @@ struct ol_tx_desc_t *ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev,
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 @@ struct ol_tx_desc_t *ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev,
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 @@ void ol_tx_desc_free(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc)
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 @@ void ol_tx_desc_free(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc)
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 @@ struct ol_tx_desc_t *ol_tx_desc_ll(struct ol_txrx_pdev_t *pdev,
}
/* 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,

Переглянути файл

@@ -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 @@ static inline int ol_tx_free_invalid_flow_pool(void *pool)
}
#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_ */

Переглянути файл

@@ -548,6 +548,8 @@ ol_txrx_pdev_post_attach(ol_txrx_pdev_handle pdev)
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 @@ void ol_txrx_pdev_detach(ol_txrx_pdev_handle pdev, int force)
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);

Переглянути файл

@@ -564,6 +564,9 @@ struct ol_txrx_pdev_t {
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;