qcacmn: Cleanup CE poll implementation

Change CE poll timer to wake up CPU so that timer kicks in even though
CPU is in idle state. This is needed so that poll happens in regular
10ms intervals. Also made ce_inited false during wifi down path to
prevent polling during wifi down.

Also made some cleanup in polling implementation to remove global scn
flag to enable polled mode and use attr flag to enable per CE polling.

Change-Id: I1d894c99193cc9902fcf4d6cbfd179c557ec6219
CRs-fixed: 2269599
diff --git a/hif/src/ce/ce_assignment.h b/hif/src/ce/ce_assignment.h
index ec6d54b..6d29329 100644
--- a/hif/src/ce/ce_assignment.h
+++ b/hif/src/ce/ce_assignment.h
@@ -744,16 +744,19 @@
 	/* host->target HTC control and raw streams */
 	{ /* CE0 */ CE_ATTR_FLAGS, 0, 16, 2048, 0, NULL,},
 	/* target->host HTT + HTC control */
-	{ /* CE1 */ CE_ATTR_FLAGS, 0, 0,  2048, 512, NULL,},
+	{ /* CE1 */ (CE_ATTR_FLAGS | CE_ATTR_ENABLE_POLL), 0, 0,  2048,
+		512, NULL,},
 	/* target->host WMI */
-	{ /* CE2 */ CE_ATTR_FLAGS, 0, 0,  2048, 32, NULL,},
+	{ /* CE2 */ (CE_ATTR_FLAGS | CE_ATTR_ENABLE_POLL), 0, 0,  2048,
+		32, NULL,},
 	/* host->target WMI */
 	{ /* CE3 */ CE_ATTR_FLAGS, 0, 32, 2048, 0, NULL,},
 	/* host->target HTT */
 	{ /* CE4 */ (CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR), 0,
 		CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0, NULL,},
 	/* target -> host PKTLOG */
-	{ /* CE5 */ CE_ATTR_FLAGS, 0, 0, 2048, 512, NULL,},
+	{ /* CE5 */ (CE_ATTR_FLAGS | CE_ATTR_ENABLE_POLL), 0, 0, 2048,
+		512, NULL,},
 	/* Target autonomous HIF_memcpy */
 	{ /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,},
 	/* host->target WMI (mac1) */
diff --git a/hif/src/ce/ce_main.c b/hif/src/ce/ce_main.c
index 1501043..438135e 100644
--- a/hif/src/ce/ce_main.c
+++ b/hif/src/ce/ce_main.c
@@ -1229,6 +1229,22 @@
 }
 #endif /*Note: defined(HIF_CONFIG_SLUB_DEBUG_ON) || HIF_CE_DEBUG_DATA_BUF */
 
+void ce_enable_polling(void *cestate)
+{
+	struct CE_state *CE_state = (struct CE_state *)cestate;
+
+	if (CE_state && CE_state->attr_flags & CE_ATTR_ENABLE_POLL)
+		CE_state->timer_inited = true;
+}
+
+void ce_disable_polling(void *cestate)
+{
+	struct CE_state *CE_state = (struct CE_state *)cestate;
+
+	if (CE_state && CE_state->attr_flags & CE_ATTR_ENABLE_POLL)
+		CE_state->timer_inited = false;
+}
+
 /*
  * Initialize a Copy Engine based on caller-supplied attributes.
  * This may be called once to initialize both source and destination
@@ -1410,14 +1426,13 @@
 
 			/* epping */
 			/* poll timer */
-			if ((CE_state->attr_flags & CE_ATTR_ENABLE_POLL) ||
-					scn->polled_mode_on) {
+			if (CE_state->attr_flags & CE_ATTR_ENABLE_POLL) {
 				qdf_timer_init(scn->qdf_dev,
-						       &CE_state->poll_timer,
-						       ce_poll_timeout,
-						       CE_state,
-						       QDF_TIMER_TYPE_SW);
-				CE_state->timer_inited = true;
+						&CE_state->poll_timer,
+						ce_poll_timeout,
+						CE_state,
+						QDF_TIMER_TYPE_WAKE_APPS);
+				ce_enable_polling(CE_state);
 				qdf_timer_mod(&CE_state->poll_timer,
 						      CE_POLL_TIMEOUT);
 			}
