Fresh pull from upstream 17.01 branch
[librecmc/librecmc.git] / package / kernel / mac80211 / patches / 314-ath9k-rename-tx_complete_work-to-hw_check_work.patch
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Wed, 25 Jan 2017 12:57:05 +0100
3 Subject: [PATCH] ath9k: rename tx_complete_work to hw_check_work
4
5 Also include common MAC alive check. This should make the hang checks
6 more reliable for modes where beacons are not sent and is used as a
7 starting point for further hang check improvements
8
9 Signed-off-by: Felix Fietkau <nbd@nbd.name>
10 ---
11
12 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
13 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
14 @@ -108,7 +108,7 @@ int ath_descdma_setup(struct ath_softc *
15  #define ATH_AGGR_MIN_QDEPTH        2
16  /* minimum h/w qdepth for non-aggregated traffic */
17  #define ATH_NON_AGGR_MIN_QDEPTH    8
18 -#define ATH_TX_COMPLETE_POLL_INT   1000
19 +#define ATH_HW_CHECK_POLL_INT      1000
20  #define ATH_TXFIFO_DEPTH           8
21  #define ATH_TX_ERROR               0x01
22  
23 @@ -745,7 +745,7 @@ void ath9k_csa_update(struct ath_softc *
24  #define ATH_PAPRD_TIMEOUT         100 /* msecs */
25  #define ATH_PLL_WORK_INTERVAL     100
26  
27 -void ath_tx_complete_poll_work(struct work_struct *work);
28 +void ath_hw_check_work(struct work_struct *work);
29  void ath_reset_work(struct work_struct *work);
30  bool ath_hw_check(struct ath_softc *sc);
31  void ath_hw_pll_work(struct work_struct *work);
32 @@ -1053,7 +1053,7 @@ struct ath_softc {
33  #ifdef CPTCFG_ATH9K_DEBUGFS
34         struct ath9k_debug debug;
35  #endif
36 -       struct delayed_work tx_complete_work;
37 +       struct delayed_work hw_check_work;
38         struct delayed_work hw_pll_work;
39         struct timer_list sleep_timer;
40  
41 --- a/drivers/net/wireless/ath/ath9k/init.c
42 +++ b/drivers/net/wireless/ath/ath9k/init.c
43 @@ -681,6 +681,7 @@ static int ath9k_init_softc(u16 devid, s
44         INIT_WORK(&sc->hw_reset_work, ath_reset_work);
45         INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
46         INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
47 +       INIT_DELAYED_WORK(&sc->hw_check_work, ath_hw_check_work);
48  
49         ath9k_init_channel_context(sc);
50  
51 --- a/drivers/net/wireless/ath/ath9k/link.c
52 +++ b/drivers/net/wireless/ath/ath9k/link.c
53 @@ -20,20 +20,13 @@
54   * TX polling - checks if the TX engine is stuck somewhere
55   * and issues a chip reset if so.
56   */
57 -void ath_tx_complete_poll_work(struct work_struct *work)
58 +static bool ath_tx_complete_check(struct ath_softc *sc)
59  {
60 -       struct ath_softc *sc = container_of(work, struct ath_softc,
61 -                                           tx_complete_work.work);
62         struct ath_txq *txq;
63         int i;
64 -       bool needreset = false;
65 -
66  
67 -       if (sc->tx99_state) {
68 -               ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
69 -                       "skip tx hung detection on tx99\n");
70 -               return;
71 -       }
72 +       if (sc->tx99_state)
73 +               return true;
74  
75         for (i = 0; i < IEEE80211_NUM_ACS; i++) {
76                 txq = sc->tx.txq_map[i];
77 @@ -41,25 +34,36 @@ void ath_tx_complete_poll_work(struct wo
78                 ath_txq_lock(sc, txq);
79                 if (txq->axq_depth) {
80                         if (txq->axq_tx_inprogress) {
81 -                               needreset = true;
82                                 ath_txq_unlock(sc, txq);
83 -                               break;
84 -                       } else {
85 -                               txq->axq_tx_inprogress = true;
86 +                               goto reset;
87                         }
88 +
89 +                       txq->axq_tx_inprogress = true;
90                 }
91                 ath_txq_unlock(sc, txq);
92         }
93  
94 -       if (needreset) {
95 -               ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
96 -                       "tx hung, resetting the chip\n");
97 -               ath9k_queue_reset(sc, RESET_TYPE_TX_HANG);
98 +       return true;
99 +
100 +reset:
101 +       ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
102 +               "tx hung, resetting the chip\n");
103 +       ath9k_queue_reset(sc, RESET_TYPE_TX_HANG);
104 +       return false;
105 +
106 +}
107 +
108 +void ath_hw_check_work(struct work_struct *work)
109 +{
110 +       struct ath_softc *sc = container_of(work, struct ath_softc,
111 +                                           hw_check_work.work);
112 +
113 +       if (!ath_hw_check(sc) ||
114 +           !ath_tx_complete_check(sc))
115                 return;
116 -       }
117  
118 -       ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
119 -                                    msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT));
120 +       ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work,
121 +                                    msecs_to_jiffies(ATH_HW_CHECK_POLL_INT));
122  }
123  
124  /*
125 --- a/drivers/net/wireless/ath/ath9k/main.c
126 +++ b/drivers/net/wireless/ath/ath9k/main.c
127 @@ -181,7 +181,7 @@ void ath9k_ps_restore(struct ath_softc *
128  static void __ath_cancel_work(struct ath_softc *sc)
129  {
130         cancel_work_sync(&sc->paprd_work);
131 -       cancel_delayed_work_sync(&sc->tx_complete_work);
132 +       cancel_delayed_work_sync(&sc->hw_check_work);
133         cancel_delayed_work_sync(&sc->hw_pll_work);
134  
135  #ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT
136 @@ -198,7 +198,8 @@ void ath_cancel_work(struct ath_softc *s
137  
138  void ath_restart_work(struct ath_softc *sc)
139  {
140 -       ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
141 +       ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work,
142 +                                    ATH_HW_CHECK_POLL_INT);
143  
144         if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9330(sc->sc_ah))
145                 ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work,
146 @@ -2091,7 +2092,7 @@ void __ath9k_flush(struct ieee80211_hw *
147         int timeout;
148         bool drain_txq;
149  
150 -       cancel_delayed_work_sync(&sc->tx_complete_work);
151 +       cancel_delayed_work_sync(&sc->hw_check_work);
152  
153         if (ah->ah_flags & AH_UNPLUGGED) {
154                 ath_dbg(common, ANY, "Device has been unplugged!\n");
155 @@ -2129,7 +2130,8 @@ void __ath9k_flush(struct ieee80211_hw *
156                 ath9k_ps_restore(sc);
157         }
158  
159 -       ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
160 +       ieee80211_queue_delayed_work(hw, &sc->hw_check_work,
161 +                                    ATH_HW_CHECK_POLL_INT);
162  }
163  
164  static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
165 --- a/drivers/net/wireless/ath/ath9k/xmit.c
166 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
167 @@ -2916,8 +2916,6 @@ int ath_tx_init(struct ath_softc *sc, in
168                 return error;
169         }
170  
171 -       INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
172 -
173         if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
174                 error = ath_tx_edma_init(sc);
175