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:
@@ -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,
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user