main.c 60.1 KB
Newer Older
Z
Zhu Yi 已提交
1 2
/******************************************************************************
 *
J
Johannes Berg 已提交
3
 * Copyright(c) 2003 - 2013 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
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 *****************************************************************************/
J
Joe Perches 已提交
29 30 31

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

Z
Zhu Yi 已提交
32 33 34
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
35
#include <linux/slab.h>
Z
Zhu Yi 已提交
36
#include <linux/delay.h>
37
#include <linux/sched.h>
Z
Zhu Yi 已提交
38 39 40 41 42 43 44 45 46
#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>

47 48
#include "iwl-eeprom-read.h"
#include "iwl-eeprom-parse.h"
49
#include "iwl-io.h"
50
#include "iwl-trans.h"
51
#include "iwl-op-mode.h"
52
#include "iwl-drv.h"
53
#include "iwl-modparams.h"
54
#include "iwl-prph.h"
55

56 57 58 59
#include "dev.h"
#include "calib.h"
#include "agn.h"

60

Z
Zhu Yi 已提交
61 62 63 64 65 66 67 68 69
/******************************************************************************
 *
 * module boiler plate
 *
 ******************************************************************************/

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

72
#ifdef CONFIG_IWLWIFI_DEBUG
Z
Zhu Yi 已提交
73 74 75 76 77
#define VD "d"
#else
#define VD
#endif

78
#define DRV_VERSION     IWLWIFI_VERSION VD
Z
Zhu Yi 已提交
79 80 81 82


MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERSION);
83
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
Z
Zhu Yi 已提交
84 85
MODULE_LICENSE("GPL");

86 87
static const struct iwl_op_mode_ops iwl_dvm_ops;

88
void iwl_update_chain_flags(struct iwl_priv *priv)
M
Mohamed Abbas 已提交
89
{
90
	struct iwl_rxon_context *ctx;
M
Mohamed Abbas 已提交
91

W
Wey-Yi Guy 已提交
92 93 94 95
	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);
96
	}
M
Mohamed Abbas 已提交
97 98
}

99 100
/* 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,
101 102
			       struct iwl_tx_beacon_cmd *tx_beacon_cmd,
			       u8 *beacon, u32 frame_size)
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
{
	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");
}

126
int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
127 128
{
	struct iwl_tx_beacon_cmd *tx_beacon_cmd;
129 130
	struct iwl_host_cmd cmd = {
		.id = REPLY_TX_BEACON,
131
		.flags = CMD_SYNC,
132
	};
133
	struct ieee80211_tx_info *info;
134 135 136
	u32 frame_size;
	u32 rate_flags;
	u32 rate;
137

138 139 140 141
	/*
	 * We have to set up the TX command, the TX Beacon command, and the
	 * beacon contents.
	 */
142

143
	lockdep_assert_held(&priv->mutex);
144 145 146

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

150 151 152
	if (WARN_ON(!priv->beacon_skb))
		return -EINVAL;

153 154 155 156
	/* Allocate beacon command */
	if (!priv->beacon_cmd)
		priv->beacon_cmd = kzalloc(sizeof(*tx_beacon_cmd), GFP_KERNEL);
	tx_beacon_cmd = priv->beacon_cmd;
157 158 159 160
	if (!tx_beacon_cmd)
		return -ENOMEM;

	frame_size = priv->beacon_skb->len;
161

162
	/* Set up TX command fields */
163
	tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
164
	tx_beacon_cmd->tx.sta_id = priv->beacon_ctx->bcast_sta_id;
165 166 167
	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;
168

169
	/* Set up TX beacon command fields */
170
	iwl_set_beacon_tim(priv, tx_beacon_cmd, priv->beacon_skb->data,
171
			   frame_size);
172

173
	/* Set up packet rate and flags */
174 175 176 177 178 179 180 181 182 183 184 185 186
	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;

187
	priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
188
					      priv->nvm_data->valid_tx_ant);
189
	rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
190 191 192 193 194

	/* 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)
195
		rate_flags |= RATE_MCS_CCK_MSK;
196 197 198

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

200
	/* Submit command */
201
	cmd.len[0] = sizeof(*tx_beacon_cmd);
202
	cmd.data[0] = tx_beacon_cmd;
203 204 205 206
	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;
207

208
	return iwl_dvm_send_cmd(priv, &cmd);
209 210
}

211
static void iwl_bg_beacon_update(struct work_struct *work)
Z
Zhu Yi 已提交
212
{
213 214
	struct iwl_priv *priv =
		container_of(work, struct iwl_priv, beacon_update);
Z
Zhu Yi 已提交
215 216
	struct sk_buff *beacon;

217
	mutex_lock(&priv->mutex);
218 219 220 221
	if (!priv->beacon_ctx) {
		IWL_ERR(priv, "updating beacon w/o beacon context!\n");
		goto out;
	}
Z
Zhu Yi 已提交
222

223 224 225 226 227 228 229 230 231 232
	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;
	}

233 234
	/* 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 已提交
235
	if (!beacon) {
236
		IWL_ERR(priv, "update beacon failed -- keeping old\n");
237
		goto out;
Z
Zhu Yi 已提交
238 239 240
	}

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

243
	priv->beacon_skb = beacon;
Z
Zhu Yi 已提交
244

245
	iwlagn_send_beacon_cmd(priv);
246
 out:
247
	mutex_unlock(&priv->mutex);
Z
Zhu Yi 已提交
248 249
}

250 251 252 253 254
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 已提交
255
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
256 257 258
		return;

	/* dont send host command if rf-kill is on */
D
Don Fry 已提交
259
	if (!iwl_is_ready_rf(priv))
260
		return;
W
Wey-Yi Guy 已提交
261
	iwlagn_send_advance_bt_config(priv);
262 263
}

264 265 266 267
static void iwl_bg_bt_full_concurrency(struct work_struct *work)
{
	struct iwl_priv *priv =
		container_of(work, struct iwl_priv, bt_full_concurrency);
268
	struct iwl_rxon_context *ctx;
269

270
	mutex_lock(&priv->mutex);
271

D
Don Fry 已提交
272
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
273
		goto out;
274 275

	/* dont send host command if rf-kill is on */
D
Don Fry 已提交
276
	if (!iwl_is_ready_rf(priv))
277
		goto out;
278 279 280 281 282 283 284 285 286

	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
	 */
287
	for_each_context(priv, ctx) {
W
Wey-Yi Guy 已提交
288
		iwlagn_set_rxon_chain(priv, ctx);
289
		iwlagn_commit_rxon(priv, ctx);
290
	}
291

W
Wey-Yi Guy 已提交
292
	iwlagn_send_advance_bt_config(priv);
293
out:
294
	mutex_unlock(&priv->mutex);
295 296
}

297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
{
	struct iwl_statistics_cmd statistics_cmd = {
		.configuration_flags =
			clear ? IWL_STATS_CONF_CLEAR_STATS : 0,
	};

	if (flags & CMD_ASYNC)
		return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
					CMD_ASYNC,
					sizeof(struct iwl_statistics_cmd),
					&statistics_cmd);
	else
		return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD,
					CMD_SYNC,
					sizeof(struct iwl_statistics_cmd),
					&statistics_cmd);
}

316
/**
317
 * iwl_bg_statistics_periodic - Timer callback to queue statistics
318 319 320 321 322 323 324 325
 *
 * 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.
 */
326
static void iwl_bg_statistics_periodic(unsigned long data)
327 328 329
{
	struct iwl_priv *priv = (struct iwl_priv *)data;

D
Don Fry 已提交
330
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
331 332
		return;

333
	/* dont send host command if rf-kill is on */
D
Don Fry 已提交
334
	if (!iwl_is_ready_rf(priv))
335 336
		return;

337
	iwl_send_statistics_request(priv, CMD_ASYNC, false);
338 339
}

340 341 342

static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
					u32 start_idx, u32 num_events,
J
Johannes Berg 已提交
343
					u32 capacity, u32 mode)
344 345 346 347 348 349 350 351 352 353 354 355
{
	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 */
356
	spin_lock_irqsave(&priv->trans->reg_lock, reg_flags);
357
	if (!iwl_trans_grab_nic_access(priv->trans, false)) {
358
		spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags);
359 360 361 362
		return;
	}

	/* Set starting address; reads will auto-increment */
363
	iwl_write32(priv->trans, HBUS_TARG_MEM_RADDR, ptr);
364

