iwl-agn.c 49.2 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);

D
Don Fry 已提交
247
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
248 249 250
		return;

	/* dont send host command if rf-kill is on */
D
Don Fry 已提交
251
	if (!iwl_is_ready_rf(priv))
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

D
Don Fry 已提交
264
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
265
		goto out;
266 267

	/* dont send host command if rf-kill is on */
D
Don Fry 已提交
268
	if (!iwl_is_ready_rf(priv))
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;

D
Don Fry 已提交
303
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
304 305
		return;

306
	/* dont send host command if rf-kill is on */
D
Don Fry 已提交
307
	if (!iwl_is_ready_rf(priv))
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

J
Johannes Berg 已提交
338 339 340 341 342 343 344 345 346
	/*
	 * 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;

347 348 349 350 351
	/*
	 * "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++) {
352 353
		ev = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
		time = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
354
		if (mode == 0) {
355 356
			trace_iwlwifi_dev_ucode_cont_event(
					trans(priv)->dev, 0, time, ev);
357
		} else {
358
			data = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
359 360
			trace_iwlwifi_dev_ucode_cont_event(
					trans(priv)->dev, time, data, ev);
361 362 363
		}
	}
	/* Allow device to power down */
364 365
	iwl_release_nic_access(trans(priv));
	spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags);
366 367
}

J
Johannes Berg 已提交
368
static void iwl_continuous_event_trace(struct iwl_priv *priv)
369 370
{
	u32 capacity;   /* event log capacity in # entries */
J
Johannes Berg 已提交
371 372 373 374 375 376
	struct {
		u32 capacity;
		u32 mode;
		u32 wrap_counter;
		u32 write_counter;
	} __packed read;
377 378 379 380 381
	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 已提交
382
	base = priv->shrd->device_pointers.log_event_table;
383
	if (iwlagn_hw_valid_rtc_data_addr(base)) {
384
		iwl_read_targ_mem_words(trans(priv), base, &read, sizeof(read));
J
Johannes Berg 已提交
385 386 387 388 389

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

J
Johannes Berg 已提交
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
	/*
	 * 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++;

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

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

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

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

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

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

448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
	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;

D
Don Fry 已提交
464
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
465 466 467 468 469 470 471 472 473 474
		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));
	}
}

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

D
Don Fry 已提交
480
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
481 482 483
		return;

	/* do nothing if rf-kill is on */
D
Don Fry 已提交
484
	if (!iwl_is_ready_rf(priv))
485 486
		return;

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

491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
/*
 * queue/FIFO/AC mapping definitions
 */

#define IWL_TX_FIFO_BK		0	/* shared */
#define IWL_TX_FIFO_BE		1
#define IWL_TX_FIFO_VI		2	/* shared */
#define IWL_TX_FIFO_VO		3
#define IWL_TX_FIFO_BK_IPAN	IWL_TX_FIFO_BK
#define IWL_TX_FIFO_BE_IPAN	4
#define IWL_TX_FIFO_VI_IPAN	IWL_TX_FIFO_VI
#define IWL_TX_FIFO_VO_IPAN	5
/* re-uses the VO FIFO, uCode will properly flush/schedule */
#define IWL_TX_FIFO_AUX		5
#define IWL_TX_FIFO_UNUSED	-1

#define IWLAGN_CMD_FIFO_NUM	7

/*
 * This queue number is required for proper operation
 * because the ucode will stop/start the scheduler as
 * required.
 */
#define IWL_IPAN_MCAST_QUEUE	8

static const u8 iwlagn_default_queue_to_tx_fifo[] = {
	IWL_TX_FIFO_VO,
	IWL_TX_FIFO_VI,
	IWL_TX_FIFO_BE,
	IWL_TX_FIFO_BK,
	IWLAGN_CMD_FIFO_NUM,
};

static const u8 iwlagn_ipan_queue_to_tx_fifo[] = {
	IWL_TX_FIFO_VO,
	IWL_TX_FIFO_VI,
	IWL_TX_FIFO_BE,
	IWL_TX_FIFO_BK,
	IWL_TX_FIFO_BK_IPAN,
	IWL_TX_FIFO_BE_IPAN,
	IWL_TX_FIFO_VI_IPAN,
	IWL_TX_FIFO_VO_IPAN,
	IWL_TX_FIFO_BE_IPAN,
	IWLAGN_CMD_FIFO_NUM,
	IWL_TX_FIFO_AUX,
};

static const u8 iwlagn_bss_ac_to_fifo[] = {
	IWL_TX_FIFO_VO,
	IWL_TX_FIFO_VI,
	IWL_TX_FIFO_BE,
	IWL_TX_FIFO_BK,
};

static const u8 iwlagn_bss_ac_to_queue[] = {
	0, 1, 2, 3,
};

static const u8 iwlagn_pan_ac_to_fifo[] = {
	IWL_TX_FIFO_VO_IPAN,
	IWL_TX_FIFO_VI_IPAN,
	IWL_TX_FIFO_BE_IPAN,
	IWL_TX_FIFO_BK_IPAN,
};

static const u8 iwlagn_pan_ac_to_queue[] = {
	7, 6, 5, 4,
};

static const u8 iwlagn_bss_queue_to_ac[] = {
	IEEE80211_AC_VO,
	IEEE80211_AC_VI,
	IEEE80211_AC_BE,
	IEEE80211_AC_BK,
};

static const u8 iwlagn_pan_queue_to_ac[] = {
	IEEE80211_AC_VO,
	IEEE80211_AC_VI,
	IEEE80211_AC_BE,
	IEEE80211_AC_BK,
	IEEE80211_AC_BK,
	IEEE80211_AC_BE,
	IEEE80211_AC_VI,
	IEEE80211_AC_VO,
};

578
static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
579 580 581 582 583 584 585
{
	int i;

	/*
	 * The default context is always valid,
	 * the PAN context depends on uCode.
	 */
586
	priv->shrd->valid_contexts = BIT(IWL_RXON_CTX_BSS);
587
	if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN)
588
		priv->shrd->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
589 590 591 592 593 594 595 596 597 598 599 600

	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;
601
	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
602 603 604 605 606 607 608 609
	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;
610 611 612 613
	memcpy(priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue,
	       iwlagn_bss_ac_to_queue, sizeof(iwlagn_bss_ac_to_queue));
	memcpy(priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo,
	       iwlagn_bss_ac_to_fifo, sizeof(iwlagn_bss_ac_to_fifo));
614 615 616 617 618 619 620 621 622 623 624 625 626

	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);
627 628 629 630 631 632

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

633 634 635
	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;
636 637 638 639 640
	memcpy(priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue,
	       iwlagn_pan_ac_to_queue, sizeof(iwlagn_pan_ac_to_queue));
	memcpy(priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo,
	       iwlagn_pan_ac_to_fifo, sizeof(iwlagn_pan_ac_to_fifo));
	priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE;
641 642 643 644

	BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
}

