]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c
Update lldb to upstream trunk r242221.
[FreeBSD/FreeBSD.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 /*
1204  * Return the Rx NF offset for specific channel.
1205  * The values saved in EEPROM/OTP/Flash is converted through the following way:
1206  *     ((_p) - NOISE_PWR_DATA_OFFSET) << 2
1207  * So we need to convert back to the original values.
1208  */
1209 int ar9300_get_rx_nf_offset(struct ath_hal *ah, struct ieee80211_channel *chan, int8_t *nf_pwr, int8_t *nf_cal) {
1210     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
1211     int8_t rx_nf_pwr, rx_nf_cal;
1212     int i; 
1213     //HALASSERT(ichan);
1214
1215     /* Fill 0 if valid internal channel is not found */
1216     if (ichan == AH_NULL) {
1217         OS_MEMZERO(nf_pwr, sizeof(nf_pwr[0])*OSPREY_MAX_CHAINS);
1218         OS_MEMZERO(nf_cal, sizeof(nf_cal[0])*OSPREY_MAX_CHAINS);
1219         return -1;
1220     }
1221
1222     for (i = 0; i < OSPREY_MAX_CHAINS; i++) {
1223             if ((rx_nf_pwr = ar9300_noise_floor_cal_or_power_get(ah, ichan->channel, i, 0)) == 1) {
1224                 nf_pwr[i] = 0;
1225             } else {
1226                 //printk("%s: raw nf_pwr[%d] = %d\n", __func__, i, rx_nf_pwr);
1227             nf_pwr[i] = NOISE_PWR_DBM_2_INT(rx_nf_pwr);
1228             }
1229
1230             if ((rx_nf_cal = ar9300_noise_floor_cal_or_power_get(ah, ichan->channel, i, 1)) == 1) {
1231                 nf_cal[i] = 0;
1232             } else {
1233                 //printk("%s: raw nf_cal[%d] = %d\n", __func__, i, rx_nf_cal);
1234             nf_cal[i] = NOISE_PWR_DBM_2_INT(rx_nf_cal);
1235             }
1236     }
1237
1238     return 0;
1239 }
1240
1241 int32_t ar9300_rx_gain_index_get(struct ath_hal *ah)
1242 {
1243     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1244
1245     return (eep->base_eep_header.txrxgain) & 0xf;        /* bits 3:0 */
1246 }
1247
1248
1249 int32_t ar9300_tx_gain_index_get(struct ath_hal *ah)
1250 {
1251     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1252
1253     return (eep->base_eep_header.txrxgain >> 4) & 0xf;    /* bits 7:4 */
1254 }
1255
1256 HAL_BOOL ar9300_internal_regulator_apply(struct ath_hal *ah)
1257 {
1258     struct ath_hal_9300 *ahp = AH9300(ah);
1259     int internal_regulator = ar9300_eeprom_get(ahp, EEP_INTERNAL_REGULATOR);
1260     int reg_pmu1, reg_pmu2, reg_pmu1_set, reg_pmu2_set;
1261     u_int32_t reg_PMU1, reg_PMU2;
1262     unsigned long eep_addr;
1263     u_int32_t reg_val, reg_usb = 0, reg_pmu = 0;
1264     int usb_valid = 0, pmu_valid = 0;
1265     unsigned char pmu_refv; 
1266
1267     if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
1268         reg_PMU1 = AR_PHY_PMU1_JUPITER;
1269         reg_PMU2 = AR_PHY_PMU2_JUPITER;
1270     }
1271     else {
1272         reg_PMU1 = AR_PHY_PMU1;
1273         reg_PMU2 = AR_PHY_PMU2;
1274     }
1275
1276     if (internal_regulator) {
1277         if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
1278             if (AR_SREV_HORNET(ah)) {
1279                 /* Read OTP first */
1280                 for (eep_addr = 0x14; ; eep_addr -= 0x10) {
1281
1282                     ar9300_otp_read(ah, eep_addr / 4, &reg_val, 1);
1283
1284                     if ((reg_val & 0x80) == 0x80){
1285                         usb_valid = 1;
1286                         reg_usb = reg_val & 0x000000ff;
1287                     }
1288                     
1289                     if ((reg_val & 0x80000000) == 0x80000000){
1290                         pmu_valid = 1;
1291                         reg_pmu = (reg_val & 0xff000000) >> 24;
1292                     }
1293
1294                     if (eep_addr == 0x4) {
1295                         break;
1296                     }
1297                 }
1298
1299                 if (pmu_valid) {
1300                     pmu_refv = reg_pmu & 0xf;
1301                 } else {
1302                     pmu_refv = 0x8;
1303                 }
1304
1305                 /*
1306                  * If (valid) {
1307                  *   Usb_phy_ctrl2_tx_cal_en -> 0
1308                  *   Usb_phy_ctrl2_tx_cal_sel -> 0
1309                  *   Usb_phy_ctrl2_tx_man_cal -> 0, 1, 3, 7 or 15 from OTP
1310                  * }
1311                  */
1312                 if (usb_valid) {
1313                     OS_REG_RMW_FIELD(ah, 0x16c88, AR_PHY_CTRL2_TX_CAL_EN, 0x0);
1314                     OS_REG_RMW_FIELD(ah, 0x16c88, AR_PHY_CTRL2_TX_CAL_SEL, 0x0);
1315                     OS_REG_RMW_FIELD(ah, 0x16c88, 
1316                         AR_PHY_CTRL2_TX_MAN_CAL, (reg_usb & 0xf));
1317                 }
1318
1319             } else {
1320                 pmu_refv = 0x8;
1321             }
1322             /*#ifndef USE_HIF*/
1323             /* Follow the MDK settings for Hornet PMU.
1324              * my $pwd               = 0x0;
1325              * my $Nfdiv             = 0x3;  # xtal_freq = 25MHz
1326              * my $Nfdiv             = 0x4;  # xtal_freq = 40MHz
1327              * my $Refv              = 0x7;  # 0x5:1.22V; 0x8:1.29V
1328              * my $Gm1               = 0x3;  #Poseidon $Gm1=1
1329              * my $classb            = 0x0;
1330              * my $Cc                = 0x1;  #Poseidon $Cc=7
1331              * my $Rc                = 0x6;
1332              * my $ramp_slope        = 0x1;
1333              * my $Segm              = 0x3;
1334              * my $use_local_osc     = 0x0;
1335              * my $force_xosc_stable = 0x0;
1336              * my $Selfb             = 0x0;  #Poseidon $Selfb=1
1337              * my $Filterfb          = 0x3;  #Poseidon $Filterfb=0
1338              * my $Filtervc          = 0x0;
1339              * my $disc              = 0x0;
1340              * my $discdel           = 0x4;
1341              * my $spare             = 0x0;
1342              * $reg_PMU1 =
1343              *     $pwd | ($Nfdiv<<1) | ($Refv<<4) | ($Gm1<<8) |
1344              *     ($classb<<11) | ($Cc<<14) | ($Rc<<17) | ($ramp_slope<<20) |
1345              *     ($Segm<<24) | ($use_local_osc<<26) |
1346              *     ($force_xosc_stable<<27) | ($Selfb<<28) | ($Filterfb<<29);
1347              * $reg_PMU2 = $handle->reg_rd("ch0_PMU2");
1348              * $reg_PMU2 = ($reg_PMU2 & 0xfe3fffff) | ($Filtervc<<22);
1349              * $reg_PMU2 = ($reg_PMU2 & 0xe3ffffff) | ($discdel<<26);
1350              * $reg_PMU2 = ($reg_PMU2 & 0x1fffffff) | ($spare<<29); 
1351              */
1352             if (ahp->clk_25mhz) {
1353                 reg_pmu1_set = 0 |
1354                     (3 <<  1) | (pmu_refv << 4) | (3 <<  8) | (0 << 11) |
1355                     (1 << 14) | (6 << 17) | (1 << 20) | (3 << 24) |
1356                     (0 << 26) | (0 << 27) | (0 << 28) | (0 << 29);
1357             } else {
1358                 if (AR_SREV_POSEIDON(ah)) {
1359                     reg_pmu1_set = 0 | 
1360                         (5 <<  1) | (7 <<  4) | (2 <<  8) | (0 << 11) |
1361                         (2 << 14) | (6 << 17) | (1 << 20) | (3 << 24) |
1362                         (0 << 26) | (0 << 27) | (1 << 28) | (0 << 29) ;
1363                 } else {
1364                     reg_pmu1_set = 0 |
1365                         (4 <<  1) | (7 <<  4) | (3 <<  8) | (0 << 11) |
1366                         (1 << 14) | (6 << 17) | (1 << 20) | (3 << 24) |
1367                         (0 << 26) | (0 << 27) | (0 << 28) | (0 << 29) ;
1368                 } 
1369             }
1370             OS_REG_RMW_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM, 0x0);
1371
1372             OS_REG_WRITE(ah, reg_PMU1, reg_pmu1_set);   /* 0x638c8376 */
1373             reg_pmu1 = OS_REG_READ(ah, reg_PMU1);
1374             while (reg_pmu1 != reg_pmu1_set) {
1375                 OS_REG_WRITE(ah, reg_PMU1, reg_pmu1_set);  /* 0x638c8376 */
1376                 OS_DELAY(10);
1377                 reg_pmu1 = OS_REG_READ(ah, reg_PMU1);
1378             }
1379                                 
1380             reg_pmu2_set =
1381                  (OS_REG_READ(ah, reg_PMU2) & (~0xFFC00000)) | (4 << 26);
1382             OS_REG_WRITE(ah, reg_PMU2, reg_pmu2_set);
1383             reg_pmu2 = OS_REG_READ(ah, reg_PMU2);
1384             while (reg_pmu2 != reg_pmu2_set) {
1385                 OS_REG_WRITE(ah, reg_PMU2, reg_pmu2_set);
1386                 OS_DELAY(10);
1387                 reg_pmu2 = OS_REG_READ(ah, reg_PMU2);
1388             }
1389             reg_pmu2_set =
1390                  (OS_REG_READ(ah, reg_PMU2) & (~0x00200000)) | (1 << 21);
1391             OS_REG_WRITE(ah, reg_PMU2, reg_pmu2_set);
1392             reg_pmu2 = OS_REG_READ(ah, reg_PMU2);
1393             while (reg_pmu2 != reg_pmu2_set) {
1394                 OS_REG_WRITE(ah, reg_PMU2, reg_pmu2_set);
1395                 OS_DELAY(10);
1396                 reg_pmu2 = OS_REG_READ(ah, reg_PMU2);
1397             }
1398             /*#endif*/
1399         } else if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
1400             /* Internal regulator is ON. Write swreg register. */
1401             int swreg = ar9300_eeprom_get(ahp, EEP_SWREG);
1402             OS_REG_WRITE(ah, reg_PMU1, swreg);
1403         } else {
1404             /* Internal regulator is ON. Write swreg register. */
1405             int swreg = ar9300_eeprom_get(ahp, EEP_SWREG);
1406             OS_REG_WRITE(ah, AR_RTC_REG_CONTROL1,
1407                          OS_REG_READ(ah, AR_RTC_REG_CONTROL1) &
1408                          (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
1409             OS_REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
1410             /* Set REG_CONTROL1.SWREG_PROGRAM */
1411             OS_REG_WRITE(ah, AR_RTC_REG_CONTROL1,
1412                 OS_REG_READ(ah, AR_RTC_REG_CONTROL1) |
1413                 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
1414         }
1415     } else {
1416         if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
1417             OS_REG_RMW_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM, 0x0);
1418             reg_pmu2 = OS_REG_READ_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM);
1419             while (reg_pmu2) {
1420                 OS_DELAY(10);
1421                 reg_pmu2 = OS_REG_READ_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM);
1422             }
1423             OS_REG_RMW_FIELD(ah, reg_PMU1, AR_PHY_PMU1_PWD, 0x1);
1424             reg_pmu1 = OS_REG_READ_FIELD(ah, reg_PMU1, AR_PHY_PMU1_PWD);
1425             while (!reg_pmu1) {
1426                 OS_DELAY(10);
1427                 reg_pmu1 = OS_REG_READ_FIELD(ah, reg_PMU1, AR_PHY_PMU1_PWD);
1428             }
1429             OS_REG_RMW_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM, 0x1);
1430             reg_pmu2 = OS_REG_READ_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM);
1431             while (!reg_pmu2) {
1432                 OS_DELAY(10);
1433                 reg_pmu2 = OS_REG_READ_FIELD(ah, reg_PMU2, AR_PHY_PMU2_PGM);
1434             }
1435         } else if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
1436             OS_REG_RMW_FIELD(ah, reg_PMU1, AR_PHY_PMU1_PWD, 0x1);
1437         } else {
1438             OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK,
1439                 (OS_REG_READ(ah, AR_RTC_SLEEP_CLK) |
1440                 AR_RTC_FORCE_SWREG_PRD | AR_RTC_PCIE_RST_PWDN_EN));
1441         }
1442     }
1443
1444     return 0;  
1445 }
1446
1447 HAL_BOOL ar9300_drive_strength_apply(struct ath_hal *ah)
1448 {
1449     struct ath_hal_9300 *ahp = AH9300(ah);
1450     int drive_strength;
1451     unsigned long reg;
1452
1453     drive_strength = ar9300_eeprom_get(ahp, EEP_DRIVE_STRENGTH);
1454     if (drive_strength) {
1455         reg = OS_REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
1456         reg &= ~0x00ffffc0;
1457         reg |= 0x5 << 21;
1458         reg |= 0x5 << 18;
1459         reg |= 0x5 << 15;
1460         reg |= 0x5 << 12;
1461         reg |= 0x5 << 9;
1462         reg |= 0x5 << 6;
1463         OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
1464
1465         reg = OS_REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
1466         reg &= ~0xffffffe0;
1467         reg |= 0x5 << 29;
1468         reg |= 0x5 << 26;
1469         reg |= 0x5 << 23;
1470         reg |= 0x5 << 20;
1471         reg |= 0x5 << 17;
1472         reg |= 0x5 << 14;
1473         reg |= 0x5 << 11;
1474         reg |= 0x5 << 8;
1475         reg |= 0x5 << 5;
1476         OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
1477
1478         reg = OS_REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
1479         reg &= ~0xff800000;
1480         reg |= 0x5 << 29;
1481         reg |= 0x5 << 26;
1482         reg |= 0x5 << 23;
1483         OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
1484     }
1485     return 0;
1486 }
1487
1488 int32_t ar9300_xpa_bias_level_get(struct ath_hal *ah, HAL_BOOL is_2ghz)
1489 {
1490     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1491     if (is_2ghz) {
1492         return eep->modal_header_2g.xpa_bias_lvl;
1493     } else {
1494         return eep->modal_header_5g.xpa_bias_lvl;
1495     }
1496 }
1497
1498 HAL_BOOL ar9300_xpa_bias_level_apply(struct ath_hal *ah, HAL_BOOL is_2ghz)
1499 {
1500     /*
1501      * In ar9330 emu, we can't access radio registers, 
1502      * merlin is used for radio part.
1503      */
1504     int bias;
1505     bias = ar9300_xpa_bias_level_get(ah, is_2ghz);
1506
1507     if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_WASP(ah)) {
1508         OS_REG_RMW_FIELD(ah,
1509             AR_HORNET_CH0_TOP2, AR_HORNET_CH0_TOP2_XPABIASLVL, bias);
1510     } else if (AR_SREV_SCORPION(ah)) {
1511         OS_REG_RMW_FIELD(ah,
1512             AR_SCORPION_CH0_TOP, AR_SCORPION_CH0_TOP_XPABIASLVL, bias);
1513     } else if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
1514         OS_REG_RMW_FIELD(ah,
1515             AR_PHY_65NM_CH0_TOP_JUPITER, AR_PHY_65NM_CH0_TOP_XPABIASLVL, bias);
1516     } else {
1517         OS_REG_RMW_FIELD(ah,
1518             AR_PHY_65NM_CH0_TOP, AR_PHY_65NM_CH0_TOP_XPABIASLVL, bias);
1519         OS_REG_RMW_FIELD(ah,
1520             AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_XPABIASLVL_MSB,
1521             bias >> 2);
1522         OS_REG_RMW_FIELD(ah,
1523             AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_XPASHORT2GND, 1);
1524     }
1525     return 0;
1526 }
1527
1528 u_int32_t ar9300_ant_ctrl_common_get(struct ath_hal *ah, HAL_BOOL is_2ghz)
1529 {
1530     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1531     if (is_2ghz) {
1532         return eep->modal_header_2g.ant_ctrl_common;
1533     } else {
1534         return eep->modal_header_5g.ant_ctrl_common;
1535     }
1536 }
1537 static u_int16_t 
1538 ar9300_switch_com_spdt_get(struct ath_hal *ah, HAL_BOOL is_2ghz)
1539 {
1540     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1541     if (is_2ghz) {
1542         return eep->modal_header_2g.switchcomspdt;
1543     } else {
1544         return eep->modal_header_5g.switchcomspdt;
1545     }
1546 }
1547 u_int32_t ar9300_ant_ctrl_common2_get(struct ath_hal *ah, HAL_BOOL is_2ghz)
1548 {
1549     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1550     if (is_2ghz) {
1551         return eep->modal_header_2g.ant_ctrl_common2;
1552     } else {
1553         return eep->modal_header_5g.ant_ctrl_common2;
1554     }
1555 }
1556
1557 u_int16_t ar9300_ant_ctrl_chain_get(struct ath_hal *ah, int chain,
1558     HAL_BOOL is_2ghz)
1559 {
1560     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1561     if (chain >= 0 && chain < OSPREY_MAX_CHAINS) {
1562         if (is_2ghz) {
1563             return eep->modal_header_2g.ant_ctrl_chain[chain];
1564         } else {
1565             return eep->modal_header_5g.ant_ctrl_chain[chain];
1566         }
1567     }
1568     return 0;
1569 }
1570
1571 /*
1572  * Select the usage of antenna via the RF switch.
1573  * Default values are loaded from eeprom.
1574  */
1575 HAL_BOOL ar9300_ant_swcom_sel(struct ath_hal *ah, u_int8_t ops,
1576                         u_int32_t *common_tbl1, u_int32_t *common_tbl2)
1577 {
1578     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1579     struct ath_hal_private  *ap  = AH_PRIVATE(ah);
1580     const struct ieee80211_channel *curchan = ap->ah_curchan;
1581     enum {
1582         ANT_SELECT_OPS_GET,
1583         ANT_SELECT_OPS_SET,
1584     };
1585
1586     if (AR_SREV_JUPITER(ah) || AR_SREV_SCORPION(ah))
1587         return AH_FALSE;
1588
1589     if (!curchan)
1590         return AH_FALSE;
1591
1592 #define AR_SWITCH_TABLE_COM_ALL (0xffff)
1593 #define AR_SWITCH_TABLE_COM_ALL_S (0)
1594 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
1595 #define AR_SWITCH_TABLE_COM2_ALL_S (0)
1596     switch (ops) {
1597     case ANT_SELECT_OPS_GET:
1598         *common_tbl1 = OS_REG_READ_FIELD(ah, AR_PHY_SWITCH_COM,
1599                             AR_SWITCH_TABLE_COM_ALL);
1600         *common_tbl2 = OS_REG_READ_FIELD(ah, AR_PHY_SWITCH_COM_2,
1601                             AR_SWITCH_TABLE_COM2_ALL);
1602         break;
1603     case ANT_SELECT_OPS_SET:
1604         OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
1605             AR_SWITCH_TABLE_COM_ALL, *common_tbl1);
1606         OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2,
1607             AR_SWITCH_TABLE_COM2_ALL, *common_tbl2);
1608
1609         /* write back to eeprom */
1610         if (IEEE80211_IS_CHAN_2GHZ(curchan)) {
1611             eep->modal_header_2g.ant_ctrl_common = *common_tbl1;
1612             eep->modal_header_2g.ant_ctrl_common2 = *common_tbl2;
1613         } else {
1614             eep->modal_header_5g.ant_ctrl_common = *common_tbl1;
1615             eep->modal_header_5g.ant_ctrl_common2 = *common_tbl2;
1616         }
1617
1618         break;
1619     default:
1620         break;
1621     }
1622
1623     return AH_TRUE;
1624 }
1625
1626 HAL_BOOL ar9300_ant_ctrl_apply(struct ath_hal *ah, HAL_BOOL is_2ghz)
1627 {
1628     u_int32_t value;
1629     struct ath_hal_9300 *ahp = AH9300(ah);
1630     u_int32_t regval;
1631     struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
1632 #if ATH_ANT_DIV_COMB
1633     HAL_CAPABILITIES *pcap = &ahpriv->ah_caps;
1634 #endif  /* ATH_ANT_DIV_COMB */
1635     u_int32_t xlan_gpio_cfg;
1636     u_int8_t  i;
1637
1638     if (AR_SREV_POSEIDON(ah)) {
1639         xlan_gpio_cfg = ah->ah_config.ath_hal_ext_lna_ctl_gpio;
1640         if (xlan_gpio_cfg) {
1641             for (i = 0; i < 32; i++) {
1642                 if (xlan_gpio_cfg & (1 << i)) {
1643                     ath_hal_gpioCfgOutput(ah, i, 
1644                         HAL_GPIO_OUTPUT_MUX_PCIE_ATTENTION_LED);
1645                 }
1646             }
1647         }    
1648     }
1649 #define AR_SWITCH_TABLE_COM_ALL (0xffff)
1650 #define AR_SWITCH_TABLE_COM_ALL_S (0)
1651 #define AR_SWITCH_TABLE_COM_JUPITER_ALL (0xffffff)
1652 #define AR_SWITCH_TABLE_COM_JUPITER_ALL_S (0)
1653 #define AR_SWITCH_TABLE_COM_SCORPION_ALL (0xffffff)
1654 #define AR_SWITCH_TABLE_COM_SCORPION_ALL_S (0)
1655 #define AR_SWITCH_TABLE_COM_SPDT (0x00f00000)
1656     value = ar9300_ant_ctrl_common_get(ah, is_2ghz);
1657     if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
1658         if (AR_SREV_JUPITER_10(ah)) {
1659             /* Force SPDT setting for Jupiter 1.0 chips. */
1660             value &= ~AR_SWITCH_TABLE_COM_SPDT;
1661             value |= 0x00100000;
1662         }
1663         OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 
1664             AR_SWITCH_TABLE_COM_JUPITER_ALL, value);
1665     }
1666     else if (AR_SREV_SCORPION(ah)) {
1667         OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 
1668             AR_SWITCH_TABLE_COM_SCORPION_ALL, value);
1669     }
1670     else {
1671         OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 
1672             AR_SWITCH_TABLE_COM_ALL, value);
1673     }
1674 /*
1675 *   Jupiter2.0 defines new switch table for BT/WLAN, 
1676 *       here's new field name in WB222.ref for both 2G and 5G.
1677 *   Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
1678 *   15:12       R/W     SWITCH_TABLE_COM_SPDT_WLAN_RX   SWITCH_TABLE_COM_SPDT_WLAN_RX 
1679 *   11:8        R/W     SWITCH_TABLE_COM_SPDT_WLAN_TX   SWITCH_TABLE_COM_SPDT_WLAN_TX
1680 *   7:4 R/W     SWITCH_TABLE_COM_SPDT_WLAN_IDLE SWITCH_TABLE_COM_SPDT_WLAN_IDLE 
1681 */
1682 #define AR_SWITCH_TABLE_COM_SPDT_ALL (0x0000fff0)
1683 #define AR_SWITCH_TABLE_COM_SPDT_ALL_S (4)
1684     if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) {
1685         value = ar9300_switch_com_spdt_get(ah, is_2ghz);
1686         OS_REG_RMW_FIELD(ah, AR_GLB_CONTROL, 
1687             AR_SWITCH_TABLE_COM_SPDT_ALL, value);
1688
1689         OS_REG_SET_BIT(ah, AR_GLB_CONTROL,
1690             AR_BTCOEX_CTRL_SPDT_ENABLE);
1691         //OS_REG_SET_BIT(ah, AR_GLB_CONTROL,
1692         //    AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
1693     }
1694
1695 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
1696 #define AR_SWITCH_TABLE_COM2_ALL_S (0)
1697     value = ar9300_ant_ctrl_common2_get(ah, is_2ghz);
1698 #if ATH_ANT_DIV_COMB
1699     if ( AR_SREV_POSEIDON(ah) && (ahp->ah_lna_div_use_bt_ant_enable == TRUE) ) {
1700         value &= ~AR_SWITCH_TABLE_COM2_ALL;
1701         value |= ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable;
1702         HALDEBUG(ah, HAL_DEBUG_RESET, "%s: com2=0x%08x\n", __func__, value)
1703     }
1704 #endif  /* ATH_ANT_DIV_COMB */
1705     OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
1706
1707 #define AR_SWITCH_TABLE_ALL (0xfff)
1708 #define AR_SWITCH_TABLE_ALL_S (0)
1709     value = ar9300_ant_ctrl_chain_get(ah, 0, is_2ghz);
1710     OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
1711
1712     if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah) && !AR_SREV_APHRODITE(ah)) {
1713         value = ar9300_ant_ctrl_chain_get(ah, 1, is_2ghz);
1714         OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value);
1715
1716         if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
1717             value = ar9300_ant_ctrl_chain_get(ah, 2, is_2ghz);
1718             OS_REG_RMW_FIELD(ah,
1719                 AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value);
1720         }
1721     }
1722     if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
1723         value = ar9300_eeprom_get(ahp, EEP_ANTDIV_control);
1724         /* main_lnaconf, alt_lnaconf, main_tb, alt_tb */
1725         regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
1726         regval &= (~ANT_DIV_CONTROL_ALL); /* clear bit 25~30 */     
1727         regval |= (value & 0x3f) << ANT_DIV_CONTROL_ALL_S; 
1728         /* enable_lnadiv */
1729         regval &= (~MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__MASK);
1730         regval |= ((value >> 6) & 0x1) << 
1731                   MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__SHIFT; 
1732 #if ATH_ANT_DIV_COMB
1733         if ( AR_SREV_POSEIDON(ah) && (ahp->ah_lna_div_use_bt_ant_enable == TRUE) ) {
1734             regval |= ANT_DIV_ENABLE;
1735         }
1736 #endif  /* ATH_ANT_DIV_COMB */
1737         OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
1738         
1739         /* enable fast_div */
1740         regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
1741         regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK);
1742         regval |= ((value >> 7) & 0x1) << 
1743                   BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__SHIFT;
1744 #if ATH_ANT_DIV_COMB
1745         if ( AR_SREV_POSEIDON(ah) && (ahp->ah_lna_div_use_bt_ant_enable == TRUE) ) {
1746             regval |= FAST_DIV_ENABLE;
1747         }
1748 #endif  /* ATH_ANT_DIV_COMB */
1749         OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);        
1750     }
1751
1752 #if ATH_ANT_DIV_COMB    
1753     if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON_11_OR_LATER(ah)) {
1754         if (pcap->halAntDivCombSupport) {
1755             /* If support DivComb, set MAIN to LNA1, ALT to LNA2 at beginning */
1756             regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
1757             /* clear bit 25~30 main_lnaconf, alt_lnaconf, main_tb, alt_tb */
1758             regval &= (~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK | 
1759                          MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK | 
1760                          MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK | 
1761                          MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK)); 
1762             regval |= (HAL_ANT_DIV_COMB_LNA1 << 
1763                        MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT); 
1764             regval |= (HAL_ANT_DIV_COMB_LNA2 << 
1765                        MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT); 
1766             OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
1767         }
1768
1769     }
1770 #endif /* ATH_ANT_DIV_COMB */
1771     if (AR_SREV_POSEIDON(ah) && ( ahp->ah_diversity_control == HAL_ANT_FIXED_A 
1772              || ahp->ah_diversity_control == HAL_ANT_FIXED_B))
1773     {
1774         u_int32_t reg_val = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
1775         reg_val &=  ~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK | 
1776                     MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK |
1777                     MULTICHAIN_GAIN_CTRL__ANT_FAST_DIV_BIAS__MASK |
1778                         MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK |
1779                         MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK );
1780
1781         switch (ahp->ah_diversity_control) {
1782         case HAL_ANT_FIXED_A:
1783             /* Enable first antenna only */
1784             reg_val |= (HAL_ANT_DIV_COMB_LNA1 << 
1785                        MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT); 
1786             reg_val |= (HAL_ANT_DIV_COMB_LNA2 << 
1787                        MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT); 
1788             /* main/alt gain table and Fast Div Bias all set to 0 */
1789             OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, reg_val);
1790             regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
1791             regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK);
1792             OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);        
1793             break;
1794         case HAL_ANT_FIXED_B:
1795             /* Enable second antenna only, after checking capability */
1796             reg_val |= (HAL_ANT_DIV_COMB_LNA2 << 
1797                        MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT); 
1798             reg_val |= (HAL_ANT_DIV_COMB_LNA1 << 
1799                        MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT); 
1800             /* main/alt gain table and Fast Div all set to 0 */
1801             OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, reg_val);
1802             regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
1803             regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK);
1804             OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);        
1805             /* For WB225, need to swith ANT2 from BT to Wifi
1806              * This will not affect HB125 LNA diversity feature.
1807              */
1808              HALDEBUG(ah, HAL_DEBUG_RESET, "%s: com2=0x%08x\n", __func__,
1809                  ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable)
1810             OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, 
1811                 ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable);
1812             break;
1813         default:
1814             break;
1815         }
1816     }    
1817     return 0;
1818 }
1819
1820 static u_int16_t
1821 ar9300_attenuation_chain_get(struct ath_hal *ah, int chain, u_int16_t channel)
1822 {
1823     int32_t f[3], t[3];
1824     u_int16_t value;
1825     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1826     if (chain >= 0 && chain < OSPREY_MAX_CHAINS) {
1827         if (channel < 4000) {
1828             return eep->modal_header_2g.xatten1_db[chain];
1829         } else {
1830             if (eep->base_ext2.xatten1_db_low[chain] != 0) {        
1831                 t[0] = eep->base_ext2.xatten1_db_low[chain];
1832                 f[0] = 5180;
1833                 t[1] = eep->modal_header_5g.xatten1_db[chain];
1834                 f[1] = 5500;
1835                 t[2] = eep->base_ext2.xatten1_db_high[chain];
1836                 f[2] = 5785;
1837                 value = interpolate(channel, f, t, 3);
1838                 return value;
1839             } else {
1840                 return eep->modal_header_5g.xatten1_db[chain];
1841             }
1842         }
1843     }
1844     return 0;
1845 }
1846
1847 static u_int16_t
1848 ar9300_attenuation_margin_chain_get(struct ath_hal *ah, int chain,
1849     u_int16_t channel)
1850 {
1851     int32_t f[3], t[3];
1852     u_int16_t value;
1853     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1854     if (chain >= 0 && chain < OSPREY_MAX_CHAINS) {
1855         if (channel < 4000) {
1856             return eep->modal_header_2g.xatten1_margin[chain];
1857         } else {
1858             if (eep->base_ext2.xatten1_margin_low[chain] != 0) {    
1859                 t[0] = eep->base_ext2.xatten1_margin_low[chain];
1860                 f[0] = 5180;
1861                 t[1] = eep->modal_header_5g.xatten1_margin[chain];
1862                 f[1] = 5500;
1863                 t[2] = eep->base_ext2.xatten1_margin_high[chain];
1864                 f[2] = 5785;
1865                 value = interpolate(channel, f, t, 3);
1866                 return value;
1867             } else {
1868                 return eep->modal_header_5g.xatten1_margin[chain];
1869             }
1870         }
1871     }
1872     return 0;
1873 }
1874
1875 #if 0
1876 HAL_BOOL ar9300_attenuation_apply(struct ath_hal *ah, u_int16_t channel)
1877 {
1878     u_int32_t value;
1879 //    struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
1880
1881     /* Test value. if 0 then attenuation is unused. Don't load anything. */
1882     value = ar9300_attenuation_chain_get(ah, 0, channel);
1883     OS_REG_RMW_FIELD(ah,
1884         AR_PHY_EXT_ATTEN_CTL_0, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
1885     value = ar9300_attenuation_margin_chain_get(ah, 0, channel);
1886     if (ar9300_rx_gain_index_get(ah) == 0
1887         && ah->ah_config.ath_hal_ext_atten_margin_cfg)
1888     {
1889         value = 5;
1890     }
1891     OS_REG_RMW_FIELD(ah,
1892         AR_PHY_EXT_ATTEN_CTL_0, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value);
1893
1894     if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) {
1895         value = ar9300_attenuation_chain_get(ah, 1, channel);
1896         OS_REG_RMW_FIELD(ah,
1897             AR_PHY_EXT_ATTEN_CTL_1, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
1898         value = ar9300_attenuation_margin_chain_get(ah, 1, channel);
1899         OS_REG_RMW_FIELD(ah,
1900             AR_PHY_EXT_ATTEN_CTL_1, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
1901             value);
1902         if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
1903             value = ar9300_attenuation_chain_get(ah, 2, channel);
1904             OS_REG_RMW_FIELD(ah,
1905                 AR_PHY_EXT_ATTEN_CTL_2, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
1906             value = ar9300_attenuation_margin_chain_get(ah, 2, channel);
1907             OS_REG_RMW_FIELD(ah,
1908                 AR_PHY_EXT_ATTEN_CTL_2, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
1909                 value);
1910         }
1911     }
1912     return 0;
1913 }
1914 #endif
1915 HAL_BOOL
1916 ar9300_attenuation_apply(struct ath_hal *ah, u_int16_t channel)
1917 {
1918         int i;
1919         uint32_t value;
1920         uint32_t ext_atten_reg[3] = {
1921             AR_PHY_EXT_ATTEN_CTL_0,
1922             AR_PHY_EXT_ATTEN_CTL_1,
1923             AR_PHY_EXT_ATTEN_CTL_2
1924         };
1925
1926         /*
1927          * If it's an AR9462 and we're receiving on the second
1928          * chain only, set the chain 0 details from chain 1
1929          * calibration.
1930          *
1931          * This is from ath9k.
1932          */
1933         if (AR_SREV_JUPITER(ah) && (AH9300(ah)->ah_rx_chainmask == 0x2)) {
1934                 value = ar9300_attenuation_chain_get(ah, 1, channel);
1935                 OS_REG_RMW_FIELD(ah, ext_atten_reg[0],
1936                     AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
1937                 value = ar9300_attenuation_margin_chain_get(ah, 1, channel);
1938                 OS_REG_RMW_FIELD(ah, ext_atten_reg[0],
1939                     AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value);
1940         }
1941
1942         /*
1943          * Now, loop over the configured transmit chains and
1944          * load in the attenuation/margin settings as appropriate.
1945          */
1946         for (i = 0; i < 3; i++) {
1947                 if ((AH9300(ah)->ah_tx_chainmask & (1 << i)) == 0)
1948                         continue;
1949
1950                 value = ar9300_attenuation_chain_get(ah, i, channel);
1951                 OS_REG_RMW_FIELD(ah, ext_atten_reg[i],
1952                     AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB,
1953                     value);
1954
1955                 if (AR_SREV_POSEIDON(ah) &&
1956                     (ar9300_rx_gain_index_get(ah) == 0) &&
1957                     ah->ah_config.ath_hal_ext_atten_margin_cfg) {
1958                         value = 5;
1959                 } else {
1960                         value = ar9300_attenuation_margin_chain_get(ah, 0,
1961                             channel);
1962                 }
1963
1964                 /*
1965                  * I'm not sure why it's loading in this setting into
1966                  * the chain 0 margin regardless of the current chain.
1967                  */
1968                 if (ah->ah_config.ath_hal_min_gainidx)
1969                         OS_REG_RMW_FIELD(ah,
1970                             AR_PHY_EXT_ATTEN_CTL_0,
1971                             AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
1972                             value);
1973
1974                 OS_REG_RMW_FIELD(ah,
1975                     ext_atten_reg[i],
1976                     AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
1977                     value);
1978         }
1979
1980         return (0);
1981 }
1982
1983
1984 static u_int16_t ar9300_quick_drop_get(struct ath_hal *ah, 
1985                                                                 int chain, u_int16_t channel)
1986 {
1987     int32_t f[3], t[3];
1988     u_int16_t value;
1989     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
1990
1991     if (channel < 4000) {
1992         return eep->modal_header_2g.quick_drop;
1993     } else {
1994         t[0] = eep->base_ext1.quick_drop_low;
1995         f[0] = 5180;
1996         t[1] = eep->modal_header_5g.quick_drop;
1997         f[1] = 5500;
1998         t[2] = eep->base_ext1.quick_drop_high;
1999         f[2] = 5785;
2000         value = interpolate(channel, f, t, 3);
2001         return value;
2002     }
2003 }
2004
2005
2006 static HAL_BOOL ar9300_quick_drop_apply(struct ath_hal *ah, u_int16_t channel)
2007 {
2008     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
2009     u_int32_t value;
2010     //
2011     // Test value. if 0 then quickDrop is unused. Don't load anything.
2012     //
2013     if (eep->base_eep_header.misc_configuration & 0x10)
2014         {
2015         if (AR_SREV_OSPREY(ah) || AR_SREV_AR9580(ah) || AR_SREV_WASP(ah)) 
2016         {
2017             value = ar9300_quick_drop_get(ah, 0, channel);
2018             OS_REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, value);
2019         }
2020     }
2021     return 0;
2022 }
2023
2024 static u_int16_t ar9300_tx_end_to_xpa_off_get(struct ath_hal *ah, u_int16_t channel)
2025 {
2026     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
2027
2028     if (channel < 4000) {
2029         return eep->modal_header_2g.tx_end_to_xpa_off;
2030     } else {
2031         return eep->modal_header_5g.tx_end_to_xpa_off;
2032     }
2033 }
2034
2035 static HAL_BOOL ar9300_tx_end_to_xpab_off_apply(struct ath_hal *ah, u_int16_t channel)
2036 {
2037     u_int32_t value;
2038
2039     value = ar9300_tx_end_to_xpa_off_get(ah, channel);
2040     /* Apply to both xpaa and xpab */
2041     if (AR_SREV_OSPREY(ah) || AR_SREV_AR9580(ah) || AR_SREV_WASP(ah)) 
2042     {
2043         OS_REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, 
2044             AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
2045         OS_REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, 
2046             AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
2047     }
2048     return 0;
2049 }
2050
2051 static int
2052 ar9300_eeprom_cal_pier_get(struct ath_hal *ah, int mode, int ipier, int ichain, 
2053     int *pfrequency, int *pcorrection, int *ptemperature, int *pvoltage)
2054 {
2055     u_int8_t *p_cal_pier;
2056     OSP_CAL_DATA_PER_FREQ_OP_LOOP *p_cal_pier_struct;
2057     int is_2ghz;
2058     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
2059
2060     if (ichain >= OSPREY_MAX_CHAINS) {
2061         HALDEBUG(ah, HAL_DEBUG_EEPROM,
2062             "%s: Invalid chain index, must be less than %d\n",
2063             __func__, OSPREY_MAX_CHAINS);
2064         return -1;
2065     }
2066
2067     if (mode) {/* 5GHz */
2068         if (ipier >= OSPREY_NUM_5G_CAL_PIERS){
2069             HALDEBUG(ah, HAL_DEBUG_EEPROM,
2070                 "%s: Invalid 5GHz cal pier index, must be less than %d\n",
2071                 __func__, OSPREY_NUM_5G_CAL_PIERS);
2072             return -1;
2073         }
2074         p_cal_pier = &(eep->cal_freq_pier_5g[ipier]);
2075         p_cal_pier_struct = &(eep->cal_pier_data_5g[ichain][ipier]);
2076         is_2ghz = 0;
2077     } else {
2078         if (ipier >= OSPREY_NUM_2G_CAL_PIERS){
2079             HALDEBUG(ah, HAL_DEBUG_EEPROM,
2080                 "%s: Invalid 2GHz cal pier index, must be less than %d\n",
2081                 __func__, OSPREY_NUM_2G_CAL_PIERS);
2082             return -1;
2083         }
2084
2085         p_cal_pier = &(eep->cal_freq_pier_2g[ipier]);
2086         p_cal_pier_struct = &(eep->cal_pier_data_2g[ichain][ipier]);
2087         is_2ghz = 1;
2088     }
2089     *pfrequency = FBIN2FREQ(*p_cal_pier, is_2ghz);
2090     *pcorrection = p_cal_pier_struct->ref_power;
2091     *ptemperature = p_cal_pier_struct->temp_meas;
2092     *pvoltage = p_cal_pier_struct->volt_meas;
2093     return 0;
2094 }
2095
2096 /*
2097  * Apply the recorded correction values.
2098  */
2099 static int
2100 ar9300_calibration_apply(struct ath_hal *ah, int frequency)
2101 {
2102     struct ath_hal_9300 *ahp = AH9300(ah);
2103
2104     int ichain, ipier, npier;
2105     int mode;
2106     int fdiff;
2107     int pfrequency, pcorrection, ptemperature, pvoltage; 
2108     int bf, factor, plus;
2109
2110     int lfrequency[AR9300_MAX_CHAINS];
2111     int hfrequency[AR9300_MAX_CHAINS];
2112
2113     int lcorrection[AR9300_MAX_CHAINS];
2114     int hcorrection[AR9300_MAX_CHAINS];
2115     int correction[AR9300_MAX_CHAINS];
2116
2117     int ltemperature[AR9300_MAX_CHAINS];
2118     int htemperature[AR9300_MAX_CHAINS];
2119     int temperature[AR9300_MAX_CHAINS];
2120
2121     int lvoltage[AR9300_MAX_CHAINS];
2122     int hvoltage[AR9300_MAX_CHAINS];
2123     int voltage[AR9300_MAX_CHAINS];
2124
2125     mode = (frequency >= 4000);
2126     npier = (mode) ?  OSPREY_NUM_5G_CAL_PIERS : OSPREY_NUM_2G_CAL_PIERS;
2127
2128     for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
2129         lfrequency[ichain] = 0;
2130         hfrequency[ichain] = 100000;
2131     }
2132     /*
2133      * identify best lower and higher frequency calibration measurement
2134      */
2135     for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
2136         for (ipier = 0; ipier < npier; ipier++) {
2137             if (ar9300_eeprom_cal_pier_get(
2138                     ah, mode, ipier, ichain,
2139                     &pfrequency, &pcorrection, &ptemperature, &pvoltage) == 0)
2140             {
2141                 fdiff = frequency - pfrequency;
2142                 /*
2143                  * this measurement is higher than our desired frequency
2144                  */
2145                 if (fdiff <= 0) {
2146                     if (hfrequency[ichain] <= 0 ||
2147                         hfrequency[ichain] >= 100000 ||
2148                         fdiff > (frequency - hfrequency[ichain]))
2149                     {
2150                         /*
2151                          * new best higher frequency measurement
2152                          */
2153                         hfrequency[ichain] = pfrequency;
2154                         hcorrection[ichain] = pcorrection;
2155                         htemperature[ichain] = ptemperature;
2156                         hvoltage[ichain] = pvoltage;
2157                     }
2158                 }
2159                 if (fdiff >= 0) {
2160                     if (lfrequency[ichain] <= 0 ||
2161                         fdiff < (frequency - lfrequency[ichain]))
2162                     {
2163                         /*
2164                          * new best lower frequency measurement
2165                          */
2166                         lfrequency[ichain] = pfrequency;
2167                         lcorrection[ichain] = pcorrection;
2168                         ltemperature[ichain] = ptemperature;
2169                         lvoltage[ichain] = pvoltage;
2170                     }
2171                 }
2172             }
2173         }
2174     }
2175     /* interpolate */
2176     for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
2177         HALDEBUG(ah, HAL_DEBUG_EEPROM,
2178             "%s: ch=%d f=%d low=%d %d h=%d %d\n",
2179             __func__, ichain, frequency,
2180             lfrequency[ichain], lcorrection[ichain],
2181             hfrequency[ichain], hcorrection[ichain]);
2182         /*
2183          * they're the same, so just pick one
2184          */ 
2185         if (hfrequency[ichain] == lfrequency[ichain]) {
2186             correction[ichain] = lcorrection[ichain];
2187             voltage[ichain] = lvoltage[ichain];
2188             temperature[ichain] = ltemperature[ichain];
2189         } else if (frequency - lfrequency[ichain] < 1000) {
2190             /* the low frequency is good */
2191             if (hfrequency[ichain] - frequency < 1000) {
2192                 /*
2193                  * The high frequency is good too -
2194                  * interpolate with round off.
2195                  */
2196                 int mult, div, diff;
2197                 mult = frequency - lfrequency[ichain];
2198                 div = hfrequency[ichain] - lfrequency[ichain];
2199
2200                 diff = hcorrection[ichain] - lcorrection[ichain];
2201                 bf = 2 * diff * mult / div;
2202                 plus = (bf % 2);
2203                 factor = bf / 2;
2204                 correction[ichain] = lcorrection[ichain] + factor + plus;
2205
2206                 diff = htemperature[ichain] - ltemperature[ichain];
2207                 bf = 2 * diff * mult / div;
2208                 plus = (bf % 2);
2209                 factor = bf / 2;
2210                 temperature[ichain] = ltemperature[ichain] + factor + plus;
2211
2212                 diff = hvoltage[ichain] - lvoltage[ichain];
2213                 bf = 2 * diff * mult / div;
2214                 plus = (bf % 2);
2215                 factor = bf / 2;
2216                 voltage[ichain] = lvoltage[ichain] + factor + plus;
2217             } else {
2218                 /* only low is good, use it */
2219                 correction[ichain] = lcorrection[ichain];
2220                 temperature[ichain] = ltemperature[ichain];
2221                 voltage[ichain] = lvoltage[ichain];
2222             }
2223         } else if (hfrequency[ichain] - frequency < 1000) {
2224             /* only high is good, use it */
2225             correction[ichain] = hcorrection[ichain];
2226             temperature[ichain] = htemperature[ichain];
2227             voltage[ichain] = hvoltage[ichain];
2228         } else {
2229             /* nothing is good, presume 0???? */
2230             correction[ichain] = 0;
2231             temperature[ichain] = 0;
2232             voltage[ichain] = 0;
2233         }
2234     }
2235
2236     /* GreenTx isn't currently supported */
2237     /* GreenTx */
2238     if (ah->ah_config.ath_hal_sta_update_tx_pwr_enable) {
2239         if (AR_SREV_POSEIDON(ah)) {
2240             /* Get calibrated OLPC gain delta value for GreenTx */
2241             ahp->ah_db2[POSEIDON_STORED_REG_G2_OLPC_OFFSET] = 
2242                 (u_int32_t) correction[0];
2243         }
2244     }
2245
2246     ar9300_power_control_override(
2247         ah, frequency, correction, voltage, temperature);
2248     HALDEBUG(ah, HAL_DEBUG_EEPROM,
2249         "%s: for frequency=%d, calibration correction = %d %d %d\n",
2250          __func__, frequency, correction[0], correction[1], correction[2]);
2251
2252     return 0;
2253 }
2254
2255 int
2256 ar9300_power_control_override(struct ath_hal *ah, int frequency,
2257     int *correction, int *voltage, int *temperature)
2258 {
2259     int temp_slope = 0;
2260     int temp_slope_1 = 0;
2261     int temp_slope_2 = 0;
2262     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
2263     int32_t f[8], t[8],t1[3], t2[3];
2264         int i;
2265
2266     OS_REG_RMW(ah, AR_PHY_TPC_11_B0,
2267         (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
2268         AR_PHY_TPC_OLPC_GAIN_DELTA);
2269     if (!AR_SREV_POSEIDON(ah)) {
2270         OS_REG_RMW(ah, AR_PHY_TPC_11_B1,
2271             (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
2272             AR_PHY_TPC_OLPC_GAIN_DELTA);
2273         if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
2274             OS_REG_RMW(ah, AR_PHY_TPC_11_B2, 
2275                 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
2276                 AR_PHY_TPC_OLPC_GAIN_DELTA);
2277         }
2278     }
2279     /*
2280      * enable open loop power control on chip
2281      */
2282     OS_REG_RMW(ah, AR_PHY_TPC_6_B0,
2283         (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), AR_PHY_TPC_6_ERROR_EST_MODE);
2284     if (!AR_SREV_POSEIDON(ah)) {
2285         OS_REG_RMW(ah, AR_PHY_TPC_6_B1, 
2286             (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), AR_PHY_TPC_6_ERROR_EST_MODE);
2287         if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
2288             OS_REG_RMW(ah, AR_PHY_TPC_6_B2, 
2289                 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
2290                 AR_PHY_TPC_6_ERROR_EST_MODE);
2291         }
2292     }
2293
2294     /*
2295      * Enable temperature compensation
2296      * Need to use register names
2297      */
2298     if (frequency < 4000) {
2299         temp_slope = eep->modal_header_2g.temp_slope;
2300     } else {
2301                 if ((eep->base_eep_header.misc_configuration & 0x20) != 0)
2302                 {
2303                                 for(i=0;i<8;i++)
2304                                 {
2305                                         t[i]=eep->base_ext1.tempslopextension[i];
2306                                         f[i]=FBIN2FREQ(eep->cal_freq_pier_5g[i], 0);
2307                                 }
2308                                 temp_slope=interpolate(frequency,f,t,8);
2309                 }
2310                 else
2311                 {
2312         if(!AR_SREV_SCORPION(ah)) {
2313           if (eep->base_ext2.temp_slope_low != 0) {
2314              t[0] = eep->base_ext2.temp_slope_low;
2315              f[0] = 5180;
2316              t[1] = eep->modal_header_5g.temp_slope;
2317              f[1] = 5500;
2318              t[2] = eep->base_ext2.temp_slope_high;
2319              f[2] = 5785;
2320              temp_slope = interpolate(frequency, f, t, 3);
2321            } else {
2322              temp_slope = eep->modal_header_5g.temp_slope;
2323            }
2324          } else {
2325             /*
2326              * Scorpion has individual chain tempslope values
2327              */
2328              t[0] = eep->base_ext1.tempslopextension[2];
2329              t1[0]= eep->base_ext1.tempslopextension[3];
2330              t2[0]= eep->base_ext1.tempslopextension[4];
2331              f[0] = 5180;
2332              t[1] = eep->modal_header_5g.temp_slope;
2333              t1[1]= eep->base_ext1.tempslopextension[0];
2334              t2[1]= eep->base_ext1.tempslopextension[1];
2335              f[1] = 5500;
2336              t[2] = eep->base_ext1.tempslopextension[5];
2337              t1[2]= eep->base_ext1.tempslopextension[6];
2338              t2[2]= eep->base_ext1.tempslopextension[7];
2339              f[2] = 5785;
2340              temp_slope = interpolate(frequency, f, t, 3);
2341              temp_slope_1=interpolate(frequency, f, t1,3);
2342              temp_slope_2=interpolate(frequency, f, t2,3);
2343        } 
2344          }
2345   }
2346
2347     if (!AR_SREV_SCORPION(ah)) {
2348         OS_REG_RMW_FIELD(ah,
2349             AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, temp_slope);
2350     } else {
2351         /*Scorpion has tempSlope register for each chain*/
2352         /*Check whether temp_compensation feature is enabled or not*/
2353         if (eep->base_eep_header.feature_enable & 0x1){
2354             if(frequency < 4000) {
2355                     OS_REG_RMW_FIELD(ah,
2356                                     AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, 
2357                                     eep->base_ext2.temp_slope_low);
2358                     OS_REG_RMW_FIELD(ah,
2359                                     AR_SCORPION_PHY_TPC_19_B1, AR_PHY_TPC_19_ALPHA_THERM, 
2360                                     temp_slope);
2361                     OS_REG_RMW_FIELD(ah,
2362                                     AR_SCORPION_PHY_TPC_19_B2, AR_PHY_TPC_19_ALPHA_THERM, 
2363                                     eep->base_ext2.temp_slope_high);
2364             } else {
2365                     OS_REG_RMW_FIELD(ah,
2366                                     AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, 
2367                                     temp_slope);
2368                     OS_REG_RMW_FIELD(ah,
2369                                     AR_SCORPION_PHY_TPC_19_B1, AR_PHY_TPC_19_ALPHA_THERM, 
2370                                     temp_slope_1);
2371                     OS_REG_RMW_FIELD(ah,
2372                                     AR_SCORPION_PHY_TPC_19_B2, AR_PHY_TPC_19_ALPHA_THERM, 
2373                                     temp_slope_2);
2374             }
2375         }else {
2376                 /* If temp compensation is not enabled, set all registers to 0*/
2377             OS_REG_RMW_FIELD(ah,
2378                 AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, 0);
2379             OS_REG_RMW_FIELD(ah,
2380                 AR_SCORPION_PHY_TPC_19_B1, AR_PHY_TPC_19_ALPHA_THERM, 0);
2381             OS_REG_RMW_FIELD(ah,
2382                 AR_SCORPION_PHY_TPC_19_B2, AR_PHY_TPC_19_ALPHA_THERM, 0);
2383         }
2384     }
2385     OS_REG_RMW_FIELD(ah,
2386         AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE, temperature[0]);
2387
2388     return 0;
2389 }
2390
2391 /**************************************************************
2392  * ar9300_eep_def_get_max_edge_power
2393  *
2394  * Find the maximum conformance test limit for the given channel and CTL info
2395  */
2396 static inline u_int16_t
2397 ar9300_eep_def_get_max_edge_power(ar9300_eeprom_t *p_eep_data, u_int16_t freq,
2398     int idx, HAL_BOOL is_2ghz)
2399 {
2400     u_int16_t twice_max_edge_power = AR9300_MAX_RATE_POWER;
2401     u_int8_t *ctl_freqbin = is_2ghz ?
2402         &p_eep_data->ctl_freqbin_2G[idx][0] :
2403         &p_eep_data->ctl_freqbin_5G[idx][0];
2404     u_int16_t num_edges = is_2ghz ?
2405         OSPREY_NUM_BAND_EDGES_2G : OSPREY_NUM_BAND_EDGES_5G;
2406     int i;
2407
2408     /* Get the edge power */
2409     for (i = 0; (i < num_edges) && (ctl_freqbin[i] != AR9300_BCHAN_UNUSED); i++)
2410     {
2411         /*
2412          * If there's an exact channel match or an inband flag set
2413          * on the lower channel use the given rd_edge_power
2414          */
2415         if (freq == fbin2freq(ctl_freqbin[i], is_2ghz)) {
2416             if (is_2ghz) {
2417                 twice_max_edge_power =
2418                     p_eep_data->ctl_power_data_2g[idx].ctl_edges[i].t_power;
2419             } else {       
2420                 twice_max_edge_power =
2421                     p_eep_data->ctl_power_data_5g[idx].ctl_edges[i].t_power;
2422             }
2423             break;
2424         } else if ((i > 0) && (freq < fbin2freq(ctl_freqbin[i], is_2ghz))) {
2425             if (is_2ghz) {
2426                 if (fbin2freq(ctl_freqbin[i - 1], 1) < freq &&
2427                     p_eep_data->ctl_power_data_2g[idx].ctl_edges[i - 1].flag)
2428                 {
2429                     twice_max_edge_power =
2430                         p_eep_data->ctl_power_data_2g[idx].
2431                             ctl_edges[i - 1].t_power;
2432                 }
2433             } else {
2434                 if (fbin2freq(ctl_freqbin[i - 1], 0) < freq &&
2435                     p_eep_data->ctl_power_data_5g[idx].ctl_edges[i - 1].flag)
2436                 {
2437                     twice_max_edge_power =
2438                         p_eep_data->ctl_power_data_5g[idx].
2439                             ctl_edges[i - 1].t_power;
2440                 }
2441             }
2442             /*
2443              * Leave loop - no more affecting edges possible
2444              * in this monotonic increasing list
2445              */
2446             break;
2447         }
2448     }
2449     /*
2450      * EV89475: EEPROM might contain 0 txpower in CTL table for certain
2451      * 2.4GHz channels. We workaround it by overwriting 60 (30 dBm) here.
2452      */
2453     if (is_2ghz && (twice_max_edge_power == 0)) {
2454         twice_max_edge_power = 60;
2455     }
2456
2457     HALASSERT(twice_max_edge_power > 0);
2458     return twice_max_edge_power;
2459 }
2460
2461 HAL_BOOL
2462 ar9300_eeprom_set_power_per_rate_table(
2463     struct ath_hal *ah,
2464     ar9300_eeprom_t *p_eep_data,
2465     const struct ieee80211_channel *chan,
2466     u_int8_t *p_pwr_array,
2467     u_int16_t cfg_ctl,
2468     u_int16_t antenna_reduction,
2469     u_int16_t twice_max_regulatory_power,
2470     u_int16_t power_limit,
2471     u_int8_t chainmask)
2472 {
2473     /* Local defines to distinguish between extension and control CTL's */
2474 #define EXT_ADDITIVE (0x8000)
2475 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
2476 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
2477 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
2478 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
2479 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN  10  /* 10*log10(3)*2 */
2480 #define PWRINCR_3_TO_1_CHAIN      9             /* 10*log(3)*2 */
2481 #define PWRINCR_3_TO_2_CHAIN      3             /* floor(10*log(3/2)*2) */
2482 #define PWRINCR_2_TO_1_CHAIN      6             /* 10*log(2)*2 */
2483
2484     static const u_int16_t tp_scale_reduction_table[5] =
2485         { 0, 3, 6, 9, AR9300_MAX_RATE_POWER };
2486     int i;
2487     int16_t twice_largest_antenna;
2488     u_int16_t twice_antenna_reduction = 2*antenna_reduction ;
2489     int16_t scaled_power = 0, min_ctl_power, max_reg_allowed_power;
2490 #define SUB_NUM_CTL_MODES_AT_5G_40 2    /* excluding HT40, EXT-OFDM */
2491 #define SUB_NUM_CTL_MODES_AT_2G_40 3    /* excluding HT40, EXT-OFDM, EXT-CCK */
2492     u_int16_t ctl_modes_for11a[] =
2493         {CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40};
2494     u_int16_t ctl_modes_for11g[] =
2495         {CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40};
2496     u_int16_t num_ctl_modes, *p_ctl_mode, ctl_mode, freq;
2497     CHAN_CENTERS centers;
2498     int tx_chainmask;
2499     struct ath_hal_9300 *ahp = AH9300(ah);
2500     u_int8_t *ctl_index;
2501     u_int8_t ctl_num;
2502     u_int16_t twice_min_edge_power;
2503     u_int16_t twice_max_edge_power = AR9300_MAX_RATE_POWER;
2504 #ifdef  AH_DEBUG
2505     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
2506 #endif
2507
2508     if (chainmask)
2509         tx_chainmask = chainmask;
2510     else
2511         tx_chainmask = ahp->ah_tx_chainmaskopt ?
2512                             ahp->ah_tx_chainmaskopt :ahp->ah_tx_chainmask;
2513
2514     ar9300_get_channel_centers(ah, chan, &centers);
2515
2516 #if 1
2517     if (IEEE80211_IS_CHAN_2GHZ(chan)) {
2518         ahp->twice_antenna_gain = p_eep_data->modal_header_2g.antenna_gain;
2519     } else {
2520         ahp->twice_antenna_gain = p_eep_data->modal_header_5g.antenna_gain;
2521     }
2522
2523 #else
2524     if (IEEE80211_IS_CHAN_2GHZ(chan)) {
2525         ahp->twice_antenna_gain = AH_MAX(p_eep_data->modal_header_2g.antenna_gain,
2526                                          AH_PRIVATE(ah)->ah_antenna_gain_2g);
2527     } else {
2528         ahp->twice_antenna_gain = AH_MAX(p_eep_data->modal_header_5g.antenna_gain,
2529                                          AH_PRIVATE(ah)->ah_antenna_gain_5g);
2530     }
2531 #endif
2532
2533     /* Save max allowed antenna gain to ease future lookups */
2534     ahp->twice_antenna_reduction = twice_antenna_reduction; 
2535
2536     /*  Deduct antenna gain from  EIRP to get the upper limit */
2537     twice_largest_antenna = (int16_t)AH_MIN((twice_antenna_reduction -
2538                                        ahp->twice_antenna_gain), 0);
2539     max_reg_allowed_power = twice_max_regulatory_power + twice_largest_antenna;
2540
2541     /* Use ah_tp_scale - see bug 30070. */
2542     if (AH_PRIVATE(ah)->ah_tpScale != HAL_TP_SCALE_MAX) { 
2543         max_reg_allowed_power -=
2544             (tp_scale_reduction_table[(AH_PRIVATE(ah)->ah_tpScale)] * 2);
2545     }
2546
2547     scaled_power = AH_MIN(power_limit, max_reg_allowed_power);
2548
2549     /*
2550      * Reduce scaled Power by number of chains active to get to
2551      * per chain tx power level
2552      */
2553     /* TODO: better value than these? */
2554     switch (ar9300_get_ntxchains(tx_chainmask)) {
2555     case 1:
2556         ahp->upper_limit[0] = AH_MAX(0, scaled_power);
2557         break;
2558     case 2:
2559         scaled_power -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
2560         ahp->upper_limit[1] = AH_MAX(0, scaled_power);
2561         break;
2562     case 3:
2563         scaled_power -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
2564         ahp->upper_limit[2] = AH_MAX(0, scaled_power);
2565         break;
2566     default:
2567         HALASSERT(0); /* Unsupported number of chains */
2568     }
2569
2570     scaled_power = AH_MAX(0, scaled_power);
2571
2572     /* Get target powers from EEPROM - our baseline for TX Power */
2573     if (IEEE80211_IS_CHAN_2GHZ(chan)) {
2574         /* Setup for CTL modes */
2575         /* CTL_11B, CTL_11G, CTL_2GHT20 */
2576         num_ctl_modes =
2577             ARRAY_LENGTH(ctl_modes_for11g) - SUB_NUM_CTL_MODES_AT_2G_40;
2578         p_ctl_mode = ctl_modes_for11g;
2579
2580         if (IEEE80211_IS_CHAN_HT40(chan)) {
2581             num_ctl_modes = ARRAY_LENGTH(ctl_modes_for11g); /* All 2G CTL's */
2582         }
2583     } else {
2584         /* Setup for CTL modes */
2585         /* CTL_11A, CTL_5GHT20 */
2586         num_ctl_modes =
2587             ARRAY_LENGTH(ctl_modes_for11a) - SUB_NUM_CTL_MODES_AT_5G_40;
2588         p_ctl_mode = ctl_modes_for11a;
2589
2590         if (IEEE80211_IS_CHAN_HT40(chan)) {
2591             num_ctl_modes = ARRAY_LENGTH(ctl_modes_for11a); /* All 5G CTL's */
2592         }
2593     }
2594
2595     /*
2596      * For MIMO, need to apply regulatory caps individually across dynamically
2597      * running modes: CCK, OFDM, HT20, HT40
2598      *
2599      * The outer loop walks through each possible applicable runtime mode.
2600      * The inner loop walks through each ctl_index entry in EEPROM.
2601      * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
2602      *
2603      */
2604     for (ctl_mode = 0; ctl_mode < num_ctl_modes; ctl_mode++) {
2605         HAL_BOOL is_ht40_ctl_mode =
2606             (p_ctl_mode[ctl_mode] == CTL_5GHT40) ||
2607             (p_ctl_mode[ctl_mode] == CTL_2GHT40);
2608         if (is_ht40_ctl_mode) {
2609             freq = centers.synth_center;
2610         } else if (p_ctl_mode[ctl_mode] & EXT_ADDITIVE) {
2611             freq = centers.ext_center;
2612         } else {
2613             freq = centers.ctl_center;
2614         }
2615
2616         HALDEBUG(ah, HAL_DEBUG_POWER_MGMT,
2617             "LOOP-Mode ctl_mode %d < %d, "
2618             "is_ht40_ctl_mode %d, EXT_ADDITIVE %d\n",
2619             ctl_mode, num_ctl_modes, is_ht40_ctl_mode,
2620             (p_ctl_mode[ctl_mode] & EXT_ADDITIVE));
2621         /* walk through each CTL index stored in EEPROM */
2622         if (IEEE80211_IS_CHAN_2GHZ(chan)) {
2623             ctl_index = p_eep_data->ctl_index_2g;
2624             ctl_num = OSPREY_NUM_CTLS_2G;
2625         } else {
2626             ctl_index = p_eep_data->ctl_index_5g;
2627             ctl_num = OSPREY_NUM_CTLS_5G;
2628         }
2629
2630         for (i = 0; (i < ctl_num) && ctl_index[i]; i++) {
2631             HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, 
2632                 "  LOOP-Ctlidx %d: cfg_ctl 0x%2.2x p_ctl_mode 0x%2.2x "
2633                 "ctl_index 0x%2.2x chan %d chanctl 0x%x\n",
2634                 i, cfg_ctl, p_ctl_mode[ctl_mode], ctl_index[i], 
2635                 ichan->channel, ath_hal_getctl(ah, chan));
2636
2637
2638             /* 
2639              * compare test group from regulatory channel list
2640              * with test mode from p_ctl_mode list
2641              */
2642             if ((((cfg_ctl & ~CTL_MODE_M) |
2643                   (p_ctl_mode[ctl_mode] & CTL_MODE_M)) == ctl_index[i]) ||
2644                 (((cfg_ctl & ~CTL_MODE_M) |
2645                   (p_ctl_mode[ctl_mode] & CTL_MODE_M)) ==
2646                  ((ctl_index[i] & CTL_MODE_M) | SD_NO_CTL)))
2647             {
2648                 twice_min_edge_power =
2649                     ar9300_eep_def_get_max_edge_power(
2650                         p_eep_data, freq, i, IEEE80211_IS_CHAN_2GHZ(chan));
2651
2652                 HALDEBUG(ah, HAL_DEBUG_POWER_MGMT,
2653                     "    MATCH-EE_IDX %d: ch %d is2 %d "
2654                     "2xMinEdge %d chainmask %d chains %d\n",
2655                     i, freq, IEEE80211_IS_CHAN_2GHZ(chan),
2656                     twice_min_edge_power, tx_chainmask,
2657                     ar9300_get_ntxchains(tx_chainmask));
2658
2659                 if ((cfg_ctl & ~CTL_MODE_M) == SD_NO_CTL) {
2660                     /*
2661                      * Find the minimum of all CTL edge powers
2662                      * that apply to this channel
2663                      */
2664                     twice_max_edge_power =
2665                         AH_MIN(twice_max_edge_power, twice_min_edge_power);
2666                 } else {
2667                     /* specific */
2668                     twice_max_edge_power = twice_min_edge_power;
2669                     break;
2670                 }
2671             }
2672         }
2673
2674         min_ctl_power = (u_int8_t)AH_MIN(twice_max_edge_power, scaled_power);
2675
2676         HALDEBUG(ah, HAL_DEBUG_POWER_MGMT,
2677             "    SEL-Min ctl_mode %d p_ctl_mode %d "
2678             "2xMaxEdge %d sP %d min_ctl_pwr %d\n",
2679             ctl_mode, p_ctl_mode[ctl_mode],
2680             twice_max_edge_power, scaled_power, min_ctl_power);
2681
2682         /* Apply ctl mode to correct target power set */
2683         switch (p_ctl_mode[ctl_mode]) {
2684         case CTL_11B:
2685             for (i = ALL_TARGET_LEGACY_1L_5L; i <= ALL_TARGET_LEGACY_11S; i++) {
2686                 p_pwr_array[i] =
2687                     (u_int8_t)AH_MIN(p_pwr_array[i], min_ctl_power);
2688             }
2689             break;
2690         case CTL_11A:
2691         case CTL_11G:
2692             for (i = ALL_TARGET_LEGACY_6_24; i <= ALL_TARGET_LEGACY_54; i++) {
2693                 p_pwr_array[i] =
2694                     (u_int8_t)AH_MIN(p_pwr_array[i], min_ctl_power);
2695 #ifdef ATH_BT_COEX
2696                 if ((ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_3WIRE) ||
2697                     (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI))
2698                 {
2699                     if ((ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_LOWER_TX_PWR)
2700                         && (ahp->ah_bt_wlan_isolation 
2701                          < HAL_BT_COEX_ISOLATION_FOR_NO_COEX))
2702                     {
2703
2704                         u_int8_t reduce_pow;
2705                         
2706                         reduce_pow = (HAL_BT_COEX_ISOLATION_FOR_NO_COEX 
2707                                      - ahp->ah_bt_wlan_isolation) << 1;
2708
2709                         if (reduce_pow <= p_pwr_array[i]) {
2710                             p_pwr_array[i] -= reduce_pow;
2711                         }
2712                     }
2713                     if ((ahp->ah_bt_coex_flag & 
2714                           HAL_BT_COEX_FLAG_LOW_ACK_PWR) &&
2715                           (i != ALL_TARGET_LEGACY_36) &&
2716                           (i != ALL_TARGET_LEGACY_48) &&
2717                           (i != ALL_TARGET_LEGACY_54) &&
2718                           (p_ctl_mode[ctl_mode] == CTL_11G))
2719                     {
2720                         p_pwr_array[i] = 0;
2721                     }
2722                 }
2723 #endif
2724             }
2725             break;
2726         case CTL_5GHT20:
2727         case CTL_2GHT20:
2728             for (i = ALL_TARGET_HT20_0_8_16; i <= ALL_TARGET_HT20_23; i++) {
2729                 p_pwr_array[i] =
2730                     (u_int8_t)AH_MIN(p_pwr_array[i], min_ctl_power);
2731 #ifdef ATH_BT_COEX
2732                 if (((ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_3WIRE) ||
2733                      (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI)) &&
2734                     (ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_LOWER_TX_PWR) && 
2735                     (ahp->ah_bt_wlan_isolation 
2736                         < HAL_BT_COEX_ISOLATION_FOR_NO_COEX)) {
2737
2738                     u_int8_t reduce_pow = (HAL_BT_COEX_ISOLATION_FOR_NO_COEX 
2739                                            - ahp->ah_bt_wlan_isolation) << 1;
2740
2741                     if (reduce_pow <= p_pwr_array[i]) {
2742                         p_pwr_array[i] -= reduce_pow;
2743                     }
2744                 }
2745 #if ATH_SUPPORT_MCI
2746                 else if ((ahp->ah_bt_coex_flag & 
2747                           HAL_BT_COEX_FLAG_MCI_MAX_TX_PWR) &&
2748                          (p_ctl_mode[ctl_mode] == CTL_2GHT20) &&
2749                          (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI))
2750                 {
2751                     u_int8_t max_pwr;
2752
2753                     max_pwr = MS(mci_concur_tx_max_pwr[2][1],
2754                                  ATH_MCI_CONCUR_TX_LOWEST_PWR_MASK);
2755                     if (p_pwr_array[i] > max_pwr) {
2756                         p_pwr_array[i] = max_pwr;
2757                     }
2758                 }
2759 #endif
2760 #endif
2761             }
2762             break;
2763         case CTL_11B_EXT:
2764 #ifdef NOT_YET
2765             target_power_cck_ext.t_pow2x[0] = (u_int8_t)
2766                 AH_MIN(target_power_cck_ext.t_pow2x[0], min_ctl_power);
2767 #endif /* NOT_YET */
2768             break;
2769         case CTL_11A_EXT:
2770         case CTL_11G_EXT:
2771 #ifdef NOT_YET
2772             target_power_ofdm_ext.t_pow2x[0] = (u_int8_t)
2773                 AH_MIN(target_power_ofdm_ext.t_pow2x[0], min_ctl_power);
2774 #endif /* NOT_YET */
2775             break;
2776         case CTL_5GHT40:
2777         case CTL_2GHT40:
2778             for (i = ALL_TARGET_HT40_0_8_16; i <= ALL_TARGET_HT40_23; i++) {
2779                 p_pwr_array[i] = (u_int8_t)
2780                     AH_MIN(p_pwr_array[i], min_ctl_power);
2781 #ifdef ATH_BT_COEX
2782                 if (((ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_3WIRE) ||
2783                      (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI)) &&
2784                     (ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_LOWER_TX_PWR) && 
2785                     (ahp->ah_bt_wlan_isolation 
2786                         < HAL_BT_COEX_ISOLATION_FOR_NO_COEX)) {
2787
2788                     u_int8_t reduce_pow = (HAL_BT_COEX_ISOLATION_FOR_NO_COEX 
2789                                               - ahp->ah_bt_wlan_isolation) << 1;
2790
2791                     if (reduce_pow <= p_pwr_array[i]) {
2792                         p_pwr_array[i] -= reduce_pow;
2793                     }
2794                 }
2795 #if ATH_SUPPORT_MCI
2796                 else if ((ahp->ah_bt_coex_flag & 
2797                           HAL_BT_COEX_FLAG_MCI_MAX_TX_PWR) &&
2798                          (p_ctl_mode[ctl_mode] == CTL_2GHT40) &&
2799                          (ahp->ah_bt_coex_config_type == HAL_BT_COEX_CFG_MCI))
2800                 {
2801                     u_int8_t max_pwr;
2802
2803                     max_pwr = MS(mci_concur_tx_max_pwr[3][1],
2804                                  ATH_MCI_CONCUR_TX_LOWEST_PWR_MASK);
2805                     if (p_pwr_array[i] > max_pwr) {
2806                         p_pwr_array[i] = max_pwr;
2807                     }
2808                 }
2809 #endif
2810 #endif
2811             }
2812             break;
2813         default:
2814             HALASSERT(0);
2815             break;
2816         }
2817     } /* end ctl mode checking */
2818
2819     return AH_TRUE;
2820 #undef EXT_ADDITIVE
2821 #undef CTL_11A_EXT
2822 #undef CTL_11G_EXT
2823 #undef CTL_11B_EXT
2824 #undef REDUCE_SCALED_POWER_BY_TWO_CHAIN
2825 #undef REDUCE_SCALED_POWER_BY_THREE_CHAIN
2826 }
2827
2828 /**************************************************************
2829  * ar9300_eeprom_set_transmit_power
2830  *
2831  * Set the transmit power in the baseband for the given
2832  * operating channel and mode.
2833  */
2834 HAL_STATUS
2835 ar9300_eeprom_set_transmit_power(struct ath_hal *ah,
2836     ar9300_eeprom_t *p_eep_data, const struct ieee80211_channel *chan, u_int16_t cfg_ctl,
2837     u_int16_t antenna_reduction, u_int16_t twice_max_regulatory_power,
2838     u_int16_t power_limit)
2839 {
2840 #define ABS(_x, _y) ((int)_x > (int)_y ? (int)_x - (int)_y : (int)_y - (int)_x)
2841 #define INCREASE_MAXPOW_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
2842 #define INCREASE_MAXPOW_BY_THREE_CHAIN   10 /* 10*log10(3)*2 */
2843     u_int8_t target_power_val_t2[ar9300_rate_size];
2844     u_int8_t target_power_val_t2_eep[ar9300_rate_size];
2845     int16_t twice_array_gain = 0, max_power_level = 0;
2846     struct ath_hal_9300 *ahp = AH9300(ah);
2847     int  i = 0;
2848     u_int32_t tmp_paprd_rate_mask = 0, *tmp_ptr = NULL;
2849     int      paprd_scale_factor = 5;
2850     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
2851
2852     u_int8_t *ptr_mcs_rate2power_table_index;
2853     u_int8_t mcs_rate2power_table_index_ht20[24] =
2854     {
2855         ALL_TARGET_HT20_0_8_16,
2856         ALL_TARGET_HT20_1_3_9_11_17_19,
2857         ALL_TARGET_HT20_1_3_9_11_17_19,
2858         ALL_TARGET_HT20_1_3_9_11_17_19,
2859         ALL_TARGET_HT20_4,
2860         ALL_TARGET_HT20_5,
2861         ALL_TARGET_HT20_6,
2862         ALL_TARGET_HT20_7,
2863         ALL_TARGET_HT20_0_8_16,
2864         ALL_TARGET_HT20_1_3_9_11_17_19,
2865         ALL_TARGET_HT20_1_3_9_11_17_19,
2866         ALL_TARGET_HT20_1_3_9_11_17_19,
2867         ALL_TARGET_HT20_12,
2868         ALL_TARGET_HT20_13,
2869         ALL_TARGET_HT20_14,
2870         ALL_TARGET_HT20_15,
2871         ALL_TARGET_HT20_0_8_16,
2872         ALL_TARGET_HT20_1_3_9_11_17_19,
2873         ALL_TARGET_HT20_1_3_9_11_17_19,
2874         ALL_TARGET_HT20_1_3_9_11_17_19,
2875         ALL_TARGET_HT20_20,
2876         ALL_TARGET_HT20_21,
2877         ALL_TARGET_HT20_22,
2878         ALL_TARGET_HT20_23
2879     };
2880
2881     u_int8_t mcs_rate2power_table_index_ht40[24] =
2882     {
2883         ALL_TARGET_HT40_0_8_16,
2884         ALL_TARGET_HT40_1_3_9_11_17_19,
2885         ALL_TARGET_HT40_1_3_9_11_17_19,
2886         ALL_TARGET_HT40_1_3_9_11_17_19,
2887         ALL_TARGET_HT40_4,
2888         ALL_TARGET_HT40_5,
2889         ALL_TARGET_HT40_6,
2890         ALL_TARGET_HT40_7,
2891         ALL_TARGET_HT40_0_8_16,
2892         ALL_TARGET_HT40_1_3_9_11_17_19,
2893         ALL_TARGET_HT40_1_3_9_11_17_19,
2894         ALL_TARGET_HT40_1_3_9_11_17_19,
2895         ALL_TARGET_HT40_12,
2896         ALL_TARGET_HT40_13,
2897         ALL_TARGET_HT40_14,
2898         ALL_TARGET_HT40_15,
2899         ALL_TARGET_HT40_0_8_16,
2900         ALL_TARGET_HT40_1_3_9_11_17_19,
2901         ALL_TARGET_HT40_1_3_9_11_17_19,
2902         ALL_TARGET_HT40_1_3_9_11_17_19,
2903         ALL_TARGET_HT40_20,
2904         ALL_TARGET_HT40_21,
2905         ALL_TARGET_HT40_22,
2906         ALL_TARGET_HT40_23,
2907     };
2908
2909     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2910         "%s[%d] +++chan %d,cfgctl 0x%04x  "
2911         "antenna_reduction 0x%04x, twice_max_regulatory_power 0x%04x "
2912         "power_limit 0x%04x\n",
2913         __func__, __LINE__, ichan->channel, cfg_ctl,
2914         antenna_reduction, twice_max_regulatory_power, power_limit);
2915     ar9300_set_target_power_from_eeprom(ah, ichan->channel, target_power_val_t2);
2916
2917     if (ar9300_eeprom_get(ahp, EEP_PAPRD_ENABLED)) {
2918         if (IEEE80211_IS_CHAN_2GHZ(chan)) {
2919             if (IEEE80211_IS_CHAN_HT40(chan)) {
2920                 tmp_paprd_rate_mask =
2921                     p_eep_data->modal_header_2g.paprd_rate_mask_ht40;
2922                 tmp_ptr = &AH9300(ah)->ah_2g_paprd_rate_mask_ht40;
2923             } else {
2924                 tmp_paprd_rate_mask =
2925                     p_eep_data->modal_header_2g.paprd_rate_mask_ht20;
2926                 tmp_ptr = &AH9300(ah)->ah_2g_paprd_rate_mask_ht20;
2927             }
2928         } else {
2929             if (IEEE80211_IS_CHAN_HT40(chan)) {
2930                 tmp_paprd_rate_mask =
2931                     p_eep_data->modal_header_5g.paprd_rate_mask_ht40;
2932                 tmp_ptr = &AH9300(ah)->ah_5g_paprd_rate_mask_ht40;
2933             } else {
2934                 tmp_paprd_rate_mask =
2935                     p_eep_data->modal_header_5g.paprd_rate_mask_ht20;
2936                 tmp_ptr = &AH9300(ah)->ah_5g_paprd_rate_mask_ht20;
2937             }
2938         }
2939         AH_PAPRD_GET_SCALE_FACTOR(
2940             paprd_scale_factor, p_eep_data, IEEE80211_IS_CHAN_2GHZ(chan), ichan->channel);
2941         HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] paprd_scale_factor %d\n",
2942             __func__, __LINE__, paprd_scale_factor);
2943         /* PAPRD is not done yet, Scale down the EEP power */
2944         if (IEEE80211_IS_CHAN_HT40(chan)) {
2945             ptr_mcs_rate2power_table_index =
2946                 &mcs_rate2power_table_index_ht40[0];
2947         } else {
2948             ptr_mcs_rate2power_table_index =
2949                 &mcs_rate2power_table_index_ht20[0];
2950         }
2951         if (! ichan->paprd_table_write_done) {
2952             for (i = 0;  i < 24; i++) {
2953                 /* PAPRD is done yet, so Scale down Power for PAPRD Rates*/
2954                 if (tmp_paprd_rate_mask & (1 << i)) {
2955                     target_power_val_t2[ptr_mcs_rate2power_table_index[i]] -=
2956                         paprd_scale_factor;
2957                     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2958                         "%s[%d]: Chan %d "
2959                         "Scale down target_power_val_t2[%d] = 0x%04x\n",
2960                         __func__, __LINE__,
2961                         ichan->channel, i, target_power_val_t2[i]);
2962                 }
2963             }
2964         } else {
2965             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2966                 "%s[%d]: PAPRD Done No TGT PWR Scaling\n", __func__, __LINE__);
2967         }
2968     }
2969
2970     /* Save the Target power for future use */
2971     OS_MEMCPY(target_power_val_t2_eep, target_power_val_t2,
2972                                    sizeof(target_power_val_t2));
2973     ar9300_eeprom_set_power_per_rate_table(ah, p_eep_data, chan,
2974                                      target_power_val_t2, cfg_ctl,
2975                                      antenna_reduction,
2976                                      twice_max_regulatory_power,
2977                                      power_limit, 0);
2978     
2979     /* Save this for quick lookup */
2980     ahp->reg_dmn = ath_hal_getctl(ah, chan);
2981
2982     /*
2983      * Always use CDD/direct per rate power table for register based approach.
2984      * For FCC, CDD calculations should factor in the array gain, hence 
2985      * this adjust call. ETSI and MKK does not have this requirement.
2986      */
2987     if (is_reg_dmn_fcc(ahp->reg_dmn)) {
2988         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2989             "%s: FCC regdomain, calling reg_txpower_cdd\n",
2990             __func__);
2991         ar9300_adjust_reg_txpower_cdd(ah, target_power_val_t2);
2992     }
2993
2994     if (ar9300_eeprom_get(ahp, EEP_PAPRD_ENABLED)) {
2995         for (i = 0;  i < ar9300_rate_size; i++) {
2996             /*
2997              * EEPROM TGT PWR is not same as current TGT PWR,
2998              * so Disable PAPRD for this rate.
2999              * Some of APs might ask to reduce Target Power,
3000              * if target power drops significantly,
3001              * disable PAPRD for that rate.
3002              */
3003             if (tmp_paprd_rate_mask & (1 << i)) {
3004                 if (ABS(target_power_val_t2_eep[i], target_power_val_t2[i]) >
3005                     paprd_scale_factor)
3006                 {
3007                     tmp_paprd_rate_mask &= ~(1 << i);
3008                     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3009                         "%s: EEP TPC[%02d] 0x%08x "
3010                         "Curr TPC[%02d] 0x%08x mask = 0x%08x\n",
3011                         __func__, i, target_power_val_t2_eep[i], i,
3012                         target_power_val_t2[i], tmp_paprd_rate_mask);
3013                 }
3014             }
3015             
3016         }
3017         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3018             "%s: Chan %d After tmp_paprd_rate_mask = 0x%08x\n",
3019             __func__, ichan->channel, tmp_paprd_rate_mask);
3020         if (tmp_ptr) {
3021             *tmp_ptr = tmp_paprd_rate_mask;
3022         }
3023     }
3024
3025     /* Write target power array to registers */
3026     ar9300_transmit_power_reg_write(ah, target_power_val_t2);
3027     
3028     /* Write target power for self generated frames to the TPC register */
3029     ar9300_selfgen_tpc_reg_write(ah, chan, target_power_val_t2);
3030
3031     /* GreenTx or Paprd */
3032     if (ah->ah_config.ath_hal_sta_update_tx_pwr_enable || 
3033         AH_PRIVATE(ah)->ah_caps.halPaprdEnabled) 
3034     {
3035         if (AR_SREV_POSEIDON(ah)) {
3036             /*For HAL_RSSI_TX_POWER_NONE array*/
3037             OS_MEMCPY(ahp->ah_default_tx_power, 
3038                 target_power_val_t2, 
3039                 sizeof(target_power_val_t2));
3040             /* Get defautl tx related register setting for GreenTx */
3041             /* Record OB/DB */
3042             ahp->ah_ob_db1[POSEIDON_STORED_REG_OBDB] = 
3043                 OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF2);
3044             /* Record TPC settting */
3045             ahp->ah_ob_db1[POSEIDON_STORED_REG_TPC] =
3046                 OS_REG_READ(ah, AR_TPC);
3047             /* Record BB_powertx_rate9 setting */ 
3048             ahp->ah_ob_db1[POSEIDON_STORED_REG_BB_PWRTX_RATE9] = 
3049                 OS_REG_READ(ah, AR_PHY_BB_POWERTX_RATE9);
3050         }
3051     }
3052
3053     /*
3054      * Return tx power used to iwconfig.
3055      * Since power is rate dependent, use one of the indices from the
3056      * AR9300_Rates enum to select an entry from target_power_val_t2[]
3057      * to report.
3058      * Currently returns the power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps
3059      * as CCK power is less interesting (?).
3060      */
3061     i = ALL_TARGET_LEGACY_6_24;         /* legacy */
3062     if (IEEE80211_IS_CHAN_HT40(chan)) {
3063         i = ALL_TARGET_HT40_0_8_16;     /* ht40 */
3064     } else if (IEEE80211_IS_CHAN_HT20(chan)) {
3065         i = ALL_TARGET_HT20_0_8_16;     /* ht20 */
3066     }
3067     max_power_level = target_power_val_t2[i];
3068     /* Adjusting the ah_max_power_level based on chains and antennaGain*/
3069     switch (ar9300_get_ntxchains(((ahp->ah_tx_chainmaskopt > 0) ?
3070                                     ahp->ah_tx_chainmaskopt : ahp->ah_tx_chainmask)))
3071     {
3072         case 1:
3073             break;
3074         case 2:
3075             twice_array_gain = (ahp->twice_antenna_gain >= ahp->twice_antenna_reduction)? 0: 
3076                                ((int16_t)AH_MIN((ahp->twice_antenna_reduction -
3077                                    (ahp->twice_antenna_gain + INCREASE_MAXPOW_BY_TWO_CHAIN)), 0));
3078             /* Adjusting maxpower with antennaGain */
3079             max_power_level -= twice_array_gain;
3080             /* Adjusting maxpower based on chain */
3081             max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
3082             break;
3083         case 3:
3084             twice_array_gain = (ahp->twice_antenna_gain >= ahp->twice_antenna_reduction)? 0:
3085                                ((int16_t)AH_MIN((ahp->twice_antenna_reduction -
3086                                    (ahp->twice_antenna_gain + INCREASE_MAXPOW_BY_THREE_CHAIN)), 0));
3087
3088             /* Adjusting maxpower with antennaGain */
3089             max_power_level -= twice_array_gain;
3090             /* Adjusting maxpower based on chain */
3091             max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
3092             break;
3093         default:
3094             HALASSERT(0); /* Unsupported number of chains */
3095     }
3096     AH_PRIVATE(ah)->ah_maxPowerLevel = (int8_t)max_power_level;
3097
3098     ar9300_calibration_apply(ah, ichan->channel);
3099 #undef ABS
3100
3101     /* Handle per packet TPC initializations */
3102     if (ah->ah_config.ath_hal_desc_tpc) {
3103         /* Transmit Power per-rate per-chain  are  computed here. A separate
3104          * power table is maintained for different MIMO modes (i.e. TXBF ON,
3105          * STBC) to enable easy lookup during packet transmit. 
3106          * The reason for maintaing each of these tables per chain is that
3107          * the transmit power used for different number of chains is different
3108          * depending on whether the power has been limited by the target power,
3109          * the regulatory domain  or the CTL limits.
3110          */
3111         u_int mode = ath_hal_get_curmode(ah, chan);
3112         u_int32_t val = 0;
3113         u_int8_t chainmasks[AR9300_MAX_CHAINS] =
3114             {OSPREY_1_CHAINMASK, OSPREY_2LOHI_CHAINMASK, OSPREY_3_CHAINMASK};
3115         for (i = 0; i < AR9300_MAX_CHAINS; i++) {
3116             OS_MEMCPY(target_power_val_t2, target_power_val_t2_eep,
3117                                    sizeof(target_power_val_t2_eep));
3118             ar9300_eeprom_set_power_per_rate_table(ah, p_eep_data, chan,
3119                                      target_power_val_t2, cfg_ctl,
3120                                      antenna_reduction,
3121                                      twice_max_regulatory_power,
3122                                      power_limit, chainmasks[i]);
3123             HALDEBUG(ah, HAL_DEBUG_POWER_MGMT,
3124                  " Channel = %d Chainmask = %d, Upper Limit = [%2d.%1d dBm]\n",
3125                                        ichan->channel, i, ahp->upper_limit[i]/2,
3126                                        ahp->upper_limit[i]%2 * 5);
3127             ar9300_init_rate_txpower(ah, mode, chan, target_power_val_t2,
3128                                                            chainmasks[i]);
3129                                      
3130         }
3131
3132         /* Enable TPC */
3133         OS_REG_WRITE(ah, AR_PHY_PWRTX_MAX, AR_PHY_PWRTX_MAX_TPC_ENABLE);
3134         /*
3135          * Disable per chain power reduction since we are already 
3136          * accounting for this in our calculations 
3137          */
3138         val = OS_REG_READ(ah, AR_PHY_POWER_TX_SUB);
3139         if (AR_SREV_WASP(ah)) {
3140             OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
3141                        val & AR_PHY_POWER_TX_SUB_2_DISABLE);
3142         } else {
3143             OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
3144                        val & AR_PHY_POWER_TX_SUB_3_DISABLE);
3145         }
3146     }
3147
3148     return HAL_OK;
3149 }
3150
3151 /**************************************************************
3152  * ar9300_eeprom_set_addac
3153  *
3154  * Set the ADDAC from eeprom.
3155  */
3156 void
3157 ar9300_eeprom_set_addac(struct ath_hal *ah, struct ieee80211_channel *chan)
3158 {
3159
3160     HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE,
3161                  "FIXME: ar9300_eeprom_def_set_addac called\n");
3162 #if 0
3163     MODAL_EEPDEF_HEADER *p_modal;
3164     struct ath_hal_9300 *ahp = AH9300(ah);
3165     ar9300_eeprom_t *eep = &ahp->ah_eeprom.def;
3166     u_int8_t biaslevel;
3167
3168     if (AH_PRIVATE(ah)->ah_macVersion != AR_SREV_VERSION_SOWL) {
3169         return;
3170     }
3171
3172     HALASSERT(owl_get_eepdef_ver(ahp) == AR9300_EEP_VER);
3173
3174     /* Xpa bias levels in eeprom are valid from rev 14.7 */
3175     if (owl_get_eepdef_rev(ahp) < AR9300_EEP_MINOR_VER_7) {
3176         return;
3177     }
3178
3179     if (ahp->ah_emu_eeprom) {
3180         return;
3181     }
3182
3183     p_modal = &(eep->modal_header[IEEE80211_IS_CHAN_2GHZ(chan)]);
3184
3185     if (p_modal->xpa_bias_lvl != 0xff) {
3186         biaslevel = p_modal->xpa_bias_lvl;
3187     } else {
3188         /* Use freqeuncy specific xpa bias level */
3189         u_int16_t reset_freq_bin, freq_bin, freq_count = 0;
3190         CHAN_CENTERS centers;
3191
3192         ar9300_get_channel_centers(ah, chan, &centers);
3193
3194         reset_freq_bin = FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan));
3195         freq_bin = p_modal->xpa_bias_lvl_freq[0] & 0xff;
3196         biaslevel = (u_int8_t)(p_modal->xpa_bias_lvl_freq[0] >> 14);
3197
3198         freq_count++;
3199
3200         while (freq_count < 3) {
3201             if (p_modal->xpa_bias_lvl_freq[freq_count] == 0x0) {
3202                 break;
3203             }
3204
3205             freq_bin = p_modal->xpa_bias_lvl_freq[freq_count] & 0xff;
3206             if (reset_freq_bin >= freq_bin) {
3207                 biaslevel =
3208                     (u_int8_t)(p_modal->xpa_bias_lvl_freq[freq_count] >> 14);
3209             } else {
3210                 break;
3211             }
3212             freq_count++;
3213         }
3214     }
3215
3216     /* Apply bias level to the ADDAC values in the INI array */
3217     if (IEEE80211_IS_CHAN_2GHZ(chan)) {
3218         INI_RA(&ahp->ah_ini_addac, 7, 1) =
3219             (INI_RA(&ahp->ah_ini_addac, 7, 1) & (~0x18)) | biaslevel << 3;
3220     } else {
3221         INI_RA(&ahp->ah_ini_addac, 6, 1) =
3222             (INI_RA(&ahp->ah_ini_addac, 6, 1) & (~0xc0)) | biaslevel << 6;
3223     }
3224 #endif
3225 }
3226
3227 u_int
3228 ar9300_eeprom_dump_support(struct ath_hal *ah, void **pp_e)
3229 {
3230     *pp_e = &(AH9300(ah)->ah_eeprom);
3231     return sizeof(ar9300_eeprom_t);
3232 }
3233
3234 u_int8_t
3235 ar9300_eeprom_get_num_ant_config(struct ath_hal_9300 *ahp,
3236     HAL_FREQ_BAND freq_band)
3237 {
3238 #if 0
3239     ar9300_eeprom_t  *eep = &ahp->ah_eeprom.def;
3240     MODAL_EEPDEF_HEADER *p_modal =
3241         &(eep->modal_header[HAL_FREQ_BAND_2GHZ == freq_band]);
3242     BASE_EEPDEF_HEADER  *p_base  = &eep->base_eep_header;
3243     u_int8_t         num_ant_config;
3244
3245     num_ant_config = 1; /* default antenna configuration */
3246
3247     if (p_base->version >= 0x0E0D) {
3248         if (p_modal->use_ant1) {
3249             num_ant_config += 1;
3250         }
3251     }
3252
3253     return num_ant_config;
3254 #else
3255     return 1;
3256 #endif
3257 }
3258
3259 HAL_STATUS
3260 ar9300_eeprom_get_ant_cfg(struct ath_hal_9300 *ahp,
3261   const struct ieee80211_channel *chan,
3262   u_int8_t index, u_int16_t *config)
3263 {
3264 #if 0
3265     ar9300_eeprom_t  *eep = &ahp->ah_eeprom.def;
3266     MODAL_EEPDEF_HEADER *p_modal = &(eep->modal_header[IEEE80211_IS_CHAN_2GHZ(chan)]);
3267     BASE_EEPDEF_HEADER  *p_base  = &eep->base_eep_header;
3268
3269     switch (index) {
3270     case 0:
3271         *config = p_modal->ant_ctrl_common & 0xFFFF;
3272         return HAL_OK;
3273     case 1:
3274         if (p_base->version >= 0x0E0D) {
3275             if (p_modal->use_ant1) {
3276                 *config = ((p_modal->ant_ctrl_common & 0xFFFF0000) >> 16);
3277                 return HAL_OK;
3278             }
3279         }
3280         break;
3281     default:
3282         break;
3283     }
3284 #endif
3285     return HAL_EINVAL;
3286 }
3287
3288 u_int8_t*
3289 ar9300_eeprom_get_cust_data(struct ath_hal_9300 *ahp)
3290 {
3291     return (u_int8_t *)ahp;
3292 }
3293
3294 #ifdef UNUSED
3295 static inline HAL_STATUS
3296 ar9300_check_eeprom(struct ath_hal *ah)
3297 {
3298 #if 0
3299     u_int32_t sum = 0, el;
3300     u_int16_t *eepdata;
3301     int i;
3302     struct ath_hal_9300 *ahp = AH9300(ah);
3303     HAL_BOOL need_swap = AH_FALSE;
3304     ar9300_eeprom_t *eep = (ar9300_eeprom_t *)&ahp->ah_eeprom.def;
3305     u_int16_t magic, magic2;
3306     int addr;
3307     u_int16_t temp;
3308
3309     /*
3310     ** We need to check the EEPROM data regardless of if it's in flash or
3311     ** in EEPROM.
3312     */
3313
3314     if (!ahp->ah_priv.priv.ah_eeprom_read(
3315             ah, AR9300_EEPROM_MAGIC_OFFSET, &magic))
3316     {
3317         HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: Reading Magic # failed\n", __func__);
3318         return AH_FALSE;
3319     }
3320
3321     HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: Read Magic = 0x%04X\n", __func__, magic);
3322
3323     if (!ar9300_eep_data_in_flash(ah)) {
3324
3325         if (magic != AR9300_EEPROM_MAGIC) {
3326             magic2 = SWAP16(magic);
3327
3328             if (magic2 == AR9300_EEPROM_MAGIC) {
3329                 need_swap = AH_TRUE;
3330                 eepdata = (u_int16_t *)(&ahp->ah_eeprom);
3331
3332                 for (addr = 0;
3333                      addr < sizeof(ar9300_eeprom_t) / sizeof(u_int16_t);
3334                      addr++)
3335                 {
3336                     temp = SWAP16(*eepdata);
3337                     *eepdata = temp;
3338                     eepdata++;
3339
3340                     HALDEBUG(ah, HAL_DEBUG_EEPROM_DUMP, "0x%04X  ", *eepdata);
3341                     if (((addr + 1) % 6) == 0) {
3342                         HALDEBUG(ah, HAL_DEBUG_EEPROM_DUMP, "\n");
3343                     }
3344                 }
3345             } else {
3346                 HALDEBUG(ah, HAL_DEBUG_EEPROM,
3347                     "Invalid EEPROM Magic. endianness missmatch.\n");
3348                 return HAL_EEBADSUM;
3349             }
3350         }
3351     } else {
3352         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3353                  "EEPROM being read from flash @0x%p\n", AH_PRIVATE(ah)->ah_st);
3354     }
3355
3356     HALDEBUG(ah, HAL_DEBUG_EEPROM, "need_swap = %s.\n", need_swap?"True":"False");
3357
3358     if (need_swap) {
3359         el = SWAP16(ahp->ah_eeprom.def.base_eep_header.length);
3360     } else {
3361         el = ahp->ah_eeprom.def.base_eep_header.length;
3362     }
3363
3364     eepdata = (u_int16_t *)(&ahp->ah_eeprom.def);
3365     for (i = 0;
3366          i < AH_MIN(el, sizeof(ar9300_eeprom_t)) / sizeof(u_int16_t);
3367          i++) {
3368         sum ^= *eepdata++;
3369     }
3370
3371     if (need_swap) {
3372         /*
3373         *  preddy: EEPROM endianness does not match. So change it
3374         *  8bit values in eeprom data structure does not need to be swapped
3375         *  Only >8bits (16 & 32) values need to be swapped
3376         *  If a new 16 or 32 bit field is added to the EEPROM contents,
3377         *  please make sure to swap the field here
3378         */
3379         u_int32_t integer, j;
3380         u_int16_t word;
3381
3382         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3383             "EEPROM Endianness is not native.. Changing \n");
3384
3385         /* convert Base Eep header */
3386         word = SWAP16(eep->base_eep_header.length);
3387         eep->base_eep_header.length = word;
3388
3389         word = SWAP16(eep->base_eep_header.checksum);
3390         eep->base_eep_header.checksum = word;
3391
3392         word = SWAP16(eep->base_eep_header.version);
3393         eep->base_eep_header.version = word;
3394
3395         word = SWAP16(eep->base_eep_header.reg_dmn[0]);
3396         eep->base_eep_header.reg_dmn[0] = word;
3397
3398         word = SWAP16(eep->base_eep_header.reg_dmn[1]);
3399         eep->base_eep_header.reg_dmn[1] = word;
3400
3401         word = SWAP16(eep->base_eep_header.rf_silent);
3402         eep->base_eep_header.rf_silent = word;
3403
3404         word = SWAP16(eep->base_eep_header.blue_tooth_options);
3405         eep->base_eep_header.blue_tooth_options = word;
3406
3407         word = SWAP16(eep->base_eep_header.device_cap);
3408         eep->base_eep_header.device_cap = word;
3409
3410         /* convert Modal Eep header */
3411         for (j = 0; j < ARRAY_LENGTH(eep->modal_header); j++) {
3412             MODAL_EEPDEF_HEADER *p_modal = &eep->modal_header[j];
3413             integer = SWAP32(p_modal->ant_ctrl_common);
3414             p_modal->ant_ctrl_common = integer;
3415
3416             for (i = 0; i < AR9300_MAX_CHAINS; i++) {
3417                 integer = SWAP32(p_modal->ant_ctrl_chain[i]);
3418                 p_modal->ant_ctrl_chain[i] = integer;
3419             }
3420
3421             for (i = 0; i < AR9300_EEPROM_MODAL_SPURS; i++) {
3422                 word = SWAP16(p_modal->spur_chans[i].spur_chan);
3423                 p_modal->spur_chans[i].spur_chan = word;
3424             }
3425         }
3426     }
3427
3428     /* Check CRC - Attach should fail on a bad checksum */
3429     if (sum != 0xffff || owl_get_eepdef_ver(ahp) != AR9300_EEP_VER ||
3430         owl_get_eepdef_rev(ahp) < AR9300_EEP_NO_BACK_VER) {
3431         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3432             "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
3433             sum, owl_get_eepdef_ver(ahp));
3434         return HAL_EEBADSUM;
3435     }
3436 #ifdef EEPROM_DUMP
3437     ar9300_eeprom_def_dump(ah, eep);
3438 #endif
3439
3440 #if 0
3441 #ifdef AH_AR9300_OVRD_TGT_PWR
3442
3443     /*
3444      * 14.4 EEPROM contains low target powers.
3445      * Hardcode until EEPROM > 14.4
3446      */
3447     if (owl_get_eepdef_ver(ahp) == 14 && owl_get_eepdef_rev(ahp) <= 4) {
3448         MODAL_EEPDEF_HEADER *p_modal;
3449
3450 #ifdef EEPROM_DUMP
3451         HALDEBUG(ah,  HAL_DEBUG_POWER_OVERRIDE, "Original Target Powers\n");
3452         ar9300_eep_def_dump_tgt_power(ah, eep);
3453 #endif
3454         HALDEBUG(ah,  HAL_DEBUG_POWER_OVERRIDE, 
3455                 "Override Target Powers. EEPROM Version is %d.%d, "
3456                 "Device Type %d\n",
3457                 owl_get_eepdef_ver(ahp),
3458                 owl_get_eepdef_rev(ahp),
3459                 eep->base_eep_header.device_type);
3460
3461
3462         ar9300_eep_def_override_tgt_power(ah, eep);
3463
3464         if (eep->base_eep_header.device_type == 5) {
3465             /* for xb72 only: improve transmit EVM for interop */
3466             p_modal = &eep->modal_header[1];
3467             p_modal->tx_frame_to_data_start = 0x23;
3468             p_modal->tx_frame_to_xpa_on = 0x23;
3469             p_modal->tx_frame_to_pa_on = 0x23;
3470     }
3471
3472 #ifdef EEPROM_DUMP
3473         HALDEBUG(ah, HAL_DEBUG_POWER_OVERRIDE, "Modified Target Powers\n");
3474         ar9300_eep_def_dump_tgt_power(ah, eep);
3475 #endif
3476         }
3477 #endif /* AH_AR9300_OVRD_TGT_PWR */
3478 #endif
3479 #endif
3480     return HAL_OK;
3481 }
3482 #endif
3483
3484 static u_int16_t
3485 ar9300_eeprom_get_spur_chan(struct ath_hal *ah, int i, HAL_BOOL is_2ghz)
3486 {
3487     u_int16_t   spur_val = AR_NO_SPUR;
3488 #if 0
3489     struct ath_hal_9300 *ahp = AH9300(ah);
3490     ar9300_eeprom_t *eep = (ar9300_eeprom_t *)&ahp->ah_eeprom;
3491
3492     HALASSERT(i <  AR_EEPROM_MODAL_SPURS );
3493
3494     HALDEBUG(ah, HAL_DEBUG_ANI,
3495              "Getting spur idx %d is2Ghz. %d val %x\n",
3496              i, is_2ghz,
3497              AH_PRIVATE(ah)->ah_config.ath_hal_spur_chans[i][is_2ghz]);
3498
3499     switch (AH_PRIVATE(ah)->ah_config.ath_hal_spur_mode) {
3500     case SPUR_DISABLE:
3501         /* returns AR_NO_SPUR */
3502         break;
3503     case SPUR_ENABLE_IOCTL:
3504         spur_val = AH_PRIVATE(ah)->ah_config.ath_hal_spur_chans[i][is_2ghz];
3505         HALDEBUG(ah, HAL_DEBUG_ANI,
3506             "Getting spur val from new loc. %d\n", spur_val);
3507         break;
3508     case SPUR_ENABLE_EEPROM:
3509         spur_val = eep->modal_header[is_2ghz].spur_chans[i].spur_chan;
3510         break;
3511
3512     }
3513 #endif
3514     return spur_val;
3515 }
3516
3517 #ifdef UNUSED
3518 static inline HAL_BOOL
3519 ar9300_fill_eeprom(struct ath_hal *ah)
3520 {
3521     return ar9300_eeprom_restore(ah);
3522 }
3523 #endif
3524
3525 u_int16_t
3526 ar9300_eeprom_struct_size(void) 
3527 {
3528     return sizeof(ar9300_eeprom_t);
3529 }
3530
3531 int ar9300_eeprom_struct_default_many(void)
3532 {
3533     return ARRAY_LENGTH(default9300);
3534 }
3535
3536
3537 ar9300_eeprom_t *
3538 ar9300_eeprom_struct_default(int default_index) 
3539 {
3540     if (default_index >= 0 &&
3541         default_index < ARRAY_LENGTH(default9300))
3542     {
3543         return default9300[default_index];
3544     } else {
3545         return 0;
3546     }
3547 }
3548
3549 ar9300_eeprom_t *
3550 ar9300_eeprom_struct_default_find_by_id(int id) 
3551 {
3552     int it;
3553
3554     for (it = 0; it < ARRAY_LENGTH(default9300); it++) {
3555         if (default9300[it] != 0 && default9300[it]->template_version == id) {
3556             return default9300[it];
3557         }
3558     }
3559     return 0;
3560 }
3561
3562
3563 HAL_BOOL
3564 ar9300_calibration_data_read_flash(struct ath_hal *ah, long address,
3565     u_int8_t *buffer, int many)
3566 {
3567
3568     if (((address) < 0) || ((address + many) > AR9300_EEPROM_SIZE - 1)) {
3569         return AH_FALSE;
3570     }
3571     return AH_FALSE;
3572 }
3573
3574 HAL_BOOL
3575 ar9300_calibration_data_read_eeprom(struct ath_hal *ah, long address,
3576     u_int8_t *buffer, int many)
3577 {
3578     int i;
3579     u_int8_t value[2];
3580     unsigned long eep_addr;
3581     unsigned long byte_addr;
3582     u_int16_t *svalue;
3583
3584     if (((address) < 0) || ((address + many) > AR9300_EEPROM_SIZE)) {
3585         return AH_FALSE;
3586     }
3587
3588     for (i = 0; i < many; i++) {
3589         eep_addr = (u_int16_t) (address + i) / 2;
3590         byte_addr = (u_int16_t) (address + i) % 2;
3591         svalue = (u_int16_t *) value;
3592         if (! ath_hal_eepromRead(ah, eep_addr, svalue)) {
3593             HALDEBUG(ah, HAL_DEBUG_EEPROM,
3594                 "%s: Unable to read eeprom region \n", __func__);
3595             return AH_FALSE;
3596         }  
3597         buffer[i] = (*svalue >> (8 * byte_addr)) & 0xff;
3598     }  
3599     return AH_TRUE;
3600 }
3601
3602 HAL_BOOL
3603 ar9300_calibration_data_read_otp(struct ath_hal *ah, long address,
3604     u_int8_t *buffer, int many, HAL_BOOL is_wifi)
3605 {
3606     int i;
3607     unsigned long eep_addr;
3608     unsigned long byte_addr;
3609     u_int32_t svalue;
3610
3611     if (((address) < 0) || ((address + many) > 0x400)) {
3612         return AH_FALSE;
3613     }
3614
3615     for (i = 0; i < many; i++) {
3616         eep_addr = (u_int16_t) (address + i) / 4; /* otp is 4 bytes long???? */
3617         byte_addr = (u_int16_t) (address + i) % 4;
3618         if (!ar9300_otp_read(ah, eep_addr, &svalue, is_wifi)) {
3619             HALDEBUG(ah, HAL_DEBUG_EEPROM,
3620                 "%s: Unable to read otp region \n", __func__);
3621             return AH_FALSE;
3622         }  
3623         buffer[i] = (svalue >> (8 * byte_addr)) & 0xff;
3624     }  
3625     return AH_TRUE;
3626 }
3627
3628 #ifdef ATH_CAL_NAND_FLASH
3629 HAL_BOOL
3630 ar9300_calibration_data_read_nand(struct ath_hal *ah, long address,
3631     u_int8_t *buffer, int many)
3632 {
3633     int ret_len;
3634     int ret_val = 1;
3635     
3636       /* Calling OS based API to read NAND */
3637     ret_val = OS_NAND_FLASH_READ(ATH_CAL_NAND_PARTITION, address, many, &ret_len, buffer);
3638     
3639     return (ret_val ? AH_FALSE: AH_TRUE);
3640 }
3641 #endif
3642
3643 HAL_BOOL
3644 ar9300_calibration_data_read(struct ath_hal *ah, long address,
3645     u_int8_t *buffer, int many)
3646 {
3647     switch (AH9300(ah)->calibration_data_source) {
3648     case calibration_data_flash:
3649         return ar9300_calibration_data_read_flash(ah, address, buffer, many);
3650     case calibration_data_eeprom:
3651         return ar9300_calibration_data_read_eeprom(ah, address, buffer, many);
3652     case calibration_data_otp:
3653         return ar9300_calibration_data_read_otp(ah, address, buffer, many, 1);
3654 #ifdef ATH_CAL_NAND_FLASH
3655     case calibration_data_nand:
3656         return ar9300_calibration_data_read_nand(ah,address,buffer,many);
3657 #endif
3658
3659     }
3660     return AH_FALSE;
3661 }
3662
3663
3664 HAL_BOOL 
3665 ar9300_calibration_data_read_array(struct ath_hal *ah, int address,
3666     u_int8_t *buffer, int many)
3667 {
3668     int it;
3669
3670     for (it = 0; it < many; it++) {
3671         (void)ar9300_calibration_data_read(ah, address - it, buffer + it, 1);
3672     }
3673     return AH_TRUE;
3674 }
3675
3676
3677 /*
3678  * the address where the first configuration block is written
3679  */
3680 static const int base_address = 0x3ff;                /* 1KB */
3681 static const int base_address_512 = 0x1ff;            /* 512Bytes */
3682
3683 /*
3684  * the address where the NAND first configuration block is written
3685  */
3686 #ifdef ATH_CAL_NAND_FLASH
3687 static const int base_address_nand = AR9300_FLASH_CAL_START_OFFSET;
3688 #endif
3689
3690
3691 /*
3692  * the lower limit on configuration data
3693  */
3694 static const int low_limit = 0x040;
3695
3696 /*
3697  * returns size of the physical eeprom in bytes.
3698  * 1024 and 2048 are normal sizes. 
3699  * 0 means there is no eeprom. 
3700  */ 
3701 int32_t 
3702 ar9300_eeprom_size(struct ath_hal *ah)
3703 {
3704     u_int16_t data;
3705     /*
3706      * first we'll try for 4096 bytes eeprom
3707      */
3708     if (ar9300_eeprom_read_word(ah, 2047, &data)) {
3709         if (data != 0) {
3710             return 4096;
3711         }
3712     }
3713     /*
3714      * then we'll try for 2048 bytes eeprom
3715      */
3716     if (ar9300_eeprom_read_word(ah, 1023, &data)) {
3717         if (data != 0) {
3718             return 2048;
3719         }
3720     }
3721     /*
3722      * then we'll try for 1024 bytes eeprom
3723      */
3724     if (ar9300_eeprom_read_word(ah, 511, &data)) {
3725         if (data != 0) {
3726             return 1024;
3727         }
3728     }
3729     return 0;
3730 }
3731
3732 /*
3733  * returns size of the physical otp in bytes.
3734  * 1024 and 2048 are normal sizes. 
3735  * 0 means there is no eeprom. 
3736  */ 
3737 int32_t 
3738 ar9300_otp_size(struct ath_hal *ah)
3739 {
3740     if (AR_SREV_POSEIDON(ah) || AR_SREV_HORNET(ah)) {
3741         return base_address_512+1;
3742     } else {
3743         return base_address+1;
3744     }
3745 }
3746
3747
3748 /*
3749  * find top of memory
3750  */
3751 int
3752 ar9300_eeprom_base_address(struct ath_hal *ah)
3753 {
3754     int size;
3755
3756     if (AH9300(ah)->calibration_data_source == calibration_data_otp) {
3757                 return ar9300_otp_size(ah)-1;
3758         }
3759         else
3760         {
3761                 size = ar9300_eeprom_size(ah);
3762                 if (size > 0) {
3763                         return size - 1;
3764                 } else {
3765                         return ar9300_otp_size(ah)-1;
3766                 }
3767         }
3768 }
3769
3770 int
3771 ar9300_eeprom_volatile(struct ath_hal *ah)
3772 {
3773     if (AH9300(ah)->calibration_data_source == calibration_data_otp) {
3774         return 0;        /* no eeprom, use otp */
3775     } else {
3776         return 1;        /* board has eeprom or flash */
3777     }
3778 }
3779
3780 /*
3781  * need to change this to look for the pcie data in the low parts of memory
3782  * cal data needs to stop a few locations above 
3783  */
3784 int
3785 ar9300_eeprom_low_limit(struct ath_hal *ah)
3786 {
3787     return low_limit;
3788 }
3789
3790 u_int16_t
3791 ar9300_compression_checksum(u_int8_t *data, int dsize)
3792 {
3793     int it;
3794     int checksum = 0;
3795
3796     for (it = 0; it < dsize; it++) {
3797         checksum += data[it];
3798         checksum &= 0xffff;
3799     }
3800
3801     return checksum;
3802 }
3803
3804 int
3805 ar9300_compression_header_unpack(u_int8_t *best, int *code, int *reference,
3806     int *length, int *major, int *minor)
3807 {
3808     unsigned long value[4];
3809
3810     value[0] = best[0];
3811     value[1] = best[1];
3812     value[2] = best[2];
3813     value[3] = best[3];
3814     *code = ((value[0] >> 5) & 0x0007);
3815     *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
3816     *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
3817     *major = (value[2] & 0x000f);
3818     *minor = (value[3] & 0x00ff);
3819
3820     return 4;
3821 }
3822
3823
3824 static HAL_BOOL
3825 ar9300_uncompress_block(struct ath_hal *ah, u_int8_t *mptr, int mdata_size,
3826     u_int8_t *block, int size)
3827 {
3828     int it;
3829     int spot;
3830     int offset;
3831     int length;
3832
3833     spot = 0;
3834     for (it = 0; it < size; it += (length + 2)) {
3835         offset = block[it];
3836         offset &= 0xff;
3837         spot += offset;
3838         length = block[it + 1];
3839         length &= 0xff;
3840         if (length > 0 && spot >= 0 && spot + length <= mdata_size) {
3841             HALDEBUG(ah, HAL_DEBUG_EEPROM,
3842                 "%s: Restore at %d: spot=%d offset=%d length=%d\n",
3843                 __func__, it, spot, offset, length);
3844             OS_MEMCPY(&mptr[spot], &block[it + 2], length);
3845             spot += length;
3846         } else if (length > 0) {
3847             HALDEBUG(ah, HAL_DEBUG_EEPROM,
3848                 "%s: Bad restore at %d: spot=%d offset=%d length=%d\n",
3849                 __func__, it, spot, offset, length);
3850             return AH_FALSE;
3851         }
3852     }
3853     return AH_TRUE;
3854 }
3855
3856 static int
3857 ar9300_eeprom_restore_internal_address(struct ath_hal *ah,
3858     ar9300_eeprom_t *mptr, int mdata_size, int cptr, u_int8_t blank)
3859 {
3860     u_int8_t word[MOUTPUT]; 
3861     ar9300_eeprom_t *dptr; /* was uint8 */
3862     int code;
3863     int reference, length, major, minor;
3864     int osize;
3865     int it;
3866     int restored;
3867     u_int16_t checksum, mchecksum;
3868
3869     restored = 0;
3870     for (it = 0; it < MSTATE; it++) {            
3871         (void) ar9300_calibration_data_read_array(
3872             ah, cptr, word, compression_header_length);
3873         if (word[0] == blank && word[1] == blank && word[2] == blank && word[3] == blank)
3874         {
3875             break;
3876         }
3877         ar9300_compression_header_unpack(
3878             word, &code, &reference, &length, &major, &minor);
3879         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3880             "%s: Found block at %x: "
3881             "code=%d ref=%d length=%d major=%d minor=%d\n",
3882             __func__, cptr, code, reference, length, major, minor);
3883 #ifdef DONTUSE
3884         if (length >= 1024) {
3885             HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: Skipping bad header\n", __func__);
3886             cptr -= compression_header_length;
3887             continue;
3888         }
3889 #endif
3890         osize = length;                
3891         (void) ar9300_calibration_data_read_array(
3892             ah, cptr, word,
3893             compression_header_length + osize + compression_checksum_length);
3894         checksum = ar9300_compression_checksum(
3895             &word[compression_header_length], length);
3896         mchecksum =
3897             word[compression_header_length + osize] |
3898             (word[compression_header_length + osize + 1] << 8);
3899         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3900             "%s: checksum %x %x\n", __func__, checksum, mchecksum);
3901         if (checksum == mchecksum) {
3902             switch (code) {
3903             case _compress_none:
3904                 if (length != mdata_size) {
3905                     HALDEBUG(ah, HAL_DEBUG_EEPROM,
3906                         "%s: EEPROM structure size mismatch "
3907                         "memory=%d eeprom=%d\n", __func__, mdata_size, length);
3908                     return -1;
3909                 }
3910                 OS_MEMCPY((u_int8_t *)mptr,
3911                     (u_int8_t *)(word + compression_header_length), length);
3912                 HALDEBUG(ah, HAL_DEBUG_EEPROM,
3913                     "%s: restored eeprom %d: uncompressed, length %d\n",
3914                     __func__, it, length);
3915                 restored = 1;
3916                 break;
3917 #ifdef UNUSED
3918             case _compress_lzma:
3919                 if (reference == reference_current) {
3920                     dptr = mptr;
3921                 } else {
3922                     dptr = (u_int8_t *)ar9300_eeprom_struct_default_find_by_id(
3923                         reference);
3924                     if (dptr == 0) {
3925                         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3926                             "%s: Can't find reference eeprom struct %d\n",
3927                             __func__, reference);
3928                         goto done;
3929                     }
3930                 }
3931                 usize = -1;
3932                 if (usize != mdata_size) {
3933                     HALDEBUG(ah, HAL_DEBUG_EEPROM,
3934                         "%s: uncompressed data is wrong size %d %d\n",
3935                         __func__, usize, mdata_size);
3936                     goto done;
3937                 }
3938
3939                 for (ib = 0; ib < mdata_size; ib++) {
3940                     mptr[ib] = dptr[ib] ^ word[ib + overhead];
3941                 }
3942                 HALDEBUG(ah, HAL_DEBUG_EEPROM,
3943                     "%s: restored eeprom %d: compressed, "
3944                     "reference %d, length %d\n",
3945                     __func__, it, reference, length);
3946                 break;
3947             case _compress_pairs:
3948                 if (reference == reference_current) {
3949                     dptr = mptr;
3950                 } else {
3951                     dptr = (u_int8_t *)ar9300_eeprom_struct_default_find_by_id(
3952                         reference);
3953                     if (dptr == 0) {
3954                         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3955                             "%s: Can't find the reference "
3956                             "eeprom structure %d\n",
3957                             __func__, reference);
3958                         goto done;
3959                     }
3960                 }
3961                 HALDEBUG(ah, HAL_DEBUG_EEPROM,
3962                     "%s: restored eeprom %d: "
3963                     "pairs, reference %d, length %d,\n",
3964                     __func__, it, reference, length);
3965                 break;
3966 #endif
3967             case _compress_block:
3968                 if (reference == reference_current) {
3969                     dptr = mptr;
3970                 } else {
3971                     dptr = ar9300_eeprom_struct_default_find_by_id(reference);
3972                     if (dptr == 0) {
3973                         HALDEBUG(ah, HAL_DEBUG_EEPROM,
3974                             "%s: cant find reference eeprom struct %d\n",
3975                             __func__, reference);
3976                         break;
3977                     }
3978                     OS_MEMCPY(mptr, dptr, mdata_size);
3979                 }
3980
3981                 HALDEBUG(ah, HAL_DEBUG_EEPROM,
3982                     "%s: restore eeprom %d: block, reference %d, length %d\n",
3983                     __func__, it, reference, length);
3984                 (void) ar9300_uncompress_block(ah,
3985                     (u_int8_t *) mptr, mdata_size,
3986                     (u_int8_t *) (word + compression_header_length), length);
3987                 restored = 1;
3988                 break;
3989             default:
3990                 HALDEBUG(ah, HAL_DEBUG_EEPROM,
3991                     "%s: unknown compression code %d\n", __func__, code);
3992                 break;
3993             }
3994         } else {
3995             HALDEBUG(ah, HAL_DEBUG_EEPROM,
3996                 "%s: skipping block with bad checksum\n", __func__);
3997         }
3998         cptr -= compression_header_length + osize + compression_checksum_length;
3999     }
4000
4001     if (!restored) {
4002         cptr = -1;
4003     }
4004     return cptr;
4005 }
4006
4007 static int
4008 ar9300_eeprom_restore_from_dram(struct ath_hal *ah, ar9300_eeprom_t *mptr,
4009     int mdata_size)
4010 {
4011     struct ath_hal_9300 *ahp = AH9300(ah);
4012 #if !defined(USE_PLATFORM_FRAMEWORK)
4013     char *cal_ptr;
4014 #endif
4015
4016     HALASSERT(mdata_size > 0);
4017
4018     /* if cal_in_flash is AH_TRUE, the address sent by LMAC to HAL
4019        (i.e. ah->ah_st) is corresponding to Flash. so return from 
4020        here if ar9300_eep_data_in_flash(ah) returns AH_TRUE */
4021     if(ar9300_eep_data_in_flash(ah))
4022         return -1;
4023
4024 #if 0
4025     /* check if LMAC sent DRAM address is valid */
4026     if (!(uintptr_t)(AH_PRIVATE(ah)->ah_st)) {
4027         return -1;
4028     }
4029 #endif
4030
4031     /* When calibration data is from host, Host will copy the 
4032        compressed data to the predefined DRAM location saved at ah->ah_st */
4033 #if 0
4034     ath_hal_printf(ah, "Restoring Cal data from DRAM\n");
4035     ahp->ah_cal_mem = OS_REMAP((uintptr_t)(AH_PRIVATE(ah)->ah_st), 
4036                                                         HOST_CALDATA_SIZE);
4037 #endif
4038     if (!ahp->ah_cal_mem)
4039     {
4040        HALDEBUG(ah, HAL_DEBUG_EEPROM,"%s: can't remap dram region\n", __func__);
4041        return -1;
4042     }
4043 #if !defined(USE_PLATFORM_FRAMEWORK)
4044     cal_ptr = &((char *)(ahp->ah_cal_mem))[AR9300_FLASH_CAL_START_OFFSET];
4045     OS_MEMCPY(mptr, cal_ptr, mdata_size);
4046 #else
4047     OS_MEMCPY(mptr, ahp->ah_cal_mem, mdata_size);
4048 #endif
4049
4050     if (mptr->eeprom_version   == 0xff ||
4051         mptr->template_version == 0xff ||
4052         mptr->eeprom_version   == 0    ||
4053         mptr->template_version == 0)
4054     {
4055         /* The board is uncalibrated */
4056         return -1;
4057     }
4058     if (mptr->eeprom_version != 0x2)
4059     {
4060         return -1;
4061     }
4062
4063     return mdata_size;
4064
4065 }
4066
4067 static int
4068 ar9300_eeprom_restore_from_flash(struct ath_hal *ah, ar9300_eeprom_t *mptr,
4069     int mdata_size)
4070 {
4071     struct ath_hal_9300 *ahp = AH9300(ah);
4072     char *cal_ptr;
4073
4074     HALASSERT(mdata_size > 0);
4075
4076     if (!ahp->ah_cal_mem) {
4077         return -1;
4078     }
4079
4080     ath_hal_printf(ah, "Restoring Cal data from Flash\n");
4081     /*
4082      * When calibration data is saved in flash, read
4083      * uncompressed eeprom structure from flash and return
4084      */
4085     cal_ptr = &((char *)(ahp->ah_cal_mem))[AR9300_FLASH_CAL_START_OFFSET];
4086     OS_MEMCPY(mptr, cal_ptr, mdata_size);
4087 #if 0
4088     ar9300_swap_eeprom((ar9300_eeprom_t *)mptr); DONE IN ar9300_restore()
4089 #endif
4090     if (mptr->eeprom_version   == 0xff ||
4091         mptr->template_version == 0xff ||
4092         mptr->eeprom_version   == 0    ||
4093         mptr->template_version == 0)
4094     {   
4095         /* The board is uncalibrated */
4096         return -1;
4097     } 
4098     if (mptr->eeprom_version != 0x2)
4099     {
4100         return -1;
4101     }
4102     return mdata_size;
4103 }
4104
4105 /*
4106  * Read the configuration data from the storage. We try the order with:
4107  * EEPROM, Flash, OTP. If all of above failed, use the default template.
4108  * The data can be put in any specified memory buffer.
4109  *
4110  * Returns -1 on error. 
4111  * Returns address of next memory location on success.
4112  */
4113 int
4114 ar9300_eeprom_restore_internal(struct ath_hal *ah, ar9300_eeprom_t *mptr,
4115     int mdata_size)
4116 {
4117     int nptr;
4118
4119     nptr = -1;    
4120
4121     if ((AH9300(ah)->calibration_data_try == calibration_data_none ||
4122          AH9300(ah)->calibration_data_try == calibration_data_dram) &&
4123          AH9300(ah)->try_dram && nptr < 0)
4124     {   
4125         ath_hal_printf(ah, "Restoring Cal data from DRAM\n");
4126         AH9300(ah)->calibration_data_source = calibration_data_dram;
4127         AH9300(ah)->calibration_data_source_address = 0;
4128         nptr = ar9300_eeprom_restore_from_dram(ah, mptr, mdata_size);
4129         if (nptr < 0) {
4130             AH9300(ah)->calibration_data_source = calibration_data_none;
4131             AH9300(ah)->calibration_data_source_address = 0;
4132         }
4133     }
4134     
4135     if ((AH9300(ah)->calibration_data_try == calibration_data_none ||
4136          AH9300(ah)->calibration_data_try == calibration_data_eeprom) &&
4137         AH9300(ah)->try_eeprom && nptr < 0)
4138     {
4139         /*
4140          * need to look at highest eeprom address as well as at
4141          * base_address=0x3ff where we used to write the data
4142          */
4143         ath_hal_printf(ah, "Restoring Cal data from EEPROM\n");
4144         AH9300(ah)->calibration_data_source = calibration_data_eeprom;
4145         if (AH9300(ah)->calibration_data_try_address != 0) {
4146             AH9300(ah)->calibration_data_source_address =
4147                 AH9300(ah)->calibration_data_try_address;
4148             nptr = ar9300_eeprom_restore_internal_address(
4149                 ah, mptr, mdata_size,
4150                 AH9300(ah)->calibration_data_source_address, 0xff);
4151         } else {
4152             AH9300(ah)->calibration_data_source_address =
4153                 ar9300_eeprom_base_address(ah);
4154             nptr = ar9300_eeprom_restore_internal_address(
4155                 ah, mptr, mdata_size,
4156                 AH9300(ah)->calibration_data_source_address, 0xff);
4157             if (nptr < 0 &&
4158                 AH9300(ah)->calibration_data_source_address != base_address)
4159             {
4160                 AH9300(ah)->calibration_data_source_address = base_address;
4161                 nptr = ar9300_eeprom_restore_internal_address(
4162                     ah, mptr, mdata_size,
4163                     AH9300(ah)->calibration_data_source_address, 0xff);
4164             }
4165         }
4166         if (nptr < 0) {
4167             AH9300(ah)->calibration_data_source = calibration_data_none;
4168             AH9300(ah)->calibration_data_source_address = 0;
4169         }
4170     }
4171
4172     /*
4173      * ##### should be an ifdef test for any AP usage,
4174      * either in driver or in nart
4175      */
4176     if ((AH9300(ah)->calibration_data_try == calibration_data_none ||
4177          AH9300(ah)->calibration_data_try == calibration_data_flash) &&
4178         AH9300(ah)->try_flash && nptr < 0)
4179     {
4180         ath_hal_printf(ah, "Restoring Cal data from Flash\n");
4181         AH9300(ah)->calibration_data_source = calibration_data_flash;
4182         /* how are we supposed to set this for flash? */
4183         AH9300(ah)->calibration_data_source_address = 0;
4184         nptr = ar9300_eeprom_restore_from_flash(ah, mptr, mdata_size);
4185         if (nptr < 0) {
4186             AH9300(ah)->calibration_data_source = calibration_data_none;
4187             AH9300(ah)->calibration_data_source_address = 0;
4188         }
4189     }
4190
4191     if ((AH9300(ah)->calibration_data_try == calibration_data_none ||
4192          AH9300(ah)->calibration_data_try == calibration_data_otp) &&
4193         AH9300(ah)->try_otp && nptr < 0)
4194     {
4195         ath_hal_printf(ah, "Restoring Cal data from OTP\n");
4196         AH9300(ah)->calibration_data_source = calibration_data_otp;
4197         if (AH9300(ah)->calibration_data_try_address != 0) {
4198             AH9300(ah)->calibration_data_source_address =
4199                 AH9300(ah)->calibration_data_try_address;
4200                 } else {
4201             AH9300(ah)->calibration_data_source_address =
4202                 ar9300_eeprom_base_address(ah);
4203                 }
4204         nptr = ar9300_eeprom_restore_internal_address(
4205             ah, mptr, mdata_size, AH9300(ah)->calibration_data_source_address, 0);
4206         if (nptr < 0) {
4207             AH9300(ah)->calibration_data_source = calibration_data_none;
4208             AH9300(ah)->calibration_data_source_address = 0;
4209         }
4210     }
4211
4212 #ifdef ATH_CAL_NAND_FLASH
4213     if ((AH9300(ah)->calibration_data_try == calibration_data_none ||
4214          AH9300(ah)->calibration_data_try == calibration_data_nand) &&
4215         AH9300(ah)->try_nand && nptr < 0)
4216     {
4217         AH9300(ah)->calibration_data_source = calibration_data_nand;
4218         AH9300(ah)->calibration_data_source_address = ((unsigned int)(AH_PRIVATE(ah)->ah_st)) + base_address_nand;
4219         if(ar9300_calibration_data_read(
4220             ah, AH9300(ah)->calibration_data_source_address, 
4221             (u_int8_t *)mptr, mdata_size) == AH_TRUE)
4222         {
4223             nptr = mdata_size;
4224         }
4225         /*nptr=ar9300EepromRestoreInternalAddress(ah, mptr, mdataSize, CalibrationDataSourceAddress);*/
4226         if(nptr < 0)
4227         {
4228             AH9300(ah)->calibration_data_source = calibration_data_none;
4229             AH9300(ah)->calibration_data_source_address = 0;
4230         }
4231     }
4232 #endif
4233     if (nptr < 0) {
4234         ath_hal_printf(ah, "%s[%d] No vaid CAL, calling default template\n",
4235             __func__, __LINE__);
4236         nptr = ar9300_eeprom_restore_something(ah, mptr, mdata_size);
4237     }
4238
4239     return nptr;
4240 }
4241
4242 /******************************************************************************/
4243 /*!
4244 **  \brief Eeprom Swapping Function
4245 **
4246 **  This function will swap the contents of the "longer" EEPROM data items
4247 **  to ensure they are consistent with the endian requirements for the platform
4248 **  they are being compiled for
4249 **
4250 **  \param eh    Pointer to the EEPROM data structure
4251 **  \return N/A
4252 */
4253 #if AH_BYTE_ORDER == AH_BIG_ENDIAN
4254 void
4255 ar9300_swap_eeprom(ar9300_eeprom_t *eep)
4256 {
4257     u_int32_t dword;
4258     u_int16_t word;
4259     int          i;
4260
4261     word = __bswap16(eep->base_eep_header.reg_dmn[0]);
4262     eep->base_eep_header.reg_dmn[0] = word;
4263
4264     word = __bswap16(eep->base_eep_header.reg_dmn[1]);
4265     eep->base_eep_header.reg_dmn[1] = word;
4266
4267     dword = __bswap32(eep->base_eep_header.swreg);
4268     eep->base_eep_header.swreg = dword;
4269
4270     dword = __bswap32(eep->modal_header_2g.ant_ctrl_common);
4271     eep->modal_header_2g.ant_ctrl_common = dword;
4272
4273     dword = __bswap32(eep->modal_header_2g.ant_ctrl_common2);
4274     eep->modal_header_2g.ant_ctrl_common2 = dword;
4275
4276     dword = __bswap32(eep->modal_header_2g.paprd_rate_mask_ht20);
4277     eep->modal_header_2g.paprd_rate_mask_ht20 = dword;
4278
4279     dword = __bswap32(eep->modal_header_2g.paprd_rate_mask_ht40);
4280     eep->modal_header_2g.paprd_rate_mask_ht40 = dword;
4281
4282     dword = __bswap32(eep->modal_header_5g.ant_ctrl_common);
4283     eep->modal_header_5g.ant_ctrl_common = dword;
4284
4285     dword = __bswap32(eep->modal_header_5g.ant_ctrl_common2);
4286     eep->modal_header_5g.ant_ctrl_common2 = dword;
4287
4288     dword = __bswap32(eep->modal_header_5g.paprd_rate_mask_ht20);
4289     eep->modal_header_5g.paprd_rate_mask_ht20 = dword;
4290
4291     dword = __bswap32(eep->modal_header_5g.paprd_rate_mask_ht40);
4292     eep->modal_header_5g.paprd_rate_mask_ht40 = dword;
4293
4294     for (i = 0; i < OSPREY_MAX_CHAINS; i++) {
4295         word = __bswap16(eep->modal_header_2g.ant_ctrl_chain[i]);
4296         eep->modal_header_2g.ant_ctrl_chain[i] = word;
4297
4298         word = __bswap16(eep->modal_header_5g.ant_ctrl_chain[i]);
4299         eep->modal_header_5g.ant_ctrl_chain[i] = word;
4300     }
4301 }
4302
4303 void ar9300_eeprom_template_swap(void)
4304 {
4305     int it;
4306     ar9300_eeprom_t *dptr;
4307
4308     for (it = 0; it < ARRAY_LENGTH(default9300); it++) {
4309         dptr = ar9300_eeprom_struct_default(it);
4310         if (dptr != 0) {
4311             ar9300_swap_eeprom(dptr);
4312         }
4313     }
4314 }
4315 #endif
4316
4317
4318 /*
4319  * Restore the configuration structure by reading the eeprom.
4320  * This function destroys any existing in-memory structure content.
4321  */
4322 HAL_BOOL
4323 ar9300_eeprom_restore(struct ath_hal *ah)
4324 {
4325     struct ath_hal_9300 *ahp = AH9300(ah);
4326     ar9300_eeprom_t *mptr;
4327     int mdata_size;
4328     HAL_BOOL status = AH_FALSE;
4329
4330     mptr = &ahp->ah_eeprom;
4331     mdata_size = ar9300_eeprom_struct_size();
4332
4333     if (mptr != 0 && mdata_size > 0) {
4334 #if AH_BYTE_ORDER == AH_BIG_ENDIAN
4335         ar9300_eeprom_template_swap();
4336         ar9300_swap_eeprom(mptr);
4337 #endif
4338         /*
4339          * At this point, mptr points to the eeprom data structure
4340          * in it's "default" state.  If this is big endian, swap the
4341          * data structures back to "little endian" form.
4342          */
4343         if (ar9300_eeprom_restore_internal(ah, mptr, mdata_size) >= 0) {
4344             status = AH_TRUE;
4345         }
4346
4347 #if AH_BYTE_ORDER == AH_BIG_ENDIAN
4348         /* Second Swap, back to Big Endian */
4349         ar9300_eeprom_template_swap();
4350         ar9300_swap_eeprom(mptr);
4351 #endif
4352
4353     }
4354     ahp->ah_2g_paprd_rate_mask_ht40 =
4355         mptr->modal_header_2g.paprd_rate_mask_ht40;
4356     ahp->ah_2g_paprd_rate_mask_ht20 =
4357         mptr->modal_header_2g.paprd_rate_mask_ht20;
4358     ahp->ah_5g_paprd_rate_mask_ht40 =
4359         mptr->modal_header_5g.paprd_rate_mask_ht40;
4360     ahp->ah_5g_paprd_rate_mask_ht20 =
4361         mptr->modal_header_5g.paprd_rate_mask_ht20;
4362     return status;
4363 }
4364
4365 int32_t ar9300_thermometer_get(struct ath_hal *ah)
4366 {
4367     struct ath_hal_9300 *ahp = AH9300(ah);
4368     int thermometer;
4369     thermometer =
4370         (ahp->ah_eeprom.base_eep_header.misc_configuration >> 1) & 0x3;
4371     thermometer--;
4372     return thermometer;
4373 }
4374
4375 HAL_BOOL ar9300_thermometer_apply(struct ath_hal *ah)
4376 {
4377     int thermometer = ar9300_thermometer_get(ah);
4378
4379 /* ch0_RXTX4 */
4380 /*#define AR_PHY_65NM_CH0_RXTX4       AR_PHY_65NM(ch0_RXTX4)*/
4381 #define AR_PHY_65NM_CH1_RXTX4       AR_PHY_65NM(ch1_RXTX4)
4382 #define AR_PHY_65NM_CH2_RXTX4       AR_PHY_65NM(ch2_RXTX4)
4383 /*#define AR_PHY_65NM_CH0_RXTX4_THERM_ON          0x10000000*/
4384 /*#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S        28*/
4385 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR_S      29
4386 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR        \
4387     (0x1<<AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR_S)
4388
4389     if (thermometer < 0) {
4390         OS_REG_RMW_FIELD(ah,
4391             AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 0);
4392         if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) {
4393             OS_REG_RMW_FIELD(ah,
4394                 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 0);
4395             if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
4396                 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4397                     AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 0);
4398             }
4399         }
4400         OS_REG_RMW_FIELD(ah,
4401             AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4402         if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) {
4403             OS_REG_RMW_FIELD(ah,
4404                 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4405             if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
4406                 OS_REG_RMW_FIELD(ah,
4407                     AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4408             }
4409         }
4410     } else {
4411         OS_REG_RMW_FIELD(ah,
4412             AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 1);
4413         if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) {
4414             OS_REG_RMW_FIELD(ah,
4415                 AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 1);
4416             if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
4417                 OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4418                     AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, 1);
4419             }
4420         }
4421         if (thermometer == 0) {
4422             OS_REG_RMW_FIELD(ah,
4423                 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 1);
4424             if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) {
4425                 OS_REG_RMW_FIELD(ah,
4426                     AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4427                 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
4428                     OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4429                         AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4430                 }
4431             }
4432         } else if (thermometer == 1) {
4433             OS_REG_RMW_FIELD(ah,
4434                 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4435             if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) {
4436                 OS_REG_RMW_FIELD(ah,
4437                     AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 1);
4438                 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
4439                     OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4440                         AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4441                 }
4442             }
4443         } else if (thermometer == 2) {
4444             OS_REG_RMW_FIELD(ah,
4445                 AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4446             if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah)) {
4447                 OS_REG_RMW_FIELD(ah,
4448                     AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_CH0_RXTX4_THERM_ON, 0);
4449                 if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
4450                     OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
4451                         AR_PHY_65NM_CH0_RXTX4_THERM_ON, 1);
4452                 }
4453             }
4454         }
4455     }
4456     return AH_TRUE;
4457 }
4458
4459 static int32_t ar9300_tuning_caps_params_get(struct ath_hal *ah)
4460 {
4461     int tuning_caps_params;
4462     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
4463     tuning_caps_params = eep->base_eep_header.params_for_tuning_caps[0];
4464     return tuning_caps_params;
4465 }
4466
4467 /*
4468  * Read the tuning caps params from eeprom and set to correct register.
4469  * To regulation the frequency accuracy.
4470  */
4471 HAL_BOOL ar9300_tuning_caps_apply(struct ath_hal *ah)
4472 {
4473     int tuning_caps_params;
4474     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
4475     tuning_caps_params = ar9300_tuning_caps_params_get(ah);
4476     if ((eep->base_eep_header.feature_enable & 0x40) >> 6) {
4477         tuning_caps_params &= 0x7f;
4478
4479         /* XXX TODO: ath9k skips it for Wasp and Honeybee/AR9531, not Poseidon */
4480         if (AR_SREV_POSEIDON(ah) || AR_SREV_WASP(ah)) {
4481             return AH_TRUE;
4482         } else if (AR_SREV_HORNET(ah)) {
4483             OS_REG_RMW_FIELD(ah,
4484                 AR_HORNET_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPINDAC,
4485                 tuning_caps_params);
4486             OS_REG_RMW_FIELD(ah,
4487                 AR_HORNET_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPOUTDAC,
4488                 tuning_caps_params);
4489         } else if (AR_SREV_SCORPION(ah)) {
4490             OS_REG_RMW_FIELD(ah,
4491                 AR_SCORPION_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPINDAC,
4492                 tuning_caps_params);
4493             OS_REG_RMW_FIELD(ah,
4494                 AR_SCORPION_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPOUTDAC,
4495                 tuning_caps_params);
4496         } else {
4497             OS_REG_RMW_FIELD(ah,
4498                 AR_OSPREY_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPINDAC,
4499                 tuning_caps_params);
4500             OS_REG_RMW_FIELD(ah,
4501                 AR_OSPREY_CH0_XTAL, AR_OSPREY_CHO_XTAL_CAPOUTDAC,
4502                 tuning_caps_params);
4503         }
4504
4505     }
4506     return AH_TRUE;
4507 }
4508
4509 /*
4510  * Read the tx_frame_to_xpa_on param from eeprom and apply the value to 
4511  * correct register.
4512  */
4513 HAL_BOOL ar9300_xpa_timing_control_apply(struct ath_hal *ah, HAL_BOOL is_2ghz)
4514 {
4515     u_int8_t xpa_timing_control;
4516     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
4517     if ((eep->base_eep_header.feature_enable & 0x80) >> 7) {
4518                 if (AR_SREV_OSPREY(ah) || AR_SREV_AR9580(ah) || AR_SREV_WASP(ah)) {
4519                         if (is_2ghz) {
4520                 xpa_timing_control = eep->modal_header_2g.tx_frame_to_xpa_on;
4521                 OS_REG_RMW_FIELD(ah,
4522                                                 AR_PHY_XPA_TIMING_CTL, AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON,
4523                                                 xpa_timing_control);
4524                         } else {
4525                 xpa_timing_control = eep->modal_header_5g.tx_frame_to_xpa_on;
4526                 OS_REG_RMW_FIELD(ah,
4527                                                 AR_PHY_XPA_TIMING_CTL, AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON,
4528                                                 xpa_timing_control);
4529                         }
4530                 }
4531         }
4532     return AH_TRUE;
4533 }
4534
4535
4536 /*
4537  * Read the xLNA_bias_strength param from eeprom and apply the value to 
4538  * correct register.
4539  */ 
4540 HAL_BOOL ar9300_x_lNA_bias_strength_apply(struct ath_hal *ah, HAL_BOOL is_2ghz)
4541 {
4542     u_int8_t x_lNABias;
4543     u_int32_t value = 0;
4544     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
4545
4546     if ((eep->base_eep_header.misc_configuration & 0x40) >> 6) {
4547         if (AR_SREV_OSPREY(ah)) {
4548             if (is_2ghz) {
4549                 x_lNABias = eep->modal_header_2g.xLNA_bias_strength;
4550             } else {
4551                 x_lNABias = eep->modal_header_5g.xLNA_bias_strength;
4552             }
4553             value = x_lNABias & ( 0x03 );       // bit0,1 for chain0
4554             OS_REG_RMW_FIELD(ah,
4555                                         AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS, value);
4556             value = (x_lNABias >> 2) & ( 0x03 );        // bit2,3 for chain1
4557             OS_REG_RMW_FIELD(ah,
4558                                         AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS, value);
4559             value = (x_lNABias >> 4) & ( 0x03 );        // bit4,5 for chain2
4560             OS_REG_RMW_FIELD(ah,
4561                                         AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS, value);
4562         }
4563     }
4564     return AH_TRUE;
4565 }
4566
4567
4568 /*
4569  * Read EEPROM header info and program the device for correct operation
4570  * given the channel value.
4571  */
4572 HAL_BOOL
4573 ar9300_eeprom_set_board_values(struct ath_hal *ah, const struct ieee80211_channel *chan)
4574 {
4575     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
4576
4577     ar9300_xpa_bias_level_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan));
4578
4579     ar9300_xpa_timing_control_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan));
4580
4581     ar9300_ant_ctrl_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan));
4582     ar9300_drive_strength_apply(ah);
4583
4584     ar9300_x_lNA_bias_strength_apply(ah, IEEE80211_IS_CHAN_2GHZ(chan));
4585
4586         /* wait for Poseidon internal regular turnning */
4587     /* for Hornet we move it before initPLL to avoid an access issue */
4588     /* Function not used when EMULATION. */
4589     if (!AR_SREV_HORNET(ah) && !AR_SREV_WASP(ah)) {
4590         ar9300_internal_regulator_apply(ah);
4591     }
4592
4593     ar9300_attenuation_apply(ah, ichan->channel);
4594     ar9300_quick_drop_apply(ah, ichan->channel);
4595     ar9300_thermometer_apply(ah);
4596     if(!AR_SREV_WASP(ah))
4597     {
4598         ar9300_tuning_caps_apply(ah);
4599     }
4600
4601     ar9300_tx_end_to_xpab_off_apply(ah, ichan->channel);
4602
4603     return AH_TRUE;
4604 }
4605
4606 u_int8_t *
4607 ar9300_eeprom_get_spur_chans_ptr(struct ath_hal *ah, HAL_BOOL is_2ghz)
4608 {
4609     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
4610
4611     if (is_2ghz) {
4612         return &(eep->modal_header_2g.spur_chans[0]);
4613     } else {
4614         return &(eep->modal_header_5g.spur_chans[0]);
4615     }
4616 }
4617
4618 static u_int8_t ar9300_eeprom_get_tx_gain_table_number_max(struct ath_hal *ah)
4619 {
4620     unsigned long tx_gain_table_max;
4621     tx_gain_table_max = OS_REG_READ_FIELD(ah,
4622         AR_PHY_TPC_7, AR_PHY_TPC_7_TX_GAIN_TABLE_MAX);
4623     return tx_gain_table_max;
4624 }
4625
4626 u_int8_t ar9300_eeprom_tx_gain_table_index_max_apply(struct ath_hal *ah, u_int16_t channel)
4627 {
4628     unsigned int index;
4629     ar9300_eeprom_t *ahp_Eeprom;
4630     struct ath_hal_9300 *ahp = AH9300(ah);
4631
4632     ahp_Eeprom = &ahp->ah_eeprom;
4633
4634     if (ahp_Eeprom->base_ext1.misc_enable == 0)
4635         return AH_FALSE;
4636
4637     if (channel < 4000) 
4638     {
4639         index = ahp_Eeprom->modal_header_2g.tx_gain_cap;
4640     }
4641     else
4642     {
4643         index = ahp_Eeprom->modal_header_5g.tx_gain_cap;
4644     }
4645
4646     OS_REG_RMW_FIELD(ah,
4647         AR_PHY_TPC_7, AR_PHY_TPC_7_TX_GAIN_TABLE_MAX, index);
4648     return AH_TRUE;
4649 }
4650
4651 static u_int8_t ar9300_eeprom_get_pcdac_tx_gain_table_i(struct ath_hal *ah, 
4652                                                int i, u_int8_t *pcdac)
4653 {
4654     unsigned long tx_gain;
4655     u_int8_t tx_gain_table_max;
4656     tx_gain_table_max = ar9300_eeprom_get_tx_gain_table_number_max(ah);
4657     if (i <= 0 || i > tx_gain_table_max) {
4658         *pcdac = 0;
4659         return AH_FALSE;
4660     }
4661
4662     tx_gain = OS_REG_READ(ah, AR_PHY_TXGAIN_TAB(1) + i * 4);
4663     *pcdac = ((tx_gain >> 24) & 0xff);
4664     return AH_TRUE;
4665 }
4666
4667 u_int8_t ar9300_eeprom_set_tx_gain_cap(struct ath_hal *ah, 
4668                                                int *tx_gain_max)
4669 // pcdac read back from reg, read back value depends on reset 2GHz/5GHz ini 
4670 // tx_gain_table, this function will be called twice after each 
4671 // band's calibration.
4672 // after 2GHz cal, tx_gain_max[0] has 2GHz, calibration max txgain, 
4673 // tx_gain_max[1]=-100
4674 // after 5GHz cal, tx_gain_max[0],tx_gain_max[1] have calibration 
4675 // value for both band
4676 // reset is on 5GHz, reg reading from tx_gain_table is for 5GHz,
4677 // so program can't recalculate 2g.tx_gain_cap at this point.
4678 {
4679     int i = 0, ig, im = 0;
4680     u_int8_t pcdac = 0;
4681     u_int8_t tx_gain_table_max;
4682     ar9300_eeprom_t *ahp_Eeprom;
4683     struct ath_hal_9300 *ahp = AH9300(ah);
4684
4685     ahp_Eeprom = &ahp->ah_eeprom;
4686
4687     if (ahp_Eeprom->base_ext1.misc_enable == 0)
4688         return AH_FALSE;
4689
4690     tx_gain_table_max = ar9300_eeprom_get_tx_gain_table_number_max(ah);
4691
4692     for (i = 0; i < 2; i++) {
4693         if (tx_gain_max[i]>-100) {      // -100 didn't cal that band.
4694             if ( i== 0) {
4695                 if (tx_gain_max[1]>-100) {
4696                     continue;
4697                     // both band are calibrated, skip 2GHz 2g.tx_gain_cap reset
4698                 }
4699             }
4700             for (ig = 1; ig <= tx_gain_table_max; ig++) {
4701                 if (ah != 0 && ah->ah_reset != 0)
4702                 {
4703                     ar9300_eeprom_get_pcdac_tx_gain_table_i(ah, ig, &pcdac);
4704                     if (pcdac >= tx_gain_max[i])
4705                         break;
4706                 }
4707             }
4708             if (ig+1 <= tx_gain_table_max) {
4709                 if (pcdac == tx_gain_max[i])
4710                     im = ig;
4711                 else
4712                     im = ig + 1;
4713                 if (i == 0) {
4714                     ahp_Eeprom->modal_header_2g.tx_gain_cap = im;
4715                 } else {
4716                     ahp_Eeprom->modal_header_5g.tx_gain_cap = im;
4717                 }
4718             } else {
4719                 if (i == 0) {
4720                     ahp_Eeprom->modal_header_2g.tx_gain_cap = ig;
4721                 } else {
4722                     ahp_Eeprom->modal_header_5g.tx_gain_cap = ig;
4723                 }
4724             }
4725         }
4726     }
4727     return AH_TRUE;
4728 }