mlme.c 143 KB
Newer Older
1 2
/*
 * BSS client mode implementation
3
 * Copyright 2003-2008, Jouni Malinen <j@w1.fi>
4 5 6 7
 * 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>
8
 * Copyright 2013-2014  Intel Mobile Communications GmbH
9
 * Copyright (C) 2015 - 2016 Intel Deutschland GmbH
10 11 12 13 14 15
 *
 * 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.
 */

16
#include <linux/delay.h>
17 18 19 20
#include <linux/if_ether.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
21
#include <linux/moduleparam.h>
22
#include <linux/rtnetlink.h>
23
#include <linux/crc32.h>
24
#include <linux/slab.h>
25
#include <linux/export.h>
26
#include <net/mac80211.h>
27
#include <asm/unaligned.h>
Johannes Berg's avatar
Johannes Berg committed
28

29
#include "ieee80211_i.h"
30
#include "driver-ops.h"
Johannes Berg's avatar
Johannes Berg committed
31 32
#include "rate.h"
#include "led.h"
33

34
#define IEEE80211_AUTH_TIMEOUT		(HZ / 5)
35
#define IEEE80211_AUTH_TIMEOUT_LONG	(HZ / 2)
36 37 38 39
#define IEEE80211_AUTH_TIMEOUT_SHORT	(HZ / 10)
#define IEEE80211_AUTH_MAX_TRIES	3
#define IEEE80211_AUTH_WAIT_ASSOC	(HZ * 5)
#define IEEE80211_ASSOC_TIMEOUT		(HZ / 5)
40
#define IEEE80211_ASSOC_TIMEOUT_LONG	(HZ / 2)
41 42
#define IEEE80211_ASSOC_TIMEOUT_SHORT	(HZ / 10)
#define IEEE80211_ASSOC_MAX_TRIES	3
43

44 45 46 47 48 49 50 51 52
static int max_nullfunc_tries = 2;
module_param(max_nullfunc_tries, int, 0644);
MODULE_PARM_DESC(max_nullfunc_tries,
		 "Maximum nullfunc tx tries before disconnecting (reason 4).");

static int max_probe_tries = 5;
module_param(max_probe_tries, int, 0644);
MODULE_PARM_DESC(max_probe_tries,
		 "Maximum probe tries before disconnecting (reason 4).");
53 54

/*
55 56 57 58 59 60
 * 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.
61
 */
62 63 64 65
static int beacon_loss_count = 7;
module_param(beacon_loss_count, int, 0644);
MODULE_PARM_DESC(beacon_loss_count,
		 "Number of beacon intervals before we decide beacon was lost.");
66

67 68 69 70
/*
 * Time the connection can be idle before we probe
 * it to see if we can still talk to the AP.
 */
71
#define IEEE80211_CONNECTION_IDLE_TIME	(30 * HZ)
72 73 74 75 76
/*
 * Time we wait for a probe response after sending
 * a probe request because of beacon loss or for
 * checking the connection still works.
 */
77 78 79 80 81
static int probe_wait_ms = 500;
module_param(probe_wait_ms, int, 0644);
MODULE_PARM_DESC(probe_wait_ms,
		 "Maximum time(ms) to wait for probe response"
		 " before disconnecting (reason 4).");
82

83 84 85 86 87 88
/*
 * 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

89 90 91 92 93 94 95 96 97 98
/*
 * 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.
 */
99 100
static void run_again(struct ieee80211_sub_if_data *sdata,
		      unsigned long timeout)
101
{
102
	sdata_assert_lock(sdata);
103

104 105 106
	if (!timer_pending(&sdata->u.mgd.timer) ||
	    time_before(timeout, sdata->u.mgd.timer.expires))
		mod_timer(&sdata->u.mgd.timer, timeout);
107 108
}

109
void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
110
{
111
	if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)
112 113
		return;

114
	if (ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
115 116
		return;

117
	mod_timer(&sdata->u.mgd.bcn_mon_timer,
118
		  round_jiffies_up(jiffies + sdata->u.mgd.beacon_timeout));
119 120
}

121 122
void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
{
123 124
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

125
	if (unlikely(!ifmgd->associated))
126 127
		return;

128 129
	if (ifmgd->probe_send_count)
		ifmgd->probe_send_count = 0;
130

131
	if (ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
132 133
		return;

134
	mod_timer(&ifmgd->conn_mon_timer,
135 136 137
		  round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
}

138
static int ecw2cw(int ecw)
Johannes Berg's avatar
Johannes Berg committed
139
{
140
	return (1 << ecw) - 1;
Johannes Berg's avatar
Johannes Berg committed
141 142
}

143 144 145 146
static u32
ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
			     struct ieee80211_supported_band *sband,
			     struct ieee80211_channel *channel,
147
			     const struct ieee80211_ht_cap *ht_cap,
148 149
			     const struct ieee80211_ht_operation *ht_oper,
			     const struct ieee80211_vht_operation *vht_oper,
150
			     struct cfg80211_chan_def *chandef, bool tracking)
151
{
152
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
153
	struct cfg80211_chan_def vht_chandef;
154
	struct ieee80211_sta_ht_cap sta_ht_cap;
155 156
	u32 ht_cfreq, ret;

157 158 159
	memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap));
	ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap);

