1 /*
2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 
18 #include "opt_ah.h"
19 
20 #include "ah.h"
21 #include "ah_desc.h"
22 #include "ah_internal.h"
23 
24 #include "ar9300/ar9300.h"
25 #include "ar9300/ar9300phy.h"
26 #include "ar9300/ar9300reg.h"
27 
28 /*
29  * Default 5413/9300 radar phy parameters
30  * Values adjusted to fix EV76432/EV76320
31  */
32 #define AR9300_DFS_FIRPWR   -28
33 #define AR9300_DFS_RRSSI    0
34 #define AR9300_DFS_HEIGHT   10
35 #define AR9300_DFS_PRSSI    6
36 #define AR9300_DFS_INBAND   8
37 #define AR9300_DFS_RELPWR   8
38 #define AR9300_DFS_RELSTEP  12
39 #define AR9300_DFS_MAXLEN   255
40 
41 /*
42  * This PRSSI value should be used during CAC.
43  */
44 #define AR9300_DFS_PRSSI_CAC 10
45 
46 /*
47  *  make sure that value matches value in ar9300_osprey_2p2_mac_core[][2]
48  *  for register 0x1040 to 0x104c
49 */
50 #define AR9300_DEFAULT_DIFS     0x002ffc0f
51 #define AR9300_FCC_RADARS_FCC_OFFSET 4
52 
53 struct dfs_pulse ar9300_etsi_radars[] = {
54 
55     /* for short pulses, RSSI threshold should be smaller than
56  * Kquick-drop. The chip has only one chance to drop the gain which
57  * will be reported as the estimated RSSI */
58 
59     /* TYPE staggered pulse */
60     /* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */
61     {30,  2,  300,  400, 2, 30,  3,  0,  5, 15, 0,   0, 1, 31},   /* Type 5*/
62     /* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */
63     {30,  2,  400, 1200, 2, 30,  7,  0,  5, 15, 0,   0, 0, 32},   /* Type 6 */
64 
65     /* constant PRF based */
66     /* 0.8-5us, 200  300 PRF, 10 pulses */
67     {10, 5,   200,  400, 0, 24,  5,  0,  8, 15, 0,   0, 2, 33},   /* Type 1 */
68     {10, 5,   400,  600, 0, 24,  5,  0,  8, 15, 0,   0, 2, 37},   /* Type 1 */
69     {10, 5,   600,  800, 0, 24,  5,  0,  8, 15, 0,   0, 2, 38},   /* Type 1 */
70     {10, 5,   800, 1000, 0, 24,  5,  0,  8, 15, 0,   0, 2, 39},   /* Type 1 */
71 //  {10, 5,   200, 1000, 0, 24,  5,  0,  8, 15, 0,   0, 2, 33},
72 
73     /* 0.8-15us, 200-1600 PRF, 15 pulses */
74     {15, 15,  200, 1600, 0, 24, 8,  0, 18, 24, 0,   0, 0, 34},    /* Type 2 */
75 
76     /* 0.8-15us, 2300-4000 PRF, 25 pulses*/
77     {25, 15, 2300, 4000,  0, 24, 10, 0, 18, 24, 0,   0, 0, 35},   /* Type 3 */
78 
79     /* 20-30us, 2000-4000 PRF, 20 pulses*/
80     {20, 30, 2000, 4000, 0, 24, 8, 19, 33, 24, 0,   0, 0, 36},    /* Type 4 */
81 };
82 
83 
84 /* The following are for FCC Bin 1-4 pulses */
85 struct dfs_pulse ar9300_fcc_radars[] = {
86 
87     /* following two filters are specific to Japan/MKK4 */
88 //  {18,  1,  720,  720, 1,  6,  6,  0,  1, 18,  0, 3, 0, 17}, // 1389 +/- 6 us
89 //  {18,  4,  250,  250, 1, 10,  5,  1,  6, 18,  0, 3, 0, 18}, // 4000 +/- 6 us
90 //  {18,  5,  260,  260, 1, 10,  6,  1,  6, 18,  0, 3, 0, 19}, // 3846 +/- 7 us
91     {18,  1,  720,  720, 0,  6,  6,  0,  1, 18,  0, 3, 0, 17}, // 1389 +/- 6 us
92     {18,  4,  250,  250, 0, 10,  5,  1,  6, 18,  0, 3, 0, 18}, // 4000 +/- 6 us
93     {18,  5,  260,  260, 0, 10,  6,  1,  6, 18,  0, 3, 1, 19}, // 3846 +/- 7 us
94 //  {18,  5,  260,  260, 1, 10,  6,  1,  6, 18,  0, 3, 1, 20}, // 3846 +/- 7 us
95 
96    {18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 1, 20}, // 3846 +/- 7 us
97 
98 
99     /* following filters are common to both FCC and JAPAN */
100 
101     // FCC TYPE 1
102     // {18,  1,  325, 1930, 0,  6,  7,  0,  1, 18,  0, 3, 0, 0}, // 518 to 3066
103     {18,  1,  700, 700, 0,  6,  5,  0,  1, 18,  0, 3, 1, 8},
104     {18,  1,  350, 350, 0,  6,  5,  0,  1, 18,  0, 3, 0, 0},
105 
106 
107     // FCC TYPE 6
108     // {9,   1, 3003, 3003, 1,  7,  5,  0,  1, 18,  0, 0, 0, 1}, // 333 +/- 7 us
109     //{9,   1, 3003, 3003, 1,  7,  5,  0,  1, 18,  0, 0, 0, 1},
110     {9,   1, 3003, 3003, 0,  7,  5,  0,  1, 18,  0, 0, 1, 1},
111 
112     // FCC TYPE 2
113     {23, 5, 4347, 6666, 0, 18, 11,  0,  7, 22,  0, 3, 0, 2},
114 
115     // FCC TYPE 3
116     {18, 10, 2000, 5000, 0, 23,  8,  6, 13, 22,  0, 3, 0, 5},
117 
118     // FCC TYPE 4
119     {16, 15, 2000, 5000, 0, 25,  7, 11, 23, 22,  0, 3, 0, 11},
120 
121 };
122 
123 struct dfs_bin5pulse ar9300_bin5pulses[] = {
124         {2, 28, 105, 12, 22, 5},
125 };
126 
127 
128 #if 0
129 /*
130  * Find the internal HAL channel corresponding to the
131  * public HAL channel specified in c
132  */
133 
134 static HAL_CHANNEL_INTERNAL *
135 getchannel(struct ath_hal *ah, const struct ieee80211_channel *c)
136 {
137 #define CHAN_FLAGS    (CHANNEL_ALL | CHANNEL_HALF | CHANNEL_QUARTER)
138     HAL_CHANNEL_INTERNAL *base, *cc;
139     int flags = c->channel_flags & CHAN_FLAGS;
140     int n, lim;
141 
142     /*
143      * Check current channel to avoid the lookup.
144      */
145     cc = AH_PRIVATE(ah)->ah_curchan;
146     if (cc != AH_NULL && cc->channel == c->channel &&
147         (cc->channel_flags & CHAN_FLAGS) == flags) {
148         return cc;
149     }
150 
151     /* binary search based on known sorting order */
152     base = AH_TABLES(ah)->ah_channels;
153     n = AH_PRIVATE(ah)->ah_nchan;
154     /* binary search based on known sorting order */
155     for (lim = n; lim != 0; lim >>= 1) {
156         int d;
157         cc = &base[lim >> 1];
158         d = c->channel - cc->channel;
159         if (d == 0) {
160             if ((cc->channel_flags & CHAN_FLAGS) == flags) {
161                 return cc;
162             }
163             d = flags - (cc->channel_flags & CHAN_FLAGS);
164         }
165         HALDEBUG(ah, HAL_DEBUG_DFS, "%s: channel %u/0x%x d %d\n", __func__,
166                 cc->channel, cc->channel_flags, d);
167         if (d > 0) {
168             base = cc + 1;
169             lim--;
170         }
171     }
172     HALDEBUG(ah, HAL_DEBUG_DFS, "%s: no match for %u/0x%x\n",
173             __func__, c->channel, c->channel_flags);
174     return AH_NULL;
175 #undef CHAN_FLAGS
176 }
177 
178 /*
179  * Check the internal channel list to see if the desired channel
180  * is ok to release from the NOL.  If not, then do nothing.  If so,
181  * mark the channel as clear and reset the internal tsf time
182  */
183 void
184 ar9300_check_dfs(struct ath_hal *ah, struct ieee80211_channel *chan)
185 {
186     HAL_CHANNEL_INTERNAL *ichan = AH_NULL;
187 
188     ichan = getchannel(ah, chan);
189     if (ichan == AH_NULL) {
190         return;
191     }
192     if (!(ichan->priv_flags & CHANNEL_INTERFERENCE)) {
193         return;
194     }
195 
196     ichan->priv_flags &= ~CHANNEL_INTERFERENCE;
197     ichan->dfs_tsf = 0;
198 }
199 
200 /*
201  * This function marks the channel as having found a dfs event
202  * It also marks the end time that the dfs event should be cleared
203  * If the channel is already marked, then tsf end time can only
204  * be increased
205  */
206 void
207 ar9300_dfs_found(struct ath_hal *ah, struct ieee80211_channel *chan, u_int64_t nol_time)
208 {
209     HAL_CHANNEL_INTERNAL *ichan;
210 
211     ichan = getchannel(ah, chan);
212     if (ichan == AH_NULL) {
213         return;
214     }
215     if (!(ichan->priv_flags & CHANNEL_INTERFERENCE)) {
216         ichan->dfs_tsf = ar9300_get_tsf64(ah);
217     }
218     ichan->dfs_tsf += nol_time;
219     ichan->priv_flags |= CHANNEL_INTERFERENCE;
220     chan->priv_flags |= CHANNEL_INTERFERENCE;
221 }
222 #endif
223 
224 /*
225  * Enable radar detection and set the radar parameters per the
226  * values in pe
227  */
228 void
229 ar9300_enable_dfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
230 {
231     u_int32_t val;
232     struct ath_hal_private  *ahp = AH_PRIVATE(ah);
233     const struct ieee80211_channel *chan = ahp->ah_curchan;
234     struct ath_hal_9300 *ah9300 = AH9300(ah);
235     int reg_writes = 0;
236 
237     val = OS_REG_READ(ah, AR_PHY_RADAR_0);
238     val |= AR_PHY_RADAR_0_FFT_ENA;
239 
240 
241     if (pe->pe_enabled != HAL_PHYERR_PARAM_NOVAL) {
242         val &= ~AR_PHY_RADAR_0_ENA;
243         val |= SM(pe->pe_enabled, AR_PHY_RADAR_0_ENA);
244     }
245 
246     if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) {
247         val &= ~AR_PHY_RADAR_0_FIRPWR;
248         val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR);
249     }
250     if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) {
251         val &= ~AR_PHY_RADAR_0_RRSSI;
252         val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI);
253     }
254     if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) {
255         val &= ~AR_PHY_RADAR_0_HEIGHT;
256         val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT);
257     }
258     if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) {
259         val &= ~AR_PHY_RADAR_0_PRSSI;
260         if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
261 #if 0
262             if (ah->ah_use_cac_prssi) {
263                 val |= SM(AR9300_DFS_PRSSI_CAC, AR_PHY_RADAR_0_PRSSI);
264             } else {
265 #endif
266                 val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI);
267 //            }
268         } else {
269             val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI);
270         }
271     }
272     if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) {
273         val &= ~AR_PHY_RADAR_0_INBAND;
274         val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND);
275     }
276     OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
277 
278     val = OS_REG_READ(ah, AR_PHY_RADAR_1);
279     val |= AR_PHY_RADAR_1_MAX_RRSSI | AR_PHY_RADAR_1_BLOCK_CHECK;
280     if (pe->pe_maxlen != HAL_PHYERR_PARAM_NOVAL) {
281         val &= ~AR_PHY_RADAR_1_MAXLEN;
282         val |= SM(pe->pe_maxlen, AR_PHY_RADAR_1_MAXLEN);
283     }
284     if (pe->pe_relstep != HAL_PHYERR_PARAM_NOVAL) {
285         val &= ~AR_PHY_RADAR_1_RELSTEP_THRESH;
286         val |= SM(pe->pe_relstep, AR_PHY_RADAR_1_RELSTEP_THRESH);
287     }
288     if (pe->pe_relpwr != HAL_PHYERR_PARAM_NOVAL) {
289         val &= ~AR_PHY_RADAR_1_RELPWR_THRESH;
290         val |= SM(pe->pe_relpwr, AR_PHY_RADAR_1_RELPWR_THRESH);
291     }
292     OS_REG_WRITE(ah, AR_PHY_RADAR_1, val);
293 
294     if (ath_hal_getcapability(ah, HAL_CAP_EXT_CHAN_DFS, 0, 0) == HAL_OK) {
295         val = OS_REG_READ(ah, AR_PHY_RADAR_EXT);
296         if (IEEE80211_IS_CHAN_HT40(chan)) {
297             /* Enable extension channel radar detection */
298             OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val | AR_PHY_RADAR_EXT_ENA);
299         } else {
300             /* HT20 mode, disable extension channel radar detect */
301             OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA);
302         }
303     }
304     /*
305         apply DFS postamble array from INI
306         column 0 is register ID, column 1 is  HT20 value, colum2 is HT40 value
307     */
308 
309     if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_OSPREY_22(ah) || AR_SREV_SCORPION(ah)) {
310         REG_WRITE_ARRAY(&ah9300->ah_ini_dfs, IEEE80211_IS_CHAN_HT40(chan)? 2:1, reg_writes);
311     }
312 #ifdef ATH_HAL_DFS_CHIRPING_FIX_APH128
313     ath_hal_printf(ah, "DFS change the timing value\n");
314     if (AR_SREV_AR9580(ah) && IEEE80211_IS_CHAN_HT40(chan)) {
315         OS_REG_WRITE(ah, AR_PHY_TIMING6, 0x3140c00a);
316     }
317 #endif
318 
319 }
320 
321 /*
322  * Get the radar parameter values and return them in the pe
323  * structure
324  */
325 void
326 ar9300_get_dfs_thresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
327 {
328     u_int32_t val, temp;
329 
330     val = OS_REG_READ(ah, AR_PHY_RADAR_0);
331     temp = MS(val, AR_PHY_RADAR_0_FIRPWR);
332     temp |= ~(AR_PHY_RADAR_0_FIRPWR >> AR_PHY_RADAR_0_FIRPWR_S);
333     pe->pe_firpwr = temp;
334     pe->pe_rrssi = MS(val, AR_PHY_RADAR_0_RRSSI);
335     pe->pe_height = MS(val, AR_PHY_RADAR_0_HEIGHT);
336     pe->pe_prssi = MS(val, AR_PHY_RADAR_0_PRSSI);
337     pe->pe_inband = MS(val, AR_PHY_RADAR_0_INBAND);
338     pe->pe_enabled = !! MS(val, AR_PHY_RADAR_0_ENA);
339 
340     val = OS_REG_READ(ah, AR_PHY_RADAR_1);
341 
342     pe->pe_relpwr = MS(val, AR_PHY_RADAR_1_RELPWR_THRESH);
343     pe->pe_enrelpwr = !! (val & AR_PHY_RADAR_1_RELPWR_ENA);
344 
345     pe->pe_relstep = MS(val, AR_PHY_RADAR_1_RELSTEP_THRESH);
346     pe->pe_en_relstep_check = !! (val & AR_PHY_RADAR_1_RELSTEP_CHECK);
347 
348     pe->pe_maxlen = MS(val, AR_PHY_RADAR_1_MAXLEN);
349 }
350 
351 #if 0
352 HAL_BOOL
353 ar9300_radar_wait(struct ath_hal *ah, struct ieee80211_channel *chan)
354 {
355     struct ath_hal_private *ahp = AH_PRIVATE(ah);
356 
357     if (!ahp->ah_curchan) {
358         return AH_TRUE;
359     }
360 
361     /*
362      * Rely on the upper layers to determine that we have spent
363      * enough time waiting.
364      */
365     chan->channel = ahp->ah_curchan->channel;
366     chan->channel_flags = ahp->ah_curchan->channel_flags;
367     chan->max_reg_tx_power = ahp->ah_curchan->max_reg_tx_power;
368 
369     ahp->ah_curchan->priv_flags |= CHANNEL_DFS_CLEAR;
370     chan->priv_flags  = ahp->ah_curchan->priv_flags;
371     return AH_FALSE;
372 
373 }
374 #endif
375 
376 struct dfs_pulse *
377 ar9300_get_dfs_radars(
378     struct ath_hal *ah,
379     u_int32_t dfsdomain,
380     int *numradars,
381     struct dfs_bin5pulse **bin5pulses,
382     int *numb5radars,
383     HAL_PHYERR_PARAM *pe)
384 {
385     struct dfs_pulse *dfs_radars = AH_NULL;
386     switch (dfsdomain) {
387     case HAL_DFS_FCC_DOMAIN:
388         dfs_radars = &ar9300_fcc_radars[AR9300_FCC_RADARS_FCC_OFFSET];
389         *numradars =
390             ARRAY_LENGTH(ar9300_fcc_radars) - AR9300_FCC_RADARS_FCC_OFFSET;
391         *bin5pulses = &ar9300_bin5pulses[0];
392         *numb5radars = ARRAY_LENGTH(ar9300_bin5pulses);
393         HALDEBUG(ah, HAL_DEBUG_DFS, "%s: DFS_FCC_DOMAIN_9300\n", __func__);
394         break;
395     case HAL_DFS_ETSI_DOMAIN:
396         dfs_radars = &ar9300_etsi_radars[0];
397         *numradars = ARRAY_LENGTH(ar9300_etsi_radars);
398         *bin5pulses = &ar9300_bin5pulses[0];
399         *numb5radars = ARRAY_LENGTH(ar9300_bin5pulses);
400         HALDEBUG(ah, HAL_DEBUG_DFS, "%s: DFS_ETSI_DOMAIN_9300\n", __func__);
401         break;
402     case HAL_DFS_MKK4_DOMAIN:
403         dfs_radars = &ar9300_fcc_radars[0];
404         *numradars = ARRAY_LENGTH(ar9300_fcc_radars);
405         *bin5pulses = &ar9300_bin5pulses[0];
406         *numb5radars = ARRAY_LENGTH(ar9300_bin5pulses);
407         HALDEBUG(ah, HAL_DEBUG_DFS, "%s: DFS_MKK4_DOMAIN_9300\n", __func__);
408         break;
409     default:
410         HALDEBUG(ah, HAL_DEBUG_DFS, "%s: no domain\n", __func__);
411         return AH_NULL;
412     }
413     /* Set the default phy parameters per chip */
414     pe->pe_firpwr = AR9300_DFS_FIRPWR;
415     pe->pe_rrssi = AR9300_DFS_RRSSI;
416     pe->pe_height = AR9300_DFS_HEIGHT;
417     pe->pe_prssi = AR9300_DFS_PRSSI;
418     /*
419         we have an issue with PRSSI.
420         For normal operation we use AR9300_DFS_PRSSI, which is set to 6.
421         Please refer to EV91563, 94164.
422         However, this causes problem during CAC as no radar is detected
423         during that period with PRSSI=6. Only PRSSI= 10 seems to fix this.
424         We use this flag to keep track of change in PRSSI.
425     */
426 
427 //    ah->ah_use_cac_prssi = 0;
428 
429     pe->pe_inband = AR9300_DFS_INBAND;
430     pe->pe_relpwr = AR9300_DFS_RELPWR;
431     pe->pe_relstep = AR9300_DFS_RELSTEP;
432     pe->pe_maxlen = AR9300_DFS_MAXLEN;
433     return dfs_radars;
434 }
435 
436 HAL_BOOL
437 ar9300_get_default_dfs_thresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe)
438 {
439 
440     pe->pe_firpwr = AR9300_DFS_FIRPWR;
441     pe->pe_rrssi = AR9300_DFS_RRSSI;
442     pe->pe_height = AR9300_DFS_HEIGHT;
443     pe->pe_prssi = AR9300_DFS_PRSSI;
444     /* see prssi comment above */
445 
446     pe->pe_inband = AR9300_DFS_INBAND;
447     pe->pe_relpwr = AR9300_DFS_RELPWR;
448     pe->pe_relstep = AR9300_DFS_RELSTEP;
449     pe->pe_maxlen = AR9300_DFS_MAXLEN;
450     return (AH_TRUE);
451 }
452 
453 void ar9300_adjust_difs(struct ath_hal *ah, u_int32_t val)
454 {
455     if (val == 0) {
456         /*
457          * EV 116936:
458          * Restore the register values with that of the HAL structure.
459          * Do not assume and overwrite these values to whatever
460          * is in ar9300_osprey22.ini.
461          */
462         struct ath_hal_9300 *ahp = AH9300(ah);
463         HAL_TX_QUEUE_INFO *qi;
464         int q;
465 
466         AH9300(ah)->ah_fccaifs = 0;
467         HALDEBUG(ah, HAL_DEBUG_DFS, "%s: restore DIFS \n", __func__);
468         for (q = 0; q < 4; q++) {
469             qi = &ahp->ah_txq[q];
470             OS_REG_WRITE(ah, AR_DLCL_IFS(q),
471                     SM(qi->tqi_cwmin, AR_D_LCL_IFS_CWMIN)
472                     | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
473                     | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
474         }
475     } else {
476         /*
477          * These are values from George Lai and are specific to
478          * FCC domain. They are yet to be determined for other domains.
479          */
480 
481         AH9300(ah)->ah_fccaifs = 1;
482         HALDEBUG(ah, HAL_DEBUG_DFS, "%s: set DIFS to default\n", __func__);
483         /*printk("%s:  modify DIFS\n", __func__);*/
484 
485         OS_REG_WRITE(ah, AR_DLCL_IFS(0), 0x05fffc0f);
486         OS_REG_WRITE(ah, AR_DLCL_IFS(1), 0x05f0fc0f);
487         OS_REG_WRITE(ah, AR_DLCL_IFS(2), 0x05f03c07);
488         OS_REG_WRITE(ah, AR_DLCL_IFS(3), 0x05f01c03);
489     }
490 }
491 
492 u_int32_t ar9300_dfs_config_fft(struct ath_hal *ah, HAL_BOOL is_enable)
493 {
494     u_int32_t val;
495 
496     val = OS_REG_READ(ah, AR_PHY_RADAR_0);
497 
498     if (is_enable) {
499         val |= AR_PHY_RADAR_0_FFT_ENA;
500     } else {
501         val &= ~AR_PHY_RADAR_0_FFT_ENA;
502     }
503 
504     OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
505     val = OS_REG_READ(ah, AR_PHY_RADAR_0);
506     return val;
507 }
508 /*
509     function to adjust PRSSI value for CAC problem
510 
511 */
512 void
513 ar9300_dfs_cac_war(struct ath_hal *ah, u_int32_t start)
514 {
515     u_int32_t val;
516 
517     if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
518         val = OS_REG_READ(ah, AR_PHY_RADAR_0);
519         if (start) {
520             val &= ~AR_PHY_RADAR_0_PRSSI;
521             val |= SM(AR9300_DFS_PRSSI_CAC, AR_PHY_RADAR_0_PRSSI);
522         } else {
523             val &= ~AR_PHY_RADAR_0_PRSSI;
524             val |= SM(AR9300_DFS_PRSSI, AR_PHY_RADAR_0_PRSSI);
525         }
526         OS_REG_WRITE(ah, AR_PHY_RADAR_0, val | AR_PHY_RADAR_0_ENA);
527 //        ah->ah_use_cac_prssi = start;
528     }
529 }
530 
531 #if 0
532 struct ieee80211_channel *
533 ar9300_get_extension_channel(struct ath_hal *ah)
534 {
535     struct ath_hal_private  *ahp = AH_PRIVATE(ah);
536     struct ath_hal_private_tables  *aht = AH_TABLES(ah);
537     int i = 0;
538 
539     HAL_CHANNEL_INTERNAL *ichan = AH_NULL;
540     CHAN_CENTERS centers;
541 
542     ichan = ahp->ah_curchan;
543     ar9300_get_channel_centers(ah, ichan, &centers);
544     if (centers.ctl_center == centers.ext_center) {
545         return AH_NULL;
546     }
547     for (i = 0; i < ahp->ah_nchan; i++) {
548         ichan = &aht->ah_channels[i];
549         if (ichan->channel == centers.ext_center) {
550             return (struct ieee80211_channel*)ichan;
551         }
552     }
553     return AH_NULL;
554 }
555 #endif
556 
557 HAL_BOOL
558 ar9300_is_fast_clock_enabled(struct ath_hal *ah)
559 {
560     struct ath_hal_private *ahp = AH_PRIVATE(ah);
561 
562     if (IS_5GHZ_FAST_CLOCK_EN(ah, ahp->ah_curchan)) {
563         return AH_TRUE;
564     }
565     return AH_FALSE;
566 }
567 
568 /*
569  * This should be enabled and linked into the build once
570  * radar support is enabled.
571  */
572 #if 0
573 HAL_BOOL
574 ar9300_handle_radar_bb_panic(struct ath_hal *ah)
575 {
576     u_int32_t status;
577     u_int32_t val;
578 #ifdef AH_DEBUG
579     struct ath_hal_9300 *ahp = AH9300(ah);
580 #endif
581 
582     status = AH_PRIVATE(ah)->ah_bb_panic_last_status;
583 
584     if ( status == 0x04000539 ) {
585         /* recover from this BB panic without reset*/
586         /* set AR9300_DFS_FIRPWR to -1 */
587         val = OS_REG_READ(ah, AR_PHY_RADAR_0);
588         val &= (~AR_PHY_RADAR_0_FIRPWR);
589         val |= SM( 0x7f, AR_PHY_RADAR_0_FIRPWR);
590         OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
591         OS_DELAY(1);
592         /* set AR9300_DFS_FIRPWR to its default value */
593         val = OS_REG_READ(ah, AR_PHY_RADAR_0);
594         val &= ~AR_PHY_RADAR_0_FIRPWR;
595         val |= SM( AR9300_DFS_FIRPWR, AR_PHY_RADAR_0_FIRPWR);
596         OS_REG_WRITE(ah, AR_PHY_RADAR_0, val);
597         return AH_TRUE;
598     } else if (status == 0x0400000a) {
599         /* EV 92527 : reset required if we see this signature */
600         HALDEBUG(ah, HAL_DEBUG_DFS, "%s: BB Panic -- 0x0400000a\n", __func__);
601         return AH_FALSE;
602     } else if (status == 0x1300000a) {
603         /* EV92527: we do not need a reset if we see this signature */
604         HALDEBUG(ah, HAL_DEBUG_DFS, "%s: BB Panic -- 0x1300000a\n", __func__);
605         return AH_TRUE;
606     } else if ((AR_SREV_WASP(ah) || AR_SREV_HONEYBEE(ah)) && (status == 0x04000409)) {
607         return AH_TRUE;
608     } else {
609         if (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK &&
610             (status & 0xff00000f) == 0x04000009 &&
611             status != 0x04000409 &&
612             status != 0x04000b09 &&
613             status != 0x04000e09 &&
614             (status & 0x0000ff00))
615         {
616             /* disable RIFS Rx */
617 #ifdef AH_DEBUG
618             HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "%s: BB status=0x%08x rifs=%d - disable\n",
619                      __func__, status, ahp->ah_rifs_enabled);
620             ar9300_set_rifs_delay(ah, AH_FALSE);
621         }
622         return AH_FALSE;
623     }
624 }
625 #endif
626 #endif
627