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

14
#include <linux/delay.h>
15 16 17 18
#include <linux/if_ether.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
19
#include <linux/rtnetlink.h>
20
#include <linux/pm_qos_params.h>
21
#include <linux/crc32.h>
22
#include <linux/slab.h>
23
#include <net/mac80211.h>
24
#include <asm/unaligned.h>
J
Johannes Berg 已提交
25

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

31
#define IEEE80211_MAX_NULLFUNC_TRIES 2
32
#define IEEE80211_MAX_PROBE_TRIES 5
J
Johannes Berg 已提交
33 34

/*
35 36 37 38 39 40
 * Beacon loss timeout is calculated as N frames times the
 * advertised beacon interval.  This may need to be somewhat
 * higher than what hardware might detect to account for
 * delays in the host processing frames. But since we also
 * probe on beacon miss before declaring the connection lost
 * default to what we want.
J
Johannes Berg 已提交
41
 */
42 43
#define IEEE80211_BEACON_LOSS_COUNT	7

J
Johannes Berg 已提交
44 45 46 47
/*
 * Time the connection can be idle before we probe
 * it to see if we can still talk to the AP.
 */
48
#define IEEE80211_CONNECTION_IDLE_TIME	(30 * HZ)
J
Johannes Berg 已提交
49 50 51 52 53
/*
 * Time we wait for a probe response after sending
 * a probe request because of beacon loss or for
 * checking the connection still works.
 */
54
#define IEEE80211_PROBE_WAIT		(HZ / 2)
55

56 57 58 59 60 61 62
/*
 * Weight given to the latest Beacon frame when calculating average signal
 * strength for Beacon frames received in the current BSS. This must be
 * between 1 and 15.
 */
#define IEEE80211_SIGNAL_AVE_WEIGHT	3

63 64 65 66 67 68
/*
 * How many Beacon frames need to have been used in average signal strength
 * before starting to indicate signal change events.
 */
#define IEEE80211_SIGNAL_AVE_MIN_COUNT	4

69 70 71
#define TMR_RUNNING_TIMER	0
#define TMR_RUNNING_CHANSW	1

72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
/*
 * All cfg80211 functions have to be called outside a locked
 * section so that they can acquire a lock themselves... This
 * is much simpler than queuing up things in cfg80211, but we
 * do need some indirection for that here.
 */
enum rx_mgmt_action {
	/* no action required */
	RX_MGMT_NONE,

	/* caller must call cfg80211_send_rx_auth() */
	RX_MGMT_CFG80211_AUTH,

	/* caller must call cfg80211_send_rx_assoc() */
	RX_MGMT_CFG80211_ASSOC,

	/* caller must call cfg80211_send_deauth() */
	RX_MGMT_CFG80211_DEAUTH,

	/* caller must call cfg80211_send_disassoc() */
	RX_MGMT_CFG80211_DISASSOC,

94 95
	/* caller must tell cfg80211 about internal error */
	RX_MGMT_CFG80211_ASSOC_ERROR,
96 97
};

98
/* utils */
99 100
static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
{
101
	lockdep_assert_held(&ifmgd->mtx);
102 103
}

J
Johannes Berg 已提交
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
/*
 * We can have multiple work items (and connection probing)
 * scheduling this timer, but we need to take care to only
 * reschedule it when it should fire _earlier_ than it was
 * asked for before, or if it's not pending right now. This
 * function ensures that. Note that it then is required to
 * run this function for all timeouts after the first one
 * has happened -- the work that runs from this timer will
 * do that.
 */
static void run_again(struct ieee80211_if_managed *ifmgd,
			     unsigned long timeout)
{
	ASSERT_MGD_MTX(ifmgd);

	if (!timer_pending(&ifmgd->timer) ||
	    time_before(timeout, ifmgd->timer.expires))
		mod_timer(&ifmgd->timer, timeout);
}

124
void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
J
Johannes Berg 已提交
125 126 127 128 129
{
	if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER)
		return;

	mod_timer(&sdata->u.mgd.bcn_mon_timer,
130
		  round_jiffies_up(jiffies + sdata->u.mgd.beacon_timeout));
J
Johannes Berg 已提交
131 132
}

133 134
void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
{
135 136
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

137 138 139 140 141
	if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
		return;

	mod_timer(&sdata->u.mgd.conn_mon_timer,
		  round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
142 143

	ifmgd->probe_send_count = 0;
144 145
}

146
static int ecw2cw(int ecw)
J
Johannes Berg 已提交
147
{
148
	return (1 << ecw) - 1;
J
Johannes Berg 已提交
149 150
}

151 152 153 154 155 156 157
/*
 * ieee80211_enable_ht should be called only after the operating band
 * has been determined as ht configuration depends on the hw's
 * HT abilities for a specific band.
 */
static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
			       struct ieee80211_ht_info *hti,
158
			       const u8 *bssid, u16 ap_ht_cap_flags)
159 160 161 162 163
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_supported_band *sband;
	struct sta_info *sta;
	u32 changed = 0;
164
	u16 ht_opmode;
165 166
	bool enable_ht = true;
	enum nl80211_channel_type prev_chantype;
167 168 169 170
	enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;

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

171 172
	prev_chantype = sdata->vif.bss_conf.channel_type;

173 174 175 176 177 178
	/* HT is not supported */
	if (!sband->ht_cap.ht_supported)
		enable_ht = false;

	/* check that channel matches the right operating channel */
	if (local->hw.conf.channel->center_freq !=
179
	    ieee80211_channel_to_frequency(hti->control_chan, sband->band))
180 181 182 183 184 185 186 187 188 189
		enable_ht = false;

	if (enable_ht) {
		channel_type = NL80211_CHAN_HT20;

		if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
		    (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
		    (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
			switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
			case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
190 191 192
				if (!(local->hw.conf.channel->flags &
				    IEEE80211_CHAN_NO_HT40PLUS))
					channel_type = NL80211_CHAN_HT40PLUS;
193 194
				break;
			case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
195 196 197
				if (!(local->hw.conf.channel->flags &
				    IEEE80211_CHAN_NO_HT40MINUS))
					channel_type = NL80211_CHAN_HT40MINUS;
198 199 200 201 202
				break;
			}
		}
	}

203 204
	if (local->tmp_channel)
		local->tmp_channel_type = channel_type;
205

206 207 208 209 210
	if (!ieee80211_set_channel_type(local, sdata, channel_type)) {
		/* can only fail due to HT40+/- mismatch */
		channel_type = NL80211_CHAN_HT20;
		WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type));
	}
211

212 213
	/* channel_type change automatically detected */
	ieee80211_hw_config(local, 0);
214

215
	if (prev_chantype != channel_type) {
216
		rcu_read_lock();
217
		sta = sta_info_get(sdata, bssid);
218 219
		if (sta)
			rate_control_rate_update(local, sband, sta,
220
						 IEEE80211_RC_HT_CHANGED,
221
						 channel_type);
222
		rcu_read_unlock();
223
	}
224

225
	ht_opmode = le16_to_cpu(hti->operation_mode);
226 227

	/* if bss configuration changed store the new one */
228 229 230
	if (sdata->ht_opmode_valid != enable_ht ||
	    sdata->vif.bss_conf.ht_operation_mode != ht_opmode ||
	    prev_chantype != channel_type) {
231
		changed |= BSS_CHANGED_HT;
232
		sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
233
		sdata->ht_opmode_valid = enable_ht;
234 235 236 237 238
	}

	return changed;
}

J
Johannes Berg 已提交
239 240
/* frame sending functions */

241
static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
J
Johannes Berg 已提交
242
					   const u8 *bssid, u16 stype, u16 reason,
243
					   void *cookie, bool send_frame)
244 245
{
	struct ieee80211_local *local = sdata->local;
246
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
247 248
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
249

250
	skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt));
251
	if (!skb) {
252
		printk(KERN_DEBUG "%s: failed to allocate buffer for "
253
		       "deauth/disassoc frame\n", sdata->name);
254 255 256 257 258 259
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
	memset(mgmt, 0, 24);
260
	memcpy(mgmt->da, bssid, ETH_ALEN);
261
	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
262
	memcpy(mgmt->bssid, bssid, ETH_ALEN);
263
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
264
	skb_put(skb, 2);
265
	/* u.deauth.reason_code == u.disassoc.reason_code */
266 267
	mgmt->u.deauth.reason_code = cpu_to_le16(reason);

268
	if (stype == IEEE80211_STYPE_DEAUTH)
269 270 271 272
		if (cookie)
			__cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
		else
			cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
273
	else
274 275 276 277
		if (cookie)
			__cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
		else
			cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
278 279
	if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
		IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
280 281 282 283 284

	if (send_frame)
		ieee80211_tx_skb(sdata, skb);
	else
		kfree_skb(skb);
285 286
}

287 288 289 290 291 292
void ieee80211_send_pspoll(struct ieee80211_local *local,
			   struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_pspoll *pspoll;
	struct sk_buff *skb;

293 294
	skb = ieee80211_pspoll_get(&local->hw, &sdata->vif);
	if (!skb)
295 296
		return;

297 298
	pspoll = (struct ieee80211_pspoll *) skb->data;
	pspoll->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
299

300 301
	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
	ieee80211_tx_skb(sdata, skb);
302 303
}

304 305 306 307 308
void ieee80211_send_nullfunc(struct ieee80211_local *local,
			     struct ieee80211_sub_if_data *sdata,
			     int powersave)
{
	struct sk_buff *skb;
309
	struct ieee80211_hdr_3addr *nullfunc;
310

311 312
	skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif);
	if (!skb)
313 314
		return;

315
	nullfunc = (struct ieee80211_hdr_3addr *) skb->data;
316
	if (powersave)
317
		nullfunc->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
318

319 320
	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
	ieee80211_tx_skb(sdata, skb);
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 354
static void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local,
					  struct ieee80211_sub_if_data *sdata)
{
	struct sk_buff *skb;
	struct ieee80211_hdr *nullfunc;
	__le16 fc;

	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
		return;

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

	nullfunc = (struct ieee80211_hdr *) skb_put(skb, 30);
	memset(nullfunc, 0, 30);
	fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
			 IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
	nullfunc->frame_control = fc;
	memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN);
	memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
	memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN);
	memcpy(nullfunc->addr4, sdata->vif.addr, ETH_ALEN);

	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
	ieee80211_tx_skb(sdata, skb);
}

355 356 357 358 359 360 361
/* spectrum management related things */
static void ieee80211_chswitch_work(struct work_struct *work)
{
	struct ieee80211_sub_if_data *sdata =
		container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

362
	if (!ieee80211_sdata_running(sdata))
363 364
		return;

365 366 367
	mutex_lock(&ifmgd->mtx);
	if (!ifmgd->associated)
		goto out;
368 369

	sdata->local->oper_channel = sdata->local->csa_channel;
370 371 372 373 374
	if (!sdata->local->ops->channel_switch) {
		/* call "hw_config" only if doing sw channel switch */
		ieee80211_hw_config(sdata->local,
			IEEE80211_CONF_CHANGE_CHANNEL);
	}
375

376
	/* XXX: shouldn't really modify cfg80211-owned data! */
377
	ifmgd->associated->channel = sdata->local->oper_channel;
378 379 380

	ieee80211_wake_queues_by_reason(&sdata->local->hw,
					IEEE80211_QUEUE_STOP_REASON_CSA);
381 382 383
 out:
	ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
	mutex_unlock(&ifmgd->mtx);
384 385
}

