linux/net/mac80211/work.c
<<
>>
Prefs
   1/*
   2 * mac80211 work implementation
   3 *
   4 * Copyright 2003-2008, Jouni Malinen <j@w1.fi>
   5 * Copyright 2004, Instant802 Networks, Inc.
   6 * Copyright 2005, Devicescape Software, Inc.
   7 * Copyright 2006-2007  Jiri Benc <jbenc@suse.cz>
   8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
   9 * Copyright 2009, Johannes Berg <johannes@sipsolutions.net>
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License version 2 as
  13 * published by the Free Software Foundation.
  14 */
  15
  16#include <linux/delay.h>
  17#include <linux/if_ether.h>
  18#include <linux/skbuff.h>
  19#include <linux/if_arp.h>
  20#include <linux/etherdevice.h>
  21#include <linux/crc32.h>
  22#include <linux/slab.h>
  23#include <net/mac80211.h>
  24#include <asm/unaligned.h>
  25
  26#include "ieee80211_i.h"
  27#include "rate.h"
  28
  29#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
  30#define IEEE80211_AUTH_MAX_TRIES 3
  31#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
  32#define IEEE80211_ASSOC_MAX_TRIES 3
  33#define IEEE80211_MAX_PROBE_TRIES 5
  34
  35enum work_action {
  36        WORK_ACT_MISMATCH,
  37        WORK_ACT_NONE,
  38        WORK_ACT_TIMEOUT,
  39        WORK_ACT_DONE,
  40};
  41
  42
  43/* utils */
  44static inline void ASSERT_WORK_MTX(struct ieee80211_local *local)
  45{
  46        lockdep_assert_held(&local->mtx);
  47}
  48
  49/*
  50 * We can have multiple work items (and connection probing)
  51 * scheduling this timer, but we need to take care to only
  52 * reschedule it when it should fire _earlier_ than it was
  53 * asked for before, or if it's not pending right now. This
  54 * function ensures that. Note that it then is required to
  55 * run this function for all timeouts after the first one
  56 * has happened -- the work that runs from this timer will
  57 * do that.
  58 */
  59static void run_again(struct ieee80211_local *local,
  60                      unsigned long timeout)
  61{
  62        ASSERT_WORK_MTX(local);
  63
  64        if (!timer_pending(&local->work_timer) ||
  65            time_before(timeout, local->work_timer.expires))
  66                mod_timer(&local->work_timer, timeout);
  67}
  68
  69static void work_free_rcu(struct rcu_head *head)
  70{
  71        struct ieee80211_work *wk =
  72                container_of(head, struct ieee80211_work, rcu_head);
  73
  74        kfree(wk);
  75}
  76
  77void free_work(struct ieee80211_work *wk)
  78{
  79        call_rcu(&wk->rcu_head, work_free_rcu);
  80}
  81
  82static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
  83                                      struct ieee80211_supported_band *sband,
  84                                      u32 *rates)
  85{
  86        int i, j, count;
  87        *rates = 0;
  88        count = 0;
  89        for (i = 0; i < supp_rates_len; i++) {
  90                int rate = (supp_rates[i] & 0x7F) * 5;
  91
  92                for (j = 0; j < sband->n_bitrates; j++)
  93                        if (sband->bitrates[j].bitrate == rate) {
  94                                *rates |= BIT(j);
  95                                count++;
  96                                break;
  97                        }
  98        }
  99
 100        return count;
 101}
 102
 103/* frame sending functions */
 104
 105static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie,
 106                                struct ieee80211_supported_band *sband,
 107                                struct ieee80211_channel *channel,
 108                                enum ieee80211_smps_mode smps)
 109{
 110        struct ieee80211_ht_info *ht_info;
 111        u8 *pos;
 112        u32 flags = channel->flags;
 113        u16 cap = sband->ht_cap.cap;
 114        __le16 tmp;
 115
 116        if (!sband->ht_cap.ht_supported)
 117                return;
 118
 119        if (!ht_info_ie)
 120                return;
 121
 122        if (ht_info_ie[1] < sizeof(struct ieee80211_ht_info))
 123                return;
 124
 125        ht_info = (struct ieee80211_ht_info *)(ht_info_ie + 2);
 126
 127        /* determine capability flags */
 128
 129        if (ieee80211_disable_40mhz_24ghz &&
 130            sband->band == IEEE80211_BAND_2GHZ) {
 131                cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 132                cap &= ~IEEE80211_HT_CAP_SGI_40;
 133        }
 134
 135        switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
 136        case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
 137                if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
 138                        cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 139                        cap &= ~IEEE80211_HT_CAP_SGI_40;
 140                }
 141                break;
 142        case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
 143                if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
 144                        cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 145                        cap &= ~IEEE80211_HT_CAP_SGI_40;
 146                }
 147                break;
 148        }
 149
 150        /* set SM PS mode properly */
 151        cap &= ~IEEE80211_HT_CAP_SM_PS;
 152        switch (smps) {
 153        case IEEE80211_SMPS_AUTOMATIC:
 154        case IEEE80211_SMPS_NUM_MODES:
 155                WARN_ON(1);
 156        case IEEE80211_SMPS_OFF:
 157                cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
 158                        IEEE80211_HT_CAP_SM_PS_SHIFT;
 159                break;
 160        case IEEE80211_SMPS_STATIC:
 161                cap |= WLAN_HT_CAP_SM_PS_STATIC <<
 162                        IEEE80211_HT_CAP_SM_PS_SHIFT;
 163                break;
 164        case IEEE80211_SMPS_DYNAMIC:
 165                cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
 166                        IEEE80211_HT_CAP_SM_PS_SHIFT;
 167                break;
 168        }
 169
 170        /* reserve and fill IE */
 171
 172        pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
 173        *pos++ = WLAN_EID_HT_CAPABILITY;
 174        *pos++ = sizeof(struct ieee80211_ht_cap);
 175        memset(pos, 0, sizeof(struct ieee80211_ht_cap));
 176
 177        /* capability flags */
 178        tmp = cpu_to_le16(cap);
 179        memcpy(pos, &tmp, sizeof(u16));
 180        pos += sizeof(u16);
 181
 182        /* AMPDU parameters */
 183        *pos++ = sband->ht_cap.ampdu_factor |
 184                 (sband->ht_cap.ampdu_density <<
 185                        IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
 186
 187        /* MCS set */
 188        memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
 189        pos += sizeof(sband->ht_cap.mcs);
 190
 191        /* extended capabilities */
 192        pos += sizeof(__le16);
 193
 194        /* BF capabilities */
 195        pos += sizeof(__le32);
 196
 197        /* antenna selection */
 198        pos += sizeof(u8);
 199}
 200
 201static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
 202                                 struct ieee80211_work *wk)
 203{
 204        struct ieee80211_local *local = sdata->local;
 205        struct sk_buff *skb;
 206        struct ieee80211_mgmt *mgmt;
 207        u8 *pos, qos_info;
 208        const u8 *ies;
 209        size_t offset = 0, noffset;
 210        int i, len, count, rates_len, supp_rates_len;
 211        u16 capab;
 212        struct ieee80211_supported_band *sband;
 213        u32 rates = 0;
 214
 215        sband = local->hw.wiphy->bands[wk->chan->band];
 216
 217        if (wk->assoc.supp_rates_len) {
 218                /*
 219                 * Get all rates supported by the device and the AP as
 220                 * some APs don't like getting a superset of their rates
 221                 * in the association request (e.g. D-Link DAP 1353 in
 222                 * b-only mode)...
 223                 */
 224                rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates,
 225                                                       wk->assoc.supp_rates_len,
 226                                                       sband, &rates);
 227        } else {
 228                /*
 229                 * In case AP not provide any supported rates information
 230                 * before association, we send information element(s) with
 231                 * all rates that we support.
 232                 */
 233                rates = ~0;
 234                rates_len = sband->n_bitrates;
 235        }
 236
 237        skb = alloc_skb(local->hw.extra_tx_headroom +
 238                        sizeof(*mgmt) + /* bit too much but doesn't matter */
 239                        2 + wk->assoc.ssid_len + /* SSID */
 240                        4 + rates_len + /* (extended) rates */
 241                        4 + /* power capability */
 242                        2 + 2 * sband->n_channels + /* supported channels */
 243                        2 + sizeof(struct ieee80211_ht_cap) + /* HT */
 244                        wk->ie_len + /* extra IEs */
 245                        9, /* WMM */
 246                        GFP_KERNEL);
 247        if (!skb) {
 248                printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
 249                       "frame\n", sdata->name);
 250                return;
 251        }
 252        skb_reserve(skb, local->hw.extra_tx_headroom);
 253
 254        capab = WLAN_CAPABILITY_ESS;
 255
 256        if (sband->band == IEEE80211_BAND_2GHZ) {
 257                if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
 258                        capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
 259                if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
 260                        capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
 261        }
 262
 263        if (wk->assoc.capability & WLAN_CAPABILITY_PRIVACY)
 264                capab |= WLAN_CAPABILITY_PRIVACY;
 265
 266        if ((wk->assoc.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
 267            (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
 268                capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
 269
 270        mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
 271        memset(mgmt, 0, 24);
 272        memcpy(mgmt->da, wk->filter_ta, ETH_ALEN);
 273        memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
 274        memcpy(mgmt->bssid, wk->filter_ta, ETH_ALEN);
 275
 276        if (!is_zero_ether_addr(wk->assoc.prev_bssid)) {
 277                skb_put(skb, 10);
 278                mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 279                                                  IEEE80211_STYPE_REASSOC_REQ);
 280                mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
 281                mgmt->u.reassoc_req.listen_interval =
 282                                cpu_to_le16(local->hw.conf.listen_interval);
 283                memcpy(mgmt->u.reassoc_req.current_ap, wk->assoc.prev_bssid,
 284                       ETH_ALEN);
 285        } else {
 286                skb_put(skb, 4);
 287                mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 288                                                  IEEE80211_STYPE_ASSOC_REQ);
 289                mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
 290                mgmt->u.assoc_req.listen_interval =
 291                                cpu_to_le16(local->hw.conf.listen_interval);
 292        }
 293
 294        /* SSID */
 295        ies = pos = skb_put(skb, 2 + wk->assoc.ssid_len);
 296        *pos++ = WLAN_EID_SSID;
 297        *pos++ = wk->assoc.ssid_len;
 298        memcpy(pos, wk->assoc.ssid, wk->assoc.ssid_len);
 299
 300        /* add all rates which were marked to be used above */
 301        supp_rates_len = rates_len;
 302        if (supp_rates_len > 8)
 303                supp_rates_len = 8;
 304
 305        len = sband->n_bitrates;
 306        pos = skb_put(skb, supp_rates_len + 2);
 307        *pos++ = WLAN_EID_SUPP_RATES;
 308        *pos++ = supp_rates_len;
 309
 310        count = 0;
 311        for (i = 0; i < sband->n_bitrates; i++) {
 312                if (BIT(i) & rates) {
 313                        int rate = sband->bitrates[i].bitrate;
 314                        *pos++ = (u8) (rate / 5);
 315                        if (++count == 8)
 316                                break;
 317                }
 318        }
 319
 320        if (rates_len > count) {
 321                pos = skb_put(skb, rates_len - count + 2);
 322                *pos++ = WLAN_EID_EXT_SUPP_RATES;
 323                *pos++ = rates_len - count;
 324
 325                for (i++; i < sband->n_bitrates; i++) {
 326                        if (BIT(i) & rates) {
 327                                int rate = sband->bitrates[i].bitrate;
 328                                *pos++ = (u8) (rate / 5);
 329                        }
 330                }
 331        }
 332
 333        if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
 334                /* 1. power capabilities */
 335                pos = skb_put(skb, 4);
 336                *pos++ = WLAN_EID_PWR_CAPABILITY;
 337                *pos++ = 2;
 338                *pos++ = 0; /* min tx power */
 339                *pos++ = wk->chan->max_power; /* max tx power */
 340
 341                /* 2. supported channels */
 342                /* TODO: get this in reg domain format */
 343                pos = skb_put(skb, 2 * sband->n_channels + 2);
 344                *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
 345                *pos++ = 2 * sband->n_channels;
 346                for (i = 0; i < sband->n_channels; i++) {
 347                        *pos++ = ieee80211_frequency_to_channel(
 348                                        sband->channels[i].center_freq);
 349                        *pos++ = 1; /* one channel in the subband*/
 350                }
 351        }
 352
 353        /* if present, add any custom IEs that go before HT */
 354        if (wk->ie_len && wk->ie) {
 355                static const u8 before_ht[] = {
 356                        WLAN_EID_SSID,
 357                        WLAN_EID_SUPP_RATES,
 358                        WLAN_EID_EXT_SUPP_RATES,
 359                        WLAN_EID_PWR_CAPABILITY,
 360                        WLAN_EID_SUPPORTED_CHANNELS,
 361                        WLAN_EID_RSN,
 362                        WLAN_EID_QOS_CAPA,
 363                        WLAN_EID_RRM_ENABLED_CAPABILITIES,
 364                        WLAN_EID_MOBILITY_DOMAIN,
 365                        WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
 366                };
 367                noffset = ieee80211_ie_split(wk->ie, wk->ie_len,
 368                                             before_ht, ARRAY_SIZE(before_ht),
 369                                             offset);
 370                pos = skb_put(skb, noffset - offset);
 371                memcpy(pos, wk->ie + offset, noffset - offset);
 372                offset = noffset;
 373        }
 374
 375        if (wk->assoc.use_11n && wk->assoc.wmm_used &&
 376            local->hw.queues >= 4)
 377                ieee80211_add_ht_ie(skb, wk->assoc.ht_information_ie,
 378                                    sband, wk->chan, wk->assoc.smps);
 379
 380        /* if present, add any custom non-vendor IEs that go after HT */
 381        if (wk->ie_len && wk->ie) {
 382                noffset = ieee80211_ie_split_vendor(wk->ie, wk->ie_len,
 383                                                    offset);
 384                pos = skb_put(skb, noffset - offset);
 385                memcpy(pos, wk->ie + offset, noffset - offset);
 386                offset = noffset;
 387        }
 388
 389        if (wk->assoc.wmm_used && local->hw.queues >= 4) {
 390                if (wk->assoc.uapsd_used) {
 391                        qos_info = local->uapsd_queues;
 392                        qos_info |= (local->uapsd_max_sp_len <<
 393                                     IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
 394                } else {
 395                        qos_info = 0;
 396                }
 397
 398                pos = skb_put(skb, 9);
 399                *pos++ = WLAN_EID_VENDOR_SPECIFIC;
 400                *pos++ = 7; /* len */
 401                *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
 402                *pos++ = 0x50;
 403                *pos++ = 0xf2;
 404                *pos++ = 2; /* WME */
 405                *pos++ = 0; /* WME info */
 406                *pos++ = 1; /* WME ver */
 407                *pos++ = qos_info;
 408        }
 409
 410        /* add any remaining custom (i.e. vendor specific here) IEs */
 411        if (wk->ie_len && wk->ie) {
 412                noffset = wk->ie_len;
 413                pos = skb_put(skb, noffset - offset);
 414                memcpy(pos, wk->ie + offset, noffset - offset);
 415        }
 416
 417        IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
 418        ieee80211_tx_skb(sdata, skb);
 419}
 420
 421static void ieee80211_remove_auth_bss(struct ieee80211_local *local,
 422                                      struct ieee80211_work *wk)
 423{
 424        struct cfg80211_bss *cbss;
 425        u16 capa_val = WLAN_CAPABILITY_ESS;
 426
 427        if (wk->probe_auth.privacy)
 428                capa_val |= WLAN_CAPABILITY_PRIVACY;
 429
 430        cbss = cfg80211_get_bss(local->hw.wiphy, wk->chan, wk->filter_ta,
 431                                wk->probe_auth.ssid, wk->probe_auth.ssid_len,
 432                                WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
 433                                capa_val);
 434        if (!cbss)
 435                return;
 436
 437        cfg80211_unlink_bss(local->hw.wiphy, cbss);
 438        cfg80211_put_bss(cbss);
 439}
 440
 441static enum work_action __must_check
 442ieee80211_direct_probe(struct ieee80211_work *wk)
 443{
 444        struct ieee80211_sub_if_data *sdata = wk->sdata;
 445        struct ieee80211_local *local = sdata->local;
 446
 447        wk->probe_auth.tries++;
 448        if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
 449                printk(KERN_DEBUG "%s: direct probe to %pM timed out\n",
 450                       sdata->name, wk->filter_ta);
 451
 452                /*
 453                 * Most likely AP is not in the range so remove the
 454                 * bss struct for that AP.
 455                 */
 456                ieee80211_remove_auth_bss(local, wk);
 457
 458                return WORK_ACT_TIMEOUT;
 459        }
 460
 461        printk(KERN_DEBUG "%s: direct probe to %pM (try %d/%i)\n",
 462               sdata->name, wk->filter_ta, wk->probe_auth.tries,
 463               IEEE80211_AUTH_MAX_TRIES);
 464
 465        /*
 466         * Direct probe is sent to broadcast address as some APs
 467         * will not answer to direct packet in unassociated state.
 468         */
 469        ieee80211_send_probe_req(sdata, NULL, wk->probe_auth.ssid,
 470                                 wk->probe_auth.ssid_len, NULL, 0);
 471
 472        wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
 473        run_again(local, wk->timeout);
 474
 475        return WORK_ACT_NONE;
 476}
 477
 478
 479static enum work_action __must_check
 480ieee80211_authenticate(struct ieee80211_work *wk)
 481{
 482        struct ieee80211_sub_if_data *sdata = wk->sdata;
 483        struct ieee80211_local *local = sdata->local;
 484
 485        wk->probe_auth.tries++;
 486        if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
 487                printk(KERN_DEBUG "%s: authentication with %pM"
 488                       " timed out\n", sdata->name, wk->filter_ta);
 489
 490                /*
 491                 * Most likely AP is not in the range so remove the
 492                 * bss struct for that AP.
 493                 */
 494                ieee80211_remove_auth_bss(local, wk);
 495
 496                return WORK_ACT_TIMEOUT;
 497        }
 498
 499        printk(KERN_DEBUG "%s: authenticate with %pM (try %d)\n",
 500               sdata->name, wk->filter_ta, wk->probe_auth.tries);
 501
 502        ieee80211_send_auth(sdata, 1, wk->probe_auth.algorithm, wk->ie,
 503                            wk->ie_len, wk->filter_ta, NULL, 0, 0);
 504        wk->probe_auth.transaction = 2;
 505
 506        wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
 507        run_again(local, wk->timeout);
 508
 509        return WORK_ACT_NONE;
 510}
 511
 512static enum work_action __must_check
 513ieee80211_associate(struct ieee80211_work *wk)
 514{
 515        struct ieee80211_sub_if_data *sdata = wk->sdata;
 516        struct ieee80211_local *local = sdata->local;
 517
 518        wk->assoc.tries++;
 519        if (wk->assoc.tries > IEEE80211_ASSOC_MAX_TRIES) {
 520                printk(KERN_DEBUG "%s: association with %pM"
 521                       " timed out\n",
 522                       sdata->name, wk->filter_ta);
 523
 524                /*
 525                 * Most likely AP is not in the range so remove the
 526                 * bss struct for that AP.
 527                 */
 528                if (wk->assoc.bss)
 529                        cfg80211_unlink_bss(local->hw.wiphy, wk->assoc.bss);
 530
 531                return WORK_ACT_TIMEOUT;
 532        }
 533
 534        printk(KERN_DEBUG "%s: associate with %pM (try %d)\n",
 535               sdata->name, wk->filter_ta, wk->assoc.tries);
 536        ieee80211_send_assoc(sdata, wk);
 537
 538        wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
 539        run_again(local, wk->timeout);
 540
 541        return WORK_ACT_NONE;
 542}
 543
 544static enum work_action __must_check
 545ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk)
 546{
 547        /*
 548         * First time we run, do nothing -- the generic code will
 549         * have switched to the right channel etc.
 550         */
 551        if (!wk->started) {
 552                wk->timeout = jiffies + msecs_to_jiffies(wk->remain.duration);
 553
 554                cfg80211_ready_on_channel(wk->sdata->dev, (unsigned long) wk,
 555                                          wk->chan, wk->chan_type,
 556                                          wk->remain.duration, GFP_KERNEL);
 557
 558                return WORK_ACT_NONE;
 559        }
 560
 561        return WORK_ACT_TIMEOUT;
 562}
 563
 564static enum work_action __must_check
 565ieee80211_offchannel_tx(struct ieee80211_work *wk)
 566{
 567        if (!wk->started) {
 568                wk->timeout = jiffies + msecs_to_jiffies(wk->offchan_tx.wait);
 569
 570                /*
 571                 * After this, offchan_tx.frame remains but now is no
 572                 * longer a valid pointer -- we still need it as the
 573                 * cookie for canceling this work.
 574                 */
 575                ieee80211_tx_skb(wk->sdata, wk->offchan_tx.frame);
 576
 577                return WORK_ACT_NONE;
 578        }
 579
 580        return WORK_ACT_TIMEOUT;
 581}
 582
 583static enum work_action __must_check
 584ieee80211_assoc_beacon_wait(struct ieee80211_work *wk)
 585{
 586        if (wk->started)
 587                return WORK_ACT_TIMEOUT;
 588
 589        /*
 590         * Wait up to one beacon interval ...
 591         * should this be more if we miss one?
 592         */
 593        printk(KERN_DEBUG "%s: waiting for beacon from %pM\n",
 594               wk->sdata->name, wk->filter_ta);
 595        wk->timeout = TU_TO_EXP_TIME(wk->assoc.bss->beacon_interval);
 596        return WORK_ACT_NONE;
 597}
 598
 599static void ieee80211_auth_challenge(struct ieee80211_work *wk,
 600                                     struct ieee80211_mgmt *mgmt,
 601                                     size_t len)
 602{
 603        struct ieee80211_sub_if_data *sdata = wk->sdata;
 604        u8 *pos;
 605        struct ieee802_11_elems elems;
 606
 607        pos = mgmt->u.auth.variable;
 608        ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
 609        if (!elems.challenge)
 610                return;
 611        ieee80211_send_auth(sdata, 3, wk->probe_auth.algorithm,
 612                            elems.challenge - 2, elems.challenge_len + 2,
 613                            wk->filter_ta, wk->probe_auth.key,
 614                            wk->probe_auth.key_len, wk->probe_auth.key_idx);
 615        wk->probe_auth.transaction = 4;
 616}
 617
 618static enum work_action __must_check
 619ieee80211_rx_mgmt_auth(struct ieee80211_work *wk,
 620                       struct ieee80211_mgmt *mgmt, size_t len)
 621{
 622        u16 auth_alg, auth_transaction, status_code;
 623
 624        if (wk->type != IEEE80211_WORK_AUTH)
 625                return WORK_ACT_MISMATCH;
 626
 627        if (len < 24 + 6)
 628                return WORK_ACT_NONE;
 629
 630        auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
 631        auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
 632        status_code = le16_to_cpu(mgmt->u.auth.status_code);
 633
 634        if (auth_alg != wk->probe_auth.algorithm ||
 635            auth_transaction != wk->probe_auth.transaction)
 636                return WORK_ACT_NONE;
 637
 638        if (status_code != WLAN_STATUS_SUCCESS) {
 639                printk(KERN_DEBUG "%s: %pM denied authentication (status %d)\n",
 640                       wk->sdata->name, mgmt->sa, status_code);
 641                return WORK_ACT_DONE;
 642        }
 643
 644        switch (wk->probe_auth.algorithm) {
 645        case WLAN_AUTH_OPEN:
 646        case WLAN_AUTH_LEAP:
 647        case WLAN_AUTH_FT:
 648                break;
 649        case WLAN_AUTH_SHARED_KEY:
 650                if (wk->probe_auth.transaction != 4) {
 651                        ieee80211_auth_challenge(wk, mgmt, len);
 652                        /* need another frame */
 653                        return WORK_ACT_NONE;
 654                }
 655                break;
 656        default:
 657                WARN_ON(1);
 658                return WORK_ACT_NONE;
 659        }
 660
 661        printk(KERN_DEBUG "%s: authenticated\n", wk->sdata->name);
 662        return WORK_ACT_DONE;
 663}
 664
 665static enum work_action __must_check
 666ieee80211_rx_mgmt_assoc_resp(struct ieee80211_work *wk,
 667                             struct ieee80211_mgmt *mgmt, size_t len,
 668                             bool reassoc)
 669{
 670        struct ieee80211_sub_if_data *sdata = wk->sdata;
 671        struct ieee80211_local *local = sdata->local;
 672        u16 capab_info, status_code, aid;
 673        struct ieee802_11_elems elems;
 674        u8 *pos;
 675
 676        if (wk->type != IEEE80211_WORK_ASSOC)
 677                return WORK_ACT_MISMATCH;
 678
 679        /*
 680         * AssocResp and ReassocResp have identical structure, so process both
 681         * of them in this function.
 682         */
 683
 684        if (len < 24 + 6)
 685                return WORK_ACT_NONE;
 686
 687        capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
 688        status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
 689        aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
 690
 691        printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x "
 692               "status=%d aid=%d)\n",
 693               sdata->name, reassoc ? "Rea" : "A", mgmt->sa,
 694               capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
 695
 696        pos = mgmt->u.assoc_resp.variable;
 697        ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
 698
 699        if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
 700            elems.timeout_int && elems.timeout_int_len == 5 &&
 701            elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
 702                u32 tu, ms;
 703                tu = get_unaligned_le32(elems.timeout_int + 1);
 704                ms = tu * 1024 / 1000;
 705                printk(KERN_DEBUG "%s: %pM rejected association temporarily; "
 706                       "comeback duration %u TU (%u ms)\n",
 707                       sdata->name, mgmt->sa, tu, ms);
 708                wk->timeout = jiffies + msecs_to_jiffies(ms);
 709                if (ms > IEEE80211_ASSOC_TIMEOUT)
 710                        run_again(local, wk->timeout);
 711                return WORK_ACT_NONE;
 712        }
 713
 714        if (status_code != WLAN_STATUS_SUCCESS)
 715                printk(KERN_DEBUG "%s: %pM denied association (code=%d)\n",
 716                       sdata->name, mgmt->sa, status_code);
 717        else
 718                printk(KERN_DEBUG "%s: associated\n", sdata->name);
 719
 720        return WORK_ACT_DONE;
 721}
 722
 723static enum work_action __must_check
 724ieee80211_rx_mgmt_probe_resp(struct ieee80211_work *wk,
 725                             struct ieee80211_mgmt *mgmt, size_t len,
 726                             struct ieee80211_rx_status *rx_status)
 727{
 728        struct ieee80211_sub_if_data *sdata = wk->sdata;
 729        struct ieee80211_local *local = sdata->local;
 730        size_t baselen;
 731
 732        ASSERT_WORK_MTX(local);
 733
 734        if (wk->type != IEEE80211_WORK_DIRECT_PROBE)
 735                return WORK_ACT_MISMATCH;
 736
 737        if (len < 24 + 12)
 738                return WORK_ACT_NONE;
 739
 740        baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
 741        if (baselen > len)
 742                return WORK_ACT_NONE;
 743
 744        printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name);
 745        return WORK_ACT_DONE;
 746}
 747
 748static enum work_action __must_check
 749ieee80211_rx_mgmt_beacon(struct ieee80211_work *wk,
 750                         struct ieee80211_mgmt *mgmt, size_t len)
 751{
 752        struct ieee80211_sub_if_data *sdata = wk->sdata;
 753        struct ieee80211_local *local = sdata->local;
 754
 755        ASSERT_WORK_MTX(local);
 756
 757        if (wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
 758                return WORK_ACT_MISMATCH;
 759
 760        if (len < 24 + 12)
 761                return WORK_ACT_NONE;
 762
 763        printk(KERN_DEBUG "%s: beacon received\n", sdata->name);
 764        return WORK_ACT_DONE;
 765}
 766
 767static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
 768                                          struct sk_buff *skb)
 769{
 770        struct ieee80211_rx_status *rx_status;
 771        struct ieee80211_mgmt *mgmt;
 772        struct ieee80211_work *wk;
 773        enum work_action rma = WORK_ACT_NONE;
 774        u16 fc;
 775
 776        rx_status = (struct ieee80211_rx_status *) skb->cb;
 777        mgmt = (struct ieee80211_mgmt *) skb->data;
 778        fc = le16_to_cpu(mgmt->frame_control);
 779
 780        mutex_lock(&local->mtx);
 781
 782        list_for_each_entry(wk, &local->work_list, list) {
 783                const u8 *bssid = NULL;
 784
 785                switch (wk->type) {
 786                case IEEE80211_WORK_DIRECT_PROBE:
 787                case IEEE80211_WORK_AUTH:
 788                case IEEE80211_WORK_ASSOC:
 789                case IEEE80211_WORK_ASSOC_BEACON_WAIT:
 790                        bssid = wk->filter_ta;
 791                        break;
 792                default:
 793                        continue;
 794                }
 795
 796                /*
 797                 * Before queuing, we already verified mgmt->sa,
 798                 * so this is needed just for matching.
 799                 */
 800                if (compare_ether_addr(bssid, mgmt->bssid))
 801                        continue;
 802
 803                switch (fc & IEEE80211_FCTL_STYPE) {
 804                case IEEE80211_STYPE_BEACON:
 805                        rma = ieee80211_rx_mgmt_beacon(wk, mgmt, skb->len);
 806                        break;
 807                case IEEE80211_STYPE_PROBE_RESP:
 808                        rma = ieee80211_rx_mgmt_probe_resp(wk, mgmt, skb->len,
 809                                                           rx_status);
 810                        break;
 811                case IEEE80211_STYPE_AUTH:
 812                        rma = ieee80211_rx_mgmt_auth(wk, mgmt, skb->len);
 813                        break;
 814                case IEEE80211_STYPE_ASSOC_RESP:
 815                        rma = ieee80211_rx_mgmt_assoc_resp(wk, mgmt,
 816                                                           skb->len, false);
 817                        break;
 818                case IEEE80211_STYPE_REASSOC_RESP:
 819                        rma = ieee80211_rx_mgmt_assoc_resp(wk, mgmt,
 820                                                           skb->len, true);
 821                        break;
 822                default:
 823                        WARN_ON(1);
 824                        rma = WORK_ACT_NONE;
 825                }
 826
 827                /*
 828                 * We've either received an unexpected frame, or we have
 829                 * multiple work items and need to match the frame to the
 830                 * right one.
 831                 */
 832                if (rma == WORK_ACT_MISMATCH)
 833                        continue;
 834
 835                /*
 836                 * We've processed this frame for that work, so it can't
 837                 * belong to another work struct.
 838                 * NB: this is also required for correctness for 'rma'!
 839                 */
 840                break;
 841        }
 842
 843        switch (rma) {
 844        case WORK_ACT_MISMATCH:
 845                /* ignore this unmatched frame */
 846                break;
 847        case WORK_ACT_NONE:
 848                break;
 849        case WORK_ACT_DONE:
 850                list_del_rcu(&wk->list);
 851                break;
 852        default:
 853                WARN(1, "unexpected: %d", rma);
 854        }
 855
 856        mutex_unlock(&local->mtx);
 857
 858        if (rma != WORK_ACT_DONE)
 859                goto out;
 860
 861        switch (wk->done(wk, skb)) {
 862        case WORK_DONE_DESTROY:
 863                free_work(wk);
 864                break;
 865        case WORK_DONE_REQUEUE:
 866                synchronize_rcu();
 867                wk->started = false; /* restart */
 868                mutex_lock(&local->mtx);
 869                list_add_tail(&wk->list, &local->work_list);
 870                mutex_unlock(&local->mtx);
 871        }
 872
 873 out:
 874        kfree_skb(skb);
 875}
 876
 877static void ieee80211_work_timer(unsigned long data)
 878{
 879        struct ieee80211_local *local = (void *) data;
 880
 881        if (local->quiescing)
 882                return;
 883
 884        ieee80211_queue_work(&local->hw, &local->work_work);
 885}
 886
 887static void ieee80211_work_work(struct work_struct *work)
 888{
 889        struct ieee80211_local *local =
 890                container_of(work, struct ieee80211_local, work_work);
 891        struct sk_buff *skb;
 892        struct ieee80211_work *wk, *tmp;
 893        LIST_HEAD(free_work);
 894        enum work_action rma;
 895        bool remain_off_channel = false;
 896
 897        if (local->scanning)
 898                return;
 899
 900        /*
 901         * ieee80211_queue_work() should have picked up most cases,
 902         * here we'll pick the rest.
 903         */
 904        if (WARN(local->suspended, "work scheduled while going to suspend\n"))
 905                return;
 906
 907        /* first process frames to avoid timing out while a frame is pending */
 908        while ((skb = skb_dequeue(&local->work_skb_queue)))
 909                ieee80211_work_rx_queued_mgmt(local, skb);
 910
 911        mutex_lock(&local->mtx);
 912
 913        ieee80211_recalc_idle(local);
 914
 915        list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
 916                bool started = wk->started;
 917
 918                /* mark work as started if it's on the current off-channel */
 919                if (!started && local->tmp_channel &&
 920                    wk->chan == local->tmp_channel &&
 921                    wk->chan_type == local->tmp_channel_type) {
 922                        started = true;
 923                        wk->timeout = jiffies;
 924                }
 925
 926                if (!started && !local->tmp_channel) {
 927                        /*
 928                         * TODO: could optimize this by leaving the
 929                         *       station vifs in awake mode if they
 930                         *       happen to be on the same channel as
 931                         *       the requested channel
 932                         */
 933                        ieee80211_offchannel_stop_beaconing(local);
 934                        ieee80211_offchannel_stop_station(local);
 935
 936                        local->tmp_channel = wk->chan;
 937                        local->tmp_channel_type = wk->chan_type;
 938                        ieee80211_hw_config(local, 0);
 939                        started = true;
 940                        wk->timeout = jiffies;
 941                }
 942
 943                /* don't try to work with items that aren't started */
 944                if (!started)
 945                        continue;
 946
 947                if (time_is_after_jiffies(wk->timeout)) {
 948                        /*
 949                         * This work item isn't supposed to be worked on
 950                         * right now, but take care to adjust the timer
 951                         * properly.
 952                         */
 953                        run_again(local, wk->timeout);
 954                        continue;
 955                }
 956
 957                switch (wk->type) {
 958                default:
 959                        WARN_ON(1);
 960                        /* nothing */
 961                        rma = WORK_ACT_NONE;
 962                        break;
 963                case IEEE80211_WORK_ABORT:
 964                        rma = WORK_ACT_TIMEOUT;
 965                        break;
 966                case IEEE80211_WORK_DIRECT_PROBE:
 967                        rma = ieee80211_direct_probe(wk);
 968                        break;
 969                case IEEE80211_WORK_AUTH:
 970                        rma = ieee80211_authenticate(wk);
 971                        break;
 972                case IEEE80211_WORK_ASSOC:
 973                        rma = ieee80211_associate(wk);
 974                        break;
 975                case IEEE80211_WORK_REMAIN_ON_CHANNEL:
 976                        rma = ieee80211_remain_on_channel_timeout(wk);
 977                        break;
 978                case IEEE80211_WORK_OFFCHANNEL_TX:
 979                        rma = ieee80211_offchannel_tx(wk);
 980                        break;
 981                case IEEE80211_WORK_ASSOC_BEACON_WAIT:
 982                        rma = ieee80211_assoc_beacon_wait(wk);
 983                        break;
 984                }
 985
 986                wk->started = started;
 987
 988                switch (rma) {
 989                case WORK_ACT_NONE:
 990                        /* might have changed the timeout */
 991                        run_again(local, wk->timeout);
 992                        break;
 993                case WORK_ACT_TIMEOUT:
 994                        list_del_rcu(&wk->list);
 995                        synchronize_rcu();
 996                        list_add(&wk->list, &free_work);
 997                        break;
 998                default:
 999                        WARN(1, "unexpected: %d", rma);
1000                }
1001        }
1002
1003        list_for_each_entry(wk, &local->work_list, list) {
1004                if (!wk->started)
1005                        continue;
1006                if (wk->chan != local->tmp_channel)
1007                        continue;
1008                if (wk->chan_type != local->tmp_channel_type)
1009                        continue;
1010                remain_off_channel = true;
1011        }
1012
1013        if (!remain_off_channel && local->tmp_channel) {
1014                local->tmp_channel = NULL;
1015                ieee80211_hw_config(local, 0);
1016                ieee80211_offchannel_return(local, true);
1017                /* give connection some time to breathe */
1018                run_again(local, jiffies + HZ/2);
1019        }
1020
1021        if (list_empty(&local->work_list) && local->scan_req &&
1022            !local->scanning)
1023                ieee80211_queue_delayed_work(&local->hw,
1024                                             &local->scan_work,
1025                                             round_jiffies_relative(0));
1026
1027        ieee80211_recalc_idle(local);
1028
1029        mutex_unlock(&local->mtx);
1030
1031        list_for_each_entry_safe(wk, tmp, &free_work, list) {
1032                wk->done(wk, NULL);
1033                list_del(&wk->list);
1034                kfree(wk);
1035        }
1036}
1037
1038void ieee80211_add_work(struct ieee80211_work *wk)
1039{
1040        struct ieee80211_local *local;
1041
1042        if (WARN_ON(!wk->chan))
1043                return;
1044
1045        if (WARN_ON(!wk->sdata))
1046                return;
1047
1048        if (WARN_ON(!wk->done))
1049                return;
1050
1051        if (WARN_ON(!ieee80211_sdata_running(wk->sdata)))
1052                return;
1053
1054        wk->started = false;
1055
1056        local = wk->sdata->local;
1057        mutex_lock(&local->mtx);
1058        list_add_tail(&wk->list, &local->work_list);
1059        mutex_unlock(&local->mtx);
1060
1061        ieee80211_queue_work(&local->hw, &local->work_work);
1062}
1063
1064void ieee80211_work_init(struct ieee80211_local *local)
1065{
1066        INIT_LIST_HEAD(&local->work_list);
1067        setup_timer(&local->work_timer, ieee80211_work_timer,
1068                    (unsigned long)local);
1069        INIT_WORK(&local->work_work, ieee80211_work_work);
1070        skb_queue_head_init(&local->work_skb_queue);
1071}
1072
1073void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
1074{
1075        struct ieee80211_local *local = sdata->local;
1076        struct ieee80211_work *wk;
1077        bool cleanup = false;
1078
1079        mutex_lock(&local->mtx);
1080        list_for_each_entry(wk, &local->work_list, list) {
1081                if (wk->sdata != sdata)
1082                        continue;
1083                cleanup = true;
1084                wk->type = IEEE80211_WORK_ABORT;
1085                wk->started = true;
1086                wk->timeout = jiffies;
1087        }
1088        mutex_unlock(&local->mtx);
1089
1090        /* run cleanups etc. */
1091        if (cleanup)
1092                ieee80211_work_work(&local->work_work);
1093
1094        mutex_lock(&local->mtx);
1095        list_for_each_entry(wk, &local->work_list, list) {
1096                if (wk->sdata != sdata)
1097                        continue;
1098                WARN_ON(1);
1099                break;
1100        }
1101        mutex_unlock(&local->mtx);
1102}
1103
1104ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
1105                                           struct sk_buff *skb)
1106{
1107        struct ieee80211_local *local = sdata->local;
1108        struct ieee80211_mgmt *mgmt;
1109        struct ieee80211_work *wk;
1110        u16 fc;
1111
1112        if (skb->len < 24)
1113                return RX_DROP_MONITOR;
1114
1115        mgmt = (struct ieee80211_mgmt *) skb->data;
1116        fc = le16_to_cpu(mgmt->frame_control);
1117
1118        list_for_each_entry_rcu(wk, &local->work_list, list) {
1119                if (sdata != wk->sdata)
1120                        continue;
1121                if (compare_ether_addr(wk->filter_ta, mgmt->sa))
1122                        continue;
1123                if (compare_ether_addr(wk->filter_ta, mgmt->bssid))
1124                        continue;
1125
1126                switch (fc & IEEE80211_FCTL_STYPE) {
1127                case IEEE80211_STYPE_AUTH:
1128                case IEEE80211_STYPE_PROBE_RESP:
1129                case IEEE80211_STYPE_ASSOC_RESP:
1130                case IEEE80211_STYPE_REASSOC_RESP:
1131                case IEEE80211_STYPE_BEACON:
1132                        skb_queue_tail(&local->work_skb_queue, skb);
1133                        ieee80211_queue_work(&local->hw, &local->work_work);
1134                        return RX_QUEUED;
1135                }
1136        }
1137
1138        return RX_CONTINUE;
1139}
1140
1141static enum work_done_result ieee80211_remain_done(struct ieee80211_work *wk,
1142                                                   struct sk_buff *skb)
1143{
1144        /*
1145         * We are done serving the remain-on-channel command.
1146         */
1147        cfg80211_remain_on_channel_expired(wk->sdata->dev, (unsigned long) wk,
1148                                           wk->chan, wk->chan_type,
1149                                           GFP_KERNEL);
1150
1151        return WORK_DONE_DESTROY;
1152}
1153
1154int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata,
1155                                   struct ieee80211_channel *chan,
1156                                   enum nl80211_channel_type channel_type,
1157                                   unsigned int duration, u64 *cookie)
1158{
1159        struct ieee80211_work *wk;
1160
1161        wk = kzalloc(sizeof(*wk), GFP_KERNEL);
1162        if (!wk)
1163                return -ENOMEM;
1164
1165        wk->type = IEEE80211_WORK_REMAIN_ON_CHANNEL;
1166        wk->chan = chan;
1167        wk->chan_type = channel_type;
1168        wk->sdata = sdata;
1169        wk->done = ieee80211_remain_done;
1170
1171        wk->remain.duration = duration;
1172
1173        *cookie = (unsigned long) wk;
1174
1175        ieee80211_add_work(wk);
1176
1177        return 0;
1178}
1179
1180int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata,
1181                                          u64 cookie)
1182{
1183        struct ieee80211_local *local = sdata->local;
1184        struct ieee80211_work *wk, *tmp;
1185        bool found = false;
1186
1187        mutex_lock(&local->mtx);
1188        list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
1189                if ((unsigned long) wk == cookie) {
1190                        wk->timeout = jiffies;
1191                        found = true;
1192                        break;
1193                }
1194        }
1195        mutex_unlock(&local->mtx);
1196
1197        if (!found)
1198                return -ENOENT;
1199
1200        ieee80211_queue_work(&local->hw, &local->work_work);
1201
1202        return 0;
1203}
1204