iwl-agn.c 44.5 KB
Newer Older
Z
Zhu Yi 已提交
1 2
/******************************************************************************
 *
W
Wey-Yi Guy 已提交
3
 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
Z
Zhu Yi 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * Portions of this file are derived from the ipw3945 project, as well
 * as portions of the ieee80211 subsystem header files.
 *
 * 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.
 *
 * Contact Information:
25
 *  Intel Linux Wireless <ilw@linux.intel.com>
Z
Zhu Yi 已提交
26 27 28 29 30 31
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 *****************************************************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
32
#include <linux/slab.h>
Z
Zhu Yi 已提交
33
#include <linux/delay.h>
34
#include <linux/sched.h>
Z
Zhu Yi 已提交
35 36 37 38 39 40 41 42 43
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>

#include <net/mac80211.h>

#include <asm/div64.h>

A
Assaf Krauss 已提交
44
#include "iwl-eeprom.h"
45
#include "iwl-dev.h"
46
#include "iwl-core.h"
47
#include "iwl-io.h"
J
Johannes Berg 已提交
48
#include "iwl-agn-calib.h"
49
#include "iwl-agn.h"
50
#include "iwl-shared.h"
51
#include "iwl-trans.h"
52
#include "iwl-op-mode.h"
53

Z
Zhu Yi 已提交
54 55 56 57 58 59 60 61 62
/******************************************************************************
 *
 * module boiler plate
 *
 ******************************************************************************/

/*
 * module name, copyright, version, etc.
 */
63
#define DRV_DESCRIPTION	"Intel(R) Wireless WiFi Link AGN driver for Linux"
Z
Zhu Yi 已提交
64

65
#ifdef CONFIG_IWLWIFI_DEBUG
Z
Zhu Yi 已提交
66 67 68 69 70
#define VD "d"
#else
#define VD
#endif

71
#define DRV_VERSION     IWLWIFI_VERSION VD
Z
Zhu Yi 已提交
72 73 74 75


MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERSION);
76
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
Z
Zhu Yi 已提交
77
MODULE_LICENSE("GPL");
78
MODULE_ALIAS("iwlagn");
Z
Zhu Yi 已提交
79

80
void iwl_update_chain_flags(struct iwl_priv *priv)
M
Mohamed Abbas 已提交
81
{
82
	struct iwl_rxon_context *ctx;
M
Mohamed Abbas 已提交
83

W
Wey-Yi Guy 已提交
84 85 86 87
	for_each_context(priv, ctx) {
		iwlagn_set_rxon_chain(priv, ctx);
		if (ctx->active.rx_chain != ctx->staging.rx_chain)
			iwlagn_commit_rxon(priv, ctx);
88
	}
M
Mohamed Abbas 已提交
89 90
}

91 92
/* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */
static void iwl_set_beacon_tim(struct iwl_priv *priv,
93 94
			       struct iwl_tx_beacon_cmd *tx_beacon_cmd,
			       u8 *beacon, u32 frame_size)
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
{
	u16 tim_idx;
	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon;

	/*
	 * The index is relative to frame start but we start looking at the
	 * variable-length part of the beacon.
	 */
	tim_idx = mgmt->u.beacon.variable - beacon;

	/* Parse variable-length elements of beacon to find WLAN_EID_TIM */
	while ((tim_idx < (frame_size - 2)) &&
			(beacon[tim_idx] != WLAN_EID_TIM))
		tim_idx += beacon[tim_idx+1] + 2;

	/* If TIM field was found, set variables */
	if ((tim_idx < (frame_size - 1)) && (beacon[tim_idx] == WLAN_EID_TIM)) {
		tx_beacon_cmd->tim_idx = cpu_to_le16(tim_idx);
		tx_beacon_cmd->tim_size = beacon[tim_idx+1];
	} else
		IWL_WARN(priv, "Unable to find TIM Element in beacon\n");
}

118
int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
119 120
{
	struct iwl_tx_beacon_cmd *tx_beacon_cmd;
121 122
	struct iwl_host_cmd cmd = {
		.id = REPLY_TX_BEACON,
123
		.flags = CMD_SYNC,
124
	};
125
	struct ieee80211_tx_info *info;
126 127 128
	u32 frame_size;
	u32 rate_flags;
	u32 rate;
129

130 131 132 133
	/*
	 * We have to set up the TX command, the TX Beacon command, and the
	 * beacon contents.
	 */
134

135
	lockdep_assert_held(&priv->mutex);
136 137 138

	if (!priv->beacon_ctx) {
		IWL_ERR(priv, "trying to build beacon w/o beacon context!\n");
139
		return 0;
140 141
	}

142 143 144
	if (WARN_ON(!priv->beacon_skb))
		return -EINVAL;

145 146 147 148
	/* Allocate beacon command */
	if (!priv->beacon_cmd)
		priv->beacon_cmd = kzalloc(sizeof(*tx_beacon_cmd), GFP_KERNEL);
	tx_beacon_cmd = priv->beacon_cmd;
149 150 151 152
	if (!tx_beacon_cmd)
		return -ENOMEM;

	frame_size = priv->beacon_skb->len;
153

154
	/* Set up TX command fields */
155
	tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
156
	tx_beacon_cmd->tx.sta_id = priv->beacon_ctx->bcast_sta_id;
157 158 159
	tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
	tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK |
		TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK;
160

161
	/* Set up TX beacon command fields */
162
	iwl_set_beacon_tim(priv, tx_beacon_cmd, priv->beacon_skb->data,
163
			   frame_size);
164

165
	/* Set up packet rate and flags */
166 167 168 169 170 171 172 173 174 175 176 177 178
	info = IEEE80211_SKB_CB(priv->beacon_skb);

	/*
	 * Let's set up the rate at least somewhat correctly;
	 * it will currently not actually be used by the uCode,
	 * it uses the broadcast station's rate instead.
	 */
	if (info->control.rates[0].idx < 0 ||
	    info->control.rates[0].flags & IEEE80211_TX_RC_MCS)
		rate = 0;
	else
		rate = info->control.rates[0].idx;

179
	priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
180
					      hw_params(priv).valid_tx_ant);
181
	rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
182 183 184 185 186

	/* In mac80211, rates for 5 GHz start at 0 */
	if (info->band == IEEE80211_BAND_5GHZ)
		rate += IWL_FIRST_OFDM_RATE;
	else if (rate >= IWL_FIRST_CCK_RATE && rate <= IWL_LAST_CCK_RATE)
187
		rate_flags |= RATE_MCS_CCK_MSK;
188 189 190

	tx_beacon_cmd->tx.rate_n_flags =
			iwl_hw_set_rate_n_flags(rate, rate_flags);
191

192
	/* Submit command */
193
	cmd.len[0] = sizeof(*tx_beacon_cmd);
194
	cmd.data[0] = tx_beacon_cmd;
195 196 197 198
	cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
	cmd.len[1] = frame_size;
	cmd.data[1] = priv->beacon_skb->data;
	cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY;
199

200
	return iwl_dvm_send_cmd(priv, &cmd);
201 202
}

