iwl-core.c 52.2 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
	}

Wey-Yi Guy's avatar
Wey-Yi Guy committed
588
	iwlagn_set_rxon_chain(priv, ctx);
589

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

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

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

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

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

	return channel;
}

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

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

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

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

	priv->band = band;

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

	return 0;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

861
862
	iwlagn_abort_notification_waits(priv);

863
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
	/* 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
891
		if (iwlagn_mod_params.restart_fw) {
892
893
894
895
896
897
898
899
900
901
902
903
904
905
			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)
{
906
907
908
909
910
911
912
	/* 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))) {
		/*
913
914
		 * Keep the restart process from trying to send host
		 * commands by clearing the ready bit.
915
916
		 */
		clear_bit(STATUS_READY, &priv->status);
917
918
		clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
		wake_up_interruptible(&priv->wait_command_queue);
919
920
921
922
		IWL_ERR(priv, "RF is used by WiMAX\n");
		return;
	}

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

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

936
	iwlagn_fw_error(priv, false);
937
938
}

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

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

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

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

953
	return ret;
954
955
956
957
}

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

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

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

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

	udelay(10);
969
970
971
972
973

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

977
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

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

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

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

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

	/*
1041
	 * Enable DMA clock and wait for it to stabilize.
1042
1043
1044
1045
1046