mlme.c 120.1 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 356 357 358 359 360 361 362 363 364 365
static void ieee80211_sta_send_apinfo(struct ieee80211_sub_if_data *sdata,
					struct ieee80211_if_sta *ifsta)
{
	union iwreq_data wrqu;
	memset(&wrqu, 0, sizeof(wrqu));
	if (ifsta->flags & IEEE80211_STA_ASSOCIATED)
		memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN);
	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
	wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
}

366
static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata,
367 368 369 370 371
					 struct ieee80211_if_sta *ifsta)
{
	union iwreq_data wrqu;

	if (ifsta->assocreq_ies) {
372 373
		memset(&wrqu, 0, sizeof(wrqu));
		wrqu.data.length = ifsta->assocreq_ies_len;
374
		wireless_send_event(sdata->dev, IWEVASSOCREQIE, &wrqu,
375
				    ifsta->assocreq_ies);
376
	}
377 378 379
	if (ifsta->assocresp_ies) {
		memset(&wrqu, 0, sizeof(wrqu));
		wrqu.data.length = ifsta->assocresp_ies_len;
380
		wireless_send_event(sdata->dev, IWEVASSOCRESPIE, &wrqu,
381
				    ifsta->assocresp_ies);
382 383 384 385
	}
}


386
static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
387
				     struct ieee80211_if_sta *ifsta)
388
{
389
	struct ieee80211_local *local = sdata->local;
T
Tomas Winkler 已提交
390
	struct ieee80211_conf *conf = &local_to_hw(local)->conf;
391
	u32 changed = BSS_CHANGED_ASSOC;
392

393
	struct ieee80211_sta_bss *bss;
394

395
	ifsta->flags |= IEEE80211_STA_ASSOCIATED;
396

397 398
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
		return;
399

400 401 402 403 404 405 406 407
	bss = ieee80211_rx_bss_get(local, ifsta->bssid,
				   conf->channel->center_freq,
				   ifsta->ssid, ifsta->ssid_len);
	if (bss) {
		/* set timing information */
		sdata->bss_conf.beacon_int = bss->beacon_int;
		sdata->bss_conf.timestamp = bss->timestamp;
		sdata->bss_conf.dtim_period = bss->dtim_period;
408

409
		changed |= ieee80211_handle_bss_capability(sdata, bss);
410

411 412
		ieee80211_rx_bss_put(local, bss);
	}
T
Tomas Winkler 已提交
413

414 415 416 417 418 419
	if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
		changed |= BSS_CHANGED_HT;
		sdata->bss_conf.assoc_ht = 1;
		sdata->bss_conf.ht_conf = &conf->ht_conf;
		sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf;
	}
T
Tomas Winkler 已提交
420

421 422 423
	ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET;
	memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN);
	ieee80211_sta_send_associnfo(sdata, ifsta);
T
Tomas Winkler 已提交
424

425
	ifsta->last_probe = jiffies;
426
	ieee80211_led_assoc(local, 1);
427

428
	sdata->bss_conf.assoc = 1;
429
	ieee80211_bss_info_change_notify(sdata, changed);
430

431
	netif_carrier_on(sdata->dev);
432

433
	ieee80211_sta_send_apinfo(sdata, ifsta);
434 435
}

436
void ieee80211_sta_tx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
437
		      int encrypt)
438 439 440 441 442 443
{
	skb->dev = sdata->local->mdev;
	skb_set_mac_header(skb, 0);
	skb_set_network_header(skb, 0);
	skb_set_transport_header(skb, 0);

444 445
	skb->iif = sdata->dev->ifindex;
	skb->do_not_encrypt = !encrypt;
446 447 448 449 450

	dev_queue_xmit(skb);
}


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

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

485
	ieee80211_sta_tx(sdata, skb, encrypt);
486 487
}

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

518

519
static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
520 521
				   struct ieee80211_if_sta *ifsta)
{
522 523
	DECLARE_MAC_BUF(mac);

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

533
	ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
534
	printk(KERN_DEBUG "%s: authenticate with AP %s\n",
535
	       sdata->dev->name, print_mac(mac, ifsta->bssid));
536

537
	ieee80211_send_auth(sdata, ifsta, 1, NULL, 0, 0);
538 539 540 541

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

542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
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;
}
562

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

	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 "
582
		       "frame\n", sdata->dev->name);
583 584 585 586
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

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

589
	capab = ifsta->capab;
590 591 592 593 594 595

	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;
596
	}
597

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

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

613 614 615 616
		if ((bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
		    (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
			capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;

617
		ieee80211_rx_bss_put(local, bss);
618 619 620
	} else {
		rates = ~0;
		rates_len = sband->n_bitrates;
621 622 623 624 625
	}

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

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

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

653
	/* add all rates which were marked to be used above */
654 655 656 657
	supp_rates_len = rates_len;
	if (supp_rates_len > 8)
		supp_rates_len = 8;

658
	len = sband->n_bitrates;
659
	pos = skb_put(skb, supp_rates_len + 2);
660
	*pos++ = WLAN_EID_SUPP_RATES;
661
	*pos++ = supp_rates_len;
662

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

673
	if (rates_len > count) {
674 675 676 677 678 679 680 681 682
		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);
			}
683 684 685
		}
	}

686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705
	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*/
		}
	}

706 707 708 709 710
	if (ifsta->extra_ie) {
		pos = skb_put(skb, ifsta->extra_ie_len);
		memcpy(pos, ifsta->extra_ie, ifsta->extra_ie_len);
	}

711
	if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
712 713 714 715 716 717 718 719 720 721 722
		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;
	}
723

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

	kfree(ifsta->assocreq_ies);
	ifsta->assocreq_ies_len = (skb->data + skb->len) - ies;
764
	ifsta->assocreq_ies = kmalloc(ifsta->assocreq_ies_len, GFP_KERNEL);
765 766 767
	if (ifsta->assocreq_ies)
		memcpy(ifsta->assocreq_ies, ies, ifsta->assocreq_ies_len);

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


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

797
	ieee80211_sta_tx(sdata, skb, 0);
798 799 800
}


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

826
	ieee80211_sta_tx(sdata, skb, 0);
827 828
}

829 830 831 832 833 834
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;
835
	u32 changed = BSS_CHANGED_ASSOC;
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

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

863 864 865 866 867 868 869 870 871 872 873 874 875 876
	ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
	changed |= ieee80211_reset_erp_info(sdata);

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

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

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

	ieee80211_sta_send_apinfo(sdata, ifsta);
877 878 879 880 881 882 883 884 885 886

	if (self_disconnected)
		ifsta->state = IEEE80211_STA_MLME_DISABLED;

	sta_info_unlink(&sta);

	rcu_read_unlock();

	sta_info_destroy(sta);
}
887

888
static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata,
889 890
				      struct ieee80211_if_sta *ifsta)
{
891
	struct ieee80211_local *local = sdata->local;
892
	struct ieee80211_sta_bss *bss;
893 894 895
	int bss_privacy;
	int wep_privacy;
	int privacy_invoked;
896

897
	if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL))
898 899
		return 0;

900
	bss = ieee80211_rx_bss_get(local, ifsta->bssid,
901
				   local->hw.conf.channel->center_freq,
902
				   ifsta->ssid, ifsta->ssid_len);
903 904 905
	if (!bss)
		return 0;

906
	bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY);
907
	wep_privacy = !!ieee80211_sta_wep_configured(sdata);
908
	privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED);
909

910
	ieee80211_rx_bss_put(local, bss);
911

912 913 914 915
	if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked))
		return 0;

	return 1;
916 917 918
}


919
static void ieee80211_associate(struct ieee80211_sub_if_data *sdata,
920 921
				struct ieee80211_if_sta *ifsta)
{
922 923
	DECLARE_MAC_BUF(mac);

924 925
	ifsta->assoc_tries++;
	if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) {
926
		printk(KERN_DEBUG "%s: association with AP %s"
927
		       " timed out\n",
928
		       sdata->dev->name, print_mac(mac, ifsta->bssid));
929
		ifsta->state = IEEE80211_STA_MLME_DISABLED;
930 931 932
		return;
	}

933
	ifsta->state = IEEE80211_STA_MLME_ASSOCIATE;
934
	printk(KERN_DEBUG "%s: associate with AP %s\n",
935 936
	       sdata->dev->name, print_mac(mac, ifsta->bssid));
	if (ieee80211_privacy_mismatch(sdata, ifsta)) {
937
		printk(KERN_DEBUG "%s: mismatch in privacy configuration and "
938
		       "mixed-cell disabled - abort association\n", sdata->dev->name);
939
		ifsta->state = IEEE80211_STA_MLME_DISABLED;
940 941 942
		return;
	}

943
	ieee80211_send_assoc(sdata, ifsta);
944 945 946 947 948

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


949
static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
950 951
				 struct ieee80211_if_sta *ifsta)
{
952
	struct ieee80211_local *local = sdata->local;
953 954
	struct sta_info *sta;
	int disassoc;
955
	DECLARE_MAC_BUF(mac);
956 957 958 959 960 961

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

962
	ifsta->state = IEEE80211_STA_MLME_ASSOCIATED;
963

964 965
	rcu_read_lock();

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

	rcu_read_unlock();

1000 1001 1002 1003
	if (disassoc)
		ieee80211_set_disassoc(sdata, ifsta, true, true,
					WLAN_REASON_PREV_AUTH_NOT_VALID);
	else
1004 1005 1006 1007 1008
		mod_timer(&ifsta->timer, jiffies +
				      IEEE80211_MONITORING_INTERVAL);
}


1009
static void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1010 1011
				     u8 *ssid, size_t ssid_len)
{
1012
	struct ieee80211_local *local = sdata->local;
1013
	struct ieee80211_supported_band *sband;
1014 1015 1016 1017 1018 1019 1020 1021
	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 "
1022
		       "request\n", sdata->dev->name);
1023 1024 1025 1026 1027 1028
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
	memset(mgmt, 0, 24);
1029 1030
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_PROBE_REQ);
1031
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046
	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;
1047 1048 1049 1050
	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];
1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062
		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]++;
		}
1063
		*pos = rate->bitrate / 5;
1064 1065
	}

1066
	ieee80211_sta_tx(sdata, skb, 0);
1067 1068 1069
}