160 161 162 163 164
	chandef->chan = channel;
	chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
	chandef->center_freq1 = channel->center_freq;
	chandef->center_freq2 = 0;

165
	if (!ht_cap || !ht_oper || !sta_ht_cap.ht_supported) {
166 167 168 169 170 171
		ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
		goto out;
	}

	chandef->width = NL80211_CHAN_WIDTH_20;

172 173
	if (!(ht_cap->cap_info &
	      cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40))) {
174
		ret = IEEE80211_STA_DISABLE_40MHZ;
175
		vht_chandef = *chandef;
176 177 178
		goto out;
	}

179 180 181
	ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan,
						  channel->band);
	/* check that channel matches the right operating channel */
182
	if (!tracking && channel->center_freq != ht_cfreq) {
183 184 185 186 187 188 189
		/*
		 * It's possible that some APs are confused here;
		 * Netgear WNDR3700 sometimes reports 4 higher than
		 * the actual channel in association responses, but
		 * since we look at probe response/beacon data here
		 * it should be OK.
		 */
190 191 192 193
		sdata_info(sdata,
			   "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n",
			   channel->center_freq, ht_cfreq,
			   ht_oper->primary_chan, channel->band);
194 195 196 197 198
		ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
		goto out;
	}

	/* check 40 MHz support, if we have it */
199
	if (sta_ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
200
		ieee80211_chandef_ht_oper(ht_oper, chandef);
201 202 203
	} else {
		/* 40 MHz (and 80 MHz) must be supported for VHT */
		ret = IEEE80211_STA_DISABLE_VHT;
204 205
		/* also mark 40 MHz disabled */
		ret |= IEEE80211_STA_DISABLE_40MHZ;
206 207 208 209 210 211 212 213
		goto out;
	}

	if (!vht_oper || !sband->vht_cap.vht_supported) {
		ret = IEEE80211_STA_DISABLE_VHT;
		goto out;
	}

214 215
	vht_chandef = *chandef;
	if (!ieee80211_chandef_vht_oper(vht_oper, &vht_chandef)) {
216
		if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
217
			sdata_info(sdata,
218
				   "AP VHT information is invalid, disable VHT\n");
219 220 221 222 223
		ret = IEEE80211_STA_DISABLE_VHT;
		goto out;
	}

	if (!cfg80211_chandef_valid(&vht_chandef)) {
224
		if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
225 226
			sdata_info(sdata,
				   "AP VHT information is invalid, disable VHT\n");
227 228 229 230 231 232 233 234 235 236
		ret = IEEE80211_STA_DISABLE_VHT;
		goto out;
	}

	if (cfg80211_chandef_identical(chandef, &vht_chandef)) {
		ret = 0;
		goto out;
	}

	if (!cfg80211_chandef_compatible(chandef, &vht_chandef)) {
237
		if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
238 239
			sdata_info(sdata,
				   "AP VHT information doesn't match HT, disable VHT\n");
240 241 242 243 244 245 246 247 248
		ret = IEEE80211_STA_DISABLE_VHT;
		goto out;
	}

	*chandef = vht_chandef;

	ret = 0;

out:
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
	/*
	 * When tracking the current AP, don't do any further checks if the
	 * new chandef is identical to the one we're currently using for the
	 * connection. This keeps us from playing ping-pong with regulatory,
	 * without it the following can happen (for example):
	 *  - connect to an AP with 80 MHz, world regdom allows 80 MHz
	 *  - AP advertises regdom US
	 *  - CRDA loads regdom US with 80 MHz prohibited (old database)
	 *  - the code below detects an unsupported channel, downgrades, and
	 *    we disconnect from the AP in the caller
	 *  - disconnect causes CRDA to reload world regdomain and the game
	 *    starts anew.
	 * (see https://bugzilla.kernel.org/show_bug.cgi?id=70881)
	 *
	 * It seems possible that there are still scenarios with CSA or real
	 * bandwidth changes where a this could happen, but those cases are
	 * less common and wouldn't completely prevent using the AP.
	 */
	if (tracking &&
	    cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef))
		return ret;

271 272 273 274
	/* don't print the message below for VHT mismatch if VHT is disabled */
	if (ret & IEEE80211_STA_DISABLE_VHT)
		vht_chandef = *chandef;

275 276 277 278 279 280 281 282
	/*
	 * Ignore the DISABLED flag when we're already connected and only
	 * tracking the APs beacon for bandwidth changes - otherwise we
	 * might get disconnected here if we connect to an AP, update our
	 * regulatory information based on the AP's country IE and the
	 * information we have is wrong/outdated and disables the channel
	 * that we're actually using for the connection to the AP.
	 */
283
	while (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
284 285
					tracking ? 0 :
						   IEEE80211_CHAN_DISABLED)) {
286 287 288
		if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) {
			ret = IEEE80211_STA_DISABLE_HT |
			      IEEE80211_STA_DISABLE_VHT;
289
			break;
290 291
		}

292
		ret |= ieee80211_chandef_downgrade(chandef);
293 294
	}

295
	if (chandef->width != vht_chandef.width && !tracking)
296 297 298 299 300 301 302
		sdata_info(sdata,
			   "capabilities/regulatory prevented using AP HT/VHT configuration, downgraded\n");

	WARN_ON_ONCE(!cfg80211_chandef_valid(chandef));
	return ret;
}

303 304
static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
			       struct sta_info *sta,
