mlme.c 144 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 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 126 127
	if (unlikely(!sdata->u.mgd.associated))
		return;

128 129
	ifmgd->probe_send_count = 0;

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

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

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

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

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

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

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

	chandef->width = NL80211_CHAN_WIDTH_20;

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

178 179 180
	ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan,
						  channel->band);
	/* check that channel matches the right operating channel */
181
	if (!tracking && channel->center_freq != ht_cfreq) {
182 183 184 185 186 187 188
		/*
		 * 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.
		 */
189 190 191 192
		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);
193 194 195 196 197
		ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
		goto out;
	}

	/* check 40 MHz support, if we have it */
198
	if (sta_ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
199 200 201 202 203 204 205 206 207 208 209 210 211
		switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
		case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
			chandef->width = NL80211_CHAN_WIDTH_40;
			chandef->center_freq1 += 10;
			break;
		case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
			chandef->width = NL80211_CHAN_WIDTH_40;
			chandef->center_freq1 -= 10;
			break;
		}
	} else {
		/* 40 MHz (and 80 MHz) must be supported for VHT */
		ret = IEEE80211_STA_DISABLE_VHT;
212 213
		/* also mark 40 MHz disabled */
		ret |= IEEE80211_STA_DISABLE_40MHZ;
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
		goto out;
	}

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

	vht_chandef.chan = channel;
	vht_chandef.center_freq1 =
		ieee80211_channel_to_frequency(vht_oper->center_freq_seg1_idx,
					       channel->band);
	vht_chandef.center_freq2 = 0;

	switch (vht_oper->chan_width) {
	case IEEE80211_VHT_CHANWIDTH_USE_HT:
		vht_chandef.width = chandef->width;
231
		vht_chandef.center_freq1 = chandef->center_freq1;
232 233 234 235 236 237 238 239 240
		break;
	case IEEE80211_VHT_CHANWIDTH_80MHZ:
		vht_chandef.width = NL80211_CHAN_WIDTH_80;
		break;
	case IEEE80211_VHT_CHANWIDTH_160MHZ:
		vht_chandef.width = NL80211_CHAN_WIDTH_160;
		break;
	case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
		vht_chandef.width = NL80211_CHAN_WIDTH_80P80;
241 242 243 244
		vht_chandef.center_freq2 =
			ieee80211_channel_to_frequency(
				vht_oper->center_freq_seg2_idx,
				channel->band);
245 246
		break;
	default:
247
		if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
248 249 250
			sdata_info(sdata,
				   "AP VHT operation IE has invalid channel width (%d), disable VHT\n",
				   vht_oper->chan_width);
251 252 253 254 255
		ret = IEEE80211_STA_DISABLE_VHT;
		goto out;
	}

	if (!cfg80211_chandef_valid(&vht_chandef)) {
256
		if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
257 258
			sdata_info(sdata,
				   "AP VHT information is invalid, disable VHT\n");
259 260 261 262 263 264 265 266 267 268
		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)) {
269
		if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
270 271
			sdata_info(sdata,
				   "AP VHT information doesn't match HT, disable VHT\n");
272 273 274 275 276 277 278 279 280
		ret = IEEE80211_STA_DISABLE_VHT;
		goto out;
	}

	*chandef = vht_chandef;

	ret = 0;

out:
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
	/*
	 * 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;

303 304 305 306
	/* don't print the message below for VHT mismatch if VHT is disabled */
	if (ret & IEEE80211_STA_DISABLE_VHT)
		vht_chandef = *chandef;

307 308 309 310 311 312 313 314
	/*
	 * 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.
	 */
315
	while (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
316 317
					tracking ? 0 :
						   IEEE80211_CHAN_DISABLED)) {
318 319 320
		if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) {
			ret = IEEE80211_STA_DISABLE_HT |
			      IEEE80211_STA_DISABLE_VHT;
321
			break;
322 323
		}

324
		ret |= ieee80211_chandef_downgrade(chandef);
325 326
	}

327
	if (chandef->width != vht_chandef.width && !tracking)
328 329 330 331 332 333 334
		sdata_info(sdata,
			   "capabilities/regulatory prevented using AP HT/VHT configuration, downgraded\n");

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

335 336
static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
			       struct sta_info *sta,
337
			       const struct ieee80211_ht_cap *ht_cap,