1070
static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata)
1071 1072
{
	if (!sdata || !sdata->default_key ||
1073
	    sdata->default_key->conf.alg != ALG_WEP)
1074 1075 1076 1077 1078
		return 0;
	return 1;
}


1079
static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata,
1080 1081
				     struct ieee80211_if_sta *ifsta)
{
1082
	printk(KERN_DEBUG "%s: authenticated\n", sdata->dev->name);
1083
	ifsta->flags |= IEEE80211_STA_AUTHENTICATED;
1084
	ieee80211_associate(sdata, ifsta);
1085 1086 1087
}


1088
static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1089 1090 1091 1092 1093 1094 1095 1096
				     struct ieee80211_if_sta *ifsta,
				     struct ieee80211_mgmt *mgmt,
				     size_t len)
{
	u8 *pos;
	struct ieee802_11_elems elems;

	pos = mgmt->u.auth.variable;
1097
	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1098
	if (!elems.challenge)
1099
		return;
1100
	ieee80211_send_auth(sdata, ifsta, 3, elems.challenge - 2,
1101 1102 1103
			    elems.challenge_len + 2, 1);
}

1104
static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
1105 1106 1107 1108
					u8 dialog_token, u16 status, u16 policy,
					u16 buf_size, u16 timeout)
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
1109
	struct ieee80211_local *local = sdata->local;
1110 1111 1112 1113
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u16 capab;

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

1116 1117
	if (!skb) {
		printk(KERN_DEBUG "%s: failed to allocate buffer "
1118
		       "for addba resp frame\n", sdata->dev->name);
1119 1120 1121 1122 1123 1124 1125
		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);
1126
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1127
	if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
1128
		memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
1129 1130
	else
		memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1131 1132
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_ACTION);
1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146

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

1147
	ieee80211_sta_tx(sdata, skb, 0);
1148 1149 1150 1151

	return;
}

1152
void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, const u8 *da,
1153 1154 1155
				u16 tid, u8 dialog_token, u16 start_seq_num,
				u16 agg_size, u16 timeout)
{
1156
	struct ieee80211_local *local = sdata->local;
1157 1158 1159 1160 1161
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u16 capab;

E
Ester Kummer 已提交
1162
	skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1163 1164 1165

	if (!skb) {
		printk(KERN_ERR "%s: failed to allocate buffer "
1166
				"for addba request frame\n", sdata->dev->name);
1167 1168 1169 1170 1171 1172
		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);
1173
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1174
	if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
1175
		memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
1176 1177 1178
	else
		memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);

1179 1180
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_ACTION);
1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197

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

1198
	ieee80211_sta_tx(sdata, skb, 0);
1199 1200
}

1201
static void ieee80211_sta_process_addba_request(struct ieee80211_local *local,
1202 1203 1204
						struct ieee80211_mgmt *mgmt,
						size_t len)
{
1205 1206
	struct ieee80211_hw *hw = &local->hw;
	struct ieee80211_conf *conf = &hw->conf;
1207
	struct sta_info *sta;
1208 1209
	struct tid_ampdu_rx *tid_agg_rx;
	u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
1210
	u8 dialog_token;
1211 1212
	int ret = -EOPNOTSUPP;
	DECLARE_MAC_BUF(mac);
1213

1214 1215
	rcu_read_lock();

1216
	sta = sta_info_get(local, mgmt->sa);
1217 1218
	if (!sta) {
		rcu_read_unlock();
1219
		return;
1220
	}
1221 1222 1223 1224

	/* 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);
1225 1226
	start_seq_num =
		le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4;
1227 1228 1229 1230 1231 1232 1233 1234

	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;

1235 1236 1237 1238 1239 1240 1241 1242 1243
	/* 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())
1244
			printk(KERN_DEBUG "AddBA Req with bad params from "
1245 1246 1247 1248 1249 1250 1251 1252
				"%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) {
1253 1254 1255
		struct ieee80211_supported_band *sband;

		sband = local->hw.wiphy->bands[conf->channel->band];
1256
		buf_size = IEEE80211_MIN_AMPDU_BUF;
1257
		buf_size = buf_size << sband->ht_info.ampdu_factor;
1258 1259 1260 1261
	}


	/* examine state machine */
1262
	spin_lock_bh(&sta->lock);
1263

1264
	if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
1265 1266
#ifdef CONFIG_MAC80211_HT_DEBUG
		if (net_ratelimit())
1267
			printk(KERN_DEBUG "unexpected AddBA Req from "
1268 1269 1270 1271 1272 1273
				"%s on tid %u\n",
				print_mac(mac, mgmt->sa), tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */
		goto end;
	}

1274 1275 1276 1277
	/* 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]) {
1278
#ifdef CONFIG_MAC80211_HT_DEBUG
1279 1280 1281
		if (net_ratelimit())
			printk(KERN_ERR "allocate rx mlme to tid %d failed\n",
					tid);
1282
#endif
1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293
		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];

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

	if (local->ops->ampdu_action)
		ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START,
1311
					       sta->addr, tid, &start_seq_num);
1312
#ifdef CONFIG_MAC80211_HT_DEBUG
1313
	printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
1314 1315 1316 1317
#endif /* CONFIG_MAC80211_HT_DEBUG */

	if (ret) {
		kfree(tid_agg_rx->reorder_buf);
1318 1319
		kfree(tid_agg_rx);
		sta->ampdu_mlme.tid_rx[tid] = NULL;
1320 1321 1322 1323
		goto end;
	}

	/* change state and send addba resp */
1324
	sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL;
1325 1326 1327 1328 1329 1330 1331 1332
	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:
1333
	spin_unlock_bh(&sta->lock);
1334 1335

end_no_lock:
1336
	ieee80211_send_addba_resp(sta->sdata, sta->addr, tid,
1337 1338
				  dialog_token, status, 1, buf_size, timeout);
	rcu_read_unlock();
1339
}
1340

1341
static void ieee80211_sta_process_addba_resp(struct ieee80211_local *local,
1342 1343 1344 1345 1346 1347 1348 1349 1350
					     struct ieee80211_mgmt *mgmt,
					     size_t len)
{
	struct ieee80211_hw *hw = &local->hw;
	struct sta_info *sta;
	u16 capab;
	u16 tid;
	u8 *state;

1351 1352
	rcu_read_lock();

1353
	sta = sta_info_get(local, mgmt->sa);
1354 1355
	if (!sta) {
		rcu_read_unlock();
1356
		return;
1357
	}
1358 1359 1360 1361

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

1362
	state = &sta->ampdu_mlme.tid_state_tx[tid];
1363

1364
	spin_lock_bh(&sta->lock);
1365

1366
	if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
1367
		spin_unlock_bh(&sta->lock);
1368 1369 1370
		goto addba_resp_exit;
	}

1371
	if (mgmt->u.action.u.addba_resp.dialog_token !=
1372
		sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
1373
		spin_unlock_bh(&sta->lock);
1374 1375 1376
#ifdef CONFIG_MAC80211_HT_DEBUG
		printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */
1377
		goto addba_resp_exit;
1378 1379
	}

1380
	del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
1381 1382 1383 1384 1385 1386
#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;
1387
		sta->ampdu_mlme.addba_req_num[tid] = 0;
1388

1389
		if (*state == HT_AGG_STATE_OPERATIONAL)
1390 1391
			ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);

1392
		spin_unlock_bh(&sta->lock);
1393
	} else {
1394
		sta->ampdu_mlme.addba_req_num[tid]++;
1395 1396
		/* this will allow the state check in stop_BA_session */
		*state = HT_AGG_STATE_OPERATIONAL;
1397
		spin_unlock_bh(&sta->lock);
1398 1399 1400
		ieee80211_stop_tx_ba_session(hw, sta->addr, tid,
					     WLAN_BACK_INITIATOR);
	}
1401 1402

addba_resp_exit:
1403
	rcu_read_unlock();
1404 1405
}

1406
void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, const u8 *da, u16 tid,
1407
			  u16 initiator, u16 reason_code)
1408
{
1409
	struct ieee80211_local *local = sdata->local;
1410 1411 1412 1413 1414
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u16 params;

E
Ester Kummer 已提交
1415
	skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1416 1417 1418

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

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

1445
	ieee80211_sta_tx(sdata, skb, 0);
1446 1447
}

1448
void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
1449
{
1450
	struct ieee80211_local *local = sdata->local;
1451 1452 1453 1454 1455 1456 1457
	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 "
1458
			"bar frame\n", sdata->dev->name);
1459 1460 1461 1462 1463
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);
	bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
	memset(bar, 0, sizeof(*bar));
1464 1465
	bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
					 IEEE80211_STYPE_BACK_REQ);
1466
	memcpy(bar->ra, ra, ETH_ALEN);
1467
	memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN);
1468 1469 1470 1471 1472 1473
	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);

1474
	ieee80211_sta_tx(sdata, skb, 0);
1475 1476
}

1477
void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid,
1478 1479
					u16 initiator, u16 reason)
{
1480
	struct ieee80211_local *local = sdata->local;
1481 1482
	struct ieee80211_hw *hw = &local->hw;
	struct sta_info *sta;
1483
	int ret, i;
1484
	DECLARE_MAC_BUF(mac);
1485

1486 1487
	rcu_read_lock();

1488
	sta = sta_info_get(local, ra);
1489 1490
	if (!sta) {
		rcu_read_unlock();
1491
		return;
1492
	}
1493 1494

	/* check if TID is in operational state */
1495
	spin_lock_bh(&sta->lock);
1496
	if (sta->ampdu_mlme.tid_state_rx[tid]
1497
				!= HT_AGG_STATE_OPERATIONAL) {
1498
		spin_unlock_bh(&sta->lock);
1499
		rcu_read_unlock();
1500 1501
		return;
	}
1502
	sta->ampdu_mlme.tid_state_rx[tid] =
1503 1504
		HT_AGG_STATE_REQ_STOP_BA_MSK |
		(initiator << HT_AGG_STATE_INITIATOR_SHIFT);
1505
	spin_unlock_bh(&sta->lock);
1506 1507 1508 1509 1510

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

1511 1512 1513 1514 1515
#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 */

1516
	ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
1517
					ra, tid, NULL);
1518 1519
	if (ret)
		printk(KERN_DEBUG "HW problem - can not stop rx "
1520
				"aggregation for tid %d\n", tid);