386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
{
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_if_managed *ifmgd;

	sdata = vif_to_sdata(vif);
	ifmgd = &sdata->u.mgd;

	trace_api_chswitch_done(sdata, success);
	if (!success) {
		/*
		 * If the channel switch was not successful, stay
		 * around on the old channel. We currently lack
		 * good handling of this situation, possibly we
		 * should just drop the association.
		 */
		sdata->local->csa_channel = sdata->local->oper_channel;
	}

	ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
}
EXPORT_SYMBOL(ieee80211_chswitch_done);

409 410 411 412 413 414
static void ieee80211_chswitch_timer(unsigned long data)
{
	struct ieee80211_sub_if_data *sdata =
		(struct ieee80211_sub_if_data *) data;
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

415 416 417 418 419
	if (sdata->local->quiescing) {
		set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
		return;
	}

420
	ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
421 422 423 424
}

void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
				      struct ieee80211_channel_sw_ie *sw_elem,
425 426
				      struct ieee80211_bss *bss,
				      u64 timestamp)
427
{
428 429
	struct cfg80211_bss *cbss =
		container_of((void *)bss, struct cfg80211_bss, priv);
430 431
	struct ieee80211_channel *new_ch;
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
432 433
	int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
						      cbss->channel->band);
434

435 436 437
	ASSERT_MGD_MTX(ifmgd);

	if (!ifmgd->associated)
438 439
		return;

440
	if (sdata->local->scanning)
441 442 443 444 445 446 447 448 449 450 451 452 453 454
		return;

	/* Disregard subsequent beacons if we are already running a timer
	   processing a CSA */

	if (ifmgd->flags & IEEE80211_STA_CSA_RECEIVED)
		return;

	new_ch = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq);
	if (!new_ch || new_ch->flags & IEEE80211_CHAN_DISABLED)
		return;

	sdata->local->csa_channel = new_ch;

455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
	if (sdata->local->ops->channel_switch) {
		/* use driver's channel switch callback */
		struct ieee80211_channel_switch ch_switch;
		memset(&ch_switch, 0, sizeof(ch_switch));
		ch_switch.timestamp = timestamp;
		if (sw_elem->mode) {
			ch_switch.block_tx = true;
			ieee80211_stop_queues_by_reason(&sdata->local->hw,
					IEEE80211_QUEUE_STOP_REASON_CSA);
		}
		ch_switch.channel = new_ch;
		ch_switch.count = sw_elem->count;
		ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
		drv_channel_switch(sdata->local, &ch_switch);
		return;
	}

	/* channel switch handled in software */
473
	if (sw_elem->count <= 1) {
474
		ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
475
	} else {
476 477
		if (sw_elem->mode)
			ieee80211_stop_queues_by_reason(&sdata->local->hw,
478 479 480 481 482
					IEEE80211_QUEUE_STOP_REASON_CSA);
		ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
		mod_timer(&ifmgd->chswitch_timer,
			  jiffies +
			  msecs_to_jiffies(sw_elem->count *
483
					   cbss->beacon_interval));
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506
	}
}

static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
					u16 capab_info, u8 *pwr_constr_elem,
					u8 pwr_constr_elem_len)
{
	struct ieee80211_conf *conf = &sdata->local->hw.conf;

	if (!(capab_info & WLAN_CAPABILITY_SPECTRUM_MGMT))
		return;

	/* Power constraint IE length should be 1 octet */
	if (pwr_constr_elem_len != 1)
		return;

	if ((*pwr_constr_elem <= conf->channel->max_power) &&
	    (*pwr_constr_elem != sdata->local->power_constr_level)) {
		sdata->local->power_constr_level = *pwr_constr_elem;
		ieee80211_hw_config(sdata->local, 0);
	}
}

507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif)
{
	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_conf *conf = &local->hw.conf;

	WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
		!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) ||
		(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS));

	local->disable_dynamic_ps = false;
	conf->dynamic_ps_timeout = local->dynamic_ps_user_timeout;
}
EXPORT_SYMBOL(ieee80211_enable_dyn_ps);

void ieee80211_disable_dyn_ps(struct ieee80211_vif *vif)
{
	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_conf *conf = &local->hw.conf;

	WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
		!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) ||
		(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS));

	local->disable_dynamic_ps = true;
	conf->dynamic_ps_timeout = 0;
	del_timer_sync(&local->dynamic_ps_timer);
	ieee80211_queue_work(&local->hw,
			     &local->dynamic_ps_enable_work);
}
EXPORT_SYMBOL(ieee80211_disable_dyn_ps);

540 541 542 543 544 545
/* powersave */
static void ieee80211_enable_ps(struct ieee80211_local *local,
				struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_conf *conf = &local->hw.conf;

J
Johannes Berg 已提交
546 547 548 549
	/*
	 * If we are scanning right now then the parameters will
	 * take effect when scan finishes.
	 */
550
	if (local->scanning)
J
Johannes Berg 已提交
551 552
		return;

553 554 555 556 557 558 559
	if (conf->dynamic_ps_timeout > 0 &&
	    !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) {
		mod_timer(&local->dynamic_ps_timer, jiffies +
			  msecs_to_jiffies(conf->dynamic_ps_timeout));
	} else {
		if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
			ieee80211_send_nullfunc(local, sdata, 1);
560

561 562 563 564 565 566
		if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
		    (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
			return;

		conf->flags |= IEEE80211_CONF_PS;
		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584
	}
}

static void ieee80211_change_ps(struct ieee80211_local *local)
{
	struct ieee80211_conf *conf = &local->hw.conf;

	if (local->ps_sdata) {
		ieee80211_enable_ps(local, local->ps_sdata);
	} else if (conf->flags & IEEE80211_CONF_PS) {
		conf->flags &= ~IEEE80211_CONF_PS;
		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
		del_timer_sync(&local->dynamic_ps_timer);
		cancel_work_sync(&local->dynamic_ps_enable_work);
	}
}

/* need to hold RTNL or interface lock */
585
void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
586 587 588
{
	struct ieee80211_sub_if_data *sdata, *found = NULL;
	int count = 0;
589
	int timeout;
590 591 592 593 594 595

	if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) {
		local->ps_sdata = NULL;
		return;
	}

J
Johannes Berg 已提交
596 597 598 599 600
	if (!list_empty(&local->work_list)) {
		local->ps_sdata = NULL;
		goto change;
	}

601
	list_for_each_entry(sdata, &local->interfaces, list) {
602
		if (!ieee80211_sdata_running(sdata))
603
			continue;
604 605 606 607 608 609 610 611
		if (sdata->vif.type == NL80211_IFTYPE_AP) {
			/* If an AP vif is found, then disable PS
			 * by setting the count to zero thereby setting
			 * ps_sdata to NULL.
			 */
			count = 0;
			break;
		}
612 613 614 615 616 617
		if (sdata->vif.type != NL80211_IFTYPE_STATION)
			continue;
		found = sdata;
		count++;
	}

618
	if (count == 1 && found->u.mgd.powersave &&
J
Johannes Berg 已提交
619
	    found->u.mgd.associated &&
620
	    found->u.mgd.associated->beacon_ies &&
J
Johannes Berg 已提交
621 622
	    !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
				    IEEE80211_STA_CONNECTION_POLL))) {
623
		struct ieee80211_conf *conf = &local->hw.conf;
624 625 626
		s32 beaconint_us;

		if (latency < 0)
M
Mark Gross 已提交
627
			latency = pm_qos_request(PM_QOS_NETWORK_LATENCY);
628 629 630 631

		beaconint_us = ieee80211_tu_to_usec(
					found->vif.bss_conf.beacon_int);

632
		timeout = local->dynamic_ps_forced_timeout;
633 634
		if (timeout < 0) {
			/*
635 636
			 * Go to full PSM if the user configures a very low
			 * latency requirement.
637 638 639
			 * The 2000 second value is there for compatibility
			 * until the PM_QOS_NETWORK_LATENCY is configured
			 * with real values.
640
			 */
641 642
			if (latency > (1900 * USEC_PER_MSEC) &&
			    latency != (2000 * USEC_PER_SEC))
643
				timeout = 0;
644 645
			else
				timeout = 100;
646
		}
647 648 649 650
		local->dynamic_ps_user_timeout = timeout;
		if (!local->disable_dynamic_ps)
			conf->dynamic_ps_timeout =
				local->dynamic_ps_user_timeout;
651

652
		if (beaconint_us > latency) {
653
			local->ps_sdata = NULL;
654
		} else {
655
			struct ieee80211_bss *bss;
656
			int maxslp = 1;
657
			u8 dtimper;
658

659 660 661 662 663 664 665
			bss = (void *)found->u.mgd.associated->priv;
			dtimper = bss->dtim_period;

			/* If the TIM IE is invalid, pretend the value is 1 */
			if (!dtimper)
				dtimper = 1;
			else if (dtimper > 1)
666 667 668
				maxslp = min_t(int, dtimper,
						    latency / beaconint_us);

669
			local->hw.conf.max_sleep_period = maxslp;
670
			local->hw.conf.ps_dtim_period = dtimper;
671
			local->ps_sdata = found;
672
		}
673
	} else {
674
		local->ps_sdata = NULL;
675
	}
676

J
Johannes Berg 已提交
677
 change:
678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701
	ieee80211_change_ps(local);
}

void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
{
	struct ieee80211_local *local =
		container_of(work, struct ieee80211_local,
			     dynamic_ps_disable_work);

	if (local->hw.conf.flags & IEEE80211_CONF_PS) {
		local->hw.conf.flags &= ~IEEE80211_CONF_PS;
		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
	}

	ieee80211_wake_queues_by_reason(&local->hw,
					IEEE80211_QUEUE_STOP_REASON_PS);
}

void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
{
	struct ieee80211_local *local =
		container_of(work, struct ieee80211_local,
			     dynamic_ps_enable_work);
	struct ieee80211_sub_if_data *sdata = local->ps_sdata;
702
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
703 704 705 706 707 708 709 710

	/* can only happen when PS was just disabled anyway */
	if (!sdata)
		return;

	if (local->hw.conf.flags & IEEE80211_CONF_PS)
		return;

711 712
	if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
	    (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)))
713 714
		ieee80211_send_nullfunc(local, sdata, 1);

715 716
	if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
	      (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) ||
717 718 719 720 721
	    (ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
		ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
		local->hw.conf.flags |= IEEE80211_CONF_PS;
		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
	}
722 723 724 725 726 727
}

void ieee80211_dynamic_ps_timer(unsigned long data)
{
	struct ieee80211_local *local = (void *) data;

728
	if (local->quiescing || local->suspended)
729 730
		return;

731
	ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work);
732 733
}

J
Johannes Berg 已提交
734
/* MLME */
735
static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
736
				     struct ieee80211_sub_if_data *sdata,
737 738 739
				     u8 *wmm_param, size_t wmm_param_len)
{
	struct ieee80211_tx_queue_params params;
740
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
741 742
	size_t left;
	int count;
K
Kalle Valo 已提交
743
	u8 *pos, uapsd_queues = 0;
744

745 746 747
	if (!local->ops->conf_tx)
		return;

J
Johannes Berg 已提交
748
	if (local->hw.queues < 4)
749 750 751 752 753
		return;

	if (!wmm_param)
		return;

754 755
	if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
		return;
K
Kalle Valo 已提交
756 757

	if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED)
