mlme.c 119.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * 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.
 */

/* TODO:
 * order BSS list by RSSI(?) ("quality of AP")
 * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
 *    SSID)
 */
19
#include <linux/delay.h>
20 21 22 23 24 25 26
#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>
27
#include <linux/rtnetlink.h>
28 29 30 31 32
#include <net/iw_handler.h>
#include <asm/types.h>

#include <net/mac80211.h>
#include "ieee80211_i.h"
J
Johannes Berg 已提交
33 34
#include "rate.h"
#include "led.h"
35
#include "mesh.h"
36

37
#define IEEE80211_ASSOC_SCANS_MAX_TRIES 2
38 39 40 41 42
#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)
43
#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
44 45 46 47
#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)
48
#define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ)
49 50 51 52 53 54 55

#define IEEE80211_PROBE_DELAY (HZ / 33)
#define IEEE80211_CHANNEL_TIME (HZ / 33)
#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5)
#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ)
#define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ)
#define IEEE80211_IBSS_INACTIVITY_LIMIT (60 * HZ)
56
#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
57 58 59 60 61 62

#define IEEE80211_IBSS_MAX_STA_ENTRIES 128


#define ERP_INFO_USE_PROTECTION BIT(1)

63
/* mgmt header + 1 byte category code */
64 65 66 67 68
#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
69 70
#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
71

72 73 74 75 76
/* 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

77
static void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
78 79
				     u8 *ssid, size_t ssid_len);
static struct ieee80211_sta_bss *
80
ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
81
		     u8 *ssid, u8 ssid_len);
82
static void ieee80211_rx_bss_put(struct ieee80211_local *local,
83
				 struct ieee80211_sta_bss *bss);
84
static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
85
				   struct ieee80211_if_sta *ifsta);
86 87
static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata);
static int ieee80211_sta_start_scan(struct ieee80211_sub_if_data *sdata,
88
				    u8 *ssid, size_t ssid_len);
89
static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata,
90
				     struct ieee80211_if_sta *ifsta);
91
static void sta_rx_agg_session_timer_expired(unsigned long data);
92 93


94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
static u8 * ieee80211_bss_get_ie(struct ieee80211_sta_bss *bss, u8 ie)
{
	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;
}


115 116
static int ecw2cw(int ecw)
{
117
	return (1 << ecw) - 1;
118 119
}

120

121
static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
					 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 已提交
157 158
		for (i = 0; i < local_to_hw(local)->queues; i++)
			local->ops->conf_tx(local_to_hw(local), i, &qparam);
159 160 161
	}
}

162
static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
163 164 165 166 167 168 169 170
				     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;

171 172 173 174 175 176
	if (!(ifsta->flags & IEEE80211_STA_WMM_ENABLED))
		return;

	if (!wmm_param)
		return;

177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
	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 已提交
200
			queue = 3;
J
Johannes Berg 已提交
201
			if (acm)
202 203 204
				local->wmm_acm |= BIT(0) | BIT(3);
			break;
		case 2:
J
Johannes Berg 已提交
205
			queue = 1;
J
Johannes Berg 已提交
206
			if (acm)
207 208 209
				local->wmm_acm |= BIT(4) | BIT(5);
			break;
		case 3:
J
Johannes Berg 已提交
210
			queue = 0;
J
Johannes Berg 已提交
211
			if (acm)
212 213 214 215
				local->wmm_acm |= BIT(6) | BIT(7);
			break;
		case 0:
		default:
J
Johannes Berg 已提交
216
			queue = 2;
J
Johannes Berg 已提交
217
			if (acm)
218 219 220 221 222 223 224
				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);
225
		params.txop = get_unaligned_le16(pos + 2);
226
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
227
		printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d "
228
		       "cWmin=%d cWmax=%d txop=%d\n",
229
		       local->mdev->name, queue, aci, acm, params.aifs, params.cw_min,
230 231
		       params.cw_max, params.txop);
#endif
232 233 234 235
		/* 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 "
236
			       "parameters for queue %d\n", local->mdev->name, queue);
237 238 239 240
		}
	}
}

241 242 243
static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata,
					   bool use_protection,
					   bool use_short_preamble)
244
{
245
	struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
246
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
247
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
248
	DECLARE_MAC_BUF(mac);
249
#endif
250
	u32 changed = 0;
251

252
	if (use_protection != bss_conf->use_cts_prot) {
253
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
254 255
		if (net_ratelimit()) {
			printk(KERN_DEBUG "%s: CTS protection %s (BSSID="
256
			       "%s)\n",
257
			       sdata->dev->name,
258
			       use_protection ? "enabled" : "disabled",
259
			       print_mac(mac, ifsta->bssid));
260
		}
261
#endif
262 263
		bss_conf->use_cts_prot = use_protection;
		changed |= BSS_CHANGED_ERP_CTS_PROT;
264
	}
265

266
	if (use_short_preamble != bss_conf->use_short_preamble) {
267
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
268 269
		if (net_ratelimit()) {
			printk(KERN_DEBUG "%s: switched to %s barker preamble"
270
			       " (BSSID=%s)\n",
271
			       sdata->dev->name,
272
			       use_short_preamble ? "short" : "long",
273
			       print_mac(mac, ifsta->bssid));
274
		}
275
#endif
276
		bss_conf->use_short_preamble = use_short_preamble;
277
		changed |= BSS_CHANGED_ERP_PREAMBLE;
278
	}
279

280
	return changed;
281 282
}

283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
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;
}

309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
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;
}
354

355
static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata,
356 357 358 359 360
					 struct ieee80211_if_sta *ifsta)
{
	union iwreq_data wrqu;

	if (ifsta->assocreq_ies) {
361 362
		memset(&wrqu, 0, sizeof(wrqu));
		wrqu.data.length = ifsta->assocreq_ies_len;
363
		wireless_send_event(sdata->dev, IWEVASSOCREQIE, &wrqu,
364
				    ifsta->assocreq_ies);
365
	}
366 367 368
	if (ifsta->assocresp_ies) {
		memset(&wrqu, 0, sizeof(wrqu));
		wrqu.data.length = ifsta->assocresp_ies_len;
369
		wireless_send_event(sdata->dev, IWEVASSOCRESPIE, &wrqu,
370
				    ifsta->assocresp_ies);
371 372 373 374
	}
}


375
static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
376
				     struct ieee80211_if_sta *ifsta,
377
				     bool assoc)
378
{
379
	struct ieee80211_local *local = sdata->local;
T
Tomas Winkler 已提交
380
	struct ieee80211_conf *conf = &local_to_hw(local)->conf;
381
	union iwreq_data wrqu;
382
	u32 changed = BSS_CHANGED_ASSOC;
383 384

	if (assoc) {
385
		struct ieee80211_sta_bss *bss;
386 387 388

		ifsta->flags |= IEEE80211_STA_ASSOCIATED;

389
		if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
390
			return;
391

392
		bss = ieee80211_rx_bss_get(local, ifsta->bssid,
T
Tomas Winkler 已提交
393
					   conf->channel->center_freq,
394
					   ifsta->ssid, ifsta->ssid_len);
395
		if (bss) {
396 397 398
			/* set timing information */
			sdata->bss_conf.beacon_int = bss->beacon_int;
			sdata->bss_conf.timestamp = bss->timestamp;
399
			sdata->bss_conf.dtim_period = bss->dtim_period;
400

401
			changed |= ieee80211_handle_bss_capability(sdata, bss);
402

403
			ieee80211_rx_bss_put(local, bss);
404 405
		}

T
Tomas Winkler 已提交
406 407 408 409 410 411 412
		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;
		}

413
		ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET;
414 415
		memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN);
		memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN);
416
		ieee80211_sta_send_associnfo(sdata, ifsta);
417
	} else {
418
		ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
419
		changed |= ieee80211_reset_erp_info(sdata);
T
Tomas Winkler 已提交
420 421 422 423 424

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

425 426 427
		memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
	}
	ifsta->last_probe = jiffies;
428
	ieee80211_led_assoc(local, assoc);
429

430
	sdata->bss_conf.assoc = assoc;
431
	ieee80211_bss_info_change_notify(sdata, changed);
432 433

	if (assoc)
434
		netif_carrier_on(sdata->dev);
435

436
	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
437
	wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
438 439
}

440
void ieee80211_sta_tx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
441
		      int encrypt)
442 443 444 445 446 447
{
	skb->dev = sdata->local->mdev;
	skb_set_mac_header(skb, 0);
	skb_set_network_header(skb, 0);
	skb_set_transport_header(skb, 0);

448 449
	skb->iif = sdata->dev->ifindex;
	skb->do_not_encrypt = !encrypt;
450 451 452 453 454

	dev_queue_xmit(skb);
}


455
static void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
456 457 458 459
				struct ieee80211_if_sta *ifsta,
				int transaction, u8 *extra, size_t extra_len,
				int encrypt)
{
460
	struct ieee80211_local *local = sdata->local;
461 462 463 464 465 466 467
	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 "
468
		       "frame\n", sdata->dev->name);
469 470 471 472 473 474
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6);
	memset(mgmt, 0, 24 + 6);
475 476
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_AUTH);
477 478 479
	if (encrypt)
		mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
	memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
480
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
481 482 483 484 485 486 487 488
	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);

489
	ieee80211_sta_tx(sdata, skb, encrypt);
490 491
}

492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
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);
}

522

523
static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
524 525
				   struct ieee80211_if_sta *ifsta)
{
526 527
	DECLARE_MAC_BUF(mac);

528 529
	ifsta->auth_tries++;
	if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) {
530
		printk(KERN_DEBUG "%s: authentication with AP %s"
531
		       " timed out\n",
532
		       sdata->dev->name, print_mac(mac, ifsta->bssid));
533
		ifsta->state = IEEE80211_STA_MLME_DISABLED;
534 535 536
		return;
	}

537
	ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
538
	printk(KERN_DEBUG "%s: authenticate with AP %s\n",
539
	       sdata->dev->name, print_mac(mac, ifsta->bssid));
540

541
	ieee80211_send_auth(sdata, ifsta, 1, NULL, 0, 0);
542 543 544 545

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

546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
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;
}
566

567
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
568 569
				 struct ieee80211_if_sta *ifsta)
{
570
	struct ieee80211_local *local = sdata->local;
571 572
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
573
	u8 *pos, *ies, *ht_add_ie;
574
	int i, len, count, rates_len, supp_rates_len;
575 576 577
	u16 capab;
	struct ieee80211_sta_bss *bss;
	int wmm = 0;
578
	struct ieee80211_supported_band *sband;
579
	u64 rates = 0;
580 581 582 583 584 585

	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 "
586
		       "frame\n", sdata->dev->name);
587 588 589 590
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

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

593
	capab = ifsta->capab;
594 595 596 597 598 599

	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;
600
	}
601

602
	bss = ieee80211_rx_bss_get(local, ifsta->bssid,
603
				   local->hw.conf.channel->center_freq,
604
				   ifsta->ssid, ifsta->ssid_len);
605 606 607
	if (bss) {
		if (bss->capability & WLAN_CAPABILITY_PRIVACY)
			capab |= WLAN_CAPABILITY_PRIVACY;
608
		if (bss->wmm_used)
609
			wmm = 1;
610 611 612 613 614 615 616

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

617 618 619 620
		if ((bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
		    (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
			capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;

621
		ieee80211_rx_bss_put(local, bss);
622 623 624
	} else {
		rates = ~0;
		rates_len = sband->n_bitrates;
625 626 627 628 629
	}

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

633
	if (ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) {
634
		skb_put(skb, 10);
635 636
		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_REASSOC_REQ);
637
		mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
638 639
		mgmt->u.reassoc_req.listen_interval =
				cpu_to_le16(local->hw.conf.listen_interval);
640 641 642 643
		memcpy(mgmt->u.reassoc_req.current_ap, ifsta->prev_bssid,
		       ETH_ALEN);
	} else {
		skb_put(skb, 4);
644 645
		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_ASSOC_REQ);
646
		mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
647 648
		mgmt->u.reassoc_req.listen_interval =
				cpu_to_le16(local->hw.conf.listen_interval);
649 650 651 652 653 654 655 656
	}

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

657
	/* add all rates which were marked to be used above */
658 659 660 661
	supp_rates_len = rates_len;
	if (supp_rates_len > 8)
		supp_rates_len = 8;

662
	len = sband->n_bitrates;
663
	pos = skb_put(skb, supp_rates_len + 2);
664
	*pos++ = WLAN_EID_SUPP_RATES;
665
	*pos++ = supp_rates_len;
666

667 668 669
	count = 0;
	for (i = 0; i < sband->n_bitrates; i++) {
		if (BIT(i) & rates) {
670
			int rate = sband->bitrates[i].bitrate;
671
			*pos++ = (u8) (rate / 5);
672 673 674 675 676
			if (++count == 8)
				break;
		}
	}

677
	if (rates_len > count) {
678 679 680 681 682 683 684 685 686
		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);
			}
