mlme.c 96.6 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
/* mgmt header + 1 byte category code */
52 53 54 55 56
#define IEEE80211_MIN_ACTION_SIZE (24 + 1)

#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0
57 58
#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
59

60 61 62 63 64
/* next values represent the buffer size for A-MPDU frame.
 * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2) */
#define IEEE80211_MIN_AMPDU_BUF 0x8
#define IEEE80211_MAX_AMPDU_BUF 0x40

65 66
/* utils */
static int ecw2cw(int ecw)
J
Johannes Berg 已提交
67
{
68
	return (1 << ecw) - 1;
J
Johannes Berg 已提交
69 70 71
}

static u8 *ieee80211_bss_get_ie(struct ieee80211_sta_bss *bss, u8 ie)
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
{
	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 已提交
91 92 93 94 95 96 97 98
/* 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);
99

J
Johannes Berg 已提交
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142
	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);
}

143 144
void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
			      u8 *ssid, size_t ssid_len)
J
Johannes Berg 已提交
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 190 191 192 193 194 195 196 197 198 199 200 201 202 203
{
	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 */
204
static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
					 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 已提交
240 241
		for (i = 0; i < local_to_hw(local)->queues; i++)
			local->ops->conf_tx(local_to_hw(local), i, &qparam);
242 243 244
	}
}

245
static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
246 247 248 249 250 251 252 253
				     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;

254 255 256 257 258 259
	if (!(ifsta->flags & IEEE80211_STA_WMM_ENABLED))
		return;

	if (!wmm_param)
		return;

260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
	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 已提交
283
			queue = 3;
J
Johannes Berg 已提交
284
			if (acm)
285 286 287
				local->wmm_acm |= BIT(0) | BIT(3);
			break;
		case 2:
J
Johannes Berg 已提交
288
			queue = 1;
J
Johannes Berg 已提交
289
			if (acm)
290 291 292
				local->wmm_acm |= BIT(4) | BIT(5);
			break;
		case 3:
J
Johannes Berg 已提交
293
			queue = 0;
J
Johannes Berg 已提交
294
			if (acm)
295 296 297 298
				local->wmm_acm |= BIT(6) | BIT(7);
			break;
		case 0:
		default:
J
Johannes Berg 已提交
299
			queue = 2;
J
Johannes Berg 已提交
300
			if (acm)
301 302 303 304 305 306 307
				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);
308
		params.txop = get_unaligned_le16(pos + 2);
309
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
310
		printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d "
311
		       "cWmin=%d cWmax=%d txop=%d\n",
312
		       local->mdev->name, queue, aci, acm, params.aifs, params.cw_min,
313 314
		       params.cw_max, params.txop);
#endif
315 316 317 318
		/* 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 "
319
			       "parameters for queue %d\n", local->mdev->name, queue);
320 321 322 323
		}
	}
}

324 325 326
static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata,
					   bool use_protection,
					   bool use_short_preamble)
327
{
328
	struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
329
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
330
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
331
	DECLARE_MAC_BUF(mac);
332
#endif
333
	u32 changed = 0;
334

335
	if (use_protection != bss_conf->use_cts_prot) {
336
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
337 338
		if (net_ratelimit()) {
			printk(KERN_DEBUG "%s: CTS protection %s (BSSID="
339
			       "%s)\n",
340
			       sdata->dev->name,
341
			       use_protection ? "enabled" : "disabled",
342
			       print_mac(mac, ifsta->bssid));
343
		}
344
#endif
345 346
		bss_conf->use_cts_prot = use_protection;
		changed |= BSS_CHANGED_ERP_CTS_PROT;
347
	}
348

349
	if (use_short_preamble != bss_conf->use_short_preamble) {
350
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
351 352
		if (net_ratelimit()) {
			printk(KERN_DEBUG "%s: switched to %s barker preamble"
353
			       " (BSSID=%s)\n",
354
			       sdata->dev->name,
355
			       use_short_preamble ? "short" : "long",
356
			       print_mac(mac, ifsta->bssid));
357
		}
358
#endif
359
		bss_conf->use_short_preamble = use_short_preamble;
360
		changed |= BSS_CHANGED_ERP_PREAMBLE;
361
	}
362

363
	return changed;
364 365
}

366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
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;
}

392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
				   struct ieee80211_ht_info *ht_info)
{

	if (ht_info == NULL)
		return -EINVAL;

	memset(ht_info, 0, sizeof(*ht_info));

	if (ht_cap_ie) {
		u8 ampdu_info = ht_cap_ie->ampdu_params_info;

		ht_info->ht_supported = 1;
		ht_info->cap = le16_to_cpu(ht_cap_ie->cap_info);
		ht_info->ampdu_factor =
			ampdu_info & IEEE80211_HT_CAP_AMPDU_FACTOR;
		ht_info->ampdu_density =
			(ampdu_info & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2;
		memcpy(ht_info->supp_mcs_set, ht_cap_ie->supp_mcs_set, 16);
	} else
		ht_info->ht_supported = 0;

	return 0;
}

int ieee80211_ht_addt_info_ie_to_ht_bss_info(
			struct ieee80211_ht_addt_info *ht_add_info_ie,
			struct ieee80211_ht_bss_info *bss_info)
{
	if (bss_info == NULL)
		return -EINVAL;

	memset(bss_info, 0, sizeof(*bss_info));

	if (ht_add_info_ie) {
		u16 op_mode;
		op_mode = le16_to_cpu(ht_add_info_ie->operation_mode);

		bss_info->primary_channel = ht_add_info_ie->control_chan;
		bss_info->bss_cap = ht_add_info_ie->ht_param;
		bss_info->bss_op_mode = (u8)(op_mode & 0xff);
	}

	return 0;
}
437

438 439 440 441 442 443 444 445 446 447 448
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);
}

449
static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata,
450 451 452 453 454
					 struct ieee80211_if_sta *ifsta)
{
	union iwreq_data wrqu;

	if (ifsta->assocreq_ies) {
455 456
		memset(&wrqu, 0, sizeof(wrqu));
		wrqu.data.length = ifsta->assocreq_ies_len;
457
		wireless_send_event(sdata->dev, IWEVASSOCREQIE, &wrqu,
458
				    ifsta->assocreq_ies);
459
	}
460 461 462
	if (ifsta->assocresp_ies) {
		memset(&wrqu, 0, sizeof(wrqu));
		wrqu.data.length = ifsta->assocresp_ies_len;
463
		wireless_send_event(sdata->dev, IWEVASSOCRESPIE, &wrqu,
464
				    ifsta->assocresp_ies);
465 466 467 468
	}
}


469
static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
470
				     struct ieee80211_if_sta *ifsta)
471
{
472
	struct ieee80211_local *local = sdata->local;
T
Tomas Winkler 已提交
473
	struct ieee80211_conf *conf = &local_to_hw(local)->conf;
474
	u32 changed = BSS_CHANGED_ASSOC;
475

476
	struct ieee80211_sta_bss *bss;
477

478
	ifsta->flags |= IEEE80211_STA_ASSOCIATED;
479

480 481
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
		return;
482

483 484 485 486 487 488 489 490
	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;
491

492
		changed |= ieee80211_handle_bss_capability(sdata, bss);
493

494 495
		ieee80211_rx_bss_put(local, bss);
	}
T
Tomas Winkler 已提交
496

497 498 499 500 501 502
	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 已提交
503

504 505 506
	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 已提交
507

508
	ifsta->last_probe = jiffies;
509
	ieee80211_led_assoc(local, 1);
510

511
	sdata->bss_conf.assoc = 1;
512
	ieee80211_bss_info_change_notify(sdata, changed);
513

514
	netif_tx_start_all_queues(sdata->dev);
515
	netif_carrier_on(sdata->dev);
516

517
	ieee80211_sta_send_apinfo(sdata, ifsta);
518 519
}

520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
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);
}

550

551
static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
552 553
				   struct ieee80211_if_sta *ifsta)
{
554 555
	DECLARE_MAC_BUF(mac);

556 557
	ifsta->auth_tries++;
	if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) {
558
		printk(KERN_DEBUG "%s: authentication with AP %s"
559
		       " timed out\n",
560
		       sdata->dev->name, print_mac(mac, ifsta->bssid));
561
		ifsta->state = IEEE80211_STA_MLME_DISABLED;
562 563 564
		return;
	}

565
	ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
566
	printk(KERN_DEBUG "%s: authenticate with AP %s\n",
567
	       sdata->dev->name, print_mac(mac, ifsta->bssid));
568

569
	ieee80211_send_auth(sdata, ifsta, 1, NULL, 0, 0);
570 571 572 573

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

574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
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;
}
594

595
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
596 597
				 struct ieee80211_if_sta *ifsta)
{
598
	struct ieee80211_local *local = sdata->local;
599 600
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
601
	u8 *pos, *ies, *ht_add_ie;
602
	int i, len, count, rates_len, supp_rates_len;
603 604 605
	u16 capab;
	struct ieee80211_sta_bss *bss;
	int wmm = 0;
606
	struct ieee80211_supported_band *sband;
607
	u64 rates = 0;
608 609 610 611 612 613

	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 "
614
		       "frame\n", sdata->dev->name);
615 616 617 618
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

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

621
	capab = ifsta->capab;
622 623 624 625 626 627

	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;
628
	}
629

630
	bss = ieee80211_rx_bss_get(local, ifsta->bssid,
631
				   local->hw.conf.channel->center_freq,
632
				   ifsta->ssid, ifsta->ssid_len);
633 634 635
	if (bss) {
		if (bss->capability & WLAN_CAPABILITY_PRIVACY)
			capab |= WLAN_CAPABILITY_PRIVACY;
636
		if (bss->wmm_used)
637
			wmm = 1;
638 639 640 641 642 643 644

		/* 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);

645 646 647 648
		if ((bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
		    (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
			capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;

649
		ieee80211_rx_bss_put(local, bss);
650 651 652
	} else {
		rates = ~0;
		rates_len = sband->n_bitrates;
653 654 655 656 657
	}

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

661
	if (ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) {
662
		skb_put(skb, 10);
663 664
		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_REASSOC_REQ);
665
		mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
666 667
		mgmt->u.reassoc_req.listen_interval =
				cpu_to_le16(local->hw.conf.listen_interval);
668 669 670 671
		memcpy(mgmt->u.reassoc_req.current_ap, ifsta->prev_bssid,
		       ETH_ALEN);
	} else {
		skb_put(skb, 4);
672 673
		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_ASSOC_REQ);
674
		mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
675 676
		mgmt->u.reassoc_req.listen_interval =
				cpu_to_le16(local->hw.conf.listen_interval);
677 678 679 680 681 682 683 684
	}

	/* 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);

685
	/* add all rates which were marked to be used above */
