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