687 688 689
		}
	}

690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709
	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*/
		}
	}

710 711 712 713 714
	if (ifsta->extra_ie) {
		pos = skb_put(skb, ifsta->extra_ie_len);
		memcpy(pos, ifsta->extra_ie, ifsta->extra_ie_len);
	}

715
	if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
716 717 718 719 720 721 722 723 724 725 726
		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;
	}
727

728
	/* wmm support is a must to HT */
729
	if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) &&
730 731
	    sband->ht_info.ht_supported &&
	    (ht_add_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_EXTRA_INFO))) {
732
		struct ieee80211_ht_addt_info *ht_add_info =
733
			(struct ieee80211_ht_addt_info *)ht_add_ie;
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753
		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);
754 755 756 757 758 759
		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);
760 761 762 763
		/* 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);
764
	}
765 766 767

	kfree(ifsta->assocreq_ies);
	ifsta->assocreq_ies_len = (skb->data + skb->len) - ies;
768
	ifsta->assocreq_ies = kmalloc(ifsta->assocreq_ies_len, GFP_KERNEL);
769 770 771
	if (ifsta->assocreq_ies)
		memcpy(ifsta->assocreq_ies, ies, ifsta->assocreq_ies_len);

772
	ieee80211_sta_tx(sdata, skb, 0);
773 774 775
}


776
static void ieee80211_send_deauth(struct ieee80211_sub_if_data *sdata,
777 778
				  struct ieee80211_if_sta *ifsta, u16 reason)
{
779
	struct ieee80211_local *local = sdata->local;
780 781 782 783 784 785
	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 "
786
		       "frame\n", sdata->dev->name);
787 788 789 790 791 792 793
		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);
794
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
795
	memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
796 797
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_DEAUTH);
798 799 800
	skb_put(skb, 2);
	mgmt->u.deauth.reason_code = cpu_to_le16(reason);

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


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

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

833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876
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;

	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;

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

	ieee80211_set_associated(sdata, ifsta, 0);

	if (self_disconnected)
		ifsta->state = IEEE80211_STA_MLME_DISABLED;

	sta_info_unlink(&sta);

	rcu_read_unlock();

	sta_info_destroy(sta);
}
877

878
static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata,
879 880
				      struct ieee80211_if_sta *ifsta)
{
881
	struct ieee80211_local *local = sdata->local;
882
	struct ieee80211_sta_bss *bss;
883 884 885
	int bss_privacy;
	int wep_privacy;
	int privacy_invoked;
886

887
	if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL))
888 889
		return 0;

890
	bss = ieee80211_rx_bss_get(local, ifsta->bssid,
891
				   local->hw.conf.channel->center_freq,
892
				   ifsta->ssid, ifsta->ssid_len);
893 894 895
	if (!bss)
		return 0;

896
	bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY);
897
	wep_privacy = !!ieee80211_sta_wep_configured(sdata);
898
	privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED);
899

900
	ieee80211_rx_bss_put(local, bss);
901

902 903 904 905
	if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked))
		return 0;

	return 1;
906 907 908
}


909
static void ieee80211_associate(struct ieee80211_sub_if_data *sdata,
910 911
				struct ieee80211_if_sta *ifsta)
{
912 913
	DECLARE_MAC_BUF(mac);

914 915
	ifsta->assoc_tries++;
	if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) {
916
		printk(KERN_DEBUG "%s: association with AP %s"
917
		       " timed out\n",
918
		       sdata->dev->name, print_mac(mac, ifsta->bssid));
919
		ifsta->state = IEEE80211_STA_MLME_DISABLED;
920 921 922
		return;
	}

923
	ifsta->state = IEEE80211_STA_MLME_ASSOCIATE;
924
	printk(KERN_DEBUG "%s: associate with AP %s\n",
925 926
	       sdata->dev->name, print_mac(mac, ifsta->bssid));
	if (ieee80211_privacy_mismatch(sdata, ifsta)) {
927
		printk(KERN_DEBUG "%s: mismatch in privacy configuration and "
928
		       "mixed-cell disabled - abort association\n", sdata->dev->name);
929
		ifsta->state = IEEE80211_STA_MLME_DISABLED;
930 931 932
		return;
	}

933
	ieee80211_send_assoc(sdata, ifsta);
934 935 936 937 938

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


939
static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
940 941
				 struct ieee80211_if_sta *ifsta)
{
942
	struct ieee80211_local *local = sdata->local;
943 944
	struct sta_info *sta;
	int disassoc;
945
	DECLARE_MAC_BUF(mac);
946 947 948 949 950 951

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

952
	ifsta->state = IEEE80211_STA_MLME_ASSOCIATED;
953

954 955
	rcu_read_lock();

956 957
	sta = sta_info_get(local, ifsta->bssid);
	if (!sta) {
958
		printk(KERN_DEBUG "%s: No STA entry for own AP %s\n",
959
		       sdata->dev->name, print_mac(mac, ifsta->bssid));
960 961 962 963 964
		disassoc = 1;
	} else {
		disassoc = 0;
		if (time_after(jiffies,
			       sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
965
			if (ifsta->flags & IEEE80211_STA_PROBEREQ_POLL) {
966
				printk(KERN_DEBUG "%s: No ProbeResp from "
967
				       "current AP %s - assume out of "
968
				       "range\n",
969
				       sdata->dev->name, print_mac(mac, ifsta->bssid));
970
				disassoc = 1;
971
			} else
972
				ieee80211_send_probe_req(sdata, ifsta->bssid,
973 974
							 local->scan_ssid,
							 local->scan_ssid_len);
975
			ifsta->flags ^= IEEE80211_STA_PROBEREQ_POLL;
976
		} else {
977
			ifsta->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
978 979 980
			if (time_after(jiffies, ifsta->last_probe +
				       IEEE80211_PROBE_INTERVAL)) {
				ifsta->last_probe = jiffies;
981
				ieee80211_send_probe_req(sdata, ifsta->bssid,
982 983 984 985 986
							 ifsta->ssid,
							 ifsta->ssid_len);
			}
		}
	}
987 988 989

	rcu_read_unlock();

990 991 992 993
	if (disassoc)
		ieee80211_set_disassoc(sdata, ifsta, true, true,
					WLAN_REASON_PREV_AUTH_NOT_VALID);
	else
994 995 996 997 998
		mod_timer(&ifsta->timer, jiffies +
				      IEEE80211_MONITORING_INTERVAL);
}


999
static void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1000 1001
				     u8 *ssid, size_t ssid_len)
{
1002
	struct ieee80211_local *local = sdata->local;
1003
	struct ieee80211_supported_band *sband;
1004 1005 1006 1007 1008 1009 1010 1011
	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 "
1012
		       "request\n", sdata->dev->name);
1013 1014 1015 1016 1017 1018
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
	memset(mgmt, 0, 24);
1019 1020
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_PROBE_REQ);
1021
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036
	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;
1037 1038 1039 1040
	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];
1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
		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]++;
		}
1053
		*pos = rate->bitrate / 5;
1054 1055
	}

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


1060
static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata)
1061 1062
{
	if (!sdata || !sdata->default_key ||
1063
	    sdata->default_key->conf.alg != ALG_WEP)
1064 1065 1066 1067 1068
		return 0;
	return 1;
}


1069
static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata,
1070 1071
				     struct ieee80211_if_sta *ifsta)
{
1072
	printk(KERN_DEBUG "%s: authenticated\n", sdata->dev->name);
1073
	ifsta->flags |= IEEE80211_STA_AUTHENTICATED;
1074
	ieee80211_associate(sdata, ifsta);
1075 1076 1077
}


1078
static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1079 1080 1081 1082 1083 1084 1085 1086
				     struct ieee80211_if_sta *ifsta,
				     struct ieee80211_mgmt *mgmt,
				     size_t len)
{
	u8 *pos;
	struct ieee802_11_elems elems;

	pos = mgmt->u.auth.variable;
1087
	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1088
	if (!elems.challenge)
1089
		return;
1090
	ieee80211_send_auth(sdata, ifsta, 3, elems.challenge - 2,
1091 1092 1093
			    elems.challenge_len + 2, 1);
}

1094
static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
1095 1096 1097 1098
					u8 dialog_token, u16 status, u16 policy,
					u16 buf_size, u16 timeout)
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
1099
	struct ieee80211_local *local = sdata->local;
1100 1101 1102 1103
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u16 capab;

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

1106 1107
	if (!skb) {
		printk(KERN_DEBUG "%s: failed to allocate buffer "
1108
		       "for addba resp frame\n", sdata->dev->name);
1109 1110 1111 1112 1113 1114 1115
		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);
1116
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1117
	if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
1118
		memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
1119 1120
	else
		memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1121 1122
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_ACTION);
1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136

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

1137
	ieee80211_sta_tx(sdata, skb, 0);
1138 1139 1140 1141

	return;
}

1142
void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, const u8 *da,
1143 1144 1145
				u16 tid, u8 dialog_token, u16 start_seq_num,
				u16 agg_size, u16 timeout)
{
1146
	struct ieee80211_local *local = sdata->local;
1147 1148 1149 1150 1151
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u16 capab;

E
Ester Kummer 已提交
1152
	skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1153 1154 1155

	if (!skb) {
		printk(KERN_ERR "%s: failed to allocate buffer "
1156
				"for addba request frame\n", sdata->dev->name);
1157 1158 1159 1160 1161 1162
		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);
1163
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1164
	if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
1165
		memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
1166 1167 1168
	else
		memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);

1169 1170
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_ACTION);
1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187

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

1188
	ieee80211_sta_tx(sdata, skb, 0);
1189 1190
}

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

1204 1205
	rcu_read_lock();

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

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

	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;

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

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


	/* examine state machine */
1252
	spin_lock_bh(&sta->lock);
1253

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

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

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

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

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

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

end_no_lock:
1326
	ieee80211_send_addba_resp(sta->sdata, sta->addr, tid,
1327 1328
				  dialog_token, status, 1, buf_size, timeout);
	rcu_read_unlock();
1329
}
1330

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

1341 1342
	rcu_read_lock();

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

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

1352
	state = &sta->ampdu_mlme.tid_state_tx[tid];
1353

1354
	spin_lock_bh(&sta->lock);
1355

1356
	if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1357
		spin_unlock_bh(&sta->lock);
1358 1359 1360
		goto addba_resp_exit;
	}

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

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

1379
		if (*state == HT_AGG_STATE_OPERATIONAL)
1380 1381
			ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);

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

addba_resp_exit:
1393
	rcu_read_unlock();
1394 1395
}

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

E
Ester Kummer 已提交
1405
	skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1406 1407 1408

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

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

1435
	ieee80211_sta_tx(sdata, skb, 0);
1436 1437
}

1438
void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
1439
{
1440
	struct ieee80211_local *local = sdata->local;
1441 1442 1443 1444 1445 1446 1447
	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 "
1448
			"bar frame\n", sdata->dev->name);
1449 1450 1451 1452 1453
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);
	bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
	memset(bar, 0, sizeof(*bar));
1454 1455
	bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
					 IEEE80211_STYPE_BACK_REQ);
1456
	memcpy(bar->ra, ra, ETH_ALEN);
1457
	memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN);
1458 1459 1460 1461 1462 1463
	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);

1464
	ieee80211_sta_tx(sdata, skb, 0);
1465 1466
}

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

1476 1477
	rcu_read_lock();

1478
	sta = sta_info_get(local, ra);
1479 1480
	if (!sta) {
		rcu_read_unlock();
1481
		return;
1482
	}
1483 1484

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

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

1501 1502 1503 1504 1505
#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 */

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

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

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

	/* free the reordering buffer */
1521 1522
	for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
		if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
1523
			/* release the reordered frames */
1524 1525 1526
			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;
1527 1528
		}
	}
1529 1530 1531 1532 1533
	/* 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;
1534

1535
	rcu_read_unlock();
1536 1537
}

1538

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

1548 1549
	rcu_read_lock();

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

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

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

1582 1583 1584 1585 1586 1587 1588 1589 1590
/*
 * 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 已提交
1591
	 * flow in sta_info_create gives the TID as data, while the timer_to_id
1592
	 * array gives the sta through container_of */
1593
	u16 tid = *(u8 *)data;
1594 1595 1596 1597 1598 1599 1600 1601
	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;

1602 1603
	rcu_read_lock();

1604
	sta = sta_info_get(local, temp_sta->addr);
1605 1606
	if (!sta) {
		rcu_read_unlock();
1607
		return;
1608
	}
1609

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

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

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

timer_expired_exit:
1634
	rcu_read_unlock();
1635 1636
}

1637
/*
1638 1639
 * After accepting the AddBA Request we activated a timer,
 * resetting it after each frame that arrives from the originator.
1640 1641
 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed.
 */