645 646 647 648 649 650
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;

651
	iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR,
652
		    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
J
Johannes Berg 已提交
653

654 655
	priv->thermal_throttle.ct_kill_toggle = false;

656
	if (cfg(priv)->base_params->support_ct_kill_exit) {
657
		adv_cmd.critical_temperature_enter =
658
			cpu_to_le32(hw_params(priv).ct_kill_threshold);
659
		adv_cmd.critical_temperature_exit =
660
			cpu_to_le32(hw_params(priv).ct_kill_exit_threshold);
661

662
		ret = iwl_dvm_send_cmd_pdu(priv,
663 664
				       REPLY_CT_KILL_CONFIG_CMD,
				       CMD_SYNC, sizeof(adv_cmd), &adv_cmd);
665 666 667 668
		if (ret)
			IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
		else
			IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
669 670 671 672
				"succeeded, critical temperature enter is %d,"
				"exit is %d\n",
				hw_params(priv).ct_kill_threshold,
				hw_params(priv).ct_kill_exit_threshold);
673 674
	} else {
		cmd.critical_temperature_R =
675
			cpu_to_le32(hw_params(priv).ct_kill_threshold);
676

677
		ret = iwl_dvm_send_cmd_pdu(priv,
678 679
				       REPLY_CT_KILL_CONFIG_CMD,
				       CMD_SYNC, sizeof(cmd), &cmd);
680 681 682 683
		if (ret)
			IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
		else
			IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
684 685 686
				"succeeded, "
				"critical temperature is %d\n",
				hw_params(priv).ct_kill_threshold);
687 688 689
	}
}

690 691 692 693 694
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,
695 696
		.len = { sizeof(struct iwl_calib_cfg_cmd), },
		.data = { &calib_cfg_cmd, },
697 698 699
	};

	memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
700
	calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_RT_CFG_ALL;
701
	calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg);
702

703
	return iwl_dvm_send_cmd(priv, &cmd);
704 705 706
}


W
Wey-Yi Guy 已提交
707 708 709 710 711 712
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),
	};