J
Johannes Berg 已提交
365 366 367 368 369 370 371 372 373
	/*
	 * 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;

374 375 376 377 378
	/*
	 * "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++) {
379 380
		ev = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT);
		time = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT);
381
		if (mode == 0) {
382
			trace_iwlwifi_dev_ucode_cont_event(
383
					priv->trans->dev, 0, time, ev);
384
		} else {
385
			data = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT);
386
			trace_iwlwifi_dev_ucode_cont_event(
387
					priv->trans->dev, time, data, ev);
388 389 390
		}
	}
	/* Allow device to power down */
391
	iwl_trans_release_nic_access(priv->trans);
392
	spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags);
393 394
}

J
Johannes Berg 已提交
395
static void iwl_continuous_event_trace(struct iwl_priv *priv)
396 397
{
	u32 capacity;   /* event log capacity in # entries */
J
Johannes Berg 已提交
398 399 400 401 402 403
	struct {
		u32 capacity;
		u32 mode;
		u32 wrap_counter;
		u32 write_counter;
	} __packed read;
404 405 406 407 408
	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 */

409
	base = priv->device_pointers.log_event_table;
410
	if (iwlagn_hw_valid_rtc_data_addr(base)) {
411 412
		iwl_trans_read_mem_bytes(priv->trans, base,
					 &read, sizeof(read));
J
Johannes Berg 已提交
413 414 415 416
		capacity = read.capacity;
		mode = read.mode;
		num_wraps = read.wrap_counter;
		next_entry = read.write_counter;
417 418 419
	} else
		return;

J
Johannes Berg 已提交
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
	/*
	 * 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++;

439
	if (num_wraps == priv->event_log.num_wraps) {
J
Johannes Berg 已提交
440 441 442 443 444
		iwl_print_cont_event_trace(
			priv, base, priv->event_log.next_entry,
			next_entry - priv->event_log.next_entry,
			capacity, mode);

445 446
		priv->event_log.non_wraps_count++;
	} else {
J
Johannes Berg 已提交
447
		if (num_wraps - priv->event_log.num_wraps > 1)
448 449 450
			priv->event_log.wraps_more_count++;
		else
			priv->event_log.wraps_once_count++;
J
Johannes Berg 已提交
451

452
		trace_iwlwifi_dev_ucode_wrap_event(priv->trans->dev,
453 454
				num_wraps - priv->event_log.num_wraps,
				next_entry, priv->event_log.next_entry);
J
Johannes Berg 已提交
455

456
		if (next_entry < priv->event_log.next_entry) {
J
Johannes Berg 已提交
457 458 459 460
			iwl_print_cont_event_trace(
				priv, base, priv->event_log.next_entry,
				capacity - priv->event_log.next_entry,
				capacity, mode);
461

J
Johannes Berg 已提交
462 463
			iwl_print_cont_event_trace(
				priv, base, 0, next_entry, capacity, mode);
464
		} else {
J
Johannes Berg 已提交
465 466 467 468
			iwl_print_cont_event_trace(
				priv, base, next_entry,
				capacity - next_entry,
				capacity, mode);
469

J
Johannes Berg 已提交
470 471
			iwl_print_cont_event_trace(
				priv, base, 0, next_entry, capacity, mode);
472 473
		}
	}
J
Johannes Berg 已提交
474

475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
	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 已提交
491
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
492 493 494 495 496 497 498 499 500 501
		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));
	}
}

502 503 504 505 506
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 已提交
507
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
508 509 510
		return;

	/* do nothing if rf-kill is on */
D
Don Fry 已提交
511
	if (!iwl_is_ready_rf(priv))
512 513
		return;

514
	IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n");
J
Johannes Berg 已提交
515
	iwlagn_dev_txfifo_flush(priv);
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
/*
 * queue/FIFO/AC mapping definitions
 */

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

544
static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
545 546 547 548 549 550 551
{
	int i;

	/*
	 * The default context is always valid,
	 * the PAN context depends on uCode.
	 */
552
	priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
553
	if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN)
554
		priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
555 556 557 558 559 560 561 562 563 564 565 566

	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;
567
	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
568
	priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
569
		BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MONITOR);
570 571 572 573 574 575
	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;
576 577 578 579
	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));
580 581 582 583 584 585 586 587 588 589 590 591 592

	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);
593 594 595 596 597 598

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

599 600 601
	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;
602 603 604 605 606
	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;
607 608 609 610

	BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
}

611
static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
612 613 614 615 616
{
	struct iwl_ct_kill_config cmd;
	struct iwl_ct_kill_throttling_config adv_cmd;
	int ret = 0;

617
	iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR,
618
		    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
J
Johannes Berg 已提交
619

620 621
	priv->thermal_throttle.ct_kill_toggle = false;

622
	if (priv->cfg->base_params->support_ct_kill_exit) {
623
		adv_cmd.critical_temperature_enter =
624
			cpu_to_le32(priv->hw_params.ct_kill_threshold);
625
		adv_cmd.critical_temperature_exit =
626
			cpu_to_le32(priv->hw_params.ct_kill_exit_threshold);
627

628
		ret = iwl_dvm_send_cmd_pdu(priv,
629 630
				       REPLY_CT_KILL_CONFIG_CMD,
				       CMD_SYNC, sizeof(adv_cmd), &adv_cmd);
631 632 633 634
		if (ret)
			IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
		else
			IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
635 636
				"succeeded, critical temperature enter is %d,"
				"exit is %d\n",
637 638
				priv->hw_params.ct_kill_threshold,
				priv->hw_params.ct_kill_exit_threshold);
639 640
	} else {
		cmd.critical_temperature_R =
641
			cpu_to_le32(priv->hw_params.ct_kill_threshold);
642

643
		ret = iwl_dvm_send_cmd_pdu(priv,
644 645
				       REPLY_CT_KILL_CONFIG_CMD,
				       CMD_SYNC, sizeof(cmd), &cmd);
646 647 648 649
		if (ret)
			IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
		else
			IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
650 651
				"succeeded, "
				"critical temperature is %d\n",
652
				priv->hw_params.ct_kill_threshold);
653 654 655
	}
}

656 657 658 659 660
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,
661 662
		.len = { sizeof(struct iwl_calib_cfg_cmd), },
		.data = { &calib_cfg_cmd, },
663 664 665
	};

	memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
666
	calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_RT_CFG_ALL;
667
	calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg);
668

669
	return iwl_dvm_send_cmd(priv, &cmd);
670 671 672
}


W
Wey-Yi Guy 已提交
673 674 675 676 677 678
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),
	};

679
	if (IWL_UCODE_API(priv->fw->ucode_ver) > 1) {
W
Wey-Yi Guy 已提交
680
		IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
681
		return iwl_dvm_send_cmd_pdu(priv,
W
Wey-Yi Guy 已提交
682 683 684 685 686 687 688 689 690 691
					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;
	}
}