1642
static void sta_rx_agg_session_timer_expired(unsigned long data)
1643 1644
{
	/* not an elegant detour, but there is no choice as the timer passes
1645
	 * only one argument, and various sta_info are needed here, so init
J
Johannes Berg 已提交
1646
	 * flow in sta_info_create gives the TID as data, while the timer_to_id
1647 1648 1649 1650 1651 1652
	 * 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]);

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

1661
void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data *sdata, u8 *addr)
1662
{
1663
	struct ieee80211_local *local = sdata->local;
1664 1665 1666 1667 1668
	int i;

	for (i = 0; i <  STA_TID_NUM; i++) {
		ieee80211_stop_tx_ba_session(&local->hw, addr, i,
					     WLAN_BACK_INITIATOR);
1669
		ieee80211_sta_stop_rx_ba_session(sdata, addr, i,
1670 1671 1672 1673
						 WLAN_BACK_RECIPIENT,
						 WLAN_REASON_QSTA_LEAVE_QBSS);
	}
}
1674

1675
static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_data *sdata,
1676 1677 1678 1679
					struct ieee80211_msrment_ie *request_ie,
					const u8 *da, const u8 *bssid,
					u8 dialog_token)
{
1680
	struct ieee80211_local *local = sdata->local;
1681 1682 1683 1684 1685 1686 1687 1688
	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 "
1689
				"measurement report frame\n", sdata->dev->name);
1690 1691 1692 1693 1694 1695 1696
		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);
1697
	memcpy(msr_report->sa, sdata->dev->dev_addr, ETH_ALEN);
1698
	memcpy(msr_report->bssid, bssid, ETH_ALEN);
1699
	msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718
						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;

1719
	ieee80211_sta_tx(sdata, skb, 0);
1720 1721
}

1722
static void ieee80211_sta_process_measurement_req(struct ieee80211_sub_if_data *sdata,
1723 1724 1725 1726 1727 1728 1729 1730 1731 1732
						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
	 */
1733
	ieee80211_send_refuse_measurement_request(sdata,
1734 1735 1736 1737 1738 1739
			&mgmt->u.action.u.measurement.msr_elem,
			mgmt->sa, mgmt->bssid,
			mgmt->u.action.u.measurement.dialog_token);
}


1740
static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1741 1742 1743 1744 1745
				   struct ieee80211_if_sta *ifsta,
				   struct ieee80211_mgmt *mgmt,
				   size_t len)
{
	u16 auth_alg, auth_transaction, status_code;
1746
	DECLARE_MAC_BUF(mac);
1747

1748
	if (ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE &&
1749
	    sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
1750 1751
		return;

1752
	if (len < 24 + 6)
1753 1754
		return;

1755
	if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
1756
	    memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0)
1757 1758
		return;

1759
	if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
1760
	    memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0)
1761 1762 1763 1764 1765 1766
		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);

1767
	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
J
Johannes Berg 已提交
1768 1769
		/*
		 * IEEE 802.11 standard does not require authentication in IBSS
1770 1771 1772
		 * 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 已提交
1773
		 */
1774
		if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
1775
			return;
1776
		ieee80211_send_auth(sdata, ifsta, 2, NULL, 0, 0);
1777 1778 1779
	}

	if (auth_alg != ifsta->auth_alg ||
1780
	    auth_transaction != ifsta->auth_transaction)
1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808
		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 &&
1809
				    !ieee80211_sta_wep_configured(sdata))
1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820
					continue;
				ifsta->auth_alg = algs[pos];
				break;
			}
		}
		return;
	}

	switch (ifsta->auth_alg) {
	case WLAN_AUTH_OPEN:
	case WLAN_AUTH_LEAP:
1821
		ieee80211_auth_completed(sdata, ifsta);
1822 1823 1824
		break;
	case WLAN_AUTH_SHARED_KEY:
		if (ifsta->auth_transaction == 4)
1825
			ieee80211_auth_completed(sdata, ifsta);
1826
		else
1827
			ieee80211_auth_challenge(sdata, ifsta, mgmt, len);
1828 1829 1830 1831 1832
		break;
	}
}


1833
static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1834 1835 1836 1837 1838
				     struct ieee80211_if_sta *ifsta,
				     struct ieee80211_mgmt *mgmt,
				     size_t len)
{
	u16 reason_code;
1839
	DECLARE_MAC_BUF(mac);
1840

1841
	if (len < 24 + 2)
1842 1843
		return;

1844
	if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN))
1845 1846 1847 1848
		return;

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

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

1852 1853 1854
	if (ifsta->state == IEEE80211_STA_MLME_AUTHENTICATE ||
	    ifsta->state == IEEE80211_STA_MLME_ASSOCIATE ||
	    ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) {
1855
		ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
1856 1857 1858 1859
		mod_timer(&ifsta->timer, jiffies +
				      IEEE80211_RETRY_AUTH_INTERVAL);
	}

1860
	ieee80211_set_disassoc(sdata, ifsta, true, false, 0);
1861
	ifsta->flags &= ~IEEE80211_STA_AUTHENTICATED;
1862 1863 1864
}


1865
static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1866 1867 1868 1869 1870
				       struct ieee80211_if_sta *ifsta,
				       struct ieee80211_mgmt *mgmt,
				       size_t len)
{
	u16 reason_code;
1871
	DECLARE_MAC_BUF(mac);
1872

1873
	if (len < 24 + 2)
1874 1875
		return;

1876
	if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN))
1877 1878 1879 1880
		return;

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

1881
	if (ifsta->flags & IEEE80211_STA_ASSOCIATED)
1882
		printk(KERN_DEBUG "%s: disassociated\n", sdata->dev->name);
1883

1884 1885
	if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) {
		ifsta->state = IEEE80211_STA_MLME_ASSOCIATE;
1886 1887 1888 1889
		mod_timer(&ifsta->timer, jiffies +
				      IEEE80211_RETRY_AUTH_INTERVAL);
	}

1890
	ieee80211_set_disassoc(sdata, ifsta, false, false, 0);
1891 1892 1893
}


1894
static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1895 1896 1897 1898 1899
					 struct ieee80211_if_sta *ifsta,
					 struct ieee80211_mgmt *mgmt,
					 size_t len,
					 int reassoc)
{
1900
	struct ieee80211_local *local = sdata->local;
1901
	struct ieee80211_supported_band *sband;
1902
	struct sta_info *sta;
1903
	u64 rates, basic_rates;
1904 1905
	u16 capab_info, status_code, aid;
	struct ieee802_11_elems elems;
1906
	struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
1907 1908
	u8 *pos;
	int i, j;
1909
	DECLARE_MAC_BUF(mac);
1910
	bool have_higher_than_11mbit = false;
1911 1912 1913 1914

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

1915
	if (ifsta->state != IEEE80211_STA_MLME_ASSOCIATE)
1916 1917
		return;

1918
	if (len < 24 + 6)
1919 1920
		return;

1921
	if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0)
1922 1923 1924 1925 1926 1927
		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);

1928
	printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x "
1929
	       "status=%d aid=%d)\n",
1930
	       sdata->dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa),
1931
	       capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
1932 1933 1934

	if (status_code != WLAN_STATUS_SUCCESS) {
		printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
1935
		       sdata->dev->name, status_code);
1936 1937 1938
		/* 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. */
1939
		ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
1940 1941 1942
		return;
	}

1943 1944
	if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
		printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
1945
		       "set\n", sdata->dev->name, aid);
1946 1947
	aid &= ~(BIT(15) | BIT(14));

1948
	pos = mgmt->u.assoc_resp.variable;
1949
	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1950 1951 1952

	if (!elems.supp_rates) {
		printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
1953
		       sdata->dev->name);
1954 1955 1956
		return;
	}

1957
	printk(KERN_DEBUG "%s: associated\n", sdata->dev->name);
1958 1959 1960 1961 1962
	ifsta->aid = aid;
	ifsta->ap_capab = capab_info;

	kfree(ifsta->assocresp_ies);
	ifsta->assocresp_ies_len = len - (pos - (u8 *) mgmt);
1963
	ifsta->assocresp_ies = kmalloc(ifsta->assocresp_ies_len, GFP_KERNEL);
1964 1965 1966
	if (ifsta->assocresp_ies)
		memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len);

1967 1968
	rcu_read_lock();

1969 1970 1971 1972
	/* Add STA entry for the AP */
	sta = sta_info_get(local, ifsta->bssid);
	if (!sta) {
		struct ieee80211_sta_bss *bss;
J
Johannes Berg 已提交
1973
		int err;
1974

J
Johannes Berg 已提交
1975 1976 1977
		sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC);
		if (!sta) {
			printk(KERN_DEBUG "%s: failed to alloc STA entry for"
1978
			       " the AP\n", sdata->dev->name);
1979
			rcu_read_unlock();
1980 1981
			return;
		}
1982
		bss = ieee80211_rx_bss_get(local, ifsta->bssid,
1983
					   local->hw.conf.channel->center_freq,
1984
					   ifsta->ssid, ifsta->ssid_len);
1985 1986
		if (bss) {
			sta->last_signal = bss->signal;
1987
			sta->last_qual = bss->qual;
1988
			sta->last_noise = bss->noise;
1989
			ieee80211_rx_bss_put(local, bss);
1990
		}
J
Johannes Berg 已提交
1991 1992 1993 1994

		err = sta_info_insert(sta);
		if (err) {
			printk(KERN_DEBUG "%s: failed to insert STA entry for"
1995
			       " the AP (error %d)\n", sdata->dev->name, err);
J
Johannes Berg 已提交
1996 1997 1998
			rcu_read_unlock();
			return;
		}
1999 2000
		/* update new sta with its last rx activity */
		sta->last_rx = jiffies;
2001 2002
	}

J
Johannes Berg 已提交
2003 2004 2005 2006 2007 2008 2009 2010 2011 2012
	/*
	 * 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.
	 */

2013 2014
	set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP |
			   WLAN_STA_AUTHORIZED);
2015 2016

	rates = 0;
2017 2018 2019
	basic_rates = 0;
	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];

2020 2021
	for (i = 0; i < elems.supp_rates_len; i++) {
		int rate = (elems.supp_rates[i] & 0x7f) * 5;
2022 2023 2024 2025 2026 2027

		if (rate > 110)
			have_higher_than_11mbit = true;

		for (j = 0; j < sband->n_bitrates; j++) {
			if (sband->bitrates[j].bitrate == rate)
2028
				rates |= BIT(j);
2029 2030 2031
			if (elems.supp_rates[i] & 0x80)
				basic_rates |= BIT(j);
		}
2032
	}
2033

2034 2035
	for (i = 0; i < elems.ext_supp_rates_len; i++) {
		int rate = (elems.ext_supp_rates[i] & 0x7f) * 5;
2036 2037 2038 2039 2040 2041

		if (rate > 110)
			have_higher_than_11mbit = true;

		for (j = 0; j < sband->n_bitrates; j++) {
			if (sband->bitrates[j].bitrate == rate)
2042
				rates |= BIT(j);
2043 2044 2045
			if (elems.ext_supp_rates[i] & 0x80)
				basic_rates |= BIT(j);
		}
2046
	}
2047 2048 2049 2050 2051 2052 2053 2054 2055 2056

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

2058 2059
	if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param &&
	    (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
2060 2061 2062 2063 2064 2065 2066
		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);
T
Tomas Winkler 已提交
2067
		ieee80211_handle_ht(local, 1, &sta->ht_info, &bss_info);
2068 2069
	}

2070 2071
	rate_control_rate_init(sta, local);

2072
	if (elems.wmm_param) {
2073
		set_sta_flags(sta, WLAN_STA_WME);
2074
		rcu_read_unlock();
2075
		ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
2076
					 elems.wmm_param_len);
2077 2078
	} else
		rcu_read_unlock();
2079

2080 2081
	/* set AID and assoc capability,
	 * ieee80211_set_associated() will tell the driver */
2082
	bss_conf->aid = aid;
2083
	bss_conf->assoc_capability = capab_info;
2084
	ieee80211_set_associated(sdata, ifsta, 1);
2085

2086
	ieee80211_associated(sdata, ifsta);
2087 2088 2089 2090
}


/* Caller must hold local->sta_bss_lock */
2091
static void __ieee80211_rx_bss_hash_add(struct ieee80211_local *local,
2092 2093
					struct ieee80211_sta_bss *bss)
{
2094
	u8 hash_idx;
J
Johannes Berg 已提交
2095 2096 2097 2098

	if (bss_mesh_cfg(bss))
		hash_idx = mesh_id_hash(bss_mesh_id(bss),
					bss_mesh_id_len(bss));
2099 2100
	else
		hash_idx = STA_HASH(bss->bssid);
J
Johannes Berg 已提交
2101

2102 2103
	bss->hnext = local->sta_bss_hash[hash_idx];
	local->sta_bss_hash[hash_idx] = bss;
2104 2105 2106 2107
}


