Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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