Fix a number of typos in messages and manual pages.
[dragonfly.git] / sys / contrib / dev / ath / ath_hal / ar9300 / ar9300_eeprom.c
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 #include "opt_ah.h"
18
19 #include "ah.h"
20 #include "ah_internal.h"
21 #include "ah_devid.h"
22 #ifdef AH_DEBUG
23 #include "ah_desc.h"                    /* NB: for HAL_PHYERR* */
24 #endif
25 #include "ar9300/ar9300.h"
26 #include "ar9300/ar9300eep.h"
27 #include "ar9300/ar9300template_generic.h"
28 #include "ar9300/ar9300template_xb112.h"
29 #include "ar9300/ar9300template_hb116.h"
30 #include "ar9300/ar9300template_xb113.h"
31 #include "ar9300/ar9300template_hb112.h"
32 #include "ar9300/ar9300template_ap121.h"
33 #include "ar9300/ar9300template_osprey_k31.h"
34 #include "ar9300/ar9300template_wasp_2.h"
35 #include "ar9300/ar9300template_wasp_k31.h"
36 #include "ar9300/ar9300template_aphrodite.h"
37 #include "ar9300/ar9300reg.h"
38 #include "ar9300/ar9300phy.h"
39
40
41
42 #if AH_BYTE_ORDER == AH_BIG_ENDIAN
43 void ar9300_swap_eeprom(ar9300_eeprom_t *eep);
44 void ar9300_eeprom_template_swap(void);
45 #endif
46
47 static u_int16_t ar9300_eeprom_get_spur_chan(struct ath_hal *ah,
48     int spur_chan, HAL_BOOL is_2ghz);
49 #ifdef UNUSED
50 static inline HAL_BOOL ar9300_fill_eeprom(struct ath_hal *ah);
51 static inline HAL_STATUS ar9300_check_eeprom(struct ath_hal *ah);
52 #endif
53
54 static ar9300_eeprom_t *default9300[] =
55 {
56     &ar9300_template_generic,
57     &ar9300_template_xb112,
58     &ar9300_template_hb116,
59     &ar9300_template_hb112,
60     &ar9300_template_xb113,
61     &ar9300_template_ap121,
62     &ar9300_template_wasp_2,
63     &ar9300_template_wasp_k31,
64     &ar9300_template_osprey_k31,
65     &ar9300_template_aphrodite,
66 };
67
68 /*
69  * Different types of memory where the calibration data might be stored.
70  * All types are searched in ar9300_eeprom_restore()
71  * in the order flash, eeprom, otp.
72  * To disable searching a type, set its parameter to 0.
73  */
74
75 /*
76  * This is where we look for the calibration data.
77  * must be set before ath_attach() is called
78  */
79 static int calibration_data_try = calibration_data_none;
80 static int calibration_data_try_address = 0;
81
82 /*
83  * Set the type of memory used to store calibration data.
84  * Used by nart to force reading/writing of a specific type.
85  * The driver can normally allow autodetection
86  * by setting source to calibration_data_none=0.
87  */
88 void ar9300_calibration_data_set(struct ath_hal *ah, int32_t source)
89 {
90     if (ah != 0) {
91         AH9300(ah)->calibration_data_source = source;
92     } else {
93         calibration_data_try = source;
94     }
95 }
96
97 int32_t ar9300_calibration_data_get(struct ath_hal *ah)
98 {
99     if (ah != 0) {
100         return AH9300(ah)->calibration_data_source;
101     } else {
102         return calibration_data_try;
103     }
104 }
105
106 /*
107  * Set the address of first byte used to store calibration data.
108  * Used by nart to force reading/writing at a specific address.
109  * The driver can normally allow autodetection by setting size=0.
110  */
111 void ar9300_calibration_data_address_set(struct ath_hal *ah, int32_t size)
112 {
113     if (ah != 0) {
114         AH9300(ah)->calibration_data_source_address = size;
115     } else {
116         calibration_data_try_address = size;
117     }
118 }
119
120 int32_t ar9300_calibration_data_address_get(struct ath_hal *ah)
121 {
122     if (ah != 0) {
123         return AH9300(ah)->calibration_data_source_address;
124     } else {
125         return calibration_data_try_address;
126     }
127 }
128
129 /*
130  * This is the template that is loaded if ar9300_eeprom_restore()
131  * can't find valid data in the memory.
132  */
133 static int Ar9300_eeprom_template_preference = ar9300_eeprom_template_generic;
134
135 void ar9300_eeprom_template_preference(int32_t value)
136 {
137     Ar9300_eeprom_template_preference = value;
138 }
139
140 /*
141  * Install the specified default template.
142  * Overwrites any existing calibration and configuration information in memory.
143  */
144 int32_t ar9300_eeprom_template_install(struct ath_hal *ah, int32_t value)
145 {
146     struct ath_hal_9300 *ahp = AH9300(ah);
147     ar9300_eeprom_t *mptr, *dptr;
148     int mdata_size;
149
150     mptr = &ahp->ah_eeprom;
151     mdata_size = ar9300_eeprom_struct_size();
152     if (mptr != 0) {
153 #if 0
154         calibration_data_source = calibration_data_none;
155         calibration_data_source_address = 0;
156 #endif
157         dptr = ar9300_eeprom_struct_default_find_by_id(value);
158         if (dptr != 0) {
159             OS_MEMCPY(mptr, dptr, mdata_size);
160             return 0;
161         }
162     }
163     return -1;
164 }
165
166 static int
167 ar9300_eeprom_restore_something(struct ath_hal *ah, ar9300_eeprom_t *mptr,
168     int mdata_size)
169 {
170     int it;
171     ar9300_eeprom_t *dptr;
172     int nptr;
173
174     nptr = -1; 
175     /*
176      * if we didn't find any blocks in the memory,
177      * put the prefered template in place
178      */
179     if (nptr < 0) {
180         AH9300(ah)->calibration_data_source = calibration_data_none;
181         AH9300(ah)->calibration_data_source_address = 0;
182         dptr = ar9300_eeprom_struct_default_find_by_id(
183             Ar9300_eeprom_template_preference);
184         if (dptr != 0) {
185             OS_MEMCPY(mptr, dptr, mdata_size);    
186             nptr = 0;
187         }
188     }
189     /*
190      * if we didn't find the prefered one,
191      * put the normal default template in place
192      */
193     if (nptr < 0) {
194         AH9300(ah)->calibration_data_source = calibration_data_none;
195         AH9300(ah)->calibration_data_source_address = 0;
196         dptr = ar9300_eeprom_struct_default_find_by_id(
197             ar9300_eeprom_template_default);
198         if (dptr != 0) {
199             OS_MEMCPY(mptr, dptr, mdata_size);    
200             nptr = 0;
201         }
202     }
203     /*
204      * if we can't find the best template, put any old template in place
205      * presume that newer ones are better, so search backwards
206      */
207     if (nptr < 0) {
208         AH9300(ah)->calibration_data_source = calibration_data_none;
209         AH9300(ah)->calibration_data_source_address = 0;
210         for (it = ar9300_eeprom_struct_default_many() - 1; it >= 0; it--) {
211             dptr = ar9300_eeprom_struct_default(it);
212             if (dptr != 0) {
213                 OS_MEMCPY(mptr, dptr, mdata_size);    
214                 nptr = 0;
215                 break;
216             }
217         }
218     }
219     return nptr;
220 }
221
222 /*
223  * Read 16 bits of data from offset into *data
224  */
225 HAL_BOOL
226 ar9300_eeprom_read_word(struct ath_hal *ah, u_int off, u_int16_t *data)
227 {
228     if (AR_SREV_OSPREY(ah) || AR_SREV_POSEIDON(ah))
229     {
230         (void) OS_REG_READ(ah, AR9300_EEPROM_OFFSET + (off << AR9300_EEPROM_S));
231         if (!ath_hal_wait(ah,
232                           AR_HOSTIF_REG(ah, AR_EEPROM_STATUS_DATA),
233                           AR_EEPROM_STATUS_DATA_BUSY | AR_EEPROM_STATUS_DATA_PROT_ACCESS,
234                           0))
235         {
236             return AH_FALSE;
237         }
238         *data = MS(OS_REG_READ(ah,
239                                AR_HOSTIF_REG(ah, AR_EEPROM_STATUS_DATA)), AR_EEPROM_STATUS_DATA_VAL);
240        return AH_TRUE;
241     }
242     else
243     {
244         *data = 0;
245         return AH_FALSE;
246     }
247 }
248
249
250 HAL_BOOL
251 ar9300_otp_read(struct ath_hal *ah, u_int off, u_int32_t *data, HAL_BOOL is_wifi)
252 {
253     int time_out = 1000;
254     int status = 0;
255     u_int32_t addr;
256
257     addr = (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah))?
258         OTP_MEM_START_ADDRESS_WASP : OTP_MEM_START_ADDRESS;
259         if (!is_wifi) {
260         addr = BTOTP_MEM_START_ADDRESS;
261     }
262     addr += off * 4; /* OTP is 32 bit addressable */
263     (void) OS_REG_READ(ah, addr);
264
265     addr = (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) ?
266         OTP_STATUS0_OTP_SM_BUSY_WASP : OTP_STATUS0_OTP_SM_BUSY;
267         if (!is_wifi) {
268         addr = BTOTP_STATUS0_OTP_SM_BUSY;
269     }
270     while ((time_out > 0) && (!status)) { /* wait for access complete */
271         /* Read data valid, access not busy, sm not busy */
272         status = ((OS_REG_READ(ah, addr) & 0x7) == 0x4) ? 1 : 0;
273         time_out--;
274     }
275     if (time_out == 0) {
276         HALDEBUG(ah, HAL_DEBUG_EEPROM,
277             "%s: Timed out during OTP Status0 validation\n", __func__);
278         return AH_FALSE;
279     }
280
281     addr = (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) ?
282         OTP_STATUS1_EFUSE_READ_DATA_WASP : OTP_STATUS1_EFUSE_READ_DATA;
283         if (!is_wifi) {
284         addr = BTOTP_STATUS1_EFUSE_READ_DATA;
285     }
286     *data = OS_REG_READ(ah, addr);
287     return AH_TRUE;
288 }
289
290
291
292
293 static HAL_STATUS
294 ar9300_flash_map(struct ath_hal *ah)
295 {
296     /* XXX disable flash remapping for now (ie, SoC support) */
297     ath_hal_printf(ah, "%s: unimplemented for now\n", __func__);
298 #if 0
299     struct ath_hal_9300 *ahp = AH9300(ah);
300 #if defined(AR9100) || defined(__NetBSD__)
301     ahp->ah_cal_mem = OS_REMAP(ah, AR9300_EEPROM_START_ADDR, AR9300_EEPROM_MAX);
302 #else
303     ahp->ah_cal_mem = OS_REMAP((uintptr_t)(AH_PRIVATE(ah)->ah_st),
304         (AR9300_EEPROM_MAX + AR9300_FLASH_CAL_START_OFFSET));
305 #endif
306     if (!ahp->ah_cal_mem) {
307         HALDEBUG(ah, HAL_DEBUG_EEPROM,
308             "%s: cannot remap eeprom region \n", __func__);
309         return HAL_EIO;
310     }
311 #endif
312     return HAL_OK;
313 }
314
315 HAL_BOOL
316 ar9300_flash_read(struct ath_hal *ah, u_int off, u_int16_t *data)
317 {
318     struct ath_hal_9300 *ahp = AH9300(ah);
319
320     *data = ((u_int16_t *)ahp->ah_cal_mem)[off];
321     return AH_TRUE;
322 }
323
324 HAL_BOOL
325 ar9300_flash_write(struct ath_hal *ah, u_int off, u_int16_t data)
326 {
327     struct ath_hal_9300 *ahp = AH9300(ah);
328
329     ((u_int16_t *)ahp->ah_cal_mem)[off] = data;
330     return AH_TRUE;
331 }
332
333 HAL_STATUS
334 ar9300_eeprom_attach(struct ath_hal *ah)
335 {
336     struct ath_hal_9300 *ahp = AH9300(ah);
337     ahp->try_dram = 1;
338     ahp->try_eeprom = 1;
339     ahp->try_otp = 1;
340 #ifdef ATH_CAL_NAND_FLASH
341     ahp->try_nand = 1;
342 #else
343     ahp->try_flash = 1;
344 #endif
345     ahp->calibration_data_source = calibration_data_none;
346     ahp->calibration_data_source_address = 0;
347     ahp->calibration_data_try = calibration_data_try;
348     ahp->calibration_data_try_address = 0;
349
350     /*
351      * In case flash will be used for EEPROM. Otherwise ahp->ah_cal_mem
352      * must be set to NULL or the real EEPROM address.
353      */
354     ar9300_flash_map(ah);
355     /*
356      * ###### This function always return NO SPUR.
357      * This is not AH_TRUE for many board designs.
358      * Does anyone use this?
359      */
360     AH_PRIVATE(ah)->ah_getSpurChan = ar9300_eeprom_get_spur_chan;
361
362 #ifdef OLDCODE
363     /* XXX Needs to be moved for dynamic selection */
364     ahp->ah_eeprom = *(default9300[ar9300_eeprom_template_default]);
365
366
367     if (AR_SREV_HORNET(ah)) {
368         /* Set default values for Hornet. */
369         ahp->ah_eeprom.base_eep_header.op_cap_flags.op_flags =
370             AR9300_OPFLAGS_11G;
371         ahp->ah_eeprom.base_eep_header.txrx_mask = 0x11;
372     } else if (AR_SREV_POSEIDON(ah)) {
373         /* Set default values for Poseidon. */
374         ahp->ah_eeprom.base_eep_header.op_cap_flags.op_flags =
375             AR9300_OPFLAGS_11G;
376         ahp->ah_eeprom.base_eep_header.txrx_mask = 0x11;
377     }
378
379     if (AH_PRIVATE(ah)->ah_config.ath_hal_skip_eeprom_read) {
380         ahp->ah_emu_eeprom = 1;
381         return HAL_OK;
382     }
383
384     ahp->ah_emu_eeprom = 1;
385
386 #ifdef UNUSED
387 #endif
388     
389     if (!ar9300_fill_eeprom(ah)) {
390         return HAL_EIO;
391     }
392
393     return HAL_OK;
394     /* return ar9300_check_eeprom(ah); */
395 #else
396     ahp->ah_emu_eeprom = 1;
397
398 #if 0
399 /*#ifdef MDK_AP*/ /* MDK_AP is defined only in NART AP build */
400     u_int8_t buffer[10];
401     int caldata_check = 0;
402
403     ar9300_calibration_data_read_flash(
404         ah, FLASH_BASE_CALDATA_OFFSET, buffer, 4);
405     printf("flash caldata:: %x\n", buffer[0]);
406     if (buffer[0] != 0xff) {
407         caldata_check = 1;
408     }
409     if (!caldata_check) {
410         ar9300_eeprom_t *mptr;
411         int mdata_size;
412         if (AR_SREV_HORNET(ah)) {
413             /* XXX: For initial testing */
414             mptr = &ahp->ah_eeprom;
415             mdata_size = ar9300_eeprom_struct_size();
416             ahp->ah_eeprom = ar9300_template_ap121;
417             ahp->ah_emu_eeprom = 1;
418             /* need it to let art save in to flash ????? */
419             calibration_data_source = calibration_data_flash;
420         } else if (AR_SREV_WASP(ah)) {
421             /* XXX: For initial testing */
422             ath_hal_printf(ah, " wasp eep attach\n");
423             mptr = &ahp->ah_eeprom;
424             mdata_size = ar9300_eeprom_struct_size();
425             ahp->ah_eeprom = ar9300_template_generic;
426             ahp->ah_eeprom.mac_addr[0] = 0x00;
427             ahp->ah_eeprom.mac_addr[1] = 0x03;
428             ahp->ah_eeprom.mac_addr[2] = 0x7F;
429             ahp->ah_eeprom.mac_addr[3] = 0xBA;
430             ahp->ah_eeprom.mac_addr[4] = 0xD0;
431             ahp->ah_eeprom.mac_addr[5] = 0x00;
432             ahp->ah_emu_eeprom = 1;
433             ahp->ah_eeprom.base_eep_header.txrx_mask = 0x33;
434             ahp->ah_eeprom.base_eep_header.txrxgain = 0x10;
435             /* need it to let art save in to flash ????? */
436             calibration_data_source = calibration_data_flash;
437         }
438         return HAL_OK;
439     }
440 #endif
441     if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
442         ahp->try_eeprom = 0;
443     }
444
445     if (!ar9300_eeprom_restore(ah)) {
446         return HAL_EIO;
447     }
448     return HAL_OK;
449 #endif
450 }
451
452 u_int32_t
453 ar9300_eeprom_get(struct ath_hal_9300 *ahp, EEPROM_PARAM param)
454 {
455     ar9300_eeprom_t *eep = &ahp->ah_eeprom;
456     OSPREY_BASE_EEP_HEADER *p_base = &eep->base_eep_header;
457     OSPREY_BASE_EXTENSION_1 *base_ext1 = &eep->base_ext1;
458
459     switch (param) {
460 #ifdef NOTYET
461     case EEP_NFTHRESH_5:
462         return p_modal[0].noise_floor_thresh_ch[0];
463     case EEP_NFTHRESH_2:
464         return p_modal[1].noise_floor_thresh_ch[0];
465 #endif
466     case EEP_MAC_LSW:
467         return eep->mac_addr[0] << 8 | eep->mac_addr[1];
468     case EEP_MAC_MID:
469         return eep->mac_addr[2] << 8 | eep->mac_addr[3];
470     case EEP_MAC_MSW:
471         return eep->mac_addr[4] << 8 | eep->mac_addr[5];
472     case EEP_REG_0:
473         return p_base->reg_dmn[0];
474     case EEP_REG_1:
475         return p_base->reg_dmn[1];
476     case EEP_OP_CAP:
477         return p_base->device_cap;
478     case EEP_OP_MODE:
479         return p_base->op_cap_flags.op_flags;
480     case EEP_RF_SILENT:
481         return p_base->rf_silent;
482 #ifdef NOTYET
483     case EEP_OB_5:
484         return p_modal[0].ob;
485     case EEP_DB_5:
486         return p_modal[0].db;
487     case EEP_OB_2:
488         return p_modal[1].ob;
489     case EEP_DB_2:
490         return p_modal[1].db;
491     case EEP_MINOR_REV:
492         return p_base->eeprom_version & AR9300_EEP_VER_MINOR_MASK;
493 #endif
494     case EEP_TX_MASK:
495         return (p_base->txrx_mask >> 4) & 0xf;
496     case EEP_RX_MASK:
497         return p_base->txrx_mask & 0xf;
498 #ifdef NOTYET
499     case EEP_FSTCLK_5G:
500         return p_base->fast_clk5g;
501     case EEP_RXGAIN_TYPE:
502         return p_base->rx_gain_type;
503 #endif
504     case EEP_DRIVE_STRENGTH:
505 #define AR9300_EEP_BASE_DRIVE_STRENGTH    0x1 
506         return p_base->misc_configuration & AR9300_EEP_BASE_DRIVE_STRENGTH;
507     case EEP_INTERNAL_REGULATOR:
508         /* Bit 4 is internal regulator flag */
509         return ((p_base->feature_enable & 0x10) >> 4);
510     case EEP_SWREG:
511         return (p_base->swreg);
512     case EEP_PAPRD_ENABLED:
513         /* Bit 5 is paprd flag */
514         return ((p_base->feature_enable & 0x20) >> 5);
515     case EEP_ANTDIV_control:
516         return (u_int32_t)(base_ext1->ant_div_control);
517     case EEP_CHAIN_MASK_REDUCE:
518         return ((p_base->misc_configuration >> 3) & 0x1);
519     case EEP_OL_PWRCTRL:
520         return 0;
521      case EEP_DEV_TYPE:
522         return p_base->device_type;
523     default:
524         HALASSERT(0);
525         return 0;
526     }
527 }
528
529
530
531 /******************************************************************************/
532 /*!
533 **  \brief EEPROM fixup code for INI values
534 **
535 ** This routine provides a place to insert "fixup" code for specific devices
536 ** that need to modify INI values based on EEPROM values, BEFORE the INI values
537 ** are written.
538 ** Certain registers in the INI file can only be written once without
539 ** undesired side effects, and this provides a place for EEPROM overrides
540 ** in these cases.
541 **
542 ** This is called at attach time once.  It should not affect run time
543 ** performance at all
544 **
545 **  \param ah       Pointer to HAL object (this)
546 **  \param p_eep_data Pointer to (filled in) eeprom data structure
547 **  \param reg      register being inspected on this call
548 **  \param value    value in INI file
549 **
550 **  \return Updated value for INI file.
551 */
552 u_int32_t
553 ar9300_ini_fixup(struct ath_hal *ah, ar9300_eeprom_t *p_eep_data,
554     u_int32_t reg, u_int32_t value)
555 {
556     HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE,
557         "ar9300_eeprom_def_ini_fixup: FIXME\n");
558 #if 0
559     BASE_EEPDEF_HEADER  *p_base  = &(p_eep_data->base_eep_header);
560
561     switch (AH_PRIVATE(ah)->ah_devid)
562     {
563     case AR9300_DEVID_AR9300_PCI:
564         /*
565         ** Need to set the external/internal regulator bit to the proper value.
566         ** Can only write this ONCE.
567         */
568
569         if ( reg == 0x7894 )
570         {
571             /*
572             ** Check for an EEPROM data structure of "0x0b" or better
573             */
574
575             HALDEBUG(ah, HAL_DEBUG_EEPROM, "ini VAL: %x  EEPROM: %x\n",
576                      value, (p_base->version & 0xff));
577
578             if ( (p_base->version & 0xff) > 0x0a) {
579                 HALDEBUG(ah, HAL_DEBUG_EEPROM,
580                     "PWDCLKIND: %d\n", p_base->pwdclkind);
581                 value &= ~AR_AN_TOP2_PWDCLKIND;
582                 value |=
583                     AR_AN_TOP2_PWDCLKIND &
584                     (p_base->pwdclkind <<  AR_AN_TOP2_PWDCLKIND_S);
585             } else {
586                 HALDEBUG(ah, HAL_DEBUG_EEPROM, "PWDCLKIND Earlier Rev\n");
587             }
588
589             HALDEBUG(ah, HAL_DEBUG_EEPROM, "final ini VAL: %x\n", value);
590         }
591         break;
592
593     }
594
595     return (value);
596 #else
597     return 0;
598 #endif
599 }
600
601 /*
602  * Returns the interpolated y value corresponding to the specified x value
603  * from the np ordered pairs of data (px,py).
604  * The pairs do not have to be in any order.
605  * If the specified x value is less than any of the px,
606  * the returned y value is equal to the py for the lowest px.
607  * If the specified x value is greater than any of the px,
608  * the returned y value is equal to the py for the highest px.
609  */
610 static int
611 interpolate(int32_t x, int32_t *px, int32_t *py, u_int16_t np)
612 {
613     int ip = 0;
614     int lx = 0, ly = 0, lhave = 0;
615     int hx = 0, hy = 0, hhave = 0;
616     int dx = 0;
617     int y = 0;
618     int bf, factor, plus;
619
620     lhave = 0;
621     hhave = 0;
622     /*
623      * identify best lower and higher x calibration measurement
624      */
625     for (ip = 0; ip < np; ip++) {
626         dx = x - px[ip];
627         /* this measurement is higher than our desired x */
628         if (dx <= 0) {
629             if (!hhave || dx > (x - hx)) {
630                 /* new best higher x measurement */
631                 hx = px[ip];
632                 hy = py[ip];
633                 hhave = 1;
634             }
635         }
636         /* this measurement is lower than our desired x */
637         if (dx >= 0) {
638             if (!lhave || dx < (x - lx)) {
639                 /* new best lower x measurement */
640                 lx = px[ip];
641                 ly = py[ip];
642                 lhave = 1;
643             }
644         }
645     }
646     /* the low x is good */
647     if (lhave) {
648         /* so is the high x */
649         if (hhave) {
650             /* they're the same, so just pick one */
651             if (hx == lx) {
652                 y = ly;
653             } else {
654                 /* interpolate with round off */
655                 bf = (2 * (hy - ly) * (x - lx)) / (hx - lx);
656                 plus = (bf % 2);
657                 factor = bf / 2;
658                 y = ly + factor + plus;
659             }
660         } else {
661             /* only low is good, use it */
662             y = ly;
663         }
664     } else if (hhave) {
665         /* only high is good, use it */
666         y = hy;
667     } else {
668         /* nothing is good,this should never happen unless np=0, ????  */
669         y = -(1 << 30);
670     }
671
672     return y;
673 }
674
675 u_int8_t
676 ar9300_eeprom_get_legacy_trgt_pwr(struct ath_hal *ah, u_int16_t rate_index,
677     u_int16_t freq, HAL_BOOL is_2ghz)
678 {
679     u_int16_t            num_piers, i;
680     int32_t              target_power_array[OSPREY_NUM_5G_20_TARGET_POWERS];
681     int32_t              freq_array[OSPREY_NUM_5G_20_TARGET_POWERS]; 
682     u_int8_t             *p_freq_bin;
683     ar9300_eeprom_t      *eep = &AH9300(ah)->ah_eeprom;
684     CAL_TARGET_POWER_LEG *p_eeprom_target_pwr;
685
686     if (is_2ghz) {
687         num_piers = OSPREY_NUM_2G_20_TARGET_POWERS;    
688         p_eeprom_target_pwr = eep->cal_target_power_2g;
689         p_freq_bin = eep->cal_target_freqbin_2g;
690     } else {
691         num_piers = OSPREY_NUM_5G_20_TARGET_POWERS;
692         p_eeprom_target_pwr = eep->cal_target_power_5g;
693         p_freq_bin = eep->cal_target_freqbin_5g;
694    }
695
696     /*
697      * create array of channels and targetpower from
698      * targetpower piers stored on eeprom
699      */
700     for (i = 0; i < num_piers; i++) {
701         freq_array[i] = FBIN2FREQ(p_freq_bin[i], is_2ghz);
702         target_power_array[i] = p_eeprom_target_pwr[i].t_pow2x[rate_index];
703     }
704
705     /* interpolate to get target power for given frequency */
706     return
707         ((u_int8_t)interpolate(
708             (int32_t)freq, freq_array, target_power_array, num_piers));
709 }
710
711 u_int8_t
712 ar9300_eeprom_get_ht20_trgt_pwr(struct ath_hal *ah, u_int16_t rate_index,
713     u_int16_t freq, HAL_BOOL is_2ghz)
714 {
715     u_int16_t               num_piers, i;
716     int32_t                 target_power_array[OSPREY_NUM_5G_20_TARGET_POWERS];
717     int32_t                 freq_array[OSPREY_NUM_5G_20_TARGET_POWERS]; 
718     u_int8_t                *p_freq_bin;
719     ar9300_eeprom_t         *eep = &AH9300(ah)->ah_eeprom;
720     OSP_CAL_TARGET_POWER_HT *p_eeprom_target_pwr;
721
722     if (is_2ghz) {
723         num_piers = OSPREY_NUM_2G_20_TARGET_POWERS;    
724         p_eeprom_target_pwr = eep->cal_target_power_2g_ht20;
725         p_freq_bin = eep->cal_target_freqbin_2g_ht20;
726     } else {
727         num_piers = OSPREY_NUM_5G_20_TARGET_POWERS;
728         p_eeprom_target_pwr = eep->cal_target_power_5g_ht20;
729         p_freq_bin = eep->cal_target_freqbin_5g_ht20;
730     }
731
732     /*
733      * create array of channels and targetpower from
734      * targetpower piers stored on eeprom
735      */
736     for (i = 0; i < num_piers; i++) {
737         freq_array[i] = FBIN2FREQ(p_freq_bin[i], is_2ghz);
738         target_power_array[i] = p_eeprom_target_pwr[i].t_pow2x[rate_index];
739     }
740
741     /* interpolate to get target power for given frequency */
742     return
743         ((u_int8_t)interpolate(
744             (int32_t)freq, freq_array, target_power_array, num_piers));
745 }
746
747 u_int8_t
748 ar9300_eeprom_get_ht40_trgt_pwr(struct ath_hal *ah, u_int16_t rate_index,
749     u_int16_t freq, HAL_BOOL is_2ghz)
750 {
751     u_int16_t               num_piers, i;
752     int32_t                 target_power_array[OSPREY_NUM_5G_40_TARGET_POWERS];
753     int32_t                 freq_array[OSPREY_NUM_5G_40_TARGET_POWERS]; 
754     u_int8_t                *p_freq_bin;
755     ar9300_eeprom_t         *eep = &AH9300(ah)->ah_eeprom;
756     OSP_CAL_TARGET_POWER_HT *p_eeprom_target_pwr;
757
758     if (is_2ghz) {
759         num_piers = OSPREY_NUM_2G_40_TARGET_POWERS;    
760         p_eeprom_target_pwr = eep->cal_target_power_2g_ht40;
761         p_freq_bin = eep->cal_target_freqbin_2g_ht40;
762     } else {
763         num_piers = OSPREY_NUM_5G_40_TARGET_POWERS;
764         p_eeprom_target_pwr = eep->cal_target_power_5g_ht40;
765         p_freq_bin = eep->cal_target_freqbin_5g_ht40;
766     }
767
768     /*
769      * create array of channels and targetpower from
770      * targetpower piers stored on eeprom
771      */
772     for (i = 0; i < num_piers; i++) {
773         freq_array[i] = FBIN2FREQ(p_freq_bin[i], is_2ghz);
774         target_power_array[i] = p_eeprom_target_pwr[i].t_pow2x[rate_index];
775     }
776
777     /* interpolate to get target power for given frequency */
778     return
779         ((u_int8_t)interpolate(
780             (int32_t)freq, freq_array, target_power_array, num_piers));
781 }
782
783 u_int8_t
784 ar9300_eeprom_get_cck_trgt_pwr(struct ath_hal *ah, u_int16_t rate_index,
785     u_int16_t freq)
786 {
787     u_int16_t            num_piers = OSPREY_NUM_2G_CCK_TARGET_POWERS, i;
788     int32_t              target_power_array[OSPREY_NUM_2G_CCK_TARGET_POWERS];
789     int32_t              freq_array[OSPREY_NUM_2G_CCK_TARGET_POWERS]; 
790     ar9300_eeprom_t      *eep = &AH9300(ah)->ah_eeprom;
791     u_int8_t             *p_freq_bin = eep->cal_target_freqbin_cck;
792     CAL_TARGET_POWER_LEG *p_eeprom_target_pwr = eep->cal_target_power_cck;
793
794     /*
795      * create array of channels and targetpower from
796      * targetpower piers stored on eeprom
797      */
798     for (i = 0; i < num_piers; i++) {
799         freq_array[i] = FBIN2FREQ(p_freq_bin[i], 1);
800         target_power_array[i] = p_eeprom_target_pwr[i].t_pow2x[rate_index];
801     }
802
803     /* interpolate to get target power for given frequency */
804     return
805         ((u_int8_t)interpolate(
806             (int32_t)freq, freq_array, target_power_array, num_piers));
807 }
808
809 /*
810  * Set tx power registers to array of values passed in
811  */
812 int
813 ar9300_transmit_power_reg_write(struct ath_hal *ah, u_int8_t *p_pwr_array) 
814 {   
815 #define POW_SM(_r, _s)     (((_r) & 0x3f) << (_s))
816     /* make sure forced gain is not set */
817 #if 0
818     field_write("force_dac_gain", 0);
819     OS_REG_WRITE(ah, 0xa3f8, 0);
820     field_write("force_tx_gain", 0);
821 #endif
822
823     OS_REG_WRITE(ah, 0xa458, 0);
824
825     /* Write the OFDM power per rate set */
826     /* 6 (LSB), 9, 12, 18 (MSB) */
827     OS_REG_WRITE(ah, 0xa3c0,
828         POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 24)
829           | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 16)
830           | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24],  8)
831           | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24],  0)
832     );
833     /* 24 (LSB), 36, 48, 54 (MSB) */
834     OS_REG_WRITE(ah, 0xa3c4,
835         POW_SM(p_pwr_array[ALL_TARGET_LEGACY_54], 24)
836           | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_48], 16)
837           | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_36],  8)
838           | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24],  0)
839     );
840
841     /* Write the CCK power per rate set */
842     /* 1L (LSB), reserved, 2L, 2S (MSB) */  
843     OS_REG_WRITE(ah, 0xa3c8,
844         POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 24)
845           | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L],  16)
846 /*          | POW_SM(tx_power_times2,  8)*/ /* this is reserved for Osprey */
847           | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L],   0)
848     );
849     /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
850     OS_REG_WRITE(ah, 0xa3cc,
851         POW_SM(p_pwr_array[ALL_TARGET_LEGACY_11S], 24)
852           | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_11L], 16)
853           | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_5S],  8)
854           | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L],  0)
855     );
856
857         /* write the power for duplicated frames - HT40 */
858         /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm  (MSB) */
859     OS_REG_WRITE(ah, 0xa3e0,
860         POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 24)
861           | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 16)
862           | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24],  8)
863           | POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L],  0)
864     );
865
866     /* Write the HT20 power per rate set */
867     /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
868     OS_REG_WRITE(ah, 0xa3d0,
869         POW_SM(p_pwr_array[ALL_TARGET_HT20_5], 24)
870           | POW_SM(p_pwr_array[ALL_TARGET_HT20_4],  16)
871           | POW_SM(p_pwr_array[ALL_TARGET_HT20_1_3_9_11_17_19],  8)
872           | POW_SM(p_pwr_array[ALL_TARGET_HT20_0_8_16],   0)
873     );
874     
875     /* 6 (LSB), 7, 12, 13 (MSB) */
876     OS_REG_WRITE(ah, 0xa3d4,
877         POW_SM(p_pwr_array[ALL_TARGET_HT20_13], 24)
878           | POW_SM(p_pwr_array[ALL_TARGET_HT20_12],  16)
879           | POW_SM(p_pwr_array[ALL_TARGET_HT20_7],  8)
880           | POW_SM(p_pwr_array[ALL_TARGET_HT20_6],   0)
881     );
882
883     /* 14 (LSB), 15, 20, 21 */
884     OS_REG_WRITE(ah, 0xa3e4,
885         POW_SM(p_pwr_array[ALL_TARGET_HT20_21], 24)
886           | POW_SM(p_pwr_array[ALL_TARGET_HT20_20],  16)
887           | POW_SM(p_pwr_array[ALL_TARGET_HT20_15],  8)
888           | POW_SM(p_pwr_array[ALL_TARGET_HT20_14],   0)
889     );
890
891     /* Mixed HT20 and HT40 rates */
892     /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
893     OS_REG_WRITE(ah, 0xa3e8,
894         POW_SM(p_pwr_array[ALL_TARGET_HT40_23], 24)
895           | POW_SM(p_pwr_array[ALL_TARGET_HT40_22],  16)
896           | POW_SM(p_pwr_array[ALL_TARGET_HT20_23],  8)
897           | POW_SM(p_pwr_array[ALL_TARGET_HT20_22],   0)
898     );
899     
900     /* Write the HT40 power per rate set */
901     /* correct PAR difference between HT40 and HT20/LEGACY */
902     /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
903     OS_REG_WRITE(ah, 0xa3d8,
904         POW_SM(p_pwr_array[ALL_TARGET_HT40_5], 24)
905           | POW_SM(p_pwr_array[ALL_TARGET_HT40_4],  16)
906           | POW_SM(p_pwr_array[ALL_TARGET_HT40_1_3_9_11_17_19],  8)
907           | POW_SM(p_pwr_array[ALL_TARGET_HT40_0_8_16],   0)
908     );
909
910     /* 6 (LSB), 7, 12, 13 (MSB) */
911     OS_REG_WRITE(ah, 0xa3dc,
912         POW_SM(p_pwr_array[ALL_TARGET_HT40_13], 24)
913           | POW_SM(p_pwr_array[ALL_TARGET_HT40_12],  16)
914           | POW_SM(p_pwr_array[ALL_TARGET_HT40_7], 8)
915           | POW_SM(p_pwr_array[ALL_TARGET_HT40_6], 0)
916     );
917
918     /* 14 (LSB), 15, 20, 21 */
919     OS_REG_WRITE(ah, 0xa3ec,
920         POW_SM(p_pwr_array[ALL_TARGET_HT40_21], 24)
921           | POW_SM(p_pwr_array[ALL_TARGET_HT40_20],  16)
922           | POW_SM(p_pwr_array[ALL_TARGET_HT40_15],  8)
923           | POW_SM(p_pwr_array[ALL_TARGET_HT40_14],   0)
924     );
925
926     return 0;
927 #undef POW_SM    
928 }
929
930 static void
931 ar9300_selfgen_tpc_reg_write(struct ath_hal *ah, const struct ieee80211_channel *chan,
932                              u_int8_t *p_pwr_array) 
933 {
934     u_int32_t tpc_reg_val;
935
936     /* Set the target power values for self generated frames (ACK,RTS/CTS) to
937      * be within limits. This is just a safety measure.With per packet TPC mode
938      * enabled the target power value used with self generated frames will be
939      * MIN( TPC reg, BB_powertx_rate register)
940      */
941     
942     if (IEEE80211_IS_CHAN_2GHZ(chan)) {
943         tpc_reg_val = (SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_ACK) |
944                        SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], AR_TPC_CTS) |
945                        SM(0x3f, AR_TPC_CHIRP) |
946                        SM(0x3f, AR_TPC_RPT));
947     } else {
948         tpc_reg_val = (SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_ACK) |
949                        SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], AR_TPC_CTS) |
950                        SM(0x3f, AR_TPC_CHIRP) |
951                        SM(0x3f, AR_TPC_RPT));
952     }
953     OS_REG_WRITE(ah, AR_TPC, tpc_reg_val);
954 }
955
956 void
957 ar9300_set_target_power_from_eeprom(struct ath_hal *ah, u_int16_t freq,
958     u_int8_t *target_power_val_t2)
959 {
960     /* hard code for now, need to get from eeprom struct */
961     u_int8_t ht40_power_inc_for_pdadc = 0;
962     HAL_BOOL  is_2ghz = 0;
963     
964     if (freq < 4000) {
965         is_2ghz = 1;
966     }
967
968     target_power_val_t2[ALL_TARGET_LEGACY_6_24] =
969         ar9300_eeprom_get_legacy_trgt_pwr(
970             ah, LEGACY_TARGET_RATE_6_24, freq, is_2ghz);
971     target_power_val_t2[ALL_TARGET_LEGACY_36] =
972         ar9300_eeprom_get_legacy_trgt_pwr(
973             ah, LEGACY_TARGET_RATE_36, freq, is_2ghz);
974     target_power_val_t2[ALL_TARGET_LEGACY_48] =
975         ar9300_eeprom_get_legacy_trgt_pwr(
976             ah, LEGACY_TARGET_RATE_48, freq, is_2ghz);
977     target_power_val_t2[ALL_TARGET_LEGACY_54] =
978         ar9300_eeprom_get_legacy_trgt_pwr(
979             ah, LEGACY_TARGET_RATE_54, freq, is_2ghz);
980     target_power_val_t2[ALL_TARGET_LEGACY_1L_5L] =
981         ar9300_eeprom_get_cck_trgt_pwr(
982             ah, LEGACY_TARGET_RATE_1L_5L, freq);
983     target_power_val_t2[ALL_TARGET_LEGACY_5S] =
984         ar9300_eeprom_get_cck_trgt_pwr(
985             ah, LEGACY_TARGET_RATE_5S, freq);
986     target_power_val_t2[ALL_TARGET_LEGACY_11L] =
987         ar9300_eeprom_get_cck_trgt_pwr(
988             ah, LEGACY_TARGET_RATE_11L, freq);
989     target_power_val_t2[ALL_TARGET_LEGACY_11S] =
990         ar9300_eeprom_get_cck_trgt_pwr(
991             ah, LEGACY_TARGET_RATE_11S, freq);
992     target_power_val_t2[ALL_TARGET_HT20_0_8_16] =
993         ar9300_eeprom_get_ht20_trgt_pwr(
994             ah, HT_TARGET_RATE_0_8_16, freq, is_2ghz);
995     target_power_val_t2[ALL_TARGET_HT20_1_3_9_11_17_19] =
996         ar9300_eeprom_get_ht20_trgt_pwr(
997             ah, HT_TARGET_RATE_1_3_9_11_17_19, freq, is_2ghz);
998     target_power_val_t2[ALL_TARGET_HT20_4] =
999         ar9300_eeprom_get_ht20_trgt_pwr(
1000             ah, HT_TARGET_RATE_4, freq, is_2ghz);
1001     target_power_val_t2[ALL_TARGET_HT20_5] =
1002         ar9300_eeprom_get_ht20_trgt_pwr(
1003             ah, HT_TARGET_RATE_5, freq, is_2ghz);
1004     target_power_val_t2[ALL_TARGET_HT20_6] =
1005         ar9300_eeprom_get_ht20_trgt_pwr(
1006             ah, HT_TARGET_RATE_6, freq, is_2ghz);
1007     target_power_val_t2[ALL_TARGET_HT20_7] =
1008         ar9300_eeprom_get_ht20_trgt_pwr(
1009             ah, HT_TARGET_RATE_7, freq, is_2ghz);
1010     target_power_val_t2[ALL_TARGET_HT20_12] =
1011         ar9300_eeprom_get_ht20_trgt_pwr(
1012             ah, HT_TARGET_RATE_12, freq, is_2ghz);
1013     target_power_val_t2[ALL_TARGET_HT20_13] =
1014         ar9300_eeprom_get_ht20_trgt_pwr(
1015             ah, HT_TARGET_RATE_13, freq, is_2ghz);
1016     target_power_val_t2[ALL_TARGET_HT20_14] =
1017         ar9300_eeprom_get_ht20_trgt_pwr(
1018             ah, HT_TARGET_RATE_14, freq, is_2ghz);
1019     target_power_val_t2[ALL_TARGET_HT20_15] =
1020         ar9300_eeprom_get_ht20_trgt_pwr(
1021             ah, HT_TARGET_RATE_15, freq, is_2ghz);
1022     target_power_val_t2[ALL_TARGET_HT20_20] =
1023         ar9300_eeprom_get_ht20_trgt_pwr(
1024             ah, HT_TARGET_RATE_20, freq, is_2ghz);
1025     target_power_val_t2[ALL_TARGET_HT20_21] =
1026         ar9300_eeprom_get_ht20_trgt_pwr(
1027             ah, HT_TARGET_RATE_21, freq, is_2ghz);
1028     target_power_val_t2[ALL_TARGET_HT20_22] =
1029         ar9300_eeprom_get_ht20_trgt_pwr(
1030             ah, HT_TARGET_RATE_22, freq, is_2ghz);
1031     target_power_val_t2[ALL_TARGET_HT20_23] =
1032         ar9300_eeprom_get_ht20_trgt_pwr(
1033             ah, HT_TARGET_RATE_23, freq, is_2ghz);
1034     target_power_val_t2[ALL_TARGET_HT40_0_8_16] =
1035         ar9300_eeprom_get_ht40_trgt_pwr(
1036             ah, HT_TARGET_RATE_0_8_16, freq, is_2ghz) +
1037         ht40_power_inc_for_pdadc;
1038     target_power_val_t2[ALL_TARGET_HT40_1_3_9_11_17_19] =
1039         ar9300_eeprom_get_ht40_trgt_pwr(
1040             ah, HT_TARGET_RATE_1_3_9_11_17_19, freq, is_2ghz) +
1041         ht40_power_inc_for_pdadc;
1042     target_power_val_t2[ALL_TARGET_HT40_4] =
1043         ar9300_eeprom_get_ht40_trgt_pwr(
1044             ah, HT_TARGET_RATE_4, freq, is_2ghz) + ht40_power_inc_for_pdadc;
1045     target_power_val_t2[ALL_TARGET_HT40_5] =
1046         ar9300_eeprom_get_ht40_trgt_pwr(
1047             ah, HT_TARGET_RATE_5, freq, is_2ghz) + ht40_power_inc_for_pdadc;
1048     target_power_val_t2[ALL_TARGET_HT40_6] =
1049         ar9300_eeprom_get_ht40_trgt_pwr(
1050             ah, HT_TARGET_RATE_6, freq, is_2ghz) + ht40_power_inc_for_pdadc;
1051     target_power_val_t2[ALL_TARGET_HT40_7] =
1052         ar9300_eeprom_get_ht40_trgt_pwr(
1053             ah, HT_TARGET_RATE_7, freq, is_2ghz) + ht40_power_inc_for_pdadc;
1054     target_power_val_t2[ALL_TARGET_HT40_12] =
1055         ar9300_eeprom_get_ht40_trgt_pwr(
1056             ah, HT_TARGET_RATE_12, freq, is_2ghz) + ht40_power_inc_for_pdadc;
1057     target_power_val_t2[ALL_TARGET_HT40_13] =
1058         ar9300_eeprom_get_ht40_trgt_pwr(
1059             ah, HT_TARGET_RATE_13, freq, is_2ghz) + ht40_power_inc_for_pdadc;
1060     target_power_val_t2[ALL_TARGET_HT40_14] =
1061         ar9300_eeprom_get_ht40_trgt_pwr(
1062             ah, HT_TARGET_RATE_14, freq, is_2ghz) + ht40_power_inc_for_pdadc;
1063     target_power_val_t2[ALL_TARGET_HT40_15] =
1064         ar9300_eeprom_get_ht40_trgt_pwr(
1065             ah, HT_TARGET_RATE_15, freq, is_2ghz) + ht40_power_inc_for_pdadc;
1066     target_power_val_t2[ALL_TARGET_HT40_20] =
1067         ar9300_eeprom_get_ht40_trgt_pwr(
1068             ah, HT_TARGET_RATE_20, freq, is_2ghz) + ht40_power_inc_for_pdadc;
1069     target_power_val_t2[ALL_TARGET_HT40_21] =
1070         ar9300_eeprom_get_ht40_trgt_pwr(
1071             ah, HT_TARGET_RATE_21, freq, is_2ghz) + ht40_power_inc_for_pdadc;
1072     target_power_val_t2[ALL_TARGET_HT40_22] =
1073         ar9300_eeprom_get_ht40_trgt_pwr(
1074             ah, HT_TARGET_RATE_22, freq, is_2ghz) + ht40_power_inc_for_pdadc;
1075     target_power_val_t2[ALL_TARGET_HT40_23] =
1076         ar9300_eeprom_get_ht40_trgt_pwr(
1077             ah, HT_TARGET_RATE_23, freq, is_2ghz) + ht40_power_inc_for_pdadc;
1078
1079 #ifdef AH_DEBUG
1080     {
1081         int  i = 0;
1082
1083         HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: APPLYING TARGET POWERS\n", __func__);
1084         while (i < ar9300_rate_size) {
1085             HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: TPC[%02d] 0x%08x ",
1086                      __func__, i, target_power_val_t2[i]);
1087             i++;
1088                         if (i == ar9300_rate_size) {
1089                 break;
1090                         }
1091             HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: TPC[%02d] 0x%08x ",
1092                      __func__, i, target_power_val_t2[i]);
1093             i++;
1094                         if (i == ar9300_rate_size) {
1095                 break;
1096                         }
1097             HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: TPC[%02d] 0x%08x ",
1098                      __func__, i, target_power_val_t2[i]);
1099             i++;
1100                         if (i == ar9300_rate_size) {
1101                 break;
1102                         }
1103             HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: TPC[%02d] 0x%08x \n",
1104                      __func__, i, target_power_val_t2[i]);
1105             i++;
1106         }
1107     }
1108 #endif
1109
1110
1111 u_int16_t *ar9300_regulatory_domain_get(struct ath_hal *ah)
1112 {
1113     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1114     return eep->base_eep_header.reg_dmn;
1115 }
1116
1117
1118 int32_t 
1119 ar9300_eeprom_write_enable_gpio_get(struct ath_hal *ah)
1120 {
1121     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1122     return eep->base_eep_header.eeprom_write_enable_gpio;
1123 }
1124
1125 int32_t 
1126 ar9300_wlan_disable_gpio_get(struct ath_hal *ah)
1127 {
1128     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1129     return eep->base_eep_header.wlan_disable_gpio;
1130 }
1131
1132 int32_t 
1133 ar9300_wlan_led_gpio_get(struct ath_hal *ah)
1134 {
1135     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1136     return eep->base_eep_header.wlan_led_gpio;
1137 }
1138
1139 int32_t 
1140 ar9300_rx_band_select_gpio_get(struct ath_hal *ah)
1141 {
1142     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1143     return eep->base_eep_header.rx_band_select_gpio;
1144 }
1145
1146 /*
1147  * since valid noise floor values are negative, returns 1 on error
1148  */
1149 int32_t
1150 ar9300_noise_floor_cal_or_power_get(struct ath_hal *ah, int32_t frequency,
1151     int32_t ichain, HAL_BOOL use_cal)
1152 {
1153     int     nf_use = 1; /* start with an error return value */
1154     int32_t fx[OSPREY_NUM_5G_CAL_PIERS + OSPREY_NUM_2G_CAL_PIERS];
1155     int32_t nf[OSPREY_NUM_5G_CAL_PIERS + OSPREY_NUM_2G_CAL_PIERS];
1156     int     nnf;
1157     int     is_2ghz;
1158     int     ipier, npier;
1159     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1160     u_int8_t        *p_cal_pier;
1161     OSP_CAL_DATA_PER_FREQ_OP_LOOP *p_cal_pier_struct;
1162
1163     /*
1164      * check chain value
1165      */
1166     if (ichain < 0 || ichain >= OSPREY_MAX_CHAINS) {
1167         return 1;
1168     }
1169
1170     /* figure out which band we're using */
1171     is_2ghz = (frequency < 4000);
1172     if (is_2ghz) {
1173         npier = OSPREY_NUM_2G_CAL_PIERS;
1174         p_cal_pier = eep->cal_freq_pier_2g;
1175         p_cal_pier_struct = eep->cal_pier_data_2g[ichain];
1176     } else {
1177         npier = OSPREY_NUM_5G_CAL_PIERS;
1178         p_cal_pier = eep->cal_freq_pier_5g;
1179         p_cal_pier_struct = eep->cal_pier_data_5g[ichain];
1180     }
1181     /* look for valid noise floor values */
1182     nnf = 0;
1183     for (ipier = 0; ipier < npier; ipier++) {
1184         fx[nnf] = FBIN2FREQ(p_cal_pier[ipier], is_2ghz);
1185         nf[nnf] = use_cal ?
1186             p_cal_pier_struct[ipier].rx_noisefloor_cal :
1187             p_cal_pier_struct[ipier].rx_noisefloor_power;
1188         if (nf[nnf] < 0) {
1189             nnf++;
1190         }
1191     }
1192     /*
1193      * If we have some valid values, interpolate to find the value
1194      * at the desired frequency.
1195      */
1196     if (nnf > 0) {
1197         nf_use = interpolate(frequency, fx, nf, nnf);
1198     }
1199
1200     return nf_use;
1201 }
1202
1203 int32_t ar9300_rx_gain_index_get(struct ath_hal *ah)
1204 {
1205     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1206
1207     return (eep->base_eep_header.txrxgain) & 0xf;        /* bits 3:0 */
1208 }
1209
1210
1211 int32_t ar9300_tx_gain_index_get(struct ath_hal *ah)
1212 {
1213     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1214
1215     return (eep->base_eep_header.txrxgain >> 4) & 0xf;    /* bits 7:4 */
1216 }
1217
1218 HAL_BOOL ar9300_internal_regulator_apply(struct ath_hal *ah)
1219 {
1220     struct ath_hal_9300 *ahp = AH9300(ah);
1221     int internal_regulator = ar9300_eeprom_get(ahp, EEP_INTERNAL_REGULATOR);
1222     int reg_pmu1, reg_pmu2, reg_pmu1_set, reg_pmu2_set;
1223     u_int32_t reg_PMU1, reg_PMU2;
1224     unsigned long eep_addr;
1225     u_int32_t reg_val, reg_usb = 0, reg_pmu = 0;
1226     int usb_valid = 0, pmu_valid = 0;
1227     unsigned char pmu_refv; 
1228
1229     if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
1230         reg_PMU1 = AR_PHY_PMU1_JUPITER;
1231         reg_PMU2 = AR_PHY_PMU2_JUPITER;
1232     }
1233     else {
1234         reg_PMU1 = AR_PHY_PMU1;
1235         reg_PMU2 = AR_PHY_PMU2;
1236     }
1237
1238     if (internal_regulator) {
1239         if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
1240             if (AR_SREV_HORNET(ah)) {
1241                 /* Read OTP first */
1242                 for (eep_addr = 0x14; ; eep_addr -= 0x10) {
1243
1244                     ar9300_otp_read(ah, eep_addr / 4, &reg_val, 1);
1245
1246                     if ((reg_val & 0x80) == 0x80){
1247                         usb_valid = 1;
1248                         reg_usb = reg_val & 0x000000ff;
1249                     }
1250                     
1251                     if ((reg_val & 0x80000000) == 0x80000000){
1252                         pmu_valid = 1;
1253                         reg_pmu = (reg_val & 0xff000000) >> 24;
1254                     }
1255
1256                     if (eep_addr == 0x4) {
1257                         break;
1258                     }
1259                 }
1260
1261                 if (pmu_valid) {
1262                     pmu_refv = reg_pmu & 0xf;
1263                 } else {
1264                     pmu_refv = 0x8;
1265                 }
1266
1267                 /*
1268                  * If (valid) {
1269                  *   Usb_phy_ctrl2_tx_cal_en -> 0
1270                  *   Usb_phy_ctrl2_tx_cal_sel -> 0
1271                  *   Usb_phy_ctrl2_tx_man_cal -> 0, 1, 3, 7 or 15 from OTP
1272                  * }
1273                  */
1274                 if (usb_valid) {
1275                     OS_REG_RMW_FIELD(ah, 0x16c88, AR_PHY_CTRL2_TX_CAL_EN, 0x0);
1276                     OS_REG_RMW_FIELD(ah, 0x16c88, AR_PHY_CTRL2_TX_CAL_SEL, 0x0);
1277                     OS_REG_RMW_FIELD(ah, 0x16c88, 
1278                         AR_PHY_CTRL2_TX_MAN_CAL, (reg_usb & 0xf));
1279                 }
1280
1281             } else {
1282                 pmu_refv = 0x8;
1283             }
1284             /*#ifndef USE_HIF*/
1285             /* Follow the MDK settings for Hornet PMU.
1286              * my $pwd               = 0x0;
1287              * my $Nfdiv             = 0x3;  # xtal_freq = 25MHz
1288              * my $Nfdiv             = 0x4;  # xtal_freq = 40MHz
1289              * my $Refv              = 0x7;  # 0x5:1.22V; 0x8:1.29V
1290              * my $Gm1               = 0x3;  #Poseidon $Gm1=1
1291              * my $classb            = 0x0;
1292              * my $Cc                = 0x1;  #Poseidon $Cc=7
1293              * my $Rc                = 0x6;
1294              * my $ramp_slope        = 0x1;
1295              * my $Segm              = 0x3;
1296              * my $use_local_osc     = 0x0;
1297              * my $force_xosc_stable = 0x0;
1298              * my $Selfb             = 0x0;  #Poseidon $Selfb=1
1299              * my $Filterfb          = 0x3;  #Poseidon $Filterfb=0
1300              * my $Filtervc          = 0x0;
1301              * my $disc              = 0x0;
1302              * my $discdel           = 0x4;
1303              * my $spare             = 0x0;
1304              * $reg_PMU1 =
1305              *     $pwd | ($Nfdiv<<1) | ($Refv<<4) | ($Gm1<<8) |
1306              *     ($classb<<11) | ($Cc<<14) | ($Rc<<17) | ($ramp_slope<<20) |
1307              *     ($Segm<<24) | ($use_local_osc<<26) |
1308              *     ($force_xosc_stable<<27) | ($Selfb<<28) | ($Filterfb<<29);
1309              * $reg_PMU2 = $handle->reg_rd("ch0_PMU2");
1310              * $reg_PMU2 = ($reg_PMU2 & 0xfe3fffff) | ($Filtervc<<22);
1311              * $reg_PMU2 = ($reg_PMU2 & 0xe3ffffff) | ($discdel<<26);
1312              * $reg_PMU2 = ($reg_PMU2 & 0x1fffffff) | ($spare<<29); 
1313              */
1314             if (ahp->clk_25mhz) {
1315                 reg_pmu1_set = 0 |
1316                     (3 <<  1) | (pmu_refv << 4) | (3 <<  8) | (0 << 11) |
1317                     (1 << 14) | (6 << 17) | (1 << 20) | (3 << 24) |
1318                     (0 << 26) | (0 << 27) | (0 << 28) | (0 << 29);
1319             } else {
1320                 if (AR_SREV_POSEIDON(ah)) {
1321                     reg_pmu1_set = 0 | 
1322                         (5 <<  1) | (7 <<  4) | (2 <<  8) | (0 << 11) |
1323                         (2 << 14) | (6 << 17) | (1 << 20) | (3 << 24) |
1324                         (0 << 26) | (0 << 27) | (1 << 28) | (0 << 29) ;
1325                 } else {
1326                     reg_pmu1_set = 0 |
1327                         (4 <<  1) | (7 <<  4) | (3 <<  8) | (0 << 11) |
1328                         (1 << 14) | (6 << 17) | (1 << 20) | (3 << 24) |
1329                         (0 << 26) | (0 << 27) | (0 << 28) | (0 << 29) ;
1330                 } 
1331             }
1332             OS_REG_RMW_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM, 0x0);
1333
1334             OS_REG_WRITE(ah, reg_PMU1, reg_pmu1_set);   /* 0x638c8376 */
1335             reg_pmu1 = OS_REG_READ(ah, reg_PMU1);
1336             while (reg_pmu1 != reg_pmu1_set) {
1337                 OS_REG_WRITE(ah, reg_PMU1, reg_pmu1_set);  /* 0x638c8376 */
1338                 OS_DELAY(10);
1339                 reg_pmu1 = OS_REG_READ(ah, reg_PMU1);
1340             }
1341                                 
1342             reg_pmu2_set =
1343                  (OS_REG_READ(ah, reg_PMU2) & (~0xFFC00000)) | (4 << 26);
1344             OS_REG_WRITE(ah, reg_PMU2, reg_pmu2_set);
1345             reg_pmu2 = OS_REG_READ(ah, reg_PMU2);
1346             while (reg_pmu2 != reg_pmu2_set) {
1347                 OS_REG_WRITE(ah, reg_PMU2, reg_pmu2_set);
1348                 OS_DELAY(10);
1349                 reg_pmu2 = OS_REG_READ(ah, reg_PMU2);
1350             }
1351             reg_pmu2_set =
1352                  (OS_REG_READ(ah, reg_PMU2) & (~0x00200000)) | (1 << 21);
1353             OS_REG_WRITE(ah, reg_PMU2, reg_pmu2_set);
1354             reg_pmu2 = OS_REG_READ(ah, reg_PMU2);
1355             while (reg_pmu2 != reg_pmu2_set) {
1356                 OS_REG_WRITE(ah, reg_PMU2, reg_pmu2_set);
1357                 OS_DELAY(10);
1358                 reg_pmu2 = OS_REG_READ(ah, reg_PMU2);
1359             }
1360             /*#endif*/
1361         } else if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
1362             /* Internal regulator is ON. Write swreg register. */
1363             int swreg = ar9300_eeprom_get(ahp, EEP_SWREG);
1364             OS_REG_WRITE(ah, reg_PMU1, swreg);
1365         } else {
1366             /* Internal regulator is ON. Write swreg register. */
1367             int swreg = ar9300_eeprom_get(ahp, EEP_SWREG);
1368             OS_REG_WRITE(ah, AR_RTC_REG_CONTROL1,
1369                          OS_REG_READ(ah, AR_RTC_REG_CONTROL1) &
1370                          (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
1371             OS_REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
1372             /* Set REG_CONTROL1.SWREG_PROGRAM */
1373             OS_REG_WRITE(ah, AR_RTC_REG_CONTROL1,
1374                 OS_REG_READ(ah, AR_RTC_REG_CONTROL1) |
1375                 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
1376         }
1377     } else {
1378         if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
1379             OS_REG_RMW_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM, 0x0);
1380             reg_pmu2 = OS_REG_READ_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM);
1381             while (reg_pmu2) {
1382                 OS_DELAY(10);
1383                 reg_pmu2 = OS_REG_READ_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM);
1384             }
1385             OS_REG_RMW_FIELD(ah, reg_PMU1, AR_PHY_PMU1_PWD, 0x1);
1386             reg_pmu1 = OS_REG_READ_FIELD(ah, reg_PMU1, AR_PHY_PMU1_PWD);
1387             while (!reg_pmu1) {
1388                 OS_DELAY(10);
1389                 reg_pmu1 = OS_REG_READ_FIELD(ah, reg_PMU1, AR_PHY_PMU1_PWD);
1390             }
1391             OS_REG_RMW_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM, 0x1);
1392             reg_pmu2 = OS_REG_READ_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM);
1393             while (!reg_pmu2) {
1394                 OS_DELAY(10);
1395                 reg_pmu2 = OS_REG_READ_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM);
1396             }
1397         } else if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
1398             OS_REG_RMW_FIELD(ah, reg_PMU1, AR_PHY_PMU1_PWD, 0x1);
1399         } else {
1400             OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK,
1401                 (OS_REG_READ(ah, AR_RTC_SLEEP_CLK) |
1402                 AR_RTC_FORCE_SWREG_PRD | AR_RTC_PCIE_RST_PWDN_EN));
1403         }
1404     }
1405
1406     return 0;  
1407 }
1408
1409 HAL_BOOL ar9300_drive_strength_apply(struct ath_hal *ah)
1410 {
1411     struct ath_hal_9300 *ahp = AH9300(ah);
1412     int drive_strength;
1413     unsigned long reg;
1414
1415     drive_strength = ar9300_eeprom_get(ahp, EEP_DRIVE_STRENGTH);
1416     if (drive_strength) {
1417         reg = OS_REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
1418         reg &= ~0x00ffffc0;
1419         reg |= 0x5 << 21;
1420         reg |= 0x5 << 18;
1421         reg |= 0x5 << 15;
1422         reg |= 0x5 << 12;
1423         reg |= 0x5 << 9;
1424         reg |= 0x5 << 6;
1425         OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
1426
1427         reg = OS_REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
1428         reg &= ~0xffffffe0;
1429         reg |= 0x5 << 29;
1430         reg |= 0x5 << 26;
1431         reg |= 0x5 << 23;
1432         reg |= 0x5 << 20;
1433         reg |= 0x5 << 17;
1434         reg |= 0x5 << 14;
1435         reg |= 0x5 << 11;
1436         reg |= 0x5 << 8;
1437         reg |= 0x5 << 5;
1438         OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
1439
1440         reg = OS_REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
1441         reg &= ~0xff800000;
1442         reg |= 0x5 << 29;
1443         reg |= 0x5 << 26;
1444         reg |= 0x5 << 23;
1445         OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
1446     }
1447     return 0;
1448 }
1449
1450 int32_t ar9300_xpa_bias_level_get(struct ath_hal *ah, HAL_BOOL is_2ghz)
1451 {
1452     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1453     if (is_2ghz) {
1454         return eep->modal_header_2g.xpa_bias_lvl;
1455     } else {
1456         return eep->modal_header_5g.xpa_bias_lvl;
1457     }
1458 }
1459
1460 HAL_BOOL ar9300_xpa_bias_level_apply(struct ath_hal *ah, HAL_BOOL is_2ghz)
1461 {
1462     /*
1463      * In ar9330 emu, we can't access radio registers, 
1464      * merlin is used for radio part.
1465      */
1466     int bias;
1467     bias = ar9300_xpa_bias_level_get(ah, is_2ghz);
1468
1469     if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_WASP(ah)) {
1470         OS_REG_RMW_FIELD(ah,
1471             AR_HORNET_CH0_TOP2, AR_HORNET_CH0_TOP2_XPABIASLVL, bias);
1472     } else if (AR_SREV_SCORPION(ah)) {
1473         OS_REG_RMW_FIELD(ah,
1474             AR_SCORPION_CH0_TOP, AR_SCORPION_CH0_TOP_XPABIASLVL, bias);
1475     } else if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
1476         OS_REG_RMW_FIELD(ah,
1477             AR_PHY_65NM_CH0_TOP_JUPITER, AR_PHY_65NM_CH0_TOP_XPABIASLVL, bias);
1478     } else {
1479         OS_REG_RMW_FIELD(ah,
1480             AR_PHY_65NM_CH0_TOP, AR_PHY_65NM_CH0_TOP_XPABIASLVL, bias);
1481         OS_REG_RMW_FIELD(ah,
1482             AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_XPABIASLVL_MSB,
1483             bias >> 2);
1484         OS_REG_RMW_FIELD(ah,
1485             AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_XPASHORT2GND, 1);
1486     }
1487     return 0;
1488 }
1489
1490 u_int32_t ar9300_ant_ctrl_common_get(struct ath_hal *ah, HAL_BOOL is_2ghz)
1491 {
1492     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1493     if (is_2ghz) {
1494         return eep->modal_header_2g.ant_ctrl_common;
1495     } else {
1496         return eep->modal_header_5g.ant_ctrl_common;
1497     }
1498 }
1499 static u_int16_t 
1500 ar9300_switch_com_spdt_get(struct ath_hal *ah, HAL_BOOL is_2ghz)
1501 {
1502     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1503     if (is_2ghz) {
1504         return eep->modal_header_2g.switchcomspdt;
1505     } else {
1506         return eep->modal_header_5g.switchcomspdt;
1507     }
1508 }
1509 u_int32_t ar9300_ant_ctrl_common2_get(struct ath_hal *ah, HAL_BOOL is_2ghz)
1510 {
1511     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1512     if (is_2ghz) {
1513         return eep->modal_header_2g.ant_ctrl_common2;
1514     } else {
1515         return eep->modal_header_5g.ant_ctrl_common2;
1516     }
1517 }
1518
1519 u_int16_t ar9300_ant_ctrl_chain_get(struct ath_hal *ah, int chain,
1520     HAL_BOOL is_2ghz)
1521 {
1522     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1523     if (chain >= 0 && chain < OSPREY_MAX_CHAINS) {
1524         if (is_2ghz) {
1525             return eep->modal_header_2g.ant_ctrl_chain[chain];
1526         } else {
1527             return eep->modal_header_5g.ant_ctrl_chain[chain];
1528         }
1529     }
1530     return 0;
1531 }
1532
1533 HAL_BOOL ar9300_ant_ctrl_apply(struct ath_hal *ah, HAL_BOOL is_2ghz)
1534 {
1535     u_int32_t value;
1536     struct ath_hal_9300 *ahp = AH9300(ah);
1537     u_int32_t regval;
1538     struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
1539 #if ATH_ANT_DIV_COMB
1540     HAL_CAPABILITIES *pcap = &ahpriv->ah_caps;
1541 #endif  /* ATH_ANT_DIV_COMB */
1542     u_int32_t xlan_gpio_cfg;
1543     u_int8_t  i;
1544
1545     if (AR_SREV_POSEIDON(ah)) {
1546         xlan_gpio_cfg = ah->ah_config.ath_hal_ext_lna_ctl_gpio;
1547         if (xlan_gpio_cfg) {
1548             for (i = 0; i < 32; i++) {
1549                 if (xlan_gpio_cfg & (1 << i)) {
1550                     ath_hal_gpioCfgOutput(ah, i, 
1551                         HAL_GPIO_OUTPUT_MUX_PCIE_ATTENTION_LED);
1552                 }
1553             }
1554         }    
1555     }
1556 #define AR_SWITCH_TABLE_COM_ALL (0xffff)
1557 #define AR_SWITCH_TABLE_COM_ALL_S (0)
1558 #define AR_SWITCH_TABLE_COM_JUPITER_ALL (0xffffff)
1559 #define AR_SWITCH_TABLE_COM_JUPITER_ALL_S (0)
1560 #define AR_SWITCH_TABLE_COM_SCORPION_ALL (0xffffff)
1561 #define AR_SWITCH_TABLE_COM_SCORPION_ALL_S (0)
1562 #define AR_SWITCH_TABLE_COM_SPDT (0x00f00000)
1563     value = ar9300_ant_ctrl_common_get(ah, is_2ghz);
1564     if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
1565         if (AR_SREV_JUPITER_10(ah)) {
1566             /* Force SPDT setting for Jupiter 1.0 chips. */
1567             value &= ~AR_SWITCH_TABLE_COM_SPDT;
1568             value |= 0x00100000;
1569         }
1570         OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 
1571             AR_SWITCH_TABLE_COM_JUPITER_ALL, value);
1572     }
1573     else if (AR_SREV_SCORPION(ah)) {
1574         OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 
1575             AR_SWITCH_TABLE_COM_SCORPION_ALL, value);
1576     }
1577     else {
1578         OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 
1579             AR_SWITCH_TABLE_COM_ALL, value);
1580     }
1581 /*
1582 *   Jupiter2.0 defines new switch table for BT/WLAN, 
1583 *       here's new field name in WB222.ref for both 2G and 5G.
1584 *   Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
1585 *   15:12       R/W     SWITCH_TABLE_COM_SPDT_WLAN_RX   SWITCH_TABLE_COM_SPDT_WLAN_RX 
1586 *   11:8        R/W     SWITCH_TABLE_COM_SPDT_WLAN_TX   SWITCH_TABLE_COM_SPDT_WLAN_TX
1587 *   7:4 R/W     SWITCH_TABLE_COM_SPDT_WLAN_IDLE SWITCH_TABLE_COM_SPDT_WLAN_IDLE 
1588 */
1589 #define AR_SWITCH_TABLE_COM_SPDT_ALL (0x0000fff0)
1590 #define AR_SWITCH_TABLE_COM_SPDT_ALL_S (4)
1591     if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) {
1592         value = ar9300_switch_com_spdt_get(ah, is_2ghz);
1593         OS_REG_RMW_FIELD(ah, AR_GLB_CONTROL, 
1594             AR_SWITCH_TABLE_COM_SPDT_ALL, value);
1595
1596         OS_REG_SET_BIT(ah, AR_GLB_CONTROL,
1597             AR_BTCOEX_CTRL_SPDT_ENABLE);
1598         //OS_REG_SET_BIT(ah, AR_GLB_CONTROL,
1599         //    AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
1600     }
1601
1602 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
1603 #define AR_SWITCH_TABLE_COM2_ALL_S (0)
1604     value = ar9300_ant_ctrl_common2_get(ah, is_2ghz);
1605 #if ATH_ANT_DIV_COMB
1606     if ( AR_SREV_POSEIDON(ah) && (ahp->ah_lna_div_use_bt_ant_enable == TRUE) ) {
1607         value &= ~AR_SWITCH_TABLE_COM2_ALL;
1608         value |= ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable;
1609     }
1610 #endif  /* ATH_ANT_DIV_COMB */
1611     OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
1612
1613 #define AR_SWITCH_TABLE_ALL (0xfff)
1614 #define AR_SWITCH_TABLE_ALL_S (0)
1615     value = ar9300_ant_ctrl_chain_get(ah, 0, is_2ghz);
1616     OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
1617
1618     if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah) && !AR_SREV_APHRODITE(ah)) {
1619         value = ar9300_ant_ctrl_chain_get(ah, 1, is_2ghz);
1620         OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value);
1621
1622         if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
1623             value = ar9300_ant_ctrl_chain_get(ah, 2, is_2ghz);
1624             OS_REG_RMW_FIELD(ah,
1625                 AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value);
1626         }
1627     }
1628     if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
1629         value = ar9300_eeprom_get(ahp, EEP_ANTDIV_control);
1630         /* main_lnaconf, alt_lnaconf, main_tb, alt_tb */
1631         regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
1632         regval &= (~ANT_DIV_CONTROL_ALL); /* clear bit 25~30 */     
1633         regval |= (value & 0x3f) << ANT_DIV_CONTROL_ALL_S; 
1634         /* enable_lnadiv */
1635         regval &= (~MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__MASK);
1636         regval |= ((value >> 6) & 0x1) << 
1637                   MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__SHIFT; 
1638 #if ATH_ANT_DIV_COMB
1639         if ( AR_SREV_POSEIDON(ah) && (ahp->ah_lna_div_use_bt_ant_enable == TRUE) ) {
1640             regval |= ANT_DIV_ENABLE;
1641         }
1642 #endif  /* ATH_ANT_DIV_COMB */
1643         OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
1644         
1645         /* enable fast_div */
1646         regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
1647         regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK);
1648         regval |= ((value >> 7) & 0x1) << 
1649                   BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__SHIFT;
1650 #if ATH_ANT_DIV_COMB
1651         if ( AR_SREV_POSEIDON(ah) && (ahp->ah_lna_div_use_bt_ant_enable == TRUE) ) {
1652             regval |= FAST_DIV_ENABLE;
1653         }
1654 #endif  /* ATH_ANT_DIV_COMB */
1655         OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);        
1656     }
1657
1658 #if ATH_ANT_DIV_COMB    
1659     if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON_11_OR_LATER(ah)) {
1660         if (pcap->halAntDivCombSupport) {
1661             /* If support DivComb, set MAIN to LNA1, ALT to LNA2 at beginning */
1662             regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
1663             /* clear bit 25~30 main_lnaconf, alt_lnaconf, main_tb, alt_tb */
1664             regval &= (~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK | 
1665                          MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK | 
1666                          MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK | 
1667                          MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK)); 
1668             regval |= (HAL_ANT_DIV_COMB_LNA1 << 
1669                        MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT); 
1670             regval |= (HAL_ANT_DIV_COMB_LNA2 << 
1671                        MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT); 
1672             OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
1673         }
1674
1675     }
1676 #endif /* ATH_ANT_DIV_COMB */
1677     if (AR_SREV_POSEIDON(ah) && ( ahp->ah_diversity_control == HAL_ANT_FIXED_A 
1678              || ahp->ah_diversity_control == HAL_ANT_FIXED_B))
1679     {
1680         u_int32_t reg_val = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
1681         reg_val &=  ~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK | 
1682                     MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK |
1683                     MULTICHAIN_GAIN_CTRL__ANT_FAST_DIV_BIAS__MASK |
1684                         MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK |
1685                         MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK );
1686
1687         switch (ahp->ah_diversity_control) {
1688         case HAL_ANT_FIXED_A:
1689             /* Enable first antenna only */
1690             reg_val |= (HAL_ANT_DIV_COMB_LNA1 << 
1691                        MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT); 
1692             reg_val |= (HAL_ANT_DIV_COMB_LNA2 << 
1693                        MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT); 
1694             /* main/alt gain table and Fast Div Bias all set to 0 */
1695             OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, reg_val);
1696             regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
1697             regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK);
1698             OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);        
1699             break;
1700         case HAL_ANT_FIXED_B:
1701             /* Enable second antenna only, after checking capability */
1702             reg_val |= (HAL_ANT_DIV_COMB_LNA2 << 
1703                        MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT); 
1704             reg_val |= (HAL_ANT_DIV_COMB_LNA1 << 
1705                        MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT); 
1706             /* main/alt gain table and Fast Div all set to 0 */
1707             OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, reg_val);
1708             regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
1709             regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK);
1710             OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);        
1711             /* For WB225, need to swith ANT2 from BT to Wifi
1712              * This will not affect HB125 LNA diversity feature.
1713              */
1714             OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, 
1715                 ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable);
1716             break;
1717         default:
1718             break;
1719         }
1720     }    
1721     return 0;
1722 }
1723
1724 static u_int16_t
1725 ar9300_attenuation_chain_get(struct ath_hal *ah, int chain, u_int16_t channel)
1726 {
1727     int32_t f[3], t[3];
1728     u_int16_t value;
1729     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1730     if (chain >= 0 && chain < OSPREY_MAX_CHAINS) {
1731         if (channel < 4000) {
1732             return eep->modal_header_2g.xatten1_db[chain];
1733         } else {
1734             if (eep->base_ext2.xatten1_db_low[chain] != 0) {        
1735                 t[0] = eep->base_ext2.xatten1_db_low[chain];
1736                 f[0] = 5180;
1737                 t[1] = eep->modal_header_5g.xatten1_db[chain];
1738                 f[1] = 5500;
1739                 t[2] = eep->base_ext2.xatten1_db_high[chain];
1740                 f[2] = 5785;
1741                 value = interpolate(channel, f, t, 3);
1742                 return value;
1743             } else {
1744                 return eep->modal_header_5g.xatten1_db[chain];
1745             }
1746         }
1747     }
1748     return 0;
1749 }
1750
1751 static u_int16_t
1752 ar9300_attenuation_margin_chain_get(struct ath_hal *ah, int chain,
1753     u_int16_t channel)
1754 {
1755     int32_t f[3], t[3];
1756     u_int16_t value;
1757     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1758     if (chain >= 0 && chain < OSPREY_MAX_CHAINS) {
1759         if (channel < 4000) {
1760             return eep->modal_header_2g.xatten1_margin[chain];
1761         } else {
1762             if (eep->base_ext2.xatten1_margin_low[chain] != 0) {    
1763                 t[0] = eep->base_ext2.xatten1_margin_low[chain];
1764                 f[0] = 5180;
1765                 t[1] = eep->modal_header_5g.xatten1_margin[chain];
1766                 f[1] = 5500;
1767                 t[2] = eep->base_ext2.xatten1_margin_high[chain];
1768                 f[2] = 5785;
1769                 value = interpolate(channel, f, t, 3);
1770                 return value;
1771             } else {
1772                 return eep->modal_header_5g.xatten1_margin[chain];
1773             }
1774         }
1775     }
1776     return 0;
1777 }
1778
1779 HAL_BOOL ar9300_attenuation_apply(struct ath_hal *ah, u_int16_t channel)
1780 {
1781     u_int32_t value;
1782 //    struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
1783
1784     /* Test value. if 0 then attenuation is unused. Don't load anything. */
1785     value = ar9300_attenuation_chain_get(ah, 0, channel);
1786     OS_REG_RMW_FIELD(ah,
1787         AR_PHY_EXT_ATTEN_CTL_0, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
1788     value = ar9300_attenuation_margin_chain_get(ah, 0, channel);
1789     if (ar9300_rx_gain_index_get(ah) == 0
1790         && ah->ah_config.ath_hal_ext_atten_margin_cfg)
1791     {
1792         value = 5;
1793     }
1794     OS_REG_RMW_FIELD(ah,
1795         AR_PHY_EXT_ATTEN_CTL_0, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value);
1796
1797     if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) {
1798         value = ar9300_attenuation_chain_get(ah, 1, channel);
1799         OS_REG_RMW_FIELD(ah,
1800             AR_PHY_EXT_ATTEN_CTL_1, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
1801         value = ar9300_attenuation_margin_chain_get(ah, 1, channel);
1802         OS_REG_RMW_FIELD(ah,
1803             AR_PHY_EXT_ATTEN_CTL_1, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
1804             value);
1805         if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
1806             value = ar9300_attenuation_chain_get(ah, 2, channel);
1807             OS_REG_RMW_FIELD(ah,
1808                 AR_PHY_EXT_ATTEN_CTL_2, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
1809             value = ar9300_attenuation_margin_chain_get(ah, 2, channel);
1810             OS_REG_RMW_FIELD(ah,
1811                 AR_PHY_EXT_ATTEN_CTL_2, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
1812                 value);
1813         }
1814     }
1815     return 0;
1816 }
1817
1818 static u_int16_t ar9300_quick_drop_get(struct ath_hal *ah, 
1819                                                                 int chain, u_int16_t channel)
1820 {
1821     int32_t f[3], t[3];
1822     u_int16_t value;
1823     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1824
1825     if (channel < 4000) {
1826         return eep->modal_header_2g.quick_drop;
1827     } else {
1828         t[0] = eep->base_ext1.quick_drop_low;
1829         f[0] = 5180;
1830         t[1] = eep->modal_header_5g.quick_drop;
1831         f[1] = 5500;
1832         t[2] = eep->base_ext1.quick_drop_high;
1833         f[2] = 5785;
1834         value = interpolate(channel, f, t, 3);
1835         return value;
1836     }
1837 }
1838
1839
1840 static HAL_BOOL ar9300_quick_drop_apply(struct ath_hal *ah, u_int16_t channel)
1841 {
1842     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1843     u_int32_t value;
1844     //
1845     // Test value. if 0 then quickDrop is unused. Don't load anything.
1846     //
1847     if (eep->base_eep_header.misc_configuration & 0x10)
1848         {
1849         if (AR_SREV_OSPREY(ah) || AR_SREV_AR9580(ah) || AR_SREV_WASP(ah)) 
1850         {
1851             value = ar9300_quick_drop_get(ah, 0, channel);
1852             OS_REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, value);
1853         }
1854     }
1855     return 0;
1856 }
1857
1858 static u_int16_t ar9300_tx_end_to_xpa_off_get(struct ath_hal *ah, u_int16_t channel)
1859 {
1860     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1861
1862     if (channel < 4000) {
1863         return eep->modal_header_2g.tx_end_to_xpa_off;
1864     } else {
1865         return eep->modal_header_5g.tx_end_to_xpa_off;
1866     }
1867 }
1868
1869 static HAL_BOOL ar9300_tx_end_to_xpab_off_apply(struct ath_hal *ah, u_int16_t channel)
1870 {
1871     u_int32_t value;
1872
1873     value = ar9300_tx_end_to_xpa_off_get(ah, channel);
1874     /* Apply to both xpaa and xpab */
1875     if (AR_SREV_OSPREY(ah) || AR_SREV_AR9580(ah) || AR_SREV_WASP(ah)) 
1876     {
1877         OS_REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, 
1878             AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
1879         OS_REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, 
1880             AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
1881     }
1882     return 0;
1883 }
1884
1885 static int
1886 ar9300_eeprom_cal_pier_get(struct ath_hal *ah, int mode, int ipier, int ichain, 
1887     int *pfrequency, int *pcorrection, int *ptemperature, int *pvoltage)
1888 {
1889     u_int8_t *p_cal_pier;
1890     OSP_CAL_DATA_PER_FREQ_OP_LOOP *p_cal_pier_struct;
1891     int is_2ghz;
1892     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1893
1894     if (ichain >= OSPREY_MAX_CHAINS) {
1895         HALDEBUG(ah, HAL_DEBUG_EEPROM,
1896             "%s: Invalid chain index, must be less than %d\n",
1897             __func__, OSPREY_MAX_CHAINS);
1898         return -1;
1899     }
1900
1901     if (mode) {/* 5GHz */
1902         if (ipier >= OSPREY_NUM_5G_CAL_PIERS){
1903             HALDEBUG(ah, HAL_DEBUG_EEPROM,
1904                 "%s: Invalid 5GHz cal pier index, must be less than %d\n",
1905                 __func__, OSPREY_NUM_5G_CAL_PIERS);
1906             return -1;
1907         }
1908         p_cal_pier = &(eep->cal_freq_pier_5g[ipier]);
1909         p_cal_pier_struct = &(eep->cal_pier_data_5g[ichain][ipier]);
1910         is_2ghz = 0;
1911     } else {
1912         if (ipier >= OSPREY_NUM_2G_CAL_PIERS){
1913             HALDEBUG(ah, HAL_DEBUG_EEPROM,
1914                 "%s: Invalid 2GHz cal pier index, must be less than %d\n",
1915                 __func__, OSPREY_NUM_2G_CAL_PIERS);
1916             return -1;
1917         }
1918
1919         p_cal_pier = &(eep->cal_freq_pier_2g[ipier]);
1920         p_cal_pier_struct = &(eep->cal_pier_data_2g[ichain][ipier]);
1921         is_2ghz = 1;
1922     }
1923     *pfrequency = FBIN2FREQ(*p_cal_pier, is_2ghz);
1924     *pcorrection = p_cal_pier_struct->ref_power;
1925     *ptemperature = p_cal_pier_struct->temp_meas;
1926     *pvoltage = p_cal_pier_struct->volt_meas;
1927     return 0;
1928 }
1929
1930 /*
1931  * Apply the recorded correction values.
1932  */
1933 static int
1934 ar9300_calibration_apply(struct ath_hal *ah, int frequency)
1935 {
1936     struct ath_hal_9300 *ahp = AH9300(ah);
1937
1938     int ichain, ipier, npier;
1939     int mode;
1940     int fdiff;
1941     int pfrequency, pcorrection, ptemperature, pvoltage; 
1942     int bf, factor, plus;
1943
1944     int lfrequency[AR9300_MAX_CHAINS];
1945     int hfrequency[AR9300_MAX_CHAINS];
1946
1947     int lcorrection[AR9300_MAX_CHAINS];
1948     int hcorrection[AR9300_MAX_CHAINS];
1949     int correction[AR9300_MAX_CHAINS];
1950
1951     int ltemperature[AR9300_MAX_CHAINS];
1952     int htemperature[AR9300_MAX_CHAINS];
1953     int temperature[AR9300_MAX_CHAINS];
1954
1955     int lvoltage[AR9300_MAX_CHAINS];
1956     int hvoltage[AR9300_MAX_CHAINS];
1957     int voltage[AR9300_MAX_CHAINS];
1958
1959     mode = (frequency >= 4000);
1960     npier = (mode) ?  OSPREY_NUM_5G_CAL_PIERS : OSPREY_NUM_2G_CAL_PIERS;
1961
1962     for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1963         lfrequency[ichain] = 0;
1964         hfrequency[ichain] = 100000;
1965     }
1966     /*
1967      * identify best lower and higher frequency calibration measurement
1968      */
1969     for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1970         for (ipier = 0; ipier < npier; ipier++) {
1971             if (ar9300_eeprom_cal_pier_get(
1972                     ah, mode, ipier, ichain,
1973                     &pfrequency, &pcorrection, &ptemperature, &pvoltage) == 0)
1974             {
1975                 fdiff = frequency - pfrequency;
1976                 /*
1977                  * this measurement is higher than our desired frequency
1978                  */
1979                 if (fdiff <= 0) {
1980                     if (hfrequency[ichain] <= 0 ||
1981                         hfrequency[ichain] >= 100000 ||
1982                         fdiff > (frequency - hfrequency[ichain]))
1983                     {
1984                         /*
1985                          * new best higher frequency measurement
1986                          */
1987                         hfrequency[ichain] = pfrequency;
1988                         hcorrection[ichain] = pcorrection;
1989                         htemperature[ichain] = ptemperature;
1990                         hvoltage[ichain] = pvoltage;
1991                     }
1992                 }
1993                 if (fdiff >= 0) {
1994                     if (lfrequency[ichain] <= 0 ||
1995                         fdiff < (frequency - lfrequency[ichain]))
1996                     {
1997                         /*
1998                          * new best lower frequency measurement
1999                          */
2000                         lfrequency[ichain] = pfrequency;
2001                         lcorrection[ichain] = pcorrection;
2002                         ltemperature[ichain] = ptemperature;
2003                         lvoltage[ichain] = pvoltage;
2004                     }
2005                 }
2006             }
2007         }
2008     }
2009     /* interpolate */
2010     for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
2011         HALDEBUG(ah, HAL_DEBUG_EEPROM,
2012             "%s: ch=%d f=%d low=%d %d h=%d %d\n",
2013             __func__, ichain, frequency,
2014             lfrequency[ichain], lcorrection[ichain],
2015             hfrequency[ichain], hcorrection[ichain]);
2016         /*
2017          * they're the same, so just pick one
2018          */ 
2019         if (hfrequency[ichain] == lfrequency[ichain]) {
2020             correction[ichain] = lcorrection[ichain];
2021             voltage[ichain] = lvoltage[ichain];
2022             temperature[ichain] = ltemperature[ichain];
2023         } else if (frequency - lfrequency[ichain] < 1000) {
2024             /* the low frequency is good */
2025             if (hfrequency[ichain] - frequency < 1000) {
2026                 /*
2027                  * The high frequency is good too -
2028                  * interpolate with round off.
2029                  */
2030                 int mult, div, diff;
2031                 mult = frequency - lfrequency[ichain];
2032                 div = hfrequency[ichain] - lfrequency[ichain];
2033
2034                 diff = hcorrection[ichain] - lcorrection[ichain];
2035                 bf = 2 * diff * mult / div;
2036                 plus = (bf % 2);
2037                 factor = bf / 2;
2038                 correction[ichain] = lcorrection[ichain] + factor + plus;
2039
2040                 diff = htemperature[ichain] - ltemperature[ichain];
2041                 bf = 2 * diff * mult / div;
2042                 plus = (bf % 2);
2043                 factor = bf / 2;
2044                 temperature[ichain] = ltemperature[ichain] + factor + plus;
2045
2046                 diff = hvoltage[ichain] - lvoltage[ichain];
2047                 bf = 2 * diff * mult / div;
2048                 plus = (bf % 2);
2049                 factor = bf / 2;
2050                 voltage[ichain] = lvoltage[ichain] + factor + plus;
2051             } else {
2052                 /* only low is good, use it */
2053                 correction[ichain] = lcorrection[ichain];
2054                 temperature[ichain] = ltemperature[ichain];
2055                 voltage[ichain] = lvoltage[ichain];
2056             }
2057         } else if (hfrequency[ichain] - frequency < 1000) {
2058             /* only high is good, use it */
2059             correction[ichain] = hcorrection[ichain];
2060             temperature[ichain] = htemperature[ichain];
2061             voltage[ichain] = hvoltage[ichain];
2062         } else {
2063             /* nothing is good, presume 0???? */
2064             correction[ichain] = 0;
2065             temperature[ichain] = 0;
2066             voltage[ichain] = 0;
2067         }
2068     }
2069
2070     /* GreenTx isn't currently supported */
2071     /* GreenTx */
2072     if (ah->ah_config.ath_hal_sta_update_tx_pwr_enable) {
2073         if (AR_SREV_POSEIDON(ah)) {
2074             /* Get calibrated OLPC gain delta value for GreenTx */
2075             ahp->ah_db2[POSEIDON_STORED_REG_G2_OLPC_OFFSET] = 
2076                 (u_int32_t) correction[0];
2077         }
2078     }
2079
2080     ar9300_power_control_override(
2081         ah, frequency, correction, voltage, temperature);
2082     HALDEBUG(ah, HAL_DEBUG_EEPROM,
2083         "%s: for frequency=%d, calibration correction = %d %d %d\n",
2084          __func__, frequency, correction[0], correction[1], correction[2]);
2085
2086     return 0;
2087 }
2088
2089 int
2090 ar9300_power_control_override(struct ath_hal *ah, int frequency,
2091     int *correction, int *voltage, int *temperature)
2092 {
2093     int temp_slope = 0;
2094     int temp_slope_1 = 0;
2095     int temp_slope_2 = 0;
2096     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
2097     int32_t f[8], t[8],t1[3], t2[3];
2098         int i;
2099
2100     OS_REG_RMW(ah, AR_PHY_TPC_11_B0,
2101         (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
2102         AR_PHY_TPC_OLPC_GAIN_DELTA);
2103     if (!AR_SREV_POSEIDON(ah)) {
2104         OS_REG_RMW(ah, AR_PHY_TPC_11_B1,
2105             (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
2106             AR_PHY_TPC_OLPC_GAIN_DELTA);
2107         if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
2108             OS_REG_RMW(ah, AR_PHY_TPC_11_B2, 
2109                 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
2110                 AR_PHY_TPC_OLPC_GAIN_DELTA);
2111         }
2112     }
2113     /*
2114      * enable open loop power control on chip
2115      */
2116     OS_REG_RMW(ah, AR_PHY_TPC_6_B0,
2117         (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), AR_PHY_TPC_6_ERROR_EST_MODE);
2118     if (!AR_SREV_POSEIDON(ah)) {
2119         OS_REG_RMW(ah, AR_PHY_TPC_6_B1, 
2120             (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), AR_PHY_TPC_6_ERROR_EST_MODE);
2121         if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
2122             OS_REG_RMW(ah, AR_PHY_TPC_6_B2, 
2123                 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
2124                 AR_PHY_TPC_6_ERROR_EST_MODE);
2125         }
2126     }
2127
2128     /*
2129      * Enable temperature compensation
2130      * Need to use register names
2131      */
2132     if (frequency < 4000) {
2133         temp_slope = eep->modal_header_2g.temp_slope;
2134     } else {
2135                 if ((eep->base_eep_header.misc_configuration & 0x20) != 0)
2136                 {
2137                                 for(i=0;i<8;i++)
2138                                 {
2139                                         t[i]=eep->base_ext1.tempslopextension[i];
2140                                         f[i]=FBIN2FREQ(eep->cal_freq_pier_5g[i], 0);
2141                                 }
2142                                 temp_slope=interpolate(frequency,f,t,8);
2143                 }
2144                 else
2145                 {
2146         if(!AR_SREV_SCORPION(ah)) {
2147           if (eep->base_ext2.temp_slope_low != 0) {
2148              t[0] = eep->base_ext2.temp_slope_low;
2149              f[0] = 5180;
2150              t[1] = eep->modal_header_5g.temp_slope;
2151              f[1] = 5500;
2152              t[2] = eep->base_ext2.temp_slope_high;
2153              f[2] = 5785;
2154              temp_slope = interpolate(frequency, f, t, 3);
2155            } else {
2156              temp_slope = eep->modal_header_5g.temp_slope;
2157            }
2158          } else {
2159             /*
2160              * Scorpion has individual chain tempslope values
2161              */
2162              t[0] = eep->base_ext1.tempslopextension[2];
2163              t1[0]= eep->base_ext1.tempslopextension[3];
2164              t2[0]= eep->base_ext1.tempslopextension[4];
2165              f[0] = 5180;
2166              t[1] = eep->modal_header_5g.temp_slope;
2167              t1[1]= eep->base_ext1.tempslopextension[0];
2168              t2[1]= eep->base_ext1.tempslopextension[1];
2169              f[1] = 5500;
2170              t[2] = eep->base_ext1.tempslopextension[5];
2171              t1[2]= eep->base_ext1.tempslopextension[6];
2172              t2[2]= eep->base_ext1.tempslopextension[7];
2173              f[2] = 5785;
2174              temp_slope = interpolate(frequency, f, t, 3);
2175              temp_slope_1=interpolate(frequency, f, t1,3);
2176              temp_slope_2=interpolate(frequency, f, t2,3);
2177        } 
2178          }
2179   }
2180
2181     if (!AR_SREV_SCORPION(ah)) {
2182         OS_REG_RMW_FIELD(ah,
2183             AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, temp_slope);
2184     } else {
2185         /*Scorpion has tempSlope register for each chain*/
2186         /*Check whether temp_compensation feature is enabled or not*/
2187         if (eep->base_eep_header.feature_enable & 0x1){
2188             if(frequency < 4000) {
2189                     OS_REG_RMW_FIELD(ah,
2190                                     AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, 
2191                                     eep->base_ext2.temp_slope_low);
2192                     OS_REG_RMW_FIELD(ah,
2193                                     AR_SCORPION_PHY_TPC_19_B1, AR_PHY_TPC_19_ALPHA_THERM, 
2194                                     temp_slope);
2195                     OS_REG_RMW_FIELD(ah,
2196                                     AR_SCORPION_PHY_TPC_19_B2, AR_PHY_TPC_19_ALPHA_THERM, 
2197                                     eep->base_ext2.temp_slope_high);
2198             } else {
2199                     OS_REG_RMW_FIELD(ah,
2200                                     AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, 
2201                                     temp_slope);
2202                     OS_REG_RMW_FIELD(ah,
2203                                     AR_SCORPION_PHY_TPC_19_B1, AR_PHY_TPC_19_ALPHA_THERM, 
2204                                     temp_slope_1);
2205                     OS_REG_RMW_FIELD(ah,
2206                                     AR_SCORPION_PHY_TPC_19_B2, AR_PHY_TPC_19_ALPHA_THERM, 
2207                                     temp_slope_2);
2208             }
2209         }else {
2210                 /* If temp compensation is not enabled, set all registers to 0*/
2211             OS_REG_RMW_FIELD(ah,
2212                 AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, 0);
2213             OS_REG_RMW_FIELD(ah,
2214                 AR_SCORPION_PHY_TPC_19_B1, AR_PHY_TPC_19_ALPHA_THERM, 0);
2215             OS_REG_RMW_FIELD(ah,
2216                 AR_SCORPION_PHY_TPC_19_B2, AR_PHY_TPC_19_ALPHA_THERM, 0);
2217         }
2218     }
2219     OS_REG_RMW_FIELD(ah,
2220         AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE, temperature[0]);
2221
2222     return 0;
2223 }
2224
2225 /**************************************************************
2226  * ar9300_eep_def_get_max_edge_power
2227  *
2228  * Find the maximum conformance test limit for the given channel and CTL info
2229  */
2230 static inline u_int16_t
2231 ar9300_eep_def_get_max_edge_power(ar9300_eeprom_t *p_eep_data, u_int16_t freq,
2232     int idx, HAL_BOOL is_2ghz)
2233 {
2234     u_int16_t twice_max_edge_power = AR9300_MAX_RATE_POWER;
2235     u_int8_t *ctl_freqbin = is_2ghz ?
2236         &p_eep_data->ctl_freqbin_2G[idx][0] :
2237         &p_eep_data->ctl_freqbin_5G[idx][0];
2238     u_int16_t num_edges = is_2ghz ?
2239         OSPREY_NUM_BAND_EDGES_2G : OSPREY_NUM_BAND_EDGES_5G;
2240     int i;
2241
2242     /* Get the edge power */
2243     for (i = 0; (i < num_edges) && (ctl_freqbin[i] != AR9300_BCHAN_UNUSED); i++)
2244     {
2245         /*
2246          * If there's an exact channel match or an inband flag set
2247          * on the lower channel use the given rd_edge_power
2248          */
2249         if (freq == fbin2freq(ctl_freqbin[i], is_2ghz)) {
2250             if (is_2ghz) {
2251                 twice_max_edge_power =
2252                     p_eep_data->ctl_power_data_2g[idx].ctl_edges[i].t_power;
2253             } else {       
2254                 twice_max_edge_power =
2255                     p_eep_data->ctl_power_data_5g[idx].ctl_edges[i].t_power;
2256             }
2257             break;
2258         } else if ((i > 0) && (freq < fbin2freq(ctl_freqbin[i], is_2ghz))) {
2259             if (is_2ghz) {
2260                 if (fbin2freq(ctl_freqbin[i - 1], 1) < freq &&
2261                     p_eep_data->ctl_power_data_2g[idx].ctl_edges[i - 1].flag)
2262                 {
2263                     twice_max_edge_power =
2264                         p_eep_data->ctl_power_data_2g[idx].
2265                             ctl_edges[i - 1].t_power;
2266                 }
2267             } else {
2268                 if (fbin2freq(ctl_freqbin[i - 1], 0) < freq &&
2269                     p_eep_data->ctl_power_data_5g[idx].ctl_edges[i - 1].flag)
2270                 {
2271                     twice_max_edge_power =
2272                         p_eep_data->ctl_power_data_5g[idx].
2273                             ctl_edges[i - 1].t_power;
2274                 }
2275             }
2276             /*
2277              * Leave loop - no more affecting edges possible
2278              * in this monotonic increasing list
2279              */
2280             break;
2281         }
2282     }
2283     /*
2284      * EV89475: EEPROM might contain 0 txpower in CTL table for certain
2285      * 2.4GHz channels. We workaround it by overwriting 60 (30 dBm) here.
2286      */
2287     if (is_2ghz && (twice_max_edge_power == 0)) {
2288         twice_max_edge_power = 60;
2289     }
2290
2291     HALASSERT(twice_max_edge_power > 0);
2292     return twice_max_edge_power;
2293 }
2294
2295 HAL_BOOL
2296 ar9300_eeprom_set_power_per_rate_table(
2297     struct ath_hal *ah,
2298     ar9300_eeprom_t *p_eep_data,
2299     const struct ieee80211_channel *chan,
2300     u_int8_t *p_pwr_array,
2301     u_int16_t cfg_ctl,
2302     u_int16_t antenna_reduction,
2303     u_int16_t twice_max_regulatory_power,
2304     u_int16_t power_limit,
2305     u_int8_t chainmask)
2306 {
2307     /* Local defines to distinguish between extension and control CTL's */
2308 #define EXT_ADDITIVE (0x8000)
2309 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
2310 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
2311 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
2312 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
2313 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN  10  /* 10*log10(3)*2 */
2314 #define PWRINCR_3_TO_1_CHAIN      9             /* 10*log(3)*2 */
2315 #define PWRINCR_3_TO_2_CHAIN      3             /* floor(10*log(3/2)*2) */
2316 #define PWRINCR_2_TO_1_CHAIN      6             /* 10*log(2)*2 */
2317
2318     static const u_int16_t tp_scale_reduction_table[5] =
2319         { 0, 3, 6, 9, AR9300_MAX_RATE_POWER };
2320     int i;
2321     int16_t twice_largest_antenna;
2322     u_int16_t twice_antenna_reduction = 2*antenna_reduction ;
2323     int16_t scaled_power = 0, min_ctl_power, max_reg_allowed_power;
2324 #define SUB_NUM_CTL_MODES_AT_5G_40 2    /* excluding HT40, EXT-OFDM */
2325 #define SUB_NUM_CTL_MODES_AT_2G_40 3    /* excluding HT40, EXT-OFDM, EXT-CCK */
2326     u_int16_t ctl_modes_for11a[] =
2327         {CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40};
2328     u_int16_t ctl_modes_for11g[] =
2329         {CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40};
2330     u_int16_t num_ctl_modes, *p_ctl_mode, ctl_mode, freq;
2331     CHAN_CENTERS centers;
2332     int tx_chainmask;
2333     struct ath_hal_9300 *ahp = AH9300(ah);
2334     u_int8_t *ctl_index;
2335     u_int8_t ctl_num;
2336     u_int16_t twice_min_edge_power;
2337     u_int16_t twice_max_edge_power = AR9300_MAX_RATE_POWER;
2338 #ifdef  AH_DEBUG
2339     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
2340 #endif
2341
2342     tx_chainmask = chainmask ? chainmask : ahp->ah_tx_chainmask;
2343
2344     ar9300_get_channel_centers(ah, chan, &centers);
2345
2346     if (IEEE80211_IS_CHAN_2GHZ(chan)) {
2347         ahp->twice_antenna_gain = p_eep_data->modal_header_2g.antenna_gain;
2348     } else {
2349         ahp->twice_antenna_gain = p_eep_data->modal_header_5g.antenna_gain;
2350     }
2351
2352     /* Save max allowed antenna gain to ease future lookups */
2353     ahp->twice_antenna_reduction = twice_antenna_reduction; 
2354
2355     /*  Deduct antenna gain from  EIRP to get the upper limit */
2356     twice_largest_antenna = (int16_t)AH_MIN((twice_antenna_reduction -
2357                                        ahp->twice_antenna_gain), 0);
2358     max_reg_allowed_power = twice_max_regulatory_power + twice_largest_antenna;
2359
2360     /* Use ah_tp_scale - see bug 30070. */
2361     if (AH_PRIVATE(ah)->ah_tpScale != HAL_TP_SCALE_MAX) { 
2362         max_reg_allowed_power -=
2363             (tp_scale_reduction_table[(AH_PRIVATE(ah)->ah_tpScale)] * 2);
2364     }
2365
2366     scaled_power = AH_MIN(power_limit, max_reg_allowed_power);
2367
2368     /*
2369      * Reduce scaled Power by number of chains active to get to
2370      * per chain tx power level
2371      */
2372     /* TODO: better value than these? */
2373     switch (ar9300_get_ntxchains(tx_chainmask)) {
2374     case 1:
2375         ahp->upper_limit[0] = AH_MAX(0, scaled_power);
2376         break;
2377     case 2:
2378         scaled_power -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
2379         ahp->upper_limit[1] = AH_MAX(0, scaled_power);
2380         break;
2381     case 3:
2382         scaled_power -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
2383         ahp->upper_limit[2] = AH_MAX(0, scaled_power);
2384         break;
2385     default:
2386         HALASSERT(0); /* Unsupported number of chains */
2387     }
2388
2389     scaled_power = AH_MAX(0, scaled_power);
2390
2391     /* Get target powers from EEPROM - our baseline for TX Power */
2392     if (IEEE80211_IS_CHAN_2GHZ(chan)) {
2393         /* Setup for CTL modes */
2394         /* CTL_11B, CTL_11G, CTL_2GHT20 */
2395         num_ctl_modes =
2396             ARRAY_LENGTH(ctl_modes_for11g) - SUB_NUM_CTL_MODES_AT_2G_40;
2397         p_ctl_mode = ctl_modes_for11g;
2398
2399         if (IEEE80211_IS_CHAN_HT40(chan)) {
2400             num_ctl_modes = ARRAY_LENGTH(ctl_modes_for11g); /* All 2G CTL's */
2401         }
2402     } else {
2403         /* Setup for CTL modes */
2404         /* CTL_11A, CTL_5GHT20 */
2405         num_ctl_modes =
2406             ARRAY_LENGTH(ctl_modes_for11a) - SUB_NUM_CTL_MODES_AT_5G_40;
2407         p_ctl_mode = ctl_modes_for11a;
2408
2409         if (IEEE80211_IS_CHAN_HT40(chan)) {
2410             num_ctl_modes = ARRAY_LENGTH(ctl_modes_for11a); /* All 5G CTL's */
2411         }
2412     }
2413
2414     /*
2415      * For MIMO, need to apply regulatory caps individually across dynamically
2416      * running modes: CCK, OFDM, HT20, HT40
2417      *
2418      * The outer loop walks through each possible applicable runtime mode.
2419      * The inner loop walks through each ctl_index entry in EEPROM.
2420      * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
2421      *
2422      */
2423     for (ctl_mode = 0; ctl_mode < num_ctl_modes; ctl_mode++) {
2424         HAL_BOOL is_ht40_ctl_mode =
2425             (p_ctl_mode[ctl_mode] == CTL_5GHT40) ||
2426             (p_ctl_mode[ctl_mode] == CTL_2GHT40);
2427         if (is_ht40_ctl_mode) {
2428             freq = centers.synth_center;
2429         } else if (p_ctl_mode[ctl_mode] & EXT_ADDITIVE) {
2430             freq = centers.ext_center;
2431         } else {
2432             freq = centers.ctl_center;
2433         }
2434
2435         HALDEBUG(ah, HAL_DEBUG_POWER_MGMT,
2436             "LOOP-Mode ctl_mode %d < %d, "
2437             "is_ht40_ctl_mode %d, EXT_ADDITIVE %d\n",
2438             ctl_mode, num_ctl_modes, is_ht40_ctl_mode,
2439             (p_ctl_mode[ctl_mode] & EXT_ADDITIVE));
2440         /* walk through each CTL index stored in EEPROM */
2441         if (IEEE80211_IS_CHAN_2GHZ(chan)) {
2442             ctl_index = p_eep_data->ctl_index_2g;
2443             ctl_num = OSPREY_NUM_CTLS_2G;
2444         } else {
2445             ctl_index = p_eep_data->ctl_index_5g;
2446             ctl_num = OSPREY_NUM_CTLS_5G;
2447         }
2448
2449         for (i = 0; (i < ctl_num) && ctl_index[i]; i++) {
2450             HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, 
2451                 "  LOOP-Ctlidx %d: cfg_ctl 0x%2.2x p_ctl_mode 0x%2.2x "
2452                 "ctl_index 0x%2.2x chan %d chanctl 0x%x\n",
2453                 i, cfg_ctl, p_ctl_mode[ctl_mode], ctl_index[i], 
2454                 ichan->channel, ath_hal_getctl(ah, chan));
2455
2456
2457             /* 
2458              * compare test group from regulatory channel list
2459              * with test mode from p_ctl_mode list
2460              */
2461             if ((((cfg_ctl & ~CTL_MODE_M) |
2462                   (p_ctl_mode[ctl_mode] & CTL_MODE_M)) == ctl_index[i]) ||
2463                 (((cfg_ctl & ~CTL_MODE_M) |
2464                   (p_ctl_mode[ctl_mode] & CTL_MODE_M)) ==
2465                  ((ctl_index[i] & CTL_MODE_M) | SD_NO_CTL)))
2466             {
2467                 twice_min_edge_power =
2468                     ar9300_eep_def_get_max_edge_power(
2469                         p_eep_data, freq, i, IEEE80211_IS_CHAN_2GHZ(chan));
2470
2471                 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT,
2472                     "    MATCH-EE_IDX %d: ch %d is2 %d "
2473                     "2xMinEdge %d chainmask %d chains %d\n",
2474                     i, freq, IEEE80211_IS_CHAN_2GHZ(chan),
2475                     twice_min_edge_power, tx_chainmask,
2476                     ar9300_get_ntxchains(tx_chainmask));
2477
2478                 if ((cfg_ctl & ~CTL_MODE_M) == SD_NO_CTL) {
2479                     /*
2480                      * Find the minimum of all CTL edge powers
2481                      * that apply to this channel
2482                      */
2483                     twice_max_edge_power =
2484                         AH_MIN(twice_max_edge_power, twice_min_edge_power);
2485                 } else {
2486                     /* specific */
2487                     twice_max_edge_power = twice_min_edge_power;
2488                     break;
2489                 }
2490             }
2491         }
2492
2493         min_ctl_power = (u_int8_t)AH_MIN(twice_max_edge_power, scaled_power);
2494
2495         HALDEBUG(ah, HAL_DEBUG_POWER_MGMT,
2496             "    SEL-Min ctl_mode %d p_ctl_mode %d "
2497             "2xMaxEdge %d sP %d min_ctl_pwr %d\n",
2498             ctl_mode, p_ctl_mode[ctl_mode],
2499             twice_max_edge_power, scaled_power, min_ctl_power);
2500
2501         /* Apply ctl mode to correct target power set */
2502         switch (p_ctl_mode[ctl_mode]) {
2503         case CTL_11B:
2504             for (i = ALL_TARGET_LEGACY_1L_5L; i <= ALL_TARGET_LEGACY_11S; i++) {
2505                 p_pwr_array[i] =
2506                     (u_int8_t)AH_MIN(p_pwr_array[i], min_ctl_power);
2507             }
2508             break;
2509         case CTL_11A:
2510         case CTL_11G:
2511             for (i = ALL_TARGET_LEGACY_6_24; i <= ALL_TARGET_LEGACY_54; i++) {
2512                 p_pwr_array[i] =
2513                     (u_int8_t)AH_MIN(p_pwr_array[i], min_ctl_power);
2514 #ifdef ATH_BT_COEX
2515                 if ((ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_3WIRE) ||
2516                     (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI))
2517                 {
2518                     if ((ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_LOWER_TX_PWR)
2519                         && (ahp->ah_bt_wlan_isolation 
2520                          < HAL_BT_COEX_ISOLATION_FOR_NO_COEX))
2521                     {
2522
2523                         u_int8_t reduce_pow;
2524                         
2525                         reduce_pow = (HAL_BT_COEX_ISOLATION_FOR_NO_COEX 
2526                                      - ahp->ah_bt_wlan_isolation) << 1;
2527
2528                         if (reduce_pow <= p_pwr_array[i]) {
2529                             p_pwr_array[i] -= reduce_pow;
2530                         }
2531                     }
2532                     if ((ahp->ah_bt_coex_flag & 
2533                           HAL_BT_COEX_FLAG_LOW_ACK_PWR) &&
2534                           (i != ALL_TARGET_LEGACY_36) &&
2535                           (i != ALL_TARGET_LEGACY_48) &&
2536                           (i != ALL_TARGET_LEGACY_54) &&
2537                           (p_ctl_mode[ctl_mode] == CTL_11G))
2538                     {
2539                         p_pwr_array[i] = 0;
2540                     }
2541                 }
2542 #endif
2543             }
2544             break;
2545         case CTL_5GHT20:
2546         case CTL_2GHT20:
2547             for (i = ALL_TARGET_HT20_0_8_16; i <= ALL_TARGET_HT20_23; i++) {
2548                 p_pwr_array[i] =
2549                     (u_int8_t)AH_MIN(p_pwr_array[i], min_ctl_power);
2550 #ifdef ATH_BT_COEX
2551                 if (((ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_3WIRE) ||
2552                      (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI)) &&
2553                     (ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_LOWER_TX_PWR) && 
2554                     (ahp->ah_bt_wlan_isolation 
2555                         < HAL_BT_COEX_ISOLATION_FOR_NO_COEX)) {
2556
2557                     u_int8_t reduce_pow = (HAL_BT_COEX_ISOLATION_FOR_NO_COEX 
2558                                            - ahp->ah_bt_wlan_isolation) << 1;
2559
2560                     if (reduce_pow <= p_pwr_array[i]) {
2561                         p_pwr_array[i] -= reduce_pow;
2562                     }
2563                 }
2564 #if ATH_SUPPORT_MCI
2565                 else if ((ahp->ah_bt_coex_flag & 
2566                           HAL_BT_COEX_FLAG_MCI_MAX_TX_PWR) &&
2567                          (p_ctl_mode[ctl_mode] == CTL_2GHT20) &&
2568                          (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI))
2569                 {
2570                     u_int8_t max_pwr;
2571
2572                     max_pwr = MS(mci_concur_tx_max_pwr[2][1],
2573                                  ATH_MCI_CONCUR_TX_LOWEST_PWR_MASK);
2574                     if (p_pwr_array[i] > max_pwr) {
2575                         p_pwr_array[i] = max_pwr;
2576                     }
2577                 }
2578 #endif
2579 #endif
2580             }
2581             break;
2582         case CTL_11B_EXT:
2583 #ifdef NOT_YET
2584             target_power_cck_ext.t_pow2x[0] = (u_int8_t)
2585                 AH_MIN(target_power_cck_ext.t_pow2x[0], min_ctl_power);
2586 #endif /* NOT_YET */
2587             break;
2588         case CTL_11A_EXT:
2589         case CTL_11G_EXT:
2590 #ifdef NOT_YET
2591             target_power_ofdm_ext.t_pow2x[0] = (u_int8_t)
2592                 AH_MIN(target_power_ofdm_ext.t_pow2x[0], min_ctl_power);
2593 #endif /* NOT_YET */
2594             break;
2595         case CTL_5GHT40:
2596         case CTL_2GHT40:
2597             for (i = ALL_TARGET_HT40_0_8_16; i <= ALL_TARGET_HT40_23; i++) {
2598                 p_pwr_array[i] = (u_int8_t)
2599                     AH_MIN(p_pwr_array[i], min_ctl_power);
2600 #ifdef ATH_BT_COEX
2601                 if (((ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_3WIRE) ||
2602                      (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI)) &&
2603                     (ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_LOWER_TX_PWR) && 
2604                     (ahp->ah_bt_wlan_isolation 
2605                         < HAL_BT_COEX_ISOLATION_FOR_NO_COEX)) {
2606
2607                     u_int8_t reduce_pow = (HAL_BT_COEX_ISOLATION_FOR_NO_COEX 
2608                                               - ahp->ah_bt_wlan_isolation) << 1;
2609
2610                     if (reduce_pow <= p_pwr_array[i]) {
2611                         p_pwr_array[i] -= reduce_pow;
2612                     }
2613                 }
2614 #if ATH_SUPPORT_MCI
2615                 else if ((ahp->ah_bt_coex_flag & 
2616                           HAL_BT_COEX_FLAG_MCI_MAX_TX_PWR) &&
2617                          (p_ctl_mode[ctl_mode] == CTL_2GHT40) &&
2618                          (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI))
2619                 {
2620                     u_int8_t max_pwr;
2621
2622                     max_pwr = MS(mci_concur_tx_max_pwr[3][1],
2623                                  ATH_MCI_CONCUR_TX_LOWEST_PWR_MASK);
2624                     if (p_pwr_array[i] > max_pwr) {
2625                         p_pwr_array[i] = max_pwr;
2626                     }
2627                 }
2628 #endif
2629 #endif
2630             }
2631             break;
2632         default:
2633             HALASSERT(0);
2634             break;
2635         }
2636     } /* end ctl mode checking */
2637
2638     return AH_TRUE;
2639 #undef EXT_ADDITIVE
2640 #undef CTL_11A_EXT
2641 #undef CTL_11G_EXT
2642 #undef CTL_11B_EXT
2643 #undef REDUCE_SCALED_POWER_BY_TWO_CHAIN
2644 #undef REDUCE_SCALED_POWER_BY_THREE_CHAIN
2645 }
2646
2647 /**************************************************************
2648  * ar9300_eeprom_set_transmit_power
2649  *
2650  * Set the transmit power in the baseband for the given
2651  * operating channel and mode.
2652  */
2653 HAL_STATUS
2654 ar9300_eeprom_set_transmit_power(struct ath_hal *ah,
2655     ar9300_eeprom_t *p_eep_data, const struct ieee80211_channel *chan, u_int16_t cfg_ctl,
2656     u_int16_t antenna_reduction, u_int16_t twice_max_regulatory_power,
2657     u_int16_t power_limit)
2658 {
2659 #define ABS(_x, _y) ((int)_x > (int)_y ? (int)_x - (int)_y : (int)_y - (int)_x)
2660 #define INCREASE_MAXPOW_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
2661 #define INCREASE_MAXPOW_BY_THREE_CHAIN   10 /* 10*log10(3)*2 */
2662     u_int8_t target_power_val_t2[ar9300_rate_size];
2663     u_int8_t target_power_val_t2_eep[ar9300_rate_size];
2664     int16_t twice_array_gain = 0, max_power_level = 0;
2665     struct ath_hal_9300 *ahp = AH9300(ah);
2666     int  i = 0;
2667     u_int32_t tmp_paprd_rate_mask = 0, *tmp_ptr = NULL;
2668     int      paprd_scale_factor = 5;
2669     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
2670
2671     u_int8_t *ptr_mcs_rate2power_table_index;
2672     u_int8_t mcs_rate2power_table_index_ht20[24] =
2673     {
2674         ALL_TARGET_HT20_0_8_16,
2675         ALL_TARGET_HT20_1_3_9_11_17_19,
2676         ALL_TARGET_HT20_1_3_9_11_17_19,
2677         ALL_TARGET_HT20_1_3_9_11_17_19,
2678         ALL_TARGET_HT20_4,
2679         ALL_TARGET_HT20_5,
2680         ALL_TARGET_HT20_6,
2681         ALL_TARGET_HT20_7,
2682         ALL_TARGET_HT20_0_8_16,
2683         ALL_TARGET_HT20_1_3_9_11_17_19,
2684         ALL_TARGET_HT20_1_3_9_11_17_19,
2685         ALL_TARGET_HT20_1_3_9_11_17_19,
2686         ALL_TARGET_HT20_12,
2687         ALL_TARGET_HT20_13,
2688         ALL_TARGET_HT20_14,
2689         ALL_TARGET_HT20_15,
2690         ALL_TARGET_HT20_0_8_16,
2691         ALL_TARGET_HT20_1_3_9_11_17_19,
2692         ALL_TARGET_HT20_1_3_9_11_17_19,
2693         ALL_TARGET_HT20_1_3_9_11_17_19,
2694         ALL_TARGET_HT20_20,
2695         ALL_TARGET_HT20_21,
2696         ALL_TARGET_HT20_22,
2697         ALL_TARGET_HT20_23
2698     };
2699
2700     u_int8_t mcs_rate2power_table_index_ht40[24] =
2701     {
2702         ALL_TARGET_HT40_0_8_16,
2703         ALL_TARGET_HT40_1_3_9_11_17_19,
2704         ALL_TARGET_HT40_1_3_9_11_17_19,
2705         ALL_TARGET_HT40_1_3_9_11_17_19,
2706         ALL_TARGET_HT40_4,
2707         ALL_TARGET_HT40_5,
2708         ALL_TARGET_HT40_6,
2709         ALL_TARGET_HT40_7,
2710         ALL_TARGET_HT40_0_8_16,
2711         ALL_TARGET_HT40_1_3_9_11_17_19,
2712         ALL_TARGET_HT40_1_3_9_11_17_19,
2713         ALL_TARGET_HT40_1_3_9_11_17_19,
2714         ALL_TARGET_HT40_12,
2715         ALL_TARGET_HT40_13,
2716         ALL_TARGET_HT40_14,
2717         ALL_TARGET_HT40_15,
2718         ALL_TARGET_HT40_0_8_16,
2719         ALL_TARGET_HT40_1_3_9_11_17_19,
2720         ALL_TARGET_HT40_1_3_9_11_17_19,
2721         ALL_TARGET_HT40_1_3_9_11_17_19,
2722         ALL_TARGET_HT40_20,
2723         ALL_TARGET_HT40_21,
2724         ALL_TARGET_HT40_22,
2725         ALL_TARGET_HT40_23,
2726     };
2727
2728     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2729         "%s[%d] +++chan %d,cfgctl 0x%04x  "
2730         "antenna_reduction 0x%04x, twice_max_regulatory_power 0x%04x "
2731         "power_limit 0x%04x\n",
2732         __func__, __LINE__, ichan->channel, cfg_ctl,
2733         antenna_reduction, twice_max_regulatory_power, power_limit);
2734     ar9300_set_target_power_from_eeprom(ah, ichan->channel, target_power_val_t2);
2735
2736     if (ar9300_eeprom_get(ahp, EEP_PAPRD_ENABLED)) {
2737         if (IEEE80211_IS_CHAN_2GHZ(chan)) {
2738             if (IEEE80211_IS_CHAN_HT40(chan)) {
2739                 tmp_paprd_rate_mask =
2740                     p_eep_data->modal_header_2g.paprd_rate_mask_ht40;
2741                 tmp_ptr = &AH9300(ah)->ah_2g_paprd_rate_mask_ht40;
2742             } else {
2743                 tmp_paprd_rate_mask =
2744                     p_eep_data->modal_header_2g.paprd_rate_mask_ht20;
2745                 tmp_ptr = &AH9300(ah)->ah_2g_paprd_rate_mask_ht20;
2746             }
2747         } else {
2748             if (IEEE80211_IS_CHAN_HT40(chan)) {
2749                 tmp_paprd_rate_mask =
2750                     p_eep_data->modal_header_5g.paprd_rate_mask_ht40;
2751                 tmp_ptr = &AH9300(ah)->ah_5g_paprd_rate_mask_ht40;
2752             } else {
2753                 tmp_paprd_rate_mask =
2754                     p_eep_data->modal_header_5g.paprd_rate_mask_ht20;
2755                 tmp_ptr = &AH9300(ah)->ah_5g_paprd_rate_mask_ht20;
2756             }
2757         }
2758         AH_PAPRD_GET_SCALE_FACTOR(
2759             paprd_scale_factor, p_eep_data, IEEE80211_IS_CHAN_2GHZ(chan), ichan->channel);
2760         HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] paprd_scale_factor %d\n",
2761             __func__, __LINE__, paprd_scale_factor);
2762         /* PAPRD is not done yet, Scale down the EEP power */
2763         if (IEEE80211_IS_CHAN_HT40(chan)) {
2764             ptr_mcs_rate2power_table_index =
2765                 &mcs_rate2power_table_index_ht40[0];
2766         } else {
2767             ptr_mcs_rate2power_table_index =
2768                 &mcs_rate2power_table_index_ht20[0];
2769         }
2770         if (! ichan->paprd_table_write_done) {
2771             for (i = 0;  i < 24; i++) {
2772                 /* PAPRD is done yet, so Scale down Power for PAPRD Rates*/
2773                 if (tmp_paprd_rate_mask & (1 << i)) {
2774                     target_power_val_t2[ptr_mcs_rate2power_table_index[i]] -=
2775                         paprd_scale_factor;
2776                     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2777                         "%s[%d]: Chan %d "
2778                         "Scale down target_power_val_t2[%d] = 0x%04x\n",
2779                         __func__, __LINE__,
2780                         ichan->channel, i, target_power_val_t2[i]);
2781                 }
2782             }
2783         } else {
2784             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2785                 "%s[%d]: PAPRD Done No TGT PWR Scaling\n", __func__, __LINE__);
2786         }
2787     }
2788
2789     /* Save the Target power for future use */
2790     OS_MEMCPY(target_power_val_t2_eep, target_power_val_t2,
2791                                    sizeof(target_power_val_t2));
2792     ar9300_eeprom_set_power_per_rate_table(ah, p_eep_data, chan,
2793                                      target_power_val_t2, cfg_ctl,
2794                                      antenna_reduction,
2795                                      twice_max_regulatory_power,
2796                                      power_limit, 0);
2797     
2798     /* Save this for quick lookup */
2799     ahp->reg_dmn = ath_hal_getctl(ah, chan);
2800
2801     /*
2802      * Always use CDD/direct per rate power table for register based approach.
2803      * For FCC, CDD calculations should factor in the array gain, hence 
2804      * this adjust call. ETSI and MKK does not have this requirement.
2805      */
2806     if (is_reg_dmn_fcc(ahp->reg_dmn)) {
2807         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2808             "%s: FCC regdomain, calling reg_txpower_cdd\n",
2809             __func__);
2810         ar9300_adjust_reg_txpower_cdd(ah, target_power_val_t2);
2811     }
2812
2813     if (ar9300_eeprom_get(ahp, EEP_PAPRD_ENABLED)) {
2814         for (i = 0;  i < ar9300_rate_size; i++) {
2815             /*
2816              * EEPROM TGT PWR is not same as current TGT PWR,
2817              * so Disable PAPRD for this rate.
2818              * Some of APs might ask to reduce Target Power,
2819              * if target power drops significantly,
2820              * disable PAPRD for that rate.
2821              */
2822             if (tmp_paprd_rate_mask & (1 << i)) {
2823                 if (ABS(target_power_val_t2_eep[i], target_power_val_t2[i]) >
2824                     paprd_scale_factor)
2825                 {
2826                     tmp_paprd_rate_mask &= ~(1 << i);
2827                     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2828                         "%s: EEP TPC[%02d] 0x%08x "
2829                         "Curr TPC[%02d] 0x%08x mask = 0x%08x\n",
2830                         __func__, i, target_power_val_t2_eep[i], i,
2831                         target_power_val_t2[i], tmp_paprd_rate_mask);
2832                 }
2833             }
2834             
2835         }
2836         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2837             "%s: Chan %d After tmp_paprd_rate_mask = 0x%08x\n",
2838             __func__, ichan->channel, tmp_paprd_rate_mask);
2839         if (tmp_ptr) {
2840             *tmp_ptr = tmp_paprd_rate_mask;
2841         }
2842     }
2843
2844     /* Write target power array to registers */
2845     ar9300_transmit_power_reg_write(ah, target_power_val_t2);
2846     
2847     /* Write target power for self generated frames to the TPC register */
2848     ar9300_selfgen_tpc_reg_write(ah, chan, target_power_val_t2);
2849
2850     /* GreenTx or Paprd */
2851     if (ah->ah_config.ath_hal_sta_update_tx_pwr_enable || 
2852         AH_PRIVATE(ah)->ah_caps.halPaprdEnabled) 
2853     {
2854         if (AR_SREV_POSEIDON(ah)) {
2855             /*For HAL_RSSI_TX_POWER_NONE array*/
2856             OS_MEMCPY(ahp->ah_default_tx_power, 
2857                 target_power_val_t2, 
2858                 sizeof(target_power_val_t2));
2859             /* Get defautl tx related register setting for GreenTx */
2860             /* Record OB/DB */
2861             ahp->ah_ob_db1[POSEIDON_STORED_REG_OBDB] = 
2862                 OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF2);
2863             /* Record TPC settting */
2864             ahp->ah_ob_db1[POSEIDON_STORED_REG_TPC] =
2865                 OS_REG_READ(ah, AR_TPC);
2866             /* Record BB_powertx_rate9 setting */ 
2867             ahp->ah_ob_db1[POSEIDON_STORED_REG_BB_PWRTX_RATE9] = 
2868                 OS_REG_READ(ah, AR_PHY_BB_POWERTX_RATE9);
2869         }
2870     }
2871
2872     /*
2873      * Return tx power used to iwconfig.
2874      * Since power is rate dependent, use one of the indices from the
2875      * AR9300_Rates enum to select an entry from target_power_val_t2[]
2876      * to report.
2877      * Currently returns the power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps
2878      * as CCK power is less interesting (?).
2879      */
2880     i = ALL_TARGET_LEGACY_6_24;         /* legacy */
2881     if (IEEE80211_IS_CHAN_HT40(chan)) {
2882         i = ALL_TARGET_HT40_0_8_16;     /* ht40 */
2883     } else if (IEEE80211_IS_CHAN_HT20(chan)) {
2884         i = ALL_TARGET_HT20_0_8_16;     /* ht20 */
2885     }
2886     max_power_level = target_power_val_t2[i];
2887     /* Adjusting the ah_max_power_level based on chains and antennaGain*/
2888     switch (ar9300_get_ntxchains(ahp->ah_tx_chainmask))
2889     {
2890         case 1:
2891             break;
2892         case 2:
2893             twice_array_gain = (ahp->twice_antenna_gain >= ahp->twice_antenna_reduction)? 0: 
2894                                ((int16_t)AH_MIN((ahp->twice_antenna_reduction -
2895                                    (ahp->twice_antenna_gain + INCREASE_MAXPOW_BY_TWO_CHAIN)), 0));
2896             /* Adjusting maxpower with antennaGain */
2897             max_power_level -= twice_array_gain;
2898             /* Adjusting maxpower based on chain */
2899             max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
2900             break;
2901         case 3:
2902             twice_array_gain = (ahp->twice_antenna_gain >= ahp->twice_antenna_reduction)? 0:
2903                                ((int16_t)AH_MIN((ahp->twice_antenna_reduction -
2904                                    (ahp->twice_antenna_gain + INCREASE_MAXPOW_BY_THREE_CHAIN)), 0));
2905
2906             /* Adjusting maxpower with antennaGain */
2907             max_power_level -= twice_array_gain;
2908             /* Adjusting maxpower based on chain */
2909             max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
2910             break;
2911         default:
2912             HALASSERT(0); /* Unsupported number of chains */
2913     }
2914     AH_PRIVATE(ah)->ah_maxPowerLevel = (int8_t)max_power_level;
2915
2916     ar9300_calibration_apply(ah, ichan->channel);
2917 #undef ABS
2918
2919     /* Handle per packet TPC initializations */
2920     if (ah->ah_config.ath_hal_desc_tpc) {
2921         /* Transmit Power per-rate per-chain  are  computed here. A separate
2922          * power table is maintained for different MIMO modes (i.e. TXBF ON,
2923          * STBC) to enable easy lookup during packet transmit. 
2924          * The reason for maintaing each of these tables per chain is that
2925          * the transmit power used for different number of chains is different
2926          * depending on whether the power has been limited by the target power,
2927          * the regulatory domain  or the CTL limits.
2928          */
2929         u_int mode = ath_hal_get_curmode(ah, chan);
2930         u_int32_t val = 0;
2931         u_int8_t chainmasks[AR9300_MAX_CHAINS] =
2932             {OSPREY_1_CHAINMASK, OSPREY_2LOHI_CHAINMASK, OSPREY_3_CHAINMASK};
2933         for (i = 0; i < AR9300_MAX_CHAINS; i++) {
2934             OS_MEMCPY(target_power_val_t2, target_power_val_t2_eep,
2935                                    sizeof(target_power_val_t2_eep));
2936             ar9300_eeprom_set_power_per_rate_table(ah, p_eep_data, chan,
2937                                      target_power_val_t2, cfg_ctl,
2938                                      antenna_reduction,
2939                                      twice_max_regulatory_power,
2940                                      power_limit, chainmasks[i]);
2941             HALDEBUG(ah, HAL_DEBUG_POWER_MGMT,
2942                  " Channel = %d Chainmask = %d, Upper Limit = [%2d.%1d dBm]\n",
2943                                        ichan->channel, i, ahp->upper_limit[i]/2,
2944                                        ahp->upper_limit[i]%2 * 5);
2945             ar9300_init_rate_txpower(ah, mode, chan, target_power_val_t2,
2946                                                            chainmasks[i]);
2947                                      
2948         }
2949
2950         /* Enable TPC */
2951         OS_REG_WRITE(ah, AR_PHY_PWRTX_MAX, AR_PHY_PWRTX_MAX_TPC_ENABLE);
2952         /*
2953          * Disable per chain power reduction since we are already 
2954          * accounting for this in our calculations 
2955          */
2956         val = OS_REG_READ(ah, AR_PHY_POWER_TX_SUB);
2957         if (AR_SREV_WASP(ah)) {
2958             OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
2959                        val & AR_PHY_POWER_TX_SUB_2_DISABLE);
2960         } else {
2961             OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
2962                        val & AR_PHY_POWER_TX_SUB_3_DISABLE);
2963         }
2964     }
2965
2966     return HAL_OK;
2967 }
2968
2969 /**************************************************************
2970  * ar9300_eeprom_set_addac
2971  *
2972  * Set the ADDAC from eeprom.
2973  */
2974 void
2975 ar9300_eeprom_set_addac(struct ath_hal *ah, struct ieee80211_channel *chan)
2976 {
2977
2978     HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE,
2979                  "FIXME: ar9300_eeprom_def_set_addac called\n");
2980 #if 0
2981     MODAL_EEPDEF_HEADER *p_modal;
2982     struct ath_hal_9300 *ahp = AH9300(ah);
2983     ar9300_eeprom_t *eep = &ahp->ah_eeprom.def;
2984     u_int8_t biaslevel;
2985
2986     if (AH_PRIVATE(ah)->ah_macVersion != AR_SREV_VERSION_SOWL) {
2987         return;
2988     }
2989
2990     HALASSERT(owl_get_eepdef_ver(ahp) == AR9300_EEP_VER);
2991
2992     /* Xpa bias levels in eeprom are valid from rev 14.7 */
2993     if (owl_get_eepdef_rev(ahp) < AR9300_EEP_MINOR_VER_7) {
2994         return;
2995     }
2996
2997     if (ahp->ah_emu_eeprom) {
2998         return;
2999     }
3000
3001     p_modal = &(eep->modal_header[IEEE80211_IS_CHAN_2GHZ(chan)]);
3002
3003     if (p_modal->xpa_bias_lvl != 0xff) {
3004         biaslevel = p_modal->xpa_bias_lvl;
3005     } else {
3006         /* Use freqeuncy specific xpa bias level */
3007         u_int16_t reset_freq_bin, freq_bin, freq_count = 0;
3008         CHAN_CENTERS centers;
3009
3010         ar9300_get_channel_centers(ah, chan, &centers);
3011
3012         reset_freq_bin = FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan));
3013         freq_bin = p_modal->xpa_bias_lvl_freq[0] & 0xff;
3014         biaslevel = (u_int8_t)(p_modal->xpa_bias_lvl_freq[0] >> 14);
3015
3016         freq_count++;
3017
3018         while (freq_count < 3) {
3019             if (p_modal->xpa_bias_lvl_freq[freq_count] == 0x0) {
3020                 break;
3021             }
3022
3023             freq_bin = p_modal->xpa_bias_lvl_freq[freq_count] & 0xff;
3024             if (reset_freq_bin >= freq_bin) {
3025                 biaslevel =
3026                     (u_int8_t)(p_modal->xpa_bias_lvl_freq[freq_count] >> 14);
3027             } else {
3028                 break;
3029             }
3030             freq_count++;
3031         }
3032     }
3033
3034     /* Apply bias level to the ADDAC values in the INI array */
3035     if (IEEE80211_IS_CHAN_2GHZ(chan)) {
3036         INI_RA(&ahp->ah_ini_addac, 7, 1) =
3037             (INI_RA(&ahp->ah_ini_addac, 7, 1) & (~0x18)) | biaslevel << 3;
3038     } else {
3039         INI_RA(&ahp->ah_ini_addac, 6, 1) =
3040             (INI_RA(&ahp->ah_ini_addac, 6, 1) & (~0xc0)) | biaslevel << 6;
3041     }
3042 #endif
3043 }
3044
3045 u_int
3046 ar9300_eeprom_dump_support(struct ath_hal *ah, void **pp_e)
3047 {
3048     *pp_e = &(AH9300(ah)->ah_eeprom);
3049     return sizeof(ar9300_eeprom_t);
3050 }
3051
3052 u_int8_t
3053 ar9300_eeprom_get_num_ant_config(struct ath_hal_9300 *ahp,
3054     HAL_FREQ_BAND freq_band)
3055 {
3056 #if 0
3057     ar9300_eeprom_t  *eep = &ahp->ah_eeprom.def;
3058     MODAL_EEPDEF_HEADER *p_modal =
3059         &(eep->modal_header[HAL_FREQ_BAND_2GHZ == freq_band]);
3060     BASE_EEPDEF_HEADER  *p_base  = &eep->base_eep_header;
3061     u_int8_t         num_ant_config;
3062
3063     num_ant_config = 1; /* default antenna configuration */
3064
3065     if (p_base->version >= 0x0E0D) {
3066         if (p_modal->use_ant1) {
3067             num_ant_config += 1;
3068         }
3069     }
3070
3071     return num_ant_config;
3072 #else
3073     return 1;
3074 #endif
3075 }
3076
3077 HAL_STATUS
3078 ar9300_eeprom_get_ant_cfg(struct ath_hal_9300 *ahp,
3079   const struct ieee80211_channel *chan,
3080   u_int8_t index, u_int16_t *config)
3081 {
3082 #if 0
3083     ar9300_eeprom_t  *eep = &ahp->ah_eeprom.def;
3084     MODAL_EEPDEF_HEADER *p_modal = &(eep->modal_header[IEEE80211_IS_CHAN_2GHZ(chan)]);
3085     BASE_EEPDEF_HEADER  *p_base  = &eep->base_eep_header;
3086
3087     switch (index) {
3088     case 0:
3089         *config = p_modal->ant_ctrl_common & 0xFFFF;
3090         return HAL_OK;
3091     case 1:
3092         if (p_base->version >= 0x0E0D) {
3093             if (p_modal->use_ant1) {
3094                 *config = ((p_modal->ant_ctrl_common & 0xFFFF0000) >> 16);
3095                 return HAL_OK;
3096             }
3097         }
3098         break;
3099     default:
3100         break;
3101     }
3102 #endif
3103     return HAL_EINVAL;
3104 }
3105
3106 u_int8_t*
3107 ar9300_eeprom_get_cust_data(struct ath_hal_9300 *ahp)
3108 {
3109     return (u_int8_t *)ahp;
3110 }
3111
3112 #ifdef UNUSED
3113 static inline HAL_STATUS
3114 ar9300_check_eeprom(struct ath_hal *ah)
3115 {
3116 #if 0
3117     u_int32_t sum = 0, el;
3118     u_int16_t *eepdata;
3119     int i;
3120     struct ath_hal_9300 *ahp = AH9300(ah);
3121     HAL_BOOL need_swap = AH_FALSE;
3122     ar9300_eeprom_t *eep = (ar9300_eeprom_t *)&ahp->ah_eeprom.def;
3123     u_int16_t magic, magic2;
3124     int addr;
3125     u_int16_t temp;
3126
3127     /*
3128     ** We need to check the EEPROM data regardless of if it's in flash or
3129     ** in EEPROM.
3130     */
3131
3132     if (!ahp->ah_priv.priv.ah_eeprom_read(
3133             ah, AR9300_EEPROM_MAGIC_OFFSET, &magic))
3134     {
3135         HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: Reading Magic # failed\n", __func__);
3136         return AH_FALSE;
3137     }
3138
3139     HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: Read Magic = 0x%04X\n", __func__, magic);
3140
3141     if (!ar9300_eep_data_in_flash(ah)) {
3142
3143         if (magic != AR9300_EEPROM_MAGIC) {
3144             magic2 = SWAP16(magic);
3145
3146             if (magic2 == AR9300_EEPROM_MAGIC) {
3147                 need_swap = AH_TRUE;
3148                 eepdata = (u_int16_t *)(&ahp->ah_eeprom);
3149
3150                 for (addr = 0;
3151                      addr < sizeof(ar9300_eeprom_t) / sizeof(u_int16_t);
3152                      addr++)
3153                 {
3154                     temp = SWAP16(*eepdata);
3155                     *eepdata = temp;
3156                     eepdata++;
3157
3158                     HALDEBUG(ah, HAL_DEBUG_EEPROM_DUMP, "0x%04X  ", *eepdata);
3159                     if (((addr + 1) % 6) == 0) {
3160                         HALDEBUG(ah, HAL_DEBUG_EEPROM_DUMP, "\n");
3161                     }
3162                 }
3163             } else {
3164                 HALDEBUG(ah, HAL_DEBUG_EEPROM,
3165                     "Invalid EEPROM Magic. endianness missmatch.\n");
3166                 return HAL_EEBADSUM;
3167             }
3168         }
3169     } else {
3170         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3171                  "EEPROM being read from flash @0x%p\n", AH_PRIVATE(ah)->ah_st);
3172     }
3173
3174     HALDEBUG(ah, HAL_DEBUG_EEPROM, "need_swap = %s.\n", need_swap?"True":"False");
3175
3176     if (need_swap) {
3177         el = SWAP16(ahp->ah_eeprom.def.base_eep_header.length);
3178     } else {
3179         el = ahp->ah_eeprom.def.base_eep_header.length;
3180     }
3181
3182     eepdata = (u_int16_t *)(&ahp->ah_eeprom.def);
3183     for (i = 0;
3184          i < AH_MIN(el, sizeof(ar9300_eeprom_t)) / sizeof(u_int16_t);
3185          i++) {
3186         sum ^= *eepdata++;
3187     }
3188
3189     if (need_swap) {
3190         /*
3191         *  preddy: EEPROM endianness does not match. So change it
3192         *  8bit values in eeprom data structure does not need to be swapped
3193         *  Only >8bits (16 & 32) values need to be swapped
3194         *  If a new 16 or 32 bit field is added to the EEPROM contents,
3195         *  please make sure to swap the field here
3196         */
3197         u_int32_t integer, j;
3198         u_int16_t word;
3199
3200         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3201             "EEPROM Endianness is not native.. Changing \n");
3202
3203         /* convert Base Eep header */
3204         word = SWAP16(eep->base_eep_header.length);
3205         eep->base_eep_header.length = word;
3206
3207         word = SWAP16(eep->base_eep_header.checksum);
3208         eep->base_eep_header.checksum = word;
3209
3210         word = SWAP16(eep->base_eep_header.version);
3211         eep->base_eep_header.version = word;
3212
3213         word = SWAP16(eep->base_eep_header.reg_dmn[0]);
3214         eep->base_eep_header.reg_dmn[0] = word;
3215
3216         word = SWAP16(eep->base_eep_header.reg_dmn[1]);
3217         eep->base_eep_header.reg_dmn[1] = word;
3218
3219         word = SWAP16(eep->base_eep_header.rf_silent);
3220         eep->base_eep_header.rf_silent = word;
3221
3222         word = SWAP16(eep->base_eep_header.blue_tooth_options);
3223         eep->base_eep_header.blue_tooth_options = word;
3224
3225         word = SWAP16(eep->base_eep_header.device_cap);
3226         eep->base_eep_header.device_cap = word;
3227
3228         /* convert Modal Eep header */
3229         for (j = 0; j < ARRAY_LENGTH(eep->modal_header); j++) {
3230             MODAL_EEPDEF_HEADER *p_modal = &eep->modal_header[j];
3231             integer = SWAP32(p_modal->ant_ctrl_common);
3232             p_modal->ant_ctrl_common = integer;
3233
3234             for (i = 0; i < AR9300_MAX_CHAINS; i++) {
3235                 integer = SWAP32(p_modal->ant_ctrl_chain[i]);
3236                 p_modal->ant_ctrl_chain[i] = integer;
3237             }
3238
3239             for (i = 0; i < AR9300_EEPROM_MODAL_SPURS; i++) {
3240                 word = SWAP16(p_modal->spur_chans[i].spur_chan);
3241                 p_modal->spur_chans[i].spur_chan = word;
3242             }
3243         }
3244     }
3245
3246     /* Check CRC - Attach should fail on a bad checksum */
3247     if (sum != 0xffff || owl_get_eepdef_ver(ahp) != AR9300_EEP_VER ||
3248         owl_get_eepdef_rev(ahp) < AR9300_EEP_NO_BACK_VER) {
3249         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3250             "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
3251             sum, owl_get_eepdef_ver(ahp));
3252         return HAL_EEBADSUM;
3253     }
3254 #ifdef EEPROM_DUMP
3255     ar9300_eeprom_def_dump(ah, eep);
3256 #endif
3257
3258 #if 0
3259 #ifdef AH_AR9300_OVRD_TGT_PWR
3260
3261     /*
3262      * 14.4 EEPROM contains low target powers.
3263      * Hardcode until EEPROM > 14.4
3264      */
3265     if (owl_get_eepdef_ver(ahp) == 14 && owl_get_eepdef_rev(ahp) <= 4) {
3266         MODAL_EEPDEF_HEADER *p_modal;
3267
3268 #ifdef EEPROM_DUMP
3269         HALDEBUG(ah,  HAL_DEBUG_POWER_OVERRIDE, "Original Target Powers\n");
3270         ar9300_eep_def_dump_tgt_power(ah, eep);
3271 #endif
3272         HALDEBUG(ah,  HAL_DEBUG_POWER_OVERRIDE, 
3273                 "Override Target Powers. EEPROM Version is %d.%d, "
3274                 "Device Type %d\n",
3275                 owl_get_eepdef_ver(ahp),
3276                 owl_get_eepdef_rev(ahp),
3277                 eep->base_eep_header.device_type);
3278
3279
3280         ar9300_eep_def_override_tgt_power(ah, eep);
3281
3282         if (eep->base_eep_header.device_type == 5) {
3283             /* for xb72 only: improve transmit EVM for interop */
3284             p_modal = &eep->modal_header[1];
3285             p_modal->tx_frame_to_data_start = 0x23;
3286             p_modal->tx_frame_to_xpa_on = 0x23;
3287             p_modal->tx_frame_to_pa_on = 0x23;
3288     }
3289
3290 #ifdef EEPROM_DUMP
3291         HALDEBUG(ah, HAL_DEBUG_POWER_OVERRIDE, "Modified Target Powers\n");
3292         ar9300_eep_def_dump_tgt_power(ah, eep);
3293 #endif
3294         }
3295 #endif /* AH_AR9300_OVRD_TGT_PWR */
3296 #endif
3297 #endif
3298     return HAL_OK;
3299 }
3300 #endif
3301
3302 static u_int16_t
3303 ar9300_eeprom_get_spur_chan(struct ath_hal *ah, int i, HAL_BOOL is_2ghz)
3304 {
3305     u_int16_t   spur_val = AR_NO_SPUR;
3306 #if 0
3307     struct ath_hal_9300 *ahp = AH9300(ah);
3308     ar9300_eeprom_t *eep = (ar9300_eeprom_t *)&ahp->ah_eeprom;
3309
3310     HALASSERT(i <  AR_EEPROM_MODAL_SPURS );
3311
3312     HALDEBUG(ah, HAL_DEBUG_ANI,
3313              "Getting spur idx %d is2Ghz. %d val %x\n",
3314              i, is_2ghz,
3315              AH_PRIVATE(ah)->ah_config.ath_hal_spur_chans[i][is_2ghz]);
3316
3317     switch (AH_PRIVATE(ah)->ah_config.ath_hal_spur_mode) {
3318     case SPUR_DISABLE:
3319         /* returns AR_NO_SPUR */
3320         break;
3321     case SPUR_ENABLE_IOCTL:
3322         spur_val = AH_PRIVATE(ah)->ah_config.ath_hal_spur_chans[i][is_2ghz];
3323         HALDEBUG(ah, HAL_DEBUG_ANI,
3324             "Getting spur val from new loc. %d\n", spur_val);
3325         break;
3326     case SPUR_ENABLE_EEPROM:
3327         spur_val = eep->modal_header[is_2ghz].spur_chans[i].spur_chan;
3328         break;
3329
3330     }
3331 #endif
3332     return spur_val;
3333 }
3334
3335 #ifdef UNUSED
3336 static inline HAL_BOOL
3337 ar9300_fill_eeprom(struct ath_hal *ah)
3338 {
3339     return ar9300_eeprom_restore(ah);
3340 }
3341 #endif
3342
3343 u_int16_t
3344 ar9300_eeprom_struct_size(void) 
3345 {
3346     return sizeof(ar9300_eeprom_t);
3347 }
3348
3349 int ar9300_eeprom_struct_default_many(void)
3350 {
3351     return ARRAY_LENGTH(default9300);
3352 }
3353
3354
3355 ar9300_eeprom_t *
3356 ar9300_eeprom_struct_default(int default_index) 
3357 {
3358     if (default_index >= 0 &&
3359         default_index < ARRAY_LENGTH(default9300))
3360     {
3361         return default9300[default_index];
3362     } else {
3363         return 0;
3364     }
3365 }
3366
3367 ar9300_eeprom_t *
3368 ar9300_eeprom_struct_default_find_by_id(int id) 
3369 {
3370     int it;
3371
3372     for (it = 0; it < ARRAY_LENGTH(default9300); it++) {
3373         if (default9300[it] != 0 && default9300[it]->template_version == id) {
3374             return default9300[it];
3375         }
3376     }
3377     return 0;
3378 }
3379
3380
3381 HAL_BOOL
3382 ar9300_calibration_data_read_flash(struct ath_hal *ah, long address,
3383     u_int8_t *buffer, int many)
3384 {
3385
3386     if (((address) < 0) || ((address + many) > AR9300_EEPROM_SIZE - 1)) {
3387         return AH_FALSE;
3388     }
3389     return AH_FALSE;
3390 }
3391
3392 HAL_BOOL
3393 ar9300_calibration_data_read_eeprom(struct ath_hal *ah, long address,
3394     u_int8_t *buffer, int many)
3395 {
3396     int i;
3397     u_int8_t value[2];
3398     unsigned long eep_addr;
3399     unsigned long byte_addr;
3400     u_int16_t *svalue;
3401
3402     if (((address) < 0) || ((address + many) > AR9300_EEPROM_SIZE)) {
3403         return AH_FALSE;
3404     }
3405
3406     for (i = 0; i < many; i++) {
3407         eep_addr = (u_int16_t) (address + i) / 2;
3408         byte_addr = (u_int16_t) (address + i) % 2;
3409         svalue = (u_int16_t *) value;
3410         if (! ath_hal_eepromRead(ah, eep_addr, svalue)) {
3411             HALDEBUG(ah, HAL_DEBUG_EEPROM,
3412                 "%s: Unable to read eeprom region \n", __func__);
3413             return AH_FALSE;
3414         }  
3415         buffer[i] = (*svalue >> (8 * byte_addr)) & 0xff;
3416     }  
3417     return AH_TRUE;
3418 }
3419
3420 HAL_BOOL
3421 ar9300_calibration_data_read_otp(struct ath_hal *ah, long address,
3422     u_int8_t *buffer, int many, HAL_BOOL is_wifi)
3423 {
3424     int i;
3425     unsigned long eep_addr;
3426     unsigned long byte_addr;
3427     u_int32_t svalue;
3428
3429     if (((address) < 0) || ((address + many) > 0x400)) {
3430         return AH_FALSE;
3431     }
3432
3433     for (i = 0; i < many; i++) {
3434         eep_addr = (u_int16_t) (address + i) / 4; /* otp is 4 bytes long???? */
3435         byte_addr = (u_int16_t) (address + i) % 4;
3436         if (!ar9300_otp_read(ah, eep_addr, &svalue, is_wifi)) {
3437             HALDEBUG(ah, HAL_DEBUG_EEPROM,
3438                 "%s: Unable to read otp region \n", __func__);
3439             return AH_FALSE;
3440         }  
3441         buffer[i] = (svalue >> (8 * byte_addr)) & 0xff;
3442     }  
3443     return AH_TRUE;
3444 }
3445
3446 #ifdef ATH_CAL_NAND_FLASH
3447 HAL_BOOL
3448 ar9300_calibration_data_read_nand(struct ath_hal *ah, long address,
3449     u_int8_t *buffer, int many)
3450 {
3451     int ret_len;
3452     int ret_val = 1;
3453     
3454       /* Calling OS based API to read NAND */
3455     ret_val = OS_NAND_FLASH_READ(ATH_CAL_NAND_PARTITION, address, many, &ret_len, buffer);
3456     
3457     return (ret_val ? AH_FALSE: AH_TRUE);
3458 }
3459 #endif
3460
3461 HAL_BOOL
3462 ar9300_calibration_data_read(struct ath_hal *ah, long address,
3463     u_int8_t *buffer, int many)
3464 {
3465     switch (AH9300(ah)->calibration_data_source) {
3466     case calibration_data_flash:
3467         return ar9300_calibration_data_read_flash(ah, address, buffer, many);
3468     case calibration_data_eeprom:
3469         return ar9300_calibration_data_read_eeprom(ah, address, buffer, many);
3470     case calibration_data_otp:
3471         return ar9300_calibration_data_read_otp(ah, address, buffer, many, 1);
3472 #ifdef ATH_CAL_NAND_FLASH
3473     case calibration_data_nand:
3474         return ar9300_calibration_data_read_nand(ah,address,buffer,many);
3475 #endif
3476
3477     }
3478     return AH_FALSE;
3479 }
3480
3481
3482 HAL_BOOL 
3483 ar9300_calibration_data_read_array(struct ath_hal *ah, int address,
3484     u_int8_t *buffer, int many)
3485 {
3486     int it;
3487
3488     for (it = 0; it < many; it++) {
3489         (void)ar9300_calibration_data_read(ah, address - it, buffer + it, 1);
3490     }
3491     return AH_TRUE;
3492 }
3493
3494
3495 /*
3496  * the address where the first configuration block is written
3497  */
3498 static const int base_address = 0x3ff;                /* 1KB */
3499 static const int base_address_512 = 0x1ff;            /* 512Bytes */
3500
3501 /*
3502  * the address where the NAND first configuration block is written
3503  */
3504 #ifdef ATH_CAL_NAND_FLASH
3505 static const int base_address_nand = AR9300_FLASH_CAL_START_OFFSET;
3506 #endif
3507
3508
3509 /*
3510  * the lower limit on configuration data
3511  */
3512 static const int low_limit = 0x040;
3513
3514 /*
3515  * returns size of the physical eeprom in bytes.
3516  * 1024 and 2048 are normal sizes. 
3517  * 0 means there is no eeprom. 
3518  */ 
3519 int32_t 
3520 ar9300_eeprom_size(struct ath_hal *ah)
3521 {
3522     u_int16_t data;
3523     /*
3524      * first we'll try for 4096 bytes eeprom
3525      */
3526     if (ar9300_eeprom_read_word(ah, 2047, &data)) {
3527         if (data != 0) {
3528             return 4096;
3529         }
3530     }
3531     /*
3532      * then we'll try for 2048 bytes eeprom
3533      */
3534     if (ar9300_eeprom_read_word(ah, 1023, &data)) {
3535         if (data != 0) {
3536             return 2048;
3537         }
3538     }
3539     /*
3540      * then we'll try for 1024 bytes eeprom
3541      */
3542     if (ar9300_eeprom_read_word(ah, 511, &data)) {
3543         if (data != 0) {
3544             return 1024;
3545         }
3546     }
3547     return 0;
3548 }
3549
3550 /*
3551  * returns size of the physical otp in bytes.
3552  * 1024 and 2048 are normal sizes. 
3553  * 0 means there is no eeprom. 
3554  */ 
3555 int32_t 
3556 ar9300_otp_size(struct ath_hal *ah)
3557 {
3558     if (AR_SREV_POSEIDON(ah) || AR_SREV_HORNET(ah)) {
3559         return base_address_512+1;
3560     } else {
3561         return base_address+1;
3562     }
3563 }
3564
3565
3566 /*
3567  * find top of memory
3568  */
3569 int
3570 ar9300_eeprom_base_address(struct ath_hal *ah)
3571 {
3572     int size;
3573
3574     if (AH9300(ah)->calibration_data_source == calibration_data_otp) {
3575                 return ar9300_otp_size(ah)-1;
3576         }
3577         else
3578         {
3579                 size = ar9300_eeprom_size(ah);
3580                 if (size > 0) {
3581                         return size - 1;
3582                 } else {
3583                         return ar9300_otp_size(ah)-1;
3584                 }
3585         }
3586 }
3587
3588 int
3589 ar9300_eeprom_volatile(struct ath_hal *ah)
3590 {
3591     if (AH9300(ah)->calibration_data_source == calibration_data_otp) {
3592         return 0;        /* no eeprom, use otp */
3593     } else {
3594         return 1;        /* board has eeprom or flash */
3595     }
3596 }
3597
3598 /*
3599  * need to change this to look for the pcie data in the low parts of memory
3600  * cal data needs to stop a few locations above 
3601  */
3602 int
3603 ar9300_eeprom_low_limit(struct ath_hal *ah)
3604 {
3605     return low_limit;
3606 }
3607
3608 u_int16_t
3609 ar9300_compression_checksum(u_int8_t *data, int dsize)
3610 {
3611     int it;
3612     int checksum = 0;
3613
3614     for (it = 0; it < dsize; it++) {
3615         checksum += data[it];
3616         checksum &= 0xffff;
3617     }
3618
3619     return checksum;
3620 }
3621
3622 int
3623 ar9300_compression_header_unpack(u_int8_t *best, int *code, int *reference,
3624     int *length, int *major, int *minor)
3625 {
3626     unsigned long value[4];
3627
3628     value[0] = best[0];
3629     value[1] = best[1];
3630     value[2] = best[2];
3631     value[3] = best[3];
3632     *code = ((value[0] >> 5) & 0x0007);
3633     *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
3634     *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
3635     *major = (value[2] & 0x000f);
3636     *minor = (value[3] & 0x00ff);
3637
3638     return 4;
3639 }
3640
3641
3642 static HAL_BOOL
3643 ar9300_uncompress_block(struct ath_hal *ah, u_int8_t *mptr, int mdata_size,
3644     u_int8_t *block, int size)
3645 {
3646     int it;
3647     int spot;
3648     int offset;
3649     int length;
3650
3651     spot = 0;
3652     for (it = 0; it < size; it += (length + 2)) {
3653         offset = block[it];
3654         offset &= 0xff;
3655         spot += offset;
3656         length = block[it + 1];
3657         length &= 0xff;
3658         if (length > 0 && spot >= 0 && spot + length <= mdata_size) {
3659             HALDEBUG(ah, HAL_DEBUG_EEPROM,
3660                 "%s: Restore at %d: spot=%d offset=%d length=%d\n",
3661                 __func__, it, spot, offset, length);
3662             OS_MEMCPY(&mptr[spot], &block[it + 2], length);
3663             spot += length;
3664         } else if (length > 0) {
3665             HALDEBUG(ah, HAL_DEBUG_EEPROM,
3666                 "%s: Bad restore at %d: spot=%d offset=%d length=%d\n",
3667                 __func__, it, spot, offset, length);
3668             return AH_FALSE;
3669         }
3670     }
3671     return AH_TRUE;
3672 }
3673
3674 static int
3675 ar9300_eeprom_restore_internal_address(struct ath_hal *ah,
3676     ar9300_eeprom_t *mptr, int mdata_size, int cptr, u_int8_t blank)
3677 {
3678     u_int8_t word[MOUTPUT]; 
3679     ar9300_eeprom_t *dptr; /* was uint8 */
3680     int code;
3681     int reference, length, major, minor;
3682     int osize;
3683     int it;
3684     int restored;
3685     u_int16_t checksum, mchecksum;
3686
3687     restored = 0;
3688     for (it = 0; it < MSTATE; it++) {            
3689         (void) ar9300_calibration_data_read_array(
3690             ah, cptr, word, compression_header_length);
3691         if (word[0] == blank && word[1] == blank && word[2] == blank && word[3] == blank)
3692         {
3693             break;
3694         }
3695         ar9300_compression_header_unpack(
3696             word, &code, &reference, &length, &major, &minor);
3697         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3698             "%s: Found block at %x: "
3699             "code=%d ref=%d length=%d major=%d minor=%d\n",
3700             __func__, cptr, code, reference, length, major, minor);
3701 #ifdef DONTUSE
3702         if (length >= 1024) {
3703             HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: Skipping bad header\n", __func__);
3704             cptr -= compression_header_length;
3705             continue;
3706         }
3707 #endif
3708         osize = length;                
3709         (void) ar9300_calibration_data_read_array(
3710             ah, cptr, word,
3711             compression_header_length + osize + compression_checksum_length);
3712         checksum = ar9300_compression_checksum(
3713             &word[compression_header_length], length);
3714         mchecksum =
3715             word[compression_header_length + osize] |
3716             (word[compression_header_length + osize + 1] << 8);
3717         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3718             "%s: checksum %x %x\n", __func__, checksum, mchecksum);
3719         if (checksum == mchecksum) {
3720             switch (code) {
3721             case _compress_none:
3722                 if (length != mdata_size) {
3723                     HALDEBUG(ah, HAL_DEBUG_EEPROM,
3724                         "%s: EEPROM structure size mismatch "
3725                         "memory=%d eeprom=%d\n", __func__, mdata_size, length);
3726                     return -1;
3727                 }
3728                 OS_MEMCPY((u_int8_t *)mptr,
3729                     (u_int8_t *)(word + compression_header_length), length);
3730                 HALDEBUG(ah, HAL_DEBUG_EEPROM,
3731                     "%s: restored eeprom %d: uncompressed, length %d\n",
3732                     __func__, it, length);
3733                 restored = 1;
3734                 break;
3735 #ifdef UNUSED
3736             case _compress_lzma:
3737                 if (reference == reference_current) {
3738                     dptr = mptr;
3739                 } else {
3740                     dptr = (u_int8_t *)ar9300_eeprom_struct_default_find_by_id(
3741                         reference);
3742                     if (dptr == 0) {
3743                         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3744                             "%s: Can't find reference eeprom struct %d\n",
3745                             __func__, reference);
3746                         goto done;
3747                     }
3748                 }
3749                 usize = -1;
3750                 if (usize != mdata_size) {
3751                     HALDEBUG(ah, HAL_DEBUG_EEPROM,
3752                         "%s: uncompressed data is wrong size %d %d\n",
3753                         __func__, usize, mdata_size);
3754                     goto done;
3755                 }
3756
3757                 for (ib = 0; ib < mdata_size; ib++) {
3758                     mptr[ib] = dptr[ib] ^ word[ib + overhead];
3759                 }
3760                 HALDEBUG(ah, HAL_DEBUG_EEPROM,
3761                     "%s: restored eeprom %d: compressed, "
3762                     "reference %d, length %d\n",
3763                     __func__, it, reference, length);
3764                 break;
3765             case _compress_pairs:
3766                 if (reference == reference_current) {
3767                     dptr = mptr;
3768                 } else {
3769                     dptr = (u_int8_t *)ar9300_eeprom_struct_default_find_by_id(
3770                         reference);
3771                     if (dptr == 0) {
3772                         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3773                             "%s: Can't find the reference "
3774                             "eeprom structure %d\n",
3775                             __func__, reference);
3776                         goto done;
3777                     }
3778                 }
3779                 HALDEBUG(ah, HAL_DEBUG_EEPROM,
3780                     "%s: restored eeprom %d: "
3781                     "pairs, reference %d, length %d,\n",
3782                     __func__, it, reference, length);
3783                 break;
3784 #endif
3785             case _compress_block:
3786                 if (reference == reference_current) {
3787                     dptr = mptr;
3788                 } else {
3789                     dptr = ar9300_eeprom_struct_default_find_by_id(reference);
3790                     if (dptr == 0) {
3791                         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3792                             "%s: can't find reference eeprom struct %d\n",
3793                             __func__, reference);
3794                         break;
3795                     }
3796                     OS_MEMCPY(mptr, dptr, mdata_size);
3797                 }
3798
3799                 HALDEBUG(ah, HAL_DEBUG_EEPROM,
3800                     "%s: restore eeprom %d: block, reference %d, length %d\n",
3801                     __func__, it, reference, length);
3802                 (void) ar9300_uncompress_block(ah,
3803                     (u_int8_t *) mptr, mdata_size,
3804                     (u_int8_t *) (word + compression_header_length), length);
3805                 restored = 1;
3806                 break;
3807             default:
3808                 HALDEBUG(ah, HAL_DEBUG_EEPROM,
3809                     "%s: unknown compression code %d\n", __func__, code);
3810                 break;
3811             }
3812         } else {
3813             HALDEBUG(ah, HAL_DEBUG_EEPROM,
3814                 "%s: skipping block with bad checksum\n", __func__);
3815         }
3816         cptr -= compression_header_length + osize + compression_checksum_length;
3817     }
3818
3819     if (!restored) {
3820         cptr = -1;
3821     }
3822     return cptr;
3823 }
3824
3825 static int
3826 ar9300_eeprom_restore_from_dram(struct ath_hal *ah, ar9300_eeprom_t *mptr,
3827     int mdata_size)
3828 {
3829     struct ath_hal_9300 *ahp = AH9300(ah);
3830 #if !defined(USE_PLATFORM_FRAMEWORK)
3831     char *cal_ptr;
3832 #endif
3833
3834     HALASSERT(mdata_size > 0);
3835
3836     /* if cal_in_flash is AH_TRUE, the address sent by LMAC to HAL
3837        (i.e. ah->ah_st) is corresponding to Flash. so return from 
3838        here if ar9300_eep_data_in_flash(ah) returns AH_TRUE */
3839     if(ar9300_eep_data_in_flash(ah))
3840         return -1;
3841
3842 #if 0
3843     /* check if LMAC sent DRAM address is valid */
3844     if (!(uintptr_t)(AH_PRIVATE(ah)->ah_st)) {
3845         return -1;
3846     }
3847 #endif
3848
3849     /* When calibration data is from host, Host will copy the 
3850        compressed data to the predefined DRAM location saved at ah->ah_st */
3851 #if 0
3852     ath_hal_printf(ah, "Restoring Cal data from DRAM\n");
3853     ahp->ah_cal_mem = OS_REMAP((uintptr_t)(AH_PRIVATE(ah)->ah_st), 
3854                                                         HOST_CALDATA_SIZE);
3855 #endif
3856     if (!ahp->ah_cal_mem)
3857     {
3858        HALDEBUG(ah, HAL_DEBUG_EEPROM,"%s: can't remap dram region\n", __func__);
3859        return -1;
3860     }
3861 #if !defined(USE_PLATFORM_FRAMEWORK)
3862     cal_ptr = &((char *)(ahp->ah_cal_mem))[AR9300_FLASH_CAL_START_OFFSET];
3863     OS_MEMCPY(mptr, cal_ptr, mdata_size);
3864 #else
3865     OS_MEMCPY(mptr, ahp->ah_cal_mem, mdata_size);
3866 #endif
3867
3868     if (mptr->eeprom_version   == 0xff ||
3869         mptr->template_version == 0xff ||
3870         mptr->eeprom_version   == 0    ||
3871         mptr->template_version == 0)
3872     {
3873         /* The board is uncalibrated */
3874         return -1;
3875     }
3876     if (mptr->eeprom_version != 0x2)
3877     {
3878         return -1;
3879     }
3880
3881     return mdata_size;
3882
3883 }
3884
3885 static int
3886 ar9300_eeprom_restore_from_flash(struct ath_hal *ah, ar9300_eeprom_t *mptr,
3887     int mdata_size)
3888 {
3889     struct ath_hal_9300 *ahp = AH9300(ah);
3890     char *cal_ptr;
3891
3892     HALASSERT(mdata_size > 0);
3893
3894     if (!ahp->ah_cal_mem) {
3895         return -1;
3896     }
3897
3898     ath_hal_printf(ah, "Restoring Cal data from Flash\n");
3899     /*
3900      * When calibration data is saved in flash, read
3901      * uncompressed eeprom structure from flash and return
3902      */
3903     cal_ptr = &((char *)(ahp->ah_cal_mem))[AR9300_FLASH_CAL_START_OFFSET];
3904     OS_MEMCPY(mptr, cal_ptr, mdata_size);
3905 #if 0
3906     ar9300_swap_eeprom((ar9300_eeprom_t *)mptr); DONE IN ar9300_restore()
3907 #endif
3908     if (mptr->eeprom_version   == 0xff ||
3909         mptr->template_version == 0xff ||
3910         mptr->eeprom_version   == 0    ||
3911         mptr->template_version == 0)
3912     {   
3913         /* The board is uncalibrated */
3914         return -1;
3915     } 
3916     if (mptr->eeprom_version != 0x2)
3917     {
3918         return -1;
3919     }
3920     return mdata_size;
3921 }
3922
3923 /*
3924  * Read the configuration data from the storage. We try the order with:
3925  * EEPROM, Flash, OTP. If all of above failed, use the default template.
3926  * The data can be put in any specified memory buffer.
3927  *
3928  * Returns -1 on error. 
3929  * Returns address of next memory location on success.
3930  */
3931 int
3932 ar9300_eeprom_restore_internal(struct ath_hal *ah, ar9300_eeprom_t *mptr,
3933     int mdata_size)
3934 {
3935     int nptr;
3936
3937     nptr = -1;    
3938
3939     if ((AH9300(ah)->calibration_data_try == calibration_data_none ||
3940          AH9300(ah)->calibration_data_try == calibration_data_dram) &&
3941          AH9300(ah)->try_dram && nptr < 0)
3942     {   
3943         ath_hal_printf(ah, "Restoring Cal data from DRAM\n");
3944         AH9300(ah)->calibration_data_source = calibration_data_dram;
3945         AH9300(ah)->calibration_data_source_address = 0;
3946         nptr = ar9300_eeprom_restore_from_dram(ah, mptr, mdata_size);
3947         if (nptr < 0) {
3948             AH9300(ah)->calibration_data_source = calibration_data_none;
3949             AH9300(ah)->calibration_data_source_address = 0;
3950         }
3951     }
3952     
3953     if ((AH9300(ah)->calibration_data_try == calibration_data_none ||
3954          AH9300(ah)->calibration_data_try == calibration_data_eeprom) &&
3955         AH9300(ah)->try_eeprom && nptr < 0)
3956     {
3957         /*
3958          * need to look at highest eeprom address as well as at
3959          * base_address=0x3ff where we used to write the data
3960          */
3961         ath_hal_printf(ah, "Restoring Cal data from EEPROM\n");
3962         AH9300(ah)->calibration_data_source = calibration_data_eeprom;
3963         if (AH9300(ah)->calibration_data_try_address != 0) {
3964             AH9300(ah)->calibration_data_source_address =
3965                 AH9300(ah)->calibration_data_try_address;
3966             nptr = ar9300_eeprom_restore_internal_address(
3967                 ah, mptr, mdata_size,
3968                 AH9300(ah)->calibration_data_source_address, 0xff);
3969         } else {
3970             AH9300(ah)->calibration_data_source_address =
3971                 ar9300_eeprom_base_address(ah);
3972             nptr = ar9300_eeprom_restore_internal_address(
3973                 ah, mptr, mdata_size,
3974                 AH9300(ah)->calibration_data_source_address, 0xff);
3975             if (nptr < 0 &&
3976                 AH9300(ah)->calibration_data_source_address != base_address)
3977             {
3978                 AH9300(ah)->calibration_data_source_address = base_address;
3979                 nptr = ar9300_eeprom_restore_internal_address(
3980                     ah, mptr, mdata_size,
3981                     AH9300(ah)->calibration_data_source_address, 0xff);
3982             }
3983         }
3984         if (nptr < 0) {
3985             AH9300(ah)->calibration_data_source = calibration_data_none;
3986             AH9300(ah)->calibration_data_source_address = 0;
3987         }
3988     }
3989
3990     /*
3991      * ##### should be an ifdef test for any AP usage,
3992      * either in driver or in nart
3993      */
3994     if ((AH9300(ah)->calibration_data_try == calibration_data_none ||
3995          AH9300(ah)->calibration_data_try == calibration_data_flash) &&
3996         AH9300(ah)->try_flash && nptr < 0)
3997     {
3998         ath_hal_printf(ah, "Restoring Cal data from Flash\n");
3999         AH9300(ah)->calibration_data_source = calibration_data_flash;
4000         /* how are we supposed to set this for flash? */
4001         AH9300(ah)->calibration_data_source_address = 0;
4002         nptr = ar9300_eeprom_restore_from_flash(ah, mptr, mdata_size);
4003         if (nptr < 0) {
4004             AH9300(ah)->calibration_data_source = calibration_data_none;
4005             AH9300(ah)->calibration_data_source_address = 0;
4006         }
4007     }
4008
4009     if ((AH9300(ah)->calibration_data_try == calibration_data_none ||
4010          AH9300(ah)->calibration_data_try == calibration_data_otp) &&
4011         AH9300(ah)->try_otp && nptr < 0)
4012     {
4013         ath_hal_printf(ah, "Restoring Cal data from OTP\n");
4014         AH9300(ah)->calibration_data_source = calibration_data_otp;
4015         if (AH9300(ah)->calibration_data_try_address != 0) {
4016             AH9300(ah)->calibration_data_source_address =
4017                 AH9300(ah)->calibration_data_try_address;
4018                 } else {
4019             AH9300(ah)->calibration_data_source_address =
4020                 ar9300_eeprom_base_address(ah);
4021                 }
4022         nptr = ar9300_eeprom_restore_internal_address(
4023             ah, mptr, mdata_size, AH9300(ah)->calibration_data_source_address, 0);
4024         if (nptr < 0) {
4025             AH9300(ah)->calibration_data_source = calibration_data_none;
4026             AH9300(ah)->calibration_data_source_address = 0;
4027         }
4028     }
4029
4030 #ifdef ATH_CAL_NAND_FLASH
4031     if ((AH9300(ah)->calibration_data_try == calibration_data_none ||
4032          AH9300(ah)->calibration_data_try == calibration_data_nand) &&
4033         AH9300(ah)->try_nand && nptr < 0)
4034     {
4035         AH9300(ah)->calibration_data_source = calibration_data_nand;
4036         AH9300(ah)->calibration_data_source_address = ((unsigned int)(AH_PRIVATE(ah)->ah_st)) + base_address_nand;
4037         if(ar9300_calibration_data_read(
4038             ah, AH9300(ah)->calibration_data_source_address, 
4039             (u_int8_t *)mptr, mdata_size) == AH_TRUE)
4040         {
4041             nptr = mdata_size;
4042         }
4043         /*nptr=ar9300EepromRestoreInternalAddress(ah, mptr, mdataSize, CalibrationDataSourceAddress);*/
4044         if(nptr < 0)
4045         {
4046             AH9300(ah)->calibration_data_source = calibration_data_none;
4047             AH9300(ah)->calibration_data_source_address = 0;
4048         }
4049     }
4050 #endif
4051     if (nptr < 0) {
4052         ath_hal_printf(ah, "%s[%d] No vaid CAL, calling default template\n",
4053             __func__, __LINE__);
4054         nptr = ar9300_eeprom_restore_something(ah, mptr, mdata_size);
4055     }
4056
4057     return nptr;
4058 }
4059
4060 /******************************************************************************/
4061 /*!
4062 **  \brief Eeprom Swapping Function
4063 **
4064 **  This function will swap the contents of the "longer" EEPROM data items
4065 **  to ensure they are consistent with the endian requirements for the platform
4066 **  they are being compiled for
4067 **
4068 **  \param eh    Pointer to the EEPROM data structure
4069 **  \return N/A
4070 */
4071 #if AH_BYTE_ORDER == AH_BIG_ENDIAN
4072 void
4073 ar9300_swap_eeprom(ar9300_eeprom_t *eep)
4074 {
4075     u_int32_t dword;
4076     u_int16_t word;
4077     int          i;
4078
4079     word = __bswap16(eep->base_eep_header.reg_dmn[0]);
4080     eep->base_eep_header.reg_dmn[0] = word;
4081
4082     word = __bswap16(eep->base_eep_header.reg_dmn[1]);
4083     eep->base_eep_header.reg_dmn[1] = word;
4084
4085     dword = __bswap32(eep->base_eep_header.swreg);
4086     eep->base_eep_header.swreg = dword;
4087
4088     dword = __bswap32(eep->modal_header_2g.ant_ctrl_common);
4089     eep->modal_header_2g.ant_ctrl_common = dword;
4090
4091     dword = __bswap32(eep->modal_header_2g.ant_ctrl_common2);
4092     eep->modal_header_2g.ant_ctrl_common2 = dword;
4093
4094     dword = __bswap32(eep->modal_header_2g.paprd_rate_mask_ht20);
4095     eep->modal_header_2g.paprd_rate_mask_ht20 = dword;
4096
4097     dword = __bswap32(eep->modal_header_2g.paprd_rate_mask_ht40);
4098     eep->modal_header_2g.paprd_rate_mask_ht40 = dword;
4099
4100     dword = __bswap32(eep->modal_header_5g.ant_ctrl_common);
4101     eep->modal_header_5g.ant_ctrl_common = dword;
4102
4103     dword = __bswap32(eep->modal_header_5g.ant_ctrl_common2);
4104     eep->modal_header_5g.ant_ctrl_common2 = dword;
4105
4106     dword = __bswap32(eep->modal_header_5g.paprd_rate_mask_ht20);
4107     eep->modal_header_5g.paprd_rate_mask_ht20 = dword;
4108
4109     dword = __bswap32(eep->modal_header_5g.paprd_rate_mask_ht40);
4110     eep->modal_header_5g.paprd_rate_mask_ht40 = dword;
4111
4112     for (i = 0; i < OSPREY_MAX_CHAINS; i++) {
4113         word = __bswap16(eep->modal_header_2g.ant_ctrl_chain[i]);
4114         eep->modal_header_2g.ant_ctrl_chain[i] = word;
4115
4116         word = __bswap16(eep->modal_header_5g.ant_ctrl_chain[i]);
4117         eep->modal_header_5g.ant_ctrl_chain[i] = word;
4118     }
4119 }
4120
4121 void ar9300_eeprom_template_swap(void)
4122 {
4123     int it;
4124     ar9300_eeprom_t *dptr;
4125
4126     for (it = 0; it < ARRAY_LENGTH(default9300); it++) {
4127         dptr = ar9300_eeprom_struct_default(it);
4128         if (dptr != 0) {
4129             ar9300_swap_eeprom(dptr);
4130         }
4131     }
4132 }
4133 #endif
4134
4135
4136 /*
4137  * Restore the configuration structure by reading the eeprom.
4138  * This function destroys any existing in-memory structure content.
4139  */
4140 HAL_BOOL
4141 ar9300_eeprom_restore(struct ath_hal *ah)
4142 {
4143     struct ath_hal_9300 *ahp = AH9300(ah);
4144     ar9300_eeprom_t *mptr;
4145     int mdata_size;
4146     HAL_BOOL status = AH_FALSE;
4147
4148     mptr = &ahp->ah_eeprom;
4149     mdata_size = ar9300_eeprom_struct_size();
4150
4151     if (mptr != 0 && mdata_size > 0) {
4152 #if AH_BYTE_ORDER == AH_BIG_ENDIAN
4153         ar9300_eeprom_template_swap();
4154         ar9300_swap_eeprom(mptr);
4155 #endif
4156         /*
4157          * At this point, mptr points to the eeprom data structure
4158          * in it's "default" state.  If this is big endian, swap the
4159          * data structures back to "little endian" form.
4160          */
4161         if (ar9300_eeprom_restore_internal(ah, mptr, mdata_size) >= 0) {
4162             status = AH_TRUE;
4163         }
4164
4165 #if AH_BYTE_ORDER == AH_BIG_ENDIAN
4166         /* Second Swap, back to Big Endian */
4167         ar9300_eeprom_template_swap();
4168         ar9300_swap_eeprom(mptr);
4169 #endif
4170
4171     }
4172     ahp->ah_2g_paprd_rate_mask_ht40 =
4173         mptr->modal_header_2g.paprd_rate_mask_ht40;
4174     ahp->ah_2g_paprd_rate_mask_ht20 =
4175         mptr->modal_header_2g.paprd_rate_mask_ht20;
4176     ahp->ah_5g_paprd_rate_mask_ht40 =
4177         mptr->modal_header_5g.paprd_rate_mask_ht40;
4178     ahp->ah_5g_paprd_rate_mask_ht20 =
4179         mptr->modal_header_5g.paprd_rate_mask_ht20;
4180     return status;
4181 }
4182
4183 int32_t ar9300_thermometer_get(struct ath_hal *ah)
4184 {
4185     struct ath_hal_9300 *ahp = AH9300(ah);
4186     int thermometer;
4187     thermometer =
4188         (ahp->ah_eeprom.base_eep_header.misc_configuration >> 1) & 0x3;
4189     thermometer--;
4190     return thermometer;
4191 }
4192
4193 HAL_BOOL ar9300_thermometer_apply(struct ath_hal *ah)
4194 {
4195     int thermometer = ar9300_thermometer_get(ah);
4196
4197 /* ch0_RXTX4 */
4198 /*#define AR_PHY_65NM_CH0_RXTX4       AR_PHY_65NM(ch0_RXTX4)*/
4199 #define AR_PHY_65NM_CH1_RXTX4       AR_PHY_65NM(ch1_RXTX4)
4200 #define AR_PHY_65NM_CH2_RXTX4       AR_PHY_65NM(ch2_RXTX4)
4201 /*#define AR_PHY_65NM_CH0_RXTX4_THERM_ON          0x10000000*/
4202 /*#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S        28*/
4203 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR_S      29
4204 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR        \
4205     (0x1<<AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR_S)
4206
4207     if (thermometer < 0) {
4208         OS_REG_RMW_FIELD(ah,
4209             AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 0);
4210         if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) {
4211             OS_REG_RMW_FIELD(ah,
4212                 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 0);
4213             if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
4214                 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4215                     AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 0);
4216             }
4217         }
4218         OS_REG_RMW_FIELD(ah,
4219             AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4220         if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) {
4221             OS_REG_RMW_FIELD(ah,
4222                 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4223             if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
4224                 OS_REG_RMW_FIELD(ah,
4225                     AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4226             }
4227         }
4228     } else {
4229         OS_REG_RMW_FIELD(ah,
4230             AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 1);
4231         if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) {
4232             OS_REG_RMW_FIELD(ah,
4233                 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 1);
4234             if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
4235                 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4236                     AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 1);
4237             }
4238         }
4239         if (thermometer == 0) {
4240             OS_REG_RMW_FIELD(ah,
4241                 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 1);
4242             if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) {
4243                 OS_REG_RMW_FIELD(ah,
4244                     AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4245                 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
4246                     OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4247                         AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4248                 }
4249             }
4250         } else if (thermometer == 1) {
4251             OS_REG_RMW_FIELD(ah,
4252                 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4253             if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) {
4254                 OS_REG_RMW_FIELD(ah,
4255                     AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 1);
4256                 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
4257                     OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4258                         AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4259                 }
4260             }
4261         } else if (thermometer == 2) {
4262             OS_REG_RMW_FIELD(ah,
4263                 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4264             if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) {
4265                 OS_REG_RMW_FIELD(ah,
4266                     AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4267                 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
4268                     OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4269                         AR_PHY_65NM_CH0_RXTX4_THERM_ON, 1);
4270                 }
4271             }
4272         }
4273     }
4274     return AH_TRUE;
4275 }
4276
4277 static int32_t ar9300_tuning_caps_params_get(struct ath_hal *ah)
4278 {
4279     int tuning_caps_params;
4280     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
4281     tuning_caps_params = eep->base_eep_header.params_for_tuning_caps[0];
4282     return tuning_caps_params;
4283 }
4284
4285 /*
4286  * Read the tuning caps params from eeprom and set to correct register.
4287  * To regulation the frequency accuracy.
4288  */
4289 HAL_BOOL ar9300_tuning_caps_apply(struct ath_hal *ah)
4290 {
4291     int tuning_caps_params;
4292     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
4293     tuning_caps_params = ar9300_tuning_caps_params_get(ah);
4294     if ((eep->base_eep_header.feature_enable & 0x40) >> 6) {
4295         tuning_caps_params &= 0x7f;
4296
4297         if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_WASP(ah)) {
4298             return AH_TRUE;
4299         } else if (AR_SREV_SCORPION(ah)) {
4300             OS_REG_RMW_FIELD(ah,
4301                 AR_SCORPION_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPINDAC,
4302                 tuning_caps_params);
4303             OS_REG_RMW_FIELD(ah,
4304                 AR_SCORPION_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPOUTDAC,
4305                 tuning_caps_params);
4306         } else {
4307             OS_REG_RMW_FIELD(ah,
4308                 AR_OSPREY_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPINDAC,
4309                 tuning_caps_params);
4310             OS_REG_RMW_FIELD(ah,
4311                 AR_OSPREY_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPOUTDAC,
4312                 tuning_caps_params);
4313         }
4314
4315     }
4316     return AH_TRUE;
4317 }
4318
4319 /*
4320  * Read the tx_frame_to_xpa_on param from eeprom and apply the value to 
4321  * correct register.
4322  */
4323 HAL_BOOL ar9300_xpa_timing_control_apply(struct ath_hal *ah, HAL_BOOL is_2ghz)
4324 {
4325     u_int8_t xpa_timing_control;
4326     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
4327     if ((eep->base_eep_header.feature_enable & 0x80) >> 7) {
4328                 if (AR_SREV_OSPREY(ah) || AR_SREV_AR9580(ah) || AR_SREV_WASP(ah)) {
4329                         if (is_2ghz) {
4330                 xpa_timing_control = eep->modal_header_2g.tx_frame_to_xpa_on;
4331                 OS_REG_RMW_FIELD(ah,
4332                                                 AR_PHY_XPA_TIMING_CTL, AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON,
4333                                                 xpa_timing_control);
4334                         } else {
4335                 xpa_timing_control = eep->modal_header_5g.tx_frame_to_xpa_on;
4336                 OS_REG_RMW_FIELD(ah,
4337                                                 AR_PHY_XPA_TIMING_CTL, AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON,
4338                                                 xpa_timing_control);
4339                         }
4340                 }
4341         }
4342     return AH_TRUE;
4343 }
4344
4345
4346 /*
4347  * Read the xLNA_bias_strength param from eeprom and apply the value to 
4348  * correct register.
4349  */ 
4350 HAL_BOOL ar9300_x_lNA_bias_strength_apply(struct ath_hal *ah, HAL_BOOL is_2ghz)
4351 {
4352     u_int8_t x_lNABias;
4353     u_int32_t value = 0;
4354     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
4355
4356     if ((eep->base_eep_header.misc_configuration & 0x40) >> 6) {
4357         if (AR_SREV_OSPREY(ah)) {
4358             if (is_2ghz) {
4359                 x_lNABias = eep->modal_header_2g.xLNA_bias_strength;
4360             } else {
4361                 x_lNABias = eep->modal_header_5g.xLNA_bias_strength;
4362             }
4363             value = x_lNABias & ( 0x03 );       // bit0,1 for chain0
4364             OS_REG_RMW_FIELD(ah,
4365                                         AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS, value);
4366             value = (x_lNABias >> 2) & ( 0x03 );        // bit2,3 for chain1
4367             OS_REG_RMW_FIELD(ah,
4368                                         AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS, value);
4369             value = (x_lNABias >> 4) & ( 0x03 );        // bit4,5 for chain2
4370             OS_REG_RMW_FIELD(ah,
4371                                         AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS, value);
4372         }
4373     }
4374     return AH_TRUE;
4375 }
4376
4377
4378 /*
4379  * Read EEPROM header info and program the device for correct operation
4380  * given the channel value.
4381  */
4382 HAL_BOOL
4383 ar9300_eeprom_set_board_values(struct ath_hal *ah, const struct ieee80211_channel *chan)
4384 {
4385     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
4386
4387     ar9300_xpa_bias_level_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan));
4388
4389     ar9300_xpa_timing_control_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan));
4390
4391     ar9300_ant_ctrl_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan));
4392     ar9300_drive_strength_apply(ah);
4393
4394     ar9300_x_lNA_bias_strength_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan));
4395
4396         /* wait for Poseidon internal regular turnning */
4397     /* for Hornet we move it before initPLL to avoid an access issue */
4398     /* Function not used when EMULATION. */
4399     if (!AR_SREV_HORNET(ah) && !AR_SREV_WASP(ah)) {
4400         ar9300_internal_regulator_apply(ah);
4401     }
4402
4403     ar9300_attenuation_apply(ah, ichan->channel);
4404     ar9300_quick_drop_apply(ah, ichan->channel);
4405     ar9300_thermometer_apply(ah);
4406     if(!AR_SREV_WASP(ah))
4407     {
4408         ar9300_tuning_caps_apply(ah);
4409     }
4410
4411     ar9300_tx_end_to_xpab_off_apply(ah, ichan->channel);
4412
4413     return AH_TRUE;
4414 }
4415
4416 u_int8_t *
4417 ar9300_eeprom_get_spur_chans_ptr(struct ath_hal *ah, HAL_BOOL is_2ghz)
4418 {
4419     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
4420
4421     if (is_2ghz) {
4422         return &(eep->modal_header_2g.spur_chans[0]);
4423     } else {
4424         return &(eep->modal_header_5g.spur_chans[0]);
4425     }
4426 }
4427
4428 static u_int8_t ar9300_eeprom_get_tx_gain_table_number_max(struct ath_hal *ah)
4429 {
4430     unsigned long tx_gain_table_max;
4431     tx_gain_table_max = OS_REG_READ_FIELD(ah,
4432         AR_PHY_TPC_7, AR_PHY_TPC_7_TX_GAIN_TABLE_MAX);
4433     return tx_gain_table_max;
4434 }
4435
4436 u_int8_t ar9300_eeprom_tx_gain_table_index_max_apply(struct ath_hal *ah, u_int16_t channel)
4437 {
4438     unsigned int index;
4439     ar9300_eeprom_t *ahp_Eeprom;
4440     struct ath_hal_9300 *ahp = AH9300(ah);
4441
4442     ahp_Eeprom = &ahp->ah_eeprom;
4443
4444     if (ahp_Eeprom->base_ext1.misc_enable == 0)
4445         return AH_FALSE;
4446
4447     if (channel < 4000) 
4448     {
4449         index = ahp_Eeprom->modal_header_2g.tx_gain_cap;
4450     }
4451     else
4452     {
4453         index = ahp_Eeprom->modal_header_5g.tx_gain_cap;
4454     }
4455
4456     OS_REG_RMW_FIELD(ah,
4457         AR_PHY_TPC_7, AR_PHY_TPC_7_TX_GAIN_TABLE_MAX, index);
4458     return AH_TRUE;
4459 }
4460
4461 static u_int8_t ar9300_eeprom_get_pcdac_tx_gain_table_i(struct ath_hal *ah, 
4462                                                int i, u_int8_t *pcdac)
4463 {
4464     unsigned long tx_gain;
4465     u_int8_t tx_gain_table_max;
4466     tx_gain_table_max = ar9300_eeprom_get_tx_gain_table_number_max(ah);
4467     if (i <= 0 || i > tx_gain_table_max) {
4468         *pcdac = 0;
4469         return AH_FALSE;
4470     }
4471
4472     tx_gain = OS_REG_READ(ah, AR_PHY_TXGAIN_TAB(1) + i * 4);
4473     *pcdac = ((tx_gain >> 24) & 0xff);
4474     return AH_TRUE;
4475 }
4476
4477 u_int8_t ar9300_eeprom_set_tx_gain_cap(struct ath_hal *ah, 
4478                                                int *tx_gain_max)
4479 // pcdac read back from reg, read back value depends on reset 2GHz/5GHz ini 
4480 // tx_gain_table, this function will be called twice after each 
4481 // band's calibration.
4482 // after 2GHz cal, tx_gain_max[0] has 2GHz, calibration max txgain, 
4483 // tx_gain_max[1]=-100
4484 // after 5GHz cal, tx_gain_max[0],tx_gain_max[1] have calibration 
4485 // value for both band
4486 // reset is on 5GHz, reg reading from tx_gain_table is for 5GHz,
4487 // so program can't recalculate 2g.tx_gain_cap at this point.
4488 {
4489     int i = 0, ig, im = 0;
4490     u_int8_t pcdac = 0;
4491     u_int8_t tx_gain_table_max;
4492     ar9300_eeprom_t *ahp_Eeprom;
4493     struct ath_hal_9300 *ahp = AH9300(ah);
4494
4495     ahp_Eeprom = &ahp->ah_eeprom;
4496
4497     if (ahp_Eeprom->base_ext1.misc_enable == 0)
4498         return AH_FALSE;
4499
4500     tx_gain_table_max = ar9300_eeprom_get_tx_gain_table_number_max(ah);
4501
4502     for (i = 0; i < 2; i++) {
4503         if (tx_gain_max[i]>-100) {      // -100 didn't cal that band.
4504             if ( i== 0) {
4505                 if (tx_gain_max[1]>-100) {
4506                     continue;
4507                     // both band are calibrated, skip 2GHz 2g.tx_gain_cap reset
4508                 }
4509             }
4510             for (ig = 1; ig <= tx_gain_table_max; ig++) {
4511                 if (ah != 0 && ah->ah_reset != 0)
4512                 {
4513                     ar9300_eeprom_get_pcdac_tx_gain_table_i(ah, ig, &pcdac);
4514                     if (pcdac >= tx_gain_max[i])
4515                         break;
4516                 }
4517             }
4518             if (ig+1 <= tx_gain_table_max) {
4519                 if (pcdac == tx_gain_max[i])
4520                     im = ig;
4521                 else
4522                     im = ig + 1;
4523                 if (i == 0) {
4524                     ahp_Eeprom->modal_header_2g.tx_gain_cap = im;
4525                 } else {
4526                     ahp_Eeprom->modal_header_5g.tx_gain_cap = im;
4527                 }
4528             } else {
4529                 if (i == 0) {
4530                     ahp_Eeprom->modal_header_2g.tx_gain_cap = ig;
4531                 } else {
4532                     ahp_Eeprom->modal_header_5g.tx_gain_cap = ig;
4533                 }
4534             }
4535         }
4536     }
4537     return AH_TRUE;
4538 }