rtl819x_HTProc.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410
  1. //As this function is mainly ported from Windows driver, so leave the name little changed. If any confusion caused, tell me. Created by WB. 2008.05.08
  2. #include "ieee80211.h"
  3. #include "rtl819x_HT.h"
  4. u8 MCS_FILTER_ALL[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  5. u8 MCS_FILTER_1SS[16] = {0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  6. u16 MCS_DATA_RATE[2][2][77] =
  7. { { {13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78 ,104, 156, 208, 234, 260,
  8. 39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416, 468, 520,
  9. 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182, 182, 208, 156, 195,
  10. 195, 234, 273, 273, 312, 130, 156, 181, 156, 181, 208, 234, 208, 234, 260, 260,
  11. 286, 195, 234, 273, 234, 273, 312, 351, 312, 351, 390, 390, 429}, // Long GI, 20MHz
  12. {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289,
  13. 43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520, 578,
  14. 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231, 173, 217,
  15. 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260, 231, 260, 289, 289,
  16. 318, 217, 260, 303, 260, 303, 347, 390, 347, 390, 433, 433, 477} }, // Short GI, 20MHz
  17. { {27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540,
  18. 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648, 864, 972, 1080,
  19. 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324, 378, 378, 432, 324, 405,
  20. 405, 486, 567, 567, 648, 270, 324, 378, 324, 378, 432, 486, 432, 486, 540, 540,
  21. 594, 405, 486, 567, 486, 567, 648, 729, 648, 729, 810, 810, 891}, // Long GI, 40MHz
  22. {30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600,
  23. 90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720, 960, 1080, 1200,
  24. 13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360, 420, 420, 480, 360, 450,
  25. 450, 540, 630, 630, 720, 300, 360, 420, 360, 420, 480, 540, 480, 540, 600, 600,
  26. 660, 450, 540, 630, 540, 630, 720, 810, 720, 810, 900, 900, 990} } // Short GI, 40MHz
  27. };
  28. static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
  29. static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
  30. static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
  31. static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f};
  32. static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f}; //cosa 03202008
  33. static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
  34. static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
  35. static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e};
  36. static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
  37. //static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0};
  38. static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
  39. // 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the
  40. // code in other place??
  41. //static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96};
  42. /********************************************************************************************************************
  43. *function: This function update default settings in pHTInfo structure
  44. * input: PRT_HIGH_THROUGHPUT pHTInfo
  45. * output: none
  46. * return: none
  47. * notice: These value need be modified if any changes.
  48. * *****************************************************************************************************************/
  49. void HTUpdateDefaultSetting(struct ieee80211_device *ieee)
  50. {
  51. PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
  52. //const typeof( ((struct ieee80211_device *)0)->pHTInfo ) *__mptr = &pHTInfo;
  53. //printk("pHTinfo:%p, &pHTinfo:%p, mptr:%p, offsetof:%x\n", pHTInfo, &pHTInfo, __mptr, offsetof(struct ieee80211_device, pHTInfo));
  54. //printk("===>ieee:%p,\n", ieee);
  55. // ShortGI support
  56. pHTInfo->bRegShortGI20MHz= 1;
  57. pHTInfo->bRegShortGI40MHz= 1;
  58. // 40MHz channel support
  59. pHTInfo->bRegBW40MHz = 1;
  60. // CCK rate support in 40MHz channel
  61. if(pHTInfo->bRegBW40MHz)
  62. pHTInfo->bRegSuppCCK = 1;
  63. else
  64. pHTInfo->bRegSuppCCK = true;
  65. // AMSDU related
  66. pHTInfo->nAMSDU_MaxSize = 7935UL;
  67. pHTInfo->bAMSDU_Support = 0;
  68. // AMPDU related
  69. pHTInfo->bAMPDUEnable = 1;
  70. pHTInfo->AMPDU_Factor = 2; //// 0: 2n13(8K), 1:2n14(16K), 2:2n15(32K), 3:2n16(64k)
  71. pHTInfo->MPDU_Density = 0;// 0: No restriction, 1: 1/8usec, 2: 1/4usec, 3: 1/2usec, 4: 1usec, 5: 2usec, 6: 4usec, 7:8usec
  72. // MIMO Power Save
  73. pHTInfo->SelfMimoPs = 3;// 0: Static Mimo Ps, 1: Dynamic Mimo Ps, 3: No Limitation, 2: Reserved(Set to 3 automatically.)
  74. if(pHTInfo->SelfMimoPs == 2)
  75. pHTInfo->SelfMimoPs = 3;
  76. // 8190 only. Assign rate operation mode to firmware
  77. ieee->bTxDisableRateFallBack = 0;
  78. ieee->bTxUseDriverAssingedRate = 0;
  79. #ifdef TO_DO_LIST
  80. // 8190 only. Assign duration operation mode to firmware
  81. pMgntInfo->bTxEnableFwCalcDur = (BOOLEAN)pNdisCommon->bRegTxEnableFwCalcDur;
  82. #endif
  83. // 8190 only, Realtek proprietary aggregation mode
  84. // Set MPDUDensity=2, 1: Set MPDUDensity=2(32k) for Realtek AP and set MPDUDensity=0(8k) for others
  85. pHTInfo->bRegRT2RTAggregation = 1;//0: Set MPDUDensity=2, 1: Set MPDUDensity=2(32k) for Realtek AP and set MPDUDensity=0(8k) for others
  86. // For Rx Reorder Control
  87. pHTInfo->bRegRxReorderEnable = 1;
  88. pHTInfo->RxReorderWinSize = 64;
  89. pHTInfo->RxReorderPendingTime = 30;
  90. #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
  91. pHTInfo->UsbTxAggrNum = 4;
  92. #endif
  93. #ifdef USB_RX_AGGREGATION_SUPPORT
  94. pHTInfo->UsbRxFwAggrEn = 1;
  95. pHTInfo->UsbRxFwAggrPageNum = 24;
  96. pHTInfo->UsbRxFwAggrPacketNum = 8;
  97. pHTInfo->UsbRxFwAggrTimeout = 16; ////usb rx FW aggregation timeout threshold.It's in units of 64us
  98. #endif
  99. }
  100. /********************************************************************************************************************
  101. *function: This function print out each field on HT capability IE mainly from (Beacon/ProbeRsp/AssocReq)
  102. * input: u8* CapIE //Capability IE to be printed out
  103. * u8* TitleString //mainly print out caller function
  104. * output: none
  105. * return: none
  106. * notice: Driver should not print out this message by default.
  107. * *****************************************************************************************************************/
  108. void HTDebugHTCapability(u8 *CapIE, u8 *TitleString )
  109. {
  110. static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily
  111. PHT_CAPABILITY_ELE pCapELE;
  112. if(!memcmp(CapIE, EWC11NHTCap, sizeof(EWC11NHTCap)))
  113. {
  114. //EWC IE
  115. IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __func__);
  116. pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[4]);
  117. }else
  118. pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[0]);
  119. IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Capability>. Called by %s\n", TitleString );
  120. IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupported Channel Width = %s\n", (pCapELE->ChlWidth)?"20MHz": "20/40MHz");
  121. IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport Short GI for 20M = %s\n", (pCapELE->ShortGI20Mhz)?"YES": "NO");
  122. IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport Short GI for 40M = %s\n", (pCapELE->ShortGI40Mhz)?"YES": "NO");
  123. IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport TX STBC = %s\n", (pCapELE->TxSTBC)?"YES": "NO");
  124. IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMax AMSDU Size = %s\n", (pCapELE->MaxAMSDUSize)?"3839": "7935");
  125. IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport CCK in 20/40 mode = %s\n", (pCapELE->DssCCk)?"YES": "NO");
  126. IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMax AMPDU Factor = %d\n", pCapELE->MaxRxAMPDUFactor);
  127. IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMPDU Density = %d\n", pCapELE->MPDUDensity);
  128. IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMCS Rate Set = [%x][%x][%x][%x][%x]\n", pCapELE->MCS[0],\
  129. pCapELE->MCS[1], pCapELE->MCS[2], pCapELE->MCS[3], pCapELE->MCS[4]);
  130. return;
  131. }
  132. /********************************************************************************************************************
  133. *function: This function print out each field on HT Information IE mainly from (Beacon/ProbeRsp)
  134. * input: u8* InfoIE //Capability IE to be printed out
  135. * u8* TitleString //mainly print out caller function
  136. * output: none
  137. * return: none
  138. * notice: Driver should not print out this message by default.
  139. * *****************************************************************************************************************/
  140. void HTDebugHTInfo(u8 *InfoIE, u8 *TitleString)
  141. {
  142. static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; // For 11n EWC definition, 2007.07.17, by Emily
  143. PHT_INFORMATION_ELE pHTInfoEle;
  144. if(!memcmp(InfoIE, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
  145. {
  146. // Not EWC IE
  147. IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __func__);
  148. pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[4]);
  149. }else
  150. pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[0]);
  151. IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Information Element>. Called by %s\n", TitleString);
  152. IEEE80211_DEBUG(IEEE80211_DL_HT, "\tPrimary channel = %d\n", pHTInfoEle->ControlChl);
  153. IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSenondary channel =");
  154. switch (pHTInfoEle->ExtChlOffset)
  155. {
  156. case 0:
  157. IEEE80211_DEBUG(IEEE80211_DL_HT, "Not Present\n");
  158. break;
  159. case 1:
  160. IEEE80211_DEBUG(IEEE80211_DL_HT, "Upper channel\n");
  161. break;
  162. case 2:
  163. IEEE80211_DEBUG(IEEE80211_DL_HT, "Reserved. Eooro!!!\n");
  164. break;
  165. case 3:
  166. IEEE80211_DEBUG(IEEE80211_DL_HT, "Lower Channel\n");
  167. break;
  168. }
  169. IEEE80211_DEBUG(IEEE80211_DL_HT, "\tRecommended channel width = %s\n", (pHTInfoEle->RecommemdedTxWidth)?"20Mhz": "40Mhz");
  170. IEEE80211_DEBUG(IEEE80211_DL_HT, "\tOperation mode for protection = ");
  171. switch (pHTInfoEle->OptMode)
  172. {
  173. case 0:
  174. IEEE80211_DEBUG(IEEE80211_DL_HT, "No Protection\n");
  175. break;
  176. case 1:
  177. IEEE80211_DEBUG(IEEE80211_DL_HT, "HT non-member protection mode\n");
  178. break;
  179. case 2:
  180. IEEE80211_DEBUG(IEEE80211_DL_HT, "Suggest to open protection\n");
  181. break;
  182. case 3:
  183. IEEE80211_DEBUG(IEEE80211_DL_HT, "HT mixed mode\n");
  184. break;
  185. }
  186. IEEE80211_DEBUG(IEEE80211_DL_HT, "\tBasic MCS Rate Set = [%x][%x][%x][%x][%x]\n", pHTInfoEle->BasicMSC[0],\
  187. pHTInfoEle->BasicMSC[1], pHTInfoEle->BasicMSC[2], pHTInfoEle->BasicMSC[3], pHTInfoEle->BasicMSC[4]);
  188. return;
  189. }
  190. /*
  191. * Return: true if station in half n mode and AP supports 40 bw
  192. */
  193. static bool IsHTHalfNmode40Bandwidth(struct ieee80211_device *ieee)
  194. {
  195. bool retValue = false;
  196. PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
  197. if(!pHTInfo->bCurrentHTSupport) // wireless is n mode
  198. retValue = false;
  199. else if(!pHTInfo->bRegBW40MHz) // station supports 40 bw
  200. retValue = false;
  201. else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) // station in half n mode
  202. retValue = false;
  203. else if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ChlWidth) // ap support 40 bw
  204. retValue = true;
  205. else
  206. retValue = false;
  207. return retValue;
  208. }
  209. static bool IsHTHalfNmodeSGI(struct ieee80211_device *ieee, bool is40MHz)
  210. {
  211. bool retValue = false;
  212. PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
  213. if(!pHTInfo->bCurrentHTSupport) // wireless is n mode
  214. retValue = false;
  215. else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) // station in half n mode
  216. retValue = false;
  217. else if(is40MHz) // ap support 40 bw
  218. {
  219. if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI40Mhz) // ap support 40 bw short GI
  220. retValue = true;
  221. else
  222. retValue = false;
  223. }
  224. else
  225. {
  226. if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI20Mhz) // ap support 40 bw short GI
  227. retValue = true;
  228. else
  229. retValue = false;
  230. }
  231. return retValue;
  232. }
  233. u16 HTHalfMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate)
  234. {
  235. u8 is40MHz;
  236. u8 isShortGI;
  237. is40MHz = (IsHTHalfNmode40Bandwidth(ieee))?1:0;
  238. isShortGI = (IsHTHalfNmodeSGI(ieee, is40MHz))? 1:0;
  239. return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)];
  240. }
  241. u16 HTMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate)
  242. {
  243. PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
  244. u8 is40MHz = (pHTInfo->bCurBW40MHz)?1:0;
  245. u8 isShortGI = (pHTInfo->bCurBW40MHz)?
  246. ((pHTInfo->bCurShortGI40MHz)?1:0):
  247. ((pHTInfo->bCurShortGI20MHz)?1:0);
  248. return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)];
  249. }
  250. /********************************************************************************************************************
  251. *function: This function returns current datarate.
  252. * input: struct ieee80211_device* ieee
  253. * u8 nDataRate
  254. * output: none
  255. * return: tx rate
  256. * notice: quite unsure about how to use this function //wb
  257. * *****************************************************************************************************************/
  258. u16 TxCountToDataRate(struct ieee80211_device *ieee, u8 nDataRate)
  259. {
  260. //PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
  261. u16 CCKOFDMRate[12] = {0x02 , 0x04 , 0x0b , 0x16 , 0x0c , 0x12 , 0x18 , 0x24 , 0x30 , 0x48 , 0x60 , 0x6c};
  262. u8 is40MHz = 0;
  263. u8 isShortGI = 0;
  264. if(nDataRate < 12)
  265. {
  266. return CCKOFDMRate[nDataRate];
  267. }
  268. else
  269. {
  270. if (nDataRate >= 0x10 && nDataRate <= 0x1f)//if(nDataRate > 11 && nDataRate < 28 )
  271. {
  272. is40MHz = 0;
  273. isShortGI = 0;
  274. // nDataRate = nDataRate - 12;
  275. }
  276. else if(nDataRate >=0x20 && nDataRate <= 0x2f ) //(27, 44)
  277. {
  278. is40MHz = 1;
  279. isShortGI = 0;
  280. //nDataRate = nDataRate - 28;
  281. }
  282. else if(nDataRate >= 0x30 && nDataRate <= 0x3f ) //(43, 60)
  283. {
  284. is40MHz = 0;
  285. isShortGI = 1;
  286. //nDataRate = nDataRate - 44;
  287. }
  288. else if(nDataRate >= 0x40 && nDataRate <= 0x4f ) //(59, 76)
  289. {
  290. is40MHz = 1;
  291. isShortGI = 1;
  292. //nDataRate = nDataRate - 60;
  293. }
  294. return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate&0xf];
  295. }
  296. }
  297. bool IsHTHalfNmodeAPs(struct ieee80211_device *ieee)
  298. {
  299. bool retValue = false;
  300. struct ieee80211_network *net = &ieee->current_network;
  301. if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
  302. (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
  303. (memcmp(net->bssid, PCI_RALINK, 3)==0) ||
  304. (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) ||
  305. (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) ||
  306. (net->ralink_cap_exist))
  307. retValue = true;
  308. else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
  309. (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
  310. (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
  311. (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ||
  312. (net->broadcom_cap_exist))
  313. retValue = true;
  314. else if(net->bssht.bdRT2RTAggregation)
  315. retValue = true;
  316. else
  317. retValue = false;
  318. return retValue;
  319. }
  320. /********************************************************************************************************************
  321. *function: This function returns peer IOT.
  322. * input: struct ieee80211_device* ieee
  323. * output: none
  324. * return:
  325. * notice:
  326. * *****************************************************************************************************************/
  327. static void HTIOTPeerDetermine(struct ieee80211_device *ieee)
  328. {
  329. PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
  330. struct ieee80211_network *net = &ieee->current_network;
  331. if(net->bssht.bdRT2RTAggregation)
  332. pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK;
  333. else if(net->broadcom_cap_exist)
  334. pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
  335. else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
  336. (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
  337. (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
  338. (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) )
  339. pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
  340. else if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
  341. (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
  342. (memcmp(net->bssid, PCI_RALINK, 3)==0) ||
  343. (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) ||
  344. (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) ||
  345. net->ralink_cap_exist)
  346. pHTInfo->IOTPeer = HT_IOT_PEER_RALINK;
  347. else if(net->atheros_cap_exist)
  348. pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS;
  349. else if(memcmp(net->bssid, CISCO_BROADCOM, 3)==0)
  350. pHTInfo->IOTPeer = HT_IOT_PEER_CISCO;
  351. else
  352. pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
  353. IEEE80211_DEBUG(IEEE80211_DL_IOT, "Joseph debug!! IOTPEER: %x\n", pHTInfo->IOTPeer);
  354. }
  355. /********************************************************************************************************************
  356. *function: Check whether driver should declare received rate up to MCS13 only since some chipset is not good
  357. * at receiving MCS14~15 frame from some AP.
  358. * input: struct ieee80211_device* ieee
  359. * u8 * PeerMacAddr
  360. * output: none
  361. * return: return 1 if driver should declare MCS13 only(otherwise return 0)
  362. * *****************************************************************************************************************/
  363. static u8 HTIOTActIsDisableMCS14(struct ieee80211_device *ieee, u8 *PeerMacAddr)
  364. {
  365. return 0;
  366. }
  367. /**
  368. * Function: HTIOTActIsDisableMCS15
  369. *
  370. * Overview: Check whether driver should declare capability of receiving MCS15
  371. *
  372. * Input:
  373. * PADAPTER Adapter,
  374. *
  375. * Output: None
  376. * Return: true if driver should disable MCS15
  377. * 2008.04.15 Emily
  378. */
  379. static bool HTIOTActIsDisableMCS15(struct ieee80211_device *ieee)
  380. {
  381. bool retValue = false;
  382. #ifdef TODO
  383. // Apply for 819u only
  384. #if (HAL_CODE_BASE==RTL8192)
  385. #if (DEV_BUS_TYPE == USB_INTERFACE)
  386. // Alway disable MCS15 by Jerry Chang's request.by Emily, 2008.04.15
  387. retValue = true;
  388. #elif (DEV_BUS_TYPE == PCI_INTERFACE)
  389. // Enable MCS15 if the peer is Cisco AP. by Emily, 2008.05.12
  390. // if(pBssDesc->bCiscoCapExist)
  391. // retValue = false;
  392. // else
  393. retValue = false;
  394. #endif
  395. #endif
  396. #endif
  397. // Jerry Chang suggest that 8190 1x2 does not need to disable MCS15
  398. return retValue;
  399. }
  400. /**
  401. * Function: HTIOTActIsDisableMCSTwoSpatialStream
  402. *
  403. * Overview: Check whether driver should declare capability of receiving All 2 ss packets
  404. *
  405. * Input:
  406. * PADAPTER Adapter,
  407. *
  408. * Output: None
  409. * Return: true if driver should disable all two spatial stream packet
  410. * 2008.04.21 Emily
  411. */
  412. static bool HTIOTActIsDisableMCSTwoSpatialStream(struct ieee80211_device *ieee,
  413. u8 *PeerMacAddr)
  414. {
  415. #ifdef TODO
  416. // Apply for 819u only
  417. #endif
  418. return false;
  419. }
  420. /********************************************************************************************************************
  421. *function: Check whether driver should disable EDCA turbo mode
  422. * input: struct ieee80211_device* ieee
  423. * u8* PeerMacAddr
  424. * output: none
  425. * return: return 1 if driver should disable EDCA turbo mode(otherwise return 0)
  426. * *****************************************************************************************************************/
  427. static u8 HTIOTActIsDisableEDCATurbo(struct ieee80211_device *ieee,
  428. u8 *PeerMacAddr)
  429. { /* default enable EDCA Turbo mode. */
  430. return false;
  431. }
  432. /********************************************************************************************************************
  433. *function: Check whether we need to use OFDM to sned MGNT frame for broadcom AP
  434. * input: struct ieee80211_network *network //current network we live
  435. * output: none
  436. * return: return 1 if true
  437. * *****************************************************************************************************************/
  438. static u8 HTIOTActIsMgntUseCCK6M(struct ieee80211_network *network)
  439. {
  440. u8 retValue = 0;
  441. // 2008/01/25 MH Judeg if we need to use OFDM to sned MGNT frame for broadcom AP.
  442. // 2008/01/28 MH We must prevent that we select null bssid to link.
  443. if (network->broadcom_cap_exist)
  444. {
  445. retValue = 1;
  446. }
  447. return retValue;
  448. }
  449. static u8 HTIOTActIsCCDFsync(u8 *PeerMacAddr)
  450. {
  451. u8 retValue = 0;
  452. if( (memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0) ||
  453. (memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0) ||
  454. (memcmp(PeerMacAddr, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) ==0))
  455. {
  456. retValue = 1;
  457. }
  458. return retValue;
  459. }
  460. void HTResetIOTSetting(
  461. PRT_HIGH_THROUGHPUT pHTInfo
  462. )
  463. {
  464. pHTInfo->IOTAction = 0;
  465. pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
  466. }
  467. /********************************************************************************************************************
  468. *function: Construct Capablility Element in Beacon... if HTEnable is turned on
  469. * input: struct ieee80211_device* ieee
  470. * u8* posHTCap //pointer to store Capability Ele
  471. * u8* len //store length of CE
  472. * u8 IsEncrypt //whether encrypt, needed further
  473. * output: none
  474. * return: none
  475. * notice: posHTCap can't be null and should be initialized before.
  476. * *****************************************************************************************************************/
  477. void HTConstructCapabilityElement(struct ieee80211_device *ieee, u8 *posHTCap, u8 *len, u8 IsEncrypt)
  478. {
  479. PRT_HIGH_THROUGHPUT pHT = ieee->pHTInfo;
  480. PHT_CAPABILITY_ELE pCapELE = NULL;
  481. //u8 bIsDeclareMCS13;
  482. if ((posHTCap == NULL) || (pHT == NULL))
  483. {
  484. IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTCap or pHTInfo can't be null in HTConstructCapabilityElement()\n");
  485. return;
  486. }
  487. memset(posHTCap, 0, *len);
  488. if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)
  489. {
  490. u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily
  491. memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap));
  492. pCapELE = (PHT_CAPABILITY_ELE)&(posHTCap[4]);
  493. }else
  494. {
  495. pCapELE = (PHT_CAPABILITY_ELE)posHTCap;
  496. }
  497. //HT capability info
  498. pCapELE->AdvCoding = 0; // This feature is not supported now!!
  499. if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
  500. {
  501. pCapELE->ChlWidth = 0;
  502. }
  503. else
  504. {
  505. pCapELE->ChlWidth = (pHT->bRegBW40MHz?1:0);
  506. }
  507. // pCapELE->ChlWidth = (pHT->bRegBW40MHz?1:0);
  508. pCapELE->MimoPwrSave = pHT->SelfMimoPs;
  509. pCapELE->GreenField = 0; // This feature is not supported now!!
  510. pCapELE->ShortGI20Mhz = 1; // We can receive Short GI!!
  511. pCapELE->ShortGI40Mhz = 1; // We can receive Short GI!!
  512. //DbgPrint("TX HT cap/info ele BW=%d SG20=%d SG40=%d\n\r",
  513. //pCapELE->ChlWidth, pCapELE->ShortGI20Mhz, pCapELE->ShortGI40Mhz);
  514. pCapELE->TxSTBC = 1;
  515. pCapELE->RxSTBC = 0;
  516. pCapELE->DelayBA = 0; // Do not support now!!
  517. pCapELE->MaxAMSDUSize = (MAX_RECEIVE_BUFFER_SIZE>=7935)?1:0;
  518. pCapELE->DssCCk = ((pHT->bRegBW40MHz)?(pHT->bRegSuppCCK?1:0):0);
  519. pCapELE->PSMP = 0; // Do not support now!!
  520. pCapELE->LSigTxopProtect = 0; // Do not support now!!
  521. //MAC HT parameters info
  522. // TODO: Nedd to take care of this part
  523. IEEE80211_DEBUG(IEEE80211_DL_HT, "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk);
  524. if (IsEncrypt) {
  525. pCapELE->MPDUDensity = 7; // 8us
  526. pCapELE->MaxRxAMPDUFactor = 2; // 2 is for 32 K and 3 is 64K
  527. }
  528. else
  529. {
  530. pCapELE->MaxRxAMPDUFactor = 3; // 2 is for 32 K and 3 is 64K
  531. pCapELE->MPDUDensity = 0; // no density
  532. }
  533. //Supported MCS set
  534. memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16);
  535. if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15)
  536. pCapELE->MCS[1] &= 0x7f;
  537. if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14)
  538. pCapELE->MCS[1] &= 0xbf;
  539. if(pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS)
  540. pCapELE->MCS[1] &= 0x00;
  541. // 2008.06.12
  542. // For RTL819X, if pairwisekey = wep/tkip, ap is ralink, we support only MCS0~7.
  543. if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
  544. {
  545. int i;
  546. for(i = 1; i< 16; i++)
  547. pCapELE->MCS[i] = 0;
  548. }
  549. //Extended HT Capability Info
  550. memset(&pCapELE->ExtHTCapInfo, 0, 2);
  551. //TXBF Capabilities
  552. memset(pCapELE->TxBFCap, 0, 4);
  553. //Antenna Selection Capabilities
  554. pCapELE->ASCap = 0;
  555. //add 2 to give space for element ID and len when construct frames
  556. if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)
  557. *len = 30 + 2;
  558. else
  559. *len = 26 + 2;
  560. // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTCap, *len -2);
  561. //Print each field in detail. Driver should not print out this message by default
  562. // HTDebugHTCapability(posHTCap, (u8*)"HTConstructCapability()");
  563. return;
  564. }
  565. /********************************************************************************************************************
  566. *function: Construct Information Element in Beacon... if HTEnable is turned on
  567. * input: struct ieee80211_device* ieee
  568. * u8* posHTCap //pointer to store Information Ele
  569. * u8* len //store len of
  570. * u8 IsEncrypt //whether encrypt, needed further
  571. * output: none
  572. * return: none
  573. * notice: posHTCap can't be null and be initialized before. only AP and IBSS sta should do this
  574. * *****************************************************************************************************************/
  575. void HTConstructInfoElement(struct ieee80211_device *ieee, u8 *posHTInfo, u8 *len, u8 IsEncrypt)
  576. {
  577. PRT_HIGH_THROUGHPUT pHT = ieee->pHTInfo;
  578. PHT_INFORMATION_ELE pHTInfoEle = (PHT_INFORMATION_ELE)posHTInfo;
  579. if ((posHTInfo == NULL) || (pHTInfoEle == NULL))
  580. {
  581. IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTInfo or pHTInfoEle can't be null in HTConstructInfoElement()\n");
  582. return;
  583. }
  584. memset(posHTInfo, 0, *len);
  585. if ( (ieee->iw_mode == IW_MODE_ADHOC) || (ieee->iw_mode == IW_MODE_MASTER)) //ap mode is not currently supported
  586. {
  587. pHTInfoEle->ControlChl = ieee->current_network.channel;
  588. pHTInfoEle->ExtChlOffset = ((!pHT->bRegBW40MHz)?HT_EXTCHNL_OFFSET_NO_EXT:
  589. (ieee->current_network.channel<=6)?
  590. HT_EXTCHNL_OFFSET_UPPER:HT_EXTCHNL_OFFSET_LOWER);
  591. pHTInfoEle->RecommemdedTxWidth = pHT->bRegBW40MHz;
  592. pHTInfoEle->RIFS = 0;
  593. pHTInfoEle->PSMPAccessOnly = 0;
  594. pHTInfoEle->SrvIntGranularity = 0;
  595. pHTInfoEle->OptMode = pHT->CurrentOpMode;
  596. pHTInfoEle->NonGFDevPresent = 0;
  597. pHTInfoEle->DualBeacon = 0;
  598. pHTInfoEle->SecondaryBeacon = 0;
  599. pHTInfoEle->LSigTxopProtectFull = 0;
  600. pHTInfoEle->PcoActive = 0;
  601. pHTInfoEle->PcoPhase = 0;
  602. memset(pHTInfoEle->BasicMSC, 0, 16);
  603. *len = 22 + 2; //same above
  604. }
  605. else
  606. {
  607. //STA should not generate High Throughput Information Element
  608. *len = 0;
  609. }
  610. //IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTInfo, *len - 2);
  611. //HTDebugHTInfo(posHTInfo, "HTConstructInforElement");
  612. return;
  613. }
  614. /*
  615. * According to experiment, Realtek AP to STA (based on rtl8190) may achieve best performance
  616. * if both STA and AP set limitation of aggregation size to 32K, that is, set AMPDU density to 2
  617. * (Ref: IEEE 11n specification). However, if Realtek STA associates to other AP, STA should set
  618. * limitation of aggregation size to 8K, otherwise, performance of traffic stream from STA to AP
  619. * will be much less than the traffic stream from AP to STA if both of the stream runs concurrently
  620. * at the same time.
  621. *
  622. * Frame Format
  623. * Element ID Length OUI Type1 Reserved
  624. * 1 byte 1 byte 3 bytes 1 byte 1 byte
  625. *
  626. * OUI = 0x00, 0xe0, 0x4c,
  627. * Type = 0x02
  628. * Reserved = 0x00
  629. *
  630. * 2007.8.21 by Emily
  631. */
  632. /********************************************************************************************************************
  633. *function: Construct Information Element in Beacon... in RT2RT condition
  634. * input: struct ieee80211_device* ieee
  635. * u8* posRT2RTAgg //pointer to store Information Ele
  636. * u8* len //store len
  637. * output: none
  638. * return: none
  639. * notice:
  640. * *****************************************************************************************************************/
  641. void HTConstructRT2RTAggElement(struct ieee80211_device *ieee, u8 *posRT2RTAgg, u8 *len)
  642. {
  643. if (posRT2RTAgg == NULL) {
  644. IEEE80211_DEBUG(IEEE80211_DL_ERR, "posRT2RTAgg can't be null in HTConstructRT2RTAggElement()\n");
  645. return;
  646. }
  647. memset(posRT2RTAgg, 0, *len);
  648. *posRT2RTAgg++ = 0x00;
  649. *posRT2RTAgg++ = 0xe0;
  650. *posRT2RTAgg++ = 0x4c;
  651. *posRT2RTAgg++ = 0x02;
  652. *posRT2RTAgg++ = 0x01;
  653. *posRT2RTAgg = 0x10;//*posRT2RTAgg = 0x02;
  654. if (ieee->bSupportRemoteWakeUp) {
  655. *posRT2RTAgg |= 0x08;//RT_HT_CAP_USE_WOW;
  656. }
  657. *len = 6 + 2;
  658. return;
  659. #ifdef TODO
  660. #if (HAL_CODE_BASE == RTL8192 && DEV_BUS_TYPE == USB_INTERFACE)
  661. /*
  662. //Emily. If it is required to Ask Realtek AP to send AMPDU during AES mode, enable this
  663. section of code.
  664. if(IS_UNDER_11N_AES_MODE(Adapter))
  665. {
  666. posRT2RTAgg->Octet[5] |=RT_HT_CAP_USE_AMPDU;
  667. }else
  668. {
  669. posRT2RTAgg->Octet[5] &= 0xfb;
  670. }
  671. */
  672. #else
  673. // Do Nothing
  674. #endif
  675. posRT2RTAgg->Length = 6;
  676. #endif
  677. }
  678. /********************************************************************************************************************
  679. *function: Pick the right Rate Adaptive table to use
  680. * input: struct ieee80211_device* ieee
  681. * u8* pOperateMCS //A pointer to MCS rate bitmap
  682. * return: always we return true
  683. * notice:
  684. * *****************************************************************************************************************/
  685. static u8 HT_PickMCSRate(struct ieee80211_device *ieee, u8 *pOperateMCS)
  686. {
  687. u8 i;
  688. if (pOperateMCS == NULL)
  689. {
  690. IEEE80211_DEBUG(IEEE80211_DL_ERR, "pOperateMCS can't be null in HT_PickMCSRate()\n");
  691. return false;
  692. }
  693. switch (ieee->mode)
  694. {
  695. case IEEE_A:
  696. case IEEE_B:
  697. case IEEE_G:
  698. //legacy rate routine handled at selectedrate
  699. //no MCS rate
  700. for(i=0;i<=15;i++){
  701. pOperateMCS[i] = 0;
  702. }
  703. break;
  704. case IEEE_N_24G: //assume CCK rate ok
  705. case IEEE_N_5G:
  706. // Legacy part we only use 6, 5.5,2,1 for N_24G and 6 for N_5G.
  707. // Legacy part shall be handled at SelectRateSet().
  708. //HT part
  709. // TODO: may be different if we have different number of antenna
  710. pOperateMCS[0] &=RATE_ADPT_1SS_MASK; //support MCS 0~7
  711. pOperateMCS[1] &=RATE_ADPT_2SS_MASK;
  712. pOperateMCS[3] &=RATE_ADPT_MCS32_MASK;
  713. break;
  714. //should never reach here
  715. default:
  716. break;
  717. }
  718. return true;
  719. }
  720. /*
  721. * Description:
  722. * This function will get the highest speed rate in input MCS set.
  723. *
  724. * /param Adapter Pionter to Adapter entity
  725. * pMCSRateSet Pointer to MCS rate bitmap
  726. * pMCSFilter Pointer to MCS rate filter
  727. *
  728. * /return Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter.
  729. *
  730. */
  731. /********************************************************************************************************************
  732. *function: This function will get the highest speed rate in input MCS set.
  733. * input: struct ieee80211_device* ieee
  734. * u8* pMCSRateSet //Pointer to MCS rate bitmap
  735. * u8* pMCSFilter //Pointer to MCS rate filter
  736. * return: Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter
  737. * notice:
  738. * *****************************************************************************************************************/
  739. u8 HTGetHighestMCSRate(struct ieee80211_device *ieee, u8 *pMCSRateSet, u8 *pMCSFilter)
  740. {
  741. u8 i, j;
  742. u8 bitMap;
  743. u8 mcsRate = 0;
  744. u8 availableMcsRate[16];
  745. if (pMCSRateSet == NULL || pMCSFilter == NULL)
  746. {
  747. IEEE80211_DEBUG(IEEE80211_DL_ERR, "pMCSRateSet or pMCSFilter can't be null in HTGetHighestMCSRate()\n");
  748. return false;
  749. }
  750. for(i=0; i<16; i++)
  751. availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i];
  752. for(i = 0; i < 16; i++)
  753. {
  754. if(availableMcsRate[i] != 0)
  755. break;
  756. }
  757. if(i == 16)
  758. return false;
  759. for(i = 0; i < 16; i++)
  760. {
  761. if (availableMcsRate[i] != 0)
  762. {
  763. bitMap = availableMcsRate[i];
  764. for(j = 0; j < 8; j++)
  765. {
  766. if ((bitMap%2) != 0)
  767. {
  768. if(HTMcsToDataRate(ieee, (8*i+j)) > HTMcsToDataRate(ieee, mcsRate))
  769. mcsRate = (8*i+j);
  770. }
  771. bitMap >>= 1;
  772. }
  773. }
  774. }
  775. return (mcsRate|0x80);
  776. }
  777. /*
  778. **
  779. **1.Filter our operation rate set with AP's rate set
  780. **2.shall reference channel bandwidth, STBC, Antenna number
  781. **3.generate rate adative table for firmware
  782. **David 20060906
  783. **
  784. ** \pHTSupportedCap: the connected STA's supported rate Capability element
  785. */
  786. static u8 HTFilterMCSRate(struct ieee80211_device *ieee, u8 *pSupportMCS,
  787. u8 *pOperateMCS)
  788. {
  789. u8 i=0;
  790. // filter out operational rate set not supported by AP, the length of it is 16
  791. for(i=0;i<=15;i++){
  792. pOperateMCS[i] = ieee->Regdot11HTOperationalRateSet[i]&pSupportMCS[i];
  793. }
  794. // TODO: adjust our operational rate set according to our channel bandwidth, STBC and Antenna number
  795. // TODO: fill suggested rate adaptive rate index and give firmware info using Tx command packet
  796. // we also shall suggested the first start rate set according to our singal strength
  797. HT_PickMCSRate(ieee, pOperateMCS);
  798. // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
  799. if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
  800. pOperateMCS[1] = 0;
  801. //
  802. // For RTL819X, we support only MCS0~15.
  803. // And also, we do not know how to use MCS32 now.
  804. //
  805. for(i=2; i<=15; i++)
  806. pOperateMCS[i] = 0;
  807. return true;
  808. }
  809. void HTSetConnectBwMode(struct ieee80211_device *ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
  810. void HTOnAssocRsp(struct ieee80211_device *ieee)
  811. {
  812. PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
  813. PHT_CAPABILITY_ELE pPeerHTCap = NULL;
  814. PHT_INFORMATION_ELE pPeerHTInfo = NULL;
  815. u16 nMaxAMSDUSize = 0;
  816. u8 *pMcsFilter = NULL;
  817. static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily
  818. static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; // For 11n EWC definition, 2007.07.17, by Emily
  819. if (!pHTInfo->bCurrentHTSupport) {
  820. IEEE80211_DEBUG(IEEE80211_DL_ERR, "<=== HTOnAssocRsp(): HT_DISABLE\n");
  821. return;
  822. }
  823. IEEE80211_DEBUG(IEEE80211_DL_HT, "===> HTOnAssocRsp_wq(): HT_ENABLE\n");
  824. // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTCapBuf, sizeof(HT_CAPABILITY_ELE));
  825. // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTInfoBuf, sizeof(HT_INFORMATION_ELE));
  826. // HTDebugHTCapability(pHTInfo->PeerHTCapBuf,"HTOnAssocRsp_wq");
  827. // HTDebugHTInfo(pHTInfo->PeerHTInfoBuf,"HTOnAssocRsp_wq");
  828. //
  829. if (!memcmp(pHTInfo->PeerHTCapBuf, EWC11NHTCap, sizeof(EWC11NHTCap)))
  830. pPeerHTCap = (PHT_CAPABILITY_ELE)(&pHTInfo->PeerHTCapBuf[4]);
  831. else
  832. pPeerHTCap = (PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf);
  833. if(!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
  834. pPeerHTInfo = (PHT_INFORMATION_ELE)(&pHTInfo->PeerHTInfoBuf[4]);
  835. else
  836. pPeerHTInfo = (PHT_INFORMATION_ELE)(pHTInfo->PeerHTInfoBuf);
  837. ////////////////////////////////////////////////////////
  838. // Configurations:
  839. ////////////////////////////////////////////////////////
  840. IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTCap, sizeof(HT_CAPABILITY_ELE));
  841. // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTInfo, sizeof(HT_INFORMATION_ELE));
  842. // Config Supported Channel Width setting
  843. //
  844. HTSetConnectBwMode(ieee, (HT_CHANNEL_WIDTH)(pPeerHTCap->ChlWidth), (HT_EXTCHNL_OFFSET)(pPeerHTInfo->ExtChlOffset));
  845. // if (pHTInfo->bCurBW40MHz)
  846. pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1)?true:false);
  847. //
  848. // Update short GI/ long GI setting
  849. //
  850. // TODO:
  851. pHTInfo->bCurShortGI20MHz=
  852. ((pHTInfo->bRegShortGI20MHz)?((pPeerHTCap->ShortGI20Mhz==1)?true:false):false);
  853. pHTInfo->bCurShortGI40MHz=
  854. ((pHTInfo->bRegShortGI40MHz)?((pPeerHTCap->ShortGI40Mhz==1)?true:false):false);
  855. //
  856. // Config TX STBC setting
  857. //
  858. // TODO:
  859. //
  860. // Config DSSS/CCK mode in 40MHz mode
  861. //
  862. // TODO:
  863. pHTInfo->bCurSuppCCK =
  864. ((pHTInfo->bRegSuppCCK)?((pPeerHTCap->DssCCk==1)?true:false):false);
  865. //
  866. // Config and configure A-MSDU setting
  867. //
  868. pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
  869. nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize==0)?3839:7935;
  870. if(pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize )
  871. pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize;
  872. else
  873. pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
  874. //
  875. // Config A-MPDU setting
  876. //
  877. pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
  878. // <1> Decide AMPDU Factor
  879. // By Emily
  880. if(!pHTInfo->bRegRT2RTAggregation)
  881. {
  882. // Decide AMPDU Factor according to protocol handshake
  883. if(pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor)
  884. pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
  885. else
  886. pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
  887. }else
  888. {
  889. // Set MPDU density to 2 to Realtek AP, and set it to 0 for others
  890. // Replace MPDU factor declared in original association response frame format. 2007.08.20 by Emily
  891. if (ieee->current_network.bssht.bdRT2RTAggregation)
  892. {
  893. if (ieee->pairwise_key_type != KEY_TYPE_NA)
  894. // Realtek may set 32k in security mode and 64k for others
  895. pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
  896. else
  897. pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K;
  898. }else
  899. {
  900. if(pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K)
  901. pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
  902. else
  903. pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K;
  904. }
  905. }
  906. // <2> Set AMPDU Minimum MPDU Start Spacing
  907. // 802.11n 3.0 section 9.7d.3
  908. if(pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity)
  909. pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
  910. else
  911. pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity;
  912. if(ieee->pairwise_key_type != KEY_TYPE_NA )
  913. pHTInfo->CurrentMPDUDensity = 7; // 8us
  914. // Force TX AMSDU
  915. // Lanhsin: mark for tmp to avoid deauth by ap from s3
  916. //if(memcmp(pMgntInfo->Bssid, NETGEAR834Bv2_BROADCOM, 3)==0)
  917. if (0)
  918. {
  919. pHTInfo->bCurrentAMPDUEnable = false;
  920. pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE;
  921. pHTInfo->ForcedAMSDUMaxSize = 7935;
  922. pHTInfo->IOTAction |= HT_IOT_ACT_TX_USE_AMSDU_8K;
  923. }
  924. // Rx Reorder Setting
  925. pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable;
  926. //
  927. // Filter out unsupported HT rate for this AP
  928. // Update RATR table
  929. // This is only for 8190 ,8192 or later product which using firmware to handle rate adaptive mechanism.
  930. //
  931. // Handle Ralink AP bad MCS rate set condition. Joseph.
  932. // This fix the bug of Ralink AP. This may be removed in the future.
  933. if(pPeerHTCap->MCS[0] == 0)
  934. pPeerHTCap->MCS[0] = 0xff;
  935. HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet);
  936. //
  937. // Config MIMO Power Save setting
  938. //
  939. pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave;
  940. if(pHTInfo->PeerMimoPs == MIMO_PS_STATIC)
  941. pMcsFilter = MCS_FILTER_1SS;
  942. else
  943. pMcsFilter = MCS_FILTER_ALL;
  944. //WB add for MCS8 bug
  945. // pMcsFilter = MCS_FILTER_1SS;
  946. ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, pMcsFilter);
  947. ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
  948. //
  949. // Config current operation mode.
  950. //
  951. pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
  952. }
  953. void HTSetConnectBwModeCallback(struct ieee80211_device *ieee);
  954. /********************************************************************************************************************
  955. *function: initialize HT info(struct PRT_HIGH_THROUGHPUT)
  956. * input: struct ieee80211_device* ieee
  957. * output: none
  958. * return: none
  959. * notice: This function is called when * (1) MPInitialization Phase * (2) Receiving of Deauthentication from AP
  960. ********************************************************************************************************************/
  961. // TODO: Should this funciton be called when receiving of Disassociation?
  962. void HTInitializeHTInfo(struct ieee80211_device *ieee)
  963. {
  964. PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
  965. //
  966. // These parameters will be reset when receiving deauthentication packet
  967. //
  968. IEEE80211_DEBUG(IEEE80211_DL_HT, "===========>%s()\n", __func__);
  969. pHTInfo->bCurrentHTSupport = false;
  970. // 40MHz channel support
  971. pHTInfo->bCurBW40MHz = false;
  972. pHTInfo->bCurTxBW40MHz = false;
  973. // Short GI support
  974. pHTInfo->bCurShortGI20MHz = false;
  975. pHTInfo->bCurShortGI40MHz = false;
  976. pHTInfo->bForcedShortGI = false;
  977. // CCK rate support
  978. // This flag is set to true to support CCK rate by default.
  979. // It will be affected by "pHTInfo->bRegSuppCCK" and AP capabilities only when associate to
  980. // 11N BSS.
  981. pHTInfo->bCurSuppCCK = true;
  982. // AMSDU related
  983. pHTInfo->bCurrent_AMSDU_Support = false;
  984. pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
  985. // AMPUD related
  986. pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
  987. pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
  988. // Initialize all of the parameters related to 11n
  989. memset((void *)(&(pHTInfo->SelfHTCap)), 0, sizeof(pHTInfo->SelfHTCap));
  990. memset((void *)(&(pHTInfo->SelfHTInfo)), 0, sizeof(pHTInfo->SelfHTInfo));
  991. memset((void *)(&(pHTInfo->PeerHTCapBuf)), 0, sizeof(pHTInfo->PeerHTCapBuf));
  992. memset((void *)(&(pHTInfo->PeerHTInfoBuf)), 0, sizeof(pHTInfo->PeerHTInfoBuf));
  993. pHTInfo->bSwBwInProgress = false;
  994. pHTInfo->ChnlOp = CHNLOP_NONE;
  995. // Set default IEEE spec for Draft N
  996. pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE;
  997. // Realtek proprietary aggregation mode
  998. pHTInfo->bCurrentRT2RTAggregation = false;
  999. pHTInfo->bCurrentRT2RTLongSlotTime = false;
  1000. pHTInfo->IOTPeer = 0;
  1001. pHTInfo->IOTAction = 0;
  1002. //MCS rate initialized here
  1003. {
  1004. u8 *RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]);
  1005. RegHTSuppRateSets[0] = 0xFF; //support MCS 0~7
  1006. RegHTSuppRateSets[1] = 0xFF; //support MCS 8~15
  1007. RegHTSuppRateSets[4] = 0x01; //support MCS 32
  1008. }
  1009. }
  1010. /********************************************************************************************************************
  1011. *function: initialize Bss HT structure(struct PBSS_HT)
  1012. * input: PBSS_HT pBssHT //to be initialized
  1013. * output: none
  1014. * return: none
  1015. * notice: This function is called when initialize network structure
  1016. ********************************************************************************************************************/
  1017. void HTInitializeBssDesc(PBSS_HT pBssHT)
  1018. {
  1019. pBssHT->bdSupportHT = false;
  1020. memset(pBssHT->bdHTCapBuf, 0, sizeof(pBssHT->bdHTCapBuf));
  1021. pBssHT->bdHTCapLen = 0;
  1022. memset(pBssHT->bdHTInfoBuf, 0, sizeof(pBssHT->bdHTInfoBuf));
  1023. pBssHT->bdHTInfoLen = 0;
  1024. pBssHT->bdHTSpecVer= HT_SPEC_VER_IEEE;
  1025. pBssHT->bdRT2RTAggregation = false;
  1026. pBssHT->bdRT2RTLongSlotTime = false;
  1027. }
  1028. /********************************************************************************************************************
  1029. *function: initialize Bss HT structure(struct PBSS_HT)
  1030. * input: struct ieee80211_device *ieee
  1031. * struct ieee80211_network *pNetwork //usually current network we are live in
  1032. * output: none
  1033. * return: none
  1034. * notice: This function should ONLY be called before association
  1035. ********************************************************************************************************************/
  1036. void HTResetSelfAndSavePeerSetting(struct ieee80211_device *ieee, struct ieee80211_network *pNetwork)
  1037. {
  1038. PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
  1039. // u16 nMaxAMSDUSize;
  1040. // PHT_CAPABILITY_ELE pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf;
  1041. // PHT_INFORMATION_ELE pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf;
  1042. // u8* pMcsFilter;
  1043. u8 bIOTAction = 0;
  1044. //
  1045. // Save Peer Setting before Association
  1046. //
  1047. IEEE80211_DEBUG(IEEE80211_DL_HT, "==============>%s()\n", __func__);
  1048. /*unmark bEnableHT flag here is the same reason why unmarked in function ieee80211_softmac_new_net. WB 2008.09.10*/
  1049. // if( pHTInfo->bEnableHT && pNetwork->bssht.bdSupportHT)
  1050. if (pNetwork->bssht.bdSupportHT)
  1051. {
  1052. pHTInfo->bCurrentHTSupport = true;
  1053. pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bdHTSpecVer;
  1054. // Save HTCap and HTInfo information Element
  1055. if(pNetwork->bssht.bdHTCapLen > 0 && pNetwork->bssht.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf))
  1056. memcpy(pHTInfo->PeerHTCapBuf, pNetwork->bssht.bdHTCapBuf, pNetwork->bssht.bdHTCapLen);
  1057. if(pNetwork->bssht.bdHTInfoLen > 0 && pNetwork->bssht.bdHTInfoLen <= sizeof(pHTInfo->PeerHTInfoBuf))
  1058. memcpy(pHTInfo->PeerHTInfoBuf, pNetwork->bssht.bdHTInfoBuf, pNetwork->bssht.bdHTInfoLen);
  1059. // Check whether RT to RT aggregation mode is enabled
  1060. if(pHTInfo->bRegRT2RTAggregation)
  1061. {
  1062. pHTInfo->bCurrentRT2RTAggregation = pNetwork->bssht.bdRT2RTAggregation;
  1063. pHTInfo->bCurrentRT2RTLongSlotTime = pNetwork->bssht.bdRT2RTLongSlotTime;
  1064. }
  1065. else
  1066. {
  1067. pHTInfo->bCurrentRT2RTAggregation = false;
  1068. pHTInfo->bCurrentRT2RTLongSlotTime = false;
  1069. }
  1070. // Determine the IOT Peer Vendor.
  1071. HTIOTPeerDetermine(ieee);
  1072. // Decide IOT Action
  1073. // Must be called after the parameter of pHTInfo->bCurrentRT2RTAggregation is decided
  1074. pHTInfo->IOTAction = 0;
  1075. bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid);
  1076. if(bIOTAction)
  1077. pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14;
  1078. bIOTAction = HTIOTActIsDisableMCS15(ieee);
  1079. if(bIOTAction)
  1080. pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15;
  1081. bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee, pNetwork->bssid);
  1082. if(bIOTAction)
  1083. pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS;
  1084. bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid);
  1085. if(bIOTAction)
  1086. pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO;
  1087. bIOTAction = HTIOTActIsMgntUseCCK6M(pNetwork);
  1088. if(bIOTAction)
  1089. pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M;
  1090. bIOTAction = HTIOTActIsCCDFsync(pNetwork->bssid);
  1091. if(bIOTAction)
  1092. pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC;
  1093. }
  1094. else
  1095. {
  1096. pHTInfo->bCurrentHTSupport = false;
  1097. pHTInfo->bCurrentRT2RTAggregation = false;
  1098. pHTInfo->bCurrentRT2RTLongSlotTime = false;
  1099. pHTInfo->IOTAction = 0;
  1100. }
  1101. }
  1102. void HTUpdateSelfAndPeerSetting(struct ieee80211_device *ieee, struct ieee80211_network *pNetwork)
  1103. {
  1104. PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
  1105. // PHT_CAPABILITY_ELE pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf;
  1106. PHT_INFORMATION_ELE pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf;
  1107. if (pHTInfo->bCurrentHTSupport)
  1108. {
  1109. //
  1110. // Config current operation mode.
  1111. //
  1112. if(pNetwork->bssht.bdHTInfoLen != 0)
  1113. pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
  1114. //
  1115. // <TODO: Config according to OBSS non-HT STA present!!>
  1116. //
  1117. }
  1118. }
  1119. EXPORT_SYMBOL(HTUpdateSelfAndPeerSetting);
  1120. /********************************************************************************************************************
  1121. *function: check whether HT control field exists
  1122. * input: struct ieee80211_device *ieee
  1123. * u8* pFrame //coming skb->data
  1124. * output: none
  1125. * return: return true if HT control field exists(false otherwise)
  1126. * notice:
  1127. ********************************************************************************************************************/
  1128. u8 HTCCheck(struct ieee80211_device *ieee, u8 *pFrame)
  1129. {
  1130. if (ieee->pHTInfo->bCurrentHTSupport)
  1131. {
  1132. if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) {
  1133. IEEE80211_DEBUG(IEEE80211_DL_HT, "HT CONTROL FILED EXIST!!\n");
  1134. return true;
  1135. }
  1136. }
  1137. return false;
  1138. }
  1139. //
  1140. // This function set bandwidth mode in protocol layer.
  1141. //
  1142. void HTSetConnectBwMode(struct ieee80211_device *ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset)
  1143. {
  1144. PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
  1145. // u32 flags = 0;
  1146. if(!pHTInfo->bRegBW40MHz)
  1147. return;
  1148. // To reduce dummy operation
  1149. // if((pHTInfo->bCurBW40MHz==false && Bandwidth==HT_CHANNEL_WIDTH_20) ||
  1150. // (pHTInfo->bCurBW40MHz==true && Bandwidth==HT_CHANNEL_WIDTH_20_40 && Offset==pHTInfo->CurSTAExtChnlOffset))
  1151. // return;
  1152. // spin_lock_irqsave(&(ieee->bw_spinlock), flags);
  1153. if (pHTInfo->bSwBwInProgress) {
  1154. // spin_unlock_irqrestore(&(ieee->bw_spinlock), flags);
  1155. return;
  1156. }
  1157. //if in half N mode, set to 20M bandwidth please 09.08.2008 WB.
  1158. if(Bandwidth==HT_CHANNEL_WIDTH_20_40 && (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)))
  1159. {
  1160. // Handle Illegal extension channel offset!!
  1161. if(ieee->current_network.channel<2 && Offset==HT_EXTCHNL_OFFSET_LOWER)
  1162. Offset = HT_EXTCHNL_OFFSET_NO_EXT;
  1163. if(Offset==HT_EXTCHNL_OFFSET_UPPER || Offset==HT_EXTCHNL_OFFSET_LOWER) {
  1164. pHTInfo->bCurBW40MHz = true;
  1165. pHTInfo->CurSTAExtChnlOffset = Offset;
  1166. } else {
  1167. pHTInfo->bCurBW40MHz = false;
  1168. pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
  1169. }
  1170. } else {
  1171. pHTInfo->bCurBW40MHz = false;
  1172. pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
  1173. }
  1174. pHTInfo->bSwBwInProgress = true;
  1175. // TODO: 2007.7.13 by Emily Wait 2000ms in order to guarantee that switching
  1176. // bandwidth is executed after scan is finished. It is a temporal solution
  1177. // because software should ganrantee the last operation of switching bandwidth
  1178. // is executed properlly.
  1179. HTSetConnectBwModeCallback(ieee);
  1180. // spin_unlock_irqrestore(&(ieee->bw_spinlock), flags);
  1181. }
  1182. void HTSetConnectBwModeCallback(struct ieee80211_device *ieee)
  1183. {
  1184. PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
  1185. IEEE80211_DEBUG(IEEE80211_DL_HT, "======>%s()\n", __func__);
  1186. if(pHTInfo->bCurBW40MHz)
  1187. {
  1188. if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_UPPER)
  1189. ieee->set_chan(ieee->dev, ieee->current_network.channel+2);
  1190. else if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_LOWER)
  1191. ieee->set_chan(ieee->dev, ieee->current_network.channel-2);
  1192. else
  1193. ieee->set_chan(ieee->dev, ieee->current_network.channel);
  1194. ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, pHTInfo->CurSTAExtChnlOffset);
  1195. } else {
  1196. ieee->set_chan(ieee->dev, ieee->current_network.channel);
  1197. ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
  1198. }
  1199. pHTInfo->bSwBwInProgress = false;
  1200. }