static void dumpchannels(struct ath_hal *ah, int nc, HAL_CHANNEL *chans, int16_t *txpow) { int i; for (i = 0; i < nc; i++) { HAL_CHANNEL *c = &chans[i]; int type; printf("%s%u", sep, c->channel); if (IS_CHAN_TURBO(c)) type = 'T'; else if (IS_CHAN_A(c)) type = 'A'; else if (IS_CHAN_G(c)) type = 'G'; else type = 'B'; if (dopassive && IS_CHAN_PASSIVE(c)) type = tolower(type); printf("%c %d.%d", type, txpow[i]/2, (txpow[i]%2)*5); if ((n++ % 6) == 0) sep = "\n"; else sep = " "; } }
/* * Determines and returns the new Tx rate index. */ A_UINT16 rcRateFind(struct ath_softc *sc, struct atheros_node *pSib, A_UINT32 frameLen, const RATE_TABLE *pRateTable, HAL_CHANNEL *curchan, int isretry) { #ifdef notyet WLAN_STA_CONFIG *pConfig = &pdevInfo->staConfig; VPORT_BSS *pVportXrBss = GET_XR_BSS(pdevInfo); WLAN_DATA_MAC_HEADER *pHdr = pDesc->pBufferVirtPtr.header; #endif struct TxRateCtrl_s *pRc; A_UINT32 dt; A_UINT32 bestThruput,thisThruput = 0; A_UINT32 nowMsec; A_UINT8 rate, nextRate, bestRate; A_RSSI rssiLast, rssiReduce; #if ATH_SUPERG_DYNTURBO A_UINT8 currentPrimeState = IS_CHAN_TURBO(curchan); /* 0 = regular; 1 = turbo */ A_UINT8 primeInUse = sc->sc_dturbo; #else A_UINT8 primeInUse = 0; A_UINT8 currentPrimeState = 0; #endif #ifdef notyet A_UINT8 xrRateAdaptation = FALSE; #endif int isChanTurbo = FALSE; A_UINT8 maxIndex, minIndex; A_INT8 index; int isProbing = FALSE; /* have the real rate control logic kick in */ pRc = &pSib->txRateCtrl; #if ATH_SUPERG_DYNTURBO /* * Reset primeInUse state, if we are currently using XR * rate tables or if we have any clients associated in XR mode */ #ifdef notyet if ((pRateTable == sc->sc_rates[WLAN_MODE_XR]) || (isXrAp(sc) && (pVportXrBss->bss.numAssociatedClients > 0))) { currentPrimeState = 0; primeInUse = 0; } #endif /* make sure that rateMax is correct when using TURBO_PRIME tables */ if (currentPrimeState) { pRc->rateMax = pRateTable->rateCount - 1; } else { pRc->rateMax = pRateTable->rateCount - 1 - pRateTable->numTurboRates; } #endif /* ATH_SUPERG_DYNTURBO */ rssiLast = median(pRc->rssiLast, pRc->rssiLastPrev, pRc->rssiLastPrev2); rssiReduce = 0; /* * Age (reduce) last ack rssi based on how old it is. * The bizarre numbers are so the delta is 160msec, * meaning we divide by 16. * 0msec <= dt <= 25msec: don't derate * 25msec <= dt <= 185msec: derate linearly from 0 to 10dB * 185msec <= dt: derate by 10dB */ nowMsec = A_MS_TICKGET(); dt = nowMsec - pRc->rssiTime; if (dt >= 185) { rssiReduce = 10; } else if (dt >= 25) { rssiReduce = (A_UINT8)((dt - 25) >> 4); }
/* * Sets the transmit power in the baseband for the given * operating channel and mode. */ static HAL_BOOL setRateTable(struct ath_hal *ah, HAL_CHANNEL *chan, int16_t tpcScaleReduction, int16_t powerLimit, int16_t *pMinPower, int16_t *pMaxPower) { u_int16_t ratesArray[16]; u_int16_t *rpow = ratesArray; u_int16_t twiceMaxRDPower, twiceMaxEdgePower, twiceMaxEdgePowerCck; int8_t twiceAntennaGain, twiceAntennaReduction; TRGT_POWER_INFO targetPowerOfdm, targetPowerCck; RD_EDGES_POWER *rep; int16_t scaledPower; u_int8_t cfgCtl; twiceMaxRDPower = ath_hal_getchannelpower(ah, chan) * 2; *pMaxPower = -MAX_RATE_POWER; *pMinPower = MAX_RATE_POWER; /* Get conformance test limit maximum for this channel */ cfgCtl = ath_hal_getctl(ah, chan); rep = findEdgePower(ah, cfgCtl); if (rep != AH_NULL) twiceMaxEdgePower = ar5212GetMaxEdgePower(chan->channel, rep); else twiceMaxEdgePower = MAX_RATE_POWER; if (IS_CHAN_G(chan)) { /* Check for a CCK CTL for 11G CCK powers */ cfgCtl = (cfgCtl & 0xFC) | 0x01; rep = findEdgePower(ah, cfgCtl); if (rep != AH_NULL) twiceMaxEdgePowerCck = ar5212GetMaxEdgePower(chan->channel, rep); else twiceMaxEdgePowerCck = MAX_RATE_POWER; } else { /* Set the 11B cck edge power to the one found before */ twiceMaxEdgePowerCck = twiceMaxEdgePower; } /* Get Antenna Gain reduction */ if (IS_CHAN_5GHZ(chan)) { twiceAntennaGain = antennaGainMax[0]; } else { twiceAntennaGain = antennaGainMax[1]; } twiceAntennaReduction = ath_hal_getantennareduction(ah, chan, twiceAntennaGain); if (IS_CHAN_OFDM(chan)) { /* Get final OFDM target powers */ if (IS_CHAN_G(chan)) { /* TODO - add Turbo 2.4 to this mode check */ ar5212GetTargetPowers(ah, chan, trgtPwr_11g, numTargetPwr_11g, &targetPowerOfdm); } else { ar5212GetTargetPowers(ah, chan, trgtPwr_11a, numTargetPwr_11a, &targetPowerOfdm); } /* Get Maximum OFDM power */ /* Minimum of target and edge powers */ scaledPower = AH_MIN(twiceMaxEdgePower, twiceMaxRDPower - twiceAntennaReduction); /* * If turbo is set, reduce power to keep power * consumption under 2 Watts. Note that we always do * this unless specially configured. Then we limit * power only for non-AP operation. */ if (IS_CHAN_TURBO(chan) #ifdef AH_ENABLE_AP_SUPPORT && AH_PRIVATE(ah)->ah_opmode != HAL_M_HOSTAP #endif ) { /* * If turbo is set, reduce power to keep power * consumption under 2 Watts */ if (eeversion >= AR_EEPROM_VER3_1) scaledPower = AH_MIN(scaledPower, turbo2WMaxPower5); /* * EEPROM version 4.0 added an additional * constraint on 2.4GHz channels. */ if (eeversion >= AR_EEPROM_VER4_0 && IS_CHAN_2GHZ(chan)) scaledPower = AH_MIN(scaledPower, turbo2WMaxPower2); } /* Reduce power by max regulatory domain allowed restrictions */ scaledPower -= (tpcScaleReduction * 2); scaledPower = (scaledPower < 0) ? 0 : scaledPower; scaledPower = AH_MIN(scaledPower, powerLimit); scaledPower = AH_MIN(scaledPower, targetPowerOfdm.twicePwr6_24); /* Set OFDM rates 9, 12, 18, 24, 36, 48, 54, XR */ rpow[0] = rpow[1] = rpow[2] = rpow[3] = rpow[4] = scaledPower; rpow[5] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr36); rpow[6] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr48); rpow[7] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr54); #ifdef notyet if (eeversion >= AR_EEPROM_VER4_0) { /* Setup XR target power from EEPROM */ rpow[15] = AH_MIN(scaledPower, IS_CHAN_2GHZ(chan) ? xrTargetPower2 : xrTargetPower5); } else { /* XR uses 6mb power */ rpow[15] = rpow[0]; } #else rpow[15] = rpow[0]; #endif *pMinPower = rpow[7]; *pMaxPower = rpow[0]; #if 0 ahp->ah_ofdmTxPower = rpow[0]; #endif HALDEBUG(ah, "%s: MaxRD: %d TurboMax: %d MaxCTL: %d " "TPC_Reduction %d\n", __func__, twiceMaxRDPower, turbo2WMaxPower5, twiceMaxEdgePower, tpcScaleReduction * 2); } if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) { /* Get final CCK target powers */ ar5212GetTargetPowers(ah, chan, trgtPwr_11b, numTargetPwr_11b, &targetPowerCck); /* Reduce power by max regulatory domain allowed restrictions */ scaledPower = AH_MIN(twiceMaxEdgePowerCck, twiceMaxRDPower - twiceAntennaReduction); scaledPower -= (tpcScaleReduction * 2); scaledPower = (scaledPower < 0) ? 0 : scaledPower; scaledPower = AH_MIN(scaledPower, powerLimit); rpow[8] = (scaledPower < 1) ? 1 : scaledPower; /* Set CCK rates 2L, 2S, 5.5L, 5.5S, 11L, 11S */ rpow[8] = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24); rpow[9] = AH_MIN(scaledPower, targetPowerCck.twicePwr36); rpow[10] = rpow[9]; rpow[11] = AH_MIN(scaledPower, targetPowerCck.twicePwr48); rpow[12] = rpow[11]; rpow[13] = AH_MIN(scaledPower, targetPowerCck.twicePwr54); rpow[14] = rpow[13]; /* Set min/max power based off OFDM values or initialization */ if (rpow[13] < *pMinPower) *pMinPower = rpow[13]; if (rpow[9] > *pMaxPower) *pMaxPower = rpow[9]; } #if 0 ahp->ah_tx6PowerInHalfDbm = *pMaxPower; #endif return AH_TRUE; }
/* * Places the hardware into reset and then pulls it out of reset * * TODO: Only write the PLL if we're changing to or from CCK mode * * WARNING: The order of the PLL and mode registers must be correct. */ HAL_BOOL ar5312ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan) { OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->channel : 0); /* * Reset the HW */ if (!ar5312SetResetReg(ah, AR_RC_MAC | AR_RC_BB)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5312SetResetReg failed\n", __func__); return AH_FALSE; } /* Bring out of sleep mode (AGAIN) */ if (!ar5312SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5312SetPowerMode failed\n", __func__); return AH_FALSE; } /* Clear warm reset register */ if (!ar5312SetResetReg(ah, 0)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5312SetResetReg failed\n", __func__); return AH_FALSE; } /* * Perform warm reset before the mode/PLL/turbo registers * are changed in order to deactivate the radio. Mode changes * with an active radio can result in corrupted shifts to the * radio device. */ /* * Set CCK and Turbo modes correctly. */ if (chan != AH_NULL) { /* NB: can be null during attach */ uint32_t rfMode, phyPLL = 0, curPhyPLL, turbo; if (IS_RAD5112_ANY(ah)) { rfMode = AR_PHY_MODE_AR5112; if (!IS_5315(ah)) { if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) { phyPLL = AR_PHY_PLL_CTL_44_5312; } else { if (IS_CHAN_HALF_RATE(chan)) { phyPLL = AR_PHY_PLL_CTL_40_5312_HALF; } else if (IS_CHAN_QUARTER_RATE(chan)) { phyPLL = AR_PHY_PLL_CTL_40_5312_QUARTER; } else { phyPLL = AR_PHY_PLL_CTL_40_5312; } } } else { if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) phyPLL = AR_PHY_PLL_CTL_44_5112; else phyPLL = AR_PHY_PLL_CTL_40_5112; if (IS_CHAN_HALF_RATE(chan)) phyPLL |= AR_PHY_PLL_CTL_HALF; else if (IS_CHAN_QUARTER_RATE(chan)) phyPLL |= AR_PHY_PLL_CTL_QUARTER; } } else { rfMode = AR_PHY_MODE_AR5111; if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) phyPLL = AR_PHY_PLL_CTL_44; else phyPLL = AR_PHY_PLL_CTL_40; if (IS_CHAN_HALF_RATE(chan)) phyPLL = AR_PHY_PLL_CTL_HALF; else if (IS_CHAN_QUARTER_RATE(chan)) phyPLL = AR_PHY_PLL_CTL_QUARTER; } if (IS_CHAN_OFDM(chan) && (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))) rfMode |= AR_PHY_MODE_DYNAMIC; else if (IS_CHAN_OFDM(chan)) rfMode |= AR_PHY_MODE_OFDM; else rfMode |= AR_PHY_MODE_CCK; if (IS_CHAN_5GHZ(chan)) rfMode |= AR_PHY_MODE_RF5GHZ; else rfMode |= AR_PHY_MODE_RF2GHZ; turbo = IS_CHAN_TURBO(chan) ? (AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT) : 0; curPhyPLL = OS_REG_READ(ah, AR_PHY_PLL_CTL); /* * PLL, Mode, and Turbo values must be written in the correct * order to ensure: * - The PLL cannot be set to 44 unless the CCK or DYNAMIC * mode bit is set * - Turbo cannot be set at the same time as CCK or DYNAMIC */ if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) { OS_REG_WRITE(ah, AR_PHY_TURBO, turbo); OS_REG_WRITE(ah, AR_PHY_MODE, rfMode); if (curPhyPLL != phyPLL) { OS_REG_WRITE(ah, AR_PHY_PLL_CTL, phyPLL); /* Wait for the PLL to settle */ OS_DELAY(PLL_SETTLE_DELAY); } } else { if (curPhyPLL != phyPLL) { OS_REG_WRITE(ah, AR_PHY_PLL_CTL, phyPLL); /* Wait for the PLL to settle */ OS_DELAY(PLL_SETTLE_DELAY); } OS_REG_WRITE(ah, AR_PHY_TURBO, turbo); OS_REG_WRITE(ah, AR_PHY_MODE, rfMode); } } return AH_TRUE; }
/* * Return the next series 0 transmit rate and setup for a callback * to install the multi-rate transmit data if appropriate. We cannot * install the multi-rate transmit data here because the caller is * going to initialize the tx descriptor and so would clobber whatever * we write. Note that we choose an arbitrary series 0 try count to * insure we get called back; this permits us to defer calculating * the actual number of tries until the callback at which time we * can just copy the pre-calculated series data. */ void ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, int shortPreamble, u_int32_t frameLen, int numTries, unsigned int rcflag, u_int8_t ac, struct ath_rc_series rcs[], int *isProbe, int isretry,u_int32_t bf_flags) { struct atheros_node *oan = an->an_rc_node; struct atheros_softc *asc = oan->asc; struct atheros_vap *avap = oan->avp; struct ath_vap *avp = oan->avp->athdev_vap; const RATE_TABLE *pRateTable = avap->rateTable; u_int8_t *retrySched; int i; u_int8_t fixedratecode; u_int32_t old_av_fixed_rateset; u_int32_t old_av_fixed_retryset; ASSERT(rcs != NULL); if (sc->sc_ah->ah_magic == 0x19641014 || sc->sc_ah->ah_magic == 0x19741014) { #ifdef ATH_SUPPORT_TxBF // set calibration and sounding indicator #define MS(_v, _f) (((_v) & _f) >> _f##_S) sc->sc_txbfsounding = 0; oan->txbf_sounding = 0; sc->sc_txbfcalibrating = 0; if ((MS(bf_flags,HAL_TXDESC_TXBF_SOUND)==HAL_TXDESC_STAG_SOUND) ||(MS(bf_flags,HAL_TXDESC_TXBF_SOUND)== HAL_TXDESC_SOUND)){ sc->sc_txbfsounding = 1; oan->txbf_sounding = 1; } if (bf_flags & HAL_TXDESC_CAL) { sc->sc_txbfcalibrating = 1; } #endif /* store the previous values */ old_av_fixed_rateset = avp->av_config.av_fixed_rateset; old_av_fixed_retryset = avp->av_config.av_fixed_retryset; /* If fixed node rate is enabled, we fixed the link rate */ if (an->an_fixedrate_enable) { fixedratecode = an->an_fixedratecode; avp->av_config.av_fixed_rateset = 0; for (i=0; i<4; i++) { avp->av_config.av_fixed_rateset <<= 8; avp->av_config.av_fixed_rateset |= fixedratecode; } avp->av_config.av_fixed_retryset = 0x03030303; } ath_rate_findrate_11n(sc, an, frameLen, numTries, 4, rcflag, ac, rcs, isProbe, isretry); /* restore the previous values */ avp->av_config.av_fixed_rateset = old_av_fixed_rateset; avp->av_config.av_fixed_retryset = old_av_fixed_retryset; return; } if (asc->fixedrix == IEEE80211_FIXED_RATE_NONE) { rcs[0].rix = rcRateFind(sc, oan, frameLen, pRateTable, &sc->sc_curchan, isretry); /* multi-rate support implied */ rcs[0].tries = ATH_TXMAXTRY-1; /* anything != ATH_TXMAXTRY */ } else { rcs[0].rix = asc->fixedrix; rcs[0].tries = ATH_TXMAXTRY; } /* If fixed node rate is enabled, we fixed the link rate */ if (an->an_fixedrate_enable) { rcs[0].rix = an->an_fixedrix; rcs[0].tries = ATH_TXMAXTRY; } ASSERT(rcs[0].rix != (u_int8_t)-1); /* get the corresponding index for the choosen rate in txRateCtrl */ for (i = 0; oan->txRateCtrl.validRateIndex[i] != rcs[0].rix && i < oan->txRateCtrl.maxValidRate ; i++); ASSERT(asc->fixedrix != IEEE80211_FIXED_RATE_NONE || i != oan->txRateCtrl.maxValidRate); if (rcs[0].tries != ATH_TXMAXTRY) { /* NB: only called for data frames */ if (oan->txRateCtrl.probeRate) { retrySched = shortPreamble ? (u_int8_t *)&(oan->txRateCtrl.validRateSeries[i][24]) : (u_int8_t *)&(oan->txRateCtrl.validRateSeries[i][16]); } else { retrySched = shortPreamble ? (u_int8_t *)&(oan->txRateCtrl.validRateSeries[i][8]) : (u_int8_t *)&(oan->txRateCtrl.validRateSeries[i][0]); } #ifdef ATH_SUPPORT_UAPSD_RATE_CONTROL if (oan->uapsd) { retrySched = shortPreamble ? (u_int8_t *)&(oan->txRateCtrl.validRateSeries[i][40]) : (u_int8_t *)&(oan->txRateCtrl.validRateSeries[i][32]); } #endif /* ATH_SUPPORT_UAPSD_RATE_CONTROL */ /* Update rate seies based on retry schedule */ rcs[0].tries = retrySched[0]; rcs[1].tries = retrySched[1]; rcs[2].tries = retrySched[2]; rcs[3].tries = retrySched[3]; if (!IS_CHAN_TURBO(&sc->sc_curchan)) ASSERT(rcs[0].rix == pRateTable->rateCodeToIndex[retrySched[4]]); /* * Retry scheduler assumes that all the rates below max rate in the * intersection rate table are present and so it takes the next possible * lower rates for the retries, which is not correct. So check them * before filling the retry rates. */ rcs[1].rix = pRateTable->rateCodeToIndex[retrySched[5]]; rcs[2].rix = pRateTable->rateCodeToIndex[retrySched[6]]; rcs[3].rix = pRateTable->rateCodeToIndex[retrySched[7]]; if (sc->sc_curchan.privFlags & CHANNEL_4MS_LIMIT) { u_int32_t prevrix = rcs[0].rix; for (i=1; i<4; i++) { if (rcs[i].tries) { if (pRateTable->info[rcs[i].rix].max4msFrameLen < frameLen) { rcs[i].rix = prevrix; } else { prevrix = rcs[i].rix; } } else { /* Retries are 0 from here */ break; } } } } if (sc->sc_ieee_ops->update_txrate) { sc->sc_ieee_ops->update_txrate(an->an_node, oan->rixMap[rcs[0].rix]); } #if ATH_SUPERG_DYNTURBO /* XXX map from merged table to split for driver */ if (IS_CHAN_TURBO(&sc->sc_curchan) && rcs[0].rix >= (pRateTable->rateCount - pRateTable->numTurboRates)) { u_int32_t numCCKRates = 5; u_int32_t i; rcs[0].rix -= (pRateTable->rateCount-pRateTable->numTurboRates); if (IS_CHAN_2GHZ(&sc->sc_curchan)) { for (i=1;i<=3;i++) { /*Mapping for retry rates from merged table to split table*/ if (rcs[i].rix >= numCCKRates) { rcs[i].rix -= numCCKRates; } else { /* For 6Mbps Turbo rate */ rcs[i].rix -= numCCKRates-1; } } } } #endif if (oan->txRateCtrl.consecRtsFailCount > MAX_CONSEC_RTS_FAILED_FRAMES) { rcs[0].flags |= ATH_RC_RTSCTS_FLAG; rcs[1].rix = rcs[2].rix = rcs[3].rix = 0; rcs[1].tries = rcs[2].tries = rcs[3].tries = 0; } }
HAL_BOOL ar5210ResetTxQueue(struct ath_hal *ah, u_int q) { struct ath_hal_5210 *ahp = AH5210(ah); HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan; HAL_TX_QUEUE_INFO *qi; uint32_t cwMin; if (q >= HAL_NUM_TX_QUEUES) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid queue num %u\n", __func__, q); return AH_FALSE; } qi = &ahp->ah_txq[q]; if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) { HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: inactive queue %u\n", __func__, q); return AH_FALSE; } /* * Ignore any non-data queue(s). */ if (qi->tqi_type != HAL_TX_QUEUE_DATA) return AH_TRUE; /* Set turbo mode / base mode parameters on or off */ if (IS_CHAN_TURBO(chan)) { OS_REG_WRITE(ah, AR_SLOT_TIME, INIT_SLOT_TIME_TURBO); OS_REG_WRITE(ah, AR_TIME_OUT, INIT_ACK_CTS_TIMEOUT_TURBO); OS_REG_WRITE(ah, AR_USEC, INIT_TRANSMIT_LATENCY_TURBO); OS_REG_WRITE(ah, AR_IFS0, ((INIT_SIFS_TURBO + qi->tqi_aifs * INIT_SLOT_TIME_TURBO) << AR_IFS0_DIFS_S) | INIT_SIFS_TURBO); OS_REG_WRITE(ah, AR_IFS1, INIT_PROTO_TIME_CNTRL_TURBO); OS_REG_WRITE(ah, AR_PHY(17), (OS_REG_READ(ah, AR_PHY(17)) & ~0x7F) | 0x38); OS_REG_WRITE(ah, AR_PHY_FRCTL, AR_PHY_SERVICE_ERR | AR_PHY_TXURN_ERR | AR_PHY_ILLLEN_ERR | AR_PHY_ILLRATE_ERR | AR_PHY_PARITY_ERR | AR_PHY_TIMING_ERR | 0x2020 | AR_PHY_TURBO_MODE | AR_PHY_TURBO_SHORT); } else { OS_REG_WRITE(ah, AR_SLOT_TIME, INIT_SLOT_TIME); OS_REG_WRITE(ah, AR_TIME_OUT, INIT_ACK_CTS_TIMEOUT); OS_REG_WRITE(ah, AR_USEC, INIT_TRANSMIT_LATENCY); OS_REG_WRITE(ah, AR_IFS0, ((INIT_SIFS + qi->tqi_aifs * INIT_SLOT_TIME) << AR_IFS0_DIFS_S) | INIT_SIFS); OS_REG_WRITE(ah, AR_IFS1, INIT_PROTO_TIME_CNTRL); OS_REG_WRITE(ah, AR_PHY(17), (OS_REG_READ(ah, AR_PHY(17)) & ~0x7F) | 0x1C); OS_REG_WRITE(ah, AR_PHY_FRCTL, AR_PHY_SERVICE_ERR | AR_PHY_TXURN_ERR | AR_PHY_ILLLEN_ERR | AR_PHY_ILLRATE_ERR | AR_PHY_PARITY_ERR | AR_PHY_TIMING_ERR | 0x1020); } if (qi->tqi_cwmin == HAL_TXQ_USEDEFAULT) cwMin = INIT_CWMIN; else cwMin = qi->tqi_cwmin; /* Set cwmin and retry limit values */ OS_REG_WRITE(ah, AR_RETRY_LMT, (cwMin << AR_RETRY_LMT_CW_MIN_S) | SM(INIT_SLG_RETRY, AR_RETRY_LMT_SLG_RETRY) | SM(INIT_SSH_RETRY, AR_RETRY_LMT_SSH_RETRY) | SM(qi->tqi_lgretry, AR_RETRY_LMT_LG_RETRY) | SM(qi->tqi_shretry, AR_RETRY_LMT_SH_RETRY) ); if (qi->tqi_qflags & HAL_TXQ_TXOKINT_ENABLE) ahp->ah_txOkInterruptMask |= 1 << q; else ahp->ah_txOkInterruptMask &= ~(1 << q); if (qi->tqi_qflags & HAL_TXQ_TXERRINT_ENABLE) ahp->ah_txErrInterruptMask |= 1 << q; else ahp->ah_txErrInterruptMask &= ~(1 << q); if (qi->tqi_qflags & HAL_TXQ_TXDESCINT_ENABLE) ahp->ah_txDescInterruptMask |= 1 << q; else ahp->ah_txDescInterruptMask &= ~(1 << q); if (qi->tqi_qflags & HAL_TXQ_TXEOLINT_ENABLE) ahp->ah_txEolInterruptMask |= 1 << q; else ahp->ah_txEolInterruptMask &= ~(1 << q); if (qi->tqi_qflags & HAL_TXQ_TXURNINT_ENABLE) ahp->ah_txUrnInterruptMask |= 1 << q; else ahp->ah_txUrnInterruptMask &= ~(1 << q); return AH_TRUE; }