Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
0004  *
0005  * Contact Information: wlanfae <wlanfae@realtek.com>
0006  */
0007 #include "rtllib.h"
0008 #include "rtl819x_HT.h"
0009 u8 MCS_FILTER_ALL[16] = {
0010     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0011     0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0012 };
0013 
0014 u8 MCS_FILTER_1SS[16] = {
0015     0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0016     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
0017 ;
0018 
0019 u16 MCS_DATA_RATE[2][2][77] = {
0020     {{13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234,
0021      260, 39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416,
0022      468, 520, 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182,
0023      182, 208, 156, 195, 195, 234, 273, 273, 312, 130, 156, 181, 156,
0024      181, 208, 234, 208, 234, 260, 260, 286, 195, 234, 273, 234, 273,
0025      312, 351, 312, 351, 390, 390, 429},
0026     {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289,
0027      43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520,
0028      578, 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231,
0029      173, 217, 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260,
0030      231, 260, 289, 289, 318, 217, 260, 303, 260, 303, 347, 390, 347, 390,
0031      433, 433, 477} },
0032     {{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486,
0033      540, 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648,
0034      864, 972, 1080, 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324,
0035      378, 378, 432, 324, 405, 405, 486, 567, 567, 648, 270, 324, 378, 324,
0036      378, 432, 486, 432, 486, 540, 540, 594, 405, 486, 567, 486, 567, 648,
0037      729, 648, 729, 810, 810, 891},
0038     {30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
0039      600, 90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720,
0040      960, 1080, 1200, 13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360,
0041      420, 420, 480, 360, 450, 450, 540, 630, 630, 720, 300, 360, 420, 360,
0042      420, 480, 540, 480, 540, 600, 600, 660, 450, 540, 630, 540, 630, 720,
0043      810, 720, 810, 900, 900, 990} }
0044 };
0045 
0046 static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
0047 
0048 static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
0049 
0050 static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
0051 
0052 static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f};
0053 
0054 static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
0055 
0056 static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
0057 
0058 static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e};
0059 
0060 static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
0061 
0062 static u8 DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0};
0063 
0064 static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91};
0065 
0066 static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
0067 
0068 static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4};
0069 
0070 void HTUpdateDefaultSetting(struct rtllib_device *ieee)
0071 {
0072     struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
0073 
0074     pHTInfo->bAcceptAddbaReq = 1;
0075 
0076     pHTInfo->bRegShortGI20MHz = 1;
0077     pHTInfo->bRegShortGI40MHz = 1;
0078 
0079     pHTInfo->bRegBW40MHz = 1;
0080 
0081     if (pHTInfo->bRegBW40MHz)
0082         pHTInfo->bRegSuppCCK = 1;
0083     else
0084         pHTInfo->bRegSuppCCK = true;
0085 
0086     pHTInfo->nAMSDU_MaxSize = 7935UL;
0087     pHTInfo->bAMSDU_Support = 0;
0088 
0089     pHTInfo->bAMPDUEnable = 1;
0090     pHTInfo->AMPDU_Factor = 2;
0091     pHTInfo->MPDU_Density = 0;
0092 
0093     pHTInfo->SelfMimoPs = 3;
0094     if (pHTInfo->SelfMimoPs == 2)
0095         pHTInfo->SelfMimoPs = 3;
0096     ieee->bTxDisableRateFallBack = 0;
0097     ieee->bTxUseDriverAssingedRate = 0;
0098 
0099     ieee->bTxEnableFwCalcDur = 1;
0100 
0101     pHTInfo->bRegRT2RTAggregation = 1;
0102 
0103     pHTInfo->bRegRxReorderEnable = 1;
0104     pHTInfo->RxReorderWinSize = 64;
0105     pHTInfo->RxReorderPendingTime = 30;
0106 }
0107 
0108 static u16 HTMcsToDataRate(struct rtllib_device *ieee, u8 nMcsRate)
0109 {
0110     struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
0111 
0112     u8  is40MHz = (pHTInfo->bCurBW40MHz) ? 1 : 0;
0113     u8  isShortGI = (pHTInfo->bCurBW40MHz) ?
0114                 ((pHTInfo->bCurShortGI40MHz) ? 1 : 0) :
0115                 ((pHTInfo->bCurShortGI20MHz) ? 1 : 0);
0116     return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate & 0x7f)];
0117 }
0118 
0119 u16  TxCountToDataRate(struct rtllib_device *ieee, u8 nDataRate)
0120 {
0121     u16 CCKOFDMRate[12] = {0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18,
0122                    0x24, 0x30, 0x48, 0x60, 0x6c};
0123     u8  is40MHz = 0;
0124     u8  isShortGI = 0;
0125 
0126     if (nDataRate < 12)
0127         return CCKOFDMRate[nDataRate];
0128     if (nDataRate >= 0x10 && nDataRate <= 0x1f) {
0129         is40MHz = 0;
0130         isShortGI = 0;
0131     } else if (nDataRate >= 0x20  && nDataRate <= 0x2f) {
0132         is40MHz = 1;
0133         isShortGI = 0;
0134     } else if (nDataRate >= 0x30  && nDataRate <= 0x3f) {
0135         is40MHz = 0;
0136         isShortGI = 1;
0137     } else if (nDataRate >= 0x40  && nDataRate <= 0x4f) {
0138         is40MHz = 1;
0139         isShortGI = 1;
0140     }
0141     return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate & 0xf];
0142 }
0143 
0144 bool IsHTHalfNmodeAPs(struct rtllib_device *ieee)
0145 {
0146     bool            retValue = false;
0147     struct rtllib_network *net = &ieee->current_network;
0148 
0149     if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) ||
0150         (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) ||
0151         (memcmp(net->bssid, PCI_RALINK, 3) == 0) ||
0152         (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) ||
0153         (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) ||
0154         (net->ralink_cap_exist))
0155         retValue = true;
0156     else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) ||
0157         !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) ||
0158         !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) ||
0159         (net->broadcom_cap_exist))
0160         retValue = true;
0161     else if (net->bssht.bd_rt2rt_aggregation)
0162         retValue = true;
0163     else
0164         retValue = false;
0165 
0166     return retValue;
0167 }
0168 
0169 static void HTIOTPeerDetermine(struct rtllib_device *ieee)
0170 {
0171     struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
0172     struct rtllib_network *net = &ieee->current_network;
0173 
0174     if (net->bssht.bd_rt2rt_aggregation) {
0175         pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK;
0176         if (net->bssht.rt2rt_ht_mode & RT_HT_CAP_USE_92SE)
0177             pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK_92SE;
0178         if (net->bssht.rt2rt_ht_mode & RT_HT_CAP_USE_SOFTAP)
0179             pHTInfo->IOTPeer = HT_IOT_PEER_92U_SOFTAP;
0180     } else if (net->broadcom_cap_exist) {
0181         pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
0182     } else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) ||
0183          !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) ||
0184          !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)) {
0185         pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
0186     } else if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) ||
0187          (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) ||
0188          (memcmp(net->bssid, PCI_RALINK, 3) == 0) ||
0189          (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) ||
0190          (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) ||
0191           net->ralink_cap_exist) {
0192         pHTInfo->IOTPeer = HT_IOT_PEER_RALINK;
0193     } else if ((net->atheros_cap_exist) ||
0194         (memcmp(net->bssid, DLINK_ATHEROS_1, 3) == 0) ||
0195         (memcmp(net->bssid, DLINK_ATHEROS_2, 3) == 0)) {
0196         pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS;
0197     } else if ((memcmp(net->bssid, CISCO_BROADCOM, 3) == 0) ||
0198           net->cisco_cap_exist) {
0199         pHTInfo->IOTPeer = HT_IOT_PEER_CISCO;
0200     } else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) ||
0201           net->marvell_cap_exist) {
0202         pHTInfo->IOTPeer = HT_IOT_PEER_MARVELL;
0203     } else if (net->airgo_cap_exist) {
0204         pHTInfo->IOTPeer = HT_IOT_PEER_AIRGO;
0205     } else {
0206         pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
0207     }
0208 
0209     netdev_dbg(ieee->dev, "IOTPEER: %x\n", pHTInfo->IOTPeer);
0210 }
0211 
0212 static u8 HTIOTActIsDisableMCS14(struct rtllib_device *ieee, u8 *PeerMacAddr)
0213 {
0214     return 0;
0215 }
0216 
0217 static bool HTIOTActIsDisableMCS15(struct rtllib_device *ieee)
0218 {
0219     return false;
0220 }
0221 
0222 static bool HTIOTActIsDisableMCSTwoSpatialStream(struct rtllib_device *ieee)
0223 {
0224     return false;
0225 }
0226 
0227 static u8 HTIOTActIsDisableEDCATurbo(struct rtllib_device *ieee,
0228                      u8 *PeerMacAddr)
0229 {
0230     return false;
0231 }
0232 
0233 static u8 HTIOTActIsMgntUseCCK6M(struct rtllib_device *ieee,
0234                  struct rtllib_network *network)
0235 {
0236     u8  retValue = 0;
0237 
0238     if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
0239         retValue = 1;
0240 
0241     return retValue;
0242 }
0243 
0244 static u8 HTIOTActIsCCDFsync(struct rtllib_device *ieee)
0245 {
0246     u8  retValue = 0;
0247 
0248     if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
0249         retValue = 1;
0250     return retValue;
0251 }
0252 
0253 static void HTIOTActDetermineRaFunc(struct rtllib_device *ieee, bool bPeerRx2ss)
0254 {
0255     struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
0256 
0257     pHTInfo->IOTRaFunc &= HT_IOT_RAFUNC_DISABLE_ALL;
0258 
0259     if (pHTInfo->IOTPeer == HT_IOT_PEER_RALINK && !bPeerRx2ss)
0260         pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_PEER_1R;
0261 
0262     if (pHTInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE)
0263         pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_TX_AMSDU;
0264 }
0265 
0266 void HTResetIOTSetting(struct rt_hi_throughput *pHTInfo)
0267 {
0268     pHTInfo->IOTAction = 0;
0269     pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
0270     pHTInfo->IOTRaFunc = 0;
0271 }
0272 
0273 void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap,
0274                   u8 *len, u8 IsEncrypt, bool bAssoc)
0275 {
0276     struct rt_hi_throughput *pHT = ieee->pHTInfo;
0277     struct ht_capab_ele *pCapELE = NULL;
0278 
0279     if (!posHTCap || !pHT) {
0280         netdev_warn(ieee->dev,
0281                 "%s(): posHTCap and pHTInfo are null\n", __func__);
0282         return;
0283     }
0284     memset(posHTCap, 0, *len);
0285 
0286     if ((bAssoc) && (pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)) {
0287         u8  EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
0288 
0289         memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap));
0290         pCapELE = (struct ht_capab_ele *)&(posHTCap[4]);
0291         *len = 30 + 2;
0292     } else {
0293         pCapELE = (struct ht_capab_ele *)posHTCap;
0294         *len = 26 + 2;
0295     }
0296 
0297     pCapELE->AdvCoding      = 0;
0298     if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
0299         pCapELE->ChlWidth = 0;
0300     else
0301         pCapELE->ChlWidth = (pHT->bRegBW40MHz ? 1 : 0);
0302 
0303     pCapELE->MimoPwrSave        = pHT->SelfMimoPs;
0304     pCapELE->GreenField     = 0;
0305     pCapELE->ShortGI20Mhz       = 1;
0306     pCapELE->ShortGI40Mhz       = 1;
0307 
0308     pCapELE->TxSTBC         = 1;
0309     pCapELE->RxSTBC         = 0;
0310     pCapELE->DelayBA        = 0;
0311     pCapELE->MaxAMSDUSize = (MAX_RECEIVE_BUFFER_SIZE >= 7935) ? 1 : 0;
0312     pCapELE->DssCCk = ((pHT->bRegBW40MHz) ? (pHT->bRegSuppCCK ? 1 : 0) : 0);
0313     pCapELE->PSMP = 0;
0314     pCapELE->LSigTxopProtect = 0;
0315 
0316     netdev_dbg(ieee->dev,
0317            "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n",
0318            pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk);
0319 
0320     if (IsEncrypt) {
0321         pCapELE->MPDUDensity    = 7;
0322         pCapELE->MaxRxAMPDUFactor   = 2;
0323     } else {
0324         pCapELE->MaxRxAMPDUFactor   = 3;
0325         pCapELE->MPDUDensity    = 0;
0326     }
0327 
0328     memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16);
0329     memset(&pCapELE->ExtHTCapInfo, 0, 2);
0330     memset(pCapELE->TxBFCap, 0, 4);
0331 
0332     pCapELE->ASCap = 0;
0333 
0334     if (bAssoc) {
0335         if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15)
0336             pCapELE->MCS[1] &= 0x7f;
0337 
0338         if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14)
0339             pCapELE->MCS[1] &= 0xbf;
0340 
0341         if (pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS)
0342             pCapELE->MCS[1] &= 0x00;
0343 
0344         if (pHT->IOTAction & HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI)
0345             pCapELE->ShortGI40Mhz       = 0;
0346 
0347         if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) {
0348             pCapELE->ChlWidth = 0;
0349             pCapELE->MCS[1] = 0;
0350         }
0351     }
0352 }
0353 
0354 void HTConstructInfoElement(struct rtllib_device *ieee, u8 *posHTInfo,
0355                 u8 *len, u8 IsEncrypt)
0356 {
0357     struct rt_hi_throughput *pHT = ieee->pHTInfo;
0358     struct ht_info_ele *pHTInfoEle = (struct ht_info_ele *)posHTInfo;
0359 
0360     if (!posHTInfo || !pHTInfoEle) {
0361         netdev_warn(ieee->dev,
0362                 "%s(): posHTInfo and pHTInfoEle are null\n",
0363                 __func__);
0364         return;
0365     }
0366 
0367     memset(posHTInfo, 0, *len);
0368     if ((ieee->iw_mode == IW_MODE_ADHOC) ||
0369         (ieee->iw_mode == IW_MODE_MASTER)) {
0370         pHTInfoEle->ControlChl  = ieee->current_network.channel;
0371         pHTInfoEle->ExtChlOffset = ((!pHT->bRegBW40MHz) ?
0372                         HT_EXTCHNL_OFFSET_NO_EXT :
0373                         (ieee->current_network.channel <= 6)
0374                         ? HT_EXTCHNL_OFFSET_UPPER :
0375                         HT_EXTCHNL_OFFSET_LOWER);
0376         pHTInfoEle->RecommemdedTxWidth  = pHT->bRegBW40MHz;
0377         pHTInfoEle->RIFS            = 0;
0378         pHTInfoEle->PSMPAccessOnly      = 0;
0379         pHTInfoEle->SrvIntGranularity       = 0;
0380         pHTInfoEle->OptMode         = pHT->CurrentOpMode;
0381         pHTInfoEle->NonGFDevPresent     = 0;
0382         pHTInfoEle->DualBeacon          = 0;
0383         pHTInfoEle->SecondaryBeacon     = 0;
0384         pHTInfoEle->LSigTxopProtectFull     = 0;
0385         pHTInfoEle->PcoActive           = 0;
0386         pHTInfoEle->PcoPhase            = 0;
0387 
0388         memset(pHTInfoEle->BasicMSC, 0, 16);
0389 
0390         *len = 22 + 2;
0391 
0392     } else {
0393         *len = 0;
0394     }
0395 }
0396 
0397 void HTConstructRT2RTAggElement(struct rtllib_device *ieee, u8 *posRT2RTAgg,
0398                 u8 *len)
0399 {
0400     if (!posRT2RTAgg) {
0401         netdev_warn(ieee->dev, "%s(): posRT2RTAgg is null\n", __func__);
0402         return;
0403     }
0404     memset(posRT2RTAgg, 0, *len);
0405     *posRT2RTAgg++ = 0x00;
0406     *posRT2RTAgg++ = 0xe0;
0407     *posRT2RTAgg++ = 0x4c;
0408     *posRT2RTAgg++ = 0x02;
0409     *posRT2RTAgg++ = 0x01;
0410 
0411     *posRT2RTAgg = 0x30;
0412 
0413     if (ieee->bSupportRemoteWakeUp)
0414         *posRT2RTAgg |= RT_HT_CAP_USE_WOW;
0415 
0416     *len = 6 + 2;
0417 }
0418 
0419 static u8 HT_PickMCSRate(struct rtllib_device *ieee, u8 *pOperateMCS)
0420 {
0421     u8 i;
0422 
0423     if (!pOperateMCS) {
0424         netdev_warn(ieee->dev, "%s(): pOperateMCS is null\n", __func__);
0425         return false;
0426     }
0427 
0428     switch (ieee->mode) {
0429     case IEEE_A:
0430     case IEEE_B:
0431     case IEEE_G:
0432         for (i = 0; i <= 15; i++)
0433             pOperateMCS[i] = 0;
0434         break;
0435     case IEEE_N_24G:
0436     case IEEE_N_5G:
0437         pOperateMCS[0] &= RATE_ADPT_1SS_MASK;
0438         pOperateMCS[1] &= RATE_ADPT_2SS_MASK;
0439         pOperateMCS[3] &= RATE_ADPT_MCS32_MASK;
0440         break;
0441     default:
0442         break;
0443     }
0444 
0445     return true;
0446 }
0447 
0448 u8 HTGetHighestMCSRate(struct rtllib_device *ieee, u8 *pMCSRateSet,
0449                u8 *pMCSFilter)
0450 {
0451     u8      i, j;
0452     u8      bitMap;
0453     u8      mcsRate = 0;
0454     u8      availableMcsRate[16];
0455 
0456     if (!pMCSRateSet || !pMCSFilter) {
0457         netdev_warn(ieee->dev,
0458                 "%s(): pMCSRateSet and pMCSFilter are null\n",
0459                 __func__);
0460         return false;
0461     }
0462     for (i = 0; i < 16; i++)
0463         availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i];
0464 
0465     for (i = 0; i < 16; i++) {
0466         if (availableMcsRate[i] != 0)
0467             break;
0468     }
0469     if (i == 16)
0470         return false;
0471 
0472     for (i = 0; i < 16; i++) {
0473         if (availableMcsRate[i] != 0) {
0474             bitMap = availableMcsRate[i];
0475             for (j = 0; j < 8; j++) {
0476                 if ((bitMap % 2) != 0) {
0477                     if (HTMcsToDataRate(ieee, (8 * i + j)) >
0478                         HTMcsToDataRate(ieee, mcsRate))
0479                         mcsRate = 8 * i + j;
0480                 }
0481                 bitMap >>= 1;
0482             }
0483         }
0484     }
0485     return mcsRate | 0x80;
0486 }
0487 
0488 static u8 HTFilterMCSRate(struct rtllib_device *ieee, u8 *pSupportMCS,
0489               u8 *pOperateMCS)
0490 {
0491     u8 i;
0492 
0493     for (i = 0; i <= 15; i++)
0494         pOperateMCS[i] = ieee->Regdot11TxHTOperationalRateSet[i] &
0495                  pSupportMCS[i];
0496 
0497     HT_PickMCSRate(ieee, pOperateMCS);
0498 
0499     if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
0500         pOperateMCS[1] = 0;
0501 
0502     for (i = 2; i <= 15; i++)
0503         pOperateMCS[i] = 0;
0504 
0505     return true;
0506 }
0507 
0508 void HTSetConnectBwMode(struct rtllib_device *ieee,
0509             enum ht_channel_width Bandwidth,
0510             enum ht_extchnl_offset Offset);
0511 
0512 void HTOnAssocRsp(struct rtllib_device *ieee)
0513 {
0514     struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
0515     struct ht_capab_ele *pPeerHTCap = NULL;
0516     struct ht_info_ele *pPeerHTInfo = NULL;
0517     u16 nMaxAMSDUSize = 0;
0518     u8 *pMcsFilter = NULL;
0519 
0520     static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
0521     static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34};
0522 
0523     if (!pHTInfo->bCurrentHTSupport) {
0524         netdev_warn(ieee->dev, "%s(): HT_DISABLE\n", __func__);
0525         return;
0526     }
0527     netdev_dbg(ieee->dev, "%s(): HT_ENABLE\n", __func__);
0528 
0529     if (!memcmp(pHTInfo->PeerHTCapBuf, EWC11NHTCap, sizeof(EWC11NHTCap)))
0530         pPeerHTCap = (struct ht_capab_ele *)(&pHTInfo->PeerHTCapBuf[4]);
0531     else
0532         pPeerHTCap = (struct ht_capab_ele *)(pHTInfo->PeerHTCapBuf);
0533 
0534     if (!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
0535         pPeerHTInfo = (struct ht_info_ele *)
0536                  (&pHTInfo->PeerHTInfoBuf[4]);
0537     else
0538         pPeerHTInfo = (struct ht_info_ele *)(pHTInfo->PeerHTInfoBuf);
0539 
0540 #ifdef VERBOSE_DEBUG
0541     print_hex_dump_bytes("%s: ", __func__, DUMP_PREFIX_NONE,
0542                  pPeerHTCap, sizeof(struct ht_capab_ele));
0543 #endif
0544     HTSetConnectBwMode(ieee, (enum ht_channel_width)(pPeerHTCap->ChlWidth),
0545               (enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset));
0546     pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ?
0547                  true : false);
0548 
0549     pHTInfo->bCurShortGI20MHz = ((pHTInfo->bRegShortGI20MHz) ?
0550                     ((pPeerHTCap->ShortGI20Mhz == 1) ?
0551                     true : false) : false);
0552     pHTInfo->bCurShortGI40MHz = ((pHTInfo->bRegShortGI40MHz) ?
0553                      ((pPeerHTCap->ShortGI40Mhz == 1) ?
0554                      true : false) : false);
0555 
0556     pHTInfo->bCurSuppCCK = ((pHTInfo->bRegSuppCCK) ?
0557                    ((pPeerHTCap->DssCCk == 1) ? true :
0558                    false) : false);
0559 
0560     pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
0561 
0562     nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize == 0) ? 3839 : 7935;
0563 
0564     if (pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize)
0565         pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize;
0566     else
0567         pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
0568 
0569     pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
0570     if (ieee->rtllib_ap_sec_type &&
0571        (ieee->rtllib_ap_sec_type(ieee) & (SEC_ALG_WEP | SEC_ALG_TKIP))) {
0572         if ((pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) ||
0573                 (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN))
0574             pHTInfo->bCurrentAMPDUEnable = false;
0575     }
0576 
0577     if (!pHTInfo->bRegRT2RTAggregation) {
0578         if (pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor)
0579             pHTInfo->CurrentAMPDUFactor =
0580                          pPeerHTCap->MaxRxAMPDUFactor;
0581         else
0582             pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
0583 
0584     } else {
0585         if (ieee->current_network.bssht.bd_rt2rt_aggregation) {
0586             if (ieee->pairwise_key_type != KEY_TYPE_NA)
0587                 pHTInfo->CurrentAMPDUFactor =
0588                          pPeerHTCap->MaxRxAMPDUFactor;
0589             else
0590                 pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K;
0591         } else {
0592             if (pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K)
0593                 pHTInfo->CurrentAMPDUFactor =
0594                          pPeerHTCap->MaxRxAMPDUFactor;
0595             else
0596                 pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K;
0597         }
0598     }
0599     if (pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity)
0600         pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
0601     else
0602         pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity;
0603     if (pHTInfo->IOTAction & HT_IOT_ACT_TX_USE_AMSDU_8K) {
0604         pHTInfo->bCurrentAMPDUEnable = false;
0605         pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE;
0606         pHTInfo->ForcedAMSDUMaxSize = 7935;
0607     }
0608     pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable;
0609 
0610     if (pPeerHTCap->MCS[0] == 0)
0611         pPeerHTCap->MCS[0] = 0xff;
0612 
0613     HTIOTActDetermineRaFunc(ieee, ((pPeerHTCap->MCS[1]) != 0));
0614 
0615     HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet);
0616 
0617     pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave;
0618     if (pHTInfo->PeerMimoPs == MIMO_PS_STATIC)
0619         pMcsFilter = MCS_FILTER_1SS;
0620     else
0621         pMcsFilter = MCS_FILTER_ALL;
0622     ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee,
0623                    ieee->dot11HTOperationalRateSet, pMcsFilter);
0624     ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
0625 
0626     pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
0627 }
0628 
0629 void HTInitializeHTInfo(struct rtllib_device *ieee)
0630 {
0631     struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
0632 
0633     pHTInfo->bCurrentHTSupport = false;
0634 
0635     pHTInfo->bCurBW40MHz = false;
0636     pHTInfo->bCurTxBW40MHz = false;
0637 
0638     pHTInfo->bCurShortGI20MHz = false;
0639     pHTInfo->bCurShortGI40MHz = false;
0640     pHTInfo->bForcedShortGI = false;
0641 
0642     pHTInfo->bCurSuppCCK = true;
0643 
0644     pHTInfo->bCurrent_AMSDU_Support = false;
0645     pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
0646     pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
0647     pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
0648 
0649     memset((void *)(&(pHTInfo->SelfHTCap)), 0,
0650         sizeof(pHTInfo->SelfHTCap));
0651     memset((void *)(&(pHTInfo->SelfHTInfo)), 0,
0652         sizeof(pHTInfo->SelfHTInfo));
0653     memset((void *)(&(pHTInfo->PeerHTCapBuf)), 0,
0654         sizeof(pHTInfo->PeerHTCapBuf));
0655     memset((void *)(&(pHTInfo->PeerHTInfoBuf)), 0,
0656         sizeof(pHTInfo->PeerHTInfoBuf));
0657 
0658     pHTInfo->bSwBwInProgress = false;
0659 
0660     pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE;
0661 
0662     pHTInfo->bCurrentRT2RTAggregation = false;
0663     pHTInfo->bCurrentRT2RTLongSlotTime = false;
0664     pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0;
0665 
0666     pHTInfo->IOTPeer = 0;
0667     pHTInfo->IOTAction = 0;
0668     pHTInfo->IOTRaFunc = 0;
0669 
0670     {
0671         u8 *RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]);
0672 
0673         RegHTSuppRateSets[0] = 0xFF;
0674         RegHTSuppRateSets[1] = 0xFF;
0675         RegHTSuppRateSets[4] = 0x01;
0676     }
0677 }
0678 
0679 void HTInitializeBssDesc(struct bss_ht *pBssHT)
0680 {
0681     pBssHT->bd_support_ht = false;
0682     memset(pBssHT->bd_ht_cap_buf, 0, sizeof(pBssHT->bd_ht_cap_buf));
0683     pBssHT->bd_ht_cap_len = 0;
0684     memset(pBssHT->bd_ht_info_buf, 0, sizeof(pBssHT->bd_ht_info_buf));
0685     pBssHT->bd_ht_info_len = 0;
0686 
0687     pBssHT->bd_ht_spec_ver = HT_SPEC_VER_IEEE;
0688 
0689     pBssHT->bd_rt2rt_aggregation = false;
0690     pBssHT->bd_rt2rt_long_slot_time = false;
0691     pBssHT->rt2rt_ht_mode = (enum rt_ht_capability)0;
0692 }
0693 
0694 void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee,
0695                    struct rtllib_network *pNetwork)
0696 {
0697     struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
0698     u8  bIOTAction = 0;
0699 
0700     /* unmark bEnableHT flag here is the same reason why unmarked in
0701      * function rtllib_softmac_new_net. WB 2008.09.10
0702      */
0703     if (pNetwork->bssht.bd_support_ht) {
0704         pHTInfo->bCurrentHTSupport = true;
0705         pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bd_ht_spec_ver;
0706 
0707         if (pNetwork->bssht.bd_ht_cap_len > 0 &&
0708             pNetwork->bssht.bd_ht_cap_len <= sizeof(pHTInfo->PeerHTCapBuf))
0709             memcpy(pHTInfo->PeerHTCapBuf,
0710                    pNetwork->bssht.bd_ht_cap_buf,
0711                    pNetwork->bssht.bd_ht_cap_len);
0712 
0713         if (pNetwork->bssht.bd_ht_info_len > 0 &&
0714             pNetwork->bssht.bd_ht_info_len <=
0715             sizeof(pHTInfo->PeerHTInfoBuf))
0716             memcpy(pHTInfo->PeerHTInfoBuf,
0717                    pNetwork->bssht.bd_ht_info_buf,
0718                    pNetwork->bssht.bd_ht_info_len);
0719 
0720         if (pHTInfo->bRegRT2RTAggregation) {
0721             pHTInfo->bCurrentRT2RTAggregation =
0722                  pNetwork->bssht.bd_rt2rt_aggregation;
0723             pHTInfo->bCurrentRT2RTLongSlotTime =
0724                  pNetwork->bssht.bd_rt2rt_long_slot_time;
0725             pHTInfo->RT2RT_HT_Mode = pNetwork->bssht.rt2rt_ht_mode;
0726         } else {
0727             pHTInfo->bCurrentRT2RTAggregation = false;
0728             pHTInfo->bCurrentRT2RTLongSlotTime = false;
0729             pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0;
0730         }
0731 
0732         HTIOTPeerDetermine(ieee);
0733 
0734         pHTInfo->IOTAction = 0;
0735         bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid);
0736         if (bIOTAction)
0737             pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14;
0738 
0739         bIOTAction = HTIOTActIsDisableMCS15(ieee);
0740         if (bIOTAction)
0741             pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15;
0742 
0743         bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee);
0744         if (bIOTAction)
0745             pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS;
0746 
0747         bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid);
0748         if (bIOTAction)
0749             pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO;
0750 
0751         bIOTAction = HTIOTActIsMgntUseCCK6M(ieee, pNetwork);
0752         if (bIOTAction)
0753             pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M;
0754         bIOTAction = HTIOTActIsCCDFsync(ieee);
0755         if (bIOTAction)
0756             pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC;
0757     } else {
0758         pHTInfo->bCurrentHTSupport = false;
0759         pHTInfo->bCurrentRT2RTAggregation = false;
0760         pHTInfo->bCurrentRT2RTLongSlotTime = false;
0761         pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0;
0762 
0763         pHTInfo->IOTAction = 0;
0764         pHTInfo->IOTRaFunc = 0;
0765     }
0766 }
0767 
0768 void HT_update_self_and_peer_setting(struct rtllib_device *ieee,
0769                      struct rtllib_network *pNetwork)
0770 {
0771     struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
0772     struct ht_info_ele *pPeerHTInfo =
0773          (struct ht_info_ele *)pNetwork->bssht.bd_ht_info_buf;
0774 
0775     if (pHTInfo->bCurrentHTSupport) {
0776         if (pNetwork->bssht.bd_ht_info_len != 0)
0777             pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
0778     }
0779 }
0780 EXPORT_SYMBOL(HT_update_self_and_peer_setting);
0781 
0782 void HTUseDefaultSetting(struct rtllib_device *ieee)
0783 {
0784     struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
0785 
0786     if (pHTInfo->bEnableHT) {
0787         pHTInfo->bCurrentHTSupport = true;
0788         pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK;
0789 
0790         pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz;
0791         pHTInfo->bCurShortGI20MHz = pHTInfo->bRegShortGI20MHz;
0792 
0793         pHTInfo->bCurShortGI40MHz = pHTInfo->bRegShortGI40MHz;
0794 
0795         if (ieee->iw_mode == IW_MODE_ADHOC)
0796             ieee->current_network.qos_data.active =
0797                  ieee->current_network.qos_data.supported;
0798         pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
0799         pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
0800 
0801         pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
0802         pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
0803 
0804         pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity;
0805 
0806         HTFilterMCSRate(ieee, ieee->Regdot11TxHTOperationalRateSet,
0807                 ieee->dot11HTOperationalRateSet);
0808         ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee,
0809                        ieee->dot11HTOperationalRateSet,
0810                        MCS_FILTER_ALL);
0811         ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
0812 
0813     } else {
0814         pHTInfo->bCurrentHTSupport = false;
0815     }
0816 }
0817 
0818 u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame)
0819 {
0820     if (ieee->pHTInfo->bCurrentHTSupport) {
0821         if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) {
0822             netdev_dbg(ieee->dev, "HT CONTROL FILED EXIST!!\n");
0823             return true;
0824         }
0825     }
0826     return false;
0827 }
0828 
0829 static void HTSetConnectBwModeCallback(struct rtllib_device *ieee)
0830 {
0831     struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
0832 
0833     if (pHTInfo->bCurBW40MHz) {
0834         if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_UPPER)
0835             ieee->set_chan(ieee->dev,
0836                        ieee->current_network.channel + 2);
0837         else if (pHTInfo->CurSTAExtChnlOffset ==
0838              HT_EXTCHNL_OFFSET_LOWER)
0839             ieee->set_chan(ieee->dev,
0840                        ieee->current_network.channel - 2);
0841         else
0842             ieee->set_chan(ieee->dev,
0843                        ieee->current_network.channel);
0844 
0845         ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40,
0846                        pHTInfo->CurSTAExtChnlOffset);
0847     } else {
0848         ieee->set_chan(ieee->dev, ieee->current_network.channel);
0849         ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20,
0850                        HT_EXTCHNL_OFFSET_NO_EXT);
0851     }
0852 
0853     pHTInfo->bSwBwInProgress = false;
0854 }
0855 
0856 void HTSetConnectBwMode(struct rtllib_device *ieee,
0857             enum ht_channel_width Bandwidth,
0858             enum ht_extchnl_offset Offset)
0859 {
0860     struct rt_hi_throughput *pHTInfo = ieee->pHTInfo;
0861 
0862     if (!pHTInfo->bRegBW40MHz)
0863         return;
0864 
0865     if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
0866         Bandwidth = HT_CHANNEL_WIDTH_20;
0867 
0868     if (pHTInfo->bSwBwInProgress) {
0869         pr_info("%s: bSwBwInProgress!!\n", __func__);
0870         return;
0871     }
0872     if (Bandwidth == HT_CHANNEL_WIDTH_20_40) {
0873         if (ieee->current_network.channel < 2 &&
0874             Offset == HT_EXTCHNL_OFFSET_LOWER)
0875             Offset = HT_EXTCHNL_OFFSET_NO_EXT;
0876         if (Offset == HT_EXTCHNL_OFFSET_UPPER ||
0877             Offset == HT_EXTCHNL_OFFSET_LOWER) {
0878             pHTInfo->bCurBW40MHz = true;
0879             pHTInfo->CurSTAExtChnlOffset = Offset;
0880         } else {
0881             pHTInfo->bCurBW40MHz = false;
0882             pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
0883         }
0884     } else {
0885         pHTInfo->bCurBW40MHz = false;
0886         pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
0887     }
0888 
0889     netdev_dbg(ieee->dev, "%s():pHTInfo->bCurBW40MHz:%x\n", __func__,
0890            pHTInfo->bCurBW40MHz);
0891 
0892     pHTInfo->bSwBwInProgress = true;
0893 
0894     HTSetConnectBwModeCallback(ieee);
0895 }