/* Caller must hold local->sta_bss_lock */
2108
static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local,
2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128
					struct ieee80211_sta_bss *bss)
{
	struct ieee80211_sta_bss *b, *prev = NULL;
	b = local->sta_bss_hash[STA_HASH(bss->bssid)];
	while (b) {
		if (b == bss) {
			if (!prev)
				local->sta_bss_hash[STA_HASH(bss->bssid)] =
					bss->hnext;
			else
				prev->hnext = bss->hnext;
			break;
		}
		prev = b;
		b = b->hnext;
	}
}


static struct ieee80211_sta_bss *
2129
ieee80211_rx_bss_add(struct ieee80211_sub_if_data *sdata, u8 *bssid, int freq,
2130
		     u8 *ssid, u8 ssid_len)
2131
{
2132
	struct ieee80211_local *local = sdata->local;
2133 2134
	struct ieee80211_sta_bss *bss;

2135
	bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
2136 2137 2138 2139 2140
	if (!bss)
		return NULL;
	atomic_inc(&bss->users);
	atomic_inc(&bss->users);
	memcpy(bss->bssid, bssid, ETH_ALEN);
2141
	bss->freq = freq;
2142 2143 2144 2145
	if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
		memcpy(bss->ssid, ssid, ssid_len);
		bss->ssid_len = ssid_len;
	}
2146 2147 2148 2149

	spin_lock_bh(&local->sta_bss_lock);
	/* TODO: order by RSSI? */
	list_add_tail(&bss->list, &local->sta_bss_list);
2150
	__ieee80211_rx_bss_hash_add(local, bss);
2151 2152 2153 2154 2155
	spin_unlock_bh(&local->sta_bss_lock);
	return bss;
}

static struct ieee80211_sta_bss *
2156
ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
2157
		     u8 *ssid, u8 ssid_len)
2158 2159 2160 2161 2162 2163
{
	struct ieee80211_sta_bss *bss;

	spin_lock_bh(&local->sta_bss_lock);
	bss = local->sta_bss_hash[STA_HASH(bssid)];
	while (bss) {
J
Johannes Berg 已提交
2164 2165
		if (!bss_mesh_cfg(bss) &&
		    !memcmp(bss->bssid, bssid, ETH_ALEN) &&
2166
		    bss->freq == freq &&
2167 2168
		    bss->ssid_len == ssid_len &&
		    (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
2169 2170 2171 2172 2173 2174 2175 2176 2177
			atomic_inc(&bss->users);
			break;
		}
		bss = bss->hnext;
	}
	spin_unlock_bh(&local->sta_bss_lock);
	return bss;
}

2178 2179
#ifdef CONFIG_MAC80211_MESH
static struct ieee80211_sta_bss *
2180
ieee80211_rx_mesh_bss_get(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
2181 2182 2183 2184 2185 2186 2187
			  u8 *mesh_cfg, int freq)
{
	struct ieee80211_sta_bss *bss;

	spin_lock_bh(&local->sta_bss_lock);
	bss = local->sta_bss_hash[mesh_id_hash(mesh_id, mesh_id_len)];
	while (bss) {
J
Johannes Berg 已提交
2188 2189
		if (bss_mesh_cfg(bss) &&
		    !memcmp(bss_mesh_cfg(bss), mesh_cfg, MESH_CFG_CMP_LEN) &&
2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203
		    bss->freq == freq &&
		    mesh_id_len == bss->mesh_id_len &&
		    (mesh_id_len == 0 || !memcmp(bss->mesh_id, mesh_id,
						 mesh_id_len))) {
			atomic_inc(&bss->users);
			break;
		}
		bss = bss->hnext;
	}
	spin_unlock_bh(&local->sta_bss_lock);
	return bss;
}

static struct ieee80211_sta_bss *
2204
ieee80211_rx_mesh_bss_add(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
2205
			  u8 *mesh_cfg, int mesh_config_len, int freq)
2206 2207 2208
{
	struct ieee80211_sta_bss *bss;

2209 2210 2211
	if (mesh_config_len != MESH_CFG_LEN)
		return NULL;

2212 2213 2214 2215
	bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
	if (!bss)
		return NULL;

2216
	bss->mesh_cfg = kmalloc(MESH_CFG_CMP_LEN, GFP_ATOMIC);
2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233
	if (!bss->mesh_cfg) {
		kfree(bss);
		return NULL;
	}

	if (mesh_id_len && mesh_id_len <= IEEE80211_MAX_MESH_ID_LEN) {
		bss->mesh_id = kmalloc(mesh_id_len, GFP_ATOMIC);
		if (!bss->mesh_id) {
			kfree(bss->mesh_cfg);
			kfree(bss);
			return NULL;
		}
		memcpy(bss->mesh_id, mesh_id, mesh_id_len);
	}

	atomic_inc(&bss->users);
	atomic_inc(&bss->users);
2234
	memcpy(bss->mesh_cfg, mesh_cfg, MESH_CFG_CMP_LEN);
2235 2236 2237 2238 2239
	bss->mesh_id_len = mesh_id_len;
	bss->freq = freq;
	spin_lock_bh(&local->sta_bss_lock);
	/* TODO: order by RSSI? */
	list_add_tail(&bss->list, &local->sta_bss_list);
2240
	__ieee80211_rx_bss_hash_add(local, bss);
2241 2242 2243 2244
	spin_unlock_bh(&local->sta_bss_lock);
	return bss;
}
#endif
2245 2246 2247

static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss)
{
2248
	kfree(bss->ies);
J
Johannes Berg 已提交
2249 2250
	kfree(bss_mesh_id(bss));
	kfree(bss_mesh_cfg(bss));
2251 2252 2253 2254
	kfree(bss);
}


2255
static void ieee80211_rx_bss_put(struct ieee80211_local *local,
2256 2257
				 struct ieee80211_sta_bss *bss)
{
2258 2259 2260
	local_bh_disable();
	if (!atomic_dec_and_lock(&bss->users, &local->sta_bss_lock)) {
		local_bh_enable();
2261
		return;
2262
	}
2263

2264
	__ieee80211_rx_bss_hash_del(local, bss);
2265 2266 2267 2268 2269 2270
	list_del(&bss->list);
	spin_unlock_bh(&local->sta_bss_lock);
	ieee80211_rx_bss_free(bss);
}


2271
void ieee80211_rx_bss_list_init(struct ieee80211_local *local)
2272 2273 2274 2275 2276 2277
{
	spin_lock_init(&local->sta_bss_lock);
	INIT_LIST_HEAD(&local->sta_bss_list);
}


2278
void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local)
2279 2280 2281 2282
{
	struct ieee80211_sta_bss *bss, *tmp;

	list_for_each_entry_safe(bss, tmp, &local->sta_bss_list, list)
2283
		ieee80211_rx_bss_put(local, bss);
2284 2285 2286
}


2287
static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
2288 2289 2290
				   struct ieee80211_if_sta *ifsta,
				   struct ieee80211_sta_bss *bss)
{
2291
	struct ieee80211_local *local = sdata->local;
2292 2293 2294 2295 2296
	int res, rates, i, j;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u8 *pos;
	struct ieee80211_supported_band *sband;
2297
	union iwreq_data wrqu;
2298 2299 2300 2301

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

	/* Remove possible STA entries from other IBSS networks. */
J
Johannes Berg 已提交
2302
	sta_info_flush_delayed(sdata);
2303 2304 2305 2306 2307 2308

	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);
2309
	res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
2310 2311 2312 2313 2314 2315 2316 2317
	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;

2318
	res = ieee80211_set_freq(sdata, bss->freq);
2319

2320 2321
	if (res)
		return res;
2322

2323
	/* Build IBSS probe response */
2324
	skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
2325
	if (skb) {
2326 2327 2328 2329 2330
		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));
2331 2332
		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_PROBE_RESP);
2333
		memset(mgmt->da, 0xff, ETH_ALEN);
2334
		memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
2335 2336 2337
		memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
		mgmt->u.beacon.beacon_int =
			cpu_to_le16(local->hw.conf.beacon_int);
2338
		mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp);
2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375
		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);
		}

2376
		ifsta->probe_resp = skb;
2377

2378 2379
		ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
	}
2380

2381 2382 2383 2384 2385 2386 2387
	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);
2388
	}
2389 2390
	ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;

2391
	ieee80211_sta_def_wmm_params(sdata, bss, 1);
2392

2393
	ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED;
2394 2395
	mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);

2396 2397
	memset(&wrqu, 0, sizeof(wrqu));
	memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN);
2398
	wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
2399 2400 2401 2402

	return res;
}

2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438
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;
}

2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465
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;
}
2466

2467
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2468 2469 2470
				  struct ieee80211_mgmt *mgmt,
				  size_t len,
				  struct ieee80211_rx_status *rx_status,
2471
				  struct ieee802_11_elems *elems)
2472
{
2473
	struct ieee80211_local *local = sdata->local;
2474
	int freq, clen;
2475 2476
	struct ieee80211_sta_bss *bss;
	struct sta_info *sta;
2477
	struct ieee80211_channel *channel;
2478 2479
	u64 beacon_timestamp, rx_timestamp;
	u64 supp_rates = 0;
2480
	bool beacon = ieee80211_is_beacon(mgmt->frame_control);
2481
	enum ieee80211_band band = rx_status->band;
2482 2483
	DECLARE_MAC_BUF(mac);
	DECLARE_MAC_BUF(mac2);
2484

2485 2486 2487 2488 2489 2490 2491 2492 2493
	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;
2494

2495
	if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id &&
2496
	    elems->mesh_config && mesh_matches_local(elems, sdata)) {
2497
		supp_rates = ieee80211_sta_get_rates(local, elems, band);
J
Johannes Berg 已提交
2498

2499
		mesh_neighbour_update(mgmt->sa, supp_rates, sdata,
2500
				      mesh_peer_accepts_plinks(elems));
J
Johannes Berg 已提交
2501
	}
2502

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

2507 2508
		rcu_read_lock();

2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530
		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);
2531 2532
		}

2533 2534
		rcu_read_unlock();
	}
2535

2536
#ifdef CONFIG_MAC80211_MESH
2537
	if (elems->mesh_config)
2538
		bss = ieee80211_rx_mesh_bss_get(local, elems->mesh_id,
2539
				elems->mesh_id_len, elems->mesh_config, freq);
2540 2541
	else
#endif
2542
		bss = ieee80211_rx_bss_get(local, mgmt->bssid, freq,
2543
					   elems->ssid, elems->ssid_len);
2544 2545
	if (!bss) {
#ifdef CONFIG_MAC80211_MESH
2546
		if (elems->mesh_config)
2547
			bss = ieee80211_rx_mesh_bss_add(local, elems->mesh_id,
2548 2549
				elems->mesh_id_len, elems->mesh_config,
				elems->mesh_config_len, freq);
2550 2551
		else
#endif
2552
			bss = ieee80211_rx_bss_add(sdata, mgmt->bssid, freq,
2553
						  elems->ssid, elems->ssid_len);
2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564
		if (!bss)
			return;
	} else {
#if 0
		/* TODO: order by RSSI? */
		spin_lock_bh(&local->sta_bss_lock);
		list_move_tail(&bss->list, &local->sta_bss_list);
		spin_unlock_bh(&local->sta_bss_lock);
#endif
	}

2565
	/* save the ERP value so that it is available at association time */
2566 2567
	if (elems->erp_info && elems->erp_info_len >= 1) {
		bss->erp_value = elems->erp_info[0];
2568 2569 2570
		bss->has_erp_value = 1;
	}

2571 2572 2573
	bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
	bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);

2574 2575 2576 2577 2578 2579 2580 2581 2582 2583
	if (elems->tim) {
		struct ieee80211_tim_ie *tim_ie =
			(struct ieee80211_tim_ie *)elems->tim;
		bss->dtim_period = tim_ie->dtim_period;
	}

	/* set default value for buggy APs */
	if (!elems->tim || bss->dtim_period == 0)
		bss->dtim_period = 1;

2584
	bss->supp_rates_len = 0;
2585
	if (elems->supp_rates) {
2586
		clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
2587 2588 2589
		if (clen > elems->supp_rates_len)
			clen = elems->supp_rates_len;
		memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates,
2590 2591 2592
		       clen);
		bss->supp_rates_len += clen;
	}
2593
	if (elems->ext_supp_rates) {
2594
		clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
2595 2596
		if (clen > elems->ext_supp_rates_len)
			clen = elems->ext_supp_rates_len;
2597
		memcpy(&bss->supp_rates[bss->supp_rates_len],
2598
		       elems->ext_supp_rates, clen);
2599 2600 2601
		bss->supp_rates_len += clen;
	}

2602
	bss->band = band;
2603

2604 2605
	beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);