758
		uapsd_queues = local->uapsd_queues;
K
Kalle Valo 已提交
759

760
	count = wmm_param[6] & 0x0f;
761
	if (count == ifmgd->wmm_last_param_set)
762
		return;
763
	ifmgd->wmm_last_param_set = count;
764 765 766 767 768 769 770 771 772 773

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

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

	local->wmm_acm = 0;
	for (; left >= 4; left -= 4, pos += 4) {
		int aci = (pos[0] >> 5) & 0x03;
		int acm = (pos[0] >> 4) & 0x01;
K
Kalle Valo 已提交
774
		bool uapsd = false;
775 776 777
		int queue;

		switch (aci) {
778
		case 1: /* AC_BK */
J
Johannes Berg 已提交
779
			queue = 3;
J
Johannes Berg 已提交
780
			if (acm)
781
				local->wmm_acm |= BIT(1) | BIT(2); /* BK/- */
K
Kalle Valo 已提交
782 783
			if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
				uapsd = true;
784
			break;
785
		case 2: /* AC_VI */
J
Johannes Berg 已提交
786
			queue = 1;
J
Johannes Berg 已提交
787
			if (acm)
788
				local->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
K
Kalle Valo 已提交
789 790
			if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
				uapsd = true;
791
			break;
792
		case 3: /* AC_VO */
J
Johannes Berg 已提交
793
			queue = 0;
J
Johannes Berg 已提交
794
			if (acm)
795
				local->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
K
Kalle Valo 已提交
796 797
			if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
				uapsd = true;
798
			break;
799
		case 0: /* AC_BE */
800
		default:
J
Johannes Berg 已提交
801
			queue = 2;
J
Johannes Berg 已提交
802
			if (acm)
803
				local->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
K
Kalle Valo 已提交
804 805
			if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
				uapsd = true;
806 807 808 809 810 811
			break;
		}

		params.aifs = pos[0] & 0x0f;
		params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4);
		params.cw_min = ecw2cw(pos[1] & 0x0f);
812
		params.txop = get_unaligned_le16(pos + 2);
K
Kalle Valo 已提交
813 814
		params.uapsd = uapsd;

815
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
J
Joe Perches 已提交
816 817 818 819 820 821
		wiphy_debug(local->hw.wiphy,
			    "WMM queue=%d aci=%d acm=%d aifs=%d "
			    "cWmin=%d cWmax=%d txop=%d uapsd=%d\n",
			    queue, aci, acm,
			    params.aifs, params.cw_min, params.cw_max,
			    params.txop, params.uapsd);
822
#endif
823
		if (drv_conf_tx(local, queue, &params))
J
Joe Perches 已提交
824 825 826
			wiphy_debug(local->hw.wiphy,
				    "failed to set TX queue parameters for queue %d\n",
				    queue);
827
	}
828 829

	/* enable WMM or activate new settings */
830 831
	sdata->vif.bss_conf.qos = true;
	ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS);
832 833
}

J
Johannes Berg 已提交
834 835
static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
					   u16 capab, bool erp_valid, u8 erp)
836
{
J
Johannes Berg 已提交
837
	struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
838
	u32 changed = 0;
J
Johannes Berg 已提交
839 840 841 842 843 844 845 846 847 848 849 850 851
	bool use_protection;
	bool use_short_preamble;
	bool use_short_slot;

	if (erp_valid) {
		use_protection = (erp & WLAN_ERP_USE_PROTECTION) != 0;
		use_short_preamble = (erp & WLAN_ERP_BARKER_PREAMBLE) == 0;
	} else {
		use_protection = false;
		use_short_preamble = !!(capab & WLAN_CAPABILITY_SHORT_PREAMBLE);
	}

	use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
852 853
	if (sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ)
		use_short_slot = true;
854

855 856 857
	if (use_protection != bss_conf->use_cts_prot) {
		bss_conf->use_cts_prot = use_protection;
		changed |= BSS_CHANGED_ERP_CTS_PROT;
858
	}
859

860 861
	if (use_short_preamble != bss_conf->use_short_preamble) {
		bss_conf->use_short_preamble = use_short_preamble;
862
		changed |= BSS_CHANGED_ERP_PREAMBLE;
863
	}
864

J
Johannes Berg 已提交
865 866 867
	if (use_short_slot != bss_conf->use_short_slot) {
		bss_conf->use_short_slot = use_short_slot;
		changed |= BSS_CHANGED_ERP_SLOT;
868 869 870 871 872
	}

	return changed;
}

873
static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
874
				     struct cfg80211_bss *cbss,
J
Johannes Berg 已提交
875
				     u32 bss_info_changed)
876
{
877
	struct ieee80211_bss *bss = (void *)cbss->priv;
878
	struct ieee80211_local *local = sdata->local;
879
	struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
880

J
Johannes Berg 已提交
881
	bss_info_changed |= BSS_CHANGED_ASSOC;
882
	/* set timing information */
883 884
	bss_conf->beacon_int = cbss->beacon_interval;
	bss_conf->timestamp = cbss->tsf;
885

886 887
	bss_info_changed |= BSS_CHANGED_BEACON_INT;
	bss_info_changed |= ieee80211_handle_bss_capability(sdata,
888
		cbss->capability, bss->has_erp_value, bss->erp_value);
889

890 891 892
	sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec(
		IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int));

893 894
	sdata->u.mgd.associated = cbss;
	memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
895

896 897
	sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;

J
Johannes Berg 已提交
898 899 900 901
	/* just to be sure */
	sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
				IEEE80211_STA_BEACON_POLL);

902
	ieee80211_led_assoc(local, 1);
903

904 905 906 907 908
	if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD)
		bss_conf->dtim_period = bss->dtim_period;
	else
		bss_conf->dtim_period = 0;

909
	bss_conf->assoc = 1;
910 911 912 913 914
	/*
	 * For now just always ask the driver to update the basic rateset
	 * when we have associated, we aren't checking whether it actually
	 * changed or not.
	 */
J
Johannes Berg 已提交
915
	bss_info_changed |= BSS_CHANGED_BASIC_RATES;
916 917 918 919

	/* And the BSSID changed - we're associated now */
	bss_info_changed |= BSS_CHANGED_BSSID;

920 921
	/* Tell the driver to monitor connection quality (if supported) */
	if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) &&
922
	    bss_conf->cqm_rssi_thold)
923 924
		bss_info_changed |= BSS_CHANGED_CQM;

925 926 927 928 929 930
	/* Enable ARP filtering */
	if (bss_conf->arp_filter_enabled != sdata->arp_filter_state) {
		bss_conf->arp_filter_enabled = sdata->arp_filter_state;
		bss_info_changed |= BSS_CHANGED_ARP_FILTER;
	}

J
Johannes Berg 已提交
931
	ieee80211_bss_info_change_notify(sdata, bss_info_changed);
932

J
Johannes Berg 已提交
933 934
	mutex_lock(&local->iflist_mtx);
	ieee80211_recalc_ps(local, -1);
935
	ieee80211_recalc_smps(local);
J
Johannes Berg 已提交
936
	mutex_unlock(&local->iflist_mtx);
937

938
	netif_tx_start_all_queues(sdata->dev);
939
	netif_carrier_on(sdata->dev);
940 941
}

942
static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
943
				   bool remove_sta, bool tx)
944
{
945
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
946 947
	struct ieee80211_local *local = sdata->local;
	struct sta_info *sta;
948
	u32 changed = 0, config_changed = 0;
J
Johannes Berg 已提交
949
	u8 bssid[ETH_ALEN];
950

951 952
	ASSERT_MGD_MTX(ifmgd);

J
Johannes Berg 已提交
953 954 955
	if (WARN_ON(!ifmgd->associated))
		return;

956
	memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
J
Johannes Berg 已提交
957

958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973
	ifmgd->associated = NULL;
	memset(ifmgd->bssid, 0, ETH_ALEN);

	/*
	 * we need to commit the associated = NULL change because the
	 * scan code uses that to determine whether this iface should
	 * go to/wake up from powersave or not -- and could otherwise
	 * wake the queues erroneously.
	 */
	smp_mb();

	/*
	 * Thus, we can only afterwards stop the queues -- to account
	 * for the case where another CPU is finishing a scan at this
	 * time -- we don't want the scan code to enable queues.
	 */
974

975
	netif_tx_stop_all_queues(sdata->dev);
976 977
	netif_carrier_off(sdata->dev);

978
	mutex_lock(&local->sta_mtx);
979
	sta = sta_info_get(sdata, bssid);
980
	if (sta) {
981
		set_sta_flags(sta, WLAN_STA_BLOCK_BA);
982
		ieee80211_sta_tear_down_BA_sessions(sta, tx);
983
	}
984
	mutex_unlock(&local->sta_mtx);
985

986 987 988
	changed |= ieee80211_reset_erp_info(sdata);

	ieee80211_led_assoc(local, 0);
J
Johannes Berg 已提交
989 990
	changed |= BSS_CHANGED_ASSOC;
	sdata->vif.bss_conf.assoc = false;
991

992 993
	ieee80211_set_wmm_default(sdata);

994
	/* channel(_type) changes are handled by ieee80211_hw_config */
995
	WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
996

997 998 999
	/* on the next assoc, re-program HT parameters */
	sdata->ht_opmode_valid = false;

1000 1001
	local->power_constr_level = 0;

1002 1003 1004
	del_timer_sync(&local->dynamic_ps_timer);
	cancel_work_sync(&local->dynamic_ps_enable_work);

1005 1006 1007 1008
	if (local->hw.conf.flags & IEEE80211_CONF_PS) {
		local->hw.conf.flags &= ~IEEE80211_CONF_PS;
		config_changed |= IEEE80211_CONF_CHANGE_PS;
	}
J
Johannes Berg 已提交
1009

1010
	ieee80211_hw_config(local, config_changed);
1011

1012 1013 1014 1015 1016 1017
	/* Disable ARP filtering */
	if (sdata->vif.bss_conf.arp_filter_enabled) {
		sdata->vif.bss_conf.arp_filter_enabled = false;
		changed |= BSS_CHANGED_ARP_FILTER;
	}

1018 1019
	/* The BSSID (not really interesting) and HT changed */
	changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
J
Johannes Berg 已提交
1020
	ieee80211_bss_info_change_notify(sdata, changed);
1021

1022 1023
	if (remove_sta)
		sta_info_destroy_addr(sdata, bssid);
1024 1025 1026 1027 1028

	del_timer_sync(&sdata->u.mgd.conn_mon_timer);
	del_timer_sync(&sdata->u.mgd.bcn_mon_timer);
	del_timer_sync(&sdata->u.mgd.timer);
	del_timer_sync(&sdata->u.mgd.chswitch_timer);
1029
}
1030

1031 1032 1033 1034 1035 1036 1037 1038
void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
			     struct ieee80211_hdr *hdr)
{
	/*
	 * We can postpone the mgd.timer whenever receiving unicast frames
	 * from AP because we know that the connection is working both ways
	 * at that time. But multicast frames (and hence also beacons) must
	 * be ignored here, because we need to trigger the timer during
J
Johannes Berg 已提交
1039 1040
	 * data idle periods for sending the periodic probe request to the
	 * AP we're connected to.
1041
	 */
J
Johannes Berg 已提交
1042 1043 1044
	if (is_multicast_ether_addr(hdr->addr1))
		return;

1045
	ieee80211_sta_reset_conn_monitor(sdata);
1046
}
1047

