linux/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/******************************************************************************
   3 *
   4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
   5 *
   6 ******************************************************************************/
   7#define _RTW_WLAN_UTIL_C_
   8
   9#include <linux/ieee80211.h>
  10
  11#include <osdep_service.h>
  12#include <drv_types.h>
  13#include <wifi.h>
  14
  15static const u8 ARTHEROS_OUI1[] = {0x00, 0x03, 0x7f};
  16static const u8 ARTHEROS_OUI2[] = {0x00, 0x13, 0x74};
  17
  18static const u8 BROADCOM_OUI1[] = {0x00, 0x10, 0x18};
  19static const u8 BROADCOM_OUI2[] = {0x00, 0x0a, 0xf7};
  20
  21static const u8 CISCO_OUI[] = {0x00, 0x40, 0x96};
  22static const u8 MARVELL_OUI[] = {0x00, 0x50, 0x43};
  23static const u8 RALINK_OUI[] = {0x00, 0x0c, 0x43};
  24static const u8 REALTEK_OUI[] = {0x00, 0xe0, 0x4c};
  25static const u8 AIRGOCAP_OUI[] = {0x00, 0x0a, 0xf5};
  26static const u8 EPIGRAM_OUI[] = {0x00, 0x90, 0x4c};
  27
  28u8 REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
  29
  30#define WAIT_FOR_BCN_TO_MIN     (6000)
  31#define WAIT_FOR_BCN_TO_MAX     (20000)
  32
  33static const u8 rtw_basic_rate_cck[4] = {
  34        IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK,
  35        IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
  36        IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK,
  37        IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK
  38};
  39
  40static const u8 rtw_basic_rate_ofdm[3] = {
  41        IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK,
  42        IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK,
  43        IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK
  44};
  45
  46static const u8 rtw_basic_rate_mix[7] = {
  47        IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK,
  48        IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK,
  49        IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK,
  50        IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK,
  51        IEEE80211_OFDM_RATE_6MB | IEEE80211_BASIC_RATE_MASK,
  52        IEEE80211_OFDM_RATE_12MB | IEEE80211_BASIC_RATE_MASK,
  53        IEEE80211_OFDM_RATE_24MB | IEEE80211_BASIC_RATE_MASK
  54};
  55
  56unsigned char networktype_to_raid(unsigned char network_type)
  57{
  58        switch (network_type) {
  59        case WIRELESS_11B:
  60                return RATR_INX_WIRELESS_B;
  61        case WIRELESS_11A:
  62        case WIRELESS_11G:
  63                return RATR_INX_WIRELESS_G;
  64        case WIRELESS_11BG:
  65                return RATR_INX_WIRELESS_GB;
  66        case WIRELESS_11_24N:
  67        case WIRELESS_11_5N:
  68                return RATR_INX_WIRELESS_N;
  69        case WIRELESS_11A_5N:
  70        case WIRELESS_11G_24N:
  71                return  RATR_INX_WIRELESS_NG;
  72        case WIRELESS_11BG_24N:
  73                return RATR_INX_WIRELESS_NGB;
  74        default:
  75                return RATR_INX_WIRELESS_GB;
  76        }
  77}
  78
  79u8 judge_network_type(struct adapter *padapter, unsigned char *rate)
  80{
  81        u8 network_type = 0;
  82        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  83        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
  84
  85        if (pmlmeinfo->HT_enable)
  86                network_type = WIRELESS_11_24N;
  87
  88        if (rtw_is_cckratesonly_included(rate))
  89                network_type |= WIRELESS_11B;
  90        else if (rtw_is_cckrates_included(rate))
  91                network_type |= WIRELESS_11BG;
  92        else
  93                network_type |= WIRELESS_11G;
  94
  95        return network_type;
  96}
  97
  98static unsigned char ratetbl_val_2wifirate(unsigned char rate)
  99{
 100        switch (rate & 0x7f) {
 101        case 0:
 102                return IEEE80211_CCK_RATE_1MB;
 103        case 1:
 104                return IEEE80211_CCK_RATE_2MB;
 105        case 2:
 106                return IEEE80211_CCK_RATE_5MB;
 107        case 3:
 108                return IEEE80211_CCK_RATE_11MB;
 109        case 4:
 110                return IEEE80211_OFDM_RATE_6MB;
 111        case 5:
 112                return IEEE80211_OFDM_RATE_9MB;
 113        case 6:
 114                return IEEE80211_OFDM_RATE_12MB;
 115        case 7:
 116                return IEEE80211_OFDM_RATE_18MB;
 117        case 8:
 118                return IEEE80211_OFDM_RATE_24MB;
 119        case 9:
 120                return IEEE80211_OFDM_RATE_36MB;
 121        case 10:
 122                return IEEE80211_OFDM_RATE_48MB;
 123        case 11:
 124                return IEEE80211_OFDM_RATE_54MB;
 125        default:
 126                return 0;
 127        }
 128}
 129
 130static bool is_basicrate(struct adapter *padapter, unsigned char rate)
 131{
 132        int i;
 133        unsigned char val;
 134        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 135
 136        for (i = 0; i < NumRates; i++) {
 137                val = pmlmeext->basicrate[i];
 138
 139                if ((val != 0xff) && (val != 0xfe)) {
 140                        if (rate == ratetbl_val_2wifirate(val))
 141                                return true;
 142                }
 143        }
 144        return false;
 145}
 146
 147static unsigned int ratetbl2rateset(struct adapter *padapter, unsigned char *rateset)
 148{
 149        int i;
 150        unsigned char rate;
 151        unsigned int len = 0;
 152        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 153
 154        for (i = 0; i < NumRates; i++) {
 155                rate = pmlmeext->datarate[i];
 156
 157                switch (rate) {
 158                case 0xff:
 159                        return len;
 160                case 0xfe:
 161                        continue;
 162                default:
 163                        rate = ratetbl_val_2wifirate(rate);
 164
 165                        if (is_basicrate(padapter, rate))
 166                                rate |= IEEE80211_BASIC_RATE_MASK;
 167
 168                        rateset[len] = rate;
 169                        len++;
 170                        break;
 171                }
 172        }
 173        return len;
 174}
 175
 176void get_rate_set(struct adapter *padapter, unsigned char *pbssrate, int *bssrate_len)
 177{
 178        unsigned char supportedrates[NumRates];
 179
 180        memset(supportedrates, 0, NumRates);
 181        *bssrate_len = ratetbl2rateset(padapter, supportedrates);
 182        memcpy(pbssrate, supportedrates, *bssrate_len);
 183}
 184
 185void UpdateBrateTbl(struct adapter *Adapter, u8 *mbrate)
 186{
 187        u8 i;
 188        u8 rate;
 189
 190        /*  1M, 2M, 5.5M, 11M, 6M, 12M, 24M are mandatory. */
 191        for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
 192                rate = mbrate[i] & 0x7f;
 193                switch (rate) {
 194                case IEEE80211_CCK_RATE_1MB:
 195                case IEEE80211_CCK_RATE_2MB:
 196                case IEEE80211_CCK_RATE_5MB:
 197                case IEEE80211_CCK_RATE_11MB:
 198                case IEEE80211_OFDM_RATE_6MB:
 199                case IEEE80211_OFDM_RATE_12MB:
 200                case IEEE80211_OFDM_RATE_24MB:
 201                        mbrate[i] |= IEEE80211_BASIC_RATE_MASK;
 202                        break;
 203                }
 204        }
 205}
 206
 207void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen)
 208{
 209        u8 i;
 210        u8 rate;
 211
 212        for (i = 0; i < bssratelen; i++) {
 213                rate = bssrateset[i] & 0x7f;
 214                switch (rate) {
 215                case IEEE80211_CCK_RATE_1MB:
 216                case IEEE80211_CCK_RATE_2MB:
 217                case IEEE80211_CCK_RATE_5MB:
 218                case IEEE80211_CCK_RATE_11MB:
 219                        bssrateset[i] |= IEEE80211_BASIC_RATE_MASK;
 220                        break;
 221                }
 222        }
 223}
 224
 225void Save_DM_Func_Flag(struct adapter *padapter)
 226{
 227        u8 saveflag = true;
 228
 229        rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&saveflag));
 230}
 231
 232void Restore_DM_Func_Flag(struct adapter *padapter)
 233{
 234        u8 saveflag = false;
 235
 236        rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&saveflag));
 237}
 238
 239void Switch_DM_Func(struct adapter *padapter, u32 mode, u8 enable)
 240{
 241        if (enable)
 242                rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_SET, (u8 *)(&mode));
 243        else
 244                rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_CLR, (u8 *)(&mode));
 245}
 246
 247void Set_MSR(struct adapter *padapter, u8 type)
 248{
 249        rtw_hal_set_hwreg(padapter, HW_VAR_MEDIA_STATUS, (u8 *)(&type));
 250}
 251
 252inline u8 rtw_get_oper_ch(struct adapter *adapter)
 253{
 254        return adapter->mlmeextpriv.oper_channel;
 255}
 256
 257inline void rtw_set_oper_ch(struct adapter *adapter, u8 ch)
 258{
 259        adapter->mlmeextpriv.oper_channel = ch;
 260}
 261
 262inline void rtw_set_oper_bw(struct adapter *adapter, u8 bw)
 263{
 264        adapter->mlmeextpriv.oper_bwmode = bw;
 265}
 266
 267inline void rtw_set_oper_choffset(struct adapter *adapter, u8 offset)
 268{
 269        adapter->mlmeextpriv.oper_ch_offset = offset;
 270}
 271
 272void SelectChannel(struct adapter *padapter, unsigned char channel)
 273{
 274        /* saved channel info */
 275        rtw_set_oper_ch(padapter, channel);
 276        rtw_hal_set_chan(padapter, channel);
 277}
 278
 279void SetBWMode(struct adapter *padapter, unsigned short bwmode,
 280               unsigned char channel_offset)
 281{
 282        /* saved bw info */
 283        rtw_set_oper_bw(padapter, bwmode);
 284        rtw_set_oper_choffset(padapter, channel_offset);
 285
 286        rtw_hal_set_bwmode(padapter, (enum ht_channel_width)bwmode, channel_offset);
 287}
 288
 289void set_channel_bwmode(struct adapter *padapter, unsigned char channel, unsigned char channel_offset, unsigned short bwmode)
 290{
 291        u8 center_ch;
 292
 293        if ((bwmode == HT_CHANNEL_WIDTH_20) ||
 294            (channel_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)) {
 295                /* SelectChannel(padapter, channel); */
 296                center_ch = channel;
 297        } else {
 298                /* switch to the proper channel */
 299                if (channel_offset == HAL_PRIME_CHNL_OFFSET_LOWER) {
 300                        /* SelectChannel(padapter, channel + 2); */
 301                        center_ch = channel + 2;
 302                } else {
 303                        /* SelectChannel(padapter, channel - 2); */
 304                        center_ch = channel - 2;
 305                }
 306        }
 307
 308        /* set Channel */
 309        /* saved channel/bw info */
 310        rtw_set_oper_ch(padapter, channel);
 311        rtw_set_oper_bw(padapter, bwmode);
 312        rtw_set_oper_choffset(padapter, channel_offset);
 313
 314        rtw_hal_set_chan(padapter, center_ch); /*  set center channel */
 315        SetBWMode(padapter, bwmode, channel_offset);
 316}
 317
 318u16 get_beacon_interval(struct wlan_bssid_ex *bss)
 319{
 320        __le16 val;
 321
 322        memcpy((unsigned char *)&val, rtw_get_beacon_interval_from_ie(bss->ies), 2);
 323
 324        return le16_to_cpu(val);
 325}
 326
 327int is_client_associated_to_ap(struct adapter *padapter)
 328{
 329        struct mlme_ext_priv *pmlmeext;
 330        struct mlme_ext_info *pmlmeinfo;
 331
 332        if (!padapter)
 333                return _FAIL;
 334
 335        pmlmeext = &padapter->mlmeextpriv;
 336        pmlmeinfo = &pmlmeext->mlmext_info;
 337
 338        if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) &&
 339            (pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
 340                return true;
 341        else
 342                return _FAIL;
 343}
 344
 345int is_client_associated_to_ibss(struct adapter *padapter)
 346{
 347        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 348        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 349
 350        if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) &&
 351            (pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)
 352                return true;
 353        else
 354                return _FAIL;
 355}
 356
 357int is_IBSS_empty(struct adapter *padapter)
 358{
 359        unsigned int i;
 360        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 361        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 362
 363        for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) {
 364                if (pmlmeinfo->FW_sta_info[i].status == 1)
 365                        return _FAIL;
 366        }
 367        return true;
 368}
 369
 370unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval)
 371{
 372        if ((bcn_interval << 2) < WAIT_FOR_BCN_TO_MIN)
 373                return WAIT_FOR_BCN_TO_MIN;
 374        else if ((bcn_interval << 2) > WAIT_FOR_BCN_TO_MAX)
 375                return WAIT_FOR_BCN_TO_MAX;
 376        else
 377                return bcn_interval << 2;
 378}
 379
 380void invalidate_cam_all(struct adapter *padapter)
 381{
 382        rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, NULL);
 383}
 384
 385void write_cam(struct adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key)
 386{
 387        unsigned int i, val, addr;
 388        int j;
 389        u32 cam_val[2];
 390
 391        addr = entry << 3;
 392
 393        for (j = 5; j >= 0; j--) {
 394                switch (j) {
 395                case 0:
 396                        val = ctrl | (mac[0] << 16) | (mac[1] << 24);
 397                        break;
 398                case 1:
 399                        val = mac[2] | (mac[3] << 8) | (mac[4] << 16) | (mac[5] << 24);
 400                        break;
 401                default:
 402                        i = (j - 2) << 2;
 403                        val = key[i] | (key[i + 1] << 8) | (key[i + 2] << 16) |
 404                              (key[i + 3] << 24);
 405                        break;
 406                }
 407
 408                cam_val[0] = val;
 409                cam_val[1] = addr + (unsigned int)j;
 410
 411                rtw_hal_set_hwreg(padapter, HW_VAR_CAM_WRITE, (u8 *)cam_val);
 412        }
 413}
 414
 415void clear_cam_entry(struct adapter *padapter, u8 entry)
 416{
 417        u8 null_sta[ETH_ALEN] = {};
 418        u8 null_key[16] = {};
 419
 420        write_cam(padapter, entry, 0, null_sta, null_key);
 421}
 422
 423int allocate_fw_sta_entry(struct adapter *padapter)
 424{
 425        unsigned int mac_id;
 426        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 427        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 428
 429        for (mac_id = IBSS_START_MAC_ID; mac_id < NUM_STA; mac_id++) {
 430                if (pmlmeinfo->FW_sta_info[mac_id].status == 0) {
 431                        pmlmeinfo->FW_sta_info[mac_id].status = 1;
 432                        pmlmeinfo->FW_sta_info[mac_id].retry = 0;
 433                        break;
 434                }
 435        }
 436
 437        return mac_id;
 438}
 439
 440void flush_all_cam_entry(struct adapter *padapter)
 441{
 442        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 443        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 444
 445        rtw_hal_set_hwreg(padapter, HW_VAR_CAM_INVALID_ALL, NULL);
 446
 447        memset((u8 *)(pmlmeinfo->FW_sta_info), 0, sizeof(pmlmeinfo->FW_sta_info));
 448}
 449
 450int WMM_param_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
 451{
 452        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 453        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 454        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 455
 456        if (pmlmepriv->qospriv.qos_option == 0) {
 457                pmlmeinfo->WMM_enable = 0;
 458                return _FAIL;
 459        }
 460
 461        pmlmeinfo->WMM_enable = 1;
 462        memcpy(&pmlmeinfo->WMM_param, pIE->data + 6, sizeof(struct WMM_para_element));
 463        return true;
 464}
 465
 466void WMMOnAssocRsp(struct adapter *padapter)
 467{
 468        u8 ACI, ACM, AIFS, ECWMin, ECWMax, aSifsTime;
 469        u8 acm_mask;
 470        u16 TXOP;
 471        u32 acParm, i;
 472        u32 edca[4], inx[4];
 473        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 474        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 475        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 476        struct registry_priv *pregpriv = &padapter->registrypriv;
 477
 478        if (pmlmeinfo->WMM_enable == 0) {
 479                padapter->mlmepriv.acm_mask = 0;
 480                return;
 481        }
 482
 483        acm_mask = 0;
 484
 485        if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
 486                aSifsTime = 10;
 487        else
 488                aSifsTime = 16;
 489
 490        for (i = 0; i < 4; i++) {
 491                ACI = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 5) & 0x03;
 492                ACM = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 4) & 0x01;
 493
 494                /* AIFS = AIFSN * slot time + SIFS - r2t phy delay */
 495                AIFS = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN & 0x0f) * pmlmeinfo->slotTime + aSifsTime;
 496
 497                ECWMin = pmlmeinfo->WMM_param.ac_param[i].CW & 0x0f;
 498                ECWMax = (pmlmeinfo->WMM_param.ac_param[i].CW & 0xf0) >> 4;
 499                TXOP = le16_to_cpu(pmlmeinfo->WMM_param.ac_param[i].TXOP_limit);
 500
 501                acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
 502
 503                switch (ACI) {
 504                case 0x0:
 505                        rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acParm));
 506                        acm_mask |= (ACM ? BIT(1) : 0);
 507                        edca[XMIT_BE_QUEUE] = acParm;
 508                        break;
 509                case 0x1:
 510                        rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acParm));
 511                        edca[XMIT_BK_QUEUE] = acParm;
 512                        break;
 513                case 0x2:
 514                        rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acParm));
 515                        acm_mask |= (ACM ? BIT(2) : 0);
 516                        edca[XMIT_VI_QUEUE] = acParm;
 517                        break;
 518                case 0x3:
 519                        rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acParm));
 520                        acm_mask |= (ACM ? BIT(3) : 0);
 521                        edca[XMIT_VO_QUEUE] = acParm;
 522                        break;
 523                }
 524        }
 525
 526        if (padapter->registrypriv.acm_method == 1)
 527                rtw_hal_set_hwreg(padapter, HW_VAR_ACM_CTRL, (u8 *)(&acm_mask));
 528        else
 529                padapter->mlmepriv.acm_mask = acm_mask;
 530
 531        inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;
 532
 533        if (pregpriv->wifi_spec == 1) {
 534                u32 j, change_inx = false;
 535
 536                /* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */
 537                for (i = 0; i < 4; i++) {
 538                        for (j = i + 1; j < 4; j++) {
 539                                /* compare CW and AIFS */
 540                                if ((edca[j] & 0xFFFF) < (edca[i] & 0xFFFF)) {
 541                                        change_inx = true;
 542                                } else if ((edca[j] & 0xFFFF) == (edca[i] & 0xFFFF)) {
 543                                        /* compare TXOP */
 544                                        if ((edca[j] >> 16) > (edca[i] >> 16))
 545                                                change_inx = true;
 546                                }
 547
 548                                if (change_inx) {
 549                                        swap(edca[i], edca[j]);
 550                                        swap(inx[i], inx[j]);
 551                                        change_inx = false;
 552                                }
 553                        }
 554                }
 555        }
 556
 557        for (i = 0; i < 4; i++)
 558                pxmitpriv->wmm_para_seq[i] = inx[i];
 559}
 560
 561static void bwmode_update_check(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
 562{
 563        unsigned char new_bwmode;
 564        unsigned char new_ch_offset;
 565        struct HT_info_element *pHT_info;
 566        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 567        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 568        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 569        struct registry_priv *pregistrypriv = &padapter->registrypriv;
 570        struct ht_priv *phtpriv = &pmlmepriv->htpriv;
 571
 572        if (!pIE)
 573                return;
 574
 575        if (!phtpriv)
 576                return;
 577
 578        if (pIE->Length > sizeof(struct HT_info_element))
 579                return;
 580
 581        pHT_info = (struct HT_info_element *)pIE->data;
 582
 583        if ((pHT_info->infos[0] & BIT(2)) && pregistrypriv->cbw40_enable) {
 584                new_bwmode = HT_CHANNEL_WIDTH_40;
 585
 586                switch (pHT_info->infos[0] & 0x3) {
 587                case 1:
 588                        new_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
 589                        break;
 590                case 3:
 591                        new_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
 592                        break;
 593                default:
 594                        new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
 595                        break;
 596                }
 597        } else {
 598                new_bwmode = HT_CHANNEL_WIDTH_20;
 599                new_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
 600        }
 601
 602        if ((new_bwmode != pmlmeext->cur_bwmode) ||
 603            (new_ch_offset != pmlmeext->cur_ch_offset)) {
 604                pmlmeinfo->bwmode_updated = true;
 605
 606                pmlmeext->cur_bwmode = new_bwmode;
 607                pmlmeext->cur_ch_offset = new_ch_offset;
 608
 609                /* update HT info also */
 610                HT_info_handler(padapter, pIE);
 611        } else {
 612                pmlmeinfo->bwmode_updated = false;
 613        }
 614
 615        if (pmlmeinfo->bwmode_updated) {
 616                struct sta_info *psta;
 617                struct wlan_bssid_ex    *cur_network = &pmlmeinfo->network;
 618                struct sta_priv *pstapriv = &padapter->stapriv;
 619
 620                /* update ap's stainfo */
 621                psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
 622                if (psta) {
 623                        struct ht_priv  *phtpriv_sta = &psta->htpriv;
 624
 625                        if (phtpriv_sta->ht_option) {
 626                                /*  bwmode */
 627                                phtpriv_sta->bwmode = pmlmeext->cur_bwmode;
 628                                phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
 629                        } else {
 630                                phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20;
 631                                phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
 632                        }
 633                }
 634        }
 635}
 636
 637void HT_caps_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
 638{
 639        unsigned int i;
 640        u8 max_ampdu_len, min_mpdu_spacing;
 641        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 642        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 643        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 644        struct ht_priv *phtpriv = &pmlmepriv->htpriv;
 645        u8 *HT_cap = (u8 *)(&pmlmeinfo->HT_caps);
 646
 647        if (!pIE)
 648                return;
 649
 650        if (!phtpriv->ht_option)
 651                return;
 652
 653        pmlmeinfo->HT_caps_enable = 1;
 654
 655        for (i = 0; i < (pIE->Length); i++) {
 656                if (i != 2) {
 657                        /*      Got the endian issue here. */
 658                        HT_cap[i] &= (pIE->data[i]);
 659                } else {
 660                        /* modify from  fw by Thomas 2010/11/17 */
 661                        if ((pmlmeinfo->HT_caps.ampdu_params_info & 0x3) > (pIE->data[i] & 0x3))
 662                                max_ampdu_len = pIE->data[i] & 0x3;
 663                        else
 664                                max_ampdu_len = pmlmeinfo->HT_caps.ampdu_params_info & 0x3;
 665
 666                        if ((pmlmeinfo->HT_caps.ampdu_params_info & 0x1c) > (pIE->data[i] & 0x1c))
 667                                min_mpdu_spacing = pmlmeinfo->HT_caps.ampdu_params_info & 0x1c;
 668                        else
 669                                min_mpdu_spacing = pIE->data[i] & 0x1c;
 670
 671                        pmlmeinfo->HT_caps.ampdu_params_info = max_ampdu_len | min_mpdu_spacing;
 672                }
 673        }
 674
 675        /* update the MCS rates */
 676        for (i = 0; i < 16; i++)
 677                ((u8 *)&pmlmeinfo->HT_caps.mcs)[i] &= MCS_rate_1R[i];
 678}
 679
 680void HT_info_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
 681{
 682        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 683        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 684        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 685        struct ht_priv *phtpriv = &pmlmepriv->htpriv;
 686
 687        if (!pIE)
 688                return;
 689
 690        if (!phtpriv->ht_option)
 691                return;
 692
 693        if (pIE->Length > sizeof(struct HT_info_element))
 694                return;
 695
 696        pmlmeinfo->HT_info_enable = 1;
 697        memcpy(&pmlmeinfo->HT_info, pIE->data, pIE->Length);
 698}
 699
 700void HTOnAssocRsp(struct adapter *padapter)
 701{
 702        u8 max_ampdu_len;
 703        u8 min_mpdu_spacing;
 704        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 705        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 706
 707        if ((pmlmeinfo->HT_info_enable) && (pmlmeinfo->HT_caps_enable)) {
 708                pmlmeinfo->HT_enable = 1;
 709        } else {
 710                pmlmeinfo->HT_enable = 0;
 711                return;
 712        }
 713
 714        /* handle A-MPDU parameter field
 715         *
 716         * AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
 717         * AMPDU_para [4:2]:Min MPDU Start Spacing
 718         */
 719        max_ampdu_len = pmlmeinfo->HT_caps.ampdu_params_info & 0x03;
 720        min_mpdu_spacing = (pmlmeinfo->HT_caps.ampdu_params_info & 0x1c) >> 2;
 721
 722        rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, &min_mpdu_spacing);
 723        rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, &max_ampdu_len);
 724}
 725
 726void ERP_IE_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
 727{
 728        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 729        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 730
 731        if (pIE->Length > 1)
 732                return;
 733
 734        pmlmeinfo->ERP_enable = 1;
 735        memcpy(&pmlmeinfo->ERP_IE, pIE->data, pIE->Length);
 736}
 737
 738void VCS_update(struct adapter *padapter, struct sta_info *psta)
 739{
 740        struct registry_priv *pregpriv = &padapter->registrypriv;
 741        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 742        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 743
 744        switch (pregpriv->vrtl_carrier_sense) { /* 0:off 1:on 2:auto */
 745        case 0: /* off */
 746                psta->rtsen = 0;
 747                psta->cts2self = 0;
 748                break;
 749        case 1: /* on */
 750                if (pregpriv->vcs_type == 1) { /* 1:RTS/CTS 2:CTS to self */
 751                        psta->rtsen = 1;
 752                        psta->cts2self = 0;
 753                } else {
 754                        psta->rtsen = 0;
 755                        psta->cts2self = 1;
 756                }
 757                break;
 758        case 2: /* auto */
 759        default:
 760                if ((pmlmeinfo->ERP_enable) && (pmlmeinfo->ERP_IE & BIT(1))) {
 761                        if (pregpriv->vcs_type == 1) {
 762                                psta->rtsen = 1;
 763                                psta->cts2self = 0;
 764                        } else {
 765                                psta->rtsen = 0;
 766                                psta->cts2self = 1;
 767                        }
 768                } else {
 769                        psta->rtsen = 0;
 770                        psta->cts2self = 0;
 771                }
 772                break;
 773        }
 774}
 775
 776int rtw_check_bcn_info(struct adapter  *Adapter, u8 *pframe, u32 packet_len)
 777{
 778        unsigned int len;
 779        unsigned char *p;
 780        unsigned short val16, subtype;
 781        struct wlan_network *cur_network = &Adapter->mlmepriv.cur_network;
 782        u16 wpa_len = 0, rsn_len = 0;
 783        u8 encryp_protocol = 0;
 784        struct wlan_bssid_ex *bssid;
 785        int group_cipher = 0, pairwise_cipher = 0, is_8021x = 0;
 786        unsigned char *pbuf;
 787        u32 wpa_ielen = 0;
 788        u8 *pbssid = GetAddr3Ptr(pframe);
 789        struct HT_info_element *pht_info = NULL;
 790        u32 bcn_channel;
 791        unsigned short ht_cap_info;
 792        unsigned char ht_info_infos_0;
 793        int ssid_len;
 794
 795        if (!is_client_associated_to_ap(Adapter))
 796                return true;
 797
 798        len = packet_len - sizeof(struct ieee80211_hdr_3addr);
 799
 800        if (len > MAX_IE_SZ)
 801                return _FAIL;
 802
 803        if (memcmp(cur_network->network.MacAddress, pbssid, 6))
 804                return true;
 805
 806        bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
 807        if (!bssid)
 808                return _FAIL;
 809
 810        subtype = GetFrameSubType(pframe) >> 4;
 811
 812        if (subtype == IEEE80211_STYPE_BEACON)
 813                bssid->Reserved[0] = 1;
 814
 815        bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len;
 816
 817        /* below is to copy the information element */
 818        bssid->ie_length = len;
 819        memcpy(bssid->ies, (pframe + sizeof(struct ieee80211_hdr_3addr)), bssid->ie_length);
 820
 821        /* check bw and channel offset */
 822        /* parsing HT_CAP_IE */
 823        p = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, WLAN_EID_HT_CAPABILITY, &len, bssid->ie_length - _FIXED_IE_LENGTH_);
 824        if (p && len > 0) {
 825                struct ieee80211_ht_cap *ht_cap =
 826                        (struct ieee80211_ht_cap *)(p + 2);
 827
 828                ht_cap_info = le16_to_cpu(ht_cap->cap_info);
 829        } else {
 830                ht_cap_info = 0;
 831        }
 832        /* parsing HT_INFO_IE */
 833        p = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, WLAN_EID_HT_OPERATION, &len, bssid->ie_length - _FIXED_IE_LENGTH_);
 834        if (p && len > 0) {
 835                pht_info = (struct HT_info_element *)(p + 2);
 836                ht_info_infos_0 = pht_info->infos[0];
 837        } else {
 838                ht_info_infos_0 = 0;
 839        }
 840        if (ht_cap_info != cur_network->BcnInfo.ht_cap_info ||
 841            ((ht_info_infos_0 & 0x03) != (cur_network->BcnInfo.ht_info_infos_0 & 0x03))) {
 842                /* bcn_info_update */
 843                cur_network->BcnInfo.ht_cap_info = ht_cap_info;
 844                cur_network->BcnInfo.ht_info_infos_0 = ht_info_infos_0;
 845                /* to do : need to check that whether modify related register of BB or not */
 846                /* goto _mismatch; */
 847        }
 848
 849        /* Checking for channel */
 850        p = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, WLAN_EID_DS_PARAMS, &len, bssid->ie_length - _FIXED_IE_LENGTH_);
 851        if (p) {
 852                bcn_channel = *(p + 2);
 853        } else {/* In 5G, some ap do not have DSSET IE checking HT info for channel */
 854                p = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, WLAN_EID_HT_OPERATION, &len, bssid->ie_length - _FIXED_IE_LENGTH_);
 855                if (pht_info)
 856                        bcn_channel = pht_info->primary_channel;
 857                else /* we don't find channel IE, so don't check it */
 858                        bcn_channel = Adapter->mlmeextpriv.cur_channel;
 859        }
 860        if (bcn_channel != Adapter->mlmeextpriv.cur_channel)
 861                goto _mismatch;
 862
 863        /* checking SSID */
 864        ssid_len = 0;
 865        p = rtw_get_ie(bssid->ies + _FIXED_IE_LENGTH_, WLAN_EID_SSID, &len, bssid->ie_length - _FIXED_IE_LENGTH_);
 866        if (p) {
 867                ssid_len = *(p + 1);
 868                if (ssid_len > NDIS_802_11_LENGTH_SSID)
 869                        ssid_len = 0;
 870        }
 871        memcpy(bssid->ssid.ssid, (p + 2), ssid_len);
 872        bssid->ssid.ssid_length = ssid_len;
 873
 874        if (memcmp(bssid->ssid.ssid, cur_network->network.ssid.ssid, 32) ||
 875            bssid->ssid.ssid_length != cur_network->network.ssid.ssid_length) {
 876                if (bssid->ssid.ssid[0] != '\0' && bssid->ssid.ssid_length != 0) /* not hidden ssid */
 877                        goto _mismatch;
 878        }
 879
 880        /* check encryption info */
 881        val16 = rtw_get_capability(bssid);
 882
 883        if (val16 & BIT(4))
 884                bssid->Privacy = 1;
 885        else
 886                bssid->Privacy = 0;
 887
 888        if (cur_network->network.Privacy != bssid->Privacy)
 889                goto _mismatch;
 890
 891        rtw_get_sec_ie(bssid->ies, bssid->ie_length, NULL, &rsn_len, NULL, &wpa_len);
 892
 893        if (rsn_len > 0) {
 894                encryp_protocol = ENCRYP_PROTOCOL_WPA2;
 895        } else if (wpa_len > 0) {
 896                encryp_protocol = ENCRYP_PROTOCOL_WPA;
 897        } else {
 898                if (bssid->Privacy)
 899                        encryp_protocol = ENCRYP_PROTOCOL_WEP;
 900        }
 901
 902        if (cur_network->BcnInfo.encryp_protocol != encryp_protocol)
 903                goto _mismatch;
 904
 905        if (encryp_protocol == ENCRYP_PROTOCOL_WPA || encryp_protocol == ENCRYP_PROTOCOL_WPA2) {
 906                pbuf = rtw_get_wpa_ie(&bssid->ies[12], &wpa_ielen,
 907                                      bssid->ie_length - 12);
 908                if (pbuf && (wpa_ielen > 0)) {
 909                        rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher,
 910                                         &pairwise_cipher, &is_8021x);
 911                } else {
 912                        pbuf = rtw_get_wpa2_ie(&bssid->ies[12], &wpa_ielen,
 913                                               bssid->ie_length - 12);
 914
 915                        if (pbuf && (wpa_ielen > 0))
 916                                rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher,
 917                                                  &pairwise_cipher, &is_8021x);
 918                }
 919
 920                if (pairwise_cipher != cur_network->BcnInfo.pairwise_cipher || group_cipher != cur_network->BcnInfo.group_cipher)
 921                        goto _mismatch;
 922
 923                if (is_8021x != cur_network->BcnInfo.is_8021x)
 924                        goto _mismatch;
 925        }
 926
 927        kfree(bssid);
 928        return _SUCCESS;
 929
 930_mismatch:
 931        kfree(bssid);
 932        return _FAIL;
 933}
 934
 935void update_beacon_info(struct adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta)
 936{
 937        unsigned int i;
 938        unsigned int len;
 939        struct ndis_802_11_var_ie *pIE;
 940
 941        len = pkt_len - (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN);
 942
 943        for (i = 0; i < len;) {
 944                pIE = (struct ndis_802_11_var_ie *)(pframe + (_BEACON_IE_OFFSET_ + WLAN_HDR_A3_LEN) + i);
 945
 946                switch (pIE->ElementID) {
 947                case WLAN_EID_HT_OPERATION:     /* HT info */
 948                        bwmode_update_check(padapter, pIE);
 949                        break;
 950                case WLAN_EID_ERP_INFO:
 951                        ERP_IE_handler(padapter, pIE);
 952                        VCS_update(padapter, psta);
 953                        break;
 954                default:
 955                        break;
 956                }
 957
 958                i += (pIE->Length + 2);
 959        }
 960}
 961
 962unsigned int is_ap_in_tkip(struct adapter *padapter)
 963{
 964        u32 i;
 965        struct ndis_802_11_var_ie *pIE;
 966        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 967        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 968        struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
 969
 970        if (rtw_get_capability(cur_network) & WLAN_CAPABILITY_PRIVACY) {
 971                for (i = sizeof(struct ndis_802_11_fixed_ie); i < pmlmeinfo->network.ie_length;) {
 972                        pIE = (struct ndis_802_11_var_ie *)(pmlmeinfo->network.ies + i);
 973
 974                        switch (pIE->ElementID) {
 975                        case WLAN_EID_VENDOR_SPECIFIC:
 976                                if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) && (!memcmp((pIE->data + 12), WPA_TKIP_CIPHER, 4)))
 977                                        return true;
 978                                break;
 979                        case WLAN_EID_RSN:
 980                                if (!memcmp((pIE->data + 8), RSN_TKIP_CIPHER, 4))
 981                                        return true;
 982                                break;
 983                        default:
 984                                break;
 985                        }
 986
 987                        i += (pIE->Length + 2);
 988                }
 989                return false;
 990        } else {
 991                return false;
 992        }
 993}
 994
 995static int wifirate2_ratetbl_inx(unsigned char rate)
 996{
 997        rate = rate & 0x7f;
 998
 999        switch (rate) {
1000        case 108:
1001                return 11;
1002        case 96:
1003                return 10;
1004        case 72:
1005                return 9;
1006        case 48:
1007                return 8;
1008        case 36:
1009                return 7;
1010        case 24:
1011                return 6;
1012        case 18:
1013                return 5;
1014        case 12:
1015                return 4;
1016        case 22:
1017                return 3;
1018        case 11:
1019                return 2;
1020        case 4:
1021                return 1;
1022        case 2:
1023                return 0;
1024        default:
1025                return 0;
1026        }
1027}
1028
1029unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz)
1030{
1031        unsigned int i, num_of_rate;
1032        unsigned int mask = 0;
1033
1034        num_of_rate = min_t(unsigned int, ptn_sz, NumRates);
1035
1036        for (i = 0; i < num_of_rate; i++) {
1037                if ((*(ptn + i)) & 0x80)
1038                        mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i));
1039        }
1040        return mask;
1041}
1042
1043unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz)
1044{
1045        unsigned int i, num_of_rate;
1046        unsigned int mask = 0;
1047
1048        num_of_rate = min_t(unsigned int, ptn_sz, NumRates);
1049
1050        for (i = 0; i < num_of_rate; i++)
1051                mask |= 0x1 << wifirate2_ratetbl_inx(*(ptn + i));
1052        return mask;
1053}
1054
1055unsigned int update_MSC_rate(struct ieee80211_ht_cap *pHT_caps)
1056{
1057        return (pHT_caps->mcs.rx_mask[0] << 12) |
1058               (pHT_caps->mcs.rx_mask[1] << 20);
1059}
1060
1061int support_short_GI(struct adapter *padapter, struct ieee80211_ht_cap *pHT_caps)
1062{
1063        unsigned char bit_offset;
1064        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1065        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1066
1067        if (!(pmlmeinfo->HT_enable))
1068                return _FAIL;
1069
1070        if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_RALINK)
1071                return _FAIL;
1072
1073        bit_offset = (pmlmeext->cur_bwmode & HT_CHANNEL_WIDTH_40) ? 6 : 5;
1074
1075        if (__le16_to_cpu(pHT_caps->cap_info) & (0x1 << bit_offset))
1076                return _SUCCESS;
1077        else
1078                return _FAIL;
1079}
1080
1081unsigned char get_highest_rate_idx(u32 mask)
1082{
1083        int i;
1084        unsigned char rate_idx = 0;
1085
1086        for (i = 27; i >= 0; i--) {
1087                if (mask & BIT(i)) {
1088                        rate_idx = i;
1089                        break;
1090                }
1091        }
1092        return rate_idx;
1093}
1094
1095void Update_RA_Entry(struct adapter *padapter, u32 mac_id)
1096{
1097        rtw_hal_update_ra_mask(padapter, mac_id, 0);
1098}
1099
1100void set_sta_rate(struct adapter *padapter, struct sta_info *psta)
1101{
1102        /* rate adaptive */
1103        Update_RA_Entry(padapter, psta->mac_id);
1104}
1105
1106/*  Update RRSR and Rate for USERATE */
1107void update_tx_basic_rate(struct adapter *padapter, u8 wirelessmode)
1108{
1109        unsigned char supported_rates[NDIS_802_11_LENGTH_RATES_EX];
1110
1111        memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
1112
1113        if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B))
1114                memcpy(supported_rates, rtw_basic_rate_cck, 4);
1115        else if (wirelessmode & WIRELESS_11B)
1116                memcpy(supported_rates, rtw_basic_rate_mix, 7);
1117        else
1118                memcpy(supported_rates, rtw_basic_rate_ofdm, 3);
1119
1120        if (wirelessmode & WIRELESS_11B)
1121                update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB);
1122        else
1123                update_mgnt_tx_rate(padapter, IEEE80211_OFDM_RATE_6MB);
1124
1125        rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, supported_rates);
1126}
1127
1128unsigned char check_assoc_AP(u8 *pframe, uint len)
1129{
1130        unsigned int i;
1131        struct ndis_802_11_var_ie *pIE;
1132        u8 epigram_vendor_flag;
1133        u8 ralink_vendor_flag;
1134
1135        epigram_vendor_flag = 0;
1136        ralink_vendor_flag = 0;
1137
1138        for (i = sizeof(struct ndis_802_11_fixed_ie); i < len;) {
1139                pIE = (struct ndis_802_11_var_ie *)(pframe + i);
1140
1141                switch (pIE->ElementID) {
1142                case WLAN_EID_VENDOR_SPECIFIC:
1143                        if ((!memcmp(pIE->data, ARTHEROS_OUI1, 3)) ||
1144                            (!memcmp(pIE->data, ARTHEROS_OUI2, 3))) {
1145                                return HT_IOT_PEER_ATHEROS;
1146                        } else if ((!memcmp(pIE->data, BROADCOM_OUI1, 3)) ||
1147                                   (!memcmp(pIE->data, BROADCOM_OUI2, 3))) {
1148                                return HT_IOT_PEER_BROADCOM;
1149                        } else if (!memcmp(pIE->data, MARVELL_OUI, 3)) {
1150                                return HT_IOT_PEER_MARVELL;
1151                        } else if (!memcmp(pIE->data, RALINK_OUI, 3)) {
1152                                if (!ralink_vendor_flag)
1153                                        ralink_vendor_flag = 1;
1154                                else
1155                                        return HT_IOT_PEER_RALINK;
1156                        } else if (!memcmp(pIE->data, CISCO_OUI, 3)) {
1157                                return HT_IOT_PEER_CISCO;
1158                        } else if (!memcmp(pIE->data, REALTEK_OUI, 3)) {
1159                                return HT_IOT_PEER_REALTEK;
1160                        } else if (!memcmp(pIE->data, AIRGOCAP_OUI, 3)) {
1161                                return HT_IOT_PEER_AIRGO;
1162                        } else if (!memcmp(pIE->data, EPIGRAM_OUI, 3)) {
1163                                epigram_vendor_flag = 1;
1164                                if (ralink_vendor_flag)
1165                                        return HT_IOT_PEER_TENDA;
1166                        } else {
1167                                break;
1168                        }
1169                        break;
1170
1171                default:
1172                        break;
1173                }
1174                i += (pIE->Length + 2);
1175        }
1176
1177        if (ralink_vendor_flag && !epigram_vendor_flag)
1178                return HT_IOT_PEER_RALINK;
1179        else if (ralink_vendor_flag && epigram_vendor_flag)
1180                return HT_IOT_PEER_TENDA;
1181        return HT_IOT_PEER_UNKNOWN;
1182}
1183
1184void update_IOT_info(struct adapter *padapter)
1185{
1186        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1187        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1188
1189        switch (pmlmeinfo->assoc_AP_vendor) {
1190        case HT_IOT_PEER_MARVELL:
1191                pmlmeinfo->turboMode_cts2self = 1;
1192                pmlmeinfo->turboMode_rtsen = 0;
1193                break;
1194        case HT_IOT_PEER_RALINK:
1195                pmlmeinfo->turboMode_cts2self = 0;
1196                pmlmeinfo->turboMode_rtsen = 1;
1197                /* disable high power */
1198                Switch_DM_Func(padapter, (u32)(~DYNAMIC_BB_DYNAMIC_TXPWR),
1199                               false);
1200                break;
1201        case HT_IOT_PEER_REALTEK:
1202                /* disable high power */
1203                Switch_DM_Func(padapter, (u32)(~DYNAMIC_BB_DYNAMIC_TXPWR),
1204                               false);
1205                break;
1206        default:
1207                pmlmeinfo->turboMode_cts2self = 0;
1208                pmlmeinfo->turboMode_rtsen = 1;
1209                break;
1210        }
1211}
1212
1213void update_capinfo(struct adapter *Adapter, u16 updateCap)
1214{
1215        struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
1216        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1217        bool ShortPreamble;
1218
1219        /*  Check preamble mode, 2005.01.06, by rcnjko. */
1220        /*  Mark to update preamble value forever, 2008.03.18 by lanhsin */
1221
1222        if (updateCap & cShortPreamble) { /*  Short Preamble */
1223                if (pmlmeinfo->preamble_mode != PREAMBLE_SHORT) { /*  PREAMBLE_LONG or PREAMBLE_AUTO */
1224                        ShortPreamble = true;
1225                        pmlmeinfo->preamble_mode = PREAMBLE_SHORT;
1226                        rtw_hal_set_hwreg(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble);
1227                }
1228        } else { /*  Long Preamble */
1229                if (pmlmeinfo->preamble_mode != PREAMBLE_LONG) {  /*  PREAMBLE_SHORT or PREAMBLE_AUTO */
1230                        ShortPreamble = false;
1231                        pmlmeinfo->preamble_mode = PREAMBLE_LONG;
1232                        rtw_hal_set_hwreg(Adapter, HW_VAR_ACK_PREAMBLE, (u8 *)&ShortPreamble);
1233                }
1234        }
1235
1236        if (updateCap & cIBSS) {
1237                /* Filen: See 802.11-2007 p.91 */
1238                pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
1239        } else { /* Filen: See 802.11-2007 p.90 */
1240                if (pmlmeext->cur_wireless_mode & (WIRELESS_11G | WIRELESS_11_24N)) {
1241                        if (updateCap & cShortSlotTime) { /*  Short Slot Time */
1242                                if (pmlmeinfo->slotTime != SHORT_SLOT_TIME)
1243                                        pmlmeinfo->slotTime = SHORT_SLOT_TIME;
1244                        } else { /*  Long Slot Time */
1245                                if (pmlmeinfo->slotTime != NON_SHORT_SLOT_TIME)
1246                                        pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
1247                        }
1248                } else if (pmlmeext->cur_wireless_mode & (WIRELESS_11A | WIRELESS_11_5N)) {
1249                        pmlmeinfo->slotTime = SHORT_SLOT_TIME;
1250                } else {
1251                        /* B Mode */
1252                        pmlmeinfo->slotTime = NON_SHORT_SLOT_TIME;
1253                }
1254        }
1255
1256        rtw_hal_set_hwreg(Adapter, HW_VAR_SLOT_TIME, &pmlmeinfo->slotTime);
1257}
1258
1259void update_wireless_mode(struct adapter *padapter)
1260{
1261        int network_type = 0;
1262        u32 SIFS_Timer;
1263        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1264        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1265        struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
1266        unsigned char *rate = cur_network->SupportedRates;
1267
1268        if (pmlmeinfo->HT_info_enable && pmlmeinfo->HT_caps_enable)
1269                pmlmeinfo->HT_enable = 1;
1270
1271        if (pmlmeinfo->HT_enable)
1272                network_type = WIRELESS_11_24N;
1273
1274        if (rtw_is_cckratesonly_included(rate))
1275                network_type |= WIRELESS_11B;
1276        else if (rtw_is_cckrates_included(rate))
1277                network_type |= WIRELESS_11BG;
1278        else
1279                network_type |= WIRELESS_11G;
1280
1281        pmlmeext->cur_wireless_mode = network_type & padapter->registrypriv.wireless_mode;
1282
1283        SIFS_Timer = 0x0a0a0808;/* 0x0808 -> for CCK, 0x0a0a -> for OFDM */
1284                                /* change this value if having IOT issues. */
1285
1286        rtw_hal_set_hwreg(padapter, HW_VAR_RESP_SIFS,  (u8 *)&SIFS_Timer);
1287
1288        update_mgnt_tx_rate(padapter,
1289                            pmlmeext->cur_wireless_mode & WIRELESS_11B ?
1290                            IEEE80211_CCK_RATE_1MB : IEEE80211_OFDM_RATE_6MB);
1291}
1292
1293void update_bmc_sta_support_rate(struct adapter *padapter, u32 mac_id)
1294{
1295        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1296        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1297
1298        if (pmlmeext->cur_wireless_mode & WIRELESS_11B) {
1299                /*  Only B, B/G, and B/G/N AP could use CCK rate */
1300                memcpy((pmlmeinfo->FW_sta_info[mac_id].SupportedRates), rtw_basic_rate_cck, 4);
1301        } else {
1302                memcpy((pmlmeinfo->FW_sta_info[mac_id].SupportedRates), rtw_basic_rate_ofdm, 3);
1303        }
1304}
1305
1306int update_sta_support_rate(struct adapter *padapter, u8 *pvar_ie, uint var_ie_len, int cam_idx)
1307{
1308        unsigned int ie_len;
1309        struct ndis_802_11_var_ie *pIE;
1310        int supportRateNum = 0;
1311        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1312        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1313
1314        pIE = (struct ndis_802_11_var_ie *)rtw_get_ie(pvar_ie, WLAN_EID_SUPP_RATES, &ie_len, var_ie_len);
1315        if (!pIE)
1316                return _FAIL;
1317        if (ie_len > NDIS_802_11_LENGTH_RATES_EX)
1318                return _FAIL;
1319
1320        memcpy(pmlmeinfo->FW_sta_info[cam_idx].SupportedRates, pIE->data, ie_len);
1321        supportRateNum = ie_len;
1322
1323        pIE = (struct ndis_802_11_var_ie *)rtw_get_ie(pvar_ie, WLAN_EID_EXT_SUPP_RATES, &ie_len, var_ie_len);
1324        if (pIE) {
1325                if (supportRateNum + ie_len > NDIS_802_11_LENGTH_RATES_EX)
1326                        return _FAIL;
1327                memcpy((pmlmeinfo->FW_sta_info[cam_idx].SupportedRates + supportRateNum), pIE->data, ie_len);
1328        }
1329
1330        return _SUCCESS;
1331}
1332
1333void process_addba_req(struct adapter *padapter, u8 *paddba_req, u8 *addr)
1334{
1335        struct sta_info *psta;
1336        u16 tid;
1337        u16 param;
1338        struct recv_reorder_ctrl *preorder_ctrl;
1339        struct sta_priv *pstapriv = &padapter->stapriv;
1340        struct ADDBA_request *preq = (struct ADDBA_request *)paddba_req;
1341        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1342        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1343
1344        psta = rtw_get_stainfo(pstapriv, addr);
1345
1346        if (psta) {
1347                param = le16_to_cpu(preq->BA_para_set);
1348                tid = (param >> 2) & 0x0f;
1349                preorder_ctrl = &psta->recvreorder_ctrl[tid];
1350                preorder_ctrl->indicate_seq = 0xffff;
1351                preorder_ctrl->enable = pmlmeinfo->accept_addba_req;
1352        }
1353}
1354
1355void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len)
1356{
1357        u8 *pIE;
1358        __le32 *pbuf;
1359
1360        pIE = pframe + sizeof(struct ieee80211_hdr_3addr);
1361        pbuf = (__le32 *)pIE;
1362
1363        pmlmeext->TSFValue = le32_to_cpu(*(pbuf + 1));
1364
1365        pmlmeext->TSFValue = pmlmeext->TSFValue << 32;
1366
1367        pmlmeext->TSFValue |= le32_to_cpu(*pbuf);
1368}
1369
1370void correct_TSF(struct adapter *padapter, struct mlme_ext_priv *pmlmeext)
1371{
1372        rtw_hal_set_hwreg(padapter, HW_VAR_CORRECT_TSF, NULL);
1373}
1374