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
diff --git a/hif/inc/hif_napi.h b/hif/inc/hif_napi.h
index b81895d..a4b0e71 100644
--- a/hif/inc/hif_napi.h
+++ b/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 @@
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,
diff --git a/hif/src/ce/ce_tasklet.c b/hif/src/ce/ce_tasklet.c
index ef99334..c820d87 100644
--- a/hif/src/ce/ce_tasklet.c
+++ b/hif/src/ce/ce_tasklet.c
@@ -549,6 +549,13 @@
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) {
diff --git a/hif/src/hif_napi.c b/hif/src/hif_napi.c
index fe6c39b..0574866 100644
--- a/hif/src/hif_napi.c
+++ b/hif/src/hif_napi.c
@@ -473,25 +473,25 @@
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 @@
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 @@
} 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 {