1521 1522 1523

	/* shutdown timer has not expired */
	if (initiator != WLAN_BACK_TIMER)
1524
		del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
1525 1526 1527

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

	/* free the reordering buffer */
1531 1532
	for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
		if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
1533
			/* release the reordered frames */
1534 1535 1536
			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;
1537 1538
		}
	}
1539 1540 1541 1542 1543
	/* 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;
1544

1545
	rcu_read_unlock();
1546 1547
}

1548

1549
static void ieee80211_sta_process_delba(struct ieee80211_sub_if_data *sdata,
1550 1551
			struct ieee80211_mgmt *mgmt, size_t len)
{
1552
	struct ieee80211_local *local = sdata->local;
1553 1554 1555 1556 1557
	struct sta_info *sta;
	u16 tid, params;
	u16 initiator;
	DECLARE_MAC_BUF(mac);

1558 1559
	rcu_read_lock();

1560
	sta = sta_info_get(local, mgmt->sa);
1561 1562
	if (!sta) {
		rcu_read_unlock();
1563
		return;
1564
	}
1565 1566 1567 1568 1569 1570 1571

	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())
1572 1573
		printk(KERN_DEBUG "delba from %s (%s) tid %d reason code %d\n",
			print_mac(mac, mgmt->sa),
1574
			initiator ? "initiator" : "recipient", tid,
1575 1576 1577 1578
			mgmt->u.action.u.delba.reason_code);
#endif /* CONFIG_MAC80211_HT_DEBUG */

	if (initiator == WLAN_BACK_INITIATOR)
1579
		ieee80211_sta_stop_rx_ba_session(sdata, sta->addr, tid,
1580
						 WLAN_BACK_INITIATOR, 0);
1581
	else { /* WLAN_BACK_RECIPIENT */
1582
		spin_lock_bh(&sta->lock);
1583
		sta->ampdu_mlme.tid_state_tx[tid] =
1584
				HT_AGG_STATE_OPERATIONAL;
1585
		spin_unlock_bh(&sta->lock);
1586 1587 1588
		ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid,
					     WLAN_BACK_RECIPIENT);
	}
1589
	rcu_read_unlock();
1590 1591
}

1592 1593 1594 1595 1596 1597 1598 1599 1600
/*
 * 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 已提交
1601
	 * flow in sta_info_create gives the TID as data, while the timer_to_id
1602
	 * array gives the sta through container_of */
1603
	u16 tid = *(u8 *)data;
1604 1605 1606 1607 1608 1609 1610 1611
	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;

1612 1613
	rcu_read_lock();

1614
	sta = sta_info_get(local, temp_sta->addr);
1615 1616
	if (!sta) {
		rcu_read_unlock();
1617
		return;
1618
	}
1619

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

1633
#ifdef CONFIG_MAC80211_HT_DEBUG
1634
	printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
1635
#endif
1636 1637 1638

	/* go through the state check in stop_BA_session */
	*state = HT_AGG_STATE_OPERATIONAL;
1639
	spin_unlock_bh(&sta->lock);
1640 1641 1642 1643
	ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid,
				     WLAN_BACK_INITIATOR);

timer_expired_exit:
1644
	rcu_read_unlock();
1645 1646
}

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

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

1671
void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data *sdata, u8 *addr)
1672
{
1673
	struct ieee80211_local *local = sdata->local;
1674 1675 1676 1677 1678
	int i;

	for (i = 0; i <  STA_TID_NUM; i++) {
		ieee80211_stop_tx_ba_session(&local->hw, addr, i,
					     WLAN_BACK_INITIATOR);
1679
		ieee80211_sta_stop_rx_ba_session(sdata, addr, i,
1680 1681 1682 1683
						 WLAN_BACK_RECIPIENT,
						 WLAN_REASON_QSTA_LEAVE_QBSS);
	}
}
1684

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

1729
	ieee80211_sta_tx(sdata, skb, 0);
1730 1731
}

1732
static void ieee80211_sta_process_measurement_req(struct ieee80211_sub_if_data *sdata,
1733 1734 1735 1736 1737 1738 1739 1740 1741 1742
						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
	 */
1743
	ieee80211_send_refuse_measurement_request(sdata,
1744 1745 1746 1747 1748 1749
			&mgmt->u.action.u.measurement.msr_elem,
			mgmt->sa, mgmt->bssid,
			mgmt->u.action.u.measurement.dialog_token);
}


1750
static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1751 1752 1753 1754 1755
				   struct ieee80211_if_sta *ifsta,
				   struct ieee80211_mgmt *mgmt,
				   size_t len)
{
	u16 auth_alg, auth_transaction, status_code;
1756
	DECLARE_MAC_BUF(mac);
1757

1758
	if (ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE &&
1759
	    sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
1760 1761
		return;

1762
	if (len < 24 + 6)
1763 1764
		return;

1765
	if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
1766
	    memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0)
1767 1768
		return;

1769
	if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
1770
	    memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0)
1771 1772 1773 1774 1775 1776
		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);

1777
	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
J
Johannes Berg 已提交
1778 1779
		/*
		 * IEEE 802.11 standard does not require authentication in IBSS
1780 1781 1782
		 * 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 已提交
1783
		 */
1784
		if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
1785
			return;
1786
		ieee80211_send_auth(sdata, ifsta, 2, NULL, 0, 0);
1787 1788 1789
	}

	if (auth_alg != ifsta->auth_alg ||
1790
	    auth_transaction != ifsta->auth_transaction)
1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818
		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 &&
1819
				    !ieee80211_sta_wep_configured(sdata))
1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830
					continue;
				ifsta->auth_alg = algs[pos];
				break;
			}
		}
		return;
	}

	switch (ifsta->auth_alg) {
	case WLAN_AUTH_OPEN:
	case WLAN_AUTH_LEAP:
1831
		ieee80211_auth_completed(sdata, ifsta);
1832 1833 1834
		break;
	case WLAN_AUTH_SHARED_KEY:
		if (ifsta->auth_transaction == 4)
1835
			ieee80211_auth_completed(sdata, ifsta);
1836
		else
1837
			ieee80211_auth_challenge(sdata, ifsta, mgmt, len);
1838 1839 1840 1841 1842
		break;
	}
}


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

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

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

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

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

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

1870
	ieee80211_set_disassoc(sdata, ifsta, true, false, 0);
1871
	ifsta->flags &= ~IEEE80211_STA_AUTHENTICATED;
1872 1873 1874
}


1875
static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1876 1877 1878 1879 1880
				       struct ieee80211_if_sta *ifsta,
				       struct ieee80211_mgmt *mgmt,
				       size_t len)
{
	u16 reason_code;
1881
	DECLARE_MAC_BUF(mac);
1882

1883
	if (len < 24 + 2)
1884 1885
		return;

1886
	if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN))
1887 1888 1889 1890
		return;

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

1891
	if (ifsta->flags & IEEE80211_STA_ASSOCIATED)
1892
		printk(KERN_DEBUG "%s: disassociated\n", sdata->dev->name);
1893

1894 1895
	if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) {
		ifsta->state = IEEE80211_STA_MLME_ASSOCIATE;
1896 1897 1898 1899
		mod_timer(&ifsta->timer, jiffies +
				      IEEE80211_RETRY_AUTH_INTERVAL);
	}

1900
	ieee80211_set_disassoc(sdata, ifsta, false, false, 0);
1901 1902 1903
}


1904
static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1905 1906 1907 1908 1909
					 struct ieee80211_if_sta *ifsta,
					 struct ieee80211_mgmt *mgmt,
					 size_t len,
					 int reassoc)
{
1910
	struct ieee80211_local *local = sdata->local;
1911
	struct ieee80211_supported_band *sband;
1912
	struct sta_info *sta;
1913
	u64 rates, basic_rates;
1914 1915
	u16 capab_info, status_code, aid;
	struct ieee802_11_elems elems;
1916
	struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
1917 1918
	u8 *pos;
	int i, j;
1919
	DECLARE_MAC_BUF(mac);
1920
	bool have_higher_than_11mbit = false;
1921 1922 1923 1924

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

1925
	if (ifsta->state != IEEE80211_STA_MLME_ASSOCIATE)
1926 1927
		return;

1928
	if (len < 24 + 6)
1929 1930
		return;

1931
	if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0)
1932 1933 1934 1935 1936 1937
		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);

1938
	printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x "
1939
	       "status=%d aid=%d)\n",
1940
	       sdata->dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa),
1941
	       capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
1942 1943 1944

	if (status_code != WLAN_STATUS_SUCCESS) {
		printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
1945
		       sdata->dev->name, status_code);
1946 1947 1948
		/* 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. */
1949
		ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
1950 1951 1952
		return;
	}

1953 1954
	if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
		printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
1955
		       "set\n", sdata->dev->name, aid);
1956 1957
	aid &= ~(BIT(15) | BIT(14));

1958
	pos = mgmt->u.assoc_resp.variable;
1959
	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1960 1961 1962

	if (!elems.supp_rates) {
		printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
1963
		       sdata->dev->name);
1964 1965 1966
		return;
	}

1967
	printk(KERN_DEBUG "%s: associated\n", sdata->dev->name);
1968 1969 1970 1971 1972
	ifsta->aid = aid;
	ifsta->ap_capab = capab_info;

	kfree(ifsta->assocresp_ies);
	ifsta->assocresp_ies_len = len - (pos - (u8 *) mgmt);
1973
	ifsta->assocresp_ies = kmalloc(ifsta->assocresp_ies_len, GFP_KERNEL);
1974 1975 1976
	if (ifsta->assocresp_ies)
		memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len);

1977 1978
	rcu_read_lock();

1979 1980 1981 1982
	/* Add STA entry for the AP */
	sta = sta_info_get(local, ifsta->bssid);
	if (!sta) {
		struct ieee80211_sta_bss *bss;
J
Johannes Berg 已提交
1983
		int err;
1984

J
Johannes Berg 已提交
1985 1986 1987
		sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC);
		if (!sta) {
			printk(KERN_DEBUG "%s: failed to alloc STA entry for"
1988
			       " the AP\n", sdata->dev->name);
1989
			rcu_read_unlock();
1990 1991
			return;
		}
1992
		bss = ieee80211_rx_bss_get(local, ifsta->bssid,
1993
					   local->hw.conf.channel->center_freq,
1994
					   ifsta->ssid, ifsta->ssid_len);
