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