iwl-core.c 52.3 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
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014

/*
 * Start up NIC's basic functionality after it has been reset
 * (e.g. after platform boot, or shutdown via iwl_apm_stop())
 * NOTE:  This does not load uCode nor start the embedded processor
 */
int iwl_apm_init(struct iwl_priv *priv)
{
	int ret = 0;
	IWL_DEBUG_INFO(priv, "Init card's basic functions\n");

	/*
	 * Use "set_bit" below rather than "write", to preserve any hardware
	 * bits already set by default after reset.
	 */

	/* Disable L0S exit timer (platform NMI Work/Around) */
	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
			  CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);

	/*
	 * Disable L0s without affecting L1;
	 *  don't wait for ICH L0s (ICH bug W/A)
	 */
	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
			  CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);

	/* Set FH wait threshold to maximum (HW error during stress W/A) */
	iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);

	/*
	 * Enable HAP INTA (interrupt from management bus) to
	 * wake device's PCI Express link L1a -> L0s
	 */
	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
				    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);

1015
	priv->bus.ops->apm_config(&priv->bus);
1016
1017

	/* Configure analog phase-lock-loop before activating to D0A */
1018
1019
1020
	if (priv->cfg->base_params->pll_cfg_val)
		iwl_set_bit(priv, CSR_ANA_PLL_CFG,
			    priv->cfg->base_params->pll_cfg_val);
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041

	/*
	 * Set "initialization complete" bit to move adapter from
	 * D0U* --> D0A* (powered-up active) state.
	 */
	iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);

	/*
	 * Wait for clock stabilization; once stabilized, access to
	 * device-internal resources is supported, e.g. iwl_write_prph()
	 * and accesses to uCode SRAM.
	 */
	ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
	if (ret < 0) {
		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
		goto out;
	}

	/*
1042
	 * Enable DMA clock and wait for it to stabilize.