Deleted Added
full compact
ar9285_reset.c (217631) ar9285_reset.c (219393)
1/*
2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3 * Copyright (c) 2002-2008 Atheros Communications, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
1/*
2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3 * Copyright (c) 2002-2008 Atheros Communications, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 * $FreeBSD: head/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c 217631 2011-01-20 09:03:40Z adrian $
17 * $FreeBSD: head/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c 219393 2011-03-08 06:59:59Z adrian $
18 */
19
20/*
21 * This is almost the same as ar5416_reset.c but uses the v4k EEPROM and
22 * supports only 2Ghz operation.
23 */
24
25#include "opt_ah.h"

--- 36 unchanged lines hidden (view full) ---

62static HAL_BOOL ar9285FillVpdTable(uint8_t, uint8_t, uint8_t *, uint8_t *,
63 uint16_t, uint8_t *);
64static void ar9285GetGainBoundariesAndPdadcs(struct ath_hal *ah,
65 const struct ieee80211_channel *chan, CAL_DATA_PER_FREQ_4K *pRawDataSet,
66 uint8_t * bChans, uint16_t availPiers,
67 uint16_t tPdGainOverlap, int16_t *pMinCalPower,
68 uint16_t * pPdGainBoundaries, uint8_t * pPDADCValues,
69 uint16_t numXpdGains);
18 */
19
20/*
21 * This is almost the same as ar5416_reset.c but uses the v4k EEPROM and
22 * supports only 2Ghz operation.
23 */
24
25#include "opt_ah.h"

--- 36 unchanged lines hidden (view full) ---

