Browse Source

qcacmn: REO management changes

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

Change-Id: I3500d45db021ef314b4d03fa878314d407ddfe65
Karunakar Dasineni 8 years ago
parent
commit
a0f09eae1d
7 changed files with 290 additions and 47 deletions
  1. 9 0
      dp/wifi3.0/dp_internal.h
  2. 5 0
      dp/wifi3.0/dp_main.c
  3. 138 33
      dp/wifi3.0/dp_peer.c
  4. 21 0
      dp/wifi3.0/dp_rx_err.c
  5. 1 0
      dp/wifi3.0/dp_types.h
  6. 69 0
      dp/wifi3.0/hal_rx.h
  7. 47 14
      hal/wifi3.0/hal_api.h

+ 9 - 0
dp/wifi3.0/dp_internal.h

@@ -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_ */

+ 5 - 0
dp/wifi3.0/dp_main.c

@@ -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;
 	}
 

+ 138 - 33
dp/wifi3.0/dp_peer.c

@@ -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);
 		}

+ 21 - 0
dp/wifi3.0/dp_rx_err.c

@@ -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) {

+ 1 - 0
dp/wifi3.0/dp_types.h

@@ -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 */
 };

+ 69 - 0
dp/wifi3.0/hal_rx.h

@@ -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
  ******************************************************************************/

+ 47 - 14
hal/wifi3.0/hal_api.h

@@ -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;
 	}