aboutsummaryrefslogtreecommitdiffstats
path: root/package/mac80211/patches/582-ath9k_merge_reset_functions.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/mac80211/patches/582-ath9k_merge_reset_functions.patch')
-rw-r--r--package/mac80211/patches/582-ath9k_merge_reset_functions.patch448
1 files changed, 0 insertions, 448 deletions
diff --git a/package/mac80211/patches/582-ath9k_merge_reset_functions.patch b/package/mac80211/patches/582-ath9k_merge_reset_functions.patch
deleted file mode 100644
index 54d0eafc89..0000000000
--- a/package/mac80211/patches/582-ath9k_merge_reset_functions.patch
+++ /dev/null
@@ -1,448 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -212,84 +212,57 @@ static int ath_update_survey_stats(struc
- return ret;
- }
-
--/*
-- * 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
-- * DMA, then restart stuff.
--*/
--static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
-- struct ath9k_channel *hchan)
-+static void __ath_cancel_work(struct ath_softc *sc)
- {
-- struct ath_hw *ah = sc->sc_ah;
-- struct ath_common *common = ath9k_hw_common(ah);
-- struct ieee80211_conf *conf = &common->hw->conf;
-- bool fastcc = true, stopped;
-- struct ieee80211_channel *channel = hw->conf.channel;
-- struct ath9k_hw_cal_data *caldata = NULL;
-- int r;
--
-- if (sc->sc_flags & SC_OP_INVALID)
-- return -EIO;
--
-- sc->hw_busy_count = 0;
--
-- del_timer_sync(&common->ani.timer);
- cancel_work_sync(&sc->paprd_work);
- cancel_work_sync(&sc->hw_check_work);
-- cancel_work_sync(&sc->hw_reset_work);
- cancel_delayed_work_sync(&sc->tx_complete_work);
- cancel_delayed_work_sync(&sc->hw_pll_work);
-+}
-
-- ath9k_ps_wakeup(sc);
-+static void ath_cancel_work(struct ath_softc *sc)
-+{
-+ __ath_cancel_work(sc);
-+ cancel_work_sync(&sc->hw_reset_work);
-+}
-
-- spin_lock_bh(&sc->sc_pcu_lock);
-+static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
-+{
-+ struct ath_hw *ah = sc->sc_ah;
-+ struct ath_common *common = ath9k_hw_common(ah);
-+ bool ret;
-
-- /*
-- * This is only performed if the channel settings have
-- * actually changed.
-- *
-- * To switch channels clear any pending DMA operations;
-- * wait long enough for the RX fifo to drain, reset the
-- * hardware at the new frequency, and then re-enable
-- * the relevant bits of the h/w.
-- */
-- ath9k_hw_disable_interrupts(ah);
-- stopped = ath_drain_all_txq(sc, false);
-+ ieee80211_stop_queues(sc->hw);
-
-- if (!ath_stoprecv(sc))
-- stopped = false;
-+ sc->hw_busy_count = 0;
-+ del_timer_sync(&common->ani.timer);
-
-- if (!ath9k_hw_check_alive(ah))
-- stopped = false;
-+ ath9k_hw_disable_interrupts(ah);
-
-- /* XXX: do not flush receive queue here. We don't want
-- * to flush data frames already in queue because of
-- * changing channel. */
-+ ret = ath_drain_all_txq(sc, retry_tx);
-
-- if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL))
-- fastcc = false;
-+ if (!ath_stoprecv(sc))
-+ ret = false;
-
-- if (!(sc->sc_flags & SC_OP_OFFCHANNEL))
-- caldata = &sc->caldata;
-+ if (!flush) {
-+ if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
-+ ath_rx_tasklet(sc, 0, true);
-+ ath_rx_tasklet(sc, 0, false);
-+ } else {
-+ ath_flushrecv(sc);
-+ }
-
-- ath_dbg(common, ATH_DBG_CONFIG,
-- "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n",
-- sc->sc_ah->curchan->channel,
-- channel->center_freq, conf_is_ht40(conf),
-- fastcc);
-+ return ret;
-+}
-
-- r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
-- if (r) {
-- ath_err(common,
-- "Unable to reset channel (%u MHz), reset status %d\n",
-- channel->center_freq, r);
-- goto ps_restore;
-- }
-+static bool ath_complete_reset(struct ath_softc *sc, bool start)
-+{
-+ struct ath_hw *ah = sc->sc_ah;
-+ struct ath_common *common = ath9k_hw_common(ah);
-
- if (ath_startrecv(sc) != 0) {
- ath_err(common, "Unable to restart recv logic\n");
-- r = -EIO;
-- goto ps_restore;
-+ return false;
- }
-
- ath9k_cmn_update_txpow(ah, sc->curtxpow,
-@@ -297,21 +270,93 @@ static int ath_set_channel(struct ath_so
- ath9k_hw_set_interrupts(ah, ah->imask);
- ath9k_hw_enable_interrupts(ah);
-
-- if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
-+ if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && start) {
- if (sc->sc_flags & SC_OP_BEACONS)
- ath_set_beacon(sc);
-+
- ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
- ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2);
- if (!common->disable_ani)
- ath_start_ani(common);
- }
-
-- ps_restore:
-- ieee80211_wake_queues(hw);
-+ ieee80211_wake_queues(sc->hw);
-+
-+ return true;
-+}
-+
-+static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
-+ bool retry_tx)
-+{
-+ struct ath_hw *ah = sc->sc_ah;
-+ struct ath_common *common = ath9k_hw_common(ah);
-+ struct ath9k_hw_cal_data *caldata = NULL;
-+ bool fastcc = true;
-+ bool flush = false;
-+ int r;
-+
-+ __ath_cancel_work(sc);
-+
-+ spin_lock_bh(&sc->sc_pcu_lock);
-
-+ if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) {
-+ fastcc = false;
-+ caldata = &sc->caldata;
-+ }
-+
-+ if (!hchan) {
-+ fastcc = false;
-+ flush = true;
-+ hchan = ah->curchan;
-+ }
-+
-+ if (fastcc && !ath9k_hw_check_alive(ah))
-+ fastcc = false;
-+
-+ if (!ath_prepare_reset(sc, retry_tx, flush))
-+ fastcc = false;
-+
-+ ath_dbg(common, ATH_DBG_CONFIG,
-+ "Reset to %u MHz, HT40: %d fastcc: %d\n",
-+ hchan->channel, !!(hchan->channelFlags & (CHANNEL_HT40MINUS |
-+ CHANNEL_HT40PLUS)),
-+ fastcc);
-+
-+ r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
-+ if (r) {
-+ ath_err(common,
-+ "Unable to reset channel, reset status %d\n", r);
-+ goto out;
-+ }
-+
-+ if (!ath_complete_reset(sc, true))
-+ r = -EIO;
-+
-+out:
- spin_unlock_bh(&sc->sc_pcu_lock);
-+ return r;
-+}
-+
-+
-+/*
-+ * 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
-+ * DMA, then restart stuff.
-+*/
-+static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
-+ struct ath9k_channel *hchan)
-+{
-+ int r;
-+
-+ if (sc->sc_flags & SC_OP_INVALID)
-+ return -EIO;
-+
-+ ath9k_ps_wakeup(sc);
-+
-+ r = ath_reset_internal(sc, hchan, false);
-
- ath9k_ps_restore(sc);
-+
- return r;
- }
-
-@@ -824,28 +869,13 @@ static void ath_radio_enable(struct ath_
- channel->center_freq, r);
- }
-
-- ath9k_cmn_update_txpow(ah, sc->curtxpow,
-- sc->config.txpowlimit, &sc->curtxpow);
-- if (ath_startrecv(sc) != 0) {
-- ath_err(common, "Unable to restart recv logic\n");
-- goto out;
-- }
-- if (sc->sc_flags & SC_OP_BEACONS)
-- ath_set_beacon(sc); /* restart beacons */
--
-- /* Re-Enable interrupts */
-- ath9k_hw_set_interrupts(ah, ah->imask);
-- ath9k_hw_enable_interrupts(ah);
-+ ath_complete_reset(sc, true);
-
- /* Enable LED */
- ath9k_hw_cfg_output(ah, ah->led_pin,
- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- ath9k_hw_set_gpio(ah, ah->led_pin, 0);
-
-- ieee80211_wake_queues(hw);
-- ieee80211_queue_delayed_work(hw, &sc->hw_pll_work, HZ/2);
--
--out:
- spin_unlock_bh(&sc->sc_pcu_lock);
-
- ath9k_ps_restore(sc);
-@@ -858,11 +888,10 @@ void ath_radio_disable(struct ath_softc
- int r;
-
- ath9k_ps_wakeup(sc);
-- cancel_delayed_work_sync(&sc->hw_pll_work);
-
-- spin_lock_bh(&sc->sc_pcu_lock);
-+ ath_cancel_work(sc);
-
-- ieee80211_stop_queues(hw);
-+ spin_lock_bh(&sc->sc_pcu_lock);
-
- /*
- * Keep the LED on when the radio is disabled
-@@ -873,13 +902,7 @@ void ath_radio_disable(struct ath_softc
- ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
- }
-
-- /* Disable interrupts */
-- ath9k_hw_disable_interrupts(ah);
--
-- ath_drain_all_txq(sc, false); /* clear pending tx frames */
--
-- ath_stoprecv(sc); /* turn off frame recv */
-- ath_flushrecv(sc); /* flush recv queue */
-+ ath_prepare_reset(sc, false, true);
-
- if (!ah->curchan)
- ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
-@@ -901,48 +924,11 @@ void ath_radio_disable(struct ath_softc
-
- static int ath_reset(struct ath_softc *sc, bool retry_tx)
- {
-- struct ath_hw *ah = sc->sc_ah;
-- struct ath_common *common = ath9k_hw_common(ah);
-- struct ieee80211_hw *hw = sc->hw;
- int r;
-
-- sc->hw_busy_count = 0;
--
-- /* Stop ANI */
--
-- del_timer_sync(&common->ani.timer);
--
- ath9k_ps_wakeup(sc);
-
-- ieee80211_stop_queues(hw);
--
-- ath9k_hw_disable_interrupts(ah);
-- ath_drain_all_txq(sc, retry_tx);
--
-- ath_stoprecv(sc);
-- ath_flushrecv(sc);
--
-- r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
-- if (r)
-- ath_err(common,
-- "Unable to reset hardware; reset status %d\n", r);
--
-- if (ath_startrecv(sc) != 0)
-- ath_err(common, "Unable to start recv logic\n");
--
-- /*
-- * We may be doing a reset in response to a request
-- * that changes the channel so update any state that
-- * might change as a result.
-- */
-- ath9k_cmn_update_txpow(ah, sc->curtxpow,
-- sc->config.txpowlimit, &sc->curtxpow);
--
-- if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL)))
-- ath_set_beacon(sc); /* restart beacons */
--
-- ath9k_hw_set_interrupts(ah, ah->imask);
-- ath9k_hw_enable_interrupts(ah);
-+ r = ath_reset_internal(sc, NULL, retry_tx);
-
- if (retry_tx) {
- int i;
-@@ -955,12 +941,6 @@ static int ath_reset(struct ath_softc *s
- }
- }
-
-- ieee80211_wake_queues(hw);
--
-- /* Start ANI */
-- if (!common->disable_ani)
-- ath_start_ani(common);
--
- ath9k_ps_restore(sc);
-
- return r;
-@@ -970,9 +950,7 @@ void ath_reset_work(struct work_struct *
- {
- struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work);
-
-- spin_lock_bh(&sc->sc_pcu_lock);
- ath_reset(sc, true);
-- spin_unlock_bh(&sc->sc_pcu_lock);
- }
-
- void ath_hw_check(struct work_struct *work)
-@@ -993,11 +971,8 @@ void ath_hw_check(struct work_struct *wo
- ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, "
- "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
- if (busy >= 99) {
-- if (++sc->hw_busy_count >= 3) {
-- spin_lock_bh(&sc->sc_pcu_lock);
-- ath_reset(sc, true);
-- spin_unlock_bh(&sc->sc_pcu_lock);
-- }
-+ if (++sc->hw_busy_count >= 3)
-+ ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
-
- } else if (busy >= 0)
- sc->hw_busy_count = 0;
-@@ -1017,9 +992,7 @@ static void ath_hw_pll_rx_hang_check(str
- /* Rx is hung for more than 500ms. Reset it */
- ath_dbg(common, ATH_DBG_RESET,
- "Possible RX hang, resetting");
-- spin_lock_bh(&sc->sc_pcu_lock);
-- ath_reset(sc, true);
-- spin_unlock_bh(&sc->sc_pcu_lock);
-+ ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
- count = 0;
- }
- } else
-@@ -1090,28 +1063,6 @@ static int ath9k_start(struct ieee80211_
- goto mutex_unlock;
- }
-
-- /*
-- * This is needed only to setup initial state
-- * but it's best done after a reset.
-- */
-- ath9k_cmn_update_txpow(ah, sc->curtxpow,
-- sc->config.txpowlimit, &sc->curtxpow);
--
-- /*
-- * Setup the hardware after reset:
-- * The receive engine is set going.
-- * Frame transmit is handled entirely
-- * in the frame output path; there's nothing to do
-- * here except setup the interrupt mask.
-- */
-- if (ath_startrecv(sc) != 0) {
-- ath_err(common, "Unable to start recv logic\n");
-- r = -EIO;
-- spin_unlock_bh(&sc->sc_pcu_lock);
-- goto mutex_unlock;
-- }
-- spin_unlock_bh(&sc->sc_pcu_lock);
--
- /* Setup our intr mask. */
- ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
- ATH9K_INT_RXORN | ATH9K_INT_FATAL |
-@@ -1134,12 +1085,14 @@ static int ath9k_start(struct ieee80211_
-
- /* Disable BMISS interrupt when we're not associated */
- ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
-- ath9k_hw_set_interrupts(ah, ah->imask);
-- ath9k_hw_enable_interrupts(ah);
-
-- ieee80211_wake_queues(hw);
-+ if (!ath_complete_reset(sc, false)) {
-+ r = -EIO;
-+ spin_unlock_bh(&sc->sc_pcu_lock);
-+ goto mutex_unlock;
-+ }
-
-- ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
-+ spin_unlock_bh(&sc->sc_pcu_lock);
-
- if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
- !ah->btcoex_hw.enabled) {
-@@ -1232,11 +1185,7 @@ static void ath9k_stop(struct ieee80211_
-
- mutex_lock(&sc->mutex);
-
-- cancel_delayed_work_sync(&sc->tx_complete_work);
-- cancel_delayed_work_sync(&sc->hw_pll_work);
-- cancel_work_sync(&sc->paprd_work);
-- cancel_work_sync(&sc->hw_check_work);
-- cancel_work_sync(&sc->hw_reset_work);
-+ ath_cancel_work(sc);
-
- if (sc->sc_flags & SC_OP_INVALID) {
- ath_dbg(common, ATH_DBG_ANY, "Device not present\n");
-@@ -2353,9 +2302,11 @@ static void ath9k_flush(struct ieee80211
- ath9k_ps_wakeup(sc);
- spin_lock_bh(&sc->sc_pcu_lock);
- drain_txq = ath_drain_all_txq(sc, false);
-+ spin_unlock_bh(&sc->sc_pcu_lock);
-+
- if (!drain_txq)
- ath_reset(sc, false);
-- spin_unlock_bh(&sc->sc_pcu_lock);
-+
- ath9k_ps_restore(sc);
- ieee80211_wake_queues(hw);
-