1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077
static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

	if (!(ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
			      IEEE80211_STA_CONNECTION_POLL)))
	    return;

	ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
			  IEEE80211_STA_BEACON_POLL);
	mutex_lock(&sdata->local->iflist_mtx);
	ieee80211_recalc_ps(sdata->local, -1);
	mutex_unlock(&sdata->local->iflist_mtx);

	if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
		return;

	/*
	 * We've received a probe response, but are not sure whether
	 * we have or will be receiving any beacons or data, so let's
	 * schedule the timers again, just in case.
	 */
	ieee80211_sta_reset_beacon_monitor(sdata);

	mod_timer(&ifmgd->conn_mon_timer,
		  round_jiffies_up(jiffies +
				   IEEE80211_CONNECTION_IDLE_TIME));
}

void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
1078
			     struct ieee80211_hdr *hdr, bool ack)
1079
{
F
Felix Fietkau 已提交
1080
	if (!ieee80211_is_data(hdr->frame_control))
1081 1082
	    return;

1083 1084
	if (ack)
		ieee80211_sta_reset_conn_monitor(sdata);
1085 1086 1087

	if (ieee80211_is_nullfunc(hdr->frame_control) &&
	    sdata->u.mgd.probe_send_count > 0) {
1088 1089 1090 1091
		if (ack)
			sdata->u.mgd.probe_send_count = 0;
		else
			sdata->u.mgd.nullfunc_failed = true;
1092 1093 1094 1095
		ieee80211_queue_work(&sdata->local->hw, &sdata->work);
	}
}

1096 1097 1098 1099
static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
	const u8 *ssid;
1100 1101 1102 1103 1104 1105 1106 1107 1108 1109
	u8 *dst = ifmgd->associated->bssid;
	u8 unicast_limit = max(1, IEEE80211_MAX_PROBE_TRIES - 3);

	/*
	 * Try sending broadcast probe requests for the last three
	 * probe requests after the first ones failed since some
	 * buggy APs only support broadcast probe requests.
	 */
	if (ifmgd->probe_send_count >= unicast_limit)
		dst = NULL;
1110

1111 1112 1113 1114 1115 1116 1117
	/*
	 * When the hardware reports an accurate Tx ACK status, it's
	 * better to send a nullfunc frame instead of a probe request,
	 * as it will kick us off the AP quickly if we aren't associated
	 * anymore. The timeout will be reset if the frame is ACKed by
	 * the AP.
	 */
1118 1119
	if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
		ifmgd->nullfunc_failed = false;
1120
		ieee80211_send_nullfunc(sdata->local, sdata, 0);
1121
	} else {
1122 1123 1124
		ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
		ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0);
	}
1125 1126 1127 1128 1129 1130

	ifmgd->probe_send_count++;
	ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
	run_again(ifmgd, ifmgd->probe_timeout);
}

J
Johannes Berg 已提交
1131 1132
static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
				   bool beacon)
1133 1134
{
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
J
Johannes Berg 已提交
1135
	bool already = false;
1136

1137
	if (!ieee80211_sdata_running(sdata))
1138 1139
		return;

1140 1141 1142
	if (sdata->local->scanning)
		return;

1143 1144 1145
	if (sdata->local->tmp_channel)
		return;

1146 1147 1148 1149 1150
	mutex_lock(&ifmgd->mtx);

	if (!ifmgd->associated)
		goto out;

1151
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
J
Johannes Berg 已提交
1152 1153
	if (beacon && net_ratelimit())
		printk(KERN_DEBUG "%s: detected beacon loss from AP "
1154
		       "- sending probe request\n", sdata->name);
1155
#endif
1156

J
Johannes Berg 已提交
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179
	/*
	 * The driver/our work has already reported this event or the
	 * connection monitoring has kicked in and we have already sent
	 * a probe request. Or maybe the AP died and the driver keeps
	 * reporting until we disassociate...
	 *
	 * In either case we have to ignore the current call to this
	 * function (except for setting the correct probe reason bit)
	 * because otherwise we would reset the timer every time and
	 * never check whether we received a probe response!
	 */
	if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
			    IEEE80211_STA_CONNECTION_POLL))
		already = true;

	if (beacon)
		ifmgd->flags |= IEEE80211_STA_BEACON_POLL;
	else
		ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL;

	if (already)
		goto out;

1180 1181 1182 1183
	mutex_lock(&sdata->local->iflist_mtx);
	ieee80211_recalc_ps(sdata->local, -1);
	mutex_unlock(&sdata->local->iflist_mtx);

1184 1185
	ifmgd->probe_send_count = 0;
	ieee80211_mgd_probe_ap_send(sdata);
1186 1187
 out:
	mutex_unlock(&ifmgd->mtx);
1188 1189
}

1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213
struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
					  struct ieee80211_vif *vif)
{
	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
	struct sk_buff *skb;
	const u8 *ssid;

	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
		return NULL;

	ASSERT_MGD_MTX(ifmgd);

	if (!ifmgd->associated)
		return NULL;

	ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
	skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid,
					ssid + 2, ssid[1], NULL, 0);

	return skb;
}
EXPORT_SYMBOL(ieee80211_ap_probereq_get);

1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229
static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
	struct ieee80211_local *local = sdata->local;
	u8 bssid[ETH_ALEN];

	mutex_lock(&ifmgd->mtx);
	if (!ifmgd->associated) {
		mutex_unlock(&ifmgd->mtx);
		return;
	}

	memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);

	printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid);

1230
	ieee80211_set_disassoc(sdata, true, true);
1231
	mutex_unlock(&ifmgd->mtx);
1232 1233 1234 1235

	mutex_lock(&local->mtx);
	ieee80211_recalc_idle(local);
	mutex_unlock(&local->mtx);
1236 1237 1238 1239 1240 1241 1242
	/*
	 * must be outside lock due to cfg80211,
	 * but that's not a problem.
	 */
	ieee80211_send_deauth_disassoc(sdata, bssid,
				       IEEE80211_STYPE_DEAUTH,
				       WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
1243
				       NULL, true);
1244 1245 1246
}

void ieee80211_beacon_connection_loss_work(struct work_struct *work)
J
Johannes Berg 已提交
1247 1248 1249
{
	struct ieee80211_sub_if_data *sdata =
		container_of(work, struct ieee80211_sub_if_data,
1250
			     u.mgd.beacon_connection_loss_work);
J
Johannes Berg 已提交
1251

1252 1253 1254 1255
	if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
		__ieee80211_connection_loss(sdata);
	else
		ieee80211_mgd_probe_ap(sdata, true);
J
Johannes Berg 已提交
1256 1257
}

1258 1259 1260
void ieee80211_beacon_loss(struct ieee80211_vif *vif)
{
	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1261
	struct ieee80211_hw *hw = &sdata->local->hw;
1262

J
Johannes Berg 已提交
1263 1264
	trace_api_beacon_loss(sdata);

1265 1266
	WARN_ON(hw->flags & IEEE80211_HW_CONNECTION_MONITOR);
	ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
1267 1268 1269
}
EXPORT_SYMBOL(ieee80211_beacon_loss);

1270 1271 1272 1273 1274
void ieee80211_connection_loss(struct ieee80211_vif *vif)
{
	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
	struct ieee80211_hw *hw = &sdata->local->hw;

J
Johannes Berg 已提交
1275 1276
	trace_api_connection_loss(sdata);

1277 1278 1279 1280 1281 1282
	WARN_ON(!(hw->flags & IEEE80211_HW_CONNECTION_MONITOR));
	ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
}
EXPORT_SYMBOL(ieee80211_connection_loss);


1283 1284 1285
static enum rx_mgmt_action __must_check
ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
			 struct ieee80211_mgmt *mgmt, size_t len)
1286
{
1287
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1288
	const u8 *bssid = NULL;
1289 1290
	u16 reason_code;

1291
	if (len < 24 + 2)
1292
		return RX_MGMT_NONE;
1293

1294 1295
	ASSERT_MGD_MTX(ifmgd);

1296
	bssid = ifmgd->associated->bssid;
1297 1298 1299

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

1300
	printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
1301
			sdata->name, bssid, reason_code);
1302

1303
	ieee80211_set_disassoc(sdata, true, false);
1304
	mutex_lock(&sdata->local->mtx);
1305
	ieee80211_recalc_idle(sdata->local);
1306
	mutex_unlock(&sdata->local->mtx);
1307

1308
	return RX_MGMT_CFG80211_DEAUTH;
1309 1310 1311
}


1312 1313 1314
static enum rx_mgmt_action __must_check
ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
			   struct ieee80211_mgmt *mgmt, size_t len)
1315
{
1316
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1317 1318
	u16 reason_code;

1319
	if (len < 24 + 2)
1320
		return RX_MGMT_NONE;
1321

1322 1323 1324 1325 1326
	ASSERT_MGD_MTX(ifmgd);

	if (WARN_ON(!ifmgd->associated))
		return RX_MGMT_NONE;

1327
	if (WARN_ON(memcmp(ifmgd->associated->bssid, mgmt->sa, ETH_ALEN)))
1328
		return RX_MGMT_NONE;
1329 1330 1331

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

1332
	printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
1333
			sdata->name, mgmt->sa, reason_code);
1334

1335
	ieee80211_set_disassoc(sdata, true, false);
1336
	mutex_lock(&sdata->local->mtx);
1337
	ieee80211_recalc_idle(sdata->local);
1338
	mutex_unlock(&sdata->local->mtx);
1339
	return RX_MGMT_CFG80211_DISASSOC;
1340 1341 1342
}


J
Johannes Berg 已提交
1343 1344
static bool ieee80211_assoc_success(struct ieee80211_work *wk,
				    struct ieee80211_mgmt *mgmt, size_t len)
1345
{
J
Johannes Berg 已提交
1346
	struct ieee80211_sub_if_data *sdata = wk->sdata;
1347
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1348
	struct ieee80211_local *local = sdata->local;
1349
	struct ieee80211_supported_band *sband;
1350
	struct sta_info *sta;
1351
	struct cfg80211_bss *cbss = wk->assoc.bss;
J
Johannes Berg 已提交
1352
	u8 *pos;
1353
	u32 rates, basic_rates;
J
Johannes Berg 已提交
1354
	u16 capab_info, aid;
1355
	struct ieee802_11_elems elems;
J
Johannes Berg 已提交
1356
	struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
J
Johannes Berg 已提交
1357
	u32 changed = 0;
1358 1359
	int i, j, err;
	bool have_higher_than_11mbit = false;
J
Johannes Berg 已提交
1360
	u16 ap_ht_cap_flags;
1361

J
Johannes Berg 已提交
1362
	/* AssocResp and ReassocResp have identical structure */
1363 1364

	aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
J
Johannes Berg 已提交
1365
	capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
1366

1367 1368
	if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
		printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
1369
		       "set\n", sdata->name, aid);
1370 1371
	aid &= ~(BIT(15) | BIT(14));

J
Johannes Berg 已提交
1372 1373 1374
	pos = mgmt->u.assoc_resp.variable;
	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);

1375 1376
	if (!elems.supp_rates) {
		printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
1377
		       sdata->name);
J
Johannes Berg 已提交
1378
		return false;
1379 1380
	}

1381
	ifmgd->aid = aid;
1382

1383
	sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL);