692
static void iwl_send_bt_config(struct iwl_priv *priv)
693 694 695 696 697 698 699 700
{
	struct iwl_bt_cmd bt_cmd = {
		.lead_time = BT_LEAD_TIME_DEF,
		.max_kill = BT_MAX_KILL_DEF,
		.kill_ack_mask = 0,
		.kill_cts_mask = 0,
	};

701
	if (!iwlwifi_mod_params.bt_coex_active)
702 703 704 705 706 707 708 709 710 711 712 713 714
		bt_cmd.flags = BT_COEX_DISABLE;
	else
		bt_cmd.flags = BT_COEX_ENABLE;

	priv->bt_enable_flag = bt_cmd.flags;
	IWL_DEBUG_INFO(priv, "BT coex %s\n",
		(bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");

	if (iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
			     CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd))
		IWL_ERR(priv, "failed to send BT Coex Config\n");
}

Z
Zhu Yi 已提交
715
/**
716
 * iwl_alive_start - called after REPLY_ALIVE notification received
Z
Zhu Yi 已提交
717
 *                   from protocol/runtime uCode (initialization uCode's
718
 *                   Alive gets handled by iwl_init_alive_start()).
Z
Zhu Yi 已提交
719
 */
720
int iwl_alive_start(struct iwl_priv *priv)
Z
Zhu Yi 已提交
721
{
722
	int ret = 0;
723
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
Z
Zhu Yi 已提交
724

725
	IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
726

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

D
Don Fry 已提交
730
	if (iwl_is_rfkill(priv))
731
		return -ERFKILL;
Z
Zhu Yi 已提交
732

J
Johannes Berg 已提交
733 734 735 736 737
	if (priv->event_log.ucode_trace) {
		/* start collecting data now */
		mod_timer(&priv->ucode_trace, jiffies);
	}

738
	/* download priority table before any calibration request */
739 740
	if (priv->cfg->bt_params &&
	    priv->cfg->bt_params->advanced_bt_coexist) {
741
		/* Configure Bluetooth device coexistence support */
742
		if (priv->cfg->bt_params->bt_sco_disable)
743 744 745 746
			priv->bt_enable_pspoll = false;
		else
			priv->bt_enable_pspoll = true;

747 748 749
		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 已提交
750
		iwlagn_send_advance_bt_config(priv);
751
		priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
752 753
		priv->cur_rssi_ctx = NULL;

754
		iwl_send_prio_tbl(priv);
755 756

		/* FIXME: w/a to force change uCode BT state machine */
757
		ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
758 759 760
					 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
		if (ret)
			return ret;
761
		ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
762 763 764
					 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
		if (ret)
			return ret;
W
Wey-Yi Guy 已提交
765 766 767 768 769
	} else {
		/*
		 * default is 2-wire BT coexexistence support
		 */
		iwl_send_bt_config(priv);
770
	}
W
Wey-Yi Guy 已提交
771

772 773 774 775
	/*
	 * Perform runtime calibrations, including DC calibration.
	 */
	iwlagn_send_calib_cfg_rt(priv, IWL_CALIB_CFG_DC_IDX);
776

777
	ieee80211_wake_queues(priv->hw);
Z
Zhu Yi 已提交
778

779
	/* Configure Tx antenna selection based on H/W config */
780
	iwlagn_send_tx_ant_config(priv, priv->nvm_data->valid_tx_ant);
781

782
	if (iwl_is_associated_ctx(ctx) && !priv->wowlan) {
G
Gregory Greenman 已提交
783
		struct iwl_rxon_cmd *active_rxon =
784
				(struct iwl_rxon_cmd *)&ctx->active;
785
		/* apply any changes in staging */
786
		ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
Z
Zhu Yi 已提交
787 788
		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
	} else {
789
		struct iwl_rxon_context *tmp;
Z
Zhu Yi 已提交
790
		/* Initialize our rx_config data */
791 792
		for_each_context(priv, tmp)
			iwl_connection_init_rx_config(priv, tmp);
793

W
Wey-Yi Guy 已提交
794
		iwlagn_set_rxon_chain(priv, ctx);
Z
Zhu Yi 已提交
795 796
	}

797
	if (!priv->wowlan) {
J
Johannes Berg 已提交
798 799 800
		/* WoWLAN ucode will not reply in the same way, skip it */
		iwl_reset_run_time_calib(priv);
	}
801

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

Z
Zhu Yi 已提交
804
	/* Configure the adapter for unassociated operation */
805
	ret = iwlagn_commit_rxon(priv, ctx);
806 807
	if (ret)
		return ret;
Z
Zhu Yi 已提交
808 809

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

812
	IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
813

814
	return iwl_power_update_mode(priv, true);
Z
Zhu Yi 已提交
815 816
}

817 818 819 820 821 822 823 824 825 826 827 828 829
/**
 * 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;

830
	spin_lock_bh(&priv->sta_lock);
831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847
	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;
	}

848
	spin_unlock_bh(&priv->sta_lock);
849 850
}

851
void iwl_down(struct iwl_priv *priv)
Z
Zhu Yi 已提交
852
{
853
	int exit_pending;
Z
Zhu Yi 已提交
854

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

857
	lockdep_assert_held(&priv->mutex);
858

859 860
	iwl_scan_cancel_timeout(priv, 200);

861 862 863 864 865
	/*
	 * 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.
	 */
A
Amit Beka 已提交
866 867
	if (priv->ucode_loaded && priv->cur_ucode != IWL_UCODE_INIT)
		ieee80211_remain_on_channel_expired(priv->hw);
868

869
	exit_pending =
D
Don Fry 已提交
870
		test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
Z
Zhu Yi 已提交
871

872
	iwl_clear_ucode_stations(priv, NULL);
873
	iwl_dealloc_bcast_stations(priv);
874
	iwl_clear_driver_stations(priv);
Z
Zhu Yi 已提交
875

876
	/* reset BT coex data */
877
	priv->bt_status = 0;
878 879
	priv->cur_rssi_ctx = NULL;
	priv->bt_is_sco = 0;
880
	if (priv->cfg->bt_params)
881
		priv->bt_traffic_load =
882
			 priv->cfg->bt_params->bt_init_traffic_load;
883 884
	else
		priv->bt_traffic_load = 0;
885 886
	priv->bt_full_concurrent = false;
	priv->bt_ci_compliance = 0;
887

Z
Zhu Yi 已提交
888 889 890
	/* Wipe out the EXIT_PENDING status bit if we are not actually
	 * exiting the module */
	if (!exit_pending)
D
Don Fry 已提交
891
		clear_bit(STATUS_EXIT_PENDING, &priv->status);
Z
Zhu Yi 已提交
892

893
	if (priv->mac80211_registered)
Z
Zhu Yi 已提交
894 895
		ieee80211_stop_queues(priv->hw);

896
	priv->ucode_loaded = false;
897
	iwl_trans_stop_device(priv->trans);
898

899 900 901
	/* Set num_aux_in_flight must be done after the transport is stopped */
	atomic_set(&priv->num_aux_in_flight, 0);

J
Johannes Berg 已提交
902
	/* Clear out all status bits but a few that are stable across reset */
903
	priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
Z
Zhu Yi 已提交
904
				STATUS_RF_KILL_HW |
D
Don Fry 已提交
905 906
			test_bit(STATUS_FW_ERROR, &priv->status) <<
				STATUS_FW_ERROR |
D
Don Fry 已提交
907
			test_bit(STATUS_EXIT_PENDING, &priv->status) <<
908
				STATUS_EXIT_PENDING;
Z
Zhu Yi 已提交
909

910
	dev_kfree_skb(priv->beacon_skb);
911
	priv->beacon_skb = NULL;
Z
Zhu Yi 已提交
912 913 914 915 916 917 918 919
}

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

920 921 922 923 924
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);

925
	mutex_lock(&priv->mutex);
926

D
Don Fry 已提交
927 928
	if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
	    test_bit(STATUS_SCANNING, &priv->status)) {
929
		mutex_unlock(&priv->mutex);
930 931 932 933
		return;
	}

	if (priv->start_calib) {
934 935
		iwl_chain_noise_calibration(priv);
		iwl_sensitivity_calibration(priv);
936 937
	}

938
	mutex_unlock(&priv->mutex);
939 940
}

941
void iwlagn_prepare_restart(struct iwl_priv *priv)
J
Johannes Berg 已提交
942 943 944 945 946
{
	bool bt_full_concurrent;
	u8 bt_ci_compliance;
	u8 bt_load;
	u8 bt_status;
947
	bool bt_is_sco;
948
	int i;
J
Johannes Berg 已提交
949

950
	lockdep_assert_held(&priv->mutex);
J
Johannes Berg 已提交
951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966

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

969
	iwl_down(priv);
J
Johannes Berg 已提交
970 971 972 973 974

	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;
975
	priv->bt_is_sco = bt_is_sco;
976

977
	/* reset aggregation queues */
978
	for (i = IWLAGN_FIRST_AMPDU_QUEUE; i < IWL_MAX_HW_QUEUES; i++)
979 980 981 982
		priv->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE;
	/* and stop counts */
	for (i = 0; i < IWL_MAX_HW_QUEUES; i++)
		atomic_set(&priv->queue_stop_count[i], 0);
983 984

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

987
static void iwl_bg_restart(struct work_struct *data)
Z
Zhu Yi 已提交
988
{
989
	struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
Z
Zhu Yi 已提交
990

D
Don Fry 已提交
991
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
Z
Zhu Yi 已提交
992 993
		return;

D
Don Fry 已提交
994
	if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
995
		mutex_lock(&priv->mutex);
J
Johannes Berg 已提交
996
		iwlagn_prepare_restart(priv);
997
		mutex_unlock(&priv->mutex);
998
		iwl_cancel_deferred_work(priv);
A
Amit Beka 已提交
999 1000 1001 1002 1003
		if (priv->mac80211_registered)
			ieee80211_restart_hw(priv->hw);
		else
			IWL_ERR(priv,
				"Cannot request restart before registrating with mac80211");
J
Johannes Berg 已提交
1004
	} else {
1005
		WARN_ON(1);
J
Johannes Berg 已提交
1006
	}
Z
Zhu Yi 已提交
1007 1008
}

1009 1010 1011



1012
void iwlagn_disable_roc(struct iwl_priv *priv)
1013
{
1014
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
1015

1016
	lockdep_assert_held(&priv->mutex);
1017

1018 1019
	if (!priv->hw_roc_setup)
		return;
1020

1021 1022
	ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
	ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1023

1024
	priv->hw_roc_channel = NULL;
1025

1026
	memset(ctx->staging.node_addr, 0, ETH_ALEN);
1027

1028
	iwlagn_commit_rxon(priv, ctx);
1029

1030 1031
	ctx->is_active = false;
	priv->hw_roc_setup = false;
1032 1033
}