713
	if (IWL_UCODE_API(priv->fw->ucode_ver) > 1) {
W
Wey-Yi Guy 已提交
714
		IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
715
		return iwl_dvm_send_cmd_pdu(priv,
W
Wey-Yi Guy 已提交
716 717 718 719 720 721 722 723 724 725
					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 已提交
726
/**
727
 * iwl_alive_start - called after REPLY_ALIVE notification received
Z
Zhu Yi 已提交
728
 *                   from protocol/runtime uCode (initialization uCode's
729
 *                   Alive gets handled by iwl_init_alive_start()).
Z
Zhu Yi 已提交
730
 */
731
int iwl_alive_start(struct iwl_priv *priv)
Z
Zhu Yi 已提交
732
{
733
	int ret = 0;
734
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
Z
Zhu Yi 已提交
735

736
	IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
737

738
	/* After the ALIVE response, we can send host commands to the uCode */
D
Don Fry 已提交
739
	set_bit(STATUS_ALIVE, &priv->status);
Z
Zhu Yi 已提交
740

741 742
	/* Enable watchdog to monitor the driver tx queues */
	iwl_setup_watchdog(priv);
743

D
Don Fry 已提交
744
	if (iwl_is_rfkill(priv))
745
		return -ERFKILL;
Z
Zhu Yi 已提交
746

J
Johannes Berg 已提交
747 748 749 750 751
	if (priv->event_log.ucode_trace) {
		/* start collecting data now */
		mod_timer(&priv->ucode_trace, jiffies);
	}

752
	/* download priority table before any calibration request */
753 754
	if (cfg(priv)->bt_params &&
	    cfg(priv)->bt_params->advanced_bt_coexist) {
755
		/* Configure Bluetooth device coexistence support */
756
		if (cfg(priv)->bt_params->bt_sco_disable)
757 758 759 760
			priv->bt_enable_pspoll = false;
		else
			priv->bt_enable_pspoll = true;

761 762 763
		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 已提交
764
		iwlagn_send_advance_bt_config(priv);
765
		priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
766 767
		priv->cur_rssi_ctx = NULL;

768
		iwl_send_prio_tbl(priv);
769 770

		/* FIXME: w/a to force change uCode BT state machine */
771
		ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
772 773 774
					 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
		if (ret)
			return ret;
775
		ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
776 777 778
					 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
		if (ret)
			return ret;
W
Wey-Yi Guy 已提交
779 780 781 782 783
	} else {
		/*
		 * default is 2-wire BT coexexistence support
		 */
		iwl_send_bt_config(priv);
784
	}
W
Wey-Yi Guy 已提交
785

786 787 788 789
	/*
	 * Perform runtime calibrations, including DC calibration.
	 */
	iwlagn_send_calib_cfg_rt(priv, IWL_CALIB_CFG_DC_IDX);
790

791
	ieee80211_wake_queues(priv->hw);
Z
Zhu Yi 已提交
792

793
	priv->active_rate = IWL_RATES_MASK;
Z
Zhu Yi 已提交
794

795
	/* Configure Tx antenna selection based on H/W config */
796
	iwlagn_send_tx_ant_config(priv, hw_params(priv).valid_tx_ant);
797

798
	if (iwl_is_associated_ctx(ctx) && !priv->wowlan) {
G
Gregory Greenman 已提交
799
		struct iwl_rxon_cmd *active_rxon =
800
				(struct iwl_rxon_cmd *)&ctx->active;
801
		/* apply any changes in staging */
802
		ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
Z
Zhu Yi 已提交
803 804
		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
	} else {
805
		struct iwl_rxon_context *tmp;
Z
Zhu Yi 已提交
806
		/* Initialize our rx_config data */
807 808
		for_each_context(priv, tmp)
			iwl_connection_init_rx_config(priv, tmp);
809

W
Wey-Yi Guy 已提交
810
		iwlagn_set_rxon_chain(priv, ctx);
Z
Zhu Yi 已提交
811 812
	}

813
	if (!priv->wowlan) {
J
Johannes Berg 已提交
814 815 816
		/* WoWLAN ucode will not reply in the same way, skip it */
		iwl_reset_run_time_calib(priv);
	}
817

D
Don Fry 已提交
818
	set_bit(STATUS_READY, &priv->status);
819

Z
Zhu Yi 已提交
820
	/* Configure the adapter for unassociated operation */
821
	ret = iwlagn_commit_rxon(priv, ctx);
822 823
	if (ret)
		return ret;
Z
Zhu Yi 已提交
824 825

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

828
	IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
829

830
	return iwl_power_update_mode(priv, true);
Z
Zhu Yi 已提交
831 832
}

833 834 835 836 837 838 839 840 841 842 843 844 845
/**
 * 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;

846
	spin_lock_bh(&priv->sta_lock);
847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863
	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;
	}

864
	spin_unlock_bh(&priv->sta_lock);
865 866
}

867
void iwl_down(struct iwl_priv *priv)
Z
Zhu Yi 已提交
868
{
869
	int exit_pending;
Z
Zhu Yi 已提交
870

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

873
	lockdep_assert_held(&priv->mutex);
874

875 876
	iwl_scan_cancel_timeout(priv, 200);

877 878 879 880 881 882 883
	/*
	 * 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);

884
	exit_pending =
D
Don Fry 已提交
885
		test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
Z
Zhu Yi 已提交
886

887 888
	/* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
	 * to prevent rearm timer */
889
	del_timer_sync(&priv->watchdog);
890

891
	iwl_clear_ucode_stations(priv, NULL);
892
	iwl_dealloc_bcast_stations(priv);
893
	iwl_clear_driver_stations(priv);
Z
Zhu Yi 已提交
894

895
	/* reset BT coex data */
896
	priv->bt_status = 0;
897 898
	priv->cur_rssi_ctx = NULL;
	priv->bt_is_sco = 0;
899
	if (cfg(priv)->bt_params)
900
		priv->bt_traffic_load =
901
			 cfg(priv)->bt_params->bt_init_traffic_load;
902 903
	else
		priv->bt_traffic_load = 0;
904 905
	priv->bt_full_concurrent = false;
	priv->bt_ci_compliance = 0;
906

Z
Zhu Yi 已提交
907 908 909
	/* Wipe out the EXIT_PENDING status bit if we are not actually
	 * exiting the module */
	if (!exit_pending)
D
Don Fry 已提交
910
		clear_bit(STATUS_EXIT_PENDING, &priv->status);
Z
Zhu Yi 已提交
911

912
	if (priv->mac80211_registered)
Z
Zhu Yi 已提交
913 914
		ieee80211_stop_queues(priv->hw);

915
	priv->ucode_loaded = false;
916 917
	iwl_trans_stop_device(trans(priv));

J
Johannes Berg 已提交
918
	/* Clear out all status bits but a few that are stable across reset */
919
	priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
Z
Zhu Yi 已提交
920
				STATUS_RF_KILL_HW |
D
Don Fry 已提交
921
			test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
922
				STATUS_GEO_CONFIGURED |
D
Don Fry 已提交
923
			test_bit(STATUS_EXIT_PENDING, &priv->status) <<
924
				STATUS_EXIT_PENDING;
925 926 927
	priv->shrd->status &=
			test_bit(STATUS_FW_ERROR, &priv->shrd->status) <<
				STATUS_FW_ERROR;
Z
Zhu Yi 已提交
928

929
	dev_kfree_skb(priv->beacon_skb);
930
	priv->beacon_skb = NULL;
Z
Zhu Yi 已提交
931 932 933 934 935 936 937 938
}

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

939 940 941 942 943
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);

944
	mutex_lock(&priv->mutex);
945

D
Don Fry 已提交
946 947
	if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
	    test_bit(STATUS_SCANNING, &priv->status)) {
948
		mutex_unlock(&priv->mutex);
949 950 951 952
		return;
	}

	if (priv->start_calib) {
953 954
		iwl_chain_noise_calibration(priv);
		iwl_sensitivity_calibration(priv);
955 956
	}

957
	mutex_unlock(&priv->mutex);