203
static void iwl_bg_beacon_update(struct work_struct *work)
Z
Zhu Yi 已提交
204
{
205 206
	struct iwl_priv *priv =
		container_of(work, struct iwl_priv, beacon_update);
Z
Zhu Yi 已提交
207 208
	struct sk_buff *beacon;

209
	mutex_lock(&priv->mutex);
210 211 212 213
	if (!priv->beacon_ctx) {
		IWL_ERR(priv, "updating beacon w/o beacon context!\n");
		goto out;
	}
Z
Zhu Yi 已提交
214

215 216 217 218 219 220 221 222 223 224
	if (priv->beacon_ctx->vif->type != NL80211_IFTYPE_AP) {
		/*
		 * The ucode will send beacon notifications even in
		 * IBSS mode, but we don't want to process them. But
		 * we need to defer the type check to here due to
		 * requiring locking around the beacon_ctx access.
		 */
		goto out;
	}

225 226
	/* Pull updated AP beacon from mac80211. will fail if not in AP mode */
	beacon = ieee80211_beacon_get(priv->hw, priv->beacon_ctx->vif);
Z
Zhu Yi 已提交
227
	if (!beacon) {
228
		IWL_ERR(priv, "update beacon failed -- keeping old\n");
229
		goto out;
Z
Zhu Yi 已提交
230 231 232
	}

	/* new beacon skb is allocated every time; dispose previous.*/
233
	dev_kfree_skb(priv->beacon_skb);
Z
Zhu Yi 已提交
234

235
	priv->beacon_skb = beacon;
Z
Zhu Yi 已提交
236

237
	iwlagn_send_beacon_cmd(priv);
238
 out:
239
	mutex_unlock(&priv->mutex);
Z
Zhu Yi 已提交
240 241
}

242 243 244 245 246
static void iwl_bg_bt_runtime_config(struct work_struct *work)
{
	struct iwl_priv *priv =
		container_of(work, struct iwl_priv, bt_runtime_config);

247
	if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
248 249 250
		return;

	/* dont send host command if rf-kill is on */
251
	if (!iwl_is_ready_rf(priv->shrd))
252
		return;
W
Wey-Yi Guy 已提交
253
	iwlagn_send_advance_bt_config(priv);
254 255
}

256 257 258 259
static void iwl_bg_bt_full_concurrency(struct work_struct *work)
{
	struct iwl_priv *priv =
		container_of(work, struct iwl_priv, bt_full_concurrency);
260
	struct iwl_rxon_context *ctx;
261

262
	mutex_lock(&priv->mutex);
263

264
	if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
265
		goto out;
266 267

	/* dont send host command if rf-kill is on */
268
	if (!iwl_is_ready_rf(priv->shrd))
269
		goto out;
270 271 272 273 274 275 276 277 278

	IWL_DEBUG_INFO(priv, "BT coex in %s mode\n",
		       priv->bt_full_concurrent ?
		       "full concurrency" : "3-wire");

	/*
	 * LQ & RXON updated cmds must be sent before BT Config cmd
	 * to avoid 3-wire collisions
	 */
279
	for_each_context(priv, ctx) {
W
Wey-Yi Guy 已提交
280
		iwlagn_set_rxon_chain(priv, ctx);
281
		iwlagn_commit_rxon(priv, ctx);
282
	}
283

W
Wey-Yi Guy 已提交
284
	iwlagn_send_advance_bt_config(priv);
285
out:
286
	mutex_unlock(&priv->mutex);
287 288
}

289
/**
290
 * iwl_bg_statistics_periodic - Timer callback to queue statistics
291 292 293 294 295 296 297 298
 *
 * This callback is provided in order to send a statistics request.
 *
 * This timer function is continually reset to execute within
 * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION
 * was received.  We need to ensure we receive the statistics in order
 * to update the temperature used for calibrating the TXPOWER.
 */
299
static void iwl_bg_statistics_periodic(unsigned long data)
300 301 302
{
	struct iwl_priv *priv = (struct iwl_priv *)data;

303
	if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
304 305
		return;

306
	/* dont send host command if rf-kill is on */
307
	if (!iwl_is_ready_rf(priv->shrd))
308 309
		return;

310
	iwl_send_statistics_request(priv, CMD_ASYNC, false);
311 312
}

313 314 315

static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
					u32 start_idx, u32 num_events,
J
Johannes Berg 已提交
316
					u32 capacity, u32 mode)
317 318 319 320 321 322 323 324 325 326 327 328
{
	u32 i;
	u32 ptr;        /* SRAM byte address of log data */
	u32 ev, time, data; /* event log data */
	unsigned long reg_flags;

	if (mode == 0)
		ptr = base + (4 * sizeof(u32)) + (start_idx * 2 * sizeof(u32));
	else
		ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32));

	/* Make sure device is powered up for SRAM reads */
329
	spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags);
330
	if (unlikely(!iwl_grab_nic_access(trans(priv)))) {
331
		spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags);
332 333 334 335
		return;
	}

	/* Set starting address; reads will auto-increment */
336
	iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr);
337 338
	rmb();

J
Johannes Berg 已提交
339 340 341 342 343 344 345 346 347
	/*
	 * Refuse to read more than would have fit into the log from
	 * the current start_idx. This used to happen due to the race
	 * described below, but now WARN because the code below should
	 * prevent it from happening here.
	 */
	if (WARN_ON(num_events > capacity - start_idx))
		num_events = capacity - start_idx;

348 349 350 351 352
	/*
	 * "time" is actually "data" for mode 0 (no timestamp).
	 * place event id # at far right for easier visual parsing.
	 */
	for (i = 0; i < num_events; i++) {
353 354
		ev = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
		time = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
355
		if (mode == 0) {
356 357
			trace_iwlwifi_dev_ucode_cont_event(
					trans(priv)->dev, 0, time, ev);
358
		} else {
359
			data = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
360 361
			trace_iwlwifi_dev_ucode_cont_event(
					trans(priv)->dev, time, data, ev);
362 363 364
		}
	}
	/* Allow device to power down */
365 366
	iwl_release_nic_access(trans(priv));
	spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags);
367 368
}

J
Johannes Berg 已提交
369
static void iwl_continuous_event_trace(struct iwl_priv *priv)
370 371
{
	u32 capacity;   /* event log capacity in # entries */
J
Johannes Berg 已提交
372 373 374 375 376 377
	struct {
		u32 capacity;
		u32 mode;
		u32 wrap_counter;
		u32 write_counter;
	} __packed read;
378 379 380 381 382
	u32 base;       /* SRAM byte address of event log header */
	u32 mode;       /* 0 - no timestamp, 1 - timestamp recorded */
	u32 num_wraps;  /* # times uCode wrapped to top of log */
	u32 next_entry; /* index of next entry to be written by uCode */

J
Johannes Berg 已提交
383
	base = priv->shrd->device_pointers.log_event_table;
384
	if (iwlagn_hw_valid_rtc_data_addr(base)) {
385
		iwl_read_targ_mem_words(trans(priv), base, &read, sizeof(read));
J
Johannes Berg 已提交
386 387 388 389 390

		capacity = read.capacity;
		mode = read.mode;
		num_wraps = read.wrap_counter;
		next_entry = read.write_counter;
391 392 393
	} else
		return;

J
Johannes Berg 已提交
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
	/*
	 * Unfortunately, the uCode doesn't use temporary variables.
	 * Therefore, it can happen that we read next_entry == capacity,
	 * which really means next_entry == 0.
	 */
	if (unlikely(next_entry == capacity))
		next_entry = 0;
	/*
	 * Additionally, the uCode increases the write pointer before
	 * the wraps counter, so if the write pointer is smaller than
	 * the old write pointer (wrap occurred) but we read that no
	 * wrap occurred, we actually read between the next_entry and
	 * num_wraps update (this does happen in practice!!) -- take
	 * that into account by increasing num_wraps.
	 */
	if (unlikely(next_entry < priv->event_log.next_entry &&
		     num_wraps == priv->event_log.num_wraps))
		num_wraps++;

413
	if (num_wraps == priv->event_log.num_wraps) {
J
Johannes Berg 已提交
414 415 416 417 418
		iwl_print_cont_event_trace(
			priv, base, priv->event_log.next_entry,
			next_entry - priv->event_log.next_entry,
			capacity, mode);

419 420
		priv->event_log.non_wraps_count++;
	} else {
J
Johannes Berg 已提交
421
		if (num_wraps - priv->event_log.num_wraps > 1)
422 423 424
			priv->event_log.wraps_more_count++;
		else
			priv->event_log.wraps_once_count++;
J
Johannes Berg 已提交
425

426
		trace_iwlwifi_dev_ucode_wrap_event(trans(priv)->dev,
427 428
				num_wraps - priv->event_log.num_wraps,
				next_entry, priv->event_log.next_entry);
J
Johannes Berg 已提交
429

430
		if (next_entry < priv->event_log.next_entry) {
J
Johannes Berg 已提交
431 432 433 434
			iwl_print_cont_event_trace(
				priv, base, priv->event_log.next_entry,
				capacity - priv->event_log.next_entry,
				capacity, mode);
435

J
Johannes Berg 已提交
436 437
			iwl_print_cont_event_trace(
				priv, base, 0, next_entry, capacity, mode);
438
		} else {
J
Johannes Berg 已提交
439 440 441 442
			iwl_print_cont_event_trace(
				priv, base, next_entry,
				capacity - next_entry,
				capacity, mode);
443

J
Johannes Berg 已提交
444 445
			iwl_print_cont_event_trace(
				priv, base, 0, next_entry, capacity, mode);
446 447
		}
	}
J
Johannes Berg 已提交
448

449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
	priv->event_log.num_wraps = num_wraps;
	priv->event_log.next_entry = next_entry;
}