1034
static void iwlagn_disable_roc_work(struct work_struct *work)
Z
Zhu Yi 已提交
1035
{
1036 1037
	struct iwl_priv *priv = container_of(work, struct iwl_priv,
					     hw_roc_disable_work.work);
Z
Zhu Yi 已提交
1038

1039
	mutex_lock(&priv->mutex);
1040
	iwlagn_disable_roc(priv);
1041
	mutex_unlock(&priv->mutex);
Z
Zhu Yi 已提交
1042 1043
}

1044 1045 1046 1047 1048 1049
/*****************************************************************************
 *
 * driver setup and teardown
 *
 *****************************************************************************/

1050
static void iwl_setup_deferred_work(struct iwl_priv *priv)
Z
Zhu Yi 已提交
1051
{
J
Johannes Berg 已提交
1052
	priv->workqueue = create_singlethread_workqueue(DRV_NAME);
Z
Zhu Yi 已提交
1053

1054 1055 1056 1057 1058 1059 1060 1061
	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);
1062

1063
	iwl_setup_scan_deferred_work(priv);
1064

1065
	if (priv->cfg->bt_params)
1066
		iwlagn_bt_setup_deferred_work(priv);
1067

1068 1069 1070
	init_timer(&priv->statistics_periodic);
	priv->statistics_periodic.data = (unsigned long)priv;
	priv->statistics_periodic.function = iwl_bg_statistics_periodic;
1071

1072 1073 1074
	init_timer(&priv->ucode_trace);
	priv->ucode_trace.data = (unsigned long)priv;
	priv->ucode_trace.function = iwl_bg_ucode_trace;
Z
Zhu Yi 已提交
1075 1076
}

1077
void iwl_cancel_deferred_work(struct iwl_priv *priv)
J
Johannes Berg 已提交
1078
{
1079
	if (priv->cfg->bt_params)
1080
		iwlagn_bt_cancel_deferred_work(priv);
J
Johannes Berg 已提交
1081

1082 1083
	cancel_work_sync(&priv->run_time_calib_work);
	cancel_work_sync(&priv->beacon_update);
J
Johannes Berg 已提交
1084

1085
	iwl_cancel_scan_deferred_work(priv);
J
Johannes Berg 已提交
1086

1087 1088 1089
	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 已提交
1090

1091 1092 1093
	del_timer_sync(&priv->statistics_periodic);
	del_timer_sync(&priv->ucode_trace);
}
J
Johannes Berg 已提交
1094

1095
static int iwl_init_drv(struct iwl_priv *priv)
J
Johannes Berg 已提交
1096
{
1097
	spin_lock_init(&priv->sta_lock);
J
Johannes Berg 已提交
1098

1099
	mutex_init(&priv->mutex);
J
Johannes Berg 已提交
1100

1101
	INIT_LIST_HEAD(&priv->calib_results);
1102

1103
	priv->band = IEEE80211_BAND_2GHZ;
J
Johannes Berg 已提交
1104

1105
	priv->plcp_delta_threshold =
1106
		priv->cfg->base_params->plcp_delta_threshold;
1107

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

1113 1114
	priv->ucode_owner = IWL_OWNERSHIP_DRIVER;

1115
	priv->rx_statistics_jiffies = jiffies;
J
Johannes Berg 已提交
1116

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

1120
	iwl_init_scan_params(priv);
J
Johannes Berg 已提交
1121

1122
	/* init bt coex */
1123 1124
	if (priv->cfg->bt_params &&
	    priv->cfg->bt_params->advanced_bt_coexist) {
1125 1126 1127 1128 1129 1130 1131
		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 已提交
1132

1133 1134
	return 0;
}
J
Johannes Berg 已提交
1135

1136
static void iwl_uninit_drv(struct iwl_priv *priv)
1137 1138 1139 1140
{
	kfree(priv->scan_cmd);
	kfree(priv->beacon_cmd);
	kfree(rcu_dereference_raw(priv->noa_data));
1141
	iwl_calib_free_results(priv);
1142 1143 1144 1145
#ifdef CONFIG_IWLWIFI_DEBUGFS
	kfree(priv->wowlan_sram);
#endif
}
J
Johannes Berg 已提交
1146

1147
static void iwl_set_hw_params(struct iwl_priv *priv)
1148
{
1149
	if (priv->cfg->ht_params)
1150
		priv->hw_params.use_rts_for_aggregation =
1151
			priv->cfg->ht_params->use_rts_for_aggregation;
1152

1153
	/* Device-specific setup */
1154
	priv->lib->set_hw_params(priv);
1155 1156
}

1157 1158


1159
/* show what optional capabilities we have */
1160
static void iwl_option_config(struct iwl_priv *priv)
1161 1162
{
#ifdef CONFIG_IWLWIFI_DEBUG
1163
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUG enabled\n");
1164
#else
1165
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUG disabled\n");
1166
#endif
1167

1168
#ifdef CONFIG_IWLWIFI_DEBUGFS
1169
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUGFS enabled\n");
1170
#else
1171
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUGFS disabled\n");
1172
#endif
1173

1174
#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
1175
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING enabled\n");
1176
#else
1177
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING disabled\n");
1178
#endif
1179

1180
#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
1181
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE enabled\n");
1182
#else
1183
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE disabled\n");
1184
#endif
1185

1186
#ifdef CONFIG_IWLWIFI_P2P
1187
	IWL_INFO(priv, "CONFIG_IWLWIFI_P2P enabled\n");
1188
#else
1189
	IWL_INFO(priv, "CONFIG_IWLWIFI_P2P disabled\n");
1190 1191 1192
#endif
}

1193 1194
static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
{
1195 1196 1197 1198
	struct iwl_nvm_data *data = priv->nvm_data;
	char *debug_msg;

	if (data->sku_cap_11n_enable &&
1199 1200 1201 1202 1203
	    !priv->cfg->ht_params) {
		IWL_ERR(priv, "Invalid 11n configuration\n");
		return -EINVAL;
	}

1204 1205
	if (!data->sku_cap_11n_enable && !data->sku_cap_band_24GHz_enable &&
	    !data->sku_cap_band_52GHz_enable) {
1206 1207 1208 1209
		IWL_ERR(priv, "Invalid device sku\n");
		return -EINVAL;
	}

1210 1211 1212 1213 1214
	debug_msg = "Device SKU: 24GHz %s %s, 52GHz %s %s, 11.n %s %s\n";
	IWL_DEBUG_INFO(priv, debug_msg,
		       data->sku_cap_band_24GHz_enable ? "" : "NOT", "enabled",
		       data->sku_cap_band_52GHz_enable ? "" : "NOT", "enabled",
		       data->sku_cap_11n_enable ? "" : "NOT", "enabled");
1215 1216

	priv->hw_params.tx_chains_num =
1217
		num_of_ant(data->valid_tx_ant);
1218 1219 1220 1221
	if (priv->cfg->rx_with_siso_diversity)
		priv->hw_params.rx_chains_num = 1;
	else
		priv->hw_params.rx_chains_num =
1222
			num_of_ant(data->valid_rx_ant);
1223

1224
	IWL_DEBUG_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n",
1225 1226
		       data->valid_tx_ant,
		       data->valid_rx_ant);
1227 1228 1229 1230

	return 0;
}

1231
static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1232
						 const struct iwl_cfg *cfg,
1233 1234
						 const struct iwl_fw *fw,
						 struct dentry *dbgfs_dir)