2606 2607 2608 2609
	bss->timestamp = beacon_timestamp;
	bss->last_update = jiffies;
	bss->signal = rx_status->signal;
	bss->noise = rx_status->noise;
2610
	bss->qual = rx_status->qual;
2611 2612
	if (!beacon)
		bss->last_probe_resp = jiffies;
2613 2614 2615 2616 2617
	/*
	 * 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 &&
2618
	    bss->last_probe_resp && beacon) {
2619
		ieee80211_rx_bss_put(local, bss);
2620 2621 2622
		return;
	}

2623 2624 2625
	if (bss->ies == NULL || bss->ies_len < elems->total_len) {
		kfree(bss->ies);
		bss->ies = kmalloc(elems->total_len, GFP_ATOMIC);
2626
	}
2627 2628 2629 2630 2631
	if (bss->ies) {
		memcpy(bss->ies, elems->ie_start, elems->total_len);
		bss->ies_len = elems->total_len;
	} else
		bss->ies_len = 0;
2632

2633
	bss->wmm_used = elems->wmm_param || elems->wmm_info;
B
Bruno Randolf 已提交
2634 2635 2636 2637

	/* check if we need to merge IBSS */
	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
	    !local->sta_sw_scanning && !local->sta_hw_scanning &&
J
Johannes Berg 已提交
2638
	    bss->capability & WLAN_CAPABILITY_IBSS &&
B
Bruno Randolf 已提交
2639
	    bss->freq == local->oper_channel->center_freq &&
2640 2641 2642
	    elems->ssid_len == sdata->u.sta.ssid_len &&
	    memcmp(elems->ssid, sdata->u.sta.ssid,
				sdata->u.sta.ssid_len) == 0) {
B
Bruno Randolf 已提交
2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658
		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.
			 */
2659
			int rate = local->hw.wiphy->bands[band]->
B
Bruno Randolf 已提交
2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678
					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) {
2679
#ifdef CONFIG_MAC80211_IBSS_DEBUG
2680 2681
			printk(KERN_DEBUG "%s: beacon TSF higher than "
			       "local TSF - IBSS merge with BSSID %s\n",
2682
			       sdata->dev->name, print_mac(mac, mgmt->bssid));
J
Johannes Berg 已提交
2683
#endif
2684 2685
			ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss);
			ieee80211_ibss_add_sta(sdata, NULL,
2686
					       mgmt->bssid, mgmt->sa,
2687
					       supp_rates);
B
Bruno Randolf 已提交
2688 2689 2690
		}
	}

2691
	ieee80211_rx_bss_put(local, bss);
2692 2693 2694
}


2695
static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
2696 2697 2698 2699
					 struct ieee80211_mgmt *mgmt,
					 size_t len,
					 struct ieee80211_rx_status *rx_status)
{
2700 2701
	size_t baselen;
	struct ieee802_11_elems elems;
2702
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
2703

2704 2705 2706
	if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
		return; /* ignore ProbeResp to foreign address */

2707 2708 2709 2710 2711 2712 2713
	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);

2714 2715 2716 2717 2718 2719 2720 2721 2722
	ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);

	/* 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);
	}
2723 2724 2725
}


2726
static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2727 2728 2729 2730 2731 2732 2733
				     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;
2734
	struct ieee80211_local *local = sdata->local;
2735
	struct ieee80211_conf *conf = &local->hw.conf;
2736
	u32 changed = 0;
2737

2738 2739 2740 2741 2742 2743 2744
	/* 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);

2745
	ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
2746

2747
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
2748 2749 2750
		return;
	ifsta = &sdata->u.sta;

2751
	if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED) ||
2752 2753 2754
	    memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0)
		return;

2755
	/* Do not send changes to driver if we are scanning. This removes
2756 2757 2758 2759 2760
	 * requirement that a driver's bss_info_changed/conf_tx functions
	 * need to be atomic.
	 * This is really ugly code, we should rewrite scanning and make
	 * all this more understandable for humans.
	 */
2761 2762 2763
	if (local->sta_sw_scanning || local->sta_hw_scanning)
		return;

2764 2765 2766
	ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
				 elems.wmm_param_len);

2767
	if (elems.erp_info && elems.erp_info_len >= 1)
2768
		changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]);
2769 2770 2771 2772 2773
	else {
		u16 capab = le16_to_cpu(mgmt->u.beacon.capab_info);
		changed |= ieee80211_handle_protect_preamb(sdata, false,
				(capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);
	}
2774

2775
	if (elems.ht_cap_elem && elems.ht_info_elem &&
T
Tomas Winkler 已提交
2776
	    elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
2777 2778 2779 2780 2781
		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 已提交
2782 2783
		changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf,
					       &bss_info);
2784 2785
	}

2786
	ieee80211_bss_info_change_notify(sdata, changed);
2787 2788 2789
}


2790
static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
2791 2792 2793 2794 2795
					struct ieee80211_if_sta *ifsta,
					struct ieee80211_mgmt *mgmt,
					size_t len,
					struct ieee80211_rx_status *rx_status)
{
2796
	struct ieee80211_local *local = sdata->local;
2797 2798 2799 2800
	int tx_last_beacon;
	struct sk_buff *skb;
	struct ieee80211_mgmt *resp;
	u8 *pos, *end;
2801 2802 2803 2804 2805
	DECLARE_MAC_BUF(mac);
#ifdef CONFIG_MAC80211_IBSS_DEBUG
	DECLARE_MAC_BUF(mac2);
	DECLARE_MAC_BUF(mac3);
#endif
2806

2807
	if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS ||
2808
	    ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED ||
2809 2810 2811 2812 2813 2814 2815 2816 2817
	    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
2818 2819
	printk(KERN_DEBUG "%s: RX ProbeReq SA=%s DA=%s BSSID="
	       "%s (tx_last_beacon=%d)\n",
2820
	       sdata->dev->name, print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da),
2821
	       print_mac(mac3, mgmt->bssid), tx_last_beacon);
2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834
#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) {
2835 2836 2837
#ifdef CONFIG_MAC80211_IBSS_DEBUG
		printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq "
		       "from %s\n",
2838
		       sdata->dev->name, print_mac(mac, mgmt->sa));
2839
#endif
2840 2841 2842 2843 2844 2845 2846 2847 2848 2849
		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 */
2850
	skb = skb_copy(ifsta->probe_resp, GFP_KERNEL);
2851 2852 2853 2854 2855 2856
	if (!skb)
		return;

	resp = (struct ieee80211_mgmt *) skb->data;
	memcpy(resp->da, mgmt->sa, ETH_ALEN);
#ifdef CONFIG_MAC80211_IBSS_DEBUG
2857
	printk(KERN_DEBUG "%s: Sending ProbeResp to %s\n",
2858
	       sdata->dev->name, print_mac(mac, resp->da));
2859
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2860
	ieee80211_sta_tx(sdata, skb, 0);
2861 2862
}

2863
static void ieee80211_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
2864 2865
				     struct ieee80211_if_sta *ifsta,
				     struct ieee80211_mgmt *mgmt,
2866 2867
				     size_t len,
				     struct ieee80211_rx_status *rx_status)
2868
{
2869
	struct ieee80211_local *local = sdata->local;
2870

2871 2872
	/* all categories we currently handle have action_code */
	if (len < IEEE80211_MIN_ACTION_SIZE + 1)
2873 2874 2875
		return;

	switch (mgmt->u.action.category) {
2876 2877 2878
	case WLAN_CATEGORY_SPECTRUM_MGMT:
		if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ)
			break;
2879
		switch (mgmt->u.action.u.measurement.action_code) {
2880 2881 2882 2883
		case WLAN_ACTION_SPCT_MSR_REQ:
			if (len < (IEEE80211_MIN_ACTION_SIZE +
				   sizeof(mgmt->u.action.u.measurement)))
				break;
2884
			ieee80211_sta_process_measurement_req(sdata, mgmt, len);
2885 2886 2887
			break;
		}
		break;
2888 2889 2890 2891 2892 2893
	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;
2894
			ieee80211_sta_process_addba_request(local, mgmt, len);
2895
			break;
2896 2897 2898 2899
		case WLAN_ACTION_ADDBA_RESP:
			if (len < (IEEE80211_MIN_ACTION_SIZE +
				   sizeof(mgmt->u.action.u.addba_resp)))
				break;
2900
			ieee80211_sta_process_addba_resp(local, mgmt, len);
2901
			break;
2902 2903 2904 2905
		case WLAN_ACTION_DELBA:
			if (len < (IEEE80211_MIN_ACTION_SIZE +
				   sizeof(mgmt->u.action.u.delba)))
				break;
2906
			ieee80211_sta_process_delba(sdata, mgmt, len);
2907
			break;
2908 2909
		}
		break;
2910
	case PLINK_CATEGORY:
J
Johannes Berg 已提交
2911
		if (ieee80211_vif_is_mesh(&sdata->vif))
2912
			mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
2913 2914
		break;
	case MESH_PATH_SEL_CATEGORY:
J
Johannes Berg 已提交
2915
		if (ieee80211_vif_is_mesh(&sdata->vif))
2916
			mesh_rx_path_sel_frame(sdata, mgmt, len);
2917
		break;
2918 2919
	}
}
2920

2921
void ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
2922 2923
			   struct ieee80211_rx_status *rx_status)
{
2924
	struct ieee80211_local *local = sdata->local;
2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940
	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:
2941
	case IEEE80211_STYPE_ACTION:
2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956
		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);
}

2957
static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972
					 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:
2973
		ieee80211_rx_mgmt_probe_req(sdata, ifsta, mgmt, skb->len,
2974 2975 2976
					    rx_status);
		break;
	case IEEE80211_STYPE_PROBE_RESP:
2977
		ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, rx_status);
2978 2979
		break;
	case IEEE80211_STYPE_BEACON:
2980
		ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
2981 2982
		break;
	case IEEE80211_STYPE_AUTH:
2983
		ieee80211_rx_mgmt_auth(sdata, ifsta, mgmt, skb->len);
2984 2985
		break;
	case IEEE80211_STYPE_ASSOC_RESP:
2986
		ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 0);
2987 2988
		break;
	case IEEE80211_STYPE_REASSOC_RESP:
2989
		ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 1);
2990 2991
		break;
	case IEEE80211_STYPE_DEAUTH:
2992
		ieee80211_rx_mgmt_deauth(sdata, ifsta, mgmt, skb->len);
2993 2994
		break;
	case IEEE80211_STYPE_DISASSOC:
2995
		ieee80211_rx_mgmt_disassoc(sdata, ifsta, mgmt, skb->len);
2996
		break;
2997
	case IEEE80211_STYPE_ACTION:
2998
		ieee80211_rx_mgmt_action(sdata, ifsta, mgmt, skb->len, rx_status);
2999
		break;
3000 3001 3002 3003 3004 3005
	}

	kfree_skb(skb);
}


3006
ieee80211_rx_result
3007
ieee80211_sta_rx_scan(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
Z
Zhu Yi 已提交
3008
		      struct ieee80211_rx_status *rx_status)
3009 3010
{
	struct ieee80211_mgmt *mgmt;
3011
	__le16 fc;
3012

Z
Zhu Yi 已提交
3013
	if (skb->len < 2)
J
Johannes Berg 已提交
3014
		return RX_DROP_UNUSABLE;
3015 3016

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

3019
	if (ieee80211_is_ctl(fc))
3020
		return RX_CONTINUE;
Z
Zhu Yi 已提交
3021 3022

	if (skb->len < 24)
J
Johannes Berg 已提交
3023
		return RX_DROP_MONITOR;
Z
Zhu Yi 已提交
3024

3025
	if (ieee80211_is_probe_resp(fc)) {
3026
		ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, rx_status);
3027 3028
		dev_kfree_skb(skb);
		return RX_QUEUED;
3029
	}
3030 3031

	if (ieee80211_is_beacon(fc)) {
3032
		ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
3033 3034 3035 3036
		dev_kfree_skb(skb);
		return RX_QUEUED;
	}

3037
	return RX_CONTINUE;
3038 3039 3040
}


3041
static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
3042
{
3043
	struct ieee80211_local *local = sdata->local;
3044 3045 3046
	int active = 0;
	struct sta_info *sta;

3047 3048 3049 3050
	rcu_read_lock();

	list_for_each_entry_rcu(sta, &local->sta_list, list) {
		if (sta->sdata == sdata &&
3051 3052 3053 3054 3055 3056
		    time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL,
			       jiffies)) {
			active++;
			break;
		}
	}
3057 3058

	rcu_read_unlock();
3059 3060 3061 3062 3063

	return active;
}