/**
 * iwl_bg_ucode_trace - Timer callback to log ucode event
 *
 * The timer is continually set to execute every
 * UCODE_TRACE_PERIOD milliseconds after the last timer expired
 * this function is to perform continuous uCode event logging operation
 * if enabled
 */
static void iwl_bg_ucode_trace(unsigned long data)
{
	struct iwl_priv *priv = (struct iwl_priv *)data;

465
	if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
466 467 468 469 470 471 472 473 474 475
		return;

	if (priv->event_log.ucode_trace) {
		iwl_continuous_event_trace(priv);
		/* Reschedule the timer to occur in UCODE_TRACE_PERIOD */
		mod_timer(&priv->ucode_trace,
			 jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
	}
}

476 477 478 479 480
static void iwl_bg_tx_flush(struct work_struct *work)
{
	struct iwl_priv *priv =
		container_of(work, struct iwl_priv, tx_flush);

481
	if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
482 483 484
		return;

	/* do nothing if rf-kill is on */
485
	if (!iwl_is_ready_rf(priv->shrd))
486 487
		return;

488 489
	IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n");
	iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL);
490 491
}

492
void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
493 494 495 496 497 498 499
{
	int i;

	/*
	 * The default context is always valid,
	 * the PAN context depends on uCode.
	 */
500
	priv->shrd->valid_contexts = BIT(IWL_RXON_CTX_BSS);
501
	if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN)
502
		priv->shrd->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
503 504 505 506 507 508 509 510 511 512 513 514

	for (i = 0; i < NUM_IWL_RXON_CTX; i++)
		priv->contexts[i].ctxid = i;

	priv->contexts[IWL_RXON_CTX_BSS].always_active = true;
	priv->contexts[IWL_RXON_CTX_BSS].is_active = true;
	priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON;
	priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING;
	priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
	priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
	priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
	priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
515
	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
	priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
		BIT(NL80211_IFTYPE_ADHOC);
	priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
		BIT(NL80211_IFTYPE_STATION);
	priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
	priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
	priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
	priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;

	priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON;
	priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd =
		REPLY_WIPAN_RXON_TIMING;
	priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd =
		REPLY_WIPAN_RXON_ASSOC;
	priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM;
	priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN;
	priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY;
	priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID;
	priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION;
	priv->contexts[IWL_RXON_CTX_PAN].interface_modes =
		BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
537 538 539 540 541 542

	if (ucode_flags & IWL_UCODE_TLV_FLAGS_P2P)
		priv->contexts[IWL_RXON_CTX_PAN].interface_modes |=
			BIT(NL80211_IFTYPE_P2P_CLIENT) |
			BIT(NL80211_IFTYPE_P2P_GO);

543 544 545 546 547 548 549
	priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP;
	priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA;
	priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P;

	BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
}

550 551 552 553 554 555
static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
{
	struct iwl_ct_kill_config cmd;
	struct iwl_ct_kill_throttling_config adv_cmd;
	int ret = 0;

556
	iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR,
557
		    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
J
Johannes Berg 已提交
558

559 560
	priv->thermal_throttle.ct_kill_toggle = false;

561
	if (cfg(priv)->base_params->support_ct_kill_exit) {
562
		adv_cmd.critical_temperature_enter =
563
			cpu_to_le32(hw_params(priv).ct_kill_threshold);
564
		adv_cmd.critical_temperature_exit =
565
			cpu_to_le32(hw_params(priv).ct_kill_exit_threshold);
566

567
		ret = iwl_dvm_send_cmd_pdu(priv,
568 569
				       REPLY_CT_KILL_CONFIG_CMD,
				       CMD_SYNC, sizeof(adv_cmd), &adv_cmd);
570 571 572 573
		if (ret)
			IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
		else
			IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
574 575 576 577
				"succeeded, critical temperature enter is %d,"
				"exit is %d\n",
				hw_params(priv).ct_kill_threshold,
				hw_params(priv).ct_kill_exit_threshold);
578 579
	} else {
		cmd.critical_temperature_R =
580
			cpu_to_le32(hw_params(priv).ct_kill_threshold);
581

582
		ret = iwl_dvm_send_cmd_pdu(priv,
583 584
				       REPLY_CT_KILL_CONFIG_CMD,
				       CMD_SYNC, sizeof(cmd), &cmd);
585 586 587 588
		if (ret)
			IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
		else
			IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
589 590 591
				"succeeded, "
				"critical temperature is %d\n",
				hw_params(priv).ct_kill_threshold);
592 593 594
	}
}

595 596 597 598 599
static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg)
{
	struct iwl_calib_cfg_cmd calib_cfg_cmd;
	struct iwl_host_cmd cmd = {
		.id = CALIBRATION_CFG_CMD,
600 601
		.len = { sizeof(struct iwl_calib_cfg_cmd), },
		.data = { &calib_cfg_cmd, },
602 603 604
	};

	memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
605
	calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_RT_CFG_ALL;
606
	calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg);
607

608
	return iwl_dvm_send_cmd(priv, &cmd);
609 610 611
}


W
Wey-Yi Guy 已提交
612 613 614 615 616 617
static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
{
	struct iwl_tx_ant_config_cmd tx_ant_cmd = {
	  .valid = cpu_to_le32(valid_tx_ant),
	};

618
	if (IWL_UCODE_API(priv->fw->ucode_ver) > 1) {
W
Wey-Yi Guy 已提交
619
		IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
620
		return iwl_dvm_send_cmd_pdu(priv,
W
Wey-Yi Guy 已提交
621 622 623 624 625 626 627 628 629 630
					TX_ANT_CONFIGURATION_CMD,
					CMD_SYNC,
					sizeof(struct iwl_tx_ant_config_cmd),
					&tx_ant_cmd);
	} else {
		IWL_DEBUG_HC(priv, "TX_ANT_CONFIGURATION_CMD not supported\n");
		return -EOPNOTSUPP;
	}
}

