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 120void HTDebugHTCapability(u8 *CapIE, u8 *TitleString) 121{ 122 123 static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; 124 struct ht_capab_ele *pCapELE; 125 126 if (!memcmp(CapIE, EWC11NHTCap, sizeof(EWC11NHTCap))) { 127 RTLLIB_DEBUG(RTLLIB_DL_HT, "EWC IE in %s()\n", __func__); 128 pCapELE = (struct ht_capab_ele *)(&CapIE[4]); 129 } else 130 pCapELE = (struct ht_capab_ele *)(&CapIE[0]); 131 132 RTLLIB_DEBUG(RTLLIB_DL_HT, "<Log HT Capability>. Called by %s\n", 133 TitleString); 134 135 RTLLIB_DEBUG(RTLLIB_DL_HT, "\tSupported Channel Width = %s\n", 136 (pCapELE->ChlWidth) ? "20MHz" : "20/40MHz"); 137 RTLLIB_DEBUG(RTLLIB_DL_HT, "\tSupport Short GI for 20M = %s\n", 138 (pCapELE->ShortGI20Mhz) ? "YES" : "NO"); 139 RTLLIB_DEBUG(RTLLIB_DL_HT, "\tSupport Short GI for 40M = %s\n", 140 (pCapELE->ShortGI40Mhz) ? "YES" : "NO"); 141 RTLLIB_DEBUG(RTLLIB_DL_HT, "\tSupport TX STBC = %s\n", 142 (pCapELE->TxSTBC) ? "YES" : "NO"); 143 RTLLIB_DEBUG(RTLLIB_DL_HT, "\tMax AMSDU Size = %s\n", 144 (pCapELE->MaxAMSDUSize) ? "3839" : "7935"); 145 RTLLIB_DEBUG(RTLLIB_DL_HT, "\tSupport CCK in 20/40 mode = %s\n", 146 (pCapELE->DssCCk) ? "YES" : "NO"); 147 RTLLIB_DEBUG(RTLLIB_DL_HT, "\tMax AMPDU Factor = %d\n", 148 pCapELE->MaxRxAMPDUFactor); 149 RTLLIB_DEBUG(RTLLIB_DL_HT, "\tMPDU Density = %d\n", 150 pCapELE->MPDUDensity); 151 RTLLIB_DEBUG(RTLLIB_DL_HT, "\tMCS Rate Set = [%x][%x][%x][%x][%x]\n", 152 pCapELE->MCS[0], pCapELE->MCS[1], pCapELE->MCS[2], 153 pCapELE->MCS[3], pCapELE->MCS[4]); 154 return; 155 156} 157 158void HTDebugHTInfo(u8 *InfoIE, u8 *TitleString) 159{ 160 161 static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; 162 struct ht_info_ele *pHTInfoEle; 163 164 if (!memcmp(InfoIE, EWC11NHTInfo, sizeof(EWC11NHTInfo))) { 165 RTLLIB_DEBUG(RTLLIB_DL_HT, "EWC IE in %s()\n", __func__); 166 pHTInfoEle = (struct ht_info_ele *)(&InfoIE[4]); 167 } else 168 pHTInfoEle = (struct ht_info_ele *)(&InfoIE[0]); 169 170 171 RTLLIB_DEBUG(RTLLIB_DL_HT, "<Log HT Information Element>. " 172 "Called by %s\n", TitleString); 173 174 RTLLIB_DEBUG(RTLLIB_DL_HT, "\tPrimary channel = %d\n", 175 pHTInfoEle->ControlChl); 176 RTLLIB_DEBUG(RTLLIB_DL_HT, "\tSenondary channel ="); 177 switch (pHTInfoEle->ExtChlOffset) { 178 case 0: 179 RTLLIB_DEBUG(RTLLIB_DL_HT, "Not Present\n"); 180 break; 181 case 1: 182 RTLLIB_DEBUG(RTLLIB_DL_HT, "Upper channel\n"); 183 break; 184 case 2: 185 RTLLIB_DEBUG(RTLLIB_DL_HT, "Reserved. Eooro!!!\n"); 186 break; 187 case 3: 188 RTLLIB_DEBUG(RTLLIB_DL_HT, "Lower Channel\n"); 189 break; 190 } 191 RTLLIB_DEBUG(RTLLIB_DL_HT, "\tRecommended channel width = %s\n", 192 (pHTInfoEle->RecommemdedTxWidth) ? "20Mhz" : "40Mhz"); 193 194 RTLLIB_DEBUG(RTLLIB_DL_HT, "\tOperation mode for protection = "); 195 switch (pHTInfoEle->OptMode) { 196 case 0: 197 RTLLIB_DEBUG(RTLLIB_DL_HT, "No Protection\n"); 198 break; 199 case 1: 200 RTLLIB_DEBUG(RTLLIB_DL_HT, "HT non-member protection mode\n"); 201 break; 202 case 2: 203 RTLLIB_DEBUG(RTLLIB_DL_HT, "Suggest to open protection\n"); 204 break; 205 case 3: 206 RTLLIB_DEBUG(RTLLIB_DL_HT, "HT mixed mode\n"); 207 break; 208 } 209 210 RTLLIB_DEBUG(RTLLIB_DL_HT, "\tBasic MCS Rate Set = [%x][%x][%x][%x]" 211 "[%x]\n", pHTInfoEle->BasicMSC[0], pHTInfoEle->BasicMSC[1], 212 pHTInfoEle->BasicMSC[2], pHTInfoEle->BasicMSC[3], 213 pHTInfoEle->BasicMSC[4]); 214} 215 216static bool IsHTHalfNmode40Bandwidth(struct rtllib_device *ieee) 217{ 218 bool retValue = false; 219 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 220 221 if (pHTInfo->bCurrentHTSupport == false) 222 retValue = false; 223 else if (pHTInfo->bRegBW40MHz == false) 224 retValue = false; 225 else if (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 226 retValue = false; 227 else if (((struct ht_capab_ele *)(pHTInfo->PeerHTCapBuf))->ChlWidth) 228 retValue = true; 229 else 230 retValue = false; 231 232 return retValue; 233} 234 235static bool IsHTHalfNmodeSGI(struct rtllib_device *ieee, bool is40MHz) 236{ 237 bool retValue = false; 238 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 239 240 if (pHTInfo->bCurrentHTSupport == false) 241 retValue = false; 242 else if (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 243 retValue = false; 244 else if (is40MHz) { 245 if (((struct ht_capab_ele *) 246 (pHTInfo->PeerHTCapBuf))->ShortGI40Mhz) 247 retValue = true; 248 else 249 retValue = false; 250 } else { 251 if (((struct ht_capab_ele *) 252 (pHTInfo->PeerHTCapBuf))->ShortGI20Mhz) 253 retValue = true; 254 else 255 retValue = false; 256 } 257 258 return retValue; 259} 260 261u16 HTHalfMcsToDataRate(struct rtllib_device *ieee, u8 nMcsRate) 262{ 263 264 u8 is40MHz; 265 u8 isShortGI; 266 267 is40MHz = (IsHTHalfNmode40Bandwidth(ieee)) ? 1 : 0; 268 isShortGI = (IsHTHalfNmodeSGI(ieee, is40MHz)) ? 1 : 0; 269 270 return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate & 0x7f)]; 271} 272 273 274u16 HTMcsToDataRate(struct rtllib_device *ieee, u8 nMcsRate) 275{ 276 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 277 278 u8 is40MHz = (pHTInfo->bCurBW40MHz) ? 1 : 0; 279 u8 isShortGI = (pHTInfo->bCurBW40MHz) ? 280 ((pHTInfo->bCurShortGI40MHz) ? 1 : 0) : 281 ((pHTInfo->bCurShortGI20MHz) ? 1 : 0); 282 return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate & 0x7f)]; 283} 284 285u16 TxCountToDataRate(struct rtllib_device *ieee, u8 nDataRate) 286{ 287 u16 CCKOFDMRate[12] = {0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 288 0x24, 0x30, 0x48, 0x60, 0x6c}; 289 u8 is40MHz = 0; 290 u8 isShortGI = 0; 291 292 if (nDataRate < 12) { 293 return CCKOFDMRate[nDataRate]; 294 } else { 295 if (nDataRate >= 0x10 && nDataRate <= 0x1f) { 296 is40MHz = 0; 297 isShortGI = 0; 298 } else if (nDataRate >= 0x20 && nDataRate <= 0x2f) { 299 is40MHz = 1; 300 isShortGI = 0; 301 302 } else if (nDataRate >= 0x30 && nDataRate <= 0x3f) { 303 is40MHz = 0; 304 isShortGI = 1; 305 } else if (nDataRate >= 0x40 && nDataRate <= 0x4f) { 306 is40MHz = 1; 307 isShortGI = 1; 308 } 309 return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate&0xf]; 310 } 311} 312 313bool IsHTHalfNmodeAPs(struct rtllib_device *ieee) 314{ 315 bool retValue = false; 316 struct rtllib_network *net = &ieee->current_network; 317 318 if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) || 319 (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) || 320 (memcmp(net->bssid, PCI_RALINK, 3) == 0) || 321 (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) || 322 (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) || 323 (net->ralink_cap_exist)) 324 retValue = true; 325 else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) || 326 !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) || 327 !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) || 328 (net->broadcom_cap_exist)) 329 retValue = true; 330 else if (net->bssht.bdRT2RTAggregation) 331 retValue = true; 332 else 333 retValue = false; 334 335 return retValue; 336} 337 338static void HTIOTPeerDetermine(struct rtllib_device *ieee) 339{ 340 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 341 struct rtllib_network *net = &ieee->current_network; 342 343 if (net->bssht.bdRT2RTAggregation) { 344 pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK; 345 if (net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_92SE) 346 pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK_92SE; 347 if (net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_SOFTAP) 348 pHTInfo->IOTPeer = HT_IOT_PEER_92U_SOFTAP; 349 } else if (net->broadcom_cap_exist) 350 pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; 351 else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) || 352 !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) || 353 !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)) 354 pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; 355 else if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) || 356 (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) || 357 (memcmp(net->bssid, PCI_RALINK, 3) == 0) || 358 (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) || 359 (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) || 360 net->ralink_cap_exist) 361 pHTInfo->IOTPeer = HT_IOT_PEER_RALINK; 362 else if ((net->atheros_cap_exist) || 363 (memcmp(net->bssid, DLINK_ATHEROS_1, 3) == 0) || 364 (memcmp(net->bssid, DLINK_ATHEROS_2, 3) == 0)) 365 pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS; 366 else if ((memcmp(net->bssid, CISCO_BROADCOM, 3) == 0) || 367 net->cisco_cap_exist) 368 pHTInfo->IOTPeer = HT_IOT_PEER_CISCO; 369 else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) || 370 net->marvell_cap_exist) 371 pHTInfo->IOTPeer = HT_IOT_PEER_MARVELL; 372 else if (net->airgo_cap_exist) 373 pHTInfo->IOTPeer = HT_IOT_PEER_AIRGO; 374 else 375 pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; 376 377 RTLLIB_DEBUG(RTLLIB_DL_IOT, "Joseph debug!! IOTPEER: %x\n", 378 pHTInfo->IOTPeer); 379} 380 381static u8 HTIOTActIsDisableMCS14(struct rtllib_device *ieee, u8 *PeerMacAddr) 382{ 383 return 0; 384} 385 386 387static bool HTIOTActIsDisableMCS15(struct rtllib_device *ieee) 388{ 389 bool retValue = false; 390 391 return retValue; 392} 393 394static bool HTIOTActIsDisableMCSTwoSpatialStream(struct rtllib_device *ieee) 395{ 396 return false; 397} 398 399static u8 HTIOTActIsDisableEDCATurbo(struct rtllib_device *ieee, u8 *PeerMacAddr) 400{ 401 return false; 402} 403 404static u8 HTIOTActIsMgntUseCCK6M(struct rtllib_device *ieee, 405 struct rtllib_network *network) 406{ 407 u8 retValue = 0; 408 409 410 if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) 411 retValue = 1; 412 413 return retValue; 414} 415 416static u8 HTIOTActIsCCDFsync(struct rtllib_device *ieee) 417{ 418 u8 retValue = 0; 419 420 if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) 421 retValue = 1; 422 return retValue; 423} 424 425static void HTIOTActDetermineRaFunc(struct rtllib_device *ieee, bool bPeerRx2ss) 426{ 427 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 428 429 pHTInfo->IOTRaFunc &= HT_IOT_RAFUNC_DISABLE_ALL; 430 431 if (pHTInfo->IOTPeer == HT_IOT_PEER_RALINK && !bPeerRx2ss) 432 pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_PEER_1R; 433 434 if (pHTInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE) 435 pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_TX_AMSDU; 436 437} 438 439void HTResetIOTSetting(struct rt_hi_throughput *pHTInfo) 440{ 441 pHTInfo->IOTAction = 0; 442 pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; 443 pHTInfo->IOTRaFunc = 0; 444} 445 446void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap, 447 u8 *len, u8 IsEncrypt, bool bAssoc) 448{ 449 struct rt_hi_throughput *pHT = ieee->pHTInfo; 450 struct ht_capab_ele *pCapELE = NULL; 451 452 if ((posHTCap == NULL) || (pHT == NULL)) { 453 RTLLIB_DEBUG(RTLLIB_DL_ERR, "posHTCap or pHTInfo can't be " 454 "null in HTConstructCapabilityElement()\n"); 455 return; 456 } 457 memset(posHTCap, 0, *len); 458 459 if ((bAssoc) && (pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)) { 460 u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; 461 462 memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap)); 463 pCapELE = (struct ht_capab_ele *)&(posHTCap[4]); 464 *len = 30 + 2; 465 } else { 466 pCapELE = (struct ht_capab_ele *)posHTCap; 467 *len = 26 + 2; 468 } 469 470 pCapELE->AdvCoding = 0; 471 if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 472 pCapELE->ChlWidth = 0; 473 else 474 pCapELE->ChlWidth = (pHT->bRegBW40MHz ? 1 : 0); 475 476 pCapELE->MimoPwrSave = pHT->SelfMimoPs; 477 pCapELE->GreenField = 0; 478 pCapELE->ShortGI20Mhz = 1; 479 pCapELE->ShortGI40Mhz = 1; 480 481 pCapELE->TxSTBC = 1; 482 pCapELE->RxSTBC = 0; 483 pCapELE->DelayBA = 0; 484 pCapELE->MaxAMSDUSize = (MAX_RECEIVE_BUFFER_SIZE >= 7935) ? 1 : 0; 485 pCapELE->DssCCk = ((pHT->bRegBW40MHz) ? (pHT->bRegSuppCCK ? 1 : 0) : 0); 486 pCapELE->PSMP = 0; 487 pCapELE->LSigTxopProtect = 0; 488 489 490 RTLLIB_DEBUG(RTLLIB_DL_HT, "TX HT cap/info ele BW=%d MaxAMSDUSize:%d " 491 "DssCCk:%d\n", pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, 492 pCapELE->DssCCk); 493 494 if (IsEncrypt) { 495 pCapELE->MPDUDensity = 7; 496 pCapELE->MaxRxAMPDUFactor = 2; 497 } else { 498 pCapELE->MaxRxAMPDUFactor = 3; 499 pCapELE->MPDUDensity = 0; 500 } 501 502 memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16); 503 memset(&pCapELE->ExtHTCapInfo, 0, 2); 504 memset(pCapELE->TxBFCap, 0, 4); 505 506 pCapELE->ASCap = 0; 507 508 if (bAssoc) { 509 if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15) 510 pCapELE->MCS[1] &= 0x7f; 511 512 if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14) 513 pCapELE->MCS[1] &= 0xbf; 514 515 if (pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS) 516 pCapELE->MCS[1] &= 0x00; 517 518 if (pHT->IOTAction & HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI) 519 pCapELE->ShortGI40Mhz = 0; 520 521 if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) { 522 pCapELE->ChlWidth = 0; 523 pCapELE->MCS[1] = 0; 524 } 525 } 526} 527 528void HTConstructInfoElement(struct rtllib_device *ieee, u8 *posHTInfo, 529 u8 *len, u8 IsEncrypt) 530{ 531 struct rt_hi_throughput *pHT = ieee->pHTInfo; 532 struct ht_info_ele *pHTInfoEle = (struct ht_info_ele *)posHTInfo; 533 534 if ((posHTInfo == NULL) || (pHTInfoEle == NULL)) { 535 RTLLIB_DEBUG(RTLLIB_DL_ERR, "posHTInfo or pHTInfoEle can't be " 536 "null in HTConstructInfoElement()\n"); 537 return; 538 } 539 540 memset(posHTInfo, 0, *len); 541 if ((ieee->iw_mode == IW_MODE_ADHOC) || 542 (ieee->iw_mode == IW_MODE_MASTER)) { 543 pHTInfoEle->ControlChl = ieee->current_network.channel; 544 pHTInfoEle->ExtChlOffset = ((pHT->bRegBW40MHz == false) ? 545 HT_EXTCHNL_OFFSET_NO_EXT : 546 (ieee->current_network.channel <= 6) 547 ? HT_EXTCHNL_OFFSET_UPPER : 548 HT_EXTCHNL_OFFSET_LOWER); 549 pHTInfoEle->RecommemdedTxWidth = pHT->bRegBW40MHz; 550 pHTInfoEle->RIFS = 0; 551 pHTInfoEle->PSMPAccessOnly = 0; 552 pHTInfoEle->SrvIntGranularity = 0; 553 pHTInfoEle->OptMode = pHT->CurrentOpMode; 554 pHTInfoEle->NonGFDevPresent = 0; 555 pHTInfoEle->DualBeacon = 0; 556 pHTInfoEle->SecondaryBeacon = 0; 557 pHTInfoEle->LSigTxopProtectFull = 0; 558 pHTInfoEle->PcoActive = 0; 559 pHTInfoEle->PcoPhase = 0; 560 561 memset(pHTInfoEle->BasicMSC, 0, 16); 562 563 564 *len = 22 + 2; 565 566 } else { 567 *len = 0; 568 } 569} 570 571void HTConstructRT2RTAggElement(struct rtllib_device *ieee, u8 *posRT2RTAgg, 572 u8 *len) 573{ 574 if (posRT2RTAgg == NULL) { 575 RTLLIB_DEBUG(RTLLIB_DL_ERR, "posRT2RTAgg can't be null in " 576 "HTConstructRT2RTAggElement()\n"); 577 return; 578 } 579 memset(posRT2RTAgg, 0, *len); 580 *posRT2RTAgg++ = 0x00; 581 *posRT2RTAgg++ = 0xe0; 582 *posRT2RTAgg++ = 0x4c; 583 *posRT2RTAgg++ = 0x02; 584 *posRT2RTAgg++ = 0x01; 585 586 *posRT2RTAgg = 0x30; 587 588 if (ieee->bSupportRemoteWakeUp) 589 *posRT2RTAgg |= RT_HT_CAP_USE_WOW; 590 591 *len = 6 + 2; 592} 593 594static u8 HT_PickMCSRate(struct rtllib_device *ieee, u8 *pOperateMCS) 595{ 596 u8 i; 597 598 if (pOperateMCS == NULL) { 599 RTLLIB_DEBUG(RTLLIB_DL_ERR, "pOperateMCS can't be null" 600 " in HT_PickMCSRate()\n"); 601 return false; 602 } 603 604 switch (ieee->mode) { 605 case IEEE_A: 606 case IEEE_B: 607 case IEEE_G: 608 for (i = 0; i <= 15; i++) 609 pOperateMCS[i] = 0; 610 break; 611 case IEEE_N_24G: 612 case IEEE_N_5G: 613 pOperateMCS[0] &= RATE_ADPT_1SS_MASK; 614 pOperateMCS[1] &= RATE_ADPT_2SS_MASK; 615 pOperateMCS[3] &= RATE_ADPT_MCS32_MASK; 616 break; 617 default: 618 break; 619 620 } 621 622 return true; 623} 624 625u8 HTGetHighestMCSRate(struct rtllib_device *ieee, u8 *pMCSRateSet, 626 u8 *pMCSFilter) 627{ 628 u8 i, j; 629 u8 bitMap; 630 u8 mcsRate = 0; 631 u8 availableMcsRate[16]; 632 633 if (pMCSRateSet == NULL || pMCSFilter == NULL) { 634 RTLLIB_DEBUG(RTLLIB_DL_ERR, "pMCSRateSet or pMCSFilter can't " 635 "be null in HTGetHighestMCSRate()\n"); 636 return false; 637 } 638 for (i = 0; i < 16; i++) 639 availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i]; 640 641 for (i = 0; i < 16; i++) { 642 if (availableMcsRate[i] != 0) 643 break; 644 } 645 if (i == 16) 646 return false; 647 648 for (i = 0; i < 16; i++) { 649 if (availableMcsRate[i] != 0) { 650 bitMap = availableMcsRate[i]; 651 for (j = 0; j < 8; j++) { 652 if ((bitMap%2) != 0) { 653 if (HTMcsToDataRate(ieee, (8*i+j)) > 654 HTMcsToDataRate(ieee, mcsRate)) 655 mcsRate = (8*i+j); 656 } 657 bitMap = bitMap>>1; 658 } 659 } 660 } 661 return mcsRate | 0x80; 662} 663 664u8 HTFilterMCSRate(struct rtllib_device *ieee, u8 *pSupportMCS, u8 *pOperateMCS) 665{ 666 667 u8 i; 668 669 for (i = 0; i <= 15; i++) 670 pOperateMCS[i] = ieee->Regdot11TxHTOperationalRateSet[i] & 671 pSupportMCS[i]; 672 673 HT_PickMCSRate(ieee, pOperateMCS); 674 675 if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 676 pOperateMCS[1] = 0; 677 678 for (i = 2; i <= 15; i++) 679 pOperateMCS[i] = 0; 680 681 return true; 682} 683 684void HTSetConnectBwMode(struct rtllib_device *ieee, 685 enum ht_channel_width Bandwidth, 686 enum ht_extchnl_offset Offset); 687 688void HTOnAssocRsp(struct rtllib_device *ieee) 689{ 690 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 691 struct ht_capab_ele *pPeerHTCap = NULL; 692 struct ht_info_ele *pPeerHTInfo = NULL; 693 u16 nMaxAMSDUSize = 0; 694 u8 *pMcsFilter = NULL; 695 696 static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; 697 static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; 698 699 if (pHTInfo->bCurrentHTSupport == false) { 700 RTLLIB_DEBUG(RTLLIB_DL_ERR, "<=== HTOnAssocRsp(): " 701 "HT_DISABLE\n"); 702 return; 703 } 704 RTLLIB_DEBUG(RTLLIB_DL_HT, "===> HTOnAssocRsp_wq(): HT_ENABLE\n"); 705 706 if (!memcmp(pHTInfo->PeerHTCapBuf, EWC11NHTCap, sizeof(EWC11NHTCap))) 707 pPeerHTCap = (struct ht_capab_ele *)(&pHTInfo->PeerHTCapBuf[4]); 708 else 709 pPeerHTCap = (struct ht_capab_ele *)(pHTInfo->PeerHTCapBuf); 710 711 if (!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo))) 712 pPeerHTInfo = (struct ht_info_ele *) 713 (&pHTInfo->PeerHTInfoBuf[4]); 714 else 715 pPeerHTInfo = (struct ht_info_ele *)(pHTInfo->PeerHTInfoBuf); 716 717 RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA | RTLLIB_DL_HT, pPeerHTCap, 718 sizeof(struct ht_capab_ele)); 719 HTSetConnectBwMode(ieee, (enum ht_channel_width)(pPeerHTCap->ChlWidth), 720 (enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset)); 721 pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ? 722 true : false); 723 724 pHTInfo->bCurShortGI20MHz = ((pHTInfo->bRegShortGI20MHz) ? 725 ((pPeerHTCap->ShortGI20Mhz == 1) ? 726 true : false) : false); 727 pHTInfo->bCurShortGI40MHz = ((pHTInfo->bRegShortGI40MHz) ? 728 ((pPeerHTCap->ShortGI40Mhz == 1) ? 729 true : false) : false); 730 731 pHTInfo->bCurSuppCCK = ((pHTInfo->bRegSuppCCK) ? 732 ((pPeerHTCap->DssCCk == 1) ? true : 733 false) : false); 734 735 736 pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; 737 738 nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize == 0) ? 3839 : 7935; 739 740 if (pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize) 741 pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize; 742 else 743 pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; 744 745 pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; 746 if (ieee->rtllib_ap_sec_type && 747 (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))) { 748 if ((pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) || 749 (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN)) 750 pHTInfo->bCurrentAMPDUEnable = false; 751 } 752 753 if (!pHTInfo->bRegRT2RTAggregation) { 754 if (pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor) 755 pHTInfo->CurrentAMPDUFactor = 756 pPeerHTCap->MaxRxAMPDUFactor; 757 else 758 pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; 759 760 } else { 761 if (ieee->current_network.bssht.bdRT2RTAggregation) { 762 if (ieee->pairwise_key_type != KEY_TYPE_NA) 763 pHTInfo->CurrentAMPDUFactor = 764 pPeerHTCap->MaxRxAMPDUFactor; 765 else 766 pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K; 767 } else { 768 if (pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K) 769 pHTInfo->CurrentAMPDUFactor = 770 pPeerHTCap->MaxRxAMPDUFactor; 771 else 772 pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K; 773 } 774 } 775 if (pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity) 776 pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; 777 else 778 pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity; 779 if (pHTInfo->IOTAction & HT_IOT_ACT_TX_USE_AMSDU_8K) { 780 pHTInfo->bCurrentAMPDUEnable = false; 781 pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE; 782 pHTInfo->ForcedAMSDUMaxSize = 7935; 783 } 784 pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable; 785 786 if (pPeerHTCap->MCS[0] == 0) 787 pPeerHTCap->MCS[0] = 0xff; 788 789 HTIOTActDetermineRaFunc(ieee, ((pPeerHTCap->MCS[1]) != 0)); 790 791 HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet); 792 793 pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave; 794 if (pHTInfo->PeerMimoPs == MIMO_PS_STATIC) 795 pMcsFilter = MCS_FILTER_1SS; 796 else 797 pMcsFilter = MCS_FILTER_ALL; 798 ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, 799 ieee->dot11HTOperationalRateSet, pMcsFilter); 800 ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; 801 802 pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; 803} 804 805void HTInitializeHTInfo(struct rtllib_device *ieee) 806{ 807 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 808 809 RTLLIB_DEBUG(RTLLIB_DL_HT, "===========>%s()\n", __func__); 810 pHTInfo->bCurrentHTSupport = false; 811 812 pHTInfo->bCurBW40MHz = false; 813 pHTInfo->bCurTxBW40MHz = false; 814 815 pHTInfo->bCurShortGI20MHz = false; 816 pHTInfo->bCurShortGI40MHz = false; 817 pHTInfo->bForcedShortGI = false; 818 819 pHTInfo->bCurSuppCCK = true; 820 821 pHTInfo->bCurrent_AMSDU_Support = false; 822 pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; 823 pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; 824 pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; 825 826 memset((void *)(&(pHTInfo->SelfHTCap)), 0, 827 sizeof(pHTInfo->SelfHTCap)); 828 memset((void *)(&(pHTInfo->SelfHTInfo)), 0, 829 sizeof(pHTInfo->SelfHTInfo)); 830 memset((void *)(&(pHTInfo->PeerHTCapBuf)), 0, 831 sizeof(pHTInfo->PeerHTCapBuf)); 832 memset((void *)(&(pHTInfo->PeerHTInfoBuf)), 0, 833 sizeof(pHTInfo->PeerHTInfoBuf)); 834 835 pHTInfo->bSwBwInProgress = false; 836 pHTInfo->ChnlOp = CHNLOP_NONE; 837 838 pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE; 839 840 pHTInfo->bCurrentRT2RTAggregation = false; 841 pHTInfo->bCurrentRT2RTLongSlotTime = false; 842 pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; 843 844 pHTInfo->IOTPeer = 0; 845 pHTInfo->IOTAction = 0; 846 pHTInfo->IOTRaFunc = 0; 847 848 { 849 u8 *RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]); 850 851 RegHTSuppRateSets[0] = 0xFF; 852 RegHTSuppRateSets[1] = 0xFF; 853 RegHTSuppRateSets[4] = 0x01; 854 } 855} 856 857void HTInitializeBssDesc(struct bss_ht *pBssHT) 858{ 859 860 pBssHT->bdSupportHT = false; 861 memset(pBssHT->bdHTCapBuf, 0, sizeof(pBssHT->bdHTCapBuf)); 862 pBssHT->bdHTCapLen = 0; 863 memset(pBssHT->bdHTInfoBuf, 0, sizeof(pBssHT->bdHTInfoBuf)); 864 pBssHT->bdHTInfoLen = 0; 865 866 pBssHT->bdHTSpecVer = HT_SPEC_VER_IEEE; 867 868 pBssHT->bdRT2RTAggregation = false; 869 pBssHT->bdRT2RTLongSlotTime = false; 870 pBssHT->RT2RT_HT_Mode = (enum rt_ht_capability)0; 871} 872 873void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee, 874 struct rtllib_network *pNetwork) 875{ 876 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 877 u8 bIOTAction = 0; 878 879 RTLLIB_DEBUG(RTLLIB_DL_HT, "==============>%s()\n", __func__); 880 /* unmark bEnableHT flag here is the same reason why unmarked in 881 * function rtllib_softmac_new_net. WB 2008.09.10*/ 882 if (pNetwork->bssht.bdSupportHT) { 883 pHTInfo->bCurrentHTSupport = true; 884 pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bdHTSpecVer; 885 886 if (pNetwork->bssht.bdHTCapLen > 0 && 887 pNetwork->bssht.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf)) 888 memcpy(pHTInfo->PeerHTCapBuf, 889 pNetwork->bssht.bdHTCapBuf, 890 pNetwork->bssht.bdHTCapLen); 891 892 if (pNetwork->bssht.bdHTInfoLen > 0 && 893 pNetwork->bssht.bdHTInfoLen <= 894 sizeof(pHTInfo->PeerHTInfoBuf)) 895 memcpy(pHTInfo->PeerHTInfoBuf, 896 pNetwork->bssht.bdHTInfoBuf, 897 pNetwork->bssht.bdHTInfoLen); 898 899 if (pHTInfo->bRegRT2RTAggregation) { 900 pHTInfo->bCurrentRT2RTAggregation = 901 pNetwork->bssht.bdRT2RTAggregation; 902 pHTInfo->bCurrentRT2RTLongSlotTime = 903 pNetwork->bssht.bdRT2RTLongSlotTime; 904 pHTInfo->RT2RT_HT_Mode = pNetwork->bssht.RT2RT_HT_Mode; 905 } else { 906 pHTInfo->bCurrentRT2RTAggregation = false; 907 pHTInfo->bCurrentRT2RTLongSlotTime = false; 908 pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; 909 } 910 911 HTIOTPeerDetermine(ieee); 912 913 pHTInfo->IOTAction = 0; 914 bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid); 915 if (bIOTAction) 916 pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14; 917 918 bIOTAction = HTIOTActIsDisableMCS15(ieee); 919 if (bIOTAction) 920 pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15; 921 922 bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee); 923 if (bIOTAction) 924 pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS; 925 926 927 bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid); 928 if (bIOTAction) 929 pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO; 930 931 bIOTAction = HTIOTActIsMgntUseCCK6M(ieee, pNetwork); 932 if (bIOTAction) 933 pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M; 934 bIOTAction = HTIOTActIsCCDFsync(ieee); 935 if (bIOTAction) 936 pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC; 937 } else { 938 pHTInfo->bCurrentHTSupport = false; 939 pHTInfo->bCurrentRT2RTAggregation = false; 940 pHTInfo->bCurrentRT2RTLongSlotTime = false; 941 pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; 942 943 pHTInfo->IOTAction = 0; 944 pHTInfo->IOTRaFunc = 0; 945 } 946} 947 948void HT_update_self_and_peer_setting(struct rtllib_device *ieee, 949 struct rtllib_network *pNetwork) 950{ 951 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 952 struct ht_info_ele *pPeerHTInfo = 953 (struct ht_info_ele *)pNetwork->bssht.bdHTInfoBuf; 954 955 if (pHTInfo->bCurrentHTSupport) { 956 if (pNetwork->bssht.bdHTInfoLen != 0) 957 pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; 958 } 959} 960EXPORT_SYMBOL(HT_update_self_and_peer_setting); 961 962void HTUseDefaultSetting(struct rtllib_device *ieee) 963{ 964 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 965 966 if (pHTInfo->bEnableHT) { 967 pHTInfo->bCurrentHTSupport = true; 968 pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK; 969 970 pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz; 971 pHTInfo->bCurShortGI20MHz = pHTInfo->bRegShortGI20MHz; 972 973 pHTInfo->bCurShortGI40MHz = pHTInfo->bRegShortGI40MHz; 974 975 if (ieee->iw_mode == IW_MODE_ADHOC) 976 ieee->current_network.qos_data.active = 977 ieee->current_network.qos_data.supported; 978 pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; 979 pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; 980 981 pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; 982 pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; 983 984 pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity; 985 986 HTFilterMCSRate(ieee, ieee->Regdot11TxHTOperationalRateSet, 987 ieee->dot11HTOperationalRateSet); 988 ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, 989 ieee->dot11HTOperationalRateSet, 990 MCS_FILTER_ALL); 991 ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; 992 993 } else { 994 pHTInfo->bCurrentHTSupport = false; 995 } 996} 997 998u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame) 999{ 1000 if (ieee->pHTInfo->bCurrentHTSupport) { 1001 if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) { 1002 RTLLIB_DEBUG(RTLLIB_DL_HT, "HT CONTROL FILED " 1003 "EXIST!!\n"); 1004 return true; 1005 } 1006 } 1007 return false; 1008} 1009 1010static void HTSetConnectBwModeCallback(struct rtllib_device *ieee) 1011{ 1012 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 1013 1014 RTLLIB_DEBUG(RTLLIB_DL_HT, "======>%s()\n", __func__); 1015 if (pHTInfo->bCurBW40MHz) { 1016 if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_UPPER) 1017 ieee->set_chan(ieee->dev, 1018 ieee->current_network.channel + 2); 1019 else if (pHTInfo->CurSTAExtChnlOffset == 1020 HT_EXTCHNL_OFFSET_LOWER) 1021 ieee->set_chan(ieee->dev, 1022 ieee->current_network.channel - 2); 1023 else 1024 ieee->set_chan(ieee->dev, 1025 ieee->current_network.channel); 1026 1027 ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, 1028 pHTInfo->CurSTAExtChnlOffset); 1029 } else { 1030 ieee->set_chan(ieee->dev, ieee->current_network.channel); 1031 ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, 1032 HT_EXTCHNL_OFFSET_NO_EXT); 1033 } 1034 1035 pHTInfo->bSwBwInProgress = false; 1036} 1037 1038void HTSetConnectBwMode(struct rtllib_device *ieee, 1039 enum ht_channel_width Bandwidth, 1040 enum ht_extchnl_offset Offset) 1041{ 1042 struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; 1043 1044 if (pHTInfo->bRegBW40MHz == false) 1045 return; 1046 1047 if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 1048 Bandwidth = HT_CHANNEL_WIDTH_20; 1049 1050 if (pHTInfo->bSwBwInProgress) { 1051 pr_info("%s: bSwBwInProgress!!\n", __func__); 1052 return; 1053 } 1054 if (Bandwidth == HT_CHANNEL_WIDTH_20_40) { 1055 if (ieee->current_network.channel < 2 && 1056 Offset == HT_EXTCHNL_OFFSET_LOWER) 1057 Offset = HT_EXTCHNL_OFFSET_NO_EXT; 1058 if (Offset == HT_EXTCHNL_OFFSET_UPPER || 1059 Offset == HT_EXTCHNL_OFFSET_LOWER) { 1060 pHTInfo->bCurBW40MHz = true; 1061 pHTInfo->CurSTAExtChnlOffset = Offset; 1062 } else { 1063 pHTInfo->bCurBW40MHz = false; 1064 pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; 1065 } 1066 } else { 1067 pHTInfo->bCurBW40MHz = false; 1068 pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; 1069 } 1070 1071 pr_info("%s():pHTInfo->bCurBW40MHz:%x\n", __func__, 1072 pHTInfo->bCurBW40MHz); 1073 1074 pHTInfo->bSwBwInProgress = true; 1075 1076 HTSetConnectBwModeCallback(ieee); 1077} 1078