iwl-core.c 52.8 KB
Newer Older
Tomas Winkler's avatar
Tomas Winkler committed
1
2
3
4
/******************************************************************************
 *
 * GPL LICENSE SUMMARY
 *
Wey-Yi Guy's avatar
Wey-Yi Guy committed
5
 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
Tomas Winkler's avatar
Tomas Winkler committed
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
 * USA
 *
 * The full GNU General Public License is included in this distribution
 * in the file called LICENSE.GPL.
 *
 * Contact Information:
25
 *  Intel Linux Wireless <ilw@linux.intel.com>
Tomas Winkler's avatar
Tomas Winkler committed
26
27
28
29
30
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *****************************************************************************/

#include <linux/kernel.h>
#include <linux/module.h>
31
#include <linux/etherdevice.h>
32
#include <linux/sched.h>
33
#include <linux/slab.h>
34
#include <net/mac80211.h>
Tomas Winkler's avatar
Tomas Winkler committed
35

36
#include "iwl-eeprom.h"
37
#include "iwl-dev.h" /* FIXME: remove */
38
#include "iwl-debug.h"
Tomas Winkler's avatar
Tomas Winkler committed
39
#include "iwl-core.h"
40
#include "iwl-io.h"
41
#include "iwl-power.h"
42
#include "iwl-sta.h"
Mohamed Abbas's avatar
Mohamed Abbas committed
43
#include "iwl-helpers.h"
Don Fry's avatar
Don Fry committed
44
#include "iwl-agn.h"
Tomas Winkler's avatar
Tomas Winkler committed
45

46
47
u32 iwl_debug_level;

48
49
const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

50
51
#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
52
static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
53
			      struct ieee80211_sta_ht_cap *ht_info,
54
55
			      enum ieee80211_band band)
{
Ron Rindjunsky's avatar
Ron Rindjunsky committed
56
57
58
59
	u16 max_bit_rate = 0;
	u8 rx_chains_num = priv->hw_params.rx_chains_num;
	u8 tx_chains_num = priv->hw_params.tx_chains_num;

60
	ht_info->cap = 0;
61
	memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
62

63
	ht_info->ht_supported = true;
64

65
66
	if (priv->cfg->ht_params &&
	    priv->cfg->ht_params->ht_greenfield_support)
67
		ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
68
	ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
Ron Rindjunsky's avatar
Ron Rindjunsky committed
69
	max_bit_rate = MAX_BIT_RATE_20_MHZ;
70
	if (priv->hw_params.ht40_channel & BIT(band)) {
71
72
73
		ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
		ht_info->cap |= IEEE80211_HT_CAP_SGI_40;
		ht_info->mcs.rx_mask[4] = 0x01;
Ron Rindjunsky's avatar
Ron Rindjunsky committed
74
		max_bit_rate = MAX_BIT_RATE_40_MHZ;
75
76
	}

Don Fry's avatar
Don Fry committed
77
	if (iwlagn_mod_params.amsdu_size_8K)
78
		ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
79
80

	ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
81
82
	if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_factor)
		ht_info->ampdu_factor = priv->cfg->bt_params->ampdu_factor;
83
	ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF;
84
85
	if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_density)
		ht_info->ampdu_density = priv->cfg->bt_params->ampdu_density;
86

87
	ht_info->mcs.rx_mask[0] = 0xFF;
Ron Rindjunsky's avatar
Ron Rindjunsky committed
88
	if (rx_chains_num >= 2)
89
		ht_info->mcs.rx_mask[1] = 0xFF;
Ron Rindjunsky's avatar
Ron Rindjunsky committed
90
	if (rx_chains_num >= 3)
91
		ht_info->mcs.rx_mask[2] = 0xFF;
Ron Rindjunsky's avatar
Ron Rindjunsky committed
92
93
94

	/* Highest supported Rx data rate */
	max_bit_rate *= rx_chains_num;
95
96
	WARN_ON(max_bit_rate & ~IEEE80211_HT_MCS_RX_HIGHEST_MASK);
	ht_info->mcs.rx_highest = cpu_to_le16(max_bit_rate);
Ron Rindjunsky's avatar
Ron Rindjunsky committed
97
98

	/* Tx MCS capabilities */
99
	ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
Ron Rindjunsky's avatar
Ron Rindjunsky committed
100
	if (tx_chains_num != rx_chains_num) {
101
102
103
		ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
		ht_info->mcs.tx_params |= ((tx_chains_num - 1) <<
				IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
Ron Rindjunsky's avatar
Ron Rindjunsky committed
104
	}
105
106
107
108
109
}

/**
 * iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom
 */
