iwl-core.c 55 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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/*
 * set bt_coex_active to true, uCode will do kill/defer
 * every time the priority line is asserted (BT is sending signals on the
 * priority line in the PCIx).
 * set bt_coex_active to false, uCode will ignore the BT activity and
 * perform the normal operation
 *
 * User might experience transmit issue on some platform due to WiFi/BT
 * co-exist problem. The possible behaviors are:
 *   Able to scan and finding all the available AP
 *   Not able to associate with any AP
 * On those platforms, WiFi communication can be restored by set
 * "bt_coex_active" module parameter to "false"
 *
 * default: bt_coex_active = true (BT_COEX_ENABLE)
 */
63
bool bt_coex_active = true;
64
module_param(bt_coex_active, bool, S_IRUGO);
65
MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist");
66

67
68
u32 iwl_debug_level;

69
70
const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

71
72
#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
73
static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
74
			      struct ieee80211_sta_ht_cap *ht_info,
75
76
			      enum ieee80211_band band)
{
Ron Rindjunsky's avatar
Ron Rindjunsky committed
77
78
79
80
	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;

81
	ht_info->cap = 0;
82
	memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
83

84
	ht_info->ht_supported = true;
85

86
87
	if (priv->cfg->ht_params &&
	    priv->cfg->ht_params->ht_greenfield_support)
88
		ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
89
	ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
Ron Rindjunsky's avatar
Ron Rindjunsky committed
90
	max_bit_rate = MAX_BIT_RATE_20_MHZ;
91
	if (priv->hw_params.ht40_channel & BIT(band)) {
92
93
94
		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
95
		max_bit_rate = MAX_BIT_RATE_40_MHZ;
96
97
	}

Don Fry's avatar
Don Fry committed
98
	if (iwlagn_mod_params.amsdu_size_8K)
99
		ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
100
101

	ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
102
103
	if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_factor)
		ht_info->ampdu_factor = priv->cfg->bt_params->ampdu_factor;
104
	ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF;
105
106
	if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_density)
		ht_info->ampdu_density = priv->cfg->bt_params->ampdu_density;
107

108
	ht_info->mcs.rx_mask[0] = 0xFF;
Ron Rindjunsky's avatar
Ron Rindjunsky committed
109
	if (rx_chains_num >= 2)
110
		ht_info->mcs.rx_mask[1] = 0xFF;
Ron Rindjunsky's avatar
Ron Rindjunsky committed
111
	if (rx_chains_num >= 3)
112
		ht_info->mcs.rx_mask[2] = 0xFF;
Ron Rindjunsky's avatar
Ron Rindjunsky committed
113
114
115

	/* Highest supported Rx data rate */
	max_bit_rate *= rx_chains_num;
116
117
	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
118
119

	/* Tx MCS capabilities */
120
	ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
Ron Rindjunsky's avatar
Ron Rindjunsky committed
121
	if (tx_chains_num != rx_chains_num) {
122
123
124
		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
125
	}
126
127
128
129
130
}

/**
 * iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom
 */
131
int iwlcore_init_geos(struct iwl_priv *priv)
132
133
134
135
136
137
138
{
	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;
139
	s8 max_tx_power = IWLAGN_TX_POWER_TARGET_POWER_MIN;
140
141
142

	if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
	    priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
143
		IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n");
144
145
146
147
148
149
150
151
152
		set_bit(STATUS_GEO_CONFIGURED, &priv->status);
		return 0;
	}

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

153
	rates = kzalloc((sizeof(struct ieee80211_rate) * IWL_RATE_COUNT_LEGACY),
154
155
156
157
158
159
160
161
162
163
164
			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];
165
	sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE;
166

167
	if (priv->cfg->sku & IWL_SKU_N)
168
		iwlcore_init_ht_hw_capab(priv, &sband->ht_cap,
169
					 IEEE80211_BAND_5GHZ);
170
171
172
173
174

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

177
	if (priv->cfg->sku & IWL_SKU_N)
178
		iwlcore_init_ht_hw_capab(priv, &sband->ht_cap,
179
					 IEEE80211_BAND_2GHZ);
