root/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. HTUpdateDefaultSetting
  2. HTDebugHTCapability
  3. HTDebugHTInfo
  4. HTMcsToDataRate
  5. TxCountToDataRate
  6. IsHTHalfNmodeAPs
  7. HTIOTPeerDetermine
  8. HTIOTActIsDisableMCS14
  9. HTIOTActIsDisableMCS15
  10. HTIOTActIsDisableMCSTwoSpatialStream
  11. HTIOTActIsDisableEDCATurbo
  12. HTIOTActIsMgntUseCCK6M
  13. HTIOTActIsCCDFsync
  14. HTResetIOTSetting
  15. HTConstructCapabilityElement
  16. HTConstructInfoElement
  17. HTConstructRT2RTAggElement
  18. HT_PickMCSRate
  19. HTGetHighestMCSRate
  20. HTFilterMCSRate
  21. HTOnAssocRsp
  22. HTInitializeHTInfo
  23. HTInitializeBssDesc
  24. HTResetSelfAndSavePeerSetting
  25. HTUpdateSelfAndPeerSetting
  26. HTCCheck
  27. HTSetConnectBwModeCallback
  28. HTSetConnectBwMode

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

/* [<][>][^][v][top][bottom][index][help] */