110
int iwlcore_init_geos(struct iwl_priv *priv)
111
112
113
114
115
116
117
{
	struct iwl_channel_info *ch;
	struct ieee80211_supported_band *sband;
	struct ieee80211_channel *channels;
	struct ieee80211_channel *geo_ch;
	struct ieee80211_rate *rates;
	int i = 0;
118
	s8 max_tx_power = IWLAGN_TX_POWER_TARGET_POWER_MIN;
119
120
121

	if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
	    priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
122
		IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n");
123
124
125
126
127
128
129
130
131
		set_bit(STATUS_GEO_CONFIGURED, &priv->status);
		return 0;
	}

	channels = kzalloc(sizeof(struct ieee80211_channel) *
			   priv->channel_count, GFP_KERNEL);
	if (!channels)
		return -ENOMEM;

132
	rates = kzalloc((sizeof(struct ieee80211_rate) * IWL_RATE_COUNT_LEGACY),
133
134
135
136
137
138
139
140
141
142
143
			GFP_KERNEL);
	if (!rates) {
		kfree(channels);
		return -ENOMEM;
	}

	/* 5.2GHz channels start after the 2.4GHz channels */
	sband = &priv->bands[IEEE80211_BAND_5GHZ];
	sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)];
	/* just OFDM */
	sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
144
	sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE;
145

146
	if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)
147
		iwlcore_init_ht_hw_capab(priv, &sband->ht_cap,
148
					 IEEE80211_BAND_5GHZ);
149
150
151
152
153

	sband = &priv->bands[IEEE80211_BAND_2GHZ];
	sband->channels = channels;
	/* OFDM & CCK */
	sband->bitrates = rates;
154
	sband->n_bitrates = IWL_RATE_COUNT_LEGACY;
155

156
	if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)
157
		iwlcore_init_ht_hw_capab(priv, &sband->ht_cap,
158
					 IEEE80211_BAND_2GHZ);
159
160
161
162
163
164
165
166
167
168
169

	priv->ieee_channels = channels;
	priv->ieee_rates = rates;

	for (i = 0;  i < priv->channel_count; i++) {
		ch = &priv->channel_info[i];

		/* FIXME: might be removed if scan is OK */
		if (!is_channel_valid(ch))
			continue;

170
		sband =  &priv->bands[ch->band];
171
172
173
174

		geo_ch = &sband->channels[sband->n_channels++];

		geo_ch->center_freq =
175
			ieee80211_channel_to_frequency(ch->channel, ch->band);
176
177
178
179
180
181
182
183
184
185
186
187
188
189
		geo_ch->max_power = ch->max_power_avg;
		geo_ch->max_antenna_gain = 0xff;
		geo_ch->hw_value = ch->channel;

		if (is_channel_valid(ch)) {
			if (!(ch->flags & EEPROM_CHANNEL_IBSS))
				geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;

			if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
				geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;

			if (ch->flags & EEPROM_CHANNEL_RADAR)
				geo_ch->flags |= IEEE80211_CHAN_RADAR;

190
			geo_ch->flags |= ch->ht40_extension_channel;
191

192
193
			if (ch->max_power_avg > max_tx_power)
				max_tx_power = ch->max_power_avg;
194
195
196
197
		} else {
			geo_ch->flags |= IEEE80211_CHAN_DISABLED;
		}

198
		IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
199
200
201
202
203
204
205
				ch->channel, geo_ch->center_freq,
				is_channel_a_band(ch) ?  "5.2" : "2.4",
				geo_ch->flags & IEEE80211_CHAN_DISABLED ?
				"restricted" : "valid",
				 geo_ch->flags);
	}

206
207
208
209
	priv->tx_power_device_lmt = max_tx_power;
	priv->tx_power_user_lmt = max_tx_power;
	priv->tx_power_next = max_tx_power;

210
	if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
211
	     priv->cfg->sku & EEPROM_SKU_CAP_BAND_52GHZ) {
212
213
		char buf[32];
		priv->bus.ops->get_hw_id(&priv->bus, buf, sizeof(buf));
Tomas Winkler's avatar
Tomas Winkler committed
214
		IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
215
			"Please send your %s to maintainer.\n", buf);
216
		priv->cfg->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ;
217
218
	}

Tomas Winkler's avatar
Tomas Winkler committed
219
	IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n",
220
221
		   priv->bands[IEEE80211_BAND_2GHZ].n_channels,
		   priv->bands[IEEE80211_BAND_5GHZ].n_channels);
222
223
224
225
226
227
228
229
230

	set_bit(STATUS_GEO_CONFIGURED, &priv->status);

	return 0;
}

/*
 * iwlcore_free_geos - undo allocations in iwlcore_init_geos
 */
231
void iwlcore_free_geos(struct iwl_priv *priv)
232
233
234
235
236
237
{
	kfree(priv->ieee_channels);
	kfree(priv->ieee_rates);
	clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
}