Z
Zhu Yi 已提交
631
/**
632
 * iwl_alive_start - called after REPLY_ALIVE notification received
Z
Zhu Yi 已提交
633
 *                   from protocol/runtime uCode (initialization uCode's
634
 *                   Alive gets handled by iwl_init_alive_start()).
Z
Zhu Yi 已提交
635
 */
636
int iwl_alive_start(struct iwl_priv *priv)
Z
Zhu Yi 已提交
637
{
638
	int ret = 0;
639
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
Z
Zhu Yi 已提交
640

641
	IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
642

643
	/* After the ALIVE response, we can send host commands to the uCode */
644
	set_bit(STATUS_ALIVE, &priv->shrd->status);
Z
Zhu Yi 已提交
645

646 647
	/* Enable watchdog to monitor the driver tx queues */
	iwl_setup_watchdog(priv);
648

649
	if (iwl_is_rfkill(priv->shrd))
650
		return -ERFKILL;
Z
Zhu Yi 已提交
651

J
Johannes Berg 已提交
652 653 654 655 656
	if (priv->event_log.ucode_trace) {
		/* start collecting data now */
		mod_timer(&priv->ucode_trace, jiffies);
	}

657
	/* download priority table before any calibration request */
658 659
	if (cfg(priv)->bt_params &&
	    cfg(priv)->bt_params->advanced_bt_coexist) {
660
		/* Configure Bluetooth device coexistence support */
661
		if (cfg(priv)->bt_params->bt_sco_disable)
662 663 664 665
			priv->bt_enable_pspoll = false;
		else
			priv->bt_enable_pspoll = true;

666 667 668
		priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
		priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
		priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
W
Wey-Yi Guy 已提交
669
		iwlagn_send_advance_bt_config(priv);
670
		priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
671 672
		priv->cur_rssi_ctx = NULL;

673
		iwl_send_prio_tbl(priv);
674 675

		/* FIXME: w/a to force change uCode BT state machine */
676
		ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
677 678 679
					 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
		if (ret)
			return ret;
680
		ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
681 682 683
					 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
		if (ret)
			return ret;
W
Wey-Yi Guy 已提交
684 685 686 687 688
	} else {
		/*
		 * default is 2-wire BT coexexistence support
		 */
		iwl_send_bt_config(priv);
689
	}
W
Wey-Yi Guy 已提交
690

691 692 693 694
	/*
	 * Perform runtime calibrations, including DC calibration.
	 */
	iwlagn_send_calib_cfg_rt(priv, IWL_CALIB_CFG_DC_IDX);
695

696
	ieee80211_wake_queues(priv->hw);
Z
Zhu Yi 已提交
697

698
	priv->active_rate = IWL_RATES_MASK;
Z
Zhu Yi 已提交
699

700
	/* Configure Tx antenna selection based on H/W config */
701
	iwlagn_send_tx_ant_config(priv, hw_params(priv).valid_tx_ant);
702

703
	if (iwl_is_associated_ctx(ctx) && !priv->wowlan) {
G
Gregory Greenman 已提交
704
		struct iwl_rxon_cmd *active_rxon =
705
				(struct iwl_rxon_cmd *)&ctx->active;
706
		/* apply any changes in staging */
707
		ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
Z
Zhu Yi 已提交
708 709
		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
	} else {
710
		struct iwl_rxon_context *tmp;
Z
Zhu Yi 已提交
711
		/* Initialize our rx_config data */
712 713
		for_each_context(priv, tmp)
			iwl_connection_init_rx_config(priv, tmp);
714

W
Wey-Yi Guy 已提交
715
		iwlagn_set_rxon_chain(priv, ctx);
Z
Zhu Yi 已提交
716 717
	}

718
	if (!priv->wowlan) {
J
Johannes Berg 已提交
719 720 721
		/* WoWLAN ucode will not reply in the same way, skip it */
		iwl_reset_run_time_calib(priv);
	}
722

723
	set_bit(STATUS_READY, &priv->shrd->status);
724

Z
Zhu Yi 已提交
725
	/* Configure the adapter for unassociated operation */
726
	ret = iwlagn_commit_rxon(priv, ctx);
727 728
	if (ret)
		return ret;
Z
Zhu Yi 已提交
729 730

	/* At this point, the NIC is initialized and operational */
731
	iwl_rf_kill_ct_config(priv);
732

733
	IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
734

735
	return iwl_power_update_mode(priv, true);
Z
Zhu Yi 已提交
736 737
}

738 739 740 741 742 743 744 745 746 747 748 749 750
/**
 * iwl_clear_driver_stations - clear knowledge of all stations from driver
 * @priv: iwl priv struct
 *
 * This is called during iwl_down() to make sure that in the case
 * we're coming there from a hardware restart mac80211 will be
 * able to reconfigure stations -- if we're getting there in the
 * normal down flow then the stations will already be cleared.
 */
static void iwl_clear_driver_stations(struct iwl_priv *priv)
{
	struct iwl_rxon_context *ctx;

751
	spin_lock_bh(&priv->sta_lock);
752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768
	memset(priv->stations, 0, sizeof(priv->stations));
	priv->num_stations = 0;

	priv->ucode_key_table = 0;

	for_each_context(priv, ctx) {
		/*
		 * Remove all key information that is not stored as part
		 * of station information since mac80211 may not have had
		 * a chance to remove all the keys. When device is
		 * reconfigured by mac80211 after an error all keys will
		 * be reconfigured.
		 */
		memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys));
		ctx->key_mapping_keys = 0;
	}

769
	spin_unlock_bh(&priv->sta_lock);
770 771
}

772
void iwl_down(struct iwl_priv *priv)
Z
Zhu Yi 已提交
773
{
774
	int exit_pending;
Z
Zhu Yi 已提交
775

776
	IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
Z
Zhu Yi 已提交
777

778
	lockdep_assert_held(&priv->mutex);
779

780 781
	iwl_scan_cancel_timeout(priv, 200);

782 783 784 785 786 787 788
	/*
	 * If active, scanning won't cancel it, so say it expired.
	 * No race since we hold the mutex here and a new one
	 * can't come in at this time.
	 */
	ieee80211_remain_on_channel_expired(priv->hw);

789 790
	exit_pending =
		test_and_set_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
Z
Zhu Yi 已提交
791

792 793
	/* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
	 * to prevent rearm timer */
794
	del_timer_sync(&priv->watchdog);
795

796
	iwl_clear_ucode_stations(priv, NULL);
797
	iwl_dealloc_bcast_stations(priv);
798
	iwl_clear_driver_stations(priv);
Z
Zhu Yi 已提交
799

800
	/* reset BT coex data */
801
	priv->bt_status = 0;
802 803
	priv->cur_rssi_ctx = NULL;
	priv->bt_is_sco = 0;
804
	if (cfg(priv)->bt_params)
805
		priv->bt_traffic_load =
806
			 cfg(priv)->bt_params->bt_init_traffic_load;
807 808
	else
		priv->bt_traffic_load = 0;
809 810
	priv->bt_full_concurrent = false;
	priv->bt_ci_compliance = 0;
811

Z
Zhu Yi 已提交
812 813 814
	/* Wipe out the EXIT_PENDING status bit if we are not actually
	 * exiting the module */
	if (!exit_pending)
815
		clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
Z
Zhu Yi 已提交
816

817
	if (priv->mac80211_registered)
Z
Zhu Yi 已提交
818 819
		ieee80211_stop_queues(priv->hw);

820 821
	iwl_trans_stop_device(trans(priv));

J
Johannes Berg 已提交
822
	/* Clear out all status bits but a few that are stable across reset */
823 824
	priv->shrd->status &=
			test_bit(STATUS_RF_KILL_HW, &priv->shrd->status) <<
Z
Zhu Yi 已提交
825
				STATUS_RF_KILL_HW |
826
			test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) <<
