ath9k: remove a lock to fix a deadlock on hw reset
authorFelix Fietkau <nbd@openwrt.org>
Mon, 14 Jan 2013 09:52:14 +0000 (09:52 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Mon, 14 Jan 2013 09:52:14 +0000 (09:52 +0000)
Backport of r35147

SVN-Revision: 35148

package/mac80211/patches/300-pending_work.patch
package/mac80211/patches/512-ath9k_channelbw_debugfs.patch
package/mac80211/patches/522-ath9k_per_chain_signal_strength.patch
package/mac80211/patches/540-ath9k_extra_leds.patch

index 74d1377040f0c57efe297dfd538cd45b9f929552..c0240ad01e38043927de3926f1002f8de269f237 100644 (file)
  static DECLARE_WORK(reg_regdb_work, reg_regdb_search);
 --- a/drivers/net/wireless/ath/ath9k/recv.c
 +++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -286,7 +286,6 @@ int ath_rx_init(struct ath_softc *sc, in
+@@ -254,8 +254,6 @@ rx_init_fail:
+ static void ath_edma_start_recv(struct ath_softc *sc)
+ {
+-      spin_lock_bh(&sc->rx.rxbuflock);
+-
+       ath9k_hw_rxena(sc->sc_ah);
+       ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP,
+@@ -267,8 +265,6 @@ static void ath_edma_start_recv(struct a
+       ath_opmode_init(sc);
+       ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
+-
+-      spin_unlock_bh(&sc->rx.rxbuflock);
+ }
+ static void ath_edma_stop_recv(struct ath_softc *sc)
+@@ -285,8 +281,6 @@ int ath_rx_init(struct ath_softc *sc, in
+       int error = 0;
  
        spin_lock_init(&sc->sc_pcu_lock);
-       spin_lock_init(&sc->rx.rxbuflock);
+-      spin_lock_init(&sc->rx.rxbuflock);
 -      clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
  
        common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
                             sc->sc_ah->caps.rx_status_len;
-@@ -424,8 +423,8 @@ u32 ath_calcrxfilter(struct ath_softc *s
+@@ -424,8 +418,8 @@ u32 ath_calcrxfilter(struct ath_softc *s
                rfilt |= ATH9K_RX_FILTER_COMP_BAR;
  
        if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) {
                        rfilt |= ATH9K_RX_FILTER_PROM;
                rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
        }
-@@ -473,6 +472,13 @@ start_recv:
+@@ -447,7 +441,6 @@ int ath_startrecv(struct ath_softc *sc)
+               return 0;
+       }
+-      spin_lock_bh(&sc->rx.rxbuflock);
+       if (list_empty(&sc->rx.rxbuf))
+               goto start_recv;
+@@ -468,26 +461,31 @@ start_recv:
+       ath_opmode_init(sc);
+       ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));
+-      spin_unlock_bh(&sc->rx.rxbuflock);
+-
        return 0;
  }
  
  bool ath_stoprecv(struct ath_softc *sc)
  {
        struct ath_hw *ah = sc->sc_ah;
-@@ -483,6 +489,8 @@ bool ath_stoprecv(struct ath_softc *sc)
+       bool stopped, reset = false;
+-      spin_lock_bh(&sc->rx.rxbuflock);
+       ath9k_hw_abortpcurecv(ah);
        ath9k_hw_setrxfilter(ah, 0);
        stopped = ath9k_hw_stopdmarecv(ah, &reset);
  
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
                ath_edma_stop_recv(sc);
        else
-@@ -499,15 +507,6 @@ bool ath_stoprecv(struct ath_softc *sc)
+               sc->rx.rxlink = NULL;
+-      spin_unlock_bh(&sc->rx.rxbuflock);
+       if (!(ah->ah_flags & AH_UNPLUGGED) &&
+           unlikely(!stopped)) {
+@@ -499,15 +497,6 @@ bool ath_stoprecv(struct ath_softc *sc)
        return stopped && !reset;
  }
  
  static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
  {
        /* Check whether the Beacon frame has DTIM indicating buffered bc/mc */
-@@ -744,6 +743,7 @@ static struct ath_buf *ath_get_next_rx_b
+@@ -744,6 +733,7 @@ static struct ath_buf *ath_get_next_rx_b
                        return NULL;
        }
  
        if (!bf->bf_mpdu)
                return bf;
  
-@@ -1066,9 +1066,6 @@ int ath_rx_tasklet(struct ath_softc *sc,
+@@ -1059,16 +1049,12 @@ int ath_rx_tasklet(struct ath_softc *sc,
+               dma_type = DMA_FROM_DEVICE;
+       qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
+-      spin_lock_bh(&sc->rx.rxbuflock);
+       tsf = ath9k_hw_gettsf64(ah);
+       tsf_lower = tsf & 0xffffffff;
  
        do {
                bool decrypt_error = false;
  
                memset(&rs, 0, sizeof(rs));
                if (edma)
-@@ -1108,15 +1105,6 @@ int ath_rx_tasklet(struct ath_softc *sc,
+@@ -1108,15 +1094,6 @@ int ath_rx_tasklet(struct ath_softc *sc,
                sc->rx.num_pkts++;
                ath_debug_stat_rx(sc, &rs);
  
                memset(rxs, 0, sizeof(struct ieee80211_rx_status));
  
                rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
-@@ -1251,14 +1239,15 @@ requeue_drop_frag:
+@@ -1251,19 +1228,18 @@ requeue_drop_frag:
                        sc->rx.frag = NULL;
                }
  requeue:
                }
        } while (1);
  
+-      spin_unlock_bh(&sc->rx.rxbuflock);
+-
+       if (!(ah->imask & ATH9K_INT_RXEOL)) {
+               ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
+               ath9k_hw_set_interrupts(ah);
 --- a/net/mac80211/mlme.c
 +++ b/net/mac80211/mlme.c
 @@ -818,23 +818,71 @@ void ieee80211_sta_process_chanswitch(st
  
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -324,7 +324,6 @@ struct ath_rx {
+@@ -313,7 +313,6 @@ struct ath_rx {
+       u32 *rxlink;
+       u32 num_pkts;
+       unsigned int rxfilter;
+-      spinlock_t rxbuflock;
+       struct list_head rxbuf;
+       struct ath_descdma rxdma;
+       struct ath_buf *rx_bufptr;
+@@ -324,7 +323,6 @@ struct ath_rx {
  
  int ath_startrecv(struct ath_softc *sc);
  bool ath_stoprecv(struct ath_softc *sc);
  u32 ath_calcrxfilter(struct ath_softc *sc);
  int ath_rx_init(struct ath_softc *sc, int nbufs);
  void ath_rx_cleanup(struct ath_softc *sc);
-@@ -627,7 +626,6 @@ void ath_ant_comb_update(struct ath_soft
+@@ -627,7 +625,6 @@ void ath_ant_comb_update(struct ath_soft
  enum sc_op_flags {
        SC_OP_INVALID,
        SC_OP_BEACONS,
index e64132e03a5f979df17d8bd28319f38477513a7d..db6d36b68e00e8c1bf72f928b1f79d5fc91b4cac 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -657,6 +657,7 @@ struct ath_softc {
+@@ -656,6 +656,7 @@ struct ath_softc {
        struct ieee80211_hw *hw;
        struct device *dev;
  
@@ -8,7 +8,7 @@
        struct survey_info *cur_survey;
        struct survey_info survey[ATH9K_NUM_CHANNELS];
  
-@@ -732,6 +733,7 @@ struct ath_softc {
+@@ -731,6 +732,7 @@ struct ath_softc {
  #endif
  };
  
index 2be0b56f44583eb512fc819230552a9c522d1061..9df453c2f52d26d6e78d9fe3410bdb7d87aeb84d 100644 (file)
        u8 rs_num_delims;
 --- a/drivers/net/wireless/ath/ath9k/recv.c
 +++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -955,6 +955,7 @@ static int ath9k_rx_skb_preprocess(struc
+@@ -945,6 +945,7 @@ static int ath9k_rx_skb_preprocess(struc
                                   bool *decrypt_error)
  {
        struct ath_hw *ah = common->ah;
  
        /*
         * everything but the rate is checked here, the rate check is done
-@@ -980,6 +981,20 @@ static int ath9k_rx_skb_preprocess(struc
+@@ -970,6 +971,20 @@ static int ath9k_rx_skb_preprocess(struc
        if (rx_stats->rs_moreaggr)
                rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
  
index 26bee95c372b391fad507097933acc135fe6b6a2..290853426bcca59afb6304f5dcef0c154606b193 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -537,6 +537,9 @@ struct ath9k_wow_pattern {
+@@ -536,6 +536,9 @@ struct ath9k_wow_pattern {
  #ifdef CONFIG_MAC80211_LEDS
  void ath_init_leds(struct ath_softc *sc);
  void ath_deinit_leds(struct ath_softc *sc);
@@ -10,7 +10,7 @@
  #else
  static inline void ath_init_leds(struct ath_softc *sc)
  {
-@@ -653,6 +656,13 @@ struct ath9k_vif_iter_data {
+@@ -652,6 +655,13 @@ struct ath9k_vif_iter_data {
        int nadhocs;   /* number of adhoc vifs */
  };
  
@@ -24,7 +24,7 @@
  struct ath_softc {
        struct ieee80211_hw *hw;
        struct device *dev;
-@@ -694,9 +704,8 @@ struct ath_softc {
+@@ -693,9 +703,8 @@ struct ath_softc {
        struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
  
  #ifdef CONFIG_MAC80211_LEDS