238
239
240
static bool iwl_is_channel_extension(struct iwl_priv *priv,
				     enum ieee80211_band band,
				     u16 channel, u8 extension_chan_offset)
241
242
243
244
245
{
	const struct iwl_channel_info *ch_info;

	ch_info = iwl_get_channel_info(priv, band, channel);
	if (!is_channel_valid(ch_info))
246
		return false;
247

248
	if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
249
		return !(ch_info->ht40_extension_channel &
250
					IEEE80211_CHAN_NO_HT40PLUS);
251
	else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW)
252
		return !(ch_info->ht40_extension_channel &
253
					IEEE80211_CHAN_NO_HT40MINUS);
254

255
	return false;
256
257
}

258
259
260
bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
			    struct iwl_rxon_context *ctx,
			    struct ieee80211_sta_ht_cap *ht_cap)
261
{
262
263
	if (!ctx->ht.enabled || !ctx->ht.is_40mhz)
		return false;
264

265
266
	/*
	 * We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40
267
268
	 * the bit will not set if it is pure 40MHz case
	 */
269
270
271
	if (ht_cap && !ht_cap->ht_supported)
		return false;

272
#ifdef CONFIG_IWLWIFI_DEBUGFS
273
	if (priv->disable_ht40)
274
		return false;
275
#endif
276

277
	return iwl_is_channel_extension(priv, priv->band,
278
			le16_to_cpu(ctx->staging.channel),
279
			ctx->ht.extension_chan_offset);
280
281
}

282
283
static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
{
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
	u16 new_val;
	u16 beacon_factor;

	/*
	 * If mac80211 hasn't given us a beacon interval, program
	 * the default into the device (not checking this here
	 * would cause the adjustment below to return the maximum
	 * value, which may break PAN.)
	 */
	if (!beacon_val)
		return DEFAULT_BEACON_INTERVAL;

	/*
	 * If the beacon interval we obtained from the peer
	 * is too large, we'll have to wake up more often
	 * (and in IBSS case, we'll beacon too much)
	 *
	 * For example, if max_beacon_val is 4096, and the
	 * requested beacon interval is 7000, we'll have to
	 * use 3500 to be able to wake up on the beacons.
	 *
	 * This could badly influence beacon detection stats.
	 */
307
308
309
310
311
312
313
314
315
316

	beacon_factor = (beacon_val + max_beacon_val) / max_beacon_val;
	new_val = beacon_val / beacon_factor;

	if (!new_val)
		new_val = max_beacon_val;

	return new_val;
}

317
int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
318
319
320
321
322
{
	u64 tsf;
	s32 interval_tm, rem;
	struct ieee80211_conf *conf = NULL;
	u16 beacon_int;
323
	struct ieee80211_vif *vif = ctx->vif;
324
325
326

	conf = ieee80211_get_hw_conf(priv->hw);

327
328
	lockdep_assert_held(&priv->mutex);

329
	memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd));
330

331
332
	ctx->timing.timestamp = cpu_to_le64(priv->timestamp);
	ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval);
333

334
	beacon_int = vif ? vif->bss_conf.beacon_int : 0;
335

336
337
338
339
340
	/*
	 * TODO: For IBSS we need to get atim_window from mac80211,
	 *	 for now just always use 0
	 */
	ctx->timing.atim_window = 0;
341

342
	if (ctx->ctxid == IWL_RXON_CTX_PAN &&
343
344
345
346
	    (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION) &&
	    iwl_is_associated(priv, IWL_RXON_CTX_BSS) &&
	    priv->contexts[IWL_RXON_CTX_BSS].vif &&
	    priv->contexts[IWL_RXON_CTX_BSS].vif->bss_conf.beacon_int) {
347
348
349
		ctx->timing.beacon_interval =
			priv->contexts[IWL_RXON_CTX_BSS].timing.beacon_interval;
		beacon_int = le16_to_cpu(ctx->timing.beacon_interval);
350
351
352
353
354
355
356
357
358
	} else if (ctx->ctxid == IWL_RXON_CTX_BSS &&
		   iwl_is_associated(priv, IWL_RXON_CTX_PAN) &&
		   priv->contexts[IWL_RXON_CTX_PAN].vif &&
		   priv->contexts[IWL_RXON_CTX_PAN].vif->bss_conf.beacon_int &&
		   (!iwl_is_associated_ctx(ctx) || !ctx->vif ||
		    !ctx->vif->bss_conf.beacon_int)) {
		ctx->timing.beacon_interval =
			priv->contexts[IWL_RXON_CTX_PAN].timing.beacon_interval;
		beacon_int = le16_to_cpu(ctx->timing.beacon_interval);
359
360
	} else {
		beacon_int = iwl_adjust_beacon_interval(beacon_int,
361
				priv->hw_params.max_beacon_itrvl * TIME_UNIT);
362
363
		ctx->timing.beacon_interval = cpu_to_le16(beacon_int);
	}
