Staging: Add pristine upstream vt6655 driver sources
[pandora-kernel.git] / drivers / staging / vt6655 / datarate.c
1 /*
2  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * File: datarate.c
20  *
21  * Purpose: Handles the auto fallback & data rates functions
22  *
23  * Author: Lyndon Chen
24  *
25  * Date: July 17, 2002
26  *
27  * Functions:
28  *      RATEvParseMaxRate - Parsing the highest basic & support rate in rate field of frame
29  *      RATEvTxRateFallBack - Rate fallback Algorithm Implementaion
30  *      RATEuSetIE- Set rate IE field.
31  *
32  * Revision History:
33  *
34  */
35
36 #if !defined(__TTYPE_H__)
37 #include "ttype.h"
38 #endif
39 #if !defined(__TMACRO_H__)
40 #include "tmacro.h"
41 #endif
42 #if !defined(__MAC_H__)
43 #include "mac.h"
44 #endif
45 #if !defined(__80211MGR_H__)
46 #include "80211mgr.h"
47 #endif
48 #if !defined(__BSSDB_H__)
49 #include "bssdb.h"
50 #endif
51 #if !defined(__DATARATE_H__)
52 #include "datarate.h"
53 #endif
54 #if !defined(__CARD_H__)
55 #include "card.h"
56 #endif
57 #if !defined(__BASEBAND_H__)
58 #include "baseband.h"
59 #endif
60 #if !defined(__SROM_H__)
61 #include "srom.h"
62 #endif
63
64 /*---------------------  Static Definitions -------------------------*/
65
66
67
68
69 /*---------------------  Static Classes  ----------------------------*/
70
71
72  extern WORD TxRate_iwconfig; //2008-5-8 <add> by chester
73 /*---------------------  Static Variables  --------------------------*/
74 //static int          msglevel                =MSG_LEVEL_DEBUG;
75 static int          msglevel                =MSG_LEVEL_INFO;
76 const BYTE acbyIERate[MAX_RATE] =
77 {0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
78
79 #define AUTORATE_TXOK_CNT       0x0400
80 #define AUTORATE_TXFAIL_CNT     0x0064
81 #define AUTORATE_TIMEOUT        10
82
83 /*---------------------  Static Functions  --------------------------*/
84
85 VOID s_vResetCounter (
86     IN PKnownNodeDB psNodeDBTable
87     );
88
89
90
91 VOID
92 s_vResetCounter (
93     IN PKnownNodeDB psNodeDBTable
94     )
95 {
96     BYTE            ii;
97
98     // clear statistic counter for auto_rate
99     for(ii=0;ii<=MAX_RATE;ii++) {
100         psNodeDBTable->uTxOk[ii] = 0;
101         psNodeDBTable->uTxFail[ii] = 0;
102     }
103 }
104
105 /*---------------------  Export Variables  --------------------------*/
106
107
108 /*---------------------  Export Functions  --------------------------*/
109
110
111 /*+
112  *
113  * Description:
114  *      Get RateIdx from the value in SuppRates IE or ExtSuppRates IE
115  *
116  * Parameters:
117  *  In:
118  *      BYTE    - Rate value in SuppRates IE or ExtSuppRates IE
119  *  Out:
120  *      none
121  *
122  * Return Value: RateIdx
123  *
124 -*/
125 BYTE
126 DATARATEbyGetRateIdx (
127     IN BYTE byRate
128     )
129 {
130     BYTE    ii;
131
132     //Erase basicRate flag.
133     byRate = byRate & 0x7F;//0111 1111
134
135     for (ii = 0; ii < MAX_RATE; ii ++) {
136         if (acbyIERate[ii] == byRate)
137             return ii;
138     }
139     return 0;
140 }
141
142
143
144 /*+
145  *
146  * Routine Description:
147  *      Rate fallback Algorithm Implementaion
148  *
149  * Parameters:
150  *  In:
151  *      pDevice         - Pointer to the adapter
152  *      psNodeDBTable   - Pointer to Node Data Base
153  *  Out:
154  *      none
155  *
156  * Return Value: none
157  *
158 -*/
159 #define AUTORATE_TXCNT_THRESHOLD        20
160 #define AUTORATE_INC_THRESHOLD          30
161
162
163
164
165 /*+
166  *
167  * Description:
168  *      Get RateIdx from the value in SuppRates IE or ExtSuppRates IE
169  *
170  * Parameters:
171  *  In:
172  *      BYTE    - Rate value in SuppRates IE or ExtSuppRates IE
173  *  Out:
174  *      none
175  *
176  * Return Value: RateIdx
177  *
178 -*/
179 WORD
180 wGetRateIdx(
181     IN BYTE byRate
182     )
183 {
184     WORD    ii;
185
186     //Erase basicRate flag.
187     byRate = byRate & 0x7F;//0111 1111
188
189     for (ii = 0; ii < MAX_RATE; ii ++) {
190         if (acbyIERate[ii] == byRate)
191             return ii;
192     }
193     return 0;
194 }
195
196 /*+
197  *
198  * Description:
199  *      Parsing the highest basic & support rate in rate field of frame.
200  *
201  * Parameters:
202  *  In:
203  *      pDevice         - Pointer to the adapter
204  *      pItemRates      - Pointer to Rate field defined in 802.11 spec.
205  *      pItemExtRates      - Pointer to Extended Rate field defined in 802.11 spec.
206  *  Out:
207  *      pwMaxBasicRate  - Maximum Basic Rate
208  *      pwMaxSuppRate   - Maximum Supported Rate
209  *      pbyTopCCKRate   - Maximum Basic Rate in CCK mode
210  *      pbyTopOFDMRate  - Maximum Basic Rate in OFDM mode
211  *
212  * Return Value: none
213  *
214 -*/
215 VOID
216 RATEvParseMaxRate (
217     IN PVOID pDeviceHandler,
218     IN PWLAN_IE_SUPP_RATES pItemRates,
219     IN PWLAN_IE_SUPP_RATES pItemExtRates,
220     IN BOOL bUpdateBasicRate,
221     OUT PWORD pwMaxBasicRate,
222     OUT PWORD pwMaxSuppRate,
223     OUT PWORD pwSuppRate,
224     OUT PBYTE pbyTopCCKRate,
225     OUT PBYTE pbyTopOFDMRate
226     )
227 {
228 PSDevice  pDevice = (PSDevice) pDeviceHandler;
229 UINT  ii;
230 BYTE  byHighSuppRate = 0;
231 BYTE  byRate = 0;
232 WORD  wOldBasicRate = pDevice->wBasicRate;
233 UINT  uRateLen;
234
235
236     if (pItemRates == NULL)
237         return;
238
239     *pwSuppRate = 0;
240     uRateLen = pItemRates->len;
241
242     DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate Len: %d\n", uRateLen);
243     if (pDevice->eCurrentPHYType != PHY_TYPE_11B) {
244         if (uRateLen > WLAN_RATES_MAXLEN)
245             uRateLen = WLAN_RATES_MAXLEN;
246     } else {
247         if (uRateLen > WLAN_RATES_MAXLEN_11B)
248             uRateLen = WLAN_RATES_MAXLEN_11B;
249     }
250
251     for (ii = 0; ii < uRateLen; ii++) {
252         byRate = (BYTE)(pItemRates->abyRates[ii]);
253         if (WLAN_MGMT_IS_BASICRATE(byRate) &&
254             (bUpdateBasicRate == TRUE))  {
255             // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate
256             CARDbAddBasicRate((PVOID)pDevice, wGetRateIdx(byRate));
257             DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate));
258         }
259         byRate = (BYTE)(pItemRates->abyRates[ii]&0x7F);
260         if (byHighSuppRate == 0)
261             byHighSuppRate = byRate;
262         if (byRate > byHighSuppRate)
263             byHighSuppRate = byRate;
264         *pwSuppRate |= (1<<wGetRateIdx(byRate));
265     }
266     if ((pItemExtRates != NULL) && (pItemExtRates->byElementID == WLAN_EID_EXTSUPP_RATES) &&
267         (pDevice->eCurrentPHYType != PHY_TYPE_11B)) {
268
269         UINT  uExtRateLen = pItemExtRates->len;
270
271         if (uExtRateLen > WLAN_RATES_MAXLEN)
272             uExtRateLen = WLAN_RATES_MAXLEN;
273
274         for (ii = 0; ii < uExtRateLen ; ii++) {
275             byRate = (BYTE)(pItemExtRates->abyRates[ii]);
276             // select highest basic rate
277             if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) {
278                 // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate
279                 CARDbAddBasicRate((PVOID)pDevice, wGetRateIdx(byRate));
280                 DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate));
281             }
282             byRate = (BYTE)(pItemExtRates->abyRates[ii]&0x7F);
283             if (byHighSuppRate == 0)
284                 byHighSuppRate = byRate;
285             if (byRate > byHighSuppRate)
286                 byHighSuppRate = byRate;
287             *pwSuppRate |= (1<<wGetRateIdx(byRate));
288             //DBG_PRN_GRP09(("ParseMaxRate : HighSuppRate: %d, %X\n", wGetRateIdx(byRate), byRate));
289         }
290     } //if(pItemExtRates != NULL)
291
292     if ((pDevice->byPacketType == PK_TYPE_11GB) && CARDbIsOFDMinBasicRate((PVOID)pDevice)) {
293         pDevice->byPacketType = PK_TYPE_11GA;
294     }
295
296     *pbyTopCCKRate = pDevice->byTopCCKBasicRate;
297     *pbyTopOFDMRate = pDevice->byTopOFDMBasicRate;
298     *pwMaxSuppRate = wGetRateIdx(byHighSuppRate);
299     if ((pDevice->byPacketType==PK_TYPE_11B) || (pDevice->byPacketType==PK_TYPE_11GB))
300        *pwMaxBasicRate = pDevice->byTopCCKBasicRate;
301     else
302        *pwMaxBasicRate = pDevice->byTopOFDMBasicRate;
303     if (wOldBasicRate != pDevice->wBasicRate)
304         CARDvSetRSPINF((PVOID)pDevice, pDevice->eCurrentPHYType);
305
306      DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Exit ParseMaxRate\n");
307 }
308
309
310 /*+
311  *
312  * Routine Description:
313  *      Rate fallback Algorithm Implementaion
314  *
315  * Parameters:
316  *  In:
317  *      pDevice         - Pointer to the adapter
318  *      psNodeDBTable   - Pointer to Node Data Base
319  *  Out:
320  *      none
321  *
322  * Return Value: none
323  *
324 -*/
325 #define AUTORATE_TXCNT_THRESHOLD        20
326 #define AUTORATE_INC_THRESHOLD          30
327
328 VOID
329 RATEvTxRateFallBack (
330     IN PVOID pDeviceHandler,
331     IN PKnownNodeDB psNodeDBTable
332     )
333 {
334 PSDevice        pDevice = (PSDevice) pDeviceHandler;
335 WORD            wIdxDownRate = 0;
336 UINT            ii;
337 //DWORD           dwRateTable[MAX_RATE]  = {1,   2,   5,   11,  6,    9,    12,   18,  24,  36,  48,  54};
338 BOOL            bAutoRate[MAX_RATE]    = {TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE};
339 DWORD           dwThroughputTbl[MAX_RATE] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540};
340 DWORD           dwThroughput = 0;
341 WORD            wIdxUpRate = 0;
342 DWORD           dwTxDiff = 0;
343
344     if (pDevice->pMgmt->eScanState != WMAC_NO_SCANNING) {
345         // Don't do Fallback when scanning Channel
346         return;
347     }
348
349     psNodeDBTable->uTimeCount ++;
350
351     if (psNodeDBTable->uTxFail[MAX_RATE] > psNodeDBTable->uTxOk[MAX_RATE])
352         dwTxDiff = psNodeDBTable->uTxFail[MAX_RATE] - psNodeDBTable->uTxOk[MAX_RATE];
353
354     if ((psNodeDBTable->uTxOk[MAX_RATE] < AUTORATE_TXOK_CNT) &&
355         (dwTxDiff < AUTORATE_TXFAIL_CNT) &&
356         (psNodeDBTable->uTimeCount < AUTORATE_TIMEOUT)) {
357         return;
358     }
359
360     if (psNodeDBTable->uTimeCount >= AUTORATE_TIMEOUT) {
361         psNodeDBTable->uTimeCount = 0;
362     }
363
364
365     for(ii=0;ii<MAX_RATE;ii++) {
366         if (psNodeDBTable->wSuppRate & (0x0001<<ii)) {
367             if (bAutoRate[ii] == TRUE) {
368                 wIdxUpRate = (WORD) ii;
369             }
370         } else {
371             bAutoRate[ii] = FALSE;
372         }
373     }
374
375     for(ii=0;ii<=psNodeDBTable->wTxDataRate;ii++) {
376         if ( (psNodeDBTable->uTxOk[ii] != 0) ||
377              (psNodeDBTable->uTxFail[ii] != 0) ) {
378             dwThroughputTbl[ii] *= psNodeDBTable->uTxOk[ii];
379             if (ii < RATE_11M) {
380                 psNodeDBTable->uTxFail[ii] *= 4;
381             }
382             dwThroughputTbl[ii] /= (psNodeDBTable->uTxOk[ii] + psNodeDBTable->uTxFail[ii]);
383         }
384 //        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate %d,Ok: %d, Fail:%d, Throughput:%d\n",
385 //                       ii, psNodeDBTable->uTxOk[ii], psNodeDBTable->uTxFail[ii], dwThroughputTbl[ii]);
386     }
387     dwThroughput = dwThroughputTbl[psNodeDBTable->wTxDataRate];
388
389     wIdxDownRate = psNodeDBTable->wTxDataRate;
390     for(ii = psNodeDBTable->wTxDataRate; ii > 0;) {
391         ii--;
392         if ( (dwThroughputTbl[ii] > dwThroughput) &&
393              (bAutoRate[ii]==TRUE) ) {
394             dwThroughput = dwThroughputTbl[ii];
395             wIdxDownRate = (WORD) ii;
396         }
397     }
398     psNodeDBTable->wTxDataRate = wIdxDownRate;
399     if (psNodeDBTable->uTxOk[MAX_RATE]) {
400         if (psNodeDBTable->uTxOk[MAX_RATE] >
401            (psNodeDBTable->uTxFail[MAX_RATE] * 4) ) {
402             psNodeDBTable->wTxDataRate = wIdxUpRate;
403         }
404     }else { // adhoc, if uTxOk =0 & uTxFail = 0
405         if (psNodeDBTable->uTxFail[MAX_RATE] == 0)
406             psNodeDBTable->wTxDataRate = wIdxUpRate;
407     }
408 //2008-5-8 <add> by chester
409 TxRate_iwconfig=psNodeDBTable->wTxDataRate;
410     s_vResetCounter(psNodeDBTable);
411 //    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate: %d, U:%d, D:%d\n", psNodeDBTable->wTxDataRate, wIdxUpRate, wIdxDownRate);
412
413     return;
414
415 }
416
417 /*+
418  *
419  * Description:
420  *    This routine is used to assemble available Rate IE.
421  *
422  * Parameters:
423  *  In:
424  *    pDevice
425  *  Out:
426  *
427  * Return Value: None
428  *
429 -*/
430 BYTE
431 RATEuSetIE (
432     IN PWLAN_IE_SUPP_RATES pSrcRates,
433     IN PWLAN_IE_SUPP_RATES pDstRates,
434     IN UINT                uRateLen
435     )
436 {
437     UINT ii, uu, uRateCnt = 0;
438
439     if ((pSrcRates == NULL) || (pDstRates == NULL))
440         return 0;
441
442     if (pSrcRates->len == 0)
443         return 0;
444
445     for (ii = 0; ii < uRateLen; ii++) {
446         for (uu = 0; uu < pSrcRates->len; uu++) {
447             if ((pSrcRates->abyRates[uu] & 0x7F) == acbyIERate[ii]) {
448                 pDstRates->abyRates[uRateCnt ++] = pSrcRates->abyRates[uu];
449                 break;
450             }
451         }
452     }
453     return (BYTE)uRateCnt;
454 }
455