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