1235 1236 1237
{
	struct iwl_priv *priv;
	struct ieee80211_hw *hw;
1238
	struct iwl_op_mode *op_mode;
1239
	u16 num_mac;
1240
	u32 ucode_flags;
1241
	struct iwl_trans_config trans_cfg = {};
1242 1243 1244 1245 1246 1247 1248
	static const u8 no_reclaim_cmds[] = {
		REPLY_RX_PHY_CMD,
		REPLY_RX_MPDU_CMD,
		REPLY_COMPRESSED_BA,
		STATISTICS_NOTIFICATION,
		REPLY_TX,
	};
1249
	int i;
1250 1251 1252 1253

	/************************
	 * 1. Allocating HW data
	 ************************/
D
Don Fry 已提交
1254
	hw = iwl_alloc_all();
1255
	if (!hw) {
1256
		pr_err("%s: Cannot allocate network device\n", cfg->name);
1257 1258 1259
		goto out;
	}

1260 1261 1262
	op_mode = hw->priv;
	op_mode->ops = &iwl_dvm_ops;
	priv = IWL_OP_MODE_GET_DVM(op_mode);
1263
	priv->trans = trans;
1264
	priv->dev = trans->dev;
1265
	priv->cfg = cfg;
1266
	priv->fw = fw;
1267

1268
	switch (priv->cfg->device_family) {
1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301
	case IWL_DEVICE_FAMILY_1000:
	case IWL_DEVICE_FAMILY_100:
		priv->lib = &iwl1000_lib;
		break;
	case IWL_DEVICE_FAMILY_2000:
	case IWL_DEVICE_FAMILY_105:
		priv->lib = &iwl2000_lib;
		break;
	case IWL_DEVICE_FAMILY_2030:
	case IWL_DEVICE_FAMILY_135:
		priv->lib = &iwl2030_lib;
		break;
	case IWL_DEVICE_FAMILY_5000:
		priv->lib = &iwl5000_lib;
		break;
	case IWL_DEVICE_FAMILY_5150:
		priv->lib = &iwl5150_lib;
		break;
	case IWL_DEVICE_FAMILY_6000:
	case IWL_DEVICE_FAMILY_6005:
	case IWL_DEVICE_FAMILY_6000i:
	case IWL_DEVICE_FAMILY_6050:
	case IWL_DEVICE_FAMILY_6150:
		priv->lib = &iwl6000_lib;
		break;
	case IWL_DEVICE_FAMILY_6030:
		priv->lib = &iwl6030_lib;
		break;
	default:
		break;
	}

	if (WARN_ON(!priv->lib))
J
Johannes Berg 已提交
1302
		goto out_free_hw;
1303

E
Emmanuel Grumbach 已提交
1304 1305 1306 1307 1308
	/*
	 * Populate the state variables that the transport layer needs
	 * to know about.
	 */
	trans_cfg.op_mode = op_mode;
1309 1310
	trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
	trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
1311 1312
	trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K;
	if (!iwlwifi_mod_params.wd_disable)
1313
		trans_cfg.queue_watchdog_timeout =
1314
			priv->cfg->base_params->wd_timeout;
1315
	else
1316
		trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED;
J
Johannes Berg 已提交
1317
	trans_cfg.command_names = iwl_dvm_cmd_strings;
1318
	trans_cfg.cmd_fifo = IWLAGN_CMD_FIFO_NUM;
1319

1320 1321 1322
	WARN_ON(sizeof(priv->transport_queue_stop) * BITS_PER_BYTE <
		priv->cfg->base_params->num_of_queues);

1323 1324 1325
	ucode_flags = fw->ucode_capa.flags;

#ifndef CONFIG_IWLWIFI_P2P
1326
	ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
1327
#endif
1328

1329 1330 1331 1332 1333 1334 1335 1336
	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;
	} else {
		priv->sta_key_max_num = STA_KEY_MAX_NUM;
		trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
	}

1337
	/* Configure transport layer */
1338
	iwl_trans_configure(priv->trans, &trans_cfg);
1339

1340 1341 1342
	trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD;
	trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start);

1343
	/* At this point both hw and priv are allocated. */
1344

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

1347
	iwl_option_config(priv);
1348

1349
	IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
1350

1351 1352
	/* is antenna coupling more than 35dB ? */
	priv->bt_ant_couple_ok =
1353
		(iwlwifi_mod_params.ant_coupling >
1354 1355
			IWL_BT_ANTENNA_COUPLING_THRESHOLD) ?
			true : false;
1356

1357
	/* enable/disable bt channel inhibition */
1358
	priv->bt_ch_announce = iwlwifi_mod_params.bt_ch_announce;
1359 1360
	IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n",
		       (priv->bt_ch_announce) ? "On" : "Off");
1361

1362
	/* these spin locks will be used in apm_ops.init and EEPROM access
M
Mohamed Abbas 已提交
1363 1364
	 * we should init now
	 */
1365
	spin_lock_init(&priv->statistics.lock);
1366

1367
	/***********************
E
Emmanuel Grumbach 已提交
1368
	 * 2. Read REV register
1369
	 ***********************/
1370
	IWL_INFO(priv, "Detected %s, REV=0x%X\n",
1371
		priv->cfg->name, priv->trans->hw_rev);
1372

1373
	if (iwl_trans_start_hw(priv->trans))
J
Johannes Berg 已提交
1374
		goto out_free_hw;
1375

W
Wey-Yi Guy 已提交
1376
	/* Read the EEPROM */
1377 1378
	if (iwl_read_eeprom(priv->trans, &priv->eeprom_blob,
			    &priv->eeprom_blob_size)) {
1379
		IWL_ERR(priv, "Unable to init EEPROM\n");
J
Johannes Berg 已提交
1380
		goto out_free_hw;
1381
	}
1382

W
Wey-Yi Guy 已提交
1383
	/* Reset chip to save power until we load uCode during "up". */
1384
	iwl_trans_stop_hw(priv->trans, false);
W
Wey-Yi Guy 已提交
1385

1386
	priv->nvm_data = iwl_parse_eeprom_data(priv->trans->dev, priv->cfg,
1387 1388
						  priv->eeprom_blob,
						  priv->eeprom_blob_size);
1389
	if (!priv->nvm_data)
1390 1391
		goto out_free_eeprom_blob;

1392
	if (iwl_nvm_check_version(priv->nvm_data, priv->trans))
1393
		goto out_free_eeprom;
1394

W
Wey-Yi Guy 已提交
1395
	if (iwl_eeprom_init_hw_params(priv))
1396 1397
		goto out_free_eeprom;

1398
	/* extract MAC Address */
1399
	memcpy(priv->addresses[0].addr, priv->nvm_data->hw_addr, ETH_ALEN);
1400 1401 1402
	IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr);
	priv->hw->wiphy->addresses = priv->addresses;
	priv->hw->wiphy->n_addresses = 1;
1403
	num_mac = priv->nvm_data->n_hw_addrs;
1404 1405 1406 1407 1408 1409
	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++;
	}
1410

E
Emmanuel Grumbach 已提交
1411 1412 1413 1414 1415
	/************************
	 * 4. Setup HW constants
	 ************************/
	iwl_set_hw_params(priv);

1416
	if (!(priv->nvm_data->sku_cap_ipan_enable)) {
E
Emmanuel Grumbach 已提交
1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427
		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;

		/* Configure transport layer again*/
1428
		iwl_trans_configure(priv->trans, &trans_cfg);
E
Emmanuel Grumbach 已提交
1429 1430
	}

1431
	/*******************
E
Emmanuel Grumbach 已提交
1432
	 * 5. Setup priv
1433
	 *******************/
1434
	for (i = 0; i < IWL_MAX_HW_QUEUES; i++) {
1435 1436 1437 1438 1439 1440
		priv->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE;
		if (i < IWLAGN_FIRST_AMPDU_QUEUE &&
		    i != IWL_DEFAULT_CMD_QUEUE_NUM &&
		    i != IWL_IPAN_CMD_QUEUE_NUM)
			priv->queue_to_mac80211[i] = i;
		atomic_set(&priv->queue_stop_count[i], 0);
1441 1442
	}

W
Wey-Yi Guy 已提交
1443
	if (iwl_init_drv(priv))
R
Ron Rindjunsky 已提交
1444
		goto out_free_eeprom;
W
Wey-Yi Guy 已提交
1445

1446
	/* At this point both hw and priv are initialized. */
1447 1448

	/********************
E
Emmanuel Grumbach 已提交
1449
	 * 6. Setup services
1450
	 ********************/
1451
	iwl_setup_deferred_work(priv);
1452
	iwl_setup_rx_handlers(priv);
1453
	iwl_testmode_init(priv);
1454

1455
	iwl_power_initialize(priv);
1456
	iwl_tt_initialize(priv);
J
Johannes Berg 已提交
1457

1458 1459 1460 1461 1462
	snprintf(priv->hw->wiphy->fw_version,
		 sizeof(priv->hw->wiphy->fw_version),
		 "%s", fw->fw_version);

	priv->new_scan_threshold_behaviour =
1463
		!!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
1464

1465 1466 1467 1468 1469 1470
	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 */
1471
	iwl_init_context(priv, ucode_flags);
1472 1473 1474 1475

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

1481 1482
	if (iwl_dbgfs_register(priv, dbgfs_dir))
		goto out_mac80211_unregister;
1483

1484
	return op_mode;
Z
Zhu Yi 已提交
1485

1486 1487
out_mac80211_unregister:
	iwlagn_mac_unregister(priv);
1488
out_destroy_workqueue:
1489 1490 1491
	iwl_tt_exit(priv);
	iwl_testmode_free(priv);
	iwl_cancel_deferred_work(priv);
