mlme.c 87.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * BSS client mode implementation
 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
 * Copyright 2004, Instant802 Networks, Inc.
 * Copyright 2005, Devicescape Software, Inc.
 * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz>
 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

14
#include <linux/delay.h>
15 16 17 18 19 20 21
#include <linux/if_ether.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/wireless.h>
#include <linux/random.h>
#include <linux/etherdevice.h>
22
#include <linux/rtnetlink.h>
23 24
#include <net/iw_handler.h>
#include <net/mac80211.h>
J
Johannes Berg 已提交
25

26
#include "ieee80211_i.h"
J
Johannes Berg 已提交
27 28
#include "rate.h"
#include "led.h"
29
#include "mesh.h"
30

31
#define IEEE80211_ASSOC_SCANS_MAX_TRIES 2
32 33 34 35 36
#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
#define IEEE80211_AUTH_MAX_TRIES 3
#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
#define IEEE80211_ASSOC_MAX_TRIES 3
#define IEEE80211_MONITORING_INTERVAL (2 * HZ)
37
#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
38 39 40 41
#define IEEE80211_PROBE_INTERVAL (60 * HZ)
#define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ)
#define IEEE80211_SCAN_INTERVAL (2 * HZ)
#define IEEE80211_SCAN_INTERVAL_SLOW (15 * HZ)
42
#define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ)
43 44 45

#define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ)
#define IEEE80211_IBSS_INACTIVITY_LIMIT (60 * HZ)
46
#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
47 48 49 50

#define IEEE80211_IBSS_MAX_STA_ENTRIES 128


51 52
/* utils */
static int ecw2cw(int ecw)
J
Johannes Berg 已提交
53
{
54
	return (1 << ecw) - 1;
J
Johannes Berg 已提交
55 56 57
}

static u8 *ieee80211_bss_get_ie(struct ieee80211_sta_bss *bss, u8 ie)
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
{
	u8 *end, *pos;

	pos = bss->ies;
	if (pos == NULL)
		return NULL;
	end = pos + bss->ies_len;

	while (pos + 1 < end) {
		if (pos + 2 + pos[1] > end)
			break;
		if (pos[0] == ie)
			return pos;
		pos += 2 + pos[1];
	}

	return NULL;
}

J
Johannes Berg 已提交
77 78 79 80 81 82 83 84
/* frame sending functions */
void ieee80211_sta_tx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
		      int encrypt)
{
	skb->dev = sdata->local->mdev;
	skb_set_mac_header(skb, 0);
	skb_set_network_header(skb, 0);
	skb_set_transport_header(skb, 0);
85

J
Johannes Berg 已提交
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
	skb->iif = sdata->dev->ifindex;
	skb->do_not_encrypt = !encrypt;

	dev_queue_xmit(skb);
}

static void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
				struct ieee80211_if_sta *ifsta,
				int transaction, u8 *extra, size_t extra_len,
				int encrypt)
{
	struct ieee80211_local *local = sdata->local;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;

	skb = dev_alloc_skb(local->hw.extra_tx_headroom +
			    sizeof(*mgmt) + 6 + extra_len);
	if (!skb) {
		printk(KERN_DEBUG "%s: failed to allocate buffer for auth "
		       "frame\n", sdata->dev->name);
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6);
	memset(mgmt, 0, 24 + 6);
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_AUTH);
	if (encrypt)
		mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
	memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
	memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
	mgmt->u.auth.auth_alg = cpu_to_le16(ifsta->auth_alg);
	mgmt->u.auth.auth_transaction = cpu_to_le16(transaction);
	ifsta->auth_transaction = transaction + 1;
	mgmt->u.auth.status_code = cpu_to_le16(0);
	if (extra)
		memcpy(skb_put(skb, extra_len), extra, extra_len);

	ieee80211_sta_tx(sdata, skb, encrypt);
}

129 130
void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
			      u8 *ssid, size_t ssid_len)
J
Johannes Berg 已提交
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_supported_band *sband;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u8 *pos, *supp_rates, *esupp_rates = NULL;
	int i;

	skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200);
	if (!skb) {
		printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
		       "request\n", sdata->dev->name);
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
	memset(mgmt, 0, 24);
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_PROBE_REQ);
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
	if (dst) {
		memcpy(mgmt->da, dst, ETH_ALEN);
		memcpy(mgmt->bssid, dst, ETH_ALEN);
	} else {
		memset(mgmt->da, 0xff, ETH_ALEN);
		memset(mgmt->bssid, 0xff, ETH_ALEN);
	}
	pos = skb_put(skb, 2 + ssid_len);
	*pos++ = WLAN_EID_SSID;
	*pos++ = ssid_len;
	memcpy(pos, ssid, ssid_len);

	supp_rates = skb_put(skb, 2);
	supp_rates[0] = WLAN_EID_SUPP_RATES;
	supp_rates[1] = 0;
	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];

	for (i = 0; i < sband->n_bitrates; i++) {
		struct ieee80211_rate *rate = &sband->bitrates[i];
		if (esupp_rates) {
			pos = skb_put(skb, 1);
			esupp_rates[1]++;
		} else if (supp_rates[1] == 8) {
			esupp_rates = skb_put(skb, 3);
			esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES;
			esupp_rates[1] = 1;
			pos = &esupp_rates[2];
		} else {
			pos = skb_put(skb, 1);
			supp_rates[1]++;
		}
		*pos = rate->bitrate / 5;
	}

	ieee80211_sta_tx(sdata, skb, 0);
}

/* MLME */
190
static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
					 struct ieee80211_sta_bss *bss,
					 int ibss)
{
	struct ieee80211_local *local = sdata->local;
	int i, have_higher_than_11mbit = 0;


	/* cf. IEEE 802.11 9.2.12 */
	for (i = 0; i < bss->supp_rates_len; i++)
		if ((bss->supp_rates[i] & 0x7f) * 5 > 110)
			have_higher_than_11mbit = 1;

	if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
	    have_higher_than_11mbit)
		sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
	else
		sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;


	if (local->ops->conf_tx) {
		struct ieee80211_tx_queue_params qparam;

		memset(&qparam, 0, sizeof(qparam));

		qparam.aifs = 2;

		if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
		    !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE))
			qparam.cw_min = 31;
		else
			qparam.cw_min = 15;

		qparam.cw_max = 1023;
		qparam.txop = 0;

J
Johannes Berg 已提交
226 227
		for (i = 0; i < local_to_hw(local)->queues; i++)
			local->ops->conf_tx(local_to_hw(local), i, &qparam);
228 229 230
	}
}

231
static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
232 233 234 235 236 237 238 239
				     struct ieee80211_if_sta *ifsta,
				     u8 *wmm_param, size_t wmm_param_len)
{
	struct ieee80211_tx_queue_params params;
	size_t left;
	int count;
	u8 *pos;

240 241 242 243 244 245
	if (!(ifsta->flags & IEEE80211_STA_WMM_ENABLED))
		return;

	if (!wmm_param)
		return;

246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
	if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
		return;
	count = wmm_param[6] & 0x0f;
	if (count == ifsta->wmm_last_param_set)
		return;
	ifsta->wmm_last_param_set = count;

	pos = wmm_param + 8;
	left = wmm_param_len - 8;

	memset(&params, 0, sizeof(params));

	if (!local->ops->conf_tx)
		return;

	local->wmm_acm = 0;
	for (; left >= 4; left -= 4, pos += 4) {
		int aci = (pos[0] >> 5) & 0x03;
		int acm = (pos[0] >> 4) & 0x01;
		int queue;

		switch (aci) {
		case 1:
J
Johannes Berg 已提交
269
			queue = 3;
J
Johannes Berg 已提交
270
			if (acm)
271 272 273
				local->wmm_acm |= BIT(0) | BIT(3);
			break;
		case 2:
J
Johannes Berg 已提交
274
			queue = 1;
J
Johannes Berg 已提交
275
			if (acm)
276 277 278
				local->wmm_acm |= BIT(4) | BIT(5);
			break;
		case 3:
J
Johannes Berg 已提交
279
			queue = 0;
J
Johannes Berg 已提交
280
			if (acm)
281 282 283 284
				local->wmm_acm |= BIT(6) | BIT(7);
			break;
		case 0:
		default:
J
Johannes Berg 已提交
285
			queue = 2;
J
Johannes Berg 已提交
286
			if (acm)
287 288 289 290 291 292 293
				local->wmm_acm |= BIT(1) | BIT(2);
			break;
		}

		params.aifs = pos[0] & 0x0f;
		params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4);
		params.cw_min = ecw2cw(pos[1] & 0x0f);
294
		params.txop = get_unaligned_le16(pos + 2);
295
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
296
		printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d "
297
		       "cWmin=%d cWmax=%d txop=%d\n",
298
		       local->mdev->name, queue, aci, acm, params.aifs, params.cw_min,
299 300
		       params.cw_max, params.txop);
#endif
301 302 303 304
		/* TODO: handle ACM (block TX, fallback to next lowest allowed
		 * AC for now) */
		if (local->ops->conf_tx(local_to_hw(local), queue, &params)) {
			printk(KERN_DEBUG "%s: failed to set TX queue "
305
			       "parameters for queue %d\n", local->mdev->name, queue);
306 307 308 309
		}
	}
}

310 311 312
static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata,
					   bool use_protection,
					   bool use_short_preamble)
313
{
314
	struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
315
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
316
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
317
	DECLARE_MAC_BUF(mac);
318
#endif
319
	u32 changed = 0;
320

321
	if (use_protection != bss_conf->use_cts_prot) {
322
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
323 324
		if (net_ratelimit()) {
			printk(KERN_DEBUG "%s: CTS protection %s (BSSID="
325
			       "%s)\n",
326
			       sdata->dev->name,
327
			       use_protection ? "enabled" : "disabled",
328
			       print_mac(mac, ifsta->bssid));
329
		}
330
#endif
331 332
		bss_conf->use_cts_prot = use_protection;
		changed |= BSS_CHANGED_ERP_CTS_PROT;
333
	}
334

335
	if (use_short_preamble != bss_conf->use_short_preamble) {
336
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
337 338
		if (net_ratelimit()) {
			printk(KERN_DEBUG "%s: switched to %s barker preamble"
339
			       " (BSSID=%s)\n",
340
			       sdata->dev->name,
341
			       use_short_preamble ? "short" : "long",
342
			       print_mac(mac, ifsta->bssid));
343
		}
344
#endif
345
		bss_conf->use_short_preamble = use_short_preamble;
346
		changed |= BSS_CHANGED_ERP_PREAMBLE;
347
	}
348

349
	return changed;
350 351
}

352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata,
				   u8 erp_value)
{
	bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
	bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0;

	return ieee80211_handle_protect_preamb(sdata,
			use_protection, use_short_preamble);
}

static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
					   struct ieee80211_sta_bss *bss)
{
	u32 changed = 0;

	if (bss->has_erp_value)
		changed |= ieee80211_handle_erp_ie(sdata, bss->erp_value);
	else {
		u16 capab = bss->capability;
		changed |= ieee80211_handle_protect_preamb(sdata, false,
				(capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);
	}

	return changed;
}

378 379 380 381 382 383 384 385 386 387 388
static void ieee80211_sta_send_apinfo(struct ieee80211_sub_if_data *sdata,
					struct ieee80211_if_sta *ifsta)
{
	union iwreq_data wrqu;
	memset(&wrqu, 0, sizeof(wrqu));
	if (ifsta->flags & IEEE80211_STA_ASSOCIATED)
		memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN);
	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
	wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
}

389
static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata,
390 391 392 393 394
					 struct ieee80211_if_sta *ifsta)
{
	union iwreq_data wrqu;

	if (ifsta->assocreq_ies) {
395 396
		memset(&wrqu, 0, sizeof(wrqu));
		wrqu.data.length = ifsta->assocreq_ies_len;
397
		wireless_send_event(sdata->dev, IWEVASSOCREQIE, &wrqu,
398
				    ifsta->assocreq_ies);
399
	}
400 401 402
	if (ifsta->assocresp_ies) {
		memset(&wrqu, 0, sizeof(wrqu));
		wrqu.data.length = ifsta->assocresp_ies_len;
403
		wireless_send_event(sdata->dev, IWEVASSOCRESPIE, &wrqu,
404
				    ifsta->assocresp_ies);
405 406 407 408
	}
}


409
static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
410
				     struct ieee80211_if_sta *ifsta)
411
{
412
	struct ieee80211_local *local = sdata->local;
T
Tomas Winkler 已提交
413
	struct ieee80211_conf *conf = &local_to_hw(local)->conf;
414
	u32 changed = BSS_CHANGED_ASSOC;
415

416
	struct ieee80211_sta_bss *bss;
417

418
	ifsta->flags |= IEEE80211_STA_ASSOCIATED;
419

420 421
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
		return;
422

423 424 425 426 427 428 429 430
	bss = ieee80211_rx_bss_get(local, ifsta->bssid,
				   conf->channel->center_freq,
				   ifsta->ssid, ifsta->ssid_len);
	if (bss) {
		/* set timing information */
		sdata->bss_conf.beacon_int = bss->beacon_int;
		sdata->bss_conf.timestamp = bss->timestamp;
		sdata->bss_conf.dtim_period = bss->dtim_period;
431

432
		changed |= ieee80211_handle_bss_capability(sdata, bss);
433

434 435
		ieee80211_rx_bss_put(local, bss);
	}
T
Tomas Winkler 已提交
436

437 438 439 440 441 442
	if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
		changed |= BSS_CHANGED_HT;
		sdata->bss_conf.assoc_ht = 1;
		sdata->bss_conf.ht_conf = &conf->ht_conf;
		sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf;
	}
T
Tomas Winkler 已提交
443

444 445 446
	ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET;
	memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN);
	ieee80211_sta_send_associnfo(sdata, ifsta);
T
Tomas Winkler 已提交
447

448
	ifsta->last_probe = jiffies;
449
	ieee80211_led_assoc(local, 1);
450