1995 1996
		if (bss) {
			sta->last_signal = bss->signal;
1997
			sta->last_qual = bss->qual;
1998
			sta->last_noise = bss->noise;
1999
			ieee80211_rx_bss_put(local, bss);
2000
		}
J
Johannes Berg 已提交
2001 2002 2003 2004

		err = sta_info_insert(sta);
		if (err) {
			printk(KERN_DEBUG "%s: failed to insert STA entry for"
2005
			       " the AP (error %d)\n", sdata->dev->name, err);
J
Johannes Berg 已提交
2006 2007 2008
			rcu_read_unlock();
			return;
		}
2009 2010
		/* update new sta with its last rx activity */
		sta->last_rx = jiffies;
2011 2012
	}

J
Johannes Berg 已提交
2013 2014 2015 2016 2017 2018 2019 2020 2021 2022
	/*
	 * 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.
	 */

2023 2024
	set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP |
			   WLAN_STA_AUTHORIZED);
2025 2026

	rates = 0;
2027 2028 2029
	basic_rates = 0;
	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];

2030 2031
	for (i = 0; i < elems.supp_rates_len; i++) {
		int rate = (elems.supp_rates[i] & 0x7f) * 5;
2032 2033 2034 2035 2036 2037

		if (rate > 110)
			have_higher_than_11mbit = true;

		for (j = 0; j < sband->n_bitrates; j++) {
			if (sband->bitrates[j].bitrate == rate)
2038
				rates |= BIT(j);
2039 2040 2041
			if (elems.supp_rates[i] & 0x80)
				basic_rates |= BIT(j);
		}
2042
	}
2043

2044 2045
	for (i = 0; i < elems.ext_supp_rates_len; i++) {
		int rate = (elems.ext_supp_rates[i] & 0x7f) * 5;
2046 2047 2048 2049 2050 2051

		if (rate > 110)
			have_higher_than_11mbit = true;

		for (j = 0; j < sband->n_bitrates; j++) {
			if (sband->bitrates[j].bitrate == rate)
2052
				rates |= BIT(j);
2053 2054 2055
			if (elems.ext_supp_rates[i] & 0x80)
				basic_rates |= BIT(j);
		}
2056
	}
2057 2058 2059 2060 2061 2062 2063 2064 2065 2066

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

2068 2069
	if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param &&
	    (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
2070 2071 2072 2073 2074 2075 2076
		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 已提交
2077
		ieee80211_handle_ht(local, 1, &sta->ht_info, &bss_info);
2078 2079
	}

2080 2081
	rate_control_rate_init(sta, local);

2082
	if (elems.wmm_param) {
2083
		set_sta_flags(sta, WLAN_STA_WME);
2084
		rcu_read_unlock();
2085
		ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
2086
					 elems.wmm_param_len);
2087 2088
	} else
		rcu_read_unlock();
2089

2090 2091
	/* set AID and assoc capability,
	 * ieee80211_set_associated() will tell the driver */
2092
	bss_conf->aid = aid;
2093
	bss_conf->assoc_capability = capab_info;
2094
	ieee80211_set_associated(sdata, ifsta);
2095

2096
	ieee80211_associated(sdata, ifsta);
2097 2098 2099 2100
}


/* Caller must hold local->sta_bss_lock */
2101
static void __ieee80211_rx_bss_hash_add(struct ieee80211_local *local,
2102 2103
					struct ieee80211_sta_bss *bss)
{
2104
	u8 hash_idx;
J
Johannes Berg 已提交
2105 2106 2107 2108

	if (bss_mesh_cfg(bss))
		hash_idx = mesh_id_hash(bss_mesh_id(bss),
					bss_mesh_id_len(bss));
2109 2110
	else
		hash_idx = STA_HASH(bss->bssid);
J
Johannes Berg 已提交
2111

2112 2113
	bss->hnext = local->sta_bss_hash[hash_idx];
	local->sta_bss_hash[hash_idx] = bss;
2114 2115 2116 2117
}


/* Caller must hold local->sta_bss_lock */
2118
static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local,
2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138
					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 *
2139
ieee80211_rx_bss_add(struct ieee80211_sub_if_data *sdata, u8 *bssid, int freq,
2140
		     u8 *ssid, u8 ssid_len)
2141
{
2142
	struct ieee80211_local *local = sdata->local;
2143 2144
	struct ieee80211_sta_bss *bss;

2145
	bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
2146 2147 2148 2149 2150
	if (!bss)
		return NULL;
	atomic_inc(&bss->users);
	atomic_inc(&bss->users);
	memcpy(bss->bssid, bssid, ETH_ALEN);
2151
	bss->freq = freq;
2152 2153 2154 2155
	if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
		memcpy(bss->ssid, ssid, ssid_len);
		bss->ssid_len = ssid_len;
	}
2156 2157 2158 2159

	spin_lock_bh(&local->sta_bss_lock);
	/* TODO: order by RSSI? */
	list_add_tail(&bss->list, &local->sta_bss_list);
2160
	__ieee80211_rx_bss_hash_add(local, bss);
2161 2162 2163 2164 2165
	spin_unlock_bh(&local->sta_bss_lock);
	return bss;
}

static struct ieee80211_sta_bss *
2166
ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
2167
		     u8 *ssid, u8 ssid_len)
2168 2169 2170 2171 2172 2173
{
	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 已提交
2174 2175
		if (!bss_mesh_cfg(bss) &&
		    !memcmp(bss->bssid, bssid, ETH_ALEN) &&
2176
		    bss->freq == freq &&
2177 2178
		    bss->ssid_len == ssid_len &&
		    (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
2179 2180 2181 2182 2183 2184 2185 2186 2187
			atomic_inc(&bss->users);
			break;
		}
		bss = bss->hnext;
	}
	spin_unlock_bh(&local->sta_bss_lock);
	return bss;
}

2188 2189
#ifdef CONFIG_MAC80211_MESH
static struct ieee80211_sta_bss *
2190
ieee80211_rx_mesh_bss_get(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
2191 2192 2193 2194 2195 2196 2197
			  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 已提交
2198 2199
		if (bss_mesh_cfg(bss) &&
		    !memcmp(bss_mesh_cfg(bss), mesh_cfg, MESH_CFG_CMP_LEN) &&
2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213
		    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 *
2214
ieee80211_rx_mesh_bss_add(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
2215
			  u8 *mesh_cfg, int mesh_config_len, int freq)
2216 2217 2218
{
	struct ieee80211_sta_bss *bss;

2219 2220 2221
	if (mesh_config_len != MESH_CFG_LEN)
		return NULL;

2222 2223 2224 2225
	bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
	if (!bss)
		return NULL;

2226
	bss->mesh_cfg = kmalloc(MESH_CFG_CMP_LEN, GFP_ATOMIC);
2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243
	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);
2244
	memcpy(bss->mesh_cfg, mesh_cfg, MESH_CFG_CMP_LEN);
2245 2246 2247 2248 2249
	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);
2250
	__ieee80211_rx_bss_hash_add(local, bss);
2251 2252 2253 2254
	spin_unlock_bh(&local->sta_bss_lock);
	return bss;
}
#endif
2255 2256 2257

static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss)
{
2258
	kfree(bss->ies);
J
Johannes Berg 已提交
2259 2260
	kfree(bss_mesh_id(bss));
	kfree(bss_mesh_cfg(bss));
2261 2262 2263 2264
	kfree(bss);
}


2265
static void ieee80211_rx_bss_put(struct ieee80211_local *local,
2266 2267
				 struct ieee80211_sta_bss *bss)
{
2268 2269 2270
	local_bh_disable();
	if (!atomic_dec_and_lock(&bss->users, &local->sta_bss_lock)) {
		local_bh_enable();
2271
		return;
2272
	}
2273

2274
	__ieee80211_rx_bss_hash_del(local, bss);
2275 2276 2277 2278 2279 2280
	list_del(&bss->list);
	spin_unlock_bh(&local->sta_bss_lock);
	ieee80211_rx_bss_free(bss);
}


2281
void ieee80211_rx_bss_list_init(struct ieee80211_local *local)
2282 2283 2284 2285 2286 2287
{
	spin_lock_init(&local->sta_bss_lock);
	INIT_LIST_HEAD(&local->sta_bss_list);
}


2288
void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local)
2289 2290 2291 2292
{
	struct ieee80211_sta_bss *bss, *tmp;

	list_for_each_entry_safe(bss, tmp, &local->sta_bss_list, list)
2293
		ieee80211_rx_bss_put(local, bss);
2294 2295 2296
}


2297
static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
2298 2299 2300
				   struct ieee80211_if_sta *ifsta,
				   struct ieee80211_sta_bss *bss)
{
2301
	struct ieee80211_local *local = sdata->local;
2302 2303 2304 2305 2306
	int res, rates, i, j;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u8 *pos;
	struct ieee80211_supported_band *sband;
2307
	union iwreq_data wrqu;
2308 2309 2310 2311

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

	/* Remove possible STA entries from other IBSS networks. */
J
Johannes Berg 已提交
2312
	sta_info_flush_delayed(sdata);
2313 2314 2315 2316 2317 2318

	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);
2319
	res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
2320 2321 2322 2323 2324 2325 2326 2327
	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;

2328
	res = ieee80211_set_freq(sdata, bss->freq);
2329

2330 2331
	if (res)
		return res;
2332

2333
	/* Build IBSS probe response */
2334
	skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
2335
	if (skb) {
2336 2337 2338 2339 2340
		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));
2341 2342
		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_PROBE_RESP);
2343
		memset(mgmt->da, 0xff, ETH_ALEN);
2344
		memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
2345 2346 2347
		memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
		mgmt->u.beacon.beacon_int =
			cpu_to_le16(local->hw.conf.beacon_int);
2348
		mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp);
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 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385
		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);
		}

2386
		ifsta->probe_resp = skb;
2387

2388 2389
		ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
	}
2390

2391 2392 2393 2394 2395 2396 2397
	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);
2398
	}
2399 2400
	ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;

2401
	ieee80211_sta_def_wmm_params(sdata, bss, 1);
2402

2403
	ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED;
2404 2405
	mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);

2406 2407
	memset(&wrqu, 0, sizeof(wrqu));
	memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN);
2408
	wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