180
181
182
183
184
185
186
187
188
189
190

	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;

191
		sband =  &priv->bands[ch->band];
192
193
194
195

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

		geo_ch->center_freq =
196
			ieee80211_channel_to_frequency(ch->channel, ch->band);
197
198
199
200
201
202
203
204
205
206
207
208
209
210
		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;

211
			geo_ch->flags |= ch->ht40_extension_channel;
212

213
214
			if (ch->max_power_avg > max_tx_power)
				max_tx_power = ch->max_power_avg;
215
216
217
218
		} else {
			geo_ch->flags |= IEEE80211_CHAN_DISABLED;
		}

219
		IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
220
221
222
223
224
225
226
				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);
	}

227
228
229
230
	priv->tx_power_device_lmt = max_tx_power;
	priv->tx_power_user_lmt = max_tx_power;
	priv->tx_power_next = max_tx_power;

231
232
	if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
	     priv->cfg->sku & IWL_SKU_A) {
Tomas Winkler's avatar
Tomas Winkler committed
233
234
		IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
			"Please send your PCI ID 0x%04X:0x%04X to maintainer.\n",
235
236
			   priv->pci_dev->device,
			   priv->pci_dev->subsystem_device);
237
238
239
		priv->cfg->sku &= ~IWL_SKU_A;
	}

Tomas Winkler's avatar
Tomas Winkler committed
240
	IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n",
241
242
		   priv->bands[IEEE80211_BAND_2GHZ].n_channels,
		   priv->bands[IEEE80211_BAND_5GHZ].n_channels);
243
244
245
246
247
248
249
250
251

	set_bit(STATUS_GEO_CONFIGURED, &priv->status);

	return 0;
}

/*
 * iwlcore_free_geos - undo allocations in iwlcore_init_geos
 */
252
void iwlcore_free_geos(struct iwl_priv *priv)
253
254
255
256
257
258
{
	kfree(priv->ieee_channels);
	kfree(priv->ieee_rates);
	clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
}

259
260
261
static bool iwl_is_channel_extension(struct iwl_priv *priv,
				     enum ieee80211_band band,
				     u16 channel, u8 extension_chan_offset)
262
263
264
265
266
{
	const struct iwl_channel_info *ch_info;

	ch_info = iwl_get_channel_info(priv, band, channel);
	if (!is_channel_valid(ch_info))
267
		return false;
268

269
	if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
270
		return !(ch_info->ht40_extension_channel &
271
					IEEE80211_CHAN_NO_HT40PLUS);
272
	else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW)
273
		return !(ch_info->ht40_extension_channel &
274
					IEEE80211_CHAN_NO_HT40MINUS);
275

276
	return false;
277
278
}

279
280
281
bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
			    struct iwl_rxon_context *ctx,
			    struct ieee80211_sta_ht_cap *ht_cap)
282
{
283
284
	if (!ctx->ht.enabled || !ctx->ht.is_40mhz)
		return false;
285

286
287
	/*
	 * We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40
288
289
	 * the bit will not set if it is pure 40MHz case
	 */
290
291
292
	if (ht_cap && !ht_cap->ht_supported)
		return false;

293
#ifdef CONFIG_IWLWIFI_DEBUGFS
294
	if (priv->disable_ht40)
295
		return false;
296
#endif
297

298
	return iwl_is_channel_extension(priv, priv->band,
299
			le16_to_cpu(ctx->staging.channel),
300
			ctx->ht.extension_chan_offset);
301
302
}

303
304
static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
{
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
	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.
	 */
328
329
330
331
332
333
334
335
336
337

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

338
int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
339
340
341
342
343
{
	u64 tsf;
	s32 interval_tm, rem;
	struct ieee80211_conf *conf = NULL;
	u16 beacon_int;
344
	struct ieee80211_vif *vif = ctx->vif;
345
346
347

	conf = ieee80211_get_hw_conf(priv->hw);

348
349
	lockdep_assert_held(&priv->mutex);

350
	memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd));
351

352
353
	ctx->timing.timestamp = cpu_to_le64(priv->timestamp);
	ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval);
