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"
45
#include "iwl-trans.h"
Tomas Winkler's avatar
Tomas Winkler committed
46

47
48
u32 iwl_debug_level;

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

51
52
#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
53
static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
54
			      struct ieee80211_sta_ht_cap *ht_info,
55
56
			      enum ieee80211_band band)
{
Ron Rindjunsky's avatar
Ron Rindjunsky committed
57
58
59
60
	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;

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

64
	ht_info->ht_supported = true;
65

66
67
	if (priv->cfg->ht_params &&
	    priv->cfg->ht_params->ht_greenfield_support)
68
		ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
69
	ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
Ron Rindjunsky's avatar
Ron Rindjunsky committed
70
	max_bit_rate = MAX_BIT_RATE_20_MHZ;
71
	if (priv->hw_params.ht40_channel & BIT(band)) {
72
73
74
		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
75
		max_bit_rate = MAX_BIT_RATE_40_MHZ;
76
77
	}

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

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

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

	/* Highest supported Rx data rate */
	max_bit_rate *= rx_chains_num;
96
97
	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
98
99

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

/**
 * iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom
 */
111
int iwlcore_init_geos(struct iwl_priv *priv)
112
113
114
115
116
117
118
{
	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;
119
	s8 max_tx_power = IWLAGN_TX_POWER_TARGET_POWER_MIN;
120
121
122

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

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

133
	rates = kzalloc((sizeof(struct ieee80211_rate) * IWL_RATE_COUNT_LEGACY),
134
135
136
137
138
139
140
141
142
143
144
			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];
145
	sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE;
146

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

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

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

	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;

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

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

		geo_ch->center_freq =
176
			ieee80211_channel_to_frequency(ch->channel, ch->band);
177
178
179
180
181
182
183
184
185
186
187
188
189
190
		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;

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

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

199
		IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
200
201
202
203
204
205
206
				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);
	}

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

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

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

	set_bit(STATUS_GEO_CONFIGURED, &priv->status);

	return 0;
}

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

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

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

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

256
	return false;
257
258
}

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

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

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

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

283
284
static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
{
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
	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.
	 */
308
309
310
311
312
313
314
315
316
317

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

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

	conf = ieee80211_get_hw_conf(priv->hw);

328
329
	lockdep_assert_held(&priv->mutex);

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

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

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

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

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

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

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

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

379
	return trans_send_cmd_pdu(&priv->trans, ctx->rxon_timing_cmd,
380
				CMD_SYNC, sizeof(ctx->timing), &ctx->timing);
381
382
}

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

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

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

	/* make sure basic rates 6Mbps and 1Mbps are supported */
Johannes Berg's avatar
Johannes Berg committed
426
427
428
	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
429
		errors |= BIT(5);
Johannes Berg's avatar
Johannes Berg committed
430
	}
431

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

Johannes Berg's avatar
Johannes Berg committed
437
438
439
	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
440
		errors |= BIT(7);
Johannes Berg's avatar
Johannes Berg committed
441
	}
442

Johannes Berg's avatar
Johannes Berg committed
443
444
445
	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
446
		errors |= BIT(8);
Johannes Berg's avatar
Johannes Berg committed
447
	}
448

Johannes Berg's avatar
Johannes Berg committed
449
450
451
452
	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
453
		errors |= BIT(9);
Johannes Berg's avatar
Johannes Berg committed
454
	}
455

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

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

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

/**
 * 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.
 */
475
476
int iwl_full_rxon_required(struct iwl_priv *priv,
			   struct iwl_rxon_context *ctx)
477
{
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
	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;					\
	}
494
495

	/* These items are only settable from the full RXON command */
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
	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);
511
512
513
514
515
516

	/* 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 */
517
518
	CHK_NEQ(staging->flags & RXON_FLG_BAND_24G_MSK,
		active->flags & RXON_FLG_BAND_24G_MSK);
519
520

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

#undef CHK
#undef CHK_NEQ
526
527
528
529

	return 0;
}

530
531
532
static void _iwl_set_rxon_ht(struct iwl_priv *priv,
			     struct iwl_ht_config *ht_conf,
			     struct iwl_rxon_context *ctx)
533
{
534
	struct iwl_rxon_cmd *rxon = &ctx->staging;
535

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

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

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

Wey-Yi Guy's avatar
Wey-Yi Guy committed
589
	iwlagn_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
static void iwlagn_abort_notification_waits(struct iwl_priv *priv)
{
	unsigned long flags;
	struct iwl_notification_wait *wait_entry;

843
844
	spin_lock_irqsave(&priv->notif_wait_lock, flags);
	list_for_each_entry(wait_entry, &priv->notif_waits, list)
845
		wait_entry->aborted = true;
846
	spin_unlock_irqrestore(&priv->notif_wait_lock, flags);
847

848
	wake_up_all(&priv->notif_waitq);
849
850
}

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
	bus_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->