root/drivers/staging/rtl8188eu/core/rtw_wlan_util.c

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

DEFINITIONS

This source file includes following definitions.
  1. cckrates_included
  2. cckratesonly_included
  3. networktype_to_raid
  4. judge_network_type
  5. ratetbl_val_2wifirate
  6. is_basicrate
  7. ratetbl2rateset
  8. get_rate_set
  9. UpdateBrateTbl
  10. UpdateBrateTblForSoftAP
  11. Save_DM_Func_Flag
  12. Restore_DM_Func_Flag
  13. Switch_DM_Func
  14. Set_MSR
  15. rtw_get_oper_ch
  16. rtw_set_oper_ch
  17. rtw_set_oper_bw
  18. rtw_set_oper_choffset
  19. SelectChannel
  20. SetBWMode
  21. set_channel_bwmode
  22. get_beacon_interval
  23. is_client_associated_to_ap
  24. is_client_associated_to_ibss
  25. is_IBSS_empty
  26. decide_wait_for_beacon_timeout
  27. invalidate_cam_all
  28. write_cam
  29. clear_cam_entry
  30. allocate_fw_sta_entry
  31. flush_all_cam_entry
  32. WMM_param_handler
  33. WMMOnAssocRsp
  34. bwmode_update_check
  35. HT_caps_handler
  36. HT_info_handler
  37. HTOnAssocRsp
  38. ERP_IE_handler
  39. VCS_update
  40. rtw_check_bcn_info
  41. update_beacon_info
  42. is_ap_in_tkip
  43. wifirate2_ratetbl_inx
  44. update_basic_rate
  45. update_supported_rate
  46. update_MSC_rate
  47. support_short_GI
  48. get_highest_rate_idx
  49. Update_RA_Entry
  50. set_sta_rate
  51. update_tx_basic_rate
  52. check_assoc_AP
  53. update_IOT_info
  54. update_capinfo
  55. update_wireless_mode
  56. update_bmc_sta_support_rate
  57. update_sta_support_rate
  58. process_addba_req
  59. update_TSF
  60. correct_TSF

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

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