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/ar5416/ar5416_reset.c 219218 2011-03-03 08:38:31Z adrian $
| 17 * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c 219393 2011-03-08 06:59:59Z adrian $
|
18 */ 19#include "opt_ah.h" 20 21#include "ah.h" 22#include "ah_internal.h" 23#include "ah_devid.h" 24 25#include "ah_eeprom_v14.h" 26 27#include "ar5416/ar5416.h" 28#include "ar5416/ar5416reg.h" 29#include "ar5416/ar5416phy.h" 30 31/* Eeprom versioning macros. Returns true if the version is equal or newer than the ver specified */ 32#define EEP_MINOR(_ah) \ 33 (AH_PRIVATE(_ah)->ah_eeversion & AR5416_EEP_VER_MINOR_MASK) 34#define IS_EEP_MINOR_V2(_ah) (EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_2) 35#define IS_EEP_MINOR_V3(_ah) (EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_3) 36 37/* Additional Time delay to wait after activiting the Base band */ 38#define BASE_ACTIVATE_DELAY 100 /* 100 usec */ 39#define PLL_SETTLE_DELAY 300 /* 300 usec */ 40#define RTC_PLL_SETTLE_DELAY 1000 /* 1 ms */ 41 42static void ar5416InitDMA(struct ath_hal *ah); 43static void ar5416InitBB(struct ath_hal *ah, const struct ieee80211_channel *); 44static void ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode); 45static void ar5416InitQoS(struct ath_hal *ah); 46static void ar5416InitUserSettings(struct ath_hal *ah); 47static void ar5416UpdateChainMasks(struct ath_hal *ah, HAL_BOOL is_ht); 48static void ar5416OverrideIni(struct ath_hal *ah, const struct ieee80211_channel *); 49 50#if 0 51static HAL_BOOL ar5416ChannelChange(struct ath_hal *, const struct ieee80211_channel *); 52#endif 53static void ar5416SetDeltaSlope(struct ath_hal *, const struct ieee80211_channel *); 54 55static HAL_BOOL ar5416SetResetPowerOn(struct ath_hal *ah); 56static HAL_BOOL ar5416SetReset(struct ath_hal *ah, int type); 57static void ar5416InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan); 58static HAL_BOOL ar5416SetPowerPerRateTable(struct ath_hal *ah, 59 struct ar5416eeprom *pEepData, 60 const struct ieee80211_channel *chan, int16_t *ratesArray, 61 uint16_t cfgCtl, uint16_t AntennaReduction, 62 uint16_t twiceMaxRegulatoryPower, 63 uint16_t powerLimit);
| 18 */ 19#include "opt_ah.h" 20 21#include "ah.h" 22#include "ah_internal.h" 23#include "ah_devid.h" 24 25#include "ah_eeprom_v14.h" 26 27#include "ar5416/ar5416.h" 28#include "ar5416/ar5416reg.h" 29#include "ar5416/ar5416phy.h" 30 31/* Eeprom versioning macros. Returns true if the version is equal or newer than the ver specified */ 32#define EEP_MINOR(_ah) \ 33 (AH_PRIVATE(_ah)->ah_eeversion & AR5416_EEP_VER_MINOR_MASK) 34#define IS_EEP_MINOR_V2(_ah) (EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_2) 35#define IS_EEP_MINOR_V3(_ah) (EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_3) 36 37/* Additional Time delay to wait after activiting the Base band */ 38#define BASE_ACTIVATE_DELAY 100 /* 100 usec */ 39#define PLL_SETTLE_DELAY 300 /* 300 usec */ 40#define RTC_PLL_SETTLE_DELAY 1000 /* 1 ms */ 41 42static void ar5416InitDMA(struct ath_hal *ah); 43static void ar5416InitBB(struct ath_hal *ah, const struct ieee80211_channel *); 44static void ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode); 45static void ar5416InitQoS(struct ath_hal *ah); 46static void ar5416InitUserSettings(struct ath_hal *ah); 47static void ar5416UpdateChainMasks(struct ath_hal *ah, HAL_BOOL is_ht); 48static void ar5416OverrideIni(struct ath_hal *ah, const struct ieee80211_channel *); 49 50#if 0 51static HAL_BOOL ar5416ChannelChange(struct ath_hal *, const struct ieee80211_channel *); 52#endif 53static void ar5416SetDeltaSlope(struct ath_hal *, const struct ieee80211_channel *); 54 55static HAL_BOOL ar5416SetResetPowerOn(struct ath_hal *ah); 56static HAL_BOOL ar5416SetReset(struct ath_hal *ah, int type); 57static void ar5416InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan); 58static HAL_BOOL ar5416SetPowerPerRateTable(struct ath_hal *ah, 59 struct ar5416eeprom *pEepData, 60 const struct ieee80211_channel *chan, int16_t *ratesArray, 61 uint16_t cfgCtl, uint16_t AntennaReduction, 62 uint16_t twiceMaxRegulatoryPower, 63 uint16_t powerLimit);
|
64static HAL_BOOL ar5416SetPowerCalTable(struct ath_hal *ah, 65 struct ar5416eeprom *pEepData, 66 const struct ieee80211_channel *chan, 67 int16_t *pTxPowerIndexOffset);
| |
68static uint16_t ar5416GetMaxEdgePower(uint16_t freq, 69 CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz); 70 71static int16_t interpolate(uint16_t target, uint16_t srcLeft, 72 uint16_t srcRight, int16_t targetLeft, int16_t targetRight); 73static void ar5416Set11nRegs(struct ath_hal *ah, const struct ieee80211_channel *chan);
| 64static uint16_t ar5416GetMaxEdgePower(uint16_t freq, 65 CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz); 66 67static int16_t interpolate(uint16_t target, uint16_t srcLeft, 68 uint16_t srcRight, int16_t targetLeft, int16_t targetRight); 69static void ar5416Set11nRegs(struct ath_hal *ah, const struct ieee80211_channel *chan);
|
74static void ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah, 75 const struct ieee80211_channel *chan, CAL_DATA_PER_FREQ *pRawDataSet, 76 uint8_t * bChans, uint16_t availPiers, 77 uint16_t tPdGainOverlap, int16_t *pMinCalPower, 78 uint16_t * pPdGainBoundaries, uint8_t * pPDADCValues, 79 uint16_t numXpdGains); 80static HAL_BOOL getLowerUpperIndex(uint8_t target, uint8_t *pList, 81 uint16_t listSize, uint16_t *indexL, uint16_t *indexR);
| |
82static HAL_BOOL ar5416FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, 83 uint8_t *pPwrList, uint8_t *pVpdList, 84 uint16_t numIntercepts, uint8_t *pRetVpdList); 85 86/* 87 * Places the device in and out of reset and then places sane 88 * values in the registers based on EEPROM config, initialization 89 * vectors (as determined by the mode), and station configuration 90 * 91 * bChannelChange is used to preserve DMA/PCU registers across 92 * a HW Reset during channel change. 93 */ 94HAL_BOOL 95ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode, 96 struct ieee80211_channel *chan, 97 HAL_BOOL bChannelChange, HAL_STATUS *status) 98{ 99#define N(a) (sizeof (a) / sizeof (a[0])) 100#define FAIL(_code) do { ecode = _code; goto bad; } while (0) 101 struct ath_hal_5212 *ahp = AH5212(ah); 102 HAL_CHANNEL_INTERNAL *ichan; 103 uint32_t saveDefAntenna, saveLedState; 104 uint32_t macStaId1; 105 uint16_t rfXpdGain[2]; 106 HAL_STATUS ecode; 107 uint32_t powerVal, rssiThrReg; 108 uint32_t ackTpcPow, ctsTpcPow, chirpTpcPow; 109 int i; 110 111 OS_MARK(ah, AH_MARK_RESET, bChannelChange); 112 113 /* Bring out of sleep mode */ 114 if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) { 115 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip did not wakeup\n", 116 __func__); 117 FAIL(HAL_EIO); 118 } 119 120 /* 121 * Map public channel to private. 122 */ 123 ichan = ath_hal_checkchannel(ah, chan); 124 if (ichan == AH_NULL) 125 FAIL(HAL_EINVAL); 126 switch (opmode) { 127 case HAL_M_STA: 128 case HAL_M_IBSS: 129 case HAL_M_HOSTAP: 130 case HAL_M_MONITOR: 131 break; 132 default: 133 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n", 134 __func__, opmode); 135 FAIL(HAL_EINVAL); 136 break; 137 } 138 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); 139 140 /* XXX Turn on fast channel change for 5416 */ 141 /* 142 * Preserve the bmiss rssi threshold and count threshold 143 * across resets 144 */ 145 rssiThrReg = OS_REG_READ(ah, AR_RSSI_THR); 146 /* If reg is zero, first time thru set to default val */ 147 if (rssiThrReg == 0) 148 rssiThrReg = INIT_RSSI_THR; 149 150 /* 151 * Preserve the antenna on a channel change 152 */ 153 saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA); 154 if (saveDefAntenna == 0) /* XXX magic constants */ 155 saveDefAntenna = 1; 156 157 /* Save hardware flag before chip reset clears the register */ 158 macStaId1 = OS_REG_READ(ah, AR_STA_ID1) & 159 (AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT); 160 161 /* Save led state from pci config register */ 162 saveLedState = OS_REG_READ(ah, AR_MAC_LED) & 163 (AR_MAC_LED_ASSOC | AR_MAC_LED_MODE | 164 AR_MAC_LED_BLINK_THRESH_SEL | AR_MAC_LED_BLINK_SLOW); 165 166 if (!ar5416ChipReset(ah, chan)) { 167 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__); 168 FAIL(HAL_EIO); 169 } 170 171 /* Restore bmiss rssi & count thresholds */ 172 OS_REG_WRITE(ah, AR_RSSI_THR, rssiThrReg); 173 174 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 175 if (AR_SREV_MERLIN_10_OR_LATER(ah)) 176 OS_REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); 177 178 if (AR_SREV_KITE(ah)) { 179 uint32_t val; 180 val = OS_REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS); 181 val &= ~AR_PHY_RIFS_INIT_DELAY; 182 OS_REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val); 183 } 184 185 AH5416(ah)->ah_writeIni(ah, chan); 186 187 /* Override ini values (that can be overriden in this fashion) */ 188 ar5416OverrideIni(ah, chan); 189 190 /* Setup 11n MAC/Phy mode registers */ 191 ar5416Set11nRegs(ah, chan); 192 193 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 194 195 HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_DAG_CTRLCCK=0x%x\n", 196 __func__, OS_REG_READ(ah,AR_PHY_DAG_CTRLCCK)); 197 HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_ADC_CTL=0x%x\n", 198 __func__, OS_REG_READ(ah,AR_PHY_ADC_CTL)); 199 200 /* Set the mute mask to the correct default */ 201 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) 202 OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F); 203 204 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) { 205 /* Clear reg to alllow RX_CLEAR line debug */ 206 OS_REG_WRITE(ah, AR_PHY_BLUETOOTH, 0); 207 } 208 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) { 209#ifdef notyet 210 /* Enable burst prefetch for the data queues */ 211 OS_REG_RMW_FIELD(ah, AR_D_FPCTL, ... ); 212 /* Enable double-buffering */ 213 OS_REG_CLR_BIT(ah, AR_TXCFG, AR_TXCFG_DBL_BUF_DIS); 214#endif 215 } 216 217 /* 218 * Setup ah_tx_chainmask / ah_rx_chainmask before we fiddle 219 * with enabling the TX/RX radio chains. 220 */ 221 ar5416UpdateChainMasks(ah, IEEE80211_IS_CHAN_HT(chan)); 222 /* 223 * This routine swaps the analog chains - it should be done 224 * before any radio register twiddling is done. 225 */ 226 ar5416InitChainMasks(ah);
| 70static HAL_BOOL ar5416FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, 71 uint8_t *pPwrList, uint8_t *pVpdList, 72 uint16_t numIntercepts, uint8_t *pRetVpdList); 73 74/* 75 * Places the device in and out of reset and then places sane 76 * values in the registers based on EEPROM config, initialization 77 * vectors (as determined by the mode), and station configuration 78 * 79 * bChannelChange is used to preserve DMA/PCU registers across 80 * a HW Reset during channel change. 81 */ 82HAL_BOOL 83ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode, 84 struct ieee80211_channel *chan, 85 HAL_BOOL bChannelChange, HAL_STATUS *status) 86{ 87#define N(a) (sizeof (a) / sizeof (a[0])) 88#define FAIL(_code) do { ecode = _code; goto bad; } while (0) 89 struct ath_hal_5212 *ahp = AH5212(ah); 90 HAL_CHANNEL_INTERNAL *ichan; 91 uint32_t saveDefAntenna, saveLedState; 92 uint32_t macStaId1; 93 uint16_t rfXpdGain[2]; 94 HAL_STATUS ecode; 95 uint32_t powerVal, rssiThrReg; 96 uint32_t ackTpcPow, ctsTpcPow, chirpTpcPow; 97 int i; 98 99 OS_MARK(ah, AH_MARK_RESET, bChannelChange); 100 101 /* Bring out of sleep mode */ 102 if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) { 103 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip did not wakeup\n", 104 __func__); 105 FAIL(HAL_EIO); 106 } 107 108 /* 109 * Map public channel to private. 110 */ 111 ichan = ath_hal_checkchannel(ah, chan); 112 if (ichan == AH_NULL) 113 FAIL(HAL_EINVAL); 114 switch (opmode) { 115 case HAL_M_STA: 116 case HAL_M_IBSS: 117 case HAL_M_HOSTAP: 118 case HAL_M_MONITOR: 119 break; 120 default: 121 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n", 122 __func__, opmode); 123 FAIL(HAL_EINVAL); 124 break; 125 } 126 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); 127 128 /* XXX Turn on fast channel change for 5416 */ 129 /* 130 * Preserve the bmiss rssi threshold and count threshold 131 * across resets 132 */ 133 rssiThrReg = OS_REG_READ(ah, AR_RSSI_THR); 134 /* If reg is zero, first time thru set to default val */ 135 if (rssiThrReg == 0) 136 rssiThrReg = INIT_RSSI_THR; 137 138 /* 139 * Preserve the antenna on a channel change 140 */ 141 saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA); 142 if (saveDefAntenna == 0) /* XXX magic constants */ 143 saveDefAntenna = 1; 144 145 /* Save hardware flag before chip reset clears the register */ 146 macStaId1 = OS_REG_READ(ah, AR_STA_ID1) & 147 (AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT); 148 149 /* Save led state from pci config register */ 150 saveLedState = OS_REG_READ(ah, AR_MAC_LED) & 151 (AR_MAC_LED_ASSOC | AR_MAC_LED_MODE | 152 AR_MAC_LED_BLINK_THRESH_SEL | AR_MAC_LED_BLINK_SLOW); 153 154 if (!ar5416ChipReset(ah, chan)) { 155 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__); 156 FAIL(HAL_EIO); 157 } 158 159 /* Restore bmiss rssi & count thresholds */ 160 OS_REG_WRITE(ah, AR_RSSI_THR, rssiThrReg); 161 162 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 163 if (AR_SREV_MERLIN_10_OR_LATER(ah)) 164 OS_REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); 165 166 if (AR_SREV_KITE(ah)) { 167 uint32_t val; 168 val = OS_REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS); 169 val &= ~AR_PHY_RIFS_INIT_DELAY; 170 OS_REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val); 171 } 172 173 AH5416(ah)->ah_writeIni(ah, chan); 174 175 /* Override ini values (that can be overriden in this fashion) */ 176 ar5416OverrideIni(ah, chan); 177 178 /* Setup 11n MAC/Phy mode registers */ 179 ar5416Set11nRegs(ah, chan); 180 181 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 182 183 HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_DAG_CTRLCCK=0x%x\n", 184 __func__, OS_REG_READ(ah,AR_PHY_DAG_CTRLCCK)); 185 HALDEBUG(ah, HAL_DEBUG_RESET, ">>>2 %s: AR_PHY_ADC_CTL=0x%x\n", 186 __func__, OS_REG_READ(ah,AR_PHY_ADC_CTL)); 187 188 /* Set the mute mask to the correct default */ 189 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) 190 OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F); 191 192 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) { 193 /* Clear reg to alllow RX_CLEAR line debug */ 194 OS_REG_WRITE(ah, AR_PHY_BLUETOOTH, 0); 195 } 196 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) { 197#ifdef notyet 198 /* Enable burst prefetch for the data queues */ 199 OS_REG_RMW_FIELD(ah, AR_D_FPCTL, ... ); 200 /* Enable double-buffering */ 201 OS_REG_CLR_BIT(ah, AR_TXCFG, AR_TXCFG_DBL_BUF_DIS); 202#endif 203 } 204 205 /* 206 * Setup ah_tx_chainmask / ah_rx_chainmask before we fiddle 207 * with enabling the TX/RX radio chains. 208 */ 209 ar5416UpdateChainMasks(ah, IEEE80211_IS_CHAN_HT(chan)); 210 /* 211 * This routine swaps the analog chains - it should be done 212 * before any radio register twiddling is done. 213 */ 214 ar5416InitChainMasks(ah);
|
| 215 AH5416(ah)->ah_olcInit(ah);
|
227 228 /* Setup the transmit power values. */ 229 if (!ah->ah_setTxPower(ah, chan, rfXpdGain)) { 230 HALDEBUG(ah, HAL_DEBUG_ANY, 231 "%s: error init'ing transmit power\n", __func__); 232 FAIL(HAL_EIO); 233 } 234 235 /* Write the analog registers */ 236 if (!ahp->ah_rfHal->setRfRegs(ah, chan, 237 IEEE80211_IS_CHAN_2GHZ(chan) ? 2: 1, rfXpdGain)) { 238 HALDEBUG(ah, HAL_DEBUG_ANY, 239 "%s: ar5212SetRfRegs failed\n", __func__); 240 FAIL(HAL_EIO); 241 } 242 243 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ 244 if (IEEE80211_IS_CHAN_OFDM(chan)|| IEEE80211_IS_CHAN_HT(chan)) 245 ar5416SetDeltaSlope(ah, chan); 246 247 AH5416(ah)->ah_spurMitigate(ah, chan); 248 249 /* Setup board specific options for EEPROM version 3 */ 250 if (!ah->ah_setBoardValues(ah, chan)) { 251 HALDEBUG(ah, HAL_DEBUG_ANY, 252 "%s: error setting board options\n", __func__); 253 FAIL(HAL_EIO); 254 } 255 256 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 257 258 OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr)); 259 OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4) 260 | macStaId1 261 | AR_STA_ID1_RTS_USE_DEF 262 | ahp->ah_staId1Defaults 263 ); 264 ar5212SetOperatingMode(ah, opmode); 265 266 /* Set Venice BSSID mask according to current state */ 267 OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask)); 268 OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4)); 269 270 /* Restore previous led state */ 271 OS_REG_WRITE(ah, AR_MAC_LED, OS_REG_READ(ah, AR_MAC_LED) | saveLedState); 272 273 /* Restore previous antenna */ 274 OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); 275 276 /* then our BSSID */ 277 OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid)); 278 OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4)); 279 280 /* Restore bmiss rssi & count thresholds */ 281 OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr); 282 283 OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */ 284 285 if (!ar5212SetChannel(ah, chan)) 286 FAIL(HAL_EIO); 287 288 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 289 290 /* Set 1:1 QCU to DCU mapping for all queues */ 291 for (i = 0; i < AR_NUM_DCU; i++) 292 OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); 293 294 ahp->ah_intrTxqs = 0; 295 for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++) 296 ar5212ResetTxQueue(ah, i); 297 298 ar5416InitIMR(ah, opmode); 299 ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1); 300 ar5416InitQoS(ah); 301 ar5416InitUserSettings(ah); 302 303 /* 304 * disable seq number generation in hw 305 */ 306 OS_REG_WRITE(ah, AR_STA_ID1, 307 OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM); 308 309 ar5416InitDMA(ah); 310 311 /* 312 * program OBS bus to see MAC interrupts 313 */ 314 OS_REG_WRITE(ah, AR_OBS, 8); 315 316#ifdef AR5416_INT_MITIGATION 317 OS_REG_WRITE(ah, AR_MIRT, 0); 318 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); 319 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); 320#endif 321 322 ar5416InitBB(ah, chan); 323 324 /* Setup compression registers */ 325 ar5212SetCompRegs(ah); /* XXX not needed? */ 326 327 /* 328 * 5416 baseband will check the per rate power table 329 * and select the lower of the two 330 */ 331 ackTpcPow = 63; 332 ctsTpcPow = 63; 333 chirpTpcPow = 63; 334 powerVal = SM(ackTpcPow, AR_TPC_ACK) | 335 SM(ctsTpcPow, AR_TPC_CTS) | 336 SM(chirpTpcPow, AR_TPC_CHIRP); 337 OS_REG_WRITE(ah, AR_TPC, powerVal); 338 339 if (!ar5416InitCal(ah, chan)) 340 FAIL(HAL_ESELFTEST); 341 342 ar5416RestoreChainMask(ah); 343 344 AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */ 345 346 if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan)) 347 chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT; 348 349 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__); 350 351 OS_MARK(ah, AH_MARK_RESET_DONE, 0); 352 353 return AH_TRUE; 354bad: 355 OS_MARK(ah, AH_MARK_RESET_DONE, ecode); 356 if (status != AH_NULL) 357 *status = ecode; 358 return AH_FALSE; 359#undef FAIL 360#undef N 361} 362 363#if 0 364/* 365 * This channel change evaluates whether the selected hardware can 366 * perform a synthesizer-only channel change (no reset). If the 367 * TX is not stopped, or the RFBus cannot be granted in the given 368 * time, the function returns false as a reset is necessary 369 */ 370HAL_BOOL 371ar5416ChannelChange(struct ath_hal *ah, const structu ieee80211_channel *chan) 372{ 373 uint32_t ulCount; 374 uint32_t data, synthDelay, qnum; 375 uint16_t rfXpdGain[4]; 376 struct ath_hal_5212 *ahp = AH5212(ah); 377 HAL_CHANNEL_INTERNAL *ichan; 378 379 /* 380 * Map public channel to private. 381 */ 382 ichan = ath_hal_checkchannel(ah, chan); 383 384 /* TX must be stopped or RF Bus grant will not work */ 385 for (qnum = 0; qnum < AH_PRIVATE(ah)->ah_caps.halTotalQueues; qnum++) { 386 if (ar5212NumTxPending(ah, qnum)) { 387 HALDEBUG(ah, HAL_DEBUG_ANY, 388 "%s: frames pending on queue %d\n", __func__, qnum); 389 return AH_FALSE; 390 } 391 } 392 393 /* 394 * Kill last Baseband Rx Frame - Request analog bus grant 395 */ 396 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_REQUEST); 397 if (!ath_hal_wait(ah, AR_PHY_RFBUS_GNT, AR_PHY_RFBUS_GRANT_EN, AR_PHY_RFBUS_GRANT_EN)) { 398 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: could not kill baseband rx\n", 399 __func__); 400 return AH_FALSE; 401 } 402 403 ar5416Set11nRegs(ah, chan); /* NB: setup 5416-specific regs */ 404 405 /* Change the synth */ 406 if (!ar5212SetChannel(ah, chan)) 407 return AH_FALSE; 408 409 /* Setup the transmit power values. */ 410 if (!ar5416SetTransmitPower(ah, chan, rfXpdGain)) { 411 HALDEBUG(ah, HAL_DEBUG_ANY, 412 "%s: error init'ing transmit power\n", __func__); 413 return AH_FALSE; 414 } 415 416 /* 417 * Wait for the frequency synth to settle (synth goes on 418 * via PHY_ACTIVE_EN). Read the phy active delay register. 419 * Value is in 100ns increments. 420 */ 421 data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 422 if (IS_CHAN_CCK(ichan)) { 423 synthDelay = (4 * data) / 22; 424 } else { 425 synthDelay = data / 10; 426 } 427 428 OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY); 429 430 /* Release the RFBus Grant */ 431 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); 432 433 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ 434 if (IEEE80211_IS_CHAN_OFDM(ichan)|| IEEE80211_IS_CHAN_HT(chan)) { 435 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3); 436 ar5212SetSpurMitigation(ah, chan); 437 ar5416SetDeltaSlope(ah, chan); 438 } 439 440 /* XXX spur mitigation for Melin */ 441 442 if (!IEEE80211_IS_CHAN_DFS(chan)) 443 chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT; 444 445 ichan->channel_time = 0; 446 ichan->tsf_last = ar5212GetTsf64(ah); 447 ar5212TxEnable(ah, AH_TRUE); 448 return AH_TRUE; 449} 450#endif 451 452static void 453ar5416InitDMA(struct ath_hal *ah) 454{ 455 struct ath_hal_5212 *ahp = AH5212(ah); 456 457 /* 458 * set AHB_MODE not to do cacheline prefetches 459 */ 460 OS_REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN); 461 462 /* 463 * let mac dma reads be in 128 byte chunks 464 */ 465 OS_REG_WRITE(ah, AR_TXCFG, 466 (OS_REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK) | AR_TXCFG_DMASZ_128B); 467 468 /* 469 * let mac dma writes be in 128 byte chunks 470 */ 471 OS_REG_WRITE(ah, AR_RXCFG, 472 (OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK) | AR_RXCFG_DMASZ_128B); 473 474 /* restore TX trigger level */ 475 OS_REG_WRITE(ah, AR_TXCFG, 476 (OS_REG_READ(ah, AR_TXCFG) &~ AR_FTRIG) | 477 SM(ahp->ah_txTrigLev, AR_FTRIG)); 478 479 /* 480 * Setup receive FIFO threshold to hold off TX activities 481 */ 482 OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200); 483 484 /* 485 * reduce the number of usable entries in PCU TXBUF to avoid 486 * wrap around. 487 */ 488 OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, AR_PCU_TXBUF_CTRL_USABLE_SIZE); 489} 490 491static void 492ar5416InitBB(struct ath_hal *ah, const struct ieee80211_channel *chan) 493{ 494 uint32_t synthDelay; 495 496 /* 497 * Wait for the frequency synth to settle (synth goes on 498 * via AR_PHY_ACTIVE_EN). Read the phy active delay register. 499 * Value is in 100ns increments. 500 */ 501 synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 502 if (IEEE80211_IS_CHAN_CCK(chan)) { 503 synthDelay = (4 * synthDelay) / 22; 504 } else { 505 synthDelay /= 10; 506 } 507 508 /* Turn on PLL on 5416 */ 509 HALDEBUG(ah, HAL_DEBUG_RESET, "%s %s channel\n", 510 __func__, IEEE80211_IS_CHAN_5GHZ(chan) ? "5GHz" : "2GHz"); 511 ar5416InitPLL(ah, chan); 512 513 /* Activate the PHY (includes baseband activate and synthesizer on) */ 514 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 515 516 /* 517 * If the AP starts the calibration before the base band timeout 518 * completes we could get rx_clear false triggering. Add an 519 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition 520 * does not happen. 521 */ 522 if (IEEE80211_IS_CHAN_HALF(chan)) { 523 OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY); 524 } else if (IEEE80211_IS_CHAN_QUARTER(chan)) { 525 OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY); 526 } else { 527 OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY); 528 } 529} 530 531static void 532ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode) 533{ 534 struct ath_hal_5212 *ahp = AH5212(ah); 535 536 /* 537 * Setup interrupt handling. Note that ar5212ResetTxQueue 538 * manipulates the secondary IMR's as queues are enabled 539 * and disabled. This is done with RMW ops to insure the 540 * settings we make here are preserved. 541 */ 542 ahp->ah_maskReg = AR_IMR_TXERR | AR_IMR_TXURN 543 | AR_IMR_RXERR | AR_IMR_RXORN 544 | AR_IMR_BCNMISC; 545 546#ifdef AR5416_INT_MITIGATION 547 ahp->ah_maskReg |= AR_IMR_TXINTM | AR_IMR_RXINTM 548 | AR_IMR_TXMINTR | AR_IMR_RXMINTR; 549#else 550 ahp->ah_maskReg |= AR_IMR_TXOK | AR_IMR_RXOK; 551#endif 552 if (opmode == HAL_M_HOSTAP) 553 ahp->ah_maskReg |= AR_IMR_MIB; 554 OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg); 555 /* Enable bus errors that are OR'd to set the HIUERR bit */ 556#if 0 557 OS_REG_WRITE(ah, AR_IMR_S2, 558 OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT | AR_IMR_S2_CST); 559#endif 560} 561 562static void 563ar5416InitQoS(struct ath_hal *ah) 564{ 565 /* QoS support */ 566 OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa); /* XXX magic */ 567 OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210); /* XXX magic */ 568 569 /* Turn on NOACK Support for QoS packets */ 570 OS_REG_WRITE(ah, AR_NOACK, 571 SM(2, AR_NOACK_2BIT_VALUE) | 572 SM(5, AR_NOACK_BIT_OFFSET) | 573 SM(0, AR_NOACK_BYTE_OFFSET)); 574 575 /* 576 * initialize TXOP for all TIDs 577 */ 578 OS_REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL); 579 OS_REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF); 580 OS_REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF); 581 OS_REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF); 582 OS_REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); 583} 584 585static void 586ar5416InitUserSettings(struct ath_hal *ah) 587{ 588 struct ath_hal_5212 *ahp = AH5212(ah); 589 590 /* Restore user-specified settings */ 591 if (ahp->ah_miscMode != 0) 592 OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); 593 if (ahp->ah_sifstime != (u_int) -1) 594 ar5212SetSifsTime(ah, ahp->ah_sifstime); 595 if (ahp->ah_slottime != (u_int) -1) 596 ar5212SetSlotTime(ah, ahp->ah_slottime); 597 if (ahp->ah_acktimeout != (u_int) -1) 598 ar5212SetAckTimeout(ah, ahp->ah_acktimeout); 599 if (ahp->ah_ctstimeout != (u_int) -1) 600 ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout); 601 if (AH_PRIVATE(ah)->ah_diagreg != 0) 602 OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg); 603#if 0 /* XXX Todo */ 604 if (ahp->ah_globaltxtimeout != (u_int) -1) 605 ar5416SetGlobalTxTimeout(ah, ahp->ah_globaltxtimeout); 606#endif 607} 608 609/* 610 * Places the hardware into reset and then pulls it out of reset 611 */ 612HAL_BOOL 613ar5416ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan) 614{ 615 OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0); 616 /* 617 * Warm reset is optimistic. 618 */ 619 if (AR_SREV_MERLIN_20_OR_LATER(ah) && 620 ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) { 621 if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) 622 return AH_FALSE; 623 } else { 624 if (!ar5416SetResetReg(ah, HAL_RESET_WARM)) 625 return AH_FALSE; 626 } 627 628 /* Bring out of sleep mode (AGAIN) */ 629 if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 630 return AH_FALSE; 631 632 ar5416InitPLL(ah, chan); 633 634 /* 635 * Perform warm reset before the mode/PLL/turbo registers 636 * are changed in order to deactivate the radio. Mode changes 637 * with an active radio can result in corrupted shifts to the 638 * radio device. 639 */ 640 if (chan != AH_NULL) { 641 uint32_t rfMode; 642 643 /* treat channel B as channel G , no B mode suport in owl */ 644 rfMode = IEEE80211_IS_CHAN_CCK(chan) ? 645 AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; 646 if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { 647 /* phy mode bits for 5GHz channels require Fast Clock */ 648 rfMode |= AR_PHY_MODE_DYNAMIC 649 | AR_PHY_MODE_DYN_CCK_DISABLE; 650 } else if (!AR_SREV_MERLIN_10_OR_LATER(ah)) { 651 rfMode |= IEEE80211_IS_CHAN_5GHZ(chan) ? 652 AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ; 653 } 654 OS_REG_WRITE(ah, AR_PHY_MODE, rfMode); 655 } 656 return AH_TRUE; 657} 658 659/* 660 * Delta slope coefficient computation. 661 * Required for OFDM operation. 662 */ 663static void 664ar5416GetDeltaSlopeValues(struct ath_hal *ah, uint32_t coef_scaled, 665 uint32_t *coef_mantissa, uint32_t *coef_exponent) 666{ 667#define COEF_SCALE_S 24 668 uint32_t coef_exp, coef_man; 669 /* 670 * ALGO -> coef_exp = 14-floor(log2(coef)); 671 * floor(log2(x)) is the highest set bit position 672 */ 673 for (coef_exp = 31; coef_exp > 0; coef_exp--) 674 if ((coef_scaled >> coef_exp) & 0x1) 675 break; 676 /* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */ 677 HALASSERT(coef_exp); 678 coef_exp = 14 - (coef_exp - COEF_SCALE_S); 679 680 /* 681 * ALGO -> coef_man = floor(coef* 2^coef_exp+0.5); 682 * The coefficient is already shifted up for scaling 683 */ 684 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1)); 685 686 *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp); 687 *coef_exponent = coef_exp - 16; 688 689#undef COEF_SCALE_S 690} 691 692void 693ar5416SetDeltaSlope(struct ath_hal *ah, const struct ieee80211_channel *chan) 694{ 695#define INIT_CLOCKMHZSCALED 0x64000000 696 uint32_t coef_scaled, ds_coef_exp, ds_coef_man; 697 uint32_t clockMhzScaled; 698 699 CHAN_CENTERS centers; 700 701 /* half and quarter rate can divide the scaled clock by 2 or 4 respectively */ 702 /* scale for selected channel bandwidth */ 703 clockMhzScaled = INIT_CLOCKMHZSCALED; 704 if (IEEE80211_IS_CHAN_TURBO(chan)) 705 clockMhzScaled <<= 1; 706 else if (IEEE80211_IS_CHAN_HALF(chan)) 707 clockMhzScaled >>= 1; 708 else if (IEEE80211_IS_CHAN_QUARTER(chan)) 709 clockMhzScaled >>= 2; 710 711 /* 712 * ALGO -> coef = 1e8/fcarrier*fclock/40; 713 * scaled coef to provide precision for this floating calculation 714 */ 715 ar5416GetChannelCenters(ah, chan, ¢ers); 716 coef_scaled = clockMhzScaled / centers.synth_center; 717 718 ar5416GetDeltaSlopeValues(ah, coef_scaled, &ds_coef_man, &ds_coef_exp); 719 720 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, 721 AR_PHY_TIMING3_DSC_MAN, ds_coef_man); 722 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, 723 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp); 724 725 /* 726 * For Short GI, 727 * scaled coeff is 9/10 that of normal coeff 728 */ 729 coef_scaled = (9 * coef_scaled)/10; 730 731 ar5416GetDeltaSlopeValues(ah, coef_scaled, &ds_coef_man, &ds_coef_exp); 732 733 /* for short gi */ 734 OS_REG_RMW_FIELD(ah, AR_PHY_HALFGI, 735 AR_PHY_HALFGI_DSC_MAN, ds_coef_man); 736 OS_REG_RMW_FIELD(ah, AR_PHY_HALFGI, 737 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp); 738#undef INIT_CLOCKMHZSCALED 739} 740 741/* 742 * Set a limit on the overall output power. Used for dynamic 743 * transmit power control and the like. 744 * 745 * NB: limit is in units of 0.5 dbM. 746 */ 747HAL_BOOL 748ar5416SetTxPowerLimit(struct ath_hal *ah, uint32_t limit) 749{ 750 uint16_t dummyXpdGains[2]; 751 752 AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER); 753 return ar5416SetTransmitPower(ah, AH_PRIVATE(ah)->ah_curchan, 754 dummyXpdGains); 755} 756 757HAL_BOOL 758ar5416GetChipPowerLimits(struct ath_hal *ah, 759 struct ieee80211_channel *chan) 760{ 761 struct ath_hal_5212 *ahp = AH5212(ah); 762 int16_t minPower, maxPower; 763 764 /* 765 * Get Pier table max and min powers. 766 */ 767 if (ahp->ah_rfHal->getChannelMaxMinPower(ah, chan, &maxPower, &minPower)) { 768 /* NB: rf code returns 1/4 dBm units, convert */ 769 chan->ic_maxpower = maxPower / 2; 770 chan->ic_minpower = minPower / 2; 771 } else { 772 HALDEBUG(ah, HAL_DEBUG_ANY, 773 "%s: no min/max power for %u/0x%x\n", 774 __func__, chan->ic_freq, chan->ic_flags); 775 chan->ic_maxpower = AR5416_MAX_RATE_POWER; 776 chan->ic_minpower = 0; 777 } 778 HALDEBUG(ah, HAL_DEBUG_RESET, 779 "Chan %d: MaxPow = %d MinPow = %d\n", 780 chan->ic_freq, chan->ic_maxpower, chan->ic_minpower); 781 return AH_TRUE; 782} 783 784/* XXX gag, this is sick */ 785typedef enum Ar5416_Rates { 786 rate6mb, rate9mb, rate12mb, rate18mb, 787 rate24mb, rate36mb, rate48mb, rate54mb, 788 rate1l, rate2l, rate2s, rate5_5l, 789 rate5_5s, rate11l, rate11s, rateXr, 790 rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3, 791 rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7, 792 rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3, 793 rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7, 794 rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm, 795 Ar5416RateSize 796} AR5416_RATES; 797 798/************************************************************** 799 * ar5416SetTransmitPower 800 * 801 * Set the transmit power in the baseband for the given 802 * operating channel and mode. 803 */ 804HAL_BOOL 805ar5416SetTransmitPower(struct ath_hal *ah, 806 const struct ieee80211_channel *chan, uint16_t *rfXpdGain) 807{ 808#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) 809#define N(a) (sizeof (a) / sizeof (a[0])) 810 811 MODAL_EEP_HEADER *pModal; 812 struct ath_hal_5212 *ahp = AH5212(ah); 813 int16_t ratesArray[Ar5416RateSize]; 814 int16_t txPowerIndexOffset = 0; 815 uint8_t ht40PowerIncForPdadc = 2; 816 int i; 817 818 uint16_t cfgCtl; 819 uint16_t powerLimit; 820 uint16_t twiceAntennaReduction; 821 uint16_t twiceMaxRegulatoryPower; 822 int16_t maxPower; 823 HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom; 824 struct ar5416eeprom *pEepData = &ee->ee_base; 825 826 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); 827 828 /* Setup info for the actual eeprom */ 829 OS_MEMZERO(ratesArray, sizeof(ratesArray)); 830 cfgCtl = ath_hal_getctl(ah, chan); 831 powerLimit = chan->ic_maxregpower * 2; 832 twiceAntennaReduction = chan->ic_maxantgain; 833 twiceMaxRegulatoryPower = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit); 834 pModal = &pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)]; 835 HALDEBUG(ah, HAL_DEBUG_RESET, "%s Channel=%u CfgCtl=%u\n", 836 __func__,chan->ic_freq, cfgCtl ); 837 838 if (IS_EEP_MINOR_V2(ah)) { 839 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 840 } 841 842 if (!ar5416SetPowerPerRateTable(ah, pEepData, chan, 843 &ratesArray[0],cfgCtl, 844 twiceAntennaReduction, 845 twiceMaxRegulatoryPower, powerLimit)) { 846 HALDEBUG(ah, HAL_DEBUG_ANY, 847 "%s: unable to set tx power per rate table\n", __func__); 848 return AH_FALSE; 849 } 850
| 216 217 /* Setup the transmit power values. */ 218 if (!ah->ah_setTxPower(ah, chan, rfXpdGain)) { 219 HALDEBUG(ah, HAL_DEBUG_ANY, 220 "%s: error init'ing transmit power\n", __func__); 221 FAIL(HAL_EIO); 222 } 223 224 /* Write the analog registers */ 225 if (!ahp->ah_rfHal->setRfRegs(ah, chan, 226 IEEE80211_IS_CHAN_2GHZ(chan) ? 2: 1, rfXpdGain)) { 227 HALDEBUG(ah, HAL_DEBUG_ANY, 228 "%s: ar5212SetRfRegs failed\n", __func__); 229 FAIL(HAL_EIO); 230 } 231 232 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ 233 if (IEEE80211_IS_CHAN_OFDM(chan)|| IEEE80211_IS_CHAN_HT(chan)) 234 ar5416SetDeltaSlope(ah, chan); 235 236 AH5416(ah)->ah_spurMitigate(ah, chan); 237 238 /* Setup board specific options for EEPROM version 3 */ 239 if (!ah->ah_setBoardValues(ah, chan)) { 240 HALDEBUG(ah, HAL_DEBUG_ANY, 241 "%s: error setting board options\n", __func__); 242 FAIL(HAL_EIO); 243 } 244 245 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 246 247 OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr)); 248 OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4) 249 | macStaId1 250 | AR_STA_ID1_RTS_USE_DEF 251 | ahp->ah_staId1Defaults 252 ); 253 ar5212SetOperatingMode(ah, opmode); 254 255 /* Set Venice BSSID mask according to current state */ 256 OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask)); 257 OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4)); 258 259 /* Restore previous led state */ 260 OS_REG_WRITE(ah, AR_MAC_LED, OS_REG_READ(ah, AR_MAC_LED) | saveLedState); 261 262 /* Restore previous antenna */ 263 OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); 264 265 /* then our BSSID */ 266 OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid)); 267 OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4)); 268 269 /* Restore bmiss rssi & count thresholds */ 270 OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr); 271 272 OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */ 273 274 if (!ar5212SetChannel(ah, chan)) 275 FAIL(HAL_EIO); 276 277 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__); 278 279 /* Set 1:1 QCU to DCU mapping for all queues */ 280 for (i = 0; i < AR_NUM_DCU; i++) 281 OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); 282 283 ahp->ah_intrTxqs = 0; 284 for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++) 285 ar5212ResetTxQueue(ah, i); 286 287 ar5416InitIMR(ah, opmode); 288 ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1); 289 ar5416InitQoS(ah); 290 ar5416InitUserSettings(ah); 291 292 /* 293 * disable seq number generation in hw 294 */ 295 OS_REG_WRITE(ah, AR_STA_ID1, 296 OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM); 297 298 ar5416InitDMA(ah); 299 300 /* 301 * program OBS bus to see MAC interrupts 302 */ 303 OS_REG_WRITE(ah, AR_OBS, 8); 304 305#ifdef AR5416_INT_MITIGATION 306 OS_REG_WRITE(ah, AR_MIRT, 0); 307 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); 308 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); 309#endif 310 311 ar5416InitBB(ah, chan); 312 313 /* Setup compression registers */ 314 ar5212SetCompRegs(ah); /* XXX not needed? */ 315 316 /* 317 * 5416 baseband will check the per rate power table 318 * and select the lower of the two 319 */ 320 ackTpcPow = 63; 321 ctsTpcPow = 63; 322 chirpTpcPow = 63; 323 powerVal = SM(ackTpcPow, AR_TPC_ACK) | 324 SM(ctsTpcPow, AR_TPC_CTS) | 325 SM(chirpTpcPow, AR_TPC_CHIRP); 326 OS_REG_WRITE(ah, AR_TPC, powerVal); 327 328 if (!ar5416InitCal(ah, chan)) 329 FAIL(HAL_ESELFTEST); 330 331 ar5416RestoreChainMask(ah); 332 333 AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */ 334 335 if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan)) 336 chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT; 337 338 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__); 339 340 OS_MARK(ah, AH_MARK_RESET_DONE, 0); 341 342 return AH_TRUE; 343bad: 344 OS_MARK(ah, AH_MARK_RESET_DONE, ecode); 345 if (status != AH_NULL) 346 *status = ecode; 347 return AH_FALSE; 348#undef FAIL 349#undef N 350} 351 352#if 0 353/* 354 * This channel change evaluates whether the selected hardware can 355 * perform a synthesizer-only channel change (no reset). If the 356 * TX is not stopped, or the RFBus cannot be granted in the given 357 * time, the function returns false as a reset is necessary 358 */ 359HAL_BOOL 360ar5416ChannelChange(struct ath_hal *ah, const structu ieee80211_channel *chan) 361{ 362 uint32_t ulCount; 363 uint32_t data, synthDelay, qnum; 364 uint16_t rfXpdGain[4]; 365 struct ath_hal_5212 *ahp = AH5212(ah); 366 HAL_CHANNEL_INTERNAL *ichan; 367 368 /* 369 * Map public channel to private. 370 */ 371 ichan = ath_hal_checkchannel(ah, chan); 372 373 /* TX must be stopped or RF Bus grant will not work */ 374 for (qnum = 0; qnum < AH_PRIVATE(ah)->ah_caps.halTotalQueues; qnum++) { 375 if (ar5212NumTxPending(ah, qnum)) { 376 HALDEBUG(ah, HAL_DEBUG_ANY, 377 "%s: frames pending on queue %d\n", __func__, qnum); 378 return AH_FALSE; 379 } 380 } 381 382 /* 383 * Kill last Baseband Rx Frame - Request analog bus grant 384 */ 385 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_REQUEST); 386 if (!ath_hal_wait(ah, AR_PHY_RFBUS_GNT, AR_PHY_RFBUS_GRANT_EN, AR_PHY_RFBUS_GRANT_EN)) { 387 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: could not kill baseband rx\n", 388 __func__); 389 return AH_FALSE; 390 } 391 392 ar5416Set11nRegs(ah, chan); /* NB: setup 5416-specific regs */ 393 394 /* Change the synth */ 395 if (!ar5212SetChannel(ah, chan)) 396 return AH_FALSE; 397 398 /* Setup the transmit power values. */ 399 if (!ar5416SetTransmitPower(ah, chan, rfXpdGain)) { 400 HALDEBUG(ah, HAL_DEBUG_ANY, 401 "%s: error init'ing transmit power\n", __func__); 402 return AH_FALSE; 403 } 404 405 /* 406 * Wait for the frequency synth to settle (synth goes on 407 * via PHY_ACTIVE_EN). Read the phy active delay register. 408 * Value is in 100ns increments. 409 */ 410 data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 411 if (IS_CHAN_CCK(ichan)) { 412 synthDelay = (4 * data) / 22; 413 } else { 414 synthDelay = data / 10; 415 } 416 417 OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY); 418 419 /* Release the RFBus Grant */ 420 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); 421 422 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */ 423 if (IEEE80211_IS_CHAN_OFDM(ichan)|| IEEE80211_IS_CHAN_HT(chan)) { 424 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3); 425 ar5212SetSpurMitigation(ah, chan); 426 ar5416SetDeltaSlope(ah, chan); 427 } 428 429 /* XXX spur mitigation for Melin */ 430 431 if (!IEEE80211_IS_CHAN_DFS(chan)) 432 chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT; 433 434 ichan->channel_time = 0; 435 ichan->tsf_last = ar5212GetTsf64(ah); 436 ar5212TxEnable(ah, AH_TRUE); 437 return AH_TRUE; 438} 439#endif 440 441static void 442ar5416InitDMA(struct ath_hal *ah) 443{ 444 struct ath_hal_5212 *ahp = AH5212(ah); 445 446 /* 447 * set AHB_MODE not to do cacheline prefetches 448 */ 449 OS_REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN); 450 451 /* 452 * let mac dma reads be in 128 byte chunks 453 */ 454 OS_REG_WRITE(ah, AR_TXCFG, 455 (OS_REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK) | AR_TXCFG_DMASZ_128B); 456 457 /* 458 * let mac dma writes be in 128 byte chunks 459 */ 460 OS_REG_WRITE(ah, AR_RXCFG, 461 (OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK) | AR_RXCFG_DMASZ_128B); 462 463 /* restore TX trigger level */ 464 OS_REG_WRITE(ah, AR_TXCFG, 465 (OS_REG_READ(ah, AR_TXCFG) &~ AR_FTRIG) | 466 SM(ahp->ah_txTrigLev, AR_FTRIG)); 467 468 /* 469 * Setup receive FIFO threshold to hold off TX activities 470 */ 471 OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200); 472 473 /* 474 * reduce the number of usable entries in PCU TXBUF to avoid 475 * wrap around. 476 */ 477 OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, AR_PCU_TXBUF_CTRL_USABLE_SIZE); 478} 479 480static void 481ar5416InitBB(struct ath_hal *ah, const struct ieee80211_channel *chan) 482{ 483 uint32_t synthDelay; 484 485 /* 486 * Wait for the frequency synth to settle (synth goes on 487 * via AR_PHY_ACTIVE_EN). Read the phy active delay register. 488 * Value is in 100ns increments. 489 */ 490 synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 491 if (IEEE80211_IS_CHAN_CCK(chan)) { 492 synthDelay = (4 * synthDelay) / 22; 493 } else { 494 synthDelay /= 10; 495 } 496 497 /* Turn on PLL on 5416 */ 498 HALDEBUG(ah, HAL_DEBUG_RESET, "%s %s channel\n", 499 __func__, IEEE80211_IS_CHAN_5GHZ(chan) ? "5GHz" : "2GHz"); 500 ar5416InitPLL(ah, chan); 501 502 /* Activate the PHY (includes baseband activate and synthesizer on) */ 503 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 504 505 /* 506 * If the AP starts the calibration before the base band timeout 507 * completes we could get rx_clear false triggering. Add an 508 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition 509 * does not happen. 510 */ 511 if (IEEE80211_IS_CHAN_HALF(chan)) { 512 OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY); 513 } else if (IEEE80211_IS_CHAN_QUARTER(chan)) { 514 OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY); 515 } else { 516 OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY); 517 } 518} 519 520static void 521ar5416InitIMR(struct ath_hal *ah, HAL_OPMODE opmode) 522{ 523 struct ath_hal_5212 *ahp = AH5212(ah); 524 525 /* 526 * Setup interrupt handling. Note that ar5212ResetTxQueue 527 * manipulates the secondary IMR's as queues are enabled 528 * and disabled. This is done with RMW ops to insure the 529 * settings we make here are preserved. 530 */ 531 ahp->ah_maskReg = AR_IMR_TXERR | AR_IMR_TXURN 532 | AR_IMR_RXERR | AR_IMR_RXORN 533 | AR_IMR_BCNMISC; 534 535#ifdef AR5416_INT_MITIGATION 536 ahp->ah_maskReg |= AR_IMR_TXINTM | AR_IMR_RXINTM 537 | AR_IMR_TXMINTR | AR_IMR_RXMINTR; 538#else 539 ahp->ah_maskReg |= AR_IMR_TXOK | AR_IMR_RXOK; 540#endif 541 if (opmode == HAL_M_HOSTAP) 542 ahp->ah_maskReg |= AR_IMR_MIB; 543 OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg); 544 /* Enable bus errors that are OR'd to set the HIUERR bit */ 545#if 0 546 OS_REG_WRITE(ah, AR_IMR_S2, 547 OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT | AR_IMR_S2_CST); 548#endif 549} 550 551static void 552ar5416InitQoS(struct ath_hal *ah) 553{ 554 /* QoS support */ 555 OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa); /* XXX magic */ 556 OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210); /* XXX magic */ 557 558 /* Turn on NOACK Support for QoS packets */ 559 OS_REG_WRITE(ah, AR_NOACK, 560 SM(2, AR_NOACK_2BIT_VALUE) | 561 SM(5, AR_NOACK_BIT_OFFSET) | 562 SM(0, AR_NOACK_BYTE_OFFSET)); 563 564 /* 565 * initialize TXOP for all TIDs 566 */ 567 OS_REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL); 568 OS_REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF); 569 OS_REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF); 570 OS_REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF); 571 OS_REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); 572} 573 574static void 575ar5416InitUserSettings(struct ath_hal *ah) 576{ 577 struct ath_hal_5212 *ahp = AH5212(ah); 578 579 /* Restore user-specified settings */ 580 if (ahp->ah_miscMode != 0) 581 OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); 582 if (ahp->ah_sifstime != (u_int) -1) 583 ar5212SetSifsTime(ah, ahp->ah_sifstime); 584 if (ahp->ah_slottime != (u_int) -1) 585 ar5212SetSlotTime(ah, ahp->ah_slottime); 586 if (ahp->ah_acktimeout != (u_int) -1) 587 ar5212SetAckTimeout(ah, ahp->ah_acktimeout); 588 if (ahp->ah_ctstimeout != (u_int) -1) 589 ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout); 590 if (AH_PRIVATE(ah)->ah_diagreg != 0) 591 OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg); 592#if 0 /* XXX Todo */ 593 if (ahp->ah_globaltxtimeout != (u_int) -1) 594 ar5416SetGlobalTxTimeout(ah, ahp->ah_globaltxtimeout); 595#endif 596} 597 598/* 599 * Places the hardware into reset and then pulls it out of reset 600 */ 601HAL_BOOL 602ar5416ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan) 603{ 604 OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0); 605 /* 606 * Warm reset is optimistic. 607 */ 608 if (AR_SREV_MERLIN_20_OR_LATER(ah) && 609 ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) { 610 if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) 611 return AH_FALSE; 612 } else { 613 if (!ar5416SetResetReg(ah, HAL_RESET_WARM)) 614 return AH_FALSE; 615 } 616 617 /* Bring out of sleep mode (AGAIN) */ 618 if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 619 return AH_FALSE; 620 621 ar5416InitPLL(ah, chan); 622 623 /* 624 * Perform warm reset before the mode/PLL/turbo registers 625 * are changed in order to deactivate the radio. Mode changes 626 * with an active radio can result in corrupted shifts to the 627 * radio device. 628 */ 629 if (chan != AH_NULL) { 630 uint32_t rfMode; 631 632 /* treat channel B as channel G , no B mode suport in owl */ 633 rfMode = IEEE80211_IS_CHAN_CCK(chan) ? 634 AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; 635 if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { 636 /* phy mode bits for 5GHz channels require Fast Clock */ 637 rfMode |= AR_PHY_MODE_DYNAMIC 638 | AR_PHY_MODE_DYN_CCK_DISABLE; 639 } else if (!AR_SREV_MERLIN_10_OR_LATER(ah)) { 640 rfMode |= IEEE80211_IS_CHAN_5GHZ(chan) ? 641 AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ; 642 } 643 OS_REG_WRITE(ah, AR_PHY_MODE, rfMode); 644 } 645 return AH_TRUE; 646} 647 648/* 649 * Delta slope coefficient computation. 650 * Required for OFDM operation. 651 */ 652static void 653ar5416GetDeltaSlopeValues(struct ath_hal *ah, uint32_t coef_scaled, 654 uint32_t *coef_mantissa, uint32_t *coef_exponent) 655{ 656#define COEF_SCALE_S 24 657 uint32_t coef_exp, coef_man; 658 /* 659 * ALGO -> coef_exp = 14-floor(log2(coef)); 660 * floor(log2(x)) is the highest set bit position 661 */ 662 for (coef_exp = 31; coef_exp > 0; coef_exp--) 663 if ((coef_scaled >> coef_exp) & 0x1) 664 break; 665 /* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */ 666 HALASSERT(coef_exp); 667 coef_exp = 14 - (coef_exp - COEF_SCALE_S); 668 669 /* 670 * ALGO -> coef_man = floor(coef* 2^coef_exp+0.5); 671 * The coefficient is already shifted up for scaling 672 */ 673 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1)); 674 675 *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp); 676 *coef_exponent = coef_exp - 16; 677 678#undef COEF_SCALE_S 679} 680 681void 682ar5416SetDeltaSlope(struct ath_hal *ah, const struct ieee80211_channel *chan) 683{ 684#define INIT_CLOCKMHZSCALED 0x64000000 685 uint32_t coef_scaled, ds_coef_exp, ds_coef_man; 686 uint32_t clockMhzScaled; 687 688 CHAN_CENTERS centers; 689 690 /* half and quarter rate can divide the scaled clock by 2 or 4 respectively */ 691 /* scale for selected channel bandwidth */ 692 clockMhzScaled = INIT_CLOCKMHZSCALED; 693 if (IEEE80211_IS_CHAN_TURBO(chan)) 694 clockMhzScaled <<= 1; 695 else if (IEEE80211_IS_CHAN_HALF(chan)) 696 clockMhzScaled >>= 1; 697 else if (IEEE80211_IS_CHAN_QUARTER(chan)) 698 clockMhzScaled >>= 2; 699 700 /* 701 * ALGO -> coef = 1e8/fcarrier*fclock/40; 702 * scaled coef to provide precision for this floating calculation 703 */ 704 ar5416GetChannelCenters(ah, chan, ¢ers); 705 coef_scaled = clockMhzScaled / centers.synth_center; 706 707 ar5416GetDeltaSlopeValues(ah, coef_scaled, &ds_coef_man, &ds_coef_exp); 708 709 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, 710 AR_PHY_TIMING3_DSC_MAN, ds_coef_man); 711 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, 712 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp); 713 714 /* 715 * For Short GI, 716 * scaled coeff is 9/10 that of normal coeff 717 */ 718 coef_scaled = (9 * coef_scaled)/10; 719 720 ar5416GetDeltaSlopeValues(ah, coef_scaled, &ds_coef_man, &ds_coef_exp); 721 722 /* for short gi */ 723 OS_REG_RMW_FIELD(ah, AR_PHY_HALFGI, 724 AR_PHY_HALFGI_DSC_MAN, ds_coef_man); 725 OS_REG_RMW_FIELD(ah, AR_PHY_HALFGI, 726 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp); 727#undef INIT_CLOCKMHZSCALED 728} 729 730/* 731 * Set a limit on the overall output power. Used for dynamic 732 * transmit power control and the like. 733 * 734 * NB: limit is in units of 0.5 dbM. 735 */ 736HAL_BOOL 737ar5416SetTxPowerLimit(struct ath_hal *ah, uint32_t limit) 738{ 739 uint16_t dummyXpdGains[2]; 740 741 AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER); 742 return ar5416SetTransmitPower(ah, AH_PRIVATE(ah)->ah_curchan, 743 dummyXpdGains); 744} 745 746HAL_BOOL 747ar5416GetChipPowerLimits(struct ath_hal *ah, 748 struct ieee80211_channel *chan) 749{ 750 struct ath_hal_5212 *ahp = AH5212(ah); 751 int16_t minPower, maxPower; 752 753 /* 754 * Get Pier table max and min powers. 755 */ 756 if (ahp->ah_rfHal->getChannelMaxMinPower(ah, chan, &maxPower, &minPower)) { 757 /* NB: rf code returns 1/4 dBm units, convert */ 758 chan->ic_maxpower = maxPower / 2; 759 chan->ic_minpower = minPower / 2; 760 } else { 761 HALDEBUG(ah, HAL_DEBUG_ANY, 762 "%s: no min/max power for %u/0x%x\n", 763 __func__, chan->ic_freq, chan->ic_flags); 764 chan->ic_maxpower = AR5416_MAX_RATE_POWER; 765 chan->ic_minpower = 0; 766 } 767 HALDEBUG(ah, HAL_DEBUG_RESET, 768 "Chan %d: MaxPow = %d MinPow = %d\n", 769 chan->ic_freq, chan->ic_maxpower, chan->ic_minpower); 770 return AH_TRUE; 771} 772 773/* XXX gag, this is sick */ 774typedef enum Ar5416_Rates { 775 rate6mb, rate9mb, rate12mb, rate18mb, 776 rate24mb, rate36mb, rate48mb, rate54mb, 777 rate1l, rate2l, rate2s, rate5_5l, 778 rate5_5s, rate11l, rate11s, rateXr, 779 rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3, 780 rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7, 781 rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3, 782 rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7, 783 rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm, 784 Ar5416RateSize 785} AR5416_RATES; 786 787/************************************************************** 788 * ar5416SetTransmitPower 789 * 790 * Set the transmit power in the baseband for the given 791 * operating channel and mode. 792 */ 793HAL_BOOL 794ar5416SetTransmitPower(struct ath_hal *ah, 795 const struct ieee80211_channel *chan, uint16_t *rfXpdGain) 796{ 797#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) 798#define N(a) (sizeof (a) / sizeof (a[0])) 799 800 MODAL_EEP_HEADER *pModal; 801 struct ath_hal_5212 *ahp = AH5212(ah); 802 int16_t ratesArray[Ar5416RateSize]; 803 int16_t txPowerIndexOffset = 0; 804 uint8_t ht40PowerIncForPdadc = 2; 805 int i; 806 807 uint16_t cfgCtl; 808 uint16_t powerLimit; 809 uint16_t twiceAntennaReduction; 810 uint16_t twiceMaxRegulatoryPower; 811 int16_t maxPower; 812 HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom; 813 struct ar5416eeprom *pEepData = &ee->ee_base; 814 815 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); 816 817 /* Setup info for the actual eeprom */ 818 OS_MEMZERO(ratesArray, sizeof(ratesArray)); 819 cfgCtl = ath_hal_getctl(ah, chan); 820 powerLimit = chan->ic_maxregpower * 2; 821 twiceAntennaReduction = chan->ic_maxantgain; 822 twiceMaxRegulatoryPower = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit); 823 pModal = &pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)]; 824 HALDEBUG(ah, HAL_DEBUG_RESET, "%s Channel=%u CfgCtl=%u\n", 825 __func__,chan->ic_freq, cfgCtl ); 826 827 if (IS_EEP_MINOR_V2(ah)) { 828 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 829 } 830 831 if (!ar5416SetPowerPerRateTable(ah, pEepData, chan, 832 &ratesArray[0],cfgCtl, 833 twiceAntennaReduction, 834 twiceMaxRegulatoryPower, powerLimit)) { 835 HALDEBUG(ah, HAL_DEBUG_ANY, 836 "%s: unable to set tx power per rate table\n", __func__); 837 return AH_FALSE; 838 } 839
|
851 if (!ar5416SetPowerCalTable(ah, pEepData, chan, &txPowerIndexOffset)) {
| 840 if (!AH5416(ah)->ah_setPowerCalTable(ah, pEepData, chan, &txPowerIndexOffset)) {
|
852 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set power table\n", 853 __func__); 854 return AH_FALSE; 855 } 856 857 maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]); 858 859 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 860 maxPower = AH_MAX(maxPower, ratesArray[rate1l]); 861 } 862 863 if (IEEE80211_IS_CHAN_HT40(chan)) { 864 maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]); 865 } 866 867 ahp->ah_tx6PowerInHalfDbm = maxPower; 868 AH_PRIVATE(ah)->ah_maxPowerLevel = maxPower; 869 ahp->ah_txPowerIndexOffset = txPowerIndexOffset; 870 871 /* 872 * txPowerIndexOffset is set by the SetPowerTable() call - 873 * adjust the rate table (0 offset if rates EEPROM not loaded) 874 */ 875 for (i = 0; i < N(ratesArray); i++) { 876 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 877 if (ratesArray[i] > AR5416_MAX_RATE_POWER) 878 ratesArray[i] = AR5416_MAX_RATE_POWER; 879 } 880 881#ifdef AH_EEPROM_DUMP
| 841 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set power table\n", 842 __func__); 843 return AH_FALSE; 844 } 845 846 maxPower = AH_MAX(ratesArray[rate6mb], ratesArray[rateHt20_0]); 847 848 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 849 maxPower = AH_MAX(maxPower, ratesArray[rate1l]); 850 } 851 852 if (IEEE80211_IS_CHAN_HT40(chan)) { 853 maxPower = AH_MAX(maxPower, ratesArray[rateHt40_0]); 854 } 855 856 ahp->ah_tx6PowerInHalfDbm = maxPower; 857 AH_PRIVATE(ah)->ah_maxPowerLevel = maxPower; 858 ahp->ah_txPowerIndexOffset = txPowerIndexOffset; 859 860 /* 861 * txPowerIndexOffset is set by the SetPowerTable() call - 862 * adjust the rate table (0 offset if rates EEPROM not loaded) 863 */ 864 for (i = 0; i < N(ratesArray); i++) { 865 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 866 if (ratesArray[i] > AR5416_MAX_RATE_POWER) 867 ratesArray[i] = AR5416_MAX_RATE_POWER; 868 } 869 870#ifdef AH_EEPROM_DUMP
|
| 871 /* 872 * Dump the rate array whilst it represents the intended dBm*2 873 * values versus what's being adjusted before being programmed 874 * in. Keep this in mind if you code up this function and enable 875 * this debugging; the values won't necessarily be what's being 876 * programmed into the hardware. 877 */
|
882 ar5416PrintPowerPerRate(ah, ratesArray); 883#endif 884
| 878 ar5416PrintPowerPerRate(ah, ratesArray); 879#endif 880
|
| 881 /* 882 * Merlin and later have a power offset, so subtract 883 * pwr_table_offset * 2 from each value. The default 884 * power offset is -5 dBm - ie, a register value of 0 885 * equates to a TX power of -5 dBm. 886 */ 887 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 888 int8_t pwr_table_offset; 889 890 (void) ath_hal_eepromGet(ah, AR_EEP_PWR_TABLE_OFFSET, 891 &pwr_table_offset); 892 /* Underflow power gets clamped at raw value 0 */ 893 /* Overflow power gets camped at AR5416_MAX_RATE_POWER */ 894 for (i = 0; i < N(ratesArray); i++) { 895 /* 896 * + pwr_table_offset is in dBm 897 * + ratesArray is in 1/2 dBm 898 */ 899 ratesArray[i] -= (pwr_table_offset * 2); 900 if (ratesArray[i] < 0) 901 ratesArray[i] = 0; 902 else if (ratesArray[i] > AR5416_MAX_RATE_POWER) 903 ratesArray[i] = AR5416_MAX_RATE_POWER; 904 } 905 } 906 907 /* 908 * Adjust rates for OLC where needed 909 * 910 * The following CCK rates need adjusting when doing 2.4ghz 911 * CCK transmission. 912 * 913 * + rate2s, rate2l, rate1l, rate11s, rate11l, rate5_5s, rate5_5l 914 * + rateExtCck, rateDupCck 915 * 916 * They're adjusted here regardless. The hardware then gets 917 * programmed as needed. 5GHz operation doesn't program in CCK 918 * rates for legacy mode but they seem to be initialised for 919 * HT40 regardless of channel type. 920 */ 921 if (AR_SREV_MERLIN_20_OR_LATER(ah) && 922 ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) { 923 int adj[] = { 924 rate2s, rate2l, rate1l, rate11s, rate11l, 925 rate5_5s, rate5_5l, rateExtCck, rateDupCck 926 }; 927 int cck_ofdm_delta = 2; 928 int i; 929 for (i = 0; i < N(adj); i++) { 930 ratesArray[i] -= cck_ofdm_delta; 931 if (ratesArray[i] < 0) 932 ratesArray[i] = 0; 933 } 934 } 935
|
885 /* Write the OFDM power per rate set */ 886 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 887 POW_SM(ratesArray[rate18mb], 24) 888 | POW_SM(ratesArray[rate12mb], 16) 889 | POW_SM(ratesArray[rate9mb], 8) 890 | POW_SM(ratesArray[rate6mb], 0) 891 ); 892 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, 893 POW_SM(ratesArray[rate54mb], 24) 894 | POW_SM(ratesArray[rate48mb], 16) 895 | POW_SM(ratesArray[rate36mb], 8) 896 | POW_SM(ratesArray[rate24mb], 0) 897 ); 898 899 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 900 /* Write the CCK power per rate set */ 901 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 902 POW_SM(ratesArray[rate2s], 24) 903 | POW_SM(ratesArray[rate2l], 16) 904 | POW_SM(ratesArray[rateXr], 8) /* XR target power */ 905 | POW_SM(ratesArray[rate1l], 0) 906 ); 907 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 908 POW_SM(ratesArray[rate11s], 24) 909 | POW_SM(ratesArray[rate11l], 16) 910 | POW_SM(ratesArray[rate5_5s], 8) 911 | POW_SM(ratesArray[rate5_5l], 0) 912 ); 913 HALDEBUG(ah, HAL_DEBUG_RESET, 914 "%s AR_PHY_POWER_TX_RATE3=0x%x AR_PHY_POWER_TX_RATE4=0x%x\n", 915 __func__, OS_REG_READ(ah,AR_PHY_POWER_TX_RATE3), 916 OS_REG_READ(ah,AR_PHY_POWER_TX_RATE4)); 917 } 918 919 /* Write the HT20 power per rate set */ 920 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 921 POW_SM(ratesArray[rateHt20_3], 24) 922 | POW_SM(ratesArray[rateHt20_2], 16) 923 | POW_SM(ratesArray[rateHt20_1], 8) 924 | POW_SM(ratesArray[rateHt20_0], 0) 925 ); 926 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, 927 POW_SM(ratesArray[rateHt20_7], 24) 928 | POW_SM(ratesArray[rateHt20_6], 16) 929 | POW_SM(ratesArray[rateHt20_5], 8) 930 | POW_SM(ratesArray[rateHt20_4], 0) 931 ); 932 933 if (IEEE80211_IS_CHAN_HT40(chan)) { 934 /* Write the HT40 power per rate set */ 935 /* Correct PAR difference between HT40 and HT20/LEGACY */ 936 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 937 POW_SM(ratesArray[rateHt40_3] + ht40PowerIncForPdadc, 24) 938 | POW_SM(ratesArray[rateHt40_2] + ht40PowerIncForPdadc, 16) 939 | POW_SM(ratesArray[rateHt40_1] + ht40PowerIncForPdadc, 8) 940 | POW_SM(ratesArray[rateHt40_0] + ht40PowerIncForPdadc, 0) 941 ); 942 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, 943 POW_SM(ratesArray[rateHt40_7] + ht40PowerIncForPdadc, 24) 944 | POW_SM(ratesArray[rateHt40_6] + ht40PowerIncForPdadc, 16) 945 | POW_SM(ratesArray[rateHt40_5] + ht40PowerIncForPdadc, 8) 946 | POW_SM(ratesArray[rateHt40_4] + ht40PowerIncForPdadc, 0) 947 ); 948 /* Write the Dup/Ext 40 power per rate set */ 949 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 950 POW_SM(ratesArray[rateExtOfdm], 24) 951 | POW_SM(ratesArray[rateExtCck], 16) 952 | POW_SM(ratesArray[rateDupOfdm], 8) 953 | POW_SM(ratesArray[rateDupCck], 0) 954 ); 955 } 956 957 /* Write the Power subtraction for dynamic chain changing, for per-packet powertx */ 958 OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB, 959 POW_SM(pModal->pwrDecreaseFor3Chain, 6) 960 | POW_SM(pModal->pwrDecreaseFor2Chain, 0) 961 ); 962 return AH_TRUE; 963#undef POW_SM 964#undef N 965} 966 967/* 968 * Exported call to check for a recent gain reading and return 969 * the current state of the thermal calibration gain engine. 970 */ 971HAL_RFGAIN 972ar5416GetRfgain(struct ath_hal *ah) 973{ 974 return HAL_RFGAIN_INACTIVE; 975} 976 977/* 978 * Places all of hardware into reset 979 */ 980HAL_BOOL 981ar5416Disable(struct ath_hal *ah) 982{ 983 if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 984 return AH_FALSE; 985 return ar5416SetResetReg(ah, HAL_RESET_COLD); 986} 987 988/* 989 * Places the PHY and Radio chips into reset. A full reset 990 * must be called to leave this state. The PCI/MAC/PCU are 991 * not placed into reset as we must receive interrupt to 992 * re-enable the hardware. 993 */ 994HAL_BOOL 995ar5416PhyDisable(struct ath_hal *ah) 996{ 997 return ar5416SetResetReg(ah, HAL_RESET_WARM); 998} 999 1000/* 1001 * Write the given reset bit mask into the reset register 1002 */ 1003HAL_BOOL 1004ar5416SetResetReg(struct ath_hal *ah, uint32_t type) 1005{ 1006 switch (type) { 1007 case HAL_RESET_POWER_ON: 1008 return ar5416SetResetPowerOn(ah); 1009 case HAL_RESET_WARM: 1010 case HAL_RESET_COLD: 1011 return ar5416SetReset(ah, type); 1012 default: 1013 HALASSERT(AH_FALSE); 1014 return AH_FALSE; 1015 } 1016} 1017 1018static HAL_BOOL 1019ar5416SetResetPowerOn(struct ath_hal *ah) 1020{ 1021 /* Power On Reset (Hard Reset) */ 1022 1023 /* 1024 * Set force wake 1025 * 1026 * If the MAC was running, previously calling 1027 * reset will wake up the MAC but it may go back to sleep 1028 * before we can start polling. 1029 * Set force wake stops that 1030 * This must be called before initiating a hard reset. 1031 */ 1032 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1033 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1034 1035 /* 1036 * RTC reset and clear 1037 */ 1038 OS_REG_WRITE(ah, AR_RC, AR_RC_AHB); 1039 OS_REG_WRITE(ah, AR_RTC_RESET, 0); 1040 OS_DELAY(20); 1041 OS_REG_WRITE(ah, AR_RC, 0); 1042 1043 OS_REG_WRITE(ah, AR_RTC_RESET, 1); 1044 1045 /* 1046 * Poll till RTC is ON 1047 */ 1048 if (!ath_hal_wait(ah, AR_RTC_STATUS, AR_RTC_PM_STATUS_M, AR_RTC_STATUS_ON)) { 1049 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RTC not waking up\n", __func__); 1050 return AH_FALSE; 1051 } 1052 1053 return ar5416SetReset(ah, HAL_RESET_COLD); 1054} 1055 1056static HAL_BOOL 1057ar5416SetReset(struct ath_hal *ah, int type) 1058{ 1059 uint32_t tmpReg, mask; 1060 1061 /* 1062 * Force wake 1063 */ 1064 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1065 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1066 1067 /* 1068 * Reset AHB 1069 */ 1070 tmpReg = OS_REG_READ(ah, AR_INTR_SYNC_CAUSE); 1071 if (tmpReg & (AR_INTR_SYNC_LOCAL_TIMEOUT|AR_INTR_SYNC_RADM_CPL_TIMEOUT)) { 1072 OS_REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); 1073 OS_REG_WRITE(ah, AR_RC, AR_RC_AHB|AR_RC_HOSTIF); 1074 } else { 1075 OS_REG_WRITE(ah, AR_RC, AR_RC_AHB); 1076 } 1077 1078 /* 1079 * Set Mac(BB,Phy) Warm Reset 1080 */ 1081 switch (type) { 1082 case HAL_RESET_WARM: 1083 OS_REG_WRITE(ah, AR_RTC_RC, AR_RTC_RC_MAC_WARM); 1084 break; 1085 case HAL_RESET_COLD: 1086 OS_REG_WRITE(ah, AR_RTC_RC, AR_RTC_RC_MAC_WARM|AR_RTC_RC_MAC_COLD); 1087 break; 1088 default: 1089 HALASSERT(AH_FALSE); 1090 break; 1091 } 1092 1093 /* 1094 * Clear resets and force wakeup 1095 */ 1096 OS_REG_WRITE(ah, AR_RTC_RC, 0); 1097 if (!ath_hal_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0)) { 1098 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RTC stuck in MAC reset\n", __func__); 1099 return AH_FALSE; 1100 } 1101 1102 /* Clear AHB reset */ 1103 OS_REG_WRITE(ah, AR_RC, 0); 1104 1105 if (type == HAL_RESET_COLD) { 1106 if (isBigEndian()) { 1107 /* 1108 * Set CFG, little-endian for register 1109 * and descriptor accesses. 1110 */ 1111 mask = INIT_CONFIG_STATUS | AR_CFG_SWRD | AR_CFG_SWRG; 1112#ifndef AH_NEED_DESC_SWAP 1113 mask |= AR_CFG_SWTD; 1114#endif 1115 HALDEBUG(ah, HAL_DEBUG_RESET, 1116 "%s Applying descriptor swap\n", __func__); 1117 OS_REG_WRITE(ah, AR_CFG, LE_READ_4(&mask)); 1118 } else 1119 OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS); 1120 } 1121 1122 ar5416InitPLL(ah, AH_NULL); 1123 1124 return AH_TRUE; 1125} 1126 1127void 1128ar5416InitChainMasks(struct ath_hal *ah) 1129{ 1130 if (AH5416(ah)->ah_rx_chainmask == 0x5 || 1131 AH5416(ah)->ah_tx_chainmask == 0x5) 1132 OS_REG_WRITE(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN); 1133 /* Setup Chain Masks */ 1134 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, AH5416(ah)->ah_rx_chainmask); 1135 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, AH5416(ah)->ah_rx_chainmask); 1136 OS_REG_WRITE(ah, AR_SELFGEN_MASK, AH5416(ah)->ah_tx_chainmask); 1137} 1138 1139void 1140ar5416RestoreChainMask(struct ath_hal *ah) 1141{ 1142 int rx_chainmask = AH5416(ah)->ah_rx_chainmask; 1143 1144 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) { 1145 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); 1146 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); 1147 } 1148} 1149 1150/* 1151 * Update the chainmask based on the current channel configuration. 1152 * 1153 * XXX ath9k checks bluetooth co-existence here 1154 * XXX ath9k checks whether the current state is "off-channel". 1155 * XXX ath9k sticks the hardware into 1x1 mode for legacy; 1156 * we're going to leave multi-RX on for multi-path cancellation. 1157 */ 1158static void 1159ar5416UpdateChainMasks(struct ath_hal *ah, HAL_BOOL is_ht) 1160{ 1161 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 1162 HAL_CAPABILITIES *pCap = &ahpriv->ah_caps; 1163 1164 if (is_ht) { 1165 AH5416(ah)->ah_tx_chainmask = pCap->halTxChainMask; 1166 } else { 1167 AH5416(ah)->ah_tx_chainmask = 1; 1168 } 1169 AH5416(ah)->ah_rx_chainmask = pCap->halRxChainMask; 1170 HALDEBUG(ah, HAL_DEBUG_ANY, "TX chainmask: 0x%x; RX chainmask: 0x%x\n", 1171 AH5416(ah)->ah_tx_chainmask, 1172 AH5416(ah)->ah_rx_chainmask); 1173} 1174 1175#ifndef IS_5GHZ_FAST_CLOCK_EN 1176#define IS_5GHZ_FAST_CLOCK_EN(ah, chan) AH_FALSE 1177#endif 1178 1179static void 1180ar5416InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan) 1181{ 1182 uint32_t pll; 1183 1184 if (AR_SREV_MERLIN_20(ah) && 1185 chan != AH_NULL && IEEE80211_IS_CHAN_5GHZ(chan)) { 1186 /* 1187 * PLL WAR for Merlin 2.0/2.1 1188 * When doing fast clock, set PLL to 0x142c 1189 * Else, set PLL to 0x2850 to prevent reset-to-reset variation 1190 */ 1191 pll = IS_5GHZ_FAST_CLOCK_EN(ah, chan) ? 0x142c : 0x2850; 1192 } else if (AR_SREV_MERLIN_10_OR_LATER(ah)) { 1193 pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV); 1194 if (chan != AH_NULL) { 1195 if (IEEE80211_IS_CHAN_HALF(chan)) 1196 pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL); 1197 else if (IEEE80211_IS_CHAN_QUARTER(chan)) 1198 pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL); 1199 else if (IEEE80211_IS_CHAN_5GHZ(chan)) 1200 pll |= SM(0x28, AR_RTC_SOWL_PLL_DIV); 1201 else 1202 pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV); 1203 } else 1204 pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV); 1205 } else if (AR_SREV_SOWL_10_OR_LATER(ah)) { 1206 pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV); 1207 if (chan != AH_NULL) { 1208 if (IEEE80211_IS_CHAN_HALF(chan)) 1209 pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL); 1210 else if (IEEE80211_IS_CHAN_QUARTER(chan)) 1211 pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL); 1212 else if (IEEE80211_IS_CHAN_5GHZ(chan)) 1213 pll |= SM(0x50, AR_RTC_SOWL_PLL_DIV); 1214 else 1215 pll |= SM(0x58, AR_RTC_SOWL_PLL_DIV); 1216 } else 1217 pll |= SM(0x58, AR_RTC_SOWL_PLL_DIV); 1218 } else { 1219 pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2; 1220 if (chan != AH_NULL) { 1221 if (IEEE80211_IS_CHAN_HALF(chan)) 1222 pll |= SM(0x1, AR_RTC_PLL_CLKSEL); 1223 else if (IEEE80211_IS_CHAN_QUARTER(chan)) 1224 pll |= SM(0x2, AR_RTC_PLL_CLKSEL); 1225 else if (IEEE80211_IS_CHAN_5GHZ(chan)) 1226 pll |= SM(0xa, AR_RTC_PLL_DIV); 1227 else 1228 pll |= SM(0xb, AR_RTC_PLL_DIV); 1229 } else 1230 pll |= SM(0xb, AR_RTC_PLL_DIV); 1231 } 1232 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); 1233 1234 /* TODO: 1235 * For multi-band owl, switch between bands by reiniting the PLL. 1236 */ 1237 1238 OS_DELAY(RTC_PLL_SETTLE_DELAY); 1239 1240 OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_SLEEP_DERIVED_CLK); 1241} 1242 1243static void 1244ar5416SetDefGainValues(struct ath_hal *ah, 1245 const MODAL_EEP_HEADER *pModal, 1246 const struct ar5416eeprom *eep, 1247 uint8_t txRxAttenLocal, int regChainOffset, int i) 1248{ 1249 if (IS_EEP_MINOR_V3(ah)) { 1250 txRxAttenLocal = pModal->txRxAttenCh[i]; 1251 1252 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 1253 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1254 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, 1255 pModal->bswMargin[i]); 1256 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1257 AR_PHY_GAIN_2GHZ_XATTEN1_DB, 1258 pModal->bswAtten[i]); 1259 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1260 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, 1261 pModal->xatten2Margin[i]); 1262 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1263 AR_PHY_GAIN_2GHZ_XATTEN2_DB, 1264 pModal->xatten2Db[i]); 1265 } else { 1266 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1267 (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 1268 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) 1269 | SM(pModal-> bswMargin[i], 1270 AR_PHY_GAIN_2GHZ_BSW_MARGIN)); 1271 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1272 (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 1273 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) 1274 | SM(pModal->bswAtten[i], 1275 AR_PHY_GAIN_2GHZ_BSW_ATTEN)); 1276 } 1277 } 1278 1279 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 1280 OS_REG_RMW_FIELD(ah, 1281 AR_PHY_RXGAIN + regChainOffset, 1282 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 1283 OS_REG_RMW_FIELD(ah, 1284 AR_PHY_RXGAIN + regChainOffset, 1285 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]); 1286 } else { 1287 OS_REG_WRITE(ah, 1288 AR_PHY_RXGAIN + regChainOffset, 1289 (OS_REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) & 1290 ~AR_PHY_RXGAIN_TXRX_ATTEN) 1291 | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN)); 1292 OS_REG_WRITE(ah, 1293 AR_PHY_GAIN_2GHZ + regChainOffset, 1294 (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 1295 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) | 1296 SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN)); 1297 } 1298} 1299
| 936 /* Write the OFDM power per rate set */ 937 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, 938 POW_SM(ratesArray[rate18mb], 24) 939 | POW_SM(ratesArray[rate12mb], 16) 940 | POW_SM(ratesArray[rate9mb], 8) 941 | POW_SM(ratesArray[rate6mb], 0) 942 ); 943 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, 944 POW_SM(ratesArray[rate54mb], 24) 945 | POW_SM(ratesArray[rate48mb], 16) 946 | POW_SM(ratesArray[rate36mb], 8) 947 | POW_SM(ratesArray[rate24mb], 0) 948 ); 949 950 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 951 /* Write the CCK power per rate set */ 952 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, 953 POW_SM(ratesArray[rate2s], 24) 954 | POW_SM(ratesArray[rate2l], 16) 955 | POW_SM(ratesArray[rateXr], 8) /* XR target power */ 956 | POW_SM(ratesArray[rate1l], 0) 957 ); 958 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, 959 POW_SM(ratesArray[rate11s], 24) 960 | POW_SM(ratesArray[rate11l], 16) 961 | POW_SM(ratesArray[rate5_5s], 8) 962 | POW_SM(ratesArray[rate5_5l], 0) 963 ); 964 HALDEBUG(ah, HAL_DEBUG_RESET, 965 "%s AR_PHY_POWER_TX_RATE3=0x%x AR_PHY_POWER_TX_RATE4=0x%x\n", 966 __func__, OS_REG_READ(ah,AR_PHY_POWER_TX_RATE3), 967 OS_REG_READ(ah,AR_PHY_POWER_TX_RATE4)); 968 } 969 970 /* Write the HT20 power per rate set */ 971 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, 972 POW_SM(ratesArray[rateHt20_3], 24) 973 | POW_SM(ratesArray[rateHt20_2], 16) 974 | POW_SM(ratesArray[rateHt20_1], 8) 975 | POW_SM(ratesArray[rateHt20_0], 0) 976 ); 977 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, 978 POW_SM(ratesArray[rateHt20_7], 24) 979 | POW_SM(ratesArray[rateHt20_6], 16) 980 | POW_SM(ratesArray[rateHt20_5], 8) 981 | POW_SM(ratesArray[rateHt20_4], 0) 982 ); 983 984 if (IEEE80211_IS_CHAN_HT40(chan)) { 985 /* Write the HT40 power per rate set */ 986 /* Correct PAR difference between HT40 and HT20/LEGACY */ 987 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, 988 POW_SM(ratesArray[rateHt40_3] + ht40PowerIncForPdadc, 24) 989 | POW_SM(ratesArray[rateHt40_2] + ht40PowerIncForPdadc, 16) 990 | POW_SM(ratesArray[rateHt40_1] + ht40PowerIncForPdadc, 8) 991 | POW_SM(ratesArray[rateHt40_0] + ht40PowerIncForPdadc, 0) 992 ); 993 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, 994 POW_SM(ratesArray[rateHt40_7] + ht40PowerIncForPdadc, 24) 995 | POW_SM(ratesArray[rateHt40_6] + ht40PowerIncForPdadc, 16) 996 | POW_SM(ratesArray[rateHt40_5] + ht40PowerIncForPdadc, 8) 997 | POW_SM(ratesArray[rateHt40_4] + ht40PowerIncForPdadc, 0) 998 ); 999 /* Write the Dup/Ext 40 power per rate set */ 1000 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, 1001 POW_SM(ratesArray[rateExtOfdm], 24) 1002 | POW_SM(ratesArray[rateExtCck], 16) 1003 | POW_SM(ratesArray[rateDupOfdm], 8) 1004 | POW_SM(ratesArray[rateDupCck], 0) 1005 ); 1006 } 1007 1008 /* Write the Power subtraction for dynamic chain changing, for per-packet powertx */ 1009 OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB, 1010 POW_SM(pModal->pwrDecreaseFor3Chain, 6) 1011 | POW_SM(pModal->pwrDecreaseFor2Chain, 0) 1012 ); 1013 return AH_TRUE; 1014#undef POW_SM 1015#undef N 1016} 1017 1018/* 1019 * Exported call to check for a recent gain reading and return 1020 * the current state of the thermal calibration gain engine. 1021 */ 1022HAL_RFGAIN 1023ar5416GetRfgain(struct ath_hal *ah) 1024{ 1025 return HAL_RFGAIN_INACTIVE; 1026} 1027 1028/* 1029 * Places all of hardware into reset 1030 */ 1031HAL_BOOL 1032ar5416Disable(struct ath_hal *ah) 1033{ 1034 if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) 1035 return AH_FALSE; 1036 return ar5416SetResetReg(ah, HAL_RESET_COLD); 1037} 1038 1039/* 1040 * Places the PHY and Radio chips into reset. A full reset 1041 * must be called to leave this state. The PCI/MAC/PCU are 1042 * not placed into reset as we must receive interrupt to 1043 * re-enable the hardware. 1044 */ 1045HAL_BOOL 1046ar5416PhyDisable(struct ath_hal *ah) 1047{ 1048 return ar5416SetResetReg(ah, HAL_RESET_WARM); 1049} 1050 1051/* 1052 * Write the given reset bit mask into the reset register 1053 */ 1054HAL_BOOL 1055ar5416SetResetReg(struct ath_hal *ah, uint32_t type) 1056{ 1057 switch (type) { 1058 case HAL_RESET_POWER_ON: 1059 return ar5416SetResetPowerOn(ah); 1060 case HAL_RESET_WARM: 1061 case HAL_RESET_COLD: 1062 return ar5416SetReset(ah, type); 1063 default: 1064 HALASSERT(AH_FALSE); 1065 return AH_FALSE; 1066 } 1067} 1068 1069static HAL_BOOL 1070ar5416SetResetPowerOn(struct ath_hal *ah) 1071{ 1072 /* Power On Reset (Hard Reset) */ 1073 1074 /* 1075 * Set force wake 1076 * 1077 * If the MAC was running, previously calling 1078 * reset will wake up the MAC but it may go back to sleep 1079 * before we can start polling. 1080 * Set force wake stops that 1081 * This must be called before initiating a hard reset. 1082 */ 1083 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1084 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1085 1086 /* 1087 * RTC reset and clear 1088 */ 1089 OS_REG_WRITE(ah, AR_RC, AR_RC_AHB); 1090 OS_REG_WRITE(ah, AR_RTC_RESET, 0); 1091 OS_DELAY(20); 1092 OS_REG_WRITE(ah, AR_RC, 0); 1093 1094 OS_REG_WRITE(ah, AR_RTC_RESET, 1); 1095 1096 /* 1097 * Poll till RTC is ON 1098 */ 1099 if (!ath_hal_wait(ah, AR_RTC_STATUS, AR_RTC_PM_STATUS_M, AR_RTC_STATUS_ON)) { 1100 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RTC not waking up\n", __func__); 1101 return AH_FALSE; 1102 } 1103 1104 return ar5416SetReset(ah, HAL_RESET_COLD); 1105} 1106 1107static HAL_BOOL 1108ar5416SetReset(struct ath_hal *ah, int type) 1109{ 1110 uint32_t tmpReg, mask; 1111 1112 /* 1113 * Force wake 1114 */ 1115 OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1116 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1117 1118 /* 1119 * Reset AHB 1120 */ 1121 tmpReg = OS_REG_READ(ah, AR_INTR_SYNC_CAUSE); 1122 if (tmpReg & (AR_INTR_SYNC_LOCAL_TIMEOUT|AR_INTR_SYNC_RADM_CPL_TIMEOUT)) { 1123 OS_REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); 1124 OS_REG_WRITE(ah, AR_RC, AR_RC_AHB|AR_RC_HOSTIF); 1125 } else { 1126 OS_REG_WRITE(ah, AR_RC, AR_RC_AHB); 1127 } 1128 1129 /* 1130 * Set Mac(BB,Phy) Warm Reset 1131 */ 1132 switch (type) { 1133 case HAL_RESET_WARM: 1134 OS_REG_WRITE(ah, AR_RTC_RC, AR_RTC_RC_MAC_WARM); 1135 break; 1136 case HAL_RESET_COLD: 1137 OS_REG_WRITE(ah, AR_RTC_RC, AR_RTC_RC_MAC_WARM|AR_RTC_RC_MAC_COLD); 1138 break; 1139 default: 1140 HALASSERT(AH_FALSE); 1141 break; 1142 } 1143 1144 /* 1145 * Clear resets and force wakeup 1146 */ 1147 OS_REG_WRITE(ah, AR_RTC_RC, 0); 1148 if (!ath_hal_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0)) { 1149 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RTC stuck in MAC reset\n", __func__); 1150 return AH_FALSE; 1151 } 1152 1153 /* Clear AHB reset */ 1154 OS_REG_WRITE(ah, AR_RC, 0); 1155 1156 if (type == HAL_RESET_COLD) { 1157 if (isBigEndian()) { 1158 /* 1159 * Set CFG, little-endian for register 1160 * and descriptor accesses. 1161 */ 1162 mask = INIT_CONFIG_STATUS | AR_CFG_SWRD | AR_CFG_SWRG; 1163#ifndef AH_NEED_DESC_SWAP 1164 mask |= AR_CFG_SWTD; 1165#endif 1166 HALDEBUG(ah, HAL_DEBUG_RESET, 1167 "%s Applying descriptor swap\n", __func__); 1168 OS_REG_WRITE(ah, AR_CFG, LE_READ_4(&mask)); 1169 } else 1170 OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS); 1171 } 1172 1173 ar5416InitPLL(ah, AH_NULL); 1174 1175 return AH_TRUE; 1176} 1177 1178void 1179ar5416InitChainMasks(struct ath_hal *ah) 1180{ 1181 if (AH5416(ah)->ah_rx_chainmask == 0x5 || 1182 AH5416(ah)->ah_tx_chainmask == 0x5) 1183 OS_REG_WRITE(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN); 1184 /* Setup Chain Masks */ 1185 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, AH5416(ah)->ah_rx_chainmask); 1186 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, AH5416(ah)->ah_rx_chainmask); 1187 OS_REG_WRITE(ah, AR_SELFGEN_MASK, AH5416(ah)->ah_tx_chainmask); 1188} 1189 1190void 1191ar5416RestoreChainMask(struct ath_hal *ah) 1192{ 1193 int rx_chainmask = AH5416(ah)->ah_rx_chainmask; 1194 1195 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) { 1196 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); 1197 OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); 1198 } 1199} 1200 1201/* 1202 * Update the chainmask based on the current channel configuration. 1203 * 1204 * XXX ath9k checks bluetooth co-existence here 1205 * XXX ath9k checks whether the current state is "off-channel". 1206 * XXX ath9k sticks the hardware into 1x1 mode for legacy; 1207 * we're going to leave multi-RX on for multi-path cancellation. 1208 */ 1209static void 1210ar5416UpdateChainMasks(struct ath_hal *ah, HAL_BOOL is_ht) 1211{ 1212 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 1213 HAL_CAPABILITIES *pCap = &ahpriv->ah_caps; 1214 1215 if (is_ht) { 1216 AH5416(ah)->ah_tx_chainmask = pCap->halTxChainMask; 1217 } else { 1218 AH5416(ah)->ah_tx_chainmask = 1; 1219 } 1220 AH5416(ah)->ah_rx_chainmask = pCap->halRxChainMask; 1221 HALDEBUG(ah, HAL_DEBUG_ANY, "TX chainmask: 0x%x; RX chainmask: 0x%x\n", 1222 AH5416(ah)->ah_tx_chainmask, 1223 AH5416(ah)->ah_rx_chainmask); 1224} 1225 1226#ifndef IS_5GHZ_FAST_CLOCK_EN 1227#define IS_5GHZ_FAST_CLOCK_EN(ah, chan) AH_FALSE 1228#endif 1229 1230static void 1231ar5416InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan) 1232{ 1233 uint32_t pll; 1234 1235 if (AR_SREV_MERLIN_20(ah) && 1236 chan != AH_NULL && IEEE80211_IS_CHAN_5GHZ(chan)) { 1237 /* 1238 * PLL WAR for Merlin 2.0/2.1 1239 * When doing fast clock, set PLL to 0x142c 1240 * Else, set PLL to 0x2850 to prevent reset-to-reset variation 1241 */ 1242 pll = IS_5GHZ_FAST_CLOCK_EN(ah, chan) ? 0x142c : 0x2850; 1243 } else if (AR_SREV_MERLIN_10_OR_LATER(ah)) { 1244 pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV); 1245 if (chan != AH_NULL) { 1246 if (IEEE80211_IS_CHAN_HALF(chan)) 1247 pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL); 1248 else if (IEEE80211_IS_CHAN_QUARTER(chan)) 1249 pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL); 1250 else if (IEEE80211_IS_CHAN_5GHZ(chan)) 1251 pll |= SM(0x28, AR_RTC_SOWL_PLL_DIV); 1252 else 1253 pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV); 1254 } else 1255 pll |= SM(0x2c, AR_RTC_SOWL_PLL_DIV); 1256 } else if (AR_SREV_SOWL_10_OR_LATER(ah)) { 1257 pll = SM(0x5, AR_RTC_SOWL_PLL_REFDIV); 1258 if (chan != AH_NULL) { 1259 if (IEEE80211_IS_CHAN_HALF(chan)) 1260 pll |= SM(0x1, AR_RTC_SOWL_PLL_CLKSEL); 1261 else if (IEEE80211_IS_CHAN_QUARTER(chan)) 1262 pll |= SM(0x2, AR_RTC_SOWL_PLL_CLKSEL); 1263 else if (IEEE80211_IS_CHAN_5GHZ(chan)) 1264 pll |= SM(0x50, AR_RTC_SOWL_PLL_DIV); 1265 else 1266 pll |= SM(0x58, AR_RTC_SOWL_PLL_DIV); 1267 } else 1268 pll |= SM(0x58, AR_RTC_SOWL_PLL_DIV); 1269 } else { 1270 pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2; 1271 if (chan != AH_NULL) { 1272 if (IEEE80211_IS_CHAN_HALF(chan)) 1273 pll |= SM(0x1, AR_RTC_PLL_CLKSEL); 1274 else if (IEEE80211_IS_CHAN_QUARTER(chan)) 1275 pll |= SM(0x2, AR_RTC_PLL_CLKSEL); 1276 else if (IEEE80211_IS_CHAN_5GHZ(chan)) 1277 pll |= SM(0xa, AR_RTC_PLL_DIV); 1278 else 1279 pll |= SM(0xb, AR_RTC_PLL_DIV); 1280 } else 1281 pll |= SM(0xb, AR_RTC_PLL_DIV); 1282 } 1283 OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); 1284 1285 /* TODO: 1286 * For multi-band owl, switch between bands by reiniting the PLL. 1287 */ 1288 1289 OS_DELAY(RTC_PLL_SETTLE_DELAY); 1290 1291 OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_SLEEP_DERIVED_CLK); 1292} 1293 1294static void 1295ar5416SetDefGainValues(struct ath_hal *ah, 1296 const MODAL_EEP_HEADER *pModal, 1297 const struct ar5416eeprom *eep, 1298 uint8_t txRxAttenLocal, int regChainOffset, int i) 1299{ 1300 if (IS_EEP_MINOR_V3(ah)) { 1301 txRxAttenLocal = pModal->txRxAttenCh[i]; 1302 1303 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 1304 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1305 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, 1306 pModal->bswMargin[i]); 1307 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1308 AR_PHY_GAIN_2GHZ_XATTEN1_DB, 1309 pModal->bswAtten[i]); 1310 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1311 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, 1312 pModal->xatten2Margin[i]); 1313 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1314 AR_PHY_GAIN_2GHZ_XATTEN2_DB, 1315 pModal->xatten2Db[i]); 1316 } else { 1317 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1318 (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 1319 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) 1320 | SM(pModal-> bswMargin[i], 1321 AR_PHY_GAIN_2GHZ_BSW_MARGIN)); 1322 OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1323 (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 1324 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) 1325 | SM(pModal->bswAtten[i], 1326 AR_PHY_GAIN_2GHZ_BSW_ATTEN)); 1327 } 1328 } 1329 1330 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 1331 OS_REG_RMW_FIELD(ah, 1332 AR_PHY_RXGAIN + regChainOffset, 1333 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 1334 OS_REG_RMW_FIELD(ah, 1335 AR_PHY_RXGAIN + regChainOffset, 1336 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]); 1337 } else { 1338 OS_REG_WRITE(ah, 1339 AR_PHY_RXGAIN + regChainOffset, 1340 (OS_REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) & 1341 ~AR_PHY_RXGAIN_TXRX_ATTEN) 1342 | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN)); 1343 OS_REG_WRITE(ah, 1344 AR_PHY_GAIN_2GHZ + regChainOffset, 1345 (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 1346 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) | 1347 SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN)); 1348 } 1349} 1350
|
| 1351/* 1352 * Get the register chain offset for the given chain. 1353 * 1354 * Take into account the register chain swapping with AR5416 v2.0. 1355 * 1356 * XXX make sure that the reg chain swapping is only done for 1357 * XXX AR5416 v2.0 or greater, and not later chips? 1358 */ 1359int 1360ar5416GetRegChainOffset(struct ath_hal *ah, int i) 1361{ 1362 int regChainOffset;
|
1300
| 1363
|
| 1364 if (AR_SREV_OWL_20_OR_LATER(ah) && 1365 (AH5416(ah)->ah_rx_chainmask == 0x5 || 1366 AH5416(ah)->ah_tx_chainmask == 0x5) && (i != 0)) { 1367 /* Regs are swapped from chain 2 to 1 for 5416 2_0 with 1368 * only chains 0 and 2 populated 1369 */ 1370 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 1371 } else { 1372 regChainOffset = i * 0x1000; 1373 }
|
1301
| 1374
|
| 1375 return regChainOffset; 1376} 1377
|
1302/* 1303 * Read EEPROM header info and program the device for correct operation 1304 * given the channel value. 1305 */ 1306HAL_BOOL 1307ar5416SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan) 1308{ 1309 const HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom; 1310 const struct ar5416eeprom *eep = &ee->ee_base; 1311 const MODAL_EEP_HEADER *pModal; 1312 int i, regChainOffset; 1313 uint8_t txRxAttenLocal; /* workaround for eeprom versions <= 14.2 */ 1314 1315 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); 1316 pModal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)]; 1317 1318 /* NB: workaround for eeprom versions <= 14.2 */ 1319 txRxAttenLocal = IEEE80211_IS_CHAN_2GHZ(chan) ? 23 : 44; 1320 1321 OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); 1322 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 1323 if (AR_SREV_MERLIN(ah)) { 1324 if (i >= 2) break; 1325 }
| 1378/* 1379 * Read EEPROM header info and program the device for correct operation 1380 * given the channel value. 1381 */ 1382HAL_BOOL 1383ar5416SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan) 1384{ 1385 const HAL_EEPROM_v14 *ee = AH_PRIVATE(ah)->ah_eeprom; 1386 const struct ar5416eeprom *eep = &ee->ee_base; 1387 const MODAL_EEP_HEADER *pModal; 1388 int i, regChainOffset; 1389 uint8_t txRxAttenLocal; /* workaround for eeprom versions <= 14.2 */ 1390 1391 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); 1392 pModal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)]; 1393 1394 /* NB: workaround for eeprom versions <= 14.2 */ 1395 txRxAttenLocal = IEEE80211_IS_CHAN_2GHZ(chan) ? 23 : 44; 1396 1397 OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon); 1398 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 1399 if (AR_SREV_MERLIN(ah)) { 1400 if (i >= 2) break; 1401 }
|
1326 if (AR_SREV_OWL_20_OR_LATER(ah) && 1327 (AH5416(ah)->ah_rx_chainmask == 0x5 || 1328 AH5416(ah)->ah_tx_chainmask == 0x5) && i != 0) { 1329 /* Regs are swapped from chain 2 to 1 for 5416 2_0 with 1330 * only chains 0 and 2 populated 1331 */ 1332 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 1333 } else { 1334 regChainOffset = i * 0x1000; 1335 }
| 1402 regChainOffset = ar5416GetRegChainOffset(ah, i);
|
1336 1337 OS_REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, pModal->antCtrlChain[i]); 1338 1339 OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4 + regChainOffset, 1340 (OS_REG_READ(ah, AR_PHY_TIMING_CTRL4 + regChainOffset) & 1341 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 1342 SM(pModal->iqCalICh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 1343 SM(pModal->iqCalQCh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 1344 1345 /* 1346 * Large signal upgrade. 1347 * XXX update 1348 */ 1349 1350 if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) 1351 ar5416SetDefGainValues(ah, pModal, eep, txRxAttenLocal, regChainOffset, i); 1352 1353 } 1354 1355 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 1356 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 1357 OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH0, AR_AN_RF2G1_CH0_OB, pModal->ob); 1358 OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH0, AR_AN_RF2G1_CH0_DB, pModal->db); 1359 OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH1, AR_AN_RF2G1_CH1_OB, pModal->ob_ch1); 1360 OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH1, AR_AN_RF2G1_CH1_DB, pModal->db_ch1); 1361 } else { 1362 OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH0, AR_AN_RF5G1_CH0_OB5, pModal->ob); 1363 OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH0, AR_AN_RF5G1_CH0_DB5, pModal->db); 1364 OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH1, AR_AN_RF5G1_CH1_OB5, pModal->ob_ch1); 1365 OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH1, AR_AN_RF5G1_CH1_DB5, pModal->db_ch1); 1366 } 1367 OS_A_REG_RMW_FIELD(ah, AR_AN_TOP2, AR_AN_TOP2_XPABIAS_LVL, pModal->xpaBiasLvl); 1368 OS_A_REG_RMW_FIELD(ah, AR_AN_TOP2, AR_AN_TOP2_LOCALBIAS, pModal->flagBits & AR5416_EEP_FLAG_LOCALBIAS); 1369 OS_A_REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, pModal->flagBits & AR5416_EEP_FLAG_FORCEXPAON); 1370 } 1371 1372 OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->switchSettling); 1373 OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize); 1374 1375 if (! AR_SREV_MERLIN_20_OR_LATER(ah)) 1376 OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_PGA, pModal->pgaDesiredSize); 1377 1378 OS_REG_WRITE(ah, AR_PHY_RF_CTL4, 1379 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) 1380 | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) 1381 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) 1382 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 1383 1384 OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn); 1385 1386 if (AR_SREV_MERLIN_10_OR_LATER(ah)) { 1387 OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 1388 pModal->thresh62); 1389 OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, 1390 pModal->thresh62); 1391 } else { 1392 OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62, 1393 pModal->thresh62); 1394 OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA_THRESH62, 1395 pModal->thresh62); 1396 } 1397 1398 /* Minor Version Specific application */ 1399 if (IS_EEP_MINOR_V2(ah)) { 1400 OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_FRAME_TO_DATA_START, pModal->txFrameToDataStart); 1401 OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_FRAME_TO_PA_ON, pModal->txFrameToPaOn); 1402 } 1403 1404 if (IS_EEP_MINOR_V3(ah) && IEEE80211_IS_CHAN_HT40(chan)) 1405 /* Overwrite switch settling with HT40 value */ 1406 OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40); 1407 1408 if (AR_SREV_MERLIN_20_OR_LATER(ah) && EEP_MINOR(ah) >= AR5416_EEP_MINOR_VER_19) 1409 OS_REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL, AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK, pModal->miscBits); 1410 1411 if (AR_SREV_MERLIN_20(ah) && EEP_MINOR(ah) >= AR5416_EEP_MINOR_VER_20) { 1412 if (IEEE80211_IS_CHAN_2GHZ(chan)) 1413 OS_A_REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, eep->baseEepHeader.dacLpMode); 1414 else if (eep->baseEepHeader.dacHiPwrMode_5G) 1415 OS_A_REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0); 1416 else 1417 OS_A_REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, eep->baseEepHeader.dacLpMode); 1418 1419 OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP, pModal->miscBits >> 2); 1420 OS_REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9, AR_PHY_TX_DESIRED_SCALE_CCK, eep->baseEepHeader.desiredScaleCCK); 1421 } 1422 1423 return AH_TRUE; 1424} 1425 1426/* 1427 * Helper functions common for AP/CB/XB 1428 */ 1429 1430/* 1431 * ar5416SetPowerPerRateTable 1432 * 1433 * Sets the transmit power in the baseband for the given 1434 * operating channel and mode. 1435 */ 1436static HAL_BOOL 1437ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, 1438 const struct ieee80211_channel *chan, 1439 int16_t *ratesArray, uint16_t cfgCtl, 1440 uint16_t AntennaReduction, 1441 uint16_t twiceMaxRegulatoryPower, 1442 uint16_t powerLimit) 1443{ 1444#define N(a) (sizeof(a)/sizeof(a[0])) 1445/* Local defines to distinguish between extension and control CTL's */ 1446#define EXT_ADDITIVE (0x8000) 1447#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE) 1448#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE) 1449#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) 1450 1451 uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 1452 int i; 1453 int16_t twiceLargestAntenna; 1454 CAL_CTL_DATA *rep; 1455 CAL_TARGET_POWER_LEG targetPowerOfdm, targetPowerCck = {0, {0, 0, 0, 0}}; 1456 CAL_TARGET_POWER_LEG targetPowerOfdmExt = {0, {0, 0, 0, 0}}, targetPowerCckExt = {0, {0, 0, 0, 0}}; 1457 CAL_TARGET_POWER_HT targetPowerHt20, targetPowerHt40 = {0, {0, 0, 0, 0}}; 1458 int16_t scaledPower, minCtlPower; 1459 1460#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ 1461#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ 1462 static const uint16_t ctlModesFor11a[] = { 1463 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 1464 }; 1465 static const uint16_t ctlModesFor11g[] = { 1466 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40 1467 }; 1468 const uint16_t *pCtlMode; 1469 uint16_t numCtlModes, ctlMode, freq; 1470 CHAN_CENTERS centers; 1471 1472 ar5416GetChannelCenters(ah, chan, ¢ers); 1473 1474 /* Compute TxPower reduction due to Antenna Gain */ 1475 1476 twiceLargestAntenna = AH_MAX(AH_MAX( 1477 pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[0], 1478 pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[1]), 1479 pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[2]); 1480#if 0 1481 /* Turn it back on if we need to calculate per chain antenna gain reduction */ 1482 /* Use only if the expected gain > 6dbi */ 1483 /* Chain 0 is always used */ 1484 twiceLargestAntenna = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[0]; 1485 1486 /* Look at antenna gains of Chains 1 and 2 if the TX mask is set */ 1487 if (ahp->ah_tx_chainmask & 0x2) 1488 twiceLargestAntenna = AH_MAX(twiceLargestAntenna, 1489 pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[1]); 1490 1491 if (ahp->ah_tx_chainmask & 0x4) 1492 twiceLargestAntenna = AH_MAX(twiceLargestAntenna, 1493 pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[2]); 1494#endif 1495 twiceLargestAntenna = (int16_t)AH_MIN((AntennaReduction) - twiceLargestAntenna, 0); 1496 1497 /* XXX setup for 5212 use (really used?) */ 1498 ath_hal_eepromSet(ah, 1499 IEEE80211_IS_CHAN_2GHZ(chan) ? AR_EEP_ANTGAINMAX_2 : AR_EEP_ANTGAINMAX_5, 1500 twiceLargestAntenna); 1501 1502 /* 1503 * scaledPower is the minimum of the user input power level and 1504 * the regulatory allowed power level 1505 */ 1506 scaledPower = AH_MIN(powerLimit, twiceMaxRegulatoryPower + twiceLargestAntenna); 1507 1508 /* Reduce scaled Power by number of chains active to get to per chain tx power level */ 1509 /* TODO: better value than these? */ 1510 switch (owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask)) { 1511 case 1: 1512 break; 1513 case 2: 1514 scaledPower -= pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pwrDecreaseFor2Chain; 1515 break; 1516 case 3: 1517 scaledPower -= pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pwrDecreaseFor3Chain; 1518 break; 1519 default: 1520 return AH_FALSE; /* Unsupported number of chains */ 1521 } 1522 1523 scaledPower = AH_MAX(0, scaledPower); 1524 1525 /* Get target powers from EEPROM - our baseline for TX Power */ 1526 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 1527 /* Setup for CTL modes */ 1528 numCtlModes = N(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; /* CTL_11B, CTL_11G, CTL_2GHT20 */ 1529 pCtlMode = ctlModesFor11g; 1530 1531 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPowerCck, 1532 AR5416_NUM_2G_CCK_TARGET_POWERS, &targetPowerCck, 4, AH_FALSE); 1533 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower2G, 1534 AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE); 1535 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT20, 1536 AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE); 1537 1538 if (IEEE80211_IS_CHAN_HT40(chan)) { 1539 numCtlModes = N(ctlModesFor11g); /* All 2G CTL's */ 1540 1541 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT40, 1542 AR5416_NUM_2G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE); 1543 /* Get target powers for extension channels */ 1544 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPowerCck, 1545 AR5416_NUM_2G_CCK_TARGET_POWERS, &targetPowerCckExt, 4, AH_TRUE); 1546 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower2G, 1547 AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE); 1548 } 1549 } else { 1550 /* Setup for CTL modes */ 1551 numCtlModes = N(ctlModesFor11a) - SUB_NUM_CTL_MODES_AT_5G_40; /* CTL_11A, CTL_5GHT20 */ 1552 pCtlMode = ctlModesFor11a; 1553 1554 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower5G, 1555 AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE); 1556 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower5GHT20, 1557 AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE); 1558 1559 if (IEEE80211_IS_CHAN_HT40(chan)) { 1560 numCtlModes = N(ctlModesFor11a); /* All 5G CTL's */ 1561 1562 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower5GHT40, 1563 AR5416_NUM_5G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE); 1564 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower5G, 1565 AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE); 1566 } 1567 } 1568 1569 /* 1570 * For MIMO, need to apply regulatory caps individually across dynamically 1571 * running modes: CCK, OFDM, HT20, HT40 1572 * 1573 * The outer loop walks through each possible applicable runtime mode. 1574 * The inner loop walks through each ctlIndex entry in EEPROM. 1575 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode. 1576 * 1577 */ 1578 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 1579 HAL_BOOL isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 1580 (pCtlMode[ctlMode] == CTL_2GHT40); 1581 if (isHt40CtlMode) { 1582 freq = centers.ctl_center; 1583 } else if (pCtlMode[ctlMode] & EXT_ADDITIVE) { 1584 freq = centers.ext_center; 1585 } else { 1586 freq = centers.ctl_center; 1587 } 1588 1589 /* walk through each CTL index stored in EEPROM */ 1590 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { 1591 uint16_t twiceMinEdgePower; 1592 1593 /* compare test group from regulatory channel list with test mode from pCtlMode list */ 1594 if ((((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == pEepData->ctlIndex[i]) || 1595 (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == 1596 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) { 1597 rep = &(pEepData->ctlData[i]); 1598 twiceMinEdgePower = ar5416GetMaxEdgePower(freq, 1599 rep->ctlEdges[owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask) - 1], 1600 IEEE80211_IS_CHAN_2GHZ(chan)); 1601 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { 1602 /* Find the minimum of all CTL edge powers that apply to this channel */ 1603 twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower); 1604 } else { 1605 /* specific */ 1606 twiceMaxEdgePower = twiceMinEdgePower; 1607 break; 1608 } 1609 } 1610 } 1611 minCtlPower = (uint8_t)AH_MIN(twiceMaxEdgePower, scaledPower); 1612 /* Apply ctl mode to correct target power set */ 1613 switch(pCtlMode[ctlMode]) { 1614 case CTL_11B: 1615 for (i = 0; i < N(targetPowerCck.tPow2x); i++) { 1616 targetPowerCck.tPow2x[i] = (uint8_t)AH_MIN(targetPowerCck.tPow2x[i], minCtlPower); 1617 } 1618 break; 1619 case CTL_11A: 1620 case CTL_11G: 1621 for (i = 0; i < N(targetPowerOfdm.tPow2x); i++) { 1622 targetPowerOfdm.tPow2x[i] = (uint8_t)AH_MIN(targetPowerOfdm.tPow2x[i], minCtlPower); 1623 } 1624 break; 1625 case CTL_5GHT20: 1626 case CTL_2GHT20: 1627 for (i = 0; i < N(targetPowerHt20.tPow2x); i++) { 1628 targetPowerHt20.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt20.tPow2x[i], minCtlPower); 1629 } 1630 break; 1631 case CTL_11B_EXT: 1632 targetPowerCckExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerCckExt.tPow2x[0], minCtlPower); 1633 break; 1634 case CTL_11A_EXT: 1635 case CTL_11G_EXT: 1636 targetPowerOfdmExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerOfdmExt.tPow2x[0], minCtlPower); 1637 break; 1638 case CTL_5GHT40: 1639 case CTL_2GHT40: 1640 for (i = 0; i < N(targetPowerHt40.tPow2x); i++) { 1641 targetPowerHt40.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt40.tPow2x[i], minCtlPower); 1642 } 1643 break; 1644 default: 1645 return AH_FALSE; 1646 break; 1647 } 1648 } /* end ctl mode checking */ 1649 1650 /* Set rates Array from collected data */ 1651 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = ratesArray[rate18mb] = ratesArray[rate24mb] = targetPowerOfdm.tPow2x[0]; 1652 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; 1653 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; 1654 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; 1655 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; 1656 1657 for (i = 0; i < N(targetPowerHt20.tPow2x); i++) { 1658 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; 1659 } 1660 1661 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 1662 ratesArray[rate1l] = targetPowerCck.tPow2x[0]; 1663 ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1]; 1664 ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2]; 1665 ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3]; 1666 } 1667 if (IEEE80211_IS_CHAN_HT40(chan)) { 1668 for (i = 0; i < N(targetPowerHt40.tPow2x); i++) { 1669 ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i]; 1670 } 1671 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; 1672 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; 1673 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 1674 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 1675 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; 1676 } 1677 } 1678 return AH_TRUE; 1679#undef EXT_ADDITIVE 1680#undef CTL_11A_EXT 1681#undef CTL_11G_EXT 1682#undef CTL_11B_EXT 1683#undef SUB_NUM_CTL_MODES_AT_5G_40 1684#undef SUB_NUM_CTL_MODES_AT_2G_40 1685#undef N 1686} 1687 1688/************************************************************************** 1689 * fbin2freq 1690 * 1691 * Get channel value from binary representation held in eeprom 1692 * RETURNS: the frequency in MHz 1693 */ 1694static uint16_t 1695fbin2freq(uint8_t fbin, HAL_BOOL is2GHz) 1696{ 1697 /* 1698 * Reserved value 0xFF provides an empty definition both as 1699 * an fbin and as a frequency - do not convert 1700 */ 1701 if (fbin == AR5416_BCHAN_UNUSED) { 1702 return fbin; 1703 } 1704 1705 return (uint16_t)((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); 1706} 1707 1708/* 1709 * ar5416GetMaxEdgePower 1710 * 1711 * Find the maximum conformance test limit for the given channel and CTL info 1712 */ 1713static uint16_t 1714ar5416GetMaxEdgePower(uint16_t freq, CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz) 1715{ 1716 uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 1717 int i; 1718 1719 /* Get the edge power */ 1720 for (i = 0; (i < AR5416_NUM_BAND_EDGES) && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED) ; i++) { 1721 /* 1722 * If there's an exact channel match or an inband flag set 1723 * on the lower channel use the given rdEdgePower 1724 */ 1725 if (freq == fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { 1726 twiceMaxEdgePower = MS(pRdEdgesPower[i].tPowerFlag, CAL_CTL_EDGES_POWER); 1727 break; 1728 } else if ((i > 0) && (freq < fbin2freq(pRdEdgesPower[i].bChannel, is2GHz))) { 1729 if (fbin2freq(pRdEdgesPower[i - 1].bChannel, is2GHz) < freq && (pRdEdgesPower[i - 1].tPowerFlag & CAL_CTL_EDGES_FLAG) != 0) { 1730 twiceMaxEdgePower = MS(pRdEdgesPower[i - 1].tPowerFlag, CAL_CTL_EDGES_POWER); 1731 } 1732 /* Leave loop - no more affecting edges possible in this monotonic increasing list */ 1733 break; 1734 } 1735 } 1736 HALASSERT(twiceMaxEdgePower > 0); 1737 return twiceMaxEdgePower; 1738} 1739 1740/************************************************************** 1741 * ar5416GetTargetPowers 1742 * 1743 * Return the rates of target power for the given target power table 1744 * channel, and number of channels 1745 */ 1746void 1747ar5416GetTargetPowers(struct ath_hal *ah, const struct ieee80211_channel *chan, 1748 CAL_TARGET_POWER_HT *powInfo, uint16_t numChannels, 1749 CAL_TARGET_POWER_HT *pNewPower, uint16_t numRates, 1750 HAL_BOOL isHt40Target) 1751{ 1752 uint16_t clo, chi; 1753 int i; 1754 int matchIndex = -1, lowIndex = -1; 1755 uint16_t freq; 1756 CHAN_CENTERS centers; 1757 1758 ar5416GetChannelCenters(ah, chan, ¢ers); 1759 freq = isHt40Target ? centers.synth_center : centers.ctl_center; 1760 1761 /* Copy the target powers into the temp channel list */ 1762 if (freq <= fbin2freq(powInfo[0].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) { 1763 matchIndex = 0; 1764 } else { 1765 for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) { 1766 if (freq == fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) { 1767 matchIndex = i; 1768 break; 1769 } else if ((freq < fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) && 1770 (freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)))) 1771 { 1772 lowIndex = i - 1; 1773 break; 1774 } 1775 } 1776 if ((matchIndex == -1) && (lowIndex == -1)) { 1777 HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))); 1778 matchIndex = i - 1; 1779 } 1780 } 1781 1782 if (matchIndex != -1) { 1783 OS_MEMCPY(pNewPower, &powInfo[matchIndex], sizeof(*pNewPower)); 1784 } else { 1785 HALASSERT(lowIndex != -1); 1786 /* 1787 * Get the lower and upper channels, target powers, 1788 * and interpolate between them. 1789 */ 1790 clo = fbin2freq(powInfo[lowIndex].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)); 1791 chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)); 1792 1793 for (i = 0; i < numRates; i++) { 1794 pNewPower->tPow2x[i] = (uint8_t)interpolate(freq, clo, chi, 1795 powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]); 1796 } 1797 } 1798} 1799/************************************************************** 1800 * ar5416GetTargetPowersLeg 1801 * 1802 * Return the four rates of target power for the given target power table 1803 * channel, and number of channels 1804 */ 1805void 1806ar5416GetTargetPowersLeg(struct ath_hal *ah, 1807 const struct ieee80211_channel *chan, 1808 CAL_TARGET_POWER_LEG *powInfo, uint16_t numChannels, 1809 CAL_TARGET_POWER_LEG *pNewPower, uint16_t numRates, 1810 HAL_BOOL isExtTarget) 1811{ 1812 uint16_t clo, chi; 1813 int i; 1814 int matchIndex = -1, lowIndex = -1; 1815 uint16_t freq; 1816 CHAN_CENTERS centers; 1817 1818 ar5416GetChannelCenters(ah, chan, ¢ers); 1819 freq = (isExtTarget) ? centers.ext_center :centers.ctl_center; 1820 1821 /* Copy the target powers into the temp channel list */ 1822 if (freq <= fbin2freq(powInfo[0].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) { 1823 matchIndex = 0; 1824 } else { 1825 for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) { 1826 if (freq == fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) { 1827 matchIndex = i; 1828 break; 1829 } else if ((freq < fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) && 1830 (freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)))) 1831 { 1832 lowIndex = i - 1; 1833 break; 1834 } 1835 } 1836 if ((matchIndex == -1) && (lowIndex == -1)) { 1837 HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))); 1838 matchIndex = i - 1; 1839 } 1840 } 1841 1842 if (matchIndex != -1) { 1843 OS_MEMCPY(pNewPower, &powInfo[matchIndex], sizeof(*pNewPower)); 1844 } else { 1845 HALASSERT(lowIndex != -1); 1846 /* 1847 * Get the lower and upper channels, target powers, 1848 * and interpolate between them. 1849 */ 1850 clo = fbin2freq(powInfo[lowIndex].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)); 1851 chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)); 1852 1853 for (i = 0; i < numRates; i++) { 1854 pNewPower->tPow2x[i] = (uint8_t)interpolate(freq, clo, chi, 1855 powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]); 1856 } 1857 } 1858} 1859
| 1403 1404 OS_REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, pModal->antCtrlChain[i]); 1405 1406 OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4 + regChainOffset, 1407 (OS_REG_READ(ah, AR_PHY_TIMING_CTRL4 + regChainOffset) & 1408 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 1409 SM(pModal->iqCalICh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) | 1410 SM(pModal->iqCalQCh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); 1411 1412 /* 1413 * Large signal upgrade. 1414 * XXX update 1415 */ 1416 1417 if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) 1418 ar5416SetDefGainValues(ah, pModal, eep, txRxAttenLocal, regChainOffset, i); 1419 1420 } 1421 1422 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 1423 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 1424 OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH0, AR_AN_RF2G1_CH0_OB, pModal->ob); 1425 OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH0, AR_AN_RF2G1_CH0_DB, pModal->db); 1426 OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH1, AR_AN_RF2G1_CH1_OB, pModal->ob_ch1); 1427 OS_A_REG_RMW_FIELD(ah, AR_AN_RF2G1_CH1, AR_AN_RF2G1_CH1_DB, pModal->db_ch1); 1428 } else { 1429 OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH0, AR_AN_RF5G1_CH0_OB5, pModal->ob); 1430 OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH0, AR_AN_RF5G1_CH0_DB5, pModal->db); 1431 OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH1, AR_AN_RF5G1_CH1_OB5, pModal->ob_ch1); 1432 OS_A_REG_RMW_FIELD(ah, AR_AN_RF5G1_CH1, AR_AN_RF5G1_CH1_DB5, pModal->db_ch1); 1433 } 1434 OS_A_REG_RMW_FIELD(ah, AR_AN_TOP2, AR_AN_TOP2_XPABIAS_LVL, pModal->xpaBiasLvl); 1435 OS_A_REG_RMW_FIELD(ah, AR_AN_TOP2, AR_AN_TOP2_LOCALBIAS, pModal->flagBits & AR5416_EEP_FLAG_LOCALBIAS); 1436 OS_A_REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, pModal->flagBits & AR5416_EEP_FLAG_FORCEXPAON); 1437 } 1438 1439 OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->switchSettling); 1440 OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize); 1441 1442 if (! AR_SREV_MERLIN_20_OR_LATER(ah)) 1443 OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_PGA, pModal->pgaDesiredSize); 1444 1445 OS_REG_WRITE(ah, AR_PHY_RF_CTL4, 1446 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) 1447 | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) 1448 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) 1449 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 1450 1451 OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn); 1452 1453 if (AR_SREV_MERLIN_10_OR_LATER(ah)) { 1454 OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, 1455 pModal->thresh62); 1456 OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, 1457 pModal->thresh62); 1458 } else { 1459 OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62, 1460 pModal->thresh62); 1461 OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA_THRESH62, 1462 pModal->thresh62); 1463 } 1464 1465 /* Minor Version Specific application */ 1466 if (IS_EEP_MINOR_V2(ah)) { 1467 OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_FRAME_TO_DATA_START, pModal->txFrameToDataStart); 1468 OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_FRAME_TO_PA_ON, pModal->txFrameToPaOn); 1469 } 1470 1471 if (IS_EEP_MINOR_V3(ah) && IEEE80211_IS_CHAN_HT40(chan)) 1472 /* Overwrite switch settling with HT40 value */ 1473 OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40); 1474 1475 if (AR_SREV_MERLIN_20_OR_LATER(ah) && EEP_MINOR(ah) >= AR5416_EEP_MINOR_VER_19) 1476 OS_REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL, AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK, pModal->miscBits); 1477 1478 if (AR_SREV_MERLIN_20(ah) && EEP_MINOR(ah) >= AR5416_EEP_MINOR_VER_20) { 1479 if (IEEE80211_IS_CHAN_2GHZ(chan)) 1480 OS_A_REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, eep->baseEepHeader.dacLpMode); 1481 else if (eep->baseEepHeader.dacHiPwrMode_5G) 1482 OS_A_REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0); 1483 else 1484 OS_A_REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, eep->baseEepHeader.dacLpMode); 1485 1486 OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP, pModal->miscBits >> 2); 1487 OS_REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9, AR_PHY_TX_DESIRED_SCALE_CCK, eep->baseEepHeader.desiredScaleCCK); 1488 } 1489 1490 return AH_TRUE; 1491} 1492 1493/* 1494 * Helper functions common for AP/CB/XB 1495 */ 1496 1497/* 1498 * ar5416SetPowerPerRateTable 1499 * 1500 * Sets the transmit power in the baseband for the given 1501 * operating channel and mode. 1502 */ 1503static HAL_BOOL 1504ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, 1505 const struct ieee80211_channel *chan, 1506 int16_t *ratesArray, uint16_t cfgCtl, 1507 uint16_t AntennaReduction, 1508 uint16_t twiceMaxRegulatoryPower, 1509 uint16_t powerLimit) 1510{ 1511#define N(a) (sizeof(a)/sizeof(a[0])) 1512/* Local defines to distinguish between extension and control CTL's */ 1513#define EXT_ADDITIVE (0x8000) 1514#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE) 1515#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE) 1516#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) 1517 1518 uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 1519 int i; 1520 int16_t twiceLargestAntenna; 1521 CAL_CTL_DATA *rep; 1522 CAL_TARGET_POWER_LEG targetPowerOfdm, targetPowerCck = {0, {0, 0, 0, 0}}; 1523 CAL_TARGET_POWER_LEG targetPowerOfdmExt = {0, {0, 0, 0, 0}}, targetPowerCckExt = {0, {0, 0, 0, 0}}; 1524 CAL_TARGET_POWER_HT targetPowerHt20, targetPowerHt40 = {0, {0, 0, 0, 0}}; 1525 int16_t scaledPower, minCtlPower; 1526 1527#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ 1528#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ 1529 static const uint16_t ctlModesFor11a[] = { 1530 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 1531 }; 1532 static const uint16_t ctlModesFor11g[] = { 1533 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40 1534 }; 1535 const uint16_t *pCtlMode; 1536 uint16_t numCtlModes, ctlMode, freq; 1537 CHAN_CENTERS centers; 1538 1539 ar5416GetChannelCenters(ah, chan, ¢ers); 1540 1541 /* Compute TxPower reduction due to Antenna Gain */ 1542 1543 twiceLargestAntenna = AH_MAX(AH_MAX( 1544 pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[0], 1545 pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[1]), 1546 pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[2]); 1547#if 0 1548 /* Turn it back on if we need to calculate per chain antenna gain reduction */ 1549 /* Use only if the expected gain > 6dbi */ 1550 /* Chain 0 is always used */ 1551 twiceLargestAntenna = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[0]; 1552 1553 /* Look at antenna gains of Chains 1 and 2 if the TX mask is set */ 1554 if (ahp->ah_tx_chainmask & 0x2) 1555 twiceLargestAntenna = AH_MAX(twiceLargestAntenna, 1556 pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[1]); 1557 1558 if (ahp->ah_tx_chainmask & 0x4) 1559 twiceLargestAntenna = AH_MAX(twiceLargestAntenna, 1560 pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].antennaGainCh[2]); 1561#endif 1562 twiceLargestAntenna = (int16_t)AH_MIN((AntennaReduction) - twiceLargestAntenna, 0); 1563 1564 /* XXX setup for 5212 use (really used?) */ 1565 ath_hal_eepromSet(ah, 1566 IEEE80211_IS_CHAN_2GHZ(chan) ? AR_EEP_ANTGAINMAX_2 : AR_EEP_ANTGAINMAX_5, 1567 twiceLargestAntenna); 1568 1569 /* 1570 * scaledPower is the minimum of the user input power level and 1571 * the regulatory allowed power level 1572 */ 1573 scaledPower = AH_MIN(powerLimit, twiceMaxRegulatoryPower + twiceLargestAntenna); 1574 1575 /* Reduce scaled Power by number of chains active to get to per chain tx power level */ 1576 /* TODO: better value than these? */ 1577 switch (owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask)) { 1578 case 1: 1579 break; 1580 case 2: 1581 scaledPower -= pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pwrDecreaseFor2Chain; 1582 break; 1583 case 3: 1584 scaledPower -= pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pwrDecreaseFor3Chain; 1585 break; 1586 default: 1587 return AH_FALSE; /* Unsupported number of chains */ 1588 } 1589 1590 scaledPower = AH_MAX(0, scaledPower); 1591 1592 /* Get target powers from EEPROM - our baseline for TX Power */ 1593 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 1594 /* Setup for CTL modes */ 1595 numCtlModes = N(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; /* CTL_11B, CTL_11G, CTL_2GHT20 */ 1596 pCtlMode = ctlModesFor11g; 1597 1598 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPowerCck, 1599 AR5416_NUM_2G_CCK_TARGET_POWERS, &targetPowerCck, 4, AH_FALSE); 1600 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower2G, 1601 AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE); 1602 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT20, 1603 AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE); 1604 1605 if (IEEE80211_IS_CHAN_HT40(chan)) { 1606 numCtlModes = N(ctlModesFor11g); /* All 2G CTL's */ 1607 1608 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower2GHT40, 1609 AR5416_NUM_2G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE); 1610 /* Get target powers for extension channels */ 1611 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPowerCck, 1612 AR5416_NUM_2G_CCK_TARGET_POWERS, &targetPowerCckExt, 4, AH_TRUE); 1613 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower2G, 1614 AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE); 1615 } 1616 } else { 1617 /* Setup for CTL modes */ 1618 numCtlModes = N(ctlModesFor11a) - SUB_NUM_CTL_MODES_AT_5G_40; /* CTL_11A, CTL_5GHT20 */ 1619 pCtlMode = ctlModesFor11a; 1620 1621 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower5G, 1622 AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE); 1623 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower5GHT20, 1624 AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE); 1625 1626 if (IEEE80211_IS_CHAN_HT40(chan)) { 1627 numCtlModes = N(ctlModesFor11a); /* All 5G CTL's */ 1628 1629 ar5416GetTargetPowers(ah, chan, pEepData->calTargetPower5GHT40, 1630 AR5416_NUM_5G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE); 1631 ar5416GetTargetPowersLeg(ah, chan, pEepData->calTargetPower5G, 1632 AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE); 1633 } 1634 } 1635 1636 /* 1637 * For MIMO, need to apply regulatory caps individually across dynamically 1638 * running modes: CCK, OFDM, HT20, HT40 1639 * 1640 * The outer loop walks through each possible applicable runtime mode. 1641 * The inner loop walks through each ctlIndex entry in EEPROM. 1642 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode. 1643 * 1644 */ 1645 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 1646 HAL_BOOL isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 1647 (pCtlMode[ctlMode] == CTL_2GHT40); 1648 if (isHt40CtlMode) { 1649 freq = centers.ctl_center; 1650 } else if (pCtlMode[ctlMode] & EXT_ADDITIVE) { 1651 freq = centers.ext_center; 1652 } else { 1653 freq = centers.ctl_center; 1654 } 1655 1656 /* walk through each CTL index stored in EEPROM */ 1657 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { 1658 uint16_t twiceMinEdgePower; 1659 1660 /* compare test group from regulatory channel list with test mode from pCtlMode list */ 1661 if ((((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == pEepData->ctlIndex[i]) || 1662 (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == 1663 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) { 1664 rep = &(pEepData->ctlData[i]); 1665 twiceMinEdgePower = ar5416GetMaxEdgePower(freq, 1666 rep->ctlEdges[owl_get_ntxchains(AH5416(ah)->ah_tx_chainmask) - 1], 1667 IEEE80211_IS_CHAN_2GHZ(chan)); 1668 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { 1669 /* Find the minimum of all CTL edge powers that apply to this channel */ 1670 twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower); 1671 } else { 1672 /* specific */ 1673 twiceMaxEdgePower = twiceMinEdgePower; 1674 break; 1675 } 1676 } 1677 } 1678 minCtlPower = (uint8_t)AH_MIN(twiceMaxEdgePower, scaledPower); 1679 /* Apply ctl mode to correct target power set */ 1680 switch(pCtlMode[ctlMode]) { 1681 case CTL_11B: 1682 for (i = 0; i < N(targetPowerCck.tPow2x); i++) { 1683 targetPowerCck.tPow2x[i] = (uint8_t)AH_MIN(targetPowerCck.tPow2x[i], minCtlPower); 1684 } 1685 break; 1686 case CTL_11A: 1687 case CTL_11G: 1688 for (i = 0; i < N(targetPowerOfdm.tPow2x); i++) { 1689 targetPowerOfdm.tPow2x[i] = (uint8_t)AH_MIN(targetPowerOfdm.tPow2x[i], minCtlPower); 1690 } 1691 break; 1692 case CTL_5GHT20: 1693 case CTL_2GHT20: 1694 for (i = 0; i < N(targetPowerHt20.tPow2x); i++) { 1695 targetPowerHt20.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt20.tPow2x[i], minCtlPower); 1696 } 1697 break; 1698 case CTL_11B_EXT: 1699 targetPowerCckExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerCckExt.tPow2x[0], minCtlPower); 1700 break; 1701 case CTL_11A_EXT: 1702 case CTL_11G_EXT: 1703 targetPowerOfdmExt.tPow2x[0] = (uint8_t)AH_MIN(targetPowerOfdmExt.tPow2x[0], minCtlPower); 1704 break; 1705 case CTL_5GHT40: 1706 case CTL_2GHT40: 1707 for (i = 0; i < N(targetPowerHt40.tPow2x); i++) { 1708 targetPowerHt40.tPow2x[i] = (uint8_t)AH_MIN(targetPowerHt40.tPow2x[i], minCtlPower); 1709 } 1710 break; 1711 default: 1712 return AH_FALSE; 1713 break; 1714 } 1715 } /* end ctl mode checking */ 1716 1717 /* Set rates Array from collected data */ 1718 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = ratesArray[rate18mb] = ratesArray[rate24mb] = targetPowerOfdm.tPow2x[0]; 1719 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1]; 1720 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2]; 1721 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3]; 1722 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0]; 1723 1724 for (i = 0; i < N(targetPowerHt20.tPow2x); i++) { 1725 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; 1726 } 1727 1728 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 1729 ratesArray[rate1l] = targetPowerCck.tPow2x[0]; 1730 ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1]; 1731 ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2]; 1732 ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3]; 1733 } 1734 if (IEEE80211_IS_CHAN_HT40(chan)) { 1735 for (i = 0; i < N(targetPowerHt40.tPow2x); i++) { 1736 ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i]; 1737 } 1738 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0]; 1739 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0]; 1740 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 1741 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 1742 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; 1743 } 1744 } 1745 return AH_TRUE; 1746#undef EXT_ADDITIVE 1747#undef CTL_11A_EXT 1748#undef CTL_11G_EXT 1749#undef CTL_11B_EXT 1750#undef SUB_NUM_CTL_MODES_AT_5G_40 1751#undef SUB_NUM_CTL_MODES_AT_2G_40 1752#undef N 1753} 1754 1755/************************************************************************** 1756 * fbin2freq 1757 * 1758 * Get channel value from binary representation held in eeprom 1759 * RETURNS: the frequency in MHz 1760 */ 1761static uint16_t 1762fbin2freq(uint8_t fbin, HAL_BOOL is2GHz) 1763{ 1764 /* 1765 * Reserved value 0xFF provides an empty definition both as 1766 * an fbin and as a frequency - do not convert 1767 */ 1768 if (fbin == AR5416_BCHAN_UNUSED) { 1769 return fbin; 1770 } 1771 1772 return (uint16_t)((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); 1773} 1774 1775/* 1776 * ar5416GetMaxEdgePower 1777 * 1778 * Find the maximum conformance test limit for the given channel and CTL info 1779 */ 1780static uint16_t 1781ar5416GetMaxEdgePower(uint16_t freq, CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz) 1782{ 1783 uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 1784 int i; 1785 1786 /* Get the edge power */ 1787 for (i = 0; (i < AR5416_NUM_BAND_EDGES) && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED) ; i++) { 1788 /* 1789 * If there's an exact channel match or an inband flag set 1790 * on the lower channel use the given rdEdgePower 1791 */ 1792 if (freq == fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { 1793 twiceMaxEdgePower = MS(pRdEdgesPower[i].tPowerFlag, CAL_CTL_EDGES_POWER); 1794 break; 1795 } else if ((i > 0) && (freq < fbin2freq(pRdEdgesPower[i].bChannel, is2GHz))) { 1796 if (fbin2freq(pRdEdgesPower[i - 1].bChannel, is2GHz) < freq && (pRdEdgesPower[i - 1].tPowerFlag & CAL_CTL_EDGES_FLAG) != 0) { 1797 twiceMaxEdgePower = MS(pRdEdgesPower[i - 1].tPowerFlag, CAL_CTL_EDGES_POWER); 1798 } 1799 /* Leave loop - no more affecting edges possible in this monotonic increasing list */ 1800 break; 1801 } 1802 } 1803 HALASSERT(twiceMaxEdgePower > 0); 1804 return twiceMaxEdgePower; 1805} 1806 1807/************************************************************** 1808 * ar5416GetTargetPowers 1809 * 1810 * Return the rates of target power for the given target power table 1811 * channel, and number of channels 1812 */ 1813void 1814ar5416GetTargetPowers(struct ath_hal *ah, const struct ieee80211_channel *chan, 1815 CAL_TARGET_POWER_HT *powInfo, uint16_t numChannels, 1816 CAL_TARGET_POWER_HT *pNewPower, uint16_t numRates, 1817 HAL_BOOL isHt40Target) 1818{ 1819 uint16_t clo, chi; 1820 int i; 1821 int matchIndex = -1, lowIndex = -1; 1822 uint16_t freq; 1823 CHAN_CENTERS centers; 1824 1825 ar5416GetChannelCenters(ah, chan, ¢ers); 1826 freq = isHt40Target ? centers.synth_center : centers.ctl_center; 1827 1828 /* Copy the target powers into the temp channel list */ 1829 if (freq <= fbin2freq(powInfo[0].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) { 1830 matchIndex = 0; 1831 } else { 1832 for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) { 1833 if (freq == fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) { 1834 matchIndex = i; 1835 break; 1836 } else if ((freq < fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) && 1837 (freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)))) 1838 { 1839 lowIndex = i - 1; 1840 break; 1841 } 1842 } 1843 if ((matchIndex == -1) && (lowIndex == -1)) { 1844 HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))); 1845 matchIndex = i - 1; 1846 } 1847 } 1848 1849 if (matchIndex != -1) { 1850 OS_MEMCPY(pNewPower, &powInfo[matchIndex], sizeof(*pNewPower)); 1851 } else { 1852 HALASSERT(lowIndex != -1); 1853 /* 1854 * Get the lower and upper channels, target powers, 1855 * and interpolate between them. 1856 */ 1857 clo = fbin2freq(powInfo[lowIndex].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)); 1858 chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)); 1859 1860 for (i = 0; i < numRates; i++) { 1861 pNewPower->tPow2x[i] = (uint8_t)interpolate(freq, clo, chi, 1862 powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]); 1863 } 1864 } 1865} 1866/************************************************************** 1867 * ar5416GetTargetPowersLeg 1868 * 1869 * Return the four rates of target power for the given target power table 1870 * channel, and number of channels 1871 */ 1872void 1873ar5416GetTargetPowersLeg(struct ath_hal *ah, 1874 const struct ieee80211_channel *chan, 1875 CAL_TARGET_POWER_LEG *powInfo, uint16_t numChannels, 1876 CAL_TARGET_POWER_LEG *pNewPower, uint16_t numRates, 1877 HAL_BOOL isExtTarget) 1878{ 1879 uint16_t clo, chi; 1880 int i; 1881 int matchIndex = -1, lowIndex = -1; 1882 uint16_t freq; 1883 CHAN_CENTERS centers; 1884 1885 ar5416GetChannelCenters(ah, chan, ¢ers); 1886 freq = (isExtTarget) ? centers.ext_center :centers.ctl_center; 1887 1888 /* Copy the target powers into the temp channel list */ 1889 if (freq <= fbin2freq(powInfo[0].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) { 1890 matchIndex = 0; 1891 } else { 1892 for (i = 0; (i < numChannels) && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) { 1893 if (freq == fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) { 1894 matchIndex = i; 1895 break; 1896 } else if ((freq < fbin2freq(powInfo[i].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))) && 1897 (freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)))) 1898 { 1899 lowIndex = i - 1; 1900 break; 1901 } 1902 } 1903 if ((matchIndex == -1) && (lowIndex == -1)) { 1904 HALASSERT(freq > fbin2freq(powInfo[i - 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan))); 1905 matchIndex = i - 1; 1906 } 1907 } 1908 1909 if (matchIndex != -1) { 1910 OS_MEMCPY(pNewPower, &powInfo[matchIndex], sizeof(*pNewPower)); 1911 } else { 1912 HALASSERT(lowIndex != -1); 1913 /* 1914 * Get the lower and upper channels, target powers, 1915 * and interpolate between them. 1916 */ 1917 clo = fbin2freq(powInfo[lowIndex].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)); 1918 chi = fbin2freq(powInfo[lowIndex + 1].bChannel, IEEE80211_IS_CHAN_2GHZ(chan)); 1919 1920 for (i = 0; i < numRates; i++) { 1921 pNewPower->tPow2x[i] = (uint8_t)interpolate(freq, clo, chi, 1922 powInfo[lowIndex].tPow2x[i], powInfo[lowIndex + 1].tPow2x[i]); 1923 } 1924 } 1925} 1926
|
| 1927/* 1928 * Set the gain boundaries for the given radio chain. 1929 * 1930 * The gain boundaries tell the hardware at what point in the 1931 * PDADC array to "switch over" from one PD gain setting 1932 * to another. There's also a gain overlap between two 1933 * PDADC array gain curves where there's valid PD values 1934 * for 2 gain settings. 1935 * 1936 * The hardware uses the gain overlap and gain boundaries 1937 * to determine which gain curve to use for the given 1938 * target TX power. 1939 */ 1940void 1941ar5416SetGainBoundariesClosedLoop(struct ath_hal *ah, int regChainOffset, 1942 uint16_t pdGainOverlap_t2, uint16_t gainBoundaries[]) 1943{ 1944 OS_REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, 1945 SM(pdGainOverlap_t2, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | 1946 SM(gainBoundaries[0], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) | 1947 SM(gainBoundaries[1], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) | 1948 SM(gainBoundaries[2], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) | 1949 SM(gainBoundaries[3], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); 1950} 1951 1952/* 1953 * Get the gain values and the number of gain levels given 1954 * in xpdMask. 1955 * 1956 * The EEPROM xpdMask determines which power detector gain 1957 * levels were used during calibration. Each of these mask 1958 * bits maps to a fixed gain level in hardware. 1959 */ 1960uint16_t 1961ar5416GetXpdGainValues(struct ath_hal *ah, uint16_t xpdMask, 1962 uint16_t xpdGainValues[]) 1963{ 1964 int i; 1965 uint16_t numXpdGain = 0; 1966 1967 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { 1968 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { 1969 if (numXpdGain >= AR5416_NUM_PD_GAINS) { 1970 HALASSERT(0); 1971 break; 1972 } 1973 xpdGainValues[numXpdGain] = (uint16_t)(AR5416_PD_GAINS_IN_MASK - i); 1974 numXpdGain++; 1975 } 1976 } 1977 return numXpdGain; 1978} 1979 1980/* 1981 * Write the detector gain and biases. 1982 * 1983 * There are four power detector gain levels. The xpdMask in the EEPROM 1984 * determines which power detector gain levels have TX power calibration 1985 * data associated with them. This function writes the number of 1986 * PD gain levels and their values into the hardware. 1987 * 1988 * This is valid for all TX chains - the calibration data itself however 1989 * will likely differ per-chain. 1990 */ 1991void 1992ar5416WriteDetectorGainBiases(struct ath_hal *ah, uint16_t numXpdGain, 1993 uint16_t xpdGainValues[]) 1994{ 1995 OS_REG_WRITE(ah, AR_PHY_TPCRG1, (OS_REG_READ(ah, AR_PHY_TPCRG1) & 1996 ~(AR_PHY_TPCRG1_NUM_PD_GAIN | AR_PHY_TPCRG1_PD_GAIN_1 | 1997 AR_PHY_TPCRG1_PD_GAIN_2 | AR_PHY_TPCRG1_PD_GAIN_3)) | 1998 SM(numXpdGain - 1, AR_PHY_TPCRG1_NUM_PD_GAIN) | 1999 SM(xpdGainValues[0], AR_PHY_TPCRG1_PD_GAIN_1 ) | 2000 SM(xpdGainValues[1], AR_PHY_TPCRG1_PD_GAIN_2) | 2001 SM(xpdGainValues[2], AR_PHY_TPCRG1_PD_GAIN_3)); 2002} 2003 2004/* 2005 * Write the PDADC array to the given chain offset. 2006 * 2007 * The 32 PDADC registers are written without any care about 2008 * their contents - so if various chips treat values as "special", 2009 * this routine will not care. 2010 */ 2011void 2012ar5416WritePdadcValues(struct ath_hal *ah, int regChainOffset, 2013 uint8_t pdadcValues[]) 2014{ 2015 int regOffset; 2016 int j; 2017 int reg32; 2018 2019 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; 2020 2021 for (j = 0; j < 32; j++) { 2022 reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0) | 2023 ((pdadcValues[4*j + 1] & 0xFF) << 8) | 2024 ((pdadcValues[4*j + 2] & 0xFF) << 16) | 2025 ((pdadcValues[4*j + 3] & 0xFF) << 24) ; 2026 OS_REG_WRITE(ah, regOffset, reg32); 2027#ifdef PDADC_DUMP 2028 ath_hal_printf(ah, "PDADC: Chain %d | PDADC %3d Value %3d |" 2029 " PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d" 2030 " Value %3d |\n", 2031 i, 2032 4*j, pdadcValues[4*j], 2033 4*j+1, pdadcValues[4*j + 1], 2034 4*j+2, pdadcValues[4*j + 2], 2035 4*j+3, pdadcValues[4*j + 3]); 2036#endif 2037 regOffset += 4; 2038 } 2039} 2040
|
1860/************************************************************** 1861 * ar5416SetPowerCalTable 1862 * 1863 * Pull the PDADC piers from cal data and interpolate them across the given 1864 * points as well as from the nearest pier(s) to get a power detector 1865 * linear voltage to power level table. 1866 */
| 2041/************************************************************** 2042 * ar5416SetPowerCalTable 2043 * 2044 * Pull the PDADC piers from cal data and interpolate them across the given 2045 * points as well as from the nearest pier(s) to get a power detector 2046 * linear voltage to power level table. 2047 */
|
1867static HAL_BOOL
| 2048HAL_BOOL
|
1868ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, 1869 const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset) 1870{ 1871 CAL_DATA_PER_FREQ *pRawDataset; 1872 uint8_t *pCalBChans = AH_NULL; 1873 uint16_t pdGainOverlap_t2; 1874 static uint8_t pdadcValues[AR5416_NUM_PDADC_VALUES]; 1875 uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK];
| 2049ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, 2050 const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset) 2051{ 2052 CAL_DATA_PER_FREQ *pRawDataset; 2053 uint8_t *pCalBChans = AH_NULL; 2054 uint16_t pdGainOverlap_t2; 2055 static uint8_t pdadcValues[AR5416_NUM_PDADC_VALUES]; 2056 uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK];
|
1876 uint16_t numPiers, i, j;
| 2057 uint16_t numPiers, i;
|
1877 int16_t tMinCalPower; 1878 uint16_t numXpdGain, xpdMask; 1879 uint16_t xpdGainValues[AR5416_NUM_PD_GAINS];
| 2058 int16_t tMinCalPower; 2059 uint16_t numXpdGain, xpdMask; 2060 uint16_t xpdGainValues[AR5416_NUM_PD_GAINS];
|
1880 uint32_t reg32, regOffset, regChainOffset;
| 2061 uint32_t regChainOffset;
|
1881 1882 OS_MEMZERO(xpdGainValues, sizeof(xpdGainValues)); 1883 1884 xpdMask = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].xpdGain; 1885 1886 if (IS_EEP_MINOR_V2(ah)) { 1887 pdGainOverlap_t2 = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pdGainOverlap; 1888 } else { 1889 pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5), AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); 1890 } 1891 1892 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 1893 pCalBChans = pEepData->calFreqPier2G; 1894 numPiers = AR5416_NUM_2G_CAL_PIERS; 1895 } else { 1896 pCalBChans = pEepData->calFreqPier5G; 1897 numPiers = AR5416_NUM_5G_CAL_PIERS; 1898 } 1899
| 2062 2063 OS_MEMZERO(xpdGainValues, sizeof(xpdGainValues)); 2064 2065 xpdMask = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].xpdGain; 2066 2067 if (IS_EEP_MINOR_V2(ah)) { 2068 pdGainOverlap_t2 = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pdGainOverlap; 2069 } else { 2070 pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5), AR_PHY_TPCRG5_PD_GAIN_OVERLAP)); 2071 } 2072 2073 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 2074 pCalBChans = pEepData->calFreqPier2G; 2075 numPiers = AR5416_NUM_2G_CAL_PIERS; 2076 } else { 2077 pCalBChans = pEepData->calFreqPier5G; 2078 numPiers = AR5416_NUM_5G_CAL_PIERS; 2079 } 2080
|
1900 numXpdGain = 0;
| |
1901 /* Calculate the value of xpdgains from the xpdGain Mask */
| 2081 /* Calculate the value of xpdgains from the xpdGain Mask */
|
1902 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { 1903 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) { 1904 if (numXpdGain >= AR5416_NUM_PD_GAINS) { 1905 HALASSERT(0); 1906 break; 1907 } 1908 xpdGainValues[numXpdGain] = (uint16_t)(AR5416_PD_GAINS_IN_MASK - i); 1909 numXpdGain++; 1910 } 1911 }
| 2082 numXpdGain = ar5416GetXpdGainValues(ah, xpdMask, xpdGainValues);
|
1912 1913 /* Write the detector gain biases and their number */
| 2083 2084 /* Write the detector gain biases and their number */
|
1914 OS_REG_WRITE(ah, AR_PHY_TPCRG1, (OS_REG_READ(ah, AR_PHY_TPCRG1) & 1915 ~(AR_PHY_TPCRG1_NUM_PD_GAIN | AR_PHY_TPCRG1_PD_GAIN_1 | AR_PHY_TPCRG1_PD_GAIN_2 | AR_PHY_TPCRG1_PD_GAIN_3)) | 1916 SM(numXpdGain - 1, AR_PHY_TPCRG1_NUM_PD_GAIN) | SM(xpdGainValues[0], AR_PHY_TPCRG1_PD_GAIN_1 ) | 1917 SM(xpdGainValues[1], AR_PHY_TPCRG1_PD_GAIN_2) | SM(xpdGainValues[2], AR_PHY_TPCRG1_PD_GAIN_3));
| 2085 ar5416WriteDetectorGainBiases(ah, numXpdGain, xpdGainValues);
|
1918 1919 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
| 2086 2087 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
|
| 2088 regChainOffset = ar5416GetRegChainOffset(ah, i);
|
1920
| 2089
|
1921 if (AR_SREV_OWL_20_OR_LATER(ah) && 1922 ( AH5416(ah)->ah_rx_chainmask == 0x5 || AH5416(ah)->ah_tx_chainmask == 0x5) && (i != 0)) { 1923 /* Regs are swapped from chain 2 to 1 for 5416 2_0 with 1924 * only chains 0 and 2 populated 1925 */ 1926 regChainOffset = (i == 1) ? 0x2000 : 0x1000; 1927 } else { 1928 regChainOffset = i * 0x1000; 1929 } 1930
| |
1931 if (pEepData->baseEepHeader.txMask & (1 << i)) { 1932 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 1933 pRawDataset = pEepData->calPierData2G[i]; 1934 } else { 1935 pRawDataset = pEepData->calPierData5G[i]; 1936 } 1937
| 2090 if (pEepData->baseEepHeader.txMask & (1 << i)) { 2091 if (IEEE80211_IS_CHAN_2GHZ(chan)) { 2092 pRawDataset = pEepData->calPierData2G[i]; 2093 } else { 2094 pRawDataset = pEepData->calPierData5G[i]; 2095 } 2096
|
1938 ar5416GetGainBoundariesAndPdadcs(ah, chan, pRawDataset,
| 2097 /* Fetch the gain boundaries and the PDADC values */ 2098 ar5416GetGainBoundariesAndPdadcs(ah, chan, pRawDataset,
|
1939 pCalBChans, numPiers, 1940 pdGainOverlap_t2, 1941 &tMinCalPower, gainBoundaries, 1942 pdadcValues, numXpdGain); 1943 1944 if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) {
| 2099 pCalBChans, numPiers, 2100 pdGainOverlap_t2, 2101 &tMinCalPower, gainBoundaries, 2102 pdadcValues, numXpdGain); 2103 2104 if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) {
|
1945 /* 1946 * Note the pdadc table may not start at 0 dBm power, could be 1947 * negative or greater than 0. Need to offset the power 1948 * values by the amount of minPower for griffin 1949 */ 1950 1951 OS_REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, 1952 SM(pdGainOverlap_t2, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | 1953 SM(gainBoundaries[0], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) | 1954 SM(gainBoundaries[1], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) | 1955 SM(gainBoundaries[2], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) | 1956 SM(gainBoundaries[3], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
| 2105 ar5416SetGainBoundariesClosedLoop(ah, regChainOffset, 2106 pdGainOverlap_t2, gainBoundaries);
|
1957 } 1958 1959 /* Write the power values into the baseband power table */
| 2107 } 2108 2109 /* Write the power values into the baseband power table */
|
1960 regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; 1961 1962 for (j = 0; j < 32; j++) { 1963 reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0) | 1964 ((pdadcValues[4*j + 1] & 0xFF) << 8) | 1965 ((pdadcValues[4*j + 2] & 0xFF) << 16) | 1966 ((pdadcValues[4*j + 3] & 0xFF) << 24) ; 1967 OS_REG_WRITE(ah, regOffset, reg32); 1968 1969#ifdef PDADC_DUMP 1970 ath_hal_printf(ah, "PDADC: Chain %d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d |\n", 1971 i, 1972 4*j, pdadcValues[4*j], 1973 4*j+1, pdadcValues[4*j + 1], 1974 4*j+2, pdadcValues[4*j + 2], 1975 4*j+3, pdadcValues[4*j + 3]); 1976#endif 1977 regOffset += 4; 1978 }
| 2110 ar5416WritePdadcValues(ah, regChainOffset, pdadcValues);
|
1979 } 1980 } 1981 *pTxPowerIndexOffset = 0; 1982 1983 return AH_TRUE; 1984} 1985 1986/************************************************************** 1987 * ar5416GetGainBoundariesAndPdadcs 1988 * 1989 * Uses the data points read from EEPROM to reconstruct the pdadc power table 1990 * Called by ar5416SetPowerCalTable only. 1991 */
| 2111 } 2112 } 2113 *pTxPowerIndexOffset = 0; 2114 2115 return AH_TRUE; 2116} 2117 2118/************************************************************** 2119 * ar5416GetGainBoundariesAndPdadcs 2120 * 2121 * Uses the data points read from EEPROM to reconstruct the pdadc power table 2122 * Called by ar5416SetPowerCalTable only. 2123 */
|
1992static void
| 2124void
|
1993ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah, 1994 const struct ieee80211_channel *chan, 1995 CAL_DATA_PER_FREQ *pRawDataSet, 1996 uint8_t * bChans, uint16_t availPiers, 1997 uint16_t tPdGainOverlap, int16_t *pMinCalPower, uint16_t * pPdGainBoundaries, 1998 uint8_t * pPDADCValues, uint16_t numXpdGains) 1999{ 2000 2001 int i, j, k; 2002 int16_t ss; /* potentially -ve index for taking care of pdGainOverlap */ 2003 uint16_t idxL, idxR, numPiers; /* Pier indexes */ 2004 2005 /* filled out Vpd table for all pdGains (chanL) */ 2006 static uint8_t vpdTableL[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 2007 2008 /* filled out Vpd table for all pdGains (chanR) */ 2009 static uint8_t vpdTableR[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 2010 2011 /* filled out Vpd table for all pdGains (interpolated) */ 2012 static uint8_t vpdTableI[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 2013 2014 uint8_t *pVpdL, *pVpdR, *pPwrL, *pPwrR; 2015 uint8_t minPwrT4[AR5416_NUM_PD_GAINS]; 2016 uint8_t maxPwrT4[AR5416_NUM_PD_GAINS]; 2017 int16_t vpdStep; 2018 int16_t tmpVal; 2019 uint16_t sizeCurrVpdTable, maxIndex, tgtIndex; 2020 HAL_BOOL match; 2021 int16_t minDelta = 0; 2022 CHAN_CENTERS centers; 2023 2024 ar5416GetChannelCenters(ah, chan, ¢ers); 2025 2026 /* Trim numPiers for the number of populated channel Piers */ 2027 for (numPiers = 0; numPiers < availPiers; numPiers++) { 2028 if (bChans[numPiers] == AR5416_BCHAN_UNUSED) { 2029 break; 2030 } 2031 } 2032 2033 /* Find pier indexes around the current channel */ 2034 match = getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)), 2035 bChans, numPiers, &idxL, &idxR); 2036 2037 if (match) { 2038 /* Directly fill both vpd tables from the matching index */ 2039 for (i = 0; i < numXpdGains; i++) { 2040 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; 2041 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; 2042 ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pRawDataSet[idxL].pwrPdg[i], 2043 pRawDataSet[idxL].vpdPdg[i], AR5416_PD_GAIN_ICEPTS, vpdTableI[i]); 2044 } 2045 } else { 2046 for (i = 0; i < numXpdGains; i++) { 2047 pVpdL = pRawDataSet[idxL].vpdPdg[i]; 2048 pPwrL = pRawDataSet[idxL].pwrPdg[i]; 2049 pVpdR = pRawDataSet[idxR].vpdPdg[i]; 2050 pPwrR = pRawDataSet[idxR].pwrPdg[i]; 2051 2052 /* Start Vpd interpolation from the max of the minimum powers */ 2053 minPwrT4[i] = AH_MAX(pPwrL[0], pPwrR[0]); 2054 2055 /* End Vpd interpolation from the min of the max powers */ 2056 maxPwrT4[i] = AH_MIN(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], pPwrR[AR5416_PD_GAIN_ICEPTS - 1]); 2057 HALASSERT(maxPwrT4[i] > minPwrT4[i]); 2058 2059 /* Fill pier Vpds */ 2060 ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL, AR5416_PD_GAIN_ICEPTS, vpdTableL[i]); 2061 ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR, AR5416_PD_GAIN_ICEPTS, vpdTableR[i]); 2062 2063 /* Interpolate the final vpd */ 2064 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { 2065 vpdTableI[i][j] = (uint8_t)(interpolate((uint16_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)), 2066 bChans[idxL], bChans[idxR], vpdTableL[i][j], vpdTableR[i][j])); 2067 } 2068 } 2069 } 2070 *pMinCalPower = (int16_t)(minPwrT4[0] / 2); 2071 2072 k = 0; /* index for the final table */ 2073 for (i = 0; i < numXpdGains; i++) { 2074 if (i == (numXpdGains - 1)) { 2075 pPdGainBoundaries[i] = (uint16_t)(maxPwrT4[i] / 2); 2076 } else { 2077 pPdGainBoundaries[i] = (uint16_t)((maxPwrT4[i] + minPwrT4[i+1]) / 4); 2078 } 2079 2080 pPdGainBoundaries[i] = (uint16_t)AH_MIN(AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); 2081 2082 /* NB: only applies to owl 1.0 */ 2083 if ((i == 0) && !AR_SREV_OWL_20_OR_LATER(ah) ) { 2084 /* 2085 * fix the gain delta, but get a delta that can be applied to min to 2086 * keep the upper power values accurate, don't think max needs to 2087 * be adjusted because should not be at that area of the table? 2088 */ 2089 minDelta = pPdGainBoundaries[0] - 23; 2090 pPdGainBoundaries[0] = 23; 2091 } 2092 else { 2093 minDelta = 0; 2094 } 2095 2096 /* Find starting index for this pdGain */ 2097 if (i == 0) { 2098 ss = 0; /* for the first pdGain, start from index 0 */ 2099 } else { 2100 /* need overlap entries extrapolated below. */ 2101 ss = (int16_t)((pPdGainBoundaries[i-1] - (minPwrT4[i] / 2)) - tPdGainOverlap + 1 + minDelta); 2102 } 2103 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); 2104 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 2105 /* 2106 *-ve ss indicates need to extrapolate data below for this pdGain 2107 */ 2108 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2109 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); 2110 pPDADCValues[k++] = (uint8_t)((tmpVal < 0) ? 0 : tmpVal); 2111 ss++; 2112 } 2113 2114 sizeCurrVpdTable = (uint8_t)((maxPwrT4[i] - minPwrT4[i]) / 2 +1); 2115 tgtIndex = (uint8_t)(pPdGainBoundaries[i] + tPdGainOverlap - (minPwrT4[i] / 2)); 2116 maxIndex = (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable; 2117 2118 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2119 pPDADCValues[k++] = vpdTableI[i][ss++]; 2120 } 2121 2122 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - vpdTableI[i][sizeCurrVpdTable - 2]); 2123 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 2124 /* 2125 * for last gain, pdGainBoundary == Pmax_t2, so will 2126 * have to extrapolate 2127 */ 2128 if (tgtIndex >= maxIndex) { /* need to extrapolate above */ 2129 while ((ss <= tgtIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2130 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] + 2131 (ss - maxIndex +1) * vpdStep)); 2132 pPDADCValues[k++] = (uint8_t)((tmpVal > 255) ? 255 : tmpVal); 2133 ss++; 2134 } 2135 } /* extrapolated above */ 2136 } /* for all pdGainUsed */ 2137 2138 /* Fill out pdGainBoundaries - only up to 2 allowed here, but hardware allows up to 4 */ 2139 while (i < AR5416_PD_GAINS_IN_MASK) { 2140 pPdGainBoundaries[i] = pPdGainBoundaries[i-1]; 2141 i++; 2142 } 2143 2144 while (k < AR5416_NUM_PDADC_VALUES) { 2145 pPDADCValues[k] = pPDADCValues[k-1]; 2146 k++; 2147 } 2148 return; 2149} 2150 2151/************************************************************** 2152 * getLowerUppderIndex 2153 * 2154 * Return indices surrounding the value in sorted integer lists. 2155 * Requirement: the input list must be monotonically increasing 2156 * and populated up to the list size 2157 * Returns: match is set if an index in the array matches exactly 2158 * or a the target is before or after the range of the array. 2159 */ 2160HAL_BOOL 2161getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize, 2162 uint16_t *indexL, uint16_t *indexR) 2163{ 2164 uint16_t i; 2165 2166 /* 2167 * Check first and last elements for beyond ordered array cases. 2168 */ 2169 if (target <= pList[0]) { 2170 *indexL = *indexR = 0; 2171 return AH_TRUE; 2172 } 2173 if (target >= pList[listSize-1]) { 2174 *indexL = *indexR = (uint16_t)(listSize - 1); 2175 return AH_TRUE; 2176 } 2177 2178 /* look for value being near or between 2 values in list */ 2179 for (i = 0; i < listSize - 1; i++) { 2180 /* 2181 * If value is close to the current value of the list 2182 * then target is not between values, it is one of the values 2183 */ 2184 if (pList[i] == target) { 2185 *indexL = *indexR = i; 2186 return AH_TRUE; 2187 } 2188 /* 2189 * Look for value being between current value and next value 2190 * if so return these 2 values 2191 */ 2192 if (target < pList[i + 1]) { 2193 *indexL = i; 2194 *indexR = (uint16_t)(i + 1); 2195 return AH_FALSE; 2196 } 2197 } 2198 HALASSERT(0); 2199 *indexL = *indexR = 0; 2200 return AH_FALSE; 2201} 2202 2203/************************************************************** 2204 * ar5416FillVpdTable 2205 * 2206 * Fill the Vpdlist for indices Pmax-Pmin 2207 * Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4 2208 */ 2209static HAL_BOOL 2210ar5416FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList, 2211 uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList) 2212{ 2213 uint16_t i, k; 2214 uint8_t currPwr = pwrMin; 2215 uint16_t idxL, idxR; 2216 2217 HALASSERT(pwrMax > pwrMin); 2218 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) { 2219 getLowerUpperIndex(currPwr, pPwrList, numIntercepts, 2220 &(idxL), &(idxR)); 2221 if (idxR < 1) 2222 idxR = 1; /* extrapolate below */ 2223 if (idxL == numIntercepts - 1) 2224 idxL = (uint16_t)(numIntercepts - 2); /* extrapolate above */ 2225 if (pPwrList[idxL] == pPwrList[idxR]) 2226 k = pVpdList[idxL]; 2227 else 2228 k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) / 2229 (pPwrList[idxR] - pPwrList[idxL]) ); 2230 HALASSERT(k < 256); 2231 pRetVpdList[i] = (uint8_t)k; 2232 currPwr += 2; /* half dB steps */ 2233 } 2234 2235 return AH_TRUE; 2236} 2237 2238/************************************************************************** 2239 * interpolate 2240 * 2241 * Returns signed interpolated or the scaled up interpolated value 2242 */ 2243static int16_t 2244interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight, 2245 int16_t targetLeft, int16_t targetRight) 2246{ 2247 int16_t rv; 2248 2249 if (srcRight == srcLeft) { 2250 rv = targetLeft; 2251 } else { 2252 rv = (int16_t)( ((target - srcLeft) * targetRight + 2253 (srcRight - target) * targetLeft) / (srcRight - srcLeft) ); 2254 } 2255 return rv; 2256} 2257 2258/* 2259 * The linux ath9k driver and (from what I've been told) the reference 2260 * Atheros driver enables the 11n PHY by default whether or not it's 2261 * configured. 2262 */ 2263static void 2264ar5416Set11nRegs(struct ath_hal *ah, const struct ieee80211_channel *chan) 2265{ 2266 uint32_t phymode; 2267 uint32_t enableDacFifo = 0; 2268 HAL_HT_MACMODE macmode; /* MAC - 20/40 mode */ 2269 2270 if (AR_SREV_KITE_10_OR_LATER(ah)) 2271 enableDacFifo = (OS_REG_READ(ah, AR_PHY_TURBO) & AR_PHY_FC_ENABLE_DAC_FIFO); 2272 2273 /* Enable 11n HT, 20 MHz */ 2274 phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40 2275 | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo; 2276 2277 /* Configure baseband for dynamic 20/40 operation */ 2278 if (IEEE80211_IS_CHAN_HT40(chan)) { 2279 phymode |= AR_PHY_FC_DYN2040_EN; 2280 2281 /* Configure control (primary) channel at +-10MHz */ 2282 if (IEEE80211_IS_CHAN_HT40U(chan)) 2283 phymode |= AR_PHY_FC_DYN2040_PRI_CH; 2284#if 0 2285 /* Configure 20/25 spacing */ 2286 if (ht->ht_extprotspacing == HAL_HT_EXTPROTSPACING_25) 2287 phymode |= AR_PHY_FC_DYN2040_EXT_CH; 2288#endif 2289 macmode = HAL_HT_MACMODE_2040; 2290 } else 2291 macmode = HAL_HT_MACMODE_20; 2292 OS_REG_WRITE(ah, AR_PHY_TURBO, phymode); 2293 2294 /* Configure MAC for 20/40 operation */ 2295 ar5416Set11nMac2040(ah, macmode); 2296 2297 /* global transmit timeout (25 TUs default)*/ 2298 /* XXX - put this elsewhere??? */ 2299 OS_REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S) ; 2300 2301 /* carrier sense timeout */ 2302 OS_REG_SET_BIT(ah, AR_GTTM, AR_GTTM_CST_USEC); 2303 OS_REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); 2304} 2305 2306void 2307ar5416GetChannelCenters(struct ath_hal *ah, 2308 const struct ieee80211_channel *chan, CHAN_CENTERS *centers) 2309{ 2310 uint16_t freq = ath_hal_gethwchannel(ah, chan); 2311 2312 centers->ctl_center = freq; 2313 centers->synth_center = freq; 2314 /* 2315 * In 20/40 phy mode, the center frequency is 2316 * "between" the control and extension channels. 2317 */ 2318 if (IEEE80211_IS_CHAN_HT40U(chan)) { 2319 centers->synth_center += HT40_CHANNEL_CENTER_SHIFT; 2320 centers->ext_center = 2321 centers->synth_center + HT40_CHANNEL_CENTER_SHIFT; 2322 } else if (IEEE80211_IS_CHAN_HT40D(chan)) { 2323 centers->synth_center -= HT40_CHANNEL_CENTER_SHIFT; 2324 centers->ext_center = 2325 centers->synth_center - HT40_CHANNEL_CENTER_SHIFT; 2326 } else { 2327 centers->ext_center = freq; 2328 } 2329} 2330 2331/* 2332 * Override the INI vals being programmed. 2333 */ 2334static void 2335ar5416OverrideIni(struct ath_hal *ah, const struct ieee80211_channel *chan) 2336{ 2337 uint32_t val; 2338 2339 /* 2340 * Set the RX_ABORT and RX_DIS and clear if off only after 2341 * RXE is set for MAC. This prevents frames with corrupted 2342 * descriptor status. 2343 */ 2344 OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 2345 2346 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 2347 val = OS_REG_READ(ah, AR_PCU_MISC_MODE2); 2348 2349 if (!AR_SREV_9271(ah)) 2350 val &= ~AR_PCU_MISC_MODE2_HWWAR1; 2351 2352 if (AR_SREV_9287_11_OR_LATER(ah)) 2353 val = val & (~AR_PCU_MISC_MODE2_HWWAR2); 2354 2355 OS_REG_WRITE(ah, AR_PCU_MISC_MODE2, val); 2356 } 2357 2358 /* 2359 * The AR5416 initvals have this already set to 0x11; AR9160 has 2360 * the register set to 0x0. Figure out whether AR9100/AR9160 needs 2361 * this before moving forward with it. 2362 */ 2363#if 0 2364 /* Disable BB clock gating for AR5416v2, AR9100, AR9160 */ 2365 if (AR_SREV_OWL_20_OR_LATER(ah) || AR_SREV_9100(ah) || AR_SREV_SOWL(ah)) { 2366 /* 2367 * Disable BB clock gating 2368 * Necessary to avoid issues on AR5416 2.0 2369 */ 2370 OS_REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); 2371 } 2372#endif 2373 2374 /* 2375 * Disable RIFS search on some chips to avoid baseband 2376 * hang issues. 2377 */ 2378 if (AR_SREV_9100(ah) || AR_SREV_SOWL(ah)) { 2379 val = OS_REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS); 2380 val &= ~AR_PHY_RIFS_INIT_DELAY; 2381 OS_REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val); 2382 } 2383}
| 2125ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah, 2126 const struct ieee80211_channel *chan, 2127 CAL_DATA_PER_FREQ *pRawDataSet, 2128 uint8_t * bChans, uint16_t availPiers, 2129 uint16_t tPdGainOverlap, int16_t *pMinCalPower, uint16_t * pPdGainBoundaries, 2130 uint8_t * pPDADCValues, uint16_t numXpdGains) 2131{ 2132 2133 int i, j, k; 2134 int16_t ss; /* potentially -ve index for taking care of pdGainOverlap */ 2135 uint16_t idxL, idxR, numPiers; /* Pier indexes */ 2136 2137 /* filled out Vpd table for all pdGains (chanL) */ 2138 static uint8_t vpdTableL[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 2139 2140 /* filled out Vpd table for all pdGains (chanR) */ 2141 static uint8_t vpdTableR[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 2142 2143 /* filled out Vpd table for all pdGains (interpolated) */ 2144 static uint8_t vpdTableI[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB]; 2145 2146 uint8_t *pVpdL, *pVpdR, *pPwrL, *pPwrR; 2147 uint8_t minPwrT4[AR5416_NUM_PD_GAINS]; 2148 uint8_t maxPwrT4[AR5416_NUM_PD_GAINS]; 2149 int16_t vpdStep; 2150 int16_t tmpVal; 2151 uint16_t sizeCurrVpdTable, maxIndex, tgtIndex; 2152 HAL_BOOL match; 2153 int16_t minDelta = 0; 2154 CHAN_CENTERS centers; 2155 2156 ar5416GetChannelCenters(ah, chan, ¢ers); 2157 2158 /* Trim numPiers for the number of populated channel Piers */ 2159 for (numPiers = 0; numPiers < availPiers; numPiers++) { 2160 if (bChans[numPiers] == AR5416_BCHAN_UNUSED) { 2161 break; 2162 } 2163 } 2164 2165 /* Find pier indexes around the current channel */ 2166 match = getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)), 2167 bChans, numPiers, &idxL, &idxR); 2168 2169 if (match) { 2170 /* Directly fill both vpd tables from the matching index */ 2171 for (i = 0; i < numXpdGains; i++) { 2172 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0]; 2173 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4]; 2174 ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pRawDataSet[idxL].pwrPdg[i], 2175 pRawDataSet[idxL].vpdPdg[i], AR5416_PD_GAIN_ICEPTS, vpdTableI[i]); 2176 } 2177 } else { 2178 for (i = 0; i < numXpdGains; i++) { 2179 pVpdL = pRawDataSet[idxL].vpdPdg[i]; 2180 pPwrL = pRawDataSet[idxL].pwrPdg[i]; 2181 pVpdR = pRawDataSet[idxR].vpdPdg[i]; 2182 pPwrR = pRawDataSet[idxR].pwrPdg[i]; 2183 2184 /* Start Vpd interpolation from the max of the minimum powers */ 2185 minPwrT4[i] = AH_MAX(pPwrL[0], pPwrR[0]); 2186 2187 /* End Vpd interpolation from the min of the max powers */ 2188 maxPwrT4[i] = AH_MIN(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], pPwrR[AR5416_PD_GAIN_ICEPTS - 1]); 2189 HALASSERT(maxPwrT4[i] > minPwrT4[i]); 2190 2191 /* Fill pier Vpds */ 2192 ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL, AR5416_PD_GAIN_ICEPTS, vpdTableL[i]); 2193 ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR, AR5416_PD_GAIN_ICEPTS, vpdTableR[i]); 2194 2195 /* Interpolate the final vpd */ 2196 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) { 2197 vpdTableI[i][j] = (uint8_t)(interpolate((uint16_t)FREQ2FBIN(centers.synth_center, IEEE80211_IS_CHAN_2GHZ(chan)), 2198 bChans[idxL], bChans[idxR], vpdTableL[i][j], vpdTableR[i][j])); 2199 } 2200 } 2201 } 2202 *pMinCalPower = (int16_t)(minPwrT4[0] / 2); 2203 2204 k = 0; /* index for the final table */ 2205 for (i = 0; i < numXpdGains; i++) { 2206 if (i == (numXpdGains - 1)) { 2207 pPdGainBoundaries[i] = (uint16_t)(maxPwrT4[i] / 2); 2208 } else { 2209 pPdGainBoundaries[i] = (uint16_t)((maxPwrT4[i] + minPwrT4[i+1]) / 4); 2210 } 2211 2212 pPdGainBoundaries[i] = (uint16_t)AH_MIN(AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]); 2213 2214 /* NB: only applies to owl 1.0 */ 2215 if ((i == 0) && !AR_SREV_OWL_20_OR_LATER(ah) ) { 2216 /* 2217 * fix the gain delta, but get a delta that can be applied to min to 2218 * keep the upper power values accurate, don't think max needs to 2219 * be adjusted because should not be at that area of the table? 2220 */ 2221 minDelta = pPdGainBoundaries[0] - 23; 2222 pPdGainBoundaries[0] = 23; 2223 } 2224 else { 2225 minDelta = 0; 2226 } 2227 2228 /* Find starting index for this pdGain */ 2229 if (i == 0) { 2230 ss = 0; /* for the first pdGain, start from index 0 */ 2231 } else { 2232 /* need overlap entries extrapolated below. */ 2233 ss = (int16_t)((pPdGainBoundaries[i-1] - (minPwrT4[i] / 2)) - tPdGainOverlap + 1 + minDelta); 2234 } 2235 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]); 2236 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 2237 /* 2238 *-ve ss indicates need to extrapolate data below for this pdGain 2239 */ 2240 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2241 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep); 2242 pPDADCValues[k++] = (uint8_t)((tmpVal < 0) ? 0 : tmpVal); 2243 ss++; 2244 } 2245 2246 sizeCurrVpdTable = (uint8_t)((maxPwrT4[i] - minPwrT4[i]) / 2 +1); 2247 tgtIndex = (uint8_t)(pPdGainBoundaries[i] + tPdGainOverlap - (minPwrT4[i] / 2)); 2248 maxIndex = (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable; 2249 2250 while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2251 pPDADCValues[k++] = vpdTableI[i][ss++]; 2252 } 2253 2254 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - vpdTableI[i][sizeCurrVpdTable - 2]); 2255 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep); 2256 /* 2257 * for last gain, pdGainBoundary == Pmax_t2, so will 2258 * have to extrapolate 2259 */ 2260 if (tgtIndex >= maxIndex) { /* need to extrapolate above */ 2261 while ((ss <= tgtIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) { 2262 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] + 2263 (ss - maxIndex +1) * vpdStep)); 2264 pPDADCValues[k++] = (uint8_t)((tmpVal > 255) ? 255 : tmpVal); 2265 ss++; 2266 } 2267 } /* extrapolated above */ 2268 } /* for all pdGainUsed */ 2269 2270 /* Fill out pdGainBoundaries - only up to 2 allowed here, but hardware allows up to 4 */ 2271 while (i < AR5416_PD_GAINS_IN_MASK) { 2272 pPdGainBoundaries[i] = pPdGainBoundaries[i-1]; 2273 i++; 2274 } 2275 2276 while (k < AR5416_NUM_PDADC_VALUES) { 2277 pPDADCValues[k] = pPDADCValues[k-1]; 2278 k++; 2279 } 2280 return; 2281} 2282 2283/************************************************************** 2284 * getLowerUppderIndex 2285 * 2286 * Return indices surrounding the value in sorted integer lists. 2287 * Requirement: the input list must be monotonically increasing 2288 * and populated up to the list size 2289 * Returns: match is set if an index in the array matches exactly 2290 * or a the target is before or after the range of the array. 2291 */ 2292HAL_BOOL 2293getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize, 2294 uint16_t *indexL, uint16_t *indexR) 2295{ 2296 uint16_t i; 2297 2298 /* 2299 * Check first and last elements for beyond ordered array cases. 2300 */ 2301 if (target <= pList[0]) { 2302 *indexL = *indexR = 0; 2303 return AH_TRUE; 2304 } 2305 if (target >= pList[listSize-1]) { 2306 *indexL = *indexR = (uint16_t)(listSize - 1); 2307 return AH_TRUE; 2308 } 2309 2310 /* look for value being near or between 2 values in list */ 2311 for (i = 0; i < listSize - 1; i++) { 2312 /* 2313 * If value is close to the current value of the list 2314 * then target is not between values, it is one of the values 2315 */ 2316 if (pList[i] == target) { 2317 *indexL = *indexR = i; 2318 return AH_TRUE; 2319 } 2320 /* 2321 * Look for value being between current value and next value 2322 * if so return these 2 values 2323 */ 2324 if (target < pList[i + 1]) { 2325 *indexL = i; 2326 *indexR = (uint16_t)(i + 1); 2327 return AH_FALSE; 2328 } 2329 } 2330 HALASSERT(0); 2331 *indexL = *indexR = 0; 2332 return AH_FALSE; 2333} 2334 2335/************************************************************** 2336 * ar5416FillVpdTable 2337 * 2338 * Fill the Vpdlist for indices Pmax-Pmin 2339 * Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4 2340 */ 2341static HAL_BOOL 2342ar5416FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList, 2343 uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList) 2344{ 2345 uint16_t i, k; 2346 uint8_t currPwr = pwrMin; 2347 uint16_t idxL, idxR; 2348 2349 HALASSERT(pwrMax > pwrMin); 2350 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) { 2351 getLowerUpperIndex(currPwr, pPwrList, numIntercepts, 2352 &(idxL), &(idxR)); 2353 if (idxR < 1) 2354 idxR = 1; /* extrapolate below */ 2355 if (idxL == numIntercepts - 1) 2356 idxL = (uint16_t)(numIntercepts - 2); /* extrapolate above */ 2357 if (pPwrList[idxL] == pPwrList[idxR]) 2358 k = pVpdList[idxL]; 2359 else 2360 k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) / 2361 (pPwrList[idxR] - pPwrList[idxL]) ); 2362 HALASSERT(k < 256); 2363 pRetVpdList[i] = (uint8_t)k; 2364 currPwr += 2; /* half dB steps */ 2365 } 2366 2367 return AH_TRUE; 2368} 2369 2370/************************************************************************** 2371 * interpolate 2372 * 2373 * Returns signed interpolated or the scaled up interpolated value 2374 */ 2375static int16_t 2376interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight, 2377 int16_t targetLeft, int16_t targetRight) 2378{ 2379 int16_t rv; 2380 2381 if (srcRight == srcLeft) { 2382 rv = targetLeft; 2383 } else { 2384 rv = (int16_t)( ((target - srcLeft) * targetRight + 2385 (srcRight - target) * targetLeft) / (srcRight - srcLeft) ); 2386 } 2387 return rv; 2388} 2389 2390/* 2391 * The linux ath9k driver and (from what I've been told) the reference 2392 * Atheros driver enables the 11n PHY by default whether or not it's 2393 * configured. 2394 */ 2395static void 2396ar5416Set11nRegs(struct ath_hal *ah, const struct ieee80211_channel *chan) 2397{ 2398 uint32_t phymode; 2399 uint32_t enableDacFifo = 0; 2400 HAL_HT_MACMODE macmode; /* MAC - 20/40 mode */ 2401 2402 if (AR_SREV_KITE_10_OR_LATER(ah)) 2403 enableDacFifo = (OS_REG_READ(ah, AR_PHY_TURBO) & AR_PHY_FC_ENABLE_DAC_FIFO); 2404 2405 /* Enable 11n HT, 20 MHz */ 2406 phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40 2407 | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo; 2408 2409 /* Configure baseband for dynamic 20/40 operation */ 2410 if (IEEE80211_IS_CHAN_HT40(chan)) { 2411 phymode |= AR_PHY_FC_DYN2040_EN; 2412 2413 /* Configure control (primary) channel at +-10MHz */ 2414 if (IEEE80211_IS_CHAN_HT40U(chan)) 2415 phymode |= AR_PHY_FC_DYN2040_PRI_CH; 2416#if 0 2417 /* Configure 20/25 spacing */ 2418 if (ht->ht_extprotspacing == HAL_HT_EXTPROTSPACING_25) 2419 phymode |= AR_PHY_FC_DYN2040_EXT_CH; 2420#endif 2421 macmode = HAL_HT_MACMODE_2040; 2422 } else 2423 macmode = HAL_HT_MACMODE_20; 2424 OS_REG_WRITE(ah, AR_PHY_TURBO, phymode); 2425 2426 /* Configure MAC for 20/40 operation */ 2427 ar5416Set11nMac2040(ah, macmode); 2428 2429 /* global transmit timeout (25 TUs default)*/ 2430 /* XXX - put this elsewhere??? */ 2431 OS_REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S) ; 2432 2433 /* carrier sense timeout */ 2434 OS_REG_SET_BIT(ah, AR_GTTM, AR_GTTM_CST_USEC); 2435 OS_REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); 2436} 2437 2438void 2439ar5416GetChannelCenters(struct ath_hal *ah, 2440 const struct ieee80211_channel *chan, CHAN_CENTERS *centers) 2441{ 2442 uint16_t freq = ath_hal_gethwchannel(ah, chan); 2443 2444 centers->ctl_center = freq; 2445 centers->synth_center = freq; 2446 /* 2447 * In 20/40 phy mode, the center frequency is 2448 * "between" the control and extension channels. 2449 */ 2450 if (IEEE80211_IS_CHAN_HT40U(chan)) { 2451 centers->synth_center += HT40_CHANNEL_CENTER_SHIFT; 2452 centers->ext_center = 2453 centers->synth_center + HT40_CHANNEL_CENTER_SHIFT; 2454 } else if (IEEE80211_IS_CHAN_HT40D(chan)) { 2455 centers->synth_center -= HT40_CHANNEL_CENTER_SHIFT; 2456 centers->ext_center = 2457 centers->synth_center - HT40_CHANNEL_CENTER_SHIFT; 2458 } else { 2459 centers->ext_center = freq; 2460 } 2461} 2462 2463/* 2464 * Override the INI vals being programmed. 2465 */ 2466static void 2467ar5416OverrideIni(struct ath_hal *ah, const struct ieee80211_channel *chan) 2468{ 2469 uint32_t val; 2470 2471 /* 2472 * Set the RX_ABORT and RX_DIS and clear if off only after 2473 * RXE is set for MAC. This prevents frames with corrupted 2474 * descriptor status. 2475 */ 2476 OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 2477 2478 if (AR_SREV_MERLIN_20_OR_LATER(ah)) { 2479 val = OS_REG_READ(ah, AR_PCU_MISC_MODE2); 2480 2481 if (!AR_SREV_9271(ah)) 2482 val &= ~AR_PCU_MISC_MODE2_HWWAR1; 2483 2484 if (AR_SREV_9287_11_OR_LATER(ah)) 2485 val = val & (~AR_PCU_MISC_MODE2_HWWAR2); 2486 2487 OS_REG_WRITE(ah, AR_PCU_MISC_MODE2, val); 2488 } 2489 2490 /* 2491 * The AR5416 initvals have this already set to 0x11; AR9160 has 2492 * the register set to 0x0. Figure out whether AR9100/AR9160 needs 2493 * this before moving forward with it. 2494 */ 2495#if 0 2496 /* Disable BB clock gating for AR5416v2, AR9100, AR9160 */ 2497 if (AR_SREV_OWL_20_OR_LATER(ah) || AR_SREV_9100(ah) || AR_SREV_SOWL(ah)) { 2498 /* 2499 * Disable BB clock gating 2500 * Necessary to avoid issues on AR5416 2.0 2501 */ 2502 OS_REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); 2503 } 2504#endif 2505 2506 /* 2507 * Disable RIFS search on some chips to avoid baseband 2508 * hang issues. 2509 */ 2510 if (AR_SREV_9100(ah) || AR_SREV_SOWL(ah)) { 2511 val = OS_REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS); 2512 val &= ~AR_PHY_RIFS_INIT_DELAY; 2513 OS_REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val); 2514 } 2515}
|