827
				STATUS_GEO_CONFIGURED |
828
			test_bit(STATUS_FW_ERROR, &priv->shrd->status) <<
829
				STATUS_FW_ERROR |
830
			test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) <<
831
				STATUS_EXIT_PENDING;
Z
Zhu Yi 已提交
832

833
	dev_kfree_skb(priv->beacon_skb);
834
	priv->beacon_skb = NULL;
Z
Zhu Yi 已提交
835 836 837 838 839 840 841 842
}

/*****************************************************************************
 *
 * Workqueue callbacks
 *
 *****************************************************************************/

843 844 845 846 847
static void iwl_bg_run_time_calib_work(struct work_struct *work)
{
	struct iwl_priv *priv = container_of(work, struct iwl_priv,
			run_time_calib_work);

848
	mutex_lock(&priv->mutex);
849

850 851
	if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) ||
	    test_bit(STATUS_SCANNING, &priv->shrd->status)) {
852
		mutex_unlock(&priv->mutex);
853 854 855 856
		return;
	}

	if (priv->start_calib) {
857 858
		iwl_chain_noise_calibration(priv);
		iwl_sensitivity_calibration(priv);
859 860
	}

861
	mutex_unlock(&priv->mutex);
862 863
}

864
void iwlagn_prepare_restart(struct iwl_priv *priv)
J
Johannes Berg 已提交
865 866 867 868 869 870
{
	struct iwl_rxon_context *ctx;
	bool bt_full_concurrent;
	u8 bt_ci_compliance;
	u8 bt_load;
	u8 bt_status;
871
	bool bt_is_sco;
J
Johannes Berg 已提交
872

873
	lockdep_assert_held(&priv->mutex);
J
Johannes Berg 已提交
874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891

	for_each_context(priv, ctx)
		ctx->vif = NULL;
	priv->is_open = 0;

	/*
	 * __iwl_down() will clear the BT status variables,
	 * which is correct, but when we restart we really
	 * want to keep them so restore them afterwards.
	 *
	 * The restart process will later pick them up and
	 * re-configure the hw when we reconfigure the BT
	 * command.
	 */
	bt_full_concurrent = priv->bt_full_concurrent;
	bt_ci_compliance = priv->bt_ci_compliance;
	bt_load = priv->bt_traffic_load;
	bt_status = priv->bt_status;
892
	bt_is_sco = priv->bt_is_sco;
J
Johannes Berg 已提交
893

894
	iwl_down(priv);
J
Johannes Berg 已提交
895 896 897 898 899

	priv->bt_full_concurrent = bt_full_concurrent;
	priv->bt_ci_compliance = bt_ci_compliance;
	priv->bt_traffic_load = bt_load;
	priv->bt_status = bt_status;
900
	priv->bt_is_sco = bt_is_sco;
J
Johannes Berg 已提交
901 902
}

903
static void iwl_bg_restart(struct work_struct *data)
Z
Zhu Yi 已提交
904
{
905
	struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
Z
Zhu Yi 已提交
906

907
	if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
Z
Zhu Yi 已提交
908 909
		return;

910
	if (test_and_clear_bit(STATUS_FW_ERROR, &priv->shrd->status)) {
911
		mutex_lock(&priv->mutex);
J
Johannes Berg 已提交
912
		iwlagn_prepare_restart(priv);
913
		mutex_unlock(&priv->mutex);
914
		iwl_cancel_deferred_work(priv);
J
Johannes Berg 已提交
915 916
		ieee80211_restart_hw(priv->hw);
	} else {
917
		WARN_ON(1);
J
Johannes Berg 已提交
918
	}
Z
Zhu Yi 已提交
919 920
}

921 922 923



924
void iwlagn_disable_roc(struct iwl_priv *priv)
925
{
926
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
927

928
	lockdep_assert_held(&priv->mutex);
929

930 931
	if (!priv->hw_roc_setup)
		return;
932

933 934
	ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
	ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
935

936
	priv->hw_roc_channel = NULL;
937

938
	memset(ctx->staging.node_addr, 0, ETH_ALEN);
939

940
	iwlagn_commit_rxon(priv, ctx);
941

942 943
	ctx->is_active = false;
	priv->hw_roc_setup = false;
944 945
}

946
static void iwlagn_disable_roc_work(struct work_struct *work)
Z
Zhu Yi 已提交
947
{
948 949
	struct iwl_priv *priv = container_of(work, struct iwl_priv,
					     hw_roc_disable_work.work);
Z
Zhu Yi 已提交
950

951
	mutex_lock(&priv->mutex);
952
	iwlagn_disable_roc(priv);
953
	mutex_unlock(&priv->mutex);
Z
Zhu Yi 已提交
954 955
}

956 957 958 959 960 961 962
/*****************************************************************************
 *
 * driver setup and teardown
 *
 *****************************************************************************/

static void iwl_setup_deferred_work(struct iwl_priv *priv)
Z
Zhu Yi 已提交
963
{
J
Johannes Berg 已提交
964
	priv->workqueue = create_singlethread_workqueue(DRV_NAME);
Z
Zhu Yi 已提交
965

966
	init_waitqueue_head(&priv->shrd->wait_command_queue);
M
Mohamed Abbas 已提交
967

968 969 970 971 972 973 974 975
	INIT_WORK(&priv->restart, iwl_bg_restart);
	INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
	INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
	INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush);
	INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency);
	INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config);
	INIT_DELAYED_WORK(&priv->hw_roc_disable_work,
			  iwlagn_disable_roc_work);
976

977
	iwl_setup_scan_deferred_work(priv);
978

979 980
	if (cfg(priv)->bt_params)
		iwlagn_bt_setup_deferred_work(priv);
981

982 983 984
	init_timer(&priv->statistics_periodic);
	priv->statistics_periodic.data = (unsigned long)priv;
	priv->statistics_periodic.function = iwl_bg_statistics_periodic;
985

986 987 988
	init_timer(&priv->ucode_trace);
	priv->ucode_trace.data = (unsigned long)priv;
	priv->ucode_trace.function = iwl_bg_ucode_trace;
M
Mohamed Abbas 已提交
989

990 991 992
	init_timer(&priv->watchdog);
	priv->watchdog.data = (unsigned long)priv;
	priv->watchdog.function = iwl_bg_watchdog;
Z
Zhu Yi 已提交
993 994
}

995
void iwl_cancel_deferred_work(struct iwl_priv *priv)
J
Johannes Berg 已提交
996
{
997 998
	if (cfg(priv)->bt_params)
		iwlagn_bt_cancel_deferred_work(priv);
J
Johannes Berg 已提交
999

1000 1001
	cancel_work_sync(&priv->run_time_calib_work);
	cancel_work_sync(&priv->beacon_update);
J
Johannes Berg 已提交
1002

1003
	iwl_cancel_scan_deferred_work(priv);
J
Johannes Berg 已提交
1004

1005 1006 1007
	cancel_work_sync(&priv->bt_full_concurrency);
	cancel_work_sync(&priv->bt_runtime_config);
	cancel_delayed_work_sync(&priv->hw_roc_disable_work);
J
Johannes Berg 已提交
1008

1009 1010 1011
	del_timer_sync(&priv->statistics_periodic);
	del_timer_sync(&priv->ucode_trace);
}
J
Johannes Berg 已提交
1012

