ath9k: properly sanitize calibrated noise floor values on all hardware
[oweals/openwrt.git] / package / mac80211 / patches / 530-ath9k_nf_sanitize.patch
1 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
2 +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
3 @@ -1678,6 +1678,15 @@ static void ar5008_hw_ani_cache_ini_regs
4         aniState->cycleCount = 0;
5  }
6  
7 +static void ar5008_hw_set_nf_limits(struct ath_hw *ah)
8 +{
9 +       ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ;
10 +       ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ;
11 +       ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_5416_2GHZ;
12 +       ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ;
13 +       ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ;
14 +       ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ;
15 +}
16  
17  void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
18  {
19 @@ -1715,4 +1724,6 @@ void ar5008_hw_attach_phy_ops(struct ath
20                 priv_ops->compute_pll_control = ar9160_hw_compute_pll_control;
21         else
22                 priv_ops->compute_pll_control = ar5008_hw_compute_pll_control;
23 +
24 +       ar5008_hw_set_nf_limits(ah);
25  }
26 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
27 +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
28 @@ -520,6 +520,30 @@ static void ar9002_hw_do_getnf(struct at
29         }
30  }
31  
32 +static void ar9002_hw_set_nf_limits(struct ath_hw *ah)
33 +{
34 +       if (AR_SREV_9285(ah)) {
35 +               ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ;
36 +               ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ;
37 +               ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9285_2GHZ;
38 +       } else if (AR_SREV_9287(ah)) {
39 +               ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ;
40 +               ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ;
41 +               ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9287_2GHZ;
42 +       } else if (AR_SREV_9271(ah)) {
43 +               ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ;
44 +               ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ;
45 +               ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9271_2GHZ;
46 +       } else {
47 +               ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ;
48 +               ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ;
49 +               ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9280_2GHZ;
50 +               ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ;
51 +               ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ;
52 +               ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9280_5GHZ;
53 +       }
54 +}
55 +
56  void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
57  {
58         struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
59 @@ -532,4 +556,6 @@ void ar9002_hw_attach_phy_ops(struct ath
60         priv_ops->olc_init = ar9002_olc_init;
61         priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
62         priv_ops->do_getnf = ar9002_hw_do_getnf;
63 +
64 +       ar9002_hw_set_nf_limits(ah);
65  }
66 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
67 +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
68 @@ -576,4 +576,30 @@
69  #define AR_PHY_CH2_EXT_MINCCA_PWR   0xFF800000
70  #define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
71  
72 +#define AR_PHY_CCA_NOM_VAL_5416_2GHZ            -90
73 +#define AR_PHY_CCA_NOM_VAL_5416_5GHZ            -100
74 +#define AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ     -100
75 +#define AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ     -110
76 +#define AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ     -80
77 +#define AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ     -90
78 +
79 +#define AR_PHY_CCA_NOM_VAL_9280_2GHZ         -112
80 +#define AR_PHY_CCA_NOM_VAL_9280_5GHZ         -112
81 +#define AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ  -127
82 +#define AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ  -122
83 +#define AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ  -97
84 +#define AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ  -102
85 +
86 +#define AR_PHY_CCA_NOM_VAL_9285_2GHZ           -118
87 +#define AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ    -127
88 +#define AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ    -108
89 +
90 +#define AR_PHY_CCA_NOM_VAL_9271_2GHZ             -118
91 +#define AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ      -127
92 +#define AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ      -116
93 +
94 +#define AR_PHY_CCA_NOM_VAL_9287_2GHZ           -120
95 +#define AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ    -127
96 +#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ    -110
97 +
98  #endif
99 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
100 +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
101 @@ -1015,52 +1015,6 @@ static bool ar9003_hw_ani_control(struct
102         return true;
103  }
104  
105 -static void ar9003_hw_nf_sanitize_2g(struct ath_hw *ah, s16 *nf)
106 -{
107 -       struct ath_common *common = ath9k_hw_common(ah);
108 -
109 -       if (*nf > ah->nf_2g_max) {
110 -               ath_print(common, ATH_DBG_CALIBRATE,
111 -                         "2 GHz NF (%d) > MAX (%d), "
112 -                         "correcting to MAX",
113 -                         *nf, ah->nf_2g_max);
114 -               *nf = ah->nf_2g_max;
115 -       } else if (*nf < ah->nf_2g_min) {
116 -               ath_print(common, ATH_DBG_CALIBRATE,
117 -                         "2 GHz NF (%d) < MIN (%d), "
118 -                         "correcting to MIN",
119 -                         *nf, ah->nf_2g_min);
120 -               *nf = ah->nf_2g_min;
121 -       }
122 -}
123 -
124 -static void ar9003_hw_nf_sanitize_5g(struct ath_hw *ah, s16 *nf)
125 -{
126 -       struct ath_common *common = ath9k_hw_common(ah);
127 -
128 -       if (*nf > ah->nf_5g_max) {
129 -               ath_print(common, ATH_DBG_CALIBRATE,
130 -                         "5 GHz NF (%d) > MAX (%d), "
131 -                         "correcting to MAX",
132 -                         *nf, ah->nf_5g_max);
133 -               *nf = ah->nf_5g_max;
134 -       } else if (*nf < ah->nf_5g_min) {
135 -               ath_print(common, ATH_DBG_CALIBRATE,
136 -                         "5 GHz NF (%d) < MIN (%d), "
137 -                         "correcting to MIN",
138 -                         *nf, ah->nf_5g_min);
139 -               *nf = ah->nf_5g_min;
140 -       }
141 -}
142 -
143 -static void ar9003_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
144 -{
145 -       if (IS_CHAN_2GHZ(ah->curchan))
146 -               ar9003_hw_nf_sanitize_2g(ah, nf);
147 -       else
148 -               ar9003_hw_nf_sanitize_5g(ah, nf);
149 -}
150 -
151  static void ar9003_hw_do_getnf(struct ath_hw *ah,
152                               int16_t nfarray[NUM_NF_READINGS])
153  {
154 @@ -1070,7 +1024,6 @@ static void ar9003_hw_do_getnf(struct at
155         nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR);
156         if (nf & 0x100)
157                 nf = 0 - ((nf ^ 0x1ff) + 1);
158 -       ar9003_hw_nf_sanitize(ah, &nf);
159         ath_print(common, ATH_DBG_CALIBRATE,
160                   "NF calibrated [ctl] [chain 0] is %d\n", nf);
161         nfarray[0] = nf;
162 @@ -1078,7 +1031,6 @@ static void ar9003_hw_do_getnf(struct at
163         nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR);
164         if (nf & 0x100)
165                 nf = 0 - ((nf ^ 0x1ff) + 1);
166 -       ar9003_hw_nf_sanitize(ah, &nf);
167         ath_print(common, ATH_DBG_CALIBRATE,
168                   "NF calibrated [ctl] [chain 1] is %d\n", nf);
169         nfarray[1] = nf;
170 @@ -1086,7 +1038,6 @@ static void ar9003_hw_do_getnf(struct at
171         nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR);
172         if (nf & 0x100)
173                 nf = 0 - ((nf ^ 0x1ff) + 1);
174 -       ar9003_hw_nf_sanitize(ah, &nf);
175         ath_print(common, ATH_DBG_CALIBRATE,
176                   "NF calibrated [ctl] [chain 2] is %d\n", nf);
177         nfarray[2] = nf;
178 @@ -1094,7 +1045,6 @@ static void ar9003_hw_do_getnf(struct at
179         nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
180         if (nf & 0x100)
181                 nf = 0 - ((nf ^ 0x1ff) + 1);
182 -       ar9003_hw_nf_sanitize(ah, &nf);
183         ath_print(common, ATH_DBG_CALIBRATE,
184                   "NF calibrated [ext] [chain 0] is %d\n", nf);
185         nfarray[3] = nf;
186 @@ -1102,7 +1052,6 @@ static void ar9003_hw_do_getnf(struct at
187         nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR);
188         if (nf & 0x100)
189                 nf = 0 - ((nf ^ 0x1ff) + 1);
190 -       ar9003_hw_nf_sanitize(ah, &nf);
191         ath_print(common, ATH_DBG_CALIBRATE,
192                   "NF calibrated [ext] [chain 1] is %d\n", nf);
193         nfarray[4] = nf;
194 @@ -1110,18 +1059,19 @@ static void ar9003_hw_do_getnf(struct at
195         nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR);
196         if (nf & 0x100)
197                 nf = 0 - ((nf ^ 0x1ff) + 1);
198 -       ar9003_hw_nf_sanitize(ah, &nf);
199         ath_print(common, ATH_DBG_CALIBRATE,
200                   "NF calibrated [ext] [chain 2] is %d\n", nf);
201         nfarray[5] = nf;
202  }
203  
204 -void ar9003_hw_set_nf_limits(struct ath_hw *ah)
205 +static void ar9003_hw_set_nf_limits(struct ath_hw *ah)
206  {
207 -       ah->nf_2g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ;
208 -       ah->nf_2g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ;
209 -       ah->nf_5g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ;
210 -       ah->nf_5g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ;
211 +       ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ;
212 +       ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ;
213 +       ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ;
214 +       ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ;
215 +       ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ;
216 +       ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9300_5GHZ;
217  }
218  
219  /*
220 @@ -1309,6 +1259,8 @@ void ar9003_hw_attach_phy_ops(struct ath
221         priv_ops->do_getnf = ar9003_hw_do_getnf;
222         priv_ops->loadnf = ar9003_hw_loadnf;
223         priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
224 +
225 +       ar9003_hw_set_nf_limits(ah);
226  }
227  
228  void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)
229 --- a/drivers/net/wireless/ath/ath9k/calib.c
230 +++ b/drivers/net/wireless/ath/ath9k/calib.c
231 @@ -74,13 +74,8 @@ static void ath9k_hw_update_nfcal_hist_b
232                         h[i].currIndex = 0;
233  
234                 if (h[i].invalidNFcount > 0) {
235 -                       if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE ||
236 -                           nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
237 -                               h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
238 -                       } else {
239 -                               h[i].invalidNFcount--;
240 -                               h[i].privNF = nfarray[i];
241 -                       }
242 +                       h[i].invalidNFcount--;
243 +                       h[i].privNF = nfarray[i];
244                 } else {
245                         h[i].privNF =
246                                 ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
247 @@ -172,6 +167,35 @@ void ath9k_hw_start_nfcal(struct ath_hw 
248         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
249  }
250  
251 +static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
252 +{
253 +       struct ath_common *common = ath9k_hw_common(ah);
254 +       struct ath_nf_limits *limit;
255 +       int i;
256 +
257 +       if (IS_CHAN_2GHZ(ah->curchan))
258 +               limit = &ah->nf_2g;
259 +       else
260 +               limit = &ah->nf_5g;
261 +
262 +       for (i = 0; i < NUM_NF_READINGS; i++) {
263 +               if (!nf[i])
264 +                       continue;
265 +
266 +               if (nf[i] > limit->max) {
267 +                       ath_print(common, ATH_DBG_CALIBRATE,
268 +                                 "NF[%d] (%d) > MAX (%d), correcting to MAX",
269 +                                 i, nf[i], limit->max);
270 +                       nf[i] = limit->max;
271 +               } else if (nf[i] < limit->min) {
272 +                       ath_print(common, ATH_DBG_CALIBRATE,
273 +                                 "NF[%d] (%d) < MIN (%d), correcting to NOM",
274 +                                 i, nf[i], limit->min);
275 +                       nf[i] = limit->nominal;
276 +               }
277 +       }
278 +}
279 +
280  int16_t ath9k_hw_getnf(struct ath_hw *ah,
281                        struct ath9k_channel *chan)
282  {
283 @@ -190,6 +214,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah
284                 return chan->rawNoiseFloor;
285         } else {
286                 ath9k_hw_do_getnf(ah, nfarray);
287 +               ath9k_hw_nf_sanitize(ah, nfarray);
288                 nf = nfarray[0];
289                 if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh)
290                     && nf > nfThresh) {
291 @@ -211,25 +236,21 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah
292  
293  void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
294  {
295 +       struct ath_nf_limits *limit;
296         int i, j;
297 -       s16 noise_floor;
298  
299 -       if (AR_SREV_9280(ah))
300 -               noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE;
301 -       else if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
302 -               noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE;
303 -       else if (AR_SREV_9287(ah))
304 -               noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE;
305 +       if (IS_CHAN_2GHZ(ah->curchan))
306 +               limit = &ah->nf_2g;
307         else
308 -               noise_floor = AR_PHY_CCA_MAX_AR5416_GOOD_VALUE;
309 +               limit = &ah->nf_5g;
310  
311         for (i = 0; i < NUM_NF_READINGS; i++) {
312                 ah->nfCalHist[i].currIndex = 0;
313 -               ah->nfCalHist[i].privNF = noise_floor;
314 +               ah->nfCalHist[i].privNF = limit->nominal;
315                 ah->nfCalHist[i].invalidNFcount =
316                         AR_PHY_CCA_FILTERWINDOW_LENGTH;
317                 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
318 -                       ah->nfCalHist[i].nfCalBuffer[j] = noise_floor;
319 +                       ah->nfCalHist[i].nfCalBuffer[j] = limit->nominal;
320                 }
321         }
322  }
323 --- a/drivers/net/wireless/ath/ath9k/calib.h
324 +++ b/drivers/net/wireless/ath/ath9k/calib.h
325 @@ -19,12 +19,6 @@
326  
327  #include "hw.h"
328  
329 -#define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE       -85
330 -#define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE       -112
331 -#define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE       -118
332 -#define AR_PHY_CCA_MAX_AR9287_GOOD_VALUE       -118
333 -#define AR_PHY_CCA_MAX_HIGH_VALUE                      -62
334 -#define AR_PHY_CCA_MIN_BAD_VALUE                       -140
335  #define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT     3
336  #define AR_PHY_CCA_FILTERWINDOW_LENGTH          5
337  
338 --- a/drivers/net/wireless/ath/ath9k/hw.c
339 +++ b/drivers/net/wireless/ath/ath9k/hw.c
340 @@ -621,9 +621,6 @@ static int __ath9k_hw_init(struct ath_hw
341         else
342                 ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
343  
344 -       if (AR_SREV_9300_20_OR_LATER(ah))
345 -               ar9003_hw_set_nf_limits(ah);
346 -
347         ath9k_init_nfcal_hist_buffer(ah);
348         ah->bb_watchdog_timeout_ms = 25;
349  
350 --- a/drivers/net/wireless/ath/ath9k/hw.h
351 +++ b/drivers/net/wireless/ath/ath9k/hw.h
352 @@ -630,6 +630,12 @@ struct ath_hw_ops {
353         void (*ani_monitor)(struct ath_hw *ah, struct ath9k_channel *chan);
354  };
355  
356 +struct ath_nf_limits {
357 +       s16 max;
358 +       s16 min;
359 +       s16 nominal;
360 +};
361 +
362  struct ath_hw {
363         struct ieee80211_hw *hw;
364         struct ath_common common;
365 @@ -651,10 +657,9 @@ struct ath_hw {
366         bool is_pciexpress;
367         bool need_an_top2_fixup;
368         u16 tx_trig_level;
369 -       s16 nf_2g_max;
370 -       s16 nf_2g_min;
371 -       s16 nf_5g_max;
372 -       s16 nf_5g_min;
373 +
374 +       struct ath_nf_limits nf_2g;
375 +       struct ath_nf_limits nf_5g;
376         u16 rfsilent;
377         u32 rfkill_gpio;
378         u32 rfkill_polarity;
379 @@ -945,7 +950,6 @@ void ar9002_hw_enable_wep_aggregation(st
380   * Code specific to AR9003, we stuff these here to avoid callbacks
381   * for older families
382   */
383 -void ar9003_hw_set_nf_limits(struct ath_hw *ah);
384  void ar9003_hw_bb_watchdog_config(struct ath_hw *ah);
385  void ar9003_hw_bb_watchdog_read(struct ath_hw *ah);
386  void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah);