qcacmn: REO management changes

Changes to use REO HW command/status interface to update/delete REO queues.

Change-Id: I3500d45db021ef314b4d03fa878314d407ddfe65
This commit is contained in:
Karunakar Dasineni 2016-11-21 17:41:31 -08:00 • committed by qcabuildsw
commit a0f09eae1d
7 changed files with 290 additions and 47 deletions

View file

@ -90,4 +90,13 @@ extern void dp_addba_responsesetup_wifi3(void *peer_handle, uint8_t tid,
uint16_t *buffersize, uint16_t *batimeout);
extern int dp_delba_process_wifi3(void *peer_handle,
int tid, uint16_t reasoncode);
extern int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
uint32_t ba_window_size, uint32_t start_seq);
extern QDF_STATUS dp_reo_send_cmd(struct dp_soc *soc,
enum hal_reo_cmd_type type, struct hal_reo_cmd_params *params,
void (*callback_fn), void *data);
extern void dp_reo_status_ring_handler(struct dp_soc *soc);
#endif /* #ifndef _DP_INTERNAL_H_ */

View file

@ -140,6 +140,7 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
uint8_t rx_mask = int_ctx->rx_ring_mask;
uint8_t rx_err_mask = int_ctx->rx_err_ring_mask;
uint8_t rx_wbm_rel_mask = int_ctx->rx_wbm_rel_ring_mask;
uint8_t reo_status_mask = int_ctx->reo_status_ring_mask;
/* Process Tx completion interrupts first to return back buffers */
if (tx_mask) {
@ -211,6 +212,9 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
}
}
if (reo_status_mask)
dp_reo_status_ring_handler(soc);
budget_done:
return dp_budget - budget;
}
@ -255,6 +259,7 @@ static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc)
soc->intr_ctx[i].rx_mon_ring_mask = 0xF;
soc->intr_ctx[i].rx_err_ring_mask = 0x1;
soc->intr_ctx[i].rx_wbm_rel_ring_mask = 0x1;
soc->intr_ctx[i].reo_status_ring_mask = 0x1;
soc->intr_ctx[i].soc = soc;
}

View file