2409 2410 2411 2412

	return res;
}

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 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448
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;
}

2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475
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;
}
2476

2477
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2478 2479 2480
				  struct ieee80211_mgmt *mgmt,
				  size_t len,
				  struct ieee80211_rx_status *rx_status,
2481
				  struct ieee802_11_elems *elems)
2482
{
2483
	struct ieee80211_local *local = sdata->local;
2484
	int freq, clen;
2485 2486
	struct ieee80211_sta_bss *bss;
	struct sta_info *sta;
2487
	struct ieee80211_channel *channel;
2488 2489
	u64 beacon_timestamp, rx_timestamp;
	u64 supp_rates = 0;
2490
	bool beacon = ieee80211_is_beacon(mgmt->frame_control);
2491
	enum ieee80211_band band = rx_status->band;
2492 2493
	DECLARE_MAC_BUF(mac);
	DECLARE_MAC_BUF(mac2);
2494

2495 2496 2497 2498 2499 2500 2501 2502 2503
	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;
2504

2505
	if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id &&
2506
	    elems->mesh_config && mesh_matches_local(elems, sdata)) {
2507
		supp_rates = ieee80211_sta_get_rates(local, elems, band);
J
Johannes Berg 已提交
2508

2509
		mesh_neighbour_update(mgmt->sa, supp_rates, sdata,
2510
				      mesh_peer_accepts_plinks(elems));
J
Johannes Berg 已提交
2511
	}
2512

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

2517 2518
		rcu_read_lock();

2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540
		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);
2541 2542
		}

2543 2544
		rcu_read_unlock();
	}
2545

2546
#ifdef CONFIG_MAC80211_MESH
2547
	if (elems->mesh_config)
2548
		bss = ieee80211_rx_mesh_bss_get(local, elems->mesh_id,
2549
				elems->mesh_id_len, elems->mesh_config, freq);
2550 2551
	else
#endif
2552
		bss = ieee80211_rx_bss_get(local, mgmt->bssid, freq,
2553
					   elems->ssid, elems->ssid_len);
2554 2555
	if (!bss) {
#ifdef CONFIG_MAC80211_MESH
2556
		if (elems->mesh_config)
2557
			bss = ieee80211_rx_mesh_bss_add(local, elems->mesh_id,
2558 2559
				elems->mesh_id_len, elems->mesh_config,
				elems->mesh_config_len, freq);
2560 2561
		else
#endif
2562
			bss = ieee80211_rx_bss_add(sdata, mgmt->bssid, freq,
2563
						  elems->ssid, elems->ssid_len);
2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574
		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
	}

2575
	/* save the ERP value so that it is available at association time */
2576 2577
	if (elems->erp_info && elems->erp_info_len >= 1) {
		bss->erp_value = elems->erp_info[0];
2578 2579 2580
		bss->has_erp_value = 1;
	}

2581 2582 2583
	bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
	bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);

2584 2585 2586 2587 2588 2589 2590 2591 2592 2593
	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;

2594
	bss->supp_rates_len = 0;
2595
	if (elems->supp_rates) {
2596
		clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
2597 2598 2599
		if (clen > elems->supp_rates_len)
			clen = elems->supp_rates_len;
		memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates,
2600 2601 2602
		       clen);
		bss->supp_rates_len += clen;
	}
2603
	if (elems->ext_supp_rates) {
2604
		clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
2605 2606
		if (clen > elems->ext_supp_rates_len)
			clen = elems->ext_supp_rates_len;
2607
		memcpy(&bss->supp_rates[bss->supp_rates_len],
2608
		       elems->ext_supp_rates, clen);
2609 2610 2611
		bss->supp_rates_len += clen;
	}

2612
	bss->band = band;
2613

2614 2615
	beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);

2616 2617 2618 2619
	bss->timestamp = beacon_timestamp;
	bss->last_update = jiffies;
	bss->signal = rx_status->signal;
	bss->noise = rx_status->noise;
2620
	bss->qual = rx_status->qual;
2621 2622
	if (!beacon)
		bss->last_probe_resp = jiffies;
2623 2624 2625 2626 2627
	/*
	 * 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 &&
2628
	    bss->last_probe_resp && beacon) {
2629
		ieee80211_rx_bss_put(local, bss);
2630 2631 2632
		return;
	}

2633 2634 2635
	if (bss->ies == NULL || bss->ies_len < elems->total_len) {
		kfree(bss->ies);
		bss->ies = kmalloc(elems->total_len, GFP_ATOMIC);
2636
	}
2637 2638 2639 2640 2641
	if (bss->ies) {
		memcpy(bss->ies, elems->ie_start, elems->total_len);
		bss->ies_len = elems->total_len;
	} else
		bss->ies_len = 0;
2642

2643
	bss->wmm_used = elems->wmm_param || elems->wmm_info;
B
Bruno Randolf 已提交
2644 2645 2646 2647

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

2701
	ieee80211_rx_bss_put(local, bss);
2702 2703 2704
}


2705
static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
2706 2707 2708 2709
					 struct ieee80211_mgmt *mgmt,
					 size_t len,
					 struct ieee80211_rx_status *rx_status)
{
2710 2711
	size_t baselen;
	struct ieee802_11_elems elems;
2712
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
2713

2714 2715 2716
	if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
		return; /* ignore ProbeResp to foreign address */

2717 2718 2719 2720 2721 2722 2723
	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);

2724 2725 2726 2727 2728 2729 2730 2731 2732
	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);
	}
2733 2734 2735
}


2736
static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2737 2738 2739 2740 2741 2742 2743
				     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;
2744
	struct ieee80211_local *local = sdata->local;
2745
	struct ieee80211_conf *conf = &local->hw.conf;
2746
	u32 changed = 0;
2747

2748 2749 2750 2751 2752 2753 2754
	/* 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);

2755
	ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
2756

2757
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
2758 2759 2760
		return;
	ifsta = &sdata->u.sta;

2761
	if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED) ||
2762 2763 2764
	    memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0)
		return;

2765
	/* Do not send changes to driver if we are scanning. This removes
2766 2767 2768 2769 2770
	 * 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.
	 */
2771 2772 2773
	if (local->sta_sw_scanning || local->sta_hw_scanning)
		return;

2774 2775 2776
	ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
				 elems.wmm_param_len);

2777
	if (elems.erp_info && elems.erp_info_len >= 1)
2778
		changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]);
2779 2780 2781 2782 2783
	else {
		u16 capab = le16_to_cpu(mgmt->u.beacon.capab_info);
		changed |= ieee80211_handle_protect_preamb(sdata, false,
				(capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);
	}
2784

2785
	if (elems.ht_cap_elem && elems.ht_info_elem &&
T
Tomas Winkler 已提交
2786
	    elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
2787 2788 2789 2790 2791
		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 已提交
2792 2793
		changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf,
					       &bss_info);
2794 2795
	}

2796
	ieee80211_bss_info_change_notify(sdata, changed);
2797 2798 2799
}


2800
static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
2801 2802 2803 2804 2805
					struct ieee80211_if_sta *ifsta,
					struct ieee80211_mgmt *mgmt,
					size_t len,
					struct ieee80211_rx_status *rx_status)
{
2806
	struct ieee80211_local *local = sdata->local;
2807 2808 2809 2810
	int tx_last_beacon;
	struct sk_buff *skb;
	struct ieee80211_mgmt *resp;
	u8 *pos, *end;
2811 2812 2813 2814 2815
	DECLARE_MAC_BUF(mac);
#ifdef CONFIG_MAC80211_IBSS_DEBUG
	DECLARE_MAC_BUF(mac2);
	DECLARE_MAC_BUF(mac3);
#endif
2816

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

	resp = (struct ieee80211_mgmt *) skb->data;
	memcpy(resp->da, mgmt->sa, ETH_ALEN);
#ifdef CONFIG_MAC80211_IBSS_DEBUG
2867
	printk(KERN_DEBUG "%s: Sending ProbeResp to %s\n",
2868
	       sdata->dev->name, print_mac(mac, resp->da));
2869
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2870
	ieee80211_sta_tx(sdata, skb, 0);
2871 2872
}

2873
static void ieee80211_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
2874 2875
				     struct ieee80211_if_sta *ifsta,
				     struct ieee80211_mgmt *mgmt,
2876 2877
				     size_t len,
				     struct ieee80211_rx_status *rx_status)
2878
{
2879
	struct ieee80211_local *local = sdata->local;
2880

2881 2882
	/* all categories we currently handle have action_code */
	if (len < IEEE80211_MIN_ACTION_SIZE + 1)
2883 2884 2885
		return;

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

2931
void ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
2932 2933
			   struct ieee80211_rx_status *rx_status)
{
2934
	struct ieee80211_local *local = sdata->local;
2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950
	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:
2951
	case IEEE80211_STYPE_ACTION:
2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966
		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);
}

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

	kfree_skb(skb);
}


3016
ieee80211_rx_result
3017
ieee80211_sta_rx_scan(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
Z
Zhu Yi 已提交
3018
		      struct ieee80211_rx_status *rx_status)
3019 3020
{
	struct ieee80211_mgmt *mgmt;
3021
	__le16 fc;
3022

Z
Zhu Yi 已提交
3023
	if (skb->len < 2)
J
Johannes Berg 已提交
3024
		return RX_DROP_UNUSABLE;
3025 3026

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

3029
	if (ieee80211_is_ctl(fc))
3030
		return RX_CONTINUE;
Z
Zhu Yi 已提交
3031 3032

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

3035
	if (ieee80211_is_probe_resp(fc)) {
3036
		ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, rx_status);
3037 3038
		dev_kfree_skb(skb);
		return RX_QUEUED;
3039
	}
3040 3041

	if (ieee80211_is_beacon(fc)) {
3042
		ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
3043 3044 3045 3046
		dev_kfree_skb(skb);
		return RX_QUEUED;
	}

3047
	return RX_CONTINUE;
3048 3049 3050
}


3051
static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
3052
{
3053
	struct ieee80211_local *local = sdata->local;
3054 3055 3056
	int active = 0;
	struct sta_info *sta;

3057 3058 3059 3060
	rcu_read_lock();

	list_for_each_entry_rcu(sta, &local->sta_list, list) {
		if (sta->sdata == sdata &&
3061 3062 3063 3064 3065 3066
		    time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL,
			       jiffies)) {
			active++;
			break;
		}
	}