J
Johannes Berg 已提交
1492 1493
	destroy_workqueue(priv->workqueue);
	priv->workqueue = NULL;
T
Tomas Winkler 已提交
1494
	iwl_uninit_drv(priv);
1495 1496
out_free_eeprom_blob:
	kfree(priv->eeprom_blob);
1497
out_free_eeprom:
1498
	iwl_free_nvm_data(priv->nvm_data);
J
Johannes Berg 已提交
1499
out_free_hw:
1500
	ieee80211_free_hw(priv->hw);
1501
out:
1502 1503
	op_mode = NULL;
	return op_mode;
Z
Zhu Yi 已提交
1504 1505
}

1506
static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
Z
Zhu Yi 已提交
1507
{
1508 1509
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

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

I
Ilan Peer 已提交
1512
	iwl_testmode_free(priv);
1513
	iwlagn_mac_unregister(priv);
1514

1515 1516
	iwl_tt_exit(priv);

1517
	kfree(priv->eeprom_blob);
1518
	iwl_free_nvm_data(priv->nvm_data);
Z
Zhu Yi 已提交
1519

M
Mohamed Abbas 已提交
1520
	/*netif_stop_queue(dev); */
J
Johannes Berg 已提交
1521
	flush_workqueue(priv->workqueue);
M
Mohamed Abbas 已提交
1522

1523
	/* ieee80211_unregister_hw calls iwlagn_mac_stop, which flushes
J
Johannes Berg 已提交
1524
	 * priv->workqueue... so we can't take down the workqueue
Z
Zhu Yi 已提交
1525
	 * until now... */
J
Johannes Berg 已提交
1526 1527
	destroy_workqueue(priv->workqueue);
	priv->workqueue = NULL;
Z
Zhu Yi 已提交
1528

T
Tomas Winkler 已提交
1529
	iwl_uninit_drv(priv);
Z
Zhu Yi 已提交
1530

1531
	dev_kfree_skb(priv->beacon_skb);
Z
Zhu Yi 已提交
1532

1533
	iwl_trans_stop_hw(priv->trans, true);
Z
Zhu Yi 已提交
1534 1535 1536
	ieee80211_free_hw(priv->hw);
}

1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607
static const char * const desc_lookup_text[] = {
	"OK",
	"FAIL",
	"BAD_PARAM",
	"BAD_CHECKSUM",
	"NMI_INTERRUPT_WDG",
	"SYSASSERT",
	"FATAL_ERROR",
	"BAD_COMMAND",
	"HW_ERROR_TUNE_LOCK",
	"HW_ERROR_TEMPERATURE",
	"ILLEGAL_CHAN_FREQ",
	"VCC_NOT_STABLE",
	"FH_ERROR",
	"NMI_INTERRUPT_HOST",
	"NMI_INTERRUPT_ACTION_PT",
	"NMI_INTERRUPT_UNKNOWN",
	"UCODE_VERSION_MISMATCH",
	"HW_ERROR_ABS_LOCK",
	"HW_ERROR_CAL_LOCK_FAIL",
	"NMI_INTERRUPT_INST_ACTION_PT",
	"NMI_INTERRUPT_DATA_ACTION_PT",
	"NMI_TRM_HW_ER",
	"NMI_INTERRUPT_TRM",
	"NMI_INTERRUPT_BREAK_POINT",
	"DEBUG_0",
	"DEBUG_1",
	"DEBUG_2",
	"DEBUG_3",
};

static struct { char *name; u8 num; } advanced_lookup[] = {
	{ "NMI_INTERRUPT_WDG", 0x34 },
	{ "SYSASSERT", 0x35 },
	{ "UCODE_VERSION_MISMATCH", 0x37 },
	{ "BAD_COMMAND", 0x38 },
	{ "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
	{ "FATAL_ERROR", 0x3D },
	{ "NMI_TRM_HW_ERR", 0x46 },
	{ "NMI_INTERRUPT_TRM", 0x4C },
	{ "NMI_INTERRUPT_BREAK_POINT", 0x54 },
	{ "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
	{ "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
	{ "NMI_INTERRUPT_HOST", 0x66 },
	{ "NMI_INTERRUPT_ACTION_PT", 0x7C },
	{ "NMI_INTERRUPT_UNKNOWN", 0x84 },
	{ "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
	{ "ADVANCED_SYSASSERT", 0 },
};

static const char *desc_lookup(u32 num)
{
	int i;
	int max = ARRAY_SIZE(desc_lookup_text);

	if (num < max)
		return desc_lookup_text[num];

	max = ARRAY_SIZE(advanced_lookup) - 1;
	for (i = 0; i < max; i++) {
		if (advanced_lookup[i].num == num)
			break;
	}
	return advanced_lookup[i].name;
}

#define ERROR_START_OFFSET  (1 * sizeof(u32))
#define ERROR_ELEM_SIZE     (7 * sizeof(u32))

static void iwl_dump_nic_error_log(struct iwl_priv *priv)
{
1608
	struct iwl_trans *trans = priv->trans;
1609 1610 1611 1612
	u32 base;
	struct iwl_error_event_table table;

	base = priv->device_pointers.error_event_table;
1613
	if (priv->cur_ucode == IWL_UCODE_INIT) {
1614
		if (!base)
1615
			base = priv->fw->init_errlog_ptr;
1616 1617
	} else {
		if (!base)
1618
			base = priv->fw->inst_errlog_ptr;
1619 1620 1621 1622 1623 1624
	}

	if (!iwlagn_hw_valid_rtc_data_addr(base)) {
		IWL_ERR(priv,
			"Not valid error log pointer 0x%08X for %s uCode\n",
			base,
1625
			(priv->cur_ucode == IWL_UCODE_INIT)
1626 1627 1628 1629 1630
					? "Init" : "RT");
		return;
	}

	/*TODO: Update dbgfs with ISR error stats obtained below */
1631
	iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table));
1632 1633 1634 1635

	if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
		IWL_ERR(trans, "Start IWL Error Log Dump:\n");
		IWL_ERR(trans, "Status: 0x%08lX, count: %d\n",
D
Don Fry 已提交
1636
			priv->status, table.valid);
1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697
	}

	trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
				      table.data1, table.data2, table.line,
				      table.blink1, table.blink2, table.ilink1,
				      table.ilink2, table.bcon_time, table.gp1,
				      table.gp2, table.gp3, table.ucode_ver,
				      table.hw_ver, table.brd_ver);
	IWL_ERR(priv, "0x%08X | %-28s\n", table.error_id,
		desc_lookup(table.error_id));
	IWL_ERR(priv, "0x%08X | uPc\n", table.pc);
	IWL_ERR(priv, "0x%08X | branchlink1\n", table.blink1);
	IWL_ERR(priv, "0x%08X | branchlink2\n", table.blink2);
	IWL_ERR(priv, "0x%08X | interruptlink1\n", table.ilink1);
	IWL_ERR(priv, "0x%08X | interruptlink2\n", table.ilink2);
	IWL_ERR(priv, "0x%08X | data1\n", table.data1);
	IWL_ERR(priv, "0x%08X | data2\n", table.data2);
	IWL_ERR(priv, "0x%08X | line\n", table.line);
	IWL_ERR(priv, "0x%08X | beacon time\n", table.bcon_time);
	IWL_ERR(priv, "0x%08X | tsf low\n", table.tsf_low);
	IWL_ERR(priv, "0x%08X | tsf hi\n", table.tsf_hi);
	IWL_ERR(priv, "0x%08X | time gp1\n", table.gp1);
	IWL_ERR(priv, "0x%08X | time gp2\n", table.gp2);
	IWL_ERR(priv, "0x%08X | time gp3\n", table.gp3);
	IWL_ERR(priv, "0x%08X | uCode version\n", table.ucode_ver);
	IWL_ERR(priv, "0x%08X | hw version\n", table.hw_ver);
	IWL_ERR(priv, "0x%08X | board version\n", table.brd_ver);
	IWL_ERR(priv, "0x%08X | hcmd\n", table.hcmd);
	IWL_ERR(priv, "0x%08X | isr0\n", table.isr0);
	IWL_ERR(priv, "0x%08X | isr1\n", table.isr1);
	IWL_ERR(priv, "0x%08X | isr2\n", table.isr2);
	IWL_ERR(priv, "0x%08X | isr3\n", table.isr3);
	IWL_ERR(priv, "0x%08X | isr4\n", table.isr4);
	IWL_ERR(priv, "0x%08X | isr_pref\n", table.isr_pref);
	IWL_ERR(priv, "0x%08X | wait_event\n", table.wait_event);
	IWL_ERR(priv, "0x%08X | l2p_control\n", table.l2p_control);
	IWL_ERR(priv, "0x%08X | l2p_duration\n", table.l2p_duration);
	IWL_ERR(priv, "0x%08X | l2p_mhvalid\n", table.l2p_mhvalid);
	IWL_ERR(priv, "0x%08X | l2p_addr_match\n", table.l2p_addr_match);
	IWL_ERR(priv, "0x%08X | lmpm_pmg_sel\n", table.lmpm_pmg_sel);
	IWL_ERR(priv, "0x%08X | timestamp\n", table.u_timestamp);
	IWL_ERR(priv, "0x%08X | flow_handler\n", table.flow_handler);
}