354

355
	beacon_int = vif ? vif->bss_conf.beacon_int : 0;
356

357
358
359
360
361
	/*
	 * TODO: For IBSS we need to get atim_window from mac80211,
	 *	 for now just always use 0
	 */
	ctx->timing.atim_window = 0;
362

363
	if (ctx->ctxid == IWL_RXON_CTX_PAN &&
364
365
366
367
	    (!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) {
368
369
370
		ctx->timing.beacon_interval =
			priv->contexts[IWL_RXON_CTX_BSS].timing.beacon_interval;
		beacon_int = le16_to_cpu(ctx->timing.beacon_interval);
371
372
373
374
375
376
377
378
379
	} 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);
380
381
	} else {
		beacon_int = iwl_adjust_beacon_interval(beacon_int,
382
				priv->hw_params.max_beacon_itrvl * TIME_UNIT);
383
384
		ctx->timing.beacon_interval = cpu_to_le16(beacon_int);
	}
385
386

	tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
387
	interval_tm = beacon_int * TIME_UNIT;
388
	rem = do_div(tsf, interval_tm);
389
	ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
390

391
	ctx->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ?: 1) : 1;
392

393
394
	IWL_DEBUG_ASSOC(priv,
			"beacon interval %d beacon timer %d beacon tim %d\n",
395
396
397
			le16_to_cpu(ctx->timing.beacon_interval),
			le32_to_cpu(ctx->timing.beacon_init_val),
			le16_to_cpu(ctx->timing.atim_window));
398

399
	return iwl_send_cmd_pdu(priv, ctx->rxon_timing_cmd,
400
				sizeof(ctx->timing), &ctx->timing);
401
402
}

403
404
void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
			   int hw_decrypt)
405
{
406
	struct iwl_rxon_cmd *rxon = &ctx->staging;
407
408
409
410
411
412
413
414

	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
415
/* validate RXON structure is valid */
416
int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
417
{
418
	struct iwl_rxon_cmd *rxon = &ctx->staging;
Johannes Berg's avatar
Johannes Berg committed
419
	u32 errors = 0;
420
421

	if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
Johannes Berg's avatar
Johannes Berg committed
422
423
		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
424
			errors |= BIT(0);
Johannes Berg's avatar
Johannes Berg committed
425
426
427
		}
		if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) {
			IWL_WARN(priv, "check 2.4G: wrong radar\n");
Johannes Berg's avatar
Johannes Berg committed
428
			errors |= BIT(1);
Johannes Berg's avatar
Johannes Berg committed
429
		}
430
	} else {
Johannes Berg's avatar
Johannes Berg committed
431
432
		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
433
			errors |= BIT(2);
Johannes Berg's avatar
Johannes Berg committed
434
435
436
		}
		if (rxon->flags & RXON_FLG_CCK_MSK) {
			IWL_WARN(priv, "check 5.2G: CCK!\n");
Johannes Berg's avatar
Johannes Berg committed
437
			errors |= BIT(3);
Johannes Berg's avatar
Johannes Berg committed
438
439
440
441
		}
	}
	if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) {
		IWL_WARN(priv, "mac/bssid mcast!\n");
Johannes Berg's avatar
Johannes Berg committed
442
		errors |= BIT(4);
443
444
445
	}

	/* make sure basic rates 6Mbps and 1Mbps are supported */
Johannes Berg's avatar
Johannes Berg committed
446
447
448
	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
449
		errors |= BIT(5);
Johannes Berg's avatar
Johannes Berg committed
450
	}
451

Johannes Berg's avatar
Johannes Berg committed
452
453
	if (le16_to_cpu(rxon->assoc_id) > 2007) {
		IWL_WARN(priv, "aid > 2007\n");
Johannes Berg's avatar
Johannes Berg committed
454
		errors |= BIT(6);
Johannes Berg's avatar
Johannes Berg committed
455
	}
456

Johannes Berg's avatar
Johannes Berg committed
457
458
459
	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
460
		errors |= BIT(7);
Johannes Berg's avatar
Johannes Berg committed
461
	}
