root/drivers/staging/rtl8723bs/core/rtw_ap.c

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

DEFINITIONS

This source file includes following definitions.
  1. init_mlme_ap_info
  2. free_mlme_ap_info
  3. update_BCNTIM
  4. chk_sta_is_alive
  5. expire_timeout_chk
  6. add_RATid
  7. update_bmc_sta
  8. update_sta_info_apmode
  9. update_ap_info
  10. update_hw_ht_param
  11. start_bss_network
  12. rtw_check_beacon_data
  13. rtw_set_macaddr_acl
  14. rtw_acl_add_sta
  15. rtw_acl_remove_sta
  16. rtw_ap_set_pairwise_key
  17. rtw_ap_set_key
  18. rtw_ap_set_group_key
  19. rtw_ap_set_wep_key
  20. update_bcn_fixed_ie
  21. update_bcn_erpinfo_ie
  22. update_bcn_htcap_ie
  23. update_bcn_htinfo_ie
  24. update_bcn_rsn_ie
  25. update_bcn_wpa_ie
  26. update_bcn_wmm_ie
  27. update_bcn_wps_ie
  28. update_bcn_p2p_ie
  29. update_bcn_vendor_spec_ie
  30. update_beacon
  31. rtw_ht_operation_update
  32. associated_clients_update
  33. bss_cap_update_on_sta_join
  34. bss_cap_update_on_sta_leave
  35. ap_free_sta
  36. rtw_sta_flush
  37. sta_info_update
  38. ap_sta_info_defer_update
  39. rtw_ap_restore_network
  40. start_ap_mode
  41. stop_ap_mode

   1 // SPDX-License-Identifier: GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
   5  *
   6  ******************************************************************************/
   7 #define _RTW_AP_C_
   8 
   9 #include <drv_types.h>
  10 #include <rtw_debug.h>
  11 
  12 extern unsigned char RTW_WPA_OUI[];
  13 extern unsigned char WMM_OUI[];
  14 extern unsigned char WPS_OUI[];
  15 extern unsigned char P2P_OUI[];
  16 
  17 void init_mlme_ap_info(struct adapter *padapter)
  18 {
  19         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  20         struct sta_priv *pstapriv = &padapter->stapriv;
  21         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
  22 
  23         spin_lock_init(&pmlmepriv->bcn_update_lock);
  24 
  25         /* for ACL */
  26         _rtw_init_queue(&pacl_list->acl_node_q);
  27 
  28         /* pmlmeext->bstart_bss = false; */
  29 
  30         start_ap_mode(padapter);
  31 }
  32 
  33 void free_mlme_ap_info(struct adapter *padapter)
  34 {
  35         struct sta_info *psta = NULL;
  36         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  37         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  38         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
  39 
  40         /* stop_ap_mode(padapter); */
  41 
  42         pmlmepriv->update_bcn = false;
  43         pmlmeext->bstart_bss = false;
  44 
  45         rtw_sta_flush(padapter);
  46 
  47         pmlmeinfo->state = _HW_STATE_NOLINK_;
  48 
  49         /* free_assoc_sta_resources */
  50         rtw_free_all_stainfo(padapter);
  51 
  52         /* free bc/mc sta_info */
  53         psta = rtw_get_bcmc_stainfo(padapter);
  54         rtw_free_stainfo(padapter, psta);
  55 }
  56 
  57 static void update_BCNTIM(struct adapter *padapter)
  58 {
  59         struct sta_priv *pstapriv = &padapter->stapriv;
  60         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  61         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
  62         struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network;
  63         unsigned char *pie = pnetwork_mlmeext->IEs;
  64 
  65         /* DBG_871X("%s\n", __func__); */
  66 
  67         /* update TIM IE */
  68         /* if (pstapriv->tim_bitmap) */
  69         if (true) {
  70                 u8 *p, *dst_ie, *premainder_ie = NULL, *pbackup_remainder_ie = NULL;
  71                 __le16 tim_bitmap_le;
  72                 uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;
  73 
  74                 tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap);
  75 
  76                 p = rtw_get_ie(
  77                         pie + _FIXED_IE_LENGTH_,
  78                         _TIM_IE_,
  79                         &tim_ielen,
  80                         pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_
  81                 );
  82                 if (p != NULL && tim_ielen > 0) {
  83                         tim_ielen += 2;
  84 
  85                         premainder_ie = p + tim_ielen;
  86 
  87                         tim_ie_offset = (sint)(p - pie);
  88 
  89                         remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen;
  90 
  91                         /* append TIM IE from dst_ie offset */
  92                         dst_ie = p;
  93                 } else {
  94                         tim_ielen = 0;
  95 
  96                         /* calculate head_len */
  97                         offset = _FIXED_IE_LENGTH_;
  98 
  99                         /* get ssid_ie len */
 100                         p = rtw_get_ie(
 101                                 pie + _BEACON_IE_OFFSET_,
 102                                 _SSID_IE_,
 103                                 &tmp_len,
 104                                 (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_)
 105                         );
 106                         if (p != NULL)
 107                                 offset += tmp_len + 2;
 108 
 109                         /*  get supported rates len */
 110                         p = rtw_get_ie(
 111                                 pie + _BEACON_IE_OFFSET_,
 112                                 _SUPPORTEDRATES_IE_, &tmp_len,
 113                                 (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_)
 114                         );
 115                         if (p !=  NULL)
 116                                 offset += tmp_len + 2;
 117 
 118                         /* DS Parameter Set IE, len =3 */
 119                         offset += 3;
 120 
 121                         premainder_ie = pie + offset;
 122 
 123                         remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen;
 124 
 125                         /* append TIM IE from offset */
 126                         dst_ie = pie + offset;
 127                 }
 128 
 129                 if (remainder_ielen > 0) {
 130                         pbackup_remainder_ie = rtw_malloc(remainder_ielen);
 131                         if (pbackup_remainder_ie && premainder_ie)
 132                                 memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
 133                 }
 134 
 135                 *dst_ie++ = _TIM_IE_;
 136 
 137                 if ((pstapriv->tim_bitmap & 0xff00) && (pstapriv->tim_bitmap & 0x00fe))
 138                         tim_ielen = 5;
 139                 else
 140                         tim_ielen = 4;
 141 
 142                 *dst_ie++ = tim_ielen;
 143 
 144                 *dst_ie++ = 0;/* DTIM count */
 145                 *dst_ie++ = 1;/* DTIM period */
 146 
 147                 if (pstapriv->tim_bitmap & BIT(0))/* for bc/mc frames */
 148                         *dst_ie++ = BIT(0);/* bitmap ctrl */
 149                 else
 150                         *dst_ie++ = 0;
 151 
 152                 if (tim_ielen == 4) {
 153                         __le16 pvb;
 154 
 155                         if (pstapriv->tim_bitmap & 0xff00)
 156                                 pvb = cpu_to_le16(pstapriv->tim_bitmap >> 8);
 157                         else
 158                                 pvb = tim_bitmap_le;
 159 
 160                         *dst_ie++ = le16_to_cpu(pvb);
 161 
 162                 } else if (tim_ielen == 5) {
 163                         memcpy(dst_ie, &tim_bitmap_le, 2);
 164                         dst_ie += 2;
 165                 }
 166 
 167                 /* copy remainder IE */
 168                 if (pbackup_remainder_ie) {
 169                         memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
 170 
 171                         kfree(pbackup_remainder_ie);
 172                 }
 173 
 174                 offset =  (uint)(dst_ie - pie);
 175                 pnetwork_mlmeext->IELength = offset + remainder_ielen;
 176         }
 177 }
 178 
 179 u8 chk_sta_is_alive(struct sta_info *psta);
 180 u8 chk_sta_is_alive(struct sta_info *psta)
 181 {
 182         #ifdef DBG_EXPIRATION_CHK
 183         DBG_871X(
 184                 "sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", expire_to:%u, %s%ssq_len:%u\n"
 185                 , MAC_ARG(psta->hwaddr)
 186                 , psta->rssi_stat.UndecoratedSmoothedPWDB
 187                 /*  STA_RX_PKTS_ARG(psta) */
 188                 , STA_RX_PKTS_DIFF_ARG(psta)
 189                 , psta->expire_to
 190                 , psta->state & WIFI_SLEEP_STATE ? "PS, " : ""
 191                 , psta->state & WIFI_STA_ALIVE_CHK_STATE ? "SAC, " : ""
 192                 , psta->sleepq_len
 193         );
 194         #endif
 195 
 196         sta_update_last_rx_pkts(psta);
 197 
 198         return true;
 199 }
 200 
 201 void expire_timeout_chk(struct adapter *padapter)
 202 {
 203         struct list_head        *phead, *plist;
 204         u8 updated = false;
 205         struct sta_info *psta = NULL;
 206         struct sta_priv *pstapriv = &padapter->stapriv;
 207         u8 chk_alive_num = 0;
 208         char chk_alive_list[NUM_STA];
 209         int i;
 210 
 211         spin_lock_bh(&pstapriv->auth_list_lock);
 212 
 213         phead = &pstapriv->auth_list;
 214         plist = get_next(phead);
 215 
 216         /* check auth_queue */
 217         #ifdef DBG_EXPIRATION_CHK
 218         if (phead != plist) {
 219                 DBG_871X(FUNC_NDEV_FMT" auth_list, cnt:%u\n"
 220                         , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->auth_list_cnt);
 221         }
 222         #endif
 223         while (phead != plist) {
 224                 psta = LIST_CONTAINOR(plist, struct sta_info, auth_list);
 225 
 226                 plist = get_next(plist);
 227 
 228                 if (psta->expire_to > 0) {
 229                         psta->expire_to--;
 230                         if (psta->expire_to == 0) {
 231                                 list_del_init(&psta->auth_list);
 232                                 pstapriv->auth_list_cnt--;
 233 
 234                                 DBG_871X(
 235                                         "auth expire %02X%02X%02X%02X%02X%02X\n",
 236                                         psta->hwaddr[0],
 237                                         psta->hwaddr[1],
 238                                         psta->hwaddr[2],
 239                                         psta->hwaddr[3],
 240                                         psta->hwaddr[4],
 241                                         psta->hwaddr[5]
 242                                 );
 243 
 244                                 spin_unlock_bh(&pstapriv->auth_list_lock);
 245 
 246                                 rtw_free_stainfo(padapter, psta);
 247 
 248                                 spin_lock_bh(&pstapriv->auth_list_lock);
 249                         }
 250                 }
 251         }
 252 
 253         spin_unlock_bh(&pstapriv->auth_list_lock);
 254         psta = NULL;
 255 
 256         spin_lock_bh(&pstapriv->asoc_list_lock);
 257 
 258         phead = &pstapriv->asoc_list;
 259         plist = get_next(phead);
 260 
 261         /* check asoc_queue */
 262         #ifdef DBG_EXPIRATION_CHK
 263         if (phead != plist) {
 264                 DBG_871X(FUNC_NDEV_FMT" asoc_list, cnt:%u\n"
 265                         , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->asoc_list_cnt);
 266         }
 267         #endif
 268         while (phead != plist) {
 269                 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
 270                 plist = get_next(plist);
 271 #ifdef CONFIG_AUTO_AP_MODE
 272                 if (psta->isrc)
 273                         continue;
 274 #endif
 275                 if (chk_sta_is_alive(psta) || !psta->expire_to) {
 276                         psta->expire_to = pstapriv->expire_to;
 277                         psta->keep_alive_trycnt = 0;
 278                         psta->under_exist_checking = 0;
 279                 } else {
 280                         if (psta->expire_to > 0)
 281                                 psta->expire_to--;
 282                 }
 283 
 284                 if (psta->expire_to == 0) {
 285                         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 286 
 287                         if (padapter->registrypriv.wifi_spec == 1) {
 288                                 psta->expire_to = pstapriv->expire_to;
 289                                 continue;
 290                         }
 291 
 292                         if (psta->state & WIFI_SLEEP_STATE) {
 293                                 if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
 294                                         /* to check if alive by another methods if station is at ps mode. */
 295                                         psta->expire_to = pstapriv->expire_to;
 296                                         psta->state |= WIFI_STA_ALIVE_CHK_STATE;
 297 
 298                                         /* DBG_871X("alive chk, sta:" MAC_FMT " is at ps mode!\n", MAC_ARG(psta->hwaddr)); */
 299 
 300                                         /* to update bcn with tim_bitmap for this station */
 301                                         pstapriv->tim_bitmap |= BIT(psta->aid);
 302                                         update_beacon(padapter, _TIM_IE_, NULL, true);
 303 
 304                                         if (!pmlmeext->active_keep_alive_check)
 305                                                 continue;
 306                                 }
 307                         }
 308                         if (pmlmeext->active_keep_alive_check) {
 309                                 int stainfo_offset;
 310 
 311                                 stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
 312                                 if (stainfo_offset_valid(stainfo_offset))
 313                                         chk_alive_list[chk_alive_num++] = stainfo_offset;
 314 
 315                                 continue;
 316                         }
 317                         list_del_init(&psta->asoc_list);
 318                         pstapriv->asoc_list_cnt--;
 319                         DBG_871X(
 320                                 "asoc expire "MAC_FMT", state = 0x%x\n",
 321                                 MAC_ARG(psta->hwaddr),
 322                                 psta->state
 323                         );
 324                         updated = ap_free_sta(padapter, psta, false, WLAN_REASON_DEAUTH_LEAVING);
 325                 } else {
 326                         /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */
 327                         if (psta->sleepq_len > (NR_XMITFRAME / pstapriv->asoc_list_cnt)
 328                                 && padapter->xmitpriv.free_xmitframe_cnt < ((
 329                                         NR_XMITFRAME / pstapriv->asoc_list_cnt
 330                                 ) / 2)
 331                         ) {
 332                                 DBG_871X(
 333                                         "%s sta:"MAC_FMT", sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n",
 334                                         __func__,
 335                                         MAC_ARG(psta->hwaddr),
 336                                         psta->sleepq_len,
 337                                         padapter->xmitpriv.free_xmitframe_cnt,
 338                                         pstapriv->asoc_list_cnt
 339                                 );
 340                                 wakeup_sta_to_xmit(padapter, psta);
 341                         }
 342                 }
 343         }
 344 
 345         spin_unlock_bh(&pstapriv->asoc_list_lock);
 346 
 347         if (chk_alive_num) {
 348                 u8 backup_oper_channel = 0;
 349                 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 350 
 351                 /* switch to correct channel of current network  before issue keep-alive frames */
 352                 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
 353                         backup_oper_channel = rtw_get_oper_ch(padapter);
 354                         SelectChannel(padapter, pmlmeext->cur_channel);
 355                 }
 356 
 357                 /* issue null data to check sta alive*/
 358                 for (i = 0; i < chk_alive_num; i++) {
 359                         int ret = _FAIL;
 360 
 361                         psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
 362                         if (!(psta->state & _FW_LINKED))
 363                                 continue;
 364 
 365                         if (psta->state & WIFI_SLEEP_STATE)
 366                                 ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50);
 367                         else
 368                                 ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50);
 369 
 370                         psta->keep_alive_trycnt++;
 371                         if (ret == _SUCCESS) {
 372                                 DBG_871X(
 373                                         "asoc check, sta(" MAC_FMT ") is alive\n",
 374                                         MAC_ARG(psta->hwaddr)
 375                                         );
 376                                 psta->expire_to = pstapriv->expire_to;
 377                                 psta->keep_alive_trycnt = 0;
 378                                 continue;
 379                         } else if (psta->keep_alive_trycnt <= 3) {
 380                                 DBG_871X(
 381                                         "ack check for asoc expire, keep_alive_trycnt =%d\n",
 382                                         psta->keep_alive_trycnt);
 383                                 psta->expire_to = 1;
 384                                 continue;
 385                         }
 386 
 387                         psta->keep_alive_trycnt = 0;
 388                         DBG_871X(
 389                                 "asoc expire "MAC_FMT", state = 0x%x\n",
 390                                 MAC_ARG(psta->hwaddr),
 391                                 psta->state);
 392                         spin_lock_bh(&pstapriv->asoc_list_lock);
 393                         if (list_empty(&psta->asoc_list) == false) {
 394                                 list_del_init(&psta->asoc_list);
 395                                 pstapriv->asoc_list_cnt--;
 396                                 updated = ap_free_sta(padapter, psta, false, WLAN_REASON_DEAUTH_LEAVING);
 397                         }
 398                         spin_unlock_bh(&pstapriv->asoc_list_lock);
 399                 }
 400 
 401                 if (backup_oper_channel > 0) /* back to the original operation channel */
 402                         SelectChannel(padapter, backup_oper_channel);
 403         }
 404 
 405         associated_clients_update(padapter, updated);
 406 }
 407 
 408 void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level)
 409 {
 410         unsigned char sta_band = 0, shortGIrate = false;
 411         unsigned int tx_ra_bitmap = 0;
 412         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
 413         struct wlan_bssid_ex
 414                 *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
 415 
 416         if (!psta)
 417                 return;
 418 
 419         if (!(psta->state & _FW_LINKED))
 420                 return;
 421 
 422         rtw_hal_update_sta_rate_mask(padapter, psta);
 423         tx_ra_bitmap = psta->ra_mask;
 424 
 425         shortGIrate = query_ra_short_GI(psta);
 426 
 427         if (pcur_network->Configuration.DSConfig > 14) {
 428                 if (tx_ra_bitmap & 0xffff000)
 429                         sta_band |= WIRELESS_11_5N;
 430 
 431                 if (tx_ra_bitmap & 0xff0)
 432                         sta_band |= WIRELESS_11A;
 433         } else {
 434                 if (tx_ra_bitmap & 0xffff000)
 435                         sta_band |= WIRELESS_11_24N;
 436 
 437                 if (tx_ra_bitmap & 0xff0)
 438                         sta_band |= WIRELESS_11G;
 439 
 440                 if (tx_ra_bitmap & 0x0f)
 441                         sta_band |= WIRELESS_11B;
 442         }
 443 
 444         psta->wireless_mode = sta_band;
 445         psta->raid = networktype_to_raid_ex(padapter, psta);
 446 
 447         if (psta->aid < NUM_STA) {
 448                 u8 arg[4] = {0};
 449 
 450                 arg[0] = psta->mac_id;
 451                 arg[1] = psta->raid;
 452                 arg[2] = shortGIrate;
 453                 arg[3] = psta->init_rate;
 454 
 455                 DBG_871X("%s => mac_id:%d , raid:%d , shortGIrate =%d, bitmap = 0x%x\n",
 456                         __func__, psta->mac_id, psta->raid, shortGIrate, tx_ra_bitmap);
 457 
 458                 rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, rssi_level);
 459         } else {
 460                 DBG_871X("station aid %d exceed the max number\n", psta->aid);
 461         }
 462 }
 463 
 464 void update_bmc_sta(struct adapter *padapter)
 465 {
 466         unsigned char network_type;
 467         int supportRateNum = 0;
 468         unsigned int tx_ra_bitmap = 0;
 469         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
 470         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
 471         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
 472         struct wlan_bssid_ex
 473                 *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
 474         struct sta_info *psta = rtw_get_bcmc_stainfo(padapter);
 475 
 476         if (psta) {
 477                 psta->aid = 0;/* default set to 0 */
 478                 /* psta->mac_id = psta->aid+4; */
 479                 psta->mac_id = psta->aid + 1;/* mac_id = 1 for bc/mc stainfo */
 480 
 481                 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
 482 
 483                 psta->qos_option = 0;
 484                 psta->htpriv.ht_option = false;
 485 
 486                 psta->ieee8021x_blocked = 0;
 487 
 488                 memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
 489 
 490                 /* psta->dot118021XPrivacy = _NO_PRIVACY_;//!!! remove it, because it has been set before this. */
 491 
 492                 /* prepare for add_RATid */
 493                 supportRateNum = rtw_get_rateset_len((u8 *)&pcur_network->SupportedRates);
 494                 network_type = rtw_check_network_type(
 495                         (u8 *)&pcur_network->SupportedRates,
 496                         supportRateNum,
 497                         pcur_network->Configuration.DSConfig
 498                 );
 499                 if (IsSupportedTxCCK(network_type)) {
 500                         network_type = WIRELESS_11B;
 501                 } else if (network_type == WIRELESS_INVALID) { /*  error handling */
 502 
 503                         if (pcur_network->Configuration.DSConfig > 14)
 504                                 network_type = WIRELESS_11A;
 505                         else
 506                                 network_type = WIRELESS_11B;
 507                 }
 508                 update_sta_basic_rate(psta, network_type);
 509                 psta->wireless_mode = network_type;
 510 
 511                 rtw_hal_update_sta_rate_mask(padapter, psta);
 512                 tx_ra_bitmap = psta->ra_mask;
 513 
 514                 psta->raid = networktype_to_raid_ex(padapter, psta);
 515 
 516                 /* ap mode */
 517                 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
 518 
 519                 /* if (pHalData->fw_ractrl == true) */
 520                 {
 521                         u8 arg[4] = {0};
 522 
 523                         arg[0] = psta->mac_id;
 524                         arg[1] = psta->raid;
 525                         arg[2] = 0;
 526                         arg[3] = psta->init_rate;
 527 
 528                         DBG_871X("%s => mac_id:%d , raid:%d , bitmap = 0x%x\n",
 529                                 __func__, psta->mac_id, psta->raid, tx_ra_bitmap);
 530 
 531                         rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, 0);
 532                 }
 533 
 534                 rtw_sta_media_status_rpt(padapter, psta, 1);
 535 
 536                 spin_lock_bh(&psta->lock);
 537                 psta->state = _FW_LINKED;
 538                 spin_unlock_bh(&psta->lock);
 539 
 540         } else {
 541                 DBG_871X("add_RATid_bmc_sta error!\n");
 542         }
 543 }
 544 
 545 /* notes: */
 546 /* AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode */
 547 /* MAC_ID = AID+1 for sta in ap/adhoc mode */
 548 /* MAC_ID = 1 for bc/mc for sta/ap/adhoc */
 549 /* MAC_ID = 0 for bssid for sta/ap/adhoc */
 550 /* CAM_ID = 0~3 for default key, cmd_id =macid + 3, macid =aid+1; */
 551 
 552 void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta)
 553 {
 554         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
 555         struct security_priv *psecuritypriv = &padapter->securitypriv;
 556         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
 557         struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
 558         struct ht_priv *phtpriv_sta = &psta->htpriv;
 559         u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, cur_beamform_cap = 0;
 560         /* set intf_tag to if1 */
 561         /* psta->intf_tag = 0; */
 562 
 563         DBG_871X("%s\n", __func__);
 564 
 565         /* psta->mac_id = psta->aid+4; */
 566         /* psta->mac_id = psta->aid+1;//alloc macid when call rtw_alloc_stainfo(), */
 567         /* release macid when call rtw_free_stainfo() */
 568 
 569         /* ap mode */
 570         rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
 571 
 572         if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
 573                 psta->ieee8021x_blocked = true;
 574         else
 575                 psta->ieee8021x_blocked = false;
 576 
 577         /* update sta's cap */
 578 
 579         /* ERP */
 580         VCS_update(padapter, psta);
 581 
 582         /* HT related cap */
 583         if (phtpriv_sta->ht_option) {
 584                 /* check if sta supports rx ampdu */
 585                 phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;
 586 
 587                 phtpriv_sta->rx_ampdu_min_spacing = (
 588                         phtpriv_sta->ht_cap.ampdu_params_info & IEEE80211_HT_CAP_AMPDU_DENSITY
 589                 ) >> 2;
 590 
 591                 /*  bwmode */
 592                 if ((
 593                         phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info
 594                 ) & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH))
 595                         psta->bw_mode = CHANNEL_WIDTH_40;
 596                 else
 597                         psta->bw_mode = CHANNEL_WIDTH_20;
 598 
 599                 if (pmlmeext->cur_bwmode < psta->bw_mode)
 600                         psta->bw_mode = pmlmeext->cur_bwmode;
 601 
 602                 phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
 603 
 604                 /* check if sta support s Short GI 20M */
 605                 if ((
 606                         phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info
 607                 ) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20))
 608                         phtpriv_sta->sgi_20m = true;
 609 
 610                 /* check if sta support s Short GI 40M */
 611                 if ((
 612                         phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info
 613                 ) & cpu_to_le16(IEEE80211_HT_CAP_SGI_40)) {
 614                         if (psta->bw_mode == CHANNEL_WIDTH_40) /* according to psta->bw_mode */
 615                                 phtpriv_sta->sgi_40m = true;
 616                         else
 617                                 phtpriv_sta->sgi_40m = false;
 618                 }
 619 
 620                 psta->qos_option = true;
 621 
 622                 /*  B0 Config LDPC Coding Capability */
 623                 if (TEST_FLAG(phtpriv_ap->ldpc_cap, LDPC_HT_ENABLE_TX) &&
 624                         GET_HT_CAPABILITY_ELE_LDPC_CAP((u8 *)(&phtpriv_sta->ht_cap))) {
 625                         SET_FLAG(cur_ldpc_cap, (LDPC_HT_ENABLE_TX | LDPC_HT_CAP_TX));
 626                         DBG_871X("Enable HT Tx LDPC for STA(%d)\n", psta->aid);
 627                 }
 628 
 629                 /*  B7 B8 B9 Config STBC setting */
 630                 if (TEST_FLAG(phtpriv_ap->stbc_cap, STBC_HT_ENABLE_TX) &&
 631                         GET_HT_CAPABILITY_ELE_RX_STBC((u8 *)(&phtpriv_sta->ht_cap))) {
 632                         SET_FLAG(cur_stbc_cap, (STBC_HT_ENABLE_TX | STBC_HT_CAP_TX));
 633                         DBG_871X("Enable HT Tx STBC for STA(%d)\n", psta->aid);
 634                 }
 635         } else {
 636                 phtpriv_sta->ampdu_enable = false;
 637 
 638                 phtpriv_sta->sgi_20m = false;
 639                 phtpriv_sta->sgi_40m = false;
 640                 psta->bw_mode = CHANNEL_WIDTH_20;
 641                 phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
 642         }
 643 
 644         phtpriv_sta->ldpc_cap = cur_ldpc_cap;
 645         phtpriv_sta->stbc_cap = cur_stbc_cap;
 646         phtpriv_sta->beamform_cap = cur_beamform_cap;
 647 
 648         /* Rx AMPDU */
 649         send_delba(padapter, 0, psta->hwaddr);/*  recipient */
 650 
 651         /* TX AMPDU */
 652         send_delba(padapter, 1, psta->hwaddr);/* originator */
 653         phtpriv_sta->agg_enable_bitmap = 0x0;/* reset */
 654         phtpriv_sta->candidate_tid_bitmap = 0x0;/* reset */
 655 
 656         update_ldpc_stbc_cap(psta);
 657 
 658         /* todo: init other variables */
 659 
 660         memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
 661 
 662         /* add ratid */
 663         /* add_RATid(padapter, psta);//move to ap_sta_info_defer_update() */
 664 
 665         spin_lock_bh(&psta->lock);
 666         psta->state |= _FW_LINKED;
 667         spin_unlock_bh(&psta->lock);
 668 }
 669 
 670 static void update_ap_info(struct adapter *padapter, struct sta_info *psta)
 671 {
 672         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
 673         struct wlan_bssid_ex
 674                 *pnetwork = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
 675         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
 676         struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
 677 
 678         psta->wireless_mode = pmlmeext->cur_wireless_mode;
 679 
 680         psta->bssratelen = rtw_get_rateset_len(pnetwork->SupportedRates);
 681         memcpy(psta->bssrateset, pnetwork->SupportedRates, psta->bssratelen);
 682 
 683         /* HT related cap */
 684         if (phtpriv_ap->ht_option) {
 685                 /* check if sta supports rx ampdu */
 686                 /* phtpriv_ap->ampdu_enable = phtpriv_ap->ampdu_enable; */
 687 
 688                 /* check if sta support s Short GI 20M */
 689                 if ((phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20))
 690                         phtpriv_ap->sgi_20m = true;
 691 
 692                 /* check if sta support s Short GI 40M */
 693                 if ((phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_40))
 694                         phtpriv_ap->sgi_40m = true;
 695 
 696                 psta->qos_option = true;
 697         } else {
 698                 phtpriv_ap->ampdu_enable = false;
 699 
 700                 phtpriv_ap->sgi_20m = false;
 701                 phtpriv_ap->sgi_40m = false;
 702         }
 703 
 704         psta->bw_mode = pmlmeext->cur_bwmode;
 705         phtpriv_ap->ch_offset = pmlmeext->cur_ch_offset;
 706 
 707         phtpriv_ap->agg_enable_bitmap = 0x0;/* reset */
 708         phtpriv_ap->candidate_tid_bitmap = 0x0;/* reset */
 709 
 710         memcpy(&psta->htpriv, &pmlmepriv->htpriv, sizeof(struct ht_priv));
 711 }
 712 
 713 static void update_hw_ht_param(struct adapter *padapter)
 714 {
 715         unsigned char max_AMPDU_len;
 716         unsigned char min_MPDU_spacing;
 717         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 718         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
 719 
 720         DBG_871X("%s\n", __func__);
 721 
 722         /* handle A-MPDU parameter field */
 723         /*
 724                 AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
 725                 AMPDU_para [4:2]:Min MPDU Start Spacing
 726         */
 727         max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
 728 
 729         min_MPDU_spacing = (
 730                 pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c
 731         ) >> 2;
 732 
 733         rtw_hal_set_hwreg(
 734                 padapter,
 735                 HW_VAR_AMPDU_MIN_SPACE,
 736                 (u8 *)(&min_MPDU_spacing)
 737         );
 738 
 739         rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
 740 
 741         /*  */
 742         /*  Config SM Power Save setting */
 743         /*  */
 744         pmlmeinfo->SM_PS = (le16_to_cpu(
 745                 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info
 746         ) & 0x0C) >> 2;
 747         if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
 748                 DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
 749 
 750         /*  */
 751         /*  Config current HT Protection mode. */
 752         /*  */
 753         /* pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3; */
 754 }
 755 
 756 void start_bss_network(struct adapter *padapter, u8 *pbuf)
 757 {
 758         u8 *p;
 759         u8 val8, cur_channel, cur_bwmode, cur_ch_offset;
 760         u16 bcn_interval;
 761         u32 acparm;
 762         int     ie_len;
 763         struct registry_priv  *pregpriv = &padapter->registrypriv;
 764         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
 765         struct security_priv *psecuritypriv = &(padapter->securitypriv);
 766         struct wlan_bssid_ex
 767                 *pnetwork = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
 768         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
 769         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
 770         struct wlan_bssid_ex *pnetwork_mlmeext = &(pmlmeinfo->network);
 771         struct HT_info_element *pht_info = NULL;
 772         u8 cbw40_enable = 0;
 773 
 774         /* DBG_871X("%s\n", __func__); */
 775 
 776         bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod;
 777         cur_channel = pnetwork->Configuration.DSConfig;
 778         cur_bwmode = CHANNEL_WIDTH_20;
 779         cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
 780 
 781         /* check if there is wps ie, */
 782         /* if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd, */
 783         /* and at first time the security ie (RSN/WPA IE) will not include in beacon. */
 784         if (!rtw_get_wps_ie(pnetwork->IEs + _FIXED_IE_LENGTH_,
 785                             pnetwork->IELength - _FIXED_IE_LENGTH_, NULL, NULL))
 786                 pmlmeext->bstart_bss = true;
 787 
 788         /* todo: update wmm, ht cap */
 789         /* pmlmeinfo->WMM_enable; */
 790         /* pmlmeinfo->HT_enable; */
 791         if (pmlmepriv->qospriv.qos_option)
 792                 pmlmeinfo->WMM_enable = true;
 793         if (pmlmepriv->htpriv.ht_option) {
 794                 pmlmeinfo->WMM_enable = true;
 795                 pmlmeinfo->HT_enable = true;
 796                 /* pmlmeinfo->HT_info_enable = true; */
 797                 /* pmlmeinfo->HT_caps_enable = true; */
 798 
 799                 update_hw_ht_param(padapter);
 800         }
 801 
 802         if (!pmlmepriv->cur_network.join_res) { /* setting only at  first time */
 803 
 804                 /* WEP Key will be set before this function, do not clear CAM. */
 805                 if (
 806                         (psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) &&
 807                         (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
 808                 )
 809                         flush_all_cam_entry(padapter);  /* clear CAM */
 810         }
 811 
 812         /* set MSR to AP_Mode */
 813         Set_MSR(padapter, _HW_STATE_AP_);
 814 
 815         /* Set BSSID REG */
 816         rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress);
 817 
 818         /* Set EDCA param reg */
 819         acparm = 0x002F3217; /*  VO */
 820         rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
 821         acparm = 0x005E4317; /*  VI */
 822         rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
 823         /* acparm = 0x00105320; // BE */
 824         acparm = 0x005ea42b;
 825         rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
 826         acparm = 0x0000A444; /*  BK */
 827         rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
 828 
 829         /* Set Security */
 830         val8 = (
 831                 psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X
 832         ) ? 0xcc : 0xcf;
 833         rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
 834 
 835         /* Beacon Control related register */
 836         rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval));
 837 
 838         rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL);
 839 
 840         if (!pmlmepriv->cur_network.join_res) { /* setting only at  first time */
 841                 /* u32 initialgain; */
 842 
 843                 /* initialgain = 0x1e; */
 844 
 845                 /* disable dynamic functions, such as high power, DIG */
 846                 /* Save_DM_Func_Flag(padapter); */
 847                 /* Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); */
 848 
 849                 /* turn on all dynamic functions */
 850                 Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true);
 851 
 852                 /* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
 853         }
 854 
 855         /* set channel, bwmode */
 856         p = rtw_get_ie(
 857                 (pnetwork->IEs + sizeof(struct ndis_802_11_fix_ie)),
 858                 _HT_ADD_INFO_IE_,
 859                 &ie_len,
 860                 (pnetwork->IELength - sizeof(struct ndis_802_11_fix_ie))
 861         );
 862         if (p && ie_len) {
 863                 pht_info = (struct HT_info_element *)(p + 2);
 864 
 865                 if (cur_channel > 14) {
 866                         if ((pregpriv->bw_mode & 0xf0) > 0)
 867                                 cbw40_enable = 1;
 868                 } else {
 869                         if ((pregpriv->bw_mode & 0x0f) > 0)
 870                                 cbw40_enable = 1;
 871                 }
 872 
 873                 if ((cbw40_enable) &&    (pht_info->infos[0] & BIT(2))) {
 874                         /* switch to the 40M Hz mode */
 875                         /* pmlmeext->cur_bwmode = CHANNEL_WIDTH_40; */
 876                         cur_bwmode = CHANNEL_WIDTH_40;
 877                         switch (pht_info->infos[0] & 0x3) {
 878                         case 1:
 879                                 /* pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; */
 880                                 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
 881                                 break;
 882 
 883                         case 3:
 884                                 /* pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; */
 885                                 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
 886                                 break;
 887 
 888                         default:
 889                                 /* pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; */
 890                                 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
 891                                 break;
 892                         }
 893                 }
 894         }
 895 
 896         set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
 897         DBG_871X(
 898                 "CH =%d, BW =%d, offset =%d\n",
 899                 cur_channel,
 900                 cur_bwmode,
 901                 cur_ch_offset
 902         );
 903         pmlmeext->cur_channel = cur_channel;
 904         pmlmeext->cur_bwmode = cur_bwmode;
 905         pmlmeext->cur_ch_offset = cur_ch_offset;
 906         pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type;
 907 
 908         /* let pnetwork_mlmeext == pnetwork_mlme. */
 909         memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);
 910 
 911         /* update cur_wireless_mode */
 912         update_wireless_mode(padapter);
 913 
 914         /* update RRSR after set channel and bandwidth */
 915         UpdateBrateTbl(padapter, pnetwork->SupportedRates);
 916         rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
 917 
 918         /* update capability after cur_wireless_mode updated */
 919         update_capinfo(
 920                 padapter,
 921                 rtw_get_capability((struct wlan_bssid_ex *)pnetwork)
 922         );
 923 
 924         if (pmlmeext->bstart_bss) {
 925                 update_beacon(padapter, _TIM_IE_, NULL, true);
 926 
 927 #ifndef CONFIG_INTERRUPT_BASED_TXBCN /* other case will  tx beacon when bcn interrupt coming in. */
 928                 /* issue beacon frame */
 929                 if (send_beacon(padapter) == _FAIL)
 930                         DBG_871X("issue_beacon, fail!\n");
 931 
 932 #endif /* CONFIG_INTERRUPT_BASED_TXBCN */
 933         }
 934 
 935         /* update bc/mc sta_info */
 936         update_bmc_sta(padapter);
 937 
 938         /* pmlmeext->bstart_bss = true; */
 939 }
 940 
 941 int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
 942 {
 943         int ret = _SUCCESS;
 944         u8 *p;
 945         u8 *pHT_caps_ie = NULL;
 946         u8 *pHT_info_ie = NULL;
 947         struct sta_info *psta = NULL;
 948         u16 cap, ht_cap = false;
 949         uint ie_len = 0;
 950         int group_cipher, pairwise_cipher;
 951         u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX];
 952         int supportRateNum = 0;
 953         u8 OUI1[] = {0x00, 0x50, 0xf2, 0x01};
 954         u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
 955         struct registry_priv *pregistrypriv = &padapter->registrypriv;
 956         struct security_priv *psecuritypriv = &padapter->securitypriv;
 957         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
 958         struct wlan_bssid_ex
 959                 *pbss_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
 960         u8 *ie = pbss_network->IEs;
 961 
 962         /* SSID */
 963         /* Supported rates */
 964         /* DS Params */
 965         /* WLAN_EID_COUNTRY */
 966         /* ERP Information element */
 967         /* Extended supported rates */
 968         /* WPA/WPA2 */
 969         /* Wi-Fi Wireless Multimedia Extensions */
 970         /* ht_capab, ht_oper */
 971         /* WPS IE */
 972 
 973         DBG_871X("%s, len =%d\n", __func__, len);
 974 
 975         if (!check_fwstate(pmlmepriv, WIFI_AP_STATE))
 976                 return _FAIL;
 977 
 978         if (len < 0 || len > MAX_IE_SZ)
 979                 return _FAIL;
 980 
 981         pbss_network->IELength = len;
 982 
 983         memset(ie, 0, MAX_IE_SZ);
 984 
 985         memcpy(ie, pbuf, pbss_network->IELength);
 986 
 987         if (pbss_network->InfrastructureMode != Ndis802_11APMode)
 988                 return _FAIL;
 989 
 990         pbss_network->Rssi = 0;
 991 
 992         memcpy(pbss_network->MacAddress, myid(&(padapter->eeprompriv)), ETH_ALEN);
 993 
 994         /* beacon interval */
 995         p = rtw_get_beacon_interval_from_ie(ie);/* ie + 8;      8: TimeStamp, 2: Beacon Interval 2:Capability */
 996         /* pbss_network->Configuration.BeaconPeriod = le16_to_cpu(*(unsigned short*)p); */
 997         pbss_network->Configuration.BeaconPeriod = RTW_GET_LE16(p);
 998 
 999         /* capability */
