linux/net/wireless/sme.c
<<
>>
Prefs
   1/*
   2 * SME code for cfg80211
   3 * both driver SME event handling and the SME implementation
   4 * (for nl80211's connect() and wext)
   5 *
   6 * Copyright 2009       Johannes Berg <johannes@sipsolutions.net>
   7 * Copyright (C) 2009   Intel Corporation. All rights reserved.
   8 */
   9
  10#include <linux/etherdevice.h>
  11#include <linux/if_arp.h>
  12#include <linux/slab.h>
  13#include <linux/workqueue.h>
  14#include <linux/wireless.h>
  15#include <linux/export.h>
  16#include <net/iw_handler.h>
  17#include <net/cfg80211.h>
  18#include <net/rtnetlink.h>
  19#include "nl80211.h"
  20#include "reg.h"
  21#include "rdev-ops.h"
  22
  23/*
  24 * Software SME in cfg80211, using auth/assoc/deauth calls to the
  25 * driver. This is is for implementing nl80211's connect/disconnect
  26 * and wireless extensions (if configured.)
  27 */
  28
  29struct cfg80211_conn {
  30        struct cfg80211_connect_params params;
  31        /* these are sub-states of the _CONNECTING sme_state */
  32        enum {
  33                CFG80211_CONN_SCANNING,
  34                CFG80211_CONN_SCAN_AGAIN,
  35                CFG80211_CONN_AUTHENTICATE_NEXT,
  36                CFG80211_CONN_AUTHENTICATING,
  37                CFG80211_CONN_AUTH_FAILED,
  38                CFG80211_CONN_ASSOCIATE_NEXT,
  39                CFG80211_CONN_ASSOCIATING,
  40                CFG80211_CONN_ASSOC_FAILED,
  41                CFG80211_CONN_DEAUTH,
  42                CFG80211_CONN_CONNECTED,
  43        } state;
  44        u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
  45        u8 *ie;
  46        size_t ie_len;
  47        bool auto_auth, prev_bssid_valid;
  48};
  49
  50static void cfg80211_sme_free(struct wireless_dev *wdev)
  51{
  52        if (!wdev->conn)
  53                return;
  54
  55        kfree(wdev->conn->ie);
  56        kfree(wdev->conn);
  57        wdev->conn = NULL;
  58}
  59
  60static int cfg80211_conn_scan(struct wireless_dev *wdev)
  61{
  62        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
  63        struct cfg80211_scan_request *request;
  64        int n_channels, err;
  65
  66        ASSERT_RTNL();
  67        ASSERT_RDEV_LOCK(rdev);
  68        ASSERT_WDEV_LOCK(wdev);
  69
  70        if (rdev->scan_req)
  71                return -EBUSY;
  72
  73        if (wdev->conn->params.channel) {
  74                n_channels = 1;
  75        } else {
  76                enum ieee80211_band band;
  77                n_channels = 0;
  78
  79                for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
  80                        if (!wdev->wiphy->bands[band])
  81                                continue;
  82                        n_channels += wdev->wiphy->bands[band]->n_channels;
  83                }
  84        }
  85        request = kzalloc(sizeof(*request) + sizeof(request->ssids[0]) +
  86                          sizeof(request->channels[0]) * n_channels,
  87                          GFP_KERNEL);
  88        if (!request)
  89                return -ENOMEM;
  90
  91        if (wdev->conn->params.channel)
  92                request->channels[0] = wdev->conn->params.channel;
  93        else {
  94                int i = 0, j;
  95                enum ieee80211_band band;
  96                struct ieee80211_supported_band *bands;
  97                struct ieee80211_channel *channel;
  98
  99                for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
 100                        bands = wdev->wiphy->bands[band];
 101                        if (!bands)
 102                                continue;
 103                        for (j = 0; j < bands->n_channels; j++) {
 104                                channel = &bands->channels[j];
 105                                if (channel->flags & IEEE80211_CHAN_DISABLED)
 106                                        continue;
 107                                request->channels[i++] = channel;
 108                        }
 109                        request->rates[band] = (1 << bands->n_bitrates) - 1;
 110                }
 111                n_channels = i;
 112        }
 113        request->n_channels = n_channels;
 114        request->ssids = (void *)&request->channels[n_channels];
 115        request->n_ssids = 1;
 116
 117        memcpy(request->ssids[0].ssid, wdev->conn->params.ssid,
 118                wdev->conn->params.ssid_len);
 119        request->ssids[0].ssid_len = wdev->conn->params.ssid_len;
 120
 121        request->wdev = wdev;
 122        request->wiphy = &rdev->wiphy;
 123        request->scan_start = jiffies;
 124
 125        rdev->scan_req = request;
 126
 127        err = rdev_scan(rdev, request);
 128        if (!err) {
 129                wdev->conn->state = CFG80211_CONN_SCANNING;
 130                nl80211_send_scan_start(rdev, wdev);
 131                dev_hold(wdev->netdev);
 132        } else {
 133                rdev->scan_req = NULL;
 134                kfree(request);
 135        }
 136        return err;
 137}
 138
 139static int cfg80211_conn_do_work(struct wireless_dev *wdev)
 140{
 141        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 142        struct cfg80211_connect_params *params;
 143        struct cfg80211_assoc_request req = {};
 144        int err;
 145
 146        ASSERT_WDEV_LOCK(wdev);
 147
 148        if (!wdev->conn)
 149                return 0;
 150
 151        params = &wdev->conn->params;
 152
 153        switch (wdev->conn->state) {
 154        case CFG80211_CONN_SCANNING:
 155                /* didn't find it during scan ... */
 156                return -ENOENT;
 157        case CFG80211_CONN_SCAN_AGAIN:
 158                return cfg80211_conn_scan(wdev);
 159        case CFG80211_CONN_AUTHENTICATE_NEXT:
 160                BUG_ON(!rdev->ops->auth);
 161                wdev->conn->state = CFG80211_CONN_AUTHENTICATING;
 162                return cfg80211_mlme_auth(rdev, wdev->netdev,
 163                                          params->channel, params->auth_type,
 164                                          params->bssid,
 165                                          params->ssid, params->ssid_len,
 166                                          NULL, 0,
 167                                          params->key, params->key_len,
 168                                          params->key_idx, NULL, 0);
 169        case CFG80211_CONN_AUTH_FAILED:
 170                return -ENOTCONN;
 171        case CFG80211_CONN_ASSOCIATE_NEXT:
 172                BUG_ON(!rdev->ops->assoc);
 173                wdev->conn->state = CFG80211_CONN_ASSOCIATING;
 174                if (wdev->conn->prev_bssid_valid)
 175                        req.prev_bssid = wdev->conn->prev_bssid;
 176                req.ie = params->ie;
 177                req.ie_len = params->ie_len;
 178                req.use_mfp = params->mfp != NL80211_MFP_NO;
 179                req.crypto = params->crypto;
 180                req.flags = params->flags;
 181                req.ht_capa = params->ht_capa;
 182                req.ht_capa_mask = params->ht_capa_mask;
 183                req.vht_capa = params->vht_capa;
 184                req.vht_capa_mask = params->vht_capa_mask;
 185
 186                err = cfg80211_mlme_assoc(rdev, wdev->netdev, params->channel,
 187                                          params->bssid, params->ssid,
 188                                          params->ssid_len, &req);
 189                if (err)
 190                        cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
 191                                             NULL, 0,
 192                                             WLAN_REASON_DEAUTH_LEAVING,
 193                                             false);
 194                return err;
 195        case CFG80211_CONN_ASSOC_FAILED:
 196                cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
 197                                     NULL, 0,
 198                                     WLAN_REASON_DEAUTH_LEAVING, false);
 199                return -ENOTCONN;
 200        case CFG80211_CONN_DEAUTH:
 201                cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
 202                                     NULL, 0,
 203                                     WLAN_REASON_DEAUTH_LEAVING, false);
 204                /* free directly, disconnected event already sent */
 205                cfg80211_sme_free(wdev);
 206                return 0;
 207        default:
 208                return 0;
 209        }
 210}
 211
 212void cfg80211_conn_work(struct work_struct *work)
 213{
 214        struct cfg80211_registered_device *rdev =
 215                container_of(work, struct cfg80211_registered_device, conn_work);
 216        struct wireless_dev *wdev;
 217        u8 bssid_buf[ETH_ALEN], *bssid = NULL;
 218
 219        rtnl_lock();
 220
 221        list_for_each_entry(wdev, &rdev->wdev_list, list) {
 222                if (!wdev->netdev)
 223                        continue;
 224
 225                wdev_lock(wdev);
 226                if (!netif_running(wdev->netdev)) {
 227                        wdev_unlock(wdev);
 228                        continue;
 229                }
 230                if (!wdev->conn ||
 231                    wdev->conn->state == CFG80211_CONN_CONNECTED) {
 232                        wdev_unlock(wdev);
 233                        continue;
 234                }
 235                if (wdev->conn->params.bssid) {
 236                        memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN);
 237                        bssid = bssid_buf;
 238                }
 239                if (cfg80211_conn_do_work(wdev)) {
 240                        __cfg80211_connect_result(
 241                                        wdev->netdev, bssid,
 242                                        NULL, 0, NULL, 0,
 243                                        WLAN_STATUS_UNSPECIFIED_FAILURE,
 244                                        false, NULL);
 245                        cfg80211_sme_free(wdev);
 246                }
 247                wdev_unlock(wdev);
 248        }
 249
 250        rtnl_unlock();
 251}
 252
 253/* Returned bss is reference counted and must be cleaned up appropriately. */
 254static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
 255{
 256        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 257        struct cfg80211_bss *bss;
 258        u16 capa = WLAN_CAPABILITY_ESS;
 259
 260        ASSERT_WDEV_LOCK(wdev);
 261
 262        if (wdev->conn->params.privacy)
 263                capa |= WLAN_CAPABILITY_PRIVACY;
 264
 265        bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel,
 266                               wdev->conn->params.bssid,
 267                               wdev->conn->params.ssid,
 268                               wdev->conn->params.ssid_len,
 269                               WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
 270                               capa);
 271        if (!bss)
 272                return NULL;
 273
 274        memcpy(wdev->conn->bssid, bss->bssid, ETH_ALEN);
 275        wdev->conn->params.bssid = wdev->conn->bssid;
 276        wdev->conn->params.channel = bss->channel;
 277        wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
 278        schedule_work(&rdev->conn_work);
 279
 280        return bss;
 281}
 282
 283static void __cfg80211_sme_scan_done(struct net_device *dev)
 284{
 285        struct wireless_dev *wdev = dev->ieee80211_ptr;
 286        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 287        struct cfg80211_bss *bss;
 288
 289        ASSERT_WDEV_LOCK(wdev);
 290
 291        if (!wdev->conn)
 292                return;
 293
 294        if (wdev->conn->state != CFG80211_CONN_SCANNING &&
 295            wdev->conn->state != CFG80211_CONN_SCAN_AGAIN)
 296                return;
 297
 298        bss = cfg80211_get_conn_bss(wdev);
 299        if (bss)
 300                cfg80211_put_bss(&rdev->wiphy, bss);
 301        else
 302                schedule_work(&rdev->conn_work);
 303}
 304
 305void cfg80211_sme_scan_done(struct net_device *dev)
 306{
 307        struct wireless_dev *wdev = dev->ieee80211_ptr;
 308
 309        wdev_lock(wdev);
 310        __cfg80211_sme_scan_done(dev);
 311        wdev_unlock(wdev);
 312}
 313
 314void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len)
 315{
 316        struct wiphy *wiphy = wdev->wiphy;
 317        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 318        struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 319        u16 status_code = le16_to_cpu(mgmt->u.auth.status_code);
 320
 321        ASSERT_WDEV_LOCK(wdev);
 322
 323        if (!wdev->conn || wdev->conn->state == CFG80211_CONN_CONNECTED)
 324                return;
 325
 326        if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG &&
 327            wdev->conn->auto_auth &&
 328            wdev->conn->params.auth_type != NL80211_AUTHTYPE_NETWORK_EAP) {
 329                /* select automatically between only open, shared, leap */
 330                switch (wdev->conn->params.auth_type) {
 331                case NL80211_AUTHTYPE_OPEN_SYSTEM:
 332                        if (wdev->connect_keys)
 333                                wdev->conn->params.auth_type =
 334                                        NL80211_AUTHTYPE_SHARED_KEY;
 335                        else
 336                                wdev->conn->params.auth_type =
 337                                        NL80211_AUTHTYPE_NETWORK_EAP;
 338                        break;
 339                case NL80211_AUTHTYPE_SHARED_KEY:
 340                        wdev->conn->params.auth_type =
 341                                NL80211_AUTHTYPE_NETWORK_EAP;
 342                        break;
 343                default:
 344                        /* huh? */
 345                        wdev->conn->params.auth_type =
 346                                NL80211_AUTHTYPE_OPEN_SYSTEM;
 347                        break;
 348                }
 349                wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
 350                schedule_work(&rdev->conn_work);
 351        } else if (status_code != WLAN_STATUS_SUCCESS) {
 352                __cfg80211_connect_result(wdev->netdev, mgmt->bssid,
 353                                          NULL, 0, NULL, 0,
 354                                          status_code, false, NULL);
 355        } else if (wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
 356                wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
 357                schedule_work(&rdev->conn_work);
 358        }
 359}
 360
 361bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status)
 362{
 363        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 364
 365        if (!wdev->conn)
 366                return false;
 367
 368        if (status == WLAN_STATUS_SUCCESS) {
 369                wdev->conn->state = CFG80211_CONN_CONNECTED;
 370                return false;
 371        }
 372
 373        if (wdev->conn->prev_bssid_valid) {
 374                /*
 375                 * Some stupid APs don't accept reassoc, so we
 376                 * need to fall back to trying regular assoc;
 377                 * return true so no event is sent to userspace.
 378                 */
 379                wdev->conn->prev_bssid_valid = false;
 380                wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
 381                schedule_work(&rdev->conn_work);
 382                return true;
 383        }
 384
 385        wdev->conn->state = CFG80211_CONN_ASSOC_FAILED;
 386        schedule_work(&rdev->conn_work);
 387        return false;
 388}
 389
 390void cfg80211_sme_deauth(struct wireless_dev *wdev)
 391{
 392        cfg80211_sme_free(wdev);
 393}
 394
 395void cfg80211_sme_auth_timeout(struct wireless_dev *wdev)
 396{
 397        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 398
 399        if (!wdev->conn)
 400                return;
 401
 402        wdev->conn->state = CFG80211_CONN_AUTH_FAILED;
 403        schedule_work(&rdev->conn_work);
 404}
 405
 406void cfg80211_sme_disassoc(struct wireless_dev *wdev)
 407{
 408        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 409
 410        if (!wdev->conn)
 411                return;
 412
 413        wdev->conn->state = CFG80211_CONN_DEAUTH;
 414        schedule_work(&rdev->conn_work);
 415}
 416
 417void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev)
 418{
 419        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 420
 421        if (!wdev->conn)
 422                return;
 423
 424        wdev->conn->state = CFG80211_CONN_ASSOC_FAILED;
 425        schedule_work(&rdev->conn_work);
 426}
 427
 428static int cfg80211_sme_connect(struct wireless_dev *wdev,
 429                                struct cfg80211_connect_params *connect,
 430                                const u8 *prev_bssid)
 431{
 432        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 433        struct cfg80211_bss *bss;
 434        int err;
 435
 436        if (!rdev->ops->auth || !rdev->ops->assoc)
 437                return -EOPNOTSUPP;
 438
 439        if (wdev->current_bss)
 440                return -EALREADY;
 441
 442        if (WARN_ON(wdev->conn))
 443                return -EINPROGRESS;
 444
 445        wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL);
 446        if (!wdev->conn)
 447                return -ENOMEM;
 448
 449        /*
 450         * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
 451         */
 452        memcpy(&wdev->conn->params, connect, sizeof(*connect));
 453        if (connect->bssid) {
 454                wdev->conn->params.bssid = wdev->conn->bssid;
 455                memcpy(wdev->conn->bssid, connect->bssid, ETH_ALEN);
 456        }
 457
 458        if (connect->ie) {
 459                wdev->conn->ie = kmemdup(connect->ie, connect->ie_len,
 460                                        GFP_KERNEL);
 461                wdev->conn->params.ie = wdev->conn->ie;
 462                if (!wdev->conn->ie) {
 463                        kfree(wdev->conn);
 464                        wdev->conn = NULL;
 465                        return -ENOMEM;
 466                }
 467        }
 468
 469        if (connect->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
 470                wdev->conn->auto_auth = true;
 471                /* start with open system ... should mostly work */
 472                wdev->conn->params.auth_type =
 473                        NL80211_AUTHTYPE_OPEN_SYSTEM;
 474        } else {
 475                wdev->conn->auto_auth = false;
 476        }
 477
 478        wdev->conn->params.ssid = wdev->ssid;
 479        wdev->conn->params.ssid_len = connect->ssid_len;
 480
 481        /* see if we have the bss already */
 482        bss = cfg80211_get_conn_bss(wdev);
 483
 484        if (prev_bssid) {
 485                memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN);
 486                wdev->conn->prev_bssid_valid = true;
 487        }
 488
 489        /* we're good if we have a matching bss struct */
 490        if (bss) {
 491                wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
 492                err = cfg80211_conn_do_work(wdev);
 493                cfg80211_put_bss(wdev->wiphy, bss);
 494        } else {
 495                /* otherwise we'll need to scan for the AP first */
 496                err = cfg80211_conn_scan(wdev);
 497
 498                /*
 499                 * If we can't scan right now, then we need to scan again
 500                 * after the current scan finished, since the parameters
 501                 * changed (unless we find a good AP anyway).
 502                 */
 503                if (err == -EBUSY) {
 504                        err = 0;
 505                        wdev->conn->state = CFG80211_CONN_SCAN_AGAIN;
 506                }
 507        }
 508
 509        if (err)
 510                cfg80211_sme_free(wdev);
 511
 512        return err;
 513}
 514
 515static int cfg80211_sme_disconnect(struct wireless_dev *wdev, u16 reason)
 516{
 517        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 518        int err;
 519
 520        if (!wdev->conn)
 521                return 0;
 522
 523        if (!rdev->ops->deauth)
 524                return -EOPNOTSUPP;
 525
 526        if (wdev->conn->state == CFG80211_CONN_SCANNING ||
 527            wdev->conn->state == CFG80211_CONN_SCAN_AGAIN) {
 528                err = 0;
 529                goto out;
 530        }
 531
 532        /* wdev->conn->params.bssid must be set if > SCANNING */
 533        err = cfg80211_mlme_deauth(rdev, wdev->netdev,
 534                                   wdev->conn->params.bssid,
 535                                   NULL, 0, reason, false);
 536 out:
 537        cfg80211_sme_free(wdev);
 538        return err;
 539}
 540
 541/*
 542 * code shared for in-device and software SME
 543 */
 544
 545static bool cfg80211_is_all_idle(void)
 546{
 547        struct cfg80211_registered_device *rdev;
 548        struct wireless_dev *wdev;
 549        bool is_all_idle = true;
 550
 551        /*
 552         * All devices must be idle as otherwise if you are actively
 553         * scanning some new beacon hints could be learned and would
 554         * count as new regulatory hints.
 555         */
 556        list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
 557                list_for_each_entry(wdev, &rdev->wdev_list, list) {
 558                        wdev_lock(wdev);
 559                        if (wdev->conn || wdev->current_bss)
 560                                is_all_idle = false;
 561                        wdev_unlock(wdev);
 562                }
 563        }
 564
 565        return is_all_idle;
 566}
 567
 568static void disconnect_work(struct work_struct *work)
 569{
 570        rtnl_lock();
 571        if (cfg80211_is_all_idle())
 572                regulatory_hint_disconnect();
 573        rtnl_unlock();
 574}
 575
 576static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
 577
 578
 579/*
 580 * API calls for drivers implementing connect/disconnect and
 581 * SME event handling
 582 */
 583
 584/* This method must consume bss one way or another */
 585void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
 586                               const u8 *req_ie, size_t req_ie_len,
 587                               const u8 *resp_ie, size_t resp_ie_len,
 588                               u16 status, bool wextev,
 589                               struct cfg80211_bss *bss)
 590{
 591        struct wireless_dev *wdev = dev->ieee80211_ptr;
 592        const u8 *country_ie;
 593#ifdef CONFIG_CFG80211_WEXT
 594        union iwreq_data wrqu;
 595#endif
 596
 597        ASSERT_WDEV_LOCK(wdev);
 598
 599        if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
 600                    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) {
 601                cfg80211_put_bss(wdev->wiphy, bss);
 602                return;
 603        }
 604
 605        nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev,
 606                                    bssid, req_ie, req_ie_len,
 607                                    resp_ie, resp_ie_len,
 608                                    status, GFP_KERNEL);
 609
 610#ifdef CONFIG_CFG80211_WEXT
 611        if (wextev) {
 612                if (req_ie && status == WLAN_STATUS_SUCCESS) {
 613                        memset(&wrqu, 0, sizeof(wrqu));
 614                        wrqu.data.length = req_ie_len;
 615                        wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, req_ie);
 616                }
 617
 618                if (resp_ie && status == WLAN_STATUS_SUCCESS) {
 619                        memset(&wrqu, 0, sizeof(wrqu));
 620                        wrqu.data.length = resp_ie_len;
 621                        wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, resp_ie);
 622                }
 623
 624                memset(&wrqu, 0, sizeof(wrqu));
 625                wrqu.ap_addr.sa_family = ARPHRD_ETHER;
 626                if (bssid && status == WLAN_STATUS_SUCCESS) {
 627                        memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
 628                        memcpy(wdev->wext.prev_bssid, bssid, ETH_ALEN);
 629                        wdev->wext.prev_bssid_valid = true;
 630                }
 631                wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
 632        }
 633#endif
 634
 635        if (!bss && (status == WLAN_STATUS_SUCCESS)) {
 636                WARN_ON_ONCE(!wiphy_to_dev(wdev->wiphy)->ops->connect);
 637                bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
 638                                       wdev->ssid, wdev->ssid_len,
 639                                       WLAN_CAPABILITY_ESS,
 640                                       WLAN_CAPABILITY_ESS);
 641                if (bss)
 642                        cfg80211_hold_bss(bss_from_pub(bss));
 643        }
 644
 645        if (wdev->current_bss) {
 646                cfg80211_unhold_bss(wdev->current_bss);
 647                cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
 648                wdev->current_bss = NULL;
 649        }
 650
 651        if (status != WLAN_STATUS_SUCCESS) {
 652                kfree(wdev->connect_keys);
 653                wdev->connect_keys = NULL;
 654                wdev->ssid_len = 0;
 655                if (bss) {
 656                        cfg80211_unhold_bss(bss_from_pub(bss));
 657                        cfg80211_put_bss(wdev->wiphy, bss);
 658                }
 659                return;
 660        }
 661
 662        if (WARN_ON(!bss))
 663                return;
 664
 665        wdev->current_bss = bss_from_pub(bss);
 666
 667        cfg80211_upload_connect_keys(wdev);
 668
 669        rcu_read_lock();
 670        country_ie = ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
 671        if (!country_ie) {
 672                rcu_read_unlock();
 673                return;
 674        }
 675
 676        country_ie = kmemdup(country_ie, 2 + country_ie[1], GFP_ATOMIC);
 677        rcu_read_unlock();
 678
 679        if (!country_ie)
 680                return;
 681
 682        /*
 683         * ieee80211_bss_get_ie() ensures we can access:
 684         * - country_ie + 2, the start of the country ie data, and
 685         * - and country_ie[1] which is the IE length
 686         */
 687        regulatory_hint_country_ie(wdev->wiphy, bss->channel->band,
 688                                   country_ie + 2, country_ie[1]);
 689        kfree(country_ie);
 690}
 691
 692void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
 693                             const u8 *req_ie, size_t req_ie_len,
 694                             const u8 *resp_ie, size_t resp_ie_len,
 695                             u16 status, gfp_t gfp)
 696{
 697        struct wireless_dev *wdev = dev->ieee80211_ptr;
 698        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 699        struct cfg80211_event *ev;
 700        unsigned long flags;
 701
 702        ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
 703        if (!ev)
 704                return;
 705
 706        ev->type = EVENT_CONNECT_RESULT;
 707        if (bssid)
 708                memcpy(ev->cr.bssid, bssid, ETH_ALEN);
 709        if (req_ie_len) {
 710                ev->cr.req_ie = ((u8 *)ev) + sizeof(*ev);
 711                ev->cr.req_ie_len = req_ie_len;
 712                memcpy((void *)ev->cr.req_ie, req_ie, req_ie_len);
 713        }
 714        if (resp_ie_len) {
 715                ev->cr.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len;
 716                ev->cr.resp_ie_len = resp_ie_len;
 717                memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len);
 718        }
 719        ev->cr.status = status;
 720
 721        spin_lock_irqsave(&wdev->event_lock, flags);
 722        list_add_tail(&ev->list, &wdev->event_list);
 723        spin_unlock_irqrestore(&wdev->event_lock, flags);
 724        queue_work(cfg80211_wq, &rdev->event_work);
 725}
 726EXPORT_SYMBOL(cfg80211_connect_result);
 727
 728/* Consumes bss object one way or another */
 729void __cfg80211_roamed(struct wireless_dev *wdev,
 730                       struct cfg80211_bss *bss,
 731                       const u8 *req_ie, size_t req_ie_len,
 732                       const u8 *resp_ie, size_t resp_ie_len)
 733{
 734#ifdef CONFIG_CFG80211_WEXT
 735        union iwreq_data wrqu;
 736#endif
 737        ASSERT_WDEV_LOCK(wdev);
 738
 739        if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
 740                    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
 741                goto out;
 742
 743        if (WARN_ON(!wdev->current_bss))
 744                goto out;
 745
 746        cfg80211_unhold_bss(wdev->current_bss);
 747        cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
 748        wdev->current_bss = NULL;
 749
 750        cfg80211_hold_bss(bss_from_pub(bss));
 751        wdev->current_bss = bss_from_pub(bss);
 752
 753        nl80211_send_roamed(wiphy_to_dev(wdev->wiphy), wdev->netdev, bss->bssid,
 754                            req_ie, req_ie_len, resp_ie, resp_ie_len,
 755                            GFP_KERNEL);
 756
 757#ifdef CONFIG_CFG80211_WEXT
 758        if (req_ie) {
 759                memset(&wrqu, 0, sizeof(wrqu));
 760                wrqu.data.length = req_ie_len;
 761                wireless_send_event(wdev->netdev, IWEVASSOCREQIE,
 762                                    &wrqu, req_ie);
 763        }
 764
 765        if (resp_ie) {
 766                memset(&wrqu, 0, sizeof(wrqu));
 767                wrqu.data.length = resp_ie_len;
 768                wireless_send_event(wdev->netdev, IWEVASSOCRESPIE,
 769                                    &wrqu, resp_ie);
 770        }
 771
 772        memset(&wrqu, 0, sizeof(wrqu));
 773        wrqu.ap_addr.sa_family = ARPHRD_ETHER;
 774        memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN);
 775        memcpy(wdev->wext.prev_bssid, bss->bssid, ETH_ALEN);
 776        wdev->wext.prev_bssid_valid = true;
 777        wireless_send_event(wdev->netdev, SIOCGIWAP, &wrqu, NULL);
 778#endif
 779
 780        return;
 781out:
 782        cfg80211_put_bss(wdev->wiphy, bss);
 783}
 784
 785void cfg80211_roamed(struct net_device *dev,
 786                     struct ieee80211_channel *channel,
 787                     const u8 *bssid,
 788                     const u8 *req_ie, size_t req_ie_len,
 789                     const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
 790{
 791        struct wireless_dev *wdev = dev->ieee80211_ptr;
 792        struct cfg80211_bss *bss;
 793
 794        bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, wdev->ssid,
 795                               wdev->ssid_len, WLAN_CAPABILITY_ESS,
 796                               WLAN_CAPABILITY_ESS);
 797        if (WARN_ON(!bss))
 798                return;
 799
 800        cfg80211_roamed_bss(dev, bss, req_ie, req_ie_len, resp_ie,
 801                            resp_ie_len, gfp);
 802}
 803EXPORT_SYMBOL(cfg80211_roamed);
 804
 805/* Consumes bss object one way or another */
 806void cfg80211_roamed_bss(struct net_device *dev,
 807                         struct cfg80211_bss *bss, const u8 *req_ie,
 808                         size_t req_ie_len, const u8 *resp_ie,
 809                         size_t resp_ie_len, gfp_t gfp)
 810{
 811        struct wireless_dev *wdev = dev->ieee80211_ptr;
 812        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 813        struct cfg80211_event *ev;
 814        unsigned long flags;
 815
 816        if (WARN_ON(!bss))
 817                return;
 818
 819        ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
 820        if (!ev) {
 821                cfg80211_put_bss(wdev->wiphy, bss);
 822                return;
 823        }
 824
 825        ev->type = EVENT_ROAMED;
 826        ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev);
 827        ev->rm.req_ie_len = req_ie_len;
 828        memcpy((void *)ev->rm.req_ie, req_ie, req_ie_len);
 829        ev->rm.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len;
 830        ev->rm.resp_ie_len = resp_ie_len;
 831        memcpy((void *)ev->rm.resp_ie, resp_ie, resp_ie_len);
 832        ev->rm.bss = bss;
 833
 834        spin_lock_irqsave(&wdev->event_lock, flags);
 835        list_add_tail(&ev->list, &wdev->event_list);
 836        spin_unlock_irqrestore(&wdev->event_lock, flags);
 837        queue_work(cfg80211_wq, &rdev->event_work);
 838}
 839EXPORT_SYMBOL(cfg80211_roamed_bss);
 840
 841void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
 842                             size_t ie_len, u16 reason, bool from_ap)
 843{
 844        struct wireless_dev *wdev = dev->ieee80211_ptr;
 845        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 846        int i;
 847#ifdef CONFIG_CFG80211_WEXT
 848        union iwreq_data wrqu;
 849#endif
 850
 851        ASSERT_WDEV_LOCK(wdev);
 852
 853        if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
 854                    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
 855                return;
 856
 857        if (wdev->current_bss) {
 858                cfg80211_unhold_bss(wdev->current_bss);
 859                cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
 860        }
 861
 862        wdev->current_bss = NULL;
 863        wdev->ssid_len = 0;
 864
 865        nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);
 866
 867        /*
 868         * Delete all the keys ... pairwise keys can't really
 869         * exist any more anyway, but default keys might.
 870         */
 871        if (rdev->ops->del_key)
 872                for (i = 0; i < 6; i++)
 873                        rdev_del_key(rdev, dev, i, false, NULL);
 874
 875#ifdef CONFIG_CFG80211_WEXT
 876        memset(&wrqu, 0, sizeof(wrqu));
 877        wrqu.ap_addr.sa_family = ARPHRD_ETHER;
 878        wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
 879        wdev->wext.connect.ssid_len = 0;
 880#endif
 881
 882        schedule_work(&cfg80211_disconnect_work);
 883}
 884
 885void cfg80211_disconnected(struct net_device *dev, u16 reason,
 886                           u8 *ie, size_t ie_len, gfp_t gfp)
 887{
 888        struct wireless_dev *wdev = dev->ieee80211_ptr;
 889        struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 890        struct cfg80211_event *ev;
 891        unsigned long flags;
 892
 893        ev = kzalloc(sizeof(*ev) + ie_len, gfp);
 894        if (!ev)
 895                return;
 896
 897        ev->type = EVENT_DISCONNECTED;
 898        ev->dc.ie = ((u8 *)ev) + sizeof(*ev);
 899        ev->dc.ie_len = ie_len;
 900        memcpy((void *)ev->dc.ie, ie, ie_len);
 901        ev->dc.reason = reason;
 902
 903        spin_lock_irqsave(&wdev->event_lock, flags);
 904        list_add_tail(&ev->list, &wdev->event_list);
 905        spin_unlock_irqrestore(&wdev->event_lock, flags);
 906        queue_work(cfg80211_wq, &rdev->event_work);
 907}
 908EXPORT_SYMBOL(cfg80211_disconnected);
 909
 910/*
 911 * API calls for nl80211/wext compatibility code
 912 */
 913int cfg80211_connect(struct cfg80211_registered_device *rdev,
 914                     struct net_device *dev,
 915                     struct cfg80211_connect_params *connect,
 916                     struct cfg80211_cached_keys *connkeys,
 917                     const u8 *prev_bssid)
 918{
 919        struct wireless_dev *wdev = dev->ieee80211_ptr;
 920        int err;
 921
 922        ASSERT_WDEV_LOCK(wdev);
 923
 924        if (WARN_ON(wdev->connect_keys)) {
 925                kfree(wdev->connect_keys);
 926                wdev->connect_keys = NULL;
 927        }
 928
 929        cfg80211_oper_and_ht_capa(&connect->ht_capa_mask,
 930                                  rdev->wiphy.ht_capa_mod_mask);
 931
 932        if (connkeys && connkeys->def >= 0) {
 933                int idx;
 934                u32 cipher;
 935
 936                idx = connkeys->def;
 937                cipher = connkeys->params[idx].cipher;
 938                /* If given a WEP key we may need it for shared key auth */
 939                if (cipher == WLAN_CIPHER_SUITE_WEP40 ||
 940                    cipher == WLAN_CIPHER_SUITE_WEP104) {
 941                        connect->key_idx = idx;
 942                        connect->key = connkeys->params[idx].key;
 943                        connect->key_len = connkeys->params[idx].key_len;
 944
 945                        /*
 946                         * If ciphers are not set (e.g. when going through
 947                         * iwconfig), we have to set them appropriately here.
 948                         */
 949                        if (connect->crypto.cipher_group == 0)
 950                                connect->crypto.cipher_group = cipher;
 951
 952                        if (connect->crypto.n_ciphers_pairwise == 0) {
 953                                connect->crypto.n_ciphers_pairwise = 1;
 954                                connect->crypto.ciphers_pairwise[0] = cipher;
 955                        }
 956                }
 957        }
 958
 959        wdev->connect_keys = connkeys;
 960        memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
 961        wdev->ssid_len = connect->ssid_len;
 962
 963        if (!rdev->ops->connect)
 964                err = cfg80211_sme_connect(wdev, connect, prev_bssid);
 965        else
 966                err = rdev_connect(rdev, dev, connect);
 967
 968        if (err) {
 969                wdev->connect_keys = NULL;
 970                wdev->ssid_len = 0;
 971                return err;
 972        }
 973
 974        return 0;
 975}
 976
 977int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
 978                        struct net_device *dev, u16 reason, bool wextev)
 979{
 980        struct wireless_dev *wdev = dev->ieee80211_ptr;
 981        int err = 0;
 982
 983        ASSERT_WDEV_LOCK(wdev);
 984
 985        kfree(wdev->connect_keys);
 986        wdev->connect_keys = NULL;
 987
 988        if (wdev->conn)
 989                err = cfg80211_sme_disconnect(wdev, reason);
 990        else if (!rdev->ops->disconnect)
 991                cfg80211_mlme_down(rdev, dev);
 992        else if (wdev->current_bss)
 993                err = rdev_disconnect(rdev, dev, reason);
 994
 995        return err;
 996}
 997