3067 3068

	rcu_read_unlock();
3069 3070 3071 3072 3073

	return active;
}


3074
static void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, unsigned long exp_time)
3075
{
3076
	struct ieee80211_local *local = sdata->local;
3077
	struct sta_info *sta, *tmp;
3078
	LIST_HEAD(tmp_list);
3079
	DECLARE_MAC_BUF(mac);
3080
	unsigned long flags;
3081

3082
	spin_lock_irqsave(&local->sta_lock, flags);
3083
	list_for_each_entry_safe(sta, tmp, &local->sta_list, list)
3084
		if (time_after(jiffies, sta->last_rx + exp_time)) {
3085
#ifdef CONFIG_MAC80211_IBSS_DEBUG
3086
			printk(KERN_DEBUG "%s: expiring inactive STA %s\n",
3087
			       sdata->dev->name, print_mac(mac, sta->addr));
3088
#endif
3089
			__sta_info_unlink(&sta);
3090 3091
			if (sta)
				list_add(&sta->list, &tmp_list);
3092
		}
3093
	spin_unlock_irqrestore(&local->sta_lock, flags);
3094

3095 3096
	list_for_each_entry_safe(sta, tmp, &tmp_list, list)
		sta_info_destroy(sta);
3097 3098 3099
}


3100
static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata,
3101 3102 3103 3104
				     struct ieee80211_if_sta *ifsta)
{
	mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);

3105 3106
	ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT);
	if (ieee80211_sta_active_ibss(sdata))
3107 3108 3109
		return;

	printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
3110 3111
	       "IBSS networks with same SSID (merge)\n", sdata->dev->name);
	ieee80211_sta_req_scan(sdata, ifsta->ssid, ifsta->ssid_len);
3112 3113 3114
}


3115
#ifdef CONFIG_MAC80211_MESH
3116
static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
3117 3118 3119 3120
			   struct ieee80211_if_sta *ifsta)
{
	bool free_plinks;

3121 3122
	ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
	mesh_path_expire(sdata);
3123 3124 3125

	free_plinks = mesh_plink_availables(sdata);
	if (free_plinks != sdata->u.sta.accepting_plinks)
3126
		ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
3127 3128 3129 3130 3131 3132

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


3133
void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
3134 3135 3136
{
	struct ieee80211_if_sta *ifsta;
	ifsta = &sdata->u.sta;
3137
	ifsta->state = IEEE80211_STA_MLME_MESH_UP;
3138
	ieee80211_sta_timer((unsigned long)sdata);
L
Luis Carlos Cobo 已提交
3139
	ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
3140 3141 3142 3143
}
#endif


3144 3145 3146 3147 3148
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;
3149
	struct ieee80211_local *local = sdata->local;
3150 3151 3152 3153 3154 3155 3156 3157 3158

	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);
3159
	struct ieee80211_local *local = sdata->local;
3160 3161 3162
	struct ieee80211_if_sta *ifsta;
	struct sk_buff *skb;

3163
	if (!netif_running(sdata->dev))
3164 3165
		return;

Z
Zhu Yi 已提交
3166
	if (local->sta_sw_scanning || local->sta_hw_scanning)
3167 3168
		return;

3169 3170 3171
	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))
3172 3173 3174 3175
		return;
	ifsta = &sdata->u.sta;

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

3178
#ifdef CONFIG_MAC80211_MESH
J
Johannes Berg 已提交
3179 3180 3181
	if (ifsta->preq_queue_len &&
	    time_after(jiffies,
		       ifsta->last_preq + msecs_to_jiffies(ifsta->mshcfg.dot11MeshHWMPpreqMinInterval)))
3182
		mesh_path_start_discovery(sdata);
3183 3184
#endif

3185 3186
	if (ifsta->state != IEEE80211_STA_MLME_DIRECT_PROBE &&
	    ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE &&
3187
	    ifsta->state != IEEE80211_STA_MLME_ASSOCIATE &&
3188
	    test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) {
3189
		if (ifsta->scan_ssid_len)
3190
			ieee80211_sta_start_scan(sdata, ifsta->scan_ssid, ifsta->scan_ssid_len);
3191
		else
3192
			ieee80211_sta_start_scan(sdata, NULL, 0);
3193 3194 3195 3196
		return;
	}

	if (test_and_clear_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request)) {
3197
		if (ieee80211_sta_config_auth(sdata, ifsta))
3198 3199 3200 3201 3202 3203
			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) {
3204
	case IEEE80211_STA_MLME_DISABLED:
3205
		break;
3206 3207 3208
	case IEEE80211_STA_MLME_DIRECT_PROBE:
		ieee80211_direct_probe(sdata, ifsta);
		break;
3209
	case IEEE80211_STA_MLME_AUTHENTICATE:
3210
		ieee80211_authenticate(sdata, ifsta);
3211
		break;
3212
	case IEEE80211_STA_MLME_ASSOCIATE:
3213
		ieee80211_associate(sdata, ifsta);
3214
		break;
3215
	case IEEE80211_STA_MLME_ASSOCIATED:
3216
		ieee80211_associated(sdata, ifsta);
3217
		break;
3218
	case IEEE80211_STA_MLME_IBSS_SEARCH:
3219
		ieee80211_sta_find_ibss(sdata, ifsta);
3220
		break;
3221
	case IEEE80211_STA_MLME_IBSS_JOINED:
3222
		ieee80211_sta_merge_ibss(sdata, ifsta);
3223
		break;
3224
#ifdef CONFIG_MAC80211_MESH
3225
	case IEEE80211_STA_MLME_MESH_UP:
3226
		ieee80211_mesh_housekeeping(sdata, ifsta);
3227 3228
		break;
#endif
3229
	default:
3230
		WARN_ON(1);
3231 3232 3233
		break;
	}

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

3238 3239
		ieee80211_set_disassoc(sdata, ifsta, false, true,
					WLAN_REASON_UNSPECIFIED);
3240 3241 3242 3243
	}
}


3244
static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata,
3245 3246
				     struct ieee80211_if_sta *ifsta)
{
3247
	struct ieee80211_local *local = sdata->local;
3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265

	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;
3266
	ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
3267
	ifsta->assoc_scan_tries = 0;
3268
	ifsta->direct_probe_tries = 0;
3269 3270
	ifsta->auth_tries = 0;
	ifsta->assoc_tries = 0;
3271
	netif_carrier_off(sdata->dev);
3272 3273 3274
}


3275
void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata,
3276 3277
			    struct ieee80211_if_sta *ifsta)
{
3278
	struct ieee80211_local *local = sdata->local;
3279

3280
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
3281 3282
		return;

3283
	if ((ifsta->flags & (IEEE80211_STA_BSSID_SET |
3284
			     IEEE80211_STA_AUTO_BSSID_SEL)) &&
3285
	    (ifsta->flags & (IEEE80211_STA_SSID_SET |
3286 3287 3288 3289 3290 3291
			     IEEE80211_STA_AUTO_SSID_SEL))) {

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

3292 3293 3294 3295 3296 3297 3298 3299 3300 3301
		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;

3302 3303
	if (ssid_len == ifsta->ssid_len &&
	    !memcmp(ifsta->ssid, ssid, ssid_len))
3304 3305
		return 1;

3306
	if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL)
3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326
		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;
}

3327
static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata,
3328 3329
				     struct ieee80211_if_sta *ifsta)
{
3330
	struct ieee80211_local *local = sdata->local;
3331 3332 3333 3334
	struct ieee80211_sta_bss *bss, *selected = NULL;
	int top_rssi = 0, freq;

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

3340 3341 3342 3343 3344
		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))
3345 3346
			continue;

3347 3348
		if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) &&
		    bss->freq != freq)
3349 3350
			continue;

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

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

3359
		if (!selected || top_rssi < bss->signal) {
3360
			selected = bss;
3361
			top_rssi = bss->signal;
3362 3363 3364 3365 3366 3367 3368
		}
	}
	if (selected)
		atomic_inc(&selected->users);
	spin_unlock_bh(&local->sta_bss_lock);

	if (selected) {
3369
		ieee80211_set_freq(sdata, selected->freq);
3370
		if (!(ifsta->flags & IEEE80211_STA_SSID_SET))
3371
			ieee80211_sta_set_ssid(sdata, selected->ssid,
3372
					       selected->ssid_len);
3373 3374
		ieee80211_sta_set_bssid(sdata, selected->bssid);
		ieee80211_sta_def_wmm_params(sdata, selected, 0);
3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385

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

3386
		ieee80211_rx_bss_put(local, selected);
3387
		ieee80211_sta_reset_auth(sdata, ifsta);
3388 3389
		return 0;
	} else {
3390 3391
		if (ifsta->assoc_scan_tries < IEEE80211_ASSOC_SCANS_MAX_TRIES) {
			ifsta->assoc_scan_tries++;
3392
			if (ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL)
3393
				ieee80211_sta_start_scan(sdata, NULL, 0);
3394
			else
3395
				ieee80211_sta_start_scan(sdata, ifsta->ssid,
3396
							 ifsta->ssid_len);
3397
			ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
3398 3399
			set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
		} else
3400
			ifsta->state = IEEE80211_STA_MLME_DISABLED;
3401 3402 3403 3404 3405
	}
	return -1;
}


3406
static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
3407 3408
				     struct ieee80211_if_sta *ifsta)
{
3409
	struct ieee80211_local *local = sdata->local;
3410
	struct ieee80211_sta_bss *bss;
3411
	struct ieee80211_supported_band *sband;
3412 3413
	u8 bssid[ETH_ALEN], *pos;
	int i;
3414
	int ret;
3415
	DECLARE_MAC_BUF(mac);
3416 3417 3418 3419 3420 3421 3422 3423 3424 3425

#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++)
3426
		bssid[i] ^= sdata->dev->dev_addr[i];
3427 3428 3429 3430
	bssid[0] &= ~0x01;
	bssid[0] |= 0x02;
#endif

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

3434
	bss = ieee80211_rx_bss_add(sdata, bssid,
3435
				   local->hw.conf.channel->center_freq,
3436
				   sdata->u.sta.ssid, sdata->u.sta.ssid_len);
3437 3438 3439
	if (!bss)
		return -ENOMEM;

3440 3441
	bss->band = local->hw.conf.channel->band;
	sband = local->hw.wiphy->bands[bss->band];
3442 3443