364
365

	tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
366
	interval_tm = beacon_int * TIME_UNIT;
367
	rem = do_div(tsf, interval_tm);
368
	ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
369

370
	ctx->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ?: 1) : 1;
371

372
373
	IWL_DEBUG_ASSOC(priv,
			"beacon interval %d beacon timer %d beacon tim %d\n",
374
375
376
			le16_to_cpu(ctx->timing.beacon_interval),
			le32_to_cpu(ctx->timing.beacon_init_val),
			le16_to_cpu(ctx->timing.atim_window));
377

378
	return iwl_send_cmd_pdu(priv, ctx->rxon_timing_cmd,
379
				sizeof(ctx->timing), &ctx->timing);
380
381
}

382
383
void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
			   int hw_decrypt)
384
{
385
	struct iwl_rxon_cmd *rxon = &ctx->staging;
386
387
388
389
390
391
392
393

	if (hw_decrypt)
		rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
	else
		rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK;

}

Johannes Berg's avatar
Johannes Berg committed
394
/* validate RXON structure is valid */
395
int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
396
{
397
	struct iwl_rxon_cmd *rxon = &ctx->staging;
Johannes Berg's avatar
Johannes Berg committed
398
	u32 errors = 0;
399
400

	if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
Johannes Berg's avatar
Johannes Berg committed
401
402
		if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) {
			IWL_WARN(priv, "check 2.4G: wrong narrow\n");
Johannes Berg's avatar
Johannes Berg committed
403
			errors |= BIT(0);
Johannes Berg's avatar
Johannes Berg committed
404
405
406
		}
		if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) {
			IWL_WARN(priv, "check 2.4G: wrong radar\n");
Johannes Berg's avatar
Johannes Berg committed
407
			errors |= BIT(1);
Johannes Berg's avatar
Johannes Berg committed
408
		}
409
	} else {
Johannes Berg's avatar
Johannes Berg committed
410
411
		if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) {
			IWL_WARN(priv, "check 5.2G: not short slot!\n");
Johannes Berg's avatar
Johannes Berg committed
412
			errors |= BIT(2);
Johannes Berg's avatar
Johannes Berg committed
413
414
415
		}
		if (rxon->flags & RXON_FLG_CCK_MSK) {
			IWL_WARN(priv, "check 5.2G: CCK!\n");
Johannes Berg's avatar
Johannes Berg committed
416
			errors |= BIT(3);
Johannes Berg's avatar
Johannes Berg committed
417
418
419
420
		}
	}
	if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) {
		IWL_WARN(priv, "mac/bssid mcast!\n");
Johannes Berg's avatar
Johannes Berg committed
421
		errors |= BIT(4);
422
423
424
	}

	/* make sure basic rates 6Mbps and 1Mbps are supported */
Johannes Berg's avatar
Johannes Berg committed
425
426
427
	if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 &&
	    (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) {
		IWL_WARN(priv, "neither 1 nor 6 are basic\n");
Johannes Berg's avatar
Johannes Berg committed
428
		errors |= BIT(5);
Johannes Berg's avatar
Johannes Berg committed
429
	}
430

Johannes Berg's avatar
Johannes Berg committed
431
432
	if (le16_to_cpu(rxon->assoc_id) > 2007) {
		IWL_WARN(priv, "aid > 2007\n");
Johannes Berg's avatar
Johannes Berg committed
433
		errors |= BIT(6);
Johannes Berg's avatar
Johannes Berg committed
434
	}
435

Johannes Berg's avatar
Johannes Berg committed
436
437
438
	if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
			== (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) {
		IWL_WARN(priv, "CCK and short slot\n");
Johannes Berg's avatar
Johannes Berg committed
439
		errors |= BIT(7);
Johannes Berg's avatar
Johannes Berg committed
440
	}
441

Johannes Berg's avatar
Johannes Berg committed
442
443
444
	if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
			== (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) {
		IWL_WARN(priv, "CCK and auto detect");
Johannes Berg's avatar
Johannes Berg committed
445
		errors |= BIT(8);
Johannes Berg's avatar
Johannes Berg committed
446
	}
447

Johannes Berg's avatar
Johannes Berg committed
448
449
450
451
	if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
			    RXON_FLG_TGG_PROTECT_MSK)) ==
			    RXON_FLG_TGG_PROTECT_MSK) {
		IWL_WARN(priv, "TGg but no auto-detect\n");
Johannes Berg's avatar
Johannes Berg committed
452
		errors |= BIT(9);
Johannes Berg's avatar
Johannes Berg committed
453
	}