958 959
}

960
void iwlagn_prepare_restart(struct iwl_priv *priv)
J
Johannes Berg 已提交
961 962 963 964 965 966
{
	struct iwl_rxon_context *ctx;
	bool bt_full_concurrent;
	u8 bt_ci_compliance;
	u8 bt_load;
	u8 bt_status;
967
	bool bt_is_sco;
968
	int i;
J
Johannes Berg 已提交
969

970
	lockdep_assert_held(&priv->mutex);
J
Johannes Berg 已提交
971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988

	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;
989
	bt_is_sco = priv->bt_is_sco;
J
Johannes Berg 已提交
990

991
	iwl_down(priv);
J
Johannes Berg 已提交
992 993 994 995 996

	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;
997
	priv->bt_is_sco = bt_is_sco;
998 999 1000 1001 1002 1003 1004 1005 1006

	/* reset all queues */
	for (i = 0; i < IEEE80211_NUM_ACS; i++)
		atomic_set(&priv->ac_stop_count[i], 0);

	for (i = IWLAGN_FIRST_AMPDU_QUEUE; i < IWL_MAX_HW_QUEUES; i++)
		priv->queue_to_ac[i] = IWL_INVALID_AC;

	memset(priv->agg_q_alloc, 0, sizeof(priv->agg_q_alloc));
J
Johannes Berg 已提交
1007 1008
}

1009
static void iwl_bg_restart(struct work_struct *data)
Z
Zhu Yi 已提交
1010
{
1011
	struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
Z
Zhu Yi 已提交
1012

D
Don Fry 已提交
1013
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
Z
Zhu Yi 已提交
1014 1015
		return;

1016
	if (test_and_clear_bit(STATUS_FW_ERROR, &priv->shrd->status)) {
1017
		mutex_lock(&priv->mutex);
J
Johannes Berg 已提交
1018
		iwlagn_prepare_restart(priv);
1019
		mutex_unlock(&priv->mutex);
1020
		iwl_cancel_deferred_work(priv);
J
Johannes Berg 已提交
1021 1022
		ieee80211_restart_hw(priv->hw);
	} else {
1023
		WARN_ON(1);
J
Johannes Berg 已提交
1024
	}
Z
Zhu Yi 已提交
1025 1026
}

1027 1028 1029



1030
void iwlagn_disable_roc(struct iwl_priv *priv)
1031
{
1032
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
1033

1034
	lockdep_assert_held(&priv->mutex);
1035

1036 1037
	if (!priv->hw_roc_setup)
		return;
1038

1039 1040
	ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
	ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1041

1042
	priv->hw_roc_channel = NULL;
1043

1044
	memset(ctx->staging.node_addr, 0, ETH_ALEN);
1045

1046
	iwlagn_commit_rxon(priv, ctx);
1047

1048 1049
	ctx->is_active = false;
	priv->hw_roc_setup = false;
1050 1051
}

1052
static void iwlagn_disable_roc_work(struct work_struct *work)
Z
Zhu Yi 已提交
1053
{
1054 1055
	struct iwl_priv *priv = container_of(work, struct iwl_priv,
					     hw_roc_disable_work.work);
Z
Zhu Yi 已提交
1056

1057
	mutex_lock(&priv->mutex);
1058
	iwlagn_disable_roc(priv);
1059
	mutex_unlock(&priv->mutex);
Z
Zhu Yi 已提交
1060 1061
}

1062 1063 1064 1065 1066 1067 1068
/*****************************************************************************
 *
 * driver setup and teardown
 *
 *****************************************************************************/

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

1072 1073 1074 1075 1076 1077 1078 1079
	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);
1080

1081
	iwl_setup_scan_deferred_work(priv);
1082

1083 1084
	if (cfg(priv)->bt_params)
		iwlagn_bt_setup_deferred_work(priv);
1085

1086 1087 1088
	init_timer(&priv->statistics_periodic);
	priv->statistics_periodic.data = (unsigned long)priv;
	priv->statistics_periodic.function = iwl_bg_statistics_periodic;
1089

1090 1091 1092
	init_timer(&priv->ucode_trace);
	priv->ucode_trace.data = (unsigned long)priv;
	priv->ucode_trace.function = iwl_bg_ucode_trace;
M
Mohamed Abbas 已提交
1093

1094 1095 1096
	init_timer(&priv->watchdog);
	priv->watchdog.data = (unsigned long)priv;
	priv->watchdog.function = iwl_bg_watchdog;
Z
Zhu Yi 已提交
1097 1098
}

1099
void iwl_cancel_deferred_work(struct iwl_priv *priv)
J
Johannes Berg 已提交
1100
{
1101 1102
	if (cfg(priv)->bt_params)
		iwlagn_bt_cancel_deferred_work(priv);
J
Johannes Berg 已提交
1103

1104 1105
	cancel_work_sync(&priv->run_time_calib_work);
	cancel_work_sync(&priv->beacon_update);
J
Johannes Berg 已提交
1106

1107
	iwl_cancel_scan_deferred_work(priv);
J
Johannes Berg 已提交
1108

1109 1110 1111
	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 已提交
1112

1113 1114 1115
	del_timer_sync(&priv->statistics_periodic);
	del_timer_sync(&priv->ucode_trace);
}
J
Johannes Berg 已提交
1116

1117
static void iwl_init_hw_rates(struct ieee80211_rate *rates)
1118 1119
{
	int i;
J
Johannes Berg 已提交
1120

1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133
	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 已提交
1134 1135 1136
	}
}

