linux/drivers/staging/rtl8188eu/core/rtw_ap.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of version 2 of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12 * more details.
  13 *
  14 * You should have received a copy of the GNU General Public License along with
  15 * this program; if not, write to the Free Software Foundation, Inc.,
  16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17 *
  18 *
  19 ******************************************************************************/
  20#define _RTW_AP_C_
  21
  22#include <linux/ieee80211.h>
  23
  24#include <osdep_service.h>
  25#include <drv_types.h>
  26#include <wifi.h>
  27#include <ieee80211.h>
  28#include <asm/unaligned.h>
  29
  30#ifdef CONFIG_88EU_AP_MODE
  31
  32void init_mlme_ap_info(struct adapter *padapter)
  33{
  34        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  35        struct sta_priv *pstapriv = &padapter->stapriv;
  36        struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
  37
  38
  39        spin_lock_init(&pmlmepriv->bcn_update_lock);
  40
  41        /* for ACL */
  42        _rtw_init_queue(&pacl_list->acl_node_q);
  43
  44        start_ap_mode(padapter);
  45}
  46
  47void free_mlme_ap_info(struct adapter *padapter)
  48{
  49        struct sta_info *psta = NULL;
  50        struct sta_priv *pstapriv = &padapter->stapriv;
  51        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  52        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  53        struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
  54
  55        pmlmepriv->update_bcn = false;
  56        pmlmeext->bstart_bss = false;
  57
  58        rtw_sta_flush(padapter);
  59
  60        pmlmeinfo->state = _HW_STATE_NOLINK_;
  61
  62        /* free_assoc_sta_resources */
  63        rtw_free_all_stainfo(padapter);
  64
  65        /* free bc/mc sta_info */
  66        psta = rtw_get_bcmc_stainfo(padapter);
  67        spin_lock_bh(&(pstapriv->sta_hash_lock));
  68        rtw_free_stainfo(padapter, psta);
  69        spin_unlock_bh(&(pstapriv->sta_hash_lock));
  70}
  71
  72static void update_BCNTIM(struct adapter *padapter)
  73{
  74        struct sta_priv *pstapriv = &padapter->stapriv;
  75        struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
  76        struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  77        struct wlan_bssid_ex *pnetwork_mlmeext = &(pmlmeinfo->network);
  78        unsigned char *pie = pnetwork_mlmeext->IEs;
  79        u8 *p, *dst_ie, *premainder_ie = NULL;
  80        u8 *pbackup_remainder_ie = NULL;
  81        uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;
  82
  83        /* update TIM IE */
  84        p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen,
  85                        pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_);
  86        if (p != NULL && tim_ielen > 0) {
  87                tim_ielen += 2;
  88                premainder_ie = p+tim_ielen;
  89                tim_ie_offset = (int)(p - pie);
  90                remainder_ielen = pnetwork_mlmeext->IELength -
  91                                        tim_ie_offset - tim_ielen;
  92                /* append TIM IE from dst_ie offset */
  93                dst_ie = p;
  94        } else {
  95                tim_ielen = 0;
  96
  97                /* calculate head_len */
  98                offset = _FIXED_IE_LENGTH_;
  99                offset += pnetwork_mlmeext->Ssid.SsidLength + 2;
 100
 101                /*  get supported rates len */
 102                p = rtw_get_ie(pie + _BEACON_IE_OFFSET_,
 103                                _SUPPORTEDRATES_IE_, &tmp_len,
 104                                (pnetwork_mlmeext->IELength -
 105                                        _BEACON_IE_OFFSET_));
 106                if (p !=  NULL)
 107                        offset += tmp_len+2;
 108
 109                /* DS Parameter Set IE, len = 3 */
 110                offset += 3;
 111
 112                premainder_ie = pie + offset;
 113
 114                remainder_ielen = pnetwork_mlmeext->IELength -
 115                                        offset - tim_ielen;
 116
 117                /* append TIM IE from offset */
 118                dst_ie = pie + offset;
 119        }
 120
 121        if (remainder_ielen > 0) {
 122                pbackup_remainder_ie = rtw_malloc(remainder_ielen);
 123                if (pbackup_remainder_ie && premainder_ie)
 124                        memcpy(pbackup_remainder_ie,
 125                                        premainder_ie, remainder_ielen);
 126        }
 127        *dst_ie++ = _TIM_IE_;
 128
 129        if ((pstapriv->tim_bitmap&0xff00) &&
 130                        (pstapriv->tim_bitmap&0x00fc))
 131                tim_ielen = 5;
 132        else
 133                tim_ielen = 4;
 134
 135        *dst_ie++ = tim_ielen;
 136
 137        *dst_ie++ = 0;/* DTIM count */
 138        *dst_ie++ = 1;/* DTIM period */
 139
 140        if (pstapriv->tim_bitmap&BIT(0))/* for bc/mc frames */
 141                *dst_ie++ = BIT(0);/* bitmap ctrl */
 142        else
 143                *dst_ie++ = 0;
 144
 145        if (tim_ielen == 4) {
 146                *dst_ie++ = pstapriv->tim_bitmap & 0xff;
 147        } else if (tim_ielen == 5) {
 148                put_unaligned_le16(pstapriv->tim_bitmap, dst_ie);
 149                dst_ie += 2;
 150        }
 151
 152        /* copy remainder IE */
 153        if (pbackup_remainder_ie) {
 154                memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
 155
 156                kfree(pbackup_remainder_ie);
 157        }
 158        offset =  (uint)(dst_ie - pie);
 159        pnetwork_mlmeext->IELength = offset + remainder_ielen;
 160
 161        set_tx_beacon_cmd(padapter);
 162}
 163
 164void rtw_add_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork,
 165                        u8 index, u8 *data, u8 len)
 166{
 167        struct ndis_802_11_var_ie *pIE;
 168        u8 bmatch = false;
 169        u8 *pie = pnetwork->IEs;
 170        u8 *p = NULL, *dst_ie = NULL, *premainder_ie = NULL;
 171        u8 *pbackup_remainder_ie = NULL;
 172        u32 i, offset, ielen = 0, ie_offset, remainder_ielen = 0;
 173
 174        for (i = sizeof(struct ndis_802_11_fixed_ie); i < pnetwork->IELength;) {
 175                pIE = (struct ndis_802_11_var_ie *)(pnetwork->IEs + i);
 176
 177                if (pIE->ElementID > index) {
 178                        break;
 179                /*  already exist the same IE */
 180                } else if (pIE->ElementID == index) {
 181                        p = (u8 *)pIE;
 182                        ielen = pIE->Length;
 183                        bmatch = true;
 184                        break;
 185                }
 186                p = (u8 *)pIE;
 187                ielen = pIE->Length;
 188                i += (pIE->Length + 2);
 189        }
 190
 191        if (p != NULL && ielen > 0) {
 192                ielen += 2;
 193
 194                premainder_ie = p+ielen;
 195
 196                ie_offset = (int)(p - pie);
 197
 198                remainder_ielen = pnetwork->IELength - ie_offset - ielen;
 199
 200                if (bmatch)
 201                        dst_ie = p;
 202                else
 203                        dst_ie = p+ielen;
 204        }
 205
 206        if (remainder_ielen > 0) {
 207                pbackup_remainder_ie = rtw_malloc(remainder_ielen);
 208                if (pbackup_remainder_ie && premainder_ie)
 209                        memcpy(pbackup_remainder_ie,
 210                                        premainder_ie, remainder_ielen);
 211        }
 212
 213        *dst_ie++ = index;
 214        *dst_ie++ = len;
 215
 216        memcpy(dst_ie, data, len);
 217        dst_ie += len;
 218
 219        /* copy remainder IE */
 220        if (pbackup_remainder_ie) {
 221                memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
 222
 223                kfree(pbackup_remainder_ie);
 224        }
 225
 226        offset =  (uint)(dst_ie - pie);
 227        pnetwork->IELength = offset + remainder_ielen;
 228}
 229
 230void rtw_remove_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork,
 231                                u8 index)
 232{
 233        u8 *p, *dst_ie = NULL, *premainder_ie = NULL;
 234        u8 *pbackup_remainder_ie = NULL;
 235        uint offset, ielen, ie_offset, remainder_ielen = 0;
 236        u8      *pie = pnetwork->IEs;
 237
 238        p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, index, &ielen,
 239                       pnetwork->IELength - _FIXED_IE_LENGTH_);
 240        if (p != NULL && ielen > 0) {
 241                ielen += 2;
 242
 243                premainder_ie = p+ielen;
 244
 245                ie_offset = (int)(p - pie);
 246
 247                remainder_ielen = pnetwork->IELength - ie_offset - ielen;
 248
 249                dst_ie = p;
 250        }
 251
 252        if (remainder_ielen > 0) {
 253                pbackup_remainder_ie = rtw_malloc(remainder_ielen);
 254                if (pbackup_remainder_ie && premainder_ie)
 255                        memcpy(pbackup_remainder_ie,
 256                                        premainder_ie, remainder_ielen);
 257        }
 258
 259        /* copy remainder IE */
 260        if (pbackup_remainder_ie) {
 261                memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
 262
 263                kfree(pbackup_remainder_ie);
 264        }
 265
 266        offset =  (uint)(dst_ie - pie);
 267        pnetwork->IELength = offset + remainder_ielen;
 268}
 269
 270static u8 chk_sta_is_alive(struct sta_info *psta)
 271{
 272        u8 ret = false;
 273
 274        if ((psta->sta_stats.last_rx_data_pkts +
 275                        psta->sta_stats.last_rx_ctrl_pkts) ==
 276                        (psta->sta_stats.rx_data_pkts +
 277                        psta->sta_stats.rx_ctrl_pkts))
 278                ;
 279        else
 280                ret = true;
 281
 282        sta_update_last_rx_pkts(psta);
 283
 284        return ret;
 285}
 286
 287void    expire_timeout_chk(struct adapter *padapter)
 288{
 289        struct list_head *phead, *plist;
 290        u8 updated = 0;
 291        struct sta_info *psta = NULL;
 292        struct sta_priv *pstapriv = &padapter->stapriv;
 293        u8 chk_alive_num = 0;
 294        char chk_alive_list[NUM_STA];
 295        int i;
 296
 297        spin_lock_bh(&pstapriv->auth_list_lock);
 298
 299        phead = &pstapriv->auth_list;
 300        plist = phead->next;
 301
 302        /* check auth_queue */
 303        while (phead != plist) {
 304                psta = container_of(plist, struct sta_info, auth_list);
 305                plist = plist->next;
 306
 307                if (psta->expire_to > 0) {
 308                        psta->expire_to--;
 309                        if (psta->expire_to == 0) {
 310                                list_del_init(&psta->auth_list);
 311                                pstapriv->auth_list_cnt--;
 312
 313                                DBG_88E("auth expire %6ph\n",
 314                                        psta->hwaddr);
 315
 316                                spin_unlock_bh(&pstapriv->auth_list_lock);
 317
 318                                spin_lock_bh(&(pstapriv->sta_hash_lock));
 319                                rtw_free_stainfo(padapter, psta);
 320                                spin_unlock_bh(&(pstapriv->sta_hash_lock));
 321
 322                                spin_lock_bh(&pstapriv->auth_list_lock);
 323                        }
 324                }
 325
 326        }
 327        spin_unlock_bh(&pstapriv->auth_list_lock);
 328
 329        psta = NULL;
 330
 331        spin_lock_bh(&pstapriv->asoc_list_lock);
 332
 333        phead = &pstapriv->asoc_list;
 334        plist = phead->next;
 335
 336        /* check asoc_queue */
 337        while (phead != plist) {
 338                psta = container_of(plist, struct sta_info, asoc_list);
 339                plist = plist->next;
 340
 341                if (chk_sta_is_alive(psta) || !psta->expire_to) {
 342                        psta->expire_to = pstapriv->expire_to;
 343                        psta->keep_alive_trycnt = 0;
 344                        psta->under_exist_checking = 0;
 345                } else {
 346                        psta->expire_to--;
 347                }
 348
 349                if (psta->expire_to <= 0) {
 350                        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 351
 352                        if (padapter->registrypriv.wifi_spec == 1) {
 353                                psta->expire_to = pstapriv->expire_to;
 354                                continue;
 355                        }
 356
 357                        if (psta->state & WIFI_SLEEP_STATE) {
 358                                if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
 359                                        /* to check if alive by another methods
 360                                         * if station is at ps mode.
 361                                         */
 362                                        psta->expire_to = pstapriv->expire_to;
 363                                        psta->state |= WIFI_STA_ALIVE_CHK_STATE;
 364
 365                                        /* to update bcn with tim_bitmap
 366                                         * for this station
 367                                         */
 368                                        pstapriv->tim_bitmap |= BIT(psta->aid);
 369                                        update_beacon(padapter, _TIM_IE_,
 370                                                        NULL, false);
 371
 372                                        if (!pmlmeext->active_keep_alive_check)
 373                                                continue;
 374                                }
 375                        }
 376                        if (pmlmeext->active_keep_alive_check) {
 377                                int stainfo_offset;
 378
 379                                stainfo_offset =
 380                                        rtw_stainfo_offset(pstapriv, psta);
 381                                if (stainfo_offset_valid(stainfo_offset))
 382                                        chk_alive_list[chk_alive_num++] = stainfo_offset;
 383                                continue;
 384                        }
 385
 386                        list_del_init(&psta->asoc_list);
 387                        pstapriv->asoc_list_cnt--;
 388
 389                        DBG_88E("asoc expire %pM, state = 0x%x\n", (psta->hwaddr), psta->state);
 390                        updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
 391                } else {
 392                        /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */
 393                        if (psta->sleepq_len > (NR_XMITFRAME/pstapriv->asoc_list_cnt) &&
 394                            padapter->xmitpriv.free_xmitframe_cnt < (NR_XMITFRAME/pstapriv->asoc_list_cnt/2)) {
 395                                DBG_88E("%s sta:%pM, sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n", __func__,
 396                                        (psta->hwaddr), psta->sleepq_len,
 397                                        padapter->xmitpriv.free_xmitframe_cnt,
 398                                        pstapriv->asoc_list_cnt);
 399                                wakeup_sta_to_xmit(padapter, psta);
 400                        }
 401                }
 402        }
 403
 404        spin_unlock_bh(&pstapriv->asoc_list_lock);
 405
 406        if (chk_alive_num) {
 407                u8 backup_oper_channel = 0;
 408                struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 409                /* switch to correct channel of current network  before issue keep-alive frames */
 410                if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
 411                        backup_oper_channel = rtw_get_oper_ch(padapter);
 412                        SelectChannel(padapter, pmlmeext->cur_channel);
 413                }
 414
 415                /* issue null data to check sta alive*/
 416                for (i = 0; i < chk_alive_num; i++) {
 417                        int ret = _FAIL;
 418
 419                        psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
 420
 421                        if (psta->state & WIFI_SLEEP_STATE)
 422                                ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50);
 423                        else
 424                                ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50);
 425
 426                        psta->keep_alive_trycnt++;
 427                        if (ret == _SUCCESS) {
 428                                DBG_88E("asoc check, sta(%pM) is alive\n", (psta->hwaddr));
 429                                psta->expire_to = pstapriv->expire_to;
 430                                psta->keep_alive_trycnt = 0;
 431                                continue;
 432                        } else if (psta->keep_alive_trycnt <= 3) {
 433                                DBG_88E("ack check for asoc expire, keep_alive_trycnt =%d\n", psta->keep_alive_trycnt);
 434                                psta->expire_to = 1;
 435                                continue;
 436                        }
 437
 438                        psta->keep_alive_trycnt = 0;
 439
 440                        DBG_88E("asoc expire %pM, state = 0x%x\n", (psta->hwaddr), psta->state);
 441                        spin_lock_bh(&pstapriv->asoc_list_lock);
 442                        list_del_init(&psta->asoc_list);
 443                        pstapriv->asoc_list_cnt--;
 444                        updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
 445                        spin_unlock_bh(&pstapriv->asoc_list_lock);
 446                }
 447
 448                if (backup_oper_channel > 0) /* back to the original operation channel */
 449                        SelectChannel(padapter, backup_oper_channel);
 450        }
 451
 452        associated_clients_update(padapter, updated);
 453}
 454
 455void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level)
 456{
 457        int i;
 458        u8 rf_type;
 459        u32 init_rate = 0;
 460        unsigned char sta_band = 0, raid, shortGIrate = false;
 461        unsigned char limit;
 462        unsigned int tx_ra_bitmap = 0;
 463        struct ht_priv  *psta_ht = NULL;
 464        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
 465        struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
 466
 467        if (psta)
 468                psta_ht = &psta->htpriv;
 469        else
 470                return;
 471
 472        if (!(psta->state & _FW_LINKED))
 473                return;
 474
 475        /* b/g mode ra_bitmap */
 476        for (i = 0; i < sizeof(psta->bssrateset); i++) {
 477                if (psta->bssrateset[i])
 478                        tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
 479        }
 480        /* n mode ra_bitmap */
 481        if (psta_ht->ht_option) {
 482                rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
 483                if (rf_type == RF_2T2R)
 484                        limit = 16;/*  2R */
 485                else
 486                        limit = 8;/*   1R */
 487
 488                for (i = 0; i < limit; i++) {
 489                        if (psta_ht->ht_cap.supp_mcs_set[i/8] & BIT(i%8))
 490                                tx_ra_bitmap |= BIT(i+12);
 491                }
 492
 493                /* max short GI rate */
 494                shortGIrate = psta_ht->sgi;
 495        }
 496
 497        if (pcur_network->Configuration.DSConfig > 14) {
 498                /*  5G band */
 499                if (tx_ra_bitmap & 0xffff000)
 500                        sta_band |= WIRELESS_11_5N | WIRELESS_11A;
 501                else
 502                        sta_band |= WIRELESS_11A;
 503        } else {
 504                if (tx_ra_bitmap & 0xffff000)
 505                        sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B;
 506                else if (tx_ra_bitmap & 0xff0)
 507                        sta_band |= WIRELESS_11G | WIRELESS_11B;
 508                else
 509                        sta_band |= WIRELESS_11B;
 510        }
 511
 512        psta->wireless_mode = sta_band;
 513
 514        raid = networktype_to_raid(sta_band);
 515        init_rate = get_highest_rate_idx(tx_ra_bitmap&0x0fffffff)&0x3f;
 516
 517        if (psta->aid < NUM_STA) {
 518                u8 arg = 0;
 519
 520                arg = psta->mac_id&0x1f;
 521
 522                arg |= BIT(7);/* support entry 2~31 */
 523
 524                if (shortGIrate)
 525                        arg |= BIT(5);
 526
 527                tx_ra_bitmap |= ((raid<<28)&0xf0000000);
 528
 529                DBG_88E("%s => mac_id:%d , raid:%d , bitmap = 0x%x, arg = 0x%x\n",
 530                        __func__, psta->mac_id, raid, tx_ra_bitmap, arg);
 531
 532                /* bitmap[0:27] = tx_rate_bitmap */
 533                /* bitmap[28:31]= Rate Adaptive id */
 534                /* arg[0:4] = macid */
 535                /* arg[5] = Short GI */
 536                rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, rssi_level);
 537
 538                if (shortGIrate)
 539                        init_rate |= BIT(6);
 540
 541                /* set ra_id, init_rate */
 542                psta->raid = raid;
 543                psta->init_rate = init_rate;
 544
 545        } else {
 546                DBG_88E("station aid %d exceed the max number\n", psta->aid);
 547        }
 548}
 549
 550static void update_bmc_sta(struct adapter *padapter)
 551{
 552        u32 init_rate = 0;
 553        unsigned char   network_type, raid;
 554        int i, supportRateNum = 0;
 555        unsigned int tx_ra_bitmap = 0;
 556        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
 557        struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
 558        struct sta_info *psta = rtw_get_bcmc_stainfo(padapter);
 559
 560        if (psta) {
 561                psta->aid = 0;/* default set to 0 */
 562                psta->mac_id = psta->aid + 1;
 563
 564                psta->qos_option = 0;
 565                psta->htpriv.ht_option = false;
 566
 567                psta->ieee8021x_blocked = 0;
 568
 569                memset(&psta->sta_stats, 0, sizeof(struct stainfo_stats));
 570
 571                /* prepare for add_RATid */
 572                supportRateNum = rtw_get_rateset_len((u8 *)&pcur_network->SupportedRates);
 573                network_type = rtw_check_network_type((u8 *)&pcur_network->SupportedRates, supportRateNum, 1);
 574
 575                memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum);
 576                psta->bssratelen = supportRateNum;
 577
 578                /* b/g mode ra_bitmap */
 579                for (i = 0; i < supportRateNum; i++) {
 580                        if (psta->bssrateset[i])
 581                                tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
 582                }
 583
 584                if (pcur_network->Configuration.DSConfig > 14) {
 585                        /* force to A mode. 5G doesn't support CCK rates */
 586                        network_type = WIRELESS_11A;
 587                        tx_ra_bitmap = 0x150; /*  6, 12, 24 Mbps */
 588                } else {
 589                        /* force to b mode */
 590                        network_type = WIRELESS_11B;
 591                        tx_ra_bitmap = 0xf;
 592                }
 593
 594                raid = networktype_to_raid(network_type);
 595                init_rate = get_highest_rate_idx(tx_ra_bitmap&0x0fffffff)&0x3f;
 596
 597                /* ap mode */
 598                rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
 599
 600                {
 601                        u8 arg = 0;
 602
 603                        arg = psta->mac_id&0x1f;
 604                        arg |= BIT(7);
 605                        tx_ra_bitmap |= ((raid<<28)&0xf0000000);
 606                        DBG_88E("update_bmc_sta, mask = 0x%x, arg = 0x%x\n", tx_ra_bitmap, arg);
 607
 608                        /* bitmap[0:27] = tx_rate_bitmap */
 609                        /* bitmap[28:31]= Rate Adaptive id */
 610                        /* arg[0:4] = macid */
 611                        /* arg[5] = Short GI */
 612                        rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, 0);
 613                }
 614                /* set ra_id, init_rate */
 615                psta->raid = raid;
 616                psta->init_rate = init_rate;
 617
 618                rtw_stassoc_hw_rpt(padapter, psta);
 619
 620                spin_lock_bh(&psta->lock);
 621                psta->state = _FW_LINKED;
 622                spin_unlock_bh(&psta->lock);
 623
 624        } else {
 625                DBG_88E("add_RATid_bmc_sta error!\n");
 626        }
 627}
 628
 629/* notes: */
 630/* AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode */
 631/* MAC_ID = AID+1 for sta in ap/adhoc mode */
 632/* MAC_ID = 1 for bc/mc for sta/ap/adhoc */
 633/* MAC_ID = 0 for bssid for sta/ap/adhoc */
 634/* CAM_ID = 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */
 635
 636void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta)
 637{
 638        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
 639        struct security_priv *psecuritypriv = &padapter->securitypriv;
 640        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
 641        struct ht_priv  *phtpriv_ap = &pmlmepriv->htpriv;
 642        struct ht_priv  *phtpriv_sta = &psta->htpriv;
 643
 644        psta->mac_id = psta->aid+1;
 645        DBG_88E("%s\n", __func__);
 646
 647        /* ap mode */
 648        rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true);
 649
 650        if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
 651                psta->ieee8021x_blocked = true;
 652        else
 653                psta->ieee8021x_blocked = false;
 654
 655
 656        /* update sta's cap */
 657
 658        /* ERP */
 659        VCS_update(padapter, psta);
 660        /* HT related cap */
 661        if (phtpriv_sta->ht_option) {
 662                /* check if sta supports rx ampdu */
 663                phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;
 664
 665                /* check if sta support s Short GI */
 666                if ((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40))
 667                        phtpriv_sta->sgi = true;
 668
 669                /*  bwmode */
 670                if ((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & IEEE80211_HT_CAP_SUP_WIDTH) {
 671                        phtpriv_sta->bwmode = pmlmeext->cur_bwmode;
 672                        phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
 673                }
 674                psta->qos_option = true;
 675        } else {
 676                phtpriv_sta->ampdu_enable = false;
 677                phtpriv_sta->sgi = false;
 678                phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20;
 679                phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
 680        }
 681
 682        /* Rx AMPDU */
 683        send_delba(padapter, 0, psta->hwaddr);/*  recipient */
 684
 685        /* TX AMPDU */
 686        send_delba(padapter, 1, psta->hwaddr);/* originator */
 687        phtpriv_sta->agg_enable_bitmap = 0x0;/* reset */
 688        phtpriv_sta->candidate_tid_bitmap = 0x0;/* reset */
 689
 690        /* todo: init other variables */
 691
 692        memset(&psta->sta_stats, 0, sizeof(struct stainfo_stats));
 693
 694        spin_lock_bh(&psta->lock);
 695        psta->state |= _FW_LINKED;
 696        spin_unlock_bh(&psta->lock);
 697}
 698
 699static void update_hw_ht_param(struct adapter *padapter)
 700{
 701        unsigned char           max_AMPDU_len;
 702        unsigned char           min_MPDU_spacing;
 703        struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
 704        struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
 705
 706        DBG_88E("%s\n", __func__);
 707
 708        /* handle A-MPDU parameter field */
 709        /*
 710                AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
 711                AMPDU_para [4:2]:Min MPDU Start Spacing
 712        */
 713        max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
 714
 715        min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
 716
 717        rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));
 718
 719        rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
 720
 721        /*  */
 722        /*  Config SM Power Save setting */
 723        /*  */
 724        pmlmeinfo->SM_PS = (le16_to_cpu(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info) & 0x0C) >> 2;
 725        if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
 726                DBG_88E("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
 727}
 728
 729static void start_bss_network(struct adapter *padapter, u8 *pbuf)
 730{
 731        u8 *p;
 732        u8 val8, cur_channel, cur_bwmode, cur_ch_offset;
 733        u16 bcn_interval;
 734        u32     acparm;
 735        int     ie_len;
 736        struct registry_priv     *pregpriv = &padapter->registrypriv;
 737        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
 738        struct security_priv *psecuritypriv = &(padapter->securitypriv);
 739        struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
 740        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
 741        struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
 742        struct wlan_bssid_ex *pnetwork_mlmeext = &(pmlmeinfo->network);
 743        struct HT_info_element *pht_info = NULL;
 744
 745        bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod;
 746        cur_channel = pnetwork->Configuration.DSConfig;
 747        cur_bwmode = HT_CHANNEL_WIDTH_20;
 748        cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
 749
 750
 751        /* check if there is wps ie, */
 752        /* if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd, */
 753        /* and at first time the security ie (RSN/WPA IE) will not include in beacon. */
 754        if (!rtw_get_wps_ie(pnetwork->IEs+_FIXED_IE_LENGTH_, pnetwork->IELength-_FIXED_IE_LENGTH_, NULL, NULL))
 755                pmlmeext->bstart_bss = true;
 756
 757        /* todo: update wmm, ht cap */
 758        if (pmlmepriv->qospriv.qos_option)
 759                pmlmeinfo->WMM_enable = true;
 760        if (pmlmepriv->htpriv.ht_option) {
 761                pmlmeinfo->WMM_enable = true;
 762                pmlmeinfo->HT_enable = true;
 763
 764                update_hw_ht_param(padapter);
 765        }
 766
 767        if (pmlmepriv->cur_network.join_res != true) { /* setting only at  first time */
 768                /* WEP Key will be set before this function, do not clear CAM. */
 769                if ((psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) &&
 770                    (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_))
 771                        flush_all_cam_entry(padapter);  /* clear CAM */
 772        }
 773
 774        /* set MSR to AP_Mode */
 775        Set_MSR(padapter, _HW_STATE_AP_);
 776
 777        /* Set BSSID REG */
 778        rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress);
 779
 780        /* Set EDCA param reg */
 781        acparm = 0x002F3217; /*  VO */
 782        rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
 783        acparm = 0x005E4317; /*  VI */
 784        rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
 785        acparm = 0x005ea42b;
 786        rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
 787        acparm = 0x0000A444; /*  BK */
 788        rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
 789
 790        /* Set Security */
 791        val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf;
 792        rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
 793
 794        /* Beacon Control related register */
 795        rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval));
 796
 797        UpdateBrateTbl(padapter, pnetwork->SupportedRates);
 798        rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
 799
 800        if (!pmlmepriv->cur_network.join_res) { /* setting only at  first time */
 801                /* turn on all dynamic functions */
 802                Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true);
 803        }
 804        /* set channel, bwmode */
 805        p = rtw_get_ie((pnetwork->IEs + sizeof(struct ndis_802_11_fixed_ie)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - sizeof(struct ndis_802_11_fixed_ie)));
 806        if (p && ie_len) {
 807                pht_info = (struct HT_info_element *)(p+2);
 808
 809                if ((pregpriv->cbw40_enable) &&  (pht_info->infos[0] & BIT(2))) {
 810                        /* switch to the 40M Hz mode */
 811                        cur_bwmode = HT_CHANNEL_WIDTH_40;
 812                        switch (pht_info->infos[0] & 0x3) {
 813                        case 1:
 814                                cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
 815                                break;
 816                        case 3:
 817                                cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
 818                                break;
 819                        default:
 820                                cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
 821                                break;
 822                        }
 823                }
 824        }
 825        /* TODO: need to judge the phy parameters on concurrent mode for single phy */
 826        set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
 827
 828        DBG_88E("CH =%d, BW =%d, offset =%d\n", cur_channel, cur_bwmode, cur_ch_offset);
 829
 830        /*  */
 831        pmlmeext->cur_channel = cur_channel;
 832        pmlmeext->cur_bwmode = cur_bwmode;
 833        pmlmeext->cur_ch_offset = cur_ch_offset;
 834        pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type;
 835
 836        /* update cur_wireless_mode */
 837        update_wireless_mode(padapter);
 838
 839        /* update capability after cur_wireless_mode updated */
 840        update_capinfo(padapter, rtw_get_capability((struct wlan_bssid_ex *)pnetwork));
 841
 842        /* let pnetwork_mlmeext == pnetwork_mlme. */
 843        memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);
 844
 845        if (pmlmeext->bstart_bss) {
 846                update_beacon(padapter, _TIM_IE_, NULL, false);
 847
 848                /* issue beacon frame */
 849                if (send_beacon(padapter) == _FAIL)
 850                        DBG_88E("send_beacon, fail!\n");
 851        }
 852
 853        /* update bc/mc sta_info */
 854        update_bmc_sta(padapter);
 855}
 856
 857int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf,  int len)
 858{
 859        int ret = _SUCCESS;
 860        u8 *p;
 861        u8 *pHT_caps_ie = NULL;
 862        u8 *pHT_info_ie = NULL;
 863        struct sta_info *psta = NULL;
 864        u16 cap, ht_cap = false;
 865        uint ie_len = 0;
 866        int group_cipher, pairwise_cipher;
 867        u8      channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX];
 868        int supportRateNum = 0;
 869        u8 OUI1[] = {0x00, 0x50, 0xf2, 0x01};
 870        u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
 871        struct registry_priv *pregistrypriv = &padapter->registrypriv;
 872        struct security_priv *psecuritypriv = &padapter->securitypriv;
 873        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
 874        struct wlan_bssid_ex *pbss_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
 875        u8 *ie = pbss_network->IEs;
 876
 877        /* SSID */
 878        /* Supported rates */
 879        /* DS Params */
 880        /* WLAN_EID_COUNTRY */
 881        /* ERP Information element */
 882        /* Extended supported rates */
 883        /* WPA/WPA2 */
 884        /* Wi-Fi Wireless Multimedia Extensions */
 885        /* ht_capab, ht_oper */
 886        /* WPS IE */
 887
 888        DBG_88E("%s, len =%d\n", __func__, len);
 889
 890        if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
 891                return _FAIL;
 892
 893
 894        if (len > MAX_IE_SZ)
 895                return _FAIL;
 896
 897        pbss_network->IELength = len;
 898
 899        memset(ie, 0, MAX_IE_SZ);
 900
 901        memcpy(ie, pbuf, pbss_network->IELength);
 902
 903
 904        if (pbss_network->InfrastructureMode != Ndis802_11APMode)
 905                return _FAIL;
 906
 907        pbss_network->Rssi = 0;
 908
 909        ether_addr_copy(pbss_network->MacAddress, myid(&(padapter->eeprompriv)));
 910
 911        /* beacon interval */
 912        p = rtw_get_beacon_interval_from_ie(ie);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */
 913        pbss_network->Configuration.BeaconPeriod = get_unaligned_le16(p);
 914
 915        /* capability */
 916        cap = get_unaligned_le16(ie);
 917
 918        /* SSID */
 919        p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
 920        if (p && ie_len > 0) {
 921                memset(&pbss_network->Ssid, 0, sizeof(struct ndis_802_11_ssid));
 922                memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len);
 923                pbss_network->Ssid.SsidLength = ie_len;
 924        }
 925
 926        /* channel */
 927        channel = 0;
 928        pbss_network->Configuration.Length = 0;
 929        p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
 930        if (p && ie_len > 0)
 931                channel = *(p + 2);
 932
 933        pbss_network->Configuration.DSConfig = channel;
 934
 935        memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
 936        /*  get supported rates */
 937        p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
 938        if (p !=  NULL) {
 939                memcpy(supportRate, p+2, ie_len);
 940                supportRateNum = ie_len;
 941        }
 942
 943        /* get ext_supported rates */
 944        p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_);
 945        if (p !=  NULL) {
 946                memcpy(supportRate+supportRateNum, p+2, ie_len);
 947                supportRateNum += ie_len;
 948        }
 949
 950        network_type = rtw_check_network_type(supportRate, supportRateNum, channel);
 951
 952        rtw_set_supported_rate(pbss_network->SupportedRates, network_type);
 953
 954        /* parsing ERP_IE */
 955        p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
 956        if (p && ie_len > 0)
 957                ERP_IE_handler(padapter, (struct ndis_802_11_var_ie *)p);
 958
 959        /* update privacy/security */
 960        if (cap & BIT(4))
 961                pbss_network->Privacy = 1;
 962        else
 963                pbss_network->Privacy = 0;
 964
 965        psecuritypriv->wpa_psk = 0;
 966
 967        /* wpa2 */
 968        group_cipher = 0;
 969        pairwise_cipher = 0;
 970        psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
 971        psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
 972        p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
 973        if (p && ie_len > 0) {
 974                if (rtw_parse_wpa2_ie(p, ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
 975                        psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
 976
 977                        psecuritypriv->dot8021xalg = 1;/* psk,  todo:802.1x */
 978                        psecuritypriv->wpa_psk |= BIT(1);
 979
 980                        psecuritypriv->wpa2_group_cipher = group_cipher;
 981                        psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher;
 982                }
 983        }
 984        /* wpa */
 985        ie_len = 0;
 986        group_cipher = 0;
 987        pairwise_cipher = 0;
 988        psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
 989        psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
 990        for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) {
 991                p = rtw_get_ie(p, _SSN_IE_1_, &ie_len,
 992                               (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
 993                if ((p) && (!memcmp(p+2, OUI1, 4))) {
 994                        if (rtw_parse_wpa_ie(p, ie_len+2, &group_cipher,
 995                                             &pairwise_cipher, NULL) == _SUCCESS) {
 996                                psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
 997
 998                                psecuritypriv->dot8021xalg = 1;/* psk,  todo:802.1x */
 999
1000                                psecuritypriv->wpa_psk |= BIT(0);
1001
1002                                psecuritypriv->wpa_group_cipher = group_cipher;
1003                                psecuritypriv->wpa_pairwise_cipher = pairwise_cipher;
1004                        }
1005                        break;
1006                }
1007                if ((p == NULL) || (ie_len == 0))
1008                        break;
1009        }
1010
1011        /* wmm */
1012        ie_len = 0;
1013        pmlmepriv->qospriv.qos_option = 0;
1014        if (pregistrypriv->wmm_enable) {
1015                for (p = ie + _BEACON_IE_OFFSET_;; p += (ie_len + 2)) {
1016                        p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len,
1017                                       (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
1018                        if ((p) && !memcmp(p+2, WMM_PARA_IE, 6)) {
1019                                pmlmepriv->qospriv.qos_option = 1;
1020
1021                                *(p+8) |= BIT(7);/* QoS Info, support U-APSD */
1022
1023                                /* disable all ACM bits since the WMM admission control is not supported */
1024                                *(p + 10) &= ~BIT(4); /* BE */
1025                                *(p + 14) &= ~BIT(4); /* BK */
1026                                *(p + 18) &= ~BIT(4); /* VI */
1027                                *(p + 22) &= ~BIT(4); /* VO */
1028                                break;
1029                        }
1030
1031                        if ((p == NULL) || (ie_len == 0))
1032                                break;
1033                }
1034        }
1035        /* parsing HT_CAP_IE */
1036        p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len,
1037                       (pbss_network->IELength - _BEACON_IE_OFFSET_));
1038        if (p && ie_len > 0) {
1039                u8 rf_type;
1040                struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p+2);
1041
1042                pHT_caps_ie = p;
1043                ht_cap = true;
1044                network_type |= WIRELESS_11_24N;
1045
1046                rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
1047
1048                if ((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
1049                    (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP))
1050                        pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
1051                else
1052                        pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
1053
1054                /* set  Max Rx AMPDU size  to 64K */
1055                pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR & 0x03);
1056
1057                if (rf_type == RF_1T1R) {
1058                        pht_cap->supp_mcs_set[0] = 0xff;
1059                        pht_cap->supp_mcs_set[1] = 0x0;
1060                }
1061                memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len);
1062        }
1063
1064        /* parsing HT_INFO_IE */
1065        p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len,
1066                       (pbss_network->IELength - _BEACON_IE_OFFSET_));
1067        if (p && ie_len > 0)
1068                pHT_info_ie = p;
1069        switch (network_type) {
1070        case WIRELESS_11B:
1071                pbss_network->NetworkTypeInUse = Ndis802_11DS;
1072                break;
1073        case WIRELESS_11G:
1074        case WIRELESS_11BG:
1075        case WIRELESS_11G_24N:
1076        case WIRELESS_11BG_24N:
1077                pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
1078                break;
1079        case WIRELESS_11A:
1080                pbss_network->NetworkTypeInUse = Ndis802_11OFDM5;
1081                break;
1082        default:
1083                pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
1084                break;
1085        }
1086
1087        pmlmepriv->cur_network.network_type = network_type;
1088
1089        pmlmepriv->htpriv.ht_option = false;
1090
1091        if ((psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) ||
1092            (psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) {
1093                /* todo: */
1094                /* ht_cap = false; */
1095        }
1096
1097        /* ht_cap */
1098        if (pregistrypriv->ht_enable && ht_cap) {
1099                pmlmepriv->htpriv.ht_option = true;
1100                pmlmepriv->qospriv.qos_option = 1;
1101
1102                if (pregistrypriv->ampdu_enable == 1)
1103                        pmlmepriv->htpriv.ampdu_enable = true;
1104                HT_caps_handler(padapter, (struct ndis_802_11_var_ie *)pHT_caps_ie);
1105
1106                HT_info_handler(padapter, (struct ndis_802_11_var_ie *)pHT_info_ie);
1107        }
1108
1109        pbss_network->Length = get_wlan_bssid_ex_sz((struct wlan_bssid_ex  *)pbss_network);
1110
1111        /* issue beacon to start bss network */
1112        start_bss_network(padapter, (u8 *)pbss_network);
1113
1114        /* alloc sta_info for ap itself */
1115        psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);
1116        if (!psta) {
1117                psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);
1118                if (psta == NULL)
1119                        return _FAIL;
1120        }
1121
1122        /* fix bug of flush_cam_entry at STOP AP mode */
1123        psta->state |= WIFI_AP_STATE;
1124        rtw_indicate_connect(padapter);
1125        pmlmepriv->cur_network.join_res = true;/* for check if already set beacon */
1126        return ret;
1127}
1128
1129void rtw_set_macaddr_acl(struct adapter *padapter, int mode)
1130{
1131        struct sta_priv *pstapriv = &padapter->stapriv;
1132        struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1133
1134        DBG_88E("%s, mode =%d\n", __func__, mode);
1135
1136        pacl_list->mode = mode;
1137}
1138
1139int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
1140{
1141        struct list_head *plist, *phead;
1142        u8 added = false;
1143        int i, ret = 0;
1144        struct rtw_wlan_acl_node *paclnode;
1145        struct sta_priv *pstapriv = &padapter->stapriv;
1146        struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1147        struct __queue *pacl_node_q = &pacl_list->acl_node_q;
1148
1149        DBG_88E("%s(acl_num =%d) =%pM\n", __func__, pacl_list->num, (addr));
1150
1151        if ((NUM_ACL-1) < pacl_list->num)
1152                return -1;
1153
1154        spin_lock_bh(&(pacl_node_q->lock));
1155
1156        phead = get_list_head(pacl_node_q);
1157        plist = phead->next;
1158
1159        while (phead != plist) {
1160                paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
1161                plist = plist->next;
1162
1163                if (!memcmp(paclnode->addr, addr, ETH_ALEN)) {
1164                        if (paclnode->valid) {
1165                                added = true;
1166                                DBG_88E("%s, sta has been added\n", __func__);
1167                                break;
1168                        }
1169                }
1170        }
1171
1172        spin_unlock_bh(&(pacl_node_q->lock));
1173
1174        if (added)
1175                return ret;
1176
1177        spin_lock_bh(&(pacl_node_q->lock));
1178
1179        for (i = 0; i < NUM_ACL; i++) {
1180                paclnode = &pacl_list->aclnode[i];
1181
1182                if (!paclnode->valid) {
1183                        INIT_LIST_HEAD(&paclnode->list);
1184
1185                        ether_addr_copy(paclnode->addr, addr);
1186
1187                        paclnode->valid = true;
1188
1189                        list_add_tail(&paclnode->list, get_list_head(pacl_node_q));
1190
1191                        pacl_list->num++;
1192
1193                        break;
1194                }
1195        }
1196
1197        DBG_88E("%s, acl_num =%d\n", __func__, pacl_list->num);
1198
1199        spin_unlock_bh(&(pacl_node_q->lock));
1200
1201        return ret;
1202}
1203
1204int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr)
1205{
1206        struct list_head *plist, *phead;
1207        struct rtw_wlan_acl_node *paclnode;
1208        struct sta_priv *pstapriv = &padapter->stapriv;
1209        struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1210        struct __queue *pacl_node_q = &pacl_list->acl_node_q;
1211
1212        DBG_88E("%s(acl_num =%d) =%pM\n", __func__, pacl_list->num, (addr));
1213
1214        spin_lock_bh(&(pacl_node_q->lock));
1215
1216        phead = get_list_head(pacl_node_q);
1217        plist = phead->next;
1218
1219        while (phead != plist) {
1220                paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
1221                plist = plist->next;
1222
1223                if (!memcmp(paclnode->addr, addr, ETH_ALEN)) {
1224                        if (paclnode->valid) {
1225                                paclnode->valid = false;
1226
1227                                list_del_init(&paclnode->list);
1228
1229                                pacl_list->num--;
1230                        }
1231                }
1232        }
1233
1234        spin_unlock_bh(&(pacl_node_q->lock));
1235
1236        DBG_88E("%s, acl_num =%d\n", __func__, pacl_list->num);
1237        return 0;
1238}
1239
1240static void update_bcn_erpinfo_ie(struct adapter *padapter)
1241{
1242        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1243        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
1244        struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1245        struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1246        unsigned char *p, *ie = pnetwork->IEs;
1247        u32 len = 0;
1248
1249        DBG_88E("%s, ERP_enable =%d\n", __func__, pmlmeinfo->ERP_enable);
1250
1251        if (!pmlmeinfo->ERP_enable)
1252                return;
1253
1254        /* parsing ERP_IE */
1255        p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len,
1256                       (pnetwork->IELength - _BEACON_IE_OFFSET_));
1257        if (p && len > 0) {
1258                struct ndis_802_11_var_ie *pIE = (struct ndis_802_11_var_ie *)p;
1259
1260                if (pmlmepriv->num_sta_non_erp == 1)
1261                        pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION;
1262                else
1263                        pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION);
1264
1265                if (pmlmepriv->num_sta_no_short_preamble > 0)
1266                        pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;
1267                else
1268                        pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE);
1269
1270                ERP_IE_handler(padapter, pIE);
1271        }
1272}
1273
1274static void update_bcn_wps_ie(struct adapter *padapter)
1275{
1276        u8 *pwps_ie = NULL, *pwps_ie_src;
1277        u8 *premainder_ie, *pbackup_remainder_ie = NULL;
1278        uint wps_ielen = 0, wps_offset, remainder_ielen;
1279        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1280        struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
1281        struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1282        struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
1283        unsigned char *ie = pnetwork->IEs;
1284        u32 ielen = pnetwork->IELength;
1285
1286        DBG_88E("%s\n", __func__);
1287
1288        pwps_ie_src = pmlmepriv->wps_beacon_ie;
1289        if (pwps_ie_src == NULL)
1290                return;
1291
1292        pwps_ie = rtw_get_wps_ie(ie+_FIXED_IE_LENGTH_, ielen-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
1293
1294        if (pwps_ie == NULL || wps_ielen == 0)
1295                return;
1296
1297        wps_offset = (uint)(pwps_ie-ie);
1298
1299        premainder_ie = pwps_ie + wps_ielen;
1300
1301        remainder_ielen = ielen - wps_offset - wps_ielen;
1302
1303        if (remainder_ielen > 0) {
1304                pbackup_remainder_ie = rtw_malloc(remainder_ielen);
1305                if (pbackup_remainder_ie)
1306                        memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
1307        }
1308
1309        wps_ielen = (uint)pwps_ie_src[1];/* to get ie data len */
1310        if ((wps_offset+wps_ielen+2+remainder_ielen) <= MAX_IE_SZ) {
1311                memcpy(pwps_ie, pwps_ie_src, wps_ielen+2);
1312                pwps_ie += (wps_ielen+2);
1313
1314                if (pbackup_remainder_ie)
1315                        memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen);
1316
1317                /* update IELength */
1318                pnetwork->IELength = wps_offset + (wps_ielen+2) + remainder_ielen;
1319        }
1320
1321        kfree(pbackup_remainder_ie);
1322}
1323
1324static void update_bcn_vendor_spec_ie(struct adapter *padapter, u8 *oui)
1325{
1326        DBG_88E("%s\n", __func__);
1327
1328        if (!memcmp(WPS_OUI, oui, 4))
1329                update_bcn_wps_ie(padapter);
1330        else
1331                DBG_88E("unknown OUI type!\n");
1332}
1333
1334void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
1335{
1336        struct mlme_priv *pmlmepriv;
1337        struct mlme_ext_priv    *pmlmeext;
1338
1339        if (!padapter)
1340                return;
1341
1342        pmlmepriv = &(padapter->mlmepriv);
1343        pmlmeext = &(padapter->mlmeextpriv);
1344
1345        if (!pmlmeext->bstart_bss)
1346                return;
1347
1348        spin_lock_bh(&pmlmepriv->bcn_update_lock);
1349
1350        switch (ie_id) {
1351        case _TIM_IE_:
1352                update_BCNTIM(padapter);
1353                break;
1354        case _ERPINFO_IE_:
1355                update_bcn_erpinfo_ie(padapter);
1356                break;
1357        case _VENDOR_SPECIFIC_IE_:
1358                update_bcn_vendor_spec_ie(padapter, oui);
1359                break;
1360        default:
1361                break;
1362        }
1363
1364        pmlmepriv->update_bcn = true;
1365
1366        spin_unlock_bh(&pmlmepriv->bcn_update_lock);
1367
1368        if (tx)
1369                set_tx_beacon_cmd(padapter);
1370}
1371
1372/*
1373op_mode
1374Set to 0 (HT pure) under the following conditions
1375        - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
1376        - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
1377Set to 1 (HT non-member protection) if there may be non-HT STAs
1378        in both the primary and the secondary channel
1379Set to 2 if only HT STAs are associated in BSS,
1380        however and at least one 20 MHz HT STA is associated
1381Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
1382        (currently non-GF HT station is considered as non-HT STA also)
1383*/
1384static int rtw_ht_operation_update(struct adapter *padapter)
1385{
1386        u16 cur_op_mode, new_op_mode;
1387        int op_mode_changes = 0;
1388        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1389        struct ht_priv  *phtpriv_ap = &pmlmepriv->htpriv;
1390
1391        if (pmlmepriv->htpriv.ht_option)
1392                return 0;
1393
1394        DBG_88E("%s current operation mode = 0x%X\n",
1395                __func__, pmlmepriv->ht_op_mode);
1396
1397        if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
1398            pmlmepriv->num_sta_ht_no_gf) {
1399                pmlmepriv->ht_op_mode |=
1400                        HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
1401                op_mode_changes++;
1402        } else if ((pmlmepriv->ht_op_mode &
1403                   HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
1404                   pmlmepriv->num_sta_ht_no_gf == 0) {
1405                pmlmepriv->ht_op_mode &=
1406                        ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
1407                op_mode_changes++;
1408        }
1409
1410        if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
1411            (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) {
1412                pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
1413                op_mode_changes++;
1414        } else if ((pmlmepriv->ht_op_mode &
1415                    HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
1416                   (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) {
1417                pmlmepriv->ht_op_mode &=
1418                        ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
1419                op_mode_changes++;
1420        }
1421
1422        /* Note: currently we switch to the MIXED op mode if HT non-greenfield
1423         * station is associated. Probably it's a theoretical case, since
1424         * it looks like all known HT STAs support greenfield.
1425         */
1426        new_op_mode = 0;
1427        if (pmlmepriv->num_sta_no_ht ||
1428            (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
1429                new_op_mode = OP_MODE_MIXED;
1430        else if ((phtpriv_ap->ht_cap.cap_info & IEEE80211_HT_CAP_SUP_WIDTH) &&
1431                 pmlmepriv->num_sta_ht_20mhz)
1432                new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
1433        else if (pmlmepriv->olbc_ht)
1434                new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
1435        else
1436                new_op_mode = OP_MODE_PURE;
1437
1438        cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
1439        if (cur_op_mode != new_op_mode) {
1440                pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
1441                pmlmepriv->ht_op_mode |= new_op_mode;
1442                op_mode_changes++;
1443        }
1444
1445        DBG_88E("%s new operation mode = 0x%X changes =%d\n",
1446                __func__, pmlmepriv->ht_op_mode, op_mode_changes);
1447
1448        return op_mode_changes;
1449}
1450
1451void associated_clients_update(struct adapter *padapter, u8 updated)
1452{
1453        /* update associated stations cap. */
1454        if (updated) {
1455                struct list_head *phead, *plist;
1456                struct sta_info *psta = NULL;
1457                struct sta_priv *pstapriv = &padapter->stapriv;
1458
1459                spin_lock_bh(&pstapriv->asoc_list_lock);
1460
1461                phead = &pstapriv->asoc_list;
1462                plist = phead->next;
1463
1464                /* check asoc_queue */
1465                while (phead != plist) {
1466                        psta = container_of(plist, struct sta_info, asoc_list);
1467
1468                        plist = plist->next;
1469
1470                        VCS_update(padapter, psta);
1471                }
1472                spin_unlock_bh(&pstapriv->asoc_list_lock);
1473        }
1474}
1475
1476/* called > TSR LEVEL for USB or SDIO Interface*/
1477void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta)
1478{
1479        u8 beacon_updated = false;
1480        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1481        struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1482
1483        if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) {
1484                if (!psta->no_short_preamble_set) {
1485                        psta->no_short_preamble_set = 1;
1486
1487                        pmlmepriv->num_sta_no_short_preamble++;
1488
1489                        if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1490                            (pmlmepriv->num_sta_no_short_preamble == 1)) {
1491                                beacon_updated = true;
1492                                update_beacon(padapter, 0xFF, NULL, true);
1493                        }
1494                }
1495        } else {
1496                if (psta->no_short_preamble_set) {
1497                        psta->no_short_preamble_set = 0;
1498
1499                        pmlmepriv->num_sta_no_short_preamble--;
1500
1501                        if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1502                            (pmlmepriv->num_sta_no_short_preamble == 0)) {
1503                                beacon_updated = true;
1504                                update_beacon(padapter, 0xFF, NULL, true);
1505                        }
1506                }
1507        }
1508
1509        if (psta->flags & WLAN_STA_NONERP) {
1510                if (!psta->nonerp_set) {
1511                        psta->nonerp_set = 1;
1512
1513                        pmlmepriv->num_sta_non_erp++;
1514
1515                        if (pmlmepriv->num_sta_non_erp == 1) {
1516                                beacon_updated = true;
1517                                update_beacon(padapter, _ERPINFO_IE_, NULL, true);
1518                        }
1519                }
1520        } else {
1521                if (psta->nonerp_set) {
1522                        psta->nonerp_set = 0;
1523
1524                        pmlmepriv->num_sta_non_erp--;
1525
1526                        if (pmlmepriv->num_sta_non_erp == 0) {
1527                                beacon_updated = true;
1528                                update_beacon(padapter, _ERPINFO_IE_, NULL, true);
1529                        }
1530                }
1531        }
1532
1533        if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)) {
1534                if (!psta->no_short_slot_time_set) {
1535                        psta->no_short_slot_time_set = 1;
1536
1537                        pmlmepriv->num_sta_no_short_slot_time++;
1538
1539                        if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1540                            (pmlmepriv->num_sta_no_short_slot_time == 1)) {
1541                                beacon_updated = true;
1542                                update_beacon(padapter, 0xFF, NULL, true);
1543                        }
1544                }
1545        } else {
1546                if (psta->no_short_slot_time_set) {
1547                        psta->no_short_slot_time_set = 0;
1548
1549                        pmlmepriv->num_sta_no_short_slot_time--;
1550
1551                        if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
1552                            (pmlmepriv->num_sta_no_short_slot_time == 0)) {
1553                                beacon_updated = true;
1554                                update_beacon(padapter, 0xFF, NULL, true);
1555                        }
1556                }
1557        }
1558
1559        if (psta->flags & WLAN_STA_HT) {
1560                u16 ht_capab = psta->htpriv.ht_cap.cap_info;
1561
1562                DBG_88E("HT: STA %pM HT Capabilities Info: 0x%04x\n",
1563                        (psta->hwaddr), ht_capab);
1564
1565                if (psta->no_ht_set) {
1566                        psta->no_ht_set = 0;
1567                        pmlmepriv->num_sta_no_ht--;
1568                }
1569
1570                if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) {
1571                        if (!psta->no_ht_gf_set) {
1572                                psta->no_ht_gf_set = 1;
1573                                pmlmepriv->num_sta_ht_no_gf++;
1574                        }
1575                        DBG_88E("%s STA %pM - no greenfield, num of non-gf stations %d\n",
1576                                   __func__, (psta->hwaddr),
1577                                   pmlmepriv->num_sta_ht_no_gf);
1578                }
1579
1580                if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH) == 0) {
1581                        if (!psta->ht_20mhz_set) {
1582                                psta->ht_20mhz_set = 1;
1583                                pmlmepriv->num_sta_ht_20mhz++;
1584                        }
1585                        DBG_88E("%s STA %pM - 20 MHz HT, num of 20MHz HT STAs %d\n",
1586                                   __func__, (psta->hwaddr),
1587                                   pmlmepriv->num_sta_ht_20mhz);
1588                }
1589        } else {
1590                if (!psta->no_ht_set) {
1591                        psta->no_ht_set = 1;
1592                        pmlmepriv->num_sta_no_ht++;
1593                }
1594                if (pmlmepriv->htpriv.ht_option) {
1595                        DBG_88E("%s STA %pM - no HT, num of non-HT stations %d\n",
1596                                __func__, (psta->hwaddr),
1597                                pmlmepriv->num_sta_no_ht);
1598                }
1599        }
1600
1601        if (rtw_ht_operation_update(padapter) > 0) {
1602                update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, false);
1603                update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, true);
1604        }
1605
1606        /* update associated stations cap. */
1607        associated_clients_update(padapter,  beacon_updated);
1608
1609        DBG_88E("%s, updated =%d\n", __func__, beacon_updated);
1610}
1611
1612u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta)
1613{
1614        u8 beacon_updated = false;
1615        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1616        struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1617
1618        if (!psta)
1619                return beacon_updated;
1620
1621        if (psta->no_short_preamble_set) {
1622                psta->no_short_preamble_set = 0;
1623                pmlmepriv->num_sta_no_short_preamble--;
1624                if (pmlmeext->cur_wireless_mode > WIRELESS_11B &&
1625                    pmlmepriv->num_sta_no_short_preamble == 0) {
1626                        beacon_updated = true;
1627                        update_beacon(padapter, 0xFF, NULL, true);
1628                }
1629        }
1630
1631        if (psta->nonerp_set) {
1632                psta->nonerp_set = 0;
1633                pmlmepriv->num_sta_non_erp--;
1634                if (pmlmepriv->num_sta_non_erp == 0) {
1635                        beacon_updated = true;
1636                        update_beacon(padapter, _ERPINFO_IE_, NULL, true);
1637                }
1638        }
1639
1640        if (psta->no_short_slot_time_set) {
1641                psta->no_short_slot_time_set = 0;
1642                pmlmepriv->num_sta_no_short_slot_time--;
1643                if (pmlmeext->cur_wireless_mode > WIRELESS_11B &&
1644                    pmlmepriv->num_sta_no_short_slot_time == 0) {
1645                        beacon_updated = true;
1646                        update_beacon(padapter, 0xFF, NULL, true);
1647                }
1648        }
1649
1650        if (psta->no_ht_gf_set) {
1651                psta->no_ht_gf_set = 0;
1652                pmlmepriv->num_sta_ht_no_gf--;
1653        }
1654
1655        if (psta->no_ht_set) {
1656                psta->no_ht_set = 0;
1657                pmlmepriv->num_sta_no_ht--;
1658        }
1659
1660        if (psta->ht_20mhz_set) {
1661                psta->ht_20mhz_set = 0;
1662                pmlmepriv->num_sta_ht_20mhz--;
1663        }
1664
1665        if (rtw_ht_operation_update(padapter) > 0) {
1666                update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, false);
1667                update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, true);
1668        }
1669
1670        /* update associated stations cap. */
1671
1672        DBG_88E("%s, updated =%d\n", __func__, beacon_updated);
1673
1674        return beacon_updated;
1675}
1676
1677u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta,
1678               bool active, u16 reason)
1679{
1680        u8 beacon_updated = false;
1681        struct sta_priv *pstapriv = &padapter->stapriv;
1682
1683        if (!psta)
1684                return beacon_updated;
1685
1686        /* tear down Rx AMPDU */
1687        send_delba(padapter, 0, psta->hwaddr);/*  recipient */
1688
1689        /* tear down TX AMPDU */
1690        send_delba(padapter, 1, psta->hwaddr);/*  originator */
1691        psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
1692        psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
1693
1694        if (active)
1695                issue_deauth(padapter, psta->hwaddr, reason);
1696
1697        /* clear cam entry / key */
1698        rtw_clearstakey_cmd(padapter, (u8 *)psta, (u8)(psta->mac_id + 3), true);
1699
1700
1701        spin_lock_bh(&psta->lock);
1702        psta->state &= ~_FW_LINKED;
1703        spin_unlock_bh(&psta->lock);
1704
1705        rtw_indicate_sta_disassoc_event(padapter, psta);
1706
1707        report_del_sta_event(padapter, psta->hwaddr, reason);
1708
1709        beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);
1710
1711        spin_lock_bh(&(pstapriv->sta_hash_lock));
1712        rtw_free_stainfo(padapter, psta);
1713        spin_unlock_bh(&(pstapriv->sta_hash_lock));
1714
1715        return beacon_updated;
1716}
1717
1718int rtw_ap_inform_ch_switch(struct adapter *padapter, u8 new_ch, u8 ch_offset)
1719{
1720        struct list_head *phead, *plist;
1721        struct sta_info *psta = NULL;
1722        struct sta_priv *pstapriv = &padapter->stapriv;
1723        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1724        struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1725        u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1726
1727        if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1728                return 0;
1729
1730        DBG_88E(FUNC_NDEV_FMT" with ch:%u, offset:%u\n",
1731                FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset);
1732
1733        spin_lock_bh(&pstapriv->asoc_list_lock);
1734        phead = &pstapriv->asoc_list;
1735        plist = phead->next;
1736
1737        /* for each sta in asoc_queue */
1738        while (phead != plist) {
1739                psta = container_of(plist, struct sta_info, asoc_list);
1740                plist = plist->next;
1741
1742                issue_action_spct_ch_switch(padapter, psta->hwaddr, new_ch, ch_offset);
1743                psta->expire_to = min_t(unsigned int, pstapriv->expire_to * 2, 5);
1744        }
1745        spin_unlock_bh(&pstapriv->asoc_list_lock);
1746
1747        issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset);
1748
1749        return 0;
1750}
1751
1752int rtw_sta_flush(struct adapter *padapter)
1753{
1754        struct list_head *phead, *plist;
1755        struct sta_info *psta = NULL;
1756        struct sta_priv *pstapriv = &padapter->stapriv;
1757        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1758        struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1759        u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1760
1761        DBG_88E(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
1762
1763        if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1764                return 0;
1765
1766        spin_lock_bh(&pstapriv->asoc_list_lock);
1767        phead = &pstapriv->asoc_list;
1768        plist = phead->next;
1769
1770        /* free sta asoc_queue */
1771        while (phead != plist) {
1772                psta = container_of(plist, struct sta_info, asoc_list);
1773
1774                plist = plist->next;
1775
1776                list_del_init(&psta->asoc_list);
1777                pstapriv->asoc_list_cnt--;
1778
1779                ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
1780        }
1781        spin_unlock_bh(&pstapriv->asoc_list_lock);
1782
1783
1784        issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);
1785
1786        associated_clients_update(padapter, true);
1787
1788        return 0;
1789}
1790
1791/* called > TSR LEVEL for USB or SDIO Interface*/
1792void sta_info_update(struct adapter *padapter, struct sta_info *psta)
1793{
1794        int flags = psta->flags;
1795        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1796
1797        /* update wmm cap. */
1798        if (WLAN_STA_WME&flags)
1799                psta->qos_option = 1;
1800        else
1801                psta->qos_option = 0;
1802
1803        if (pmlmepriv->qospriv.qos_option == 0)
1804                psta->qos_option = 0;
1805
1806        /* update 802.11n ht cap. */
1807        if (WLAN_STA_HT&flags) {
1808                psta->htpriv.ht_option = true;
1809                psta->qos_option = 1;
1810        } else {
1811                psta->htpriv.ht_option = false;
1812        }
1813
1814        if (!pmlmepriv->htpriv.ht_option)
1815                psta->htpriv.ht_option = false;
1816
1817        update_sta_info_apmode(padapter, psta);
1818}
1819
1820/* called >= TSR LEVEL for USB or SDIO Interface*/
1821void ap_sta_info_defer_update(struct adapter *padapter, struct sta_info *psta)
1822{
1823        if (psta->state & _FW_LINKED) {
1824                /* add ratid */
1825                add_RATid(padapter, psta, 0);/* DM_RATR_STA_INIT */
1826        }
1827}
1828
1829void start_ap_mode(struct adapter *padapter)
1830{
1831        int i;
1832        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1833        struct sta_priv *pstapriv = &padapter->stapriv;
1834        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1835        struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1836
1837        pmlmepriv->update_bcn = false;
1838
1839        pmlmeext->bstart_bss = false;
1840
1841        pmlmepriv->num_sta_non_erp = 0;
1842
1843        pmlmepriv->num_sta_no_short_slot_time = 0;
1844
1845        pmlmepriv->num_sta_no_short_preamble = 0;
1846
1847        pmlmepriv->num_sta_ht_no_gf = 0;
1848        pmlmepriv->num_sta_no_ht = 0;
1849        pmlmepriv->num_sta_ht_20mhz = 0;
1850
1851        pmlmepriv->olbc = false;
1852
1853        pmlmepriv->olbc_ht = false;
1854
1855        pmlmepriv->ht_op_mode = 0;
1856
1857        for (i = 0; i < NUM_STA; i++)
1858                pstapriv->sta_aid[i] = NULL;
1859
1860        pmlmepriv->wps_beacon_ie = NULL;
1861        pmlmepriv->wps_probe_resp_ie = NULL;
1862        pmlmepriv->wps_assoc_resp_ie = NULL;
1863
1864        pmlmepriv->p2p_beacon_ie = NULL;
1865        pmlmepriv->p2p_probe_resp_ie = NULL;
1866
1867        /* for ACL */
1868        INIT_LIST_HEAD(&(pacl_list->acl_node_q.queue));
1869        pacl_list->num = 0;
1870        pacl_list->mode = 0;
1871        for (i = 0; i < NUM_ACL; i++) {
1872                INIT_LIST_HEAD(&pacl_list->aclnode[i].list);
1873                pacl_list->aclnode[i].valid = false;
1874        }
1875}
1876
1877void stop_ap_mode(struct adapter *padapter)
1878{
1879        struct list_head *phead, *plist;
1880        struct rtw_wlan_acl_node *paclnode;
1881        struct sta_info *psta = NULL;
1882        struct sta_priv *pstapriv = &padapter->stapriv;
1883        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1884        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1885        struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
1886        struct __queue *pacl_node_q = &pacl_list->acl_node_q;
1887
1888        pmlmepriv->update_bcn = false;
1889        pmlmeext->bstart_bss = false;
1890
1891        /* reset and init security priv , this can refine with rtw_reset_securitypriv */
1892        memset((unsigned char *)&padapter->securitypriv, 0, sizeof(struct security_priv));
1893        padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
1894        padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
1895
1896        /* for ACL */
1897        spin_lock_bh(&(pacl_node_q->lock));
1898        phead = get_list_head(pacl_node_q);
1899        plist = phead->next;
1900        while (phead != plist) {
1901                paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
1902                plist = plist->next;
1903
1904                if (paclnode->valid) {
1905                        paclnode->valid = false;
1906
1907                        list_del_init(&paclnode->list);
1908
1909                        pacl_list->num--;
1910                }
1911        }
1912        spin_unlock_bh(&(pacl_node_q->lock));
1913
1914        DBG_88E("%s, free acl_node_queue, num =%d\n", __func__, pacl_list->num);
1915
1916        rtw_sta_flush(padapter);
1917
1918        /* free_assoc_sta_resources */
1919        rtw_free_all_stainfo(padapter);
1920
1921        psta = rtw_get_bcmc_stainfo(padapter);
1922        spin_lock_bh(&(pstapriv->sta_hash_lock));
1923        rtw_free_stainfo(padapter, psta);
1924        spin_unlock_bh(&(pstapriv->sta_hash_lock));
1925
1926        rtw_init_bcmc_stainfo(padapter);
1927
1928        rtw_free_mlme_priv_ie_data(pmlmepriv);
1929}
1930
1931#endif /* CONFIG_88EU_AP_MODE */
1932