686 687 688 689
	supp_rates_len = rates_len;
	if (supp_rates_len > 8)
		supp_rates_len = 8;

690
	len = sband->n_bitrates;
691
	pos = skb_put(skb, supp_rates_len + 2);
692
	*pos++ = WLAN_EID_SUPP_RATES;
693
	*pos++ = supp_rates_len;
694

695 696 697
	count = 0;
	for (i = 0; i < sband->n_bitrates; i++) {
		if (BIT(i) & rates) {
698
			int rate = sband->bitrates[i].bitrate;
699
			*pos++ = (u8) (rate / 5);
700 701 702 703 704
			if (++count == 8)
				break;
		}
	}

705
	if (rates_len > count) {
706 707 708 709 710 711 712 713 714
		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);
			}
715 716 717
		}
	}

718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737
	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*/
		}
	}

738 739 740 741 742
	if (ifsta->extra_ie) {
		pos = skb_put(skb, ifsta->extra_ie_len);
		memcpy(pos, ifsta->extra_ie, ifsta->extra_ie_len);
	}

743
	if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
744 745 746 747 748 749 750 751 752 753 754
		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;
	}
755

756
	/* wmm support is a must to HT */
757
	if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) &&
758 759
	    sband->ht_info.ht_supported &&
	    (ht_add_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_EXTRA_INFO))) {
760
		struct ieee80211_ht_addt_info *ht_add_info =
761
			(struct ieee80211_ht_addt_info *)ht_add_ie;
762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781
		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);
782 783 784 785 786 787
		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);
788 789 790 791
		/* 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);
792
	}
793 794 795

	kfree(ifsta->assocreq_ies);
	ifsta->assocreq_ies_len = (skb->data + skb->len) - ies;
796
	ifsta->assocreq_ies = kmalloc(ifsta->assocreq_ies_len, GFP_KERNEL);
797 798 799
	if (ifsta->assocreq_ies)
		memcpy(ifsta->assocreq_ies, ies, ifsta->assocreq_ies_len);

800
	ieee80211_sta_tx(sdata, skb, 0);
801 802 803
}


804
static void ieee80211_send_deauth(struct ieee80211_sub_if_data *sdata,
805 806
				  struct ieee80211_if_sta *ifsta, u16 reason)
{
807
	struct ieee80211_local *local = sdata->local;
808 809 810 811 812 813
	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 "
814
		       "frame\n", sdata->dev->name);
815 816 817 818 819 820 821
		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);
822
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
823
	memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
824 825
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_DEAUTH);
826 827 828
	skb_put(skb, 2);
	mgmt->u.deauth.reason_code = cpu_to_le16(reason);

829
	ieee80211_sta_tx(sdata, skb, 0);
830 831
}

J
Johannes Berg 已提交
832 833 834 835 836 837 838
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;
}
839

840
static void ieee80211_send_disassoc(struct ieee80211_sub_if_data *sdata,
841 842
				    struct ieee80211_if_sta *ifsta, u16 reason)
{
843
	struct ieee80211_local *local = sdata->local;
844 845 846 847 848 849
	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 "
850
		       "frame\n", sdata->dev->name);
851 852 853 854 855 856 857
		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);
858
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
859
	memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
860 861
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_DISASSOC);
862 863 864
	skb_put(skb, 2);
	mgmt->u.disassoc.reason_code = cpu_to_le16(reason);

865
	ieee80211_sta_tx(sdata, skb, 0);
866 867
}

868 869 870 871 872 873
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;
874
	u32 changed = BSS_CHANGED_ASSOC;
875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890

	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;

891
	netif_tx_stop_all_queues(sdata->dev);
892 893 894 895 896 897 898 899 900 901 902
	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);
	}

903 904 905 906 907 908 909 910 911 912 913 914 915 916
	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);
917 918 919 920 921 922 923 924 925 926

	if (self_disconnected)
		ifsta->state = IEEE80211_STA_MLME_DISABLED;

	sta_info_unlink(&sta);

	rcu_read_unlock();

	sta_info_destroy(sta);
}
927

928
static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata,
929 930
				      struct ieee80211_if_sta *ifsta)
{
931
	struct ieee80211_local *local = sdata->local;
932
	struct ieee80211_sta_bss *bss;
933 934 935
	int bss_privacy;
	int wep_privacy;
	int privacy_invoked;
936

937
	if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL))
938 939
		return 0;

940
	bss = ieee80211_rx_bss_get(local, ifsta->bssid,
941
				   local->hw.conf.channel->center_freq,
942
				   ifsta->ssid, ifsta->ssid_len);
943 944 945
	if (!bss)
		return 0;

946
	bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY);
947
	wep_privacy = !!ieee80211_sta_wep_configured(sdata);
948
	privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED);
949

950
	ieee80211_rx_bss_put(local, bss);
951

952 953 954 955
	if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked))
		return 0;

	return 1;
956 957
}

958
static void ieee80211_associate(struct ieee80211_sub_if_data *sdata,
959 960
				struct ieee80211_if_sta *ifsta)
{
961 962
	DECLARE_MAC_BUF(mac);

963 964
	ifsta->assoc_tries++;
	if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) {
965
		printk(KERN_DEBUG "%s: association with AP %s"
966
		       " timed out\n",
967
		       sdata->dev->name, print_mac(mac, ifsta->bssid));
968
		ifsta->state = IEEE80211_STA_MLME_DISABLED;
969 970 971
		return;
	}

972
	ifsta->state = IEEE80211_STA_MLME_ASSOCIATE;
973
	printk(KERN_DEBUG "%s: associate with AP %s\n",
974 975
	       sdata->dev->name, print_mac(mac, ifsta->bssid));
	if (ieee80211_privacy_mismatch(sdata, ifsta)) {
976
		printk(KERN_DEBUG "%s: mismatch in privacy configuration and "
977
		       "mixed-cell disabled - abort association\n", sdata->dev->name);
978
		ifsta->state = IEEE80211_STA_MLME_DISABLED;
979 980 981
		return;
	}

982
	ieee80211_send_assoc(sdata, ifsta);
983 984 985 986 987

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


988
static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
989 990
				 struct ieee80211_if_sta *ifsta)
{
991
	struct ieee80211_local *local = sdata->local;
992 993
	struct sta_info *sta;
	int disassoc;
994
	DECLARE_MAC_BUF(mac);
995 996 997 998 999 1000

	/* 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 */

1001
	ifsta->state = IEEE80211_STA_MLME_ASSOCIATED;
1002

1003 1004
	rcu_read_lock();

1005 1006
	sta = sta_info_get(local, ifsta->bssid);
	if (!sta) {
1007
		printk(KERN_DEBUG "%s: No STA entry for own AP %s\n",
1008
		       sdata->dev->name, print_mac(mac, ifsta->bssid));
1009 1010 1011 1012 1013
		disassoc = 1;
	} else {
		disassoc = 0;
		if (time_after(jiffies,
			       sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
1014
			if (ifsta->flags & IEEE80211_STA_PROBEREQ_POLL) {
1015
				printk(KERN_DEBUG "%s: No ProbeResp from "
1016
				       "current AP %s - assume out of "
1017
				       "range\n",
1018
				       sdata->dev->name, print_mac(mac, ifsta->bssid));
1019
				disassoc = 1;
1020
			} else
1021
				ieee80211_send_probe_req(sdata, ifsta->bssid,
1022 1023
							 local->scan_ssid,
							 local->scan_ssid_len);
1024
			ifsta->flags ^= IEEE80211_STA_PROBEREQ_POLL;
1025
		} else {
1026
			ifsta->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
1027 1028 1029
			if (time_after(jiffies, ifsta->last_probe +
				       IEEE80211_PROBE_INTERVAL)) {
				ifsta->last_probe = jiffies;
1030
				ieee80211_send_probe_req(sdata, ifsta->bssid,
1031 1032 1033 1034 1035
							 ifsta->ssid,
							 ifsta->ssid_len);
			}
		}
	}
1036 1037 1038

	rcu_read_unlock();

J
Johannes Berg 已提交
1039 1040 1041 1042 1043 1044
	if (disassoc)
		ieee80211_set_disassoc(sdata, ifsta, true, true,
					WLAN_REASON_PREV_AUTH_NOT_VALID);
	else
		mod_timer(&ifsta->timer, jiffies +
				      IEEE80211_MONITORING_INTERVAL);
1045 1046 1047
}