#define EVENT_START_OFFSET  (4 * sizeof(u32))

/**
 * iwl_print_event_log - Dump error event log to syslog
 *
 */
static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
			       u32 num_events, u32 mode,
			       int pos, char **buf, size_t bufsz)
{
	u32 i;
	u32 base;       /* SRAM byte address of event log header */
	u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
	u32 ptr;        /* SRAM byte address of log data */
	u32 ev, time, data; /* event log data */
	unsigned long reg_flags;

1698
	struct iwl_trans *trans = priv->trans;
1699 1700 1701 1702 1703

	if (num_events == 0)
		return pos;

	base = priv->device_pointers.log_event_table;
1704
	if (priv->cur_ucode == IWL_UCODE_INIT) {
1705
		if (!base)
1706
			base = priv->fw->init_evtlog_ptr;
1707 1708
	} else {
		if (!base)
1709
			base = priv->fw->inst_evtlog_ptr;
1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720
	}

	if (mode == 0)
		event_size = 2 * sizeof(u32);
	else
		event_size = 3 * sizeof(u32);

	ptr = base + EVENT_START_OFFSET + (start_idx * event_size);

	/* Make sure device is powered up for SRAM reads */
	spin_lock_irqsave(&trans->reg_lock, reg_flags);
1721
	if (!iwl_trans_grab_nic_access(trans, false))
1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759
		goto out_unlock;

	/* Set starting address; reads will auto-increment */
	iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr);

	/* "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++) {
		ev = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
		time = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
		if (mode == 0) {
			/* data, ev */
			if (bufsz) {
				pos += scnprintf(*buf + pos, bufsz - pos,
						"EVT_LOG:0x%08x:%04u\n",
						time, ev);
			} else {
				trace_iwlwifi_dev_ucode_event(trans->dev, 0,
					time, ev);
				IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n",
					time, ev);
			}
		} else {
			data = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
			if (bufsz) {
				pos += scnprintf(*buf + pos, bufsz - pos,
						"EVT_LOGT:%010u:0x%08x:%04u\n",
						 time, data, ev);
			} else {
				IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
					time, data, ev);
				trace_iwlwifi_dev_ucode_event(trans->dev, time,
					data, ev);
			}
		}
	}

	/* Allow device to power down */
1760
	iwl_trans_release_nic_access(trans);
1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815
out_unlock:
	spin_unlock_irqrestore(&trans->reg_lock, reg_flags);
	return pos;
}

/**
 * iwl_print_last_event_logs - Dump the newest # of event log to syslog
 */
static int iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
				    u32 num_wraps, u32 next_entry,
				    u32 size, u32 mode,
				    int pos, char **buf, size_t bufsz)
{
	/*
	 * display the newest DEFAULT_LOG_ENTRIES entries
	 * i.e the entries just before the next ont that uCode would fill.
	 */
	if (num_wraps) {
		if (next_entry < size) {
			pos = iwl_print_event_log(priv,
						capacity - (size - next_entry),
						size - next_entry, mode,
						pos, buf, bufsz);
			pos = iwl_print_event_log(priv, 0,
						  next_entry, mode,
						  pos, buf, bufsz);
		} else
			pos = iwl_print_event_log(priv, next_entry - size,
						  size, mode, pos, buf, bufsz);
	} else {
		if (next_entry < size) {
			pos = iwl_print_event_log(priv, 0, next_entry,
						  mode, pos, buf, bufsz);
		} else {
			pos = iwl_print_event_log(priv, next_entry - size,
						  size, mode, pos, buf, bufsz);
		}
	}
	return pos;
}

#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20)

int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
			    char **buf, bool display)
{
	u32 base;       /* SRAM byte address of event log header */
	u32 capacity;   /* event log capacity in # entries */
	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 */
	u32 size;       /* # entries that we'll print */
	u32 logsize;
	int pos = 0;
	size_t bufsz = 0;
1816
	struct iwl_trans *trans = priv->trans;
1817 1818

	base = priv->device_pointers.log_event_table;
1819
	if (priv->cur_ucode == IWL_UCODE_INIT) {
1820
		logsize = priv->fw->init_evtlog_size;
1821
		if (!base)
1822
			base = priv->fw->init_evtlog_ptr;
1823
	} else {
1824
		logsize = priv->fw->inst_evtlog_size;
1825
		if (!base)
1826
			base = priv->fw->inst_evtlog_ptr;
1827 1828 1829 1830 1831 1832
	}

	if (!iwlagn_hw_valid_rtc_data_addr(base)) {
		IWL_ERR(priv,
			"Invalid event log pointer 0x%08X for %s uCode\n",
			base,
1833
			(priv->cur_ucode == IWL_UCODE_INIT)
1834 1835 1836 1837 1838
					? "Init" : "RT");
		return -EINVAL;
	}

	/* event log header */
1839 1840 1841 1842
	capacity = iwl_trans_read_mem32(trans, base);
	mode = iwl_trans_read_mem32(trans, base + (1 * sizeof(u32)));
	num_wraps = iwl_trans_read_mem32(trans, base + (2 * sizeof(u32)));
	next_entry = iwl_trans_read_mem32(trans, base + (3 * sizeof(u32)));
1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909

	if (capacity > logsize) {
		IWL_ERR(priv, "Log capacity %d is bogus, limit to %d "
			"entries\n", capacity, logsize);
		capacity = logsize;
	}

	if (next_entry > logsize) {
		IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n",
			next_entry, logsize);
		next_entry = logsize;
	}

	size = num_wraps ? capacity : next_entry;

	/* bail out if nothing in log */
	if (size == 0) {
		IWL_ERR(trans, "Start IWL Event Log Dump: nothing in log\n");
		return pos;
	}

#ifdef CONFIG_IWLWIFI_DEBUG
	if (!(iwl_have_debug_level(IWL_DL_FW_ERRORS)) && !full_log)
		size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES)
			? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size;
#else
	size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES)
		? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size;
#endif
	IWL_ERR(priv, "Start IWL Event Log Dump: display last %u entries\n",
		size);

#ifdef CONFIG_IWLWIFI_DEBUG
	if (display) {
		if (full_log)
			bufsz = capacity * 48;
		else
			bufsz = size * 48;
		*buf = kmalloc(bufsz, GFP_KERNEL);
		if (!*buf)
			return -ENOMEM;
	}
	if (iwl_have_debug_level(IWL_DL_FW_ERRORS) || full_log) {
		/*
		 * if uCode has wrapped back to top of log,
		 * start at the oldest entry,
		 * i.e the next one that uCode would fill.
		 */
		if (num_wraps)
			pos = iwl_print_event_log(priv, next_entry,
						capacity - next_entry, mode,
						pos, buf, bufsz);
		/* (then/else) start at top of log */
		pos = iwl_print_event_log(priv, 0,
					  next_entry, mode, pos, buf, bufsz);
	} else
		pos = iwl_print_last_event_logs(priv, capacity, num_wraps,
						next_entry, size, mode,
						pos, buf, bufsz);
#else
	pos = iwl_print_last_event_logs(priv, capacity, num_wraps,
					next_entry, size, mode,
					pos, buf, bufsz);
#endif
	return pos;
}

1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953
static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
{
	unsigned int reload_msec;
	unsigned long reload_jiffies;

#ifdef CONFIG_IWLWIFI_DEBUG
	if (iwl_have_debug_level(IWL_DL_FW_ERRORS))
		iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS);
#endif

	/* uCode is no longer loaded. */
	priv->ucode_loaded = false;

	/* Set the FW error flag -- cleared on iwl_down */
	set_bit(STATUS_FW_ERROR, &priv->status);

	iwl_abort_notification_waits(&priv->notif_wait);

	/* Keep the restart process from trying to send host
	 * commands by clearing the ready bit */
	clear_bit(STATUS_READY, &priv->status);

	if (!ondemand) {
		/*
		 * If firmware keep reloading, then it indicate something
		 * serious wrong and firmware having problem to recover
		 * from it. Instead of keep trying which will fill the syslog
		 * and hang the system, let's just stop it
		 */
		reload_jiffies = jiffies;
		reload_msec = jiffies_to_msecs((long) reload_jiffies -
					(long) priv->reload_jiffies);
		priv->reload_jiffies = reload_jiffies;
		if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
			priv->reload_count++;
			if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
				IWL_ERR(priv, "BUG_ON, Stop restarting\n");
				return;
			}
		} else
			priv->reload_count = 0;
	}

	if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