454

Johannes Berg's avatar
Johannes Berg committed
455
456
457
	if (rxon->channel == 0) {
		IWL_WARN(priv, "zero channel is invalid\n");
		errors |= BIT(10);
458
	}
Johannes Berg's avatar
Johannes Berg committed
459
460
461
462
463

	WARN(errors, "Invalid RXON (%#x), channel %d",
	     errors, le16_to_cpu(rxon->channel));

	return errors ? -EINVAL : 0;
464
465
466
467
468
469
470
471
472
473
}

/**
 * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
 * @priv: staging_rxon is compared to active_rxon
 *
 * If the RXON structure is changing enough to require a new tune,
 * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
 * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
 */
474
475
int iwl_full_rxon_required(struct iwl_priv *priv,
			   struct iwl_rxon_context *ctx)
476
{
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
	const struct iwl_rxon_cmd *staging = &ctx->staging;
	const struct iwl_rxon_cmd *active = &ctx->active;

#define CHK(cond)							\
	if ((cond)) {							\
		IWL_DEBUG_INFO(priv, "need full RXON - " #cond "\n");	\
		return 1;						\
	}

#define CHK_NEQ(c1, c2)						\
	if ((c1) != (c2)) {					\
		IWL_DEBUG_INFO(priv, "need full RXON - "	\
			       #c1 " != " #c2 " - %d != %d\n",	\
			       (c1), (c2));			\
		return 1;					\
	}
493
494

	/* These items are only settable from the full RXON command */
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
	CHK(!iwl_is_associated_ctx(ctx));
	CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr));
	CHK(compare_ether_addr(staging->node_addr, active->node_addr));
	CHK(compare_ether_addr(staging->wlap_bssid_addr,
				active->wlap_bssid_addr));
	CHK_NEQ(staging->dev_type, active->dev_type);
	CHK_NEQ(staging->channel, active->channel);
	CHK_NEQ(staging->air_propagation, active->air_propagation);
	CHK_NEQ(staging->ofdm_ht_single_stream_basic_rates,
		active->ofdm_ht_single_stream_basic_rates);
	CHK_NEQ(staging->ofdm_ht_dual_stream_basic_rates,
		active->ofdm_ht_dual_stream_basic_rates);
	CHK_NEQ(staging->ofdm_ht_triple_stream_basic_rates,
		active->ofdm_ht_triple_stream_basic_rates);
	CHK_NEQ(staging->assoc_id, active->assoc_id);
510
511
512
513
514
515

	/* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
	 * be updated with the RXON_ASSOC command -- however only some
	 * flag transitions are allowed using RXON_ASSOC */

	/* Check if we are not switching bands */
516
517
	CHK_NEQ(staging->flags & RXON_FLG_BAND_24G_MSK,
		active->flags & RXON_FLG_BAND_24G_MSK);
518
519

	/* Check if we are switching association toggle */
520
521
522
523
524
	CHK_NEQ(staging->filter_flags & RXON_FILTER_ASSOC_MSK,
		active->filter_flags & RXON_FILTER_ASSOC_MSK);

#undef CHK
#undef CHK_NEQ
525
526
527
528

	return 0;
}

529
530
u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv,
			    struct iwl_rxon_context *ctx)
531
{
532
533
534
535
	/*
	 * Assign the lowest rate -- should really get this from
	 * the beacon skb from mac80211.
	 */
536
	if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK)
537
538
539
540
541
		return IWL_RATE_1M_PLCP;
	else
		return IWL_RATE_6M_PLCP;
}

542
543
544
static void _iwl_set_rxon_ht(struct iwl_priv *priv,
			     struct iwl_ht_config *ht_conf,
			     struct iwl_rxon_context *ctx)
545
{
546
	struct iwl_rxon_cmd *rxon = &ctx->staging;
547

548
	if (!ctx->ht.enabled) {
549
		rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
550
			RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
551
			RXON_FLG_HT40_PROT_MSK |
552
			RXON_FLG_HT_PROT_MSK);
553
		return;
554
	}
555

556
	/* FIXME: if the definition of ht.protection changed, the "translation"
557
558
	 * will be needed for rxon->flags
	 */
559
	rxon->flags |= cpu_to_le32(ctx->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS);
560
561

	/* Set up channel bandwidth:
562
	 * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */
563
564
565
	/* clear the HT channel mode before set the mode */
	rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
			 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