305
			       const struct ieee80211_ht_cap *ht_cap,
306 307 308
			       const struct ieee80211_ht_operation *ht_oper,
			       const struct ieee80211_vht_operation *vht_oper,
			       const u8 *bssid, u32 *changed)
309 310
{
	struct ieee80211_local *local = sdata->local;
311
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
312
	struct ieee80211_supported_band *sband;
313
	struct ieee80211_channel *chan;
314
	struct cfg80211_chan_def chandef;
315
	u16 ht_opmode;
316 317 318
	u32 flags;
	enum ieee80211_sta_rx_bandwidth new_sta_bw;
	int ret;
319

320 321
	/* if HT was/is disabled, don't track any bandwidth changes */
	if (ifmgd->flags & IEEE80211_STA_DISABLE_HT || !ht_oper)
322 323
		return 0;

324 325 326 327 328 329 330
	/* don't check VHT if we associated as non-VHT station */
	if (ifmgd->flags & IEEE80211_STA_DISABLE_VHT)
		vht_oper = NULL;

	if (WARN_ON_ONCE(!sta))
		return -EINVAL;

331 332 333 334 335 336 337 338 339 340
	/*
	 * if bss configuration changed store the new one -
	 * this may be applicable even if channel is identical
	 */
	ht_opmode = le16_to_cpu(ht_oper->operation_mode);
	if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
		*changed |= BSS_CHANGED_HT;
		sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
	}

341
	chan = sdata->vif.bss_conf.chandef.chan;
342
	sband = local->hw.wiphy->bands[chan->band];
343

344
	/* calculate new channel (type) based on HT/VHT operation IEs */
345 346 347
	flags = ieee80211_determine_chantype(sdata, sband, chan,
					     ht_cap, ht_oper, vht_oper,
					     &chandef, true);
348 349 350 351 352 353 354 355 356 357

	/*
	 * Downgrade the new channel if we associated with restricted
	 * capabilities. For example, if we associated as a 20 MHz STA
	 * to a 40 MHz AP (due to regulatory, capabilities or config
	 * reasons) then switching to a 40 MHz channel now won't do us
	 * any good -- we couldn't use it with the AP.
	 */
	if (ifmgd->flags & IEEE80211_STA_DISABLE_80P80MHZ &&
	    chandef.width == NL80211_CHAN_WIDTH_80P80)
358
		flags |= ieee80211_chandef_downgrade(&chandef);
359 360
	if (ifmgd->flags & IEEE80211_STA_DISABLE_160MHZ &&
	    chandef.width == NL80211_CHAN_WIDTH_160)
361
		flags |= ieee80211_chandef_downgrade(&chandef);
362 363
	if (ifmgd->flags & IEEE80211_STA_DISABLE_40MHZ &&
	    chandef.width > NL80211_CHAN_WIDTH_20)
364
		flags |= ieee80211_chandef_downgrade(&chandef);
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390

	if (cfg80211_chandef_identical(&chandef, &sdata->vif.bss_conf.chandef))
		return 0;

	sdata_info(sdata,
		   "AP %pM changed bandwidth, new config is %d MHz, width %d (%d/%d MHz)\n",
		   ifmgd->bssid, chandef.chan->center_freq, chandef.width,
		   chandef.center_freq1, chandef.center_freq2);

	if (flags != (ifmgd->flags & (IEEE80211_STA_DISABLE_HT |
				      IEEE80211_STA_DISABLE_VHT |
				      IEEE80211_STA_DISABLE_40MHZ |
				      IEEE80211_STA_DISABLE_80P80MHZ |
				      IEEE80211_STA_DISABLE_160MHZ)) ||
	    !cfg80211_chandef_valid(&chandef)) {
		sdata_info(sdata,
			   "AP %pM changed bandwidth in a way we can't support - disconnect\n",
			   ifmgd->bssid);
		return -EINVAL;
	}

	switch (chandef.width) {
	case NL80211_CHAN_WIDTH_20_NOHT:
	case NL80211_CHAN_WIDTH_20:
		new_sta_bw = IEEE80211_STA_RX_BW_20;
		break;
391
	case NL80211_CHAN_WIDTH_40:
392
		new_sta_bw = IEEE80211_STA_RX_BW_40;
393
		break;
394 395 396 397 398 399
	case NL80211_CHAN_WIDTH_80:
		new_sta_bw = IEEE80211_STA_RX_BW_80;
		break;
	case NL80211_CHAN_WIDTH_80P80:
	case NL80211_CHAN_WIDTH_160:
		new_sta_bw = IEEE80211_STA_RX_BW_160;
400
		break;
401 402
	default:
		return -EINVAL;
403
	}
404

405 406
	if (new_sta_bw > sta->cur_max_bandwidth)
		new_sta_bw = sta->cur_max_bandwidth;
407

408 409 410 411 412
	if (new_sta_bw < sta->sta.bandwidth) {
		sta->sta.bandwidth = new_sta_bw;
		rate_control_rate_update(local, sband, sta,
					 IEEE80211_RC_BW_CHANGED);
	}
413

414 415 416 417 418 419 420
	ret = ieee80211_vif_change_bandwidth(sdata, &chandef, changed);
	if (ret) {
		sdata_info(sdata,
			   "AP %pM changed bandwidth to incompatible one - disconnect\n",
			   ifmgd->bssid);
		return ret;
	}
