AA: mac80211: sync with trunk r41113
[12.09/openwrt.git] / package / mac80211 / patches / 565-ath9k_restart_after_nfcal_failure.patch
1 --- a/drivers/net/wireless/ath/ath9k/calib.c
2 +++ b/drivers/net/wireless/ath/ath9k/calib.c
3 @@ -234,7 +234,7 @@ void ath9k_hw_start_nfcal(struct ath_hw 
4         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
5  }
6  
7 -void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
8 +int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
9  {
10         struct ath9k_nfcal_hist *h = NULL;
11         unsigned i, j;
12 @@ -301,7 +301,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, 
13                 ath_dbg(common, ANY,
14                         "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n",
15                         REG_READ(ah, AR_PHY_AGC_CONTROL));
16 -               return;
17 +               return -ETIMEDOUT;
18         }
19  
20         /*
21 @@ -322,6 +322,8 @@ void ath9k_hw_loadnf(struct ath_hw *ah, 
22                 }
23         }
24         REGWRITE_BUFFER_FLUSH(ah);
25 +
26 +       return 0;
27  }
28  
29  
30 --- a/drivers/net/wireless/ath/ath9k/calib.h
31 +++ b/drivers/net/wireless/ath/ath9k/calib.h
32 @@ -109,7 +109,7 @@ struct ath9k_pacal_info{
33  
34  bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
35  void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update);
36 -void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
37 +int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
38  bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan);
39  void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
40                                   struct ath9k_channel *chan);
41 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
42 +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
43 @@ -657,14 +657,13 @@ static void ar9002_hw_olc_temp_compensat
44                 ar9280_hw_olc_temp_compensation(ah);
45  }
46  
47 -static bool ar9002_hw_calibrate(struct ath_hw *ah,
48 -                               struct ath9k_channel *chan,
49 -                               u8 rxchainmask,
50 -                               bool longcal)
51 +static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
52 +                              u8 rxchainmask, bool longcal)
53  {
54         bool iscaldone = true;
55         struct ath9k_cal_list *currCal = ah->cal_list_curr;
56         bool nfcal, nfcal_pending = false;
57 +       int ret;
58  
59         nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF);
60         if (ah->caldata)
61 @@ -698,7 +697,9 @@ static bool ar9002_hw_calibrate(struct a
62                          * NF is slow time-variant, so it is OK to use a
63                          * historical value.
64                          */
65 -                       ath9k_hw_loadnf(ah, ah->curchan);
66 +                       ret = ath9k_hw_loadnf(ah, ah->curchan);
67 +                       if (ret < 0)
68 +                               return ret;
69                 }
70  
71                 if (longcal) {
72 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h
73 +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
74 @@ -41,10 +41,9 @@ static inline void ath9k_hw_set_desc_lin
75         ath9k_hw_ops(ah)->set_desc_link(ds, link);
76  }
77  
78 -static inline bool ath9k_hw_calibrate(struct ath_hw *ah,
79 -                                     struct ath9k_channel *chan,
80 -                                     u8 rxchainmask,
81 -                                     bool longcal)
82 +static inline int ath9k_hw_calibrate(struct ath_hw *ah,
83 +                                    struct ath9k_channel *chan,
84 +                                    u8 rxchainmask, bool longcal)
85  {
86         return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal);
87  }
88 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
89 +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
90 @@ -121,13 +121,12 @@ static bool ar9003_hw_per_calibration(st
91         return iscaldone;
92  }
93  
94 -static bool ar9003_hw_calibrate(struct ath_hw *ah,
95 -                               struct ath9k_channel *chan,
96 -                               u8 rxchainmask,
97 -                               bool longcal)
98 +static int ar9003_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
99 +                              u8 rxchainmask, bool longcal)
100  {
101         bool iscaldone = true;
102         struct ath9k_cal_list *currCal = ah->cal_list_curr;
103 +       int ret;
104  
105         /*
106          * For given calibration:
107 @@ -163,7 +162,9 @@ static bool ar9003_hw_calibrate(struct a
108                  * NF is slow time-variant, so it is OK to use a historical
109                  * value.
110                  */
111 -               ath9k_hw_loadnf(ah, ah->curchan);
112 +               ret = ath9k_hw_loadnf(ah, ah->curchan);
113 +               if (ret < 0)
114 +                       return ret;
115  
116                 /* start NF calibration, without updating BB NF register */
117                 ath9k_hw_start_nfcal(ah, false);
118 --- a/drivers/net/wireless/ath/ath9k/hw.h
119 +++ b/drivers/net/wireless/ath/ath9k/hw.h
120 @@ -695,10 +695,8 @@ struct ath_hw_ops {
121                                      bool power_off);
122         void (*rx_enable)(struct ath_hw *ah);
123         void (*set_desc_link)(void *ds, u32 link);
124 -       bool (*calibrate)(struct ath_hw *ah,
125 -                         struct ath9k_channel *chan,
126 -                         u8 rxchainmask,
127 -                         bool longcal);
128 +       int (*calibrate)(struct ath_hw *ah, struct ath9k_channel *chan,
129 +                        u8 rxchainmask, bool longcal);
130         bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked,
131                         u32 *sync_cause_p);
132         void (*set_txdesc)(struct ath_hw *ah, void *ds,
133 --- a/drivers/net/wireless/ath/ath9k/debug.h
134 +++ b/drivers/net/wireless/ath/ath9k/debug.h
135 @@ -49,6 +49,7 @@ enum ath_reset_type {
136         RESET_TYPE_MAC_HANG,
137         RESET_TYPE_BEACON_STUCK,
138         RESET_TYPE_MCI,
139 +       RESET_TYPE_CALIBRATION,
140         __RESET_TYPE_MAX
141  };
142  
143 --- a/drivers/net/wireless/ath/ath9k/debug.c
144 +++ b/drivers/net/wireless/ath/ath9k/debug.c
145 @@ -857,6 +857,7 @@ static ssize_t read_file_reset(struct fi
146                 [RESET_TYPE_MAC_HANG] = "MAC Hang",
147                 [RESET_TYPE_BEACON_STUCK] = "Stuck Beacon",
148                 [RESET_TYPE_MCI] = "MCI Reset",
149 +               [RESET_TYPE_CALIBRATION] = "Calibration error",
150         };
151         char buf[512];
152         unsigned int len = 0;
153 --- a/drivers/net/wireless/ath/ath9k/link.c
154 +++ b/drivers/net/wireless/ath/ath9k/link.c
155 @@ -376,9 +376,14 @@ void ath_ani_calibrate(unsigned long dat
156  
157         /* Perform calibration if necessary */
158         if (longcal || shortcal) {
159 -               common->ani.caldone =
160 -                       ath9k_hw_calibrate(ah, ah->curchan,
161 -                                          ah->rxchainmask, longcal);
162 +               int ret = ath9k_hw_calibrate(ah, ah->curchan, ah->rxchainmask,
163 +                                            longcal);
164 +               if (ret < 0) {
165 +                       ath9k_queue_reset(sc, RESET_TYPE_CALIBRATION);
166 +                       return;
167 +               }
168 +
169 +               common->ani.caldone = ret;
170         }
171  
172         ath_dbg(common, ANI,