338 339 340
			       const struct ieee80211_ht_operation *ht_oper,
			       const struct ieee80211_vht_operation *vht_oper,
			       const u8 *bssid, u32 *changed)
341 342
{
	struct ieee80211_local *local = sdata->local;
343
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
344
	struct ieee80211_supported_band *sband;
345
	struct ieee80211_channel *chan;
346
	struct cfg80211_chan_def chandef;
347
	u16 ht_opmode;
348 349 350
	u32 flags;
	enum ieee80211_sta_rx_bandwidth new_sta_bw;
	int ret;
351

352 353
	/* if HT was/is disabled, don't track any bandwidth changes */
	if (ifmgd->flags & IEEE80211_STA_DISABLE_HT || !ht_oper)
354 355
		return 0;

356 357 358 359 360 361 362
	/* 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;

363 364 365 366 367 368 369 370 371 372
	/*
	 * 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;
	}

373
	chan = sdata->vif.bss_conf.chandef.chan;
374
	sband = local->hw.wiphy->bands[chan->band];
375

376
	/* calculate new channel (type) based on HT/VHT operation IEs */
377 378 379
	flags = ieee80211_determine_chantype(sdata, sband, chan,
					     ht_cap, ht_oper, vht_oper,
					     &chandef, true);
380 381 382 383 384 385 386 387 388 389

	/*
	 * 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)
390
		flags |= ieee80211_chandef_downgrade(&chandef);
391 392
	if (ifmgd->flags & IEEE80211_STA_DISABLE_160MHZ &&
	    chandef.width == NL80211_CHAN_WIDTH_160)
393
		flags |= ieee80211_chandef_downgrade(&chandef);
394 395
	if (ifmgd->flags & IEEE80211_STA_DISABLE_40MHZ &&
	    chandef.width > NL80211_CHAN_WIDTH_20)
396
		flags |= ieee80211_chandef_downgrade(&chandef);
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422

	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;
423
	case NL80211_CHAN_WIDTH_40:
424
		new_sta_bw = IEEE80211_STA_RX_BW_40;
425
		break;
426 427 428 429 430 431
	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;
432
		break;
433 434
	default:
		return -EINVAL;
435
	}
436

437 438
	if (new_sta_bw > sta->cur_max_bandwidth)
		new_sta_bw = sta->cur_max_bandwidth;
439

440 441 442 443 444
	if (new_sta_bw < sta->sta.bandwidth) {
		sta->sta.bandwidth = new_sta_bw;
		rate_control_rate_update(local, sband, sta,
					 IEEE80211_RC_BW_CHANGED);
	}
445

446 447 448 449 450 451 452
	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;
	}
453

454 455 456 457
	if (new_sta_bw > sta->sta.bandwidth) {
		sta->sta.bandwidth = new_sta_bw;
		rate_control_rate_update(local, sband, sta,
					 IEEE80211_RC_BW_CHANGED);
458
	}
459

460
	return 0;
461 462
}

463 464
/* frame sending functions */

465
static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
466
				struct sk_buff *skb, u8 ap_ht_param,
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
				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;

484
	switch (ap_ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
485 486 487 488 489 490 491 492 493 494 495 496 497 498
	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;
	}

499 500 501 502 503 504 505 506 507 508
	/*
	 * 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;
	}

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

534 535 536 537
/* 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
 */
538 539
static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
				 struct sk_buff *skb,
540 541
				 struct ieee80211_supported_band *sband,
				 struct ieee80211_vht_cap *ap_vht_cap)
542
{
543
	struct ieee80211_local *local = sdata->local;
544 545 546
	u8 *pos;
	u32 cap;
	struct ieee80211_sta_vht_cap vht_cap;
547
	u32 mask, ap_bf_sts, our_bf_sts;
548 549 550 551

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

	memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap));
552
	ieee80211_apply_vhtcap_overrides(sdata, &vht_cap);
553 554 555 556

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

557
	if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_80P80MHZ) {
558 559 560 561 562 563
		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;
564 565 566 567
	}

	if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_160MHZ) {
		cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160;
568
		cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
569 570
	}

