linux/drivers/staging/rtl8723bs/core/rtw_ioctl_set.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 ******************************************************************************/
  15#define _RTW_IOCTL_SET_C_
  16
  17#include <drv_types.h>
  18#include <rtw_debug.h>
  19
  20#define IS_MAC_ADDRESS_BROADCAST(addr) \
  21(\
  22        ((addr[0] == 0xff) && (addr[1] == 0xff) && \
  23                (addr[2] == 0xff) && (addr[3] == 0xff) && \
  24                (addr[4] == 0xff) && (addr[5] == 0xff))  ? true : false \
  25)
  26
  27u8 rtw_validate_bssid(u8 *bssid)
  28{
  29        u8 ret = true;
  30
  31        if (is_zero_mac_addr(bssid)
  32                || is_broadcast_mac_addr(bssid)
  33                || is_multicast_mac_addr(bssid)
  34        ) {
  35                ret = false;
  36        }
  37
  38        return ret;
  39}
  40
  41u8 rtw_validate_ssid(struct ndis_802_11_ssid *ssid)
  42{
  43        u8 ret = true;
  44
  45        if (ssid->SsidLength > 32) {
  46                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid length >32\n"));
  47                ret = false;
  48                goto exit;
  49        }
  50
  51#ifdef CONFIG_VALIDATE_SSID
  52        for (i = 0; i < ssid->SsidLength; i++) {
  53                /* wifi, printable ascii code must be supported */
  54                if (!((ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e))) {
  55                        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid has nonprintabl ascii\n"));
  56                        ret = false;
  57                        break;
  58                }
  59        }
  60#endif /* CONFIG_VALIDATE_SSID */
  61
  62exit:
  63        return ret;
  64}
  65
  66u8 rtw_do_join(struct adapter *padapter);
  67u8 rtw_do_join(struct adapter *padapter)
  68{
  69        struct list_head        *plist, *phead;
  70        u8 *pibss = NULL;
  71        struct  mlme_priv *pmlmepriv = &(padapter->mlmepriv);
  72        struct __queue  *queue  = &(pmlmepriv->scanned_queue);
  73        u8 ret = _SUCCESS;
  74
  75        spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
  76        phead = get_list_head(queue);
  77        plist = get_next(phead);
  78
  79        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("\n rtw_do_join: phead = %p; plist = %p\n\n\n", phead, plist));
  80
  81        pmlmepriv->cur_network.join_res = -2;
  82
  83        set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
  84
  85        pmlmepriv->pscanned = plist;
  86
  87        pmlmepriv->to_join = true;
  88
  89        if (list_empty(&queue->queue)) {
  90                spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
  91                _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
  92
  93                /* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */
  94                /* we try to issue sitesurvey firstly */
  95
  96                if (pmlmepriv->LinkDetectInfo.bBusyTraffic == false
  97                        || rtw_to_roam(padapter) > 0
  98                ) {
  99                        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("rtw_do_join(): site survey if scanned_queue is empty\n."));
 100                        /*  submit site_survey_cmd */
 101                        ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
 102                        if (_SUCCESS != ret) {
 103                                pmlmepriv->to_join = false;
 104                                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_do_join(): site survey return error\n."));
 105                        }
 106                } else{
 107                        pmlmepriv->to_join = false;
 108                        ret = _FAIL;
 109                }
 110
 111                goto exit;
 112        } else{
 113                int select_ret;
 114                spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
 115                select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
 116                if (select_ret == _SUCCESS) {
 117                        pmlmepriv->to_join = false;
 118                        _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
 119                } else{
 120                        if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) {
 121                                /*  submit createbss_cmd to change to a ADHOC_MASTER */
 122
 123                                /* pmlmepriv->lock has been acquired by caller... */
 124                                struct wlan_bssid_ex    *pdev_network = &(padapter->registrypriv.dev_network);
 125
 126                                pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
 127
 128                                pibss = padapter->registrypriv.dev_network.MacAddress;
 129
 130                                memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(struct ndis_802_11_ssid));
 131
 132                                rtw_update_registrypriv_dev_network(padapter);
 133
 134                                rtw_generate_random_ibss(pibss);
 135
 136                                if (rtw_createbss_cmd(padapter) != _SUCCESS) {
 137                                        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("***Error =>do_goin: rtw_createbss_cmd status FAIL***\n "));
 138                                        ret =  false;
 139                                        goto exit;
 140                                }
 141
 142                                pmlmepriv->to_join = false;
 143
 144                                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("***Error => rtw_select_and_join_from_scanned_queue FAIL under STA_Mode***\n "));
 145
 146                        } else{
 147                                /*  can't associate ; reset under-linking */
 148                                _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
 149
 150                                /* when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue */
 151                                /* we try to issue sitesurvey firstly */
 152                                if (pmlmepriv->LinkDetectInfo.bBusyTraffic == false
 153                                        || rtw_to_roam(padapter) > 0
 154                                ) {
 155                                        /* DBG_871X("rtw_do_join() when   no desired bss in scanning queue\n"); */
 156                                        ret = rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
 157                                        if (_SUCCESS != ret) {
 158                                                pmlmepriv->to_join = false;
 159                                                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("do_join(): site survey return error\n."));
 160                                        }
 161                                } else{
 162                                        ret = _FAIL;
 163                                        pmlmepriv->to_join = false;
 164                                }
 165                        }
 166
 167                }
 168
 169        }
 170
 171exit:
 172        return ret;
 173}
 174
 175u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid)
 176{
 177        u8 status = _SUCCESS;
 178
 179        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 180
 181        DBG_871X_LEVEL(_drv_always_, "set bssid:%pM\n", bssid);
 182
 183        if ((bssid[0] == 0x00 && bssid[1] == 0x00 && bssid[2] == 0x00 && bssid[3] == 0x00 && bssid[4] == 0x00 && bssid[5] == 0x00) ||
 184            (bssid[0] == 0xFF && bssid[1] == 0xFF && bssid[2] == 0xFF && bssid[3] == 0xFF && bssid[4] == 0xFF && bssid[5] == 0xFF)) {
 185                status = _FAIL;
 186                goto exit;
 187        }
 188
 189        spin_lock_bh(&pmlmepriv->lock);
 190
 191
 192        DBG_871X("Set BSSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
 193        if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
 194                goto handle_tkip_countermeasure;
 195        } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
 196                goto release_mlme_lock;
 197        }
 198
 199        if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) {
 200                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
 201
 202                if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN)) {
 203                        if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)
 204                                goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
 205                } else {
 206                        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("Set BSSID not the same bssid\n"));
 207                        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid ="MAC_FMT"\n", MAC_ARG(bssid)));
 208                        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("cur_bssid ="MAC_FMT"\n", MAC_ARG(pmlmepriv->cur_network.network.MacAddress)));
 209
 210                        rtw_disassoc_cmd(padapter, 0, true);
 211
 212                        if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
 213                                rtw_indicate_disconnect(padapter);
 214
 215                        rtw_free_assoc_resources(padapter, 1);
 216
 217                        if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
 218                                _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
 219                                set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
 220                        }
 221                }
 222        }
 223
 224handle_tkip_countermeasure:
 225        if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
 226                status = _FAIL;
 227                goto release_mlme_lock;
 228        }
 229
 230        memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
 231        memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
 232        pmlmepriv->assoc_by_bssid = true;
 233
 234        if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
 235                pmlmepriv->to_join = true;
 236        } else {
 237                status = rtw_do_join(padapter);
 238        }
 239
 240release_mlme_lock:
 241        spin_unlock_bh(&pmlmepriv->lock);
 242
 243exit:
 244        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
 245                ("rtw_set_802_11_bssid: status =%d\n", status));
 246
 247        return status;
 248}
 249
 250u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid)
 251{
 252        u8 status = _SUCCESS;
 253
 254        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 255        struct wlan_network *pnetwork = &pmlmepriv->cur_network;
 256
 257        DBG_871X_LEVEL(_drv_always_, "set ssid [%s] fw_state = 0x%08x\n",
 258                        ssid->Ssid, get_fwstate(pmlmepriv));
 259
 260        if (padapter->hw_init_completed == false) {
 261                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
 262                         ("set_ssid: hw_init_completed ==false =>exit!!!\n"));
 263                status = _FAIL;
 264                goto exit;
 265        }
 266
 267        spin_lock_bh(&pmlmepriv->lock);
 268
 269        DBG_871X("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
 270        if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
 271                goto handle_tkip_countermeasure;
 272        } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
 273                goto release_mlme_lock;
 274        }
 275
 276        if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) {
 277                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
 278                         ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
 279
 280                if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
 281                    (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength))) {
 282                        if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)) {
 283                                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
 284                                         ("Set SSID is the same ssid, fw_state = 0x%08x\n",
 285                                          get_fwstate(pmlmepriv)));
 286
 287                                if (rtw_is_same_ibss(padapter, pnetwork) == false) {
 288                                        /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */
 289                                        rtw_disassoc_cmd(padapter, 0, true);
 290
 291                                        if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
 292                                                rtw_indicate_disconnect(padapter);
 293
 294                                        rtw_free_assoc_resources(padapter, 1);
 295
 296                                        if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
 297                                                _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
 298                                                set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
 299                                        }
 300                                } else{
 301                                        goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */
 302                                }
 303                        } else {
 304                                rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1);
 305                        }
 306                } else{
 307                        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("Set SSID not the same ssid\n"));
 308                        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid =[%s] len = 0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength));
 309                        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("assoc_ssid =[%s] len = 0x%x\n", pmlmepriv->assoc_ssid.Ssid, (unsigned int)pmlmepriv->assoc_ssid.SsidLength));
 310
 311                        rtw_disassoc_cmd(padapter, 0, true);
 312
 313                        if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
 314                                rtw_indicate_disconnect(padapter);
 315
 316                        rtw_free_assoc_resources(padapter, 1);
 317
 318                        if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) {
 319                                _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
 320                                set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
 321                        }
 322                }
 323        }
 324
 325handle_tkip_countermeasure:
 326        if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
 327                status = _FAIL;
 328                goto release_mlme_lock;
 329        }
 330
 331        if (rtw_validate_ssid(ssid) == false) {
 332                status = _FAIL;
 333                goto release_mlme_lock;
 334        }
 335
 336        memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid));
 337        pmlmepriv->assoc_by_bssid = false;
 338
 339        if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
 340                pmlmepriv->to_join = true;
 341        } else {
 342                status = rtw_do_join(padapter);
 343        }
 344
 345release_mlme_lock:
 346        spin_unlock_bh(&pmlmepriv->lock);
 347
 348exit:
 349        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
 350                ("-rtw_set_802_11_ssid: status =%d\n", status));
 351
 352        return status;
 353}
 354
 355u8 rtw_set_802_11_connect(struct adapter *padapter, u8 *bssid, struct ndis_802_11_ssid *ssid)
 356{
 357        u8 status = _SUCCESS;
 358        bool bssid_valid = true;
 359        bool ssid_valid = true;
 360        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 361
 362        if (!ssid || rtw_validate_ssid(ssid) == false)
 363                ssid_valid = false;
 364
 365        if (!bssid || rtw_validate_bssid(bssid) == false)
 366                bssid_valid = false;
 367
 368        if (ssid_valid == false && bssid_valid == false) {
 369                DBG_871X(FUNC_ADPT_FMT" ssid:%p, ssid_valid:%d, bssid:%p, bssid_valid:%d\n",
 370                        FUNC_ADPT_ARG(padapter), ssid, ssid_valid, bssid, bssid_valid);
 371                status = _FAIL;
 372                goto exit;
 373        }
 374
 375        if (padapter->hw_init_completed == false) {
 376                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
 377                         ("set_ssid: hw_init_completed ==false =>exit!!!\n"));
 378                status = _FAIL;
 379                goto exit;
 380        }
 381
 382        spin_lock_bh(&pmlmepriv->lock);
 383
 384        DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT"  fw_state = 0x%08x\n",
 385                FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv));
 386
 387        if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
 388                goto handle_tkip_countermeasure;
 389        } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
 390                goto release_mlme_lock;
 391        }
 392
 393handle_tkip_countermeasure:
 394        if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
 395                status = _FAIL;
 396                goto release_mlme_lock;
 397        }
 398
 399        if (ssid && ssid_valid)
 400                memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid));
 401        else
 402                memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
 403
 404        if (bssid && bssid_valid) {
 405                memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
 406                pmlmepriv->assoc_by_bssid = true;
 407        } else {
 408                pmlmepriv->assoc_by_bssid = false;
 409        }
 410
 411        if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
 412                pmlmepriv->to_join = true;
 413        } else {
 414                status = rtw_do_join(padapter);
 415        }
 416
 417release_mlme_lock:
 418        spin_unlock_bh(&pmlmepriv->lock);
 419
 420exit:
 421        return status;
 422}
 423
 424u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter,
 425        enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
 426{
 427        struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;
 428        struct  wlan_network    *cur_network = &pmlmepriv->cur_network;
 429        enum NDIS_802_11_NETWORK_INFRASTRUCTURE *pold_state = &(cur_network->network.InfrastructureMode);
 430
 431        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_,
 432                 ("+rtw_set_802_11_infrastructure_mode: old =%d new =%d fw_state = 0x%08x\n",
 433                  *pold_state, networktype, get_fwstate(pmlmepriv)));
 434
 435        if (*pold_state != networktype) {
 436                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, (" change mode!"));
 437                /* DBG_871X("change mode, old_mode =%d, new_mode =%d, fw_state = 0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv)); */
 438
 439                if (*pold_state == Ndis802_11APMode) {
 440                        /* change to other mode from Ndis802_11APMode */
 441                        cur_network->join_res = -1;
 442
 443                        stop_ap_mode(padapter);
 444                }
 445
 446                spin_lock_bh(&pmlmepriv->lock);
 447
 448                if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) || (*pold_state == Ndis802_11IBSS))
 449                        rtw_disassoc_cmd(padapter, 0, true);
 450
 451                if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) ||
 452                        (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true))
 453                        rtw_free_assoc_resources(padapter, 1);
 454
 455                if ((*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) {
 456                        if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
 457                                rtw_indicate_disconnect(padapter); /* will clr Linked_state; before this function, we must have chked whether  issue dis-assoc_cmd or not */
 458                        }
 459               }
 460
 461                *pold_state = networktype;
 462
 463                _clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
 464
 465                switch (networktype) {
 466                case Ndis802_11IBSS:
 467                        set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
 468                        break;
 469
 470                case Ndis802_11Infrastructure:
 471                        set_fwstate(pmlmepriv, WIFI_STATION_STATE);
 472                        break;
 473
 474                case Ndis802_11APMode:
 475                        set_fwstate(pmlmepriv, WIFI_AP_STATE);
 476                        start_ap_mode(padapter);
 477                        /* rtw_indicate_connect(padapter); */
 478
 479                        break;
 480
 481                case Ndis802_11AutoUnknown:
 482                case Ndis802_11InfrastructureMax:
 483                        break;
 484                }
 485
 486                /* SecClearAllKeys(adapter); */
 487
 488                /* RT_TRACE(COMP_OID_SET, DBG_LOUD, ("set_infrastructure: fw_state:%x after changing mode\n", */
 489                /*                                                                      get_fwstate(pmlmepriv))); */
 490
 491                spin_unlock_bh(&pmlmepriv->lock);
 492        }
 493        return true;
 494}
 495
 496
 497u8 rtw_set_802_11_disassociate(struct adapter *padapter)
 498{
 499        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 500
 501        spin_lock_bh(&pmlmepriv->lock);
 502
 503        if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
 504                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_disassociate: rtw_indicate_disconnect\n"));
 505
 506                rtw_disassoc_cmd(padapter, 0, true);
 507                rtw_indicate_disconnect(padapter);
 508                /* modify for CONFIG_IEEE80211W, none 11w can use it */
 509                rtw_free_assoc_resources_cmd(padapter);
 510                if (_FAIL == rtw_pwr_wakeup(padapter))
 511                        DBG_871X("%s(): rtw_pwr_wakeup fail !!!\n", __func__);
 512        }
 513
 514        spin_unlock_bh(&pmlmepriv->lock);
 515
 516        return true;
 517}
 518
 519u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_ssid *pssid, int ssid_max_num)
 520{
 521        struct  mlme_priv       *pmlmepriv = &padapter->mlmepriv;
 522        u8 res = true;
 523
 524        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("+rtw_set_802_11_bssid_list_scan(), fw_state =%x\n", get_fwstate(pmlmepriv)));
 525
 526        if (padapter == NULL) {
 527                res = false;
 528                goto exit;
 529        }
 530        if (padapter->hw_init_completed == false) {
 531                res = false;
 532                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n ===rtw_set_802_11_bssid_list_scan:hw_init_completed ==false ===\n"));
 533                goto exit;
 534        }
 535
 536        if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true) ||
 537                (pmlmepriv->LinkDetectInfo.bBusyTraffic == true)) {
 538                /*  Scan or linking is in progress, do nothing. */
 539                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_set_802_11_bssid_list_scan fail since fw_state = %x\n", get_fwstate(pmlmepriv)));
 540                res = true;
 541
 542                if (check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)) == true) {
 543                        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n###_FW_UNDER_SURVEY|_FW_UNDER_LINKING\n\n"));
 544                } else {
 545                        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n###pmlmepriv->sitesurveyctrl.traffic_busy ==true\n\n"));
 546                }
 547        } else {
 548                if (rtw_is_scan_deny(padapter)) {
 549                        DBG_871X(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter));
 550                        indicate_wx_scan_complete_event(padapter);
 551                        return _SUCCESS;
 552                }
 553
 554                spin_lock_bh(&pmlmepriv->lock);
 555
 556                res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, NULL, 0);
 557
 558                spin_unlock_bh(&pmlmepriv->lock);
 559        }
 560exit:
 561
 562        return res;
 563}
 564
 565u8 rtw_set_802_11_authentication_mode(struct adapter *padapter, enum NDIS_802_11_AUTHENTICATION_MODE authmode)
 566{
 567        struct security_priv *psecuritypriv = &padapter->securitypriv;
 568        int res;
 569        u8 ret;
 570
 571        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_802_11_auth.mode(): mode =%x\n", authmode));
 572
 573        psecuritypriv->ndisauthtype = authmode;
 574
 575        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("rtw_set_802_11_authentication_mode:psecuritypriv->ndisauthtype =%d", psecuritypriv->ndisauthtype));
 576
 577        if (psecuritypriv->ndisauthtype > 3)
 578                psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
 579
 580        res = rtw_set_auth(padapter, psecuritypriv);
 581
 582        if (res == _SUCCESS)
 583                ret = true;
 584        else
 585                ret = false;
 586
 587        return ret;
 588}
 589
 590u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep)
 591{
 592
 593        sint            keyid, res;
 594        struct security_priv *psecuritypriv = &(padapter->securitypriv);
 595        u8 ret = _SUCCESS;
 596
 597        keyid = wep->KeyIndex & 0x3fffffff;
 598
 599        if (keyid >= 4) {
 600                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("MgntActrtw_set_802_11_add_wep:keyid>4 =>fail\n"));
 601                ret = false;
 602                goto exit;
 603        }
 604
 605        switch (wep->KeyLength) {
 606        case 5:
 607                psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
 608                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_add_wep:wep->KeyLength =5\n"));
 609                break;
 610        case 13:
 611                psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
 612                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_add_wep:wep->KeyLength = 13\n"));
 613                break;
 614        default:
 615                psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
 616                RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("MgntActrtw_set_802_11_add_wep:wep->KeyLength!=5 or 13\n"));
 617                break;
 618        }
 619
 620        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
 621                 ("rtw_set_802_11_add_wep:before memcpy, wep->KeyLength = 0x%x wep->KeyIndex = 0x%x  keyid =%x\n",
 622                  wep->KeyLength, wep->KeyIndex, keyid));
 623
 624        memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]), &(wep->KeyMaterial), wep->KeyLength);
 625
 626        psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength;
 627
 628        psecuritypriv->dot11PrivacyKeyIndex = keyid;
 629
 630        RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("rtw_set_802_11_add_wep:security key material : %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
 631                psecuritypriv->dot11DefKey[keyid].skey[0], psecuritypriv->dot11DefKey[keyid].skey[1], psecuritypriv->dot11DefKey[keyid].skey[2],
 632                psecuritypriv->dot11DefKey[keyid].skey[3], psecuritypriv->dot11DefKey[keyid].skey[4], psecuritypriv->dot11DefKey[keyid].skey[5],
 633                psecuritypriv->dot11DefKey[keyid].skey[6], psecuritypriv->dot11DefKey[keyid].skey[7], psecuritypriv->dot11DefKey[keyid].skey[8],
 634                psecuritypriv->dot11DefKey[keyid].skey[9], psecuritypriv->dot11DefKey[keyid].skey[10], psecuritypriv->dot11DefKey[keyid].skey[11],
 635                psecuritypriv->dot11DefKey[keyid].skey[12]));
 636
 637        res = rtw_set_key(padapter, psecuritypriv, keyid, 1, true);
 638
 639        if (res == _FAIL)
 640                ret = false;
 641exit:
 642
 643        return ret;
 644}
 645
 646/*
 647* rtw_get_cur_max_rate -
 648* @adapter: pointer to struct adapter structure
 649*
 650* Return 0 or 100Kbps
 651*/
 652u16 rtw_get_cur_max_rate(struct adapter *adapter)
 653{
 654        int     i = 0;
 655        u16 rate = 0, max_rate = 0;
 656        struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
 657        struct wlan_bssid_ex    *pcur_bss = &pmlmepriv->cur_network.network;
 658        struct sta_info *psta = NULL;
 659        u8 short_GI = 0;
 660        u8 rf_type = 0;
 661
 662        if ((check_fwstate(pmlmepriv, _FW_LINKED) != true)
 663                && (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != true))
 664                return 0;
 665
 666        psta = rtw_get_stainfo(&adapter->stapriv, get_bssid(pmlmepriv));
 667        if (psta == NULL)
 668                return 0;
 669
 670        short_GI = query_ra_short_GI(psta);
 671
 672        if (IsSupportedHT(psta->wireless_mode)) {
 673                rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
 674
 675                max_rate = rtw_mcs_rate(
 676                        rf_type,
 677                        ((psta->bw_mode == CHANNEL_WIDTH_40)?1:0),
 678                        short_GI,
 679                        psta->htpriv.ht_cap.supp_mcs_set
 680                );
 681        } else{
 682                while ((pcur_bss->SupportedRates[i] != 0) && (pcur_bss->SupportedRates[i] != 0xFF)) {
 683                        rate = pcur_bss->SupportedRates[i]&0x7F;
 684                        if (rate > max_rate)
 685                                max_rate = rate;
 686                        i++;
 687                }
 688
 689                max_rate = max_rate*10/2;
 690        }
 691
 692        return max_rate;
 693}
 694