1048
static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata,
1049 1050
				     struct ieee80211_if_sta *ifsta)
{
1051
	printk(KERN_DEBUG "%s: authenticated\n", sdata->dev->name);
1052
	ifsta->flags |= IEEE80211_STA_AUTHENTICATED;
1053
	ieee80211_associate(sdata, ifsta);
1054 1055 1056
}


1057
static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1058 1059 1060 1061 1062 1063 1064 1065
				     struct ieee80211_if_sta *ifsta,
				     struct ieee80211_mgmt *mgmt,
				     size_t len)
{
	u8 *pos;
	struct ieee802_11_elems elems;

	pos = mgmt->u.auth.variable;
1066
	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1067
	if (!elems.challenge)
1068
		return;
1069
	ieee80211_send_auth(sdata, ifsta, 3, elems.challenge - 2,
1070 1071 1072
			    elems.challenge_len + 2, 1);
}

1073
static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
1074 1075 1076 1077
					u8 dialog_token, u16 status, u16 policy,
					u16 buf_size, u16 timeout)
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
1078
	struct ieee80211_local *local = sdata->local;
1079 1080 1081 1082
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u16 capab;

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

1085 1086
	if (!skb) {
		printk(KERN_DEBUG "%s: failed to allocate buffer "
1087
		       "for addba resp frame\n", sdata->dev->name);
1088 1089 1090 1091 1092 1093 1094
		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);
1095
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1096
	if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
1097
		memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
1098 1099
	else
		memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1100 1101
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_ACTION);
1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115

	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);

1116
	ieee80211_sta_tx(sdata, skb, 0);
1117 1118 1119 1120

	return;
}

1121
void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, const u8 *da,
1122 1123 1124
				u16 tid, u8 dialog_token, u16 start_seq_num,
				u16 agg_size, u16 timeout)
{
1125
	struct ieee80211_local *local = sdata->local;
1126 1127 1128 1129 1130
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u16 capab;

E
Ester Kummer 已提交
1131
	skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1132 1133 1134

	if (!skb) {
		printk(KERN_ERR "%s: failed to allocate buffer "
1135
				"for addba request frame\n", sdata->dev->name);
1136 1137 1138 1139 1140 1141
		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);
1142
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1143
	if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
1144
		memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
1145 1146 1147
	else
		memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);

1148 1149
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_ACTION);
1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166

	skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req));

	mgmt->u.action.category = WLAN_CATEGORY_BACK;
	mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;

	mgmt->u.action.u.addba_req.dialog_token = dialog_token;
	capab = (u16)(1 << 1);		/* bit 1 aggregation policy */
	capab |= (u16)(tid << 2); 	/* bit 5:2 TID number */
	capab |= (u16)(agg_size << 6);	/* bit 15:6 max size of aggergation */

	mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);

	mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout);
	mgmt->u.action.u.addba_req.start_seq_num =
					cpu_to_le16(start_seq_num << 4);

1167
	ieee80211_sta_tx(sdata, skb, 0);
1168 1169
}

J
Johannes Berg 已提交
1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193
/*
 * 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);
}

1194
static void ieee80211_sta_process_addba_request(struct ieee80211_local *local,
1195 1196 1197
						struct ieee80211_mgmt *mgmt,
						size_t len)
{
1198 1199
	struct ieee80211_hw *hw = &local->hw;
	struct ieee80211_conf *conf = &hw->conf;
1200
	struct sta_info *sta;
1201 1202
	struct tid_ampdu_rx *tid_agg_rx;
	u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
1203
	u8 dialog_token;
1204 1205
	int ret = -EOPNOTSUPP;
	DECLARE_MAC_BUF(mac);
1206

1207 1208
	rcu_read_lock();

1209
	sta = sta_info_get(local, mgmt->sa);
1210 1211
	if (!sta) {
		rcu_read_unlock();
1212
		return;
1213
	}
1214 1215 1216 1217

	/* 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);
1218 1219
	start_seq_num =
		le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4;
1220 1221 1222 1223 1224 1225 1226 1227

	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;

1228 1229 1230 1231 1232 1233 1234 1235 1236
	/* 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())
1237
			printk(KERN_DEBUG "AddBA Req with bad params from "
1238 1239 1240 1241 1242 1243 1244 1245
				"%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) {
1246 1247 1248
		struct ieee80211_supported_band *sband;

		sband = local->hw.wiphy->bands[conf->channel->band];
1249
		buf_size = IEEE80211_MIN_AMPDU_BUF;
1250
		buf_size = buf_size << sband->ht_info.ampdu_factor;
1251 1252 1253 1254
	}


	/* examine state machine */
1255
	spin_lock_bh(&sta->lock);
1256

1257
	if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
1258 1259
#ifdef CONFIG_MAC80211_HT_DEBUG
		if (net_ratelimit())
1260
			printk(KERN_DEBUG "unexpected AddBA Req from "
1261 1262 1263 1264 1265 1266
				"%s on tid %u\n",
				print_mac(mac, mgmt->sa), tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */
		goto end;
	}

1267 1268 1269 1270
	/* 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]) {
1271
#ifdef CONFIG_MAC80211_HT_DEBUG
1272 1273 1274
		if (net_ratelimit())
			printk(KERN_ERR "allocate rx mlme to tid %d failed\n",
					tid);
1275
#endif
1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286
		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];

1287 1288
	/* prepare reordering buffer */
	tid_agg_rx->reorder_buf =
1289
		kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC);
1290
	if (!tid_agg_rx->reorder_buf) {
1291
#ifdef CONFIG_MAC80211_HT_DEBUG
1292 1293 1294
		if (net_ratelimit())
			printk(KERN_ERR "can not allocate reordering buffer "
			       "to tid %d\n", tid);
1295
#endif
1296
		kfree(sta->ampdu_mlme.tid_rx[tid]);
1297 1298 1299
		goto end;
	}
	memset(tid_agg_rx->reorder_buf, 0,
1300
		buf_size * sizeof(struct sk_buff *));
1301 1302 1303

	if (local->ops->ampdu_action)
		ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START,
1304
					       sta->addr, tid, &start_seq_num);
1305
#ifdef CONFIG_MAC80211_HT_DEBUG
1306
	printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
1307 1308 1309 1310
#endif /* CONFIG_MAC80211_HT_DEBUG */

	if (ret) {
		kfree(tid_agg_rx->reorder_buf);
1311 1312
		kfree(tid_agg_rx);
		sta->ampdu_mlme.tid_rx[tid] = NULL;
1313 1314 1315 1316
		goto end;
	}

	/* change state and send addba resp */
1317
	sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL;
1318 1319 1320 1321 1322 1323 1324 1325
	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:
1326
	spin_unlock_bh(&sta->lock);
1327 1328

end_no_lock:
1329
	ieee80211_send_addba_resp(sta->sdata, sta->addr, tid,
1330 1331
				  dialog_token, status, 1, buf_size, timeout);
	rcu_read_unlock();
1332
}
1333

1334
static void ieee80211_sta_process_addba_resp(struct ieee80211_local *local,
1335 1336 1337 1338 1339 1340 1341 1342 1343
					     struct ieee80211_mgmt *mgmt,
					     size_t len)
{
	struct ieee80211_hw *hw = &local->hw;
	struct sta_info *sta;
	u16 capab;
	u16 tid;
	u8 *state;

1344 1345
	rcu_read_lock();

1346
	sta = sta_info_get(local, mgmt->sa);
1347 1348
	if (!sta) {
		rcu_read_unlock();
1349
		return;
1350
	}
1351 1352 1353 1354

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

1355
	state = &sta->ampdu_mlme.tid_state_tx[tid];
1356

1357
	spin_lock_bh(&sta->lock);
1358

1359
	if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1360
		spin_unlock_bh(&sta->lock);
1361 1362 1363
		goto addba_resp_exit;
	}

1364
	if (mgmt->u.action.u.addba_resp.dialog_token !=
1365
		sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
1366
		spin_unlock_bh(&sta->lock);
1367 1368 1369
#ifdef CONFIG_MAC80211_HT_DEBUG
		printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */
1370
		goto addba_resp_exit;
1371 1372
	}

1373
	del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
1374 1375 1376 1377 1378 1379
#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;
1380
		sta->ampdu_mlme.addba_req_num[tid] = 0;
1381

1382
		if (*state == HT_AGG_STATE_OPERATIONAL)
1383 1384
			ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);

1385
		spin_unlock_bh(&sta->lock);