571 572 573 574 575 576
	/*
	 * 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)))
577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
		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) {
			if (other->flags & IEEE80211_SDATA_MU_MIMO_OWNER) {
				disable_mu_mimo = true;
				break;
			}
		}
		if (disable_mu_mimo)
			cap &= ~IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
		else
			sdata->flags |= IEEE80211_SDATA_MU_MIMO_OWNER;
	}
605

606 607 608 609 610 611 612 613 614 615
	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;
	}

616
	/* reserve and fill IE */
617
	pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2);
618 619 620
	ieee80211_ie_build_vht_cap(pos, &vht_cap, cap);
}

621 622 623 624 625 626 627 628 629
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;
630
	int i, count, rates_len, supp_rates_len, shift;
631 632
	u16 capab;
	struct ieee80211_supported_band *sband;
633 634
	struct ieee80211_chanctx_conf *chanctx_conf;
	struct ieee80211_channel *chan;
635
	u32 rate_flags, rates = 0;
636

637
	sdata_assert_lock(sdata);
638

639 640 641 642 643 644
	rcu_read_lock();
	chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
	if (WARN_ON(!chanctx_conf)) {
		rcu_read_unlock();
		return;
	}
645
	chan = chanctx_conf->def.chan;
646
	rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
647 648
	rcu_read_unlock();
	sband = local->hw.wiphy->bands[chan->band];
649
	shift = ieee80211_vif_get_shift(&sdata->vif);
650 651 652 653 654 655 656 657

	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)...
		 */
658 659 660 661
		rates_len = ieee80211_parse_bitrates(&chanctx_conf->def, sband,
						     assoc_data->supp_rates,
						     assoc_data->supp_rates_len,
						     &rates);
662 663 664 665 666 667
	} else {
		/*
		 * In case AP not provide any supported rates information
		 * before association, we send information element(s) with
		 * all rates that we support.
		 */
668 669 670 671 672 673 674 675
		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++;
		}
676 677 678 679 680 681 682 683 684
	}

	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 */
685
			2 + sizeof(struct ieee80211_vht_cap) + /* VHT */
686 687 688 689 690 691 692 693 694 695 696
			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;

	if (sband->band == IEEE80211_BAND_2GHZ) {
697 698
		capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
		capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
699 700 701 702 703 704
	}

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

	if ((assoc_data->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
705
	    ieee80211_hw_check(&local->hw, SPECTRUM_MGMT))
706 707
		capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;

708 709 710
	if (ifmgd->flags & IEEE80211_STA_ENABLE_RRM)
		capab |= WLAN_CAPABILITY_RADIO_MEASURE;

711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752
	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) {
753 754 755
			int rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
						5 * (1 << shift));
			*pos++ = (u8) rate;
756 757 758 759 760 761 762 763 764 765 766 767
			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) {
768 769 770 771
				int rate;
				rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
						    5 * (1 << shift));
				*pos++ = (u8) rate;
772 773 774 775
			}
		}
	}

776 777
	if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT ||
	    capab & WLAN_CAPABILITY_RADIO_MEASURE) {
778 779 780 781
		pos = skb_put(skb, 4);
		*pos++ = WLAN_EID_PWR_CAPABILITY;
		*pos++ = 2;
		*pos++ = 0; /* min tx power */
782 783
		 /* max tx power */
		*pos++ = ieee80211_chandef_max_power(&chanctx_conf->def);
784
	}
785

786
	if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
787 788 789 790 791 792 793 794 795 796 797 798
		/* 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 */
799
	if (assoc_data->ie_len) {
800 801 802 803 804 805 806 807 808 809
		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,
810 811
			WLAN_EID_FAST_BSS_TRANSITION,	/* reassoc only */
			WLAN_EID_RIC_DATA,		/* reassoc only */
812 813
			WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
		};
814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833
		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);
834 835 836 837 838
		pos = skb_put(skb, noffset - offset);
		memcpy(pos, assoc_data->ie + offset, noffset - offset);
		offset = noffset;
	}

839 840 841 842
	if (WARN_ON_ONCE((ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
			 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)))
		ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;

843
	if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
844
		ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param,
845
				    sband, chan, sdata->smps_mode);
846

847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866
	/* 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,
		};
867 868

		/* RIC already taken above, so no need to handle here anymore */
869 870 871 872 873 874 875 876
		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;
	}

877
	if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
878 879
		ieee80211_add_vht_ie(sdata, skb, sband,
				     &assoc_data->ap_vht_cap);
880

881
	/* if present, add any custom non-vendor IEs that go after HT */