	if (local->hw.conf.beacon_int == 0)
3444
		local->hw.conf.beacon_int = 100;
3445 3446 3447
	bss->beacon_int = local->hw.conf.beacon_int;
	bss->last_update = jiffies;
	bss->capability = WLAN_CAPABILITY_IBSS;
J
Johannes Berg 已提交
3448 3449

	if (sdata->default_key)
3450
		bss->capability |= WLAN_CAPABILITY_PRIVACY;
J
Johannes Berg 已提交
3451
	else
3452
		sdata->drop_unencrypted = 0;
J
Johannes Berg 已提交
3453

3454
	bss->supp_rates_len = sband->n_bitrates;
3455
	pos = bss->supp_rates;
3456 3457
	for (i = 0; i < sband->n_bitrates; i++) {
		int rate = sband->bitrates[i].bitrate;
3458 3459 3460
		*pos++ = (u8) (rate / 5);
	}

3461
	ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
3462
	ieee80211_rx_bss_put(local, bss);
3463
	return ret;
3464 3465 3466
}


3467
static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
3468 3469
				   struct ieee80211_if_sta *ifsta)
{
3470
	struct ieee80211_local *local = sdata->local;
3471 3472 3473 3474
	struct ieee80211_sta_bss *bss;
	int found = 0;
	u8 bssid[ETH_ALEN];
	int active_ibss;
3475 3476
	DECLARE_MAC_BUF(mac);
	DECLARE_MAC_BUF(mac2);
3477 3478 3479 3480

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

3481
	active_ibss = ieee80211_sta_active_ibss(sdata);
3482 3483
#ifdef CONFIG_MAC80211_IBSS_DEBUG
	printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n",
3484
	       sdata->dev->name, active_ibss);
3485 3486 3487 3488 3489 3490 3491 3492
#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
3493 3494
		printk(KERN_DEBUG "   bssid=%s found\n",
		       print_mac(mac, bss->bssid));
3495 3496 3497 3498 3499 3500 3501 3502 3503
#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
3504 3505 3506 3507
	if (found)
		printk(KERN_DEBUG "   sta_find_ibss: selected %s current "
		       "%s\n", print_mac(mac, bssid),
		       print_mac(mac2, ifsta->bssid));
3508
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
3509 3510

	if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) {
3511
		int ret;
3512 3513 3514 3515 3516 3517 3518
		int search_freq;

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

3519
		bss = ieee80211_rx_bss_get(local, bssid, search_freq,
3520 3521 3522 3523
					   ifsta->ssid, ifsta->ssid_len);
		if (!bss)
			goto dont_join;

3524
		printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
3525
		       " based on configured SSID\n",
3526 3527
		       sdata->dev->name, print_mac(mac, bssid));
		ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
3528
		ieee80211_rx_bss_put(local, bss);
3529
		return ret;
3530
	}
3531 3532

dont_join:
3533 3534 3535 3536 3537
#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 */
3538
	if (ifsta->state == IEEE80211_STA_MLME_IBSS_JOINED &&
3539
	    !ieee80211_sta_active_ibss(sdata)) {
3540 3541 3542 3543 3544
		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 "
3545 3546
		       "join\n", sdata->dev->name);
		return ieee80211_sta_req_scan(sdata, ifsta->ssid,
3547
					      ifsta->ssid_len);
3548
	} else if (ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED) {
3549 3550 3551 3552
		int interval = IEEE80211_SCAN_INTERVAL;

		if (time_after(jiffies, ifsta->ibss_join_req +
			       IEEE80211_IBSS_JOIN_TIMEOUT)) {
3553
			if ((ifsta->flags & IEEE80211_STA_CREATE_IBSS) &&
3554 3555
			    (!(local->oper_channel->flags &
					IEEE80211_CHAN_NO_IBSS)))
3556
				return ieee80211_sta_create_ibss(sdata, ifsta);
3557
			if (ifsta->flags & IEEE80211_STA_CREATE_IBSS) {
3558
				printk(KERN_DEBUG "%s: IBSS not allowed on"
3559
				       " %d MHz\n", sdata->dev->name,
3560
				       local->hw.conf.channel->center_freq);
3561 3562 3563 3564 3565 3566 3567
			}

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

3568
		ifsta->state = IEEE80211_STA_MLME_IBSS_SEARCH;
3569 3570 3571 3572 3573 3574 3575 3576
		mod_timer(&ifsta->timer, jiffies + interval);
		return 0;
	}

	return 0;
}


3577
int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
3578 3579
{
	struct ieee80211_if_sta *ifsta;
3580
	int res;
3581 3582 3583 3584 3585 3586

	if (len > IEEE80211_MAX_SSID_LEN)
		return -EINVAL;

	ifsta = &sdata->u.sta;

3587 3588 3589 3590
	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;
3591
		ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
3592 3593 3594 3595 3596 3597 3598 3599 3600 3601

		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 "
3602
			       "the low-level driver\n", sdata->dev->name);
3603 3604 3605
			return res;
		}
	}
3606

3607 3608 3609 3610
	if (len)
		ifsta->flags |= IEEE80211_STA_SSID_SET;
	else
		ifsta->flags &= ~IEEE80211_STA_SSID_SET;
3611

3612
	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
3613
	    !(ifsta->flags & IEEE80211_STA_BSSID_SET)) {
3614
		ifsta->ibss_join_req = jiffies;
3615
		ifsta->state = IEEE80211_STA_MLME_IBSS_SEARCH;
3616
		return ieee80211_sta_find_ibss(sdata, ifsta);
3617
	}
3618

3619 3620 3621 3622
	return 0;
}


3623
int ieee80211_sta_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len)
3624 3625 3626 3627 3628 3629 3630 3631
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
	memcpy(ssid, ifsta->ssid, ifsta->ssid_len);
	*len = ifsta->ssid_len;
	return 0;
}


3632
int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
3633 3634 3635 3636 3637 3638 3639 3640
{
	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);
3641 3642 3643 3644 3645 3646
		res = 0;
		/*
		 * Hack! See also ieee80211_sta_set_ssid.
		 */
		if (netif_running(sdata->dev))
			res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
3647 3648
		if (res) {
			printk(KERN_DEBUG "%s: Failed to config new BSSID to "
3649
			       "the low-level driver\n", sdata->dev->name);
3650 3651 3652 3653
			return res;
		}
	}

3654 3655
	if (is_valid_ether_addr(bssid))
		ifsta->flags |= IEEE80211_STA_BSSID_SET;
3656
	else
3657 3658
		ifsta->flags &= ~IEEE80211_STA_BSSID_SET;

3659 3660 3661 3662 3663 3664 3665 3666 3667 3668
	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;
3669
	__le16 fc;
3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680

	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);
3681 3682
	fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
			 IEEE80211_FCTL_TODS);
3683
	if (powersave)
3684 3685
		fc |= cpu_to_le16(IEEE80211_FCTL_PM);
	nullfunc->frame_control = fc;
3686 3687 3688 3689
	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);

3690
	ieee80211_sta_tx(sdata, skb, 0);
3691 3692 3693
}


3694 3695 3696 3697 3698 3699 3700
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);
}

3701 3702 3703 3704 3705 3706 3707 3708
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 已提交
3709 3710
	memset(&wrqu, 0, sizeof(wrqu));
	wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
3711

Z
Zhu Yi 已提交
3712 3713
	if (local->sta_hw_scanning) {
		local->sta_hw_scanning = 0;
3714 3715 3716
		if (ieee80211_hw_config(local))
			printk(KERN_DEBUG "%s: failed to restore operational "
			       "channel after scan\n", dev->name);
3717 3718 3719 3720 3721 3722
		/* 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 已提交
3723 3724 3725 3726
		goto done;
	}

	local->sta_sw_scanning = 0;
3727
	if (ieee80211_hw_config(local))
3728
		printk(KERN_DEBUG "%s: failed to restore operational "
3729 3730
		       "channel after scan\n", dev->name);

3731 3732

	netif_tx_lock_bh(local->mdev);
3733
	netif_addr_lock(local->mdev);
3734 3735 3736 3737 3738 3739 3740
	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);

3741
	netif_addr_unlock(local->mdev);
3742
	netif_tx_unlock_bh(local->mdev);
3743

3744 3745
	rcu_read_lock();
	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
3746 3747 3748 3749
		/* 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);
3750

3751
		ieee80211_restart_sta_timer(sdata);
3752

3753 3754
		netif_wake_queue(sdata->dev);
	}
3755
	rcu_read_unlock();
3756

Z
Zhu Yi 已提交
3757
done:
3758
	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3759
	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
3760
		struct ieee80211_if_sta *ifsta = &sdata->u.sta;
3761
		if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) ||
3762
		    (!(ifsta->state == IEEE80211_STA_MLME_IBSS_JOINED) &&
3763 3764
		    !ieee80211_sta_active_ibss(sdata)))
			ieee80211_sta_find_ibss(sdata, ifsta);
3765 3766 3767 3768 3769 3770 3771 3772 3773 3774
	}
}
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);
3775
	struct ieee80211_supported_band *sband;
3776 3777 3778 3779
	struct ieee80211_channel *chan;
	int skip;
	unsigned long next_delay = 0;

Z
Zhu Yi 已提交
3780
	if (!local->sta_sw_scanning)
3781 3782 3783 3784
		return;

	switch (local->scan_state) {
	case SCAN_SET_CHANNEL:
3785 3786 3787 3788 3789
		/*
		 * 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)
		 */
3790 3791 3792 3793 3794
		if (local->scan_band < IEEE80211_NUM_BANDS)
			sband = local->hw.wiphy->bands[local->scan_band];
		else
			sband = NULL;

3795 3796 3797 3798 3799
		/*
		 * 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) {
3800 3801 3802 3803 3804
			local->scan_band++;
			sband = local->hw.wiphy->bands[local->scan_band];
			local->scan_channel_idx = 0;
		}

3805 3806
		/* if no more bands/channels left, complete scan */
		if (!sband || local->scan_channel_idx >= sband->n_channels) {
3807 3808 3809
			ieee80211_scan_completed(local_to_hw(local));
			return;
		}
3810 3811 3812 3813
		skip = 0;
		chan = &sband->channels[local->scan_channel_idx];

		if (chan->flags & IEEE80211_CHAN_DISABLED ||
3814
		    (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
3815
		     chan->flags & IEEE80211_CHAN_NO_IBSS))
3816 3817 3818 3819 3820
			skip = 1;

		if (!skip) {
			local->scan_channel = chan;
			if (ieee80211_hw_config(local)) {
3821 3822 3823
				printk(KERN_DEBUG "%s: failed to set freq to "
				       "%d MHz for scan\n", dev->name,
				       chan->center_freq);
3824 3825 3826 3827
				skip = 1;
			}
		}

3828
		/* advance state machine to next channel/band */
3829
		local->scan_channel_idx++;
3830
		if (local->scan_channel_idx >= sband->n_channels) {
3831 3832 3833 3834 3835
			/*
			 * scan_band may end up == IEEE80211_NUM_BANDS, but
			 * we'll catch that case above and complete the scan
			 * if that is the case.
			 */
3836 3837
			local->scan_band++;
			local->scan_channel_idx = 0;
3838 3839 3840 3841 3842 3843 3844 3845 3846 3847
		}

		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:
3848
		next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
3849
		local->scan_state = SCAN_SET_CHANNEL;
3850 3851 3852

		if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN)
			break;