@ -23,6 +23,7 @@
#include "dp_internal.h"
#include "dp_peer.h"
#include <hal_api.h>
#include <hal_reo.h>
/* Temporary definitions to be moved to wlan_cfg */
static inline uint32_t wlan_cfg_max_peer_id(void *wlan_cfg_ctx)
@ -401,6 +402,91 @@ dp_peer_find_detach(struct dp_soc *soc)
dp_peer_find_hash_detach(soc);
}
static void dp_rx_tid_stats_cb(struct dp_soc *soc, void *cb_ctxt,
union hal_reo_status *reo_status)
{
struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt;
struct hal_reo_queue_status *queue_status = &(reo_status->queue_status);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"%s: rx_tid: %d status: %d\n", __func__,
rx_tid->tid, queue_status->header.status);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"REO queue stats: \n"
"ssn: %d\n"
"curr_idx : %d\n"
"pn_31_0 : %08x\n"
"pn_63_32 : %08x\n"
"pn_95_64 : %08x\n"
"pn_127_96 : %08x\n"
"last_rx_enq_tstamp : %08x\n"
"last_rx_deq_tstamp : %08x\n"
"rx_bitmap_31_0 : %08x\n"
"rx_bitmap_63_32 : %08x\n"
"rx_bitmap_95_64 : %08x\n"
"rx_bitmap_127_96 : %08x\n"
"rx_bitmap_159_128 : %08x\n"
"rx_bitmap_191_160 : %08x\n"
"rx_bitmap_223_192 : %08x\n"
"rx_bitmap_255_224 : %08x\n"
"curr_mpdu_cnt : %d\n"
"curr_msdu_cnt : %d\n"
"fwd_timeout_cnt : %d\n"
"fwd_bar_cnt : %d\n"
"dup_cnt : %d\n"
"frms_in_order_cnt : %d\n"
"bar_rcvd_cnt : %d\n"
"mpdu_frms_cnt : %d\n"
"msdu_frms_cnt : %d\n"
"total_cnt : %d\n"
"late_recv_mpdu_cnt : %d\n"
"win_jump_2k : %d\n"
"hole_cnt : %d\n",
queue_status->ssn, queue_status->curr_idx,
queue_status->pn_31_0, queue_status->pn_63_32,
queue_status->pn_95_64, queue_status->pn_127_96,
queue_status->last_rx_enq_tstamp,
queue_status->last_rx_deq_tstamp,
queue_status->rx_bitmap_31_0, queue_status->rx_bitmap_63_32,
queue_status->rx_bitmap_95_64, queue_status->rx_bitmap_127_96,
queue_status->rx_bitmap_159_128,
queue_status->rx_bitmap_191_160,
queue_status->rx_bitmap_223_192,
queue_status->rx_bitmap_255_224,
queue_status->curr_mpdu_cnt, queue_status->curr_msdu_cnt,
queue_status->fwd_timeout_cnt, queue_status->fwd_bar_cnt,
queue_status->dup_cnt, queue_status->frms_in_order_cnt,
queue_status->bar_rcvd_cnt, queue_status->mpdu_frms_cnt,
queue_status->msdu_frms_cnt, queue_status->total_cnt,
queue_status->late_recv_mpdu_cnt, queue_status->win_jump_2k,
queue_status->hole_cnt);
}
static void dp_rx_tid_update_cb(struct dp_soc *soc, void *cb_ctxt,
union hal_reo_status *reo_status)
{
struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt;
struct hal_reo_cmd_params params;
if (reo_status->queue_status.header.status) {
/* Should not happen normally. Just print error for now */
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"%s: Rx tid HW desc update failed(%d): tid %d\n",
__func__,
reo_status->rx_queue_status.header.status,
rx_tid->tid);
}
qdf_mem_zero(&params, sizeof(params));
params.std.need_status = 1;
params.std.addr_lo = rx_tid->hw_qdesc_paddr & 0xffffffff;
params.std.addr_hi = (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32;
dp_reo_send_cmd(soc, CMD_GET_QUEUE_STATS, &params, dp_rx_tid_stats_cb, rx_tid);
}
/*
* dp_find_peer_by_addr - find peer instance by mac address
* @dev: physical device instance
@ -442,7 +528,24 @@ void *dp_find_peer_by_addr(void *dev, uint8_t *peer_mac_addr,
static int dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t
ba_window_size, uint32_t start_seq)
{
/* TODO: Implement this once REO command API is available */
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
struct dp_soc *soc = peer->vdev->pdev->soc;
struct hal_reo_cmd_params params;
qdf_mem_zero(&params, sizeof(params));
params.std.need_status = 1;
params.std.addr_lo = rx_tid->hw_qdesc_paddr & 0xffffffff;
params.std.addr_hi = (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32;
params.u.upd_queue_params.update_ba_window_size = 1;
params.u.upd_queue_params.ba_window_size = ba_window_size;
if (start_seq < IEEE80211_SEQ_MAX) {
params.u.upd_queue_params.update_ssn = 1;
params.u.upd_queue_params.ssn = start_seq;
}
dp_reo_send_cmd(soc, CMD_UPDATE_RX_REO_QUEUE, &params, dp_rx_tid_update_cb, rx_tid);
return 0;
}
@ -455,7 +558,7 @@ static int dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t
*
* Return: 0 on success, error code on failure
*/
static int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
uint32_t ba_window_size, uint32_t start_seq)
{
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
@ -570,42 +673,34 @@ static int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
peer->vdev->vdev_id, peer->mac_addr.raw,
rx_tid->hw_qdesc_paddr, tid, tid);
if (tid == DP_NON_QOS_TID) {
/* TODO: Setting up default queue - currently using
* same queue for BE and non-qos traffic till BA
* session is setup. Check if there are any HW
* restrictions and also if this can be done for
* all other TIDs
*/
soc->cdp_soc.ol_ops->
peer_rx_reorder_queue_setup(soc->osif_soc,
peer->vdev->vdev_id, peer->mac_addr.raw,
rx_tid->hw_qdesc_paddr, 0, tid);
}
}
return 0;
}
#ifdef notyet /* TBD: Enable this once REO command interface is available */
/*
* Rx TID deletion callback to free memory allocated for HW queue descriptor
*/
static void dp_rx_tid_delete_cb(struct dp_pdev *pdev, void *cb_ctxt, int status)
static void dp_rx_tid_delete_cb(struct dp_soc *soc, void *cb_ctxt,
union hal_reo_status *reo_status)
{
struct dp_soc *soc = pdev->soc;
struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt;
if (status) {
if (reo_status->rx_queue_status.header.status) {
/* Should not happen normally. Just print error for now */
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"%s: Rx tid HW desc deletion failed: tid %d\n",
__func__, rx_tid->tid);
"%s: Rx tid HW desc deletion failed(%d): tid %d\n",
__func__,
reo_status->rx_queue_status.header.status,
rx_tid->tid);
}
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
"%s: rx_tid: %d status: %d\n", __func__,
rx_tid->tid, reo_status->rx_queue_status.header.status);
qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
rx_tid->hw_qdesc_alloc_size,
rx_tid->hw_qdesc_vaddr_unaligned,
rx_tid->hw_qdesc_paddr_unaligned, 0);
rx_tid->hw_qdesc_alloc_size,
rx_tid->hw_qdesc_vaddr_unaligned,
rx_tid->hw_qdesc_paddr_unaligned, 0);
rx_tid->hw_qdesc_vaddr_unaligned = NULL;
rx_tid->hw_qdesc_alloc_size = 0;
@ -620,17 +715,22 @@ static void dp_rx_tid_delete_cb(struct dp_pdev *pdev, void *cb_ctxt, int status)
*/
static int dp_rx_tid_delete_wifi3(struct dp_peer *peer, int tid)
{
struct dp_rx_tid *rx_tid = peer->rx_tid[tid];
dp_rx_tid_hw_update_valid(rx_tid->hw_qdesc_paddr, 0,
struct dp_rx_tid *rx_tid = &(peer->rx_tid[tid]);
struct dp_soc *soc = peer->vdev->pdev->soc;
struct hal_reo_cmd_params params;
qdf_mem_zero(&params, sizeof(params));
params.std.need_status = 1;
params.std.addr_lo = rx_tid->hw_qdesc_paddr & 0xffffffff;
params.std.addr_hi = (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32;
params.u.upd_queue_params.update_vld = 1;
params.u.upd_queue_params.vld = 0;
dp_reo_send_cmd(soc, CMD_UPDATE_RX_REO_QUEUE, &params,
dp_rx_tid_delete_cb, (void *)rx_tid);
return 0;
}
#else
static int dp_rx_tid_delete_wifi3(struct dp_peer *peer, int tid)
{
return 0;
}
#endif
/*
* dp_peer_rx_init() – Initialize receive TID state
@ -663,6 +763,12 @@ void dp_peer_rx_init(struct dp_pdev *pdev, struct dp_peer *peer)
/* Setup default (non-qos) rx tid queue */
dp_rx_tid_setup_wifi3(peer, DP_NON_QOS_TID, 1, 0);
/* Setup rx tid queue for TID 0.
* Other queues will be setup on receiving first packet, which will cause
* NULL REO queue error
*/
dp_rx_tid_setup_wifi3(peer, 0, 1, 0);
/*
* Set security defaults: no PN check, no security. The target may
* send a HTT SEC_IND message to overwrite these defaults.
@ -680,10 +786,9 @@ void dp_peer_rx_init(struct dp_pdev *pdev, struct dp_peer *peer)
void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer)
{
int tid;
struct dp_rx_tid *rx_tid;
uint32_t tid_delete_mask = 0;
for (tid = 0; tid < DP_MAX_TIDS; tid++) {
if (rx_tid->hw_qdesc_vaddr_unaligned != NULL) {
if (peer->rx_tid[tid].hw_qdesc_vaddr_unaligned != NULL) {
dp_rx_tid_delete_wifi3(peer, tid);
tid_delete_mask |= (1 << tid);
}

View file

@ -19,9 +19,11 @@
#include "dp_types.h"
#include "dp_rx.h"
#include "dp_peer.h"
#include "dp_internal.h"
#include "hal_api.h"
#include "qdf_trace.h"
#include "qdf_nbuf.h"
#include <ieee80211.h>
/**
* dp_rx_cookie_2_link_desc_va() - Converts cookie to a virtual address of
@ -254,6 +256,9 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, void *ring_desc,
qdf_nbuf_t nbuf;
struct dp_pdev *pdev0;
struct dp_vdev *vdev0;
uint32_t tid = 0;
uint16_t peer_id;
struct dp_peer *peer = NULL;
rx_buf_cookie = HAL_RX_WBM_BUF_COOKIE_GET(ring_desc);
@ -300,6 +305,22 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, void *ring_desc,
if (l2_hdr_offset)
qdf_nbuf_pull_head(nbuf, l2_hdr_offset);
if (hal_rx_mpdu_start_mpdu_qos_control_valid_get(
rx_desc->rx_buf_start)) {
/* TODO: Assuming that qos_control_valid also indicates
* unicast. Should we check this?
*/
tid = hal_rx_mpdu_start_tid_get(rx_desc->rx_buf_start);
peer_id = hal_rx_mpdu_start_sw_peer_id_get(
rx_desc->rx_buf_start);
peer = dp_peer_find_by_id(soc, peer_id);
if (peer &&
peer->rx_tid[tid].hw_qdesc_vaddr_unaligned == NULL) {
/* IEEE80211_SEQ_MAX indicates invalid start_seq */
dp_rx_tid_setup_wifi3(peer, tid, 1, IEEE80211_SEQ_MAX);
}
}
pdev0 = soc->pdev_list[0];/* Hard code 0th elem */
if (pdev0) {

View file

@ -249,6 +249,7 @@ struct dp_intr {
uint8_t rx_mon_ring_mask; /* Rx monitor ring mask (0-2) */
uint8_t rx_err_ring_mask; /* REO Exception Ring */
uint8_t rx_wbm_rel_ring_mask; /* WBM2SW Rx Release Ring */
uint8_t reo_status_ring_mask; /* REO command response ring */
struct dp_soc *soc; /* Reference to SoC structure ,
to get DMA ring handles */
};

View file

@ -631,6 +631,75 @@ hal_rx_msdu_start_msdu_len_get(uint8_t *buf)
return msdu_len;
}
/*
* Get qos_control_valid from RX_MPDU_START
*/
#define HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \
RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_OFFSET)), \
RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_MASK, \
RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_LSB))
static inline uint32_t
hal_rx_mpdu_start_mpdu_qos_control_valid_get(uint8_t *buf)
{
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
struct rx_mpdu_start *mpdu_start =
&pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
uint32_t qos_control_valid;
qos_control_valid = HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET(
&(mpdu_start->rx_mpdu_info_details));
return qos_control_valid;
}
/*
* Get tid from RX_MPDU_START
*/
#define HAL_RX_MPDU_INFO_TID_GET(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \
RX_MPDU_INFO_3_TID_OFFSET)), \
RX_MPDU_INFO_3_TID_MASK, \
RX_MPDU_INFO_3_TID_LSB))
static inline uint32_t
hal_rx_mpdu_start_tid_get(uint8_t *buf)
{
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
struct rx_mpdu_start *mpdu_start =
&pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
uint32_t tid;
tid = HAL_RX_MPDU_INFO_TID_GET(
&(mpdu_start->rx_mpdu_info_details));
return tid;
}
/*
* Get SW peer id from RX_MPDU_START
*/
#define HAL_RX_MPDU_INFO_SW_PEER_ID_GET(_rx_mpdu_info) \
(_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \
RX_MPDU_INFO_1_SW_PEER_ID_OFFSET)), \
RX_MPDU_INFO_1_SW_PEER_ID_MASK, \
RX_MPDU_INFO_1_SW_PEER_ID_LSB))
static inline uint32_t
hal_rx_mpdu_start_sw_peer_id_get(uint8_t *buf)
{
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
struct rx_mpdu_start *mpdu_start =
&pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
uint32_t sw_peer_id;
sw_peer_id = HAL_RX_MPDU_INFO_SW_PEER_ID_GET(
&(mpdu_start->rx_mpdu_info_details));
return sw_peer_id;
}
/*******************************************************************************
* RX ERROR APIS
******************************************************************************/

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, The Linux Foundation. All rights reserved.
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -210,15 +210,22 @@ static inline int hal_srng_access_start(void *hal_soc, void *hal_ring)
static inline void *hal_srng_dst_get_next(void *hal_soc, void *hal_ring)
{
struct hal_srng *srng = (struct hal_srng *)hal_ring;
uint32_t *desc = &(srng->ring_base_vaddr[srng->u.dst_ring.tp]);
volatile uint32_t *desc = &(srng->ring_base_vaddr[srng->u.dst_ring.tp]);
uint32_t desc_loop_cnt;
desc_loop_cnt = (desc[srng->entry_size - 1] & SRNG_LOOP_CNT_MASK)
>> SRNG_LOOP_CNT_LSB;
if (srng->u.dst_ring.loop_cnt == desc_loop_cnt) {
srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size) &
srng->ring_size_mask;
/* TODO: Using % is expensive, but we have to do this since
* size of some SRNG rings is not power of 2 (due to descriptor
* sizes). Need to create separate API for rings used
* per-packet, with sizes power of 2 (TCL2SW, REO2SW,
* SW2RXDMA and CE rings)
*/
srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size) %
srng->ring_size;
srng->u.dst_ring.loop_cnt = (srng->u.dst_ring.loop_cnt +
!srng->u.dst_ring.tp) &
(SRNG_LOOP_CNT_MASK >> SRNG_LOOP_CNT_LSB);
@ -298,8 +305,15 @@ static inline void *hal_srng_src_reap_next(void *hal_soc, void *hal_ring)
{
struct hal_srng *srng = (struct hal_srng *)hal_ring;
uint32_t *desc;
uint32_t next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) &
srng->ring_size_mask;
/* TODO: Using % is expensive, but we have to do this since
* size of some SRNG rings is not power of 2 (due to descriptor
* sizes). Need to create separate API for rings used
* per-packet, with sizes power of 2 (TCL2SW, REO2SW,
* SW2RXDMA and CE rings)
*/
uint32_t next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) %
srng->ring_size;
if (next_reap_hp != srng->u.src_ring.cached_tp) {
desc = &(srng->ring_base_vaddr[next_reap_hp]);
@ -327,8 +341,9 @@ static inline void *hal_srng_src_get_next_reaped(void *hal_soc, void *hal_ring)
if (srng->u.src_ring.hp != srng->u.src_ring.reap_hp) {
desc = &(srng->ring_base_vaddr[srng->u.src_ring.hp]);
srng->u.src_ring.hp = (srng->u.src_ring.hp + srng->entry_size) &
srng->ring_size_mask;
srng->u.src_ring.hp = (srng->u.src_ring.hp + srng->entry_size) %
srng->ring_size;
return (void *)desc;
}
@ -346,8 +361,14 @@ static inline void *hal_srng_src_get_next_reaped(void *hal_soc, void *hal_ring)
static inline uint32_t hal_srng_src_done_val(void *hal_soc, void *hal_ring)
{
struct hal_srng *srng = (struct hal_srng *)hal_ring;
uint32_t next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) &
srng->ring_size_mask;
/* TODO: Using % is expensive, but we have to do this since
* size of some SRNG rings is not power of 2 (due to descriptor
* sizes). Need to create separate API for rings used
* per-packet, with sizes power of 2 (TCL2SW, REO2SW,
* SW2RXDMA and CE rings)
*/
uint32_t next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) %
srng->ring_size;
if (next_reap_hp == srng->u.src_ring.cached_tp)
return 0;
@ -371,8 +392,14 @@ static inline void *hal_srng_src_get_next(void *hal_soc, void *hal_ring)
{
struct hal_srng *srng = (struct hal_srng *)hal_ring;
uint32_t *desc;
uint32_t next_hp = (srng->u.src_ring.hp + srng->entry_size) &
srng->ring_size_mask;
/* TODO: Using % is expensive, but we have to do this since
* size of some SRNG rings is not power of 2 (due to descriptor
* sizes). Need to create separate API for rings used
* per-packet, with sizes power of 2 (TCL2SW, REO2SW,
* SW2RXDMA and CE rings)
*/
uint32_t next_hp = (srng->u.src_ring.hp + srng->entry_size) %
srng->ring_size;
if (next_hp != srng->u.src_ring.cached_tp) {
desc = &(srng->ring_base_vaddr[srng->u.src_ring.hp]);
@ -403,8 +430,14 @@ static inline void *hal_srng_src_peek(void *hal_soc, void *hal_ring)
struct hal_srng *srng = (struct hal_srng *)hal_ring;
uint32_t *desc;
if (((srng->u.src_ring.hp + srng->entry_size) &
srng->ring_size_mask) != srng->u.src_ring.cached_tp) {
/* TODO: Using % is expensive, but we have to do this since
* size of some SRNG rings is not power of 2 (due to descriptor
* sizes). Need to create separate API for rings used
* per-packet, with sizes power of 2 (TCL2SW, REO2SW,
* SW2RXDMA and CE rings)
*/
if (((srng->u.src_ring.hp + srng->entry_size) %
srng->ring_size) != srng->u.src_ring.cached_tp) {
desc = &(srng->ring_base_vaddr[srng->u.src_ring.hp]);
return (void *)desc;
}