1954
		if (iwlwifi_mod_params.restart_fw) {
1955 1956 1957 1958 1959 1960 1961 1962 1963
			IWL_DEBUG_FW_ERRORS(priv,
				  "Restarting adapter due to uCode error.\n");
			queue_work(priv->workqueue, &priv->restart);
		} else
			IWL_DEBUG_FW_ERRORS(priv,
				  "Detected FW error, but not restarting\n");
	}
}

1964
static void iwl_nic_error(struct iwl_op_mode *op_mode)
1965 1966 1967
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

1968
	IWL_ERR(priv, "Loaded firmware version: %s\n",
1969
		priv->fw->fw_version);
1970 1971 1972 1973

	iwl_dump_nic_error_log(priv);
	iwl_dump_nic_event_log(priv, false, NULL, false);

1974 1975 1976
	iwlagn_fw_error(priv, false);
}

1977
static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode)
1978 1979 1980 1981 1982
{
	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");
1983
		iwlagn_fw_error(priv, false);
1984 1985 1986
	}
}

1987 1988
#define EEPROM_RF_CONFIG_TYPE_MAX      0x3

1989
static void iwl_nic_config(struct iwl_op_mode *op_mode)
J
Johannes Berg 已提交
1990 1991 1992
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

1993
	/* SKU Control */
1994 1995 1996 1997 1998 1999 2000
	iwl_trans_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG,
				CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
				CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP,
				(CSR_HW_REV_STEP(priv->trans->hw_rev) <<
					CSR_HW_IF_CONFIG_REG_POS_MAC_STEP) |
				(CSR_HW_REV_DASH(priv->trans->hw_rev) <<
					CSR_HW_IF_CONFIG_REG_POS_MAC_DASH));
2001

2002
	/* write radio config values to register */
2003
	if (priv->nvm_data->radio_cfg_type <= EEPROM_RF_CONFIG_TYPE_MAX) {
2004
		u32 reg_val =
2005
			priv->nvm_data->radio_cfg_type <<
2006
				CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE |
2007
			priv->nvm_data->radio_cfg_step <<
2008
				CSR_HW_IF_CONFIG_REG_POS_PHY_STEP |
2009
			priv->nvm_data->radio_cfg_dash <<
2010 2011
				CSR_HW_IF_CONFIG_REG_POS_PHY_DASH;

2012 2013 2014 2015 2016
		iwl_trans_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG,
					CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE |
					CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP |
					CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH,
					reg_val);
2017 2018

		IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n",
2019 2020 2021
			 priv->nvm_data->radio_cfg_type,
			 priv->nvm_data->radio_cfg_step,
			 priv->nvm_data->radio_cfg_dash);
2022 2023 2024 2025 2026 2027 2028 2029 2030
	} else {
		WARN_ON(1);
	}

	/* set CSR_HW_CONFIG_REG for uCode use */
	iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG,
		    CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
		    CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);

2031 2032 2033 2034 2035 2036 2037 2038 2039 2040
	/* W/A : NIC is stuck in a reset state after Early PCIe power off
	 * (PCIe power is lost before PERST# is asserted),
	 * causing ME FW to lose ownership and not being able to obtain it back.
	 */
	iwl_set_bits_mask_prph(priv->trans, APMG_PS_CTRL_REG,
			       APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
			       ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);

	if (priv->lib->nic_config)
		priv->lib->nic_config(priv);
J
Johannes Berg 已提交
2041 2042
}

2043 2044 2045 2046 2047 2048 2049 2050
static void iwl_wimax_active(struct iwl_op_mode *op_mode)
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

	clear_bit(STATUS_READY, &priv->status);
	IWL_ERR(priv, "RF is used by WiMAX\n");
}

2051
static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue)
2052 2053
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2054
	int mq = priv->queue_to_mac80211[queue];
2055

2056
	if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE))
2057 2058
		return;

2059
	if (atomic_inc_return(&priv->queue_stop_count[mq]) > 1) {
2060
		IWL_DEBUG_TX_QUEUES(priv,
2061 2062
			"queue %d (mac80211 %d) already stopped\n",
			queue, mq);
2063 2064
		return;
	}
2065

2066 2067
	set_bit(mq, &priv->transport_queue_stop);
	ieee80211_stop_queue(priv->hw, mq);
2068 2069
}

2070
static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue)
2071 2072
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2073
	int mq = priv->queue_to_mac80211[queue];
2074

2075
	if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE))
2076 2077
		return;

2078
	if (atomic_dec_return(&priv->queue_stop_count[mq]) > 0) {
2079
		IWL_DEBUG_TX_QUEUES(priv,
2080 2081
			"queue %d (mac80211 %d) already awake\n",
			queue, mq);
2082 2083
		return;
	}
2084

2085
	clear_bit(mq, &priv->transport_queue_stop);
2086 2087

	if (!priv->passive_no_rx)
2088
		ieee80211_wake_queue(priv->hw, mq);
2089 2090 2091 2092
}

void iwlagn_lift_passive_no_rx(struct iwl_priv *priv)
{
2093
	int mq;
2094 2095 2096 2097

	if (!priv->passive_no_rx)
		return;

2098 2099 2100 2101
	for (mq = 0; mq < IWLAGN_FIRST_AMPDU_QUEUE; mq++) {
		if (!test_bit(mq, &priv->transport_queue_stop)) {
			IWL_DEBUG_TX_QUEUES(priv, "Wake queue %d", mq);
			ieee80211_wake_queue(priv->hw, mq);
2102
		} else {
2103
			IWL_DEBUG_TX_QUEUES(priv, "Don't wake queue %d", mq);
2104
		}
2105 2106 2107 2108 2109
	}

	priv->passive_no_rx = false;
}

2110
static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
2111
{
2112
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2113 2114 2115
	struct ieee80211_tx_info *info;

	info = IEEE80211_SKB_CB(skb);
2116
	iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]);
J
Johannes Berg 已提交
2117
	ieee80211_free_txskb(priv->hw, skb);
2118 2119
}

2120
static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

	if (state)
		set_bit(STATUS_RF_KILL_HW, &priv->status);
	else
		clear_bit(STATUS_RF_KILL_HW, &priv->status);

	wiphy_rfkill_set_hw_state(priv->hw->wiphy, state);
}

2132
static const struct iwl_op_mode_ops iwl_dvm_ops = {
2133 2134
	.start = iwl_op_mode_dvm_start,
	.stop = iwl_op_mode_dvm_stop,
2135
	.rx = iwl_rx_dispatch,
2136 2137
	.queue_full = iwl_stop_sw_queue,
	.queue_not_full = iwl_wake_sw_queue,
2138
	.hw_rf_kill = iwl_set_hw_rfkill_state,
2139
	.free_skb = iwl_free_skb,
2140
	.nic_error = iwl_nic_error,
2141
	.cmd_queue_full = iwl_cmd_queue_full,
J
Johannes Berg 已提交
2142
	.nic_config = iwl_nic_config,
2143
	.wimax_active = iwl_wimax_active,
2144
};
Z
Zhu Yi 已提交
2145 2146 2147 2148 2149 2150

/*****************************************************************************
 *
 * driver and module entry point
 *
 *****************************************************************************/
2151
static int __init iwl_init(void)
Z
Zhu Yi 已提交
2152 2153 2154
{

	int ret;
2155

2156
	ret = iwlagn_rate_control_register();
2157
	if (ret) {
2158
		pr_err("Unable to register rate control algorithm: %d\n", ret);
2159
		return ret;
2160 2161
	}

2162 2163 2164
	ret = iwl_opmode_register("iwldvm", &iwl_dvm_ops);
	if (ret) {
		pr_err("Unable to register op_mode: %d\n", ret);
2165
		iwlagn_rate_control_unregister();
2166
	}
2167 2168

	return ret;
Z
Zhu Yi 已提交
2169
}
2170
module_init(iwl_init);
Z
Zhu Yi 已提交
2171

2172
static void __exit iwl_exit(void)
Z
Zhu Yi 已提交
2173
{
2174
	iwl_opmode_deregister("iwldvm");
2175
	iwlagn_rate_control_unregister();
Z
Zhu Yi 已提交
2176
}
2177
module_exit(iwl_exit);