@@ -1471,14 +1486,6 @@
 	scn->fastpath_mode_on = true;
 }
 
-void hif_enable_polled_mode(struct hif_opaque_softc *hif_ctx)
-{
-	struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
-	HIF_DBG("%s, Enabling polled mode", __func__);
-
-	scn->polled_mode_on = true;
-}
-
 /**
  * hif_is_fastpath_mode_enabled - API to query if fasthpath mode is enabled
  * @hif_ctx: HIF Context
@@ -1494,13 +1501,30 @@
 	return scn->fastpath_mode_on;
 }
 
+/**
+ * hif_is_polled_mode_enabled - API to query if polling is enabled on all CEs
+ * @hif_ctx: HIF Context
+ *
+ * API to check if polling is enabled on all CEs. Returns true when polling
+ * is enabled on all CEs.
+ *
+ * Return: bool
+ */
 bool hif_is_polled_mode_enabled(struct hif_opaque_softc *hif_ctx)
 {
 	struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
+	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
+	struct CE_attr *attr;
+	int id;
 
-	return scn->polled_mode_on;
+	for (id = 0; id < scn->ce_count; id++) {
+		attr = &hif_state->host_ce_config[id];
+		if (attr && (attr->dest_nentries) &&
+		    !(attr->flags & CE_ATTR_ENABLE_POLL))
+			return false;
+	}
+	return true;
 }
-
 qdf_export_symbol(hif_is_polled_mode_enabled);
 
 /**
@@ -1663,7 +1687,8 @@
 	CE_state->state = CE_UNUSED;
 	scn->ce_id_to_state[CE_id] = NULL;
 	/* Set the flag to false first to stop processing in ce_poll_timeout */
-	CE_state->timer_inited = false;
+	ce_disable_polling(CE_state);
+
 	qdf_lro_deinit(CE_state->lro_data);
 
 	if (CE_state->src_ring) {
diff --git a/hif/src/ce/ce_main.h b/hif/src/ce/ce_main.h
index 58906c5..75342a2 100644
--- a/hif/src/ce/ce_main.h
+++ b/hif/src/ce/ce_main.h
@@ -200,6 +200,8 @@
 
 #endif
 int hif_wlan_enable(struct hif_softc *scn);
+void ce_enable_polling(void *cestate);
+void ce_disable_polling(void *cestate);
 void hif_wlan_disable(struct hif_softc *scn);
 void hif_get_target_ce_config(struct hif_softc *scn,
 		struct CE_pipe_config **target_ce_config_ret,
diff --git a/hif/src/ce/ce_tasklet.c b/hif/src/ce/ce_tasklet.c
index 95f34c7..c60cafa 100644
--- a/hif/src/ce/ce_tasklet.c
+++ b/hif/src/ce/ce_tasklet.c
@@ -512,6 +512,7 @@
 					"%s: pld_unregister_irq error - ce_id = %d, ret = %d",
 					__func__, id, ret);
 		}
+		ce_disable_polling(scn->ce_id_to_state[id]);
 	}
 	hif_ce_state->ce_register_irq_done &= ~mask;
 
diff --git a/hif/src/hif_main.h b/hif/src/hif_main.h
index 5e6c4e1..0740338 100644
--- a/hif/src/hif_main.h
+++ b/hif/src/hif_main.h
@@ -163,7 +163,6 @@
 	qdf_dma_addr_t paddr_rri_on_ddr;
 	int linkstate_vote;
 	bool fastpath_mode_on;
-	bool polled_mode_on;
 	atomic_t tasklet_from_intr;
 	int htc_htt_tx_endpoint;
 	qdf_dma_addr_t mem_pa;
diff --git a/hif/src/pcie/if_pci.c b/hif/src/pcie/if_pci.c
index f909b6a..b05a289 100644
--- a/hif/src/pcie/if_pci.c
+++ b/hif/src/pcie/if_pci.c
@@ -3682,7 +3682,8 @@
 	struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(scn);
 
 	HIF_TRACE("%s: E", __func__);
-	if (scn->polled_mode_on) {
+
+	if (hif_is_polled_mode_enabled(GET_HIF_OPAQUE_HDL(scn))) {
 		scn->request_irq_done = false;
 		return 0;
 	}