462

Johannes Berg's avatar
Johannes Berg committed
463
464
465
	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
466
		errors |= BIT(8);
Johannes Berg's avatar
Johannes Berg committed
467
	}
468

Johannes Berg's avatar
Johannes Berg committed
469
470
471
472
	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
473
		errors |= BIT(9);
Johannes Berg's avatar
Johannes Berg committed
474
	}
475

Johannes Berg's avatar
Johannes Berg committed
476
477
478
	if (rxon->channel == 0) {
		IWL_WARN(priv, "zero channel is invalid\n");
		errors |= BIT(10);
479
	}
Johannes Berg's avatar
Johannes Berg committed
480
481
482
483
484

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

	return errors ? -EINVAL : 0;
485
486
487
488
489
490
491
492
493
494
}

/**
 * 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.
 */
495
496
int iwl_full_rxon_required(struct iwl_priv *priv,
			   struct iwl_rxon_context *ctx)
497
{
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
	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;					\
	}
514
515

	/* These items are only settable from the full RXON command */
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
	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);
531
532
533
534
535
536

	/* 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 */
537
538
	CHK_NEQ(staging->flags & RXON_FLG_BAND_24G_MSK,
		active->flags & RXON_FLG_BAND_24G_MSK);
539
540

	/* Check if we are switching association toggle */
541
542
543
544
545
	CHK_NEQ(staging->filter_flags & RXON_FILTER_ASSOC_MSK,
		active->filter_flags & RXON_FILTER_ASSOC_MSK);

#undef CHK
#undef CHK_NEQ
546
547
548
549

	return 0;
}

550
551
u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv,
			    struct iwl_rxon_context *ctx)
552
{
553
554
555
556
	/*
	 * Assign the lowest rate -- should really get this from
	 * the beacon skb from mac80211.
	 */
557
	if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK)
558
559
560
561
562
		return IWL_RATE_1M_PLCP;
	else
		return IWL_RATE_6M_PLCP;
}

563
564
565
static void _iwl_set_rxon_ht(struct iwl_priv *priv,
			     struct iwl_ht_config *ht_conf,
			     struct iwl_rxon_context *ctx)
566
{
567
	struct iwl_rxon_cmd *rxon = &ctx->staging;
568

569
	if (!ctx->ht.enabled) {
570
		rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
571
			RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
572
			RXON_FLG_HT40_PROT_MSK |
573
			RXON_FLG_HT_PROT_MSK);
574
		return;
575
	}
576

577
	/* FIXME: if the definition of ht.protection changed, the "translation"
578
579
	 * will be needed for rxon->flags
	 */
580
	rxon->flags |= cpu_to_le32(ctx->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS);
581
582

	/* Set up channel bandwidth:
583
	 * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */
584
585
586
	/* clear the HT channel mode before set the mode */
	rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
			 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
587
	if (iwl_is_ht40_tx_allowed(priv, ctx, NULL)) {
588
		/* pure ht40 */
589
		if (ctx->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
590
			rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
591
			/* Note: control channel is opposite of extension channel */
592
			switch (ctx->ht.extension_chan_offset) {
593
594
595
596
597
598
599
600
			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 {
601
			/* Note: control channel is opposite of extension channel */
602
			switch (ctx->ht.extension_chan_offset) {
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
			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;
620
621
	}

622
	if (priv->cfg->ops->hcmd->set_rxon_chain)
623
		priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
624

625
	IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X "
Johannes Berg's avatar
Johannes Berg committed
626
			"extension channel offset 0x%x\n",
627
628
			le32_to_cpu(rxon->flags), ctx->ht.protection,
			ctx->ht.extension_chan_offset);
629
}
630
631
632
633
634
635
636
637

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

639
/* Return valid, unused, channel for a passive scan to reset the RF */
Abhijeet Kolekar's avatar
Abhijeet Kolekar committed
640
u8 iwl_get_single_channel_number(struct iwl_priv *priv,
641
				 enum ieee80211_band band)
Abhijeet Kolekar's avatar
Abhijeet Kolekar committed
642
643
644
645
{
	const struct iwl_channel_info *ch_info;
	int i;
	u8 channel = 0;
646
647
	u8 min, max;
	struct iwl_rxon_context *ctx;
Abhijeet Kolekar's avatar
Abhijeet Kolekar committed
648
649

	if (band == IEEE80211_BAND_5GHZ) {
650
651
		min = 14;
		max = priv->channel_count;
Abhijeet Kolekar's avatar
Abhijeet Kolekar committed
652
	} else {
653
654
655
656
657
658
659
660
661
662
663
664
		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
665
		}
666
667
668
669
670
671
672
673

		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
674
675
676
677
678
	}

	return channel;
}

679
/**
680
681
 * iwl_set_rxon_channel - Set the band and channel values in staging RXON
 * @ch: requested channel as a pointer to struct ieee80211_channel
682
683

 * NOTE:  Does not commit to the hardware; it sets appropriate bit fields
684
 * in the staging RXON flag structure based on the ch->band
685
 */
686
687
int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
			 struct iwl_rxon_context *ctx)