1013
static void iwl_init_hw_rates(struct ieee80211_rate *rates)
1014 1015
{
	int i;
J
Johannes Berg 已提交
1016

1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029
	for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
		rates[i].bitrate = iwl_rates[i].ieee * 5;
		rates[i].hw_value = i; /* Rate scaling will work on indexes */
		rates[i].hw_value_short = i;
		rates[i].flags = 0;
		if ((i >= IWL_FIRST_CCK_RATE) && (i <= IWL_LAST_CCK_RATE)) {
			/*
			 * If CCK != 1M then set short preamble rate flag.
			 */
			rates[i].flags |=
				(iwl_rates[i].plcp == IWL_RATE_1M_PLCP) ?
					0 : IEEE80211_RATE_SHORT_PREAMBLE;
		}
J
Johannes Berg 已提交
1030 1031 1032
	}
}

1033
static int iwl_init_drv(struct iwl_priv *priv)
J
Johannes Berg 已提交
1034
{
1035
	int ret;
J
Johannes Berg 已提交
1036

1037
	spin_lock_init(&priv->sta_lock);
J
Johannes Berg 已提交
1038

1039
	mutex_init(&priv->mutex);
J
Johannes Berg 已提交
1040

1041
	INIT_LIST_HEAD(&priv->calib_results);
1042

1043 1044 1045
	priv->ieee_channels = NULL;
	priv->ieee_rates = NULL;
	priv->band = IEEE80211_BAND_2GHZ;
J
Johannes Berg 已提交
1046

1047 1048 1049
	priv->plcp_delta_threshold =
		cfg(priv)->base_params->plcp_delta_threshold;

1050 1051 1052 1053
	priv->iw_mode = NL80211_IFTYPE_STATION;
	priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
	priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
	priv->agg_tids_count = 0;
J
Johannes Berg 已提交
1054

1055 1056
	priv->ucode_owner = IWL_OWNERSHIP_DRIVER;

1057 1058 1059 1060 1061
	/* initialize force reset */
	priv->force_reset[IWL_RF_RESET].reset_duration =
		IWL_DELAY_NEXT_FORCE_RF_RESET;
	priv->force_reset[IWL_FW_RESET].reset_duration =
		IWL_DELAY_NEXT_FORCE_FW_RELOAD;
J
Johannes Berg 已提交
1062

1063
	priv->rx_statistics_jiffies = jiffies;
J
Johannes Berg 已提交
1064

1065 1066
	/* Choose which receivers/antennas to use */
	iwlagn_set_rxon_chain(priv, &priv->contexts[IWL_RXON_CTX_BSS]);
J
Johannes Berg 已提交
1067

1068
	iwl_init_scan_params(priv);
J
Johannes Berg 已提交
1069

1070
	/* init bt coex */
1071 1072
	if (cfg(priv)->bt_params &&
	    cfg(priv)->bt_params->advanced_bt_coexist) {
1073 1074 1075 1076 1077 1078 1079
		priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
		priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
		priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
		priv->bt_on_thresh = BT_ON_THRESHOLD_DEF;
		priv->bt_duration = BT_DURATION_LIMIT_DEF;
		priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF;
	}
J
Johannes Berg 已提交
1080

1081
	ret = iwl_init_channel_map(priv);
J
Johannes Berg 已提交
1082
	if (ret) {
1083 1084
		IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
		goto err;
J
Johannes Berg 已提交
1085 1086
	}

1087 1088 1089 1090 1091
	ret = iwl_init_geos(priv);
	if (ret) {
		IWL_ERR(priv, "initializing geos failed: %d\n", ret);
		goto err_free_channel_map;
	}
1092
	iwl_init_hw_rates(priv->ieee_rates);
J
Johannes Berg 已提交
1093

1094
	return 0;
J
Johannes Berg 已提交
1095

1096 1097 1098 1099 1100
err_free_channel_map:
	iwl_free_channel_map(priv);
err:
	return ret;
}
J
Johannes Berg 已提交
1101

1102 1103 1104 1105 1106 1107 1108 1109 1110
static void iwl_uninit_drv(struct iwl_priv *priv)
{
	iwl_free_geos(priv);
	iwl_free_channel_map(priv);
	if (priv->tx_cmd_pool)
		kmem_cache_destroy(priv->tx_cmd_pool);
	kfree(priv->scan_cmd);
	kfree(priv->beacon_cmd);
	kfree(rcu_dereference_raw(priv->noa_data));
1111
	iwl_calib_free_results(priv);
1112 1113 1114 1115
#ifdef CONFIG_IWLWIFI_DEBUGFS
	kfree(priv->wowlan_sram);
#endif
}
J
Johannes Berg 已提交
1116

1117 1118 1119
/* Size of one Rx buffer in host DRAM */
#define IWL_RX_BUF_SIZE_4K (4 * 1024)
#define IWL_RX_BUF_SIZE_8K (8 * 1024)
1120

1121
static void iwl_set_hw_params(struct iwl_priv *priv)
1122
{
1123 1124 1125 1126
	if (cfg(priv)->ht_params)
		hw_params(priv).use_rts_for_aggregation =
			cfg(priv)->ht_params->use_rts_for_aggregation;

D
Don Fry 已提交
1127
	if (iwlagn_mod_params.amsdu_size_8K)
1128 1129
		hw_params(priv).rx_page_order =
			get_order(IWL_RX_BUF_SIZE_8K);
1130
	else
1131 1132
		hw_params(priv).rx_page_order =
			get_order(IWL_RX_BUF_SIZE_4K);
1133

J
Johannes Berg 已提交
1134
	if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
J
Johannes Berg 已提交
1135
		hw_params(priv).sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
1136

1137
	hw_params(priv).num_ampdu_queues =
1138 1139
		cfg(priv)->base_params->num_of_ampdu_queues;
	hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout;
1140

1141
	/* Device-specific setup */
1142
	cfg(priv)->lib->set_hw_params(priv);
1143 1144
}

1145 1146


1147 1148
static void iwl_debug_config(struct iwl_priv *priv)
{
1149
	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUG "
1150 1151 1152 1153 1154
#ifdef CONFIG_IWLWIFI_DEBUG
		"enabled\n");
#else
		"disabled\n");
#endif
1155
	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS "
1156 1157 1158 1159 1160
#ifdef CONFIG_IWLWIFI_DEBUGFS
		"enabled\n");
#else
		"disabled\n");
#endif
1161
	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING "
1162 1163 1164 1165 1166 1167
#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
		"enabled\n");
#else
		"disabled\n");
#endif

1168
	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE "
1169
#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
1170 1171 1172
		"enabled\n");
#else
		"disabled\n");
1173
#endif
1174
	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_P2P "
1175 1176 1177 1178
#ifdef CONFIG_IWLWIFI_P2P
		"enabled\n");
#else
		"disabled\n");
1179 1180 1181
#endif
}

1182 1183
static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
						 const struct iwl_fw *fw)
1184 1185 1186 1187
{
	int err = 0;
	struct iwl_priv *priv;
	struct ieee80211_hw *hw;
1188
	struct iwl_op_mode *op_mode;
1189
	u16 num_mac;
1190
	u32 ucode_flags;
1191 1192 1193 1194

	/************************
	 * 1. Allocating HW data
	 ************************/
D
Don Fry 已提交
1195
	hw = iwl_alloc_all();
1196
	if (!hw) {
1197 1198
		pr_err("%s: Cannot allocate network device\n",
				cfg(trans)->name);
1199
		err = -ENOMEM;
1200 1201 1202
		goto out;
	}

1203 1204 1205 1206
	op_mode = hw->priv;
	op_mode->ops = &iwl_dvm_ops;
	priv = IWL_OP_MODE_GET_DVM(op_mode);
	priv->shrd = trans->shrd;
1207 1208 1209
	priv->fw = fw;
	/* TODO: remove fw from shared data later */
	priv->shrd->fw = fw;
1210

1211 1212
	iwl_trans_configure(trans(priv), op_mode);

1213
	/* At this point both hw and priv are allocated. */
1214

1215
	SET_IEEE80211_DEV(priv->hw, trans(priv)->dev);
Z
Zhu Yi 已提交
1216

D
Don Fry 已提交
1217
	/* show what debugging capabilities we have */
1218 1219
	iwl_debug_config(priv);

1220
	IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
1221

1222 1223
	/* is antenna coupling more than 35dB ? */
	priv->bt_ant_couple_ok =
1224 1225 1226
		(iwlagn_mod_params.ant_coupling >
			IWL_BT_ANTENNA_COUPLING_THRESHOLD) ?
			true : false;
1227

1228
	/* enable/disable bt channel inhibition */
1229
	priv->bt_ch_announce = iwlagn_mod_params.bt_ch_announce;
1230 1231
	IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n",
		       (priv->bt_ch_announce) ? "On" : "Off");
