2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted (subject to the limitations in the
7 * disclaimer below) provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
17 * * Neither the name of Qualcomm Atheros nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
22 * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
23 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include <adf_os_types.h>
37 #include <adf_os_dma.h>
38 #include <adf_os_timer.h>
39 #include <adf_os_lock.h>
40 #include <adf_os_io.h>
41 #include <adf_os_mem.h>
42 #include <adf_os_module.h>
43 #include <adf_os_pci.h>
44 #include <adf_os_util.h>
45 #include <adf_os_stdtypes.h>
46 #include <adf_os_defer.h>
47 #include <adf_os_atomic.h>
51 #include <ieee80211_var.h>
53 #include <if_athvar.h>
57 #include "ratectrl11n.h"
59 INLINE A_RSSI median(A_RSSI a, A_RSSI b, A_RSSI c);
61 static void ath_rate_newassoc_11n(struct ath_softc_tgt *sc, struct ath_node_target *an, int isnew,
62 unsigned int capflag, struct ieee80211_rate *rs);
65 static void ath_rate_tx_complete_11n(struct ath_softc_tgt *sc, struct ath_node_target *an,
66 struct ath_tx_desc *ds,
67 struct ath_rc_series rcs[], int nframes,
70 static void ath_rate_findrate_11n(struct ath_softc_tgt *sc,
71 struct ath_node_target *an,
77 struct ath_rc_series series[],
81 rcSortValidRates(const RATE_TABLE_11N *pRateTable, TX_RATE_CTRL *pRc)
85 for (i=pRc->maxValidRate-1; i > 0; i--) {
86 for (j=0; j <= i-1; j++) {
88 if (pRateTable->info[pRc->validRateIndex[j]].rateKbps >
89 pRateTable->info[pRc->validRateIndex[j+1]].rateKbps)
92 if (pRateTable->info[pRc->validRateIndex[j]].userRateKbps >
93 pRateTable->info[pRc->validRateIndex[j+1]].userRateKbps)
97 tmp = pRc->validRateIndex[j];
98 pRc->validRateIndex[j] = pRc->validRateIndex[j+1];
99 pRc->validRateIndex[j+1] = tmp;
105 /* Access functions for validTxRateMask */
108 rcInitValidTxMask(TX_RATE_CTRL *pRc)
112 for (i = 0; i < pRc->rateTableSize; i++) {
113 pRc->validRateIndex[i] = FALSE;
118 rcSetValidTxMask(TX_RATE_CTRL *pRc, A_UINT8 index, A_BOOL validTxRate)
120 ASSERT(index < pRc->rateTableSize);
121 pRc->validRateIndex[index] = validTxRate ? TRUE : FALSE;
126 rcIsValidTxMask(TX_RATE_CTRL *pRc, A_UINT8 index)
128 ASSERT(index < pRc->rateTableSize);
129 return (pRc->validRateIndex[index]);
132 /* Iterators for validTxRateMask */
134 rcGetNextValidTxRate(const RATE_TABLE_11N *pRateTable, TX_RATE_CTRL *pRc,
135 A_UINT8 curValidTxRate, A_UINT8 *pNextIndex)
139 for (i = 0; i < pRc->maxValidRate-1; i++) {
140 if (pRc->validRateIndex[i] == curValidTxRate) {
141 *pNextIndex = pRc->validRateIndex[i+1];
146 /* No more valid rates */
153 rcGetNextLowerValidTxRate(const RATE_TABLE_11N *pRateTable, TX_RATE_CTRL *pRc,
154 A_UINT8 curValidTxRate, A_UINT8 *pNextIndex)
158 for (i = 1; i < pRc->maxValidRate ; i++) {
159 if (pRc->validRateIndex[i] == curValidTxRate) {
160 *pNextIndex = pRc->validRateIndex[i-1];
168 /* Return true only for single stream */
171 rcIsValidPhyRate(A_UINT32 phy, A_UINT32 capflag, A_BOOL ignoreCW)
173 if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG)) {
177 if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG)) {
180 if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_HT40_SGI_FLAG)) {
184 if (!ignoreCW && WLAN_RC_PHY_HT(phy)) {
185 if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG)) {
189 if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG)) {
198 * Initialize the Valid Rate Index from valid entries in Rate Table
200 static A_UINT8 rcSibInitValidRates(const RATE_TABLE_11N *pRateTable,
203 PHY_STATE_CTRL *pPhyStateCtrl)
206 A_UINT8 singleStream = (capflag & WLAN_RC_DS_FLAG) ? 0 : 1;
209 for (i = 0; i < pRateTable->rateCount; i++) {
211 valid = pRateTable->info[i].validSingleStream;
213 valid = pRateTable->info[i].valid;
217 A_UINT32 phy = pRateTable->info[i].phy;
219 if (!rcIsValidPhyRate(phy, capflag, FALSE))
222 pPhyStateCtrl->validPhyRateIndex[phy][pPhyStateCtrl->validPhyRateCount[phy]] = i;
223 pPhyStateCtrl->validPhyRateCount[phy] += 1;
225 rcSetValidTxMask(pRc, i, TRUE);
235 * Initialize the Valid Rate Index from Rate Set
238 rcSibSetValidRates(const RATE_TABLE_11N *pRateTable,
240 struct ieee80211_rateset *pRateSet,
242 struct ath_node_target *an,
243 PHY_STATE_CTRL *pPhyStateCtrl)
245 A_UINT8 i, j, hi = 0;
246 A_UINT8 singleStream = (capflag & WLAN_RC_DS_FLAG) ? 0 : 1;
249 /* Use intersection of working rates and valid rates */
250 for (i = 0; i < pRateSet->rs_nrates; i++) {
251 for (j = 0; j < pRateTable->rateCount; j++) {
252 A_UINT32 phy = pRateTable->info[j].phy;
254 struct atheros_node *pSib = ATH_NODE_ATHEROS(an);
257 valid = pRateTable->info[j].validSTBC;
258 } else if (singleStream) {
262 valid = pRateTable->info[j].validSingleStream;
264 valid = pRateTable->info[j].valid;
268 * We allow a rate only if its valid and the capflag matches one of
269 * the validity (TRUE/TRUE_20/TRUE_40) flags
272 if (((pRateSet->rs_rates[i] & 0x7F) ==
273 (pRateTable->info[j].dot11Rate & 0x7F))
274 && ((valid & WLAN_RC_CAP_MODE(capflag)) ==
275 WLAN_RC_CAP_MODE(capflag)) && !WLAN_RC_PHY_HT(phy)) {
276 if (!rcIsValidPhyRate(phy, capflag, FALSE))
279 pPhyStateCtrl->validPhyRateIndex[phy][pPhyStateCtrl->validPhyRateCount[phy]] = j;
280 pPhyStateCtrl->validPhyRateCount[phy] += 1;
282 rcSetValidTxMask(pRc, j, TRUE);
292 rcSibSetValidHtRates(const RATE_TABLE_11N *pRateTable,
296 struct ath_node_target *an,
297 PHY_STATE_CTRL *pPhyStateCtrl)
299 A_UINT8 i, j, hi = 0;
300 A_UINT8 singleStream = (capflag & WLAN_RC_DS_FLAG) ? 0 : 1;
303 /* Use intersection of working rates and valid rates */
304 for (i = 0; i < ((struct ieee80211_rateset *)pMcsSet)->rs_nrates; i++) {
305 for (j = 0; j < pRateTable->rateCount; j++) {
306 A_UINT32 phy = pRateTable->info[j].phy;
308 struct atheros_node *pSib = ATH_NODE_ATHEROS(an);
311 valid = pRateTable->info[j].validSTBC;
312 } else if (singleStream) {
316 valid = pRateTable->info[j].validSingleStream;
318 valid = pRateTable->info[j].valid;
321 if (((((struct ieee80211_rateset *)pMcsSet)->rs_rates[i] & 0x7F)
322 != (pRateTable->info[j].dot11Rate & 0x7F))
323 || !WLAN_RC_PHY_HT(phy)
324 || !WLAN_RC_PHY_HT_VALID(valid, capflag)
325 || ((pRateTable->info[j].dot11Rate == 15) &&
327 (capflag & WLAN_RC_WEP_TKIP_FLAG)) )
332 if (!rcIsValidPhyRate(phy, capflag, FALSE))
335 pPhyStateCtrl->validPhyRateIndex[phy][pPhyStateCtrl->validPhyRateCount[phy]] = j;
336 pPhyStateCtrl->validPhyRateCount[phy] += 1;
338 rcSetValidTxMask(pRc, j, TRUE);
347 * Update the SIB's rate control information
349 * This should be called when the supported rates change
350 * (e.g. SME operation, wireless mode change)
352 * It will determine which rates are valid for use.
355 rcSibUpdate_ht(struct ath_softc_tgt *sc, struct ath_node_target *an,
356 A_UINT32 capflag, A_BOOL keepState, struct ieee80211_rate *pRateSet)
358 RATE_TABLE_11N *pRateTable = 0;
359 struct atheros_node *pSib = ATH_NODE_ATHEROS(an);
360 struct atheros_softc *asc = (struct atheros_softc*)sc->sc_rc;
361 A_UINT8 *phtMcs = (A_UINT8*)&pRateSet->htrates;
362 TX_RATE_CTRL *pRc = (TX_RATE_CTRL *)(pSib);
363 PHY_STATE_CTRL mPhyCtrlState;
365 A_UINT8 i, j, k, hi = 0, htHi = 0;
367 pRateTable = (RATE_TABLE_11N*)asc->hwRateTable[sc->sc_curmode];
369 /* Initial rate table size. Will change depending on the working rate set */
370 pRc->rateTableSize = MAX_TX_RATE_TBL;
372 /* Initialize thresholds according to the global rate table */
373 for (i = 0 ; (i < pRc->rateTableSize) && (!keepState); i++) {
374 pRc->state[i].per = 0;
377 /* Determine the valid rates */
378 rcInitValidTxMask(pRc);
380 for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
381 for (j = 0; j < MAX_TX_RATE_PHY; j++) {
382 mPhyCtrlState.validPhyRateIndex[i][j] = 0;
384 mPhyCtrlState.validPhyRateCount[i] = 0;
387 pRc->rcPhyMode = (capflag & WLAN_RC_40_FLAG);
389 if (pRateSet == NULL || !pRateSet->rates.rs_nrates) {
390 /* No working rate, just initialize valid rates */
391 hi = rcSibInitValidRates(pRateTable, pRc, capflag, &mPhyCtrlState);
393 /* Use intersection of working rates and valid rates */
394 hi = rcSibSetValidRates(pRateTable, pRc, &(pRateSet->rates),
395 capflag, an, &mPhyCtrlState);
397 if (capflag & WLAN_RC_HT_FLAG) {
398 htHi = rcSibSetValidHtRates(pRateTable, pRc, phtMcs,
399 capflag, an, &mPhyCtrlState);
402 hi = A_MAX(hi, htHi);
405 pRc->rateTableSize = hi + 1;
408 ASSERT(pRc->rateTableSize <= MAX_TX_RATE_TBL);
410 for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
411 for (j = 0; j < mPhyCtrlState.validPhyRateCount[i]; j++) {
412 pRc->validRateIndex[k++] = mPhyCtrlState.validPhyRateIndex[i][j];
415 if (!rcIsValidPhyRate(i, pRateTable->initialRateMax, TRUE) ||
416 !mPhyCtrlState.validPhyRateCount[i])
419 pRc->rateMaxPhy = mPhyCtrlState.validPhyRateIndex[i][j-1];
422 ASSERT(pRc->rateTableSize <= MAX_TX_RATE_TBL);
423 ASSERT(k <= MAX_TX_RATE_TBL);
425 pRc->rateMaxPhy = pRc->validRateIndex[k-4];
426 pRc->maxValidRate = k;
428 rcSortValidRates(pRateTable, pRc);
434 * Return the median of three numbers
436 INLINE A_RSSI median(A_RSSI a, A_RSSI b, A_RSSI c)
458 rcRateFind_ht(struct ath_softc_tgt *sc, struct atheros_node *pSib,
459 const RATE_TABLE_11N *pRateTable, A_BOOL probeAllowed, A_BOOL *isProbing)
462 A_UINT32 bestThruput, thisThruput;
464 A_UINT8 rate, nextRate, bestRate;
465 A_UINT8 maxIndex, minIndex;
467 TX_RATE_CTRL *pRc = NULL;
469 pRc = (TX_RATE_CTRL *)(pSib ? (pSib) : NULL);
474 * Age (reduce) last ack rssi based on how old it is.
475 * The bizarre numbers are so the delta is 160msec,
476 * meaning we divide by 16.
477 * 0msec <= dt <= 25msec: don't derate
478 * 25msec <= dt <= 185msec: derate linearly from 0 to 10dB
479 * 185msec <= dt: derate by 10dB
482 nowMsec = A_MS_TICKGET();
483 dt = nowMsec - pRc->rssiTime;
486 * Now look up the rate in the rssi table and return it.
487 * If no rates match then we return 0 (lowest rate)
491 maxIndex = pRc->maxValidRate-1;
497 * Try the higher rate first. It will reduce memory moving time
498 * if we have very good channel characteristics.
500 for (index = maxIndex; index >= minIndex ; index--) {
503 rate = pRc->validRateIndex[index];
504 if (rate > pRc->rateMaxPhy) {
508 /* if the best throughput is already larger than the userRateKbps..
509 * then we could skip of rest of calculation..
511 if( bestThruput >= pRateTable->info[rate].userRateKbps)
515 * For TCP the average collision rate is around 11%,
516 * so we ignore PERs less than this. This is to
517 * prevent the rate we are currently using (whose
518 * PER might be in the 10-15 range because of TCP
519 * collisions) looking worse than the next lower
520 * rate whose PER has decayed close to 0. If we
521 * used to next lower rate, its PER would grow to
522 * 10-15 and we would be worse off then staying
523 * at the current rate.
525 perThres = pRc->state[rate].per;
526 if ( perThres < 12 ) {
530 thisThruput = pRateTable->info[rate].userRateKbps * (100 - perThres);
531 if (bestThruput <= thisThruput) {
532 bestThruput = thisThruput;
540 * Must check the actual rate (rateKbps) to account for non-monoticity of
544 if (rate >= pRc->rateMaxPhy && probeAllowed) {
545 rate = pRc->rateMaxPhy;
547 /* Probe the next allowed phy state */
548 /* FIXME: Check to make sure ratMax is checked properly */
549 if (rcGetNextValidTxRate( pRateTable, pRc, rate, &nextRate) &&
550 (nowMsec - pRc->probeTime > pRateTable->probeInterval) &&
551 (pRc->hwMaxRetryPktCnt >= 1))
554 pRc->probeRate = rate;
555 pRc->probeTime = nowMsec;
556 pRc->hwMaxRetryPktCnt = 0;
563 * Make sure rate is not higher than the allowed maximum.
564 * We should also enforce the min, but I suspect the min is
565 * normally 1 rather than 0 because of the rate 9 vs 6 issue
568 if (rate > (pRc->rateTableSize - 1)) {
569 rate = pRc->rateTableSize - 1;
572 /* record selected rate, which is used to decide if we want to do fast frame */
573 if (!(*isProbing) && pSib) {
574 pSib->lastRateKbps = pRateTable->info[rate].rateKbps;
575 ((struct atheros_softc*)sc->sc_rc)->currentTxRateKbps = pSib->lastRateKbps;
576 ((struct atheros_softc*)sc->sc_rc)->currentTxRateIndex = rate;
583 rcRateSetseries(const RATE_TABLE_11N *pRateTable ,
584 struct ath_rc_series *series,
585 A_UINT8 tries, A_UINT8 rix,
586 A_BOOL rtsctsenable, A_UINT32 chainmask,int stbc)
588 series->tries = tries;
589 series->flags = (rtsctsenable? ATH_RC_RTSCTS_FLAG : 0) |
590 (WLAN_RC_PHY_DS(pRateTable->info[rix].phy) ? ATH_RC_DS_FLAG : 0) |
591 (WLAN_RC_PHY_40(pRateTable->info[rix].phy) ? ATH_RC_CW40_FLAG : 0) |
592 (WLAN_RC_PHY_SGI(pRateTable->info[rix].phy) ? ATH_RC_HT40_SGI_FLAG : 0);
595 /* For now, only single stream STBC is supported */
596 if (pRateTable->info[rix].rateCode >= 0x80 &&
597 pRateTable->info[rix].rateCode <= 0x87)
599 series->flags |= ATH_RC_TX_STBC_FLAG;
603 series->rix = pRateTable->info[rix].baseIndex;
604 series->max4msframelen = pRateTable->info[rix].max4msframelen;
605 series->txrateKbps = pRateTable->info[rix].rateKbps;
607 /* If the hardware is capable of multiple transmit chains (chainmask is 3, 5 or 7),
608 * then choose the number of transmit chains dynamically based on entries in the rate table.
610 #ifndef ATH_ENABLE_WLAN_FOR_K2
612 series->tx_chainmask = pRateTable->info[rix].txChainMask_3ch;
613 else if(chainmask == 1)
614 series->tx_chainmask = 1;
616 series->tx_chainmask = pRateTable->info[rix].txChainMask_2ch; /*Chainmask is 3 or 5*/
618 series->tx_chainmask = 1;
623 rcRateGetIndex(struct ath_softc_tgt *sc, struct ath_node_target *an,
624 const RATE_TABLE_11N *pRateTable ,
625 A_UINT8 rix, A_UINT16 stepDown, A_UINT16 minRate)
629 struct atheros_node *pSib = ATH_NODE_ATHEROS(an);
630 TX_RATE_CTRL *pRc = (TX_RATE_CTRL *)(pSib);
633 for (j = RATE_TABLE_11N_SIZE; j > 0; j-- ) {
634 if (rcGetNextLowerValidTxRate(pRateTable, pRc, rix, &nextIndex)) {
641 for (j = stepDown; j > 0; j-- ) {
642 if (rcGetNextLowerValidTxRate(pRateTable, pRc, rix, &nextIndex)) {
653 void rcRateFind_11n(struct ath_softc_tgt *sc, struct ath_node_target *an,
654 int numTries, int numRates, int stepDnInc,
655 unsigned int rcflag, struct ath_rc_series series[], int *isProbe)
658 A_UINT8 tryPerRate = 0;
659 struct atheros_softc *asc = (struct atheros_softc*)sc->sc_rc;
660 RATE_TABLE_11N *pRateTable = (RATE_TABLE_11N *)asc->hwRateTable[sc->sc_curmode];
661 struct atheros_node *asn = ATH_NODE_ATHEROS(an);
666 rix = rcRateFind_ht(sc, asn, pRateTable, (rcflag & ATH_RC_PROBE_ALLOWED) ? 1 : 0,
670 if ((rcflag & ATH_RC_PROBE_ALLOWED) && (*isProbe)) {
671 /* set one try for probe rates. For the probes don't enable rts */
672 rcRateSetseries(pRateTable, &series[i++], 1, nrix,
673 FALSE, asc->tx_chainmask, asn->stbc);
676 * Get the next tried/allowed rate. No RTS for the next series
677 * after the probe rate
679 nrix = rcRateGetIndex( sc, an, pRateTable, nrix, 1, FALSE);
682 tryPerRate = (numTries/numRates);
684 /* Set the choosen rate. No RTS for first series entry. */
685 rcRateSetseries(pRateTable, &series[i++], tryPerRate,
686 nrix, FALSE, asc->tx_chainmask, asn->stbc);
688 /* Fill in the other rates for multirate retry */
689 for (; i < numRates; i++) {
693 tryNum = ((i + 1) == numRates) ? numTries - (tryPerRate * i) : tryPerRate ;
694 minRate = (((i + 1) == numRates) && (rcflag & ATH_RC_MINRATE_LASTRATE)) ? 1 : 0;
696 nrix = rcRateGetIndex(sc, an, pRateTable, nrix, stepDnInc, minRate);
698 /* All other rates in the series have RTS enabled */
699 rcRateSetseries(pRateTable, &series[i], tryNum,
700 nrix, TRUE, asc->tx_chainmask, asn->stbc);
705 * Change rate series to enable aggregation when operating at lower MCS rates.
706 * When first rate in series is MCS2 in HT40 @ 2.4GHz, series should look like:
707 * {MCS2, MCS1, MCS0, MCS0}.
708 * When first rate in series is MCS3 in HT20 @ 2.4GHz, series should look like:
709 * {MCS3, MCS2, MCS1, MCS1}
710 * So, set fourth rate in series to be same as third one for above conditions.
712 if (sc->sc_curmode == IEEE80211_MODE_11NG) {
713 dot11Rate = pRateTable->info[rix].dot11Rate;
714 phy = pRateTable->info[rix].phy;
716 ((dot11Rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
717 (dot11Rate == 3 && phy == WLAN_RC_PHY_HT_20_SS)))
719 series[3].rix = series[2].rix;
720 series[3].flags = series[2].flags;
721 series[3].max4msframelen = series[2].max4msframelen;
727 * AP91 Kite: NetGear OTA location-4 downlink.
728 * Enable RTS/CTS at MCS 3-0 for downlink throughput.
730 if (sc->sc_curmode == IEEE80211_MODE_11NG) {
731 dot11Rate = pRateTable->info[rix].dot11Rate;
732 if (dot11Rate <= 3 ) {
733 series[0].flags |= ATH_RC_RTSCTS_FLAG;
739 rcUpdate_ht(struct ath_softc_tgt *sc, struct ath_node_target *an, int txRate,
740 A_BOOL Xretries, int retries, A_UINT8 curTxAnt,
741 A_UINT16 nFrames, A_UINT16 nBad)
744 A_UINT32 nowMsec = A_MS_TICKGET();
747 struct atheros_node *pSib = ATH_NODE_ATHEROS(an);
748 struct atheros_softc *asc = (struct atheros_softc*)sc->sc_rc;
749 RATE_TABLE_11N *pRateTable = (RATE_TABLE_11N *)asc->hwRateTable[sc->sc_curmode];
751 static A_UINT32 nRetry2PerLookup[10] = {
767 pRc = (TX_RATE_CTRL *)(pSib);
769 ASSERT(retries >= 0 && retries < MAX_TX_RETRIES);
776 lastPer = pRc->state[txRate].per;
779 /* Update the PER. */
781 pRc->state[txRate].per += 30;
782 if (pRc->state[txRate].per > 100) {
783 pRc->state[txRate].per = 100;
788 count = sizeof(nRetry2PerLookup) / sizeof(nRetry2PerLookup[0]);
789 if (retries >= count) {
793 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
794 pRc->state[txRate].per = (A_UINT8)(pRc->state[txRate].per -
795 (pRc->state[txRate].per / 8) + ((100) / 8));
798 /* Xretries == 1 or 2 */
800 if (pRc->probeRate == txRate)
806 * Update the PER. Make sure it doesn't index out of array's bounds.
808 count = sizeof(nRetry2PerLookup) / sizeof(nRetry2PerLookup[0]);
809 if (retries >= count) {
814 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
816 * Assuming that nFrames is not 0. The current PER
817 * from the retries is 100 * retries / (retries+1),
818 * since the first retries attempts failed, and the
819 * next one worked. For the one that worked, nBad
820 * subframes out of nFrames wored, so the PER for
821 * that part is 100 * nBad / nFrames, and it contributes
822 * 100 * nBad / (nFrames * (retries+1)) to the above
823 * PER. The expression below is a simplified version
824 * of the sum of these two terms.
827 pRc->state[txRate].per = (A_UINT8)(pRc->state[txRate].per -
828 (pRc->state[txRate].per / 8) +
829 ((100*(retries*nFrames + nBad)/(nFrames*(retries+1))) / 8));
831 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
833 pRc->state[txRate].per = (A_UINT8)(pRc->state[txRate].per -
834 (pRc->state[txRate].per / 8) + (nRetry2PerLookup[retries] / 8));
838 * If we got at most one retry then increase the max rate if
839 * this was a probe. Otherwise, ignore the probe.
842 if (pRc->probeRate && pRc->probeRate == txRate) {
843 if (retries > 0 || 2 * nBad > nFrames) {
845 * Since we probed with just a single attempt,
846 * any retries means the probe failed. Also,
847 * if the attempt worked, but more than half
848 * the subframes were bad then also consider
849 * the probe a failure.
853 pRc->rateMaxPhy = pRc->probeRate;
855 if (pRc->state[pRc->probeRate].per > 30) {
856 pRc->state[pRc->probeRate].per = 20;
862 * Since this probe succeeded, we allow the next probe
863 * twice as soon. This allows the maxRate to move up
864 * faster if the probes are succesful.
866 pRc->probeTime = nowMsec - pRateTable->probeInterval / 2;
872 * Don't update anything. We don't know if this was because
873 * of collisions or poor signal.
875 * Later: if rssiAck is close to pRc->state[txRate].rssiThres
876 * and we see lots of retries, then we could increase
877 * pRc->state[txRate].rssiThres.
879 pRc->hwMaxRetryPktCnt = 0;
882 * It worked with no retries. First ignore bogus (small)
885 if (txRate == pRc->rateMaxPhy && pRc->hwMaxRetryPktCnt < 255) {
886 pRc->hwMaxRetryPktCnt++;
894 ASSERT((pRc->rateMaxPhy >= 0 && pRc->rateMaxPhy <= pRc->rateTableSize &&
895 pRc->rateMaxPhy != INVALID_RATE_MAX));
898 * If this rate looks bad (high PER) then stop using it for
899 * a while (except if we are probing).
901 if (pRc->state[txRate].per >= 55 && txRate > 0 &&
902 pRateTable->info[txRate].rateKbps <=
903 pRateTable->info[pRc->rateMaxPhy].rateKbps)
905 rcGetNextLowerValidTxRate(pRateTable, pRc, (A_UINT8) txRate,
908 /* Don't probe for a little while. */
909 pRc->probeTime = nowMsec;
912 /* Make sure the rates below this have lower PER */
913 /* Monotonicity is kept only for rates below the current rate. */
914 if (pRc->state[txRate].per < lastPer) {
915 for (rate = txRate - 1; rate >= 0; rate--) {
916 if (pRateTable->info[rate].phy != pRateTable->info[txRate].phy) {
920 if (pRc->state[rate].per > pRc->state[rate+1].per) {
921 pRc->state[rate].per = pRc->state[rate+1].per;
926 /* Maintain monotonicity for rates above the current rate*/
927 for (rate = txRate; rate < pRc->rateTableSize - 1; rate++) {
928 if (pRc->state[rate+1].per < pRc->state[rate].per) {
929 pRc->state[rate+1].per = pRc->state[rate].per;
933 /* Every so often, we reduce the thresholds and PER (different for CCK and OFDM). */
934 if (nowMsec - pRc->perDownTime >= pRateTable->rssiReduceInterval) {
935 for (rate = 0; rate < pRc->rateTableSize; rate++) {
936 pRc->state[rate].per = 7*pRc->state[rate].per/8;
939 pRc->perDownTime = nowMsec;
944 * This routine is called by the Tx interrupt service routine to give
945 * the status of previous frames.
947 void rcUpdate_11n(struct ath_softc_tgt *sc, struct ath_node_target *an,
949 int finalTSIdx, int Xretries,
950 struct ath_rc_series rcs[], int nFrames,
951 int nBad, int long_retry)
955 struct atheros_softc *asc = (struct atheros_softc*)sc->sc_rc;
956 RATE_TABLE_11N *pRateTable = (RATE_TABLE_11N *)asc->hwRateTable[sc->sc_curmode];
957 struct atheros_node *pSib = ATH_NODE_ATHEROS(an);
958 TX_RATE_CTRL *pRc = (TX_RATE_CTRL *)(pSib);
966 ASSERT (rcs[0].tries != 0);
969 * If the first rate is not the final index, there are intermediate rate failures
972 if (finalTSIdx != 0) {
974 /* Process intermediate rates that failed.*/
975 for (series = 0; series < finalTSIdx ; series++) {
976 if (rcs[series].tries != 0) {
977 flags = rcs[series].flags;
978 /* If HT40 and we have switched mode from 40 to 20 => don't update */
979 if ((flags & ATH_RC_CW40_FLAG) &&
980 (pRc->rcPhyMode != (flags & ATH_RC_CW40_FLAG))) {
983 if ((flags & ATH_RC_CW40_FLAG) && (flags & ATH_RC_HT40_SGI_FLAG)) {
984 rix = pRateTable->info[rcs[series].rix].htIndex;
985 } else if (flags & ATH_RC_HT40_SGI_FLAG) {
986 rix = pRateTable->info[rcs[series].rix].sgiIndex;
987 } else if (flags & ATH_RC_CW40_FLAG) {
988 rix = pRateTable->info[rcs[series].rix].cw40Index;
990 rix = pRateTable->info[rcs[series].rix].baseIndex;
993 /* FIXME:XXXX, too many args! */
994 rcUpdate_ht(sc, an, rix, Xretries? 1 : 2, rcs[series].tries,
995 curTxAnt, nFrames, nFrames);
1000 * Handle the special case of MIMO PS burst, where the second aggregate is sent
1001 * out with only one rate and one try. Treating it as an excessive retry penalizes
1002 * the rate inordinately.
1004 if (rcs[0].tries == 1 && Xretries == 1) {
1009 flags = rcs[series].flags;
1010 /* If HT40 and we have switched mode from 40 to 20 => don't update */
1011 if ((flags & ATH_RC_CW40_FLAG) &&
1012 (pRc->rcPhyMode != (flags & ATH_RC_CW40_FLAG))) {
1015 if ((flags & ATH_RC_CW40_FLAG) && (flags & ATH_RC_HT40_SGI_FLAG)) {
1016 rix = pRateTable->info[rcs[series].rix].htIndex;
1017 } else if (flags & ATH_RC_HT40_SGI_FLAG) {
1018 rix = pRateTable->info[rcs[series].rix].sgiIndex;
1019 } else if (flags & ATH_RC_CW40_FLAG) {
1020 rix = pRateTable->info[rcs[series].rix].cw40Index;
1022 rix = pRateTable->info[rcs[series].rix].baseIndex;
1025 /* FIXME:XXXX, too many args! */
1026 rcUpdate_ht(sc, an, rix, Xretries, long_retry, curTxAnt,
1030 void ath_tx_status_update_rate(struct ath_softc_tgt *sc,
1031 struct ath_rc_series rcs[],
1033 WMI_TXSTATUS_EVENT *txs)
1035 struct atheros_softc *asc = (struct atheros_softc*)sc->sc_rc;
1036 RATE_TABLE_11N *pRateTable = (RATE_TABLE_11N *)asc->hwRateTable[sc->sc_curmode];
1039 if (pRateTable->info[rcs[series].rix].rateCode & 0x80) {
1040 txs->txstatus[txs->cnt].ts_rate |= SM(pRateTable->info[rcs[series].rix].dot11Rate,
1041 ATH9K_HTC_TXSTAT_RATE);
1042 txs->txstatus[txs->cnt].ts_flags |= ATH9K_HTC_TXSTAT_MCS;
1044 if (rcs[series].flags & ATH_RC_CW40_FLAG)
1045 txs->txstatus[txs->cnt].ts_flags |= ATH9K_HTC_TXSTAT_CW40;
1047 if (rcs[series].flags & ATH_RC_HT40_SGI_FLAG)
1048 txs->txstatus[txs->cnt].ts_flags |= ATH9K_HTC_TXSTAT_SGI;
1051 txs->txstatus[txs->cnt].ts_rate |= SM(rcs[series].rix, ATH9K_HTC_TXSTAT_RATE);
1054 if (rcs[series].flags & ATH_RC_RTSCTS_FLAG)
1055 txs->txstatus[txs->cnt].ts_flags |= ATH9K_HTC_TXSTAT_RTC_CTS;
1059 struct ath_ratectrl *
1060 ath_rate_attach(struct ath_softc_tgt *sc)
1062 struct atheros_softc *asc;
1064 asc = adf_os_mem_alloc(sizeof(struct atheros_softc));
1068 adf_os_mem_set(asc, 0, sizeof(struct atheros_softc));
1069 asc->arc.arc_space = sizeof(struct atheros_node);
1071 ar5416AttachRateTables(asc);
1073 asc->tx_chainmask = 1;
1079 ath_rate_detach(struct ath_ratectrl *rc)
1081 adf_os_mem_free(rc);
1085 ath_rate_findrate(struct ath_softc_tgt *sc,
1086 struct ath_node_target *an,
1092 unsigned int rcflag,
1093 struct ath_rc_series series[],
1098 if (!numRates || !numTries) {
1102 ath_rate_findrate_11n(sc, an, frameLen, numTries, numRates, stepDnInc,
1103 rcflag, series, isProbe);
1106 #define MS(_v, _f) (((_v) & _f) >> _f##_S)
1109 ath_rate_tx_complete(struct ath_softc_tgt *sc,
1110 struct ath_node_target *an,
1111 struct ath_tx_desc *ds,
1112 struct ath_rc_series rcs[],
1113 int nframes, int nbad)
1115 ath_rate_tx_complete_11n(sc, an, ds, rcs, nframes, nbad);
1119 ath_rate_newassoc(struct ath_softc_tgt *sc, struct ath_node_target *an, int isnew,
1120 unsigned int capflag, struct ieee80211_rate *rs)
1122 ath_rate_newassoc_11n(sc, an, isnew, capflag, rs);
1125 void ath_rate_node_update(struct ath_softc_tgt *sc,
1126 struct ath_node_target *an,
1129 struct ieee80211_rate *rs)
1131 struct ieee80211_node_target *ni = &an->ni;
1133 ath_rate_newassoc(sc, ATH_NODE_TARGET(ni), isnew, capflag, rs);
1136 static int init_ath_rate_atheros(void);
1137 static void exit_ath_rate_atheros(void);
1140 ath_rate_newstate(struct ath_softc_tgt *sc,
1141 struct ieee80211vap_target *vap,
1142 enum ieee80211_state state,
1144 struct ieee80211_rate *rs)
1146 struct ieee80211_node_target *ni = vap->iv_bss;
1147 struct atheros_softc *asc = (struct atheros_softc *) sc->sc_rc;
1149 asc->tx_chainmask = sc->sc_ic.ic_tx_chainmask;
1150 ath_rate_newassoc(sc, ATH_NODE_TARGET(ni), 1, capflag, rs);
1154 ath_rate_findrate_11n(struct ath_softc_tgt *sc,
1155 struct ath_node_target *an,
1160 unsigned int rcflag,
1161 struct ath_rc_series series[],
1165 if (!numRates || !numTries) {
1169 rcRateFind_11n(sc, an, numTries, numRates, stepDnInc, rcflag, series, isProbe);
1173 ath_rate_tx_complete_11n(struct ath_softc_tgt *sc,
1174 struct ath_node_target *an,
1175 struct ath_tx_desc *ds,
1176 struct ath_rc_series rcs[],
1177 int nframes, int nbad)
1179 int finalTSIdx = ds->ds_txstat.ts_rate;
1182 if ((ds->ds_txstat.ts_status & HAL_TXERR_XRETRY) ||
1183 (ds->ds_txstat.ts_status & HAL_TXERR_FIFO) ||
1184 (ds->ds_txstat.ts_flags & HAL_TX_DATA_UNDERRUN) ||
1185 (ds->ds_txstat.ts_flags & HAL_TX_DELIM_UNDERRUN)) {
1189 rcUpdate_11n(sc, an,
1190 ds->ds_txstat.ts_antenna, finalTSIdx,
1191 tx_status, rcs, nframes , nbad,
1192 ds->ds_txstat.ts_longretry);
1196 ath_rate_newassoc_11n(struct ath_softc_tgt *sc, struct ath_node_target *an, int isnew,
1197 unsigned int capflag, struct ieee80211_rate *rs)
1200 #ifdef MAGPIE_MERLIN
1201 struct atheros_node *oan = ATH_NODE_ATHEROS(an);
1202 /* Only MERLIN can send STBC */
1203 oan->stbc = (capflag & ATH_RC_TX_STBC_FLAG) ? 1 : 0;
1205 rcSibUpdate_ht(sc, an, capflag, 0, rs);
1209 void ath_rate_mcs2rate(struct ath_softc_tgt *sc,a_uint8_t sgi, a_uint8_t ht40,
1210 a_uint8_t rateCode, a_uint32_t *txrate, a_uint32_t *rxrate)
1213 struct atheros_softc *asc = (struct atheros_softc*)sc->sc_rc;
1214 RATE_TABLE_11N *pRateTable = (RATE_TABLE_11N *)asc->hwRateTable[sc->sc_curmode];
1215 a_uint32_t rateKbps = 0;
1217 *txrate = asc->currentTxRateKbps;
1219 /* look 11NA table for rateKbps*/
1220 for (idx = 0; idx < pRateTable->rateCount && !rateKbps; ++idx) {
1221 if (pRateTable->info[idx].rateCode == rateCode) {
1223 if(pRateTable->info[idx].valid == TRUE_40 &&
1224 pRateTable->info[idx].phy == WLAN_RC_PHY_HT_40_DS_HGI)
1225 rateKbps = pRateTable->info[idx].rateKbps;
1227 if (pRateTable->info[idx].valid == TRUE_40)/* HT40 only*/
1228 rateKbps = pRateTable->info[idx].rateKbps;
1230 if (pRateTable->info[idx].valid != FALSE)
1231 rateKbps = pRateTable->info[idx].rateKbps;