451
	sdata->bss_conf.assoc = 1;
452
	ieee80211_bss_info_change_notify(sdata, changed);
453

454
	netif_tx_start_all_queues(sdata->dev);
455
	netif_carrier_on(sdata->dev);
456

457
	ieee80211_sta_send_apinfo(sdata, ifsta);
458 459
}

460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489
static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
				   struct ieee80211_if_sta *ifsta)
{
	DECLARE_MAC_BUF(mac);

	ifsta->direct_probe_tries++;
	if (ifsta->direct_probe_tries > IEEE80211_AUTH_MAX_TRIES) {
		printk(KERN_DEBUG "%s: direct probe to AP %s timed out\n",
		       sdata->dev->name, print_mac(mac, ifsta->bssid));
		ifsta->state = IEEE80211_STA_MLME_DISABLED;
		return;
	}

	printk(KERN_DEBUG "%s: direct probe to AP %s try %d\n",
			sdata->dev->name, print_mac(mac, ifsta->bssid),
			ifsta->direct_probe_tries);

	ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;

	set_bit(IEEE80211_STA_REQ_DIRECT_PROBE, &ifsta->request);

	/* Direct probe is sent to broadcast address as some APs
	 * will not answer to direct packet in unassociated state.
	 */
	ieee80211_send_probe_req(sdata, NULL,
				 ifsta->ssid, ifsta->ssid_len);

	mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
}

490

491
static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
492 493
				   struct ieee80211_if_sta *ifsta)
{
494 495
	DECLARE_MAC_BUF(mac);

496 497
	ifsta->auth_tries++;
	if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) {
498
		printk(KERN_DEBUG "%s: authentication with AP %s"
499
		       " timed out\n",
500
		       sdata->dev->name, print_mac(mac, ifsta->bssid));
501
		ifsta->state = IEEE80211_STA_MLME_DISABLED;
502 503 504
		return;
	}

505
	ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
506
	printk(KERN_DEBUG "%s: authenticate with AP %s\n",
507
	       sdata->dev->name, print_mac(mac, ifsta->bssid));
508

509
	ieee80211_send_auth(sdata, ifsta, 1, NULL, 0, 0);
510 511 512 513

	mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
}

514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533
static int ieee80211_compatible_rates(struct ieee80211_sta_bss *bss,
				      struct ieee80211_supported_band *sband,
				      u64 *rates)
{
	int i, j, count;
	*rates = 0;
	count = 0;
	for (i = 0; i < bss->supp_rates_len; i++) {
		int rate = (bss->supp_rates[i] & 0x7F) * 5;

		for (j = 0; j < sband->n_bitrates; j++)
			if (sband->bitrates[j].bitrate == rate) {
				*rates |= BIT(j);
				count++;
				break;
			}
	}

	return count;
}
534

535
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
536 537
				 struct ieee80211_if_sta *ifsta)
{
538
	struct ieee80211_local *local = sdata->local;
539 540
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
541
	u8 *pos, *ies, *ht_add_ie;
542
	int i, len, count, rates_len, supp_rates_len;
543 544 545
	u16 capab;
	struct ieee80211_sta_bss *bss;
	int wmm = 0;
546
	struct ieee80211_supported_band *sband;
547
	u64 rates = 0;
548 549 550 551 552 553

	skb = dev_alloc_skb(local->hw.extra_tx_headroom +
			    sizeof(*mgmt) + 200 + ifsta->extra_ie_len +
			    ifsta->ssid_len);
	if (!skb) {
		printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
554
		       "frame\n", sdata->dev->name);
555 556 557 558
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

559 560
	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];

561
	capab = ifsta->capab;
562 563 564 565 566 567

	if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) {
		if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
			capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
		if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
			capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
568
	}
569

570
	bss = ieee80211_rx_bss_get(local, ifsta->bssid,
571
				   local->hw.conf.channel->center_freq,
572
				   ifsta->ssid, ifsta->ssid_len);
573 574 575
	if (bss) {
		if (bss->capability & WLAN_CAPABILITY_PRIVACY)
			capab |= WLAN_CAPABILITY_PRIVACY;
576
		if (bss->wmm_used)
577
			wmm = 1;
578 579 580 581 582 583 584

		/* get all rates supported by the device and the AP as
		 * some APs don't like getting a superset of their rates
		 * in the association request (e.g. D-Link DAP 1353 in
		 * b-only mode) */
		rates_len = ieee80211_compatible_rates(bss, sband, &rates);

585 586 587 588
		if ((bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
		    (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
			capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;

589
		ieee80211_rx_bss_put(local, bss);
590 591 592
	} else {
		rates = ~0;
		rates_len = sband->n_bitrates;
593 594 595 596 597
	}

	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
	memset(mgmt, 0, 24);
	memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
598
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
599 600
	memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);

601
	if (ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) {
602
		skb_put(skb, 10);
603 604
		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_REASSOC_REQ);
605
		mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
606 607
		mgmt->u.reassoc_req.listen_interval =
				cpu_to_le16(local->hw.conf.listen_interval);
608 609 610 611
		memcpy(mgmt->u.reassoc_req.current_ap, ifsta->prev_bssid,
		       ETH_ALEN);
	} else {
		skb_put(skb, 4);
612 613
		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_ASSOC_REQ);
614
		mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
615 616
		mgmt->u.reassoc_req.listen_interval =
				cpu_to_le16(local->hw.conf.listen_interval);
617 618 619 620 621 622 623 624
	}

	/* SSID */
	ies = pos = skb_put(skb, 2 + ifsta->ssid_len);
	*pos++ = WLAN_EID_SSID;
	*pos++ = ifsta->ssid_len;
	memcpy(pos, ifsta->ssid, ifsta->ssid_len);

625
	/* add all rates which were marked to be used above */
626 627 628 629
	supp_rates_len = rates_len;
	if (supp_rates_len > 8)
		supp_rates_len = 8;

630
	len = sband->n_bitrates;
631
	pos = skb_put(skb, supp_rates_len + 2);
632
	*pos++ = WLAN_EID_SUPP_RATES;
633
	*pos++ = supp_rates_len;
634

635 636 637
	count = 0;
	for (i = 0; i < sband->n_bitrates; i++) {
		if (BIT(i) & rates) {
638
			int rate = sband->bitrates[i].bitrate;
639
			*pos++ = (u8) (rate / 5);
640 641 642 643 644
			if (++count == 8)
				break;
		}
	}

645
	if (rates_len > count) {
646 647 648 649 650 651 652 653 654
		pos = skb_put(skb, rates_len - count + 2);
		*pos++ = WLAN_EID_EXT_SUPP_RATES;
		*pos++ = rates_len - count;

		for (i++; i < sband->n_bitrates; i++) {
			if (BIT(i) & rates) {
				int rate = sband->bitrates[i].bitrate;
				*pos++ = (u8) (rate / 5);
			}
655 656 657
		}
	}

658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677
	if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
		/* 1. power capabilities */
		pos = skb_put(skb, 4);
		*pos++ = WLAN_EID_PWR_CAPABILITY;
		*pos++ = 2;
		*pos++ = 0; /* min tx power */
		*pos++ = local->hw.conf.channel->max_power; /* max tx power */

		/* 2. supported channels */
		/* TODO: get this in reg domain format */
		pos = skb_put(skb, 2 * sband->n_channels + 2);
		*pos++ = WLAN_EID_SUPPORTED_CHANNELS;
		*pos++ = 2 * sband->n_channels;
		for (i = 0; i < sband->n_channels; i++) {
			*pos++ = ieee80211_frequency_to_channel(
					sband->channels[i].center_freq);
			*pos++ = 1; /* one channel in the subband*/
		}
	}

678 679 680 681 682
	if (ifsta->extra_ie) {
		pos = skb_put(skb, ifsta->extra_ie_len);
		memcpy(pos, ifsta->extra_ie, ifsta->extra_ie_len);
	}

683
	if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
684 685 686 687 688 689 690 691 692 693 694
		pos = skb_put(skb, 9);
		*pos++ = WLAN_EID_VENDOR_SPECIFIC;
		*pos++ = 7; /* len */
		*pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
		*pos++ = 0x50;
		*pos++ = 0xf2;
		*pos++ = 2; /* WME */
		*pos++ = 0; /* WME info */
		*pos++ = 1; /* WME ver */
		*pos++ = 0;
	}
695

696
	/* wmm support is a must to HT */
697
	if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) &&
698 699
	    sband->ht_info.ht_supported &&
	    (ht_add_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_EXTRA_INFO))) {
700
		struct ieee80211_ht_addt_info *ht_add_info =
701
			(struct ieee80211_ht_addt_info *)ht_add_ie;
702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721
		u16 cap = sband->ht_info.cap;
		__le16 tmp;
		u32 flags = local->hw.conf.channel->flags;

		switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) {
		case IEEE80211_HT_IE_CHA_SEC_ABOVE:
			if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) {
				cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
				cap &= ~IEEE80211_HT_CAP_SGI_40;
			}
			break;
		case IEEE80211_HT_IE_CHA_SEC_BELOW:
			if (flags & IEEE80211_CHAN_NO_FAT_BELOW) {
				cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
				cap &= ~IEEE80211_HT_CAP_SGI_40;
			}
			break;
		}

		tmp = cpu_to_le16(cap);
722 723 724 725 726 727
		pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2);
		*pos++ = WLAN_EID_HT_CAPABILITY;
		*pos++ = sizeof(struct ieee80211_ht_cap);
		memset(pos, 0, sizeof(struct ieee80211_ht_cap));
		memcpy(pos, &tmp, sizeof(u16));
		pos += sizeof(u16);
728 729 730 731
		/* TODO: needs a define here for << 2 */
		*pos++ = sband->ht_info.ampdu_factor |
			 (sband->ht_info.ampdu_density << 2);
		memcpy(pos, sband->ht_info.supp_mcs_set, 16);
732
	}
733 734 735

	kfree(ifsta->assocreq_ies);
	ifsta->assocreq_ies_len = (skb->data + skb->len) - ies;
736
	ifsta->assocreq_ies = kmalloc(ifsta->assocreq_ies_len, GFP_KERNEL);
737 738 739
	if (ifsta->assocreq_ies)
		memcpy(ifsta->assocreq_ies, ies, ifsta->assocreq_ies_len);

740
	ieee80211_sta_tx(sdata, skb, 0);
741 742 743
}


744
static void ieee80211_send_deauth(struct ieee80211_sub_if_data *sdata,
745 746
				  struct ieee80211_if_sta *ifsta, u16 reason)
{
747
	struct ieee80211_local *local = sdata->local;
748 749 750 751 752 753
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;

	skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt));
	if (!skb) {
		printk(KERN_DEBUG "%s: failed to allocate buffer for deauth "
754
		       "frame\n", sdata->dev->name);
755 756 757 758 759 760 761
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
	memset(mgmt, 0, 24);
	memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
762
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
763
	memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
764 765
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_DEAUTH);
766 767 768
	skb_put(skb, 2);
	mgmt->u.deauth.reason_code = cpu_to_le16(reason);

769
	ieee80211_sta_tx(sdata, skb, 0);
770 771
}

J
Johannes Berg 已提交
772 773 774 775 776 777 778
static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata)
{
	if (!sdata || !sdata->default_key ||
	    sdata->default_key->conf.alg != ALG_WEP)
		return 0;
	return 1;
}
779

780
static void ieee80211_send_disassoc(struct ieee80211_sub_if_data *sdata,
781 782
				    struct ieee80211_if_sta *ifsta, u16 reason)
{
783
	struct ieee80211_local *local = sdata->local;
784 785 786 787 788 789
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;

	skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt));
	if (!skb) {
		printk(KERN_DEBUG "%s: failed to allocate buffer for disassoc "
790
		       "frame\n", sdata->dev->name);
791 792 793 794 795 796 797
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
	memset(mgmt, 0, 24);
	memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
798
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
799
	memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
800 801
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_DISASSOC);
802 803 804
	skb_put(skb, 2);
	mgmt->u.disassoc.reason_code = cpu_to_le16(reason);

805
	ieee80211_sta_tx(sdata, skb, 0);
806 807
}

808 809 810 811 812 813
static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
				   struct ieee80211_if_sta *ifsta, bool deauth,
				   bool self_disconnected, u16 reason)
{
	struct ieee80211_local *local = sdata->local;
	struct sta_info *sta;
814
	u32 changed = BSS_CHANGED_ASSOC;
815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830

	rcu_read_lock();

	sta = sta_info_get(local, ifsta->bssid);
	if (!sta) {
		rcu_read_unlock();
		return;
	}

	if (deauth) {
		ifsta->direct_probe_tries = 0;
		ifsta->auth_tries = 0;
	}
	ifsta->assoc_scan_tries = 0;
	ifsta->assoc_tries = 0;

831
	netif_tx_stop_all_queues(sdata->dev);
832 833 834 835 836 837 838 839 840 841 842
	netif_carrier_off(sdata->dev);

	ieee80211_sta_tear_down_BA_sessions(sdata, sta->addr);

	if (self_disconnected) {
		if (deauth)
			ieee80211_send_deauth(sdata, ifsta, reason);
		else
			ieee80211_send_disassoc(sdata, ifsta, reason);
	}

843 844 845 846 847 848 849 850 851 852 853 854 855 856
	ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
	changed |= ieee80211_reset_erp_info(sdata);

	if (sdata->bss_conf.assoc_ht)
		changed |= BSS_CHANGED_HT;

	sdata->bss_conf.assoc_ht = 0;
	sdata->bss_conf.ht_conf = NULL;
	sdata->bss_conf.ht_bss_conf = NULL;

	ieee80211_led_assoc(local, 0);
	sdata->bss_conf.assoc = 0;

	ieee80211_sta_send_apinfo(sdata, ifsta);
857 858 859 860 861 862 863 864 865 866

	if (self_disconnected)
		ifsta->state = IEEE80211_STA_MLME_DISABLED;

	sta_info_unlink(&sta);

	rcu_read_unlock();

	sta_info_destroy(sta);
}
867

