8b88f6ec84de9ed82b47d91d34c89249ce36127f
[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 /* Iterators for validTxRateMask */
126 static INLINE A_BOOL
127 rcGetNextValidTxRate(const RATE_TABLE_11N *pRateTable, TX_RATE_CTRL *pRc, 
128                      A_UINT8 curValidTxRate, A_UINT8 *pNextIndex)
129 {
130         A_UINT8 i;
131
132         for (i = 0; i < pRc->maxValidRate-1; i++) {
133                 if (pRc->validRateIndex[i] == curValidTxRate) {
134                         *pNextIndex = pRc->validRateIndex[i+1];
135                         return TRUE;
136                 }
137         }
138
139         /* No more valid rates */
140         *pNextIndex = 0;
141     
142         return FALSE;
143 }
144
145 static INLINE A_BOOL
146 rcGetNextLowerValidTxRate(const RATE_TABLE_11N *pRateTable, TX_RATE_CTRL *pRc,  
147                           A_UINT8 curValidTxRate, A_UINT8 *pNextIndex)
148 {
149         A_INT8 i;
150
151         for (i = 1; i < pRc->maxValidRate ; i++) {
152                 if (pRc->validRateIndex[i] == curValidTxRate) {
153                         *pNextIndex = pRc->validRateIndex[i-1];
154                         return TRUE;
155                 }
156         }
157
158         return FALSE;
159 }
160
161 /* Return true only for single stream */
162
163 static A_BOOL
164 rcIsValidPhyRate(A_UINT32 phy, A_UINT32 capflag, A_BOOL ignoreCW)
165 {
166         if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG)) {
167                 return FALSE;
168         }
169
170         if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))  {
171                 return FALSE;
172         }
173         if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_HT40_SGI_FLAG)) {
174                 return FALSE;
175         }
176
177         if (!ignoreCW && WLAN_RC_PHY_HT(phy)) {
178                 if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG)) {
179                         return FALSE;
180                 }
181
182                 if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG)) {
183                         return FALSE;
184                 }
185         }
186     
187         return TRUE;
188 }
189
190 /* 
191  * Initialize the Valid Rate Index from valid entries in Rate Table 
192  */
193 static A_UINT8 rcSibInitValidRates(const RATE_TABLE_11N *pRateTable,
194                                    TX_RATE_CTRL *pRc,
195                                    A_UINT32 capflag,
196                                    PHY_STATE_CTRL *pPhyStateCtrl)
197 {
198         A_UINT8 i, hi = 0;
199         A_UINT8 singleStream = (capflag & WLAN_RC_DS_FLAG) ? 0 : 1;
200         A_UINT8 valid;
201     
202         for (i = 0; i < pRateTable->rateCount; i++) {
203                 if (singleStream) {
204                         valid = pRateTable->info[i].validSingleStream;
205                 } else {
206                         valid = pRateTable->info[i].valid;
207                 }
208             
209                 if (valid == TRUE) {
210                         A_UINT32 phy = pRateTable->info[i].phy;
211
212                         if (!rcIsValidPhyRate(phy, capflag, FALSE)) 
213                                 continue;
214
215                         pPhyStateCtrl->validPhyRateIndex[phy][pPhyStateCtrl->validPhyRateCount[phy]] = i;
216                         pPhyStateCtrl->validPhyRateCount[phy] += 1;
217
218                         rcSetValidTxMask(pRc, i, TRUE);
219
220                         hi = A_MAX(hi, i);
221                 }
222         } 
223     
224         return hi;
225 }
226
227 /* 
228  * Initialize the Valid Rate Index from Rate Set 
229  */
230 static A_UINT8
231 rcSibSetValidRates(const RATE_TABLE_11N *pRateTable,
232                    TX_RATE_CTRL *pRc, 
233                    struct ieee80211_rateset *pRateSet,
234                    A_UINT32 capflag,
235                    struct ath_node_target *an,
236                    PHY_STATE_CTRL *pPhyStateCtrl)
237 {
238         A_UINT8 i, j, hi = 0;
239         A_UINT8 singleStream = (capflag & WLAN_RC_DS_FLAG) ? 0 : 1;
240         A_UINT32 valid;
241        
242         /* Use intersection of working rates and valid rates */
243         for (i = 0; i < pRateSet->rs_nrates; i++) {
244                 for (j = 0; j < pRateTable->rateCount; j++) {
245                         A_UINT32 phy = pRateTable->info[j].phy;
246 #ifdef MAGPIE_MERLIN
247                         struct atheros_node *pSib = ATH_NODE_ATHEROS(an);
248
249                         if (pSib->stbc) {
250                                 valid = pRateTable->info[j].validSTBC;
251                         } else if (singleStream) {
252 #else
253                         if (singleStream) {
254 #endif            
255                                 valid = pRateTable->info[j].validSingleStream;
256                         } else {
257                                 valid = pRateTable->info[j].valid;
258                         }
259         
260                         /*
261                          * We allow a rate only if its valid and the capflag matches one of
262                          * the validity (TRUE/TRUE_20/TRUE_40) flags
263                          */
264
265                         if (((pRateSet->rs_rates[i] & 0x7F) == 
266                              (pRateTable->info[j].dot11Rate & 0x7F))
267                             && ((valid & WLAN_RC_CAP_MODE(capflag)) == 
268                                 WLAN_RC_CAP_MODE(capflag)) && !WLAN_RC_PHY_HT(phy)) {
269                                 if (!rcIsValidPhyRate(phy, capflag, FALSE)) 
270                                         continue;
271
272                                 pPhyStateCtrl->validPhyRateIndex[phy][pPhyStateCtrl->validPhyRateCount[phy]] = j;
273                                 pPhyStateCtrl->validPhyRateCount[phy] += 1;
274
275                                 rcSetValidTxMask(pRc, j, TRUE);
276                                 hi = A_MAX(hi, j);
277                         }
278                 }
279         }
280   
281         return hi;
282 }
283
284 static A_UINT8
285 rcSibSetValidHtRates(const RATE_TABLE_11N *pRateTable,
286                      TX_RATE_CTRL *pRc, 
287                      A_UINT8 *pMcsSet,
288                      A_UINT32 capflag,
289                      struct ath_node_target *an,
290                      PHY_STATE_CTRL *pPhyStateCtrl)
291 {
292         A_UINT8 i, j, hi = 0;
293         A_UINT8 singleStream = (capflag & WLAN_RC_DS_FLAG) ? 0 : 1;
294         A_UINT8 valid;
295     
296         /* Use intersection of working rates and valid rates */
297         for (i = 0; i <  ((struct ieee80211_rateset *)pMcsSet)->rs_nrates; i++) {
298                 for (j = 0; j < pRateTable->rateCount; j++) {
299                         A_UINT32 phy = pRateTable->info[j].phy;
300 #ifdef MAGPIE_MERLIN
301                         struct atheros_node *pSib = ATH_NODE_ATHEROS(an);
302
303                         if (pSib->stbc) {
304                                 valid = pRateTable->info[j].validSTBC;
305                         } else if (singleStream) {
306 #else
307                         if (singleStream) {
308 #endif
309                                 valid = pRateTable->info[j].validSingleStream;
310                         } else {
311                                 valid = pRateTable->info[j].valid;
312                         }
313                            
314                         if (((((struct ieee80211_rateset *)pMcsSet)->rs_rates[i] & 0x7F) 
315                              != (pRateTable->info[j].dot11Rate & 0x7F)) 
316                             || !WLAN_RC_PHY_HT(phy) 
317                             || !WLAN_RC_PHY_HT_VALID(valid, capflag)
318                             || ((pRateTable->info[j].dot11Rate == 15) && 
319                                 (valid & TRUE_20) && 
320                                 (capflag & WLAN_RC_WEP_TKIP_FLAG)) )
321                         {
322                                 continue;
323                         }
324     
325                         if (!rcIsValidPhyRate(phy, capflag, FALSE)) 
326                                 continue;
327     
328                         pPhyStateCtrl->validPhyRateIndex[phy][pPhyStateCtrl->validPhyRateCount[phy]] = j;
329                         pPhyStateCtrl->validPhyRateCount[phy] += 1;
330
331                         rcSetValidTxMask(pRc, j, TRUE);
332                         hi = A_MAX(hi, j);
333                 }
334         }
335
336         return hi;
337 }
338
339 /*
340  *  Update the SIB's rate control information
341  *
342  *  This should be called when the supported rates change
343  *  (e.g. SME operation, wireless mode change)
344  *
345  *  It will determine which rates are valid for use.
346  */
347 static void
348 rcSibUpdate_ht(struct ath_softc_tgt *sc, struct ath_node_target *an,
349                A_UINT32 capflag, A_BOOL keepState, struct ieee80211_rate  *pRateSet)
350 {
351         RATE_TABLE_11N *pRateTable = 0;
352         struct atheros_node *pSib = ATH_NODE_ATHEROS(an);
353         struct atheros_softc *asc = (struct atheros_softc*)sc->sc_rc;
354         A_UINT8 *phtMcs = (A_UINT8*)&pRateSet->htrates;
355         TX_RATE_CTRL *pRc = (TX_RATE_CTRL *)(pSib);
356         PHY_STATE_CTRL mPhyCtrlState;  
357
358         A_UINT8 i, j, k, hi = 0, htHi = 0;
359
360         pRateTable = (RATE_TABLE_11N*)asc->hwRateTable[sc->sc_curmode];
361
362         /* Initial rate table size. Will change depending on the working rate set */
363         pRc->rateTableSize = MAX_TX_RATE_TBL;
364
365         /* Initialize thresholds according to the global rate table */
366         for (i = 0 ; (i < pRc->rateTableSize) && (!keepState); i++) {
367                 pRc->state[i].per       = 0;
368         }
369
370         /* Determine the valid rates */
371         rcInitValidTxMask(pRc);
372
373         for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
374                 for (j = 0; j < MAX_TX_RATE_PHY; j++) {
375                         mPhyCtrlState.validPhyRateIndex[i][j] = 0;
376                 }   
377                 mPhyCtrlState.validPhyRateCount[i] = 0;
378         }
379
380         pRc->rcPhyMode = (capflag & WLAN_RC_40_FLAG);
381
382         if (pRateSet == NULL || !pRateSet->rates.rs_nrates) {
383                 /* No working rate, just initialize valid rates */
384                 hi = rcSibInitValidRates(pRateTable, pRc, capflag, &mPhyCtrlState);
385         } else {
386                 /* Use intersection of working rates and valid rates */
387                 hi = rcSibSetValidRates(pRateTable, pRc, &(pRateSet->rates),
388                                         capflag, an, &mPhyCtrlState);
389
390                 if (capflag & WLAN_RC_HT_FLAG) {
391                         htHi = rcSibSetValidHtRates(pRateTable, pRc, phtMcs,
392                                                     capflag, an, &mPhyCtrlState);
393                 }
394
395                 hi = A_MAX(hi, htHi);
396         }
397
398         pRc->rateTableSize = hi + 1;
399         pRc->rateMaxPhy    = 0;
400     
401         ASSERT(pRc->rateTableSize <= MAX_TX_RATE_TBL);
402
403         for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
404                 for (j = 0; j < mPhyCtrlState.validPhyRateCount[i]; j++) {
405                         pRc->validRateIndex[k++] = mPhyCtrlState.validPhyRateIndex[i][j];
406                 }   
407
408                 if (!rcIsValidPhyRate(i, pRateTable->initialRateMax, TRUE) ||
409                     !mPhyCtrlState.validPhyRateCount[i]) 
410                         continue;
411
412                 pRc->rateMaxPhy = mPhyCtrlState.validPhyRateIndex[i][j-1];      
413         }
414     
415         ASSERT(pRc->rateTableSize <= MAX_TX_RATE_TBL);
416         ASSERT(k <= MAX_TX_RATE_TBL);
417
418         pRc->rateMaxPhy = pRc->validRateIndex[k-4];
419         pRc->maxValidRate = k;
420
421         rcSortValidRates(pRateTable, pRc);
422 }
423
424
425
426 /*
427  * Return the median of three numbers
428  */
429 INLINE A_RSSI median(A_RSSI a, A_RSSI b, A_RSSI c)
430 {
431         if (a >= b) {
432                 if (b >= c) {
433                         return b;
434                 } else if (a > c) {
435                         return c;
436                 } else {
437                         return a;
438                 }
439         } else {
440                 if (a >= c) {
441                         return a;
442                 } else if (b >= c) {
443                         return c;
444                 } else {
445                         return b;
446                 }
447         }
448 }
449
450 static A_UINT8
451 rcRateFind_ht(struct ath_softc_tgt *sc, struct atheros_node *pSib,
452               const RATE_TABLE_11N *pRateTable, A_BOOL probeAllowed, A_BOOL *isProbing)
453 {
454         A_UINT32             dt;
455         A_UINT32             bestThruput, thisThruput;
456         A_UINT32             nowMsec;
457         A_UINT8              rate, nextRate, bestRate;
458         A_UINT8              maxIndex, minIndex;
459         A_INT8               index;
460         TX_RATE_CTRL         *pRc = NULL;
461
462         pRc = (TX_RATE_CTRL *)(pSib ? (pSib) : NULL);
463
464         *isProbing = FALSE;
465
466         /*
467          * Age (reduce) last ack rssi based on how old it is.
468          * The bizarre numbers are so the delta is 160msec,
469          * meaning we divide by 16.
470          *   0msec   <= dt <= 25msec:   don't derate
471          *   25msec  <= dt <= 185msec:  derate linearly from 0 to 10dB
472          *   185msec <= dt:             derate by 10dB
473          */
474
475         nowMsec = A_MS_TICKGET();
476         dt = nowMsec - pRc->rssiTime;
477
478         /*
479          * Now look up the rate in the rssi table and return it.
480          * If no rates match then we return 0 (lowest rate)
481          */
482
483         bestThruput = 0;
484         maxIndex = pRc->maxValidRate-1;
485
486         minIndex = 0;
487         bestRate = minIndex;
488     
489         /*
490          * Try the higher rate first. It will reduce memory moving time
491          * if we have very good channel characteristics.
492          */
493         for (index = maxIndex; index >= minIndex ; index--) {
494                 A_UINT8 perThres;
495     
496                 rate = pRc->validRateIndex[index];
497                 if (rate > pRc->rateMaxPhy) {
498                         continue;
499                 }
500
501                 /* if the best throughput is already larger than the userRateKbps..
502                  * then we could skip of rest of calculation.. 
503                  */
504                 if( bestThruput >= pRateTable->info[rate].userRateKbps)
505                         break;
506
507                 /*
508                  * For TCP the average collision rate is around 11%,
509                  * so we ignore PERs less than this.  This is to
510                  * prevent the rate we are currently using (whose
511                  * PER might be in the 10-15 range because of TCP
512                  * collisions) looking worse than the next lower
513                  * rate whose PER has decayed close to 0.  If we
514                  * used to next lower rate, its PER would grow to
515                  * 10-15 and we would be worse off then staying
516                  * at the current rate.
517                  */
518                 perThres = pRc->state[rate].per;
519                 if ( perThres < 12 ) {
520                         perThres = 12;
521                 }
522
523                 thisThruput = pRateTable->info[rate].userRateKbps * (100 - perThres);
524                 if (bestThruput <= thisThruput) {
525                         bestThruput = thisThruput;
526                         bestRate    = rate;
527                 }
528         }
529
530         rate = bestRate;
531
532         /*
533          * Must check the actual rate (rateKbps) to account for non-monoticity of
534          * 11g's rate table
535          */
536
537         if (rate >= pRc->rateMaxPhy && probeAllowed) {
538                 rate = pRc->rateMaxPhy;
539
540                 /* Probe the next allowed phy state */
541                 /* FIXME: Check to make sure ratMax is checked properly */
542                 if (rcGetNextValidTxRate( pRateTable, pRc, rate, &nextRate) && 
543                     (nowMsec - pRc->probeTime > pRateTable->probeInterval) &&
544                     (pRc->hwMaxRetryPktCnt >= 1))
545                 {
546                         rate                  = nextRate;
547                         pRc->probeRate        = rate;
548                         pRc->probeTime        = nowMsec;
549                         pRc->hwMaxRetryPktCnt = 0;
550                         *isProbing            = TRUE;
551
552                 }
553         }
554
555         /*
556          * Make sure rate is not higher than the allowed maximum.
557          * We should also enforce the min, but I suspect the min is
558          * normally 1 rather than 0 because of the rate 9 vs 6 issue
559          * in the old code.
560          */
561         if (rate > (pRc->rateTableSize - 1)) {
562                 rate = pRc->rateTableSize - 1;
563         }
564
565         /* record selected rate, which is used to decide if we want to do fast frame */
566         if (!(*isProbing) && pSib) {
567                 pSib->lastRateKbps = pRateTable->info[rate].rateKbps;
568                 ((struct atheros_softc*)sc->sc_rc)->currentTxRateKbps = pSib->lastRateKbps;
569                 ((struct atheros_softc*)sc->sc_rc)->currentTxRateIndex = rate;
570         }
571
572         return rate;
573 }
574
575 static void
576 rcRateSetseries(const RATE_TABLE_11N *pRateTable ,
577                 struct ath_rc_series *series,
578                 A_UINT8 tries, A_UINT8 rix,
579                 A_BOOL rtsctsenable, A_UINT32 chainmask,int stbc)
580 {
581         series->tries = tries;
582         series->flags = (rtsctsenable? ATH_RC_RTSCTS_FLAG : 0) | 
583                 (WLAN_RC_PHY_DS(pRateTable->info[rix].phy) ? ATH_RC_DS_FLAG : 0) | 
584                 (WLAN_RC_PHY_40(pRateTable->info[rix].phy) ? ATH_RC_CW40_FLAG : 0) | 
585                 (WLAN_RC_PHY_SGI(pRateTable->info[rix].phy) ? ATH_RC_HT40_SGI_FLAG : 0);
586 #ifdef MAGPIE_MERLIN
587         if (stbc) {
588                 /* For now, only single stream STBC is supported */
589                 if (pRateTable->info[rix].rateCode >= 0x80 && 
590                     pRateTable->info[rix].rateCode <= 0x87)
591                 {
592                         series->flags |= ATH_RC_TX_STBC_FLAG;
593                 }
594         }
595 #endif
596         series->rix = pRateTable->info[rix].baseIndex;
597         series->max4msframelen = pRateTable->info[rix].max4msframelen;
598         series->txrateKbps = pRateTable->info[rix].rateKbps;
599
600         /* If the hardware is capable of multiple transmit chains (chainmask is 3, 5 or 7), 
601          * then choose the number of transmit chains dynamically based on entries in the rate table.
602          */
603 #ifndef ATH_ENABLE_WLAN_FOR_K2
604         if(chainmask == 7)
605                 series->tx_chainmask = pRateTable->info[rix].txChainMask_3ch;
606         else if(chainmask == 1) 
607                 series->tx_chainmask = 1;
608         else 
609                 series->tx_chainmask = pRateTable->info[rix].txChainMask_2ch;  /*Chainmask is 3 or 5*/
610 #else
611         series->tx_chainmask = 1;
612 #endif
613 }
614
615 static A_UINT8 
616 rcRateGetIndex(struct ath_softc_tgt *sc, struct ath_node_target *an,        
617                const RATE_TABLE_11N *pRateTable , 
618                A_UINT8 rix, A_UINT16 stepDown, A_UINT16 minRate)
619 {
620         A_UINT32                j;
621         A_UINT8                 nextIndex;
622         struct atheros_node     *pSib = ATH_NODE_ATHEROS(an);
623         TX_RATE_CTRL            *pRc = (TX_RATE_CTRL *)(pSib);
624     
625         if (minRate) {
626                 for (j = RATE_TABLE_11N_SIZE; j > 0; j-- ) {
627                         if (rcGetNextLowerValidTxRate(pRateTable, pRc, rix, &nextIndex)) {
628                                 rix = nextIndex;
629                         } else {
630                                 break;
631                         }
632                 }
633         } else {
634                 for (j = stepDown; j > 0; j-- ) {
635                         if (rcGetNextLowerValidTxRate(pRateTable, pRc, rix, &nextIndex)) {
636                                 rix = nextIndex;
637                         } else {
638                                 break;
639                         }
640                 }
641         }
642
643         return rix;
644 }
645
646 void rcRateFind_11n(struct ath_softc_tgt *sc, struct ath_node_target *an, 
647                     int numTries, int numRates, int stepDnInc,
648                     unsigned int rcflag, struct ath_rc_series series[], int *isProbe)
649 {
650         A_UINT8 i = 0; 
651         A_UINT8 tryPerRate  = 0;
652         struct atheros_softc *asc = (struct atheros_softc*)sc->sc_rc;
653         RATE_TABLE_11N *pRateTable = (RATE_TABLE_11N *)asc->hwRateTable[sc->sc_curmode];
654         struct atheros_node *asn = ATH_NODE_ATHEROS(an);
655         A_UINT8 rix, nrix;
656         A_UINT8 dot11Rate;
657         WLAN_PHY phy;
658
659         rix = rcRateFind_ht(sc, asn, pRateTable, (rcflag & ATH_RC_PROBE_ALLOWED) ? 1 : 0, 
660                             isProbe);
661         nrix = rix;
662
663         if ((rcflag & ATH_RC_PROBE_ALLOWED) && (*isProbe)) {
664                 /* set one try for probe rates. For the probes don't enable rts */
665                 rcRateSetseries(pRateTable, &series[i++], 1, nrix,
666                                 FALSE, asc->tx_chainmask, asn->stbc);
667           
668                 /*
669                  * Get the next tried/allowed rate. No RTS for the next series
670                  * after the probe rate
671                  */
672                 nrix = rcRateGetIndex( sc, an, pRateTable, nrix, 1, FALSE);
673         }
674
675         tryPerRate = (numTries/numRates);
676
677         /* Set the choosen rate. No RTS for first series entry. */
678         rcRateSetseries(pRateTable, &series[i++], tryPerRate,
679                         nrix, FALSE, asc->tx_chainmask, asn->stbc);
680
681         /* Fill in the other rates for multirate retry */
682         for (; i < numRates; i++) {
683                 A_UINT8 tryNum;
684                 A_UINT8 minRate;
685
686                 tryNum  = ((i + 1) == numRates) ? numTries - (tryPerRate * i) : tryPerRate ;
687                 minRate = (((i + 1) == numRates) && (rcflag & ATH_RC_MINRATE_LASTRATE)) ? 1 : 0;
688
689                 nrix = rcRateGetIndex(sc, an, pRateTable, nrix, stepDnInc, minRate);
690
691                 /* All other rates in the series have RTS enabled */
692                 rcRateSetseries(pRateTable, &series[i], tryNum,
693                                 nrix, TRUE, asc->tx_chainmask, asn->stbc);
694         }
695
696         /*
697          * BUG 26545:
698          * Change rate series to enable aggregation when operating at lower MCS rates. 
699          * When first rate in series is MCS2 in HT40 @ 2.4GHz, series should look like:
700          *    {MCS2, MCS1, MCS0, MCS0}.
701          * When first rate in series is MCS3 in HT20 @ 2.4GHz, series should look like:
702          *    {MCS3, MCS2, MCS1, MCS1}
703          * So, set fourth rate in series to be same as third one for above conditions.
704          */
705         if (sc->sc_curmode == IEEE80211_MODE_11NG) {
706                 dot11Rate = pRateTable->info[rix].dot11Rate;
707                 phy = pRateTable->info[rix].phy;
708                 if (i == 4 &&
709                     ((dot11Rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) || 
710                      (dot11Rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) 
711                 {
712                         series[3].rix = series[2].rix;
713                         series[3].flags = series[2].flags;
714                         series[3].max4msframelen = series[2].max4msframelen;
715                 }
716         }
717
718         /*
719          * 2009/02/06
720          * AP91 Kite: NetGear OTA location-4 downlink.
721          *            Enable RTS/CTS at MCS 3-0 for downlink throughput.
722          */
723         if (sc->sc_curmode == IEEE80211_MODE_11NG) {
724                 dot11Rate = pRateTable->info[rix].dot11Rate;
725                 if (dot11Rate <= 3 ) {
726                         series[0].flags |= ATH_RC_RTSCTS_FLAG;         
727                 }
728         }
729 }
730
731 static void
732 rcUpdate_ht(struct ath_softc_tgt *sc, struct ath_node_target *an, int txRate, 
733             A_BOOL Xretries, int retries, A_UINT8 curTxAnt, 
734             A_UINT16 nFrames, A_UINT16 nBad)
735 {
736         TX_RATE_CTRL *pRc;
737         A_UINT32 nowMsec = A_MS_TICKGET();
738         A_UINT8 lastPer;
739         int rate,count;
740         struct atheros_node *pSib = ATH_NODE_ATHEROS(an);
741         struct atheros_softc *asc = (struct atheros_softc*)sc->sc_rc;
742         RATE_TABLE_11N *pRateTable = (RATE_TABLE_11N *)asc->hwRateTable[sc->sc_curmode];
743
744         static A_UINT32 nRetry2PerLookup[10] = {
745                 100 * 0 / 1,    // 0
746                 100 * 1 / 4,    // 25
747                 100 * 1 / 2,    // 50
748                 100 * 3 / 4,    // 75
749                 100 * 4 / 5,    // 80
750                 100 * 5 / 6,    // 83.3
751                 100 * 6 / 7,    // 85.7
752                 100 * 7 / 8,    // 87.5
753                 100 * 8 / 9,    // 88.8
754                 100 * 9 / 10    // 90
755         };
756
757         if (!pSib)
758                 return;
759
760         pRc = (TX_RATE_CTRL *)(pSib);
761
762         ASSERT(retries >= 0 && retries < MAX_TX_RETRIES);
763         ASSERT(txRate >= 0);
764     
765         if (txRate < 0) {
766                 return;
767         }
768
769         lastPer = pRc->state[txRate].per;
770
771         if (Xretries) {
772                 /* Update the PER. */
773                 if (Xretries == 1) {
774                         pRc->state[txRate].per += 30;
775                         if (pRc->state[txRate].per > 100) {
776                                 pRc->state[txRate].per = 100;
777                         }
778                 } else {
779                         /* Xretries == 2 */
780
781                         count = sizeof(nRetry2PerLookup) / sizeof(nRetry2PerLookup[0]);
782                         if (retries >= count) {
783                                 retries = count - 1;
784                         }
785
786                         /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
787                         pRc->state[txRate].per = (A_UINT8)(pRc->state[txRate].per - 
788                                                    (pRc->state[txRate].per / 8) + ((100) / 8));
789                 }
790
791                 /* Xretries == 1 or 2 */
792
793                 if (pRc->probeRate == txRate)
794                         pRc->probeRate = 0;
795         } else {
796                 /* Xretries == 0 */
797
798                 /*
799                  * Update the PER.  Make sure it doesn't index out of array's bounds.
800                  */
801                 count = sizeof(nRetry2PerLookup) / sizeof(nRetry2PerLookup[0]);
802                 if (retries >= count) {
803                         retries = count - 1;
804                 }
805
806                 if (nBad) {
807                         /* new_PER = 7/8*old_PER + 1/8*(currentPER)  */
808                         /*
809                          * Assuming that nFrames is not 0.  The current PER
810                          * from the retries is 100 * retries / (retries+1),
811                          * since the first retries attempts failed, and the
812                          * next one worked.  For the one that worked, nBad
813                          * subframes out of nFrames wored, so the PER for
814                          * that part is 100 * nBad / nFrames, and it contributes
815                          * 100 * nBad / (nFrames * (retries+1)) to the above
816                          * PER.  The expression below is a simplified version
817                          * of the sum of these two terms.
818                          */
819                         if (nFrames > 0)
820                                 pRc->state[txRate].per = (A_UINT8)(pRc->state[txRate].per - 
821                                            (pRc->state[txRate].per / 8) + 
822                                            ((100*(retries*nFrames + nBad)/(nFrames*(retries+1))) / 8));
823                 } else {
824                         /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
825
826                         pRc->state[txRate].per = (A_UINT8)(pRc->state[txRate].per - 
827                                    (pRc->state[txRate].per / 8) + (nRetry2PerLookup[retries] / 8));
828                 }
829
830                 /*
831                  * If we got at most one retry then increase the max rate if
832                  * this was a probe.  Otherwise, ignore the probe.
833                  */
834
835                 if (pRc->probeRate && pRc->probeRate == txRate) {
836                         if (retries > 0 || 2 * nBad > nFrames) {
837                                 /*
838                                  * Since we probed with just a single attempt,
839                                  * any retries means the probe failed.  Also,
840                                  * if the attempt worked, but more than half
841                                  * the subframes were bad then also consider
842                                  * the probe a failure.
843                                  */
844                                 pRc->probeRate = 0;
845                         } else {
846                                 pRc->rateMaxPhy = pRc->probeRate;
847
848                                 if (pRc->state[pRc->probeRate].per > 30) {
849                                         pRc->state[pRc->probeRate].per = 20;
850                                 }
851
852                                 pRc->probeRate = 0;
853
854                                 /*
855                                  * Since this probe succeeded, we allow the next probe
856                                  * twice as soon.  This allows the maxRate to move up
857                                  * faster if the probes are succesful.
858                                  */
859                                 pRc->probeTime = nowMsec - pRateTable->probeInterval / 2;
860                         }
861                 }
862
863                 if (retries > 0) {
864                         /*
865                          * Don't update anything.  We don't know if this was because
866                          * of collisions or poor signal.
867                          *
868                          * Later: if rssiAck is close to pRc->state[txRate].rssiThres
869                          * and we see lots of retries, then we could increase
870                          * pRc->state[txRate].rssiThres.
871                          */
872                         pRc->hwMaxRetryPktCnt = 0;
873                 } else {
874                         /*
875                          * It worked with no retries.  First ignore bogus (small)
876                          * rssiAck values.
877                          */
878                         if (txRate == pRc->rateMaxPhy && pRc->hwMaxRetryPktCnt < 255) {
879                                 pRc->hwMaxRetryPktCnt++;
880                         }
881
882                 }
883         }
884
885         /* For all cases */
886
887         ASSERT((pRc->rateMaxPhy >= 0 && pRc->rateMaxPhy <= pRc->rateTableSize && 
888                 pRc->rateMaxPhy != INVALID_RATE_MAX));
889     
890         /*
891          * If this rate looks bad (high PER) then stop using it for
892          * a while (except if we are probing).
893          */
894         if (pRc->state[txRate].per >= 55 && txRate > 0 &&
895             pRateTable->info[txRate].rateKbps <= 
896             pRateTable->info[pRc->rateMaxPhy].rateKbps)
897         {
898                 rcGetNextLowerValidTxRate(pRateTable, pRc, (A_UINT8) txRate, 
899                                           &pRc->rateMaxPhy);
900
901                 /* Don't probe for a little while. */
902                 pRc->probeTime = nowMsec;
903         }
904
905         /* Make sure the rates below this have lower PER */
906         /* Monotonicity is kept only for rates below the current rate. */
907         if (pRc->state[txRate].per < lastPer) {
908                 for (rate = txRate - 1; rate >= 0; rate--) {
909                         if (pRateTable->info[rate].phy != pRateTable->info[txRate].phy) {
910                                 break;
911                         }
912
913                         if (pRc->state[rate].per > pRc->state[rate+1].per) {
914                                 pRc->state[rate].per = pRc->state[rate+1].per;
915                         }
916                 }
917         }
918
919         /* Maintain monotonicity for rates above the current rate*/
920         for (rate = txRate; rate < pRc->rateTableSize - 1; rate++) {
921                 if (pRc->state[rate+1].per < pRc->state[rate].per) {
922                         pRc->state[rate+1].per = pRc->state[rate].per;
923                 }
924         }
925
926         /* Every so often, we reduce the thresholds and PER (different for CCK and OFDM). */
927         if (nowMsec - pRc->perDownTime >= pRateTable->rssiReduceInterval) {
928                 for (rate = 0; rate < pRc->rateTableSize; rate++) {
929                         pRc->state[rate].per = 7*pRc->state[rate].per/8;
930                 }
931
932                 pRc->perDownTime = nowMsec;
933         }
934 }
935
936 /*
937  * This routine is called by the Tx interrupt service routine to give
938  * the status of previous frames.
939  */
940 void rcUpdate_11n(struct ath_softc_tgt *sc, struct ath_node_target *an,
941                   A_UINT8 curTxAnt, 
942                   int finalTSIdx, int Xretries,
943                   struct ath_rc_series rcs[], int nFrames, 
944                   int nBad, int long_retry)
945 {
946         A_UINT32 series = 0;
947         A_UINT32 rix;
948         struct atheros_softc *asc = (struct atheros_softc*)sc->sc_rc;
949         RATE_TABLE_11N *pRateTable = (RATE_TABLE_11N *)asc->hwRateTable[sc->sc_curmode];
950         struct atheros_node *pSib = ATH_NODE_ATHEROS(an);
951         TX_RATE_CTRL *pRc = (TX_RATE_CTRL *)(pSib);
952         A_UINT8 flags;
953
954         if (!an) {
955                 adf_os_assert(0);
956                 return;
957         }
958
959         ASSERT (rcs[0].tries != 0);
960
961         /*
962          * If the first rate is not the final index, there are intermediate rate failures
963          * to be processed.
964          */
965         if (finalTSIdx != 0) {
966
967                 /* Process intermediate rates that failed.*/
968                 for (series = 0; series < finalTSIdx ; series++) {
969                         if (rcs[series].tries != 0) {
970                                 flags = rcs[series].flags;
971                                 /* If HT40 and we have switched mode from 40 to 20 => don't update */
972                                 if ((flags & ATH_RC_CW40_FLAG) && 
973                                     (pRc->rcPhyMode != (flags & ATH_RC_CW40_FLAG))) {
974                                         return;
975                                 }
976                                 if ((flags & ATH_RC_CW40_FLAG) && (flags & ATH_RC_HT40_SGI_FLAG)) {
977                                         rix = pRateTable->info[rcs[series].rix].htIndex;
978                                 } else if (flags & ATH_RC_HT40_SGI_FLAG) {
979                                         rix = pRateTable->info[rcs[series].rix].sgiIndex;
980                                 } else if (flags & ATH_RC_CW40_FLAG) {
981                                         rix = pRateTable->info[rcs[series].rix].cw40Index;
982                                 } else {
983                                         rix = pRateTable->info[rcs[series].rix].baseIndex;
984                                 }
985
986                                 /* FIXME:XXXX, too many args! */
987                                 rcUpdate_ht(sc, an, rix, Xretries? 1 : 2, rcs[series].tries, 
988                                             curTxAnt, nFrames, nFrames);
989                         }
990                 }
991         } else {
992                 /*
993                  * Handle the special case of MIMO PS burst, where the second aggregate is sent
994                  *  out with only one rate and one try. Treating it as an excessive retry penalizes
995                  * the rate inordinately.
996                  */
997                 if (rcs[0].tries == 1 && Xretries == 1) {
998                         Xretries = 2;
999                 }
1000         }
1001
1002         flags = rcs[series].flags;
1003         /* If HT40 and we have switched mode from 40 to 20 => don't update */
1004         if ((flags & ATH_RC_CW40_FLAG) && 
1005             (pRc->rcPhyMode != (flags & ATH_RC_CW40_FLAG))) {
1006                 return;
1007         }
1008         if ((flags & ATH_RC_CW40_FLAG) && (flags & ATH_RC_HT40_SGI_FLAG)) {
1009                 rix = pRateTable->info[rcs[series].rix].htIndex;
1010         } else if (flags & ATH_RC_HT40_SGI_FLAG) {
1011                 rix = pRateTable->info[rcs[series].rix].sgiIndex;
1012         } else if (flags & ATH_RC_CW40_FLAG) {
1013                 rix = pRateTable->info[rcs[series].rix].cw40Index;
1014         } else {
1015                 rix = pRateTable->info[rcs[series].rix].baseIndex;
1016         }
1017
1018         /* FIXME:XXXX, too many args! */
1019         rcUpdate_ht(sc, an, rix, Xretries, long_retry, curTxAnt, 
1020                     nFrames, nBad);
1021 }
1022
1023 void ath_tx_status_update_rate(struct ath_softc_tgt *sc,
1024                                struct ath_rc_series rcs[],
1025                                int series,
1026                                WMI_TXSTATUS_EVENT *txs)
1027 {
1028         struct atheros_softc *asc = (struct atheros_softc*)sc->sc_rc;
1029         RATE_TABLE_11N *pRateTable = (RATE_TABLE_11N *)asc->hwRateTable[sc->sc_curmode];
1030
1031         /* HT Rate */
1032         if (pRateTable->info[rcs[series].rix].rateCode & 0x80) {
1033                 txs->txstatus[txs->cnt].ts_rate |= SM(pRateTable->info[rcs[series].rix].dot11Rate,
1034                                                                        ATH9K_HTC_TXSTAT_RATE);
1035                 txs->txstatus[txs->cnt].ts_flags |= ATH9K_HTC_TXSTAT_MCS;
1036
1037                 if (rcs[series].flags & ATH_RC_CW40_FLAG)
1038                         txs->txstatus[txs->cnt].ts_flags |= ATH9K_HTC_TXSTAT_CW40;
1039
1040                 if (rcs[series].flags & ATH_RC_HT40_SGI_FLAG)
1041                         txs->txstatus[txs->cnt].ts_flags |= ATH9K_HTC_TXSTAT_SGI;
1042
1043         } else {
1044                 txs->txstatus[txs->cnt].ts_rate |= SM(rcs[series].rix, ATH9K_HTC_TXSTAT_RATE);
1045         }
1046
1047         if (rcs[series].flags & ATH_RC_RTSCTS_FLAG)
1048                 txs->txstatus[txs->cnt].ts_flags |= ATH9K_HTC_TXSTAT_RTC_CTS;
1049
1050 }
1051
1052 struct ath_ratectrl *
1053 ath_rate_attach(struct ath_softc_tgt *sc)
1054 {
1055         struct atheros_softc *asc;
1056
1057         asc = adf_os_mem_alloc(sizeof(struct atheros_softc));
1058         if (asc == NULL)
1059                 return NULL;
1060
1061         adf_os_mem_set(asc, 0, sizeof(struct atheros_softc));
1062         asc->arc.arc_space = sizeof(struct atheros_node);
1063
1064         ar5416AttachRateTables(asc);
1065
1066         asc->tx_chainmask = 1;
1067     
1068         return &asc->arc;
1069 }
1070
1071 void
1072 ath_rate_detach(struct ath_ratectrl *rc)
1073 {
1074         adf_os_mem_free(rc);
1075 }
1076
1077 void
1078 ath_rate_findrate(struct ath_softc_tgt *sc,
1079                   struct ath_node_target *an,
1080                   int shortPreamble,
1081                   size_t frameLen,
1082                   int numTries,
1083                   int numRates,
1084                   int stepDnInc,
1085                   unsigned int rcflag,
1086                   struct ath_rc_series series[],
1087                   int *isProbe)
1088 {
1089         *isProbe = 0;
1090
1091         if (!numRates || !numTries) {
1092                 return;
1093         }
1094
1095         ath_rate_findrate_11n(sc, an, frameLen, numTries, numRates, stepDnInc,
1096                               rcflag, series, isProbe);
1097 }
1098
1099 #define MS(_v, _f)  (((_v) & _f) >> _f##_S)
1100
1101 void
1102 ath_rate_tx_complete(struct ath_softc_tgt *sc,
1103                      struct ath_node_target *an,
1104                      struct ath_tx_desc *ds,
1105                      struct ath_rc_series rcs[], 
1106                      int nframes, int nbad)
1107 {
1108         ath_rate_tx_complete_11n(sc, an, ds, rcs, nframes, nbad);
1109 }
1110
1111 void
1112 ath_rate_newassoc(struct ath_softc_tgt *sc, struct ath_node_target *an, int isnew, 
1113                   unsigned int capflag, struct ieee80211_rate *rs)
1114 {
1115         ath_rate_newassoc_11n(sc, an, isnew, capflag, rs);
1116 }
1117
1118 void ath_rate_node_update(struct ath_softc_tgt *sc,
1119                           struct ath_node_target *an,
1120                           a_int32_t isnew,
1121                           a_uint32_t capflag,
1122                           struct ieee80211_rate *rs)
1123 {
1124         struct ieee80211_node_target *ni = &an->ni;
1125
1126         ath_rate_newassoc(sc, ATH_NODE_TARGET(ni), isnew, capflag, rs); 
1127 }
1128
1129 static int init_ath_rate_atheros(void);
1130 static void exit_ath_rate_atheros(void);
1131
1132 void
1133 ath_rate_newstate(struct ath_softc_tgt *sc,
1134                   struct ieee80211vap_target *vap,
1135                   enum ieee80211_state state,
1136                   a_uint32_t capflag,
1137                   struct ieee80211_rate *rs)
1138 {
1139         struct ieee80211_node_target *ni = vap->iv_bss;
1140         struct atheros_softc *asc = (struct atheros_softc *) sc->sc_rc;
1141
1142         asc->tx_chainmask = sc->sc_ic.ic_tx_chainmask;
1143         ath_rate_newassoc(sc, ATH_NODE_TARGET(ni), 1, capflag, rs);
1144 }
1145
1146 static void
1147 ath_rate_findrate_11n(struct ath_softc_tgt *sc,
1148                       struct ath_node_target *an,
1149                       size_t frameLen,
1150                       int numTries,
1151                       int numRates,
1152                       int stepDnInc,
1153                       unsigned int rcflag,
1154                       struct ath_rc_series series[],
1155                       int *isProbe)
1156 {
1157         *isProbe = 0;
1158         if (!numRates || !numTries) {
1159                 return;
1160         }
1161
1162         rcRateFind_11n(sc, an, numTries, numRates, stepDnInc, rcflag, series, isProbe);
1163 }
1164
1165 static void
1166 ath_rate_tx_complete_11n(struct ath_softc_tgt *sc,
1167                          struct ath_node_target *an,
1168                          struct ath_tx_desc *ds,
1169                          struct ath_rc_series rcs[], 
1170                          int nframes, int nbad)
1171 {
1172         int finalTSIdx = ds->ds_txstat.ts_rate;
1173         int tx_status = 0;
1174
1175         if ((ds->ds_txstat.ts_status & HAL_TXERR_XRETRY) ||
1176             (ds->ds_txstat.ts_status & HAL_TXERR_FIFO) || 
1177             (ds->ds_txstat.ts_flags & HAL_TX_DATA_UNDERRUN) ||
1178             (ds->ds_txstat.ts_flags & HAL_TX_DELIM_UNDERRUN)) {
1179                 tx_status = 1;
1180         }
1181
1182         rcUpdate_11n(sc, an,
1183                      ds->ds_txstat.ts_antenna, finalTSIdx,
1184                      tx_status, rcs, nframes , nbad,
1185                      ds->ds_txstat.ts_longretry);
1186 }
1187
1188 static void
1189 ath_rate_newassoc_11n(struct ath_softc_tgt *sc, struct ath_node_target *an, int isnew, 
1190                       unsigned int capflag, struct ieee80211_rate *rs)
1191 {
1192         if (isnew) {
1193 #ifdef MAGPIE_MERLIN
1194                 struct atheros_node *oan = ATH_NODE_ATHEROS(an);
1195                 /* Only MERLIN can send STBC */
1196                 oan->stbc = (capflag & ATH_RC_TX_STBC_FLAG) ? 1 : 0;
1197 #endif
1198                 rcSibUpdate_ht(sc, an, capflag, 0, rs);
1199         }
1200 }
1201
1202 void ath_rate_mcs2rate(struct ath_softc_tgt *sc,a_uint8_t sgi, a_uint8_t ht40, 
1203                        a_uint8_t rateCode, a_uint32_t *txrate, a_uint32_t *rxrate)
1204 {
1205         int idx;
1206         struct atheros_softc *asc = (struct atheros_softc*)sc->sc_rc;
1207         RATE_TABLE_11N *pRateTable = (RATE_TABLE_11N *)asc->hwRateTable[sc->sc_curmode];
1208         a_uint32_t rateKbps = 0;
1209    
1210         *txrate = asc->currentTxRateKbps;
1211
1212         /* look  11NA table for rateKbps*/
1213         for (idx = 0; idx < pRateTable->rateCount && !rateKbps; ++idx) {   
1214                 if (pRateTable->info[idx].rateCode == rateCode) {
1215                         if(ht40 && sgi) {
1216                                 if(pRateTable->info[idx].valid == TRUE_40 &&
1217                                    pRateTable->info[idx].phy == WLAN_RC_PHY_HT_40_DS_HGI)
1218                                         rateKbps = pRateTable->info[idx].rateKbps;
1219                         } else if (ht40) {
1220                                 if (pRateTable->info[idx].valid == TRUE_40)/* HT40 only*/
1221                                         rateKbps = pRateTable->info[idx].rateKbps;
1222                         } else { 
1223                                 if (pRateTable->info[idx].valid != FALSE)
1224                                         rateKbps = pRateTable->info[idx].rateKbps;
1225                         }
1226                 }
1227         }
1228     
1229         *rxrate = rateKbps;
1230 }