root/drivers/staging/rtl8192e/rtl819x_HTProc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. HTUpdateDefaultSetting
  2. HTMcsToDataRate
  3. TxCountToDataRate
  4. IsHTHalfNmodeAPs
  5. HTIOTPeerDetermine
  6. HTIOTActIsDisableMCS14
  7. HTIOTActIsDisableMCS15
  8. HTIOTActIsDisableMCSTwoSpatialStream
  9. HTIOTActIsDisableEDCATurbo
  10. HTIOTActIsMgntUseCCK6M
  11. HTIOTActIsCCDFsync
  12. HTIOTActDetermineRaFunc
  13. HTResetIOTSetting
  14. HTConstructCapabilityElement
  15. HTConstructInfoElement
  16. HTConstructRT2RTAggElement
  17. HT_PickMCSRate
  18. HTGetHighestMCSRate
  19. HTFilterMCSRate
  20. HTOnAssocRsp
  21. HTInitializeHTInfo
  22. HTInitializeBssDesc
  23. HTResetSelfAndSavePeerSetting
  24. HT_update_self_and_peer_setting
  25. HTUseDefaultSetting
  26. HTCCheck
  27. HTSetConnectBwModeCallback
  28. HTSetConnectBwMode

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

/* [<][>][^][v][top][bottom][index][help] */