1137
static int iwl_init_drv(struct iwl_priv *priv)
J
Johannes Berg 已提交
1138
{
1139
	int ret;
J
Johannes Berg 已提交
1140

1141
	spin_lock_init(&priv->sta_lock);
J
Johannes Berg 已提交
1142

1143
	mutex_init(&priv->mutex);
J
Johannes Berg 已提交
1144

1145
	INIT_LIST_HEAD(&priv->calib_results);
1146

1147 1148 1149
	priv->ieee_channels = NULL;
	priv->ieee_rates = NULL;
	priv->band = IEEE80211_BAND_2GHZ;
J
Johannes Berg 已提交
1150

1151 1152 1153
	priv->plcp_delta_threshold =
		cfg(priv)->base_params->plcp_delta_threshold;

1154 1155 1156 1157
	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 已提交
1158

1159 1160
	priv->ucode_owner = IWL_OWNERSHIP_DRIVER;

1161 1162 1163 1164 1165
	/* 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 已提交
1166

1167
	priv->rx_statistics_jiffies = jiffies;
J
Johannes Berg 已提交
1168

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

1172
	iwl_init_scan_params(priv);
J
Johannes Berg 已提交
1173

1174
	/* init bt coex */
1175 1176
	if (cfg(priv)->bt_params &&
	    cfg(priv)->bt_params->advanced_bt_coexist) {
1177 1178 1179 1180 1181 1182 1183
		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 已提交
1184

1185
	ret = iwl_init_channel_map(priv);
J
Johannes Berg 已提交
1186
	if (ret) {
1187 1188
		IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
		goto err;
J
Johannes Berg 已提交
1189 1190
	}

1191 1192 1193 1194 1195
	ret = iwl_init_geos(priv);
	if (ret) {
		IWL_ERR(priv, "initializing geos failed: %d\n", ret);
		goto err_free_channel_map;
	}
1196
	iwl_init_hw_rates(priv->ieee_rates);
J
Johannes Berg 已提交
1197

1198
	return 0;
J
Johannes Berg 已提交
1199

1200 1201 1202 1203 1204
err_free_channel_map:
	iwl_free_channel_map(priv);
err:
	return ret;
}
J
Johannes Berg 已提交
1205

1206 1207 1208 1209 1210 1211 1212
static void iwl_uninit_drv(struct iwl_priv *priv)
{
	iwl_free_geos(priv);
	iwl_free_channel_map(priv);
	kfree(priv->scan_cmd);
	kfree(priv->beacon_cmd);
	kfree(rcu_dereference_raw(priv->noa_data));
1213
	iwl_calib_free_results(priv);
1214 1215 1216 1217
#ifdef CONFIG_IWLWIFI_DEBUGFS
	kfree(priv->wowlan_sram);
#endif
}
J
Johannes Berg 已提交
1218

1219 1220 1221
/* Size of one Rx buffer in host DRAM */
#define IWL_RX_BUF_SIZE_4K (4 * 1024)
#define IWL_RX_BUF_SIZE_8K (8 * 1024)
1222

1223
static void iwl_set_hw_params(struct iwl_priv *priv)
1224
{
1225 1226 1227 1228
	if (cfg(priv)->ht_params)
		hw_params(priv).use_rts_for_aggregation =
			cfg(priv)->ht_params->use_rts_for_aggregation;

D
Don Fry 已提交
1229
	if (iwlagn_mod_params.amsdu_size_8K)
1230 1231
		hw_params(priv).rx_page_order =
			get_order(IWL_RX_BUF_SIZE_8K);
1232
	else
1233 1234
		hw_params(priv).rx_page_order =
			get_order(IWL_RX_BUF_SIZE_4K);
1235

J
Johannes Berg 已提交
1236
	if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
J
Johannes Berg 已提交
1237
		hw_params(priv).sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
1238

1239
	hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout;
1240

1241
	/* Device-specific setup */
1242
	cfg(priv)->lib->set_hw_params(priv);
1243 1244
}

1245 1246


1247 1248
static void iwl_debug_config(struct iwl_priv *priv)
{
1249
	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUG "
1250 1251 1252 1253 1254
#ifdef CONFIG_IWLWIFI_DEBUG
		"enabled\n");
#else
		"disabled\n");
#endif
1255
	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS "
1256 1257 1258 1259 1260
#ifdef CONFIG_IWLWIFI_DEBUGFS
		"enabled\n");
#else
		"disabled\n");
#endif
1261
	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING "
1262 1263 1264 1265 1266 1267
#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
		"enabled\n");
#else
		"disabled\n");
#endif

1268
	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE "
1269
#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
1270 1271 1272
		"enabled\n");
#else
		"disabled\n");
1273
#endif
1274
	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_P2P "
1275 1276 1277 1278
#ifdef CONFIG_IWLWIFI_P2P
		"enabled\n");
#else
		"disabled\n");
1279 1280 1281
#endif
}

1282 1283
static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
						 const struct iwl_fw *fw)
