]> Git Repo - linux.git/blob - drivers/staging/vt6656/datarate.c
selinux: Remove security_ops extern
[linux.git] / drivers / staging / vt6656 / 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 #include "tmacro.h"
37 #include "mac.h"
38 #include "80211mgr.h"
39 #include "bssdb.h"
40 #include "datarate.h"
41 #include "card.h"
42 #include "baseband.h"
43 #include "rf.h"
44
45 /* static int msglevel = MSG_LEVEL_DEBUG; */
46 static int msglevel = MSG_LEVEL_INFO;
47 static const u8 acbyIERate[MAX_RATE] = {0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18,
48         0x24, 0x30, 0x48, 0x60, 0x6C};
49
50 #define AUTORATE_TXOK_CNT       0x0400
51 #define AUTORATE_TXFAIL_CNT     0x0064
52 #define AUTORATE_TIMEOUT        10
53
54 void s_vResetCounter(PKnownNodeDB psNodeDBTable);
55
56 void s_vResetCounter(PKnownNodeDB psNodeDBTable)
57 {
58         u8 ii;
59
60         /* clear statistics counter for auto_rate */
61         for (ii = 0; ii <= MAX_RATE; ii++) {
62                 psNodeDBTable->uTxOk[ii] = 0;
63                 psNodeDBTable->uTxFail[ii] = 0;
64         }
65 }
66
67 /*+
68  *
69  * Routine Description:
70  *      Rate fallback Algorithm Implementaion
71  *
72  * Parameters:
73  *  In:
74  *      pDevice         - Pointer to the adapter
75  *      psNodeDBTable   - Pointer to Node Data Base
76  *  Out:
77  *      none
78  *
79  * Return Value: none
80  *
81 -*/
82 #define AUTORATE_TXCNT_THRESHOLD        20
83 #define AUTORATE_INC_THRESHOLD          30
84
85 /*+
86  *
87  * Description:
88  *      Get RateIdx from the value in SuppRates IE or ExtSuppRates IE
89  *
90  * Parameters:
91  *  In:
92  *      u8    - Rate value in SuppRates IE or ExtSuppRates IE
93  *  Out:
94  *      none
95  *
96  * Return Value: RateIdx
97  *
98 -*/
99 u16 RATEwGetRateIdx(u8 byRate)
100 {
101         u16 ii;
102
103         /* erase BasicRate flag */
104         byRate = byRate & 0x7F;
105
106         for (ii = 0; ii < MAX_RATE; ii++) {
107                 if (acbyIERate[ii] == byRate)
108                         return ii;
109         }
110         return 0;
111 }
112
113 /*+
114  *
115  * Description:
116  *      Parsing the highest basic & support rate in rate field of frame.
117  *
118  * Parameters:
119  *  In:
120  *      pDevice         - Pointer to the adapter
121  *      pItemRates      - Pointer to Rate field defined in 802.11 spec.
122  *      pItemExtRates      - Pointer to Extended Rate field defined in 802.11 spec.
123  *  Out:
124  *      pwMaxBasicRate  - Maximum Basic Rate
125  *      pwMaxSuppRate   - Maximum Supported Rate
126  *      pbyTopCCKRate   - Maximum Basic Rate in CCK mode
127  *      pbyTopOFDMRate  - Maximum Basic Rate in OFDM mode
128  *
129  * Return Value: none
130  *
131 -*/
132
133 void RATEvParseMaxRate(struct vnt_private *pDevice,
134         PWLAN_IE_SUPP_RATES pItemRates, PWLAN_IE_SUPP_RATES pItemExtRates,
135         int bUpdateBasicRate, u16 *pwMaxBasicRate, u16 *pwMaxSuppRate,
136         u16 *pwSuppRate, u8 *pbyTopCCKRate, u8 *pbyTopOFDMRate)
137 {
138         int ii;
139         u8 byHighSuppRate = 0, byRate = 0;
140         u16 wOldBasicRate = pDevice->wBasicRate;
141         u32 uRateLen;
142
143         if (pItemRates == NULL)
144                 return;
145
146         *pwSuppRate = 0;
147         uRateLen = pItemRates->len;
148
149         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate Len: %d\n", uRateLen);
150         if (pDevice->byBBType != BB_TYPE_11B) {
151                 if (uRateLen > WLAN_RATES_MAXLEN)
152                         uRateLen = WLAN_RATES_MAXLEN;
153         } else {
154                 if (uRateLen > WLAN_RATES_MAXLEN_11B)
155                         uRateLen = WLAN_RATES_MAXLEN_11B;
156         }
157
158         for (ii = 0; ii < uRateLen; ii++) {
159                 byRate = (u8)(pItemRates->abyRates[ii]);
160                 if (WLAN_MGMT_IS_BASICRATE(byRate) &&
161                                 (bUpdateBasicRate == true)) {
162                         /*
163                          * add to basic rate set, update pDevice->byTopCCKBasicRate and
164                          * pDevice->byTopOFDMBasicRate
165                          */
166                         CARDbAddBasicRate((void *)pDevice, RATEwGetRateIdx(byRate));
167                         DBG_PRT(MSG_LEVEL_DEBUG,
168                                 KERN_INFO"ParseMaxRate AddBasicRate: %d\n",
169                                 RATEwGetRateIdx(byRate));
170                 }
171                 byRate = (u8)(pItemRates->abyRates[ii]&0x7F);
172                 if (byHighSuppRate == 0)
173                         byHighSuppRate = byRate;
174                 if (byRate > byHighSuppRate)
175                         byHighSuppRate = byRate;
176                 *pwSuppRate |= (1<<RATEwGetRateIdx(byRate));
177         }
178         if ((pItemExtRates != NULL) && (pItemExtRates->byElementID == WLAN_EID_EXTSUPP_RATES) &&
179                         (pDevice->byBBType != BB_TYPE_11B)) {
180
181                 unsigned int uExtRateLen = pItemExtRates->len;
182
183                 if (uExtRateLen > WLAN_RATES_MAXLEN)
184                         uExtRateLen = WLAN_RATES_MAXLEN;
185
186                 for (ii = 0; ii < uExtRateLen; ii++) {
187                         byRate = (u8)(pItemExtRates->abyRates[ii]);
188                         /* select highest basic rate */
189                         if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) {
190                                 /*
191                                  * add to basic rate set, update pDevice->byTopCCKBasicRate and
192                                  * pDevice->byTopOFDMBasicRate
193                                  */
194                                 CARDbAddBasicRate((void *)pDevice, RATEwGetRateIdx(byRate));
195                                 DBG_PRT(MSG_LEVEL_DEBUG,
196                                                 KERN_INFO"ParseMaxRate AddBasicRate: %d\n",
197                                                 RATEwGetRateIdx(byRate));
198                         }
199                         byRate = (u8)(pItemExtRates->abyRates[ii]&0x7F);
200                         if (byHighSuppRate == 0)
201                                 byHighSuppRate = byRate;
202                         if (byRate > byHighSuppRate)
203                                 byHighSuppRate = byRate;
204                         *pwSuppRate |= (1<<RATEwGetRateIdx(byRate));
205
206                         /* DBG_PRN_GRP09(("ParseMaxRate : HighSuppRate: %d, %X\n",
207                          * RATEwGetRateIdx(byRate), byRate));
208                          */
209                 }
210         }
211
212         if ((pDevice->byPacketType == PK_TYPE_11GB)
213                         && CARDbIsOFDMinBasicRate((void *)pDevice)) {
214                 pDevice->byPacketType = PK_TYPE_11GA;
215         }
216
217         *pbyTopCCKRate = pDevice->byTopCCKBasicRate;
218         *pbyTopOFDMRate = pDevice->byTopOFDMBasicRate;
219         *pwMaxSuppRate = RATEwGetRateIdx(byHighSuppRate);
220         if ((pDevice->byPacketType == PK_TYPE_11B) || (pDevice->byPacketType == PK_TYPE_11GB))
221                 *pwMaxBasicRate = pDevice->byTopCCKBasicRate;
222         else
223                 *pwMaxBasicRate = pDevice->byTopOFDMBasicRate;
224         if (wOldBasicRate != pDevice->wBasicRate)
225                 CARDvSetRSPINF((void *)pDevice, pDevice->byBBType);
226
227         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Exit ParseMaxRate\n");
228 }
229
230 /*+
231  *
232  * Routine Description:
233  *      Rate fallback Algorithm Implementaion
234  *
235  * Parameters:
236  *  In:
237  *      pDevice         - Pointer to the adapter
238  *      psNodeDBTable   - Pointer to Node Data Base
239  *  Out:
240  *      none
241  *
242  * Return Value: none
243  *
244 -*/
245 #define AUTORATE_TXCNT_THRESHOLD        20
246 #define AUTORATE_INC_THRESHOLD          30
247
248 void RATEvTxRateFallBack(struct vnt_private *pDevice,
249         PKnownNodeDB psNodeDBTable)
250 {
251         struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
252         u16 wIdxDownRate = 0;
253         int ii;
254         int bAutoRate[MAX_RATE] = {true, true, true, true, false, false, true,
255                                          true, true, true, true, true};
256         u32 dwThroughputTbl[MAX_RATE] = {10, 20, 55, 110, 60, 90, 120, 180,
257                 240, 360, 480, 540};
258         u32 dwThroughput = 0;
259         u16 wIdxUpRate = 0;
260         u32 dwTxDiff = 0;
261
262         if (pMgmt->eScanState != WMAC_NO_SCANNING)
263                 return; /* Don't do Fallback when scanning Channel */
264
265         psNodeDBTable->uTimeCount++;
266
267         if (psNodeDBTable->uTxFail[MAX_RATE] > psNodeDBTable->uTxOk[MAX_RATE])
268                 dwTxDiff = psNodeDBTable->uTxFail[MAX_RATE] - psNodeDBTable->uTxOk[MAX_RATE];
269
270         if ((psNodeDBTable->uTxOk[MAX_RATE] < AUTORATE_TXOK_CNT) &&
271                         (dwTxDiff < AUTORATE_TXFAIL_CNT) &&
272                         (psNodeDBTable->uTimeCount < AUTORATE_TIMEOUT)) {
273                 return;
274         }
275
276         if (psNodeDBTable->uTimeCount >= AUTORATE_TIMEOUT)
277                 psNodeDBTable->uTimeCount = 0;
278
279         for (ii = 0; ii < MAX_RATE; ii++) {
280                 if (psNodeDBTable->wSuppRate & (0x0001<<ii)) {
281                         if (bAutoRate[ii] == true)
282                                 wIdxUpRate = (u16) ii;
283                 } else {
284                         bAutoRate[ii] = false;
285                 }
286         }
287
288         for (ii = 0; ii <= psNodeDBTable->wTxDataRate; ii++) {
289                 if ((psNodeDBTable->uTxOk[ii] != 0) ||
290                                 (psNodeDBTable->uTxFail[ii] != 0)) {
291                         dwThroughputTbl[ii] *= psNodeDBTable->uTxOk[ii];
292                         if (ii < RATE_11M)
293                                 psNodeDBTable->uTxFail[ii] *= 4;
294                         dwThroughputTbl[ii] /= (psNodeDBTable->uTxOk[ii] + psNodeDBTable->uTxFail[ii]);
295                 }
296                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate %d,Ok: %d, Fail:%d, Throughput:%d\n",
297                                 ii, (int)psNodeDBTable->uTxOk[ii], (int)psNodeDBTable->uTxFail[ii], (int)dwThroughputTbl[ii]);
298         }
299         dwThroughput = dwThroughputTbl[psNodeDBTable->wTxDataRate];
300
301         wIdxDownRate = psNodeDBTable->wTxDataRate;
302         for (ii = psNodeDBTable->wTxDataRate; ii > 0;) {
303                 ii--;
304                 if ((dwThroughputTbl[ii] > dwThroughput) &&
305                                 (bAutoRate[ii] == true)) {
306                         dwThroughput = dwThroughputTbl[ii];
307                         wIdxDownRate = (u16) ii;
308                 }
309         }
310         psNodeDBTable->wTxDataRate = wIdxDownRate;
311         if (psNodeDBTable->uTxOk[MAX_RATE]) {
312                 if (psNodeDBTable->uTxOk[MAX_RATE] >
313                                 (psNodeDBTable->uTxFail[MAX_RATE] * 4)) {
314                         psNodeDBTable->wTxDataRate = wIdxUpRate;
315                 }
316         } else { /* adhoc, if uTxOk(total) == 0 & uTxFail(total) == 0 */
317                 if (psNodeDBTable->uTxFail[MAX_RATE] == 0)
318                         psNodeDBTable->wTxDataRate = wIdxUpRate;
319         }
320
321         if (pDevice->byBBType == BB_TYPE_11A) {
322                 if (psNodeDBTable->wTxDataRate <= RATE_11M)
323                         psNodeDBTable->wTxDataRate = RATE_6M;
324         }
325         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uTxOk[MAX_RATE] %d, uTxFail[MAX_RATE]:%d\n", (int)psNodeDBTable->uTxOk[MAX_RATE], (int)psNodeDBTable->uTxFail[MAX_RATE]);
326         s_vResetCounter(psNodeDBTable);
327         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate: %d, U:%d, D:%d\n", (int)psNodeDBTable->wTxDataRate, (int)wIdxUpRate, (int)wIdxDownRate);
328         return;
329 }
330
331 /*+
332  *
333  * Description:
334  *    This routine is used to assemble available Rate IE.
335  *
336  * Parameters:
337  *  In:
338  *    pDevice
339  *  Out:
340  *
341  * Return Value: None
342  *
343 -*/
344 u8 RATEuSetIE(PWLAN_IE_SUPP_RATES pSrcRates, PWLAN_IE_SUPP_RATES pDstRates,
345                 unsigned int uRateLen)
346 {
347         unsigned int ii, uu, uRateCnt = 0;
348
349         if ((pSrcRates == NULL) || (pDstRates == NULL))
350                 return 0;
351
352         if (pSrcRates->len == 0)
353                 return 0;
354
355         for (ii = 0; ii < uRateLen; ii++) {
356                 for (uu = 0; uu < pSrcRates->len; uu++) {
357                         if ((pSrcRates->abyRates[uu] & 0x7F) == acbyIERate[ii]) {
358                                 pDstRates->abyRates[uRateCnt++] = pSrcRates->abyRates[uu];
359                                 break;
360                         }
361                 }
362         }
363         return (u8)uRateCnt;
364 }
This page took 0.056515 seconds and 4 git commands to generate.