0001
0002
0003
0004
0005
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
0701
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 }