qcacmn: Add RXDMA_DST ring support

Setup & process the RXDMA_DST ring to handle error frames
from RXDMA block. Pro-active fix to handle the WAR for
the WBM stuck issue seen when sending RX_FLUSH command.

Change-Id: Ibf56062da2cd9b5d447f1d43bbae5944426d88c8
CRs-Fixed: 2059870
This commit is contained in:
Pramod Simha
2017-06-05 18:09:26 -07:00
parent a0e6f88b15
commit e382ff88b9
6 changed files with 201 additions and 0 deletions

View File

@@ -316,6 +316,10 @@ int htt_srng_setup(void *htt_soc, int mac_id, void *hal_srng,
htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING; htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING;
htt_ring_type = HTT_SW_TO_HW_RING; htt_ring_type = HTT_SW_TO_HW_RING;
break; break;
case RXDMA_DST:
htt_ring_id = HTT_RXDMA_NON_MONITOR_DEST_RING;
htt_ring_type = HTT_HW_TO_SW_RING;
break;
default: default:
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
@@ -544,6 +548,10 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng,
htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING; htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING;
htt_ring_type = HTT_SW_TO_HW_RING; htt_ring_type = HTT_SW_TO_HW_RING;
break; break;
case RXDMA_DST:
htt_ring_id = HTT_RXDMA_NON_MONITOR_DEST_RING;
htt_ring_type = HTT_HW_TO_SW_RING;
break;
default: default:
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,

View File

@@ -330,6 +330,13 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
dp_mon_process(soc, ring, budget); dp_mon_process(soc, ring, budget);
budget -= work_done; budget -= work_done;
} }
if (int_ctx->rxdma2host_ring_mask & (1 << ring)) {
work_done =
dp_rxdma_err_process(soc, ring, budget);
budget -= work_done;
}
} }
qdf_lro_flush(int_ctx->lro_ctx); qdf_lro_flush(int_ctx->lro_ctx);
@@ -871,6 +878,7 @@ static void dp_hw_link_desc_pool_cleanup(struct dp_soc *soc)
#define RXDMA_MONITOR_DST_RING_SIZE 1024 #define RXDMA_MONITOR_DST_RING_SIZE 1024
#define RXDMA_MONITOR_STATUS_RING_SIZE 1024 #define RXDMA_MONITOR_STATUS_RING_SIZE 1024
#define RXDMA_MONITOR_DESC_RING_SIZE 1024 #define RXDMA_MONITOR_DESC_RING_SIZE 1024
#define RXDMA_ERR_DST_RING_SIZE 1024
/* /*
* dp_soc_cmn_setup() - Common SoC level initializion * dp_soc_cmn_setup() - Common SoC level initializion
@@ -1301,6 +1309,13 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc,
goto fail1; goto fail1;
} }
if (dp_srng_setup(soc, &pdev->rxdma_err_dst_ring, RXDMA_DST, 0,
pdev_id, RXDMA_ERR_DST_RING_SIZE)) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
FL("dp_srng_setup failed for rxdma_mon_dst_ring"));
goto fail1;
}
/* Rx specific init */ /* Rx specific init */
if (dp_rx_pdev_attach(pdev)) { if (dp_rx_pdev_attach(pdev)) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
@@ -1438,6 +1453,8 @@ static void dp_pdev_detach_wifi3(struct cdp_pdev *txrx_pdev, int force)
dp_srng_cleanup(soc, &pdev->rxdma_mon_desc_ring, dp_srng_cleanup(soc, &pdev->rxdma_mon_desc_ring,
RXDMA_MONITOR_DESC, 0); RXDMA_MONITOR_DESC, 0);
dp_srng_cleanup(soc, &pdev->rxdma_err_dst_ring, RXDMA_DST, 0);
soc->pdev_list[pdev->pdev_id] = NULL; soc->pdev_list[pdev->pdev_id] = NULL;
soc->pdev_count--; soc->pdev_count--;
wlan_cfg_pdev_detach(pdev->wlan_cfg_ctx); wlan_cfg_pdev_detach(pdev->wlan_cfg_ctx);
@@ -1633,6 +1650,10 @@ static void dp_rxdma_ring_config(struct dp_soc *soc)
htt_srng_setup(soc->htt_handle, i, htt_srng_setup(soc->htt_handle, i,
pdev->rxdma_mon_desc_ring.hal_srng, pdev->rxdma_mon_desc_ring.hal_srng,
RXDMA_MONITOR_DESC); RXDMA_MONITOR_DESC);
htt_srng_setup(soc->htt_handle, i,
pdev->rxdma_err_dst_ring.hal_srng,
RXDMA_DST);
} }
} }
} }
@@ -1660,6 +1681,9 @@ static void dp_rxdma_ring_config(struct dp_soc *soc)
htt_srng_setup(soc->htt_handle, i, htt_srng_setup(soc->htt_handle, i,
pdev->rxdma_mon_desc_ring.hal_srng, pdev->rxdma_mon_desc_ring.hal_srng,
RXDMA_MONITOR_DESC); RXDMA_MONITOR_DESC);
htt_srng_setup(soc->htt_handle, i,
pdev->rxdma_err_dst_ring.hal_srng,
RXDMA_DST);
} }
} }
} }