1000         /* cap = *(unsigned short *)rtw_get_capability_from_ie(ie); */
1001         /* cap = le16_to_cpu(cap); */
1002         cap = RTW_GET_LE16(ie);
1003 
1004         /* SSID */
1005         p = rtw_get_ie(
1006                 ie + _BEACON_IE_OFFSET_,
1007                 _SSID_IE_,
1008                 &ie_len,
1009                 (pbss_network->IELength - _BEACON_IE_OFFSET_)
1010         );
1011         if (p && ie_len > 0) {
1012                 memset(&pbss_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
1013                 memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len);
1014                 pbss_network->Ssid.SsidLength = ie_len;
1015         }
1016 
1017         /* channel */
1018         channel = 0;
1019         pbss_network->Configuration.Length = 0;
1020         p = rtw_get_ie(
1021                 ie + _BEACON_IE_OFFSET_,
1022                 _DSSET_IE_, &ie_len,
1023                 (pbss_network->IELength - _BEACON_IE_OFFSET_)
1024         );
1025         if (p && ie_len > 0)
1026                 channel = *(p + 2);
1027 
1028         pbss_network->Configuration.DSConfig = channel;
1029 
1030         memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
1031         /*  get supported rates */
1032         p = rtw_get_ie(
1033                 ie + _BEACON_IE_OFFSET_,
1034                 _SUPPORTEDRATES_IE_,
1035                 &ie_len,
1036                 (pbss_network->IELength - _BEACON_IE_OFFSET_)
1037         );
1038         if (p !=  NULL) {
1039                 memcpy(supportRate, p + 2, ie_len);
1040                 supportRateNum = ie_len;
1041         }
1042 
1043         /* get ext_supported rates */
1044         p = rtw_get_ie(
1045                 ie + _BEACON_IE_OFFSET_,
1046                 _EXT_SUPPORTEDRATES_IE_,
1047                 &ie_len,
1048                 pbss_network->IELength - _BEACON_IE_OFFSET_
1049         );
1050         if (p !=  NULL) {
1051                 memcpy(supportRate + supportRateNum, p + 2, ie_len);
1052                 supportRateNum += ie_len;
1053         }
1054 
1055         network_type = rtw_check_network_type(supportRate, supportRateNum, channel);
1056 
1057         rtw_set_supported_rate(pbss_network->SupportedRates, network_type);
1058 
1059         /* parsing ERP_IE */
1060         p = rtw_get_ie(
1061                 ie + _BEACON_IE_OFFSET_,
1062                 _ERPINFO_IE_,
1063                 &ie_len,
1064                 (pbss_network->IELength - _BEACON_IE_OFFSET_)
1065         );
1066         if (p && ie_len > 0)
1067                 ERP_IE_handler(padapter, (struct ndis_80211_var_ie *)p);
1068 
1069         /* update privacy/security */
1070         if (cap & BIT(4))
1071                 pbss_network->Privacy = 1;
1072         else
1073                 pbss_network->Privacy = 0;
1074 
1075         psecuritypriv->wpa_psk = 0;
1076 
1077         /* wpa2 */
1078         group_cipher = 0; pairwise_cipher = 0;
1079         psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
1080         psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
1081         p = rtw_get_ie(
1082                 ie + _BEACON_IE_OFFSET_,
1083                 _RSN_IE_2_,
1084                 &ie_len,
1085                 (pbss_network->IELength - _BEACON_IE_OFFSET_)
1086         );
1087         if (p && ie_len > 0) {
1088                 if (rtw_parse_wpa2_ie(
1089                         p,
1090                         ie_len + 2,
1091                         &group_cipher,
1092                         &pairwise_cipher,
1093                         NULL
1094                 ) == _SUCCESS) {
1095                         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1096 
1097                         psecuritypriv->dot8021xalg = 1;/* psk,  todo:802.1x */
1098                         psecuritypriv->wpa_psk |= BIT(1);
1099 
1100                         psecuritypriv->wpa2_group_cipher = group_cipher;
1101                         psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher;
1102                 }
1103         }
1104 
1105         /* wpa */
1106         ie_len = 0;
1107         group_cipher = 0; pairwise_cipher = 0;
1108         psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
1109         psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
1110         for (p = ie + _BEACON_IE_OFFSET_; ; p += (ie_len + 2)) {
1111                 p = rtw_get_ie(
1112                         p,
1113                         _SSN_IE_1_,
1114                         &ie_len,
1115                         (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))
1116                 );
1117                 if ((p) && (!memcmp(p + 2, OUI1, 4))) {
1118                         if (rtw_parse_wpa_ie(
1119                                 p,
1120                                 ie_len + 2,
1121                                 &group_cipher,
1122                                 &pairwise_cipher,
1123                                 NULL
1124                         ) == _SUCCESS) {
1125                                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1126 
1127                                 psecuritypriv->dot8021xalg = 1;/* psk,  todo:802.1x */
1128 
1129                                 psecuritypriv->wpa_psk |= BIT(0);
1130 
1131                                 psecuritypriv->wpa_group_cipher = group_cipher;
1132                                 psecuritypriv->wpa_pairwise_cipher = pairwise_cipher;
1133                         }
1134 
1135                         break;
1136                 }
1137 
1138                 if ((p == NULL) || (ie_len == 0))
1139                                 break;
1140         }
1141 
1142         /* wmm */
1143         ie_len = 0;
1144         pmlmepriv->qospriv.qos_option = 0;
1145         if (pregistrypriv->wmm_enable) {
1146                 for (p = ie + _BEACON_IE_OFFSET_; ; p += (ie_len + 2)) {
1147                         p = rtw_get_ie(
1148                                 p,
1149                                 _VENDOR_SPECIFIC_IE_,
1150                                 &ie_len,
1151                                 (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))
1152                         );
1153                         if ((p) && !memcmp(p + 2, WMM_PARA_IE, 6)) {
1154                                 pmlmepriv->qospriv.qos_option = 1;
1155 
1156                                 *(p + 8) |= BIT(7);/* QoS Info, support U-APSD */
1157 
1158                                 /* disable all ACM bits since the WMM admission control is not supported */
1159                                 *(p + 10) &= ~BIT(4); /* BE */
1160                                 *(p + 14) &= ~BIT(4); /* BK */
1161                                 *(p + 18) &= ~BIT(4); /* VI */
1162                                 *(p + 22) &= ~BIT(4); /* VO */
1163 
1164                                 break;
1165                         }
1166 
1167                         if ((p == NULL) || (ie_len == 0))
1168                                 break;
1169                 }
1170         }
1171 
1172         /* parsing HT_CAP_IE */
1173         p = rtw_get_ie(
1174                 ie + _BEACON_IE_OFFSET_,
1175                 _HT_CAPABILITY_IE_,
1176                 &ie_len,
1177                 (pbss_network->IELength - _BEACON_IE_OFFSET_)
1178         );
1179         if (p && ie_len > 0) {
1180                 u8 rf_type = 0;
1181                 u8 max_rx_ampdu_factor = 0;
1182                 struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p + 2);
1183 
1184                 pHT_caps_ie = p;
1185 
1186                 ht_cap = true;
1187                 network_type |= WIRELESS_11_24N;
1188 
1189                 rtw_ht_use_default_setting(padapter);
1190 
1191                 if (pmlmepriv->htpriv.sgi_20m == false)
1192                         pht_cap->cap_info &= cpu_to_le16(~(IEEE80211_HT_CAP_SGI_20));
1193 
1194                 if (pmlmepriv->htpriv.sgi_40m == false)
1195                         pht_cap->cap_info &= cpu_to_le16(~(IEEE80211_HT_CAP_SGI_40));
1196 
1197                 if (!TEST_FLAG(pmlmepriv->htpriv.ldpc_cap, LDPC_HT_ENABLE_RX))
1198                         pht_cap->cap_info &= cpu_to_le16(~(IEEE80211_HT_CAP_LDPC_CODING));
1199 
1200                 if (!TEST_FLAG(pmlmepriv->htpriv.stbc_cap, STBC_HT_ENABLE_TX))
1201                         pht_cap->cap_info &= cpu_to_le16(~(IEEE80211_HT_CAP_TX_STBC));
1202 
1203                 if (!TEST_FLAG(pmlmepriv->htpriv.stbc_cap, STBC_HT_ENABLE_RX))
1204                         pht_cap->cap_info &= cpu_to_le16(~(IEEE80211_HT_CAP_RX_STBC_3R));
1205 
1206                 pht_cap->ampdu_params_info &= ~(
1207                         IEEE80211_HT_CAP_AMPDU_FACTOR | IEEE80211_HT_CAP_AMPDU_DENSITY
1208                 );
1209 
1210                 if ((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
1211                         (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP)) {
1212                         pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & (0x07 << 2));
1213                 } else {
1214                         pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00);
1215                 }
1216 
1217                 rtw_hal_get_def_var(
1218                         padapter,
1219                         HW_VAR_MAX_RX_AMPDU_FACTOR,
1220                         &max_rx_ampdu_factor
1221                 );
1222                 pht_cap->ampdu_params_info |= (
1223                         IEEE80211_HT_CAP_AMPDU_FACTOR & max_rx_ampdu_factor
1224                 ); /* set  Max Rx AMPDU size  to 64K */
1225 
1226                 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
1227                 if (rf_type == RF_1T1R) {
1228                         pht_cap->supp_mcs_set[0] = 0xff;
1229                         pht_cap->supp_mcs_set[1] = 0x0;
1230                 }
1231 
1232                 memcpy(&pmlmepriv->htpriv.ht_cap, p + 2, ie_len);
1233         }
1234 
1235         /* parsing HT_INFO_IE */
1236         p = rtw_get_ie(
1237                 ie + _BEACON_IE_OFFSET_,
1238                 _HT_ADD_INFO_IE_,
1239                 &ie_len,
1240                 (pbss_network->IELength - _BEACON_IE_OFFSET_)
1241         );
1242         if (p && ie_len > 0)
1243                 pHT_info_ie = p;
1244 
1245         switch (network_type) {
1246         case WIRELESS_11B:
1247                 pbss_network->NetworkTypeInUse = Ndis802_11DS;
1248                 break;
1249         case WIRELESS_11G:
1250         case WIRELESS_11BG:
1251         case WIRELESS_11G_24N:
1252         case WIRELESS_11BG_24N:
1253                 pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
1254                 break;
1255         case WIRELESS_11A:
1256                 pbss_network->NetworkTypeInUse = Ndis802_11OFDM5;
1257                 break;
1258         default:
1259                 pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
1260                 break;
1261         }
1262 
1263         pmlmepriv->cur_network.network_type = network_type;
1264 
1265         pmlmepriv->htpriv.ht_option = false;
1266 
1267         if ((psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) ||
1268                       (psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) {
1269                 /* todo: */
1270                 /* ht_cap = false; */
1271         }
1272 
1273         /* ht_cap */
1274         if (pregistrypriv->ht_enable && ht_cap) {
1275                 pmlmepriv->htpriv.ht_option = true;
1276                 pmlmepriv->qospriv.qos_option = 1;
1277 
1278                 if (pregistrypriv->ampdu_enable == 1)
1279                         pmlmepriv->htpriv.ampdu_enable = true;
1280 
1281                 HT_caps_handler(padapter, (struct ndis_80211_var_ie *)pHT_caps_ie);
1282 
1283                 HT_info_handler(padapter, (struct ndis_80211_var_ie *)pHT_info_ie);
1284         }
1285 
1286         pbss_network->Length = get_wlan_bssid_ex_sz(
1287                 (struct wlan_bssid_ex  *)pbss_network
1288         );
1289 
1290         /* issue beacon to start bss network */
1291         /* start_bss_network(padapter, (u8 *)pbss_network); */
1292         rtw_startbss_cmd(padapter, RTW_CMDF_WAIT_ACK);
1293 
1294         /* alloc sta_info for ap itself */
1295         psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);
1296         if (!psta) {
1297                 psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);
1298                 if (psta == NULL)
1299                         return _FAIL;
1300         }
1301 
1302         /*  update AP's sta info */
1303         update_ap_info(padapter, psta);
1304 
1305         psta->state |= WIFI_AP_STATE;           /* Aries, add, fix bug of flush_cam_entry at STOP AP mode , 0724 */
1306         rtw_indicate_connect(padapter);
1307 
1308         pmlmepriv->cur_network.join_res = true;/* for check if already set beacon */
1309 
1310         /* update bc/mc sta_info */
1311         /* update_bmc_sta(padapter); */
1312 
1313         return ret;
1314 }
1315 
1316 void rtw_set_macaddr_acl(struct adapter *padapter, int mode)
1317 {
1318         struct sta_priv *pstapriv = &padapter->stapriv;
1319         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1320 
1321         DBG_871X("%s, mode =%d\n", __func__, mode);
1322 
1323         pacl_list->mode = mode;
1324 }
1325 
1326 int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
1327 {
1328         struct list_head        *plist, *phead;
1329         u8 added = false;
1330         int i, ret = 0;
1331         struct rtw_wlan_acl_node *paclnode;
1332         struct sta_priv *pstapriv = &padapter->stapriv;
1333         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1334         struct __queue  *pacl_node_q = &pacl_list->acl_node_q;
1335 
1336         DBG_871X(
1337                 "%s(acl_num =%d) =" MAC_FMT "\n",
1338                 __func__,
1339                 pacl_list->num,
1340                 MAC_ARG(addr)
1341         );
1342 
1343         if ((NUM_ACL - 1) < pacl_list->num)
1344                 return (-1);
1345 
1346         spin_lock_bh(&(pacl_node_q->lock));
1347 
1348         phead = get_list_head(pacl_node_q);
1349         plist = get_next(phead);
1350 
1351         while (phead != plist) {
1352                 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
1353                 plist = get_next(plist);
1354 
1355                 if (!memcmp(paclnode->addr, addr, ETH_ALEN)) {
1356                         if (paclnode->valid == true) {
1357                                 added = true;
1358                                 DBG_871X("%s, sta has been added\n", __func__);
1359                                 break;
1360                         }
1361                 }
1362         }
1363 
1364         spin_unlock_bh(&(pacl_node_q->lock));
1365 
1366         if (added)
1367                 return ret;
1368 
1369         spin_lock_bh(&(pacl_node_q->lock));
1370 
1371         for (i = 0; i < NUM_ACL; i++) {
1372                 paclnode = &pacl_list->aclnode[i];
1373 
1374                 if (!paclnode->valid) {
1375                         INIT_LIST_HEAD(&paclnode->list);
1376 
1377                         memcpy(paclnode->addr, addr, ETH_ALEN);
1378 
1379                         paclnode->valid = true;
1380 
1381                         list_add_tail(&paclnode->list, get_list_head(pacl_node_q));
1382 
1383                         pacl_list->num++;
1384 
1385                         break;
1386                 }
1387         }
1388 
1389         DBG_871X("%s, acl_num =%d\n", __func__, pacl_list->num);
1390 
1391         spin_unlock_bh(&(pacl_node_q->lock));
1392 
1393         return ret;
1394 }
1395 
1396 void rtw_acl_remove_sta(struct adapter *padapter, u8 *addr)
1397 {
1398         struct list_head        *plist, *phead;
1399         struct rtw_wlan_acl_node *paclnode;
1400         struct sta_priv *pstapriv = &padapter->stapriv;
1401         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1402         struct __queue  *pacl_node_q = &pacl_list->acl_node_q;
1403         u8 baddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };    /* Baddr is used for clearing acl_list */
1404 
1405         DBG_871X(
1406                 "%s(acl_num =%d) =" MAC_FMT "\n",
1407                 __func__,
1408                 pacl_list->num,
1409                 MAC_ARG(addr)
1410         );
1411 
1412         spin_lock_bh(&(pacl_node_q->lock));
1413 
1414         phead = get_list_head(pacl_node_q);
1415         plist = get_next(phead);
1416 
1417         while (phead != plist) {
1418                 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
1419                 plist = get_next(plist);
1420 
1421                 if (
1422                         !memcmp(paclnode->addr, addr, ETH_ALEN) ||
1423                         !memcmp(baddr, addr, ETH_ALEN)
1424                 ) {
1425                         if (paclnode->valid) {
1426                                 paclnode->valid = false;
1427 
1428                                 list_del_init(&paclnode->list);
1429 
1430                                 pacl_list->num--;
1431                         }
1432                 }
1433         }
1434 
1435         spin_unlock_bh(&(pacl_node_q->lock));
1436 
1437         DBG_871X("%s, acl_num =%d\n", __func__, pacl_list->num);
1438 
1439 }
1440 
1441 u8 rtw_ap_set_pairwise_key(struct adapter *padapter, struct sta_info *psta)
1442 {
1443         struct cmd_obj *ph2c;
1444         struct set_stakey_parm  *psetstakey_para;
1445         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1446         u8 res = _SUCCESS;
1447 
1448         ph2c = rtw_zmalloc(sizeof(struct cmd_obj));
1449         if (ph2c == NULL) {
1450                 res = _FAIL;
1451                 goto exit;
1452         }
1453 
1454         psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm));
1455         if (psetstakey_para == NULL) {
1456                 kfree((u8 *)ph2c);
1457                 res = _FAIL;
1458                 goto exit;
1459         }
1460 
1461         init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
1462 
1463         psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy;
1464 
1465         memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN);
1466 
1467         memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16);
1468 
1469         res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1470 
1471 exit:
1472 
1473         return res;
1474 }
1475 
1476 static int rtw_ap_set_key(
1477         struct adapter *padapter,
1478         u8 *key,
1479         u8 alg,
1480         int keyid,
1481         u8 set_tx
1482 )
1483 {
1484         u8 keylen;
1485         struct cmd_obj *pcmd;
1486         struct setkey_parm *psetkeyparm;
1487         struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
1488         int res = _SUCCESS;
1489 
1490         /* DBG_871X("%s\n", __func__); */
1491 
1492         pcmd = rtw_zmalloc(sizeof(struct cmd_obj));
1493         if (pcmd == NULL) {
1494                 res = _FAIL;
1495                 goto exit;
1496         }
1497         psetkeyparm = rtw_zmalloc(sizeof(struct setkey_parm));
1498         if (psetkeyparm == NULL) {
1499                 kfree((unsigned char *)pcmd);
1500                 res = _FAIL;
1501                 goto exit;
1502         }
1503 
1504         psetkeyparm->keyid = (u8)keyid;
1505         if (is_wep_enc(alg))
1506                 padapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid);
1507 
1508         psetkeyparm->algorithm = alg;
1509 
1510         psetkeyparm->set_tx = set_tx;
1511 
1512         switch (alg) {
1513         case _WEP40_:
1514                 keylen = 5;
1515                 break;
1516         case _WEP104_:
1517                 keylen = 13;
1518                 break;
1519         case _TKIP_:
1520         case _TKIP_WTMIC_:
1521         case _AES_:
1522         default:
1523                 keylen = 16;
1524         }
1525 
1526         memcpy(&(psetkeyparm->key[0]), key, keylen);
1527 
1528         pcmd->cmdcode = _SetKey_CMD_;
1529         pcmd->parmbuf = (u8 *)psetkeyparm;
1530         pcmd->cmdsz =  (sizeof(struct setkey_parm));
1531         pcmd->rsp = NULL;
1532         pcmd->rspsz = 0;
1533 
1534         INIT_LIST_HEAD(&pcmd->list);
1535 
1536         res = rtw_enqueue_cmd(pcmdpriv, pcmd);
1537 
1538 exit:
1539 
1540         return res;
1541 }
1542 
1543 int rtw_ap_set_group_key(struct adapter *padapter, u8 *key, u8 alg, int keyid)
1544 {
1545         DBG_871X("%s\n", __func__);
1546 
1547         return rtw_ap_set_key(padapter, key, alg, keyid, 1);
1548 }
1549 
1550 int rtw_ap_set_wep_key(
1551         struct adapter *padapter,
1552         u8 *key,
1553         u8 keylen,
1554         int keyid,
1555         u8 set_tx
1556 )
1557 {
1558         u8 alg;
1559 
1560         switch (keylen) {
1561         case 5:
1562                 alg = _WEP40_;
1563                 break;
1564         case 13:
1565                 alg = _WEP104_;
1566                 break;
1567         default:
1568                 alg = _NO_PRIVACY_;
1569         }
1570 
1571         DBG_871X("%s\n", __func__);
1572 
1573         return rtw_ap_set_key(padapter, key, alg, keyid, set_tx);
1574 }
1575 
1576 static void update_bcn_fixed_ie(struct adapter *padapter)
1577 {
1578         DBG_871X("%s\n", __func__);
1579 }
1580 
1581 static void update_bcn_erpinfo_ie(struct adapter *padapter)
1582 {
1583         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1584         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1585         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1586         struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1587         unsigned char *p, *ie = pnetwork->IEs;
1588         u32 len = 0;
1589 
1590         DBG_871X("%s, ERP_enable =%d\n", __func__, pmlmeinfo->ERP_enable);
1591 
1592         if (!pmlmeinfo->ERP_enable)
1593                 return;
1594 
1595         /* parsing ERP_IE */
1596         p = rtw_get_ie(
1597                 ie + _BEACON_IE_OFFSET_,
1598                 _ERPINFO_IE_,
1599                 &len,
1600                 (pnetwork->IELength - _BEACON_IE_OFFSET_)
1601         );
1602         if (p && len > 0) {
1603                 struct ndis_80211_var_ie *pIE = (struct ndis_80211_var_ie *)p;
1604 
1605                 if (pmlmepriv->num_sta_non_erp == 1)
1606                         pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT | RTW_ERP_INFO_USE_PROTECTION;
1607                 else
1608                         pIE->data[0] &= ~(
1609                                 RTW_ERP_INFO_NON_ERP_PRESENT | RTW_ERP_INFO_USE_PROTECTION
1610                         );
1611 
1612                 if (pmlmepriv->num_sta_no_short_preamble > 0)
1613                         pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;
1614                 else
1615                         pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE);
1616 
1617                 ERP_IE_handler(padapter, pIE);
1618         }
1619 }
1620 
1621 static void update_bcn_htcap_ie(struct adapter *padapter)
1622 {
1623         DBG_871X("%s\n", __func__);
1624 }
1625 
1626 static void update_bcn_htinfo_ie(struct adapter *padapter)
1627 {
1628         DBG_871X("%s\n", __func__);
1629 }
1630 
1631 static void update_bcn_rsn_ie(struct adapter *padapter)
1632 {
1633         DBG_871X("%s\n", __func__);
1634 }
1635 
1636 static void update_bcn_wpa_ie(struct adapter *padapter)
1637 {
1638         DBG_871X("%s\n", __func__);
1639 }
1640 
1641 static void update_bcn_wmm_ie(struct adapter *padapter)
1642 {
1643         DBG_871X("%s\n", __func__);
1644 }
1645 
1646 static void update_bcn_wps_ie(struct adapter *padapter)
1647 {
1648         u8 *pwps_ie = NULL;
1649         u8 *pwps_ie_src;
1650         u8 *premainder_ie;
1651         u8 *pbackup_remainder_ie = NULL;
1652 
1653         uint wps_ielen = 0, wps_offset, remainder_ielen;
1654         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1655         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1656         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1657         struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1658         unsigned char *ie = pnetwork->IEs;
1659         u32 ielen = pnetwork->IELength;
1660 
1661         DBG_871X("%s\n", __func__);
1662 
1663         pwps_ie = rtw_get_wps_ie(
1664                 ie + _FIXED_IE_LENGTH_,
1665                 ielen - _FIXED_IE_LENGTH_,
1666                 NULL,
1667                 &wps_ielen
1668         );
1669 
1670         if (pwps_ie == NULL || wps_ielen == 0)
1671                 return;
1672 
1673         pwps_ie_src = pmlmepriv->wps_beacon_ie;
1674         if (pwps_ie_src == NULL)
1675                 return;
1676 
1677         wps_offset = (uint)(pwps_ie - ie);
1678 
1679         premainder_ie = pwps_ie + wps_ielen;
1680 
1681         remainder_ielen = ielen - wps_offset - wps_ielen;
1682 
1683         if (remainder_ielen > 0) {
1684                 pbackup_remainder_ie = rtw_malloc(remainder_ielen);
1685                 if (pbackup_remainder_ie)
1686                         memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
1687         }
1688 
1689         wps_ielen = (uint)pwps_ie_src[1];/* to get ie data len */
1690         if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) {
1691                 memcpy(pwps_ie, pwps_ie_src, wps_ielen + 2);
1692                 pwps_ie += (wps_ielen+2);
1693 
1694                 if (pbackup_remainder_ie)
1695                         memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen);
1696 
1697                 /* update IELength */
1698                 pnetwork->IELength = wps_offset + (wps_ielen + 2) + remainder_ielen;
1699         }
1700 
1701         kfree(pbackup_remainder_ie);
1702 
1703         /*  deal with the case without set_tx_beacon_cmd() in update_beacon() */
1704 #if defined(CONFIG_INTERRUPT_BASED_TXBCN)
1705         if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
1706                 u8 sr = 0;
1707 
1708                 rtw_get_wps_attr_content(
1709                         pwps_ie_src,
1710                         wps_ielen,
1711                         WPS_ATTR_SELECTED_REGISTRAR,
1712                         (u8 *)(&sr),
1713                         NULL
1714                 );
1715 
1716                 if (sr) {
1717                         set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
1718                         DBG_871X("%s, set WIFI_UNDER_WPS\n", __func__);
1719                 }
1720         }
1721 #endif
1722 }
1723 
1724 static void update_bcn_p2p_ie(struct adapter *padapter)
1725 {
1726 }
1727 
1728 static void update_bcn_vendor_spec_ie(struct adapter *padapter, u8 *oui)
1729 {
1730         DBG_871X("%s\n", __func__);
1731 
1732         if (!memcmp(RTW_WPA_OUI, oui, 4))
1733                 update_bcn_wpa_ie(padapter);
1734 
1735         else if (!memcmp(WMM_OUI, oui, 4))
1736                 update_bcn_wmm_ie(padapter);
1737 
1738         else if (!memcmp(WPS_OUI, oui, 4))
1739                 update_bcn_wps_ie(padapter);
1740 
1741         else if (!memcmp(P2P_OUI, oui, 4))
1742                 update_bcn_p2p_ie(padapter);
1743 
1744         else
1745                 DBG_871X("unknown OUI type!\n");
1746 }
1747 
1748 void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
1749 {
1750         struct mlme_priv *pmlmepriv;
1751         struct mlme_ext_priv *pmlmeext;
1752         /* struct mlme_ext_info *pmlmeinfo; */
1753 
1754         /* DBG_871X("%s\n", __func__); */
1755 
1756         if (!padapter)
1757                 return;
1758 
1759         pmlmepriv = &(padapter->mlmepriv);
1760         pmlmeext = &(padapter->mlmeextpriv);
1761         /* pmlmeinfo = &(pmlmeext->mlmext_info); */
1762 
1763         if (!pmlmeext->bstart_bss)
1764                 return;
1765 
1766         spin_lock_bh(&pmlmepriv->bcn_update_lock);
1767 
1768         switch (ie_id) {
1769         case 0xFF:
1770 
1771                 update_bcn_fixed_ie(padapter);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */
1772 
1773                 break;
1774 
1775         case _TIM_IE_:
1776 
1777                 update_BCNTIM(padapter);
1778 
1779                 break;
1780 
1781         case _ERPINFO_IE_:
1782 
1783                 update_bcn_erpinfo_ie(padapter);
1784 
1785                 break;
1786 
1787         case _HT_CAPABILITY_IE_:
1788 
1789                 update_bcn_htcap_ie(padapter);
1790 
1791                 break;
1792 
1793         case _RSN_IE_2_:
1794 
1795                 update_bcn_rsn_ie(padapter);
1796 
1797                 break;
1798 
1799         case _HT_ADD_INFO_IE_:
1800 
1801                 update_bcn_htinfo_ie(padapter);
1802 
1803                 break;
1804 
1805         case _VENDOR_SPECIFIC_IE_:
1806 
1807                 update_bcn_vendor_spec_ie(padapter, oui);
1808 
1809                 break;
1810 
1811         default:
1812                 break;
1813         }
1814 
1815         pmlmepriv->update_bcn = true;
1816 
1817         spin_unlock_bh(&pmlmepriv->bcn_update_lock);
1818 
1819 #ifndef CONFIG_INTERRUPT_BASED_TXBCN
1820         if (tx) {
1821                 /* send_beacon(padapter);//send_beacon must execute on TSR level */
1822                 set_tx_beacon_cmd(padapter);
1823         }
1824 #endif /* CONFIG_INTERRUPT_BASED_TXBCN */
1825 }
1826 
1827 /*
1828 op_mode
1829 Set to 0 (HT pure) under the following conditions
1830         - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
1831         - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
1832 Set to 1 (HT non-member protection) if there may be non-HT STAs
1833         in both the primary and the secondary channel
1834 Set to 2 if only HT STAs are associated in BSS,
1835         however and at least one 20 MHz HT STA is associated
1836 Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
1837         (currently non-GF HT station is considered as non-HT STA also)
1838 */
1839 static int rtw_ht_operation_update(struct adapter *padapter)
1840 {
1841         u16 cur_op_mode, new_op_mode;
1842         int op_mode_changes = 0;
1843         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1844         struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
1845 
1846         if (pmlmepriv->htpriv.ht_option)
1847                 return 0;
1848 
1849         /* if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed) */
1850         /*  return 0; */
1851 
1852         DBG_871X("%s current operation mode = 0x%X\n",
1853                    __func__, pmlmepriv->ht_op_mode);
1854 
1855         if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)
1856             && pmlmepriv->num_sta_ht_no_gf) {
1857                 pmlmepriv->ht_op_mode |=
1858                         HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
1859                 op_mode_changes++;
1860         } else if ((pmlmepriv->ht_op_mode &
1861                     HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
1862                    pmlmepriv->num_sta_ht_no_gf == 0) {
1863                 pmlmepriv->ht_op_mode &=
1864                         ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
1865                 op_mode_changes++;
1866         }
1867 
1868         if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
1869             (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) {
1870                 pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
1871                 op_mode_changes++;
1872         } else if ((pmlmepriv->ht_op_mode &
1873                     HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
1874                    (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) {
1875                 pmlmepriv->ht_op_mode &=
1876                         ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
1877                 op_mode_changes++;
1878         }
1879 
1880         /* Note: currently we switch to the MIXED op mode if HT non-greenfield
1881          * station is associated. Probably it's a theoretical case, since
1882          * it looks like all known HT STAs support greenfield.
1883          */
1884         new_op_mode = 0;
1885         if (pmlmepriv->num_sta_no_ht ||
1886             (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
1887                 new_op_mode = OP_MODE_MIXED;
1888         else if (
1889                 (le16_to_cpu(phtpriv_ap->ht_cap.cap_info) & IEEE80211_HT_CAP_SUP_WIDTH)
1890                 && pmlmepriv->num_sta_ht_20mhz)
1891                 new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
1892         else if (pmlmepriv->olbc_ht)
1893                 new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
1894         else
1895                 new_op_mode = OP_MODE_PURE;
1896 
1897         cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
1898         if (cur_op_mode != new_op_mode) {
1899                 pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
1900                 pmlmepriv->ht_op_mode |= new_op_mode;
1901                 op_mode_changes++;
1902         }
1903 
1904         DBG_871X("%s new operation mode = 0x%X changes =%d\n",
1905                    __func__, pmlmepriv->ht_op_mode, op_mode_changes);
1906 
1907         return op_mode_changes;
1908 }
1909 
1910 void associated_clients_update(struct adapter *padapter, u8 updated)
1911 {
1912         /* update associated stations cap. */
1913         if (updated) {
1914                 struct list_head        *phead, *plist;
1915                 struct sta_info *psta = NULL;
1916                 struct sta_priv *pstapriv = &padapter->stapriv;
1917 
1918                 spin_lock_bh(&pstapriv->asoc_list_lock);
1919 
1920                 phead = &pstapriv->asoc_list;
1921                 plist = get_next(phead);
1922 
1923                 /* check asoc_queue */
1924                 while (phead != plist) {
1925                         psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
1926 
1927                         plist = get_next(plist);
1928 
1929                         VCS_update(padapter, psta);
1930                 }
1931 
1932                 spin_unlock_bh(&pstapriv->asoc_list_lock);
1933         }
1934 }
1935 
1936 /* called > TSR LEVEL for USB or SDIO Interface*/
1937 void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta)
1938 {
1939         u8 beacon_updated = false;
1940         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1941         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1942 
1943         if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) {
1944                 if (!psta->no_short_preamble_set) {
1945                         psta->no_short_preamble_set = 1;
1946 
1947                         pmlmepriv->num_sta_no_short_preamble++;
1948 
1949                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1950                                 (pmlmepriv->num_sta_no_short_preamble == 1)) {
1951                                 beacon_updated = true;
1952                                 update_beacon(padapter, 0xFF, NULL, true);
1953                         }
1954                 }
1955         } else {
1956                 if (psta->no_short_preamble_set) {
1957                         psta->no_short_preamble_set = 0;
1958 
1959                         pmlmepriv->num_sta_no_short_preamble--;
1960 
1961                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1962                                 (pmlmepriv->num_sta_no_short_preamble == 0)) {
1963                                 beacon_updated = true;
1964                                 update_beacon(padapter, 0xFF, NULL, true);
1965                         }
1966                 }
1967         }
1968 
1969         if (psta->flags & WLAN_STA_NONERP) {
1970                 if (!psta->nonerp_set) {
1971                         psta->nonerp_set = 1;
1972 
1973                         pmlmepriv->num_sta_non_erp++;
1974 
1975                         if (pmlmepriv->num_sta_non_erp == 1) {
1976                                 beacon_updated = true;
1977                                 update_beacon(padapter, _ERPINFO_IE_, NULL, true);
1978                         }
1979                 }
1980         } else {
1981                 if (psta->nonerp_set) {
1982                         psta->nonerp_set = 0;
1983 
1984                         pmlmepriv->num_sta_non_erp--;
1985 
1986                         if (pmlmepriv->num_sta_non_erp == 0) {
1987                                 beacon_updated = true;
1988                                 update_beacon(padapter, _ERPINFO_IE_, NULL, true);
1989                         }
1990                 }
1991         }
1992 
1993         if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT)) {
1994                 if (!psta->no_short_slot_time_set) {
1995                         psta->no_short_slot_time_set = 1;
1996 
1997                         pmlmepriv->num_sta_no_short_slot_time++;
1998 
1999                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
2000                                  (pmlmepriv->num_sta_no_short_slot_time == 1)) {
2001                                 beacon_updated = true;
2002                                 update_beacon(padapter, 0xFF, NULL, true);
2003                         }
2004                 }
2005         } else {
2006                 if (psta->no_short_slot_time_set) {
2007                         psta->no_short_slot_time_set = 0;
2008 
2009                         pmlmepriv->num_sta_no_short_slot_time--;
2010 
2011                         if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
2012                                  (pmlmepriv->num_sta_no_short_slot_time == 0)) {
2013                                 beacon_updated = true;
2014                                 update_beacon(padapter, 0xFF, NULL, true);
2015                         }
2016                 }
2017         }
2018 
2019         if (psta->flags & WLAN_STA_HT) {
2020                 u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info);
2021 
2022                 DBG_871X("HT: STA " MAC_FMT " HT Capabilities "
2023                            "Info: 0x%04x\n", MAC_ARG(psta->hwaddr), ht_capab);
2024 
2025                 if (psta->no_ht_set) {
2026                         psta->no_ht_set = 0;
2027                         pmlmepriv->num_sta_no_ht--;
2028                 }
2029 
2030                 if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) {
2031                         if (!psta->no_ht_gf_set) {
2032                                 psta->no_ht_gf_set = 1;
2033                                 pmlmepriv->num_sta_ht_no_gf++;
2034                         }
2035                         DBG_871X("%s STA " MAC_FMT " - no "
2036                                    "greenfield, num of non-gf stations %d\n",
2037                                    __func__, MAC_ARG(psta->hwaddr),
2038                                    pmlmepriv->num_sta_ht_no_gf);
2039                 }
2040 
2041                 if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH) == 0) {
2042                         if (!psta->ht_20mhz_set) {
2043                                 psta->ht_20mhz_set = 1;
2044                                 pmlmepriv->num_sta_ht_20mhz++;
2045                         }
2046                         DBG_871X("%s STA " MAC_FMT " - 20 MHz HT, "
2047                                    "num of 20MHz HT STAs %d\n",
2048                                    __func__, MAC_ARG(psta->hwaddr),
2049                                    pmlmepriv->num_sta_ht_20mhz);
2050                 }
2051 
2052         } else {
2053                 if (!psta->no_ht_set) {
2054                         psta->no_ht_set = 1;
2055                         pmlmepriv->num_sta_no_ht++;
2056                 }
2057                 if (pmlmepriv->htpriv.ht_option == true) {
2058                         DBG_871X("%s STA " MAC_FMT
2059                                    " - no HT, num of non-HT stations %d\n",
2060                                    __func__, MAC_ARG(psta->hwaddr),
2061                                    pmlmepriv->num_sta_no_ht);
2062                 }
2063         }
2064 
2065         if (rtw_ht_operation_update(padapter) > 0) {
2066                 update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, false);
2067                 update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, true);
2068         }
2069 
2070         /* update associated stations cap. */
2071         associated_clients_update(padapter,  beacon_updated);
2072 
2073         DBG_871X("%s, updated =%d\n", __func__, beacon_updated);
2074 }
2075 
2076 u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta)
2077 {
2078         u8 beacon_updated = false;
2079         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2080         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2081 
2082         if (!psta)
2083                 return beacon_updated;
2084 
2085         if (psta->no_short_preamble_set) {
2086                 psta->no_short_preamble_set = 0;
2087                 pmlmepriv->num_sta_no_short_preamble--;
2088                 if (pmlmeext->cur_wireless_mode > WIRELESS_11B
2089                     && pmlmepriv->num_sta_no_short_preamble == 0){
2090                         beacon_updated = true;
2091                         update_beacon(padapter, 0xFF, NULL, true);
2092                 }
2093         }
2094 
2095         if (psta->nonerp_set) {
2096                 psta->nonerp_set = 0;
2097                 pmlmepriv->num_sta_non_erp--;
2098                 if (pmlmepriv->num_sta_non_erp == 0) {
2099                         beacon_updated = true;
2100                         update_beacon(padapter, _ERPINFO_IE_, NULL, true);
2101                 }
2102         }
2103 
2104         if (psta->no_short_slot_time_set) {
2105                 psta->no_short_slot_time_set = 0;
2106                 pmlmepriv->num_sta_no_short_slot_time--;
2107                 if (pmlmeext->cur_wireless_mode > WIRELESS_11B
2108                     && pmlmepriv->num_sta_no_short_slot_time == 0){
2109                         beacon_updated = true;
2110                         update_beacon(padapter, 0xFF, NULL, true);
2111                 }
2112         }
2113 
2114         if (psta->no_ht_gf_set) {
2115                 psta->no_ht_gf_set = 0;
2116                 pmlmepriv->num_sta_ht_no_gf--;
2117         }
2118 
2119         if (psta->no_ht_set) {
2120                 psta->no_ht_set = 0;
2121                 pmlmepriv->num_sta_no_ht--;
2122         }
2123 
2124         if (psta->ht_20mhz_set) {
2125                 psta->ht_20mhz_set = 0;
2126                 pmlmepriv->num_sta_ht_20mhz--;
2127         }
2128 
2129         if (rtw_ht_operation_update(padapter) > 0) {
2130                 update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, false);
2131                 update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, true);
2132         }
2133 
2134         /* update associated stations cap. */
2135         /* associated_clients_update(padapter,  beacon_updated); //move it to avoid deadlock */
2136 
2137         DBG_871X("%s, updated =%d\n", __func__, beacon_updated);
2138 
2139         return beacon_updated;
2140 }
2141 
2142 u8 ap_free_sta(
2143         struct adapter *padapter,
2144         struct sta_info *psta,
2145         bool active,
2146         u16 reason
2147 )
2148 {
2149         u8 beacon_updated = false;
2150 
2151         if (!psta)
2152                 return beacon_updated;
2153 
2154         if (active) {
2155                 /* tear down Rx AMPDU */
2156                 send_delba(padapter, 0, psta->hwaddr);/*  recipient */
2157 
2158                 /* tear down TX AMPDU */
2159                 send_delba(padapter, 1, psta->hwaddr);/*  // originator */
2160 
2161                 issue_deauth(padapter, psta->hwaddr, reason);
2162         }
2163 
2164         psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
2165         psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
2166 
2167         /* report_del_sta_event(padapter, psta->hwaddr, reason); */
2168 
2169         /* clear cam entry / key */
2170         rtw_clearstakey_cmd(padapter, psta, true);
2171 
2172         spin_lock_bh(&psta->lock);
2173         psta->state &= ~_FW_LINKED;
2174         spin_unlock_bh(&psta->lock);
2175 
2176         rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);
2177 
2178         report_del_sta_event(padapter, psta->hwaddr, reason);
2179 
2180         beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);
2181 
2182         rtw_free_stainfo(padapter, psta);
2183 
2184         return beacon_updated;
2185 }
2186 
2187 void rtw_sta_flush(struct adapter *padapter)
2188 {
2189         struct list_head        *phead, *plist;
2190         struct sta_info *psta = NULL;
2191         struct sta_priv *pstapriv = &padapter->stapriv;
2192         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2193         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2194         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2195 
2196         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
2197 
2198         if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
2199                 return;
2200 
2201         spin_lock_bh(&pstapriv->asoc_list_lock);
2202         phead = &pstapriv->asoc_list;
2203         plist = get_next(phead);
2204 
2205         /* free sta asoc_queue */
2206         while (phead != plist) {
2207                 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
2208 
2209                 plist = get_next(plist);
2210 
2211                 list_del_init(&psta->asoc_list);
2212                 pstapriv->asoc_list_cnt--;
2213 
2214                 /* spin_unlock_bh(&pstapriv->asoc_list_lock); */
2215                 ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
2216                 /* spin_lock_bh(&pstapriv->asoc_list_lock); */
2217         }
2218         spin_unlock_bh(&pstapriv->asoc_list_lock);
2219 
2220         issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);
2221 
2222         associated_clients_update(padapter, true);
2223 }
2224 
2225 /* called > TSR LEVEL for USB or SDIO Interface*/
2226 void sta_info_update(struct adapter *padapter, struct sta_info *psta)
2227 {
2228         int flags = psta->flags;
2229         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2230 
2231         /* update wmm cap. */
2232         if (WLAN_STA_WME & flags)
2233                 psta->qos_option = 1;
2234         else
2235                 psta->qos_option = 0;
2236 
2237         if (pmlmepriv->qospriv.qos_option == 0)
2238                 psta->qos_option = 0;
2239 
2240         /* update 802.11n ht cap. */
2241         if (WLAN_STA_HT & flags) {
2242                 psta->htpriv.ht_option = true;
2243                 psta->qos_option = 1;
2244         } else {
2245                 psta->htpriv.ht_option = false;
2246         }
2247 
2248         if (!pmlmepriv->htpriv.ht_option)
2249                 psta->htpriv.ht_option = false;
2250 
2251         update_sta_info_apmode(padapter, psta);
2252 }
2253 
2254 /* called >= TSR LEVEL for USB or SDIO Interface*/
2255 void ap_sta_info_defer_update(struct adapter *padapter, struct sta_info *psta)
2256 {
2257         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2258         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2259 
2260         if (psta->state & _FW_LINKED) {
2261                 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
2262 
2263                 /* add ratid */
2264                 add_RATid(padapter, psta, 0);/* DM_RATR_STA_INIT */
2265         }
2266 }
2267 /* restore hw setting from sw data structures */
2268 void rtw_ap_restore_network(struct adapter *padapter)
2269 {
2270         struct mlme_priv *mlmepriv = &padapter->mlmepriv;
2271         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2272         struct sta_priv *pstapriv = &padapter->stapriv;
2273         struct sta_info *psta;
2274         struct security_priv *psecuritypriv = &(padapter->securitypriv);
2275         struct list_head        *phead, *plist;
2276         u8 chk_alive_num = 0;
2277         char chk_alive_list[NUM_STA];
2278         int i;
2279 
2280         rtw_setopmode_cmd(padapter, Ndis802_11APMode, false);
2281 
2282         set_channel_bwmode(
2283                 padapter,
2284                 pmlmeext->cur_channel,
2285                 pmlmeext->cur_ch_offset,
2286                 pmlmeext->cur_bwmode
2287         );
2288 
2289         start_bss_network(padapter, (u8 *)&mlmepriv->cur_network.network);
2290 
2291         if ((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
2292                 (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
2293                 /* restore group key, WEP keys is restored in ips_leave() */
2294                 rtw_set_key(
2295                         padapter,
2296                         psecuritypriv,
2297                         psecuritypriv->dot118021XGrpKeyid,
2298                         0,
2299                         false
2300                 );
2301         }
2302 
2303         spin_lock_bh(&pstapriv->asoc_list_lock);
2304 
2305         phead = &pstapriv->asoc_list;
2306         plist = get_next(phead);
2307 
2308         while (phead != plist) {
2309                 int stainfo_offset;
2310 
2311                 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
2312                 plist = get_next(plist);
2313 
2314                 stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
2315                 if (stainfo_offset_valid(stainfo_offset))
2316                         chk_alive_list[chk_alive_num++] = stainfo_offset;
2317         }
2318 
2319         spin_unlock_bh(&pstapriv->asoc_list_lock);
2320 
2321         for (i = 0; i < chk_alive_num; i++) {
2322                 psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
2323 
2324                 if (psta == NULL) {
2325                         DBG_871X(FUNC_ADPT_FMT" sta_info is null\n", FUNC_ADPT_ARG(padapter));
2326                 } else if (psta->state & _FW_LINKED) {
2327                         rtw_sta_media_status_rpt(padapter, psta, 1);
2328                         Update_RA_Entry(padapter, psta);
2329                         /* pairwise key */
2330                         /* per sta pairwise key and settings */
2331                         if ((psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) ||
2332                                 (psecuritypriv->dot11PrivacyAlgrthm == _AES_)) {
2333                                 rtw_setstakey_cmd(padapter, psta, true, false);
2334                         }
2335                 }
2336         }
2337 }
2338 
2339 void start_ap_mode(struct adapter *padapter)
2340 {
2341         int i;
2342         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2343         struct sta_priv *pstapriv = &padapter->stapriv;
2344         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2345         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
2346 
2347         pmlmepriv->update_bcn = false;
2348 
2349         /* init_mlme_ap_info(padapter); */
2350         pmlmeext->bstart_bss = false;
2351 
2352         pmlmepriv->num_sta_non_erp = 0;
2353 
2354         pmlmepriv->num_sta_no_short_slot_time = 0;
2355 
2356         pmlmepriv->num_sta_no_short_preamble = 0;
2357 
2358         pmlmepriv->num_sta_ht_no_gf = 0;
2359         pmlmepriv->num_sta_no_ht = 0;
2360         pmlmepriv->num_sta_ht_20mhz = 0;
2361 
2362         pmlmepriv->olbc = false;
2363 
2364         pmlmepriv->olbc_ht = false;
2365 
2366         pmlmepriv->ht_op_mode = 0;
2367 
2368         for (i = 0; i < NUM_STA; i++)
2369                 pstapriv->sta_aid[i] = NULL;
2370 
2371         pmlmepriv->wps_beacon_ie = NULL;
2372         pmlmepriv->wps_probe_resp_ie = NULL;
2373         pmlmepriv->wps_assoc_resp_ie = NULL;
2374 
2375         pmlmepriv->p2p_beacon_ie = NULL;
2376         pmlmepriv->p2p_probe_resp_ie = NULL;
2377 
2378         /* for ACL */
2379         INIT_LIST_HEAD(&(pacl_list->acl_node_q.queue));
2380         pacl_list->num = 0;
2381         pacl_list->mode = 0;
2382         for (i = 0; i < NUM_ACL; i++) {
2383                 INIT_LIST_HEAD(&pacl_list->aclnode[i].list);
2384                 pacl_list->aclnode[i].valid = false;
2385         }
2386 }
2387 
2388 void stop_ap_mode(struct adapter *padapter)
2389 {
2390         struct list_head        *phead, *plist;
2391         struct rtw_wlan_acl_node *paclnode;
2392         struct sta_info *psta = NULL;
2393         struct sta_priv *pstapriv = &padapter->stapriv;
2394         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2395         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2396         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
2397         struct __queue  *pacl_node_q = &pacl_list->acl_node_q;
2398 
2399         pmlmepriv->update_bcn = false;
2400         pmlmeext->bstart_bss = false;
2401 
2402         /* reset and init security priv , this can refine with rtw_reset_securitypriv */
2403         memset(
2404                 (unsigned char *)&padapter->securitypriv,
2405                 0,
2406                 sizeof(struct security_priv)
2407         );
2408         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
2409         padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
2410 
2411         /* for ACL */
2412         spin_lock_bh(&(pacl_node_q->lock));
2413         phead = get_list_head(pacl_node_q);
2414         plist = get_next(phead);
2415         while (phead != plist) {
2416                 paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
2417                 plist = get_next(plist);
2418 
2419                 if (paclnode->valid == true) {
2420                         paclnode->valid = false;
2421 
2422                         list_del_init(&paclnode->list);
2423 
2424                         pacl_list->num--;
2425                 }
2426         }
2427         spin_unlock_bh(&(pacl_node_q->lock));
2428 
2429         DBG_871X("%s, free acl_node_queue, num =%d\n", __func__, pacl_list->num);
2430 
2431         rtw_sta_flush(padapter);
2432 
2433         /* free_assoc_sta_resources */
2434         rtw_free_all_stainfo(padapter);
2435 
2436         psta = rtw_get_bcmc_stainfo(padapter);
2437         rtw_free_stainfo(padapter, psta);
2438 
2439         rtw_init_bcmc_stainfo(padapter);
2440 
2441         rtw_free_mlme_priv_ie_data(pmlmepriv);
2442 
2443         rtw_btcoex_MediaStatusNotify(padapter, 0); /* disconnect */
2444 }

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