iwl-core.c 52.5 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
531
static void _iwl_set_rxon_ht(struct iwl_priv *priv,
			     struct iwl_ht_config *ht_conf,
			     struct iwl_rxon_context *ctx)
532
{
533
	struct iwl_rxon_cmd *rxon = &ctx->staging;
534

535
	if (!ctx->ht.enabled) {
536
		rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
537
			RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
538
			RXON_FLG_HT40_PROT_MSK |
539
			RXON_FLG_HT_PROT_MSK);
540
		return;
541
	}
542

543
	/* FIXME: if the definition of ht.protection changed, the "translation"
544
545
	 * will be needed for rxon->flags
	 */
546
	rxon->flags |= cpu_to_le32(ctx->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS);
547
548

	/* Set up channel bandwidth:
549
	 * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */
550
551
552
	/* clear the HT channel mode before set the mode */
	rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
			 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
553
	if (iwl_is_ht40_tx_allowed(priv, ctx, NULL)) {
554
		/* pure ht40 */
555
		if (ctx->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
556
			rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
557
			/* Note: control channel is opposite of extension channel */
558
			switch (ctx->ht.extension_chan_offset) {
559
560
561
562
563
564
565
566
			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 {
567
			/* Note: control channel is opposite of extension channel */
568
			switch (ctx->ht.extension_chan_offset) {
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
			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;
586
587
	}

588
	if (priv->cfg->ops->hcmd->set_rxon_chain)
589
		priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
590

591
	IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X "
Johannes Berg's avatar
Johannes Berg committed
592
			"extension channel offset 0x%x\n",
593
594
			le32_to_cpu(rxon->flags), ctx->ht.protection,
			ctx->ht.extension_chan_offset);
595
}
596
597
598
599
600
601
602
603

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

605
/* Return valid, unused, channel for a passive scan to reset the RF */
Abhijeet Kolekar's avatar
Abhijeet Kolekar committed
606
u8 iwl_get_single_channel_number(struct iwl_priv *priv,
607
				 enum ieee80211_band band)
Abhijeet Kolekar's avatar
Abhijeet Kolekar committed
608
609
610
611
{
	const struct iwl_channel_info *ch_info;
	int i;
	u8 channel = 0;
612
613
	u8 min, max;
	struct iwl_rxon_context *ctx;
Abhijeet Kolekar's avatar
Abhijeet Kolekar committed
614
615

	if (band == IEEE80211_BAND_5GHZ) {
616
617
		min = 14;
		max = priv->channel_count;
Abhijeet Kolekar's avatar
Abhijeet Kolekar committed
618
	} else {
619
620
621
622
623
624
625
626
627
628
629
630
		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
631
		}
632
633
634
635
636
637
638
639

		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
640
641
642
643
644
	}

	return channel;
}

645
/**
646
647
 * iwl_set_rxon_channel - Set the band and channel values in staging RXON
 * @ch: requested channel as a pointer to struct ieee80211_channel
648
649

 * NOTE:  Does not commit to the hardware; it sets appropriate bit fields
650
 * in the staging RXON flag structure based on the ch->band
651
 */
652
653
int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
			 struct iwl_rxon_context *ctx)
654
{
655
	enum ieee80211_band band = ch->band;
656
	u16 channel = ch->hw_value;
657

658
	if ((le16_to_cpu(ctx->staging.channel) == channel) &&
659
660
661
	    (priv->band == band))
		return 0;

662
	ctx->staging.channel = cpu_to_le16(channel);
663
	if (band == IEEE80211_BAND_5GHZ)
664
		ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK;
665
	else
666
		ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
667
668
669

	priv->band = band;

670
	IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band);
671
672
673
674

	return 0;
}

675
void iwl_set_flags_for_band(struct iwl_priv *priv,
676
			    struct iwl_rxon_context *ctx,
677
678
			    enum ieee80211_band band,
			    struct ieee80211_vif *vif)
679
680
{
	if (band == IEEE80211_BAND_5GHZ) {
681
		ctx->staging.flags &=
682
683
		    ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
		      | RXON_FLG_CCK_MSK);
684
		ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
685
686
	} else {
		/* Copied from iwl_post_associate() */
687
		if (vif && vif->bss_conf.use_short_slot)
688
			ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
689
		else
690
			ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
691

692
693
694
		ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
		ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK;
		ctx->staging.flags &= ~RXON_FLG_CCK_MSK;
695
696
697
698
699
700
	}
}

/*
 * initialize rxon structure with default values from eeprom
 */
701
void iwl_connection_init_rx_config(struct iwl_priv *priv,
702
				   struct iwl_rxon_context *ctx)
