mirror of https://github.com/hak5/openwrt.git
202 lines
6.4 KiB
Diff
202 lines
6.4 KiB
Diff
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
|
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
|
@@ -511,13 +511,12 @@ void ath_deinit_leds(struct ath_softc *s
|
|
#define SC_OP_BEACONS BIT(1)
|
|
#define SC_OP_RXAGGR BIT(2)
|
|
#define SC_OP_TXAGGR BIT(3)
|
|
-#define SC_OP_FULL_RESET BIT(4)
|
|
#define SC_OP_PREAMBLE_SHORT BIT(5)
|
|
#define SC_OP_PROTECT_ENABLE BIT(6)
|
|
#define SC_OP_RXFLUSH BIT(7)
|
|
#define SC_OP_LED_ASSOCIATED BIT(8)
|
|
#define SC_OP_LED_ON BIT(9)
|
|
-#define SC_OP_SCANNING BIT(10)
|
|
+#define SC_OP_OFFCHANNEL BIT(10)
|
|
#define SC_OP_TSF_RESET BIT(11)
|
|
#define SC_OP_BT_PRIORITY_DETECTED BIT(12)
|
|
#define SC_OP_BT_SCAN BIT(13)
|
|
--- a/drivers/net/wireless/ath/ath9k/main.c
|
|
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
|
@@ -155,6 +155,27 @@ void ath9k_ps_restore(struct ath_softc *
|
|
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
|
|
}
|
|
|
|
+static void ath_start_ani(struct ath_common *common)
|
|
+{
|
|
+ struct ath_hw *ah = common->ah;
|
|
+ unsigned long timestamp = jiffies_to_msecs(jiffies);
|
|
+ struct ath_softc *sc = (struct ath_softc *) common->priv;
|
|
+
|
|
+ if (!(sc->sc_flags & SC_OP_ANI_RUN))
|
|
+ return;
|
|
+
|
|
+ if (sc->sc_flags & SC_OP_OFFCHANNEL)
|
|
+ return;
|
|
+
|
|
+ common->ani.longcal_timer = timestamp;
|
|
+ common->ani.shortcal_timer = timestamp;
|
|
+ common->ani.checkani_timer = timestamp;
|
|
+
|
|
+ mod_timer(&common->ani.timer,
|
|
+ jiffies +
|
|
+ msecs_to_jiffies((u32)ah->config.ani_poll_interval));
|
|
+}
|
|
+
|
|
/*
|
|
* Set/change channels. If the channel is really being changed, it's done
|
|
* by reseting the chip. To accomplish this we must first cleanup any pending
|
|
@@ -173,6 +194,11 @@ int ath_set_channel(struct ath_softc *sc
|
|
if (sc->sc_flags & SC_OP_INVALID)
|
|
return -EIO;
|
|
|
|
+ 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);
|
|
+
|
|
ath9k_ps_wakeup(sc);
|
|
|
|
/*
|
|
@@ -192,7 +218,7 @@ int ath_set_channel(struct ath_softc *sc
|
|
* to flush data frames already in queue because of
|
|
* changing channel. */
|
|
|
|
- if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
|
|
+ if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL))
|
|
fastcc = false;
|
|
|
|
ath_print(common, ATH_DBG_CONFIG,
|
|
@@ -213,8 +239,6 @@ int ath_set_channel(struct ath_softc *sc
|
|
}
|
|
spin_unlock_bh(&sc->sc_resetlock);
|
|
|
|
- sc->sc_flags &= ~SC_OP_FULL_RESET;
|
|
-
|
|
if (ath_startrecv(sc) != 0) {
|
|
ath_print(common, ATH_DBG_FATAL,
|
|
"Unable to restart recv logic\n");
|
|
@@ -226,6 +250,12 @@ int ath_set_channel(struct ath_softc *sc
|
|
ath_update_txpow(sc);
|
|
ath9k_hw_set_interrupts(ah, ah->imask);
|
|
|
|
+ if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) {
|
|
+ ath_start_ani(common);
|
|
+ ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
|
|
+ ath_beacon_config(sc, NULL);
|
|
+ }
|
|
+
|
|
ps_restore:
|
|
ath9k_ps_restore(sc);
|
|
return r;
|
|
@@ -440,8 +470,7 @@ set_timer:
|
|
cal_interval = min(cal_interval, (u32)short_cal_interval);
|
|
|
|
mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
|
|
- if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) &&
|
|
- !(sc->sc_flags & SC_OP_SCANNING)) {
|
|
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) {
|
|
if (!sc->sc_ah->curchan->paprd_done)
|
|
ieee80211_queue_work(sc->hw, &sc->paprd_work);
|
|
else
|
|
@@ -449,24 +478,6 @@ set_timer:
|
|
}
|
|
}
|
|
|
|
-static void ath_start_ani(struct ath_common *common)
|
|
-{
|
|
- struct ath_hw *ah = common->ah;
|
|
- unsigned long timestamp = jiffies_to_msecs(jiffies);
|
|
- struct ath_softc *sc = (struct ath_softc *) common->priv;
|
|
-
|
|
- if (!(sc->sc_flags & SC_OP_ANI_RUN))
|
|
- return;
|
|
-
|
|
- common->ani.longcal_timer = timestamp;
|
|
- common->ani.shortcal_timer = timestamp;
|
|
- common->ani.checkani_timer = timestamp;
|
|
-
|
|
- mod_timer(&common->ani.timer,
|
|
- jiffies +
|
|
- msecs_to_jiffies((u32)ah->config.ani_poll_interval));
|
|
-}
|
|
-
|
|
/*
|
|
* Update tx/rx chainmask. For legacy association,
|
|
* hard code chainmask to 1x1, for 11n association, use
|
|
@@ -478,7 +489,7 @@ void ath_update_chainmask(struct ath_sof
|
|
struct ath_hw *ah = sc->sc_ah;
|
|
struct ath_common *common = ath9k_hw_common(ah);
|
|
|
|
- if ((sc->sc_flags & SC_OP_SCANNING) || is_ht ||
|
|
+ if ((sc->sc_flags & SC_OP_OFFCHANNEL) || is_ht ||
|
|
(ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) {
|
|
common->tx_chainmask = ah->caps.tx_chainmask;
|
|
common->rx_chainmask = ah->caps.rx_chainmask;
|
|
@@ -1580,6 +1591,10 @@ static int ath9k_config(struct ieee80211
|
|
|
|
aphy->chan_idx = pos;
|
|
aphy->chan_is_ht = conf_is_ht(conf);
|
|
+ if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
|
|
+ sc->sc_flags |= SC_OP_OFFCHANNEL;
|
|
+ else
|
|
+ sc->sc_flags &= ~SC_OP_OFFCHANNEL;
|
|
|
|
if (aphy->state == ATH_WIPHY_SCAN ||
|
|
aphy->state == ATH_WIPHY_ACTIVE)
|
|
@@ -1991,7 +2006,6 @@ static void ath9k_sw_scan_start(struct i
|
|
{
|
|
struct ath_wiphy *aphy = hw->priv;
|
|
struct ath_softc *sc = aphy->sc;
|
|
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
|
|
|
mutex_lock(&sc->mutex);
|
|
if (ath9k_wiphy_scanning(sc)) {
|
|
@@ -2007,11 +2021,6 @@ static void ath9k_sw_scan_start(struct i
|
|
|
|
aphy->state = ATH_WIPHY_SCAN;
|
|
ath9k_wiphy_pause_all_forced(sc, aphy);
|
|
- 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);
|
|
}
|
|
|
|
@@ -2019,15 +2028,9 @@ static void ath9k_sw_scan_complete(struc
|
|
{
|
|
struct ath_wiphy *aphy = hw->priv;
|
|
struct ath_softc *sc = aphy->sc;
|
|
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
|
|
|
mutex_lock(&sc->mutex);
|
|
aphy->state = ATH_WIPHY_ACTIVE;
|
|
- sc->sc_flags &= ~SC_OP_SCANNING;
|
|
- sc->sc_flags |= SC_OP_FULL_RESET;
|
|
- ath_start_ani(common);
|
|
- ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
|
|
- ath_beacon_config(sc, NULL);
|
|
mutex_unlock(&sc->mutex);
|
|
}
|
|
|
|
--- a/drivers/net/wireless/ath/ath9k/recv.c
|
|
+++ b/drivers/net/wireless/ath/ath9k/recv.c
|
|
@@ -292,7 +292,7 @@ static void ath_edma_start_recv(struct a
|
|
|
|
ath_opmode_init(sc);
|
|
|
|
- ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_SCANNING));
|
|
+ ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL));
|
|
}
|
|
|
|
static void ath_edma_stop_recv(struct ath_softc *sc)
|
|
@@ -498,7 +498,7 @@ int ath_startrecv(struct ath_softc *sc)
|
|
start_recv:
|
|
spin_unlock_bh(&sc->rx.rxbuflock);
|
|
ath_opmode_init(sc);
|
|
- ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_SCANNING));
|
|
+ ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL));
|
|
|
|
return 0;
|
|
}
|