mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-11-29 05:15:20 +02:00
91 lines
2.5 KiB
Diff
91 lines
2.5 KiB
Diff
|
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||
|
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||
|
@@ -428,6 +428,7 @@ int ath_beaconq_config(struct ath_softc
|
||
|
|
||
|
#define ATH_PAPRD_TIMEOUT 100 /* msecs */
|
||
|
|
||
|
+void ath_hw_check(struct work_struct *work);
|
||
|
void ath_paprd_calibrate(struct work_struct *work);
|
||
|
void ath_ani_calibrate(unsigned long data);
|
||
|
|
||
|
@@ -563,6 +564,7 @@ struct ath_softc {
|
||
|
spinlock_t sc_pm_lock;
|
||
|
struct mutex mutex;
|
||
|
struct work_struct paprd_work;
|
||
|
+ struct work_struct hw_check_work;
|
||
|
struct completion paprd_complete;
|
||
|
|
||
|
u32 intrstatus;
|
||
|
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||
|
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||
|
@@ -516,6 +516,25 @@ static void ath_node_detach(struct ath_s
|
||
|
ath_tx_node_cleanup(sc, an);
|
||
|
}
|
||
|
|
||
|
+void ath_hw_check(struct work_struct *work)
|
||
|
+{
|
||
|
+ struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work);
|
||
|
+ int i;
|
||
|
+
|
||
|
+ ath9k_ps_wakeup(sc);
|
||
|
+
|
||
|
+ for (i = 0; i < 3; i++) {
|
||
|
+ if (ath9k_hw_check_alive(sc->sc_ah))
|
||
|
+ goto out;
|
||
|
+
|
||
|
+ msleep(1);
|
||
|
+ }
|
||
|
+ ath_reset(sc, false);
|
||
|
+
|
||
|
+out:
|
||
|
+ ath9k_ps_restore(sc);
|
||
|
+}
|
||
|
+
|
||
|
void ath9k_tasklet(unsigned long data)
|
||
|
{
|
||
|
struct ath_softc *sc = (struct ath_softc *)data;
|
||
|
@@ -527,13 +546,15 @@ void ath9k_tasklet(unsigned long data)
|
||
|
|
||
|
ath9k_ps_wakeup(sc);
|
||
|
|
||
|
- if ((status & ATH9K_INT_FATAL) ||
|
||
|
- !ath9k_hw_check_alive(ah)) {
|
||
|
+ if (status & ATH9K_INT_FATAL) {
|
||
|
ath_reset(sc, false);
|
||
|
ath9k_ps_restore(sc);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
+ if (!ath9k_hw_check_alive(ah))
|
||
|
+ ieee80211_queue_work(sc->hw, &sc->hw_check_work);
|
||
|
+
|
||
|
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||
|
rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL |
|
||
|
ATH9K_INT_RXORN);
|
||
|
@@ -1254,6 +1275,7 @@ static void ath9k_stop(struct ieee80211_
|
||
|
|
||
|
cancel_delayed_work_sync(&sc->tx_complete_work);
|
||
|
cancel_work_sync(&sc->paprd_work);
|
||
|
+ cancel_work_sync(&sc->hw_check_work);
|
||
|
|
||
|
if (!sc->num_sec_wiphy) {
|
||
|
cancel_delayed_work_sync(&sc->wiphy_work);
|
||
|
@@ -1977,6 +1999,7 @@ static void ath9k_sw_scan_start(struct i
|
||
|
sc->sc_flags |= SC_OP_SCANNING;
|
||
|
del_timer_sync(&common->ani.timer);
|
||
|
cancel_work_sync(&sc->paprd_work);
|
||
|
+ cancel_work_sync(&sc->hw_check_work);
|
||
|
cancel_delayed_work_sync(&sc->tx_complete_work);
|
||
|
mutex_unlock(&sc->mutex);
|
||
|
}
|
||
|
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||
|
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||
|
@@ -751,6 +751,7 @@ int ath9k_init_device(u16 devid, struct
|
||
|
goto error_world;
|
||
|
}
|
||
|
|
||
|
+ INIT_WORK(&sc->hw_check_work, ath_hw_check);
|
||
|
INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
|
||
|
INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
|
||
|
INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
|