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