688
{
689
	enum ieee80211_band band = ch->band;
690
	u16 channel = ch->hw_value;
691

692
	if ((le16_to_cpu(ctx->staging.channel) == channel) &&
693
694
695
	    (priv->band == band))
		return 0;

696
	ctx->staging.channel = cpu_to_le16(channel);
697
	if (band == IEEE80211_BAND_5GHZ)
698
		ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK;
699
	else
700
		ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
701
702
703

	priv->band = band;

704
	IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band);
705
706
707
708

	return 0;
}

709
void iwl_set_flags_for_band(struct iwl_priv *priv,
710
			    struct iwl_rxon_context *ctx,
711
712
			    enum ieee80211_band band,
			    struct ieee80211_vif *vif)
713
714
{
	if (band == IEEE80211_BAND_5GHZ) {
715
		ctx->staging.flags &=
716
717
		    ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
		      | RXON_FLG_CCK_MSK);
718
		ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
719
720
	} else {
		/* Copied from iwl_post_associate() */
721
		if (vif && vif->bss_conf.use_short_slot)
722
			ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
723
		else
724
			ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
725

726
727
728
		ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
		ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK;
		ctx->staging.flags &= ~RXON_FLG_CCK_MSK;
729
730
731
732
733
734
	}
}

/*
 * initialize rxon structure with default values from eeprom
 */
735
void iwl_connection_init_rx_config(struct iwl_priv *priv,
736
				   struct iwl_rxon_context *ctx)
737
738
739
{
	const struct iwl_channel_info *ch_info;

740
	memset(&ctx->staging, 0, sizeof(ctx->staging));
741

742
743
744
	if (!ctx->vif) {
		ctx->staging.dev_type = ctx->unused_devtype;
	} else switch (ctx->vif->type) {
745
	case NL80211_IFTYPE_AP:
746
		ctx->staging.dev_type = ctx->ap_devtype;
747
748
749
		break;

	case NL80211_IFTYPE_STATION:
750
		ctx->staging.dev_type = ctx->station_devtype;
751
		ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
752
753
754
		break;

	case NL80211_IFTYPE_ADHOC:
755
		ctx->staging.dev_type = ctx->ibss_devtype;
756
757
		ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
		ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
758
759
760
761
						  RXON_FILTER_ACCEPT_GRP_MSK;
		break;

	default:
762
763
		IWL_ERR(priv, "Unsupported interface type %d\n",
			ctx->vif->type);
764
765
766
767
768
769
770
		break;
	}

#if 0
	/* TODO:  Figure out when short_preamble would be set and cache from
	 * that */
	if (!hw_to_local(priv->hw)->short_preamble)
771
		ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
772
	else
773
		ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
774
775
776
#endif

	ch_info = iwl_get_channel_info(priv, priv->band,
777
				       le16_to_cpu(ctx->active.channel));
778
779
780
781

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

782
	ctx->staging.channel = cpu_to_le16(ch_info->channel);
783
784
	priv->band = ch_info->band;

785
	iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif);
786

787
	ctx->staging.ofdm_basic_rates =