1384
	if (!sta) {
1385 1386
		printk(KERN_DEBUG "%s: failed to alloc STA entry for"
		       " the AP\n", sdata->name);
J
Johannes Berg 已提交
1387
		return false;
1388
	}
1389

1390 1391 1392 1393 1394
	set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC |
			   WLAN_STA_ASSOC_AP);
	if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
		set_sta_flags(sta, WLAN_STA_AUTHORIZED);

J
Johannes Berg 已提交
1395 1396
	rates = 0;
	basic_rates = 0;
1397
	sband = local->hw.wiphy->bands[wk->chan->band];
1398

J
Johannes Berg 已提交
1399 1400
	for (i = 0; i < elems.supp_rates_len; i++) {
		int rate = (elems.supp_rates[i] & 0x7f) * 5;
1401
		bool is_basic = !!(elems.supp_rates[i] & 0x80);
1402

J
Johannes Berg 已提交
1403 1404 1405 1406
		if (rate > 110)
			have_higher_than_11mbit = true;

		for (j = 0; j < sband->n_bitrates; j++) {
1407
			if (sband->bitrates[j].bitrate == rate) {
J
Johannes Berg 已提交
1408
				rates |= BIT(j);
1409 1410 1411 1412
				if (is_basic)
					basic_rates |= BIT(j);
				break;
			}
1413 1414 1415
		}
	}

J
Johannes Berg 已提交
1416 1417
	for (i = 0; i < elems.ext_supp_rates_len; i++) {
		int rate = (elems.ext_supp_rates[i] & 0x7f) * 5;
1418
		bool is_basic = !!(elems.ext_supp_rates[i] & 0x80);
1419

J
Johannes Berg 已提交
1420 1421
		if (rate > 110)
			have_higher_than_11mbit = true;
1422

J
Johannes Berg 已提交
1423
		for (j = 0; j < sband->n_bitrates; j++) {
1424
			if (sband->bitrates[j].bitrate == rate) {
J
Johannes Berg 已提交
1425
				rates |= BIT(j);
1426 1427 1428 1429
				if (is_basic)
					basic_rates |= BIT(j);
				break;
			}
J
Johannes Berg 已提交
1430
		}
1431
	}
1432

1433
	sta->sta.supp_rates[wk->chan->band] = rates;
J
Johannes Berg 已提交
1434
	sdata->vif.bss_conf.basic_rates = basic_rates;
J
Johannes Berg 已提交
1435 1436

	/* cf. IEEE 802.11 9.2.12 */
1437
	if (wk->chan->band == IEEE80211_BAND_2GHZ &&
J
Johannes Berg 已提交
1438 1439 1440 1441
	    have_higher_than_11mbit)
		sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
	else
		sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
1442

1443
	if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
J
Johannes Berg 已提交
1444
		ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
J
Johannes Berg 已提交
1445
				elems.ht_cap_elem, &sta->sta.ht_cap);
J
Johannes Berg 已提交
1446 1447

	ap_ht_cap_flags = sta->sta.ht_cap.cap;
1448

1449
	rate_control_rate_init(sta);
1450

1451
	if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED)
1452 1453
		set_sta_flags(sta, WLAN_STA_MFP);

1454
	if (elems.wmm_param)
J
Johannes Berg 已提交
1455
		set_sta_flags(sta, WLAN_STA_WME);
1456

1457 1458 1459 1460 1461
	err = sta_info_insert(sta);
	sta = NULL;
	if (err) {
		printk(KERN_DEBUG "%s: failed to insert STA entry for"
		       " the AP (error %d)\n", sdata->name, err);
1462
		return false;
1463 1464
	}

1465 1466 1467 1468 1469 1470 1471 1472
	/*
	 * Always handle WMM once after association regardless
	 * of the first value the AP uses. Setting -1 here has
	 * that effect because the AP values is an unsigned
	 * 4-bit value.
	 */
	ifmgd->wmm_last_param_set = -1;

1473
	if (elems.wmm_param)
1474
		ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
J
Johannes Berg 已提交
1475
					 elems.wmm_param_len);
1476 1477
	else
		ieee80211_set_wmm_default(sdata);
1478

1479 1480
	local->oper_channel = wk->chan;

J
Johannes Berg 已提交
1481
	if (elems.ht_info_elem && elems.wmm_param &&
J
Johannes Berg 已提交
1482
	    (sdata->local->hw.queues >= 4) &&
1483
	    !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
J
Johannes Berg 已提交
1484
		changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
1485
					       cbss->bssid, ap_ht_cap_flags);
J
Johannes Berg 已提交
1486

J
Johannes Berg 已提交
1487 1488 1489 1490
	/* set AID and assoc capability,
	 * ieee80211_set_associated() will tell the driver */
	bss_conf->aid = aid;
	bss_conf->assoc_capability = capab_info;
1491
	ieee80211_set_associated(sdata, cbss, changed);
1492

1493 1494 1495 1496 1497 1498 1499
	/*
	 * If we're using 4-addr mode, let the AP know that we're
	 * doing so, so that it can create the STA VLAN on its side
	 */
	if (ifmgd->use_4addr)
		ieee80211_send_4addr_nullfunc(local, sdata);

1500
	/*
J
Johannes Berg 已提交
1501 1502
	 * Start timer to probe the connection to the AP now.
	 * Also start the timer that will detect beacon loss.
1503
	 */
J
Johannes Berg 已提交
1504
	ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
1505
	ieee80211_sta_reset_beacon_monitor(sdata);
1506

J
Johannes Berg 已提交
1507
	return true;
1508 1509 1510
}


1511 1512 1513 1514 1515 1516 1517 1518 1519
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
				  struct ieee80211_mgmt *mgmt,
				  size_t len,
				  struct ieee80211_rx_status *rx_status,
				  struct ieee802_11_elems *elems,
				  bool beacon)
{
	struct ieee80211_local *local = sdata->local;
	int freq;
1520
	struct ieee80211_bss *bss;
1521
	struct ieee80211_channel *channel;
1522 1523 1524 1525 1526 1527 1528
	bool need_ps = false;

	if (sdata->u.mgd.associated) {
		bss = (void *)sdata->u.mgd.associated->priv;
		/* not previously set so we may need to recalc */
		need_ps = !bss->dtim_period;
	}
1529 1530

	if (elems->ds_params && elems->ds_params_len == 1)
1531 1532
		freq = ieee80211_channel_to_frequency(elems->ds_params[0],
						      rx_status->band);
1533 1534 1535 1536 1537 1538 1539 1540 1541
	else
		freq = rx_status->freq;

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

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

	bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
1542
					channel, beacon);
1543 1544 1545 1546
	if (bss)
		ieee80211_rx_bss_put(local, bss);

	if (!sdata->u.mgd.associated)
1547 1548
		return;

1549 1550 1551 1552 1553 1554
	if (need_ps) {
		mutex_lock(&local->iflist_mtx);
		ieee80211_recalc_ps(local, -1);
		mutex_unlock(&local->iflist_mtx);
	}

S
Sujith 已提交
1555
	if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) &&
1556
	    (memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid,
1557
							ETH_ALEN) == 0)) {
S
Sujith 已提交
1558 1559
		struct ieee80211_channel_sw_ie *sw_elem =
			(struct ieee80211_channel_sw_ie *)elems->ch_switch_elem;
1560 1561
		ieee80211_sta_process_chanswitch(sdata, sw_elem,
						 bss, rx_status->mactime);
S
Sujith 已提交
1562
	}
1563 1564 1565
}


1566
static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
J
Johannes Berg 已提交
1567
					 struct sk_buff *skb)
1568
{
J
Johannes Berg 已提交
1569
	struct ieee80211_mgmt *mgmt = (void *)skb->data;
1570
	struct ieee80211_if_managed *ifmgd;
J
Johannes Berg 已提交
1571 1572
	struct ieee80211_rx_status *rx_status = (void *) skb->cb;
	size_t baselen, len = skb->len;
1573 1574
	struct ieee802_11_elems elems;

1575 1576
	ifmgd = &sdata->u.mgd;

1577 1578
	ASSERT_MGD_MTX(ifmgd);

1579
	if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN))
1580 1581
		return; /* ignore ProbeResp to foreign address */

1582 1583 1584 1585 1586 1587 1588
	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);

1589
	ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
1590

1591
	if (ifmgd->associated &&
1592 1593
	    memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0)
		ieee80211_reset_ap_probe(sdata);
1594 1595
}

1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609
/*
 * This is the canonical list of information elements we care about,
 * the filter code also gives us all changes to the Microsoft OUI
 * (00:50:F2) vendor IE which is used for WMM which we need to track.
 *
 * We implement beacon filtering in software since that means we can
 * avoid processing the frame here and in cfg80211, and userspace
 * will not be able to tell whether the hardware supports it or not.
 *
 * XXX: This list needs to be dynamic -- userspace needs to be able to
 *	add items it requires. It also needs to be able to tell us to
 *	look out for other vendor IEs.
 */
static const u64 care_about_ies =
1610 1611 1612 1613 1614 1615
	(1ULL << WLAN_EID_COUNTRY) |
	(1ULL << WLAN_EID_ERP_INFO) |
	(1ULL << WLAN_EID_CHANNEL_SWITCH) |
	(1ULL << WLAN_EID_PWR_CONSTRAINT) |
	(1ULL << WLAN_EID_HT_CAPABILITY) |
	(1ULL << WLAN_EID_HT_INFORMATION);
1616

1617
static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1618 1619 1620 1621
				     struct ieee80211_mgmt *mgmt,
				     size_t len,
				     struct ieee80211_rx_status *rx_status)
{
1622
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1623
	struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
1624 1625
	size_t baselen;
	struct ieee802_11_elems elems;
1626
	struct ieee80211_local *local = sdata->local;
1627
	u32 changed = 0;
1628
	bool erp_valid, directed_tim = false;
J
Johannes Berg 已提交
1629
	u8 erp_value = 0;
1630
	u32 ncrc;
1631 1632 1633
	u8 *bssid;

	ASSERT_MGD_MTX(ifmgd);
1634

1635 1636 1637 1638 1639
	/* Process beacon from the current BSS */
	baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
	if (baselen > len)
		return;

1640
	if (rx_status->freq != local->hw.conf.channel->center_freq)
1641 1642
		return;

J
Johannes Berg 已提交
1643 1644 1645 1646 1647
	/*
	 * We might have received a number of frames, among them a
	 * disassoc frame and a beacon...
	 */
	if (!ifmgd->associated)
1648 1649
		return;

1650
	bssid = ifmgd->associated->bssid;
1651

J
Johannes Berg 已提交
1652 1653 1654 1655 1656
	/*
	 * And in theory even frames from a different AP we were just
	 * associated to a split-second ago!
	 */
	if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)
1657 1658
		return;

