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