3064
static void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, unsigned long exp_time)
3065
{
3066
	struct ieee80211_local *local = sdata->local;
3067
	struct sta_info *sta, *tmp;
3068
	LIST_HEAD(tmp_list);
3069
	DECLARE_MAC_BUF(mac);
3070
	unsigned long flags;
3071

3072
	spin_lock_irqsave(&local->sta_lock, flags);
3073
	list_for_each_entry_safe(sta, tmp, &local->sta_list, list)
3074
		if (time_after(jiffies, sta->last_rx + exp_time)) {
3075
#ifdef CONFIG_MAC80211_IBSS_DEBUG
3076
			printk(KERN_DEBUG "%s: expiring inactive STA %s\n",
3077
			       sdata->dev->name, print_mac(mac, sta->addr));
3078
#endif
3079
			__sta_info_unlink(&sta);
3080 3081
			if (sta)
				list_add(&sta->list, &tmp_list);
3082
		}
3083
	spin_unlock_irqrestore(&local->sta_lock, flags);
3084

3085 3086
	list_for_each_entry_safe(sta, tmp, &tmp_list, list)
		sta_info_destroy(sta);
3087 3088 3089
}


3090
static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata,
3091 3092 3093 3094
				     struct ieee80211_if_sta *ifsta)
{
	mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);

3095 3096
	ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT);
	if (ieee80211_sta_active_ibss(sdata))
3097 3098 3099
		return;

	printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
3100 3101
	       "IBSS networks with same SSID (merge)\n", sdata->dev->name);
	ieee80211_sta_req_scan(sdata, ifsta->ssid, ifsta->ssid_len);
3102 3103 3104
}


3105
#ifdef CONFIG_MAC80211_MESH
3106
static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
3107 3108 3109 3110
			   struct ieee80211_if_sta *ifsta)
{
	bool free_plinks;

3111 3112
	ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
	mesh_path_expire(sdata);
3113 3114 3115

	free_plinks = mesh_plink_availables(sdata);
	if (free_plinks != sdata->u.sta.accepting_plinks)
3116
		ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
3117 3118 3119 3120 3121 3122

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


3123
void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
3124 3125 3126
{
	struct ieee80211_if_sta *ifsta;
	ifsta = &sdata->u.sta;
3127
	ifsta->state = IEEE80211_STA_MLME_MESH_UP;
3128
	ieee80211_sta_timer((unsigned long)sdata);
L
Luis Carlos Cobo 已提交
3129
	ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
3130 3131 3132 3133
}
#endif


3134 3135 3136 3137 3138
void ieee80211_sta_timer(unsigned long data)
{
	struct ieee80211_sub_if_data *sdata =
		(struct ieee80211_sub_if_data *) data;
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
3139
	struct ieee80211_local *local = sdata->local;
3140 3141 3142 3143 3144 3145 3146 3147 3148

	set_bit(IEEE80211_STA_REQ_RUN, &ifsta->request);
	queue_work(local->hw.workqueue, &ifsta->work);
}

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);
3149
	struct ieee80211_local *local = sdata->local;
3150 3151 3152
	struct ieee80211_if_sta *ifsta;
	struct sk_buff *skb;

3153
	if (!netif_running(sdata->dev))
3154 3155
		return;

Z
Zhu Yi 已提交
3156
	if (local->sta_sw_scanning || local->sta_hw_scanning)
3157 3158
		return;

3159 3160 3161
	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))
3162 3163 3164 3165
		return;
	ifsta = &sdata->u.sta;

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

3168
#ifdef CONFIG_MAC80211_MESH
J
Johannes Berg 已提交
3169 3170 3171
	if (ifsta->preq_queue_len &&
	    time_after(jiffies,
		       ifsta->last_preq + msecs_to_jiffies(ifsta->mshcfg.dot11MeshHWMPpreqMinInterval)))
3172
		mesh_path_start_discovery(sdata);
3173 3174
#endif

3175 3176
	if (ifsta->state != IEEE80211_STA_MLME_DIRECT_PROBE &&
	    ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE &&
3177
	    ifsta->state != IEEE80211_STA_MLME_ASSOCIATE &&
3178
	    test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) {
3179
		if (ifsta->scan_ssid_len)
3180
			ieee80211_sta_start_scan(sdata, ifsta->scan_ssid, ifsta->scan_ssid_len);
3181
		else
3182
			ieee80211_sta_start_scan(sdata, NULL, 0);
3183 3184 3185 3186
		return;
	}

	if (test_and_clear_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request)) {
3187
		if (ieee80211_sta_config_auth(sdata, ifsta))
3188 3189 3190 3191 3192 3193
			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) {
3194
	case IEEE80211_STA_MLME_DISABLED:
3195
		break;
3196 3197 3198
	case IEEE80211_STA_MLME_DIRECT_PROBE:
		ieee80211_direct_probe(sdata, ifsta);
		break;
3199
	case IEEE80211_STA_MLME_AUTHENTICATE:
3200
		ieee80211_authenticate(sdata, ifsta);
3201
		break;
3202
	case IEEE80211_STA_MLME_ASSOCIATE:
3203
		ieee80211_associate(sdata, ifsta);
3204
		break;
3205
	case IEEE80211_STA_MLME_ASSOCIATED:
3206
		ieee80211_associated(sdata, ifsta);
3207
		break;
3208
	case IEEE80211_STA_MLME_IBSS_SEARCH:
3209
		ieee80211_sta_find_ibss(sdata, ifsta);
3210
		break;
3211
	case IEEE80211_STA_MLME_IBSS_JOINED:
3212
		ieee80211_sta_merge_ibss(sdata, ifsta);
3213
		break;
3214
#ifdef CONFIG_MAC80211_MESH
3215
	case IEEE80211_STA_MLME_MESH_UP:
3216
		ieee80211_mesh_housekeeping(sdata, ifsta);
3217 3218
		break;
#endif
3219
	default:
3220
		WARN_ON(1);
3221 3222 3223
		break;
	}

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

3228 3229
		ieee80211_set_disassoc(sdata, ifsta, false, true,
					WLAN_REASON_UNSPECIFIED);
3230 3231 3232 3233
	}
}


3234
static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata,
3235 3236
				     struct ieee80211_if_sta *ifsta)
{
3237
	struct ieee80211_local *local = sdata->local;
3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255

	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;
3256
	ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
3257
	ifsta->assoc_scan_tries = 0;
3258
	ifsta->direct_probe_tries = 0;
3259 3260
	ifsta->auth_tries = 0;
	ifsta->assoc_tries = 0;
3261
	netif_carrier_off(sdata->dev);
3262 3263 3264
}


3265
void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata,
3266 3267
			    struct ieee80211_if_sta *ifsta)
{
3268
	struct ieee80211_local *local = sdata->local;
3269

3270
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
3271 3272
		return;

3273
	if ((ifsta->flags & (IEEE80211_STA_BSSID_SET |
3274
			     IEEE80211_STA_AUTO_BSSID_SEL)) &&
3275
	    (ifsta->flags & (IEEE80211_STA_SSID_SET |
3276 3277 3278 3279 3280 3281
			     IEEE80211_STA_AUTO_SSID_SEL))) {

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

3282 3283 3284 3285 3286 3287 3288 3289 3290 3291
		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;

3292 3293
	if (ssid_len == ifsta->ssid_len &&
	    !memcmp(ifsta->ssid, ssid, ssid_len))
3294 3295
		return 1;

3296
	if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL)
3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316
		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;
}

3317
static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata,
3318 3319
				     struct ieee80211_if_sta *ifsta)
{
3320
	struct ieee80211_local *local = sdata->local;
3321 3322 3323 3324
	struct ieee80211_sta_bss *bss, *selected = NULL;
	int top_rssi = 0, freq;

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

3330 3331 3332 3333 3334
		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))
3335 3336
			continue;

3337 3338
		if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) &&
		    bss->freq != freq)
3339 3340
			continue;

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

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

3349
		if (!selected || top_rssi < bss->signal) {
3350
			selected = bss;
3351
			top_rssi = bss->signal;
3352 3353 3354 3355 3356 3357 3358
		}
	}
	if (selected)
		atomic_inc(&selected->users);
	spin_unlock_bh(&local->sta_bss_lock);

	if (selected) {
3359
		ieee80211_set_freq(sdata, selected->freq);
3360
		if (!(ifsta->flags & IEEE80211_STA_SSID_SET))
3361
			ieee80211_sta_set_ssid(sdata, selected->ssid,
3362
					       selected->ssid_len);
3363 3364
		ieee80211_sta_set_bssid(sdata, selected->bssid);
		ieee80211_sta_def_wmm_params(sdata, selected, 0);
3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375

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

3376
		ieee80211_rx_bss_put(local, selected);
3377
		ieee80211_sta_reset_auth(sdata, ifsta);
3378 3379
		return 0;
	} else {
3380 3381
		if (ifsta->assoc_scan_tries < IEEE80211_ASSOC_SCANS_MAX_TRIES) {
			ifsta->assoc_scan_tries++;
3382
			if (ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL)
3383
				ieee80211_sta_start_scan(sdata, NULL, 0);
3384
			else
3385
				ieee80211_sta_start_scan(sdata, ifsta->ssid,
3386
							 ifsta->ssid_len);
3387
			ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
3388 3389
			set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
		} else
3390
			ifsta->state = IEEE80211_STA_MLME_DISABLED;
3391 3392 3393 3394 3395
	}
	return -1;
}


3396
static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
3397 3398
				     struct ieee80211_if_sta *ifsta)
{
3399
	struct ieee80211_local *local = sdata->local;
3400
	struct ieee80211_sta_bss *bss;
3401
	struct ieee80211_supported_band *sband;
3402 3403
	u8 bssid[ETH_ALEN], *pos;
	int i;
3404
	int ret;
3405
	DECLARE_MAC_BUF(mac);
3406 3407 3408 3409 3410 3411 3412 3413 3414 3415

#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++)
3416
		bssid[i] ^= sdata->dev->dev_addr[i];
3417 3418 3419 3420
	bssid[0] &= ~0x01;
	bssid[0] |= 0x02;
#endif

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

3424
	bss = ieee80211_rx_bss_add(sdata, bssid,
3425
				   local->hw.conf.channel->center_freq,
3426
				   sdata->u.sta.ssid, sdata->u.sta.ssid_len);
3427 3428 3429
	if (!bss)
		return -ENOMEM;

3430 3431
	bss->band = local->hw.conf.channel->band;
	sband = local->hw.wiphy->bands[bss->band];
3432 3433

	if (local->hw.conf.beacon_int == 0)
3434
		local->hw.conf.beacon_int = 100;
3435 3436 3437
	bss->beacon_int = local->hw.conf.beacon_int;
	bss->last_update = jiffies;
	bss->capability = WLAN_CAPABILITY_IBSS;
J
Johannes Berg 已提交
3438 3439

	if (sdata->default_key)
3440
		bss->capability |= WLAN_CAPABILITY_PRIVACY;
J
Johannes Berg 已提交
3441
	else
3442
		sdata->drop_unencrypted = 0;
J
Johannes Berg 已提交
3443

3444
	bss->supp_rates_len = sband->n_bitrates;
3445
	pos = bss->supp_rates;
3446 3447
	for (i = 0; i < sband->n_bitrates; i++) {
		int rate = sband->bitrates[i].bitrate;
3448 3449 3450
		*pos++ = (u8) (rate / 5);
	}

3451
	ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
3452
	ieee80211_rx_bss_put(local, bss);
3453
	return ret;
3454 3455 3456
}


3457
static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
3458 3459
				   struct ieee80211_if_sta *ifsta)
{
3460
	struct ieee80211_local *local = sdata->local;
3461 3462 3463 3464
	struct ieee80211_sta_bss *bss;
	int found = 0;
	u8 bssid[ETH_ALEN];
	int active_ibss;
3465 3466
	DECLARE_MAC_BUF(mac);
	DECLARE_MAC_BUF(mac2);
3467 3468 3469 3470

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

3471
	active_ibss = ieee80211_sta_active_ibss(sdata);
3472 3473
#ifdef CONFIG_MAC80211_IBSS_DEBUG
	printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n",
3474
	       sdata->dev->name, active_ibss);
3475 3476 3477 3478 3479 3480 3481 3482
#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
3483 3484
		printk(KERN_DEBUG "   bssid=%s found\n",
		       print_mac(mac, bss->bssid));
3485 3486 3487 3488 3489 3490 3491 3492 3493
#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
3494 3495 3496 3497
	if (found)
		printk(KERN_DEBUG "   sta_find_ibss: selected %s current "
		       "%s\n", print_mac(mac, bssid),
		       print_mac(mac2, ifsta->bssid));
3498
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
3499 3500

	if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) {
3501
		int ret;
3502 3503 3504 3505 3506 3507 3508
		int search_freq;

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

3509
		bss = ieee80211_rx_bss_get(local, bssid, search_freq,
3510 3511 3512 3513
					   ifsta->ssid, ifsta->ssid_len);
		if (!bss)
			goto dont_join;

3514
		printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
3515
		       " based on configured SSID\n",
3516 3517
		       sdata->dev->name, print_mac(mac, bssid));
		ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
3518
		ieee80211_rx_bss_put(local, bss);
3519
		return ret;