1284 1285 1286
{
	struct iwl_priv *priv;
	struct ieee80211_hw *hw;
1287
	struct iwl_op_mode *op_mode;
1288
	u16 num_mac;
1289
	u32 ucode_flags;
1290
	struct iwl_trans_config trans_cfg;
1291 1292 1293 1294 1295 1296 1297 1298
	static const u8 no_reclaim_cmds[] = {
		REPLY_RX_PHY_CMD,
		REPLY_RX,
		REPLY_RX_MPDU_CMD,
		REPLY_COMPRESSED_BA,
		STATISTICS_NOTIFICATION,
		REPLY_TX,
	};
1299 1300 1301
	const u8 *q_to_ac;
	int n_q_to_ac;
	int i;
1302 1303 1304 1305

	/************************
	 * 1. Allocating HW data
	 ************************/
D
Don Fry 已提交
1306
	hw = iwl_alloc_all();
1307
	if (!hw) {
1308 1309
		pr_err("%s: Cannot allocate network device\n",
				cfg(trans)->name);
1310 1311 1312
		goto out;
	}

1313 1314 1315 1316
	op_mode = hw->priv;
	op_mode->ops = &iwl_dvm_ops;
	priv = IWL_OP_MODE_GET_DVM(op_mode);
	priv->shrd = trans->shrd;
1317 1318 1319
	priv->fw = fw;
	/* TODO: remove fw from shared data later */
	priv->shrd->fw = fw;
1320

E
Emmanuel Grumbach 已提交
1321 1322 1323 1324 1325
	/*
	 * Populate the state variables that the transport layer needs
	 * to know about.
	 */
	trans_cfg.op_mode = op_mode;
1326 1327
	trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
	trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
1328 1329 1330 1331 1332 1333

	ucode_flags = fw->ucode_capa.flags;

#ifndef CONFIG_IWLWIFI_P2P
	ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
#endif
1334

1335 1336 1337
	if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) {
		priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
		trans_cfg.cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
1338 1339 1340 1341 1342
		trans_cfg.queue_to_fifo = iwlagn_ipan_queue_to_tx_fifo;
		trans_cfg.n_queue_to_fifo =
			ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo);
		q_to_ac = iwlagn_pan_queue_to_ac;
		n_q_to_ac = ARRAY_SIZE(iwlagn_pan_queue_to_ac);
1343 1344 1345
	} else {
		priv->sta_key_max_num = STA_KEY_MAX_NUM;
		trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
1346 1347 1348 1349 1350
		trans_cfg.queue_to_fifo = iwlagn_default_queue_to_tx_fifo;
		trans_cfg.n_queue_to_fifo =
			ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo);
		q_to_ac = iwlagn_bss_queue_to_ac;
		n_q_to_ac = ARRAY_SIZE(iwlagn_bss_queue_to_ac);
1351 1352
	}

1353 1354
	/* Configure transport layer */
	iwl_trans_configure(trans(priv), &trans_cfg);
1355

1356
	/* At this point both hw and priv are allocated. */
1357

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

D
Don Fry 已提交
1360
	/* show what debugging capabilities we have */
1361 1362
	iwl_debug_config(priv);

1363
	IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
1364

1365 1366
	/* is antenna coupling more than 35dB ? */
	priv->bt_ant_couple_ok =
1367 1368 1369
		(iwlagn_mod_params.ant_coupling >
			IWL_BT_ANTENNA_COUPLING_THRESHOLD) ?
			true : false;
1370

1371
	/* enable/disable bt channel inhibition */
1372
	priv->bt_ch_announce = iwlagn_mod_params.bt_ch_announce;
1373 1374
	IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n",
		       (priv->bt_ch_announce) ? "On" : "Off");
1375

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

1379
	/* these spin locks will be used in apm_ops.init and EEPROM access
M
Mohamed Abbas 已提交
1380 1381
	 * we should init now
	 */
1382
	spin_lock_init(&trans(priv)->reg_lock);
1383
	spin_lock_init(&priv->statistics.lock);
1384

1385
	/***********************
E
Emmanuel Grumbach 已提交
1386
	 * 2. Read REV register
1387
	 ***********************/
1388
	IWL_INFO(priv, "Detected %s, REV=0x%X\n",
1389
		cfg(priv)->name, trans(priv)->hw_rev);
1390

W
Wey-Yi Guy 已提交
1391
	if (iwl_trans_start_hw(trans(priv)))
1392
		goto out_free_traffic_mem;
1393

T
Tomas Winkler 已提交
1394
	/*****************
E
Emmanuel Grumbach 已提交
1395
	 * 3. Read EEPROM
T
Tomas Winkler 已提交
1396
	 *****************/
W
Wey-Yi Guy 已提交
1397 1398
	/* Read the EEPROM */
	if (iwl_eeprom_init(trans(priv), trans(priv)->hw_rev)) {
1399
		IWL_ERR(priv, "Unable to init EEPROM\n");
1400
		goto out_free_traffic_mem;
1401
	}
W
Wey-Yi Guy 已提交
1402 1403 1404 1405
	/* Reset chip to save power until we load uCode during "up". */
	iwl_trans_stop_hw(trans(priv));

	if (iwl_eeprom_check_version(priv))
1406
		goto out_free_eeprom;
1407

W
Wey-Yi Guy 已提交
1408
	if (iwl_eeprom_init_hw_params(priv))
1409 1410
		goto out_free_eeprom;

1411
	/* extract MAC Address */
1412
	iwl_eeprom_get_mac(priv->shrd, priv->addresses[0].addr);
1413 1414 1415
	IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr);
	priv->hw->wiphy->addresses = priv->addresses;
	priv->hw->wiphy->n_addresses = 1;
1416
	num_mac = iwl_eeprom_query16(priv->shrd, EEPROM_NUM_MAC_ADDRESS);
1417 1418 1419 1420 1421 1422
	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++;
	}
1423

E
Emmanuel Grumbach 已提交
1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438
	/************************
	 * 4. Setup HW constants
	 ************************/
	iwl_set_hw_params(priv);

	if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE)) {
		IWL_DEBUG_INFO(priv, "Your EEPROM disabled PAN");
		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
		 */
		ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
		priv->sta_key_max_num = STA_KEY_MAX_NUM;
		trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
1439 1440 1441 1442 1443
		trans_cfg.queue_to_fifo = iwlagn_default_queue_to_tx_fifo;
		trans_cfg.n_queue_to_fifo =
			ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo);
		q_to_ac = iwlagn_bss_queue_to_ac;
		n_q_to_ac = ARRAY_SIZE(iwlagn_bss_queue_to_ac);