868
static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata,
869 870
				      struct ieee80211_if_sta *ifsta)
{
871
	struct ieee80211_local *local = sdata->local;
872
	struct ieee80211_sta_bss *bss;
873 874 875
	int bss_privacy;
	int wep_privacy;
	int privacy_invoked;
876

877
	if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL))
878 879
		return 0;

880
	bss = ieee80211_rx_bss_get(local, ifsta->bssid,
881
				   local->hw.conf.channel->center_freq,
882
				   ifsta->ssid, ifsta->ssid_len);
883 884 885
	if (!bss)
		return 0;

886
	bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY);
887
	wep_privacy = !!ieee80211_sta_wep_configured(sdata);
888
	privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED);
889

890
	ieee80211_rx_bss_put(local, bss);
891

892 893 894 895
	if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked))
		return 0;

	return 1;
896 897
}

898
static void ieee80211_associate(struct ieee80211_sub_if_data *sdata,
899 900
				struct ieee80211_if_sta *ifsta)
{
901 902
	DECLARE_MAC_BUF(mac);

903 904
	ifsta->assoc_tries++;
	if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) {
905
		printk(KERN_DEBUG "%s: association with AP %s"
906
		       " timed out\n",
907
		       sdata->dev->name, print_mac(mac, ifsta->bssid));
908
		ifsta->state = IEEE80211_STA_MLME_DISABLED;
909 910 911
		return;
	}

912
	ifsta->state = IEEE80211_STA_MLME_ASSOCIATE;
913
	printk(KERN_DEBUG "%s: associate with AP %s\n",
914 915
	       sdata->dev->name, print_mac(mac, ifsta->bssid));
	if (ieee80211_privacy_mismatch(sdata, ifsta)) {
916
		printk(KERN_DEBUG "%s: mismatch in privacy configuration and "
917
		       "mixed-cell disabled - abort association\n", sdata->dev->name);
918
		ifsta->state = IEEE80211_STA_MLME_DISABLED;
919 920 921
		return;
	}

922
	ieee80211_send_assoc(sdata, ifsta);
923 924 925 926 927

	mod_timer(&ifsta->timer, jiffies + IEEE80211_ASSOC_TIMEOUT);
}


928
static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
929 930
				 struct ieee80211_if_sta *ifsta)
{
931
	struct ieee80211_local *local = sdata->local;
932 933
	struct sta_info *sta;
	int disassoc;
934
	DECLARE_MAC_BUF(mac);
935 936 937 938 939 940

	/* TODO: start monitoring current AP signal quality and number of
	 * missed beacons. Scan other channels every now and then and search
	 * for better APs. */
	/* TODO: remove expired BSSes */

941
	ifsta->state = IEEE80211_STA_MLME_ASSOCIATED;
942

943 944
	rcu_read_lock();

945 946
	sta = sta_info_get(local, ifsta->bssid);
	if (!sta) {
947
		printk(KERN_DEBUG "%s: No STA entry for own AP %s\n",
948
		       sdata->dev->name, print_mac(mac, ifsta->bssid));
949 950 951 952 953
		disassoc = 1;
	} else {
		disassoc = 0;
		if (time_after(jiffies,
			       sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
954
			if (ifsta->flags & IEEE80211_STA_PROBEREQ_POLL) {
955
				printk(KERN_DEBUG "%s: No ProbeResp from "
956
				       "current AP %s - assume out of "
957
				       "range\n",
958
				       sdata->dev->name, print_mac(mac, ifsta->bssid));
959
				disassoc = 1;
960
			} else
961
				ieee80211_send_probe_req(sdata, ifsta->bssid,
962 963
							 local->scan_ssid,
							 local->scan_ssid_len);
964
			ifsta->flags ^= IEEE80211_STA_PROBEREQ_POLL;
965
		} else {
966
			ifsta->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
967 968 969
			if (time_after(jiffies, ifsta->last_probe +
				       IEEE80211_PROBE_INTERVAL)) {
				ifsta->last_probe = jiffies;
970
				ieee80211_send_probe_req(sdata, ifsta->bssid,
971 972 973 974 975
							 ifsta->ssid,
							 ifsta->ssid_len);
			}
		}
	}
976 977 978

	rcu_read_unlock();

J
Johannes Berg 已提交
979 980 981 982 983 984
	if (disassoc)
		ieee80211_set_disassoc(sdata, ifsta, true, true,
					WLAN_REASON_PREV_AUTH_NOT_VALID);
	else
		mod_timer(&ifsta->timer, jiffies +
				      IEEE80211_MONITORING_INTERVAL);
985 986 987
}


988
static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata,
989 990
				     struct ieee80211_if_sta *ifsta)
{
991
	printk(KERN_DEBUG "%s: authenticated\n", sdata->dev->name);
992
	ifsta->flags |= IEEE80211_STA_AUTHENTICATED;
993
	ieee80211_associate(sdata, ifsta);
994 995 996
}


997
static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
998 999 1000 1001 1002 1003 1004 1005
				     struct ieee80211_if_sta *ifsta,
				     struct ieee80211_mgmt *mgmt,
				     size_t len)
{
	u8 *pos;
	struct ieee802_11_elems elems;

	pos = mgmt->u.auth.variable;
1006
	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1007
	if (!elems.challenge)
1008
		return;
1009
	ieee80211_send_auth(sdata, ifsta, 3, elems.challenge - 2,
1010 1011 1012
			    elems.challenge_len + 2, 1);
}

1013
static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
1014 1015 1016 1017
					u8 dialog_token, u16 status, u16 policy,
					u16 buf_size, u16 timeout)
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
1018
	struct ieee80211_local *local = sdata->local;
1019 1020 1021 1022
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u16 capab;

E
Ester Kummer 已提交
1023 1024
	skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);

1025 1026
	if (!skb) {
		printk(KERN_DEBUG "%s: failed to allocate buffer "
1027
		       "for addba resp frame\n", sdata->dev->name);
1028 1029 1030 1031 1032 1033 1034
		return;
	}

	skb_reserve(skb, local->hw.extra_tx_headroom);
	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
	memset(mgmt, 0, 24);
	memcpy(mgmt->da, da, ETH_ALEN);
1035
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1036
	if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
1037
		memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
1038 1039
	else
		memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1040 1041
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_ACTION);
1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055

	skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_resp));
	mgmt->u.action.category = WLAN_CATEGORY_BACK;
	mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP;
	mgmt->u.action.u.addba_resp.dialog_token = dialog_token;

	capab = (u16)(policy << 1);	/* bit 1 aggregation policy */
	capab |= (u16)(tid << 2); 	/* bit 5:2 TID number */
	capab |= (u16)(buf_size << 6);	/* bit 15:6 max size of aggregation */

	mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab);
	mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout);
	mgmt->u.action.u.addba_resp.status = cpu_to_le16(status);

1056
	ieee80211_sta_tx(sdata, skb, 0);
1057 1058 1059 1060

	return;
}

J
Johannes Berg 已提交
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084
/*
 * After accepting the AddBA Request we activated a timer,
 * resetting it after each frame that arrives from the originator.
 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed.
 */
static void sta_rx_agg_session_timer_expired(unsigned long data)
{
	/* not an elegant detour, but there is no choice as the timer passes
	 * only one argument, and various sta_info are needed here, so init
	 * flow in sta_info_create gives the TID as data, while the timer_to_id
	 * array gives the sta through container_of */
	u8 *ptid = (u8 *)data;
	u8 *timer_to_id = ptid - *ptid;
	struct sta_info *sta = container_of(timer_to_id, struct sta_info,
					 timer_to_tid[0]);

#ifdef CONFIG_MAC80211_HT_DEBUG
	printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
#endif
	ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->addr,
					 (u16)*ptid, WLAN_BACK_TIMER,
					 WLAN_REASON_QSTA_TIMEOUT);
}

1085
static void ieee80211_sta_process_addba_request(struct ieee80211_local *local,
1086 1087 1088
						struct ieee80211_mgmt *mgmt,
						size_t len)
{
1089 1090
	struct ieee80211_hw *hw = &local->hw;
	struct ieee80211_conf *conf = &hw->conf;
1091
	struct sta_info *sta;
1092 1093
	struct tid_ampdu_rx *tid_agg_rx;
	u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
1094
	u8 dialog_token;
1095 1096
	int ret = -EOPNOTSUPP;
	DECLARE_MAC_BUF(mac);
1097

1098 1099
	rcu_read_lock();

1100
	sta = sta_info_get(local, mgmt->sa);
1101 1102
	if (!sta) {
		rcu_read_unlock();
1103
		return;
1104
	}
1105 1106 1107 1108

	/* extract session parameters from addba request frame */
	dialog_token = mgmt->u.action.u.addba_req.dialog_token;
	timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout);
1109 1110
	start_seq_num =
		le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4;
1111 1112 1113 1114 1115 1116 1117 1118

	capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
	ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1;
	tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
	buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;

	status = WLAN_STATUS_REQUEST_DECLINED;

1119 1120 1121 1122 1123 1124 1125 1126 1127
	/* sanity check for incoming parameters:
	 * check if configuration can support the BA policy
	 * and if buffer size does not exceeds max value */
	if (((ba_policy != 1)
		&& (!(conf->ht_conf.cap & IEEE80211_HT_CAP_DELAY_BA)))
		|| (buf_size > IEEE80211_MAX_AMPDU_BUF)) {
		status = WLAN_STATUS_INVALID_QOS_PARAM;
#ifdef CONFIG_MAC80211_HT_DEBUG
		if (net_ratelimit())
1128
			printk(KERN_DEBUG "AddBA Req with bad params from "
1129 1130 1131 1132 1133 1134 1135 1136
				"%s on tid %u. policy %d, buffer size %d\n",
				print_mac(mac, mgmt->sa), tid, ba_policy,
				buf_size);
#endif /* CONFIG_MAC80211_HT_DEBUG */
		goto end_no_lock;
	}
	/* determine default buffer size */
	if (buf_size == 0) {
1137 1138 1139
		struct ieee80211_supported_band *sband;

		sband = local->hw.wiphy->bands[conf->channel->band];
1140
		buf_size = IEEE80211_MIN_AMPDU_BUF;
1141
		buf_size = buf_size << sband->ht_info.ampdu_factor;
1142 1143 1144 1145
	}


	/* examine state machine */
1146
	spin_lock_bh(&sta->lock);
1147

1148
	if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
1149 1150
#ifdef CONFIG_MAC80211_HT_DEBUG
		if (net_ratelimit())
1151
			printk(KERN_DEBUG "unexpected AddBA Req from "
1152 1153 1154 1155 1156 1157
				"%s on tid %u\n",
				print_mac(mac, mgmt->sa), tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */
		goto end;
	}

1158 1159 1160 1161
	/* prepare A-MPDU MLME for Rx aggregation */
	sta->ampdu_mlme.tid_rx[tid] =
			kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC);
	if (!sta->ampdu_mlme.tid_rx[tid]) {
1162
#ifdef CONFIG_MAC80211_HT_DEBUG
1163 1164 1165
		if (net_ratelimit())
			printk(KERN_ERR "allocate rx mlme to tid %d failed\n",
					tid);
1166
#endif
1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177
		goto end;
	}
	/* rx timer */
	sta->ampdu_mlme.tid_rx[tid]->session_timer.function =
				sta_rx_agg_session_timer_expired;
	sta->ampdu_mlme.tid_rx[tid]->session_timer.data =
				(unsigned long)&sta->timer_to_tid[tid];
	init_timer(&sta->ampdu_mlme.tid_rx[tid]->session_timer);

	tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];

1178 1179
	/* prepare reordering buffer */
	tid_agg_rx->reorder_buf =
1180
		kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC);
1181
	if (!tid_agg_rx->reorder_buf) {
1182
#ifdef CONFIG_MAC80211_HT_DEBUG
1183 1184 1185
		if (net_ratelimit())
			printk(KERN_ERR "can not allocate reordering buffer "
			       "to tid %d\n", tid);
1186
#endif
1187
		kfree(sta->ampdu_mlme.tid_rx[tid]);
1188 1189 1190
		goto end;
	}
	memset(tid_agg_rx->reorder_buf, 0,
1191
		buf_size * sizeof(struct sk_buff *));
1192 1193 1194

	if (local->ops->ampdu_action)
		ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START,
1195
					       sta->addr, tid, &start_seq_num);
1196
#ifdef CONFIG_MAC80211_HT_DEBUG
1197
	printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
1198 1199 1200 1201
#endif /* CONFIG_MAC80211_HT_DEBUG */

	if (ret) {
		kfree(tid_agg_rx->reorder_buf);
1202 1203
		kfree(tid_agg_rx);
		sta->ampdu_mlme.tid_rx[tid] = NULL;
1204 1205 1206 1207
		goto end;
	}

	/* change state and send addba resp */
1208
	sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL;
1209 1210 1211 1212 1213 1214 1215 1216
	tid_agg_rx->dialog_token = dialog_token;
	tid_agg_rx->ssn = start_seq_num;
	tid_agg_rx->head_seq_num = start_seq_num;
	tid_agg_rx->buf_size = buf_size;
	tid_agg_rx->timeout = timeout;
	tid_agg_rx->stored_mpdu_num = 0;
	status = WLAN_STATUS_SUCCESS;
end:
1217
	spin_unlock_bh(&sta->lock);
1218 1219

end_no_lock:
1220
	ieee80211_send_addba_resp(sta->sdata, sta->addr, tid,
1221 1222
				  dialog_token, status, 1, buf_size, timeout);
	rcu_read_unlock();
1223
}
1224

1225
static void ieee80211_sta_process_addba_resp(struct ieee80211_local *local,
1226 1227 1228 1229 1230 1231 1232 1233 1234
					     struct ieee80211_mgmt *mgmt,
					     size_t len)
{
	struct ieee80211_hw *hw = &local->hw;
	struct sta_info *sta;
	u16 capab;
	u16 tid;
	u8 *state;

1235 1236
	rcu_read_lock();

1237
	sta = sta_info_get(local, mgmt->sa);
1238 1239
	if (!sta) {
		rcu_read_unlock();
1240
		return;
1241
	}
1242 1243 1244 1245

	capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
	tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;

1246
	state = &sta->ampdu_mlme.tid_state_tx[tid];
1247

1248
	spin_lock_bh(&sta->lock);
1249

1250
	if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1251
		spin_unlock_bh(&sta->lock);
1252 1253 1254
		goto addba_resp_exit;
	}

1255
	if (mgmt->u.action.u.addba_resp.dialog_token !=
1256
		sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
1257
		spin_unlock_bh(&sta->lock);
1258 1259 1260
#ifdef CONFIG_MAC80211_HT_DEBUG
		printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */
1261
		goto addba_resp_exit;
1262 1263
	}

1264
	del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
1265 1266 1267 1268 1269 1270
#ifdef CONFIG_MAC80211_HT_DEBUG
	printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */
	if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
			== WLAN_STATUS_SUCCESS) {
		*state |= HT_ADDBA_RECEIVED_MSK;
1271
		sta->ampdu_mlme.addba_req_num[tid] = 0;
1272

1273
		if (*state == HT_AGG_STATE_OPERATIONAL)
1274 1275
			ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);

1276
		spin_unlock_bh(&sta->lock);
1277
	} else {
1278
		sta->ampdu_mlme.addba_req_num[tid]++;
1279 1280
		/* this will allow the state check in stop_BA_session */
		*state = HT_AGG_STATE_OPERATIONAL;
1281
		spin_unlock_bh(&sta->lock);
1282 1283 1284
		ieee80211_stop_tx_ba_session(hw, sta->addr, tid,
					     WLAN_BACK_INITIATOR);
	}
1285 1286

addba_resp_exit:
1287
	rcu_read_unlock();
1288 1289
}

1290
static void ieee80211_sta_process_delba(struct ieee80211_sub_if_data *sdata,
1291 1292
			struct ieee80211_mgmt *mgmt, size_t len)
{
1293
	struct ieee80211_local *local = sdata->local;
1294 1295 1296 1297 1298
	struct sta_info *sta;
	u16 tid, params;
	u16 initiator;
	DECLARE_MAC_BUF(mac);

1299 1300
	rcu_read_lock();

1301
	sta = sta_info_get(local, mgmt->sa);
1302 1303
	if (!sta) {
		rcu_read_unlock();
1304
		return;
1305
	}
1306 1307 1308 1309 1310 1311 1312

	params = le16_to_cpu(mgmt->u.action.u.delba.params);
	tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
	initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11;

#ifdef CONFIG_MAC80211_HT_DEBUG
	if (net_ratelimit())
1313 1314
		printk(KERN_DEBUG "delba from %s (%s) tid %d reason code %d\n",
			print_mac(mac, mgmt->sa),
1315
			initiator ? "initiator" : "recipient", tid,
1316 1317 1318 1319
			mgmt->u.action.u.delba.reason_code);
#endif /* CONFIG_MAC80211_HT_DEBUG */

	if (initiator == WLAN_BACK_INITIATOR)
1320
		ieee80211_sta_stop_rx_ba_session(sdata, sta->addr, tid,
1321
						 WLAN_BACK_INITIATOR, 0);
1322
	else { /* WLAN_BACK_RECIPIENT */
1323
		spin_lock_bh(&sta->lock);
1324
		sta->ampdu_mlme.tid_state_tx[tid] =
1325
				HT_AGG_STATE_OPERATIONAL;
1326
		spin_unlock_bh(&sta->lock);
1327 1328 1329
		ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid,
					     WLAN_BACK_RECIPIENT);
	}
1330
	rcu_read_unlock();
1331 1332
}

1333
static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_data *sdata,
1334 1335 1336 1337
					struct ieee80211_msrment_ie *request_ie,
					const u8 *da, const u8 *bssid,
					u8 dialog_token)
{
1338
	struct ieee80211_local *local = sdata->local;
1339 1340 1341 1342 1343 1344 1345 1346
	struct sk_buff *skb;
	struct ieee80211_mgmt *msr_report;

	skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom +
				sizeof(struct ieee80211_msrment_ie));

	if (!skb) {
		printk(KERN_ERR "%s: failed to allocate buffer for "
1347
				"measurement report frame\n", sdata->dev->name);
1348 1349 1350 1351 1352 1353 1354
		return;
	}

	skb_reserve(skb, local->hw.extra_tx_headroom);
	msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24);
	memset(msr_report, 0, 24);
	memcpy(msr_report->da, da, ETH_ALEN);
1355
	memcpy(msr_report->sa, sdata->dev->dev_addr, ETH_ALEN);
1356
	memcpy(msr_report->bssid, bssid, ETH_ALEN);
1357
	msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376
						IEEE80211_STYPE_ACTION);

	skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement));
	msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
	msr_report->u.action.u.measurement.action_code =
				WLAN_ACTION_SPCT_MSR_RPRT;
	msr_report->u.action.u.measurement.dialog_token = dialog_token;

	msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT;
	msr_report->u.action.u.measurement.length =
			sizeof(struct ieee80211_msrment_ie);

	memset(&msr_report->u.action.u.measurement.msr_elem, 0,
		sizeof(struct ieee80211_msrment_ie));
	msr_report->u.action.u.measurement.msr_elem.token = request_ie->token;
	msr_report->u.action.u.measurement.msr_elem.mode |=
			IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED;
	msr_report->u.action.u.measurement.msr_elem.type = request_ie->type;

1377
	ieee80211_sta_tx(sdata, skb, 0);
1378 1379
}

1380
static void ieee80211_sta_process_measurement_req(struct ieee80211_sub_if_data *sdata,
1381 1382 1383 1384 1385 1386 1387 1388 1389 1390
						struct ieee80211_mgmt *mgmt,
						size_t len)
{
	/*
	 * Ignoring measurement request is spec violation.
	 * Mandatory measurements must be reported optional
	 * measurements might be refused or reported incapable
	 * For now just refuse
	 * TODO: Answer basic measurement as unmeasured
	 */
1391
	ieee80211_send_refuse_measurement_request(sdata,
1392 1393 1394 1395 1396 1397
			&mgmt->u.action.u.measurement.msr_elem,
			mgmt->sa, mgmt->bssid,
			mgmt->u.action.u.measurement.dialog_token);
}


1398
static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1399 1400 1401 1402 1403
				   struct ieee80211_if_sta *ifsta,
				   struct ieee80211_mgmt *mgmt,
				   size_t len)
{
	u16 auth_alg, auth_transaction, status_code;
1404
	DECLARE_MAC_BUF(mac);
1405

1406
	if (ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE &&
1407
	    sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
1408 1409
		return;

1410
	if (len < 24 + 6)
1411 1412
		return;

1413
	if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
1414
	    memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0)
1415 1416
		return;

1417
	if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
1418
	    memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0)
1419 1420 1421 1422 1423 1424
		return;

	auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
	auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
	status_code = le16_to_cpu(mgmt->u.auth.status_code);

1425
	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
J
Johannes Berg 已提交
1426 1427
		/*
		 * IEEE 802.11 standard does not require authentication in IBSS
1428 1429 1430
		 * networks and most implementations do not seem to use it.
		 * However, try to reply to authentication attempts if someone
		 * has actually implemented this.
J
Johannes Berg 已提交
1431
		 */
1432
		if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
1433
			return;
1434
		ieee80211_send_auth(sdata, ifsta, 2, NULL, 0, 0);
1435 1436 1437
	}

	if (auth_alg != ifsta->auth_alg ||
1438
	    auth_transaction != ifsta->auth_transaction)
1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466
		return;

	if (status_code != WLAN_STATUS_SUCCESS) {
		if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
			u8 algs[3];
			const int num_algs = ARRAY_SIZE(algs);
			int i, pos;
			algs[0] = algs[1] = algs[2] = 0xff;
			if (ifsta->auth_algs & IEEE80211_AUTH_ALG_OPEN)
				algs[0] = WLAN_AUTH_OPEN;
			if (ifsta->auth_algs & IEEE80211_AUTH_ALG_SHARED_KEY)
				algs[1] = WLAN_AUTH_SHARED_KEY;
			if (ifsta->auth_algs & IEEE80211_AUTH_ALG_LEAP)
				algs[2] = WLAN_AUTH_LEAP;
			if (ifsta->auth_alg == WLAN_AUTH_OPEN)
				pos = 0;
			else if (ifsta->auth_alg == WLAN_AUTH_SHARED_KEY)
				pos = 1;
			else
				pos = 2;
			for (i = 0; i < num_algs; i++) {
				pos++;
				if (pos >= num_algs)
					pos = 0;
				if (algs[pos] == ifsta->auth_alg ||
				    algs[pos] == 0xff)
					continue;
				if (algs[pos] == WLAN_AUTH_SHARED_KEY &&
1467
				    !ieee80211_sta_wep_configured(sdata))
1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478
					continue;
				ifsta->auth_alg = algs[pos];
				break;
			}
		}
		return;
	}

	switch (ifsta->auth_alg) {
	case WLAN_AUTH_OPEN:
	case WLAN_AUTH_LEAP:
1479
		ieee80211_auth_completed(sdata, ifsta);
1480 1481 1482
		break;
	case WLAN_AUTH_SHARED_KEY:
		if (ifsta->auth_transaction == 4)
1483
			ieee80211_auth_completed(sdata, ifsta);
1484
		else
1485
			ieee80211_auth_challenge(sdata, ifsta, mgmt, len);
1486 1487 1488 1489 1490
		break;
	}
}


1491
static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1492 1493 1494 1495 1496
				     struct ieee80211_if_sta *ifsta,
				     struct ieee80211_mgmt *mgmt,
				     size_t len)
{
	u16 reason_code;
1497
	DECLARE_MAC_BUF(mac);
1498

1499
	if (len < 24 + 2)
1500 1501
		return;

1502
	if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN))
1503 1504 1505 1506
		return;

	reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);

J
Johannes Berg 已提交
1507
	if (ifsta->flags & IEEE80211_STA_AUTHENTICATED)
1508
		printk(KERN_DEBUG "%s: deauthenticated\n", sdata->dev->name);
1509

1510 1511 1512
	if (ifsta->state == IEEE80211_STA_MLME_AUTHENTICATE ||
	    ifsta->state == IEEE80211_STA_MLME_ASSOCIATE ||
	    ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) {
1513
		ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
1514 1515 1516 1517
		mod_timer(&ifsta->timer, jiffies +
				      IEEE80211_RETRY_AUTH_INTERVAL);
	}

1518
	ieee80211_set_disassoc(sdata, ifsta, true, false, 0);
1519
	ifsta->flags &= ~IEEE80211_STA_AUTHENTICATED;
1520 1521 1522
}


1523
static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1524 1525 1526 1527 1528
				       struct ieee80211_if_sta *ifsta,
				       struct ieee80211_mgmt *mgmt,
				       size_t len)
{
	u16 reason_code;
1529
	DECLARE_MAC_BUF(mac);
1530

1531
	if (len < 24 + 2)
1532 1533
		return;

1534
	if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN))
1535 1536 1537 1538
		return;

	reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);

1539
	if (ifsta->flags & IEEE80211_STA_ASSOCIATED)
1540
		printk(KERN_DEBUG "%s: disassociated\n", sdata->dev->name);
1541

1542 1543
	if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) {
		ifsta->state = IEEE80211_STA_MLME_ASSOCIATE;
1544 1545 1546 1547
		mod_timer(&ifsta->timer, jiffies +
				      IEEE80211_RETRY_AUTH_INTERVAL);
	}

1548
	ieee80211_set_disassoc(sdata, ifsta, false, false, 0);
1549 1550 1551
}


1552
static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1553 1554 1555 1556 1557
					 struct ieee80211_if_sta *ifsta,
					 struct ieee80211_mgmt *mgmt,
					 size_t len,
					 int reassoc)
{
1558
	struct ieee80211_local *local = sdata->local;
1559
	struct ieee80211_supported_band *sband;
1560
	struct sta_info *sta;
1561
	u64 rates, basic_rates;
1562 1563
	u16 capab_info, status_code, aid;
	struct ieee802_11_elems elems;
1564
	struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
1565 1566
	u8 *pos;
	int i, j;
1567
	DECLARE_MAC_BUF(mac);
1568
	bool have_higher_than_11mbit = false;
1569 1570 1571 1572

	/* AssocResp and ReassocResp have identical structure, so process both
	 * of them in this function. */

1573
	if (ifsta->state != IEEE80211_STA_MLME_ASSOCIATE)
1574 1575
		return;

1576
	if (len < 24 + 6)
1577 1578
		return;

1579
	if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0)
1580 1581 1582 1583 1584 1585
		return;

	capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
	status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
	aid = le16_to_cpu(mgmt->u.assoc_resp.aid);

1586
	printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x "
1587
	       "status=%d aid=%d)\n",
1588
	       sdata->dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa),
1589
	       capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
1590 1591 1592

	if (status_code != WLAN_STATUS_SUCCESS) {
		printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
1593
		       sdata->dev->name, status_code);
1594 1595 1596
		/* if this was a reassociation, ensure we try a "full"
		 * association next time. This works around some broken APs
		 * which do not correctly reject reassociation requests. */
1597
		ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
1598 1599 1600
		return;
	}

1601 1602
	if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
		printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
1603
		       "set\n", sdata->dev->name, aid);
1604 1605
	aid &= ~(BIT(15) | BIT(14));

1606
	pos = mgmt->u.assoc_resp.variable;
1607
	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1608 1609 1610

	if (!elems.supp_rates) {
		printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
1611
		       sdata->dev->name);
1612 1613 1614
		return;
	}

1615
	printk(KERN_DEBUG "%s: associated\n", sdata->dev->name);
1616 1617 1618 1619 1620
	ifsta->aid = aid;
	ifsta->ap_capab = capab_info;

	kfree(ifsta->assocresp_ies);
	ifsta->assocresp_ies_len = len - (pos - (u8 *) mgmt);
1621
	ifsta->assocresp_ies = kmalloc(ifsta->assocresp_ies_len, GFP_KERNEL);
1622 1623 1624
	if (ifsta->assocresp_ies)
		memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len);

1625 1626
	rcu_read_lock();

1627 1628 1629 1630
	/* Add STA entry for the AP */
	sta = sta_info_get(local, ifsta->bssid);
	if (!sta) {
		struct ieee80211_sta_bss *bss;
J
Johannes Berg 已提交
1631
		int err;
1632

J
Johannes Berg 已提交
1633 1634 1635
		sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC);
		if (!sta) {
			printk(KERN_DEBUG "%s: failed to alloc STA entry for"
1636
			       " the AP\n", sdata->dev->name);
1637
			rcu_read_unlock();
1638 1639
			return;
		}
J
Johannes Berg 已提交
1640 1641 1642 1643 1644 1645 1646 1647 1648
		bss = ieee80211_rx_bss_get(local, ifsta->bssid,
					   local->hw.conf.channel->center_freq,
					   ifsta->ssid, ifsta->ssid_len);
		if (bss) {
			sta->last_signal = bss->signal;
			sta->last_qual = bss->qual;
			sta->last_noise = bss->noise;
			ieee80211_rx_bss_put(local, bss);
		}
1649

J
Johannes Berg 已提交
1650 1651 1652 1653 1654 1655
		err = sta_info_insert(sta);
		if (err) {
			printk(KERN_DEBUG "%s: failed to insert STA entry for"
			       " the AP (error %d)\n", sdata->dev->name, err);
			rcu_read_unlock();
			return;
1656
		}
J
Johannes Berg 已提交
1657 1658
		/* update new sta with its last rx activity */
		sta->last_rx = jiffies;
1659 1660
	}

J
Johannes Berg 已提交
1661 1662 1663 1664 1665 1666 1667 1668 1669
	/*
	 * FIXME: Do we really need to update the sta_info's information here?
	 *	  We already know about the AP (we found it in our list) so it
	 *	  should already be filled with the right info, no?
	 *	  As is stands, all this is racy because typically we assume
	 *	  the information that is filled in here (except flags) doesn't
	 *	  change while a STA structure is alive. As such, it should move
	 *	  to between the sta_info_alloc() and sta_info_insert() above.
	 */
1670

J
Johannes Berg 已提交
1671 1672
	set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP |
			   WLAN_STA_AUTHORIZED);
1673

J
Johannes Berg 已提交
1674 1675 1676
	rates = 0;
	basic_rates = 0;
	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1677

J
Johannes Berg 已提交
1678 1679
	for (i = 0; i < elems.supp_rates_len; i++) {
		int rate = (elems.supp_rates[i] & 0x7f) * 5;
1680

J
Johannes Berg 已提交
1681 1682 1683 1684 1685 1686 1687 1688
		if (rate > 110)
			have_higher_than_11mbit = true;

		for (j = 0; j < sband->n_bitrates; j++) {
			if (sband->bitrates[j].bitrate == rate)
				rates |= BIT(j);
			if (elems.supp_rates[i] & 0x80)
				basic_rates |= BIT(j);
1689 1690 1691
		}
	}

J
Johannes Berg 已提交
1692 1693
	for (i = 0; i < elems.ext_supp_rates_len; i++) {
		int rate = (elems.ext_supp_rates[i] & 0x7f) * 5;
1694

J
Johannes Berg 已提交
1695 1696
		if (rate > 110)
			have_higher_than_11mbit = true;
1697

J
Johannes Berg 已提交
1698 1699 1700 1701 1702 1703
		for (j = 0; j < sband->n_bitrates; j++) {
			if (sband->bitrates[j].bitrate == rate)
				rates |= BIT(j);
			if (elems.ext_supp_rates[i] & 0x80)
				basic_rates |= BIT(j);
		}
1704
	}
1705

J
Johannes Berg 已提交
1706 1707 1708 1709 1710 1711 1712 1713 1714
	sta->supp_rates[local->hw.conf.channel->band] = rates;
	sdata->basic_rates = basic_rates;

	/* cf. IEEE 802.11 9.2.12 */
	if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
	    have_higher_than_11mbit)
		sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
	else
		sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
1715

J
Johannes Berg 已提交
1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726
	if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param &&
	    (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
		struct ieee80211_ht_bss_info bss_info;
		ieee80211_ht_cap_ie_to_ht_info(
				(struct ieee80211_ht_cap *)
				elems.ht_cap_elem, &sta->ht_info);
		ieee80211_ht_addt_info_ie_to_ht_bss_info(
				(struct ieee80211_ht_addt_info *)
				elems.ht_info_elem, &bss_info);
		ieee80211_handle_ht(local, 1, &sta->ht_info, &bss_info);
	}
1727

J
Johannes Berg 已提交
1728
	rate_control_rate_init(sta, local);
1729

J
Johannes Berg 已提交
1730 1731 1732 1733 1734 1735 1736
	if (elems.wmm_param) {
		set_sta_flags(sta, WLAN_STA_WME);
		rcu_read_unlock();
		ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
					 elems.wmm_param_len);
	} else
		rcu_read_unlock();
1737

J
Johannes Berg 已提交
1738 1739 1740 1741 1742
	/* set AID and assoc capability,
	 * ieee80211_set_associated() will tell the driver */
	bss_conf->aid = aid;
	bss_conf->assoc_capability = capab_info;
	ieee80211_set_associated(sdata, ifsta);
1743

J
Johannes Berg 已提交
1744
	ieee80211_associated(sdata, ifsta);
1745 1746 1747
}


1748
static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1749 1750 1751
				   struct ieee80211_if_sta *ifsta,
				   struct ieee80211_sta_bss *bss)
{
1752
	struct ieee80211_local *local = sdata->local;
1753 1754 1755 1756 1757
	int res, rates, i, j;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u8 *pos;
	struct ieee80211_supported_band *sband;
1758
	union iwreq_data wrqu;
1759 1760 1761 1762

	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];

	/* Remove possible STA entries from other IBSS networks. */
J
Johannes Berg 已提交
1763
	sta_info_flush_delayed(sdata);
1764 1765 1766 1767 1768 1769

	if (local->ops->reset_tsf) {
		/* Reset own TSF to allow time synchronization work. */
		local->ops->reset_tsf(local_to_hw(local));
	}
	memcpy(ifsta->bssid, bss->bssid, ETH_ALEN);
1770
	res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
1771 1772 1773 1774 1775 1776 1777 1778
	if (res)
		return res;

	local->hw.conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10;

	sdata->drop_unencrypted = bss->capability &
		WLAN_CAPABILITY_PRIVACY ? 1 : 0;

1779
	res = ieee80211_set_freq(sdata, bss->freq);
1780

1781 1782
	if (res)
		return res;
1783

1784
	/* Build IBSS probe response */
1785
	skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
1786
	if (skb) {
1787 1788 1789 1790 1791
		skb_reserve(skb, local->hw.extra_tx_headroom);

		mgmt = (struct ieee80211_mgmt *)
			skb_put(skb, 24 + sizeof(mgmt->u.beacon));
		memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
1792 1793
		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_PROBE_RESP);
1794
		memset(mgmt->da, 0xff, ETH_ALEN);
1795
		memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1796 1797 1798
		memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
		mgmt->u.beacon.beacon_int =
			cpu_to_le16(local->hw.conf.beacon_int);
1799
		mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp);
1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836
		mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability);

		pos = skb_put(skb, 2 + ifsta->ssid_len);
		*pos++ = WLAN_EID_SSID;
		*pos++ = ifsta->ssid_len;
		memcpy(pos, ifsta->ssid, ifsta->ssid_len);

		rates = bss->supp_rates_len;
		if (rates > 8)
			rates = 8;
		pos = skb_put(skb, 2 + rates);
		*pos++ = WLAN_EID_SUPP_RATES;
		*pos++ = rates;
		memcpy(pos, bss->supp_rates, rates);

		if (bss->band == IEEE80211_BAND_2GHZ) {
			pos = skb_put(skb, 2 + 1);
			*pos++ = WLAN_EID_DS_PARAMS;
			*pos++ = 1;
			*pos++ = ieee80211_frequency_to_channel(bss->freq);
		}

		pos = skb_put(skb, 2 + 2);
		*pos++ = WLAN_EID_IBSS_PARAMS;
		*pos++ = 2;
		/* FIX: set ATIM window based on scan results */
		*pos++ = 0;
		*pos++ = 0;

		if (bss->supp_rates_len > 8) {
			rates = bss->supp_rates_len - 8;
			pos = skb_put(skb, 2 + rates);
			*pos++ = WLAN_EID_EXT_SUPP_RATES;
			*pos++ = rates;
			memcpy(pos, &bss->supp_rates[8], rates);
		}

1837
		ifsta->probe_resp = skb;
1838

1839 1840
		ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
	}
1841

1842 1843 1844 1845 1846 1847 1848
	rates = 0;
	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
	for (i = 0; i < bss->supp_rates_len; i++) {
		int bitrate = (bss->supp_rates[i] & 0x7f) * 5;
		for (j = 0; j < sband->n_bitrates; j++)
			if (sband->bitrates[j].bitrate == bitrate)
				rates |= BIT(j);
1849
	}
1850 1851
	ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;

1852
	ieee80211_sta_def_wmm_params(sdata, bss, 1);
1853

1854
	ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED;
1855 1856
	mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);

1857 1858
	memset(&wrqu, 0, sizeof(wrqu));
	memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN);
1859
	wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
1860 1861 1862 1863

	return res;
}

1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899
u64 ieee80211_sta_get_rates(struct ieee80211_local *local,
			    struct ieee802_11_elems *elems,
			    enum ieee80211_band band)
{
	struct ieee80211_supported_band *sband;
	struct ieee80211_rate *bitrates;
	size_t num_rates;
	u64 supp_rates;
	int i, j;
	sband = local->hw.wiphy->bands[band];

	if (!sband) {
		WARN_ON(1);
		sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
	}

	bitrates = sband->bitrates;
	num_rates = sband->n_bitrates;
	supp_rates = 0;
	for (i = 0; i < elems->supp_rates_len +
		     elems->ext_supp_rates_len; i++) {
		u8 rate = 0;
		int own_rate;
		if (i < elems->supp_rates_len)
			rate = elems->supp_rates[i];
		else if (elems->ext_supp_rates)
			rate = elems->ext_supp_rates
				[i - elems->supp_rates_len];
		own_rate = 5 * (rate & 0x7f);
		for (j = 0; j < num_rates; j++)
			if (bitrates[j].bitrate == own_rate)
				supp_rates |= BIT(j);
	}
	return supp_rates;
}

1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926
static u64 ieee80211_sta_get_mandatory_rates(struct ieee80211_local *local,
					enum ieee80211_band band)
{
	struct ieee80211_supported_band *sband;
	struct ieee80211_rate *bitrates;
	u64 mandatory_rates;
	enum ieee80211_rate_flags mandatory_flag;
	int i;

	sband = local->hw.wiphy->bands[band];
	if (!sband) {
		WARN_ON(1);
		sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
	}

	if (band == IEEE80211_BAND_2GHZ)
		mandatory_flag = IEEE80211_RATE_MANDATORY_B;
	else
		mandatory_flag = IEEE80211_RATE_MANDATORY_A;

	bitrates = sband->bitrates;
	mandatory_rates = 0;
	for (i = 0; i < sband->n_bitrates; i++)
		if (bitrates[i].flags & mandatory_flag)
			mandatory_rates |= BIT(i);
	return mandatory_rates;
}
1927

1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
				  struct ieee80211_mgmt *mgmt,
				  size_t len,
				  struct ieee80211_rx_status *rx_status,
				  struct ieee802_11_elems *elems,
				  bool beacon)
{
	struct ieee80211_local *local = sdata->local;
	int freq;
	struct ieee80211_sta_bss *bss;
	struct sta_info *sta;
	struct ieee80211_channel *channel;
	u64 beacon_timestamp, rx_timestamp;
	u64 supp_rates = 0;
	enum ieee80211_band band = rx_status->band;
	DECLARE_MAC_BUF(mac);
	DECLARE_MAC_BUF(mac2);

	if (elems->ds_params && elems->ds_params_len == 1)
		freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
	else
		freq = rx_status->freq;

	channel = ieee80211_get_channel(local->hw.wiphy, freq);

	if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
		return;

	if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id &&
	    elems->mesh_config && mesh_matches_local(elems, sdata)) {
		supp_rates = ieee80211_sta_get_rates(local, elems, band);

		mesh_neighbour_update(mgmt->sa, supp_rates, sdata,
				      mesh_peer_accepts_plinks(elems));
	}

	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems->supp_rates &&
	    memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
		supp_rates = ieee80211_sta_get_rates(local, elems, band);

		rcu_read_lock();

		sta = sta_info_get(local, mgmt->sa);
		if (sta) {
			u64 prev_rates;

			prev_rates = sta->supp_rates[band];
			/* make sure mandatory rates are always added */
			sta->supp_rates[band] = supp_rates |
				ieee80211_sta_get_mandatory_rates(local, band);

#ifdef CONFIG_MAC80211_IBSS_DEBUG
			if (sta->supp_rates[band] != prev_rates)
				printk(KERN_DEBUG "%s: updated supp_rates set "
				    "for %s based on beacon info (0x%llx | "
				    "0x%llx -> 0x%llx)\n",
				    sdata->dev->name, print_mac(mac, sta->addr),
				    (unsigned long long) prev_rates,
				    (unsigned long long) supp_rates,
				    (unsigned long long) sta->supp_rates[band]);
#endif
		} else {
			ieee80211_ibss_add_sta(sdata, NULL, mgmt->bssid,
					       mgmt->sa, supp_rates);
		}

		rcu_read_unlock();
	}

	bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
					freq, beacon);
	if (!bss)
		return;

	/* was just updated in ieee80211_bss_info_update */
	beacon_timestamp = bss->timestamp;

2005 2006 2007 2008 2009
	/*
	 * In STA mode, the remaining parameters should not be overridden
	 * by beacons because they're not necessarily accurate there.
	 */
	if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
2010
	    bss->last_probe_resp && beacon) {
2011
		ieee80211_rx_bss_put(local, bss);
2012 2013 2014
		return;
	}

B
Bruno Randolf 已提交
2015 2016
	/* check if we need to merge IBSS */
	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
J
Johannes Berg 已提交
2017
	    bss->capability & WLAN_CAPABILITY_IBSS &&
B
Bruno Randolf 已提交
2018
	    bss->freq == local->oper_channel->center_freq &&
2019 2020 2021
	    elems->ssid_len == sdata->u.sta.ssid_len &&
	    memcmp(elems->ssid, sdata->u.sta.ssid,
				sdata->u.sta.ssid_len) == 0) {
B
Bruno Randolf 已提交
2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037
		if (rx_status->flag & RX_FLAG_TSFT) {
			/* in order for correct IBSS merging we need mactime
			 *
			 * since mactime is defined as the time the first data
			 * symbol of the frame hits the PHY, and the timestamp
			 * of the beacon is defined as "the time that the data
			 * symbol containing the first bit of the timestamp is
			 * transmitted to the PHY plus the transmitting STA’s
			 * delays through its local PHY from the MAC-PHY
			 * interface to its interface with the WM"
			 * (802.11 11.1.2) - equals the time this bit arrives at
			 * the receiver - we have to take into account the
			 * offset between the two.
			 * e.g: at 1 MBit that means mactime is 192 usec earlier
			 * (=24 bytes * 8 usecs/byte) than the beacon timestamp.
			 */
2038
			int rate = local->hw.wiphy->bands[band]->
B
Bruno Randolf 已提交
2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057
					bitrates[rx_status->rate_idx].bitrate;
			rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
		} else if (local && local->ops && local->ops->get_tsf)
			/* second best option: get current TSF */
			rx_timestamp = local->ops->get_tsf(local_to_hw(local));
		else
			/* can't merge without knowing the TSF */
			rx_timestamp = -1LLU;
#ifdef CONFIG_MAC80211_IBSS_DEBUG
		printk(KERN_DEBUG "RX beacon SA=%s BSSID="
		       "%s TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n",
		       print_mac(mac, mgmt->sa),
		       print_mac(mac2, mgmt->bssid),
		       (unsigned long long)rx_timestamp,
		       (unsigned long long)beacon_timestamp,
		       (unsigned long long)(rx_timestamp - beacon_timestamp),
		       jiffies);
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
		if (beacon_timestamp > rx_timestamp) {
2058
#ifdef CONFIG_MAC80211_IBSS_DEBUG
2059 2060
			printk(KERN_DEBUG "%s: beacon TSF higher than "
			       "local TSF - IBSS merge with BSSID %s\n",
2061
			       sdata->dev->name, print_mac(mac, mgmt->bssid));
J
Johannes Berg 已提交
2062
#endif
2063 2064
			ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss);
			ieee80211_ibss_add_sta(sdata, NULL,
2065
					       mgmt->bssid, mgmt->sa,
2066
					       supp_rates);
B
Bruno Randolf 已提交
2067 2068 2069
		}
	}

2070
	ieee80211_rx_bss_put(local, bss);
2071 2072 2073
}


2074
static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
2075 2076 2077 2078
					 struct ieee80211_mgmt *mgmt,
					 size_t len,
					 struct ieee80211_rx_status *rx_status)
{
2079 2080
	size_t baselen;
	struct ieee802_11_elems elems;
2081
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
2082

2083 2084 2085
	if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
		return; /* ignore ProbeResp to foreign address */

2086 2087 2088 2089 2090 2091 2092
	baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
	if (baselen > len)
		return;

	ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
				&elems);

2093
	ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
2094 2095 2096 2097 2098 2099 2100 2101

	/* direct probe may be part of the association flow */
	if (test_and_clear_bit(IEEE80211_STA_REQ_DIRECT_PROBE,
							&ifsta->request)) {
		printk(KERN_DEBUG "%s direct probe responded\n",
		       sdata->dev->name);
		ieee80211_authenticate(sdata, ifsta);
	}
2102 2103 2104
}


2105
static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2106 2107 2108 2109 2110 2111 2112
				     struct ieee80211_mgmt *mgmt,
				     size_t len,
				     struct ieee80211_rx_status *rx_status)
{
	struct ieee80211_if_sta *ifsta;
	size_t baselen;
	struct ieee802_11_elems elems;
2113
	struct ieee80211_local *local = sdata->local;
2114
	struct ieee80211_conf *conf = &local->hw.conf;
2115
	u32 changed = 0;
2116

2117 2118 2119 2120 2121 2122 2123
	/* Process beacon from the current BSS */
	baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
	if (baselen > len)
		return;

	ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);

2124
	ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true);
2125

2126
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
2127 2128 2129
		return;
	ifsta = &sdata->u.sta;

2130
	if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED) ||
2131 2132 2133
	    memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0)
		return;

2134 2135 2136
	ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
				 elems.wmm_param_len);

2137
	if (elems.erp_info && elems.erp_info_len >= 1)
2138
		changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]);
2139 2140 2141 2142 2143
	else {
		u16 capab = le16_to_cpu(mgmt->u.beacon.capab_info);
		changed |= ieee80211_handle_protect_preamb(sdata, false,
				(capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);
	}
2144

2145
	if (elems.ht_cap_elem && elems.ht_info_elem &&
T
Tomas Winkler 已提交
2146
	    elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
2147 2148 2149 2150 2151
		struct ieee80211_ht_bss_info bss_info;

		ieee80211_ht_addt_info_ie_to_ht_bss_info(
				(struct ieee80211_ht_addt_info *)
				elems.ht_info_elem, &bss_info);
T
Tomas Winkler 已提交
2152 2153
		changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf,
					       &bss_info);
2154 2155
	}

2156
	ieee80211_bss_info_change_notify(sdata, changed);
2157 2158 2159
}


2160
static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
2161 2162 2163 2164 2165
					struct ieee80211_if_sta *ifsta,
					struct ieee80211_mgmt *mgmt,
					size_t len,
					struct ieee80211_rx_status *rx_status)
{
2166
	struct ieee80211_local *local = sdata->local;
2167 2168 2169 2170
	int tx_last_beacon;
	struct sk_buff *skb;
	struct ieee80211_mgmt *resp;
	u8 *pos, *end;
2171 2172 2173 2174 2175
	DECLARE_MAC_BUF(mac);
#ifdef CONFIG_MAC80211_IBSS_DEBUG
	DECLARE_MAC_BUF(mac2);
	DECLARE_MAC_BUF(mac3);
#endif
2176

2177
	if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS ||
2178
	    ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED ||
2179 2180 2181 2182 2183 2184 2185 2186 2187
	    len < 24 + 2 || !ifsta->probe_resp)
		return;

	if (local->ops->tx_last_beacon)
		tx_last_beacon = local->ops->tx_last_beacon(local_to_hw(local));
	else
		tx_last_beacon = 1;

#ifdef CONFIG_MAC80211_IBSS_DEBUG
2188 2189
	printk(KERN_DEBUG "%s: RX ProbeReq SA=%s DA=%s BSSID="
	       "%s (tx_last_beacon=%d)\n",
2190
	       sdata->dev->name, print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da),
2191
	       print_mac(mac3, mgmt->bssid), tx_last_beacon);
2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204
#endif /* CONFIG_MAC80211_IBSS_DEBUG */

	if (!tx_last_beacon)
		return;

	if (memcmp(mgmt->bssid, ifsta->bssid, ETH_ALEN) != 0 &&
	    memcmp(mgmt->bssid, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0)
		return;

	end = ((u8 *) mgmt) + len;
	pos = mgmt->u.probe_req.variable;
	if (pos[0] != WLAN_EID_SSID ||
	    pos + 2 + pos[1] > end) {
2205 2206 2207
#ifdef CONFIG_MAC80211_IBSS_DEBUG
		printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq "
		       "from %s\n",
2208
		       sdata->dev->name, print_mac(mac, mgmt->sa));
2209
#endif
2210 2211 2212 2213 2214 2215 2216 2217 2218 2219
		return;
	}
	if (pos[1] != 0 &&
	    (pos[1] != ifsta->ssid_len ||
	     memcmp(pos + 2, ifsta->ssid, ifsta->ssid_len) != 0)) {
		/* Ignore ProbeReq for foreign SSID */
		return;
	}

	/* Reply with ProbeResp */
2220
	skb = skb_copy(ifsta->probe_resp, GFP_KERNEL);
2221 2222 2223 2224 2225 2226
	if (!skb)
		return;

	resp = (struct ieee80211_mgmt *) skb->data;
	memcpy(resp->da, mgmt->sa, ETH_ALEN);
#ifdef CONFIG_MAC80211_IBSS_DEBUG
2227
	printk(KERN_DEBUG "%s: Sending ProbeResp to %s\n",
2228
	       sdata->dev->name, print_mac(mac, resp->da));
2229
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2230
	ieee80211_sta_tx(sdata, skb, 0);
2231 2232
}

2233
static void ieee80211_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
2234 2235
				     struct ieee80211_if_sta *ifsta,
				     struct ieee80211_mgmt *mgmt,
2236 2237
				     size_t len,
				     struct ieee80211_rx_status *rx_status)
2238
{
2239
	struct ieee80211_local *local = sdata->local;
2240

2241 2242
	/* all categories we currently handle have action_code */
	if (len < IEEE80211_MIN_ACTION_SIZE + 1)
2243 2244 2245
		return;

	switch (mgmt->u.action.category) {
2246 2247 2248
	case WLAN_CATEGORY_SPECTRUM_MGMT:
		if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ)
			break;
2249
		switch (mgmt->u.action.u.measurement.action_code) {
2250 2251 2252 2253
		case WLAN_ACTION_SPCT_MSR_REQ:
			if (len < (IEEE80211_MIN_ACTION_SIZE +
				   sizeof(mgmt->u.action.u.measurement)))
				break;
2254
			ieee80211_sta_process_measurement_req(sdata, mgmt, len);
2255 2256 2257
			break;
		}
		break;
2258 2259 2260 2261 2262 2263
	case WLAN_CATEGORY_BACK:
		switch (mgmt->u.action.u.addba_req.action_code) {
		case WLAN_ACTION_ADDBA_REQ:
			if (len < (IEEE80211_MIN_ACTION_SIZE +
				   sizeof(mgmt->u.action.u.addba_req)))
				break;
2264
			ieee80211_sta_process_addba_request(local, mgmt, len);
2265
			break;
2266 2267 2268 2269
		case WLAN_ACTION_ADDBA_RESP:
			if (len < (IEEE80211_MIN_ACTION_SIZE +
				   sizeof(mgmt->u.action.u.addba_resp)))
				break;
2270
			ieee80211_sta_process_addba_resp(local, mgmt, len);
2271
			break;
2272 2273 2274 2275
		case WLAN_ACTION_DELBA:
			if (len < (IEEE80211_MIN_ACTION_SIZE +
				   sizeof(mgmt->u.action.u.delba)))
				break;
2276
			ieee80211_sta_process_delba(sdata, mgmt, len);
2277
			break;
2278 2279
		}
		break;
2280
	case PLINK_CATEGORY:
J
Johannes Berg 已提交
2281
		if (ieee80211_vif_is_mesh(&sdata->vif))
2282
			mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
2283 2284
		break;
	case MESH_PATH_SEL_CATEGORY:
J
Johannes Berg 已提交
2285
		if (ieee80211_vif_is_mesh(&sdata->vif))
2286
			mesh_rx_path_sel_frame(sdata, mgmt, len);
2287
		break;
2288 2289
	}
}
2290

2291
void ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
2292 2293
			   struct ieee80211_rx_status *rx_status)
{
2294
	struct ieee80211_local *local = sdata->local;
2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310
	struct ieee80211_if_sta *ifsta;
	struct ieee80211_mgmt *mgmt;
	u16 fc;

	if (skb->len < 24)
		goto fail;

	ifsta = &sdata->u.sta;

	mgmt = (struct ieee80211_mgmt *) skb->data;
	fc = le16_to_cpu(mgmt->frame_control);

	switch (fc & IEEE80211_FCTL_STYPE) {
	case IEEE80211_STYPE_PROBE_REQ:
	case IEEE80211_STYPE_PROBE_RESP:
	case IEEE80211_STYPE_BEACON:
2311
	case IEEE80211_STYPE_ACTION:
2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326
		memcpy(skb->cb, rx_status, sizeof(*rx_status));
	case IEEE80211_STYPE_AUTH:
	case IEEE80211_STYPE_ASSOC_RESP:
	case IEEE80211_STYPE_REASSOC_RESP:
	case IEEE80211_STYPE_DEAUTH:
	case IEEE80211_STYPE_DISASSOC:
		skb_queue_tail(&ifsta->skb_queue, skb);
		queue_work(local->hw.workqueue, &ifsta->work);
		return;
	}

 fail:
	kfree_skb(skb);
}

2327
static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342
					 struct sk_buff *skb)
{
	struct ieee80211_rx_status *rx_status;
	struct ieee80211_if_sta *ifsta;
	struct ieee80211_mgmt *mgmt;
	u16 fc;

	ifsta = &sdata->u.sta;

	rx_status = (struct ieee80211_rx_status *) skb->cb;
	mgmt = (struct ieee80211_mgmt *) skb->data;
	fc = le16_to_cpu(mgmt->frame_control);

	switch (fc & IEEE80211_FCTL_STYPE) {
	case IEEE80211_STYPE_PROBE_REQ:
2343
		ieee80211_rx_mgmt_probe_req(sdata, ifsta, mgmt, skb->len,
2344 2345 2346
					    rx_status);
		break;
	case IEEE80211_STYPE_PROBE_RESP:
2347
		ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, rx_status);
2348 2349
		break;
	case IEEE80211_STYPE_BEACON:
2350
		ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
2351 2352
		break;
	case IEEE80211_STYPE_AUTH:
2353
		ieee80211_rx_mgmt_auth(sdata, ifsta, mgmt, skb->len);
2354 2355
		break;
	case IEEE80211_STYPE_ASSOC_RESP:
2356
		ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 0);
2357 2358
		break;
	case IEEE80211_STYPE_REASSOC_RESP:
2359
		ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 1);
2360 2361
		break;
	case IEEE80211_STYPE_DEAUTH:
2362
		ieee80211_rx_mgmt_deauth(sdata, ifsta, mgmt, skb->len);
2363 2364
		break;
	case IEEE80211_STYPE_DISASSOC:
2365
		ieee80211_rx_mgmt_disassoc(sdata, ifsta, mgmt, skb->len);
2366
		break;
2367
	case IEEE80211_STYPE_ACTION:
2368
		ieee80211_rx_mgmt_action(sdata, ifsta, mgmt, skb->len, rx_status);
2369
		break;
2370 2371 2372 2373 2374 2375
	}

	kfree_skb(skb);
}


2376
static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
2377
{
2378
	struct ieee80211_local *local = sdata->local;
2379 2380 2381
	int active = 0;
	struct sta_info *sta;

2382 2383 2384 2385
	rcu_read_lock();

	list_for_each_entry_rcu(sta, &local->sta_list, list) {
		if (sta->sdata == sdata &&
2386 2387 2388 2389 2390 2391
		    time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL,
			       jiffies)) {
			active++;
			break;
		}
	}
2392 2393

	rcu_read_unlock();
2394 2395 2396 2397 2398

	return active;
}


2399
static void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, unsigned long exp_time)
2400
{
2401
	struct ieee80211_local *local = sdata->local;
2402
	struct sta_info *sta, *tmp;
2403
	LIST_HEAD(tmp_list);
2404
	DECLARE_MAC_BUF(mac);
2405
	unsigned long flags;
2406

2407
	spin_lock_irqsave(&local->sta_lock, flags);
2408
	list_for_each_entry_safe(sta, tmp, &local->sta_list, list)
2409
		if (time_after(jiffies, sta->last_rx + exp_time)) {
2410
#ifdef CONFIG_MAC80211_IBSS_DEBUG
2411
			printk(KERN_DEBUG "%s: expiring inactive STA %s\n",
2412
			       sdata->dev->name, print_mac(mac, sta->addr));
2413
#endif
2414
			__sta_info_unlink(&sta);
2415 2416
			if (sta)
				list_add(&sta->list, &tmp_list);
2417
		}
2418
	spin_unlock_irqrestore(&local->sta_lock, flags);
2419

2420 2421
	list_for_each_entry_safe(sta, tmp, &tmp_list, list)
		sta_info_destroy(sta);
2422 2423 2424
}


2425
static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata,
2426 2427 2428 2429
				     struct ieee80211_if_sta *ifsta)
{
	mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);

2430 2431
	ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT);
	if (ieee80211_sta_active_ibss(sdata))
2432 2433 2434
		return;

	printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
2435 2436
	       "IBSS networks with same SSID (merge)\n", sdata->dev->name);
	ieee80211_sta_req_scan(sdata, ifsta->ssid, ifsta->ssid_len);
2437 2438 2439
}


2440
#ifdef CONFIG_MAC80211_MESH
2441
static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
2442 2443 2444 2445
			   struct ieee80211_if_sta *ifsta)
{
	bool free_plinks;

2446 2447
	ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
	mesh_path_expire(sdata);
2448 2449 2450

	free_plinks = mesh_plink_availables(sdata);
	if (free_plinks != sdata->u.sta.accepting_plinks)
2451
		ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
2452 2453 2454 2455 2456 2457

	mod_timer(&ifsta->timer, jiffies +
			IEEE80211_MESH_HOUSEKEEPING_INTERVAL);
}


2458
void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
2459 2460 2461
{
	struct ieee80211_if_sta *ifsta;
	ifsta = &sdata->u.sta;
2462
	ifsta->state = IEEE80211_STA_MLME_MESH_UP;
2463
	ieee80211_sta_timer((unsigned long)sdata);
L
Luis Carlos Cobo 已提交
2464
	ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
2465 2466 2467 2468
}
#endif


2469 2470
void ieee80211_sta_timer(unsigned long data)
{
J
Johannes Berg 已提交
2471 2472 2473 2474
	struct ieee80211_sub_if_data *sdata =
		(struct ieee80211_sub_if_data *) data;
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
	struct ieee80211_local *local = sdata->local;
2475

J
Johannes Berg 已提交
2476 2477
	set_bit(IEEE80211_STA_REQ_RUN, &ifsta->request);
	queue_work(local->hw.workqueue, &ifsta->work);
2478 2479
}

2480
static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata,
2481 2482
				     struct ieee80211_if_sta *ifsta)
{
2483
	struct ieee80211_local *local = sdata->local;
2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501

	if (local->ops->reset_tsf) {
		/* Reset own TSF to allow time synchronization work. */
		local->ops->reset_tsf(local_to_hw(local));
	}

	ifsta->wmm_last_param_set = -1; /* allow any WMM update */


	if (ifsta->auth_algs & IEEE80211_AUTH_ALG_OPEN)
		ifsta->auth_alg = WLAN_AUTH_OPEN;
	else if (ifsta->auth_algs & IEEE80211_AUTH_ALG_SHARED_KEY)
		ifsta->auth_alg = WLAN_AUTH_SHARED_KEY;
	else if (ifsta->auth_algs & IEEE80211_AUTH_ALG_LEAP)
		ifsta->auth_alg = WLAN_AUTH_LEAP;
	else
		ifsta->auth_alg = WLAN_AUTH_OPEN;
	ifsta->auth_transaction = -1;
2502
	ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
2503
	ifsta->assoc_scan_tries = 0;
2504
	ifsta->direct_probe_tries = 0;
2505 2506
	ifsta->auth_tries = 0;
	ifsta->assoc_tries = 0;
2507
	netif_tx_stop_all_queues(sdata->dev);
2508
	netif_carrier_off(sdata->dev);
2509 2510 2511
}


2512
void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata,
2513 2514
			    struct ieee80211_if_sta *ifsta)
{
2515
	struct ieee80211_local *local = sdata->local;
2516

2517
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
2518 2519
		return;

2520
	if ((ifsta->flags & (IEEE80211_STA_BSSID_SET |
2521
			     IEEE80211_STA_AUTO_BSSID_SEL)) &&
2522
	    (ifsta->flags & (IEEE80211_STA_SSID_SET |
2523 2524 2525 2526 2527 2528
			     IEEE80211_STA_AUTO_SSID_SEL))) {

		if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED)
			ieee80211_set_disassoc(sdata, ifsta, true, true,
					       WLAN_REASON_DEAUTH_LEAVING);

2529 2530 2531 2532 2533 2534 2535 2536 2537 2538
		set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
		queue_work(local->hw.workqueue, &ifsta->work);
	}
}

static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta,
				    const char *ssid, int ssid_len)
{
	int tmp, hidden_ssid;

2539 2540
	if (ssid_len == ifsta->ssid_len &&
	    !memcmp(ifsta->ssid, ssid, ssid_len))
2541 2542
		return 1;

2543
	if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL)
2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563
		return 0;

	hidden_ssid = 1;
	tmp = ssid_len;
	while (tmp--) {
		if (ssid[tmp] != '\0') {
			hidden_ssid = 0;
			break;
		}
	}

	if (hidden_ssid && ifsta->ssid_len == ssid_len)
		return 1;

	if (ssid_len == 1 && ssid[0] == ' ')
		return 1;

	return 0;
}

2564
static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
2565 2566
				     struct ieee80211_if_sta *ifsta)
{
2567
	struct ieee80211_local *local = sdata->local;
2568
	struct ieee80211_sta_bss *bss;
2569
	struct ieee80211_supported_band *sband;
2570 2571
	u8 bssid[ETH_ALEN], *pos;
	int i;
2572
	int ret;
2573
	DECLARE_MAC_BUF(mac);
2574 2575 2576 2577 2578 2579 2580 2581 2582 2583

#if 0
	/* Easier testing, use fixed BSSID. */
	memset(bssid, 0xfe, ETH_ALEN);
#else
	/* Generate random, not broadcast, locally administered BSSID. Mix in
	 * own MAC address to make sure that devices that do not have proper
	 * random number generator get different BSSID. */
	get_random_bytes(bssid, ETH_ALEN);
	for (i = 0; i < ETH_ALEN; i++)
2584
		bssid[i] ^= sdata->dev->dev_addr[i];
2585 2586 2587 2588
	bssid[0] &= ~0x01;
	bssid[0] |= 0x02;
#endif

2589
	printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n",
2590
	       sdata->dev->name, print_mac(mac, bssid));
2591

2592
	bss = ieee80211_rx_bss_add(local, bssid,
2593
				   local->hw.conf.channel->center_freq,
2594
				   sdata->u.sta.ssid, sdata->u.sta.ssid_len);
2595 2596 2597
	if (!bss)
		return -ENOMEM;

2598 2599
	bss->band = local->hw.conf.channel->band;
	sband = local->hw.wiphy->bands[bss->band];
2600 2601

	if (local->hw.conf.beacon_int == 0)
2602
		local->hw.conf.beacon_int = 100;
2603 2604 2605
	bss->beacon_int = local->hw.conf.beacon_int;
	bss->last_update = jiffies;
	bss->capability = WLAN_CAPABILITY_IBSS;
J
Johannes Berg 已提交
2606 2607

	if (sdata->default_key)
2608
		bss->capability |= WLAN_CAPABILITY_PRIVACY;
J
Johannes Berg 已提交
2609
	else
2610
		sdata->drop_unencrypted = 0;
J
Johannes Berg 已提交
2611

2612
	bss->supp_rates_len = sband->n_bitrates;
2613
	pos = bss->supp_rates;
2614 2615
	for (i = 0; i < sband->n_bitrates; i++) {
		int rate = sband->bitrates[i].bitrate;
2616 2617 2618
		*pos++ = (u8) (rate / 5);
	}

2619
	ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
2620
	ieee80211_rx_bss_put(local, bss);
2621
	return ret;
2622 2623 2624
}


2625
static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
2626 2627
				   struct ieee80211_if_sta *ifsta)
{
2628
	struct ieee80211_local *local = sdata->local;
2629 2630 2631 2632
	struct ieee80211_sta_bss *bss;
	int found = 0;
	u8 bssid[ETH_ALEN];
	int active_ibss;
2633 2634
	DECLARE_MAC_BUF(mac);
	DECLARE_MAC_BUF(mac2);
2635 2636 2637 2638

	if (ifsta->ssid_len == 0)
		return -EINVAL;

2639
	active_ibss = ieee80211_sta_active_ibss(sdata);
2640 2641
#ifdef CONFIG_MAC80211_IBSS_DEBUG
	printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n",
2642
	       sdata->dev->name, active_ibss);
2643 2644 2645 2646 2647 2648 2649 2650
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
	spin_lock_bh(&local->sta_bss_lock);
	list_for_each_entry(bss, &local->sta_bss_list, list) {
		if (ifsta->ssid_len != bss->ssid_len ||
		    memcmp(ifsta->ssid, bss->ssid, bss->ssid_len) != 0
		    || !(bss->capability & WLAN_CAPABILITY_IBSS))
			continue;
#ifdef CONFIG_MAC80211_IBSS_DEBUG
2651 2652
		printk(KERN_DEBUG "   bssid=%s found\n",
		       print_mac(mac, bss->bssid));
2653 2654 2655 2656 2657 2658 2659 2660 2661
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
		memcpy(bssid, bss->bssid, ETH_ALEN);
		found = 1;
		if (active_ibss || memcmp(bssid, ifsta->bssid, ETH_ALEN) != 0)
			break;
	}
	spin_unlock_bh(&local->sta_bss_lock);

#ifdef CONFIG_MAC80211_IBSS_DEBUG
2662 2663 2664 2665
	if (found)
		printk(KERN_DEBUG "   sta_find_ibss: selected %s current "
		       "%s\n", print_mac(mac, bssid),
		       print_mac(mac2, ifsta->bssid));
2666
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2667 2668

	if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) {
2669
		int ret;
2670 2671 2672 2673 2674 2675 2676
		int search_freq;

		if (ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL)
			search_freq = bss->freq;
		else
			search_freq = local->hw.conf.channel->center_freq;

2677
		bss = ieee80211_rx_bss_get(local, bssid, search_freq,
2678 2679 2680 2681
					   ifsta->ssid, ifsta->ssid_len);
		if (!bss)
			goto dont_join;

2682
		printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
2683
		       " based on configured SSID\n",
2684 2685
		       sdata->dev->name, print_mac(mac, bssid));
		ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
2686
		ieee80211_rx_bss_put(local, bss);
2687
		return ret;
2688
	}
2689 2690

dont_join:
2691 2692 2693 2694 2695
#ifdef CONFIG_MAC80211_IBSS_DEBUG
	printk(KERN_DEBUG "   did not try to join ibss\n");
#endif /* CONFIG_MAC80211_IBSS_DEBUG */

	/* Selected IBSS not found in current scan results - try to scan */
2696
	if (ifsta->state == IEEE80211_STA_MLME_IBSS_JOINED &&
2697
	    !ieee80211_sta_active_ibss(sdata)) {
2698 2699 2700 2701 2702
		mod_timer(&ifsta->timer, jiffies +
				      IEEE80211_IBSS_MERGE_INTERVAL);
	} else if (time_after(jiffies, local->last_scan_completed +
			      IEEE80211_SCAN_INTERVAL)) {
		printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
2703 2704
		       "join\n", sdata->dev->name);
		return ieee80211_sta_req_scan(sdata, ifsta->ssid,
2705
					      ifsta->ssid_len);