1659 1660 1661 1662
	/* Track average RSSI from the Beacon frames of the current AP */
	ifmgd->last_beacon_signal = rx_status->signal;
	if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) {
		ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE;
1663
		ifmgd->ave_beacon_signal = rx_status->signal * 16;
1664
		ifmgd->last_cqm_event_signal = 0;
1665
		ifmgd->count_beacon_signal = 1;
1666 1667 1668 1669 1670
	} else {
		ifmgd->ave_beacon_signal =
			(IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 +
			 (16 - IEEE80211_SIGNAL_AVE_WEIGHT) *
			 ifmgd->ave_beacon_signal) / 16;
1671
		ifmgd->count_beacon_signal++;
1672 1673
	}
	if (bss_conf->cqm_rssi_thold &&
1674
	    ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT &&
1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696
	    !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
		int sig = ifmgd->ave_beacon_signal / 16;
		int last_event = ifmgd->last_cqm_event_signal;
		int thold = bss_conf->cqm_rssi_thold;
		int hyst = bss_conf->cqm_rssi_hyst;
		if (sig < thold &&
		    (last_event == 0 || sig < last_event - hyst)) {
			ifmgd->last_cqm_event_signal = sig;
			ieee80211_cqm_rssi_notify(
				&sdata->vif,
				NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
				GFP_KERNEL);
		} else if (sig > thold &&
			   (last_event == 0 || sig > last_event + hyst)) {
			ifmgd->last_cqm_event_signal = sig;
			ieee80211_cqm_rssi_notify(
				&sdata->vif,
				NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
				GFP_KERNEL);
		}
	}

J
Johannes Berg 已提交
1697
	if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) {
1698 1699 1700
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
		if (net_ratelimit()) {
			printk(KERN_DEBUG "%s: cancelling probereq poll due "
1701
			       "to a received beacon\n", sdata->name);
1702 1703
		}
#endif
J
Johannes Berg 已提交
1704
		ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL;
1705 1706 1707
		mutex_lock(&local->iflist_mtx);
		ieee80211_recalc_ps(local, -1);
		mutex_unlock(&local->iflist_mtx);
1708 1709
	}

J
Johannes Berg 已提交
1710 1711 1712 1713
	/*
	 * Push the beacon loss detection into the future since
	 * we are processing a beacon from the AP just now.
	 */
1714
	ieee80211_sta_reset_beacon_monitor(sdata);
J
Johannes Berg 已提交
1715

1716 1717 1718 1719 1720 1721
	ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
	ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable,
					  len - baselen, &elems,
					  care_about_ies, ncrc);

	if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
1722 1723
		directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len,
						   ifmgd->aid);
1724

1725
	if (ncrc != ifmgd->beacon_crc || !ifmgd->beacon_crc_valid) {
1726 1727
		ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
				      true);
1728

1729
		ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
1730 1731
					 elems.wmm_param_len);
	}
1732

1733
	if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) {
1734
		if (directed_tim) {
1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752
			if (local->hw.conf.dynamic_ps_timeout > 0) {
				local->hw.conf.flags &= ~IEEE80211_CONF_PS;
				ieee80211_hw_config(local,
						    IEEE80211_CONF_CHANGE_PS);
				ieee80211_send_nullfunc(local, sdata, 0);
			} else {
				local->pspolling = true;

				/*
				 * Here is assumed that the driver will be
				 * able to send ps-poll frame and receive a
				 * response even though power save mode is
				 * enabled, but some drivers might require
				 * to disable power save here. This needs
				 * to be investigated.
				 */
				ieee80211_send_pspoll(local, sdata);
			}
1753 1754
		}
	}
J
Johannes Berg 已提交
1755

1756
	if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
1757 1758
		return;
	ifmgd->beacon_crc = ncrc;
1759
	ifmgd->beacon_crc_valid = true;
1760

J
Johannes Berg 已提交
1761 1762 1763 1764 1765
	if (elems.erp_info && elems.erp_info_len >= 1) {
		erp_valid = true;
		erp_value = elems.erp_info[0];
	} else {
		erp_valid = false;
1766
	}
J
Johannes Berg 已提交
1767 1768 1769
	changed |= ieee80211_handle_bss_capability(sdata,
			le16_to_cpu(mgmt->u.beacon.capab_info),
			erp_valid, erp_value);
1770

1771

1772
	if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param &&
1773
	    !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) {
J
Johannes Berg 已提交
1774 1775 1776 1777 1778 1779
		struct sta_info *sta;
		struct ieee80211_supported_band *sband;
		u16 ap_ht_cap_flags;

		rcu_read_lock();

1780
		sta = sta_info_get(sdata, bssid);
1781
		if (WARN_ON(!sta)) {
J
Johannes Berg 已提交
1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795
			rcu_read_unlock();
			return;
		}

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

		ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
				elems.ht_cap_elem, &sta->sta.ht_cap);

		ap_ht_cap_flags = sta->sta.ht_cap.cap;

		rcu_read_unlock();

		changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
1796
					       bssid, ap_ht_cap_flags);
1797 1798
	}

1799
	/* Note: country IE parsing is done for us by cfg80211 */
1800
	if (elems.country_elem) {
1801 1802 1803 1804 1805 1806
		/* TODO: IBSS also needs this */
		if (elems.pwr_constr_elem)
			ieee80211_handle_pwr_constr(sdata,
				le16_to_cpu(mgmt->u.probe_resp.capab_info),
				elems.pwr_constr_elem,
				elems.pwr_constr_elem_len);
1807 1808
	}

1809
	ieee80211_bss_info_change_notify(sdata, changed);
1810 1811
}

1812 1813
void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
				  struct sk_buff *skb)
1814
{
1815
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1816 1817
	struct ieee80211_rx_status *rx_status;
	struct ieee80211_mgmt *mgmt;
1818
	enum rx_mgmt_action rma = RX_MGMT_NONE;
1819 1820 1821 1822 1823 1824
	u16 fc;

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

1825 1826 1827
	mutex_lock(&ifmgd->mtx);

	if (ifmgd->associated &&
1828
	    memcmp(ifmgd->associated->bssid, mgmt->bssid, ETH_ALEN) == 0) {
1829 1830 1831 1832 1833 1834
		switch (fc & IEEE80211_FCTL_STYPE) {
		case IEEE80211_STYPE_BEACON:
			ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len,
						 rx_status);
			break;
		case IEEE80211_STYPE_PROBE_RESP:
J
Johannes Berg 已提交
1835
			ieee80211_rx_mgmt_probe_resp(sdata, skb);
1836 1837
			break;
		case IEEE80211_STYPE_DEAUTH:
1838
			rma = ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len);
1839 1840 1841 1842 1843
			break;
		case IEEE80211_STYPE_DISASSOC:
			rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
			break;
		case IEEE80211_STYPE_ACTION:
1844 1845 1846 1847 1848 1849 1850 1851
			switch (mgmt->u.action.category) {
			case WLAN_CATEGORY_SPECTRUM_MGMT:
				ieee80211_sta_process_chanswitch(sdata,
						&mgmt->u.action.u.chan_switch.sw_elem,
						(void *)ifmgd->associated->priv,
						rx_status->mactime);
				break;
			}
1852 1853 1854 1855 1856 1857 1858 1859
		}
		mutex_unlock(&ifmgd->mtx);

		switch (rma) {
		case RX_MGMT_NONE:
			/* no action */
			break;
		case RX_MGMT_CFG80211_DEAUTH:
1860
			cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
1861 1862
			break;
		case RX_MGMT_CFG80211_DISASSOC:
1863
			cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
1864 1865 1866 1867
			break;
		default:
			WARN(1, "unexpected: %d", rma);
		}
1868
		return;
1869 1870 1871 1872
	}

	mutex_unlock(&ifmgd->mtx);

1873
	if (skb->len >= 24 + 2 /* mgmt + deauth reason */ &&
1874 1875 1876 1877
	    (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DEAUTH) {
		struct ieee80211_local *local = sdata->local;
		struct ieee80211_work *wk;

1878
		mutex_lock(&local->mtx);
1879 1880 1881 1882
		list_for_each_entry(wk, &local->work_list, list) {
			if (wk->sdata != sdata)
				continue;

1883 1884
			if (wk->type != IEEE80211_WORK_ASSOC &&
			    wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909
				continue;

			if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN))
				continue;
			if (memcmp(mgmt->sa, wk->filter_ta, ETH_ALEN))
				continue;

			/*
			 * Printing the message only here means we can't
			 * spuriously print it, but it also means that it
			 * won't be printed when the frame comes in before
			 * we even tried to associate or in similar cases.
			 *
			 * Ultimately, I suspect cfg80211 should print the
			 * messages instead.
			 */
			printk(KERN_DEBUG
			       "%s: deauthenticated from %pM (Reason: %u)\n",
			       sdata->name, mgmt->bssid,
			       le16_to_cpu(mgmt->u.deauth.reason_code));

			list_del_rcu(&wk->list);
			free_work(wk);
			break;
		}
1910
		mutex_unlock(&local->mtx);
1911

1912
		cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
1913
	}
1914 1915
}

J
Johannes Berg 已提交
1916
static void ieee80211_sta_timer(unsigned long data)
1917
{
J
Johannes Berg 已提交
1918 1919
	struct ieee80211_sub_if_data *sdata =
		(struct ieee80211_sub_if_data *) data;
1920
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
J
Johannes Berg 已提交
1921
	struct ieee80211_local *local = sdata->local;
1922

1923 1924 1925 1926 1927
	if (local->quiescing) {
		set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
		return;
	}

J
Johannes Berg 已提交
1928
	ieee80211_queue_work(&local->hw, &sdata->work);
1929 1930
}

1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955
static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
					  u8 *bssid)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

	ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
			  IEEE80211_STA_BEACON_POLL);

	ieee80211_set_disassoc(sdata, true, true);
	mutex_unlock(&ifmgd->mtx);
	mutex_lock(&local->mtx);
	ieee80211_recalc_idle(local);
	mutex_unlock(&local->mtx);
	/*
	 * must be outside lock due to cfg80211,
	 * but that's not a problem.
	 */
	ieee80211_send_deauth_disassoc(sdata, bssid,
			IEEE80211_STYPE_DEAUTH,
			WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
			NULL, true);
	mutex_lock(&ifmgd->mtx);
}

1956
void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
J
Johannes Berg 已提交
1957 1958
{
	struct ieee80211_local *local = sdata->local;
1959
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
J
Johannes Berg 已提交
1960

1961 1962 1963
	/* then process the rest of the work */
	mutex_lock(&ifmgd->mtx);

J
Johannes Berg 已提交
1964 1965 1966
	if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
			    IEEE80211_STA_CONNECTION_POLL) &&
	    ifmgd->associated) {
1967
		u8 bssid[ETH_ALEN];
1968
		int max_tries;
1969

1970
		memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
1971

1972 1973 1974 1975 1976
		if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
			max_tries = IEEE80211_MAX_NULLFUNC_TRIES;
		else
			max_tries = IEEE80211_MAX_PROBE_TRIES;

1977 1978 1979
		/* ACK received for nullfunc probing frame */
		if (!ifmgd->probe_send_count)
			ieee80211_reset_ap_probe(sdata);
1980 1981 1982 1983 1984
		else if (ifmgd->nullfunc_failed) {
			if (ifmgd->probe_send_count < max_tries) {
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
				wiphy_debug(local->hw.wiphy,
					    "%s: No ack for nullfunc frame to"
1985
					    " AP %pM, try %d/%i\n",
1986
					    sdata->name, bssid,
1987
					    ifmgd->probe_send_count, max_tries);
1988 1989 1990 1991 1992 1993 1994
#endif
				ieee80211_mgd_probe_ap_send(sdata);
			} else {
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
				wiphy_debug(local->hw.wiphy,
					    "%s: No ack for nullfunc frame to"
					    " AP %pM, disconnecting.\n",
F
Felix Fietkau 已提交
1995
					    sdata->name, bssid);
1996 1997 1998 1999
#endif
				ieee80211_sta_connection_lost(sdata, bssid);
			}
		} else if (time_is_after_jiffies(ifmgd->probe_timeout))
J
Johannes Berg 已提交
2000
			run_again(ifmgd, ifmgd->probe_timeout);
2001 2002 2003 2004 2005 2006 2007 2008 2009 2010
		else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
			wiphy_debug(local->hw.wiphy,
				    "%s: Failed to send nullfunc to AP %pM"
				    " after %dms, disconnecting.\n",
				    sdata->name,
				    bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
#endif
			ieee80211_sta_connection_lost(sdata, bssid);
		} else if (ifmgd->probe_send_count < max_tries) {
2011
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
2012 2013
			wiphy_debug(local->hw.wiphy,
				    "%s: No probe response from AP %pM"
2014
				    " after %dms, try %d/%i\n",
2015 2016
				    sdata->name,
				    bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ,
2017
				    ifmgd->probe_send_count, max_tries);
2018 2019 2020
#endif
			ieee80211_mgd_probe_ap_send(sdata);
		} else {
J
Johannes Berg 已提交
2021 2022 2023 2024
			/*
			 * We actually lost the connection ... or did we?
			 * Let's make sure!
			 */
2025 2026 2027 2028 2029
			wiphy_debug(local->hw.wiphy,
				    "%s: No probe response from AP %pM"
				    " after %dms, disconnecting.\n",
				    sdata->name,
				    bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
2030 2031

			ieee80211_sta_connection_lost(sdata, bssid);
J
Johannes Berg 已提交
2032 2033 2034
		}
	}

2035
	mutex_unlock(&ifmgd->mtx);
2036 2037
}