E
Emmanuel Grumbach 已提交
1444 1445 1446 1447 1448

		/* Configure transport layer again*/
		iwl_trans_configure(trans(priv), &trans_cfg);
	}

1449
	/*******************
E
Emmanuel Grumbach 已提交
1450
	 * 5. Setup priv
1451
	 *******************/
1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463
	for (i = 0; i < IEEE80211_NUM_ACS; i++)
		atomic_set(&priv->ac_stop_count[i], 0);

	for (i = 0; i < IWL_MAX_HW_QUEUES; i++) {
		if (i < n_q_to_ac)
			priv->queue_to_ac[i] = q_to_ac[i];
		else
			priv->queue_to_ac[i] = IWL_INVALID_AC;
	}

	WARN_ON(trans_cfg.queue_to_fifo[trans_cfg.cmd_queue] !=
						IWLAGN_CMD_FIFO_NUM);
Z
Zhu Yi 已提交
1464

W
Wey-Yi Guy 已提交
1465
	if (iwl_init_drv(priv))
R
Ron Rindjunsky 已提交
1466
		goto out_free_eeprom;
W
Wey-Yi Guy 已提交
1467

1468
	/* At this point both hw and priv are initialized. */
1469 1470

	/********************
E
Emmanuel Grumbach 已提交
1471
	 * 6. Setup services
1472
	 ********************/
1473
	iwl_setup_deferred_work(priv);
1474
	iwl_setup_rx_handlers(priv);
1475
	iwl_testmode_init(priv);
1476

1477
	iwl_power_initialize(priv);
1478
	iwl_tt_initialize(priv);
J
Johannes Berg 已提交
1479

1480 1481 1482 1483 1484
	snprintf(priv->hw->wiphy->fw_version,
		 sizeof(priv->hw->wiphy->fw_version),
		 "%s", fw->fw_version);

	priv->new_scan_threshold_behaviour =
1485
		!!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
1486

1487 1488 1489 1490 1491 1492
	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 */
1493
	iwl_init_context(priv, ucode_flags);
1494 1495 1496 1497

	/**************************************************
	 * This is still part of probe() in a sense...
	 *
E
Emmanuel Grumbach 已提交
1498
	 * 7. Setup and register with mac80211 and debugfs
1499
	 **************************************************/
W
Wey-Yi Guy 已提交
1500
	if (iwlagn_mac_setup_register(priv, &fw->ucode_capa))
1501
		goto out_destroy_workqueue;
J
Johannes Berg 已提交
1502

W
Wey-Yi Guy 已提交
1503
	if (iwl_dbgfs_register(priv, DRV_NAME))
1504
		IWL_ERR(priv,
W
Wey-Yi Guy 已提交
1505
			"failed to create debugfs files. Ignoring error\n");
1506

1507
	return op_mode;
Z
Zhu Yi 已提交
1508

1509
out_destroy_workqueue:
J
Johannes Berg 已提交
1510 1511
	destroy_workqueue(priv->workqueue);
	priv->workqueue = NULL;
T
Tomas Winkler 已提交
1512
	iwl_uninit_drv(priv);
1513
out_free_eeprom:
1514
	iwl_eeprom_free(priv->shrd);
1515
out_free_traffic_mem:
1516
	iwl_free_traffic_mem(priv);
1517
	ieee80211_free_hw(priv->hw);
1518
out:
1519 1520
	op_mode = NULL;
	return op_mode;
Z
Zhu Yi 已提交
1521 1522
}

1523
static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
Z
Zhu Yi 已提交
1524
{
1525 1526
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

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

1529 1530
	iwl_dbgfs_unregister(priv);

W
Wey-Yi Guy 已提交
1531
	iwl_testmode_cleanup(priv);
1532
	iwlagn_mac_unregister(priv);
1533

1534 1535
	iwl_tt_exit(priv);

1536
	/*This will stop the queues, move the device to low power state */
1537
	priv->ucode_loaded = false;
1538
	iwl_trans_stop_device(trans(priv));
1539

1540
	iwl_eeprom_free(priv->shrd);
Z
Zhu Yi 已提交
1541

M
Mohamed Abbas 已提交
1542
	/*netif_stop_queue(dev); */
J
Johannes Berg 已提交
1543
	flush_workqueue(priv->workqueue);
M
Mohamed Abbas 已提交
1544

1545
	/* ieee80211_unregister_hw calls iwlagn_mac_stop, which flushes
J
Johannes Berg 已提交
1546
	 * priv->workqueue... so we can't take down the workqueue
Z
Zhu Yi 已提交
1547
	 * until now... */
J
Johannes Berg 已提交
1548 1549
	destroy_workqueue(priv->workqueue);
	priv->workqueue = NULL;
1550
	iwl_free_traffic_mem(priv);
Z
Zhu Yi 已提交
1551

T
Tomas Winkler 已提交
1552
	iwl_uninit_drv(priv);
Z
Zhu Yi 已提交
1553

1554
	dev_kfree_skb(priv->beacon_skb);
Z
Zhu Yi 已提交
1555 1556 1557 1558

	ieee80211_free_hw(priv->hw);
}

1559 1560 1561 1562 1563 1564 1565 1566 1567 1568
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 已提交
1569 1570 1571 1572 1573 1574 1575
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);
}

1576
static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue)
1577 1578
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589
	int ac = priv->queue_to_ac[queue];

	if (WARN_ON_ONCE(ac == IWL_INVALID_AC))
		return;

	if (atomic_inc_return(&priv->ac_stop_count[ac]) > 1) {
		IWL_DEBUG_TX_QUEUES(priv,
			"queue %d (AC %d) already stopped\n",
			queue, ac);
		return;
	}