788
	    (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
789
	ctx->staging.cck_basic_rates =
790
791
	    (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;

792
	/* clear both MIX and PURE40 mode flag */
793
	ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |
794
					RXON_FLG_CHANNEL_MODE_PURE_40);
795
796
	if (ctx->vif)
		memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN);
797

798
799
800
	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;
801
802
}

803
void iwl_set_rate(struct iwl_priv *priv)
804
805
806
{
	const struct ieee80211_supported_band *hw = NULL;
	struct ieee80211_rate *rate;
807
	struct iwl_rxon_context *ctx;
808
809
810
811
812
813
814
815
816
817
818
819
	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]);
820
		if (rate->hw_value < IWL_RATE_COUNT_LEGACY)
821
822
823
			priv->active_rate |= (1 << rate->hw_value);
	}

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

826
827
828
	for_each_context(priv, ctx) {
		ctx->staging.cck_basic_rates =
		    (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
829

830
831
832
		ctx->staging.ofdm_basic_rates =
		   (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
	}
833
}
834
835
836

void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
{
837
838
839
840
841
842
	/*
	 * MULTI-FIXME
	 * See iwl_mac_channel_switch.
	 */
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];

843
844
845
846
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return;

	if (priv->switch_rxon.switch_in_progress) {
847
		ieee80211_chswitch_done(ctx->vif, is_success);
848
849
850
851
852
		mutex_lock(&priv->mutex);
		priv->switch_rxon.switch_in_progress = false;
		mutex_unlock(&priv->mutex);
	}
}
853
854

#ifdef CONFIG_IWLWIFI_DEBUG
855
856
void iwl_print_rx_config_cmd(struct iwl_priv *priv,
			     struct iwl_rxon_context *ctx)
857
{
858
	struct iwl_rxon_cmd *rxon = &ctx->staging;
859

860
	IWL_DEBUG_RADIO(priv, "RX CONFIG:\n");
861
	iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
862
863
864
	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",
865
			le32_to_cpu(rxon->filter_flags));
866
867
	IWL_DEBUG_RADIO(priv, "u8 dev_type: 0x%x\n", rxon->dev_type);
	IWL_DEBUG_RADIO(priv, "u8 ofdm_basic_rates: 0x%02x\n",
868
			rxon->ofdm_basic_rates);
869
870
871
872
	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));
873
}
874
#endif
875

876
877
878
879
880
881
882
883
884
885
886
887
888
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);
}

889
void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
890
{
891
892
893
	unsigned int reload_msec;
	unsigned long reload_jiffies;

894
895
896
897
898
899
	/* 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);

900
901
	iwlagn_abort_notification_waits(priv);

902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
	/* 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
930
		if (iwlagn_mod_params.restart_fw) {
931
932
933
934
935
936
937
938
939
940
941
942
943
944
			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)
{
945
946
947
948
949
950
951
	/* 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))) {
		/*
952
953
		 * Keep the restart process from trying to send host
		 * commands by clearing the ready bit.
954
955
		 */
		clear_bit(STATUS_READY, &priv->status);
956
957
		clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
		wake_up_interruptible(&priv->wait_command_queue);
958
959
960
961
		IWL_ERR(priv, "RF is used by WiMAX\n");
		return;
	}

962
963
964
	IWL_ERR(priv, "Loaded firmware version: %s\n",
		priv->hw->wiphy->fw_version);

965
966
967
968
	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);
969
#ifdef CONFIG_IWLWIFI_DEBUG
970
	if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
971
972
		iwl_print_rx_config_cmd(priv,
					&priv->contexts[IWL_RXON_CTX_BSS]);
973
974
#endif

975
	iwlagn_fw_error(priv, false);
976
977
}

978
static int iwl_apm_stop_master(struct iwl_priv *priv)
979
{
980
	int ret = 0;
981

982
	/* stop device's busmaster DMA activity */
983
984
	iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);

985
	ret = iwl_poll_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED,
986
			CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
987
988
	if (ret)
		IWL_WARN(priv, "Master Disable Timed Out, 100 usec\n");
989
990
991

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

992
	return ret;