421

422 423 424 425
	if (new_sta_bw > sta->sta.bandwidth) {
		sta->sta.bandwidth = new_sta_bw;
		rate_control_rate_update(local, sband, sta,
					 IEEE80211_RC_BW_CHANGED);
426
	}
427

428
	return 0;
429 430
}

431 432
/* frame sending functions */

433
static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
434
				struct sk_buff *skb, u8 ap_ht_param,
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451
				struct ieee80211_supported_band *sband,
				struct ieee80211_channel *channel,
				enum ieee80211_smps_mode smps)
{
	u8 *pos;
	u32 flags = channel->flags;
	u16 cap;
	struct ieee80211_sta_ht_cap ht_cap;

	BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap));

	memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
	ieee80211_apply_htcap_overrides(sdata, &ht_cap);

	/* determine capability flags */
	cap = ht_cap.cap;

452
	switch (ap_ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
453 454 455 456 457 458 459 460 461 462 463 464 465 466
	case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
		if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
			cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
			cap &= ~IEEE80211_HT_CAP_SGI_40;
		}
		break;
	case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
		if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
			cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
			cap &= ~IEEE80211_HT_CAP_SGI_40;
		}
		break;
	}

467 468 469 470 471 472 473 474 475 476
	/*
	 * If 40 MHz was disabled associate as though we weren't
	 * capable of 40 MHz -- some broken APs will never fall
	 * back to trying to transmit in 20 MHz.
	 */
	if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_40MHZ) {
		cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
		cap &= ~IEEE80211_HT_CAP_SGI_40;
	}

477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501
	/* set SM PS mode properly */
	cap &= ~IEEE80211_HT_CAP_SM_PS;
	switch (smps) {
	case IEEE80211_SMPS_AUTOMATIC:
	case IEEE80211_SMPS_NUM_MODES:
		WARN_ON(1);
	case IEEE80211_SMPS_OFF:
		cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
			IEEE80211_HT_CAP_SM_PS_SHIFT;
		break;
	case IEEE80211_SMPS_STATIC:
		cap |= WLAN_HT_CAP_SM_PS_STATIC <<
			IEEE80211_HT_CAP_SM_PS_SHIFT;
		break;
	case IEEE80211_SMPS_DYNAMIC:
		cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
			IEEE80211_HT_CAP_SM_PS_SHIFT;
		break;
	}

	/* reserve and fill IE */
	pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
	ieee80211_ie_build_ht_cap(pos, &ht_cap, cap);
}

502 503 504 505
/* This function determines vht capability flags for the association
 * and builds the IE.
 * Note - the function may set the owner of the MU-MIMO capability
 */
506 507
static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
				 struct sk_buff *skb,
508 509
				 struct ieee80211_supported_band *sband,
				 struct ieee80211_vht_cap *ap_vht_cap)
510
{
511
	struct ieee80211_local *local = sdata->local;
512 513 514
	u8 *pos;
	u32 cap;
	struct ieee80211_sta_vht_cap vht_cap;
515
	u32 mask, ap_bf_sts, our_bf_sts;
516 517 518 519

	BUILD_BUG_ON(sizeof(vht_cap) != sizeof(sband->vht_cap));

	memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap));
520
	ieee80211_apply_vhtcap_overrides(sdata, &vht_cap);
521 522 523 524

	/* determine capability flags */
	cap = vht_cap.cap;

525
	if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_80P80MHZ) {
526 527 528 529 530 531
		u32 bw = cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;

		cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
		if (bw == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ ||
		    bw == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
			cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
532 533 534 535
	}

	if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_160MHZ) {
		cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160;
536
		cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
537 538
	}

