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} | |