J
Johannes Berg 已提交
2038 2039 2040 2041 2042 2043 2044 2045 2046
static void ieee80211_sta_bcn_mon_timer(unsigned long data)
{
	struct ieee80211_sub_if_data *sdata =
		(struct ieee80211_sub_if_data *) data;
	struct ieee80211_local *local = sdata->local;

	if (local->quiescing)
		return;

2047 2048
	ieee80211_queue_work(&sdata->local->hw,
			     &sdata->u.mgd.beacon_connection_loss_work);
J
Johannes Berg 已提交
2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060
}

static void ieee80211_sta_conn_mon_timer(unsigned long data)
{
	struct ieee80211_sub_if_data *sdata =
		(struct ieee80211_sub_if_data *) data;
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
	struct ieee80211_local *local = sdata->local;

	if (local->quiescing)
		return;

2061
	ieee80211_queue_work(&local->hw, &ifmgd->monitor_work);
J
Johannes Berg 已提交
2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072
}

static void ieee80211_sta_monitor_work(struct work_struct *work)
{
	struct ieee80211_sub_if_data *sdata =
		container_of(work, struct ieee80211_sub_if_data,
			     u.mgd.monitor_work);

	ieee80211_mgd_probe_ap(sdata, false);
}

J
Johannes Berg 已提交
2073 2074
static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
{
2075
	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
J
Johannes Berg 已提交
2076 2077
		sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL |
					IEEE80211_STA_CONNECTION_POLL);
2078

J
Johannes Berg 已提交
2079
		/* let's probe the connection once */
2080
		ieee80211_queue_work(&sdata->local->hw,
J
Johannes Berg 已提交
2081 2082
			   &sdata->u.mgd.monitor_work);
		/* and do all the other regular work too */
J
Johannes Berg 已提交
2083
		ieee80211_queue_work(&sdata->local->hw, &sdata->work);
2084
	}
J
Johannes Berg 已提交
2085
}
2086

2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097
#ifdef CONFIG_PM
void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

	/*
	 * we need to use atomic bitops for the running bits
	 * only because both timers might fire at the same
	 * time -- the code here is properly synchronised.
	 */

2098 2099
	cancel_work_sync(&ifmgd->request_smps_work);

2100
	cancel_work_sync(&ifmgd->beacon_connection_loss_work);
2101 2102 2103 2104 2105 2106
	if (del_timer_sync(&ifmgd->timer))
		set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);

	cancel_work_sync(&ifmgd->chswitch_work);
	if (del_timer_sync(&ifmgd->chswitch_timer))
		set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
J
Johannes Berg 已提交
2107 2108 2109 2110 2111

	cancel_work_sync(&ifmgd->monitor_work);
	/* these will just be re-established on connection */
	del_timer_sync(&ifmgd->conn_mon_timer);
	del_timer_sync(&ifmgd->bcn_mon_timer);
2112 2113 2114 2115 2116 2117 2118 2119 2120 2121
}

void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

	if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running))
		add_timer(&ifmgd->timer);
	if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running))
		add_timer(&ifmgd->chswitch_timer);
2122
	ieee80211_sta_reset_beacon_monitor(sdata);
2123
	ieee80211_restart_sta_timer(sdata);
2124 2125 2126
}
#endif

J
Johannes Berg 已提交
2127 2128
/* interface setup */
void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
2129
{
2130
	struct ieee80211_if_managed *ifmgd;
J
Johannes Berg 已提交
2131

2132
	ifmgd = &sdata->u.mgd;
J
Johannes Berg 已提交
2133
	INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work);
2134
	INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
2135 2136
	INIT_WORK(&ifmgd->beacon_connection_loss_work,
		  ieee80211_beacon_connection_loss_work);
2137
	INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_work);
2138
	setup_timer(&ifmgd->timer, ieee80211_sta_timer,
S
Sujith 已提交
2139
		    (unsigned long) sdata);
J
Johannes Berg 已提交
2140 2141 2142 2143
	setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer,
		    (unsigned long) sdata);
	setup_timer(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer,
		    (unsigned long) sdata);
2144
	setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer,
J
Johannes Berg 已提交
2145 2146
		    (unsigned long) sdata);

2147
	ifmgd->flags = 0;
J
Johannes Berg 已提交
2148

2149
	mutex_init(&ifmgd->mtx);
2150 2151 2152 2153 2154

	if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS)
		ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC;
	else
		ifmgd->req_smps = IEEE80211_SMPS_OFF;
2155 2156
}

2157 2158
/* scan finished notification */
void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
J
Johannes Berg 已提交
2159
{
2160
	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
J
Johannes Berg 已提交
2161

2162 2163 2164 2165 2166 2167
	/* Restart STA timers */
	rcu_read_lock();
	list_for_each_entry_rcu(sdata, &local->interfaces, list)
		ieee80211_restart_sta_timer(sdata);
	rcu_read_unlock();
}
J
Johannes Berg 已提交
2168

2169 2170 2171 2172 2173 2174 2175
int ieee80211_max_network_latency(struct notifier_block *nb,
				  unsigned long data, void *dummy)
{
	s32 latency_usec = (s32) data;
	struct ieee80211_local *local =
		container_of(nb, struct ieee80211_local,
			     network_latency_notifier);
2176

2177 2178 2179
	mutex_lock(&local->iflist_mtx);
	ieee80211_recalc_ps(local, latency_usec);
	mutex_unlock(&local->iflist_mtx);
2180

2181
	return 0;
J
Johannes Berg 已提交
2182 2183
}

2184
/* config hooks */
J
Johannes Berg 已提交
2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207
static enum work_done_result
ieee80211_probe_auth_done(struct ieee80211_work *wk,
			  struct sk_buff *skb)
{
	if (!skb) {
		cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
		return WORK_DONE_DESTROY;
	}

	if (wk->type == IEEE80211_WORK_AUTH) {
		cfg80211_send_rx_auth(wk->sdata->dev, skb->data, skb->len);
		return WORK_DONE_DESTROY;
	}

	mutex_lock(&wk->sdata->u.mgd.mtx);
	ieee80211_rx_mgmt_probe_resp(wk->sdata, skb);
	mutex_unlock(&wk->sdata->u.mgd.mtx);

	wk->type = IEEE80211_WORK_AUTH;
	wk->probe_auth.tries = 0;
	return WORK_DONE_REQUEUE;
}

2208 2209
int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
		       struct cfg80211_auth_request *req)
J
Johannes Berg 已提交
2210
{
2211
	const u8 *ssid;
2212
	struct ieee80211_work *wk;
2213
	u16 auth_alg;
J
Johannes Berg 已提交
2214

2215 2216 2217
	if (req->local_state_change)
		return 0; /* no need to update mac80211 state */

2218 2219 2220 2221 2222
	switch (req->auth_type) {
	case NL80211_AUTHTYPE_OPEN_SYSTEM:
		auth_alg = WLAN_AUTH_OPEN;
		break;
	case NL80211_AUTHTYPE_SHARED_KEY:
2223 2224
		if (IS_ERR(sdata->local->wep_tx_tfm))
			return -EOPNOTSUPP;
2225 2226 2227 2228 2229 2230 2231 2232 2233 2234
		auth_alg = WLAN_AUTH_SHARED_KEY;
		break;
	case NL80211_AUTHTYPE_FT:
		auth_alg = WLAN_AUTH_FT;
		break;
	case NL80211_AUTHTYPE_NETWORK_EAP:
		auth_alg = WLAN_AUTH_LEAP;
		break;
	default:
		return -EOPNOTSUPP;
J
Johannes Berg 已提交
2235
	}
2236 2237 2238

	wk = kzalloc(sizeof(*wk) + req->ie_len, GFP_KERNEL);
	if (!wk)
J
Johannes Berg 已提交
2239
		return -ENOMEM;
2240

2241
	memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN);
2242 2243 2244 2245

	if (req->ie && req->ie_len) {
		memcpy(wk->ie, req->ie, req->ie_len);
		wk->ie_len = req->ie_len;
J
Johannes Berg 已提交
2246
	}
2247

J
Johannes Berg 已提交
2248
	if (req->key && req->key_len) {
J
Johannes Berg 已提交
2249 2250 2251
		wk->probe_auth.key_len = req->key_len;
		wk->probe_auth.key_idx = req->key_idx;
		memcpy(wk->probe_auth.key, req->key, req->key_len);
J
Johannes Berg 已提交
2252 2253
	}

2254
	ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
J
Johannes Berg 已提交
2255 2256
	memcpy(wk->probe_auth.ssid, ssid + 2, ssid[1]);
	wk->probe_auth.ssid_len = ssid[1];
2257

J
Johannes Berg 已提交
2258 2259
	wk->probe_auth.algorithm = auth_alg;
	wk->probe_auth.privacy = req->bss->capability & WLAN_CAPABILITY_PRIVACY;
2260

2261 2262 2263 2264 2265
	/* if we already have a probe, don't probe again */
	if (req->bss->proberesp_ies)
		wk->type = IEEE80211_WORK_AUTH;
	else
		wk->type = IEEE80211_WORK_DIRECT_PROBE;
2266
	wk->chan = req->bss->channel;
J
Johannes Berg 已提交
2267 2268
	wk->sdata = sdata;
	wk->done = ieee80211_probe_auth_done;
2269

J
Johannes Berg 已提交
2270
	ieee80211_add_work(wk);
J
Johannes Berg 已提交
2271
	return 0;
J
Johannes Berg 已提交
2272 2273
}

J
Johannes Berg 已提交
2274 2275 2276 2277
static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
						  struct sk_buff *skb)
{
	struct ieee80211_mgmt *mgmt;
2278 2279
	struct ieee80211_rx_status *rx_status;
	struct ieee802_11_elems elems;
J
Johannes Berg 已提交
2280 2281 2282 2283 2284 2285 2286
	u16 status;

