wl12xx: Fix sdio out-of-sync power state

wl12xx_sdio_power_off() manually powers down the card regardless of the
runtime pm state. If wl12xx_sdio_power_on() is called before the card
was suspended by runtime PM, it will not power up the card.

As part of the HW detection, the chip's power is toggled. Since this
happens in the context of probing sdio, the power reference counter will
be higher than zero. As a result, when wl12xx_sdio_power_off() is
called, the chip will be powered down while still having a positive
power reference counter. If the interface is quickly activated, the
driver might try to transfer data to a powered off chip.

Fix this by ensuring that wl12xx_sdio_power_on() explicitly powers on
the chip in case runtime pm claims the chip is already powered on. To
avoid cases in which it is not possible to determine if the chip was
really powered on (card's power reference counter is positive), operate
on the mmc_card instead of the function.

Also verify that the chip is indeed powered on before powering off, to
avoid wrong reference counter values in error cases.

Signed-off-by: Ido Yariv <ido@wizery.com>
wl12xx: Disable interrupts while recovering

In case a recovery is initiated, the FW can no longer be trusted, and
the driver should not handle any new FW events.

Disable the interrupt handler when a recovery is scheduled and balance
it back in the op_stop callback.

Signed-off-by: Ido Yariv <ido@wizery.com>
wl12xx: Change read/write ops to return errors

While bus operations may fail, either due to HW or FW issues, these are
never propagated to higher layers. As a result, the core driver has no
way of knowing that the operations failed, and will only recover if high
level logic requires it (e.g. no command completion).

Change read/write bus operations to return errors to let higher layer
functionality handle these.

Signed-off-by: Ido Yariv <ido@wizery.com>
wl12xx: Check return value when reading the FW status

The return value of the bus read operation is not checked when reading
the FW status. This can lead to various problems. For instance, the
driver might not be able to acknowledge interrupts, which will keep on
firing as soon as the interrupt handler exits. Fix this by propagating
the bus operation return value and handling it.

Signed-off-by: Ido Yariv <ido@wizery.com>
wl12xx: Propagate errors from wl1271_raw_read32

Propagate errors from wl1271_raw_read32. Since the read functions had no
way of returning errors in-band, change their prototypes.

Signed-off-by: Ido Yariv <ido@wizery.com>
wl12xx: Propagate errors from wl1271_raw_write32

Propagate errors from wl1271_raw_write32 and request for recovery when
appropriate.

Signed-off-by: Ido Yariv <ido@wizery.com>
wl12xx: Propagate errors from wl1271_read

Propagate return values from wl1271_read and change prototypes of
functions calling this function to return errors.

Signed-off-by: Ido Yariv <ido@wizery.com>
wl12xx: Propagate errors from wl1271_write

Propagate return values from wl1271_write in order to handle bus
operations failures.

Signed-off-by: Ido Yariv <ido@wizery.com>
wl12xx: Propagate errors from wl1271_read_hwaddr

Propagate errors from wl1271_read_hwaddr. This function is only used
when reading the FW log (following a recovery), so don't read the FW log
in case of a bus error.

Signed-off-by: Ido Yariv <ido@wizery.com>
wl12xx: Force checking of io functions' return values

All io functions' return values should be propagated and handled. Add a
__must_check annotation to verify that the return values are checked and
to avoid future mistakes.

Signed-off-by: Ido Yariv <ido@wizery.com>
mac80211: handle auth failure returned with unmatching auth algo

Some Netgear APs like WNAP210 have a quirk behavior when
configured for WEP Shared. They send an auth response with algo
SHARED and status code NOT_SUPPORTED_AUTH_ALG (13) when being
sent a request made with auth algo OPEN. Enable such response to
propagate to userspace instead of discarding it so wpa_s can
reattempt to auth with SHARED.

Reported-by: Noam Shaked <noams@ti.com>
Signed-off-by: Eyal Shapira <eyal@wizery.com>
mac80211: fix cleanup if driver suspend callback fails

In case the driver suspend callback fails, mac80211 is left
with stopped queues which prevents any further traffic as well
as all STAs are left marked with WLAN_STA_BLOCK_BA which will
cause any further ADDBA requests to be declined. Fix it by
undoing both before returning from __iee80211_suspend.

Signed-off-by: Eyal Shapira <eyal@wizery.com>
wl12xx: cancel suspend when recovery is pending

We wish to postpone suspend if recovery is pending. This will make sure
the FW is in a good state and perform wowlan wakeup.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
wl12xx: don't allow SDIO read/writes after failure

Set a flag and after the first read/write failure is encountered.
This flag will disallow further SDIO read/writes until op_stop() is
executed, which will clear all flags.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
wl12xx: force recovery on resume if suspended without recovering

If an error is detected after mac80211 is already suspended, the recovery
work will not be queued. This will leave the driver in a bad state on
resume.

Detect this in the resume op and re-queue a recovery.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
wl12xx: check Rx-filter functions in the suspend path

Propagate some missing return values for Rx-filter related functions.
This and makes sure we always fail the suspend in case of SDIO errors.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
wl12xx: refactor threaded IRQ routine

Separate the threaded IRQ handling routine into two functions.
The outer function takes the mutex and calls recovery on errors. It also
performs a Tx-path optimization to avoid redundant works.

The inner function is simplified - all calls to recovery are removed and
it assumes the lock is taken. The locked variant will be reused elsewhere.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
wl12xx: prevent recovery in the middle of resume

Take the mutex early in the resume handler and use the locked version of
the IRQ routine. This ensures any recoveries queued will only take place
after resume has fully completed.

Signed-off-by: Arik Nemtsov <arik@wizery.com>