linux/drivers/staging/rtl8192e/rtl819x_HTProc.c
<<
>>
Prefs
   1/******************************************************************************
   2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
   3 *
   4 * This program is distributed in the hope that it will be useful, but WITHOUT
   5 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   6 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   7 * more details.
   8 *
   9 * The full GNU General Public License is included in this distribution in the
  10 * file called LICENSE.
  11 *
  12 * Contact Information:
  13 * wlanfae <wlanfae@realtek.com>
  14 ******************************************************************************/
  15#include "rtllib.h"
  16#include "rtl819x_HT.h"
  17u8 MCS_FILTER_ALL[16] = {
  18        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  19        0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  20};
  21
  22u8 MCS_FILTER_1SS[16] = {
  23        0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
  24        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
  25;
  26
  27u16 MCS_DATA_RATE[2][2][77] = {
  28        {{13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234,
  29         260, 39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416,
  30         468, 520, 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182,
  31         182, 208, 156, 195, 195, 234, 273, 273, 312, 130, 156, 181, 156,
  32         181, 208, 234, 208, 234, 260, 260, 286, 195, 234, 273, 234, 273,
  33         312, 351, 312, 351, 390, 390, 429},
  34        {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289,
  35         43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520,
  36         578, 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231,
  37         173, 217, 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260,
  38         231, 260, 289, 289, 318, 217, 260, 303, 260, 303, 347, 390, 347, 390,
  39         433, 433, 477} },
  40        {{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486,
  41         540, 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648,
  42         864, 972, 1080, 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324,
  43         378, 378, 432, 324, 405, 405, 486, 567, 567, 648, 270, 324, 378, 324,
  44         378, 432, 486, 432, 486, 540, 540, 594, 405, 486, 567, 486, 567, 648,
  45         729, 648, 729, 810, 810, 891},
  46        {30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
  47         600, 90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720,
  48         960, 1080, 1200, 13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360,
  49         420, 420, 480, 360, 450, 450, 540, 630, 630, 720, 300, 360, 420, 360,
  50         420, 480, 540, 480, 540, 600, 600, 660, 450, 540, 630, 540, 630, 720,
  51         810, 720, 810, 900, 900, 990} }
  52};
  53
  54static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
  55
  56static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
  57
  58static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
  59
  60static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f};
  61
  62static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
  63
  64static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
  65
  66static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e};
  67
  68static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
  69
  70static u8 DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0};
  71
  72static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91};
  73
  74static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
  75
  76static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
  77
  78void HTUpdateDefaultSetting(struct rtllib_device *ieee)
  79{
  80        struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
  81
  82        pHTInfo->bAcceptAddbaReq = 1;
  83
  84        pHTInfo->bRegShortGI20MHz = 1;
  85        pHTInfo->bRegShortGI40MHz = 1;
  86
  87        pHTInfo->bRegBW40MHz = 1;
  88
  89        if (pHTInfo->bRegBW40MHz)
  90                pHTInfo->bRegSuppCCK = 1;
  91        else
  92                pHTInfo->bRegSuppCCK = true;
  93
  94        pHTInfo->nAMSDU_MaxSize = 7935UL;
  95        pHTInfo->bAMSDU_Support = 0;
  96
  97        pHTInfo->bAMPDUEnable = 1;
  98        pHTInfo->AMPDU_Factor = 2;
  99        pHTInfo->MPDU_Density = 0;
 100
 101        pHTInfo->SelfMimoPs = 3;
 102        if (pHTInfo->SelfMimoPs == 2)
 103                pHTInfo->SelfMimoPs = 3;
 104        ieee->bTxDisableRateFallBack = 0;
 105        ieee->bTxUseDriverAssingedRate = 0;
 106
 107        ieee->bTxEnableFwCalcDur = 1;
 108
 109        pHTInfo->bRegRT2RTAggregation = 1;
 110
 111        pHTInfo->bRegRxReorderEnable = 1;
 112        pHTInfo->RxReorderWinSize = 64;
 113        pHTInfo->RxReorderPendingTime = 30;
 114}
 115
 116static u16 HTMcsToDataRate(struct rtllib_device *ieee, u8 nMcsRate)
 117{
 118        struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
 119
 120        u8      is40MHz = (pHTInfo->bCurBW40MHz) ? 1 : 0;
 121        u8      isShortGI = (pHTInfo->bCurBW40MHz) ?
 122                            ((pHTInfo->bCurShortGI40MHz) ? 1 : 0) :
 123                            ((pHTInfo->bCurShortGI20MHz) ? 1 : 0);
 124        return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate & 0x7f)];
 125}
 126
 127u16  TxCountToDataRate(struct rtllib_device *ieee, u8 nDataRate)
 128{
 129        u16     CCKOFDMRate[12] = {0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18,
 130                                   0x24, 0x30, 0x48, 0x60, 0x6c};
 131        u8      is40MHz = 0;
 132        u8      isShortGI = 0;
 133
 134        if (nDataRate < 12)
 135                return CCKOFDMRate[nDataRate];
 136        if (nDataRate >= 0x10 && nDataRate <= 0x1f) {
 137                is40MHz = 0;
 138                isShortGI = 0;
 139        } else if (nDataRate >= 0x20  && nDataRate <= 0x2f) {
 140                is40MHz = 1;
 141                isShortGI = 0;
 142        } else if (nDataRate >= 0x30  && nDataRate <= 0x3f) {
 143                is40MHz = 0;
 144                isShortGI = 1;
 145        } else if (nDataRate >= 0x40  && nDataRate <= 0x4f) {
 146                is40MHz = 1;
 147                isShortGI = 1;
 148        }
 149        return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate&0xf];
 150}
 151
 152bool IsHTHalfNmodeAPs(struct rtllib_device *ieee)
 153{
 154        bool                    retValue = false;
 155        struct rtllib_network *net = &ieee->current_network;
 156
 157        if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) ||
 158            (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) ||
 159            (memcmp(net->bssid, PCI_RALINK, 3) == 0) ||
 160            (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) ||
 161            (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) ||
 162            (net->ralink_cap_exist))
 163                retValue = true;
 164        else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) ||
 165                !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) ||
 166                !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) ||
 167                (net->broadcom_cap_exist))
 168                retValue = true;
 169        else if (net->bssht.bdRT2RTAggregation)
 170                retValue = true;
 171        else
 172                retValue = false;
 173
 174        return retValue;
 175}
 176
 177static void HTIOTPeerDetermine(struct rtllib_device *ieee)
 178{
 179        struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
 180        struct rtllib_network *net = &ieee->current_network;
 181
 182        if (net->bssht.bdRT2RTAggregation) {
 183                pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK;
 184                if (net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_92SE)
 185                        pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK_92SE;
 186                if (net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_SOFTAP)
 187                        pHTInfo->IOTPeer = HT_IOT_PEER_92U_SOFTAP;
 188        } else if (net->broadcom_cap_exist)
 189                pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
 190        else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) ||
 191                 !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) ||
 192                 !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3))
 193                pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
 194        else if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) ||
 195                 (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) ||
 196                 (memcmp(net->bssid, PCI_RALINK, 3) == 0) ||
 197                 (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) ||
 198                 (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) ||
 199                  net->ralink_cap_exist)
 200                pHTInfo->IOTPeer = HT_IOT_PEER_RALINK;
 201        else if ((net->atheros_cap_exist) ||
 202                (memcmp(net->bssid, DLINK_ATHEROS_1, 3) == 0) ||
 203                (memcmp(net->bssid, DLINK_ATHEROS_2, 3) == 0))
 204                pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS;
 205        else if ((memcmp(net->bssid, CISCO_BROADCOM, 3) == 0) ||
 206                  net->cisco_cap_exist)
 207                pHTInfo->IOTPeer = HT_IOT_PEER_CISCO;
 208        else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) ||
 209                  net->marvell_cap_exist)
 210                pHTInfo->IOTPeer = HT_IOT_PEER_MARVELL;
 211        else if (net->airgo_cap_exist)
 212                pHTInfo->IOTPeer = HT_IOT_PEER_AIRGO;
 213        else
 214                pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
 215
 216        netdev_dbg(ieee->dev, "IOTPEER: %x\n", pHTInfo->IOTPeer);
 217}
 218
 219static u8 HTIOTActIsDisableMCS14(struct rtllib_device *ieee, u8 *PeerMacAddr)
 220{
 221        return 0;
 222}
 223
 224
 225static bool HTIOTActIsDisableMCS15(struct rtllib_device *ieee)
 226{
 227        return false;
 228}
 229
 230static bool HTIOTActIsDisableMCSTwoSpatialStream(struct rtllib_device *ieee)
 231{
 232        return false;
 233}
 234
 235static u8 HTIOTActIsDisableEDCATurbo(struct rtllib_device *ieee,
 236                                     u8 *PeerMacAddr)
 237{
 238        return false;
 239}
 240
 241static u8 HTIOTActIsMgntUseCCK6M(struct rtllib_device *ieee,
 242                                 struct rtllib_network *network)
 243{
 244        u8      retValue = 0;
 245
 246
 247        if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
 248                retValue = 1;
 249
 250        return retValue;
 251}
 252
 253static u8 HTIOTActIsCCDFsync(struct rtllib_device *ieee)
 254{
 255        u8      retValue = 0;
 256
 257        if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
 258                retValue = 1;
 259        return retValue;
 260}
 261
 262static void HTIOTActDetermineRaFunc(struct rtllib_device *ieee, bool bPeerRx2ss)
 263{
 264        struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
 265
 266        pHTInfo->IOTRaFunc &= HT_IOT_RAFUNC_DISABLE_ALL;
 267
 268        if (pHTInfo->IOTPeer == HT_IOT_PEER_RALINK && !bPeerRx2ss)
 269                pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_PEER_1R;
 270
 271        if (pHTInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE)
 272                pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_TX_AMSDU;
 273
 274}
 275
 276void HTResetIOTSetting(struct rt_hi_throughput *pHTInfo)
 277{
 278        pHTInfo->IOTAction = 0;
 279        pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
 280        pHTInfo->IOTRaFunc = 0;
 281}
 282
 283void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap,
 284                                  u8 *len, u8 IsEncrypt, bool bAssoc)
 285{
 286        struct rt_hi_throughput *pHT = ieee->pHTInfo;
 287        struct ht_capab_ele *pCapELE = NULL;
 288
 289        if ((posHTCap == NULL) || (pHT == NULL)) {
 290                netdev_warn(ieee->dev,
 291                            "%s(): posHTCap and pHTInfo are null\n", __func__);
 292                return;
 293        }
 294        memset(posHTCap, 0, *len);
 295
 296        if ((bAssoc) && (pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)) {
 297                u8      EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
 298
 299                memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap));
 300                pCapELE = (struct ht_capab_ele *)&(posHTCap[4]);
 301                *len = 30 + 2;
 302        } else {
 303                pCapELE = (struct ht_capab_ele *)posHTCap;
 304                *len = 26 + 2;
 305        }
 306
 307        pCapELE->AdvCoding              = 0;
 308        if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
 309                pCapELE->ChlWidth = 0;
 310        else
 311                pCapELE->ChlWidth = (pHT->bRegBW40MHz ? 1 : 0);
 312
 313        pCapELE->MimoPwrSave            = pHT->SelfMimoPs;
 314        pCapELE->GreenField             = 0;
 315        pCapELE->ShortGI20Mhz           = 1;
 316        pCapELE->ShortGI40Mhz           = 1;
 317
 318        pCapELE->TxSTBC                 = 1;
 319        pCapELE->RxSTBC                 = 0;
 320        pCapELE->DelayBA                = 0;
 321        pCapELE->MaxAMSDUSize = (MAX_RECEIVE_BUFFER_SIZE >= 7935) ? 1 : 0;
 322        pCapELE->DssCCk = ((pHT->bRegBW40MHz) ? (pHT->bRegSuppCCK ? 1 : 0) : 0);
 323        pCapELE->PSMP = 0;
 324        pCapELE->LSigTxopProtect = 0;
 325
 326
 327        netdev_dbg(ieee->dev,
 328                   "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n",
 329                   pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk);
 330
 331        if (IsEncrypt) {
 332                pCapELE->MPDUDensity    = 7;
 333                pCapELE->MaxRxAMPDUFactor       = 2;
 334        } else {
 335                pCapELE->MaxRxAMPDUFactor       = 3;
 336                pCapELE->MPDUDensity    = 0;
 337        }
 338
 339        memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16);
 340        memset(&pCapELE->ExtHTCapInfo, 0, 2);
 341        memset(pCapELE->TxBFCap, 0, 4);
 342
 343        pCapELE->ASCap = 0;
 344
 345        if (bAssoc) {
 346                if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15)
 347                        pCapELE->MCS[1] &= 0x7f;
 348
 349                if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14)
 350                        pCapELE->MCS[1] &= 0xbf;
 351
 352                if (pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS)
 353                        pCapELE->MCS[1] &= 0x00;
 354
 355                if (pHT->IOTAction & HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI)
 356                        pCapELE->ShortGI40Mhz           = 0;
 357
 358                if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) {
 359                        pCapELE->ChlWidth = 0;
 360                        pCapELE->MCS[1] = 0;
 361                }
 362        }
 363}
 364
 365void HTConstructInfoElement(struct rtllib_device *ieee, u8 *posHTInfo,
 366                            u8 *len, u8 IsEncrypt)
 367{
 368        struct rt_hi_throughput *pHT = ieee->pHTInfo;
 369        struct ht_info_ele *pHTInfoEle = (struct ht_info_ele *)posHTInfo;
 370
 371        if ((posHTInfo == NULL) || (pHTInfoEle == NULL)) {
 372                netdev_warn(ieee->dev,
 373                            "%s(): posHTInfo and pHTInfoEle are null\n",
 374                            __func__);
 375                return;
 376        }
 377
 378        memset(posHTInfo, 0, *len);
 379        if ((ieee->iw_mode == IW_MODE_ADHOC) ||
 380            (ieee->iw_mode == IW_MODE_MASTER)) {
 381                pHTInfoEle->ControlChl  = ieee->current_network.channel;
 382                pHTInfoEle->ExtChlOffset = ((pHT->bRegBW40MHz == false) ?
 383                                            HT_EXTCHNL_OFFSET_NO_EXT :
 384                                            (ieee->current_network.channel <= 6)
 385                                            ? HT_EXTCHNL_OFFSET_UPPER :
 386                                            HT_EXTCHNL_OFFSET_LOWER);
 387                pHTInfoEle->RecommemdedTxWidth  = pHT->bRegBW40MHz;
 388                pHTInfoEle->RIFS                        = 0;
 389                pHTInfoEle->PSMPAccessOnly              = 0;
 390                pHTInfoEle->SrvIntGranularity           = 0;
 391                pHTInfoEle->OptMode                     = pHT->CurrentOpMode;
 392                pHTInfoEle->NonGFDevPresent             = 0;
 393                pHTInfoEle->DualBeacon                  = 0;
 394                pHTInfoEle->SecondaryBeacon             = 0;
 395                pHTInfoEle->LSigTxopProtectFull         = 0;
 396                pHTInfoEle->PcoActive                   = 0;
 397                pHTInfoEle->PcoPhase                    = 0;
 398
 399                memset(pHTInfoEle->BasicMSC, 0, 16);
 400
 401
 402                *len = 22 + 2;
 403
 404        } else {
 405                *len = 0;
 406        }
 407}
 408
 409void HTConstructRT2RTAggElement(struct rtllib_device *ieee, u8 *posRT2RTAgg,
 410                                u8 *len)
 411{
 412        if (posRT2RTAgg == NULL) {
 413                netdev_warn(ieee->dev, "%s(): posRT2RTAgg is null\n", __func__);
 414                return;
 415        }
 416        memset(posRT2RTAgg, 0, *len);
 417        *posRT2RTAgg++ = 0x00;
 418        *posRT2RTAgg++ = 0xe0;
 419        *posRT2RTAgg++ = 0x4c;
 420        *posRT2RTAgg++ = 0x02;
 421        *posRT2RTAgg++ = 0x01;
 422
 423        *posRT2RTAgg = 0x30;
 424
 425        if (ieee->bSupportRemoteWakeUp)
 426                *posRT2RTAgg |= RT_HT_CAP_USE_WOW;
 427
 428        *len = 6 + 2;
 429}
 430
 431static u8 HT_PickMCSRate(struct rtllib_device *ieee, u8 *pOperateMCS)
 432{
 433        u8 i;
 434
 435        if (pOperateMCS == NULL) {
 436                netdev_warn(ieee->dev, "%s(): pOperateMCS is null\n", __func__);
 437                return false;
 438        }
 439
 440        switch (ieee->mode) {
 441        case IEEE_A:
 442        case IEEE_B:
 443        case IEEE_G:
 444                for (i = 0; i <= 15; i++)
 445                        pOperateMCS[i] = 0;
 446                break;
 447        case IEEE_N_24G:
 448        case IEEE_N_5G:
 449                pOperateMCS[0] &= RATE_ADPT_1SS_MASK;
 450                pOperateMCS[1] &= RATE_ADPT_2SS_MASK;
 451                pOperateMCS[3] &= RATE_ADPT_MCS32_MASK;
 452                break;
 453        default:
 454                break;
 455
 456        }
 457
 458        return true;
 459}
 460
 461u8 HTGetHighestMCSRate(struct rtllib_device *ieee, u8 *pMCSRateSet,
 462                       u8 *pMCSFilter)
 463{
 464        u8              i, j;
 465        u8              bitMap;
 466        u8              mcsRate = 0;
 467        u8              availableMcsRate[16];
 468
 469        if (pMCSRateSet == NULL || pMCSFilter == NULL) {
 470                netdev_warn(ieee->dev,
 471                            "%s(): pMCSRateSet and pMCSFilter are null\n",
 472                            __func__);
 473                return false;
 474        }
 475        for (i = 0; i < 16; i++)
 476                availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i];
 477
 478        for (i = 0; i < 16; i++) {
 479                if (availableMcsRate[i] != 0)
 480                        break;
 481        }
 482        if (i == 16)
 483                return false;
 484
 485        for (i = 0; i < 16; i++) {
 486                if (availableMcsRate[i] != 0) {
 487                        bitMap = availableMcsRate[i];
 488                        for (j = 0; j < 8; j++) {
 489                                if ((bitMap%2) != 0) {
 490                                        if (HTMcsToDataRate(ieee, (8*i+j)) >
 491                                            HTMcsToDataRate(ieee, mcsRate))
 492                                                mcsRate = 8 * i + j;
 493                                }
 494                                bitMap >>= 1;
 495                        }
 496                }
 497        }
 498        return mcsRate | 0x80;
 499}
 500
 501static u8 HTFilterMCSRate(struct rtllib_device *ieee, u8 *pSupportMCS,
 502                          u8 *pOperateMCS)
 503{
 504
 505        u8 i;
 506
 507        for (i = 0; i <= 15; i++)
 508                pOperateMCS[i] = ieee->Regdot11TxHTOperationalRateSet[i] &
 509                                 pSupportMCS[i];
 510
 511        HT_PickMCSRate(ieee, pOperateMCS);
 512
 513        if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
 514                pOperateMCS[1] = 0;
 515
 516        for (i = 2; i <= 15; i++)
 517                pOperateMCS[i] = 0;
 518
 519        return true;
 520}
 521
 522void HTSetConnectBwMode(struct rtllib_device *ieee,
 523                        enum ht_channel_width Bandwidth,
 524                        enum ht_extchnl_offset Offset);
 525
 526void HTOnAssocRsp(struct rtllib_device *ieee)
 527{
 528        struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
 529        struct ht_capab_ele *pPeerHTCap = NULL;
 530        struct ht_info_ele *pPeerHTInfo = NULL;
 531        u16 nMaxAMSDUSize = 0;
 532        u8 *pMcsFilter = NULL;
 533
 534        static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
 535        static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34};
 536
 537        if (pHTInfo->bCurrentHTSupport == false) {
 538                netdev_warn(ieee->dev, "%s(): HT_DISABLE\n", __func__);
 539                return;
 540        }
 541        netdev_dbg(ieee->dev, "%s(): HT_ENABLE\n", __func__);
 542
 543        if (!memcmp(pHTInfo->PeerHTCapBuf, EWC11NHTCap, sizeof(EWC11NHTCap)))
 544                pPeerHTCap = (struct ht_capab_ele *)(&pHTInfo->PeerHTCapBuf[4]);
 545        else
 546                pPeerHTCap = (struct ht_capab_ele *)(pHTInfo->PeerHTCapBuf);
 547
 548        if (!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
 549                pPeerHTInfo = (struct ht_info_ele *)
 550                             (&pHTInfo->PeerHTInfoBuf[4]);
 551        else
 552                pPeerHTInfo = (struct ht_info_ele *)(pHTInfo->PeerHTInfoBuf);
 553
 554
 555#ifdef VERBOSE_DEBUG
 556        print_hex_dump_bytes("HTOnAssocRsp(): ", DUMP_PREFIX_NONE,
 557                             pPeerHTCap, sizeof(struct ht_capab_ele));
 558#endif
 559        HTSetConnectBwMode(ieee, (enum ht_channel_width)(pPeerHTCap->ChlWidth),
 560                          (enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset));
 561        pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ?
 562                                 true : false);
 563
 564        pHTInfo->bCurShortGI20MHz = ((pHTInfo->bRegShortGI20MHz) ?
 565                                    ((pPeerHTCap->ShortGI20Mhz == 1) ?
 566                                    true : false) : false);
 567        pHTInfo->bCurShortGI40MHz = ((pHTInfo->bRegShortGI40MHz) ?
 568                                     ((pPeerHTCap->ShortGI40Mhz == 1) ?
 569                                     true : false) : false);
 570
 571        pHTInfo->bCurSuppCCK = ((pHTInfo->bRegSuppCCK) ?
 572                               ((pPeerHTCap->DssCCk == 1) ? true :
 573                               false) : false);
 574
 575
 576        pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
 577
 578        nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize == 0) ? 3839 : 7935;
 579
 580        if (pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize)
 581                pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize;
 582        else
 583                pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
 584
 585        pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
 586        if (ieee->rtllib_ap_sec_type &&
 587           (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))) {
 588                if ((pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) ||
 589                                (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN))
 590                        pHTInfo->bCurrentAMPDUEnable = false;
 591        }
 592
 593        if (!pHTInfo->bRegRT2RTAggregation) {
 594                if (pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor)
 595                        pHTInfo->CurrentAMPDUFactor =
 596                                                 pPeerHTCap->MaxRxAMPDUFactor;
 597                else
 598                        pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
 599
 600        } else {
 601                if (ieee->current_network.bssht.bdRT2RTAggregation) {
 602                        if (ieee->pairwise_key_type != KEY_TYPE_NA)
 603                                pHTInfo->CurrentAMPDUFactor =
 604                                                 pPeerHTCap->MaxRxAMPDUFactor;
 605                        else
 606                                pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K;
 607                } else {
 608                        if (pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K)
 609                                pHTInfo->CurrentAMPDUFactor =
 610                                                 pPeerHTCap->MaxRxAMPDUFactor;
 611                        else
 612                                pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K;
 613                }
 614        }
 615        if (pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity)
 616                pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
 617        else
 618                pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity;
 619        if (pHTInfo->IOTAction & HT_IOT_ACT_TX_USE_AMSDU_8K) {
 620                pHTInfo->bCurrentAMPDUEnable = false;
 621                pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE;
 622                pHTInfo->ForcedAMSDUMaxSize = 7935;
 623        }
 624        pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable;
 625
 626        if (pPeerHTCap->MCS[0] == 0)
 627                pPeerHTCap->MCS[0] = 0xff;
 628
 629        HTIOTActDetermineRaFunc(ieee, ((pPeerHTCap->MCS[1]) != 0));
 630
 631        HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet);
 632
 633        pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave;
 634        if (pHTInfo->PeerMimoPs == MIMO_PS_STATIC)
 635                pMcsFilter = MCS_FILTER_1SS;
 636        else
 637                pMcsFilter = MCS_FILTER_ALL;
 638        ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee,
 639                                   ieee->dot11HTOperationalRateSet, pMcsFilter);
 640        ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
 641
 642        pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
 643}
 644
 645void HTInitializeHTInfo(struct rtllib_device *ieee)
 646{
 647        struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
 648
 649        netdev_vdbg(ieee->dev, "%s()\n", __func__);
 650        pHTInfo->bCurrentHTSupport = false;
 651
 652        pHTInfo->bCurBW40MHz = false;
 653        pHTInfo->bCurTxBW40MHz = false;
 654
 655        pHTInfo->bCurShortGI20MHz = false;
 656        pHTInfo->bCurShortGI40MHz = false;
 657        pHTInfo->bForcedShortGI = false;
 658
 659        pHTInfo->bCurSuppCCK = true;
 660
 661        pHTInfo->bCurrent_AMSDU_Support = false;
 662        pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
 663        pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
 664        pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
 665
 666        memset((void *)(&(pHTInfo->SelfHTCap)), 0,
 667                sizeof(pHTInfo->SelfHTCap));
 668        memset((void *)(&(pHTInfo->SelfHTInfo)), 0,
 669                sizeof(pHTInfo->SelfHTInfo));
 670        memset((void *)(&(pHTInfo->PeerHTCapBuf)), 0,
 671                sizeof(pHTInfo->PeerHTCapBuf));
 672        memset((void *)(&(pHTInfo->PeerHTInfoBuf)), 0,
 673                sizeof(pHTInfo->PeerHTInfoBuf));
 674
 675        pHTInfo->bSwBwInProgress = false;
 676
 677        pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE;
 678
 679        pHTInfo->bCurrentRT2RTAggregation = false;
 680        pHTInfo->bCurrentRT2RTLongSlotTime = false;
 681        pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0;
 682
 683        pHTInfo->IOTPeer = 0;
 684        pHTInfo->IOTAction = 0;
 685        pHTInfo->IOTRaFunc = 0;
 686
 687        {
 688                u8 *RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]);
 689
 690                RegHTSuppRateSets[0] = 0xFF;
 691                RegHTSuppRateSets[1] = 0xFF;
 692                RegHTSuppRateSets[4] = 0x01;
 693        }
 694}
 695
 696void HTInitializeBssDesc(struct bss_ht *pBssHT)
 697{
 698
 699        pBssHT->bdSupportHT = false;
 700        memset(pBssHT->bdHTCapBuf, 0, sizeof(pBssHT->bdHTCapBuf));
 701        pBssHT->bdHTCapLen = 0;
 702        memset(pBssHT->bdHTInfoBuf, 0, sizeof(pBssHT->bdHTInfoBuf));
 703        pBssHT->bdHTInfoLen = 0;
 704
 705        pBssHT->bdHTSpecVer = HT_SPEC_VER_IEEE;
 706
 707        pBssHT->bdRT2RTAggregation = false;
 708        pBssHT->bdRT2RTLongSlotTime = false;
 709        pBssHT->RT2RT_HT_Mode = (enum rt_ht_capability)0;
 710}
 711
 712void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee,
 713                                   struct rtllib_network *pNetwork)
 714{
 715        struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
 716        u8      bIOTAction = 0;
 717
 718        netdev_vdbg(ieee->dev, "%s()\n", __func__);
 719        /* unmark bEnableHT flag here is the same reason why unmarked in
 720         * function rtllib_softmac_new_net. WB 2008.09.10
 721         */
 722        if (pNetwork->bssht.bdSupportHT) {
 723                pHTInfo->bCurrentHTSupport = true;
 724                pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bdHTSpecVer;
 725
 726                if (pNetwork->bssht.bdHTCapLen > 0 &&
 727                    pNetwork->bssht.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf))
 728                        memcpy(pHTInfo->PeerHTCapBuf,
 729                               pNetwork->bssht.bdHTCapBuf,
 730                               pNetwork->bssht.bdHTCapLen);
 731
 732                if (pNetwork->bssht.bdHTInfoLen > 0 &&
 733                    pNetwork->bssht.bdHTInfoLen <=
 734                    sizeof(pHTInfo->PeerHTInfoBuf))
 735                        memcpy(pHTInfo->PeerHTInfoBuf,
 736                               pNetwork->bssht.bdHTInfoBuf,
 737                               pNetwork->bssht.bdHTInfoLen);
 738
 739                if (pHTInfo->bRegRT2RTAggregation) {
 740                        pHTInfo->bCurrentRT2RTAggregation =
 741                                 pNetwork->bssht.bdRT2RTAggregation;
 742                        pHTInfo->bCurrentRT2RTLongSlotTime =
 743                                 pNetwork->bssht.bdRT2RTLongSlotTime;
 744                        pHTInfo->RT2RT_HT_Mode = pNetwork->bssht.RT2RT_HT_Mode;
 745                } else {
 746                        pHTInfo->bCurrentRT2RTAggregation = false;
 747                        pHTInfo->bCurrentRT2RTLongSlotTime = false;
 748                        pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0;
 749                }
 750
 751                HTIOTPeerDetermine(ieee);
 752
 753                pHTInfo->IOTAction = 0;
 754                bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid);
 755                if (bIOTAction)
 756                        pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14;
 757
 758                bIOTAction = HTIOTActIsDisableMCS15(ieee);
 759                if (bIOTAction)
 760                        pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15;
 761
 762                bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee);
 763                if (bIOTAction)
 764                        pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS;
 765
 766
 767                bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid);
 768                if (bIOTAction)
 769                        pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO;
 770
 771                bIOTAction = HTIOTActIsMgntUseCCK6M(ieee, pNetwork);
 772                if (bIOTAction)
 773                        pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M;
 774                bIOTAction = HTIOTActIsCCDFsync(ieee);
 775                if (bIOTAction)
 776                        pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC;
 777        } else {
 778                pHTInfo->bCurrentHTSupport = false;
 779                pHTInfo->bCurrentRT2RTAggregation = false;
 780                pHTInfo->bCurrentRT2RTLongSlotTime = false;
 781                pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0;
 782
 783                pHTInfo->IOTAction = 0;
 784                pHTInfo->IOTRaFunc = 0;
 785        }
 786}
 787
 788void HT_update_self_and_peer_setting(struct rtllib_device *ieee,
 789                                     struct rtllib_network *pNetwork)
 790{
 791        struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
 792        struct ht_info_ele *pPeerHTInfo =
 793                 (struct ht_info_ele *)pNetwork->bssht.bdHTInfoBuf;
 794
 795        if (pHTInfo->bCurrentHTSupport) {
 796                if (pNetwork->bssht.bdHTInfoLen != 0)
 797                        pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
 798        }
 799}
 800EXPORT_SYMBOL(HT_update_self_and_peer_setting);
 801
 802void HTUseDefaultSetting(struct rtllib_device *ieee)
 803{
 804        struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
 805
 806        if (pHTInfo->bEnableHT) {
 807                pHTInfo->bCurrentHTSupport = true;
 808                pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK;
 809
 810                pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz;
 811                pHTInfo->bCurShortGI20MHz = pHTInfo->bRegShortGI20MHz;
 812
 813                pHTInfo->bCurShortGI40MHz = pHTInfo->bRegShortGI40MHz;
 814
 815                if (ieee->iw_mode == IW_MODE_ADHOC)
 816                        ieee->current_network.qos_data.active =
 817                                 ieee->current_network.qos_data.supported;
 818                pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
 819                pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
 820
 821                pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
 822                pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
 823
 824                pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity;
 825
 826                HTFilterMCSRate(ieee, ieee->Regdot11TxHTOperationalRateSet,
 827                                ieee->dot11HTOperationalRateSet);
 828                ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee,
 829                                           ieee->dot11HTOperationalRateSet,
 830                                           MCS_FILTER_ALL);
 831                ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
 832
 833        } else {
 834                pHTInfo->bCurrentHTSupport = false;
 835        }
 836}
 837
 838u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame)
 839{
 840        if (ieee->pHTInfo->bCurrentHTSupport) {
 841                if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) {
 842                        netdev_dbg(ieee->dev, "HT CONTROL FILED EXIST!!\n");
 843                        return true;
 844                }
 845        }
 846        return false;
 847}
 848
 849static void HTSetConnectBwModeCallback(struct rtllib_device *ieee)
 850{
 851        struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
 852
 853        netdev_vdbg(ieee->dev, "%s()\n", __func__);
 854
 855        if (pHTInfo->bCurBW40MHz) {
 856                if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_UPPER)
 857                        ieee->set_chan(ieee->dev,
 858                                       ieee->current_network.channel + 2);
 859                else if (pHTInfo->CurSTAExtChnlOffset ==
 860                         HT_EXTCHNL_OFFSET_LOWER)
 861                        ieee->set_chan(ieee->dev,
 862                                       ieee->current_network.channel - 2);
 863                else
 864                        ieee->set_chan(ieee->dev,
 865                                       ieee->current_network.channel);
 866
 867                ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40,
 868                                       pHTInfo->CurSTAExtChnlOffset);
 869        } else {
 870                ieee->set_chan(ieee->dev, ieee->current_network.channel);
 871                ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20,
 872                                       HT_EXTCHNL_OFFSET_NO_EXT);
 873        }
 874
 875        pHTInfo->bSwBwInProgress = false;
 876}
 877
 878void HTSetConnectBwMode(struct rtllib_device *ieee,
 879                        enum ht_channel_width Bandwidth,
 880                        enum ht_extchnl_offset Offset)
 881{
 882        struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
 883
 884        if (pHTInfo->bRegBW40MHz == false)
 885                return;
 886
 887        if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
 888                Bandwidth = HT_CHANNEL_WIDTH_20;
 889
 890        if (pHTInfo->bSwBwInProgress) {
 891                pr_info("%s: bSwBwInProgress!!\n", __func__);
 892                return;
 893        }
 894        if (Bandwidth == HT_CHANNEL_WIDTH_20_40) {
 895                if (ieee->current_network.channel < 2 &&
 896                    Offset == HT_EXTCHNL_OFFSET_LOWER)
 897                        Offset = HT_EXTCHNL_OFFSET_NO_EXT;
 898                if (Offset == HT_EXTCHNL_OFFSET_UPPER ||
 899                    Offset == HT_EXTCHNL_OFFSET_LOWER) {
 900                        pHTInfo->bCurBW40MHz = true;
 901                        pHTInfo->CurSTAExtChnlOffset = Offset;
 902                } else {
 903                        pHTInfo->bCurBW40MHz = false;
 904                        pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
 905                }
 906        } else {
 907                pHTInfo->bCurBW40MHz = false;
 908                pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
 909        }
 910
 911        netdev_dbg(ieee->dev, "%s():pHTInfo->bCurBW40MHz:%x\n", __func__,
 912                   pHTInfo->bCurBW40MHz);
 913
 914        pHTInfo->bSwBwInProgress = true;
 915
 916        HTSetConnectBwModeCallback(ieee);
 917}
 918