62static HAL_BOOL ar9285FillVpdTable(uint8_t, uint8_t, uint8_t *, uint8_t *,
63 uint16_t, uint8_t *);
64static void ar9285GetGainBoundariesAndPdadcs(struct ath_hal *ah,
65 const struct ieee80211_channel *chan, CAL_DATA_PER_FREQ_4K *pRawDataSet,
66 uint8_t * bChans, uint16_t availPiers,
67 uint16_t tPdGainOverlap, int16_t *pMinCalPower,
68 uint16_t * pPdGainBoundaries, uint8_t * pPDADCValues,
69 uint16_t numXpdGains);
70static HAL_BOOL getLowerUpperIndex(uint8_t target, uint8_t *pList,
71 uint16_t listSize, uint16_t *indexL, uint16_t *indexR);
72static uint16_t ar9285GetMaxEdgePower(uint16_t, CAL_CTL_EDGES *);
73
74/* XXX gag, this is sick */
75typedef enum Ar5416_Rates {
76 rate6mb, rate9mb, rate12mb, rate18mb,
77 rate24mb, rate36mb, rate48mb, rate54mb,
78 rate1l, rate2l, rate2s, rate5_5l,
79 rate5_5s, rate11l, rate11s, rateXr,

--- 70 unchanged lines hidden (view full) ---

150 ahp->ah_txPowerIndexOffset = txPowerIndexOffset;
151
152 /*
153 * txPowerIndexOffset is set by the SetPowerTable() call -
154 * adjust the rate table (0 offset if rates EEPROM not loaded)
155 */
156 for (i = 0; i < N(ratesArray); i++) {
157 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
70static uint16_t ar9285GetMaxEdgePower(uint16_t, CAL_CTL_EDGES *);
71
72/* XXX gag, this is sick */
73typedef enum Ar5416_Rates {
74 rate6mb, rate9mb, rate12mb, rate18mb,
75 rate24mb, rate36mb, rate48mb, rate54mb,
76 rate1l, rate2l, rate2s, rate5_5l,
77 rate5_5s, rate11l, rate11s, rateXr,

--- 70 unchanged lines hidden (view full) ---

148 ahp->ah_txPowerIndexOffset = txPowerIndexOffset;
149
150 /*
151 * txPowerIndexOffset is set by the SetPowerTable() call -
152 * adjust the rate table (0 offset if rates EEPROM not loaded)
153 */
154 for (i = 0; i < N(ratesArray); i++) {
155 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
156 /* -5 dBm offset for Merlin and later; this includes Kite */
157 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
158 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
159 ratesArray[i] = AR5416_MAX_RATE_POWER;
158 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
159 ratesArray[i] = AR5416_MAX_RATE_POWER;
160 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2;
160 if (ratesArray[i] < 0)
161 ratesArray[i] = 0;
161 }
162
163#ifdef AH_EEPROM_DUMP
164 ar5416PrintPowerPerRate(ah, ratesArray);
165#endif
166
167 /* Write the OFDM power per rate set */
168 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,

--- 378 unchanged lines hidden (view full) ---

547ar9285SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom_4k *pEepData,
548 const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset)
549{
550 CAL_DATA_PER_FREQ_4K *pRawDataset;
551 uint8_t *pCalBChans = AH_NULL;
552 uint16_t pdGainOverlap_t2;
553 static uint8_t pdadcValues[AR5416_NUM_PDADC_VALUES];
554 uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK];
162 }
163
164#ifdef AH_EEPROM_DUMP
165 ar5416PrintPowerPerRate(ah, ratesArray);
166#endif
167
168 /* Write the OFDM power per rate set */
169 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,

--- 378 unchanged lines hidden (view full) ---

548ar9285SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom_4k *pEepData,
549 const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset)
550{
551 CAL_DATA_PER_FREQ_4K *pRawDataset;
552 uint8_t *pCalBChans = AH_NULL;
553 uint16_t pdGainOverlap_t2;
554 static uint8_t pdadcValues[AR5416_NUM_PDADC_VALUES];
555 uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK];
555 uint16_t numPiers, i, j;
556 uint16_t numPiers, i;
556 int16_t tMinCalPower;
557 uint16_t numXpdGain, xpdMask;
557 int16_t tMinCalPower;
558 uint16_t numXpdGain, xpdMask;
558 uint16_t xpdGainValues[AR5416_4K_NUM_PD_GAINS];
559 uint32_t reg32, regOffset, regChainOffset;
559 uint16_t xpdGainValues[4]; /* v4k eeprom has 2; the other two stay 0 */
560 uint32_t regChainOffset;
560
561 OS_MEMZERO(xpdGainValues, sizeof(xpdGainValues));
562
563 xpdMask = pEepData->modalHeader.xpdGain;
564
565 if (IS_EEP_MINOR_V2(ah)) {
566 pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap;
567 } else {
568 pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5), AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
569 }
570
571 pCalBChans = pEepData->calFreqPier2G;
572 numPiers = AR5416_4K_NUM_2G_CAL_PIERS;
573 numXpdGain = 0;
561
562 OS_MEMZERO(xpdGainValues, sizeof(xpdGainValues));
563
564 xpdMask = pEepData->modalHeader.xpdGain;
565
566 if (IS_EEP_MINOR_V2(ah)) {
567 pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap;
568 } else {
569 pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5), AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
570 }
571
572 pCalBChans = pEepData->calFreqPier2G;
573 numPiers = AR5416_4K_NUM_2G_CAL_PIERS;
574 numXpdGain = 0;
575
574 /* Calculate the value of xpdgains from the xpdGain Mask */
575 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
576 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
577 if (numXpdGain >= AR5416_4K_NUM_PD_GAINS) {
578 HALASSERT(0);
579 break;
580 }
581 xpdGainValues[numXpdGain] = (uint16_t)(AR5416_PD_GAINS_IN_MASK - i);
582 numXpdGain++;
583 }
584 }
585
586 /* Write the detector gain biases and their number */
576 /* Calculate the value of xpdgains from the xpdGain Mask */
577 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
578 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
579 if (numXpdGain >= AR5416_4K_NUM_PD_GAINS) {
580 HALASSERT(0);
581 break;
582 }
583 xpdGainValues[numXpdGain] = (uint16_t)(AR5416_PD_GAINS_IN_MASK - i);
584 numXpdGain++;
585 }
586 }
587
588 /* Write the detector gain biases and their number */
587 OS_REG_WRITE(ah, AR_PHY_TPCRG1, (OS_REG_READ(ah, AR_PHY_TPCRG1) &
588 ~(AR_PHY_TPCRG1_NUM_PD_GAIN | AR_PHY_TPCRG1_PD_GAIN_1 | AR_PHY_TPCRG1_PD_GAIN_2 | AR_PHY_TPCRG1_PD_GAIN_3)) |
589 SM(numXpdGain - 1, AR_PHY_TPCRG1_NUM_PD_GAIN) | SM(xpdGainValues[0], AR_PHY_TPCRG1_PD_GAIN_1 ) |
590 SM(xpdGainValues[1], AR_PHY_TPCRG1_PD_GAIN_2) | SM(0, AR_PHY_TPCRG1_PD_GAIN_3));
589 ar5416WriteDetectorGainBiases(ah, numXpdGain, xpdGainValues);
591
592 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
590
591 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
593
594 if (AR_SREV_OWL_20_OR_LATER(ah) &&
595 ( AH5416(ah)->ah_rx_chainmask == 0x5 || AH5416(ah)->ah_tx_chainmask == 0x5) && (i != 0)) {
596 /* Regs are swapped from chain 2 to 1 for 5416 2_0 with
597 * only chains 0 and 2 populated
598 */
599 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
600 } else {
601 regChainOffset = i * 0x1000;
602 }
603
592 regChainOffset = ar5416GetRegChainOffset(ah, i);
604 if (pEepData->baseEepHeader.txMask & (1 << i)) {
605 pRawDataset = pEepData->calPierData2G[i];
606
607 ar9285GetGainBoundariesAndPdadcs(ah, chan, pRawDataset,
608 pCalBChans, numPiers,
609 pdGainOverlap_t2,
610 &tMinCalPower, gainBoundaries,
611 pdadcValues, numXpdGain);
612
613 if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) {
614 /*
615 * Note the pdadc table may not start at 0 dBm power, could be
616 * negative or greater than 0. Need to offset the power
617 * values by the amount of minPower for griffin
618 */
593 if (pEepData->baseEepHeader.txMask & (1 << i)) {
594 pRawDataset = pEepData->calPierData2G[i];
595
596 ar9285GetGainBoundariesAndPdadcs(ah, chan, pRawDataset,
597 pCalBChans, numPiers,
598 pdGainOverlap_t2,
599 &tMinCalPower, gainBoundaries,
600 pdadcValues, numXpdGain);
601
602 if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) {
603 /*
604 * Note the pdadc table may not start at 0 dBm power, could be
605 * negative or greater than 0. Need to offset the power
606 * values by the amount of minPower for griffin
607 */
619
620 OS_REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
621 SM(pdGainOverlap_t2, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
622 SM(gainBoundaries[0], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) |
623 SM(gainBoundaries[1], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) |
624 SM(gainBoundaries[2], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) |
625 SM(gainBoundaries[3], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
608 ar5416SetGainBoundariesClosedLoop(ah, regChainOffset, pdGainOverlap_t2, gainBoundaries);
626 }
627
628 /* Write the power values into the baseband power table */
609 }
610
611 /* Write the power values into the baseband power table */
629 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
630
631 for (j = 0; j < 32; j++) {
632 reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0) |
633 ((pdadcValues[4*j + 1] & 0xFF) << 8) |
634 ((pdadcValues[4*j + 2] & 0xFF) << 16) |
635 ((pdadcValues[4*j + 3] & 0xFF) << 24) ;
636 OS_REG_WRITE(ah, regOffset, reg32);
637
638#ifdef PDADC_DUMP
639 ath_hal_printf(ah, "PDADC: Chain %d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d |\n",
640 i,
641 4*j, pdadcValues[4*j],
642 4*j+1, pdadcValues[4*j + 1],
643 4*j+2, pdadcValues[4*j + 2],
644 4*j+3, pdadcValues[4*j + 3]);
645#endif
646 regOffset += 4;
647 }
612 ar5416WritePdadcValues(ah, regChainOffset, pdadcValues);
648 }
649 }
650 *pTxPowerIndexOffset = 0;
651
652 return AH_TRUE;
653}
654
655static void

