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