539 540 541 542 543 544
	/*
	 * Some APs apparently get confused if our capabilities are better
	 * than theirs, so restrict what we advertise in the assoc request.
	 */
	if (!(ap_vht_cap->vht_cap_info &
			cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)))
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562
		cap &= ~(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
			 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE);
	else if (!(ap_vht_cap->vht_cap_info &
			cpu_to_le32(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
		cap &= ~IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;

	/*
	 * If some other vif is using the MU-MIMO capablity we cannot associate
	 * using MU-MIMO - this will lead to contradictions in the group-id
	 * mechanism.
	 * Ownership is defined since association request, in order to avoid
	 * simultaneous associations with MU-MIMO.
	 */
	if (cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE) {
		bool disable_mu_mimo = false;
		struct ieee80211_sub_if_data *other;

		list_for_each_entry_rcu(other, &local->interfaces, list) {
563
			if (other->vif.mu_mimo_owner) {
564 565 566 567 568 569 570
				disable_mu_mimo = true;
				break;
			}
		}
		if (disable_mu_mimo)
			cap &= ~IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
		else
571
			sdata->vif.mu_mimo_owner = true;
572
	}
573

574 575 576 577 578 579 580 581 582 583
	mask = IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;

	ap_bf_sts = le32_to_cpu(ap_vht_cap->vht_cap_info) & mask;
	our_bf_sts = cap & mask;

	if (ap_bf_sts < our_bf_sts) {
		cap &= ~mask;
		cap |= ap_bf_sts;
	}

584
	/* reserve and fill IE */
585
	pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2);
586 587 588
	ieee80211_ie_build_vht_cap(pos, &vht_cap, cap);
}

589 590 591 592 593 594 595 596 597
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
	struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u8 *pos, qos_info;
	size_t offset = 0, noffset;
598
	int i, count, rates_len, supp_rates_len, shift;
599 600
	u16 capab;
	struct ieee80211_supported_band *sband;
601 602
	struct ieee80211_chanctx_conf *chanctx_conf;
	struct ieee80211_channel *chan;
603
	u32 rate_flags, rates = 0;
604

605
	sdata_assert_lock(sdata);
606

607 608 609 610 611 612
	rcu_read_lock();
	chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
	if (WARN_ON(!chanctx_conf)) {
		rcu_read_unlock();
		return;
	}
613
	chan = chanctx_conf->def.chan;
614
	rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
615 616
	rcu_read_unlock();
	sband = local->hw.wiphy->bands[chan->band];
617
	shift = ieee80211_vif_get_shift(&sdata->vif);
618 619 620 621 622 623 624 625

	if (assoc_data->supp_rates_len) {
		/*
		 * 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)...
		 */
626 627 628 629
		rates_len = ieee80211_parse_bitrates(&chanctx_conf->def, sband,
						     assoc_data->supp_rates,
						     assoc_data->supp_rates_len,
						     &rates);
630 631 632 633 634 635
	} else {
		/*
		 * In case AP not provide any supported rates information
		 * before association, we send information element(s) with
		 * all rates that we support.
		 */
636 637 638 639 640 641 642 643
		rates_len = 0;
		for (i = 0; i < sband->n_bitrates; i++) {
			if ((rate_flags & sband->bitrates[i].flags)
			    != rate_flags)
				continue;
			rates |= BIT(i);
			rates_len++;
		}
644 645 646 647 648 649 650 651 652
	}

	skb = alloc_skb(local->hw.extra_tx_headroom +
			sizeof(*mgmt) + /* bit too much but doesn't matter */
			2 + assoc_data->ssid_len + /* SSID */
			4 + rates_len + /* (extended) rates */
			4 + /* power capability */
			2 + 2 * sband->n_channels + /* supported channels */
			2 + sizeof(struct ieee80211_ht_cap) + /* HT */
653
			2 + sizeof(struct ieee80211_vht_cap) + /* VHT */
654 655 656 657 658 659 660 661 662 663
			assoc_data->ie_len + /* extra IEs */
			9, /* WMM */
			GFP_KERNEL);
	if (!skb)
		return;

	skb_reserve(skb, local->hw.extra_tx_headroom);

	capab = WLAN_CAPABILITY_ESS;

664
	if (sband->band == NL80211_BAND_2GHZ) {
665 666
		capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
		capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
667 668 669 670 671 672
	}

	if (assoc_data->capability & WLAN_CAPABILITY_PRIVACY)
		capab |= WLAN_CAPABILITY_PRIVACY;

	if ((assoc_data->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
673
	    ieee80211_hw_check(&local->hw, SPECTRUM_MGMT))
674 675
		capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;

676 677 678
	if (ifmgd->flags & IEEE80211_STA_ENABLE_RRM)
		capab |= WLAN_CAPABILITY_RADIO_MEASURE;

679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
	memset(mgmt, 0, 24);
	memcpy(mgmt->da, assoc_data->bss->bssid, ETH_ALEN);
	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
	memcpy(mgmt->bssid, assoc_data->bss->bssid, ETH_ALEN);

	if (!is_zero_ether_addr(assoc_data->prev_bssid)) {
		skb_put(skb, 10);
		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_REASSOC_REQ);
		mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
		mgmt->u.reassoc_req.listen_interval =
				cpu_to_le16(local->hw.conf.listen_interval);
		memcpy(mgmt->u.reassoc_req.current_ap, assoc_data->prev_bssid,
		       ETH_ALEN);
	} else {
		skb_put(skb, 4);
		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_ASSOC_REQ);
		mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
		mgmt->u.assoc_req.listen_interval =
				cpu_to_le16(local->hw.conf.listen_interval);
	}

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

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

	pos = skb_put(skb, supp_rates_len + 2);
	*pos++ = WLAN_EID_SUPP_RATES;
	*pos++ = supp_rates_len;

	count = 0;
	for (i = 0; i < sband->n_bitrates; i++) {
		if (BIT(i) & rates) {
721 722 723
			int rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
						5 * (1 << shift));
			*pos++ = (u8) rate;
724 725 726 727 728 729 730 731 732 733 734 735
			if (++count == 8)
				break;
		}
	}

	if (rates_len > count) {
		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) {
736 737 738 739
				int rate;
				rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
						    5 * (1 << shift));
				*pos++ = (u8) rate;
740 741 742 743
			}
		}
	}

744 745
	if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT ||
	    capab & WLAN_CAPABILITY_RADIO_MEASURE) {
746 747 748 749
		pos = skb_put(skb, 4);
		*pos++ = WLAN_EID_PWR_CAPABILITY;
		*pos++ = 2;
		*pos++ = 0; /* min tx power */
750 751
		 /* max tx power */
		*pos++ = ieee80211_chandef_max_power(&chanctx_conf->def);
752
	}
753

754
	if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
755 756 757 758 759 760 761 762 763 764 765 766
		/* 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*/
		}
	}

	/* if present, add any custom IEs that go before HT */
