linux/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/******************************************************************************
   3 *
   4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
   5 *
   6 ******************************************************************************/
   7#define  _IOCTL_CFG80211_C_
   8
   9#include <linux/etherdevice.h>
  10#include <drv_types.h>
  11#include <rtw_debug.h>
  12#include <linux/jiffies.h>
  13
  14#include <rtw_wifi_regd.h>
  15
  16#define RTW_MAX_MGMT_TX_CNT (8)
  17
  18#define RTW_SCAN_IE_LEN_MAX      2304
  19#define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 5000 /* ms */
  20#define RTW_MAX_NUM_PMKIDS 4
  21
  22#define RTW_CH_MAX_2G_CHANNEL               14      /* Max channel in 2G band */
  23
  24static const u32 rtw_cipher_suites[] = {
  25        WLAN_CIPHER_SUITE_WEP40,
  26        WLAN_CIPHER_SUITE_WEP104,
  27        WLAN_CIPHER_SUITE_TKIP,
  28        WLAN_CIPHER_SUITE_CCMP,
  29        WLAN_CIPHER_SUITE_AES_CMAC,
  30};
  31
  32#define RATETAB_ENT(_rate, _rateid, _flags) \
  33        {                                                               \
  34                .bitrate        = (_rate),                              \
  35                .hw_value       = (_rateid),                            \
  36                .flags          = (_flags),                             \
  37        }
  38
  39#define CHAN2G(_channel, _freq, _flags) {                       \
  40        .band                   = NL80211_BAND_2GHZ,            \
  41        .center_freq            = (_freq),                      \
  42        .hw_value               = (_channel),                   \
  43        .flags                  = (_flags),                     \
  44        .max_antenna_gain       = 0,                            \
  45        .max_power              = 30,                           \
  46}
  47
  48/* if wowlan is not supported, kernel generate a disconnect at each suspend
  49 * cf: /net/wireless/sysfs.c, so register a stub wowlan.
  50 * Moreover wowlan has to be enabled via a the nl80211_set_wowlan callback.
  51 * (from user space, e.g. iw phy0 wowlan enable)
  52 */
  53static const struct wiphy_wowlan_support wowlan_stub = {
  54        .flags = WIPHY_WOWLAN_ANY,
  55        .n_patterns = 0,
  56        .pattern_max_len = 0,
  57        .pattern_min_len = 0,
  58        .max_pkt_offset = 0,
  59};
  60
  61static struct ieee80211_rate rtw_rates[] = {
  62        RATETAB_ENT(10,  0x1,   0),
  63        RATETAB_ENT(20,  0x2,   0),
  64        RATETAB_ENT(55,  0x4,   0),
  65        RATETAB_ENT(110, 0x8,   0),
  66        RATETAB_ENT(60,  0x10,  0),
  67        RATETAB_ENT(90,  0x20,  0),
  68        RATETAB_ENT(120, 0x40,  0),
  69        RATETAB_ENT(180, 0x80,  0),
  70        RATETAB_ENT(240, 0x100, 0),
  71        RATETAB_ENT(360, 0x200, 0),
  72        RATETAB_ENT(480, 0x400, 0),
  73        RATETAB_ENT(540, 0x800, 0),
  74};
  75
  76#define rtw_a_rates             (rtw_rates + 4)
  77#define RTW_A_RATES_NUM 8
  78#define rtw_g_rates             (rtw_rates + 0)
  79#define RTW_G_RATES_NUM 12
  80
  81#define RTW_2G_CHANNELS_NUM 14
  82#define RTW_5G_CHANNELS_NUM 37
  83
  84static struct ieee80211_channel rtw_2ghz_channels[] = {
  85        CHAN2G(1, 2412, 0),
  86        CHAN2G(2, 2417, 0),
  87        CHAN2G(3, 2422, 0),
  88        CHAN2G(4, 2427, 0),
  89        CHAN2G(5, 2432, 0),
  90        CHAN2G(6, 2437, 0),
  91        CHAN2G(7, 2442, 0),
  92        CHAN2G(8, 2447, 0),
  93        CHAN2G(9, 2452, 0),
  94        CHAN2G(10, 2457, 0),
  95        CHAN2G(11, 2462, 0),
  96        CHAN2G(12, 2467, 0),
  97        CHAN2G(13, 2472, 0),
  98        CHAN2G(14, 2484, 0),
  99};
 100
 101static void rtw_2g_channels_init(struct ieee80211_channel *channels)
 102{
 103        memcpy((void*)channels, (void*)rtw_2ghz_channels,
 104                sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
 105        );
 106}
 107
 108static void rtw_2g_rates_init(struct ieee80211_rate *rates)
 109{
 110        memcpy(rates, rtw_g_rates,
 111                sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM
 112        );
 113}
 114
 115static struct ieee80211_supported_band *rtw_spt_band_alloc(
 116        enum nl80211_band band
 117        )
 118{
 119        struct ieee80211_supported_band *spt_band = NULL;
 120        int n_channels, n_bitrates;
 121
 122        if (band == NL80211_BAND_2GHZ)
 123        {
 124                n_channels = RTW_2G_CHANNELS_NUM;
 125                n_bitrates = RTW_G_RATES_NUM;
 126        }
 127        else
 128        {
 129                goto exit;
 130        }
 131
 132        spt_band = rtw_zmalloc(sizeof(struct ieee80211_supported_band) +
 133                               sizeof(struct ieee80211_channel) * n_channels +
 134                               sizeof(struct ieee80211_rate) * n_bitrates);
 135        if (!spt_band)
 136                goto exit;
 137
 138        spt_band->channels = (struct ieee80211_channel*)(((u8 *)spt_band)+sizeof(struct ieee80211_supported_band));
 139        spt_band->bitrates = (struct ieee80211_rate*)(((u8 *)spt_band->channels)+sizeof(struct ieee80211_channel)*n_channels);
 140        spt_band->band = band;
 141        spt_band->n_channels = n_channels;
 142        spt_band->n_bitrates = n_bitrates;
 143
 144        if (band == NL80211_BAND_2GHZ)
 145        {
 146                rtw_2g_channels_init(spt_band->channels);
 147                rtw_2g_rates_init(spt_band->bitrates);
 148        }
 149
 150        /* spt_band.ht_cap */
 151
 152exit:
 153
 154        return spt_band;
 155}
 156
 157static void rtw_spt_band_free(struct ieee80211_supported_band *spt_band)
 158{
 159        u32 size = 0;
 160
 161        if (!spt_band)
 162                return;
 163
 164        if (spt_band->band == NL80211_BAND_2GHZ)
 165        {
 166                size = sizeof(struct ieee80211_supported_band)
 167                        + sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
 168                        + sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM;
 169        }
 170        kfree((u8 *)spt_band);
 171}
 172
 173static const struct ieee80211_txrx_stypes
 174rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
 175        [NL80211_IFTYPE_ADHOC] = {
 176                .tx = 0xffff,
 177                .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
 178        },
 179        [NL80211_IFTYPE_STATION] = {
 180                .tx = 0xffff,
 181                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
 182                BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
 183        },
 184        [NL80211_IFTYPE_AP] = {
 185                .tx = 0xffff,
 186                .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
 187                BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
 188                BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
 189                BIT(IEEE80211_STYPE_DISASSOC >> 4) |
 190                BIT(IEEE80211_STYPE_AUTH >> 4) |
 191                BIT(IEEE80211_STYPE_DEAUTH >> 4) |
 192                BIT(IEEE80211_STYPE_ACTION >> 4)
 193        },
 194        [NL80211_IFTYPE_AP_VLAN] = {
 195                /* copy AP */
 196                .tx = 0xffff,
 197                .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
 198                BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
 199                BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
 200                BIT(IEEE80211_STYPE_DISASSOC >> 4) |
 201                BIT(IEEE80211_STYPE_AUTH >> 4) |
 202                BIT(IEEE80211_STYPE_DEAUTH >> 4) |
 203                BIT(IEEE80211_STYPE_ACTION >> 4)
 204        },
 205        [NL80211_IFTYPE_P2P_CLIENT] = {
 206                .tx = 0xffff,
 207                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
 208                BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
 209        },
 210        [NL80211_IFTYPE_P2P_GO] = {
 211                .tx = 0xffff,
 212                .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
 213                BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
 214                BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
 215                BIT(IEEE80211_STYPE_DISASSOC >> 4) |
 216                BIT(IEEE80211_STYPE_AUTH >> 4) |
 217                BIT(IEEE80211_STYPE_DEAUTH >> 4) |
 218                BIT(IEEE80211_STYPE_ACTION >> 4)
 219        },
 220};
 221
 222static int rtw_ieee80211_channel_to_frequency(int chan, int band)
 223{
 224        /* see 802.11 17.3.8.3.2 and Annex J
 225        * there are overlapping channel numbers in 5GHz and 2GHz bands */
 226        if (band == NL80211_BAND_2GHZ) {
 227                if (chan == 14)
 228                        return 2484;
 229             else if (chan < 14)
 230                        return 2407 + chan * 5;
 231        }
 232
 233        return 0; /* not supported */
 234}
 235
 236#define MAX_BSSINFO_LEN 1000
 237struct cfg80211_bss *rtw_cfg80211_inform_bss(struct adapter *padapter, struct wlan_network *pnetwork)
 238{
 239        struct ieee80211_channel *notify_channel;
 240        struct cfg80211_bss *bss = NULL;
 241        /* struct ieee80211_supported_band *band; */
 242        u16 channel;
 243        u32 freq;
 244        u64 notify_timestamp;
 245        u16 notify_capability;
 246        u16 notify_interval;
 247        u8 *notify_ie;
 248        size_t notify_ielen;
 249        s32 notify_signal;
 250        u8 *buf = NULL, *pbuf;
 251        size_t len, bssinf_len = 0;
 252        struct ieee80211_hdr *pwlanhdr;
 253        __le16 *fctrl;
 254        u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 255
 256        struct wireless_dev *wdev = padapter->rtw_wdev;
 257        struct wiphy *wiphy = wdev->wiphy;
 258        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
 259
 260
 261        /* DBG_8192C("%s\n", __func__); */
 262
 263        bssinf_len = pnetwork->network.IELength+sizeof (struct ieee80211_hdr_3addr);
 264        if (bssinf_len > MAX_BSSINFO_LEN) {
 265                DBG_871X("%s IE Length too long > %d byte\n", __func__, MAX_BSSINFO_LEN);
 266                goto exit;
 267        }
 268
 269        {
 270                u16 wapi_len = 0;
 271
 272                if (rtw_get_wapi_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &wapi_len)>0)
 273                {
 274                        if (wapi_len > 0)
 275                        {
 276                                DBG_871X("%s, no support wapi!\n", __func__);
 277                                goto exit;
 278                        }
 279                }
 280        }
 281
 282        /* To reduce PBC Overlap rate */
 283        /* spin_lock_bh(&pwdev_priv->scan_req_lock); */
 284        if (adapter_wdev_data(padapter)->scan_request != NULL)
 285        {
 286                u8 *psr = NULL, sr = 0;
 287                struct ndis_802_11_ssid *pssid = &pnetwork->network.Ssid;
 288                struct cfg80211_scan_request *request = adapter_wdev_data(padapter)->scan_request;
 289                struct cfg80211_ssid *ssids = request->ssids;
 290                u32 wpsielen = 0;
 291                u8 *wpsie = NULL;
 292
 293                wpsie = rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
 294
 295                if (wpsie && wpsielen>0)
 296                        psr = rtw_get_wps_attr_content(wpsie,  wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
 297
 298                if (sr != 0)
 299                {
 300                        if (request->n_ssids == 1 && request->n_channels == 1) /*  it means under processing WPS */
 301                        {
 302                                DBG_8192C("ssid =%s, len =%d\n", pssid->Ssid, pssid->SsidLength);
 303
 304                                if (ssids[0].ssid_len == 0) {
 305                                }
 306                                else if (pssid->SsidLength == ssids[0].ssid_len &&
 307                                        !memcmp(pssid->Ssid, ssids[0].ssid, ssids[0].ssid_len))
 308                                {
 309                                        DBG_871X("%s, got sr and ssid match!\n", __func__);
 310                                }
 311                                else
 312                                {
 313                                        if (psr != NULL)
 314                                                *psr = 0; /* clear sr */
 315                                }
 316                        }
 317                }
 318        }
 319        /* spin_unlock_bh(&pwdev_priv->scan_req_lock); */
 320
 321
 322        channel = pnetwork->network.Configuration.DSConfig;
 323        freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ);
 324
 325        notify_channel = ieee80211_get_channel(wiphy, freq);
 326
 327        notify_timestamp = ktime_to_us(ktime_get_boottime());
 328
 329        notify_interval = le16_to_cpu(*(__le16 *)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs));
 330        notify_capability = le16_to_cpu(*(__le16 *)rtw_get_capability_from_ie(pnetwork->network.IEs));
 331
 332        notify_ie = pnetwork->network.IEs+_FIXED_IE_LENGTH_;
 333        notify_ielen = pnetwork->network.IELength-_FIXED_IE_LENGTH_;
 334
 335        /* We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm) */
 336        if (check_fwstate(pmlmepriv, _FW_LINKED) == true &&
 337                is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
 338                notify_signal = 100*translate_percentage_to_dbm(padapter->recvpriv.signal_strength);/* dbm */
 339        } else {
 340                notify_signal = 100*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);/* dbm */
 341        }
 342
 343        buf = kzalloc(MAX_BSSINFO_LEN, GFP_ATOMIC);
 344        if (!buf)
 345                goto exit;
 346        pbuf = buf;
 347
 348        pwlanhdr = (struct ieee80211_hdr *)pbuf;
 349        fctrl = &(pwlanhdr->frame_control);
 350        *(fctrl) = 0;
 351
 352        SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
 353        /* pmlmeext->mgnt_seq++; */
 354
 355        if (pnetwork->network.Reserved[0] == 1) { /*  WIFI_BEACON */
 356                memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
 357                SetFrameSubType(pbuf, WIFI_BEACON);
 358        } else {
 359                memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
 360                SetFrameSubType(pbuf, WIFI_PROBERSP);
 361        }
 362
 363        memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN);
 364        memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN);
 365
 366
 367        pbuf += sizeof(struct ieee80211_hdr_3addr);
 368        len = sizeof (struct ieee80211_hdr_3addr);
 369
 370        memcpy(pbuf, pnetwork->network.IEs, pnetwork->network.IELength);
 371        len += pnetwork->network.IELength;
 372
 373        *((__le64*)pbuf) = cpu_to_le64(notify_timestamp);
 374
 375        bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)buf,
 376                len, notify_signal, GFP_ATOMIC);
 377
 378        if (unlikely(!bss)) {
 379                DBG_8192C(FUNC_ADPT_FMT" bss NULL\n", FUNC_ADPT_ARG(padapter));
 380                goto exit;
 381        }
 382
 383        cfg80211_put_bss(wiphy, bss);
 384        kfree(buf);
 385
 386exit:
 387        return bss;
 388
 389}
 390
 391/*
 392        Check the given bss is valid by kernel API cfg80211_get_bss()
 393        @padapter : the given adapter
 394
 395        return true if bss is valid,  false for not found.
 396*/
 397int rtw_cfg80211_check_bss(struct adapter *padapter)
 398{
 399        struct wlan_bssid_ex  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
 400        struct cfg80211_bss *bss = NULL;
 401        struct ieee80211_channel *notify_channel = NULL;
 402        u32 freq;
 403
 404        if (!(pnetwork) || !(padapter->rtw_wdev))
 405                return false;
 406
 407        freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, NL80211_BAND_2GHZ);
 408
 409        notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq);
 410        bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel,
 411                        pnetwork->MacAddress, pnetwork->Ssid.Ssid,
 412                        pnetwork->Ssid.SsidLength,
 413                        WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
 414
 415        cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
 416
 417        return  (bss!= NULL);
 418}
 419
 420void rtw_cfg80211_ibss_indicate_connect(struct adapter *padapter)
 421{
 422        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 423        struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
 424        struct wireless_dev *pwdev = padapter->rtw_wdev;
 425        struct wiphy *wiphy = pwdev->wiphy;
 426        int freq = (int)cur_network->network.Configuration.DSConfig;
 427        struct ieee80211_channel *chan;
 428
 429        DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
 430        if (pwdev->iftype != NL80211_IFTYPE_ADHOC)
 431        {
 432                return;
 433        }
 434
 435        if (!rtw_cfg80211_check_bss(padapter)) {
 436                struct wlan_bssid_ex  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
 437                struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
 438
 439                if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ==true)
 440                {
 441
 442                        memcpy(&cur_network->network, pnetwork, sizeof(struct wlan_bssid_ex));
 443                        if (!rtw_cfg80211_inform_bss(padapter, cur_network))
 444                                DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
 445                        else
 446                                DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
 447                }
 448                else
 449                {
 450                        if (scanned == NULL) {
 451                                rtw_warn_on(1);
 452                                return;
 453                        }
 454                        if (!memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(struct ndis_802_11_ssid))
 455                                && !memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS))
 456                        ) {
 457                                if (!rtw_cfg80211_inform_bss(padapter, scanned)) {
 458                                        DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
 459                                } else {
 460                                        /* DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter)); */
 461                                }
 462                        } else {
 463                                DBG_871X("scanned & pnetwork compare fail\n");
 464                                rtw_warn_on(1);
 465                        }
 466                }
 467
 468                if (!rtw_cfg80211_check_bss(padapter))
 469                        DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
 470        }
 471        /* notify cfg80211 that device joined an IBSS */
 472        chan = ieee80211_get_channel(wiphy, freq);
 473        cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, chan, GFP_ATOMIC);
 474}
 475
 476void rtw_cfg80211_indicate_connect(struct adapter *padapter)
 477{
 478        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 479        struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
 480        struct wireless_dev *pwdev = padapter->rtw_wdev;
 481
 482        DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
 483        if (pwdev->iftype != NL80211_IFTYPE_STATION
 484                && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
 485        ) {
 486                return;
 487        }
 488
 489        if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
 490                return;
 491
 492        {
 493                struct wlan_bssid_ex  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
 494                struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
 495
 496                /* DBG_871X(FUNC_ADPT_FMT" BSS not found\n", FUNC_ADPT_ARG(padapter)); */
 497
 498                if (scanned == NULL) {
 499                        rtw_warn_on(1);
 500                        goto check_bss;
 501                }
 502
 503                if (!memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS))
 504                        && !memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(struct ndis_802_11_ssid))
 505                ) {
 506                        if (!rtw_cfg80211_inform_bss(padapter, scanned)) {
 507                                DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
 508                        } else {
 509                                /* DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter)); */
 510                        }
 511                } else {
 512                        DBG_871X("scanned: %s("MAC_FMT"), cur: %s("MAC_FMT")\n",
 513                                scanned->network.Ssid.Ssid, MAC_ARG(scanned->network.MacAddress),
 514                                pnetwork->Ssid.Ssid, MAC_ARG(pnetwork->MacAddress)
 515                        );
 516                        rtw_warn_on(1);
 517                }
 518        }
 519
 520check_bss:
 521        if (!rtw_cfg80211_check_bss(padapter))
 522                DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
 523
 524        if (rtw_to_roam(padapter) > 0) {
 525                struct wiphy *wiphy = pwdev->wiphy;
 526                struct ieee80211_channel *notify_channel;
 527                u32 freq;
 528                u16 channel = cur_network->network.Configuration.DSConfig;
 529                struct cfg80211_roam_info roam_info = {};
 530
 531                freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ);
 532
 533                notify_channel = ieee80211_get_channel(wiphy, freq);
 534
 535                DBG_871X(FUNC_ADPT_FMT" call cfg80211_roamed\n", FUNC_ADPT_ARG(padapter));
 536                roam_info.channel = notify_channel;
 537                roam_info.bssid = cur_network->network.MacAddress;
 538                roam_info.req_ie =
 539                        pmlmepriv->assoc_req+sizeof(struct ieee80211_hdr_3addr)+2;
 540                roam_info.req_ie_len =
 541                        pmlmepriv->assoc_req_len-sizeof(struct ieee80211_hdr_3addr)-2;
 542                roam_info.resp_ie =
 543                        pmlmepriv->assoc_rsp+sizeof(struct ieee80211_hdr_3addr)+6;
 544                roam_info.resp_ie_len =
 545                        pmlmepriv->assoc_rsp_len-sizeof(struct ieee80211_hdr_3addr)-6;
 546                cfg80211_roamed(padapter->pnetdev, &roam_info, GFP_ATOMIC);
 547        }
 548        else
 549        {
 550                cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress
 551                        , pmlmepriv->assoc_req+sizeof(struct ieee80211_hdr_3addr)+2
 552                        , pmlmepriv->assoc_req_len-sizeof(struct ieee80211_hdr_3addr)-2
 553                        , pmlmepriv->assoc_rsp+sizeof(struct ieee80211_hdr_3addr)+6
 554                        , pmlmepriv->assoc_rsp_len-sizeof(struct ieee80211_hdr_3addr)-6
 555                        , WLAN_STATUS_SUCCESS, GFP_ATOMIC);
 556        }
 557}
 558
 559void rtw_cfg80211_indicate_disconnect(struct adapter *padapter)
 560{
 561        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 562        struct wireless_dev *pwdev = padapter->rtw_wdev;
 563
 564        DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
 565
 566        if (pwdev->iftype != NL80211_IFTYPE_STATION
 567                && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
 568        ) {
 569                return;
 570        }
 571
 572        if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
 573                return;
 574
 575        if (!padapter->mlmepriv.not_indic_disco) {
 576                if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
 577                        cfg80211_disconnected(padapter->pnetdev, 0,
 578                                              NULL, 0, true, GFP_ATOMIC);
 579                } else {
 580                        cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
 581                                WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
 582                }
 583        }
 584}
 585
 586
 587static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
 588{
 589        int ret = 0;
 590        u32 wep_key_idx, wep_key_len;
 591        struct sta_info *psta = NULL, *pbcmc_sta = NULL;
 592        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 593        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 594        struct security_priv* psecuritypriv =&(padapter->securitypriv);
 595        struct sta_priv *pstapriv = &padapter->stapriv;
 596
 597        DBG_8192C("%s\n", __func__);
 598
 599        param->u.crypt.err = 0;
 600        param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
 601
 602        if (param_len !=  sizeof(struct ieee_param) + param->u.crypt.key_len)
 603        {
 604                ret =  -EINVAL;
 605                goto exit;
 606        }
 607
 608        if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
 609            param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
 610            param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
 611        {
 612                if (param->u.crypt.idx >= WEP_KEYS)
 613                {
 614                        ret = -EINVAL;
 615                        goto exit;
 616                }
 617        }
 618        else
 619        {
 620                psta = rtw_get_stainfo(pstapriv, param->sta_addr);
 621                if (!psta)
 622                {
 623                        /* ret = -EINVAL; */
 624                        DBG_8192C("rtw_set_encryption(), sta has already been removed or never been added\n");
 625                        goto exit;
 626                }
 627        }
 628
 629        if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL))
 630        {
 631                /* todo:clear default encryption keys */
 632
 633                DBG_8192C("clear default encryption keys, keyid =%d\n", param->u.crypt.idx);
 634
 635                goto exit;
 636        }
 637
 638
 639        if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL))
 640        {
 641                DBG_8192C("r871x_set_encryption, crypt.alg = WEP\n");
 642
 643                wep_key_idx = param->u.crypt.idx;
 644                wep_key_len = param->u.crypt.key_len;
 645
 646                DBG_8192C("r871x_set_encryption, wep_key_idx =%d, len =%d\n", wep_key_idx, wep_key_len);
 647
 648                if ((wep_key_idx >= WEP_KEYS) || (wep_key_len<= 0))
 649                {
 650                        ret = -EINVAL;
 651                        goto exit;
 652                }
 653
 654                if (wep_key_len > 0)
 655                {
 656                        wep_key_len = wep_key_len <= 5 ? 5 : 13;
 657                }
 658
 659                if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
 660                {
 661                        /* wep default key has not been set, so use this key index as default key. */
 662
 663                        psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
 664                        psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
 665                        psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
 666                        psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
 667
 668                        if (wep_key_len == 13)
 669                        {
 670                                psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
 671                                psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
 672                        }
 673
 674                        psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
 675                }
 676
 677                memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
 678
 679                psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
 680
 681                rtw_ap_set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx, 1);
 682
 683                goto exit;
 684
 685        }
 686
 687
 688        if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) /* group key */ 
 689        {
 690                if (param->u.crypt.set_tx == 0) /* group key */
 691                {
 692                        if (strcmp(param->u.crypt.alg, "WEP") == 0)
 693                        {
 694                                DBG_8192C("%s, set group_key, WEP\n", __func__);
 695
 696                                memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
 697
 698                                psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
 699                                if (param->u.crypt.key_len == 13)
 700                                {
 701                                                psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
 702                                }
 703
 704                        }
 705                        else if (strcmp(param->u.crypt.alg, "TKIP") == 0)
 706                        {
 707                                DBG_8192C("%s, set group_key, TKIP\n", __func__);
 708
 709                                psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
 710
 711                                memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
 712
 713                                /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
 714                                /* set mic key */
 715                                memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
 716                                memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
 717
 718                                psecuritypriv->busetkipkey = true;
 719
 720                        }
 721                        else if (strcmp(param->u.crypt.alg, "CCMP") == 0)
 722                        {
 723                                DBG_8192C("%s, set group_key, CCMP\n", __func__);
 724
 725                                psecuritypriv->dot118021XGrpPrivacy = _AES_;
 726
 727                                memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
 728                        }
 729                        else
 730                        {
 731                                DBG_8192C("%s, set group_key, none\n", __func__);
 732
 733                                psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
 734                        }
 735
 736                        psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
 737
 738                        psecuritypriv->binstallGrpkey = true;
 739
 740                        psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/*  */
 741
 742                        rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
 743
 744                        pbcmc_sta =rtw_get_bcmc_stainfo(padapter);
 745                        if (pbcmc_sta)
 746                        {
 747                                pbcmc_sta->ieee8021x_blocked = false;
 748                                pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
 749                        }
 750
 751                }
 752
 753                goto exit;
 754
 755        }
 756
 757        if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) /*  psk/802_1x */
 758        {
 759                if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
 760                {
 761                        if (param->u.crypt.set_tx == 1) /* pairwise key */
 762                        {
 763                                memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
 764
 765                                if (strcmp(param->u.crypt.alg, "WEP") == 0)
 766                                {
 767                                        DBG_8192C("%s, set pairwise key, WEP\n", __func__);
 768
 769                                        psta->dot118021XPrivacy = _WEP40_;
 770                                        if (param->u.crypt.key_len == 13)
 771                                        {
 772                                                psta->dot118021XPrivacy = _WEP104_;
 773                                        }
 774                                }
 775                                else if (strcmp(param->u.crypt.alg, "TKIP") == 0)
 776                                {
 777                                        DBG_8192C("%s, set pairwise key, TKIP\n", __func__);
 778
 779                                        psta->dot118021XPrivacy = _TKIP_;
 780
 781                                        /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
 782                                        /* set mic key */
 783                                        memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
 784                                        memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
 785
 786                                        psecuritypriv->busetkipkey = true;
 787
 788                                }
 789                                else if (strcmp(param->u.crypt.alg, "CCMP") == 0)
 790                                {
 791
 792                                        DBG_8192C("%s, set pairwise key, CCMP\n", __func__);
 793
 794                                        psta->dot118021XPrivacy = _AES_;
 795                                }
 796                                else
 797                                {
 798                                        DBG_8192C("%s, set pairwise key, none\n", __func__);
 799
 800                                        psta->dot118021XPrivacy = _NO_PRIVACY_;
 801                                }
 802
 803                                rtw_ap_set_pairwise_key(padapter, psta);
 804
 805                                psta->ieee8021x_blocked = false;
 806
 807                                psta->bpairwise_key_installed = true;
 808
 809                        }
 810                        else/* group key??? */
 811                        {
 812                                if (strcmp(param->u.crypt.alg, "WEP") == 0)
 813                                {
 814                                        memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
 815
 816                                        psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
 817                                        if (param->u.crypt.key_len == 13)
 818                                        {
 819                                                psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
 820                                        }
 821                                }
 822                                else if (strcmp(param->u.crypt.alg, "TKIP") == 0)
 823                                {
 824                                        psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
 825
 826                                        memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
 827
 828                                        /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
 829                                        /* set mic key */
 830                                        memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
 831                                        memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
 832
 833                                        psecuritypriv->busetkipkey = true;
 834
 835                                }
 836                                else if (strcmp(param->u.crypt.alg, "CCMP") == 0)
 837                                {
 838                                        psecuritypriv->dot118021XGrpPrivacy = _AES_;
 839
 840                                        memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
 841                                }
 842                                else
 843                                {
 844                                        psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
 845                                }
 846
 847                                psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
 848
 849                                psecuritypriv->binstallGrpkey = true;
 850
 851                                psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/*  */
 852
 853                                rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
 854
 855                                pbcmc_sta =rtw_get_bcmc_stainfo(padapter);
 856                                if (pbcmc_sta)
 857                                {
 858                                        pbcmc_sta->ieee8021x_blocked = false;
 859                                        pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;/* rx will use bmc_sta's dot118021XPrivacy */
 860                                }
 861
 862                        }
 863
 864                }
 865
 866        }
 867
 868exit:
 869
 870        return ret;
 871
 872}
 873
 874static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
 875{
 876        int ret = 0;
 877        u32 wep_key_idx, wep_key_len;
 878        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 879        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 880        struct security_priv *psecuritypriv = &padapter->securitypriv;
 881
 882        DBG_8192C("%s\n", __func__);
 883
 884        param->u.crypt.err = 0;
 885        param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
 886
 887        if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
 888        {
 889                ret =  -EINVAL;
 890                goto exit;
 891        }
 892
 893        if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
 894            param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
 895            param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
 896        {
 897                if (param->u.crypt.idx >= WEP_KEYS
 898                        || param->u.crypt.idx >= BIP_MAX_KEYID
 899                )
 900                {
 901                        ret = -EINVAL;
 902                        goto exit;
 903                }
 904        } else {
 905                {
 906                ret = -EINVAL;
 907                goto exit;
 908        }
 909        }
 910
 911        if (strcmp(param->u.crypt.alg, "WEP") == 0)
 912        {
 913                RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("wpa_set_encryption, crypt.alg = WEP\n"));
 914                DBG_8192C("wpa_set_encryption, crypt.alg = WEP\n");
 915
 916                wep_key_idx = param->u.crypt.idx;
 917                wep_key_len = param->u.crypt.key_len;
 918
 919                if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0))
 920                {
 921                        ret = -EINVAL;
 922                        goto exit;
 923                }
 924
 925                if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
 926                {
 927                        /* wep default key has not been set, so use this key index as default key. */
 928
 929                        wep_key_len = wep_key_len <= 5 ? 5 : 13;
 930
 931                        psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
 932                        psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
 933                        psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
 934
 935                        if (wep_key_len == 13)
 936                        {
 937                                psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
 938                                psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
 939                        }
 940
 941                        psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
 942                }
 943
 944                memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
 945
 946                psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
 947
 948                rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, true);
 949
 950                goto exit;
 951        }
 952
 953        if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) /*  802_1x */
 954        {
 955                struct sta_info * psta,*pbcmc_sta;
 956                struct sta_priv * pstapriv = &padapter->stapriv;
 957
 958                /* DBG_8192C("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X\n", __func__); */
 959
 960                if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == true) /* sta mode */
 961                {
 962                        psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
 963                        if (psta == NULL) {
 964                                /* DEBUG_ERR(("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
 965                                DBG_8192C("%s, : Obtain Sta_info fail\n", __func__);
 966                        }
 967                        else
 968                        {
 969                                /* Jeff: don't disable ieee8021x_blocked while clearing key */
 970                                if (strcmp(param->u.crypt.alg, "none") != 0)
 971                                        psta->ieee8021x_blocked = false;
 972
 973
 974                                if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
 975                                                (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
 976                                {
 977                                        psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
 978                                }
 979
 980                                if (param->u.crypt.set_tx == 1)/* pairwise key */
 981                                {
 982
 983                                        DBG_8192C("%s, : param->u.crypt.set_tx == 1\n", __func__);
 984
 985                                        memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
 986
 987                                        if (strcmp(param->u.crypt.alg, "TKIP") == 0)/* set mic key */
 988                                        {
 989                                                /* DEBUG_ERR(("\nset key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */
 990                                                memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
 991                                                memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
 992
 993                                                padapter->securitypriv.busetkipkey =false;
 994                                                /* _set_timer(&padapter->securitypriv.tkip_timer, 50); */
 995                                        }
 996
 997                                        /* DEBUG_ERR((" param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */
 998                                        DBG_871X(" ~~~~set sta key:unicastkey\n");
 999
1000                                        rtw_setstakey_cmd(padapter, psta, true, true);
1001                                }
1002                                else/* group key */
1003                                {
1004                                        if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
1005                                        {
1006                                                memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1007                                                memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]), 8);
1008                                                memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]), 8);
1009                                                padapter->securitypriv.binstallGrpkey = true;
1010                                                /* DEBUG_ERR((" param->u.crypt.key_len =%d\n", param->u.crypt.key_len)); */
1011                                                DBG_871X(" ~~~~set sta key:groupkey\n");
1012
1013                                                padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
1014                                                rtw_set_key(padapter,&padapter->securitypriv, param->u.crypt.idx, 1, true);
1015                                        }
1016                                        else if (strcmp(param->u.crypt.alg, "BIP") == 0)
1017                                        {
1018                                                /* DBG_871X("BIP key_len =%d , index =%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx); */
1019                                                /* save the IGTK key, length 16 bytes */
1020                                                memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1021                                                /*DBG_871X("IGTK key below:\n");
1022                                                for (no = 0;no<16;no++)
1023                                                        printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
1024                                                DBG_871X("\n");*/
1025                                                padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
1026                                                padapter->securitypriv.binstallBIPkey = true;
1027                                                DBG_871X(" ~~~~set sta key:IGKT\n");
1028                                        }
1029                                }
1030                        }
1031
1032                        pbcmc_sta =rtw_get_bcmc_stainfo(padapter);
1033                        if (pbcmc_sta == NULL)
1034                        {
1035                                /* DEBUG_ERR(("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
1036                        }
1037                        else
1038                        {
1039                                /* Jeff: don't disable ieee8021x_blocked while clearing key */
1040                                if (strcmp(param->u.crypt.alg, "none") != 0)
1041                                        pbcmc_sta->ieee8021x_blocked = false;
1042
1043                                if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
1044                                                (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
1045                                {
1046                                        pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1047                                }
1048                        }
1049                }
1050                else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) /* adhoc mode */
1051                {
1052                }
1053        }
1054
1055exit:
1056
1057        DBG_8192C("%s, ret =%d\n", __func__, ret);
1058
1059        return ret;
1060}
1061
1062static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
1063                                u8 key_index, bool pairwise, const u8 *mac_addr,
1064                                struct key_params *params)
1065{
1066        char *alg_name;
1067        u32 param_len;
1068        struct ieee_param *param = NULL;
1069        int ret = 0;
1070        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
1071        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1072
1073        DBG_871X(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr);
1074        DBG_871X("cipher = 0x%x\n", params->cipher);
1075        DBG_871X("key_len = 0x%x\n", params->key_len);
1076        DBG_871X("seq_len = 0x%x\n", params->seq_len);
1077        DBG_871X("key_index =%d\n", key_index);
1078        DBG_871X("pairwise =%d\n", pairwise);
1079
1080        param_len = sizeof(struct ieee_param) + params->key_len;
1081        param = rtw_malloc(param_len);
1082        if (param == NULL)
1083                return -1;
1084
1085        memset(param, 0, param_len);
1086
1087        param->cmd = IEEE_CMD_SET_ENCRYPTION;
1088        memset(param->sta_addr, 0xff, ETH_ALEN);
1089
1090        switch (params->cipher) {
1091        case IW_AUTH_CIPHER_NONE:
1092                /* todo: remove key */
1093                /* remove = 1; */
1094                alg_name = "none";
1095                break;
1096        case WLAN_CIPHER_SUITE_WEP40:
1097        case WLAN_CIPHER_SUITE_WEP104:
1098                alg_name = "WEP";
1099                break;
1100        case WLAN_CIPHER_SUITE_TKIP:
1101                alg_name = "TKIP";
1102                break;
1103        case WLAN_CIPHER_SUITE_CCMP:
1104                alg_name = "CCMP";
1105                break;
1106        case WLAN_CIPHER_SUITE_AES_CMAC:
1107                alg_name = "BIP";
1108                break;
1109        default:
1110                ret = -ENOTSUPP;
1111                goto addkey_end;
1112        }
1113
1114        strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1115
1116
1117        if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1118        {
1119                param->u.crypt.set_tx = 0; /* for wpa/wpa2 group key */
1120        } else {
1121                param->u.crypt.set_tx = 1; /* for wpa/wpa2 pairwise key */
1122        }
1123
1124        param->u.crypt.idx = key_index;
1125
1126        if (params->seq_len && params->seq)
1127        {
1128                memcpy(param->u.crypt.seq, (u8 *)params->seq, params->seq_len);
1129        }
1130
1131        if (params->key_len && params->key)
1132        {
1133                param->u.crypt.key_len = params->key_len;
1134                memcpy(param->u.crypt.key, (u8 *)params->key, params->key_len);
1135        }
1136
1137        if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
1138        {
1139                ret =  rtw_cfg80211_set_encryption(ndev, param, param_len);
1140        }
1141        else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
1142        {
1143                if (mac_addr)
1144                        memcpy(param->sta_addr, (void*)mac_addr, ETH_ALEN);
1145
1146                ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
1147        }
1148        else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true
1149                || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)
1150        {
1151                /* DBG_8192C("@@@@@@@@@@ fw_state = 0x%x, iftype =%d\n", pmlmepriv->fw_state, rtw_wdev->iftype); */
1152                ret =  rtw_cfg80211_set_encryption(ndev, param, param_len);
1153        }
1154        else
1155        {
1156                DBG_8192C("error!\n");
1157
1158        }
1159
1160addkey_end:
1161        kfree((u8 *)param);
1162
1163        return ret;
1164
1165}
1166
1167static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
1168                                u8 key_index, bool pairwise, const u8 *mac_addr,
1169                                void *cookie,
1170                                void (*callback)(void *cookie,
1171                                                 struct key_params*))
1172{
1173        DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
1174        return 0;
1175}
1176
1177static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
1178                                u8 key_index, bool pairwise, const u8 *mac_addr)
1179{
1180        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
1181        struct security_priv *psecuritypriv = &padapter->securitypriv;
1182
1183        DBG_871X(FUNC_NDEV_FMT" key_index =%d\n", FUNC_NDEV_ARG(ndev), key_index);
1184
1185        if (key_index == psecuritypriv->dot11PrivacyKeyIndex)
1186        {
1187                /* clear the flag of wep default key set. */
1188                psecuritypriv->bWepDefaultKeyIdxSet = 0;
1189        }
1190
1191        return 0;
1192}
1193
1194static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
1195        struct net_device *ndev, u8 key_index
1196        , bool unicast, bool multicast
1197        )
1198{
1199        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
1200        struct security_priv *psecuritypriv = &padapter->securitypriv;
1201
1202        DBG_871X(FUNC_NDEV_FMT" key_index =%d, unicast =%d, multicast =%d\n",
1203                 FUNC_NDEV_ARG(ndev), key_index, unicast, multicast);
1204
1205        if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) /* set wep default key */
1206        {
1207                psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1208
1209                psecuritypriv->dot11PrivacyKeyIndex = key_index;
1210
1211                psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1212                psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1213                if (psecuritypriv->dot11DefKeylen[key_index] == 13)
1214                {
1215                        psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1216                        psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1217                }
1218
1219                psecuritypriv->bWepDefaultKeyIdxSet = 1; /* set the flag to represent that wep default key has been set */
1220        }
1221
1222        return 0;
1223
1224}
1225
1226static int cfg80211_rtw_get_station(struct wiphy *wiphy,
1227                                    struct net_device *ndev,
1228                                const u8 *mac,
1229                                struct station_info *sinfo)
1230{
1231        int ret = 0;
1232        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
1233        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1234        struct sta_info *psta = NULL;
1235        struct sta_priv *pstapriv = &padapter->stapriv;
1236
1237        sinfo->filled = 0;
1238
1239        if (!mac) {
1240                DBG_871X(FUNC_NDEV_FMT" mac ==%p\n", FUNC_NDEV_ARG(ndev), mac);
1241                ret = -ENOENT;
1242                goto exit;
1243        }
1244
1245        psta = rtw_get_stainfo(pstapriv, (u8 *)mac);
1246        if (psta == NULL) {
1247                DBG_8192C("%s, sta_info is null\n", __func__);
1248                ret = -ENOENT;
1249                goto exit;
1250        }
1251
1252#ifdef DEBUG_CFG80211
1253        DBG_871X(FUNC_NDEV_FMT" mac ="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
1254#endif
1255
1256        /* for infra./P2PClient mode */
1257        if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
1258                && check_fwstate(pmlmepriv, _FW_LINKED)
1259        )
1260        {
1261                struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
1262
1263                if (memcmp((u8 *)mac, cur_network->network.MacAddress, ETH_ALEN)) {
1264                        DBG_871X("%s, mismatch bssid ="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress));
1265                        ret = -ENOENT;
1266                        goto exit;
1267                }
1268
1269                sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
1270                sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
1271
1272                sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
1273                sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
1274
1275                sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);
1276                sinfo->rx_packets = sta_rx_data_pkts(psta);
1277
1278                sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
1279                sinfo->tx_packets = psta->sta_stats.tx_pkts;
1280
1281        }
1282
1283        /* for Ad-Hoc/AP mode */
1284        if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
1285                        ||check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
1286                        ||check_fwstate(pmlmepriv, WIFI_AP_STATE))
1287                && check_fwstate(pmlmepriv, _FW_LINKED)
1288        )
1289        {
1290                /* TODO: should acquire station info... */
1291        }
1292
1293exit:
1294        return ret;
1295}
1296
1297extern int netdev_open(struct net_device *pnetdev);
1298
1299static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
1300                                     struct net_device *ndev,
1301                                     enum nl80211_iftype type,
1302                                     struct vif_params *params)
1303{
1304        enum nl80211_iftype old_type;
1305        enum NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
1306        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
1307        struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
1308        struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1309        int ret = 0;
1310        u8 change = false;
1311
1312        DBG_871X(FUNC_NDEV_FMT" type =%d\n", FUNC_NDEV_ARG(ndev), type);
1313
1314        if (adapter_to_dvobj(padapter)->processing_dev_remove == true)
1315        {
1316                ret = -EPERM;
1317                goto exit;
1318        }
1319
1320        {
1321                DBG_871X(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev));
1322                if (netdev_open(ndev) != 0) {
1323                        DBG_871X(FUNC_NDEV_FMT" call netdev_open fail\n", FUNC_NDEV_ARG(ndev));
1324                        ret = -EPERM;
1325                        goto exit;
1326                }
1327        }
1328
1329        if (_FAIL == rtw_pwr_wakeup(padapter)) {
1330                DBG_871X(FUNC_NDEV_FMT" call rtw_pwr_wakeup fail\n", FUNC_NDEV_ARG(ndev));
1331                ret = -EPERM;
1332                goto exit;
1333        }
1334
1335        old_type = rtw_wdev->iftype;
1336        DBG_871X(FUNC_NDEV_FMT" old_iftype =%d, new_iftype =%d\n",
1337                FUNC_NDEV_ARG(ndev), old_type, type);
1338
1339        if (old_type != type)
1340        {
1341                change = true;
1342                pmlmeext->action_public_rxseq = 0xffff;
1343                pmlmeext->action_public_dialog_token = 0xff;
1344        }
1345
1346        switch (type) {
1347        case NL80211_IFTYPE_ADHOC:
1348                networkType = Ndis802_11IBSS;
1349                break;
1350        case NL80211_IFTYPE_STATION:
1351                networkType = Ndis802_11Infrastructure;
1352                break;
1353        case NL80211_IFTYPE_AP:
1354                networkType = Ndis802_11APMode;
1355                break;
1356        default:
1357                ret = -EOPNOTSUPP;
1358                goto exit;
1359        }
1360
1361        rtw_wdev->iftype = type;
1362
1363        if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==false)
1364        {
1365                rtw_wdev->iftype = old_type;
1366                ret = -EPERM;
1367                goto exit;
1368        }
1369
1370        rtw_setopmode_cmd(padapter, networkType, true);
1371
1372exit:
1373
1374        DBG_871X(FUNC_NDEV_FMT" ret:%d\n", FUNC_NDEV_ARG(ndev), ret);
1375        return ret;
1376}
1377
1378void rtw_cfg80211_indicate_scan_done(struct adapter *adapter, bool aborted)
1379{
1380        struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
1381        struct cfg80211_scan_info info = {
1382                .aborted = aborted
1383        };
1384
1385        spin_lock_bh(&pwdev_priv->scan_req_lock);
1386        if (pwdev_priv->scan_request != NULL) {
1387                #ifdef DEBUG_CFG80211
1388                DBG_871X("%s with scan req\n", __func__);
1389                #endif
1390
1391                /* avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); */
1392                if (pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy)
1393                {
1394                        DBG_8192C("error wiphy compare\n");
1395                }
1396                else
1397                {
1398                        cfg80211_scan_done(pwdev_priv->scan_request, &info);
1399                }
1400
1401                pwdev_priv->scan_request = NULL;
1402        } else {
1403                #ifdef DEBUG_CFG80211
1404                DBG_871X("%s without scan req\n", __func__);
1405                #endif
1406        }
1407        spin_unlock_bh(&pwdev_priv->scan_req_lock);
1408}
1409
1410void rtw_cfg80211_unlink_bss(struct adapter *padapter, struct wlan_network *pnetwork)
1411{
1412        struct wireless_dev *pwdev = padapter->rtw_wdev;
1413        struct wiphy *wiphy = pwdev->wiphy;
1414        struct cfg80211_bss *bss = NULL;
1415        struct wlan_bssid_ex select_network = pnetwork->network;
1416
1417        bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
1418                select_network.MacAddress, select_network.Ssid.Ssid,
1419                select_network.Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/,
1420                0/*WLAN_CAPABILITY_ESS*/);
1421
1422        if (bss) {
1423                cfg80211_unlink_bss(wiphy, bss);
1424                DBG_8192C("%s(): cfg80211_unlink %s!! () ", __func__, select_network.Ssid.Ssid);
1425                cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
1426        }
1427        return;
1428}
1429
1430void rtw_cfg80211_surveydone_event_callback(struct adapter *padapter)
1431{
1432        struct list_head                                        *plist, *phead;
1433        struct  mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1434        struct __queue *queue   = &(pmlmepriv->scanned_queue);
1435        struct  wlan_network    *pnetwork = NULL;
1436
1437#ifdef DEBUG_CFG80211
1438        DBG_8192C("%s\n", __func__);
1439#endif
1440
1441        spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1442
1443        phead = get_list_head(queue);
1444        plist = get_next(phead);
1445
1446        while (1)
1447        {
1448                if (phead == plist)
1449                        break;
1450
1451                pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1452
1453                /* report network only if the current channel set contains the channel to which this network belongs */
1454                if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
1455                        && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == true
1456                        && true == rtw_validate_ssid(&(pnetwork->network.Ssid))
1457                )
1458                {
1459                        /* ev =translate_scan(padapter, a, pnetwork, ev, stop); */
1460                        rtw_cfg80211_inform_bss(padapter, pnetwork);
1461                }
1462
1463                plist = get_next(plist);
1464
1465        }
1466
1467        spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1468}
1469
1470static int rtw_cfg80211_set_probe_req_wpsp2pie(struct adapter *padapter, char *buf, int len)
1471{
1472        int ret = 0;
1473        uint wps_ielen = 0;
1474        u8 *wps_ie;
1475        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1476
1477#ifdef DEBUG_CFG80211
1478        DBG_8192C("%s, ielen =%d\n", __func__, len);
1479#endif
1480
1481        if (len>0)
1482        {
1483                if ((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
1484                {
1485                        #ifdef DEBUG_CFG80211
1486                        DBG_8192C("probe_req_wps_ielen =%d\n", wps_ielen);
1487                        #endif
1488
1489                        if (pmlmepriv->wps_probe_req_ie)
1490                        {
1491                                pmlmepriv->wps_probe_req_ie_len = 0;
1492                                kfree(pmlmepriv->wps_probe_req_ie);
1493                                pmlmepriv->wps_probe_req_ie = NULL;
1494                        }
1495
1496                        pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen);
1497                        if (pmlmepriv->wps_probe_req_ie == NULL) {
1498                                DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __func__, __LINE__);
1499                                return -EINVAL;
1500
1501                        }
1502                        memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
1503                        pmlmepriv->wps_probe_req_ie_len = wps_ielen;
1504                }
1505        }
1506
1507        return ret;
1508
1509}
1510
1511static int cfg80211_rtw_scan(struct wiphy *wiphy
1512        , struct cfg80211_scan_request *request)
1513{
1514        struct net_device *ndev = wdev_to_ndev(request->wdev);
1515        int i;
1516        u8 _status = false;
1517        int ret = 0;
1518        struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
1519        struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
1520        u8 survey_times =3;
1521        u8 survey_times_for_one_ch =6;
1522        struct cfg80211_ssid *ssids = request->ssids;
1523        int j = 0;
1524        bool need_indicate_scan_done = false;
1525
1526        struct adapter *padapter;
1527        struct rtw_wdev_priv *pwdev_priv;
1528        struct mlme_priv *pmlmepriv;
1529
1530        if (ndev == NULL) {
1531                ret = -EINVAL;
1532                goto exit;
1533        }
1534
1535        padapter = (struct adapter *)rtw_netdev_priv(ndev);
1536        pwdev_priv = adapter_wdev_data(padapter);
1537        pmlmepriv = &padapter->mlmepriv;
1538
1539/* ifdef DEBUG_CFG80211 */
1540        DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
1541/* endif */
1542
1543        spin_lock_bh(&pwdev_priv->scan_req_lock);
1544        pwdev_priv->scan_request = request;
1545        spin_unlock_bh(&pwdev_priv->scan_req_lock);
1546
1547        if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
1548        {
1549#ifdef DEBUG_CFG80211
1550                DBG_871X("%s under WIFI_AP_STATE\n", __func__);
1551#endif
1552
1553                if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true)
1554                {
1555                        DBG_8192C("%s, fwstate = 0x%x\n", __func__, pmlmepriv->fw_state);
1556
1557                        if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
1558                        {
1559                                DBG_8192C("AP mode process WPS\n");
1560                        }
1561
1562                        need_indicate_scan_done = true;
1563                        goto check_need_indicate_scan_done;
1564                }
1565        }
1566
1567        rtw_ps_deny(padapter, PS_DENY_SCAN);
1568        if (_FAIL == rtw_pwr_wakeup(padapter)) {
1569                need_indicate_scan_done = true;
1570                goto check_need_indicate_scan_done;
1571        }
1572
1573        if (request->ie && request->ie_len>0)
1574        {
1575                rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len);
1576        }
1577
1578        if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
1579                DBG_8192C("%s, fwstate = 0x%x\n", __func__, pmlmepriv->fw_state);
1580                need_indicate_scan_done = true;
1581                goto check_need_indicate_scan_done;
1582        } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
1583                DBG_8192C("%s, fwstate = 0x%x\n", __func__, pmlmepriv->fw_state);
1584                ret = -EBUSY;
1585                goto check_need_indicate_scan_done;
1586        }
1587
1588        if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true)
1589        {
1590                static unsigned long lastscantime = 0;
1591                unsigned long passtime;
1592
1593                passtime = jiffies_to_msecs(jiffies - lastscantime);
1594                lastscantime = jiffies;
1595                if (passtime > 12000)
1596                {
1597                        DBG_871X("%s: bBusyTraffic == true\n", __func__);
1598                        need_indicate_scan_done = true;
1599                        goto check_need_indicate_scan_done;
1600                }
1601        }
1602
1603        if (rtw_is_scan_deny(padapter)) {
1604                DBG_871X(FUNC_ADPT_FMT  ": scan deny\n", FUNC_ADPT_ARG(padapter));
1605                need_indicate_scan_done = true;
1606                goto check_need_indicate_scan_done;
1607        }
1608
1609        memset(ssid, 0, sizeof(struct ndis_802_11_ssid)*RTW_SSID_SCAN_AMOUNT);
1610        /* parsing request ssids, n_ssids */
1611        for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
1612                #ifdef DEBUG_CFG80211
1613                DBG_8192C("ssid =%s, len =%d\n", ssids[i].ssid, ssids[i].ssid_len);
1614                #endif
1615                memcpy(ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len);
1616                ssid[i].SsidLength = ssids[i].ssid_len;
1617        }
1618
1619        /* parsing channels, n_channels */
1620        memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
1621        for (i = 0;i<request->n_channels && i<RTW_CHANNEL_SCAN_AMOUNT;i++) {
1622                #ifdef DEBUG_CFG80211
1623                DBG_871X(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
1624                #endif
1625                ch[i].hw_value = request->channels[i]->hw_value;
1626                ch[i].flags = request->channels[i]->flags;
1627        }
1628
1629        spin_lock_bh(&pmlmepriv->lock);
1630        if (request->n_channels == 1) {
1631                for (i = 1;i<survey_times_for_one_ch;i++)
1632                        memcpy(&ch[i], &ch[0], sizeof(struct rtw_ieee80211_channel));
1633                _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times_for_one_ch);
1634        } else if (request->n_channels <= 4) {
1635                for (j =request->n_channels-1;j>= 0;j--)
1636                        for (i = 0;i<survey_times;i++)
1637                {
1638                        memcpy(&ch[j*survey_times+i], &ch[j], sizeof(struct rtw_ieee80211_channel));
1639                }
1640                _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times * request->n_channels);
1641        } else {
1642                _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0);
1643        }
1644        spin_unlock_bh(&pmlmepriv->lock);
1645
1646
1647        if (_status == false)
1648        {
1649                ret = -1;
1650        }
1651
1652check_need_indicate_scan_done:
1653        if (true == need_indicate_scan_done)
1654        {
1655                rtw_cfg80211_surveydone_event_callback(padapter);
1656                rtw_cfg80211_indicate_scan_done(padapter, false);
1657        }
1658
1659        rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
1660
1661exit:
1662        return ret;
1663
1664}
1665
1666static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1667{
1668        DBG_8192C("%s\n", __func__);
1669        return 0;
1670}
1671
1672
1673
1674static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
1675{
1676        DBG_8192C("%s, wpa_version =%d\n", __func__, wpa_version);
1677
1678        if (!wpa_version) {
1679                psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
1680                return 0;
1681        }
1682
1683
1684        if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1685        {
1686                psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
1687        }
1688
1689        return 0;
1690
1691}
1692
1693static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
1694                             enum nl80211_auth_type sme_auth_type)
1695{
1696        DBG_8192C("%s, nl80211_auth_type =%d\n", __func__, sme_auth_type);
1697
1698
1699        switch (sme_auth_type) {
1700        case NL80211_AUTHTYPE_AUTOMATIC:
1701
1702                psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
1703
1704                break;
1705        case NL80211_AUTHTYPE_OPEN_SYSTEM:
1706
1707                psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1708
1709                if (psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA)
1710                        psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1711
1712                break;
1713        case NL80211_AUTHTYPE_SHARED_KEY:
1714
1715                psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
1716
1717                psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1718
1719
1720                break;
1721        default:
1722                psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1723                /* return -ENOTSUPP; */
1724        }
1725
1726        return 0;
1727
1728}
1729
1730static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
1731{
1732        u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
1733
1734        u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
1735                &psecuritypriv->dot118021XGrpPrivacy;
1736
1737        DBG_8192C("%s, ucast =%d, cipher = 0x%x\n", __func__, ucast, cipher);
1738
1739
1740        if (!cipher) {
1741                *profile_cipher = _NO_PRIVACY_;
1742                psecuritypriv->ndisencryptstatus = ndisencryptstatus;
1743                return 0;
1744        }
1745
1746        switch (cipher) {
1747        case IW_AUTH_CIPHER_NONE:
1748                *profile_cipher = _NO_PRIVACY_;
1749                ndisencryptstatus = Ndis802_11EncryptionDisabled;
1750                break;
1751        case WLAN_CIPHER_SUITE_WEP40:
1752                *profile_cipher = _WEP40_;
1753                ndisencryptstatus = Ndis802_11Encryption1Enabled;
1754                break;
1755        case WLAN_CIPHER_SUITE_WEP104:
1756                *profile_cipher = _WEP104_;
1757                ndisencryptstatus = Ndis802_11Encryption1Enabled;
1758                break;
1759        case WLAN_CIPHER_SUITE_TKIP:
1760                *profile_cipher = _TKIP_;
1761                ndisencryptstatus = Ndis802_11Encryption2Enabled;
1762                break;
1763        case WLAN_CIPHER_SUITE_CCMP:
1764                *profile_cipher = _AES_;
1765                ndisencryptstatus = Ndis802_11Encryption3Enabled;
1766                break;
1767        default:
1768                DBG_8192C("Unsupported cipher: 0x%x\n", cipher);
1769                return -ENOTSUPP;
1770        }
1771
1772        if (ucast)
1773        {
1774                psecuritypriv->ndisencryptstatus = ndisencryptstatus;
1775
1776                /* if (psecuritypriv->dot11PrivacyAlgrthm >= _AES_) */
1777                /*      psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK; */
1778        }
1779
1780        return 0;
1781}
1782
1783static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
1784{
1785        DBG_8192C("%s, key_mgt = 0x%x\n", __func__, key_mgt);
1786
1787        if (key_mgt == WLAN_AKM_SUITE_8021X)
1788                /* auth_type = UMAC_AUTH_TYPE_8021X; */
1789                psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1790        else if (key_mgt == WLAN_AKM_SUITE_PSK) {
1791                psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1792        }
1793        else {
1794                DBG_8192C("Invalid key mgt: 0x%x\n", key_mgt);
1795                /* return -EINVAL; */
1796        }
1797
1798        return 0;
1799}
1800
1801static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t ielen)
1802{
1803        u8 *buf = NULL, *pos = NULL;
1804        int group_cipher = 0, pairwise_cipher = 0;
1805        int ret = 0;
1806        int wpa_ielen = 0;
1807        int wpa2_ielen = 0;
1808        u8 *pwpa, *pwpa2;
1809        u8 null_addr[]= {0, 0, 0, 0, 0, 0};
1810
1811        if (pie == NULL || !ielen) {
1812                /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
1813                _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1814                goto exit;
1815        }
1816
1817        if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
1818                ret = -EINVAL;
1819                goto exit;
1820        }
1821
1822        buf = rtw_zmalloc(ielen);
1823        if (buf == NULL) {
1824                ret =  -ENOMEM;
1825                goto exit;
1826        }
1827
1828        memcpy(buf, pie , ielen);
1829
1830        /* dump */
1831        {
1832                int i;
1833                DBG_8192C("set wpa_ie(length:%zu):\n", ielen);
1834                for (i = 0;i<ielen;i =i+8)
1835                        DBG_8192C("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
1836        }
1837
1838        pos = buf;
1839        if (ielen < RSN_HEADER_LEN) {
1840                RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("Ie len too short %d\n", ielen));
1841                ret  = -1;
1842                goto exit;
1843        }
1844
1845        pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
1846        if (pwpa && wpa_ielen>0)
1847        {
1848                if (rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
1849                {
1850                        padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1851                        padapter->securitypriv.ndisauthtype =Ndis802_11AuthModeWPAPSK;
1852                        memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
1853
1854                        DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
1855                }
1856        }
1857
1858        pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
1859        if (pwpa2 && wpa2_ielen>0)
1860        {
1861                if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
1862                {
1863                        padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1864                        padapter->securitypriv.ndisauthtype =Ndis802_11AuthModeWPA2PSK;
1865                        memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
1866
1867                        DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
1868                }
1869        }
1870
1871        if (group_cipher == 0)
1872        {
1873                group_cipher = WPA_CIPHER_NONE;
1874        }
1875        if (pairwise_cipher == 0)
1876        {
1877                pairwise_cipher = WPA_CIPHER_NONE;
1878        }
1879
1880        switch (group_cipher)
1881        {
1882                case WPA_CIPHER_NONE:
1883                        padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1884                        padapter->securitypriv.ndisencryptstatus =Ndis802_11EncryptionDisabled;
1885                        break;
1886                case WPA_CIPHER_WEP40:
1887                        padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
1888                        padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1889                        break;
1890                case WPA_CIPHER_TKIP:
1891                        padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
1892                        padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1893                        break;
1894                case WPA_CIPHER_CCMP:
1895                        padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
1896                        padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1897                        break;
1898                case WPA_CIPHER_WEP104:
1899                        padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
1900                        padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1901                        break;
1902        }
1903
1904        switch (pairwise_cipher)
1905        {
1906                case WPA_CIPHER_NONE:
1907                        padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1908                        padapter->securitypriv.ndisencryptstatus =Ndis802_11EncryptionDisabled;
1909                        break;
1910                case WPA_CIPHER_WEP40:
1911                        padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1912                        padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1913                        break;
1914                case WPA_CIPHER_TKIP:
1915                        padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
1916                        padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1917                        break;
1918                case WPA_CIPHER_CCMP:
1919                        padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
1920                        padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1921                        break;
1922                case WPA_CIPHER_WEP104:
1923                        padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
1924                        padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1925                        break;
1926        }
1927
1928        {/* handle wps_ie */
1929                uint wps_ielen;
1930                u8 *wps_ie;
1931
1932                wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
1933                if (wps_ie && wps_ielen > 0) {
1934                        DBG_8192C("got wps_ie, wps_ielen:%u\n", wps_ielen);
1935                        padapter->securitypriv.wps_ie_len = wps_ielen<MAX_WPS_IE_LEN?wps_ielen:MAX_WPS_IE_LEN;
1936                        memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
1937                        set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
1938                } else {
1939                        _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1940                }
1941        }
1942
1943        /* TKIP and AES disallow multicast packets until installing group key */
1944        if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
1945                || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
1946                || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
1947                /* WPS open need to enable multicast */
1948                /*  check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == true) */
1949                rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
1950
1951        RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1952                ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->securitypriv.ndisencryptstatus =%d padapter->securitypriv.ndisauthtype =%d\n",
1953                pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
1954
1955exit:
1956        kfree(buf);
1957        if (ret)
1958                _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1959        return ret;
1960}
1961
1962static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1963                                  struct cfg80211_ibss_params *params)
1964{
1965        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
1966        struct ndis_802_11_ssid ndis_ssid;
1967        struct security_priv *psecuritypriv = &padapter->securitypriv;
1968        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1969        int ret = 0;
1970
1971        if (_FAIL == rtw_pwr_wakeup(padapter)) {
1972                ret = -EPERM;
1973                goto exit;
1974        }
1975
1976        if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1977                ret = -EPERM;
1978                goto exit;
1979        }
1980
1981        if (!params->ssid || !params->ssid_len)
1982        {
1983                ret = -EINVAL;
1984                goto exit;
1985        }
1986
1987        if (params->ssid_len > IW_ESSID_MAX_SIZE) {
1988
1989                ret = -E2BIG;
1990                goto exit;
1991        }
1992
1993        memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
1994        ndis_ssid.SsidLength = params->ssid_len;
1995        memcpy(ndis_ssid.Ssid, (u8 *)params->ssid, params->ssid_len);
1996
1997        /* DBG_8192C("ssid =%s, len =%zu\n", ndis_ssid.Ssid, params->ssid_len); */
1998
1999        psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
2000        psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
2001        psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2002        psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
2003        psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
2004
2005        ret = rtw_cfg80211_set_auth_type(psecuritypriv, NL80211_AUTHTYPE_OPEN_SYSTEM);
2006        rtw_set_802_11_authentication_mode(padapter, psecuritypriv->ndisauthtype);
2007
2008        if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == false)
2009        {
2010                ret = -1;
2011                goto exit;
2012        }
2013
2014exit:
2015        return ret;
2016}
2017
2018static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
2019{
2020        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
2021        struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
2022        enum nl80211_iftype old_type;
2023        int ret = 0;
2024
2025        DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2026
2027        padapter->mlmepriv.not_indic_disco = true;
2028
2029        old_type = rtw_wdev->iftype;
2030
2031        rtw_set_to_roam(padapter, 0);
2032
2033        if (check_fwstate(&padapter->mlmepriv, _FW_LINKED))
2034        {
2035                rtw_scan_abort(padapter);
2036                LeaveAllPowerSaveMode(padapter);
2037
2038                rtw_wdev->iftype = NL80211_IFTYPE_STATION;
2039
2040                if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure) ==false)
2041                {
2042                        rtw_wdev->iftype = old_type;
2043                        ret = -EPERM;
2044                        goto leave_ibss;
2045                }
2046                rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure, true);
2047        }
2048
2049leave_ibss:
2050        padapter->mlmepriv.not_indic_disco = false;
2051
2052        return 0;
2053}
2054
2055static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
2056                                 struct cfg80211_connect_params *sme)
2057{
2058        int ret = 0;
2059        enum NDIS_802_11_AUTHENTICATION_MODE authmode;
2060        struct ndis_802_11_ssid ndis_ssid;
2061        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
2062        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2063        struct security_priv *psecuritypriv = &padapter->securitypriv;
2064
2065        padapter->mlmepriv.not_indic_disco = true;
2066
2067        DBG_871X("=>"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2068        DBG_871X("privacy =%d, key =%p, key_len =%d, key_idx =%d\n",
2069                sme->privacy, sme->key, sme->key_len, sme->key_idx);
2070
2071
2072        if (adapter_wdev_data(padapter)->block == true)
2073        {
2074                ret = -EBUSY;
2075                DBG_871X("%s wdev_priv.block is set\n", __func__);
2076                goto exit;
2077        }
2078
2079        rtw_ps_deny(padapter, PS_DENY_JOIN);
2080        if (_FAIL == rtw_pwr_wakeup(padapter)) {
2081                ret = -EPERM;
2082                goto exit;
2083        }
2084
2085        if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2086                ret = -EPERM;
2087                goto exit;
2088        }
2089
2090        if (!sme->ssid || !sme->ssid_len)
2091        {
2092                ret = -EINVAL;
2093                goto exit;
2094        }
2095
2096        if (sme->ssid_len > IW_ESSID_MAX_SIZE) {
2097
2098                ret = -E2BIG;
2099                goto exit;
2100        }
2101
2102        memset(&ndis_ssid, 0, sizeof(struct ndis_802_11_ssid));
2103        ndis_ssid.SsidLength = sme->ssid_len;
2104        memcpy(ndis_ssid.Ssid, (u8 *)sme->ssid, sme->ssid_len);
2105
2106        DBG_8192C("ssid =%s, len =%zu\n", ndis_ssid.Ssid, sme->ssid_len);
2107
2108
2109        if (sme->bssid)
2110                DBG_8192C("bssid ="MAC_FMT"\n", MAC_ARG(sme->bssid));
2111
2112
2113        if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
2114                ret = -EBUSY;
2115                DBG_8192C("%s, fw_state = 0x%x, goto exit\n", __func__, pmlmepriv->fw_state);
2116                goto exit;
2117        }
2118        if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) {
2119                rtw_scan_abort(padapter);
2120        }
2121
2122        psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
2123        psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
2124        psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2125        psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
2126        psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
2127
2128        ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions);
2129        if (ret < 0)
2130                goto exit;
2131
2132        ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
2133
2134        if (ret < 0)
2135                goto exit;
2136
2137        DBG_8192C("%s, ie_len =%zu\n", __func__, sme->ie_len);
2138
2139        ret = rtw_cfg80211_set_wpa_ie(padapter, (u8 *)sme->ie, sme->ie_len);
2140        if (ret < 0)
2141                goto exit;
2142
2143        if (sme->crypto.n_ciphers_pairwise) {
2144                ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], true);
2145                if (ret < 0)
2146                        goto exit;
2147        }
2148
2149        /* For WEP Shared auth */
2150        if ((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared
2151                || psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) && sme->key
2152        )
2153        {
2154                u32 wep_key_idx, wep_key_len, wep_total_len;
2155                struct ndis_802_11_wep   *pwep = NULL;
2156                DBG_871X("%s(): Shared/Auto WEP\n", __func__);
2157
2158                wep_key_idx = sme->key_idx;
2159                wep_key_len = sme->key_len;
2160
2161                if (sme->key_idx > WEP_KEYS) {
2162                        ret = -EINVAL;
2163                        goto exit;
2164                }
2165
2166                if (wep_key_len > 0)
2167                {
2168                        wep_key_len = wep_key_len <= 5 ? 5 : 13;
2169                        wep_total_len = wep_key_len + FIELD_OFFSET(struct ndis_802_11_wep, KeyMaterial);
2170                        pwep = rtw_malloc(wep_total_len);
2171                        if (pwep == NULL) {
2172                                DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n");
2173                                ret = -ENOMEM;
2174                                goto exit;
2175                        }
2176
2177                        memset(pwep, 0, wep_total_len);
2178
2179                        pwep->KeyLength = wep_key_len;
2180                        pwep->Length = wep_total_len;
2181
2182                        if (wep_key_len == 13)
2183                        {
2184                                padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
2185                                padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
2186                        }
2187                }
2188                else {
2189                        ret = -EINVAL;
2190                        goto exit;
2191                }
2192
2193                pwep->KeyIndex = wep_key_idx;
2194                pwep->KeyIndex |= 0x80000000;
2195
2196                memcpy(pwep->KeyMaterial,  (void *)sme->key, pwep->KeyLength);
2197
2198                if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
2199                {
2200                        ret = -EOPNOTSUPP ;
2201                }
2202
2203                kfree((u8 *)pwep);
2204
2205                if (ret < 0)
2206                        goto exit;
2207        }
2208
2209        ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, false);
2210        if (ret < 0)
2211                return ret;
2212
2213        if (sme->crypto.n_akm_suites) {
2214                ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]);
2215                if (ret < 0)
2216                        goto exit;
2217        }
2218
2219        authmode = psecuritypriv->ndisauthtype;
2220        rtw_set_802_11_authentication_mode(padapter, authmode);
2221
2222        /* rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
2223
2224        if (rtw_set_802_11_connect(padapter, (u8 *)sme->bssid, &ndis_ssid) == false) {
2225                ret = -1;
2226                goto exit;
2227        }
2228
2229        DBG_8192C("set ssid:dot11AuthAlgrthm =%d, dot11PrivacyAlgrthm =%d, dot118021XGrpPrivacy =%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, psecuritypriv->dot118021XGrpPrivacy);
2230
2231exit:
2232
2233        rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
2234
2235        DBG_8192C("<=%s, ret %d\n", __func__, ret);
2236
2237        padapter->mlmepriv.not_indic_disco = false;
2238
2239        return ret;
2240}
2241
2242static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2243                                   u16 reason_code)
2244{
2245        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
2246
2247        DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2248
2249        padapter->mlmepriv.not_indic_disco = true;
2250
2251        rtw_set_to_roam(padapter, 0);
2252
2253        rtw_scan_abort(padapter);
2254        LeaveAllPowerSaveMode(padapter);
2255        rtw_disassoc_cmd(padapter, 500, false);
2256
2257        DBG_871X("%s...call rtw_indicate_disconnect\n", __func__);
2258
2259        rtw_indicate_disconnect(padapter);
2260
2261        rtw_free_assoc_resources(padapter, 1);
2262        rtw_pwr_wakeup(padapter);
2263
2264        padapter->mlmepriv.not_indic_disco = false;
2265
2266        DBG_871X(FUNC_NDEV_FMT" return 0\n", FUNC_NDEV_ARG(ndev));
2267        return 0;
2268}
2269
2270static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
2271        struct wireless_dev *wdev,
2272        enum nl80211_tx_power_setting type, int mbm)
2273{
2274        DBG_8192C("%s\n", __func__);
2275        return 0;
2276}
2277
2278static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
2279        struct wireless_dev *wdev,
2280        int *dbm)
2281{
2282        DBG_8192C("%s\n", __func__);
2283
2284        *dbm = (12);
2285
2286        return 0;
2287}
2288
2289inline bool rtw_cfg80211_pwr_mgmt(struct adapter *adapter)
2290{
2291        struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(adapter);
2292        return rtw_wdev_priv->power_mgmt;
2293}
2294
2295static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
2296                                       struct net_device *ndev,
2297                                       bool enabled, int timeout)
2298{
2299        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
2300        struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(padapter);
2301
2302        DBG_871X(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev),
2303                enabled, timeout);
2304
2305        rtw_wdev_priv->power_mgmt = enabled;
2306
2307        if (!enabled)
2308                LPS_Leave(padapter, "CFG80211_PWRMGMT");
2309
2310        return 0;
2311}
2312
2313static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
2314                                  struct net_device *ndev,
2315                                  struct cfg80211_pmksa *pmksa)
2316{
2317        u8 index, blInserted = false;
2318        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
2319        struct security_priv *psecuritypriv = &padapter->securitypriv;
2320        u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
2321
2322        DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2323
2324        if (!memcmp((u8 *)pmksa->bssid, strZeroMacAddress, ETH_ALEN))
2325        {
2326                return -EINVAL;
2327        }
2328
2329        blInserted = false;
2330
2331        /* overwrite PMKID */
2332        for (index = 0 ; index<NUM_PMKID_CACHE; index++)
2333        {
2334                if (!memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN))
2335                { /*  BSSID is matched, the same AP => rewrite with new PMKID. */
2336                        DBG_871X(FUNC_NDEV_FMT" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(ndev));
2337
2338                        memcpy(psecuritypriv->PMKIDList[index].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
2339                        psecuritypriv->PMKIDList[index].bUsed = true;
2340                        psecuritypriv->PMKIDIndex = index+1;
2341                        blInserted = true;
2342                        break;
2343                }
2344        }
2345
2346        if (!blInserted)
2347        {
2348                /*  Find a new entry */
2349                DBG_871X(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n",
2350                        FUNC_NDEV_ARG(ndev), psecuritypriv->PMKIDIndex);
2351
2352                memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, (u8 *)pmksa->bssid, ETH_ALEN);
2353                memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
2354
2355                psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = true;
2356                psecuritypriv->PMKIDIndex++ ;
2357                if (psecuritypriv->PMKIDIndex == 16)
2358                {
2359                        psecuritypriv->PMKIDIndex = 0;
2360                }
2361        }
2362
2363        return 0;
2364}
2365
2366static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
2367                                  struct net_device *ndev,
2368                                  struct cfg80211_pmksa *pmksa)
2369{
2370        u8 index, bMatched = false;
2371        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
2372        struct security_priv *psecuritypriv = &padapter->securitypriv;
2373
2374        DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2375
2376        for (index = 0 ; index<NUM_PMKID_CACHE; index++)
2377        {
2378                if (!memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN))
2379                { /*  BSSID is matched, the same AP => Remove this PMKID information and reset it. */
2380                        eth_zero_addr(psecuritypriv->PMKIDList[index].Bssid);
2381                        memset(psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN);
2382                        psecuritypriv->PMKIDList[index].bUsed = false;
2383                        bMatched = true;
2384                        break;
2385                }
2386        }
2387
2388        if (false == bMatched)
2389        {
2390                DBG_871X(FUNC_NDEV_FMT" do not have matched BSSID\n"
2391                        , FUNC_NDEV_ARG(ndev));
2392                return -EINVAL;
2393        }
2394
2395        return 0;
2396}
2397
2398static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
2399                                    struct net_device *ndev)
2400{
2401        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
2402        struct security_priv *psecuritypriv = &padapter->securitypriv;
2403
2404        DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2405
2406        memset(&psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
2407        psecuritypriv->PMKIDIndex = 0;
2408
2409        return 0;
2410}
2411
2412void rtw_cfg80211_indicate_sta_assoc(struct adapter *padapter, u8 *pmgmt_frame, uint frame_len)
2413{
2414        struct net_device *ndev = padapter->pnetdev;
2415
2416        DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
2417
2418        {
2419                struct station_info sinfo;
2420                u8 ie_offset;
2421                if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ)
2422                        ie_offset = _ASOCREQ_IE_OFFSET_;
2423                else /*  WIFI_REASSOCREQ */
2424                        ie_offset = _REASOCREQ_IE_OFFSET_;
2425
2426                sinfo.filled = 0;
2427                sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
2428                sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
2429                cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
2430        }
2431}
2432
2433void rtw_cfg80211_indicate_sta_disassoc(struct adapter *padapter, unsigned char *da, unsigned short reason)
2434{
2435        struct net_device *ndev = padapter->pnetdev;
2436
2437        DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
2438
2439        cfg80211_del_sta(ndev, da, GFP_ATOMIC);
2440}
2441
2442static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
2443{
2444        int ret = 0;
2445
2446        DBG_8192C("%s\n", __func__);
2447
2448        return ret;
2449}
2450
2451static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
2452{
2453        int ret = 0;
2454
2455        DBG_8192C("%s\n", __func__);
2456
2457        return ret;
2458}
2459
2460static netdev_tx_t rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
2461{
2462        int ret = 0;
2463        int rtap_len;
2464        int qos_len = 0;
2465        int dot11_hdr_len = 24;
2466        int snap_len = 6;
2467        unsigned char *pdata;
2468        u16 frame_control;
2469        unsigned char src_mac_addr[6];
2470        unsigned char dst_mac_addr[6];
2471        struct ieee80211_hdr *dot11_hdr;
2472        struct ieee80211_radiotap_header *rtap_hdr;
2473        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
2474
2475        DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2476
2477        if (!skb)
2478                goto fail;
2479
2480        rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
2481
2482        if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
2483                goto fail;
2484
2485        rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
2486        if (unlikely(rtap_hdr->it_version))
2487                goto fail;
2488
2489        rtap_len = ieee80211_get_radiotap_len(skb->data);
2490        if (unlikely(skb->len < rtap_len))
2491                goto fail;
2492
2493        if (rtap_len != 14)
2494        {
2495                DBG_8192C("radiotap len (should be 14): %d\n", rtap_len);
2496                goto fail;
2497        }
2498
2499        /* Skip the ratio tap header */
2500        skb_pull(skb, rtap_len);
2501
2502        dot11_hdr = (struct ieee80211_hdr *)skb->data;
2503        frame_control = le16_to_cpu(dot11_hdr->frame_control);
2504        /* Check if the QoS bit is set */
2505        if ((frame_control & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
2506                /* Check if this ia a Wireless Distribution System (WDS) frame
2507                 * which has 4 MAC addresses
2508                 */
2509                if (frame_control & 0x0080)
2510                        qos_len = 2;
2511                if ((frame_control & 0x0300) == 0x0300)
2512                        dot11_hdr_len += 6;
2513
2514                memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
2515                memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
2516
2517                /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
2518                 * for two MAC addresses
2519                 */
2520                skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
2521                pdata = (unsigned char*)skb->data;
2522                memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
2523                memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
2524
2525                DBG_8192C("should be eapol packet\n");
2526
2527                /* Use the real net device to transmit the packet */
2528                ret = _rtw_xmit_entry(skb, padapter->pnetdev);
2529
2530                return ret;
2531
2532        }
2533        else if ((frame_control & (IEEE80211_FCTL_FTYPE|IEEE80211_FCTL_STYPE))
2534                == (IEEE80211_FTYPE_MGMT|IEEE80211_STYPE_ACTION)
2535        )
2536        {
2537                /* only for action frames */
2538                struct xmit_frame               *pmgntframe;
2539                struct pkt_attrib       *pattrib;
2540                unsigned char *pframe;
2541                /* u8 category, action, OUI_Subtype, dialogToken = 0; */
2542                /* unsigned char *frame_body; */
2543                struct ieee80211_hdr *pwlanhdr;
2544                struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2545                struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2546                u8 *buf = skb->data;
2547                u32 len = skb->len;
2548                u8 category, action;
2549
2550                if (rtw_action_frame_parse(buf, len, &category, &action) == false) {
2551                        DBG_8192C(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev),
2552                                le16_to_cpu(((struct ieee80211_hdr_3addr *)buf)->frame_control));
2553                        goto fail;
2554                }
2555
2556                DBG_8192C("RTW_Tx:da ="MAC_FMT" via "FUNC_NDEV_FMT"\n",
2557                        MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev));
2558                if (category == RTW_WLAN_CATEGORY_PUBLIC)
2559                        DBG_871X("RTW_Tx:%s\n", action_public_str(action));
2560                else
2561                        DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
2562
2563                /* starting alloc mgmt frame to dump it */
2564                if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
2565                {
2566                        goto fail;
2567                }
2568
2569                /* update attribute */
2570                pattrib = &pmgntframe->attrib;
2571                update_mgntframe_attrib(padapter, pattrib);
2572                pattrib->retry_ctrl = false;
2573
2574                memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2575
2576                pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2577
2578                memcpy(pframe, (void*)buf, len);
2579                pattrib->pktlen = len;
2580
2581                pwlanhdr = (struct ieee80211_hdr *)pframe;
2582                /* update seq number */
2583                pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
2584                pattrib->seqnum = pmlmeext->mgnt_seq;
2585                pmlmeext->mgnt_seq++;
2586
2587
2588                pattrib->last_txcmdsz = pattrib->pktlen;
2589
2590                dump_mgntframe(padapter, pmgntframe);
2591
2592        }
2593        else
2594        {
2595                DBG_8192C("frame_control = 0x%x\n", frame_control & (IEEE80211_FCTL_FTYPE|IEEE80211_FCTL_STYPE));
2596        }
2597
2598
2599fail:
2600
2601        dev_kfree_skb_any(skb);
2602
2603        return 0;
2604
2605}
2606
2607static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
2608{
2609        int ret = 0;
2610
2611        DBG_8192C("%s\n", __func__);
2612
2613        return ret;
2614}
2615
2616static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
2617        .ndo_open = rtw_cfg80211_monitor_if_open,
2618       .ndo_stop = rtw_cfg80211_monitor_if_close,
2619       .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
2620       .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
2621};
2622
2623static int rtw_cfg80211_add_monitor_if (struct adapter *padapter, char *name, struct net_device **ndev)
2624{
2625        int ret = 0;
2626        struct net_device* mon_ndev = NULL;
2627        struct wireless_dev* mon_wdev = NULL;
2628        struct rtw_netdev_priv_indicator *pnpi;
2629        struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
2630
2631        if (!name) {
2632                DBG_871X(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter));
2633                ret = -EINVAL;
2634                goto out;
2635        }
2636
2637        if (pwdev_priv->pmon_ndev) {
2638                DBG_871X(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n",
2639                        FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev));
2640                ret = -EBUSY;
2641                goto out;
2642        }
2643
2644        mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
2645        if (!mon_ndev) {
2646                DBG_871X(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter));
2647                ret = -ENOMEM;
2648                goto out;
2649        }
2650
2651        mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
2652        strncpy(mon_ndev->name, name, IFNAMSIZ);
2653        mon_ndev->name[IFNAMSIZ - 1] = 0;
2654        mon_ndev->needs_free_netdev = true;
2655        mon_ndev->priv_destructor = rtw_ndev_destructor;
2656
2657        mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
2658
2659        pnpi = netdev_priv(mon_ndev);
2660        pnpi->priv = padapter;
2661        pnpi->sizeof_priv = sizeof(struct adapter);
2662
2663        /*  wdev */
2664        mon_wdev = rtw_zmalloc(sizeof(struct wireless_dev));
2665        if (!mon_wdev) {
2666                DBG_871X(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter));
2667                ret = -ENOMEM;
2668                goto out;
2669        }
2670
2671        mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
2672        mon_wdev->netdev = mon_ndev;
2673        mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
2674        mon_ndev->ieee80211_ptr = mon_wdev;
2675
2676        ret = register_netdevice(mon_ndev);
2677        if (ret) {
2678                goto out;
2679        }
2680
2681        *ndev = pwdev_priv->pmon_ndev = mon_ndev;
2682        memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
2683
2684out:
2685        if (ret && mon_wdev) {
2686                kfree((u8 *)mon_wdev);
2687                mon_wdev = NULL;
2688        }
2689
2690        if (ret && mon_ndev) {
2691                free_netdev(mon_ndev);
2692                *ndev = mon_ndev = NULL;
2693        }
2694
2695        return ret;
2696}
2697
2698static struct wireless_dev *
2699        cfg80211_rtw_add_virtual_intf(
2700                struct wiphy *wiphy,
2701                const char *name,
2702                unsigned char name_assign_type,
2703                enum nl80211_iftype type, struct vif_params *params)
2704{
2705        int ret = 0;
2706        struct net_device* ndev = NULL;
2707        struct adapter *padapter = wiphy_to_adapter(wiphy);
2708
2709        DBG_871X(FUNC_ADPT_FMT " wiphy:%s, name:%s, type:%d\n",
2710                FUNC_ADPT_ARG(padapter), wiphy_name(wiphy), name, type);
2711
2712        switch (type) {
2713        case NL80211_IFTYPE_ADHOC:
2714        case NL80211_IFTYPE_AP_VLAN:
2715        case NL80211_IFTYPE_WDS:
2716        case NL80211_IFTYPE_MESH_POINT:
2717                ret = -ENODEV;
2718                break;
2719        case NL80211_IFTYPE_MONITOR:
2720                ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
2721                break;
2722        case NL80211_IFTYPE_P2P_CLIENT:
2723        case NL80211_IFTYPE_STATION:
2724                ret = -ENODEV;
2725                break;
2726        case NL80211_IFTYPE_P2P_GO:
2727        case NL80211_IFTYPE_AP:
2728                ret = -ENODEV;
2729                break;
2730        default:
2731                ret = -ENODEV;
2732                DBG_871X("Unsupported interface type\n");
2733                break;
2734        }
2735
2736        DBG_871X(FUNC_ADPT_FMT" ndev:%p, ret:%d\n", FUNC_ADPT_ARG(padapter), ndev, ret);
2737
2738        return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
2739}
2740
2741static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
2742        struct wireless_dev *wdev
2743)
2744{
2745        struct net_device *ndev = wdev_to_ndev(wdev);
2746        int ret = 0;
2747        struct adapter *adapter;
2748        struct rtw_wdev_priv *pwdev_priv;
2749
2750        if (!ndev) {
2751                ret = -EINVAL;
2752                goto exit;
2753        }
2754
2755        adapter = (struct adapter *)rtw_netdev_priv(ndev);
2756        pwdev_priv = adapter_wdev_data(adapter);
2757
2758        unregister_netdevice(ndev);
2759
2760        if (ndev == pwdev_priv->pmon_ndev) {
2761                pwdev_priv->pmon_ndev = NULL;
2762                pwdev_priv->ifname_mon[0] = '\0';
2763                DBG_871X(FUNC_NDEV_FMT" remove monitor interface\n", FUNC_NDEV_ARG(ndev));
2764        }
2765
2766exit:
2767        return ret;
2768}
2769
2770static int rtw_add_beacon(struct adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len)
2771{
2772        int ret = 0;
2773        u8 *pbuf = NULL;
2774        uint len, wps_ielen = 0;
2775        struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
2776
2777        DBG_8192C("%s beacon_head_len =%zu, beacon_tail_len =%zu\n", __func__, head_len, tail_len);
2778
2779        if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
2780                return -EINVAL;
2781
2782        if (head_len<24)
2783                return -EINVAL;
2784
2785        pbuf = rtw_zmalloc(head_len+tail_len);
2786        if (!pbuf)
2787                return -ENOMEM;
2788
2789        memcpy(pbuf, (void *)head+24, head_len-24);/*  24 =beacon header len. */
2790        memcpy(pbuf+head_len-24, (void *)tail, tail_len);
2791
2792        len = head_len+tail_len-24;
2793
2794        /* check wps ie if inclued */
2795        if (rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
2796                DBG_8192C("add bcn, wps_ielen =%d\n", wps_ielen);
2797
2798        /* pbss_network->IEs will not include p2p_ie, wfd ie */
2799        rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4);
2800        rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4);
2801
2802        if (rtw_check_beacon_data(adapter, pbuf,  len) == _SUCCESS)
2803        {
2804                ret = 0;
2805        }
2806        else
2807        {
2808                ret = -EINVAL;
2809        }
2810
2811
2812        kfree(pbuf);
2813
2814        return ret;
2815}
2816
2817static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
2818                                                                struct cfg80211_ap_settings *settings)
2819{
2820        int ret = 0;
2821        struct adapter *adapter = (struct adapter *)rtw_netdev_priv(ndev);
2822
2823        DBG_871X(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev),
2824                settings->hidden_ssid, settings->auth_type);
2825
2826        ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len,
2827                settings->beacon.tail, settings->beacon.tail_len);
2828
2829        adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid;
2830
2831        if (settings->ssid && settings->ssid_len) {
2832                struct wlan_bssid_ex *pbss_network = &adapter->mlmepriv.cur_network.network;
2833                struct wlan_bssid_ex *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network;
2834
2835                memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
2836                pbss_network->Ssid.SsidLength = settings->ssid_len;
2837                memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
2838                pbss_network_ext->Ssid.SsidLength = settings->ssid_len;
2839        }
2840
2841        return ret;
2842}
2843
2844static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
2845                                struct cfg80211_beacon_data *info)
2846{
2847        int ret = 0;
2848        struct adapter *adapter = (struct adapter *)rtw_netdev_priv(ndev);
2849
2850        DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2851
2852        ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
2853
2854        return ret;
2855}
2856
2857static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
2858{
2859        DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2860        return 0;
2861}
2862
2863static int      cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
2864                                const u8 *mac,
2865                        struct station_parameters *params)
2866{
2867        DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2868
2869        return 0;
2870}
2871
2872static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
2873                                    struct station_del_parameters *params)
2874{
2875        int ret = 0;
2876        struct list_head        *phead, *plist;
2877        u8 updated = false;
2878        struct sta_info *psta = NULL;
2879        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
2880        struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2881        struct sta_priv *pstapriv = &padapter->stapriv;
2882        const u8 *mac = params->mac;
2883
2884        DBG_871X("+"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2885
2886        if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != true)
2887        {
2888                DBG_8192C("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__);
2889                return -EINVAL;
2890        }
2891
2892
2893        if (!mac)
2894        {
2895                DBG_8192C("flush all sta, and cam_entry\n");
2896
2897                flush_all_cam_entry(padapter);  /* clear CAM */
2898
2899                ret = rtw_sta_flush(padapter);
2900
2901                return ret;
2902        }
2903
2904
2905        DBG_8192C("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac));
2906
2907        if (mac[0] == 0xff && mac[1] == 0xff &&
2908            mac[2] == 0xff && mac[3] == 0xff &&
2909            mac[4] == 0xff && mac[5] == 0xff)
2910        {
2911                return -EINVAL;
2912        }
2913
2914
2915        spin_lock_bh(&pstapriv->asoc_list_lock);
2916
2917        phead = &pstapriv->asoc_list;
2918        plist = get_next(phead);
2919
2920        /* check asoc_queue */
2921        while (phead != plist)
2922        {
2923                psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
2924
2925                plist = get_next(plist);
2926
2927                if (!memcmp((u8 *)mac, psta->hwaddr, ETH_ALEN))
2928                {
2929                        if (psta->dot8021xalg == 1 && psta->bpairwise_key_installed == false)
2930                        {
2931                                DBG_8192C("%s, sta's dot8021xalg = 1 and key_installed = false\n", __func__);
2932                        }
2933                        else
2934                        {
2935                                DBG_8192C("free psta =%p, aid =%d\n", psta, psta->aid);
2936
2937                                list_del_init(&psta->asoc_list);
2938                                pstapriv->asoc_list_cnt--;
2939
2940                                updated = ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING);
2941
2942                                psta = NULL;
2943
2944                                break;
2945                        }
2946
2947                }
2948
2949        }
2950
2951        spin_unlock_bh(&pstapriv->asoc_list_lock);
2952
2953        associated_clients_update(padapter, updated);
2954
2955        DBG_871X("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2956
2957        return ret;
2958
2959}
2960
2961static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
2962                                  const u8 *mac, struct station_parameters *params)
2963{
2964        DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2965
2966        return 0;
2967}
2968
2969static struct sta_info *rtw_sta_info_get_by_idx(const int idx, struct sta_priv *pstapriv)
2970
2971{
2972        struct list_head        *phead, *plist;
2973        struct sta_info *psta = NULL;
2974        int i = 0;
2975
2976        phead = &pstapriv->asoc_list;
2977        plist = get_next(phead);
2978
2979        /* check asoc_queue */
2980        while (phead != plist)
2981        {
2982                if (idx == i) psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
2983                plist = get_next(plist);
2984                i++;
2985        }
2986        return psta;
2987}
2988
2989static int      cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev,
2990                               int idx, u8 *mac, struct station_info *sinfo)
2991{
2992
2993        int ret = 0;
2994        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev);
2995        struct sta_info *psta = NULL;
2996        struct sta_priv *pstapriv = &padapter->stapriv;
2997        DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2998
2999        spin_lock_bh(&pstapriv->asoc_list_lock);
3000        psta = rtw_sta_info_get_by_idx(idx, pstapriv);
3001        spin_unlock_bh(&pstapriv->asoc_list_lock);
3002        if (NULL == psta)
3003        {
3004                DBG_871X("Station is not found\n");
3005                ret = -ENOENT;
3006                goto exit;
3007        }
3008        memcpy(mac, psta->hwaddr, ETH_ALEN);
3009        sinfo->filled = BIT_ULL(NL80211_STA_INFO_SIGNAL);
3010        sinfo->signal = psta->rssi;
3011
3012exit:
3013        return ret;
3014}
3015
3016static int      cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
3017                              struct bss_parameters *params)
3018{
3019        DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3020        return 0;
3021}
3022
3023void rtw_cfg80211_rx_action(struct adapter *adapter, u8 *frame, uint frame_len, const char*msg)
3024{
3025        s32 freq;
3026        int channel;
3027        u8 category, action;
3028
3029        channel = rtw_get_oper_ch(adapter);
3030
3031        rtw_action_frame_parse(frame, frame_len, &category, &action);
3032
3033        DBG_8192C("RTW_Rx:cur_ch =%d\n", channel);
3034        if (msg)
3035                DBG_871X("RTW_Rx:%s\n", msg);
3036        else
3037                DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
3038
3039        freq = rtw_ieee80211_channel_to_frequency(channel, NL80211_BAND_2GHZ);
3040
3041        rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
3042}
3043
3044static int _cfg80211_rtw_mgmt_tx(struct adapter *padapter, u8 tx_ch, const u8 *buf, size_t len)
3045{
3046        struct xmit_frame       *pmgntframe;
3047        struct pkt_attrib       *pattrib;
3048        unsigned char *pframe;
3049        int ret = _FAIL;
3050        bool ack = true;
3051        struct ieee80211_hdr *pwlanhdr;
3052        struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3053        struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3054
3055        rtw_set_scan_deny(padapter, 1000);
3056
3057        rtw_scan_abort(padapter);
3058        if (tx_ch != rtw_get_oper_ch(padapter)) {
3059                if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED))
3060                        pmlmeext->cur_channel = tx_ch;
3061                set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
3062        }
3063
3064        /* starting alloc mgmt frame to dump it */
3065        if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3066        {
3067                /* ret = -ENOMEM; */
3068                ret = _FAIL;
3069                goto exit;
3070        }
3071
3072        /* update attribute */
3073        pattrib = &pmgntframe->attrib;
3074        update_mgntframe_attrib(padapter, pattrib);
3075        pattrib->retry_ctrl = false;
3076
3077        memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3078
3079        pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3080
3081        memcpy(pframe, (void*)buf, len);
3082        pattrib->pktlen = len;
3083
3084        pwlanhdr = (struct ieee80211_hdr *)pframe;
3085        /* update seq number */
3086        pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
3087        pattrib->seqnum = pmlmeext->mgnt_seq;
3088        pmlmeext->mgnt_seq++;
3089
3090        pattrib->last_txcmdsz = pattrib->pktlen;
3091
3092        if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
3093        {
3094                ack = false;
3095                ret = _FAIL;
3096
3097                #ifdef DEBUG_CFG80211
3098                DBG_8192C("%s, ack == _FAIL\n", __func__);
3099                #endif
3100        }
3101        else
3102        {
3103
3104                msleep(50);
3105
3106                #ifdef DEBUG_CFG80211
3107                DBG_8192C("%s, ack =%d, ok!\n", __func__, ack);
3108                #endif
3109                ret = _SUCCESS;
3110        }
3111
3112exit:
3113
3114        #ifdef DEBUG_CFG80211
3115        DBG_8192C("%s, ret =%d\n", __func__, ret);
3116        #endif
3117
3118        return ret;
3119
3120}
3121
3122static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
3123        struct wireless_dev *wdev,
3124        struct cfg80211_mgmt_tx_params *params,
3125        u64 *cookie)
3126{
3127        struct net_device *ndev = wdev_to_ndev(wdev);
3128        struct ieee80211_channel *chan = params->chan;
3129        const u8 *buf = params->buf;
3130        size_t len = params->len;
3131        int ret = 0;
3132        int tx_ret;
3133        u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
3134        u32 dump_cnt = 0;
3135        bool ack = true;
3136        u8 tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq);
3137        u8 category, action;
3138        int type = (-1);
3139        struct adapter *padapter;
3140        struct rtw_wdev_priv *pwdev_priv;
3141
3142        if (ndev == NULL) {
3143                ret = -EINVAL;
3144                goto exit;
3145        }
3146
3147        padapter = (struct adapter *)rtw_netdev_priv(ndev);
3148        pwdev_priv = adapter_wdev_data(padapter);
3149
3150        /* cookie generation */
3151        *cookie = (unsigned long) buf;
3152
3153#ifdef DEBUG_CFG80211
3154        DBG_871X(FUNC_ADPT_FMT" len =%zu, ch =%d"
3155                "\n", FUNC_ADPT_ARG(padapter),
3156                len, tx_ch
3157        );
3158#endif /* DEBUG_CFG80211 */
3159
3160        /* indicate ack before issue frame to avoid racing with rsp frame */
3161        rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack, GFP_KERNEL);
3162
3163        if (rtw_action_frame_parse(buf, len, &category, &action) == false) {
3164                DBG_8192C(FUNC_ADPT_FMT" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter),
3165                        le16_to_cpu(((struct ieee80211_hdr_3addr *)buf)->frame_control));
3166                goto exit;
3167        }
3168
3169        DBG_8192C("RTW_Tx:tx_ch =%d, da ="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf)));
3170        if (category == RTW_WLAN_CATEGORY_PUBLIC)
3171                DBG_871X("RTW_Tx:%s\n", action_public_str(action));
3172        else
3173                DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
3174
3175        rtw_ps_deny(padapter, PS_DENY_MGNT_TX);
3176        if (_FAIL == rtw_pwr_wakeup(padapter)) {
3177                ret = -EFAULT;
3178                goto cancel_ps_deny;
3179        }
3180
3181        do {
3182                dump_cnt++;
3183                tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
3184        } while (dump_cnt < dump_limit && tx_ret != _SUCCESS);
3185
3186        if (tx_ret != _SUCCESS || dump_cnt > 1) {
3187                DBG_871X(FUNC_ADPT_FMT" %s (%d/%d)\n", FUNC_ADPT_ARG(padapter),
3188                        tx_ret == _SUCCESS?"OK":"FAIL", dump_cnt, dump_limit);
3189        }
3190
3191        switch (type) {
3192        case P2P_GO_NEGO_CONF:
3193                rtw_clear_scan_deny(padapter);
3194                break;
3195        case P2P_INVIT_RESP:
3196                if (pwdev_priv->invit_info.flags & BIT(0)
3197                        && pwdev_priv->invit_info.status == 0)
3198                {
3199                        DBG_871X(FUNC_ADPT_FMT" agree with invitation of persistent group\n",
3200                                FUNC_ADPT_ARG(padapter));
3201                        rtw_set_scan_deny(padapter, 5000);
3202                        rtw_pwr_wakeup_ex(padapter, 5000);
3203                        rtw_clear_scan_deny(padapter);
3204                }
3205                break;
3206        }
3207
3208cancel_ps_deny:
3209        rtw_ps_deny_cancel(padapter, PS_DENY_MGNT_TX);
3210exit:
3211        return ret;
3212}
3213
3214static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
3215        struct wireless_dev *wdev,
3216        u16 frame_type, bool reg)
3217{
3218        struct net_device *ndev = wdev_to_ndev(wdev);
3219        struct adapter *adapter;
3220
3221        if (ndev == NULL)
3222                goto exit;
3223
3224        adapter = (struct adapter *)rtw_netdev_priv(ndev);
3225
3226#ifdef DEBUG_CFG80211
3227        DBG_871X(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter),
3228                frame_type, reg);
3229#endif
3230
3231        if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
3232                return;
3233exit:
3234        return;
3235}
3236
3237#if defined(CONFIG_PNO_SUPPORT)
3238static int cfg80211_rtw_sched_scan_start(struct wiphy *wiphy,
3239                struct net_device *dev,
3240                struct cfg80211_sched_scan_request *request) {
3241
3242        struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
3243        struct  mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3244        int ret;
3245
3246        if (padapter->bup == false) {
3247                DBG_871X("%s: net device is down.\n", __func__);
3248                return -EIO;
3249        }
3250
3251        if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true ||
3252                check_fwstate(pmlmepriv, _FW_LINKED) == true  ||
3253                check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) {
3254                DBG_871X("%s: device is busy.\n", __func__);
3255                rtw_scan_abort(padapter);
3256        }
3257
3258        if (request == NULL) {
3259                DBG_871X("%s: invalid cfg80211_requests parameters.\n", __func__);
3260                return -EINVAL;
3261        }
3262
3263        ret = rtw_android_cfg80211_pno_setup(dev, request->ssids,
3264                        request->n_ssids, request->interval);
3265
3266        if (ret < 0) {
3267                DBG_871X("%s ret: %d\n", __func__, ret);
3268                goto exit;
3269        }
3270
3271        ret = rtw_android_pno_enable(dev, true);
3272        if (ret < 0) {
3273                DBG_871X("%s ret: %d\n", __func__, ret);
3274                goto exit;
3275        }
3276exit:
3277        return ret;
3278}
3279
3280static int cfg80211_rtw_sched_scan_stop(struct wiphy *wiphy,
3281                struct net_device *dev) {
3282        return rtw_android_pno_enable(dev, false);
3283}
3284#endif /* CONFIG_PNO_SUPPORT */
3285
3286static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, enum nl80211_band band, u8 rf_type)
3287{
3288
3289#define MAX_BIT_RATE_40MHZ_MCS15        300     /* Mbps */
3290#define MAX_BIT_RATE_40MHZ_MCS7         150     /* Mbps */
3291
3292        ht_cap->ht_supported = true;
3293
3294        ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
3295                                        IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
3296                                        IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
3297
3298        /*
3299         *Maximum length of AMPDU that the STA can receive.
3300         *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
3301         */
3302        ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
3303
3304        /*Minimum MPDU start spacing , */
3305        ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
3306
3307        ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
3308
3309        /*
3310         *hw->wiphy->bands[NL80211_BAND_2GHZ]
3311         *base on ant_num
3312         *rx_mask: RX mask
3313         *if rx_ant = 1 rx_mask[0]= 0xff;==>MCS0-MCS7
3314         *if rx_ant =2 rx_mask[1]= 0xff;==>MCS8-MCS15
3315         *if rx_ant >=3 rx_mask[2]= 0xff;
3316         *if BW_40 rx_mask[4]= 0x01;
3317         *highest supported RX rate
3318         */
3319        if (rf_type == RF_1T1R)
3320        {
3321                ht_cap->mcs.rx_mask[0] = 0xFF;
3322                ht_cap->mcs.rx_mask[1] = 0x00;
3323                ht_cap->mcs.rx_mask[4] = 0x01;
3324
3325                ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7);
3326        }
3327        else if ((rf_type == RF_1T2R) || (rf_type ==RF_2T2R))
3328        {
3329                ht_cap->mcs.rx_mask[0] = 0xFF;
3330                ht_cap->mcs.rx_mask[1] = 0xFF;
3331                ht_cap->mcs.rx_mask[4] = 0x01;
3332
3333                ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15);
3334        }
3335        else
3336        {
3337                DBG_8192C("%s, error rf_type =%d\n", __func__, rf_type);
3338        }
3339
3340}
3341
3342void rtw_cfg80211_init_wiphy(struct adapter *padapter)
3343{
3344        u8 rf_type;
3345        struct ieee80211_supported_band *bands;
3346        struct wireless_dev *pwdev = padapter->rtw_wdev;
3347        struct wiphy *wiphy = pwdev->wiphy;
3348
3349        rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
3350
3351        DBG_8192C("%s:rf_type =%d\n", __func__, rf_type);
3352
3353        {
3354                bands = wiphy->bands[NL80211_BAND_2GHZ];
3355                if (bands)
3356                        rtw_cfg80211_init_ht_capab(&bands->ht_cap, NL80211_BAND_2GHZ, rf_type);
3357        }
3358
3359        /* init regulary domain */
3360        rtw_regd_init(padapter, rtw_reg_notifier);
3361
3362        /* copy mac_addr to wiphy */
3363        memcpy(wiphy->perm_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
3364
3365}
3366
3367static void rtw_cfg80211_preinit_wiphy(struct adapter *padapter, struct wiphy *wiphy)
3368{
3369
3370        wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3371
3372        wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
3373        wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX;
3374        wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
3375
3376        wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
3377
3378        wiphy->interface_modes =        BIT(NL80211_IFTYPE_STATION)
3379                                                                | BIT(NL80211_IFTYPE_ADHOC)
3380                                                                | BIT(NL80211_IFTYPE_AP)
3381                                                                | BIT(NL80211_IFTYPE_MONITOR)
3382                                                                ;
3383
3384        wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
3385
3386        wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
3387
3388        wiphy->cipher_suites = rtw_cipher_suites;
3389        wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
3390
3391        /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
3392        wiphy->bands[NL80211_BAND_2GHZ] = rtw_spt_band_alloc(NL80211_BAND_2GHZ);
3393
3394        wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
3395        wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
3396
3397#if defined(CONFIG_PM)
3398        wiphy->max_sched_scan_reqs = 1;
3399#ifdef CONFIG_PNO_SUPPORT
3400        wiphy->max_sched_scan_ssids = MAX_PNO_LIST_COUNT;
3401#endif
3402#endif
3403
3404#if defined(CONFIG_PM)
3405        wiphy->wowlan = &wowlan_stub;
3406#endif
3407
3408        if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
3409                wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
3410        else
3411                wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
3412}
3413
3414static struct cfg80211_ops rtw_cfg80211_ops = {
3415        .change_virtual_intf = cfg80211_rtw_change_iface,
3416        .add_key = cfg80211_rtw_add_key,
3417        .get_key = cfg80211_rtw_get_key,
3418        .del_key = cfg80211_rtw_del_key,
3419        .set_default_key = cfg80211_rtw_set_default_key,
3420        .get_station = cfg80211_rtw_get_station,
3421        .scan = cfg80211_rtw_scan,
3422        .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
3423        .connect = cfg80211_rtw_connect,
3424        .disconnect = cfg80211_rtw_disconnect,
3425        .join_ibss = cfg80211_rtw_join_ibss,
3426        .leave_ibss = cfg80211_rtw_leave_ibss,
3427        .set_tx_power = cfg80211_rtw_set_txpower,
3428        .get_tx_power = cfg80211_rtw_get_txpower,
3429        .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
3430        .set_pmksa = cfg80211_rtw_set_pmksa,
3431        .del_pmksa = cfg80211_rtw_del_pmksa,
3432        .flush_pmksa = cfg80211_rtw_flush_pmksa,
3433
3434        .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
3435        .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
3436
3437        .start_ap = cfg80211_rtw_start_ap,
3438        .change_beacon = cfg80211_rtw_change_beacon,
3439        .stop_ap = cfg80211_rtw_stop_ap,
3440
3441        .add_station = cfg80211_rtw_add_station,
3442        .del_station = cfg80211_rtw_del_station,
3443        .change_station = cfg80211_rtw_change_station,
3444        .dump_station = cfg80211_rtw_dump_station,
3445        .change_bss = cfg80211_rtw_change_bss,
3446
3447        .mgmt_tx = cfg80211_rtw_mgmt_tx,
3448        .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
3449
3450#if defined(CONFIG_PNO_SUPPORT)
3451        .sched_scan_start = cfg80211_rtw_sched_scan_start,
3452        .sched_scan_stop = cfg80211_rtw_sched_scan_stop,
3453#endif /* CONFIG_PNO_SUPPORT */
3454};
3455
3456int rtw_wdev_alloc(struct adapter *padapter, struct device *dev)
3457{
3458        int ret = 0;
3459        struct wiphy *wiphy;
3460        struct wireless_dev *wdev;
3461        struct rtw_wdev_priv *pwdev_priv;
3462        struct net_device *pnetdev = padapter->pnetdev;
3463
3464        DBG_8192C("%s(padapter =%p)\n", __func__, padapter);
3465
3466        /* wiphy */
3467        wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct adapter *));
3468        if (!wiphy) {
3469                DBG_8192C("Couldn't allocate wiphy device\n");
3470                ret = -ENOMEM;
3471                goto exit;
3472        }
3473        set_wiphy_dev(wiphy, dev);
3474        *((struct adapter **)wiphy_priv(wiphy)) = padapter;
3475        rtw_cfg80211_preinit_wiphy(padapter, wiphy);
3476
3477        ret = wiphy_register(wiphy);
3478        if (ret < 0) {
3479                DBG_8192C("Couldn't register wiphy device\n");
3480                goto free_wiphy;
3481        }
3482
3483        /*  wdev */
3484        wdev = rtw_zmalloc(sizeof(struct wireless_dev));
3485        if (!wdev) {
3486                DBG_8192C("Couldn't allocate wireless device\n");
3487                ret = -ENOMEM;
3488                goto unregister_wiphy;
3489        }
3490        wdev->wiphy = wiphy;
3491        wdev->netdev = pnetdev;
3492
3493        wdev->iftype = NL80211_IFTYPE_STATION; /*  will be init in rtw_hal_init() */
3494                                               /*  Must sync with _rtw_init_mlme_priv() */
3495                                           /*  pmlmepriv->fw_state = WIFI_STATION_STATE */
3496        padapter->rtw_wdev = wdev;
3497        pnetdev->ieee80211_ptr = wdev;
3498
3499        /* init pwdev_priv */
3500        pwdev_priv = adapter_wdev_data(padapter);
3501        pwdev_priv->rtw_wdev = wdev;
3502        pwdev_priv->pmon_ndev = NULL;
3503        pwdev_priv->ifname_mon[0] = '\0';
3504        pwdev_priv->padapter = padapter;
3505        pwdev_priv->scan_request = NULL;
3506        spin_lock_init(&pwdev_priv->scan_req_lock);
3507
3508        pwdev_priv->p2p_enabled = false;
3509        pwdev_priv->provdisc_req_issued = false;
3510        rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
3511        rtw_wdev_nego_info_init(&pwdev_priv->nego_info);
3512
3513        pwdev_priv->bandroid_scan = false;
3514
3515        if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
3516                pwdev_priv->power_mgmt = true;
3517        else
3518                pwdev_priv->power_mgmt = false;
3519
3520        return ret;
3521
3522unregister_wiphy:
3523        wiphy_unregister(wiphy);
3524 free_wiphy:
3525        wiphy_free(wiphy);
3526exit:
3527        return ret;
3528
3529}
3530
3531void rtw_wdev_free(struct wireless_dev *wdev)
3532{
3533        DBG_8192C("%s(wdev =%p)\n", __func__, wdev);
3534
3535        if (!wdev)
3536                return;
3537
3538        rtw_spt_band_free(wdev->wiphy->bands[NL80211_BAND_2GHZ]);
3539
3540        wiphy_free(wdev->wiphy);
3541
3542        kfree((u8 *)wdev);
3543}
3544
3545void rtw_wdev_unregister(struct wireless_dev *wdev)
3546{
3547        struct net_device *ndev;
3548        struct adapter *adapter;
3549        struct rtw_wdev_priv *pwdev_priv;
3550
3551        DBG_8192C("%s(wdev =%p)\n", __func__, wdev);
3552
3553        if (!wdev)
3554                return;
3555
3556        if (!(ndev = wdev_to_ndev(wdev)))
3557                return;
3558
3559        adapter = (struct adapter *)rtw_netdev_priv(ndev);
3560        pwdev_priv = adapter_wdev_data(adapter);
3561
3562        rtw_cfg80211_indicate_scan_done(adapter, true);
3563
3564        if (pwdev_priv->pmon_ndev) {
3565                DBG_8192C("%s, unregister monitor interface\n", __func__);
3566                unregister_netdev(pwdev_priv->pmon_ndev);
3567        }
3568
3569        wiphy_unregister(wdev->wiphy);
3570}
3571