703
704
705
{
	const struct iwl_channel_info *ch_info;

706
	memset(&ctx->staging, 0, sizeof(ctx->staging));
707

708
709
710
	if (!ctx->vif) {
		ctx->staging.dev_type = ctx->unused_devtype;
	} else switch (ctx->vif->type) {
711
	case NL80211_IFTYPE_AP:
712
		ctx->staging.dev_type = ctx->ap_devtype;
713
714
715
		break;

	case NL80211_IFTYPE_STATION:
716
		ctx->staging.dev_type = ctx->station_devtype;
717
		ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
718
719
720
		break;

	case NL80211_IFTYPE_ADHOC:
721
		ctx->staging.dev_type = ctx->ibss_devtype;
722
723
		ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
		ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
724
725
726
727
						  RXON_FILTER_ACCEPT_GRP_MSK;
		break;

	default:
728
729
		IWL_ERR(priv, "Unsupported interface type %d\n",
			ctx->vif->type);
730
731
732
733
734
735
736
		break;
	}

#if 0
	/* TODO:  Figure out when short_preamble would be set and cache from
	 * that */
	if (!hw_to_local(priv->hw)->short_preamble)
737
		ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
738
	else
739
		ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
740
741
742
#endif

	ch_info = iwl_get_channel_info(priv, priv->band,
743
				       le16_to_cpu(ctx->active.channel));
744
745
746
747

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

748
	ctx->staging.channel = cpu_to_le16(ch_info->channel);
749
750
	priv->band = ch_info->band;

751
	iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif);
752

753
	ctx->staging.ofdm_basic_rates =
754
	    (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
755
	ctx->staging.cck_basic_rates =
756
757
	    (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;

758
	/* clear both MIX and PURE40 mode flag */
759
	ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |
760
					RXON_FLG_CHANNEL_MODE_PURE_40);
761
762
	if (ctx->vif)
		memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN);
763

764
765
766
	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;
767
768
}

769
void iwl_set_rate(struct iwl_priv *priv)
770
771
772
{
	const struct ieee80211_supported_band *hw = NULL;
	struct ieee80211_rate *rate;
773
	struct iwl_rxon_context *ctx;
774
775
776
777
778
779
780
781
782
783
784
785
	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]);
786
		if (rate->hw_value < IWL_RATE_COUNT_LEGACY)
787
788
789
			priv->active_rate |= (1 << rate->hw_value);
	}

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

792
793
794
	for_each_context(priv, ctx) {
		ctx->staging.cck_basic_rates =
		    (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
795

796
797
798
		ctx->staging.ofdm_basic_rates =
		   (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
	}
799
}
800
801
802

void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
{
803
804
805
806
807
808
	/*
	 * MULTI-FIXME
	 * See iwl_mac_channel_switch.
	 */
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];

809
810
811
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return;

812
	if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
813
		ieee80211_chswitch_done(ctx->vif, is_success);
814
}
815
816

#ifdef CONFIG_IWLWIFI_DEBUG
817
818
void iwl_print_rx_config_cmd(struct iwl_priv *priv,
			     struct iwl_rxon_context *ctx)
819
{
820
	struct iwl_rxon_cmd *rxon = &ctx->staging;
821

822
	IWL_DEBUG_RADIO(priv, "RX CONFIG:\n");
823
	iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
824
825
826
	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",
827
			le32_to_cpu(rxon->filter_flags));
828
829
	IWL_DEBUG_RADIO(priv, "u8 dev_type: 0x%x\n", rxon->dev_type);
	IWL_DEBUG_RADIO(priv, "u8 ofdm_basic_rates: 0x%02x\n",
830
			rxon->ofdm_basic_rates);
831
832
833
834
	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));
835
}
836
#endif
837

838
839
840
841
842
843
844
845
846
847
848
849
850
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);
}

851
void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
852
{
853
854
855
	unsigned int reload_msec;
	unsigned long reload_jiffies;

856
857
858
859
860
861
	/* 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);

862
863
	iwlagn_abort_notification_waits(priv);

864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
	/* 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
892
		if (iwlagn_mod_params.restart_fw) {
893
894
895
896
897
898
899
900
901
902
903
904
905
906
			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)
{
907
908
909
910
911
912
913
	/* 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))) {
		/*
914
915
		 * Keep the restart process from trying to send host
		 * commands by clearing the ready bit.
916
917
		 */
		clear_bit(STATUS_READY, &priv->status);
918
919
		clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
		wake_up_interruptible(&priv->wait_command_queue);
920
921
922
923
		IWL_ERR(priv, "RF is used by WiMAX\n");
		return;
	}

924
925
926
	IWL_ERR(priv, "Loaded firmware version: %s\n",
		priv->hw->wiphy->fw_version);

927
928
929
930
	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);
931
#ifdef CONFIG_IWLWIFI_DEBUG
932
	if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
933
934
		iwl_print_rx_config_cmd(priv,
					&priv->contexts[IWL_RXON_CTX_BSS]);
935
936
#endif

937
	iwlagn_fw_error(priv, false);
938
939
}

940
static int iwl_apm_stop_master(struct iwl_priv *priv)
941
{
942
	int ret = 0;
943

944
	/* stop device's busmaster DMA activity */
945
946
	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);

947
	ret = iwl_poll_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED,
948
			CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
949
950
	if (ret)
		IWL_WARN(priv, "Master Disable Timed Out, 100 usec\n");
951
952
953

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

954
	return ret;
955
956
957
958
}

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

961
962
	clear_bit(STATUS_DEVICE_ENABLED, &priv->status);

963
	/* Stop device's DMA activity */
964
965
	iwl_apm_stop_master(priv);

966
	/* Reset the entire device */
967
968
969
	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);

	udelay(10);
970
971
972
973
974

	/*
	 * Clear "initialization complete" bit to move adapter from
	 * D0A* (powered-up Active) --> D0U* (Uninitialized) state.
	 */
975
976
977
	iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
}

978