566
	if (iwl_is_ht40_tx_allowed(priv, ctx, NULL)) {
567
		/* pure ht40 */
568
		if (ctx->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
569
			rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
570
			/* Note: control channel is opposite of extension channel */
571
			switch (ctx->ht.extension_chan_offset) {
572
573
574
575
576
577
578
579
			case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
				rxon->flags &= ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
				break;
			case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
				rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
				break;
			}
		} else {
580
			/* Note: control channel is opposite of extension channel */
581
			switch (ctx->ht.extension_chan_offset) {
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
			case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
				rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
				rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;
				break;
			case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
				rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
				rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;
				break;
			case IEEE80211_HT_PARAM_CHA_SEC_NONE:
			default:
				/* channel location only valid if in Mixed mode */
				IWL_ERR(priv, "invalid extension channel offset\n");
				break;
			}
		}
	} else {
		rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY;
599
600
	}

601
	if (priv->cfg->ops->hcmd->set_rxon_chain)
602
		priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
603

604
	IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X "
Johannes Berg's avatar
Johannes Berg committed
605
			"extension channel offset 0x%x\n",
606
607
			le32_to_cpu(rxon->flags), ctx->ht.protection,
			ctx->ht.extension_chan_offset);
608
}
609
610
611
612
613
614
615
616

void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
{
	struct iwl_rxon_context *ctx;

	for_each_context(priv, ctx)
		_iwl_set_rxon_ht(priv, ht_conf, ctx);
}
617

618
/* Return valid, unused, channel for a passive scan to reset the RF */
Abhijeet Kolekar's avatar
Abhijeet Kolekar committed
619
u8 iwl_get_single_channel_number(struct iwl_priv *priv,
620
				 enum ieee80211_band band)
Abhijeet Kolekar's avatar
Abhijeet Kolekar committed
621
622
623
624
{
	const struct iwl_channel_info *ch_info;
	int i;
	u8 channel = 0;
625
626
	u8 min, max;
	struct iwl_rxon_context *ctx;
Abhijeet Kolekar's avatar
Abhijeet Kolekar committed
627
628

	if (band == IEEE80211_BAND_5GHZ) {
629
630
		min = 14;
		max = priv->channel_count;
Abhijeet Kolekar's avatar
Abhijeet Kolekar committed
631
	} else {
632
633
634
635
636
637
638
639
640
641
642
643
		min = 0;
		max = 14;
	}

	for (i = min; i < max; i++) {
		bool busy = false;

		for_each_context(priv, ctx) {
			busy = priv->channel_info[i].channel ==
				le16_to_cpu(ctx->staging.channel);
			if (busy)
				break;
Abhijeet Kolekar's avatar
Abhijeet Kolekar committed
644
		}
645
646
647
648
649
650
651
652

		if (busy)
			continue;

		channel = priv->channel_info[i].channel;
		ch_info = iwl_get_channel_info(priv, band, channel);
		if (is_channel_valid(ch_info))
			break;
Abhijeet Kolekar's avatar
Abhijeet Kolekar committed
653
654
655
656
657
	}

	return channel;
}

658
/**
659
660
 * iwl_set_rxon_channel - Set the band and channel values in staging RXON
 * @ch: requested channel as a pointer to struct ieee80211_channel
661
662

 * NOTE:  Does not commit to the hardware; it sets appropriate bit fields
663
 * in the staging RXON flag structure based on the ch->band
664
 */
665
666
int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
			 struct iwl_rxon_context *ctx)
667
{
668
	enum ieee80211_band band = ch->band;
669
	u16 channel = ch->hw_value;
670

671
	if ((le16_to_cpu(ctx->staging.channel) == channel) &&
672
673
674
	    (priv->band == band))
		return 0;

675
	ctx->staging.channel = cpu_to_le16(channel);
676
	if (band == IEEE80211_BAND_5GHZ)
677
		ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK;
678
	else
679
		ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
680
681
682

	priv->band = band;

683
	IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band);
684
685
686
687

	return 0;
}

688
void iwl_set_flags_for_band(struct iwl_priv *priv,
689
			    struct iwl_rxon_context *ctx,
690
691
			    enum ieee80211_band band,
			    struct ieee80211_vif *vif)
692
693
{
	if (band == IEEE80211_BAND_5GHZ) {
694
		ctx->staging.flags &=
695
696
		    ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
		      | RXON_FLG_CCK_MSK);
697
		ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
698
699
	} else {
		/* Copied from iwl_post_associate() */
700
		if (vif && vif->bss_conf.use_short_slot)
701
			ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
702
		else
703
			ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
704

705
706
707
		ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
		ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK;
		ctx->staging.flags &= ~RXON_FLG_CCK_MSK;
708
709
710
711
712
713
	}
}

/*
 * initialize rxon structure with default values from eeprom
 */
714
void iwl_connection_init_rx_config(struct iwl_priv *priv,
715
				   struct iwl_rxon_context *ctx)
716
717
718
{
	const struct iwl_channel_info *ch_info;

719
	memset(&ctx->staging, 0, sizeof(ctx->staging));
720

721
722
723
	if (!ctx->vif) {
		ctx->staging.dev_type = ctx->unused_devtype;
	} else switch (ctx->vif->type) {
724
	case NL80211_IFTYPE_AP:
725
		ctx->staging.dev_type = ctx->ap_devtype;
726
727
728
		break;

	case NL80211_IFTYPE_STATION:
729
		ctx->staging.dev_type = ctx->station_devtype;
730
		ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
731
732
733
		break;

	case NL80211_IFTYPE_ADHOC:
734
		ctx->staging.dev_type = ctx->ibss_devtype;
735
736
		ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
		ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
737
738
739
740
						  RXON_FILTER_ACCEPT_GRP_MSK;
		break;

	default:
741
742
		IWL_ERR(priv, "Unsupported interface type %d\n",
			ctx->vif->type);
743
744
745
746
747
748
749
		break;
	}

#if 0
	/* TODO:  Figure out when short_preamble would be set and cache from
	 * that */
	if (!hw_to_local(priv->hw)->short_preamble)
750
		ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
751
	else
752
		ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
753
754
755
#endif

	ch_info = iwl_get_channel_info(priv, priv->band,
756
				       le16_to_cpu(ctx->active.channel));
757
758
759
760

	if (!ch_info)
		ch_info = &priv->channel_info[0];

761
	ctx->staging.channel = cpu_to_le16(ch_info->channel);
762
763
	priv->band = ch_info->band;

764
	iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif);
765

766
	ctx->staging.ofdm_basic_rates =
767
	    (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
768
	ctx->staging.cck_basic_rates =
769
770
	    (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;

771
	/* clear both MIX and PURE40 mode flag */
772
	ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |
773
					RXON_FLG_CHANNEL_MODE_PURE_40);
774
775
	if (ctx->vif)
		memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN);
776

777
778
779
	ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff;
	ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff;
	ctx->staging.ofdm_ht_triple_stream_basic_rates = 0xff;
780
781
}

782
void iwl_set_rate(struct iwl_priv *priv)
783
784
785
{
	const struct ieee80211_supported_band *hw = NULL;
	struct ieee80211_rate *rate;
786
	struct iwl_rxon_context *ctx;
787
788
789
790
791
792
793
794
795
796
797
798
	int i;

	hw = iwl_get_hw_mode(priv, priv->band);
	if (!hw) {
		IWL_ERR(priv, "Failed to set rate: unable to get hw mode\n");
		return;
	}

	priv->active_rate = 0;

	for (i = 0; i < hw->n_bitrates; i++) {
		rate = &(hw->bitrates[i]);
799
		if (rate->hw_value < IWL_RATE_COUNT_LEGACY)
800
801
802
			priv->active_rate |= (1 << rate->hw_value);
	}

803
	IWL_DEBUG_RATE(priv, "Set active_rate = %0x\n", priv->active_rate);
804

805
806
807
	for_each_context(priv, ctx) {
		ctx->staging.cck_basic_rates =
		    (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
808

809
810
811
		ctx->staging.ofdm_basic_rates =
		   (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
	}
812
}
813
814
815

void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
{
816
817
818
819
820
821
	/*
	 * MULTI-FIXME
	 * See iwl_mac_channel_switch.
	 */
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];

822
823
824
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return;

825
	if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
826
		ieee80211_chswitch_done(ctx->vif, is_success);
827
}
828
829

#ifdef CONFIG_IWLWIFI_DEBUG
830
831
void iwl_print_rx_config_cmd(struct iwl_priv *priv,
			     struct iwl_rxon_context *ctx)
832
{
833
	struct iwl_rxon_cmd *rxon = &ctx->staging;
834

835
	IWL_DEBUG_RADIO(priv, "RX CONFIG:\n");
836
	iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
837
838
839
	IWL_DEBUG_RADIO(priv, "u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
	IWL_DEBUG_RADIO(priv, "u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
	IWL_DEBUG_RADIO(priv, "u32 filter_flags: 0x%08x\n",
840
			le32_to_cpu(rxon->filter_flags));
841
842
	IWL_DEBUG_RADIO(priv, "u8 dev_type: 0x%x\n", rxon->dev_type);
	IWL_DEBUG_RADIO(priv, "u8 ofdm_basic_rates: 0x%02x\n",
843
			rxon->ofdm_basic_rates);
844
845
846
847
	IWL_DEBUG_RADIO(priv, "u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
	IWL_DEBUG_RADIO(priv, "u8[6] node_addr: %pM\n", rxon->node_addr);
	IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
	IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
848
}
849
#endif
850

851
852
853
854
855
856
857
858
859
860
861
862
863
static void iwlagn_abort_notification_waits(struct iwl_priv *priv)
{
	unsigned long flags;
	struct iwl_notification_wait *wait_entry;

	spin_lock_irqsave(&priv->_agn.notif_wait_lock, flags);
	list_for_each_entry(wait_entry, &priv->_agn.notif_waits, list)
		wait_entry->aborted = true;
	spin_unlock_irqrestore(&priv->_agn.notif_wait_lock, flags);

	wake_up_all(&priv->_agn.notif_waitq);
}

864
void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
865
{
866
867
868
	unsigned int reload_msec;
	unsigned long reload_jiffies;

869
870
871
872
873
874
	/* Set the FW error flag -- cleared on iwl_down */
	set_bit(STATUS_FW_ERROR, &priv->status);

	/* Cancel currently queued command. */
	clear_bit(STATUS_HCMD_ACTIVE, &priv->status);

875
876
	iwlagn_abort_notification_waits(priv);

877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
	/* Keep the restart process from trying to send host
	 * commands by clearing the ready bit */
	clear_bit(STATUS_READY, &priv->status);

	wake_up_interruptible(&priv->wait_command_queue);

	if (!ondemand) {
		/*
		 * If firmware keep reloading, then it indicate something
		 * serious wrong and firmware having problem to recover
		 * from it. Instead of keep trying which will fill the syslog
		 * and hang the system, let's just stop it
		 */
		reload_jiffies = jiffies;
		reload_msec = jiffies_to_msecs((long) reload_jiffies -
					(long) priv->reload_jiffies);
		priv->reload_jiffies = reload_jiffies;
		if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
			priv->reload_count++;
			if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
				IWL_ERR(priv, "BUG_ON, Stop restarting\n");
				return;
			}
		} else
			priv->reload_count = 0;
	}

	if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
Don Fry's avatar
Don Fry committed
905
		if (iwlagn_mod_params.restart_fw) {
906
907
908
909
910
911
912
913
914
915
916
917
918
919
			IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
				  "Restarting adapter due to uCode error.\n");
			queue_work(priv->workqueue, &priv->restart);
		} else
			IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
				  "Detected FW error, but not restarting\n");
	}
}

/**
 * iwl_irq_handle_error - called for HW or SW error interrupt from card
 */
void iwl_irq_handle_error(struct iwl_priv *priv)
{
920
921
922
923
924
925
926
	/* W/A for WiFi/WiMAX coex and WiMAX own the RF */
	if (priv->cfg->internal_wimax_coex &&
	    (!(iwl_read_prph(priv, APMG_CLK_CTRL_REG) &
			APMS_CLK_VAL_MRB_FUNC_MODE) ||
	     (iwl_read_prph(priv, APMG_PS_CTRL_REG) &
			APMG_PS_CTRL_VAL_RESET_REQ))) {
		/*
927
928
		 * Keep the restart process from trying to send host
		 * commands by clearing the ready bit.
929
930
		 */
		clear_bit(STATUS_READY, &priv->status);
931
932
		clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
		wake_up_interruptible(&priv->wait_command_queue);
933
934
935
936
		IWL_ERR(priv, "RF is used by WiMAX\n");
		return;
	}

937
938
939
	IWL_ERR(priv, "Loaded firmware version: %s\n",
		priv->hw->wiphy->fw_version);

940
941
942
943
	iwl_dump_nic_error_log(priv);
	iwl_dump_csr(priv);
	iwl_dump_fh(priv, NULL, false);
	iwl_dump_nic_event_log(priv, false, NULL, false);
944
#ifdef CONFIG_IWLWIFI_DEBUG
945
	if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
946
947
		iwl_print_rx_config_cmd(priv,
					&priv->contexts[IWL_RXON_CTX_BSS]);
948
949
#endif

950
	iwlagn_fw_error(priv, false);
951
952
}

953
static int iwl_apm_stop_master(struct iwl_priv *priv)
954
{
955
	int ret = 0;
956

957
	/* stop device's busmaster DMA activity */
958
959
	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);

960
	ret = iwl_poll_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED,
961
			CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
962
963
	if (ret)
		IWL_WARN(priv, "Master Disable Timed Out, 100 usec\n");
964
965
966

	IWL_DEBUG_INFO(priv, "stop master\n");

967
	return ret;
968
969
970
971
}

void iwl_apm_stop(struct iwl_priv *priv)
{
972
973
	IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");

974
975
	clear_bit(STATUS_DEVICE_ENABLED, &priv->status);

976
	/* Stop device's DMA activity */
977
978
	iwl_apm_stop_maste