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
This commit is contained in:
Orhan K AKYILDIZ 2016-11-14 00:35:44 -08:00 • committed by qcabuildsw
commit f006e93682
3 changed files with 25 additions and 12 deletions

View file

@ -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,

View file

@ -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) {

View file

@ -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 {