1386
	} else {
1387
		sta->ampdu_mlme.addba_req_num[tid]++;
1388 1389
		/* this will allow the state check in stop_BA_session */
		*state = HT_AGG_STATE_OPERATIONAL;
1390
		spin_unlock_bh(&sta->lock);
1391 1392 1393
		ieee80211_stop_tx_ba_session(hw, sta->addr, tid,
					     WLAN_BACK_INITIATOR);
	}
1394 1395

addba_resp_exit:
1396
	rcu_read_unlock();
1397 1398
}

1399
void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, const u8 *da, u16 tid,
1400
			  u16 initiator, u16 reason_code)
1401
{
1402
	struct ieee80211_local *local = sdata->local;
1403 1404 1405 1406 1407
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u16 params;

E
Ester Kummer 已提交
1408
	skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1409 1410 1411

	if (!skb) {
		printk(KERN_ERR "%s: failed to allocate buffer "
1412
					"for delba frame\n", sdata->dev->name);
1413 1414 1415 1416 1417 1418 1419
		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);
1420
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1421
	if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
1422
		memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
1423 1424
	else
		memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1425 1426
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_ACTION);
1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437

	skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba));

	mgmt->u.action.category = WLAN_CATEGORY_BACK;
	mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
	params = (u16)(initiator << 11); 	/* bit 11 initiator */
	params |= (u16)(tid << 12); 		/* bit 15:12 TID number */

	mgmt->u.action.u.delba.params = cpu_to_le16(params);
	mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);

1438
	ieee80211_sta_tx(sdata, skb, 0);
1439 1440
}

1441
void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
1442
{
1443
	struct ieee80211_local *local = sdata->local;
1444 1445 1446 1447 1448 1449 1450
	struct sk_buff *skb;
	struct ieee80211_bar *bar;
	u16 bar_control = 0;

	skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
	if (!skb) {
		printk(KERN_ERR "%s: failed to allocate buffer for "
1451
			"bar frame\n", sdata->dev->name);
1452 1453 1454 1455 1456
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);
	bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
	memset(bar, 0, sizeof(*bar));
1457 1458
	bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
					 IEEE80211_STYPE_BACK_REQ);
1459
	memcpy(bar->ra, ra, ETH_ALEN);
1460
	memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN);
1461 1462 1463 1464 1465 1466
	bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
	bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
	bar_control |= (u16)(tid << 12);
	bar->control = cpu_to_le16(bar_control);
	bar->start_seq_num = cpu_to_le16(ssn);

1467
	ieee80211_sta_tx(sdata, skb, 0);
1468 1469
}

1470
void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid,
1471 1472
					u16 initiator, u16 reason)
{
1473
	struct ieee80211_local *local = sdata->local;
1474 1475
	struct ieee80211_hw *hw = &local->hw;
	struct sta_info *sta;
1476
	int ret, i;
1477
	DECLARE_MAC_BUF(mac);
1478

1479 1480
	rcu_read_lock();

1481
	sta = sta_info_get(local, ra);
1482 1483
	if (!sta) {
		rcu_read_unlock();
1484
		return;
1485
	}
1486 1487

	/* check if TID is in operational state */
1488
	spin_lock_bh(&sta->lock);
1489
	if (sta->ampdu_mlme.tid_state_rx[tid]
1490
				!= HT_AGG_STATE_OPERATIONAL) {
1491
		spin_unlock_bh(&sta->lock);
1492
		rcu_read_unlock();
1493 1494
		return;
	}
1495
	sta->ampdu_mlme.tid_state_rx[tid] =
1496 1497
		HT_AGG_STATE_REQ_STOP_BA_MSK |
		(initiator << HT_AGG_STATE_INITIATOR_SHIFT);
1498
	spin_unlock_bh(&sta->lock);
1499 1500 1501 1502 1503

	/* stop HW Rx aggregation. ampdu_action existence
	 * already verified in session init so we add the BUG_ON */
	BUG_ON(!local->ops->ampdu_action);

1504 1505 1506 1507 1508
#ifdef CONFIG_MAC80211_HT_DEBUG
	printk(KERN_DEBUG "Rx BA session stop requested for %s tid %u\n",
				print_mac(mac, ra), tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */

1509
	ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
1510
					ra, tid, NULL);
1511 1512
	if (ret)
		printk(KERN_DEBUG "HW problem - can not stop rx "
1513
				"aggregation for tid %d\n", tid);
1514 1515 1516

	/* shutdown timer has not expired */
	if (initiator != WLAN_BACK_TIMER)
1517
		del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
1518 1519 1520

	/* check if this is a self generated aggregation halt */
	if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER)
1521
		ieee80211_send_delba(sdata, ra, tid, 0, reason);
1522 1523

	/* free the reordering buffer */
1524 1525
	for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
		if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
1526
			/* release the reordered frames */
1527 1528 1529
			dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]);
			sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--;
			sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL;
1530 1531
		}
	}
1532 1533 1534 1535 1536
	/* free resources */
	kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
	kfree(sta->ampdu_mlme.tid_rx[tid]);
	sta->ampdu_mlme.tid_rx[tid] = NULL;
	sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
1537

1538
	rcu_read_unlock();
1539 1540
}

1541

1542
static void ieee80211_sta_process_delba(struct ieee80211_sub_if_data *sdata,
1543 1544
			struct ieee80211_mgmt *mgmt, size_t len)
{
1545
	struct ieee80211_local *local = sdata->local;
1546 1547 1548 1549 1550
	struct sta_info *sta;
	u16 tid, params;
	u16 initiator;
	DECLARE_MAC_BUF(mac);

1551 1552
	rcu_read_lock();

1553
	sta = sta_info_get(local, mgmt->sa);
1554 1555
	if (!sta) {
		rcu_read_unlock();
1556
		return;
1557
	}
1558 1559 1560 1561 1562 1563 1564

	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())
1565 1566
		printk(KERN_DEBUG "delba from %s (%s) tid %d reason code %d\n",
			print_mac(mac, mgmt->sa),
1567
			initiator ? "initiator" : "recipient", tid,
1568 1569 1570 1571
			mgmt->u.action.u.delba.reason_code);
#endif /* CONFIG_MAC80211_HT_DEBUG */

	if (initiator == WLAN_BACK_INITIATOR)
1572
		ieee80211_sta_stop_rx_ba_session(sdata, sta->addr, tid,
1573
						 WLAN_BACK_INITIATOR, 0);
1574
	else { /* WLAN_BACK_RECIPIENT */
1575
		spin_lock_bh(&sta->lock);
1576
		sta->ampdu_mlme.tid_state_tx[tid] =
1577
				HT_AGG_STATE_OPERATIONAL;
1578
		spin_unlock_bh(&sta->lock);
1579 1580 1581
		ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid,
					     WLAN_BACK_RECIPIENT);
	}
1582
	rcu_read_unlock();
1583 1584
}

1585 1586 1587 1588 1589 1590 1591 1592 1593
/*
 * After sending add Block Ack request we activated a timer until
 * add Block Ack response will arrive from the recipient.
 * If this timer expires sta_addba_resp_timer_expired will be executed.
 */
void sta_addba_resp_timer_expired(unsigned long data)
{
	/* not an elegant detour, but there is no choice as the timer passes
	 * only one argument, and both sta_info and TID are needed, so init
J
Johannes Berg 已提交
1594
	 * flow in sta_info_create gives the TID as data, while the timer_to_id
1595
	 * array gives the sta through container_of */
1596
	u16 tid = *(u8 *)data;
1597 1598 1599 1600 1601 1602 1603 1604
	struct sta_info *temp_sta = container_of((void *)data,
		struct sta_info, timer_to_tid[tid]);

	struct ieee80211_local *local = temp_sta->local;
	struct ieee80211_hw *hw = &local->hw;
	struct sta_info *sta;
	u8 *state;

1605 1606
	rcu_read_lock();

1607
	sta = sta_info_get(local, temp_sta->addr);
1608 1609
	if (!sta) {
		rcu_read_unlock();
1610
		return;
1611
	}
1612

1613
	state = &sta->ampdu_mlme.tid_state_tx[tid];
1614
	/* check if the TID waits for addBA response */
1615
	spin_lock_bh(&sta->lock);
1616
	if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1617
		spin_unlock_bh(&sta->lock);
1618
		*state = HT_AGG_STATE_IDLE;
1619
#ifdef CONFIG_MAC80211_HT_DEBUG
1620 1621
		printk(KERN_DEBUG "timer expired on tid %d but we are not "
				"expecting addBA response there", tid);
1622
#endif
1623 1624 1625
		goto timer_expired_exit;
	}

1626
#ifdef CONFIG_MAC80211_HT_DEBUG
1627
	printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
1628
#endif
1629 1630 1631

	/* go through the state check in stop_BA_session */
	*state = HT_AGG_STATE_OPERATIONAL;
1632
	spin_unlock_bh(&sta->lock);
1633 1634 1635 1636
	ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid,
				     WLAN_BACK_INITIATOR);

timer_expired_exit:
1637
	rcu_read_unlock();
1638 1639
}