3520
	}
3521 3522

dont_join:
3523 3524 3525 3526 3527
#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 */
3528
	if (ifsta->state == IEEE80211_STA_MLME_IBSS_JOINED &&
3529
	    !ieee80211_sta_active_ibss(sdata)) {
3530 3531 3532 3533 3534
		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 "
3535 3536
		       "join\n", sdata->dev->name);
		return ieee80211_sta_req_scan(sdata, ifsta->ssid,
3537
					      ifsta->ssid_len);
3538
	} else if (ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED) {
3539 3540 3541 3542
		int interval = IEEE80211_SCAN_INTERVAL;

		if (time_after(jiffies, ifsta->ibss_join_req +
			       IEEE80211_IBSS_JOIN_TIMEOUT)) {
3543
			if ((ifsta->flags & IEEE80211_STA_CREATE_IBSS) &&
3544 3545
			    (!(local->oper_channel->flags &
					IEEE80211_CHAN_NO_IBSS)))
3546
				return ieee80211_sta_create_ibss(sdata, ifsta);
3547
			if (ifsta->flags & IEEE80211_STA_CREATE_IBSS) {
3548
				printk(KERN_DEBUG "%s: IBSS not allowed on"
3549
				       " %d MHz\n", sdata->dev->name,
3550
				       local->hw.conf.channel->center_freq);
3551 3552 3553 3554 3555 3556 3557
			}

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

3558
		ifsta->state = IEEE80211_STA_MLME_IBSS_SEARCH;
3559 3560 3561 3562 3563 3564 3565 3566
		mod_timer(&ifsta->timer, jiffies + interval);
		return 0;
	}

	return 0;
}


3567
int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
3568 3569
{
	struct ieee80211_if_sta *ifsta;
3570
	int res;
3571 3572 3573 3574 3575 3576

	if (len > IEEE80211_MAX_SSID_LEN)
		return -EINVAL;

	ifsta = &sdata->u.sta;

3577 3578 3579 3580
	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;
3581
		ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
3582 3583 3584 3585 3586 3587 3588 3589 3590 3591

		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 "
3592
			       "the low-level driver\n", sdata->dev->name);
3593 3594 3595
			return res;
		}
	}
3596

3597 3598 3599 3600
	if (len)
		ifsta->flags |= IEEE80211_STA_SSID_SET;
	else
		ifsta->flags &= ~IEEE80211_STA_SSID_SET;
3601

3602
	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
3603
	    !(ifsta->flags & IEEE80211_STA_BSSID_SET)) {
3604
		ifsta->ibss_join_req = jiffies;
3605
		ifsta->state = IEEE80211_STA_MLME_IBSS_SEARCH;
3606
		return ieee80211_sta_find_ibss(sdata, ifsta);
3607
	}
3608

3609 3610 3611 3612
	return 0;
}


3613
int ieee80211_sta_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len)
3614 3615 3616 3617 3618 3619 3620 3621
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
	memcpy(ssid, ifsta->ssid, ifsta->ssid_len);
	*len = ifsta->ssid_len;
	return 0;
}


3622
int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
3623 3624 3625 3626 3627 3628 3629 3630
{
	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);
3631 3632 3633 3634 3635 3636
		res = 0;
		/*
		 * Hack! See also ieee80211_sta_set_ssid.
		 */
		if (netif_running(sdata->dev))
			res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
3637 3638
		if (res) {
			printk(KERN_DEBUG "%s: Failed to config new BSSID to "
3639
			       "the low-level driver\n", sdata->dev->name);
3640 3641 3642 3643
			return res;
		}
	}

3644 3645
	if (is_valid_ether_addr(bssid))
		ifsta->flags |= IEEE80211_STA_BSSID_SET;
3646
	else
3647 3648
		ifsta->flags &= ~IEEE80211_STA_BSSID_SET;

3649 3650 3651 3652 3653 3654 3655 3656 3657 3658
	return 0;
}


static void ieee80211_send_nullfunc(struct ieee80211_local *local,
				    struct ieee80211_sub_if_data *sdata,
				    int powersave)
{
	struct sk_buff *skb;
	struct ieee80211_hdr *nullfunc;
3659
	__le16 fc;
3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670

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

	nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
	memset(nullfunc, 0, 24);
3671 3672
	fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
			 IEEE80211_FCTL_TODS);
3673
	if (powersave)
3674 3675
		fc |= cpu_to_le16(IEEE80211_FCTL_PM);
	nullfunc->frame_control = fc;
3676 3677 3678 3679
	memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN);
	memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
	memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN);

3680
	ieee80211_sta_tx(sdata, skb, 0);
3681 3682 3683
}


3684 3685 3686 3687 3688 3689 3690
static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
{
	if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
	    ieee80211_vif_is_mesh(&sdata->vif))
		ieee80211_sta_timer((unsigned long)sdata);
}

3691 3692 3693 3694 3695 3696 3697 3698
void ieee80211_scan_completed(struct ieee80211_hw *hw)
{
	struct ieee80211_local *local = hw_to_local(hw);
	struct net_device *dev = local->scan_dev;
	struct ieee80211_sub_if_data *sdata;
	union iwreq_data wrqu;

	local->last_scan_completed = jiffies;
Z
Zhu Yi 已提交
3699 3700
	memset(&wrqu, 0, sizeof(wrqu));
	wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
3701

Z
Zhu Yi 已提交
3702 3703
	if (local->sta_hw_scanning) {
		local->sta_hw_scanning = 0;
3704 3705 3706
		if (ieee80211_hw_config(local))
			printk(KERN_DEBUG "%s: failed to restore operational "
			       "channel after scan\n", dev->name);
3707 3708 3709 3710 3711 3712
		/* Restart STA timer for HW scan case */
		rcu_read_lock();
		list_for_each_entry_rcu(sdata, &local->interfaces, list)
			ieee80211_restart_sta_timer(sdata);
		rcu_read_unlock();

Z
Zhu Yi 已提交
3713 3714 3715 3716
		goto done;
	}

	local->sta_sw_scanning = 0;
3717
	if (ieee80211_hw_config(local))
3718
		printk(KERN_DEBUG "%s: failed to restore operational "
3719 3720
		       "channel after scan\n", dev->name);

3721 3722

	netif_tx_lock_bh(local->mdev);
3723
	netif_addr_lock(local->mdev);
3724 3725 3726 3727 3728 3729 3730
	local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
	local->ops->configure_filter(local_to_hw(local),
				     FIF_BCN_PRBRESP_PROMISC,
				     &local->filter_flags,
				     local->mdev->mc_count,
				     local->mdev->mc_list);

3731
	netif_addr_unlock(local->mdev);
3732
	netif_tx_unlock_bh(local->mdev);
3733

3734 3735
	rcu_read_lock();
	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
3736 3737 3738 3739
		/* Tell AP we're back */
		if (sdata->vif.type == IEEE80211_IF_TYPE_STA &&
		    sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)
			ieee80211_send_nullfunc(local, sdata, 0);
3740

3741
		ieee80211_restart_sta_timer(sdata);
3742

3743 3744
		netif_wake_queue(sdata->dev);
	}
3745
	rcu_read_unlock();
3746

Z
Zhu Yi 已提交
3747
done:
3748
	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3749
	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
3750
		struct ieee80211_if_sta *ifsta = &sdata->u.sta;
3751
		if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) ||
3752
		    (!(ifsta->state == IEEE80211_STA_MLME_IBSS_JOINED) &&
3753 3754
		    !ieee80211_sta_active_ibss(sdata)))
			ieee80211_sta_find_ibss(sdata, ifsta);
3755 3756 3757 3758 3759 3760 3761 3762 3763 3764
	}
}
EXPORT_SYMBOL(ieee80211_scan_completed);

void ieee80211_sta_scan_work(struct work_struct *work)
{
	struct ieee80211_local *local =
		container_of(work, struct ieee80211_local, scan_work.work);
	struct net_device *dev = local->scan_dev;
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3765
	struct ieee80211_supported_band *sband;
3766 3767 3768 3769
	struct ieee80211_channel *chan;
	int skip;
	unsigned long next_delay = 0;

Z
Zhu Yi 已提交
3770
	if (!local->sta_sw_scanning)
3771 3772 3773 3774
		return;

	switch (local->scan_state) {
	case SCAN_SET_CHANNEL:
3775 3776 3777 3778 3779
		/*
		 * Get current scan band. scan_band may be IEEE80211_NUM_BANDS
		 * after we successfully scanned the last channel of the last
		 * band (and the last band is supported by the hw)
		 */
3780 3781 3782 3783 3784
		if (local->scan_band < IEEE80211_NUM_BANDS)
			sband = local->hw.wiphy->bands[local->scan_band];
		else
			sband = NULL;

3785 3786 3787 3788 3789
		/*
		 * If we are at an unsupported band and have more bands
		 * left to scan, advance to the next supported one.
		 */
		while (!sband && local->scan_band < IEEE80211_NUM_BANDS - 1) {
3790 3791 3792 3793 3794
			local->scan_band++;
			sband = local->hw.wiphy->bands[local->scan_band];
			local->scan_channel_idx = 0;
		}

3795 3796
		/* if no more bands/channels left, complete scan */
		if (!sband || local->scan_channel_idx >= sband->n_channels) {
3797 3798 3799
			ieee80211_scan_completed(local_to_hw(local));
			return;
		}
3800 3801 3802 3803
		skip = 0;
		chan = &sband->channels[local->scan_channel_idx];

		if (chan->flags & IEEE80211_CHAN_DISABLED ||
3804
		    (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
3805
		     chan->flags & IEEE80211_CHAN_NO_IBSS))
3806 3807 3808 3809 3810
			skip = 1;

		if (!skip) {
			local->scan_channel = chan;
			if (ieee80211_hw_config(local)) {
3811 3812 3813
				printk(KERN_DEBUG "%s: failed to set freq to "
				       "%d MHz for scan\n", dev->name,
				       chan->center_freq);
3814 3815 3816 3817
				skip = 1;
			}
		}

3818
		/* advance state machine to next channel/band */
3819
		local->scan_channel_idx++;
3820
		if (local->scan_channel_idx >= sband->n_channels) {
3821 3822 3823 3824 3825
			/*
			 * scan_band may end up == IEEE80211_NUM_BANDS, but
			 * we'll catch that case above and complete the scan
			 * if that is the case.
			 */
3826 3827
			local->scan_band++;
			local->scan_channel_idx = 0;
3828 3829 3830 3831 3832 3833 3834 3835 3836 3837
		}

		if (skip)
			break;

		next_delay = IEEE80211_PROBE_DELAY +
			     usecs_to_jiffies(local->hw.channel_change_time);
		local->scan_state = SCAN_SEND_PROBE;
		break;
	case SCAN_SEND_PROBE:
3838
		next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
3839
		local->scan_state = SCAN_SET_CHANNEL;
3840 3841 3842

		if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN)
			break;
3843
		ieee80211_send_probe_req(sdata, NULL, local->scan_ssid,
3844 3845
					 local->scan_ssid_len);
		next_delay = IEEE80211_CHANNEL_TIME;
3846 3847 3848
		break;
	}

Z
Zhu Yi 已提交
3849
	if (local->sta_sw_scanning)
3850 3851 3852 3853 3854
		queue_delayed_work(local->hw.workqueue, &local->scan_work,
				   next_delay);
}


3855
static int ieee80211_sta_start_scan(struct ieee80211_sub_if_data *scan_sdata,
3856 3857
				    u8 *ssid, size_t ssid_len)
{
3858
	struct ieee80211_local *local = scan_sdata->local;
3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880
	struct ieee80211_sub_if_data *sdata;

	if (ssid_len > IEEE80211_MAX_SSID_LEN)
		return -EINVAL;

	/* MLME-SCAN.request (page 118)  page 144 (11.1.3.1)
	 * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS
	 * BSSID: MACAddress
	 * SSID
	 * ScanType: ACTIVE, PASSIVE
	 * ProbeDelay: delay (in microseconds) to be used prior to transmitting
	 *    a Probe frame during active scanning
	 * ChannelList
	 * MinChannelTime (>= ProbeDelay), in TU
	 * MaxChannelTime: (>= MinChannelTime), in TU
	 */

	 /* MLME-SCAN.confirm
	  * BSSDescriptionSet
	  * ResultCode: SUCCESS, INVALID_PARAMETERS
	 */

Z
Zhu Yi 已提交
3881
	if (local->sta_sw_scanning || local->sta_hw_scanning) {
3882
		if (local->scan_dev == scan_sdata->dev)
3883 3884 3885 3886 3887 3888
			return 0;
		return -EBUSY;
	}

	if (local->ops->hw_scan) {
		int rc = local->ops->hw_scan(local_to_hw(local),
Z
Zhu Yi 已提交
3889
					     ssid, ssid_len);
3890
		if (!rc) {
Z
Zhu Yi 已提交
3891
			local->sta_hw_scanning = 1;
3892
			local->scan_dev = scan_sdata->dev;
3893 3894 3895 3896
		}
		return rc;
	}

Z
Zhu Yi 已提交
3897
	local->sta_sw_scanning = 1;
3898

3899 3900
	rcu_read_lock();
	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
3901
		netif_stop_queue(sdata->dev);
3902
		if (sdata->vif.type == IEEE80211_IF_TYPE_STA &&
3903
		    (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED))
3904 3905
			ieee80211_send_nullfunc(local, sdata, 1);
	}
