Browse Source

qcacmn: Disable NAPI before disabling the irq

Before disabling the interrupts, disable NAPI so that
the softirq cannot be [re-]scheduled.
Remove the affinity notification on the irq.

Change-Id: I64061d2b4f2e1e6eff67416133b928faa9c0dd4c
CRs-Fixed: 1089166
Orhan K AKYILDIZ 8 years ago
parent
commit
f006e93682
3 changed files with 25 additions and 12 deletions
  1. 2 0
      hif/inc/hif_napi.h
  2. 7 0
      hif/src/ce/ce_tasklet.c
  3. 16 12
      hif/src/hif_napi.c

+ 2 - 0
hif/inc/hif_napi.h

@@ -62,6 +62,7 @@
  * ---------------:------------------:------------------
  * EVT_INI_FILE   : cfg->napi_enable : after ini file processed
  * EVT_CMD_STATE  : cmd arg          : by the vendor cmd
+ * EVT_INT_STATE  : 0                : internal - shut off/disable
  * EVT_CPU_STATE  : (cpu << 16)|state: CPU hotplug events
  * EVT_TPUT_STATE : (high/low)       : tput trigger
  * EVT_USR_SERIAL : num-serial_calls : WMA/ROAMING-START/IND
@@ -71,6 +72,7 @@ enum qca_napi_event {
 	NAPI_EVT_INVALID,
 	NAPI_EVT_INI_FILE,
 	NAPI_EVT_CMD_STATE,
+	NAPI_EVT_INT_STATE,
 	NAPI_EVT_CPU_STATE,
 	NAPI_EVT_TPUT_STATE,
 	NAPI_EVT_USR_SERIAL,

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

@@ -549,6 +549,13 @@ QDF_STATUS ce_unregister_irq(struct HIF_CE_state *hif_ce_state, uint32_t mask)
 
 	scn = HIF_GET_SOFTC(hif_ce_state);
 	ce_count = scn->ce_count;
+	/* we are removing interrupts, so better stop NAPI */
+	ret = hif_napi_event(GET_HIF_OPAQUE_HDL(scn),
+			     NAPI_EVT_INT_STATE, (void *)0);
+	if (ret != 0)
+		HIF_ERROR("%s: napi_event INT_STATE returned %d",
+			  __func__, ret);
+	/* this is not fatal, continue */
 
 	for (id = 0; id < ce_count; id++) {
 		if ((mask & (1 << id)) && hif_ce_state->tasklets[id].inited) {

+ 16 - 12
hif/src/hif_napi.c

@@ -473,25 +473,25 @@ int hif_napi_event(struct hif_opaque_softc *hif_ctx, enum qca_napi_event event,
 	prev_state = napid->state;
 	switch (event) {
 	case NAPI_EVT_INI_FILE:
-	case NAPI_EVT_CMD_STATE: {
+	case NAPI_EVT_CMD_STATE:
+	case NAPI_EVT_INT_STATE: {
 		int on = (data != ((void *)0));
 
-		HIF_INFO("%s: received evnt: CONF %s; v = %d (state=0x%0x)",
-			 __func__,
-			 (event == NAPI_EVT_INI_FILE)?".ini file":"cmd",
+		HIF_INFO("%s: recved evnt: STATE_CMD %d; v = %d (state=0x%0x)",
+			 __func__, event,
 			 on, prev_state);
 		if (on)
 			if (prev_state & HIF_NAPI_CONF_UP) {
 				HIF_INFO("%s: duplicate NAPI conf ON msg",
 					 __func__);
 			} else {
-				HIF_INFO("%s: setting configuration to ON",
+				HIF_INFO("%s: setting state to ON",
 					 __func__);
 				napid->state |= HIF_NAPI_CONF_UP;
 			}
 		else /* off request */
 			if (prev_state & HIF_NAPI_CONF_UP) {
-				HIF_INFO("%s: setting configuration to OFF",
+				HIF_INFO("%s: setting state to OFF",
 				 __func__);
 				napid->state &= ~HIF_NAPI_CONF_UP;
 			} else {
@@ -596,12 +596,12 @@ int hif_napi_event(struct hif_opaque_softc *hif_ctx, enum qca_napi_event event,
 		break;
 	} /* switch blacklist_pending */
 
-	if (prev_state != hif->napi_data.state) {
-		if (hif->napi_data.state == ENABLE_NAPI_MASK) {
+	if (prev_state != napid->state) {
+		if (napid->state == ENABLE_NAPI_MASK) {
 			rc = 1;
 			for (i = 0; i < CE_COUNT_MAX; i++)
-				if ((hif->napi_data.ce_map & (0x01 << i))) {
-					napi = &(hif->napi_data.napis[i].napi);
+				if ((napid->ce_map & (0x01 << i))) {
+					napi = &(napid->napis[i].napi);
 					NAPI_DEBUG("%s: enabling NAPI %d",
 						   __func__, i);
 					napi_enable(napi);
@@ -609,11 +609,15 @@ int hif_napi_event(struct hif_opaque_softc *hif_ctx, enum qca_napi_event event,
 		} else {
 			rc = 0;
 			for (i = 0; i < CE_COUNT_MAX; i++)
-				if (hif->napi_data.ce_map & (0x01 << i)) {
-					napi = &(hif->napi_data.napis[i].napi);
+				if (napid->ce_map & (0x01 << i)) {
+					napi = &(napid->napis[i].napi);
 					NAPI_DEBUG("%s: disabling NAPI %d",
 						   __func__, i);
 					napi_disable(napi);
+					/* in case it is affined, remove it */
+					irq_set_affinity_hint(
+							napid->napis[i].irq,
+							NULL);
 				}
 		}
 	} else {