1640
void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data *sdata, u8 *addr)
1641
{
1642
	struct ieee80211_local *local = sdata->local;
1643 1644 1645 1646 1647
	int i;

	for (i = 0; i <  STA_TID_NUM; i++) {
		ieee80211_stop_tx_ba_session(&local->hw, addr, i,
					     WLAN_BACK_INITIATOR);
1648
		ieee80211_sta_stop_rx_ba_session(sdata, addr, i,
1649 1650 1651 1652
						 WLAN_BACK_RECIPIENT,
						 WLAN_REASON_QSTA_LEAVE_QBSS);
	}
}
1653

1654
static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_data *sdata,
1655 1656 1657 1658
					struct ieee80211_msrment_ie *request_ie,
					const u8 *da, const u8 *bssid,
					u8 dialog_token)
{
1659
	struct ieee80211_local *local = sdata->local;
1660 1661 1662 1663 1664 1665 1666 1667
	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 "
1668
				"measurement report frame\n", sdata->dev->name);
1669 1670 1671 1672 1673 1674 1675
		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);
1676
	memcpy(msr_report->sa, sdata->dev->dev_addr, ETH_ALEN);
1677
	memcpy(msr_report->bssid, bssid, ETH_ALEN);
1678
	msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697
						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;

1698
	ieee80211_sta_tx(sdata, skb, 0);
1699 1700
}

1701
static void ieee80211_sta_process_measurement_req(struct ieee80211_sub_if_data *sdata,
1702 1703 1704 1705 1706 1707 1708 1709 1710 1711
						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
	 */
1712
	ieee80211_send_refuse_measurement_request(sdata,
1713 1714 1715 1716 1717 1718
			&mgmt->u.action.u.measurement.msr_elem,
			mgmt->sa, mgmt->bssid,
			mgmt->u.action.u.measurement.dialog_token);
}


1719
static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1720 1721 1722 1723 1724
				   struct ieee80211_if_sta *ifsta,
				   struct ieee80211_mgmt *mgmt,
				   size_t len)
{
	u16 auth_alg, auth_transaction, status_code;
1725
	DECLARE_MAC_BUF(mac);
1726

1727
	if (ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE &&
1728
	    sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
1729 1730
		return;

1731
	if (len < 24 + 6)
1732 1733
		return;

1734
	if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
1735
	    memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0)
1736 1737
		return;

1738
	if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
1739
	    memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0)
1740 1741 1742 1743 1744 1745
		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);

1746
	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
J
Johannes Berg 已提交
1747 1748
		/*
		 * IEEE 802.11 standard does not require authentication in IBSS
1749 1750 1751
		 * 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 已提交
1752
		 */
1753
		if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
1754
			return;
1755
		ieee80211_send_auth(sdata, ifsta, 2, NULL, 0, 0);
1756 1757 1758
	}

	if (auth_alg != ifsta->auth_alg ||
1759
	    auth_transaction != ifsta->auth_transaction)
1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787
		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 &&
1788
				    !ieee80211_sta_wep_configured(sdata))
1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799
					continue;
				ifsta->auth_alg = algs[pos];
				break;
			}
		}
		return;
	}

	switch (ifsta->auth_alg) {
	case WLAN_AUTH_OPEN:
	case WLAN_AUTH_LEAP:
1800
		ieee80211_auth_completed(sdata, ifsta);
1801 1802 1803
		break;
	case WLAN_AUTH_SHARED_KEY:
		if (ifsta->auth_transaction == 4)
1804
			ieee80211_auth_completed(sdata, ifsta);
1805
		else
1806
			ieee80211_auth_challenge(sdata, ifsta, mgmt, len);
1807 1808 1809 1810 1811
		break;
	}
}


1812
static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1813 1814 1815 1816 1817
				     struct ieee80211_if_sta *ifsta,
				     struct ieee80211_mgmt *mgmt,
				     size_t len)
{
	u16 reason_code;
1818
	DECLARE_MAC_BUF(mac);
1819

1820
	if (len < 24 + 2)
1821 1822
		return;

1823
	if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN))
1824 1825 1826 1827
		return;

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

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

1831 1832 1833
	if (ifsta->state == IEEE80211_STA_MLME_AUTHENTICATE ||
	    ifsta->state == IEEE80211_STA_MLME_ASSOCIATE ||
	    ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) {
1834
		ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
1835 1836 1837 1838
		mod_timer(&ifsta->timer, jiffies +
				      IEEE80211_RETRY_AUTH_INTERVAL);
	}

1839
	ieee80211_set_disassoc(sdata, ifsta, true, false, 0);
1840
	ifsta->flags &= ~IEEE80211_STA_AUTHENTICATED;
1841 1842 1843
}


1844
static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1845 1846 1847 1848 1849
				       struct ieee80211_if_sta *ifsta,
				       struct ieee80211_mgmt *mgmt,
				       size_t len)
{
	u16 reason_code;
1850
	DECLARE_MAC_BUF(mac);
1851

1852
	if (len < 24 + 2)
1853 1854
		return;

1855
	if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN))
1856 1857 1858 1859
		return;

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

1860
	if (ifsta->flags & IEEE80211_STA_ASSOCIATED)
1861
		printk(KERN_DEBUG "%s: disassociated\n", sdata->dev->name);
1862

1863 1864
	if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) {
		ifsta->state = IEEE80211_STA_MLME_ASSOCIATE;
1865 1866 1867 1868
		mod_timer(&ifsta->timer, jiffies +
				      IEEE80211_RETRY_AUTH_INTERVAL);
	}

1869
	ieee80211_set_disassoc(sdata, ifsta, false, false, 0);
1870 1871 1872
}


1873
static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1874 1875 1876 1877 1878
					 struct ieee80211_if_sta *ifsta,
					 struct ieee80211_mgmt *mgmt,
					 size_t len,
					 int reassoc)
{
1879
	struct ieee80211_local *local = sdata->local;
1880
	struct ieee80211_supported_band *sband;
1881
	struct sta_info *sta;
1882
	u64 rates, basic_rates;
1883 1884
	u16 capab_info, status_code, aid;
	struct ieee802_11_elems elems;
1885
	struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
1886 1887
	u8 *pos;
	int i, j;
1888
	DECLARE_MAC_BUF(mac);
1889
	bool have_higher_than_11mbit = false;
1890 1891 1892 1893

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

1894
	if (ifsta->state != IEEE80211_STA_MLME_ASSOCIATE)
1895 1896
		return;

1897
	if (len < 24 + 6)
1898 1899
		return;

1900
	if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0)
1901 1902 1903 1904 1905 1906
		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);

1907
	printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x "
1908
	       "status=%d aid=%d)\n",
1909
	       sdata->dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa),
1910
	       capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
1911 1912 1913

	if (status_code != WLAN_STATUS_SUCCESS) {
		printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
1914
		       sdata->dev->name, status_code);
1915 1916 1917
		/* 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. */
1918
		ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
1919 1920 1921
		return;
	}

1922 1923
	if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
		printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
1924
		       "set\n", sdata->dev->name, aid);
1925 1926
	aid &= ~(BIT(15) | BIT(14));

1927
	pos = mgmt->u.assoc_resp.variable;
1928
	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1929 1930 1931

	if (!elems.supp_rates) {
		printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
1932
		       sdata->dev->name);
1933 1934 1935
		return;
	}

1936
	printk(KERN_DEBUG "%s: associated\n", sdata->dev->name);
1937 1938 1939 1940 1941
	ifsta->aid = aid;
	ifsta->ap_capab = capab_info;

	kfree(ifsta->assocresp_ies);
	ifsta->assocresp_ies_len = len - (pos - (u8 *) mgmt);
1942
	ifsta->assocresp_ies = kmalloc(ifsta->assocresp_ies_len, GFP_KERNEL);
1943 1944 1945
	if (ifsta->assocresp_ies)
		memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len);

1946 1947
	rcu_read_lock();

1948 1949 1950 1951
	/* Add STA entry for the AP */
	sta = sta_info_get(local, ifsta->bssid);
	if (!sta) {
		struct ieee80211_sta_bss *bss;
J
Johannes Berg 已提交
1952
		int err;
1953

J
Johannes Berg 已提交
1954 1955 1956
		sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC);
		if (!sta) {
			printk(KERN_DEBUG "%s: failed to alloc STA entry for"
1957
			       " the AP\n", sdata->dev->name);
1958
			rcu_read_unlock();
1959 1960
			return;
		}
J
Johannes Berg 已提交
1961 1962 1963 1964 1965 1966 1967 1968 1969
		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);
		}
1970

J
Johannes Berg 已提交
1971 1972 1973 1974 1975 1976
		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;
1977
		}
J
Johannes Berg 已提交
1978 1979
		/* update new sta with its last rx activity */
		sta->last_rx = jiffies;
1980 1981
	}

J
Johannes Berg 已提交
1982 1983 1984 1985 1986 1987 1988 1989 1990
	/*
	 * 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.
	 */
1991

J
Johannes Berg 已提交
1992 1993
	set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP |
			   WLAN_STA_AUTHORIZED);
1994

J
Johannes Berg 已提交
1995 1996 1997
	rates = 0;
	basic_rates = 0;
	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1998

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

J
Johannes Berg 已提交
2002 2003 2004 2005 2006 2007 2008 2009
		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);
2010 2011 2012
		}
	}

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

J
Johannes Berg 已提交
2016 2017
		if (rate > 110)
			have_higher_than_11mbit = true;
2018

J
Johannes Berg 已提交
2019 2020 2021 2022 2023 2024
		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);
		}
2025
	}
2026

J
Johannes Berg 已提交
2027 2028 2029 2030 2031 2032 2033 2034 2035
	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;
2036

J
Johannes Berg 已提交
2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047
	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);
	}
2048

J
Johannes Berg 已提交
2049
	rate_control_rate_init(sta, local);
2050

J
Johannes Berg 已提交
2051 2052 2053 2054 2055 2056 2057
	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();
2058

J
Johannes Berg 已提交
2059 2060 2061 2062 2063
	/* 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);
2064

J
Johannes Berg 已提交
2065
	ieee80211_associated(sdata, ifsta);
2066 2067 2068
}


2069
static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
2070 2071 2072
				   struct ieee80211_if_sta *ifsta,
				   struct ieee80211_sta_bss *bss)
{
2073
	struct ieee80211_local *local = sdata->local;
2074 2075 2076 2077 2078
	int res, rates, i, j;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u8 *pos;
	struct ieee80211_supported_band *sband;
2079
	union iwreq_data wrqu;
2080 2081 2082 2083

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

	/* Remove possible STA entries from other IBSS networks. */
J
Johannes Berg 已提交
2084
	sta_info_flush_delayed(sdata);
2085 2086 2087 2088 2089 2090

	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);
2091
	res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
2092 2093 2094 2095 2096 2097 2098 2099
	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;

2100
	res = ieee80211_set_freq(sdata, bss->freq);
2101

2102 2103
	if (res)
		return res;
2104

2105
	/* Build IBSS probe response */
2106
	skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
2107
	if (skb) {
2108 2109 2110 2111 2112
		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));
2113 2114
		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_PROBE_RESP);
2115
		memset(mgmt->da, 0xff, ETH_ALEN);
2116
		memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
2117 2118 2119
		memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
		mgmt->u.beacon.beacon_int =
			cpu_to_le16(local->hw.conf.beacon_int);
2120
		mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp);
2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157
		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);
		}

2158
		ifsta->probe_resp = skb;
2159

2160 2161
		ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
	}
2162

2163 2164 2165 2166 2167 2168 2169
	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);
2170
	}
2171 2172
	ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;

2173
	ieee80211_sta_def_wmm_params(sdata, bss, 1);
2174

2175
	ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED;
2176 2177
	mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);

2178 2179
	memset(&wrqu, 0, sizeof(wrqu));
	memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN);
2180
	wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
2181 2182 2183 2184

	return res;
}

2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220
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;
}

2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247
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;
}
2248

2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325
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;

2326 2327 2328 2329 2330
	/*
	 * 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 &&
2331
	    bss->last_probe_resp && beacon) {
2332
		ieee80211_rx_bss_put(local, bss);
2333 2334 2335
		return;
	}

B
Bruno Randolf 已提交
2336 2337
	/* check if we need to merge IBSS */
	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
J
Johannes Berg 已提交
2338
	    bss->capability & WLAN_CAPABILITY_IBSS &&
B
Bruno Randolf 已提交
2339
	    bss->freq == local->oper_channel->center_freq &&
2340 2341 2342
	    elems->ssid_len == sdata->u.sta.ssid_len &&
	    memcmp(elems->ssid, sdata->u.sta.ssid,
				sdata->u.sta.ssid_len) == 0) {
B
Bruno Randolf 已提交
2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358
		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.
			 */
2359
			int rate = local->hw.wiphy->bands[band]->
B
Bruno Randolf 已提交
2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378
					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) {
2379
#ifdef CONFIG_MAC80211_IBSS_DEBUG
2380 2381
			printk(KERN_DEBUG "%s: beacon TSF higher than "
			       "local TSF - IBSS merge with BSSID %s\n",
2382
			       sdata->dev->name, print_mac(mac, mgmt->bssid));
J
Johannes Berg 已提交
2383
#endif
2384 2385
			ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss);
			ieee80211_ibss_add_sta(sdata, NULL,
2386
					       mgmt->bssid, mgmt->sa,
2387
					       supp_rates);
B
Bruno Randolf 已提交
2388 2389 2390
		}
	}

2391
	ieee80211_rx_bss_put(local, bss);
2392 2393 2394
}


2395
static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
2396 2397 2398 2399
					 struct ieee80211_mgmt *mgmt,
					 size_t len,
					 struct ieee80211_rx_status *rx_status)
{
2400 2401
	size_t baselen;
	struct ieee802_11_elems elems;
2402
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
2403

2404 2405 2406
	if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
		return; /* ignore ProbeResp to foreign address */

2407 2408 2409 2410 2411 2412 2413
	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);

2414
	ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
2415 2416 2417 2418 2419 2420 2421 2422

	/* 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);
	}
2423 2424 2425
}


2426
static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2427 2428 2429 2430 2431 2432 2433
				     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;
2434
	struct ieee80211_local *local = sdata->local;
2435
	struct ieee80211_conf *conf = &local->hw.conf;
2436
	u32 changed = 0;
2437

2438 2439 2440 2441 2442 2443 2444
	/* 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);

2445
	ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true);
2446

2447
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
2448 2449 2450
		return;
	ifsta = &sdata->u.sta;

2451
	if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED) ||
2452 2453 2454
	    memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0)
		return;

2455 2456 2457
	ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
				 elems.wmm_param_len);

2458
	if (elems.erp_info && elems.erp_info_len >= 1)
2459
		changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]);
2460 2461 2462 2463 2464
	else {
		u16 capab = le16_to_cpu(mgmt->u.beacon.capab_info);
		changed |= ieee80211_handle_protect_preamb(sdata, false,
				(capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);
	}
2465

2466
	if (elems.ht_cap_elem && elems.ht_info_elem &&
T
Tomas Winkler 已提交
2467
	    elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
2468 2469 2470 2471 2472
		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 已提交
2473 2474
		changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf,
					       &bss_info);
2475 2476
	}

2477
	ieee80211_bss_info_change_notify(sdata, changed);
2478 2479 2480
}


2481
static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
2482 2483 2484 2485 2486
					struct ieee80211_if_sta *ifsta,
					struct ieee80211_mgmt *mgmt,
					size_t len,
					struct ieee80211_rx_status *rx_status)
{
2487
	struct ieee80211_local *local = sdata->local;
2488 2489 2490 2491
	int tx_last_beacon;
	struct sk_buff *skb;
	struct ieee80211_mgmt *resp;
	u8 *pos, *end;
2492 2493 2494 2495 2496
	DECLARE_MAC_BUF(mac);
#ifdef CONFIG_MAC80211_IBSS_DEBUG
	DECLARE_MAC_BUF(mac2);
	DECLARE_MAC_BUF(mac3);
#endif
2497

2498
	if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS ||
2499
	    ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED ||
2500 2501 2502 2503 2504 2505 2506 2507 2508
	    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
2509 2510
	printk(KERN_DEBUG "%s: RX ProbeReq SA=%s DA=%s BSSID="
	       "%s (tx_last_beacon=%d)\n",
2511
	       sdata->dev->name, print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da),
2512
	       print_mac(mac3, mgmt->bssid), tx_last_beacon);
2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525
#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) {
2526 2527 2528
#ifdef CONFIG_MAC80211_IBSS_DEBUG
		printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq "
		       "from %s\n",
2529
		       sdata->dev->name, print_mac(mac, mgmt->sa));
2530
#endif
2531 2532 2533 2534 2535 2536 2537 2538 2539 2540
		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 */
2541
	skb = skb_copy(ifsta->probe_resp, GFP_KERNEL);
2542 2543 2544 2545 2546 2547
	if (!skb)
		return;

	resp = (struct ieee80211_mgmt *) skb->data;
	memcpy(resp->da, mgmt->sa, ETH_ALEN);
#ifdef CONFIG_MAC80211_IBSS_DEBUG
2548
	printk(KERN_DEBUG "%s: Sending ProbeResp to %s\n",
2549
	       sdata->dev->name, print_mac(mac, resp->da));
2550
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2551
	ieee80211_sta_tx(sdata, skb, 0);
2552 2553
}

2554
static void ieee80211_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
2555 2556
				     struct ieee80211_if_sta *ifsta,
				     struct ieee80211_mgmt *mgmt,
2557 2558
				     size_t len,
				     struct ieee80211_rx_status *rx_status)