1232

1233 1234
	if (iwl_alloc_traffic_mem(priv))
		IWL_ERR(priv, "Not enough memory to generate traffic log\n");
Z
Zhu Yi 已提交
1235

1236
	/* these spin locks will be used in apm_ops.init and EEPROM access
M
Mohamed Abbas 已提交
1237 1238
	 * we should init now
	 */
1239
	spin_lock_init(&trans(priv)->reg_lock);
1240
	spin_lock_init(&priv->statistics.lock);
1241

1242 1243 1244
	/***********************
	 * 3. Read REV register
	 ***********************/
1245
	IWL_INFO(priv, "Detected %s, REV=0x%X\n",
1246
		cfg(priv)->name, trans(priv)->hw_rev);
1247

1248
	err = iwl_trans_start_hw(trans(priv));
1249
	if (err)
1250
		goto out_free_traffic_mem;
1251

T
Tomas Winkler 已提交
1252 1253 1254
	/*****************
	 * 4. Read EEPROM
	 *****************/
1255
	/* Read the EEPROM */
1256
	err = iwl_eeprom_init(trans(priv), trans(priv)->hw_rev);
1257
	/* Reset chip to save power until we load uCode during "up". */
1258
	iwl_trans_stop_hw(trans(priv));
1259
	if (err) {
1260
		IWL_ERR(priv, "Unable to init EEPROM\n");
1261
		goto out_free_traffic_mem;
1262
	}
1263 1264
	err = iwl_eeprom_check_version(priv);
	if (err)
1265
		goto out_free_eeprom;
1266

J
Johannes Berg 已提交
1267
	err = iwl_eeprom_init_hw_params(priv);
1268 1269 1270
	if (err)
		goto out_free_eeprom;

1271
	/* extract MAC Address */
1272
	iwl_eeprom_get_mac(priv->shrd, priv->addresses[0].addr);
1273 1274 1275
	IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr);
	priv->hw->wiphy->addresses = priv->addresses;
	priv->hw->wiphy->n_addresses = 1;
1276
	num_mac = iwl_eeprom_query16(priv->shrd, EEPROM_NUM_MAC_ADDRESS);
1277 1278 1279 1280 1281 1282
	if (num_mac > 1) {
		memcpy(priv->addresses[1].addr, priv->addresses[0].addr,
		       ETH_ALEN);
		priv->addresses[1].addr[5]++;
		priv->hw->wiphy->n_addresses++;
	}
1283 1284 1285 1286

	/************************
	 * 5. Setup HW constants
	 ************************/
1287
	iwl_set_hw_params(priv);
1288

1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304
	ucode_flags = fw->ucode_capa.flags;

#ifndef CONFIG_IWLWIFI_P2P
	ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
#endif
	if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE))
		ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN;

	/*
	 * if not PAN, then don't support P2P -- might be a uCode
	 * packaging bug or due to the eeprom check above
	 */
	if (!(ucode_flags & IWL_UCODE_TLV_FLAGS_PAN))
		ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P;


1305
	/*******************
T
Tomas Winkler 已提交
1306
	 * 6. Setup priv
1307
	 *******************/
Z
Zhu Yi 已提交
1308

T
Tomas Winkler 已提交
1309
	err = iwl_init_drv(priv);
1310
	if (err)
R
Ron Rindjunsky 已提交
1311
		goto out_free_eeprom;
1312
	/* At this point both hw and priv are initialized. */
1313 1314

	/********************
1315
	 * 7. Setup services
1316
	 ********************/
1317
	iwl_setup_deferred_work(priv);
1318
	iwl_setup_rx_handlers(priv);
1319
	iwl_testmode_init(priv);
1320

1321
	iwl_power_initialize(priv);
1322
	iwl_tt_initialize(priv);
J
Johannes Berg 已提交
1323

1324 1325 1326 1327 1328
	snprintf(priv->hw->wiphy->fw_version,
		 sizeof(priv->hw->wiphy->fw_version),
		 "%s", fw->fw_version);

	priv->new_scan_threshold_behaviour =
1329
		!!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
1330

1331
	if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) {
1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344
		priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
		priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
	} else {
		priv->sta_key_max_num = STA_KEY_MAX_NUM;
		priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
	}

	priv->phy_calib_chain_noise_reset_cmd =
		fw->ucode_capa.standard_phy_calibration_size;
	priv->phy_calib_chain_noise_gain_cmd =
		fw->ucode_capa.standard_phy_calibration_size + 1;

	/* initialize all valid contexts */
1345
	iwl_init_context(priv, ucode_flags);
1346 1347 1348 1349 1350 1351 1352

	/**************************************************
	 * This is still part of probe() in a sense...
	 *
	 * 9. Setup and register with mac80211 and debugfs
	 **************************************************/
	err = iwlagn_mac_setup_register(priv, &fw->ucode_capa);
J
Johannes Berg 已提交
1353
	if (err)
1354
		goto out_destroy_workqueue;
J
Johannes Berg 已提交
1355

1356 1357 1358 1359 1360 1361
	err = iwl_dbgfs_register(priv, DRV_NAME);
	if (err)
		IWL_ERR(priv,
			"failed to create debugfs files. Ignoring error: %d\n",
			err);

1362
	return op_mode;
Z
Zhu Yi 已提交
1363

1364
out_destroy_workqueue:
J
Johannes Berg 已提交
1365 1366
	destroy_workqueue(priv->workqueue);
	priv->workqueue = NULL;
T
Tomas Winkler 已提交
1367
	iwl_uninit_drv(priv);
1368
out_free_eeprom:
1369
	iwl_eeprom_free(priv->shrd);
1370
out_free_traffic_mem:
1371
	iwl_free_traffic_mem(priv);
1372
	ieee80211_free_hw(priv->hw);
1373
out:
1374 1375
	op_mode = NULL;
	return op_mode;
Z
Zhu Yi 已提交
1376 1377
}

1378
static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
Z
Zhu Yi 已提交
1379
{
1380 1381
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

1382
	IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
Z
Zhu Yi 已提交
1383

1384 1385
	iwl_dbgfs_unregister(priv);

W
Wey-Yi Guy 已提交
1386
	iwl_testmode_cleanup(priv);
1387
	iwlagn_mac_unregister(priv);
1388

1389 1390
	iwl_tt_exit(priv);

1391 1392
	/*This will stop the queues, move the device to low power state */
	iwl_trans_stop_device(trans(priv));
1393

1394
	iwl_eeprom_free(priv->shrd);
Z
Zhu Yi 已提交
1395

M
Mohamed Abbas 已提交
1396
	/*netif_stop_queue(dev); */
J
Johannes Berg 已提交
1397
	flush_workqueue(priv->workqueue);
M
Mohamed Abbas 已提交
1398

1399
	/* ieee80211_unregister_hw calls iwlagn_mac_stop, which flushes
J
Johannes Berg 已提交
1400
	 * priv->workqueue... so we can't take down the workqueue
Z
Zhu Yi 已提交
1401
	 * until now... */
J
Johannes Berg 已提交
1402 1403
	destroy_workqueue(priv->workqueue);
	priv->workqueue = NULL;
1404
	iwl_free_traffic_mem(priv);
Z
Zhu Yi 已提交
1405

T
Tomas Winkler 已提交
1406
	iwl_uninit_drv(priv);
Z
Zhu Yi 已提交
1407

1408
	dev_kfree_skb(priv->beacon_skb);
Z
Zhu Yi 已提交
1409 1410 1411 1412

	ieee80211_free_hw(priv->hw);
}

