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