2bc11a1d20a44bed033cae03c96f4143d5305607
[openwrt.git] / package / mac80211 / patches / 526-ath9k_improve_nf_cal.patch
1 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
2 +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
3 @@ -1518,77 +1518,6 @@ static void ar5008_hw_do_getnf(struct at
4         nfarray[5] = sign_extend(nf, 9);
5  }
6  
7 -static void ar5008_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
8 -{
9 -       struct ath9k_nfcal_hist *h;
10 -       int i, j;
11 -       int32_t val;
12 -       const u32 ar5416_cca_regs[6] = {
13 -               AR_PHY_CCA,
14 -               AR_PHY_CH1_CCA,
15 -               AR_PHY_CH2_CCA,
16 -               AR_PHY_EXT_CCA,
17 -               AR_PHY_CH1_EXT_CCA,
18 -               AR_PHY_CH2_EXT_CCA
19 -       };
20 -       u8 chainmask, rx_chain_status;
21 -
22 -       rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
23 -       if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
24 -               chainmask = 0x9;
25 -       else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
26 -               if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
27 -                       chainmask = 0x1B;
28 -               else
29 -                       chainmask = 0x09;
30 -       } else {
31 -               if (rx_chain_status & 0x4)
32 -                       chainmask = 0x3F;
33 -               else if (rx_chain_status & 0x2)
34 -                       chainmask = 0x1B;
35 -               else
36 -                       chainmask = 0x09;
37 -       }
38 -
39 -       h = ah->nfCalHist;
40 -
41 -       for (i = 0; i < NUM_NF_READINGS; i++) {
42 -               if (chainmask & (1 << i)) {
43 -                       val = REG_READ(ah, ar5416_cca_regs[i]);
44 -                       val &= 0xFFFFFE00;
45 -                       val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
46 -                       REG_WRITE(ah, ar5416_cca_regs[i], val);
47 -               }
48 -       }
49 -
50 -       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
51 -                   AR_PHY_AGC_CONTROL_ENABLE_NF);
52 -       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
53 -                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
54 -       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
55 -
56 -       for (j = 0; j < 5; j++) {
57 -               if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
58 -                    AR_PHY_AGC_CONTROL_NF) == 0)
59 -                       break;
60 -               udelay(50);
61 -       }
62 -
63 -       ENABLE_REGWRITE_BUFFER(ah);
64 -
65 -       for (i = 0; i < NUM_NF_READINGS; i++) {
66 -               if (chainmask & (1 << i)) {
67 -                       val = REG_READ(ah, ar5416_cca_regs[i]);
68 -                       val &= 0xFFFFFE00;
69 -                       val |= (((u32) (-50) << 1) & 0x1ff);
70 -                       REG_WRITE(ah, ar5416_cca_regs[i], val);
71 -               }
72 -       }
73 -
74 -       REGWRITE_BUFFER_FLUSH(ah);
75 -       DISABLE_REGWRITE_BUFFER(ah);
76 -}
77 -
78  /*
79   * Initialize the ANI register values with default (ini) values.
80   * This routine is called during a (full) hardware reset after
81 @@ -1666,6 +1595,14 @@ static void ar5008_hw_set_nf_limits(stru
82  void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
83  {
84         struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
85 +       const u32 ar5416_cca_regs[6] = {
86 +               AR_PHY_CCA,
87 +               AR_PHY_CH1_CCA,
88 +               AR_PHY_CH2_CCA,
89 +               AR_PHY_EXT_CCA,
90 +               AR_PHY_CH1_EXT_CCA,
91 +               AR_PHY_CH2_EXT_CCA
92 +       };
93  
94         priv_ops->rf_set_freq = ar5008_hw_set_channel;
95         priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate;
96 @@ -1685,7 +1622,6 @@ void ar5008_hw_attach_phy_ops(struct ath
97         priv_ops->restore_chainmask = ar5008_restore_chainmask;
98         priv_ops->set_diversity = ar5008_set_diversity;
99         priv_ops->do_getnf = ar5008_hw_do_getnf;
100 -       priv_ops->loadnf = ar5008_hw_loadnf;
101  
102         if (modparam_force_new_ani) {
103                 priv_ops->ani_control = ar5008_hw_ani_control_new;
104 @@ -1701,4 +1637,5 @@ void ar5008_hw_attach_phy_ops(struct ath
105                 priv_ops->compute_pll_control = ar5008_hw_compute_pll_control;
106  
107         ar5008_hw_set_nf_limits(ah);
108 +       memcpy(ah->nf_regs, ar5416_cca_regs, sizeof(ah->nf_regs));
109  }
110 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
111 +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
112 @@ -1050,106 +1050,6 @@ static void ar9003_hw_set_nf_limits(stru
113  }
114  
115  /*
116 - * Find out which of the RX chains are enabled
117 - */
118 -static u32 ar9003_hw_get_rx_chainmask(struct ath_hw *ah)
119 -{
120 -       u32 chain = REG_READ(ah, AR_PHY_RX_CHAINMASK);
121 -       /*
122 -        * The bits [2:0] indicate the rx chain mask and are to be
123 -        * interpreted as follows:
124 -        * 00x => Only chain 0 is enabled
125 -        * 01x => Chain 1 and 0 enabled
126 -        * 1xx => Chain 2,1 and 0 enabled
127 -        */
128 -       return chain & 0x7;
129 -}
130 -
131 -static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
132 -{
133 -       struct ath9k_nfcal_hist *h;
134 -       unsigned i, j;
135 -       int32_t val;
136 -       const u32 ar9300_cca_regs[6] = {
137 -               AR_PHY_CCA_0,
138 -               AR_PHY_CCA_1,
139 -               AR_PHY_CCA_2,
140 -               AR_PHY_EXT_CCA,
141 -               AR_PHY_EXT_CCA_1,
142 -               AR_PHY_EXT_CCA_2,
143 -       };
144 -       u8 chainmask, rx_chain_status;
145 -       struct ath_common *common = ath9k_hw_common(ah);
146 -
147 -       rx_chain_status = ar9003_hw_get_rx_chainmask(ah);
148 -
149 -       chainmask = 0x3F;
150 -       h = ah->nfCalHist;
151 -
152 -       for (i = 0; i < NUM_NF_READINGS; i++) {
153 -               if (chainmask & (1 << i)) {
154 -                       val = REG_READ(ah, ar9300_cca_regs[i]);
155 -                       val &= 0xFFFFFE00;
156 -                       val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
157 -                       REG_WRITE(ah, ar9300_cca_regs[i], val);
158 -               }
159 -       }
160 -
161 -       /*
162 -        * Load software filtered NF value into baseband internal minCCApwr
163 -        * variable.
164 -        */
165 -       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
166 -                   AR_PHY_AGC_CONTROL_ENABLE_NF);
167 -       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
168 -                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
169 -       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
170 -
171 -       /*
172 -        * Wait for load to complete, should be fast, a few 10s of us.
173 -        * The max delay was changed from an original 250us to 10000us
174 -        * since 250us often results in NF load timeout and causes deaf
175 -        * condition during stress testing 12/12/2009
176 -        */
177 -       for (j = 0; j < 1000; j++) {
178 -               if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
179 -                    AR_PHY_AGC_CONTROL_NF) == 0)
180 -                       break;
181 -               udelay(10);
182 -       }
183 -
184 -       /*
185 -        * We timed out waiting for the noisefloor to load, probably due to an
186 -        * in-progress rx. Simply return here and allow the load plenty of time
187 -        * to complete before the next calibration interval.  We need to avoid
188 -        * trying to load -50 (which happens below) while the previous load is
189 -        * still in progress as this can cause rx deafness. Instead by returning
190 -        * here, the baseband nf cal will just be capped by our present
191 -        * noisefloor until the next calibration timer.
192 -        */
193 -       if (j == 1000) {
194 -               ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf "
195 -                         "to load: AR_PHY_AGC_CONTROL=0x%x\n",
196 -                         REG_READ(ah, AR_PHY_AGC_CONTROL));
197 -               return;
198 -       }
199 -
200 -       /*
201 -        * Restore maxCCAPower register parameter again so that we're not capped
202 -        * by the median we just loaded.  This will be initial (and max) value
203 -        * of next noise floor calibration the baseband does.
204 -        */
205 -       for (i = 0; i < NUM_NF_READINGS; i++) {
206 -               if (chainmask & (1 << i)) {
207 -                       val = REG_READ(ah, ar9300_cca_regs[i]);
208 -                       val &= 0xFFFFFE00;
209 -                       val |= (((u32) (-50) << 1) & 0x1ff);
210 -                       REG_WRITE(ah, ar9300_cca_regs[i], val);
211 -               }
212 -       }
213 -}
214 -
215 -/*
216   * Initialize the ANI register values with default (ini) values.
217   * This routine is called during a (full) hardware reset after
218   * all the registers are initialised from the INI.
219 @@ -1216,6 +1116,14 @@ static void ar9003_hw_ani_cache_ini_regs
220  void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
221  {
222         struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
223 +       const u32 ar9300_cca_regs[6] = {
224 +               AR_PHY_CCA_0,
225 +               AR_PHY_CCA_1,
226 +               AR_PHY_CCA_2,
227 +               AR_PHY_EXT_CCA,
228 +               AR_PHY_EXT_CCA_1,
229 +               AR_PHY_EXT_CCA_2,
230 +       };
231  
232         priv_ops->rf_set_freq = ar9003_hw_set_channel;
233         priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate;
234 @@ -1232,10 +1140,10 @@ void ar9003_hw_attach_phy_ops(struct ath
235         priv_ops->set_diversity = ar9003_hw_set_diversity;
236         priv_ops->ani_control = ar9003_hw_ani_control;
237         priv_ops->do_getnf = ar9003_hw_do_getnf;
238 -       priv_ops->loadnf = ar9003_hw_loadnf;
239         priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
240  
241         ar9003_hw_set_nf_limits(ah);
242 +       memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs));
243  }
244  
245  void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)
246 --- a/drivers/net/wireless/ath/ath9k/calib.c
247 +++ b/drivers/net/wireless/ath/ath9k/calib.c
248 @@ -167,6 +167,100 @@ void ath9k_hw_start_nfcal(struct ath_hw 
249         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
250  }
251  
252 +void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
253 +{
254 +       struct ath9k_nfcal_hist *h;
255 +       unsigned i, j;
256 +       int32_t val;
257 +       u8 chainmask;
258 +       struct ath_common *common = ath9k_hw_common(ah);
259 +
260 +       if (AR_SREV_9300_20_OR_LATER(ah))
261 +               chainmask = 0x3F;
262 +       else if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
263 +               chainmask = 0x9;
264 +       else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
265 +               if ((ah->rxchainmask & 0x2) || (ah->rxchainmask & 0x4))
266 +                       chainmask = 0x1B;
267 +               else
268 +                       chainmask = 0x09;
269 +       } else {
270 +               if (ah->rxchainmask & 0x4)
271 +                       chainmask = 0x3F;
272 +               else if (ah->rxchainmask & 0x2)
273 +                       chainmask = 0x1B;
274 +               else
275 +                       chainmask = 0x09;
276 +       }
277 +       h = ah->nfCalHist;
278 +
279 +       for (i = 0; i < NUM_NF_READINGS; i++) {
280 +               if (chainmask & (1 << i)) {
281 +                       val = REG_READ(ah, ah->nf_regs[i]);
282 +                       val &= 0xFFFFFE00;
283 +                       val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
284 +                       REG_WRITE(ah, ah->nf_regs[i], val);
285 +               }
286 +       }
287 +
288 +       /*
289 +        * Load software filtered NF value into baseband internal minCCApwr
290 +        * variable.
291 +        */
292 +       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
293 +                   AR_PHY_AGC_CONTROL_ENABLE_NF);
294 +       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
295 +                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
296 +       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
297 +
298 +       /*
299 +        * Wait for load to complete, should be fast, a few 10s of us.
300 +        * The max delay was changed from an original 250us to 10000us
301 +        * since 250us often results in NF load timeout and causes deaf
302 +        * condition during stress testing 12/12/2009
303 +        */
304 +       for (j = 0; j < 1000; j++) {
305 +               if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
306 +                    AR_PHY_AGC_CONTROL_NF) == 0)
307 +                       break;
308 +               udelay(10);
309 +       }
310 +
311 +       /*
312 +        * We timed out waiting for the noisefloor to load, probably due to an
313 +        * in-progress rx. Simply return here and allow the load plenty of time
314 +        * to complete before the next calibration interval.  We need to avoid
315 +        * trying to load -50 (which happens below) while the previous load is
316 +        * still in progress as this can cause rx deafness. Instead by returning
317 +        * here, the baseband nf cal will just be capped by our present
318 +        * noisefloor until the next calibration timer.
319 +        */
320 +       if (j == 1000) {
321 +               ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf "
322 +                         "to load: AR_PHY_AGC_CONTROL=0x%x\n",
323 +                         REG_READ(ah, AR_PHY_AGC_CONTROL));
324 +               return;
325 +       }
326 +
327 +       /*
328 +        * Restore maxCCAPower register parameter again so that we're not capped
329 +        * by the median we just loaded.  This will be initial (and max) value
330 +        * of next noise floor calibration the baseband does.
331 +        */
332 +       ENABLE_REGWRITE_BUFFER(ah);
333 +       for (i = 0; i < NUM_NF_READINGS; i++) {
334 +               if (chainmask & (1 << i)) {
335 +                       val = REG_READ(ah, ah->nf_regs[i]);
336 +                       val &= 0xFFFFFE00;
337 +                       val |= (((u32) (-50) << 1) & 0x1ff);
338 +                       REG_WRITE(ah, ah->nf_regs[i], val);
339 +               }
340 +       }
341 +       REGWRITE_BUFFER_FLUSH(ah);
342 +       DISABLE_REGWRITE_BUFFER(ah);
343 +}
344 +
345 +
346  static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
347  {
348         struct ath_common *common = ath9k_hw_common(ah);
349 --- a/drivers/net/wireless/ath/ath9k/calib.h
350 +++ b/drivers/net/wireless/ath/ath9k/calib.h
351 @@ -109,6 +109,7 @@ struct ath9k_pacal_info{
352  
353  bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
354  void ath9k_hw_start_nfcal(struct ath_hw *ah);
355 +void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
356  int16_t ath9k_hw_getnf(struct ath_hw *ah,
357                        struct ath9k_channel *chan);
358  void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
359 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h
360 +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
361 @@ -264,12 +264,6 @@ static inline void ath9k_hw_do_getnf(str
362         ath9k_hw_private_ops(ah)->do_getnf(ah, nfarray);
363  }
364  
365 -static inline void ath9k_hw_loadnf(struct ath_hw *ah,
366 -                                  struct ath9k_channel *chan)
367 -{
368 -       ath9k_hw_private_ops(ah)->loadnf(ah, chan);
369 -}
370 -
371  static inline bool ath9k_hw_init_cal(struct ath_hw *ah,
372                                      struct ath9k_channel *chan)
373  {
374 --- a/drivers/net/wireless/ath/ath9k/hw.h
375 +++ b/drivers/net/wireless/ath/ath9k/hw.h
376 @@ -510,7 +510,6 @@ struct ath_gen_timer_table {
377   *     AR_RTC_PLL_CONTROL for a given channel
378   * @setup_calibration: set up calibration
379   * @iscal_supported: used to query if a type of calibration is supported
380 - * @loadnf: load noise floor read from each chain on the CCA registers
381   *
382   * @ani_reset: reset ANI parameters to default values
383   * @ani_lower_immunity: lower the noise immunity level. The level controls
384 @@ -564,7 +563,6 @@ struct ath_hw_private_ops {
385         bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd,
386                             int param);
387         void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
388 -       void (*loadnf)(struct ath_hw *ah, struct ath9k_channel *chan);
389  
390         /* ANI */
391         void (*ani_reset)(struct ath_hw *ah, bool is_scanning);
392 @@ -658,6 +656,7 @@ struct ath_hw {
393         bool need_an_top2_fixup;
394         u16 tx_trig_level;
395  
396 +       u32 nf_regs[6];
397         struct ath_nf_limits nf_2g;
398         struct ath_nf_limits nf_5g;
399         u16 rfsilent;