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" 21 u8 MCS_FILTER_ALL[16] = { 22 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 23 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 24 }; 25 26 u8 MCS_FILTER_1SS[16] = { 27 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 28 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 29 ; 30 31 u16 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 58 static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf}; 59 60 static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70}; 61 62 static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e}; 63 64 static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f}; 65 66 static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf}; 67 68 static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc}; 69 70 static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e}; 71 72 static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02}; 73 74 static u8 DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0}; 75 76 static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91}; 77 78 static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; 79 80 static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4}; 81 82 void 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 120 u16 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 131 u16 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 156 bool 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 181 static 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 netdev_dbg(ieee->dev, "IOTPEER: %x\n", pHTInfo->IOTPeer); 221 } 222 223 static u8 HTIOTActIsDisableMCS14(struct rtllib_device *ieee, u8 *PeerMacAddr) 224 { 225 return 0; 226 } 227 228 229 static bool HTIOTActIsDisableMCS15(struct rtllib_device *ieee) 230 { 231 return false; 232 } 233 234 static bool HTIOTActIsDisableMCSTwoSpatialStream(struct rtllib_device *ieee) 235 { 236 return false; 237 } 238 239 static u8 HTIOTActIsDisableEDCATurbo(struct rtllib_device *ieee, u8 *PeerMacAddr) 240 { 241 return false; 242 } 243 244 static u8 HTIOTActIsMgntUseCCK6M(struct rtllib_device *ieee, 245 struct rtllib_network *network) 246 { 247 u8 retValue = 0; 248 249 250 if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) 251 retValue = 1; 252 253 return retValue; 254 } 255 256 static u8 HTIOTActIsCCDFsync(struct rtllib_device *ieee) 257 { 258 u8 retValue = 0; 259 260 if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) 261 retValue = 1; 262 return retValue; 263 } 264 265 static void HTIOTActDetermineRaFunc(struct rtllib_device *ieee, bool bPeerRx2ss) 266 { 267 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 268 269 pHTInfo->IOTRaFunc &= HT_IOT_RAFUNC_DISABLE_ALL; 270 271 if (pHTInfo->IOTPeer == HT_IOT_PEER_RALINK && !bPeerRx2ss) 272 pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_PEER_1R; 273 274 if (pHTInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE) 275 pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_TX_AMSDU; 276 277 } 278 279 void HTResetIOTSetting(struct rt_hi_throughput *pHTInfo) 280 { 281 pHTInfo->IOTAction = 0; 282 pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; 283 pHTInfo->IOTRaFunc = 0; 284 } 285 286 void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap, 287 u8 *len, u8 IsEncrypt, bool bAssoc) 288 { 289 struct rt_hi_throughput *pHT = ieee->pHTInfo; 290 struct ht_capab_ele *pCapELE = NULL; 291 292 if ((posHTCap == NULL) || (pHT == NULL)) { 293 netdev_warn(ieee->dev, 294 "%s(): posHTCap and pHTInfo are null\n", __func__); 295 return; 296 } 297 memset(posHTCap, 0, *len); 298 299 if ((bAssoc) && (pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)) { 300 u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; 301 302 memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap)); 303 pCapELE = (struct ht_capab_ele *)&(posHTCap[4]); 304 *len = 30 + 2; 305 } else { 306 pCapELE = (struct ht_capab_ele *)posHTCap; 307 *len = 26 + 2; 308 } 309 310 pCapELE->AdvCoding = 0; 311 if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 312 pCapELE->ChlWidth = 0; 313 else 314 pCapELE->ChlWidth = (pHT->bRegBW40MHz ? 1 : 0); 315 316 pCapELE->MimoPwrSave = pHT->SelfMimoPs; 317 pCapELE->GreenField = 0; 318 pCapELE->ShortGI20Mhz = 1; 319 pCapELE->ShortGI40Mhz = 1; 320 321 pCapELE->TxSTBC = 1; 322 pCapELE->RxSTBC = 0; 323 pCapELE->DelayBA = 0; 324 pCapELE->MaxAMSDUSize = (MAX_RECEIVE_BUFFER_SIZE >= 7935) ? 1 : 0; 325 pCapELE->DssCCk = ((pHT->bRegBW40MHz) ? (pHT->bRegSuppCCK ? 1 : 0) : 0); 326 pCapELE->PSMP = 0; 327 pCapELE->LSigTxopProtect = 0; 328 329 330 netdev_dbg(ieee->dev, 331 "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", 332 pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk); 333 334 if (IsEncrypt) { 335 pCapELE->MPDUDensity = 7; 336 pCapELE->MaxRxAMPDUFactor = 2; 337 } else { 338 pCapELE->MaxRxAMPDUFactor = 3; 339 pCapELE->MPDUDensity = 0; 340 } 341 342 memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16); 343 memset(&pCapELE->ExtHTCapInfo, 0, 2); 344 memset(pCapELE->TxBFCap, 0, 4); 345 346 pCapELE->ASCap = 0; 347 348 if (bAssoc) { 349 if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15) 350 pCapELE->MCS[1] &= 0x7f; 351 352 if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14) 353 pCapELE->MCS[1] &= 0xbf; 354 355 if (pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS) 356 pCapELE->MCS[1] &= 0x00; 357 358 if (pHT->IOTAction & HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI) 359 pCapELE->ShortGI40Mhz = 0; 360 361 if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) { 362 pCapELE->ChlWidth = 0; 363 pCapELE->MCS[1] = 0; 364 } 365 } 366 } 367 368 void HTConstructInfoElement(struct rtllib_device *ieee, u8 *posHTInfo, 369 u8 *len, u8 IsEncrypt) 370 { 371 struct rt_hi_throughput *pHT = ieee->pHTInfo; 372 struct ht_info_ele *pHTInfoEle = (struct ht_info_ele *)posHTInfo; 373 374 if ((posHTInfo == NULL) || (pHTInfoEle == NULL)) { 375 netdev_warn(ieee->dev, 376 "%s(): posHTInfo and pHTInfoEle are null\n", 377 __func__); 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 412 void HTConstructRT2RTAggElement(struct rtllib_device *ieee, u8 *posRT2RTAgg, 413 u8 *len) 414 { 415 if (posRT2RTAgg == NULL) { 416 netdev_warn(ieee->dev, "%s(): posRT2RTAgg is null\n", __func__); 417 return; 418 } 419 memset(posRT2RTAgg, 0, *len); 420 *posRT2RTAgg++ = 0x00; 421 *posRT2RTAgg++ = 0xe0; 422 *posRT2RTAgg++ = 0x4c; 423 *posRT2RTAgg++ = 0x02; 424 *posRT2RTAgg++ = 0x01; 425 426 *posRT2RTAgg = 0x30; 427 428 if (ieee->bSupportRemoteWakeUp) 429 *posRT2RTAgg |= RT_HT_CAP_USE_WOW; 430 431 *len = 6 + 2; 432 } 433 434 static u8 HT_PickMCSRate(struct rtllib_device *ieee, u8 *pOperateMCS) 435 { 436 u8 i; 437 438 if (pOperateMCS == NULL) { 439 netdev_warn(ieee->dev, "%s(): pOperateMCS is null\n", __func__); 440 return false; 441 } 442 443 switch (ieee->mode) { 444 case IEEE_A: 445 case IEEE_B: 446 case IEEE_G: 447 for (i = 0; i <= 15; i++) 448 pOperateMCS[i] = 0; 449 break; 450 case IEEE_N_24G: 451 case IEEE_N_5G: 452 pOperateMCS[0] &= RATE_ADPT_1SS_MASK; 453 pOperateMCS[1] &= RATE_ADPT_2SS_MASK; 454 pOperateMCS[3] &= RATE_ADPT_MCS32_MASK; 455 break; 456 default: 457 break; 458 459 } 460 461 return true; 462 } 463 464 u8 HTGetHighestMCSRate(struct rtllib_device *ieee, u8 *pMCSRateSet, 465 u8 *pMCSFilter) 466 { 467 u8 i, j; 468 u8 bitMap; 469 u8 mcsRate = 0; 470 u8 availableMcsRate[16]; 471 472 if (pMCSRateSet == NULL || pMCSFilter == NULL) { 473 netdev_warn(ieee->dev, 474 "%s(): pMCSRateSet and pMCSFilter are null\n", 475 __func__); 476 return false; 477 } 478 for (i = 0; i < 16; i++) 479 availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i]; 480 481 for (i = 0; i < 16; i++) { 482 if (availableMcsRate[i] != 0) 483 break; 484 } 485 if (i == 16) 486 return false; 487 488 for (i = 0; i < 16; i++) { 489 if (availableMcsRate[i] != 0) { 490 bitMap = availableMcsRate[i]; 491 for (j = 0; j < 8; j++) { 492 if ((bitMap%2) != 0) { 493 if (HTMcsToDataRate(ieee, (8*i+j)) > 494 HTMcsToDataRate(ieee, mcsRate)) 495 mcsRate = (8*i+j); 496 } 497 bitMap >>= 1; 498 } 499 } 500 } 501 return mcsRate | 0x80; 502 } 503 504 u8 HTFilterMCSRate(struct rtllib_device *ieee, u8 *pSupportMCS, u8 *pOperateMCS) 505 { 506 507 u8 i; 508 509 for (i = 0; i <= 15; i++) 510 pOperateMCS[i] = ieee->Regdot11TxHTOperationalRateSet[i] & 511 pSupportMCS[i]; 512 513 HT_PickMCSRate(ieee, pOperateMCS); 514 515 if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 516 pOperateMCS[1] = 0; 517 518 for (i = 2; i <= 15; i++) 519 pOperateMCS[i] = 0; 520 521 return true; 522 } 523 524 void HTSetConnectBwMode(struct rtllib_device *ieee, 525 enum ht_channel_width Bandwidth, 526 enum ht_extchnl_offset Offset); 527 528 void HTOnAssocRsp(struct rtllib_device *ieee) 529 { 530 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 531 struct ht_capab_ele *pPeerHTCap = NULL; 532 struct ht_info_ele *pPeerHTInfo = NULL; 533 u16 nMaxAMSDUSize = 0; 534 u8 *pMcsFilter = NULL; 535 536 static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; 537 static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; 538 539 if (pHTInfo->bCurrentHTSupport == false) { 540 netdev_warn(ieee->dev, "%s(): HT_DISABLE\n", __func__); 541 return; 542 } 543 netdev_dbg(ieee->dev, "%s(): HT_ENABLE\n", __func__); 544 545 if (!memcmp(pHTInfo->PeerHTCapBuf, EWC11NHTCap, sizeof(EWC11NHTCap))) 546 pPeerHTCap = (struct ht_capab_ele *)(&pHTInfo->PeerHTCapBuf[4]); 547 else 548 pPeerHTCap = (struct ht_capab_ele *)(pHTInfo->PeerHTCapBuf); 549 550 if (!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo))) 551 pPeerHTInfo = (struct ht_info_ele *) 552 (&pHTInfo->PeerHTInfoBuf[4]); 553 else 554 pPeerHTInfo = (struct ht_info_ele *)(pHTInfo->PeerHTInfoBuf); 555 556 557 #ifdef VERBOSE_DEBUG 558 print_hex_dump_bytes("HTOnAssocRsp(): ", DUMP_PREFIX_NONE, 559 pPeerHTCap, sizeof(struct ht_capab_ele)); 560 #endif 561 HTSetConnectBwMode(ieee, (enum ht_channel_width)(pPeerHTCap->ChlWidth), 562 (enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset)); 563 pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ? 564 true : false); 565 566 pHTInfo->bCurShortGI20MHz = ((pHTInfo->bRegShortGI20MHz) ? 567 ((pPeerHTCap->ShortGI20Mhz == 1) ? 568 true : false) : false); 569 pHTInfo->bCurShortGI40MHz = ((pHTInfo->bRegShortGI40MHz) ? 570 ((pPeerHTCap->ShortGI40Mhz == 1) ? 571 true : false) : false); 572 573 pHTInfo->bCurSuppCCK = ((pHTInfo->bRegSuppCCK) ? 574 ((pPeerHTCap->DssCCk == 1) ? true : 575 false) : false); 576 577 578 pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; 579 580 nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize == 0) ? 3839 : 7935; 581 582 if (pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize) 583 pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize; 584 else 585 pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; 586 587 pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; 588 if (ieee->rtllib_ap_sec_type && 589 (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))) { 590 if ((pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) || 591 (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN)) 592 pHTInfo->bCurrentAMPDUEnable = false; 593 } 594 595 if (!pHTInfo->bRegRT2RTAggregation) { 596 if (pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor) 597 pHTInfo->CurrentAMPDUFactor = 598 pPeerHTCap->MaxRxAMPDUFactor; 599 else 600 pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; 601 602 } else { 603 if (ieee->current_network.bssht.bdRT2RTAggregation) { 604 if (ieee->pairwise_key_type != KEY_TYPE_NA) 605 pHTInfo->CurrentAMPDUFactor = 606 pPeerHTCap->MaxRxAMPDUFactor; 607 else 608 pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K; 609 } else { 610 if (pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K) 611 pHTInfo->CurrentAMPDUFactor = 612 pPeerHTCap->MaxRxAMPDUFactor; 613 else 614 pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K; 615 } 616 } 617 if (pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity) 618 pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; 619 else 620 pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity; 621 if (pHTInfo->IOTAction & HT_IOT_ACT_TX_USE_AMSDU_8K) { 622 pHTInfo->bCurrentAMPDUEnable = false; 623 pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE; 624 pHTInfo->ForcedAMSDUMaxSize = 7935; 625 } 626 pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable; 627 628 if (pPeerHTCap->MCS[0] == 0) 629 pPeerHTCap->MCS[0] = 0xff; 630 631 HTIOTActDetermineRaFunc(ieee, ((pPeerHTCap->MCS[1]) != 0)); 632 633 HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet); 634 635 pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave; 636 if (pHTInfo->PeerMimoPs == MIMO_PS_STATIC) 637 pMcsFilter = MCS_FILTER_1SS; 638 else 639 pMcsFilter = MCS_FILTER_ALL; 640 ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, 641 ieee->dot11HTOperationalRateSet, pMcsFilter); 642 ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; 643 644 pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; 645 } 646 647 void HTInitializeHTInfo(struct rtllib_device *ieee) 648 { 649 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 650 651 netdev_vdbg(ieee->dev, "%s()\n", __func__); 652 pHTInfo->bCurrentHTSupport = false; 653 654 pHTInfo->bCurBW40MHz = false; 655 pHTInfo->bCurTxBW40MHz = false; 656 657 pHTInfo->bCurShortGI20MHz = false; 658 pHTInfo->bCurShortGI40MHz = false; 659 pHTInfo->bForcedShortGI = false; 660 661 pHTInfo->bCurSuppCCK = true; 662 663 pHTInfo->bCurrent_AMSDU_Support = false; 664 pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; 665 pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; 666 pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; 667 668 memset((void *)(&(pHTInfo->SelfHTCap)), 0, 669 sizeof(pHTInfo->SelfHTCap)); 670 memset((void *)(&(pHTInfo->SelfHTInfo)), 0, 671 sizeof(pHTInfo->SelfHTInfo)); 672 memset((void *)(&(pHTInfo->PeerHTCapBuf)), 0, 673 sizeof(pHTInfo->PeerHTCapBuf)); 674 memset((void *)(&(pHTInfo->PeerHTInfoBuf)), 0, 675 sizeof(pHTInfo->PeerHTInfoBuf)); 676 677 pHTInfo->bSwBwInProgress = false; 678 pHTInfo->ChnlOp = CHNLOP_NONE; 679 680 pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE; 681 682 pHTInfo->bCurrentRT2RTAggregation = false; 683 pHTInfo->bCurrentRT2RTLongSlotTime = false; 684 pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; 685 686 pHTInfo->IOTPeer = 0; 687 pHTInfo->IOTAction = 0; 688 pHTInfo->IOTRaFunc = 0; 689 690 { 691 u8 *RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]); 692 693 RegHTSuppRateSets[0] = 0xFF; 694 RegHTSuppRateSets[1] = 0xFF; 695 RegHTSuppRateSets[4] = 0x01; 696 } 697 } 698 699 void HTInitializeBssDesc(struct bss_ht *pBssHT) 700 { 701 702 pBssHT->bdSupportHT = false; 703 memset(pBssHT->bdHTCapBuf, 0, sizeof(pBssHT->bdHTCapBuf)); 704 pBssHT->bdHTCapLen = 0; 705 memset(pBssHT->bdHTInfoBuf, 0, sizeof(pBssHT->bdHTInfoBuf)); 706 pBssHT->bdHTInfoLen = 0; 707 708 pBssHT->bdHTSpecVer = HT_SPEC_VER_IEEE; 709 710 pBssHT->bdRT2RTAggregation = false; 711 pBssHT->bdRT2RTLongSlotTime = false; 712 pBssHT->RT2RT_HT_Mode = (enum rt_ht_capability)0; 713 } 714 715 void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee, 716 struct rtllib_network *pNetwork) 717 { 718 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 719 u8 bIOTAction = 0; 720 721 netdev_vdbg(ieee->dev, "%s()\n", __func__); 722 /* unmark bEnableHT flag here is the same reason why unmarked in 723 * function rtllib_softmac_new_net. WB 2008.09.10 724 */ 725 if (pNetwork->bssht.bdSupportHT) { 726 pHTInfo->bCurrentHTSupport = true; 727 pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bdHTSpecVer; 728 729 if (pNetwork->bssht.bdHTCapLen > 0 && 730 pNetwork->bssht.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf)) 731 memcpy(pHTInfo->PeerHTCapBuf, 732 pNetwork->bssht.bdHTCapBuf, 733 pNetwork->bssht.bdHTCapLen); 734 735 if (pNetwork->bssht.bdHTInfoLen > 0 && 736 pNetwork->bssht.bdHTInfoLen <= 737 sizeof(pHTInfo->PeerHTInfoBuf)) 738 memcpy(pHTInfo->PeerHTInfoBuf, 739 pNetwork->bssht.bdHTInfoBuf, 740 pNetwork->bssht.bdHTInfoLen); 741 742 if (pHTInfo->bRegRT2RTAggregation) { 743 pHTInfo->bCurrentRT2RTAggregation = 744 pNetwork->bssht.bdRT2RTAggregation; 745 pHTInfo->bCurrentRT2RTLongSlotTime = 746 pNetwork->bssht.bdRT2RTLongSlotTime; 747 pHTInfo->RT2RT_HT_Mode = pNetwork->bssht.RT2RT_HT_Mode; 748 } else { 749 pHTInfo->bCurrentRT2RTAggregation = false; 750 pHTInfo->bCurrentRT2RTLongSlotTime = false; 751 pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; 752 } 753 754 HTIOTPeerDetermine(ieee); 755 756 pHTInfo->IOTAction = 0; 757 bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid); 758 if (bIOTAction) 759 pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14; 760 761 bIOTAction = HTIOTActIsDisableMCS15(ieee); 762 if (bIOTAction) 763 pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15; 764 765 bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee); 766 if (bIOTAction) 767 pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS; 768 769 770 bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid); 771 if (bIOTAction) 772 pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO; 773 774 bIOTAction = HTIOTActIsMgntUseCCK6M(ieee, pNetwork); 775 if (bIOTAction) 776 pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M; 777 bIOTAction = HTIOTActIsCCDFsync(ieee); 778 if (bIOTAction) 779 pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC; 780 } else { 781 pHTInfo->bCurrentHTSupport = false; 782 pHTInfo->bCurrentRT2RTAggregation = false; 783 pHTInfo->bCurrentRT2RTLongSlotTime = false; 784 pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; 785 786 pHTInfo->IOTAction = 0; 787 pHTInfo->IOTRaFunc = 0; 788 } 789 } 790 791 void HT_update_self_and_peer_setting(struct rtllib_device *ieee, 792 struct rtllib_network *pNetwork) 793 { 794 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 795 struct ht_info_ele *pPeerHTInfo = 796 (struct ht_info_ele *)pNetwork->bssht.bdHTInfoBuf; 797 798 if (pHTInfo->bCurrentHTSupport) { 799 if (pNetwork->bssht.bdHTInfoLen != 0) 800 pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; 801 } 802 } 803 EXPORT_SYMBOL(HT_update_self_and_peer_setting); 804 805 void HTUseDefaultSetting(struct rtllib_device *ieee) 806 { 807 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 808 809 if (pHTInfo->bEnableHT) { 810 pHTInfo->bCurrentHTSupport = true; 811 pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK; 812 813 pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz; 814 pHTInfo->bCurShortGI20MHz = pHTInfo->bRegShortGI20MHz; 815 816 pHTInfo->bCurShortGI40MHz = pHTInfo->bRegShortGI40MHz; 817 818 if (ieee->iw_mode == IW_MODE_ADHOC) 819 ieee->current_network.qos_data.active = 820 ieee->current_network.qos_data.supported; 821 pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; 822 pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; 823 824 pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; 825 pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; 826 827 pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity; 828 829 HTFilterMCSRate(ieee, ieee->Regdot11TxHTOperationalRateSet, 830 ieee->dot11HTOperationalRateSet); 831 ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, 832 ieee->dot11HTOperationalRateSet, 833 MCS_FILTER_ALL); 834 ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; 835 836 } else { 837 pHTInfo->bCurrentHTSupport = false; 838 } 839 } 840 841 u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame) 842 { 843 if (ieee->pHTInfo->bCurrentHTSupport) { 844 if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) { 845 netdev_dbg(ieee->dev, "HT CONTROL FILED EXIST!!\n"); 846 return true; 847 } 848 } 849 return false; 850 } 851 852 static void HTSetConnectBwModeCallback(struct rtllib_device *ieee) 853 { 854 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 855 856 netdev_vdbg(ieee->dev, "%s()\n", __func__); 857 858 if (pHTInfo->bCurBW40MHz) { 859 if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_UPPER) 860 ieee->set_chan(ieee->dev, 861 ieee->current_network.channel + 2); 862 else if (pHTInfo->CurSTAExtChnlOffset == 863 HT_EXTCHNL_OFFSET_LOWER) 864 ieee->set_chan(ieee->dev, 865 ieee->current_network.channel - 2); 866 else 867 ieee->set_chan(ieee->dev, 868 ieee->current_network.channel); 869 870 ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, 871 pHTInfo->CurSTAExtChnlOffset); 872 } else { 873 ieee->set_chan(ieee->dev, ieee->current_network.channel); 874 ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, 875 HT_EXTCHNL_OFFSET_NO_EXT); 876 } 877 878 pHTInfo->bSwBwInProgress = false; 879 } 880 881 void HTSetConnectBwMode(struct rtllib_device *ieee, 882 enum ht_channel_width Bandwidth, 883 enum ht_extchnl_offset Offset) 884 { 885 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 886 887 if (pHTInfo->bRegBW40MHz == false) 888 return; 889 890 if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 891 Bandwidth = HT_CHANNEL_WIDTH_20; 892 893 if (pHTInfo->bSwBwInProgress) { 894 pr_info("%s: bSwBwInProgress!!\n", __func__); 895 return; 896 } 897 if (Bandwidth == HT_CHANNEL_WIDTH_20_40) { 898 if (ieee->current_network.channel < 2 && 899 Offset == HT_EXTCHNL_OFFSET_LOWER) 900 Offset = HT_EXTCHNL_OFFSET_NO_EXT; 901 if (Offset == HT_EXTCHNL_OFFSET_UPPER || 902 Offset == HT_EXTCHNL_OFFSET_LOWER) { 903 pHTInfo->bCurBW40MHz = true; 904 pHTInfo->CurSTAExtChnlOffset = Offset; 905 } else { 906 pHTInfo->bCurBW40MHz = false; 907 pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; 908 } 909 } else { 910 pHTInfo->bCurBW40MHz = false; 911 pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; 912 } 913 914 pr_info("%s():pHTInfo->bCurBW40MHz:%x\n", __func__, 915 pHTInfo->bCurBW40MHz); 916 917 pHTInfo->bSwBwInProgress = true; 918 919 HTSetConnectBwModeCallback(ieee); 920 } 921