1413 1414 1415 1416 1417 1418 1419 1420 1421 1422
static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode)
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

	if (!iwl_check_for_ct_kill(priv)) {
		IWL_ERR(priv, "Restarting adapter queue is full\n");
		iwl_nic_error(op_mode);
	}
}

J
Johannes Berg 已提交
1423 1424 1425 1426 1427 1428 1429
static void iwl_nic_config(struct iwl_op_mode *op_mode)
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

	cfg(priv)->lib->nic_config(priv);
}

1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462
static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac)
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

	set_bit(ac, &priv->transport_queue_stop);
	ieee80211_stop_queue(priv->hw, ac);
}

static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac)
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

	clear_bit(ac, &priv->transport_queue_stop);

	if (!priv->passive_no_rx)
		ieee80211_wake_queue(priv->hw, ac);
}

void iwlagn_lift_passive_no_rx(struct iwl_priv *priv)
{
	int ac;

	if (!priv->passive_no_rx)
		return;

	for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++) {
		if (!test_bit(ac, &priv->transport_queue_stop))
			ieee80211_wake_queue(priv->hw, ac);
	}

	priv->passive_no_rx = false;
}

1463 1464 1465
const struct iwl_op_mode_ops iwl_dvm_ops = {
	.start = iwl_op_mode_dvm_start,
	.stop = iwl_op_mode_dvm_stop,
1466
	.rx = iwl_rx_dispatch,
1467 1468
	.queue_full = iwl_stop_sw_queue,
	.queue_not_full = iwl_wake_sw_queue,
1469
	.hw_rf_kill = iwl_set_hw_rfkill_state,
1470
	.free_skb = iwl_free_skb,
1471
	.nic_error = iwl_nic_error,
1472
	.cmd_queue_full = iwl_cmd_queue_full,
J
Johannes Berg 已提交
1473
	.nic_config = iwl_nic_config,
1474
};
Z
Zhu Yi 已提交
1475 1476 1477 1478 1479 1480

/*****************************************************************************
 *
 * driver and module entry point
 *
 *****************************************************************************/
1481
static int __init iwl_init(void)
Z
Zhu Yi 已提交
1482 1483 1484
{

	int ret;
1485 1486
	pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
	pr_info(DRV_COPYRIGHT "\n");
1487

1488
	ret = iwlagn_rate_control_register();
1489
	if (ret) {
1490
		pr_err("Unable to register rate control algorithm: %d\n", ret);
1491 1492 1493
		return ret;
	}

1494
	ret = iwl_pci_register_driver();
Z
Zhu Yi 已提交
1495

1496 1497
	if (ret)
		goto error_register;
Z
Zhu Yi 已提交
1498
	return ret;
1499 1500

error_register:
1501
	iwlagn_rate_control_unregister();
1502
	return ret;
Z
Zhu Yi 已提交
1503 1504
}

1505
static void __exit iwl_exit(void)
Z
Zhu Yi 已提交
1506
{
1507
	iwl_pci_unregister_driver();
1508
	iwlagn_rate_control_unregister();
Z
Zhu Yi 已提交
1509 1510
}

1511 1512
module_exit(iwl_exit);
module_init(iwl_init);
1513 1514

#ifdef CONFIG_IWLWIFI_DEBUG
1515 1516
module_param_named(debug, iwlagn_mod_params.debug_level, uint,
		   S_IRUGO | S_IWUSR);
1517 1518 1519
MODULE_PARM_DESC(debug, "debug output mask");
#endif

1520 1521
module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO);
MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
J
Johannes Berg 已提交
1522 1523 1524
module_param_named(11n_disable, iwlagn_mod_params.disable_11n, uint, S_IRUGO);
MODULE_PARM_DESC(11n_disable,
	"disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX");
1525 1526 1527 1528 1529
module_param_named(amsdu_size_8K, iwlagn_mod_params.amsdu_size_8K,
		   int, S_IRUGO);
MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO);
MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
1530

1531 1532 1533
module_param_named(ucode_alternative,
		   iwlagn_mod_params.wanted_ucode_alternative,
		   int, S_IRUGO);
1534 1535
MODULE_PARM_DESC(ucode_alternative,
		 "specify ucode alternative to use from ucode file");
1536

1537 1538
module_param_named(antenna_coupling, iwlagn_mod_params.ant_coupling,
		   int, S_IRUGO);
1539 1540
MODULE_PARM_DESC(antenna_coupling,
		 "specify antenna coupling in dB (defualt: 0 dB)");
1541

1542 1543
module_param_named(bt_ch_inhibition, iwlagn_mod_params.bt_ch_announce,
		   bool, S_IRUGO);
1544
MODULE_PARM_DESC(bt_ch_inhibition,
1545
		 "Enable BT channel inhibition (default: enable)");
1546 1547 1548 1549 1550 1551

module_param_named(plcp_check, iwlagn_mod_params.plcp_check, bool, S_IRUGO);
MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])");

module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO);
MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])");
1552

1553
module_param_named(wd_disable, iwlagn_mod_params.wd_disable, int, S_IRUGO);
1554
MODULE_PARM_DESC(wd_disable,
1555 1556
		"Disable stuck queue watchdog timer 0=system default, "
		"1=disable, 2=enable (default: 0)");
1557

1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576
/*
 * 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)
 */
module_param_named(bt_coex_active, iwlagn_mod_params.bt_coex_active,
		bool, S_IRUGO);
MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)");
1577 1578 1579

module_param_named(led_mode, iwlagn_mod_params.led_mode, int, S_IRUGO);
MODULE_PARM_DESC(led_mode, "0=system default, "
W
Wey-Yi Guy 已提交
1580
		"1=On(RF On)/Off(RF Off), 2=blinking, 3=Off (default: 0)");
1581

1582 1583 1584 1585 1586
module_param_named(power_save, iwlagn_mod_params.power_save,
		bool, S_IRUGO);
MODULE_PARM_DESC(power_save,
		 "enable WiFi power management (default: disable)");

1587 1588 1589 1590 1591
module_param_named(power_level, iwlagn_mod_params.power_level,
		int, S_IRUGO);
MODULE_PARM_DESC(power_level,
		 "default power save level (range from 1 - 5, default: 1)");

1592 1593 1594 1595 1596
module_param_named(auto_agg, iwlagn_mod_params.auto_agg,
		bool, S_IRUGO);
MODULE_PARM_DESC(auto_agg,
		 "enable agg w/o check traffic load (default: enable)");

1597 1598 1599 1600 1601 1602 1603 1604 1605
/*
 * For now, keep using power level 1 instead of automatically
 * adjusting ...
 */
module_param_named(no_sleep_autoadjust, iwlagn_mod_params.no_sleep_autoadjust,
		bool, S_IRUGO);
MODULE_PARM_DESC(no_sleep_autoadjust,
		 "don't automatically adjust sleep level "
		 "according to maximum network latency (default: true)");