5e3e84182a0eb51aca6ccbd3756393dae6142946
[open-ath9k-htc-firmware.git] / target_firmware / wlan / ratectrl_11n_ln.c
1 /*
2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3  * All rights reserved.
4  *
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:
8  *
9  *  * Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
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
15  *    distribution.
16  *
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.
20  *
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.
34  */
35
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>
48 #include <adf_nbuf.h>
49 #include <adf_net.h>
50
51 #include <ieee80211_var.h>
52
53 #include <if_athvar.h>
54 #include "ah_desc.h"
55
56 #include "ratectrl.h"
57 #include "ratectrl11n.h"
58
59 INLINE A_RSSI median(A_RSSI a, A_RSSI b, A_RSSI c);
60
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);
63
64
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, 
68                                      int nbad);
69
70 static void ath_rate_findrate_11n(struct ath_softc_tgt *sc,
71                                   struct ath_node_target *an,
72                                   size_t frameLen,
73                                   int numTries,
74                                   int numRates,
75                                   int stepDnInc,
76                                   unsigned int rcflag,
77                                   struct ath_rc_series series[],
78                                   int *isProbe);
79
80 static void
81 rcSortValidRates(const RATE_TABLE_11N *pRateTable, TX_RATE_CTRL *pRc)
82 {
83         A_UINT8 i,j;
84
85         for (i=pRc->maxValidRate-1; i > 0; i--) {
86                 for (j=0; j <= i-1; j++) {
87 #ifdef MAGPIE_MERLIN      
88                         if (pRateTable->info[pRc->validRateIndex[j]].rateKbps >
89                             pRateTable->info[pRc->validRateIndex[j+1]].rateKbps)
90 #else
91                                 // K2
92                                 if (pRateTable->info[pRc->validRateIndex[j]].userRateKbps >
93                                     pRateTable->info[pRc->validRateIndex[j+1]].userRateKbps)
94 #endif
95                                 {
96                                         A_UINT8 tmp=0;
97                                         tmp = pRc->validRateIndex[j];
98                                         pRc->validRateIndex[j] = pRc->validRateIndex[j+1];
99                                         pRc->validRateIndex[j+1] = tmp;
100                                 }
101                 }
102         }
103 }
104
105 /* Access functions for validTxRateMask */
106
107 static void
108 rcInitValidTxMask(TX_RATE_CTRL *pRc)
109 {
110         A_UINT8 i;
111
112         for (i = 0; i < pRc->rateTableSize; i++) {
113                 pRc->validRateIndex[i] = FALSE;
114         }
115 }
116
117 static INLINE void
118 rcSetValidTxMask(TX_RATE_CTRL *pRc, A_UINT8 index, A_BOOL validTxRate)
119 {
120         ASSERT(index < pRc->rateTableSize);
121         pRc->validRateIndex[index] = validTxRate ? TRUE : FALSE;
122
123 }
124
125 static INLINE A_BOOL
126 rcIsValidTxMask(TX_RATE_CTRL *pRc, A_UINT8 index)
127 {
128         ASSERT(index < pRc->rateTableSize);
129         return (pRc->validRateIndex[index]);
130 }
131
132 /* Iterators for validTxRateMask */
133 static INLINE A_BOOL
134 rcGetNextValidTxRate(const RATE_TABLE_11N *pRateTable, TX_RATE_CTRL *pRc, 
135                      A_UINT8 curValidTxRate, A_UINT8 *pNextIndex)
136 {
137         A_UINT8 i;
138
139         for (i = 0; i < pRc->maxValidRate-1; i++) {
140                 if (pRc->validRateIndex[i] == curValidTxRate) {
141                         *pNextIndex = pRc->validRateIndex[i+1];
142                         return TRUE;
143                 }
144         }
145
146         /* No more valid rates */
147         *pNextIndex = 0;
148     
149         return FALSE;
150 }
151
152 static INLINE A_BOOL
153 rcGetNextLowerValidTxRate(const RATE_TABLE_11N *pRateTable, TX_RATE_CTRL *pRc,  
154                           A_UINT8 curValidTxRate, A_UINT8 *pNextIndex)
155 {
156         A_INT8 i;
157
158         for (i = 1; i < pRc->maxValidRate ; i++) {
159                 if (pRc->validRateIndex[i] == curValidTxRate) {
160                         *pNextIndex = pRc->validRateIndex[i-1];
161                         return TRUE;
162                 }
163         }
164
165         return FALSE;
166 }
167
168 /* Return true only for single stream */
169
170 static A_BOOL
171 rcIsValidPhyRate(A_UINT32 phy, A_UINT32 capflag, A_BOOL ignoreCW)
172 {
173         if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG)) {
174                 return FALSE;
175         }
176
177         if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))  {
178                 return FALSE;
179         }
180         if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_HT40_SGI_FLAG)) {
181                 return FALSE;
182         }
183
184         if (!ignoreCW && WLAN_RC_PHY_HT(phy)) {
185                 if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG)) {
186                         return FALSE;
187                 }
188
189                 if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG)) {
190                         return FALSE;
191                 }
192         }
193     
194         return TRUE;
195 }
196
197 /* 
198  * Initialize the Valid Rate Index from valid entries in Rate Table 
199  */
200 static A_UINT8 rcSibInitValidRates(const RATE_TABLE_11N *pRateTable,
201                                    TX_RATE_CTRL *pRc,
202                                    A_UINT32 capflag,
203                                    PHY_STATE_CTRL *pPhyStateCtrl)
204 {
205         A_UINT8 i, hi = 0;
206         A_UINT8 singleStream = (capflag & WLAN_RC_DS_FLAG) ? 0 : 1;
207         A_UINT8 valid;
208     
209         for (i = 0; i < pRateTable->rateCount; i++) {
210                 if (singleStream) {
211                         valid = pRateTable->info[i].validSingleStream;
212                 } else {
213                         valid = pRateTable->info[i].valid;
214                 }
215             
216                 if (valid == TRUE) {
217                         A_UINT32 phy = pRateTable->info[i].phy;
218
219                         if (!rcIsValidPhyRate(phy, capflag, FALSE)) 
220                                 continue;
221
222                         pPhyStateCtrl->validPhyRateIndex[phy][pPhyStateCtrl->validPhyRateCount[phy]] = i;
223                         pPhyStateCtrl->validPhyRateCount[phy] += 1;
224
225                         rcSetValidTxMask(pRc, i, TRUE);
226
227                         hi = A_MAX(hi, i);
228                 }
229         } 
230     
231         return hi;
232 }
233
234 /* 
235  * Initialize the Valid Rate Index from Rate Set 
236  */
237 static A_UINT8
238 rcSibSetValidRates(const RATE_TABLE_11N *pRateTable,
239                    TX_RATE_CTRL *pRc, 
240                    struct ieee80211_rateset *pRateSet,
241                    A_UINT32 capflag,
242                    struct ath_node_target *an,
243                    PHY_STATE_CTRL *pPhyStateCtrl)
244 {
245         A_UINT8 i, j, hi = 0;
246         A_UINT8 singleStream = (capflag & WLAN_RC_DS_FLAG) ? 0 : 1;
247         A_UINT32 valid;
248        
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;
253 #ifdef MAGPIE_MERLIN
254                         struct atheros_node *pSib = ATH_NODE_ATHEROS(an);
255
256                         if (pSib->stbc) {
257                                 valid = pRateTable->info[j].validSTBC;
258                         } else if (singleStream) {
259 #else
260                         if (singleStream) {
261 #endif            
262                                 valid = pRateTable->info[j].validSingleStream;
263                         } else {
264                                 valid = pRateTable->info[j].valid;
265                         }
266         
267                         /*
268                          * We allow a rate only if its valid and the capflag matches one of
269                          * the validity (TRUE/TRUE_20/TRUE_40) flags
270                          */
271
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)) 
277                                         continue;
278
279                                 pPhyStateCtrl->validPhyRateIndex[phy][pPhyStateCtrl->validPhyRateCount[phy]] = j;
280                                 pPhyStateCtrl->validPhyRateCount[phy] += 1;
281
282                                 rcSetValidTxMask(pRc, j, TRUE);
283                                 hi = A_MAX(hi, j);
284                         }
285                 }
286         }
287   
288         return hi;
289 }
290
291 static A_UINT8
292 rcSibSetValidHtRates(const RATE_TABLE_11N *pRateTable,
293                      TX_RATE_CTRL *pRc, 
294                      A_UINT8 *pMcsSet,
295                      A_UINT32 capflag,
296                      struct ath_node_target *an,
297                      PHY_STATE_CTRL *pPhyStateCtrl)
298 {
299         A_UINT8 i, j, hi = 0;
300         A_UINT8 singleStream = (capflag & WLAN_RC_DS_FLAG) ? 0 : 1;
301         A_UINT8 valid;
302     
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;
307 #ifdef MAGPIE_MERLIN
308                         struct atheros_node *pSib = ATH_NODE_ATHEROS(an);
309
310                         if (pSib->stbc) {
311                                 valid = pRateTable->info[j].validSTBC;
312                         } else if (singleStream) {
313 #else
314                         if (singleStream) {
315 #endif
316                                 valid = pRateTable->info[j].validSingleStream;
317                         } else {
318                                 valid = pRateTable->info[j].valid;
319                         }
320                            
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) && 
326                                 (valid & TRUE_20) && 
327                                 (capflag & WLAN_RC_WEP_TKIP_FLAG)) )
328                         {
329                                 continue;
330                         }
331     
332                         if (!rcIsValidPhyRate(phy, capflag, FALSE)) 
333                                 continue;
334     
335                         pPhyStateCtrl->validPhyRateIndex[phy][pPhyStateCtrl->validPhyRateCount[phy]] = j;
336                         pPhyStateCtrl->validPhyRateCount[phy] += 1;
337
338                         rcSetValidTxMask(pRc, j, TRUE);
339                         hi = A_MAX(hi, j);
340                 }
341         }
342
343         return hi;
344 }
345
346 /*
347  *  Update the SIB's rate control information
348  *
349  *  This should be called when the supported rates change
350  *  (e.g. SME operation, wireless mode change)
351  *
352  *  It will determine which rates are valid for use.
353  */
354 static void
355 rcSibUpdate_ht(struct ath_softc_tgt *sc, struct ath_node_target *an,
356                A_UINT32 capflag, A_BOOL keepState, struct ieee80211_rate  *pRateSet)
357 {
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;  
364
365         A_UINT8 i, j, k, hi = 0, htHi = 0;
366
367         pRateTable = (RATE_TABLE_11N*)asc->hwRateTable[sc->sc_curmode];
368
369         /* Initial rate table size. Will change depending on the working rate set */
370         pRc->rateTableSize = MAX_TX_RATE_TBL;
371
372         /* Initialize thresholds according to the global rate table */
373         for (i = 0 ; (i < pRc->rateTableSize) && (!keepState); i++) {
374                 pRc->state[i].per       = 0;
375         }
376
377         /* Determine the valid rates */
378         rcInitValidTxMask(pRc);
379
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;
383                 }   
384                 mPhyCtrlState.validPhyRateCount[i] = 0;
385         }
386
387         pRc->rcPhyMode = (capflag & WLAN_RC_40_FLAG);
388
389         if (pRateSet == NULL || !pRateSet->rates.rs_nrates) {
390                 /* No working rate, just initialize valid rates */
391                 hi = rcSibInitValidRates(pRateTable, pRc, capflag, &mPhyCtrlState);
392         } else {
393                 /* Use intersection of working rates and valid rates */
394                 hi = rcSibSetValidRates(pRateTable, pRc, &(pRateSet->rates),
395                                         capflag, an, &mPhyCtrlState);
396
397                 if (capflag & WLAN_RC_HT_FLAG) {
398                         htHi = rcSibSetValidHtRates(pRateTable, pRc, phtMcs,
399                                                     capflag, an, &mPhyCtrlState);
400                 }
401
402                 hi = A_MAX(hi, htHi);
403         }
404
405         pRc->rateTableSize = hi + 1;
406         pRc->rateMaxPhy    = 0;
407     
408         ASSERT(pRc->rateTableSize <= MAX_TX_RATE_TBL);
409
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];
413                 }   
414
415                 if (!rcIsValidPhyRate(i, pRateTable->initialRateMax, TRUE) ||
416                     !mPhyCtrlState.validPhyRateCount[i]) 
417                         continue;
418
419                 pRc->rateMaxPhy = mPhyCtrlState.validPhyRateIndex[i][j-1];      
420         }
421     
422         ASSERT(pRc->rateTableSize <= MAX_TX_RATE_TBL);
423         ASSERT(k <= MAX_TX_RATE_TBL);
424
425         pRc->rateMaxPhy = pRc->validRateIndex[k-4];
426         pRc->maxValidRate = k;
427
428         rcSortValidRates(pRateTable, pRc);
429 }
430
431
432
433 /*
434  * Return the median of three numbers
435  */
436 INLINE A_RSSI median(A_RSSI a, A_RSSI b, A_RSSI c)
437 {
438         if (a >= b) {
439                 if (b >= c) {
440                         return b;
441                 } else if (a > c) {
442                         return c;
443                 } else {
444                         return a;
445                 }
446         } else {
447                 if (a >= c) {
448                         return a;
449                 } else if (b >= c) {
450                         return c;
451                 } else {
452                         return b;
453                 }
454         }
455 }
456
457 static A_UINT8
458 rcRateFind_ht(struct ath_softc_tgt *sc, struct atheros_node *pSib,
459               const RATE_TABLE_11N *pRateTable, A_BOOL probeAllowed, A_BOOL *isProbing)
460 {
461         A_UINT32             dt;
462         A_UINT32             bestThruput, thisThruput;
463         A_UINT32             nowMsec;
464         A_UINT8              rate, nextRate, bestRate;
465         A_UINT8              maxIndex, minIndex;
466         A_INT8               index;
467         TX_RATE_CTRL         *pRc = NULL;
468
469         pRc = (TX_RATE_CTRL *)(pSib ? (pSib) : NULL);
470
471         *isProbing = FALSE;
472
473         /*
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
480          */
481
482         nowMsec = A_MS_TICKGET();
483         dt = nowMsec - pRc->rssiTime;
484
485         /*
486          * Now look up the rate in the rssi table and return it.
487          * If no rates match then we return 0 (lowest rate)
488          */
489
490         bestThruput = 0;
491         maxIndex = pRc->maxValidRate-1;
492
493         minIndex = 0;
494         bestRate = minIndex;
495     
496         /*
497          * Try the higher rate first. It will reduce memory moving time
498          * if we have very good channel characteristics.
499          */
500         for (index = maxIndex; index >= minIndex ; index--) {
501                 A_UINT8 perThres;
502     
503                 rate = pRc->validRateIndex[index];
504                 if (rate > pRc->rateMaxPhy) {
505                         continue;
506                 }
507
508                 /* if the best throughput is already larger than the userRateKbps..
509                  * then we could skip of rest of calculation.. 
510                  */
511                 if( bestThruput >= pRateTable->info[rate].userRateKbps)
512                         break;
513
514                 /*
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.
524                  */
525                 perThres = pRc->state[rate].per;
526                 if ( perThres < 12 ) {
527                         perThres = 12;
528                 }
529
530                 thisThruput = pRateTable->info[rate].userRateKbps * (100 - perThres);
531                 if (bestThruput <= thisThruput) {
532                         bestThruput = thisThruput;
533                         bestRate    = rate;
534                 }
535         }
536
537         rate = bestRate;
538
539         /*
540          * Must check the actual rate (rateKbps) to account for non-monoticity of
541          * 11g's rate table
542          */
543
544         if (rate >= pRc->rateMaxPhy && probeAllowed) {
545                 rate = pRc->rateMaxPhy;
546
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))
552                 {
553                         rate                  = nextRate;
554                         pRc->probeRate        = rate;
555                         pRc->probeTime        = nowMsec;
556                         pRc->hwMaxRetryPktCnt = 0;
557                         *isProbing            = TRUE;
558
559                 }
560         }
561
562         /*
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
566          * in the old code.
567          */
568         if (rate > (pRc->rateTableSize - 1)) {
569                 rate = pRc->rateTableSize - 1;
570         }
571
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;
577         }
578
579         return rate;
580 }
581
582 static void
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)
587 {
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);
593 #ifdef MAGPIE_MERLIN
594         if (stbc) {
595                 /* For now, only single stream STBC is supported */
596                 if (pRateTable->info[rix].rateCode >= 0x80 && 
597                     pRateTable->info[rix].rateCode <= 0x87)
598                 {
599                         series->flags |= ATH_RC_TX_STBC_FLAG;
600                 }
601         }
602 #endif
603         series->rix = pRateTable->info[rix].baseIndex;
604         series->max4msframelen = pRateTable->info[rix].max4msframelen;
605         series->txrateKbps = pRateTable->info[rix].rateKbps;
606
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.
609          */
610 #ifndef ATH_ENABLE_WLAN_FOR_K2
611         if(chainmask == 7)
612                 series->tx_chainmask = pRateTable->info[rix].txChainMask_3ch;
613         else if(chainmask == 1) 
614                 series->tx_chainmask = 1;
615         else 
616                 series->tx_chainmask = pRateTable->info[rix].txChainMask_2ch;  /*Chainmask is 3 or 5*/
617 #else
618         series->tx_chainmask = 1;
619 #endif
620 }
621
622 static A_UINT8 
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)
626 {
627         A_UINT32                j;
628         A_UINT8                 nextIndex;
629         struct atheros_node     *pSib = ATH_NODE_ATHEROS(an);
630         TX_RATE_CTRL            *pRc = (TX_RATE_CTRL *)(pSib);
631     
632         if (minRate) {
633                 for (j = RATE_TABLE_11N_SIZE; j > 0; j-- ) {
634                         if (rcGetNextLowerValidTxRate(pRateTable, pRc, rix, &nextIndex)) {
635                                 rix = nextIndex;
636                         } else {
637                                 break;
638                         }
639                 }
640         } else {
641                 for (j = stepDown; j > 0; j-- ) {
642                         if (rcGetNextLowerValidTxRate(pRateTable, pRc, rix, &nextIndex)) {
643                                 rix = nextIndex;
644                         } else {
645                                 break;
646                         }
647                 }
648         }
649
650         return rix;
651 }
652
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)
656 {
657         A_UINT8 i = 0; 
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);
662         A_UINT8 rix, nrix;
663         A_UINT8 dot11Rate;
664         WLAN_PHY phy;
665
666         rix = rcRateFind_ht(sc, asn, pRateTable, (rcflag & ATH_RC_PROBE_ALLOWED) ? 1 : 0, 
667                             isProbe);
668         nrix = rix;
669
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);
674           
675                 /*
676                  * Get the next tried/allowed rate. No RTS for the next series
677                  * after the probe rate
678                  */
679                 nrix = rcRateGetIndex( sc, an, pRateTable, nrix, 1, FALSE);
680         }
681
682         tryPerRate = (numTries/numRates);
683
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);
687
688         /* Fill in the other rates for multirate retry */
689         for (; i < numRates; i++) {
690                 A_UINT8 tryNum;
691                 A_UINT8 minRate;
692
693                 tryNum  = ((i + 1) == numRates) ? numTries - (tryPerRate * i) : tryPerRate ;
694                 minRate = (((i + 1) == numRates) && (rcflag & ATH_RC_MINRATE_LASTRATE)) ? 1 : 0;
695
696                 nrix = rcRateGetIndex(sc, an, pRateTable, nrix, stepDnInc, minRate);
697
698                 /* All other rates in the series have RTS enabled */
699                 rcRateSetseries(pRateTable, &series[i], tryNum,
700                                 nrix, TRUE, asc->tx_chainmask, asn->stbc);
701         }
702
703         /*
704          * BUG 26545:
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.
711          */
712         if (sc->sc_curmode == IEEE80211_MODE_11NG) {
713                 dot11Rate = pRateTable->info[rix].dot11Rate;
714                 phy = pRateTable->info[rix].phy;
715                 if (i == 4 &&
716                     ((dot11Rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) || 
717                      (dot11Rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) 
718                 {
719                         series[3].rix = series[2].rix;
720                         series[3].flags = series[2].flags;
721                         series[3].max4msframelen = series[2].max4msframelen;
722                 }
723         }
724
725         /*
726          * 2009/02/06
727          * AP91 Kite: NetGear OTA location-4 downlink.
728          *            Enable RTS/CTS at MCS 3-0 for downlink throughput.
729          */
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;         
734                 }
735         }
736 }
737
738 static void
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)
742 {
743         TX_RATE_CTRL *pRc;
744         A_UINT32 nowMsec = A_MS_TICKGET();
745         A_UINT8 lastPer;
746         int rate,count;
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];
750
751         static A_UINT32 nRetry2PerLookup[10] = {
752                 100 * 0 / 1,    // 0
753                 100 * 1 / 4,    // 25
754                 100 * 1 / 2,    // 50
755                 100 * 3 / 4,    // 75
756                 100 * 4 / 5,    // 80
757                 100 * 5 / 6,    // 83.3
758                 100 * 6 / 7,    // 85.7
759                 100 * 7 / 8,    // 87.5
760                 100 * 8 / 9,    // 88.8
761                 100 * 9 / 10    // 90
762         };
763
764         if (!pSib)
765                 return;
766
767         pRc = (TX_RATE_CTRL *)(pSib);
768
769         ASSERT(retries >= 0 && retries < MAX_TX_RETRIES);
770         ASSERT(txRate >= 0);
771     
772         if (txRate < 0) {
773                 return;
774         }
775
776         lastPer = pRc->state[txRate].per;
777
778         if (Xretries) {
779                 /* Update the PER. */
780                 if (Xretries == 1) {
781                         pRc->state[txRate].per += 30;
782                         if (pRc->state[txRate].per > 100) {
783                                 pRc->state[txRate].per = 100;
784                         }
785                 } else {
786                         /* Xretries == 2 */
787
788                         count = sizeof(nRetry2PerLookup) / sizeof(nRetry2PerLookup[0]);
789                         if (retries >= count) {
790                                 retries = count - 1;
791                         }
792
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));
796                 }
797
798                 /* Xretries == 1 or 2 */
799
800                 if (pRc->probeRate == txRate)
801                         pRc->probeRate = 0;
802         } else {
803                 /* Xretries == 0 */
804
805                 /*
806                  * Update the PER.  Make sure it doesn't index out of array's bounds.
807                  */
808                 count = sizeof(nRetry2PerLookup) / sizeof(nRetry2PerLookup[0]);
809                 if (retries >= count) {
810                         retries = count - 1;
811                 }
812
813                 if (nBad) {
814                         /* new_PER = 7/8*old_PER + 1/8*(currentPER)  */
815                         /*
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.
825                          */
826                         if (nFrames > 0)
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));
830                 } else {
831                         /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
832
833                         pRc->state[txRate].per = (A_UINT8)(pRc->state[txRate].per - 
834                                    (pRc->state[txRate].per / 8) + (nRetry2PerLookup[retries] / 8));
835                 }
836
837                 /*
838                  * If we got at most one retry then increase the max rate if
839                  * this was a probe.  Otherwise, ignore the probe.
840                  */
841
842                 if (pRc->probeRate && pRc->probeRate == txRate) {
843                         if (retries > 0 || 2 * nBad > nFrames) {
844                                 /*
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.
850                                  */
851                                 pRc->probeRate = 0;
852                         } else {
853                                 pRc->rateMaxPhy = pRc->probeRate;
854
855                                 if (pRc->state[pRc->probeRate].per > 30) {
856                                         pRc->state[pRc->probeRate].per = 20;
857                                 }
858
859                                 pRc->probeRate = 0;
860
861                                 /*
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.
865                                  */
866                                 pRc->probeTime = nowMsec - pRateTable->probeInterval / 2;
867                         }
868                 }
869
870                 if (retries > 0) {
871                         /*
872                          * Don't update anything.  We don't know if this was because
873                          * of collisions or poor signal.
874                          *
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.
878                          */
879                         pRc->hwMaxRetryPktCnt = 0;
880                 } else {
881                         /*
882                          * It worked with no retries.  First ignore bogus (small)
883                          * rssiAck values.
884                          */
885                         if (txRate == pRc->rateMaxPhy && pRc->hwMaxRetryPktCnt < 255) {
886                                 pRc->hwMaxRetryPktCnt++;
887                         }
888
889                 }
890         }
891
892         /* For all cases */
893
894         ASSERT((pRc->rateMaxPhy >= 0 && pRc->rateMaxPhy <= pRc->rateTableSize && 
895                 pRc->rateMaxPhy != INVALID_RATE_MAX));
896     
897         /*
898          * If this rate looks bad (high PER) then stop using it for
899          * a while (except if we are probing).
900          */
901         if (pRc->state[txRate].per >= 55 && txRate > 0 &&
902             pRateTable->info[txRate].rateKbps <= 
903             pRateTable->info[pRc->rateMaxPhy].rateKbps)
904         {
905                 rcGetNextLowerValidTxRate(pRateTable, pRc, (A_UINT8) txRate, 
906                                           &pRc->rateMaxPhy);
907
908                 /* Don't probe for a little while. */
909                 pRc->probeTime = nowMsec;
910         }
911
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) {
917                                 break;
918                         }
919
920                         if (pRc->state[rate].per > pRc->state[rate+1].per) {
921                                 pRc->state[rate].per = pRc->state[rate+1].per;
922                         }
923                 }
924         }
925
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;
930                 }
931         }
932
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;
937                 }
938
939                 pRc->perDownTime = nowMsec;
940         }
941 }
942
943 /*
944  * This routine is called by the Tx interrupt service routine to give
945  * the status of previous frames.
946  */
947 void rcUpdate_11n(struct ath_softc_tgt *sc, struct ath_node_target *an,
948                   A_UINT8 curTxAnt, 
949                   int finalTSIdx, int Xretries,
950                   struct ath_rc_series rcs[], int nFrames, 
951                   int nBad, int long_retry)
952 {
953         A_UINT32 series = 0;
954         A_UINT32 rix;
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);
959         A_UINT8 flags;
960
961         if (!an) {
962                 adf_os_assert(0);
963                 return;
964         }
965
966         ASSERT (rcs[0].tries != 0);
967
968         /*
969          * If the first rate is not the final index, there are intermediate rate failures
970          * to be processed.
971          */
972         if (finalTSIdx != 0) {
973
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))) {
981                                         return;
982                                 }
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;
989                                 } else {
990                                         rix = pRateTable->info[rcs[series].rix].baseIndex;
991                                 }
992
993                                 /* FIXME:XXXX, too many args! */
994                                 rcUpdate_ht(sc, an, rix, Xretries? 1 : 2, rcs[series].tries, 
995                                             curTxAnt, nFrames, nFrames);
996                         }
997                 }
998         } else {
999                 /*
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.
1003                  */
1004                 if (rcs[0].tries == 1 && Xretries == 1) {
1005                         Xretries = 2;
1006                 }
1007         }
1008
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))) {
1013                 return;
1014         }
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;
1021         } else {
1022                 rix = pRateTable->info[rcs[series].rix].baseIndex;
1023         }
1024
1025         /* FIXME:XXXX, too many args! */
1026         rcUpdate_ht(sc, an, rix, Xretries, long_retry, curTxAnt, 
1027                     nFrames, nBad);
1028 }
1029
1030 void ath_tx_status_update_rate(struct ath_softc_tgt *sc,
1031                                struct ath_rc_series rcs[],
1032                                int series,
1033                                WMI_TXSTATUS_EVENT *txs)
1034 {
1035         struct atheros_softc *asc = (struct atheros_softc*)sc->sc_rc;
1036         RATE_TABLE_11N *pRateTable = (RATE_TABLE_11N *)asc->hwRateTable[sc->sc_curmode];
1037
1038         /* HT Rate */
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;
1043
1044                 if (rcs[series].flags & ATH_RC_CW40_FLAG)
1045                         txs->txstatus[txs->cnt].ts_flags |= ATH9K_HTC_TXSTAT_CW40;
1046
1047                 if (rcs[series].flags & ATH_RC_HT40_SGI_FLAG)
1048                         txs->txstatus[txs->cnt].ts_flags |= ATH9K_HTC_TXSTAT_SGI;
1049
1050         } else {
1051                 txs->txstatus[txs->cnt].ts_rate |= SM(rcs[series].rix, ATH9K_HTC_TXSTAT_RATE);
1052         }
1053
1054         if (rcs[series].flags & ATH_RC_RTSCTS_FLAG)
1055                 txs->txstatus[txs->cnt].ts_flags |= ATH9K_HTC_TXSTAT_RTC_CTS;
1056
1057 }
1058
1059 struct ath_ratectrl *
1060 ath_rate_attach(struct ath_softc_tgt *sc)
1061 {
1062         struct atheros_softc *asc;
1063
1064         asc = adf_os_mem_alloc(sizeof(struct atheros_softc));
1065         if (asc == NULL)
1066                 return NULL;
1067
1068         adf_os_mem_set(asc, 0, sizeof(struct atheros_softc));
1069         asc->arc.arc_space = sizeof(struct atheros_node);
1070
1071         ar5416AttachRateTables(asc);
1072
1073         asc->tx_chainmask = 1;
1074     
1075         return &asc->arc;
1076 }
1077
1078 void
1079 ath_rate_detach(struct ath_ratectrl *rc)
1080 {
1081         adf_os_mem_free(rc);
1082 }
1083
1084 void
1085 ath_rate_findrate(struct ath_softc_tgt *sc,
1086                   struct ath_node_target *an,
1087                   int shortPreamble,
1088                   size_t frameLen,
1089                   int numTries,
1090                   int numRates,
1091                   int stepDnInc,
1092                   unsigned int rcflag,
1093                   struct ath_rc_series series[],
1094                   int *isProbe)
1095 {
1096         *isProbe = 0;
1097
1098         if (!numRates || !numTries) {
1099                 return;
1100         }
1101
1102         ath_rate_findrate_11n(sc, an, frameLen, numTries, numRates, stepDnInc,
1103                               rcflag, series, isProbe);
1104 }
1105
1106 #define MS(_v, _f)  (((_v) & _f) >> _f##_S)
1107
1108 void
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)
1114 {
1115         ath_rate_tx_complete_11n(sc, an, ds, rcs, nframes, nbad);
1116 }
1117
1118 void
1119 ath_rate_newassoc(struct ath_softc_tgt *sc, struct ath_node_target *an, int isnew, 
1120                   unsigned int capflag, struct ieee80211_rate *rs)
1121 {
1122         ath_rate_newassoc_11n(sc, an, isnew, capflag, rs);
1123 }
1124
1125 void ath_rate_node_update(struct ath_softc_tgt *sc,
1126                           struct ath_node_target *an,
1127                           a_int32_t isnew,
1128                           a_uint32_t capflag,
1129                           struct ieee80211_rate *rs)
1130 {
1131         struct ieee80211_node_target *ni = &an->ni;
1132
1133         ath_rate_newassoc(sc, ATH_NODE_TARGET(ni), isnew, capflag, rs); 
1134 }
1135
1136 static int init_ath_rate_atheros(void);
1137 static void exit_ath_rate_atheros(void);
1138
1139 void
1140 ath_rate_newstate(struct ath_softc_tgt *sc,
1141                   struct ieee80211vap_target *vap,
1142                   enum ieee80211_state state,
1143                   a_uint32_t capflag,
1144                   struct ieee80211_rate *rs)
1145 {
1146         struct ieee80211_node_target *ni = vap->iv_bss;
1147         struct atheros_softc *asc = (struct atheros_softc *) sc->sc_rc;
1148
1149         asc->tx_chainmask = sc->sc_ic.ic_tx_chainmask;
1150         ath_rate_newassoc(sc, ATH_NODE_TARGET(ni), 1, capflag, rs);
1151 }
1152
1153 static void
1154 ath_rate_findrate_11n(struct ath_softc_tgt *sc,
1155                       struct ath_node_target *an,
1156                       size_t frameLen,
1157                       int numTries,
1158                       int numRates,
1159                       int stepDnInc,
1160                       unsigned int rcflag,
1161                       struct ath_rc_series series[],
1162                       int *isProbe)
1163 {
1164         *isProbe = 0;
1165         if (!numRates || !numTries) {
1166                 return;
1167         }
1168
1169         rcRateFind_11n(sc, an, numTries, numRates, stepDnInc, rcflag, series, isProbe);
1170 }
1171
1172 static void
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)
1178 {
1179         int finalTSIdx = ds->ds_txstat.ts_rate;
1180         int tx_status = 0;
1181
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)) {
1186                 tx_status = 1;
1187         }
1188
1189         rcUpdate_11n(sc, an,
1190                      ds->ds_txstat.ts_antenna, finalTSIdx,
1191                      tx_status, rcs, nframes , nbad,
1192                      ds->ds_txstat.ts_longretry);
1193 }
1194
1195 static void
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)
1198 {
1199         if (isnew) {
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;
1204 #endif
1205                 rcSibUpdate_ht(sc, an, capflag, 0, rs);
1206         }
1207 }
1208
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)
1211 {
1212         int idx;
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;
1216    
1217         *txrate = asc->currentTxRateKbps;
1218
1219         /* look  11NA table for rateKbps*/
1220         for (idx = 0; idx < pRateTable->rateCount && !rateKbps; ++idx) {   
1221                 if (pRateTable->info[idx].rateCode == rateCode) {
1222                         if(ht40 && sgi) {
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;
1226                         } else if (ht40) {
1227                                 if (pRateTable->info[idx].valid == TRUE_40)/* HT40 only*/
1228                                         rateKbps = pRateTable->info[idx].rateKbps;
1229                         } else { 
1230                                 if (pRateTable->info[idx].valid != FALSE)
1231                                         rateKbps = pRateTable->info[idx].rateKbps;
1232                         }
1233                 }
1234         }
1235     
1236         *rxrate = rateKbps;
1237 }