882
	if (assoc_data->ie_len) {
883 884 885 886 887 888 889 890
		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;
	}

891 892
	if (assoc_data->wmm) {
		if (assoc_data->uapsd) {
893 894
			qos_info = ifmgd->uapsd_queues;
			qos_info |= (ifmgd->uapsd_max_sp_len <<
895 896 897 898 899
				     IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
		} else {
			qos_info = 0;
		}

900
		pos = ieee80211_add_wmm_info_ie(skb_put(skb, 9), qos_info);
901 902 903
	}

	/* add any remaining custom (i.e. vendor specific here) IEs */
904
	if (assoc_data->ie_len) {
905 906 907 908 909
		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
910 911
	drv_mgd_prepare_tx(local, sdata);

912
	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
913
	if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
914 915
		IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS |
						IEEE80211_TX_INTFL_MLME_CONN_TX;
916 917 918
	ieee80211_tx_skb(sdata, skb);
}

919 920 921 922 923 924
void ieee80211_send_pspoll(struct ieee80211_local *local,
			   struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_pspoll *pspoll;
	struct sk_buff *skb;

925 926
	skb = ieee80211_pspoll_get(&local->hw, &sdata->vif);
	if (!skb)
927 928
		return;

929 930
	pspoll = (struct ieee80211_pspoll *) skb->data;
	pspoll->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
931

932 933
	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
	ieee80211_tx_skb(sdata, skb);
934 935
}

936 937
void ieee80211_send_nullfunc(struct ieee80211_local *local,
			     struct ieee80211_sub_if_data *sdata,
938
			     bool powersave)
939 940
{
	struct sk_buff *skb;
941
	struct ieee80211_hdr_3addr *nullfunc;
942
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
943

944 945
	skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif);
	if (!skb)
946 947
		return;

948
	nullfunc = (struct ieee80211_hdr_3addr *) skb->data;
949
	if (powersave)
950
		nullfunc->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
951

952 953
	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
					IEEE80211_TX_INTFL_OFFCHAN_TX_OK;
954

955
	if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
956 957
		IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;

958
	if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL)
959 960
		IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE;

961
	ieee80211_tx_skb(sdata, skb);
962 963
}

964 965 966 967 968 969 970 971 972 973 974
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);
975
	if (!skb)
976
		return;
977

978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993
	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);
}

994 995 996 997 998
/* 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);
999
	struct ieee80211_local *local = sdata->local;
1000
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1001
	int ret;
1002

1003
	if (!ieee80211_sdata_running(sdata))
1004 1005
		return;

1006
	sdata_lock(sdata);
1007 1008 1009
	mutex_lock(&local->mtx);
	mutex_lock(&local->chanctx_mtx);

1010 1011
	if (!ifmgd->associated)
		goto out;
1012

1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046
	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)) {
1047
		sdata_info(sdata,
1048
			   "failed to finalize channel switch, disconnecting\n");
1049 1050 1051 1052
		ieee80211_queue_work(&sdata->local->hw,
				     &ifmgd->csa_connection_drop_work);
		goto out;
	}
1053

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

1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076
	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);
1077

1078 1079 1080 1081 1082
	if (sdata->csa_block_tx) {
		ieee80211_wake_vif_queues(local, sdata,
					  IEEE80211_QUEUE_STOP_REASON_CSA);
		sdata->csa_block_tx = false;
	}
1083

1084 1085 1086
	sdata->vif.csa_active = false;
	ifmgd->csa_waiting_bcn = false;

1087 1088 1089 1090 1091 1092
	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);
1093
		return;
1094
	}
1095 1096

	cfg80211_ch_switch_notify(sdata->dev, &sdata->reserved_chandef);
1097 1098
}

1099 1100
void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
{
1101 1102
	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1103 1104 1105

	trace_api_chswitch_done(sdata, success);
	if (!success) {
1106 1107 1108 1109 1110 1111
		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);
1112 1113 1114 1115
	}
}
EXPORT_SYMBOL(ieee80211_chswitch_done);

1116 1117 1118 1119
static void ieee80211_chswitch_timer(unsigned long data)
{
	struct ieee80211_sub_if_data *sdata =
		(struct ieee80211_sub_if_data *) data;
1120

1121
	ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.chswitch_work);
1122 1123
}

1124
static void
1125
ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1126 1127
				 u64 timestamp, u32 device_timestamp,
				 struct ieee802_11_elems *elems,
1128
				 bool beacon)
1129
{
1130
	struct ieee80211_local *local = sdata->local;
1131
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1132
	struct cfg80211_bss *cbss = ifmgd->associated;
1133
	struct ieee80211_chanctx_conf *conf;
1134
	struct ieee80211_chanctx *chanctx;
1135
	enum ieee80211_band current_band;
1136
	struct ieee80211_csa_ie csa_ie;
1137
	struct ieee80211_channel_switch ch_switch;
1138
	int res;
1139

1140
	sdata_assert_lock(sdata);
1141

1142
	if (!cbss)
1143 1144
		return;

1145
	if (local->scanning)
1146 1147
		return;

1148
	/* disregard subsequent announcements if we are already processing */