View File

@@ -582,4 +582,9 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
QDF_STATUS QDF_STATUS
dp_rx_link_desc_buf_return(struct dp_soc *soc, struct dp_srng *dp_rxdma_srng, dp_rx_link_desc_buf_return(struct dp_soc *soc, struct dp_srng *dp_rxdma_srng,
void *buf_addr_info); void *buf_addr_info);
uint32_t
dp_rxdma_err_process(struct dp_soc *soc, uint32_t mac_id,
uint32_t quota);
#endif /* _DP_RX_H */ #endif /* _DP_RX_H */

View File

@@ -813,3 +813,161 @@ done:
return rx_bufs_reaped; /* Assume no scale factor for now */ return rx_bufs_reaped; /* Assume no scale factor for now */
} }
/**
* dp_rx_err_mpdu_pop() - extract the MSDU's from link descs
*
* @soc: core DP main context
* @mac_id: mac id which is one of 3 mac_ids
* @rxdma_dst_ring_desc: void pointer to monitor link descriptor buf addr info
* @head: head of descs list to be freed
* @tail: tail of decs list to be freed
* Return: number of msdu in MPDU to be popped
*/
static inline uint32_t
dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
void *rxdma_dst_ring_desc,
union dp_rx_desc_list_elem_t **head,
union dp_rx_desc_list_elem_t **tail)
{
void *rx_msdu_link_desc;
qdf_nbuf_t msdu;
qdf_nbuf_t last;
struct hal_rx_msdu_list msdu_list;
uint8_t num_msdus;
struct hal_buf_info buf_info;
void *p_buf_addr_info;
void *p_last_buf_addr_info;
uint32_t rx_bufs_used = 0;
uint32_t msdu_cnt;
uint32_t i;
bool mpdu_err;
msdu = 0;
last = NULL;
hal_rx_reo_ent_buf_paddr_get(rxdma_dst_ring_desc, &buf_info,
&p_last_buf_addr_info, &msdu_cnt, &mpdu_err);
do {
rx_msdu_link_desc =
dp_rx_cookie_2_link_desc_va(soc, &buf_info);
qdf_assert(rx_msdu_link_desc);
num_msdus = (msdu_cnt > HAL_RX_NUM_MSDU_DESC)?
HAL_RX_NUM_MSDU_DESC:msdu_cnt;
hal_rx_msdu_list_get(rx_msdu_link_desc, &msdu_list, num_msdus);
msdu_cnt -= num_msdus;
for (i = 0; i < num_msdus; i++) {
struct dp_rx_desc *rx_desc =
dp_rx_cookie_2_va_rxdma_buf(soc,
msdu_list.sw_cookie[i]);
qdf_assert(rx_desc);
msdu = rx_desc->nbuf;
qdf_nbuf_unmap_single(soc->osdev, msdu,
QDF_DMA_FROM_DEVICE);
QDF_TRACE(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_DEBUG,
"[%s][%d] msdu_nbuf=%p \n",
__func__, __LINE__, msdu);
qdf_nbuf_free(msdu);
rx_bufs_used++;
dp_rx_add_to_free_desc_list(head,
tail, rx_desc);
}
hal_rx_mon_next_link_desc_get(rx_msdu_link_desc, &buf_info,
&p_buf_addr_info);
dp_rx_link_desc_return(soc, p_last_buf_addr_info);
p_last_buf_addr_info = p_buf_addr_info;
} while (buf_info.paddr && msdu_cnt);
return rx_bufs_used;
}
/**
* dp_rxdma_err_process() - RxDMA error processing functionality
*
* @soc: core txrx main contex
* @mac_id: mac id which is one of 3 mac_ids
* @hal_ring: opaque pointer to the HAL Rx Ring, which will be serviced
* @quota: No. of units (packets) that can be serviced in one shot.
* Return: num of buffers processed
*/
uint32_t
dp_rxdma_err_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota)
{
struct dp_pdev *pdev = soc->pdev_list[mac_id];
uint8_t pdev_id;
void *hal_soc;
void *rxdma_dst_ring_desc;
void *err_dst_srng;
union dp_rx_desc_list_elem_t *head = NULL;
union dp_rx_desc_list_elem_t *tail = NULL;
struct dp_srng *dp_rxdma_srng;
struct rx_desc_pool *rx_desc_pool;
uint32_t work_done = 0;
uint32_t rx_bufs_used = 0;
#ifdef DP_INTR_POLL_BASED
if (!pdev)
return 0;
#endif
pdev_id = pdev->pdev_id;
err_dst_srng = pdev->rxdma_err_dst_ring.hal_srng;
if (!err_dst_srng) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
"%s %d : HAL Monitor Destination Ring Init \
Failed -- %p\n",
__func__, __LINE__, err_dst_srng);
return 0;
}
hal_soc = soc->hal_soc;
qdf_assert(hal_soc);
if (qdf_unlikely(hal_srng_access_start(hal_soc, err_dst_srng))) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
"%s %d : HAL Monitor Destination Ring Init \
Failed -- %p\n",
__func__, __LINE__, err_dst_srng);
return 0;
}
while (qdf_likely((rxdma_dst_ring_desc =
hal_srng_dst_get_next(hal_soc, err_dst_srng)) && quota--)) {
rx_bufs_used += dp_rx_err_mpdu_pop(soc, mac_id,
rxdma_dst_ring_desc,
&head, &tail);
}
hal_srng_access_end(hal_soc, err_dst_srng);
if (rx_bufs_used) {
dp_rxdma_srng = &pdev->rx_refill_buf_ring;
rx_desc_pool = &soc->rx_desc_buf[mac_id];
dp_rx_buffers_replenish(soc, pdev_id, dp_rxdma_srng,
rx_desc_pool, rx_bufs_used, &head, &tail,
HAL_RX_BUF_RBM_SW3_BM);
work_done += rx_bufs_used;
}
return work_done;
}

View File

@@ -48,4 +48,7 @@ QDF_STATUS dp_rx_pdev_mon_status_detach(struct dp_pdev *pdev);
uint32_t dp_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota); uint32_t dp_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota);
QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id, QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id,
qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu); qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu);
uint32_t dp_rxdma_err_process(struct dp_soc *soc, uint32_t mac_id,
uint32_t quota);
#endif #endif

View File

@@ -723,6 +723,9 @@ struct dp_pdev {
struct dp_srng rxdma_mon_desc_ring; struct dp_srng rxdma_mon_desc_ring;
/* RXDMA error destination ring */
struct dp_srng rxdma_err_dst_ring;
/* Link descriptor memory banks */ /* Link descriptor memory banks */
struct { struct {
void *base_vaddr_unaligned; void *base_vaddr_unaligned;