--- 198 unchanged lines hidden (view full) ---

854 if (srcRight == srcLeft) {
855 rv = targetLeft;
856 } else {
857 rv = (int16_t)( ((target - srcLeft) * targetRight +
858 (srcRight - target) * targetLeft) / (srcRight - srcLeft) );
859 }
860 return rv;
861}
613 }
614 }
615 *pTxPowerIndexOffset = 0;
616
617 return AH_TRUE;
618}
619
620static void

--- 198 unchanged lines hidden (view full) ---

819 if (srcRight == srcLeft) {
820 rv = targetLeft;
821 } else {
822 rv = (int16_t)( ((target - srcLeft) * targetRight +
823 (srcRight - target) * targetLeft) / (srcRight - srcLeft) );
824 }
825 return rv;
826}
862
863HAL_BOOL
864getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize,
865 uint16_t *indexL, uint16_t *indexR)
866{
867 uint16_t i;
868
869 /*
870 * Check first and last elements for beyond ordered array cases.
871 */
872 if (target <= pList[0]) {
873 *indexL = *indexR = 0;
874 return AH_TRUE;
875 }
876 if (target >= pList[listSize-1]) {
877 *indexL = *indexR = (uint16_t)(listSize - 1);
878 return AH_TRUE;
879 }
880
881 /* look for value being near or between 2 values in list */
882 for (i = 0; i < listSize - 1; i++) {
883 /*
884 * If value is close to the current value of the list
885 * then target is not between values, it is one of the values
886 */
887 if (pList[i] == target) {
888 *indexL = *indexR = i;
889 return AH_TRUE;
890 }
891 /*
892 * Look for value being between current value and next value
893 * if so return these 2 values
894 */
895 if (target < pList[i + 1]) {
896 *indexL = i;
897 *indexR = (uint16_t)(i + 1);
898 return AH_FALSE;
899 }
900 }
901 HALASSERT(0);
902 *indexL = *indexR = 0;
903 return AH_FALSE;
904}