767
	if (assoc_data->ie_len) {
768 769 770 771 772 773 774 775 776 777
		static const u8 before_ht[] = {
			WLAN_EID_SSID,
			WLAN_EID_SUPP_RATES,
			WLAN_EID_EXT_SUPP_RATES,
			WLAN_EID_PWR_CAPABILITY,
			WLAN_EID_SUPPORTED_CHANNELS,
			WLAN_EID_RSN,
			WLAN_EID_QOS_CAPA,
			WLAN_EID_RRM_ENABLED_CAPABILITIES,
			WLAN_EID_MOBILITY_DOMAIN,
778 779
			WLAN_EID_FAST_BSS_TRANSITION,	/* reassoc only */
			WLAN_EID_RIC_DATA,		/* reassoc only */
780 781
			WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
		};
782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801
		static const u8 after_ric[] = {
			WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
			WLAN_EID_HT_CAPABILITY,
			WLAN_EID_BSS_COEX_2040,
			WLAN_EID_EXT_CAPABILITY,
			WLAN_EID_QOS_TRAFFIC_CAPA,
			WLAN_EID_TIM_BCAST_REQ,
			WLAN_EID_INTERWORKING,
			/* 60GHz doesn't happen right now */
			WLAN_EID_VHT_CAPABILITY,
			WLAN_EID_OPMODE_NOTIF,
		};

		noffset = ieee80211_ie_split_ric(assoc_data->ie,
						 assoc_data->ie_len,
						 before_ht,
						 ARRAY_SIZE(before_ht),
						 after_ric,
						 ARRAY_SIZE(after_ric),
						 offset);
802 803 804 805 806
		pos = skb_put(skb, noffset - offset);
		memcpy(pos, assoc_data->ie + offset, noffset - offset);
		offset = noffset;
	}

807 808 809 810
	if (WARN_ON_ONCE((ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
			 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)))
		ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;

811
	if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
812
		ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param,
813
				    sband, chan, sdata->smps_mode);
814

815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834
	/* if present, add any custom IEs that go before VHT */
	if (assoc_data->ie_len) {
		static const u8 before_vht[] = {
			WLAN_EID_SSID,
			WLAN_EID_SUPP_RATES,
			WLAN_EID_EXT_SUPP_RATES,
			WLAN_EID_PWR_CAPABILITY,
			WLAN_EID_SUPPORTED_CHANNELS,
			WLAN_EID_RSN,
			WLAN_EID_QOS_CAPA,
			WLAN_EID_RRM_ENABLED_CAPABILITIES,
			WLAN_EID_MOBILITY_DOMAIN,
			WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
			WLAN_EID_HT_CAPABILITY,
			WLAN_EID_BSS_COEX_2040,
			WLAN_EID_EXT_CAPABILITY,
			WLAN_EID_QOS_TRAFFIC_CAPA,
			WLAN_EID_TIM_BCAST_REQ,
			WLAN_EID_INTERWORKING,
		};
835 836

		/* RIC already taken above, so no need to handle here anymore */
837 838 839 840 841 842 843 844
		noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len,
					     before_vht, ARRAY_SIZE(before_vht),
					     offset);
		pos = skb_put(skb, noffset - offset);
		memcpy(pos, assoc_data->ie + offset, noffset - offset);
		offset = noffset;
	}

845
	if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
846 847
		ieee80211_add_vht_ie(sdata, skb, sband,
				     &assoc_data->ap_vht_cap);
848

849
	/* if present, add any custom non-vendor IEs that go after HT */
850
	if (assoc_data->ie_len) {
851 852 853 854 855 856 857 858
		noffset = ieee80211_ie_split_vendor(assoc_data->ie,
						    assoc_data->ie_len,
						    offset);
		pos = skb_put(skb, noffset - offset);
		memcpy(pos, assoc_data->ie + offset, noffset - offset);
		offset = noffset;
	}

859 860
	if (assoc_data->wmm) {
		if (assoc_data->uapsd) {
861 862
			qos_info = ifmgd->uapsd_queues;
			qos_info |= (ifmgd->uapsd_max_sp_len <<
863 864 865 866 867
				     IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
		} else {
			qos_info = 0;
		}

868
		pos = ieee80211_add_wmm_info_ie(skb_put(skb, 9), qos_info);
869 870 871
	}

	/* add any remaining custom (i.e. vendor specific here) IEs */
872
	if (assoc_data->ie_len) {
873 874 875 876 877
		noffset = assoc_data->ie_len;
		pos = skb_put(skb, noffset - offset);
		memcpy(pos, assoc_data->ie + offset, noffset - offset);
	}

Johannes Berg's avatar
Johannes Berg committed
878 879
	drv_mgd_prepare_tx(local, sdata);

880
	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
881
	if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
882 883
		IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS |
						IEEE80211_TX_INTFL_MLME_CONN_TX;
884 885 886
	ieee80211_tx_skb(sdata, skb);
}

887 888 889 890 891 892
void ieee80211_send_pspoll(struct ieee80211_local *local,
			   struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_pspoll *pspoll;
	struct sk_buff *skb;

893 894
	skb = ieee80211_pspoll_get(&local->hw, &sdata->vif);
	if (!skb)
895 896
		return;

897 898
	pspoll = (struct ieee80211_pspoll *) skb->data;
	pspoll->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
899

900 901
	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
	ieee80211_tx_skb(sdata, skb);
902 903
}

