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