2559
{
2560
	struct ieee80211_local *local = sdata->local;
2561

2562 2563
	/* all categories we currently handle have action_code */
	if (len < IEEE80211_MIN_ACTION_SIZE + 1)
2564 2565 2566
		return;

	switch (mgmt->u.action.category) {
2567 2568 2569
	case WLAN_CATEGORY_SPECTRUM_MGMT:
		if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ)
			break;
2570
		switch (mgmt->u.action.u.measurement.action_code) {
2571 2572 2573 2574
		case WLAN_ACTION_SPCT_MSR_REQ:
			if (len < (IEEE80211_MIN_ACTION_SIZE +
				   sizeof(mgmt->u.action.u.measurement)))
				break;
2575
			ieee80211_sta_process_measurement_req(sdata, mgmt, len);
2576 2577 2578
			break;
		}
		break;
2579 2580 2581 2582 2583 2584
	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;
2585
			ieee80211_sta_process_addba_request(local, mgmt, len);
2586
			break;
2587 2588 2589 2590
		case WLAN_ACTION_ADDBA_RESP:
			if (len < (IEEE80211_MIN_ACTION_SIZE +
				   sizeof(mgmt->u.action.u.addba_resp)))
				break;
2591
			ieee80211_sta_process_addba_resp(local, mgmt, len);
2592
			break;
2593 2594 2595 2596
		case WLAN_ACTION_DELBA:
			if (len < (IEEE80211_MIN_ACTION_SIZE +
				   sizeof(mgmt->u.action.u.delba)))
				break;
2597
			ieee80211_sta_process_delba(sdata, mgmt, len);
2598
			break;
2599 2600
		}
		break;
2601
	case PLINK_CATEGORY:
J
Johannes Berg 已提交
2602
		if (ieee80211_vif_is_mesh(&sdata->vif))
2603
			mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
2604 2605
		break;
	case MESH_PATH_SEL_CATEGORY:
J
Johannes Berg 已提交
2606
		if (ieee80211_vif_is_mesh(&sdata->vif))
2607
			mesh_rx_path_sel_frame(sdata, mgmt, len);
2608
		break;
2609 2610
	}
}
2611

2612
void ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
2613 2614
			   struct ieee80211_rx_status *rx_status)
{
2615
	struct ieee80211_local *local = sdata->local;
2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631
	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:
2632
	case IEEE80211_STYPE_ACTION:
2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647
		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);
}

2648
static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663
					 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:
2664
		ieee80211_rx_mgmt_probe_req(sdata, ifsta, mgmt, skb->len,
2665 2666 2667
					    rx_status);
		break;
	case IEEE80211_STYPE_PROBE_RESP:
2668
		ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, rx_status);
2669 2670
		break;
	case IEEE80211_STYPE_BEACON:
2671
		ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
2672 2673
		break;
	case IEEE80211_STYPE_AUTH:
2674
		ieee80211_rx_mgmt_auth(sdata, ifsta, mgmt, skb->len);
2675 2676
		break;
	case IEEE80211_STYPE_ASSOC_RESP:
2677
		ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 0);
2678 2679
		break;
	case IEEE80211_STYPE_REASSOC_RESP:
2680
		ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 1);
2681 2682
		break;
	case IEEE80211_STYPE_DEAUTH:
2683
		ieee80211_rx_mgmt_deauth(sdata, ifsta, mgmt, skb->len);
2684 2685
		break;
	case IEEE80211_STYPE_DISASSOC:
2686
		ieee80211_rx_mgmt_disassoc(sdata, ifsta, mgmt, skb->len);
2687
		break;
2688
	case IEEE80211_STYPE_ACTION:
2689
		ieee80211_rx_mgmt_action(sdata, ifsta, mgmt, skb->len, rx_status);
2690
		break;
2691 2692 2693 2694 2695 2696
	}

	kfree_skb(skb);
}


2697
static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
2698
{
2699
	struct ieee80211_local *local = sdata->local;
2700 2701 2702
	int active = 0;
	struct sta_info *sta;

2703 2704 2705 2706
	rcu_read_lock();

	list_for_each_entry_rcu(sta, &local->sta_list, list) {
		if (sta->sdata == sdata &&
2707 2708 2709 2710 2711 2712
		    time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL,
			       jiffies)) {
			active++;
			break;
		}
	}
2713 2714

	rcu_read_unlock();
2715 2716 2717 2718 2719

	return active;
}


2720
static void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, unsigned long exp_time)
2721
{
2722
	struct ieee80211_local *local = sdata->local;
2723
	struct sta_info *sta, *tmp;
2724
	LIST_HEAD(tmp_list);
2725
	DECLARE_MAC_BUF(mac);
2726
	unsigned long flags;
2727

2728
	spin_lock_irqsave(&local->sta_lock, flags);
2729
	list_for_each_entry_safe(sta, tmp, &local->sta_list, list)
2730
		if (time_after(jiffies, sta->last_rx + exp_time)) {
2731
#ifdef CONFIG_MAC80211_IBSS_DEBUG
2732
			printk(KERN_DEBUG "%s: expiring inactive STA %s\n",
2733
			       sdata->dev->name, print_mac(mac, sta->addr));
2734
#endif
2735
			__sta_info_unlink(&sta);
2736 2737
			if (sta)
				list_add(&sta->list, &tmp_list);
2738
		}
2739
	spin_unlock_irqrestore(&local->sta_lock, flags);
2740

2741 2742
	list_for_each_entry_safe(sta, tmp, &tmp_list, list)
		sta_info_destroy(sta);
2743 2744 2745
}


2746
static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata,
2747 2748 2749 2750
				     struct ieee80211_if_sta *ifsta)
{
	mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);

2751 2752
	ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT);
	if (ieee80211_sta_active_ibss(sdata))
2753 2754 2755
		return;

	printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
2756 2757
	       "IBSS networks with same SSID (merge)\n", sdata->dev->name);
	ieee80211_sta_req_scan(sdata, ifsta->ssid, ifsta->ssid_len);
2758 2759 2760
}


2761
#ifdef CONFIG_MAC80211_MESH
2762
static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
2763 2764 2765 2766
			   struct ieee80211_if_sta *ifsta)
{
	bool free_plinks;

2767 2768
	ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
	mesh_path_expire(sdata);
2769 2770 2771

	free_plinks = mesh_plink_availables(sdata);
	if (free_plinks != sdata->u.sta.accepting_plinks)
2772
		ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
2773 2774 2775 2776 2777 2778

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


2779
void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
2780 2781 2782
{
	struct ieee80211_if_sta *ifsta;
	ifsta = &sdata->u.sta;
2783
	ifsta->state = IEEE80211_STA_MLME_MESH_UP;
2784
	ieee80211_sta_timer((unsigned long)sdata);
L
Luis Carlos Cobo 已提交
2785
	ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
2786 2787 2788 2789
}
#endif


2790 2791
void ieee80211_sta_timer(unsigned long data)
{
J
Johannes Berg 已提交
2792 2793 2794 2795
	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;
2796

J
Johannes Berg 已提交
2797 2798
	set_bit(IEEE80211_STA_REQ_RUN, &ifsta->request);
	queue_work(local->hw.workqueue, &ifsta->work);
2799 2800
}

2801
static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata,
2802 2803
				     struct ieee80211_if_sta *ifsta)
{
2804
	struct ieee80211_local *local = sdata->local;
2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822

	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;
2823
	ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
2824
	ifsta->assoc_scan_tries = 0;
2825
	ifsta->direct_probe_tries = 0;
2826 2827
	ifsta->auth_tries = 0;
	ifsta->assoc_tries = 0;
2828
	netif_tx_stop_all_queues(sdata->dev);
2829
	netif_carrier_off(sdata->dev);
2830 2831 2832
}


2833
void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata,
2834 2835
			    struct ieee80211_if_sta *ifsta)
{
2836
	struct ieee80211_local *local = sdata->local;
2837

2838
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
2839 2840
		return;

2841
	if ((ifsta->flags & (IEEE80211_STA_BSSID_SET |
2842
			     IEEE80211_STA_AUTO_BSSID_SEL)) &&
2843
	    (ifsta->flags & (IEEE80211_STA_SSID_SET |
2844 2845 2846 2847 2848 2849
			     IEEE80211_STA_AUTO_SSID_SEL))) {

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

2850 2851 2852 2853 2854 2855 2856 2857 2858 2859
		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;

2860 2861
	if (ssid_len == ifsta->ssid_len &&
	    !memcmp(ifsta->ssid, ssid, ssid_len))
2862 2863
		return 1;

2864
	if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL)
2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884
		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;
}

2885
static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
2886 2887
				     struct ieee80211_if_sta *ifsta)
{
2888
	struct ieee80211_local *local = sdata->local;
2889
	struct ieee80211_sta_bss *bss;
2890
	struct ieee80211_supported_band *sband;
2891 2892
	u8 bssid[ETH_ALEN], *pos;
	int i;
2893
	int ret;
2894
	DECLARE_MAC_BUF(mac);
2895 2896 2897 2898 2899 2900 2901 2902 2903 2904

#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++)
2905
		bssid[i] ^= sdata->dev->dev_addr[i];
2906 2907 2908 2909
	bssid[0] &= ~0x01;
	bssid[0] |= 0x02;
#endif

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

2913
	bss = ieee80211_rx_bss_add(local, bssid,
2914
				   local->hw.conf.channel->center_freq,
2915
				   sdata->u.sta.ssid, sdata->u.sta.ssid_len);
2916 2917 2918
	if (!bss)
		return -ENOMEM;

2919 2920
	bss->band = local->hw.conf.channel->band;
	sband = local->hw.wiphy->bands[bss->band];
2921 2922

	if (local->hw.conf.beacon_int == 0)
2923
		local->hw.conf.beacon_int = 100;
2924 2925 2926
	bss->beacon_int = local->hw.conf.beacon_int;
	bss->last_update = jiffies;
	bss->capability = WLAN_CAPABILITY_IBSS;
J
Johannes Berg 已提交
2927 2928

