linux/drivers/staging/rtl8192u/ieee80211/rtl819x_HTProc.c
<<
>>
Prefs
   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
   9u8 MCS_FILTER_ALL[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  10
  11u8 MCS_FILTER_1SS[16] = {0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  12
  13u16 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
  36static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
  37static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
  38static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
  39static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f};
  40static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f};       //cosa 03202008
  41static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
  42static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
  43static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e};
  44static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
  45//static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0};
  46static 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 */
  59void 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 */
 127void 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 */
 162void 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
 215static 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 */
 234u16  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
 269bool 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 */
 302static 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 */
 342static 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 */
 360static 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 */
 398static 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 */
 415static 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 */
 428static 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
 441static 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
 453void 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 */
 469void 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 */
 583void 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 */
 652void 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 */
 701static 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 */
 759u8 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 */
 805static 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
 836void 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?
1020void 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 */
1089void 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 */
1112void 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
1187void 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}
1205EXPORT_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 */
1215u8 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
1226static 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 */
1252void 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}
1299