1590 1591 1592 1593 1594

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

1595
static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue)
1596 1597
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608
	int ac = priv->queue_to_ac[queue];

	if (WARN_ON_ONCE(ac == IWL_INVALID_AC))
		return;

	if (atomic_dec_return(&priv->ac_stop_count[ac]) > 0) {
		IWL_DEBUG_TX_QUEUES(priv,
			"queue %d (AC %d) already awake\n",
			queue, ac);
		return;
	}
1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623

	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++) {
1624 1625
		if (!test_bit(ac, &priv->transport_queue_stop)) {
			IWL_DEBUG_TX_QUEUES(priv, "Wake queue %d");
1626
			ieee80211_wake_queue(priv->hw, ac);
1627 1628 1629
		} else {
			IWL_DEBUG_TX_QUEUES(priv, "Don't wake queue %d");
		}
1630 1631 1632 1633 1634
	}

	priv->passive_no_rx = false;
}

1635 1636 1637
const struct iwl_op_mode_ops iwl_dvm_ops = {
	.start = iwl_op_mode_dvm_start,
	.stop = iwl_op_mode_dvm_stop,
1638
	.rx = iwl_rx_dispatch,
1639 1640
	.queue_full = iwl_stop_sw_queue,
	.queue_not_full = iwl_wake_sw_queue,
1641
	.hw_rf_kill = iwl_set_hw_rfkill_state,
1642
	.free_skb = iwl_free_skb,
1643
	.nic_error = iwl_nic_error,
1644
	.cmd_queue_full = iwl_cmd_queue_full,
J
Johannes Berg 已提交
1645
	.nic_config = iwl_nic_config,
1646
};
Z
Zhu Yi 已提交
1647 1648 1649 1650 1651 1652

/*****************************************************************************
 *
 * driver and module entry point
 *
 *****************************************************************************/
1653 1654 1655

struct kmem_cache *iwl_tx_cmd_pool;

1656
static int __init iwl_init(void)
Z
Zhu Yi 已提交
1657 1658 1659
{

	int ret;
1660 1661
	pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
	pr_info(DRV_COPYRIGHT "\n");
1662

1663 1664 1665 1666 1667 1668
	iwl_tx_cmd_pool = kmem_cache_create("iwl_dev_cmd",
					    sizeof(struct iwl_device_cmd),
					    sizeof(void *), 0, NULL);
	if (!iwl_tx_cmd_pool)
		return -ENOMEM;

1669
	ret = iwlagn_rate_control_register();
1670
	if (ret) {
1671
		pr_err("Unable to register rate control algorithm: %d\n", ret);
1672
		goto error_rc_register;
1673 1674
	}

1675 1676
	ret = iwl_pci_register_driver();
	if (ret)
1677
		goto error_pci_register;
Z
Zhu Yi 已提交
1678
	return ret;
1679

1680
error_pci_register:
1681
	iwlagn_rate_control_unregister();
1682 1683
error_rc_register:
	kmem_cache_destroy(iwl_tx_cmd_pool);
1684
	return ret;
Z
Zhu Yi 已提交
1685 1686
}

1687
static void __exit iwl_exit(void)
Z
Zhu Yi 已提交
1688
{
1689
	iwl_pci_unregister_driver();
1690
	iwlagn_rate_control_unregister();
1691
	kmem_cache_destroy(iwl_tx_cmd_pool);
Z
Zhu Yi 已提交
1692 1693
}

1694 1695
module_exit(iwl_exit);
module_init(iwl_init);
1696 1697

#ifdef CONFIG_IWLWIFI_DEBUG
1698 1699
module_param_named(debug, iwlagn_mod_params.debug_level, uint,
		   S_IRUGO | S_IWUSR);
1700 1701 1702
MODULE_PARM_DESC(debug, "debug output mask");
#endif

1703 1704
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 已提交
1705 1706 1707
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");
1708 1709 1710 1711 1712
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");
1713

1714 1715 1716
module_param_named(ucode_alternative,
		   iwlagn_mod_params.wanted_ucode_alternative,
		   int, S_IRUGO);
1717 1718
MODULE_PARM_DESC(ucode_alternative,
		 "specify ucode alternative to use from ucode file");
1719

1720 1721
module_param_named(antenna_coupling, iwlagn_mod_params.ant_coupling,
		   int, S_IRUGO);
1722 1723
MODULE_PARM_DESC(antenna_coupling,
		 "specify antenna coupling in dB (defualt: 0 dB)");
1724

1725 1726
module_param_named(bt_ch_inhibition, iwlagn_mod_params.bt_ch_announce,
		   bool, S_IRUGO);
1727
MODULE_PARM_DESC(bt_ch_inhibition,
1728
		 "Enable BT channel inhibition (default: enable)");
1729 1730 1731 1732 1733 1734

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])");
1735

1736
module_param_named(wd_disable, iwlagn_mod_params.wd_disable, int, S_IRUGO);
1737
MODULE_PARM_DESC(wd_disable,
1738 1739
		"Disable stuck queue watchdog timer 0=system default, "
		"1=disable, 2=enable (default: 0)");
1740

1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759
/*
 * 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)");
1760 1761 1762

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 已提交
1763
		"1=On(RF On)/Off(RF Off), 2=blinking, 3=Off (default: 0)");
1764

1765 1766 1767 1768 1769
module_param_named(power_save, iwlagn_mod_params.power_save,
		bool, S_IRUGO);
MODULE_PARM_DESC(power_save,
		 "enable WiFi power management (default: disable)");

1770 1771 1772 1773 1774
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)");

1775 1776 1777 1778 1779
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)");

1780 1781 1782 1783 1784 1785 1786 1787 1788
/*
 * 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)");