2706
	} else if (ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED) {
2707 2708 2709 2710
		int interval = IEEE80211_SCAN_INTERVAL;

		if (time_after(jiffies, ifsta->ibss_join_req +
			       IEEE80211_IBSS_JOIN_TIMEOUT)) {
2711
			if ((ifsta->flags & IEEE80211_STA_CREATE_IBSS) &&
2712 2713
			    (!(local->oper_channel->flags &
					IEEE80211_CHAN_NO_IBSS)))
2714
				return ieee80211_sta_create_ibss(sdata, ifsta);
2715
			if (ifsta->flags & IEEE80211_STA_CREATE_IBSS) {
2716
				printk(KERN_DEBUG "%s: IBSS not allowed on"
2717
				       " %d MHz\n", sdata->dev->name,
2718
				       local->hw.conf.channel->center_freq);
2719 2720 2721 2722 2723 2724 2725
			}

			/* No IBSS found - decrease scan interval and continue
			 * scanning. */
			interval = IEEE80211_SCAN_INTERVAL_SLOW;
		}

2726
		ifsta->state = IEEE80211_STA_MLME_IBSS_SEARCH;
2727 2728 2729 2730 2731 2732 2733 2734
		mod_timer(&ifsta->timer, jiffies + interval);
		return 0;
	}

	return 0;
}


2735
int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
2736 2737
{
	struct ieee80211_if_sta *ifsta;
2738
	int res;
2739 2740 2741 2742 2743 2744

	if (len > IEEE80211_MAX_SSID_LEN)
		return -EINVAL;

	ifsta = &sdata->u.sta;

2745 2746 2747 2748
	if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) {
		memset(ifsta->ssid, 0, sizeof(ifsta->ssid));
		memcpy(ifsta->ssid, ssid, len);
		ifsta->ssid_len = len;
2749
		ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
2750 2751 2752 2753 2754 2755 2756 2757 2758 2759

		res = 0;
		/*
		 * Hack! MLME code needs to be cleaned up to have different
		 * entry points for configuration and internal selection change
		 */
		if (netif_running(sdata->dev))
			res = ieee80211_if_config(sdata, IEEE80211_IFCC_SSID);
		if (res) {
			printk(KERN_DEBUG "%s: Failed to config new SSID to "
2760
			       "the low-level driver\n", sdata->dev->name);
2761 2762 2763
			return res;
		}
	}
2764

2765 2766 2767 2768
	if (len)
		ifsta->flags |= IEEE80211_STA_SSID_SET;
	else
		ifsta->flags &= ~IEEE80211_STA_SSID_SET;
2769

2770
	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
2771
	    !(ifsta->flags & IEEE80211_STA_BSSID_SET)) {
2772
		ifsta->ibss_join_req = jiffies;
2773
		ifsta->state = IEEE80211_STA_MLME_IBSS_SEARCH;
2774
		return ieee80211_sta_find_ibss(sdata, ifsta);
2775
	}
2776

2777 2778 2779 2780
	return 0;
}


2781
int ieee80211_sta_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len)
2782 2783 2784 2785 2786 2787 2788 2789
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
	memcpy(ssid, ifsta->ssid, ifsta->ssid_len);
	*len = ifsta->ssid_len;
	return 0;
}


2790
int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
2791 2792 2793 2794 2795 2796 2797 2798
{
	struct ieee80211_if_sta *ifsta;
	int res;

	ifsta = &sdata->u.sta;

	if (memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) {
		memcpy(ifsta->bssid, bssid, ETH_ALEN);
2799 2800 2801 2802 2803 2804
		res = 0;
		/*
		 * Hack! See also ieee80211_sta_set_ssid.
		 */
		if (netif_running(sdata->dev))
			res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
2805 2806
		if (res) {
			printk(KERN_DEBUG "%s: Failed to config new BSSID to "
2807
			       "the low-level driver\n", sdata->dev->name);
2808 2809 2810 2811
			return res;
		}
	}

2812 2813
	if (is_valid_ether_addr(bssid))
		ifsta->flags |= IEEE80211_STA_BSSID_SET;
2814
	else
2815 2816
		ifsta->flags &= ~IEEE80211_STA_BSSID_SET;

2817 2818 2819 2820
	return 0;
}


2821
int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, char *ie, size_t len)
2822 2823
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
J
Johannes Berg 已提交
2824

2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841
	kfree(ifsta->extra_ie);
	if (len == 0) {
		ifsta->extra_ie = NULL;
		ifsta->extra_ie_len = 0;
		return 0;
	}
	ifsta->extra_ie = kmalloc(len, GFP_KERNEL);
	if (!ifsta->extra_ie) {
		ifsta->extra_ie_len = 0;
		return -ENOMEM;
	}
	memcpy(ifsta->extra_ie, ie, len);
	ifsta->extra_ie_len = len;
	return 0;
}


2842
struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
J
Johannes Berg 已提交
2843
					struct sk_buff *skb, u8 *bssid,
2844
					u8 *addr, u64 supp_rates)
2845
{
2846
	struct ieee80211_local *local = sdata->local;
2847
	struct sta_info *sta;
2848
	DECLARE_MAC_BUF(mac);
2849
	int band = local->hw.conf.channel->band;
2850 2851 2852 2853 2854 2855

	/* TODO: Could consider removing the least recently used entry and
	 * allow new one to be added. */
	if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
		if (net_ratelimit()) {
			printk(KERN_DEBUG "%s: No room for a new IBSS STA "
2856
			       "entry %s\n", sdata->dev->name, print_mac(mac, addr));
2857 2858 2859 2860
		}
		return NULL;
	}

2861
	if (compare_ether_addr(bssid, sdata->u.sta.bssid))
2862 2863
		return NULL;

2864
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
2865
	printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n",
2866
	       wiphy_name(local->hw.wiphy), print_mac(mac, addr), sdata->dev->name);
2867
#endif
2868

J
Johannes Berg 已提交
2869 2870
	sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
	if (!sta)
2871 2872
		return NULL;

2873
	set_sta_flags(sta, WLAN_STA_AUTHORIZED);
2874

2875 2876 2877
	/* make sure mandatory rates are always added */
	sta->supp_rates[band] = supp_rates |
			ieee80211_sta_get_mandatory_rates(local, band);
2878 2879 2880

	rate_control_rate_init(sta, local);

2881
	if (sta_info_insert(sta))
J
Johannes Berg 已提交
2882 2883
		return NULL;

2884
	return sta;
2885 2886 2887
}


J
Johannes Berg 已提交
2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966
static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata,
				     struct ieee80211_if_sta *ifsta)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_sta_bss *bss, *selected = NULL;
	int top_rssi = 0, freq;

	spin_lock_bh(&local->sta_bss_lock);
	freq = local->oper_channel->center_freq;
	list_for_each_entry(bss, &local->sta_bss_list, list) {
		if (!(bss->capability & WLAN_CAPABILITY_ESS))
			continue;

		if ((ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL |
			IEEE80211_STA_AUTO_BSSID_SEL |
			IEEE80211_STA_AUTO_CHANNEL_SEL)) &&
		    (!!(bss->capability & WLAN_CAPABILITY_PRIVACY) ^
		     !!sdata->default_key))
			continue;

		if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) &&
		    bss->freq != freq)
			continue;

		if (!(ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) &&
		    memcmp(bss->bssid, ifsta->bssid, ETH_ALEN))
			continue;

		if (!(ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) &&
		    !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len))
			continue;

		if (!selected || top_rssi < bss->signal) {
			selected = bss;
			top_rssi = bss->signal;
		}
	}
	if (selected)
		atomic_inc(&selected->users);
	spin_unlock_bh(&local->sta_bss_lock);

	if (selected) {
		ieee80211_set_freq(sdata, selected->freq);
		if (!(ifsta->flags & IEEE80211_STA_SSID_SET))
			ieee80211_sta_set_ssid(sdata, selected->ssid,
					       selected->ssid_len);
		ieee80211_sta_set_bssid(sdata, selected->bssid);
		ieee80211_sta_def_wmm_params(sdata, selected, 0);

		/* Send out direct probe if no probe resp was received or
		 * the one we have is outdated
		 */
		if (!selected->last_probe_resp ||
		    time_after(jiffies, selected->last_probe_resp
					+ IEEE80211_SCAN_RESULT_EXPIRE))
			ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
		else
			ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;

		ieee80211_rx_bss_put(local, selected);
		ieee80211_sta_reset_auth(sdata, ifsta);
		return 0;
	} else {
		if (ifsta->assoc_scan_tries < IEEE80211_ASSOC_SCANS_MAX_TRIES) {
			ifsta->assoc_scan_tries++;
			if (ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL)
				ieee80211_sta_start_scan(sdata, NULL, 0);
			else
				ieee80211_sta_start_scan(sdata, ifsta->ssid,
							 ifsta->ssid_len);
			ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
			set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
		} else
			ifsta->state = IEEE80211_STA_MLME_DISABLED;
	}
	return -1;
}


2967
int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason)
2968 2969 2970
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;

2971
	printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n",
2972
	       sdata->dev->name, reason);
2973

2974 2975
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA &&
	    sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
2976 2977
		return -EINVAL;

2978
	ieee80211_set_disassoc(sdata, ifsta, true, true, reason);
2979 2980 2981 2982
	return 0;
}


2983
int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason)
2984 2985 2986
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;

2987
	printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n",
2988
	       sdata->dev->name, reason);
2989

2990
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
2991 2992
		return -EINVAL;

2993
	if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED))
2994 2995
		return -1;

2996
	ieee80211_set_disassoc(sdata, ifsta, false, true, reason);
2997 2998
	return 0;
}
2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009

void ieee80211_notify_mac(struct ieee80211_hw *hw,
			  enum ieee80211_notification_types  notif_type)
{
	struct ieee80211_local *local = hw_to_local(hw);
	struct ieee80211_sub_if_data *sdata;

	switch (notif_type) {
	case IEEE80211_NOTIFY_RE_ASSOC:
		rcu_read_lock();
		list_for_each_entry_rcu(sdata, &local->interfaces, list) {
3010 3011
			if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
				continue;
3012

3013
			ieee80211_sta_req_auth(sdata, &sdata->u.sta);
3014 3015 3016 3017 3018 3019
		}
		rcu_read_unlock();
		break;
	}
}
EXPORT_SYMBOL(ieee80211_notify_mac);
J
Johannes Berg 已提交
3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054

void ieee80211_sta_work(struct work_struct *work)
{
	struct ieee80211_sub_if_data *sdata =
		container_of(work, struct ieee80211_sub_if_data, u.sta.work);
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_if_sta *ifsta;
	struct sk_buff *skb;

	if (!netif_running(sdata->dev))
		return;

	if (local->sta_sw_scanning || local->sta_hw_scanning)
		return;

	if (WARN_ON(sdata->vif.type != IEEE80211_IF_TYPE_STA &&
		    sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
		    sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT))
		return;
	ifsta = &sdata->u.sta;

	while ((skb = skb_dequeue(&ifsta->skb_queue)))
		ieee80211_sta_rx_queued_mgmt(sdata, skb);

#ifdef CONFIG_MAC80211_MESH
	if (ifsta->preq_queue_len &&
	    time_after(jiffies,
		       ifsta->last_preq + msecs_to_jiffies(ifsta->mshcfg.dot11MeshHWMPpreqMinInterval)))
		mesh_path_start_discovery(sdata);
#endif

	if (ifsta->state != IEEE80211_STA_MLME_DIRECT_PROBE &&
	    ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE &&
	    ifsta->state != IEEE80211_STA_MLME_ASSOCIATE &&
	    test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) {
J
Johannes Berg 已提交
3055
		ieee80211_sta_start_scan(sdata, ifsta->scan_ssid, ifsta->scan_ssid_len);
J
Johannes Berg 已提交
3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104
		return;
	}

	if (test_and_clear_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request)) {
		if (ieee80211_sta_config_auth(sdata, ifsta))
			return;
		clear_bit(IEEE80211_STA_REQ_RUN, &ifsta->request);
	} else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifsta->request))
		return;

	switch (ifsta->state) {
	case IEEE80211_STA_MLME_DISABLED:
		break;
	case IEEE80211_STA_MLME_DIRECT_PROBE:
		ieee80211_direct_probe(sdata, ifsta);
		break;
	case IEEE80211_STA_MLME_AUTHENTICATE:
		ieee80211_authenticate(sdata, ifsta);
		break;
	case IEEE80211_STA_MLME_ASSOCIATE:
		ieee80211_associate(sdata, ifsta);
		break;
	case IEEE80211_STA_MLME_ASSOCIATED:
		ieee80211_associated(sdata, ifsta);
		break;
	case IEEE80211_STA_MLME_IBSS_SEARCH:
		ieee80211_sta_find_ibss(sdata, ifsta);
		break;
	case IEEE80211_STA_MLME_IBSS_JOINED:
		ieee80211_sta_merge_ibss(sdata, ifsta);
		break;
#ifdef CONFIG_MAC80211_MESH
	case IEEE80211_STA_MLME_MESH_UP:
		ieee80211_mesh_housekeeping(sdata, ifsta);
		break;
#endif
	default:
		WARN_ON(1);
		break;
	}

	if (ieee80211_privacy_mismatch(sdata, ifsta)) {
		printk(KERN_DEBUG "%s: privacy configuration mismatch and "
		       "mixed-cell disabled - disassociate\n", sdata->dev->name);

		ieee80211_set_disassoc(sdata, ifsta, false, true,
					WLAN_REASON_UNSPECIFIED);
	}
}
3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118

void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
{
	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
	struct ieee80211_if_sta *ifsta;

	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
		ifsta = &sdata->u.sta;
		if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) ||
		    (!(ifsta->state == IEEE80211_STA_MLME_IBSS_JOINED) &&
		    !ieee80211_sta_active_ibss(sdata)))
			ieee80211_sta_find_ibss(sdata, ifsta);
	}
}