qcacmn: write DEST_MAX_LENGTH for CE rings

Change that allows configuration of max buffer
size for SRNG rings in the receive direction

Change-Id: Ib857f1fdf43c849078f9470ec029fe627379fcb4
CRs-Fixed: 1089874
diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h
index 6f517e8..1051286 100644
--- a/hal/wifi3.0/hal_api.h
+++ b/hal/wifi3.0/hal_api.h
@@ -109,6 +109,8 @@
 	void *ring_base_vaddr;
 	/* Number of entries in ring */
 	uint32_t num_entries;
+	/* max transfer length */
+	uint16_t max_buffer_length;
 	/* MSI Address */
 	qdf_dma_addr_t msi_addr;
 	/* MSI data */
diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h
index b3cb5a0..d073607 100644
--- a/hal/wifi3.0/hal_internal.h
+++ b/hal/wifi3.0/hal_internal.h
@@ -236,7 +236,10 @@
 			uint32_t *tp_addr;
 
 			/* Current SW loop cnt */
-			int loop_cnt;
+			uint32_t loop_cnt;
+
+			/* max transfer size */
+			uint16_t max_buffer_length;
 		} dst_ring;
 
 		struct {
diff --git a/hal/wifi3.0/hal_srng.c b/hal/wifi3.0/hal_srng.c
index ae2a073..dcdbd08 100644
--- a/hal/wifi3.0/hal_srng.c
+++ b/hal/wifi3.0/hal_srng.c
@@ -668,6 +668,31 @@
 }
 
 /**
+ * hal_ce_dst_setup - Initialize CE destination ring registers
+ * @hal_soc: HAL SOC handle
+ * @srng: SRNG ring pointer
+ */
+static inline void hal_ce_dst_setup(struct hal_soc *hal, struct hal_srng *srng,
+				    int ring_num)
+{
+	uint32_t reg_val = 0;
+	uint32_t reg_addr;
+	struct hal_hw_srng_config *ring_config =
+		HAL_SRNG_CONFIG(hal, CE_DST);
+
+	/* set DEST_MAX_LENGTH according to ce assignment */
+	reg_addr = HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_CTRL_ADDR(
+			ring_config->reg_start[R0_INDEX] +
+			(ring_num * ring_config->reg_size[R0_INDEX]));
+
+	reg_val = HAL_REG_READ(hal, reg_addr);
+	reg_val &= ~HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_CTRL_DEST_MAX_LENGTH_BMSK;
+	reg_val |= srng->u.dst_ring.max_buffer_length &
+		HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_CTRL_DEST_MAX_LENGTH_BMSK;
+	HAL_REG_WRITE(hal, reg_addr, reg_val);
+}
+
+/**
  * hal_srng_dst_hw_init - Private function to initialize SRNG
  * destination ring HW
  * @hal_soc: HAL SOC handle
@@ -889,9 +914,16 @@
 		}
 	}
 
-	if (!(ring_config->lmac_ring))
+
+	if (!(ring_config->lmac_ring)) {
 		hal_srng_hw_init(hal, srng);
 
+		if (ring_type == CE_DST) {
+			srng->u.dst_ring.max_buffer_length = ring_params->max_buffer_length;
+			hal_ce_dst_setup(hal, srng, ring_num);
+		}
+	}
+
 	SRNG_LOCK_INIT(&srng->lock);
 
 	return (void *)srng;
diff --git a/hif/src/ce/ce_service_srng.c b/hif/src/ce/ce_service_srng.c
index 112da0f..e65bf62 100644
--- a/hif/src/ce/ce_service_srng.c
+++ b/hif/src/ce/ce_service_srng.c
@@ -612,7 +612,8 @@
 }
 
 void ce_srng_dest_ring_setup(struct hif_softc *scn, uint32_t ce_id,
-				struct CE_ring_state *dest_ring)
+				struct CE_ring_state *dest_ring,
+				struct CE_attr *attr)
 {
 	struct hal_srng_params ring_params = {0};
 
@@ -621,6 +622,7 @@
 	ring_params.num_entries = dest_ring->nentries;
 	ring_params.intr_timer_thres_us = 0;
 	ring_params.intr_batch_cntr_thres_entries = 1;
+	ring_params.max_buffer_length = attr->src_sz_max;
 
 	/* TODO
 	 * ring_params.msi_addr = XXX;
@@ -663,7 +665,7 @@
 		ce_srng_src_ring_setup(scn, ce_id, ring);
 		break;
 	case CE_RING_DEST:
-		ce_srng_dest_ring_setup(scn, ce_id, ring);
+		ce_srng_dest_ring_setup(scn, ce_id, ring, attr);
 		break;
 	case CE_RING_STATUS:
 		ce_srng_status_ring_setup(scn, ce_id, ring);