	if (!skb) {
		cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta);
		return WORK_DONE_DESTROY;
	}

2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299
	if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) {
		mutex_lock(&wk->sdata->u.mgd.mtx);
		rx_status = (void *) skb->cb;
		ieee802_11_parse_elems(skb->data + 24 + 12, skb->len - 24 - 12, &elems);
		ieee80211_rx_bss_info(wk->sdata, (void *)skb->data, skb->len, rx_status,
				      &elems, true);
		mutex_unlock(&wk->sdata->u.mgd.mtx);

		wk->type = IEEE80211_WORK_ASSOC;
		/* not really done yet */
		return WORK_DONE_REQUEUE;
	}

J
Johannes Berg 已提交
2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311
	mgmt = (void *)skb->data;
	status = le16_to_cpu(mgmt->u.assoc_resp.status_code);

	if (status == WLAN_STATUS_SUCCESS) {
		mutex_lock(&wk->sdata->u.mgd.mtx);
		if (!ieee80211_assoc_success(wk, mgmt, skb->len)) {
			mutex_unlock(&wk->sdata->u.mgd.mtx);
			/* oops -- internal error -- send timeout for now */
			cfg80211_send_assoc_timeout(wk->sdata->dev,
						    wk->filter_ta);
			return WORK_DONE_DESTROY;
		}
2312 2313

		mutex_unlock(&wk->sdata->u.mgd.mtx);
J
Johannes Berg 已提交
2314 2315 2316 2317 2318 2319
	}

	cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len);
	return WORK_DONE_DESTROY;
}

2320 2321
int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
			struct cfg80211_assoc_request *req)
2322
{
2323
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2324
	struct ieee80211_bss *bss = (void *)req->bss->priv;
2325
	struct ieee80211_work *wk;
2326
	const u8 *ssid;
J
Johannes Berg 已提交
2327
	int i;
2328

2329
	mutex_lock(&ifmgd->mtx);
J
Johannes Berg 已提交
2330
	if (ifmgd->associated) {
2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343
		if (!req->prev_bssid ||
		    memcmp(req->prev_bssid, ifmgd->associated->bssid,
			   ETH_ALEN)) {
			/*
			 * We are already associated and the request was not a
			 * reassociation request from the current BSS, so
			 * reject it.
			 */
			mutex_unlock(&ifmgd->mtx);
			return -EALREADY;
		}

		/* Trying to reassociate - clear previous association state */
2344
		ieee80211_set_disassoc(sdata, true, false);
J
Johannes Berg 已提交
2345 2346
	}
	mutex_unlock(&ifmgd->mtx);
2347

2348
	wk = kzalloc(sizeof(*wk) + req->ie_len, GFP_KERNEL);
J
Johannes Berg 已提交
2349 2350
	if (!wk)
		return -ENOMEM;
2351 2352

	ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
2353
	ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
2354

2355 2356
	ifmgd->beacon_crc_valid = false;

2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369
	for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
		if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
		    req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
		    req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104)
			ifmgd->flags |= IEEE80211_STA_DISABLE_11N;


	if (req->ie && req->ie_len) {
		memcpy(wk->ie, req->ie, req->ie_len);
		wk->ie_len = req->ie_len;
	} else
		wk->ie_len = 0;

2370
	wk->assoc.bss = req->bss;
2371

J
Johannes Berg 已提交
2372
	memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN);
2373

J
Johannes Berg 已提交
2374 2375 2376 2377 2378 2379 2380 2381 2382 2383
	/* new association always uses requested smps mode */
	if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {
		if (ifmgd->powersave)
			ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC;
		else
			ifmgd->ap_smps = IEEE80211_SMPS_OFF;
	} else
		ifmgd->ap_smps = ifmgd->req_smps;

	wk->assoc.smps = ifmgd->ap_smps;
J
Johannes Berg 已提交
2384 2385 2386 2387 2388 2389 2390
	/*
	 * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode.
	 * We still associate in non-HT mode (11a/b/g) if any one of these
	 * ciphers is configured as pairwise.
	 * We can set this to true for non-11n hardware, that'll be checked
	 * separately along with the peer capabilities.
	 */
J
Johannes Berg 已提交
2391
	wk->assoc.use_11n = !(ifmgd->flags & IEEE80211_STA_DISABLE_11N);
2392
	wk->assoc.capability = req->bss->capability;
2393 2394 2395
	wk->assoc.wmm_used = bss->wmm_used;
	wk->assoc.supp_rates = bss->supp_rates;
	wk->assoc.supp_rates_len = bss->supp_rates_len;
2396 2397
	wk->assoc.ht_information_ie =
		ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_INFORMATION);
2398

K
Kalle Valo 已提交
2399 2400 2401 2402 2403 2404 2405 2406 2407
	if (bss->wmm_used && bss->uapsd_supported &&
	    (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
		wk->assoc.uapsd_used = true;
		ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED;
	} else {
		wk->assoc.uapsd_used = false;
		ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED;
	}

2408
	ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
2409 2410
	memcpy(wk->assoc.ssid, ssid + 2, ssid[1]);
	wk->assoc.ssid_len = ssid[1];
2411

2412
	if (req->prev_bssid)
2413
		memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN);
2414

2415
	wk->chan = req->bss->channel;
J
Johannes Berg 已提交
2416 2417
	wk->sdata = sdata;
	wk->done = ieee80211_assoc_done;
2418 2419 2420 2421 2422
	if (!bss->dtim_period &&
	    sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD)
		wk->type = IEEE80211_WORK_ASSOC_BEACON_WAIT;
	else
		wk->type = IEEE80211_WORK_ASSOC;
2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436

	if (req->use_mfp) {
		ifmgd->mfp = IEEE80211_MFP_REQUIRED;
		ifmgd->flags |= IEEE80211_STA_MFP_ENABLED;
	} else {
		ifmgd->mfp = IEEE80211_MFP_DISABLED;
		ifmgd->flags &= ~IEEE80211_STA_MFP_ENABLED;
	}

	if (req->crypto.control_port)
		ifmgd->flags |= IEEE80211_STA_CONTROL_PORT;
	else
		ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT;

2437 2438 2439
	sdata->control_port_protocol = req->crypto.control_port_ethertype;
	sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;

J
Johannes Berg 已提交
2440 2441
	ieee80211_add_work(wk);
	return 0;
2442 2443
}

2444
int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
J
Johannes Berg 已提交
2445 2446
			 struct cfg80211_deauth_request *req,
			 void *cookie)
2447
{
J
Johannes Berg 已提交
2448
	struct ieee80211_local *local = sdata->local;
2449
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2450
	struct ieee80211_work *wk;
2451 2452
	u8 bssid[ETH_ALEN];
	bool assoc_bss = false;
2453

2454 2455
	mutex_lock(&ifmgd->mtx);

2456
	memcpy(bssid, req->bss->bssid, ETH_ALEN);
2457
	if (ifmgd->associated == req->bss) {
2458
		ieee80211_set_disassoc(sdata, false, true);
J
Johannes Berg 已提交
2459
		mutex_unlock(&ifmgd->mtx);
2460
		assoc_bss = true;
J
Johannes Berg 已提交
2461 2462
	} else {
		bool not_auth_yet = false;
2463

2464 2465
		mutex_unlock(&ifmgd->mtx);

2466
		mutex_lock(&local->mtx);
J
Johannes Berg 已提交
2467
		list_for_each_entry(wk, &local->work_list, list) {
J
Johannes Berg 已提交
2468
			if (wk->sdata != sdata)
J
Johannes Berg 已提交
2469
				continue;
J
Johannes Berg 已提交
2470 2471

			if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
2472
			    wk->type != IEEE80211_WORK_AUTH &&
2473 2474
			    wk->type != IEEE80211_WORK_ASSOC &&
			    wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
J
Johannes Berg 已提交
2475 2476
				continue;

J
Johannes Berg 已提交
2477 2478
			if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
				continue;
J
Johannes Berg 已提交
2479 2480 2481

			not_auth_yet = wk->type == IEEE80211_WORK_DIRECT_PROBE;
			list_del_rcu(&wk->list);
J
Johannes Berg 已提交
2482 2483 2484
			free_work(wk);
			break;
		}
2485
		mutex_unlock(&local->mtx);
J
Johannes Berg 已提交
2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499

		/*
		 * If somebody requests authentication and we haven't
		 * sent out an auth frame yet there's no need to send
		 * out a deauth frame either. If the state was PROBE,
		 * then this is the case. If it's AUTH we have sent a
		 * frame, and if it's IDLE we have completed the auth
		 * process already.
		 */
		if (not_auth_yet) {
			__cfg80211_auth_canceled(sdata->dev, bssid);
			return 0;
		}
	}
2500

2501
	printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n",
2502
	       sdata->name, bssid, req->reason_code);
2503

2504 2505 2506
	ieee80211_send_deauth_disassoc(sdata, bssid, IEEE80211_STYPE_DEAUTH,
				       req->reason_code, cookie,
				       !req->local_state_change);
2507 2508
	if (assoc_bss)
		sta_info_destroy_addr(sdata, bssid);
2509

2510
	mutex_lock(&sdata->local->mtx);
2511
	ieee80211_recalc_idle(sdata->local);
2512
	mutex_unlock(&sdata->local->mtx);
2513

2514 2515
	return 0;
}
2516

2517
int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
J
Johannes Berg 已提交
2518 2519
			   struct cfg80211_disassoc_request *req,
			   void *cookie)
J
Johannes Berg 已提交
2520
{
2521
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2522
	u8 bssid[ETH_ALEN];
J
Johannes Berg 已提交
2523

2524
	mutex_lock(&ifmgd->mtx);
2525

J
Johannes Berg 已提交
2526 2527 2528 2529 2530 2531
	/*
	 * cfg80211 should catch this ... but it's racy since
	 * we can receive a disassoc frame, process it, hand it
	 * to cfg80211 while that's in a locked section already
	 * trying to tell us that the user wants to disconnect.
	 */
2532
	if (ifmgd->associated != req->bss) {
2533 2534 2535 2536
		mutex_unlock(&ifmgd->mtx);
		return -ENOLINK;
	}

2537
	printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n",
2538
	       sdata->name, req->bss->bssid, req->reason_code);
2539

2540
	memcpy(bssid, req->bss->bssid, ETH_ALEN);
2541
	ieee80211_set_disassoc(sdata, false, true);
2542 2543

	mutex_unlock(&ifmgd->mtx);
2544

2545
	ieee80211_send_deauth_disassoc(sdata, req->bss->bssid,
J
Johannes Berg 已提交
2546
			IEEE80211_STYPE_DISASSOC, req->reason_code,
2547
			cookie, !req->local_state_change);
2548
	sta_info_destroy_addr(sdata, bssid);
2549

2550
	mutex_lock(&sdata->local->mtx);
2551
	ieee80211_recalc_idle(sdata->local);
2552
	mutex_unlock(&sdata->local->mtx);
2553

2554 2555
	return 0;
}
2556

2557 2558 2559 2560 2561 2562
void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
			       enum nl80211_cqm_rssi_threshold_event rssi_event,
			       gfp_t gfp)
{
	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);

J
Johannes Berg 已提交
2563 2564
	trace_api_cqm_rssi_notify(sdata, rssi_event);

2565 2566 2567
	cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp);
}
EXPORT_SYMBOL(ieee80211_cqm_rssi_notify);