904 905
void ieee80211_send_nullfunc(struct ieee80211_local *local,
			     struct ieee80211_sub_if_data *sdata,
906
			     bool powersave)
907 908
{
	struct sk_buff *skb;
909
	struct ieee80211_hdr_3addr *nullfunc;
910
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
911

912 913
	skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif);
	if (!skb)
914 915
		return;

916
	nullfunc = (struct ieee80211_hdr_3addr *) skb->data;
917
	if (powersave)
918
		nullfunc->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
919

920 921
	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
					IEEE80211_TX_INTFL_OFFCHAN_TX_OK;
922

923
	if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
924 925
		IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;

926
	if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL)
927 928
		IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE;

929
	ieee80211_tx_skb(sdata, skb);
930 931
}

932 933 934 935 936 937 938 939 940 941 942
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);
943
	if (!skb)
944
		return;
945

946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961
	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);
}

962 963 964 965 966
/* 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);
967
	struct ieee80211_local *local = sdata->local;
968
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
969
	int ret;
970

971
	if (!ieee80211_sdata_running(sdata))
972 973
		return;

974
	sdata_lock(sdata);
975 976 977
	mutex_lock(&local->mtx);
	mutex_lock(&local->chanctx_mtx);

978 979
	if (!ifmgd->associated)
		goto out;
980

981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
	if (!sdata->vif.csa_active)
		goto out;

	/*
	 * using reservation isn't immediate as it may be deferred until later
	 * with multi-vif. once reservation is complete it will re-schedule the
	 * work with no reserved_chanctx so verify chandef to check if it
	 * completed successfully
	 */

	if (sdata->reserved_chanctx) {
		/*
		 * with multi-vif csa driver may call ieee80211_csa_finish()
		 * many times while waiting for other interfaces to use their
		 * reservations
		 */
		if (sdata->reserved_ready)
			goto out;

		ret = ieee80211_vif_use_reserved_context(sdata);
		if (ret) {
			sdata_info(sdata,
				   "failed to use reserved channel context, disconnecting (err=%d)\n",
				   ret);
			ieee80211_queue_work(&sdata->local->hw,
					     &ifmgd->csa_connection_drop_work);
			goto out;
		}

		goto out;
	}

	if (!cfg80211_chandef_identical(&sdata->vif.bss_conf.chandef,
					&sdata->csa_chandef)) {
1015
		sdata_info(sdata,
1016
			   "failed to finalize channel switch, disconnecting\n");
1017 1018 1019 1020
		ieee80211_queue_work(&sdata->local->hw,
				     &ifmgd->csa_connection_drop_work);
		goto out;
	}
1021

1022
	/* XXX: shouldn't really modify cfg80211-owned data! */
1023
	ifmgd->associated->channel = sdata->csa_chandef.chan;
1024

1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044
	ifmgd->csa_waiting_bcn = true;

	ieee80211_sta_reset_beacon_monitor(sdata);
	ieee80211_sta_reset_conn_monitor(sdata);

out:
	mutex_unlock(&local->chanctx_mtx);
	mutex_unlock(&local->mtx);
	sdata_unlock(sdata);
}

static void ieee80211_chswitch_post_beacon(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
	int ret;

	sdata_assert_lock(sdata);

	WARN_ON(!sdata->vif.csa_active);
1045

1046 1047 1048 1049 1050
	if (sdata->csa_block_tx) {
		ieee80211_wake_vif_queues(local, sdata,
					  IEEE80211_QUEUE_STOP_REASON_CSA);
		sdata->csa_block_tx = false;
	}
1051

1052 1053 1054
	sdata->vif.csa_active = false;
	ifmgd->csa_waiting_bcn = false;

1055 1056 1057 1058 1059 1060
	ret = drv_post_channel_switch(sdata);
	if (ret) {
		sdata_info(sdata,
			   "driver post channel switch failed, disconnecting\n");
		ieee80211_queue_work(&local->hw,
				     &ifmgd->csa_connection_drop_work);
1061
		return;
1062
	}
1063 1064

	cfg80211_ch_switch_notify(sdata->dev, &sdata->reserved_chandef);
1065 1066
}

1067 1068
void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
{
1069 1070
	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1071 1072 1073

	trace_api_chswitch_done(sdata, success);
	if (!success) {
1074 1075 1076 1077 1078 1079
		sdata_info(sdata,
			   "driver channel switch failed, disconnecting\n");
		ieee80211_queue_work(&sdata->local->hw,
				     &ifmgd->csa_connection_drop_work);
	} else {
		ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
1080 1081 1082 1083
	}
}
EXPORT_SYMBOL(ieee80211_chswitch_done);

1084 1085 1086 1087
static void ieee80211_chswitch_timer(unsigned long data)
{
	struct ieee80211_sub_if_data *sdata =
		(struct ieee80211_sub_if_data *) data;
1088

1089
	ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.chswitch_work);
1090 1091
}

1092
static void
1093
ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1094 1095
				 u64 timestamp, u32 device_timestamp,
				 struct ieee802_11_elems *elems,
1096
				 bool beacon)
