qcacmn: Fix ce ring timeout interrupt hw work arround

Interrupt was constantly firing because the low_threshold was
improperly configured.  The low threshold needs to be 1 less than
the number of buffers posted when the CE is fully posted.  The
srng backed CE's are setup with nentries - 2 buffers as the fully
posted amount, therefore the threshold needs to be nentries - 3.

Also fixes a bug where a reused variable is not cleared.  This
bug could result in the threshold being set to a garbages value.

Change-Id: Iac840bfd6677683bf2feb42d8bdbd050f42e895d
CRs-Fixed: 2090603
diff --git a/hal/wifi3.0/hal_srng.c b/hal/wifi3.0/hal_srng.c
index 91343f3..93760e4 100644
--- a/hal/wifi3.0/hal_srng.c
+++ b/hal/wifi3.0/hal_srng.c
@@ -882,6 +882,7 @@
 	}
 	SRNG_SRC_REG_WRITE(srng, CONSUMER_INT_SETUP_IX0, reg_val);
 
+	reg_val = 0;
 	if (srng->flags & HAL_SRNG_LOW_THRES_INTR_ENABLE) {
 		reg_val |= SRNG_SM(SRNG_SRC_FLD(CONSUMER_INT_SETUP_IX1,
 			LOW_THRESHOLD), srng->u.src_ring.low_threshold);
diff --git a/hif/src/ce/ce_service_srng.c b/hif/src/ce/ce_service_srng.c
index e39434c..19c5c4c 100644
--- a/hif/src/ce/ce_service_srng.c
+++ b/hif/src/ce/ce_service_srng.c
@@ -625,6 +625,35 @@
 			&ring_params);
 }
 
+/**
+ * ce_srng_initialize_dest_timer_interrupt_war() - war initialization
+ * @dest_ring: ring being initialized
+ * @ring_params: pointer to initialized parameters
+ *
+ * For Napier & Hawkeye v1, the status ring timer interrupts do not work
+ * As a work arround host configures the destination rings to be a proxy for
+ * work needing to be done.
+ *
+ * The interrupts are setup such that if the destination ring is less than fully
+ * posted, there is likely undone work for the status ring that the host should
+ * process.
+ *
+ * There is a timing bug in srng based copy engines such that a fully posted
+ * srng based copy engine has 2 empty entries instead of just one.  The copy
+ * engine data sturctures work with 1 empty entry, but the software frequently
+ * fails to post the last entry due to the race condition.
+ */
+static void ce_srng_initialize_dest_timer_interrupt_war(
+		struct CE_ring_state *dest_ring,
+		struct hal_srng_params *ring_params) {
+	int num_buffers_when_fully_posted = dest_ring->nentries - 2;
+
+	ring_params->low_threshold = num_buffers_when_fully_posted - 1;
+	ring_params->intr_timer_thres_us = 1024;
+	ring_params->intr_batch_cntr_thres_entries = 0;
+	ring_params->flags |= HAL_SRNG_LOW_THRES_INTR_ENABLE;
+}
+
 static void ce_srng_dest_ring_setup(struct hif_softc *scn, uint32_t ce_id,
 				struct CE_ring_state *dest_ring,
 				struct CE_attr *attr)
@@ -642,11 +671,8 @@
 	if (!(CE_ATTR_DISABLE_INTR & attr->flags)) {
 		ce_srng_msi_ring_params_setup(scn, ce_id, &ring_params);
 		if (status_ring_timer_thresh_work_arround) {
-			/* hw bug work arround*/
-			ring_params.low_threshold = dest_ring->nentries - 1;
-			ring_params.intr_timer_thres_us = 1024;
-			ring_params.intr_batch_cntr_thres_entries = 0;
-			ring_params.flags |= HAL_SRNG_LOW_THRES_INTR_ENABLE;
+			ce_srng_initialize_dest_timer_interrupt_war(
+					dest_ring, &ring_params);
 		} else {
 			/* normal behavior for future chips */
 			ring_params.low_threshold = dest_ring->nentries >> 3;