	if (sdata->default_key)
2929
		bss->capability |= WLAN_CAPABILITY_PRIVACY;
J
Johannes Berg 已提交
2930
	else
2931
		sdata->drop_unencrypted = 0;
J
Johannes Berg 已提交
2932

2933
	bss->supp_rates_len = sband->n_bitrates;
2934
	pos = bss->supp_rates;
2935 2936
	for (i = 0; i < sband->n_bitrates; i++) {
		int rate = sband->bitrates[i].bitrate;
2937 2938 2939
		*pos++ = (u8) (rate / 5);
	}

2940
	ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
2941
	ieee80211_rx_bss_put(local, bss);
2942
	return ret;
2943 2944 2945
}


2946
static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
2947 2948
				   struct ieee80211_if_sta *ifsta)
{
2949
	struct ieee80211_local *local = sdata->local;
2950 2951 2952 2953
	struct ieee80211_sta_bss *bss;
	int found = 0;
	u8 bssid[ETH_ALEN];
	int active_ibss;
2954 2955
	DECLARE_MAC_BUF(mac);
	DECLARE_MAC_BUF(mac2);
2956 2957 2958 2959

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

2960
	active_ibss = ieee80211_sta_active_ibss(sdata);
2961 2962
#ifdef CONFIG_MAC80211_IBSS_DEBUG
	printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n",
2963
	       sdata->dev->name, active_ibss);
2964 2965 2966 2967 2968 2969 2970 2971
#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
2972 2973
		printk(KERN_DEBUG "   bssid=%s found\n",
		       print_mac(mac, bss->bssid));
2974 2975 2976 2977 2978 2979 2980 2981 2982
#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
2983 2984 2985 2986
	if (found)
		printk(KERN_DEBUG "   sta_find_ibss: selected %s current "
		       "%s\n", print_mac(mac, bssid),
		       print_mac(mac2, ifsta->bssid));
2987
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2988 2989

	if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) {
2990
		int ret;
2991 2992 2993 2994 2995 2996 2997
		int search_freq;

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

2998
		bss = ieee80211_rx_bss_get(local, bssid, search_freq,
2999 3000 3001 3002
					   ifsta->ssid, ifsta->ssid_len);
		if (!bss)
			goto dont_join;

3003
		printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
3004
		       " based on configured SSID\n",
3005 3006
		       sdata->dev->name, print_mac(mac, bssid));
		ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
3007
		ieee80211_rx_bss_put(local, bss);
3008
		return ret;
3009
	}
3010 3011

dont_join:
3012 3013 3014 3015 3016
#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 */
3017
	if (ifsta->state == IEEE80211_STA_MLME_IBSS_JOINED &&
3018
	    !ieee80211_sta_active_ibss(sdata)) {
3019 3020 3021 3022 3023
		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 "
3024 3025
		       "join\n", sdata->dev->name);
		return ieee80211_sta_req_scan(sdata, ifsta->ssid,
3026
					      ifsta->ssid_len);
3027
	} else if (ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED) {
3028 3029 3030 3031
		int interval = IEEE80211_SCAN_INTERVAL;

		if (time_after(jiffies, ifsta->ibss_join_req +
			       IEEE80211_IBSS_JOIN_TIMEOUT)) {
3032
			if ((ifsta->flags & IEEE80211_STA_CREATE_IBSS) &&
3033 3034
			    (!(local->oper_channel->flags &
					IEEE80211_CHAN_NO_IBSS)))
3035
				return ieee80211_sta_create_ibss(sdata, ifsta);
3036
			if (ifsta->flags & IEEE80211_STA_CREATE_IBSS) {
3037
				printk(KERN_DEBUG "%s: IBSS not allowed on"
3038
				       " %d MHz\n", sdata->dev->name,
3039
				       local->hw.conf.channel->center_freq);
3040 3041 3042 3043 3044 3045 3046
			}

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

3047
		ifsta->state = IEEE80211_STA_MLME_IBSS_SEARCH;
3048 3049 3050 3051 3052 3053 3054 3055
		mod_timer(&ifsta->timer, jiffies + interval);
		return 0;
	}

	return 0;
}


3056
int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
3057 3058
{
	struct ieee80211_if_sta *ifsta;
3059
	int res;
3060 3061 3062 3063 3064 3065

	if (len > IEEE80211_MAX_SSID_LEN)
		return -EINVAL;

	ifsta = &sdata->u.sta;

3066 3067 3068 3069
	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;
3070
		ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
3071 3072 3073 3074 3075 3076 3077 3078 3079 3080

		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 "
3081
			       "the low-level driver\n", sdata->dev->name);
3082 3083 3084
			return res;
		}
	}
3085

3086 3087 3088 3089
	if (len)
		ifsta->flags |= IEEE80211_STA_SSID_SET;
	else
		ifsta->flags &= ~IEEE80211_STA_SSID_SET;
3090

3091
	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
3092
	    !(ifsta->flags & IEEE80211_STA_BSSID_SET)) {
3093
		ifsta->ibss_join_req = jiffies;
3094
		ifsta->state = IEEE80211_STA_MLME_IBSS_SEARCH;
3095
		return ieee80211_sta_find_ibss(sdata, ifsta);
3096
	}
3097

3098 3099 3100 3101
	return 0;
}


3102
int ieee80211_sta_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len)
3103 3104 3105 3106 3107 3108 3109 3110
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
	memcpy(ssid, ifsta->ssid, ifsta->ssid_len);
	*len = ifsta->ssid_len;
	return 0;
}


3111
int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
3112 3113 3114 3115 3116 3117 3118 3119
{
	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);
3120 3121 3122 3123 3124 3125
		res = 0;
		/*
		 * Hack! See also ieee80211_sta_set_ssid.
		 */
		if (netif_running(sdata->dev))
			res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
3126 3127
		if (res) {
			printk(KERN_DEBUG "%s: Failed to config new BSSID to "
3128
			       "the low-level driver\n", sdata->dev->name);
3129 3130 3131 3132
			return res;
		}
	}

3133 3134
	if (is_valid_ether_addr(bssid))
		ifsta->flags |= IEEE80211_STA_BSSID_SET;
3135
	else
3136 3137
		ifsta->flags &= ~IEEE80211_STA_BSSID_SET;

3138 3139 3140 3141
	return 0;
}


3142
int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, char *ie, size_t len)
3143 3144
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
J
Johannes Berg 已提交
3145

3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162
	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;
}


3163
struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
J
Johannes Berg 已提交
3164
					struct sk_buff *skb, u8 *bssid,
3165
					u8 *addr, u64 supp_rates)
3166
{
3167
	struct ieee80211_local *local = sdata->local;
3168
	struct sta_info *sta;
3169
	DECLARE_MAC_BUF(mac);
3170
	int band = local->hw.conf.channel->band;
3171 3172 3173 3174 3175 3176

	/* 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 "
3177
			       "entry %s\n", sdata->dev->name, print_mac(mac, addr));
3178 3179 3180 3181
		}
		return NULL;
	}

3182
	if (compare_ether_addr(bssid, sdata->u.sta.bssid))
3183 3184
		return NULL;

3185
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
3186
	printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n",
3187
	       wiphy_name(local->hw.wiphy), print_mac(mac, addr), sdata->dev->name);
3188
#endif
3189

J
Johannes Berg 已提交
3190 3191
	sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
	if (!sta)
3192 3193
		return NULL;

3194
	set_sta_flags(sta, WLAN_STA_AUTHORIZED);
3195

3196 3197 3198
	/* make sure mandatory rates are always added */
	sta->supp_rates[band] = supp_rates |
			ieee80211_sta_get_mandatory_rates(local, band);
3199 3200 3201

	rate_control_rate_init(sta, local);

3202
	if (sta_info_insert(sta))
J
Johannes Berg 已提交
3203 3204
		return NULL;

3205
	return sta;
3206 3207 3208
}


J
Johannes Berg 已提交
3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287
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;
}


3288
int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason)
3289 3290 3291
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;

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

3295 3296
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA &&
	    sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
3297 3298
		return -EINVAL;

3299
	ieee80211_set_disassoc(sdata, ifsta, true, true, reason);
3300 3301 3302 3303
	return 0;
}


3304
int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason)
3305 3306 3307
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;

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

3311
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
3312 3313
		return -EINVAL;

3314
	if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED))
3315 3316
		return -1;

3317
	ieee80211_set_disassoc(sdata, ifsta, false, true, reason);
3318 3319
	return 0;
}
3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330

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) {
3331 3332
			if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
				continue;
3333

3334
			ieee80211_sta_req_auth(sdata, &sdata->u.sta);
3335 3336 3337 3338 3339 3340
		}
		rcu_read_unlock();
		break;
	}
}
EXPORT_SYMBOL(ieee80211_notify_mac);
J
Johannes Berg 已提交
3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428

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)) {
		if (ifsta->scan_ssid_len)
			ieee80211_sta_start_scan(sdata, ifsta->scan_ssid, ifsta->scan_ssid_len);
		else
			ieee80211_sta_start_scan(sdata, NULL, 0);
		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);
	}
}
3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442

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);
	}
}