1149
	if (sdata->vif.csa_active)
1150 1151
		return;

1152
	current_band = cbss->channel->band;
1153
	memset(&csa_ie, 0, sizeof(csa_ie));
1154
	res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band,
1155
					   ifmgd->flags,
1156
					   ifmgd->associated->bssid, &csa_ie);
1157
	if (res	< 0)
1158
		ieee80211_queue_work(&local->hw,
1159
				     &ifmgd->csa_connection_drop_work);
1160
	if (res)
1161
		return;
1162

1163
	if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef,
1164 1165 1166
				     IEEE80211_CHAN_DISABLED)) {
		sdata_info(sdata,
			   "AP %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n",
1167
			   ifmgd->associated->bssid,
1168 1169 1170
			   csa_ie.chandef.chan->center_freq,
			   csa_ie.chandef.width, csa_ie.chandef.center_freq1,
			   csa_ie.chandef.center_freq2);
1171 1172 1173 1174 1175
		ieee80211_queue_work(&local->hw,
				     &ifmgd->csa_connection_drop_work);
		return;
	}

1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186
	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;
	}

1187 1188 1189 1190 1191 1192 1193 1194
	/*
	 * 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);

1195
	mutex_lock(&local->mtx);
1196
	mutex_lock(&local->chanctx_mtx);
1197 1198 1199 1200 1201
	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");
1202
		goto drop_connection;
1203 1204 1205 1206
	}

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

1207
	if (local->use_chanctx &&
1208
	    !ieee80211_hw_check(&local->hw, CHANCTX_STA_CSA)) {
1209 1210
		sdata_info(sdata,
			   "driver doesn't support chan-switch with channel contexts\n");
1211
		goto drop_connection;
1212 1213
	}

1214 1215 1216 1217 1218 1219 1220 1221 1222
	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");
1223
		goto drop_connection;
1224 1225
	}

1226 1227 1228
	res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef,
					    chanctx->mode, false);
	if (res) {
1229
		sdata_info(sdata,
1230 1231
			   "failed to reserve channel context for channel switch, disconnecting (err=%d)\n",
			   res);
1232
		goto drop_connection;
1233
	}
1234
	mutex_unlock(&local->chanctx_mtx);
1235

1236
	sdata->vif.csa_active = true;
1237
	sdata->csa_chandef = csa_ie.chandef;
1238
	sdata->csa_block_tx = csa_ie.mode;
1239
	ifmgd->csa_ignored_same_chan = false;
1240

1241
	if (sdata->csa_block_tx)
1242 1243
		ieee80211_stop_vif_queues(local, sdata,
					  IEEE80211_QUEUE_STOP_REASON_CSA);
1244
	mutex_unlock(&local->mtx);
1245

1246 1247 1248
	cfg80211_ch_switch_started_notify(sdata->dev, &csa_ie.chandef,
					  csa_ie.count);

1249
	if (local->ops->channel_switch) {
1250
		/* use driver's channel switch callback */
1251
		drv_channel_switch(local, sdata, &ch_switch);
1252 1253 1254 1255
		return;
	}

	/* channel switch handled in software */
1256
	if (csa_ie.count <= 1)
1257
		ieee80211_queue_work(&local->hw, &ifmgd->chswitch_work);
1258
	else
1259
		mod_timer(&ifmgd->chswitch_timer,
1260 1261
			  TU_TO_EXP_TIME((csa_ie.count - 1) *
					 cbss->beacon_interval));