Bump version to v1.5 and start work on adding 4.19 kernel suppot
[librecmc/librecmc.git] / package / kernel / mac80211 / patches / 301-ath9k_hw-issue-external-reset-for-QCA955x.patch
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Sat, 9 Jul 2016 15:26:44 +0200
3 Subject: [PATCH] ath9k_hw: issue external reset for QCA955x
4
5 The RTC interface on the SoC needs to be reset along with the rest of
6 the WMAC.
7
8 Signed-off-by: Felix Fietkau <nbd@nbd.name>
9 ---
10
11 --- a/drivers/net/wireless/ath/ath9k/hw.c
12 +++ b/drivers/net/wireless/ath/ath9k/hw.c
13 @@ -1271,39 +1271,56 @@ void ath9k_hw_get_delta_slope_vals(struc
14         *coef_exponent = coef_exp - 16;
15  }
16  
17 -/* AR9330 WAR:
18 - * call external reset function to reset WMAC if:
19 - * - doing a cold reset
20 - * - we have pending frames in the TX queues.
21 - */
22 -static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type)
23 +static bool ath9k_hw_need_external_reset(struct ath_hw *ah, int type)
24  {
25 -       int i, npend = 0;
26 +       int i;
27  
28 -       for (i = 0; i < AR_NUM_QCU; i++) {
29 -               npend = ath9k_hw_numtxpending(ah, i);
30 -               if (npend)
31 -                       break;
32 -       }
33 -
34 -       if (ah->external_reset &&
35 -           (npend || type == ATH9K_RESET_COLD)) {
36 -               int reset_err = 0;
37 -
38 -               ath_dbg(ath9k_hw_common(ah), RESET,
39 -                       "reset MAC via external reset\n");
40 -
41 -               reset_err = ah->external_reset();
42 -               if (reset_err) {
43 -                       ath_err(ath9k_hw_common(ah),
44 -                               "External reset failed, err=%d\n",
45 -                               reset_err);
46 -                       return false;
47 +       if (type == ATH9K_RESET_COLD)
48 +               return true;
49 +
50 +       if (AR_SREV_9550(ah))
51 +               return true;
52 +
53 +       /* AR9330 WAR:
54 +        * call external reset function to reset WMAC if:
55 +        * - doing a cold reset
56 +        * - we have pending frames in the TX queues.
57 +        */
58 +       if (AR_SREV_9330(ah)) {
59 +               for (i = 0; i < AR_NUM_QCU; i++) {
60 +                       if (ath9k_hw_numtxpending(ah, i))
61 +                               return true;
62                 }
63 +       }
64 +
65 +       return false;
66 +}
67 +
68 +static bool ath9k_hw_external_reset(struct ath_hw *ah, int type)
69 +{
70 +       int err;
71 +
72 +       if (!ah->external_reset || !ath9k_hw_need_external_reset(ah, type))
73 +               return true;
74 +
75 +       ath_dbg(ath9k_hw_common(ah), RESET,
76 +               "reset MAC via external reset\n");
77  
78 -               REG_WRITE(ah, AR_RTC_RESET, 1);
79 +       err = ah->external_reset();
80 +       if (err) {
81 +               ath_err(ath9k_hw_common(ah),
82 +                       "External reset failed, err=%d\n", err);
83 +               return false;
84         }
85  
86 +       if (AR_SREV_9550(ah)) {
87 +               REG_WRITE(ah, AR_RTC_RESET, 0);
88 +               udelay(10);
89 +       }
90 +
91 +       REG_WRITE(ah, AR_RTC_RESET, 1);
92 +       udelay(10);
93 +
94         return true;
95  }
96  
97 @@ -1356,24 +1373,24 @@ static bool ath9k_hw_set_reset(struct at
98                         rst_flags |= AR_RTC_RC_MAC_COLD;
99         }
100  
101 -       if (AR_SREV_9330(ah)) {
102 -               if (!ath9k_hw_ar9330_reset_war(ah, type))
103 -                       return false;
104 -       }
105 -
106         if (ath9k_hw_mci_is_enabled(ah))
107                 ar9003_mci_check_gpm_offset(ah);
108  
109         /* DMA HALT added to resolve ar9300 and ar9580 bus error during
110 -        * RTC_RC reg read
111 +        * RTC_RC reg read. Also needed for AR9550 external reset
112          */
113 -       if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) {
114 +       if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) {
115                 REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
116                 ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK,
117                               20 * AH_WAIT_TIMEOUT);
118 -               REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
119         }
120  
121 +       if (!AR_SREV_9100(ah))
122 +               ath9k_hw_external_reset(ah, type);
123 +
124 +       if (AR_SREV_9300(ah) || AR_SREV_9580(ah))
125 +               REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
126 +
127         REG_WRITE(ah, AR_RTC_RC, rst_flags);
128  
129         REGWRITE_BUFFER_FLUSH(ah);