1097
{
1098
	struct ieee80211_local *local = sdata->local;
1099
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1100
	struct cfg80211_bss *cbss = ifmgd->associated;
1101
	struct ieee80211_chanctx_conf *conf;
1102
	struct ieee80211_chanctx *chanctx;
1103
	enum nl80211_band current_band;
1104
	struct ieee80211_csa_ie csa_ie;
1105
	struct ieee80211_channel_switch ch_switch;
1106
	int res;
1107

1108
	sdata_assert_lock(sdata);
1109

1110
	if (!cbss)
1111 1112
		return;

1113
	if (local->scanning)
1114 1115
		return;

1116
	/* disregard subsequent announcements if we are already processing */
1117
	if (sdata->vif.csa_active)
1118 1119
		return;

1120
	current_band = cbss->channel->band;
1121
	memset(&csa_ie, 0, sizeof(csa_ie));
1122
	res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band,
1123
					   ifmgd->flags,
1124
					   ifmgd->associated->bssid, &csa_ie);
1125
	if (res	< 0)
1126
		ieee80211_queue_work(&local->hw,
1127
				     &ifmgd->csa_connection_drop_work);
1128
	if (res)
1129
		return;
1130

1131
	if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef,
1132 1133 1134
				     IEEE80211_CHAN_DISABLED)) {
		sdata_info(sdata,
			   "AP %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n",
1135
			   ifmgd->associated->bssid,
1136 1137 1138
			   csa_ie.chandef.chan->center_freq,
			   csa_ie.chandef.width, csa_ie.chandef.center_freq1,
			   csa_ie.chandef.center_freq2);
1139 1140 1141 1142 1143
		ieee80211_queue_work(&local->hw,
				     &ifmgd->csa_connection_drop_work);
		return;
	}

1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154
	if (cfg80211_chandef_identical(&csa_ie.chandef,
				       &sdata->vif.bss_conf.chandef)) {
		if (ifmgd->csa_ignored_same_chan)
			return;
		sdata_info(sdata,
			   "AP %pM tries to chanswitch to same channel, ignore\n",
			   ifmgd->associated->bssid);
		ifmgd->csa_ignored_same_chan = true;
		return;
	}

1155 1156 1157 1158 1159 1160 1161 1162
	/*
	 * Drop all TDLS peers - either we disconnect or move to a different
	 * channel from this point on. There's no telling what our peer will do.
	 * The TDLS WIDER_BW scenario is also problematic, as peers might now
	 * have an incompatible wider chandef.
	 */
	ieee80211_teardown_tdls_peers(sdata);

1163
	mutex_lock(&local->mtx);
1164
	mutex_lock(&local->chanctx_mtx);
1165 1166 1167 1168 1169
	conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
					 lockdep_is_held(&local->chanctx_mtx));
	if (!conf) {
		sdata_info(sdata,
			   "no channel context assigned to vif?, disconnecting\n");
1170
		goto drop_connection;
1171 1172 1173 1174
	}

	chanctx = container_of(conf, struct ieee80211_chanctx, conf);

1175
	if (local->use_chanctx &&
1176
	    !ieee80211_hw_check(&local->hw, CHANCTX_STA_CSA)) {
1177 1178
		sdata_info(sdata,
			   "driver doesn't support chan-switch with channel contexts\n");
1179
		goto drop_connection;
1180 1181
	}

1182 1183 1184 1185 1186 1187 1188 1189 1190
	ch_switch.timestamp = timestamp;
	ch_switch.device_timestamp = device_timestamp;
	ch_switch.block_tx = csa_ie.mode;
	ch_switch.chandef = csa_ie.chandef;
	ch_switch.count = csa_ie.count;

	if (drv_pre_channel_switch(sdata, &ch_switch)) {
		sdata_info(sdata,
			   "preparing for channel switch failed, disconnecting\n");
1191
		goto drop_connection;
1192 1193
	}

1194 1195 1196
	res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef,
					    chanctx->mode, false);
	if (res) {
1197
		sdata_info(sdata,
1198 1199
			   "failed to reserve channel context for channel switch, disconnecting (err=%d)\n",
			   res);
1200
		goto drop_connection;
1201
	}
1202
	mutex_unlock(&local->chanctx_mtx);
1203

1204
	sdata->vif.csa_active = true;
1205
	sdata->csa_chandef = csa_ie.chandef;
1206
	sdata->csa_block_tx = csa_ie.mode;
1207
	ifmgd->csa_ignored_same_chan = false;
1208

1209
	if (sdata->csa_block_tx)
1210 1211
		ieee80211_stop_vif_queues(local, sdata,
					  IEEE80211_QUEUE_STOP_REASON_CSA);
1212
	mutex_unlock(&local->mtx);
1213

1214 1215 1216
	cfg80211_ch_switch_started_notify(sdata->dev, &csa_ie.chandef,
					  csa_ie.count);

1217
	if (local->ops->channel_switch) {
1218
		/* use driver's channel switch callback */
1219
		drv_channel_switch(local, sdata, &ch_switch);
1220 1221 1222 1223
		return;
	}

	/* channel switch handled in software */
1224
	if (csa_ie.count <= 1)
1225
		ieee80211_queue_work(&local->hw, &ifmgd->chswitch_work);
1226
	else
1227
		mod_timer(&ifmgd->chswitch_timer,
1228 1229
			  TU_TO_EXP_TIME((csa_ie.count - 1) *
					 cbss->beacon_interval));
1230 1231