Browse Source

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
Nandha Kishore Easwaran 6 years ago
parent
commit
7cdaae2be8
6 changed files with 54 additions and 23 deletions
  1. 6 3
      hif/src/ce/ce_assignment.h
  2. 43 18
      hif/src/ce/ce_main.c
  3. 2 0
      hif/src/ce/ce_main.h
  4. 1 0
      hif/src/ce/ce_tasklet.c
  5. 0 1
      hif/src/hif_main.h
  6. 2 1
      hif/src/pcie/if_pci.c

+ 6 - 3
hif/src/ce/ce_assignment.h

@@ -744,16 +744,19 @@ static struct CE_attr host_ce_config_wlan_qca6290[] = {
 	/* 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) */

+ 43 - 18
hif/src/ce/ce_main.c

@@ -1229,6 +1229,22 @@ static inline void reset_ce_debug_history(struct hif_softc *scn)
 }
 #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 @@ struct CE_handle *ce_init(struct hif_softc *scn,
 
 			/* 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 @@ void hif_enable_fastpath(struct hif_opaque_softc *hif_ctx)
 	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 @@ bool hif_is_fastpath_mode_enabled(struct hif_opaque_softc *hif_ctx)
 	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 @@ void ce_fini(struct CE_handle *copyeng)
 	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) {

+ 2 - 0
hif/src/ce/ce_main.h

@@ -200,6 +200,8 @@ void hif_ce_ipa_get_ce_resource(struct hif_softc *scn,
 
 #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,

+ 1 - 0
hif/src/ce/ce_tasklet.c

@@ -512,6 +512,7 @@ QDF_STATUS ce_unregister_irq(struct HIF_CE_state *hif_ce_state, uint32_t mask)
 					"%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;
 

+ 0 - 1
hif/src/hif_main.h

@@ -163,7 +163,6 @@ struct hif_softc {
 	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;

+ 2 - 1
hif/src/pcie/if_pci.c

@@ -3682,7 +3682,8 @@ int hif_configure_irq(struct hif_softc *scn)
 	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;
 	}