3906
	rcu_read_unlock();
3907 3908 3909 3910 3911 3912 3913 3914

	if (ssid) {
		local->scan_ssid_len = ssid_len;
		memcpy(local->scan_ssid, ssid, ssid_len);
	} else
		local->scan_ssid_len = 0;
	local->scan_state = SCAN_SET_CHANNEL;
	local->scan_channel_idx = 0;
3915
	local->scan_band = IEEE80211_BAND_2GHZ;
3916
	local->scan_dev = scan_sdata->dev;
3917

3918
	netif_addr_lock_bh(local->mdev);
3919 3920 3921 3922 3923 3924
	local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
	local->ops->configure_filter(local_to_hw(local),
				     FIF_BCN_PRBRESP_PROMISC,
				     &local->filter_flags,
				     local->mdev->mc_count,
				     local->mdev->mc_list);
3925
	netif_addr_unlock_bh(local->mdev);
3926 3927 3928 3929 3930 3931 3932 3933 3934

	/* TODO: start scan as soon as all nullfunc frames are ACKed */
	queue_delayed_work(local->hw.workqueue, &local->scan_work,
			   IEEE80211_CHANNEL_TIME);

	return 0;
}


3935
int ieee80211_sta_req_scan(struct ieee80211_sub_if_data *sdata, u8 *ssid, size_t ssid_len)
3936 3937
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
3938
	struct ieee80211_local *local = sdata->local;
3939

3940
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
3941
		return ieee80211_sta_start_scan(sdata, ssid, ssid_len);
3942

Z
Zhu Yi 已提交
3943
	if (local->sta_sw_scanning || local->sta_hw_scanning) {
3944
		if (local->scan_dev == sdata->dev)
3945 3946 3947 3948
			return 0;
		return -EBUSY;
	}

3949 3950 3951
	ifsta->scan_ssid_len = ssid_len;
	if (ssid_len)
		memcpy(ifsta->scan_ssid, ssid, ssid_len);
3952 3953 3954 3955 3956
	set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request);
	queue_work(local->hw.workqueue, &ifsta->work);
	return 0;
}

3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998

static void ieee80211_sta_add_scan_ies(struct iw_request_info *info,
				       struct ieee80211_sta_bss *bss,
				       char **current_ev, char *end_buf)
{
	u8 *pos, *end, *next;
	struct iw_event iwe;

	if (bss == NULL || bss->ies == NULL)
		return;

	/*
	 * If needed, fragment the IEs buffer (at IE boundaries) into short
	 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
	 */
	pos = bss->ies;
	end = pos + bss->ies_len;

	while (end - pos > IW_GENERIC_IE_MAX) {
		next = pos + 2 + pos[1];
		while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
			next = next + 2 + next[1];

		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = IWEVGENIE;
		iwe.u.data.length = next - pos;
		*current_ev = iwe_stream_add_point(info, *current_ev,
						   end_buf, &iwe, pos);

		pos = next;
	}

	if (end > pos) {
		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = IWEVGENIE;
		iwe.u.data.length = end - pos;
		*current_ev = iwe_stream_add_point(info, *current_ev,
						   end_buf, &iwe, pos);
	}
}


3999
static char *
4000
ieee80211_sta_scan_result(struct ieee80211_local *local,
4001
			  struct iw_request_info *info,
4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014
			  struct ieee80211_sta_bss *bss,
			  char *current_ev, char *end_buf)
{
	struct iw_event iwe;

	if (time_after(jiffies,
		       bss->last_update + IEEE80211_SCAN_RESULT_EXPIRE))
		return current_ev;

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWAP;
	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
	memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
4015
	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4016 4017 4018 4019
					  IW_EV_ADDR_LEN);

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWESSID;
J
Johannes Berg 已提交
4020 4021
	if (bss_mesh_cfg(bss)) {
		iwe.u.data.length = bss_mesh_id_len(bss);
4022
		iwe.u.data.flags = 1;
4023 4024
		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
						  &iwe, bss_mesh_id(bss));
4025 4026 4027
	} else {
		iwe.u.data.length = bss->ssid_len;
		iwe.u.data.flags = 1;
4028 4029
		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
						  &iwe, bss->ssid);
4030
	}
4031

4032 4033
	if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
	    || bss_mesh_cfg(bss)) {
4034 4035
		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = SIOCGIWMODE;
J
Johannes Berg 已提交
4036
		if (bss_mesh_cfg(bss))
4037 4038
			iwe.u.mode = IW_MODE_MESH;
		else if (bss->capability & WLAN_CAPABILITY_ESS)
4039 4040 4041
			iwe.u.mode = IW_MODE_MASTER;
		else
			iwe.u.mode = IW_MODE_ADHOC;
4042 4043
		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
						  &iwe, IW_EV_UINT_LEN);
4044 4045 4046 4047
	}

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWFREQ;
4048 4049
	iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq);
	iwe.u.freq.e = 0;
4050
	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4051
					  IW_EV_FREQ_LEN);
4052 4053 4054

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWFREQ;
4055 4056
	iwe.u.freq.m = bss->freq;
	iwe.u.freq.e = 6;
4057
	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4058 4059 4060
					  IW_EV_FREQ_LEN);
	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = IWEVQUAL;
4061 4062
	iwe.u.qual.qual = bss->qual;
	iwe.u.qual.level = bss->signal;
4063 4064
	iwe.u.qual.noise = bss->noise;
	iwe.u.qual.updated = local->wstats_flags;
4065
	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4066 4067 4068 4069 4070 4071 4072 4073 4074
					  IW_EV_QUAL_LEN);

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWENCODE;
	if (bss->capability & WLAN_CAPABILITY_PRIVACY)
		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
	else
		iwe.u.data.flags = IW_ENCODE_DISABLED;
	iwe.u.data.length = 0;
4075 4076
	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
					  &iwe, "");
4077

4078
	ieee80211_sta_add_scan_ies(info, bss, &current_ev, end_buf);
4079

4080 4081
	if (bss && bss->supp_rates_len > 0) {
		/* display all supported rates in readable format */
4082
		char *p = current_ev + iwe_stream_lcp_len(info);
4083 4084 4085 4086 4087 4088 4089 4090 4091 4092
		int i;

		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = SIOCGIWRATE;
		/* Those two flags are ignored... */
		iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;

		for (i = 0; i < bss->supp_rates_len; i++) {
			iwe.u.bitrate.value = ((bss->supp_rates[i] &
							0x7f) * 500000);
4093
			p = iwe_stream_add_value(info, current_ev, p,
4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106
					end_buf, &iwe, IW_EV_PARAM_LEN);
		}
		current_ev = p;
	}

	if (bss) {
		char *buf;
		buf = kmalloc(30, GFP_ATOMIC);
		if (buf) {
			memset(&iwe, 0, sizeof(iwe));
			iwe.cmd = IWEVCUSTOM;
			sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp));
			iwe.u.data.length = strlen(buf);
4107 4108
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf,
4109
							  &iwe, buf);
4110 4111 4112 4113 4114 4115 4116
			memset(&iwe, 0, sizeof(iwe));
			iwe.cmd = IWEVCUSTOM;
			sprintf(buf, " Last beacon: %dms ago",
				jiffies_to_msecs(jiffies - bss->last_update));
			iwe.u.data.length = strlen(buf);
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf, &iwe, buf);
4117 4118 4119 4120
			kfree(buf);
		}
	}

J
Johannes Berg 已提交
4121
	if (bss_mesh_cfg(bss)) {
4122
		char *buf;
4123
		u8 *cfg = bss_mesh_cfg(bss);
4124
		buf = kmalloc(50, GFP_ATOMIC);
4125 4126 4127
		if (buf) {
			memset(&iwe, 0, sizeof(iwe));
			iwe.cmd = IWEVCUSTOM;
4128
			sprintf(buf, "Mesh network (version %d)", cfg[0]);
4129
			iwe.u.data.length = strlen(buf);
4130 4131
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf,
4132 4133
							  &iwe, buf);
			sprintf(buf, "Path Selection Protocol ID: "
4134 4135
				"0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
							cfg[4]);
4136
			iwe.u.data.length = strlen(buf);
4137 4138
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf,
4139 4140
							  &iwe, buf);
			sprintf(buf, "Path Selection Metric ID: "
4141 4142
				"0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
							cfg[8]);
4143
			iwe.u.data.length = strlen(buf);
4144 4145
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf,
4146 4147
							  &iwe, buf);
			sprintf(buf, "Congestion Control Mode ID: "
4148 4149
				"0x%02X%02X%02X%02X", cfg[9], cfg[10],
							cfg[11], cfg[12]);
4150
			iwe.u.data.length = strlen(buf);
4151 4152
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf,
4153 4154
							  &iwe, buf);
			sprintf(buf, "Channel Precedence: "
4155 4156
				"0x%02X%02X%02X%02X", cfg[13], cfg[14],
							cfg[15], cfg[16]);
4157
			iwe.u.data.length = strlen(buf);
4158 4159
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf,
4160 4161 4162 4163 4164
							  &iwe, buf);
			kfree(buf);
		}
	}

4165 4166 4167 4168
	return current_ev;
}


4169
int ieee80211_sta_scan_results(struct ieee80211_local *local,
4170 4171
			       struct iw_request_info *info,
			       char *buf, size_t len)
4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182
{
	char *current_ev = buf;
	char *end_buf = buf + len;
	struct ieee80211_sta_bss *bss;

	spin_lock_bh(&local->sta_bss_lock);
	list_for_each_entry(bss, &local->sta_bss_list, list) {
		if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
			spin_unlock_bh(&local->sta_bss_lock);
			return -E2BIG;
		}
4183
		current_ev = ieee80211_sta_scan_result(local, info, bss,
4184
						       current_ev, end_buf);
4185 4186 4187 4188 4189 4190
	}
	spin_unlock_bh(&local->sta_bss_lock);
	return current_ev - buf;
}


4191
int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, char *ie, size_t len)
4192 4193
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
J
Johannes Berg 已提交
4194

4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211
	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;
}


4212
struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
J
Johannes Berg 已提交
4213
					struct sk_buff *skb, u8 *bssid,
4214
					u8 *addr, u64 supp_rates)
4215
{
4216
	struct ieee80211_local *local = sdata->local;
4217
	struct sta_info *sta;
4218
	DECLARE_MAC_BUF(mac);
4219
	int band = local->hw.conf.channel->band;
4220 4221 4222 4223 4224 4225

	/* 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 "
4226
			       "entry %s\n", sdata->dev->name, print_mac(mac, addr));
4227 4228 4229 4230
		}
		return NULL;
	}

4231
	if (compare_ether_addr(bssid, sdata->u.sta.bssid))
4232 4233
		return NULL;

4234
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
4235
	printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n",
4236
	       wiphy_name(local->hw.wiphy), print_mac(mac, addr), sdata->dev->name);
4237
#endif
4238

J
Johannes Berg 已提交
4239 4240
	sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
	if (!sta)
4241 4242
		return NULL;

4243
	set_sta_flags(sta, WLAN_STA_AUTHORIZED);
4244

4245 4246 4247
	/* make sure mandatory rates are always added */
	sta->supp_rates[band] = supp_rates |
			ieee80211_sta_get_mandatory_rates(local, band);
4248 4249 4250

	rate_control_rate_init(sta, local);

4251
	if (sta_info_insert(sta))
J
Johannes Berg 已提交
4252 4253
		return NULL;

4254
	return sta;
4255 4256 4257
}


4258
int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason)
4259 4260 4261
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;

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

4265 4266
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA &&
	    sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
4267 4268
		return -EINVAL;

4269
	ieee80211_set_disassoc(sdata, ifsta, true, true, reason);
4270 4271 4272 4273
	return 0;
}


4274
int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason)
4275 4276 4277
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;

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

4281
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
4282 4283
		return -EINVAL;

4284
	if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED))
4285 4286
		return -1;

4287
	ieee80211_set_disassoc(sdata, ifsta, false, true, reason);
4288 4289
	return 0;
}
4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300

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) {
4301 4302
			if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
				continue;
4303

4304
			ieee80211_sta_req_auth(sdata, &sdata->u.sta);
4305 4306 4307 4308 4309 4310
		}
		rcu_read_unlock();
		break;
	}
}
EXPORT_SYMBOL(ieee80211_notify_mac);