3853
		ieee80211_send_probe_req(sdata, NULL, local->scan_ssid,
3854 3855
					 local->scan_ssid_len);
		next_delay = IEEE80211_CHANNEL_TIME;
3856 3857 3858
		break;
	}

Z
Zhu Yi 已提交
3859
	if (local->sta_sw_scanning)
3860 3861 3862 3863 3864
		queue_delayed_work(local->hw.workqueue, &local->scan_work,
				   next_delay);
}


3865
static int ieee80211_sta_start_scan(struct ieee80211_sub_if_data *scan_sdata,
3866 3867
				    u8 *ssid, size_t ssid_len)
{
3868
	struct ieee80211_local *local = scan_sdata->local;
3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890
	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 已提交
3891
	if (local->sta_sw_scanning || local->sta_hw_scanning) {
3892
		if (local->scan_dev == scan_sdata->dev)
3893 3894 3895 3896 3897 3898
			return 0;
		return -EBUSY;
	}

	if (local->ops->hw_scan) {
		int rc = local->ops->hw_scan(local_to_hw(local),
Z
Zhu Yi 已提交
3899
					     ssid, ssid_len);
3900
		if (!rc) {
Z
Zhu Yi 已提交
3901
			local->sta_hw_scanning = 1;
3902
			local->scan_dev = scan_sdata->dev;
3903 3904 3905 3906
		}
		return rc;
	}

Z
Zhu Yi 已提交
3907
	local->sta_sw_scanning = 1;
3908

3909 3910
	rcu_read_lock();
	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
3911
		netif_stop_queue(sdata->dev);
3912
		if (sdata->vif.type == IEEE80211_IF_TYPE_STA &&
3913
		    (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED))
3914 3915
			ieee80211_send_nullfunc(local, sdata, 1);
	}
3916
	rcu_read_unlock();
3917 3918 3919 3920 3921 3922 3923 3924

	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;
3925
	local->scan_band = IEEE80211_BAND_2GHZ;
3926
	local->scan_dev = scan_sdata->dev;
3927

3928
	netif_addr_lock_bh(local->mdev);
3929 3930 3931 3932 3933 3934
	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);
3935
	netif_addr_unlock_bh(local->mdev);
3936 3937 3938 3939 3940 3941 3942 3943 3944

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


3945
int ieee80211_sta_req_scan(struct ieee80211_sub_if_data *sdata, u8 *ssid, size_t ssid_len)
3946 3947
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
3948
	struct ieee80211_local *local = sdata->local;
3949

3950
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
3951
		return ieee80211_sta_start_scan(sdata, ssid, ssid_len);
3952

Z
Zhu Yi 已提交
3953
	if (local->sta_sw_scanning || local->sta_hw_scanning) {
3954
		if (local->scan_dev == sdata->dev)
3955 3956 3957 3958
			return 0;
		return -EBUSY;
	}

3959 3960 3961
	ifsta->scan_ssid_len = ssid_len;
	if (ssid_len)
		memcpy(ifsta->scan_ssid, ssid, ssid_len);
3962 3963 3964 3965 3966
	set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request);
	queue_work(local->hw.workqueue, &ifsta->work);
	return 0;
}

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 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008

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


4009
static char *
4010
ieee80211_sta_scan_result(struct ieee80211_local *local,
4011
			  struct iw_request_info *info,
4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024
			  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);
4025
	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4026 4027 4028 4029
					  IW_EV_ADDR_LEN);

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWESSID;
J
Johannes Berg 已提交
4030 4031
	if (bss_mesh_cfg(bss)) {
		iwe.u.data.length = bss_mesh_id_len(bss);
4032
		iwe.u.data.flags = 1;
4033 4034
		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
						  &iwe, bss_mesh_id(bss));
4035 4036 4037
	} else {
		iwe.u.data.length = bss->ssid_len;
		iwe.u.data.flags = 1;
4038 4039
		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
						  &iwe, bss->ssid);
4040
	}
4041

4042 4043
	if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
	    || bss_mesh_cfg(bss)) {
4044 4045
		memset(&iwe, 0, sizeof(iwe));
		iwe.cmd = SIOCGIWMODE;
J
Johannes Berg 已提交
4046
		if (bss_mesh_cfg(bss))
4047 4048
			iwe.u.mode = IW_MODE_MESH;
		else if (bss->capability & WLAN_CAPABILITY_ESS)
4049 4050 4051
			iwe.u.mode = IW_MODE_MASTER;
		else
			iwe.u.mode = IW_MODE_ADHOC;
4052 4053
		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
						  &iwe, IW_EV_UINT_LEN);
4054 4055 4056 4057
	}

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWFREQ;
4058 4059
	iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq);
	iwe.u.freq.e = 0;
4060
	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4061
					  IW_EV_FREQ_LEN);
4062 4063 4064

	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWFREQ;
4065 4066
	iwe.u.freq.m = bss->freq;
	iwe.u.freq.e = 6;
4067
	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4068 4069 4070
					  IW_EV_FREQ_LEN);
	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = IWEVQUAL;
4071 4072
	iwe.u.qual.qual = bss->qual;
	iwe.u.qual.level = bss->signal;
4073 4074
	iwe.u.qual.noise = bss->noise;
	iwe.u.qual.updated = local->wstats_flags;
4075
	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4076 4077 4078 4079 4080 4081 4082 4083 4084
					  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;
4085 4086
	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
					  &iwe, "");
4087

4088
	ieee80211_sta_add_scan_ies(info, bss, &current_ev, end_buf);
4089

4090 4091
	if (bss && bss->supp_rates_len > 0) {
		/* display all supported rates in readable format */
4092
		char *p = current_ev + iwe_stream_lcp_len(info);
4093 4094 4095 4096 4097 4098 4099 4100 4101 4102
		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);
4103
			p = iwe_stream_add_value(info, current_ev, p,
4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116
					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);
4117 4118
			current_ev = iwe_stream_add_point(info, current_ev,
							  end_buf,
4119
							  &iwe, buf);
4120 4121 4122 4123 4124 4125 4126
			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);
4127 4128 4129 4130
			kfree(buf);
		}
	}

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

4175 4176 4177 4178
	return current_ev;
}


4179
int ieee80211_sta_scan_results(struct ieee80211_local *local,
4180 4181
			       struct iw_request_info *info,
			       char *buf, size_t len)
4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192
{
	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;
		}
4193
		current_ev = ieee80211_sta_scan_result(local, info, bss,
4194
						       current_ev, end_buf);
4195 4196 4197 4198 4199 4200
	}
	spin_unlock_bh(&local->sta_bss_lock);
	return current_ev - buf;
}


4201
int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, char *ie, size_t len)
4202 4203
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;
J
Johannes Berg 已提交
4204

4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221
	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;
}


4222
struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
J
Johannes Berg 已提交
4223
					struct sk_buff *skb, u8 *bssid,
4224
					u8 *addr, u64 supp_rates)
4225
{
4226
	struct ieee80211_local *local = sdata->local;
4227
	struct sta_info *sta;
4228
	DECLARE_MAC_BUF(mac);
4229
	int band = local->hw.conf.channel->band;
4230 4231 4232 4233 4234 4235

	/* 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 "
4236
			       "entry %s\n", sdata->dev->name, print_mac(mac, addr));
4237 4238 4239 4240
		}
		return NULL;
	}

4241
	if (compare_ether_addr(bssid, sdata->u.sta.bssid))
4242 4243
		return NULL;

4244
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
4245
	printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n",
4246
	       wiphy_name(local->hw.wiphy), print_mac(mac, addr), sdata->dev->name);
4247
#endif
4248

J
Johannes Berg 已提交
4249 4250
	sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
	if (!sta)
4251 4252
		return NULL;

4253
	set_sta_flags(sta, WLAN_STA_AUTHORIZED);
4254

4255 4256 4257
	/* make sure mandatory rates are always added */
	sta->supp_rates[band] = supp_rates |
			ieee80211_sta_get_mandatory_rates(local, band);
4258 4259 4260

	rate_control_rate_init(sta, local);

4261
	if (sta_info_insert(sta))
J
Johannes Berg 已提交
4262 4263
		return NULL;

4264
	return sta;
4265 4266 4267
}


4268
int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason)
4269 4270 4271
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;

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

4275 4276
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA &&
	    sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
4277 4278
		return -EINVAL;

4279
	ieee80211_set_disassoc(sdata, ifsta, true, true, reason);
4280 4281 4282 4283
	return 0;
}


4284
int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason)
4285 4286 4287
{
	struct ieee80211_if_sta *ifsta = &sdata->u.sta;

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

4291
	if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
4292 4293
		return -EINVAL;

4294
	if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED))
4295 4296
		return -1;

4297
	ieee80211_set_disassoc(sdata, ifsta, false, true, reason);
4298 4299
	return 0;
}
4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310

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) {
4311 4312
			if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
				continue;
4313

4314
			ieee80211_sta_req_auth(sdata, &sdata->u.sta);
4315 4316 4317 4318 4319 4320
		}
		rcu_read_unlock();
		break;
	}
}
EXPORT_SYMBOL(ieee80211_notify_mac);