main.c 60.9 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
 * 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

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

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

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

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

76
#define DRV_VERSION     IWLWIFI_VERSION VD
Z
Zhu Yi 已提交
77 78 79 80


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

84 85
static const struct iwl_op_mode_ops iwl_dvm_ops;

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

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

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

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

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

141
	lockdep_assert_held(&priv->mutex);
142 143 144

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

148 149 150
	if (WARN_ON(!priv->beacon_skb))
		return -EINVAL;

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

	frame_size = priv->beacon_skb->len;
159

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

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

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

185
	priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
186
					      priv->eeprom_data->valid_tx_ant);
187
	rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
188 189 190 191 192

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

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

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

206
	return iwl_dvm_send_cmd(priv, &cmd);
207 208
}

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

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

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

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

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

241
	priv->beacon_skb = beacon;
Z
Zhu Yi 已提交
242

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

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

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

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

268
	mutex_lock(&priv->mutex);
269

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

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

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

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

295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
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);
}

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

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

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

335
	iwl_send_statistics_request(priv, CMD_ASYNC, false);
336 337
}

338 339 340

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

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

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

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

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

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

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

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

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

449
		trace_iwlwifi_dev_ucode_wrap_event(priv->trans->dev,
450 451
				num_wraps - priv->event_log.num_wraps,
				next_entry, priv->event_log.next_entry);
J
Johannes Berg 已提交
452

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

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

J
Johannes Berg 已提交
467 468
			iwl_print_cont_event_trace(
				priv, base, 0, next_entry, capacity, mode);
469 470
		}
	}
J
Johannes Berg 已提交
471

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

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

	/* do nothing if rf-kill is on */
D
Don Fry 已提交
508
	if (!iwl_is_ready_rf(priv))
509 510
		return;

511 512
	IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n");
	iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL);
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 578 579 580 581 582 583
/*
 * 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,
};

584
static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
585 586 587 588 589 590 591
{
	int i;

	/*
	 * The default context is always valid,
	 * the PAN context depends on uCode.
	 */
592
	priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
593
	if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN)
594
		priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
595 596 597 598 599 600 601 602 603 604 605 606

	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;
607
	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
608
	priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
609
		BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MONITOR);
610 611 612 613 614 615
	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;
616 617 618 619
	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));
620 621 622 623 624 625 626 627 628 629 630 631 632

	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);
633 634 635 636 637 638

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

639 640 641
	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;
642 643 644 645 646
	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;
647 648 649 650

	BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
}

651
static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
652 653 654 655 656
{
	struct iwl_ct_kill_config cmd;
	struct iwl_ct_kill_throttling_config adv_cmd;
	int ret = 0;

657
	iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR,
658
		    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
J
Johannes Berg 已提交
659

660 661
	priv->thermal_throttle.ct_kill_toggle = false;

662
	if (priv->cfg->base_params->support_ct_kill_exit) {
663
		adv_cmd.critical_temperature_enter =
664
			cpu_to_le32(priv->hw_params.ct_kill_threshold);
665
		adv_cmd.critical_temperature_exit =
666
			cpu_to_le32(priv->hw_params.ct_kill_exit_threshold);
667

668
		ret = iwl_dvm_send_cmd_pdu(priv,
669 670
				       REPLY_CT_KILL_CONFIG_CMD,
				       CMD_SYNC, sizeof(adv_cmd), &adv_cmd);
671 672 673 674
		if (ret)
			IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
		else
			IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
675 676
				"succeeded, critical temperature enter is %d,"
				"exit is %d\n",
677 678
				priv->hw_params.ct_kill_threshold,
				priv->hw_params.ct_kill_exit_threshold);
679 680
	} else {
		cmd.critical_temperature_R =
681
			cpu_to_le32(priv->hw_params.ct_kill_threshold);
682

683
		ret = iwl_dvm_send_cmd_pdu(priv,
684 685
				       REPLY_CT_KILL_CONFIG_CMD,
				       CMD_SYNC, sizeof(cmd), &cmd);
686 687 688 689
		if (ret)
			IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
		else
			IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
690 691
				"succeeded, "
				"critical temperature is %d\n",
692
				priv->hw_params.ct_kill_threshold);
693 694 695
	}
}

696 697 698 699 700
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,
701 702
		.len = { sizeof(struct iwl_calib_cfg_cmd), },
		.data = { &calib_cfg_cmd, },
703 704 705
	};

	memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
706
	calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_RT_CFG_ALL;
707
	calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg);
708

709
	return iwl_dvm_send_cmd(priv, &cmd);
710 711 712
}


W
Wey-Yi Guy 已提交
713 714 715 716 717 718
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),
	};

719
	if (IWL_UCODE_API(priv->fw->ucode_ver) > 1) {
W
Wey-Yi Guy 已提交
720
		IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
721
		return iwl_dvm_send_cmd_pdu(priv,
W
Wey-Yi Guy 已提交
722 723 724 725 726 727 728 729 730 731
					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;
	}
}

732
static void iwl_send_bt_config(struct iwl_priv *priv)
733 734 735 736 737 738 739 740
{
	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,
	};

741
	if (!iwlwifi_mod_params.bt_coex_active)
742 743 744 745 746 747 748 749 750 751 752 753 754
		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 已提交
755
/**
756
 * iwl_alive_start - called after REPLY_ALIVE notification received
Z
Zhu Yi 已提交
757
 *                   from protocol/runtime uCode (initialization uCode's
758
 *                   Alive gets handled by iwl_init_alive_start()).
Z
Zhu Yi 已提交
759
 */
760
int iwl_alive_start(struct iwl_priv *priv)
Z
Zhu Yi 已提交
761
{
762
	int ret = 0;
763
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
Z
Zhu Yi 已提交
764

765
	IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
766

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

D
Don Fry 已提交
770
	if (iwl_is_rfkill(priv))
771
		return -ERFKILL;
Z
Zhu Yi 已提交
772

J
Johannes Berg 已提交
773 774 775 776 777
	if (priv->event_log.ucode_trace) {
		/* start collecting data now */
		mod_timer(&priv->ucode_trace, jiffies);
	}

778
	/* download priority table before any calibration request */
779 780
	if (priv->cfg->bt_params &&
	    priv->cfg->bt_params->advanced_bt_coexist) {
781
		/* Configure Bluetooth device coexistence support */
782
		if (priv->cfg->bt_params->bt_sco_disable)
783 784 785 786
			priv->bt_enable_pspoll = false;
		else
			priv->bt_enable_pspoll = true;

787 788 789
		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 已提交
790
		iwlagn_send_advance_bt_config(priv);
791
		priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
792 793
		priv->cur_rssi_ctx = NULL;

794
		iwl_send_prio_tbl(priv);
795 796

		/* FIXME: w/a to force change uCode BT state machine */
797
		ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
798 799 800
					 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
		if (ret)
			return ret;
801
		ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
802 803 804
					 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
		if (ret)
			return ret;
W
Wey-Yi Guy 已提交
805 806 807 808 809
	} else {
		/*
		 * default is 2-wire BT coexexistence support
		 */
		iwl_send_bt_config(priv);
810
	}
W
Wey-Yi Guy 已提交
811

812 813 814 815
	/*
	 * Perform runtime calibrations, including DC calibration.
	 */
	iwlagn_send_calib_cfg_rt(priv, IWL_CALIB_CFG_DC_IDX);
816

817
	ieee80211_wake_queues(priv->hw);
Z
Zhu Yi 已提交
818

819
	/* Configure Tx antenna selection based on H/W config */
820
	iwlagn_send_tx_ant_config(priv, priv->eeprom_data->valid_tx_ant);
821

822
	if (iwl_is_associated_ctx(ctx) && !priv->wowlan) {
G
Gregory Greenman 已提交
823
		struct iwl_rxon_cmd *active_rxon =
824
				(struct iwl_rxon_cmd *)&ctx->active;
825
		/* apply any changes in staging */
826
		ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
Z
Zhu Yi 已提交
827 828
		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
	} else {
829
		struct iwl_rxon_context *tmp;
Z
Zhu Yi 已提交
830
		/* Initialize our rx_config data */
831 832
		for_each_context(priv, tmp)
			iwl_connection_init_rx_config(priv, tmp);
833

W
Wey-Yi Guy 已提交
834
		iwlagn_set_rxon_chain(priv, ctx);
Z
Zhu Yi 已提交
835 836
	}

837
	if (!priv->wowlan) {
J
Johannes Berg 已提交
838 839 840
		/* WoWLAN ucode will not reply in the same way, skip it */
		iwl_reset_run_time_calib(priv);
	}
841

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

Z
Zhu Yi 已提交
844
	/* Configure the adapter for unassociated operation */
845
	ret = iwlagn_commit_rxon(priv, ctx);
846 847
	if (ret)
		return ret;
Z
Zhu Yi 已提交
848 849

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

852
	IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
853

854
	return iwl_power_update_mode(priv, true);
Z
Zhu Yi 已提交
855 856
}

857 858 859 860 861 862 863 864 865 866 867 868 869
/**
 * 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;

870
	spin_lock_bh(&priv->sta_lock);
871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887
	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;
	}

888
	spin_unlock_bh(&priv->sta_lock);
889 890
}

891
void iwl_down(struct iwl_priv *priv)
Z
Zhu Yi 已提交
892
{
893
	int exit_pending;
Z
Zhu Yi 已提交
894

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

897
	lockdep_assert_held(&priv->mutex);
898

899 900
	iwl_scan_cancel_timeout(priv, 200);

901 902 903 904 905 906 907
	/*
	 * 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);

908
	exit_pending =
D
Don Fry 已提交
909
		test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
Z
Zhu Yi 已提交
910

911
	iwl_clear_ucode_stations(priv, NULL);
912
	iwl_dealloc_bcast_stations(priv);
913
	iwl_clear_driver_stations(priv);
Z
Zhu Yi 已提交
914

915
	/* reset BT coex data */
916
	priv->bt_status = 0;
917 918
	priv->cur_rssi_ctx = NULL;
	priv->bt_is_sco = 0;
919
	if (priv->cfg->bt_params)
920
		priv->bt_traffic_load =
921
			 priv->cfg->bt_params->bt_init_traffic_load;
922 923
	else
		priv->bt_traffic_load = 0;
924 925
	priv->bt_full_concurrent = false;
	priv->bt_ci_compliance = 0;
926

Z
Zhu Yi 已提交
927 928 929
	/* Wipe out the EXIT_PENDING status bit if we are not actually
	 * exiting the module */
	if (!exit_pending)
D
Don Fry 已提交
930
		clear_bit(STATUS_EXIT_PENDING, &priv->status);
Z
Zhu Yi 已提交
931

932
	if (priv->mac80211_registered)
Z
Zhu Yi 已提交
933 934
		ieee80211_stop_queues(priv->hw);

935
	priv->ucode_loaded = false;
936
	iwl_trans_stop_device(priv->trans);
937

938 939 940
	/* Set num_aux_in_flight must be done after the transport is stopped */
	atomic_set(&priv->num_aux_in_flight, 0);

J
Johannes Berg 已提交
941
	/* Clear out all status bits but a few that are stable across reset */
942
	priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
Z
Zhu Yi 已提交
943
				STATUS_RF_KILL_HW |
D
Don Fry 已提交
944 945
			test_bit(STATUS_FW_ERROR, &priv->status) <<
				STATUS_FW_ERROR |
D
Don Fry 已提交
946
			test_bit(STATUS_EXIT_PENDING, &priv->status) <<
947
				STATUS_EXIT_PENDING;
Z
Zhu Yi 已提交
948

949
	dev_kfree_skb(priv->beacon_skb);
950
	priv->beacon_skb = NULL;
Z
Zhu Yi 已提交
951 952 953 954 955 956 957 958
}

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

959 960 961 962 963
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);

964
	mutex_lock(&priv->mutex);
965

D
Don Fry 已提交
966 967
	if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
	    test_bit(STATUS_SCANNING, &priv->status)) {
968
		mutex_unlock(&priv->mutex);
969 970 971 972
		return;
	}

	if (priv->start_calib) {
973 974
		iwl_chain_noise_calibration(priv);
		iwl_sensitivity_calibration(priv);
975 976
	}

977
	mutex_unlock(&priv->mutex);
978 979
}

980
void iwlagn_prepare_restart(struct iwl_priv *priv)
J
Johannes Berg 已提交
981 982 983 984 985
{
	bool bt_full_concurrent;
	u8 bt_ci_compliance;
	u8 bt_load;
	u8 bt_status;
986
	bool bt_is_sco;
987
	int i;
J
Johannes Berg 已提交
988

989
	lockdep_assert_held(&priv->mutex);
J
Johannes Berg 已提交
990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005

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

1008
	iwl_down(priv);
J
Johannes Berg 已提交
1009 1010 1011 1012 1013

	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;
1014
	priv->bt_is_sco = bt_is_sco;
1015

1016
	/* reset aggregation queues */
1017
	for (i = IWLAGN_FIRST_AMPDU_QUEUE; i < IWL_MAX_HW_QUEUES; i++)
1018 1019 1020 1021
		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);
1022 1023

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

1026
static void iwl_bg_restart(struct work_struct *data)
Z
Zhu Yi 已提交
1027
{
1028
	struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
Z
Zhu Yi 已提交
1029

D
Don Fry 已提交
1030
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
Z
Zhu Yi 已提交
1031 1032
		return;

D
Don Fry 已提交
1033
	if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
1034
		mutex_lock(&priv->mutex);
J
Johannes Berg 已提交
1035
		iwlagn_prepare_restart(priv);
1036
		mutex_unlock(&priv->mutex);
1037
		iwl_cancel_deferred_work(priv);
J
Johannes Berg 已提交
1038 1039
		ieee80211_restart_hw(priv->hw);
	} else {
1040
		WARN_ON(1);
J
Johannes Berg 已提交
1041
	}
Z
Zhu Yi 已提交
1042 1043
}

1044 1045 1046



1047
void iwlagn_disable_roc(struct iwl_priv *priv)
1048
{
1049
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
1050

1051
	lockdep_assert_held(&priv->mutex);
1052

1053 1054
	if (!priv->hw_roc_setup)
		return;
1055

1056 1057
	ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
	ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1058

1059
	priv->hw_roc_channel = NULL;
1060

1061
	memset(ctx->staging.node_addr, 0, ETH_ALEN);
1062

1063
	iwlagn_commit_rxon(priv, ctx);
1064

1065 1066
	ctx->is_active = false;
	priv->hw_roc_setup = false;
1067 1068
}

1069
static void iwlagn_disable_roc_work(struct work_struct *work)
Z
Zhu Yi 已提交
1070
{
1071 1072
	struct iwl_priv *priv = container_of(work, struct iwl_priv,
					     hw_roc_disable_work.work);
Z
Zhu Yi 已提交
1073

1074
	mutex_lock(&priv->mutex);
1075
	iwlagn_disable_roc(priv);
1076
	mutex_unlock(&priv->mutex);
Z
Zhu Yi 已提交
1077 1078
}

1079 1080 1081 1082 1083 1084
/*****************************************************************************
 *
 * driver setup and teardown
 *
 *****************************************************************************/

1085
static void iwl_setup_deferred_work(struct iwl_priv *priv)
Z
Zhu Yi 已提交
1086
{
J
Johannes Berg 已提交
1087
	priv->workqueue = create_singlethread_workqueue(DRV_NAME);
Z
Zhu Yi 已提交
1088

1089 1090 1091 1092 1093 1094 1095 1096
	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);
1097

1098
	iwl_setup_scan_deferred_work(priv);
1099

1100
	if (priv->cfg->bt_params)
1101
		iwlagn_bt_setup_deferred_work(priv);
1102

1103 1104 1105
	init_timer(&priv->statistics_periodic);
	priv->statistics_periodic.data = (unsigned long)priv;
	priv->statistics_periodic.function = iwl_bg_statistics_periodic;
1106

1107 1108 1109
	init_timer(&priv->ucode_trace);
	priv->ucode_trace.data = (unsigned long)priv;
	priv->ucode_trace.function = iwl_bg_ucode_trace;
Z
Zhu Yi 已提交
1110 1111
}

1112
void iwl_cancel_deferred_work(struct iwl_priv *priv)
J
Johannes Berg 已提交
1113
{
1114
	if (priv->cfg->bt_params)
1115
		iwlagn_bt_cancel_deferred_work(priv);
J
Johannes Berg 已提交
1116

1117 1118
	cancel_work_sync(&priv->run_time_calib_work);
	cancel_work_sync(&priv->beacon_update);
J
Johannes Berg 已提交
1119

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

1122 1123 1124
	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 已提交
1125

1126 1127 1128
	del_timer_sync(&priv->statistics_periodic);
	del_timer_sync(&priv->ucode_trace);
}
J
Johannes Berg 已提交
1129

1130
static int iwl_init_drv(struct iwl_priv *priv)
J
Johannes Berg 已提交
1131
{
1132
	spin_lock_init(&priv->sta_lock);
J
Johannes Berg 已提交
1133

1134
	mutex_init(&priv->mutex);
J
Johannes Berg 已提交
1135

1136
	INIT_LIST_HEAD(&priv->calib_results);
1137

1138
	priv->band = IEEE80211_BAND_2GHZ;
J
Johannes Berg 已提交
1139

1140
	priv->plcp_delta_threshold =
1141
		priv->cfg->base_params->plcp_delta_threshold;
1142

1143 1144 1145 1146
	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 已提交
1147

1148 1149
	priv->ucode_owner = IWL_OWNERSHIP_DRIVER;

1150
	priv->rx_statistics_jiffies = jiffies;
J
Johannes Berg 已提交
1151

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

1155
	iwl_init_scan_params(priv);
J
Johannes Berg 已提交
1156

1157
	/* init bt coex */
1158 1159
	if (priv->cfg->bt_params &&
	    priv->cfg->bt_params->advanced_bt_coexist) {
1160 1161 1162 1163 1164 1165 1166
		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 已提交
1167

1168 1169
	return 0;
}
J
Johannes Berg 已提交
1170

1171
static void iwl_uninit_drv(struct iwl_priv *priv)
1172 1173 1174 1175
{
	kfree(priv->scan_cmd);
	kfree(priv->beacon_cmd);
	kfree(rcu_dereference_raw(priv->noa_data));
1176
	iwl_calib_free_results(priv);
1177 1178 1179 1180
#ifdef CONFIG_IWLWIFI_DEBUGFS
	kfree(priv->wowlan_sram);
#endif
}
J
Johannes Berg 已提交
1181

1182
static void iwl_set_hw_params(struct iwl_priv *priv)
1183
{
1184
	if (priv->cfg->ht_params)
1185
		priv->hw_params.use_rts_for_aggregation =
1186
			priv->cfg->ht_params->use_rts_for_aggregation;
1187

1188
	if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
1189
		priv->hw_params.sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
1190 1191

	/* Device-specific setup */
1192
	priv->lib->set_hw_params(priv);
1193 1194
}

1195 1196


1197
/* show what optional capabilities we have */
1198
static void iwl_option_config(struct iwl_priv *priv)
1199 1200
{
#ifdef CONFIG_IWLWIFI_DEBUG
1201
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUG enabled\n");
1202
#else
1203
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUG disabled\n");
1204
#endif
1205

1206
#ifdef CONFIG_IWLWIFI_DEBUGFS
1207
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUGFS enabled\n");
1208
#else
1209
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUGFS disabled\n");
1210
#endif
1211

1212
#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
1213
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING enabled\n");
1214
#else
1215
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING disabled\n");
1216
#endif
1217

1218
#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
1219
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE enabled\n");
1220
#else
1221
	IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE disabled\n");
1222
#endif
1223

1224
#ifdef CONFIG_IWLWIFI_P2P
1225
	IWL_INFO(priv, "CONFIG_IWLWIFI_P2P enabled\n");
1226
#else
1227
	IWL_INFO(priv, "CONFIG_IWLWIFI_P2P disabled\n");
1228 1229 1230
#endif
}

1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266
static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
{
	u16 radio_cfg;

	priv->hw_params.sku = priv->eeprom_data->sku;

	if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE &&
	    !priv->cfg->ht_params) {
		IWL_ERR(priv, "Invalid 11n configuration\n");
		return -EINVAL;
	}

	if (!priv->hw_params.sku) {
		IWL_ERR(priv, "Invalid device sku\n");
		return -EINVAL;
	}

	IWL_INFO(priv, "Device SKU: 0x%X\n", priv->hw_params.sku);

	radio_cfg = priv->eeprom_data->radio_cfg;

	priv->hw_params.tx_chains_num =
		num_of_ant(priv->eeprom_data->valid_tx_ant);
	if (priv->cfg->rx_with_siso_diversity)
		priv->hw_params.rx_chains_num = 1;
	else
		priv->hw_params.rx_chains_num =
			num_of_ant(priv->eeprom_data->valid_rx_ant);

	IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n",
		 priv->eeprom_data->valid_tx_ant,
		 priv->eeprom_data->valid_rx_ant);

	return 0;
}

1267
static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1268
						 const struct iwl_cfg *cfg,
1269
						 const struct iwl_fw *fw)
1270 1271 1272
{
	struct iwl_priv *priv;
	struct ieee80211_hw *hw;
1273
	struct iwl_op_mode *op_mode;
1274
	u16 num_mac;
1275
	u32 ucode_flags;
1276
	struct iwl_trans_config trans_cfg;
1277 1278 1279 1280 1281 1282 1283 1284
	static const u8 no_reclaim_cmds[] = {
		REPLY_RX_PHY_CMD,
		REPLY_RX,
		REPLY_RX_MPDU_CMD,
		REPLY_COMPRESSED_BA,
		STATISTICS_NOTIFICATION,
		REPLY_TX,
	};
1285
	int i;
1286 1287 1288 1289

	/************************
	 * 1. Allocating HW data
	 ************************/
D
Don Fry 已提交
1290
	hw = iwl_alloc_all();
1291
	if (!hw) {
1292
		pr_err("%s: Cannot allocate network device\n", cfg->name);
1293 1294 1295
		goto out;
	}

1296 1297 1298
	op_mode = hw->priv;
	op_mode->ops = &iwl_dvm_ops;
	priv = IWL_OP_MODE_GET_DVM(op_mode);
1299
	priv->trans = trans;
1300
	priv->dev = trans->dev;
1301
	priv->cfg = cfg;
1302
	priv->fw = fw;
1303

1304
	switch (priv->cfg->device_family) {
1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337
	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 已提交
1338
		goto out_free_hw;
1339

E
Emmanuel Grumbach 已提交
1340 1341 1342 1343 1344
	/*
	 * Populate the state variables that the transport layer needs
	 * to know about.
	 */
	trans_cfg.op_mode = op_mode;
1345 1346
	trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
	trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
1347 1348
	trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K;
	if (!iwlwifi_mod_params.wd_disable)
1349
		trans_cfg.queue_watchdog_timeout =
1350
			priv->cfg->base_params->wd_timeout;
1351
	else
1352
		trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED;
J
Johannes Berg 已提交
1353
	trans_cfg.command_names = iwl_dvm_cmd_strings;
1354

1355 1356 1357
	WARN_ON(sizeof(priv->transport_queue_stop) * BITS_PER_BYTE <
		priv->cfg->base_params->num_of_queues);

1358 1359 1360
	ucode_flags = fw->ucode_capa.flags;

#ifndef CONFIG_IWLWIFI_P2P
1361
	ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
1362
#endif
1363

1364 1365 1366
	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;
1367 1368 1369
		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);
1370 1371 1372
	} else {
		priv->sta_key_max_num = STA_KEY_MAX_NUM;
		trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
1373 1374 1375
		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);
1376 1377
	}

1378
	/* Configure transport layer */
1379
	iwl_trans_configure(priv->trans, &trans_cfg);
1380

1381
	/* At this point both hw and priv are allocated. */
1382

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

1385
	iwl_option_config(priv);
1386

1387
	IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
1388

1389 1390
	/* is antenna coupling more than 35dB ? */
	priv->bt_ant_couple_ok =
1391
		(iwlwifi_mod_params.ant_coupling >
1392 1393
			IWL_BT_ANTENNA_COUPLING_THRESHOLD) ?
			true : false;
1394

1395
	/* enable/disable bt channel inhibition */
1396
	priv->bt_ch_announce = iwlwifi_mod_params.bt_ch_announce;
1397 1398
	IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n",
		       (priv->bt_ch_announce) ? "On" : "Off");
1399

1400
	/* these spin locks will be used in apm_ops.init and EEPROM access
M
Mohamed Abbas 已提交
1401 1402
	 * we should init now
	 */
1403
	spin_lock_init(&priv->statistics.lock);
1404

1405
	/***********************
E
Emmanuel Grumbach 已提交
1406
	 * 2. Read REV register
1407
	 ***********************/
1408
	IWL_INFO(priv, "Detected %s, REV=0x%X\n",
1409
		priv->cfg->name, priv->trans->hw_rev);
1410

1411
	if (iwl_trans_start_hw(priv->trans))
J
Johannes Berg 已提交
1412
		goto out_free_hw;
1413

W
Wey-Yi Guy 已提交
1414
	/* Read the EEPROM */
1415 1416
	if (iwl_read_eeprom(priv->trans, &priv->eeprom_blob,
			    &priv->eeprom_blob_size)) {
1417
		IWL_ERR(priv, "Unable to init EEPROM\n");
J
Johannes Berg 已提交
1418
		goto out_free_hw;
1419
	}
1420

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

1424 1425 1426 1427 1428 1429 1430
	priv->eeprom_data = iwl_parse_eeprom_data(priv->trans->dev, priv->cfg,
						  priv->eeprom_blob,
						  priv->eeprom_blob_size);
	if (!priv->eeprom_data)
		goto out_free_eeprom_blob;

	if (iwl_eeprom_check_version(priv->eeprom_data, priv->trans))
1431
		goto out_free_eeprom;
1432

W
Wey-Yi Guy 已提交
1433
	if (iwl_eeprom_init_hw_params(priv))
1434 1435
		goto out_free_eeprom;

1436
	/* extract MAC Address */
1437
	memcpy(priv->addresses[0].addr, priv->eeprom_data->hw_addr, ETH_ALEN);
1438 1439 1440
	IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr);
	priv->hw->wiphy->addresses = priv->addresses;
	priv->hw->wiphy->n_addresses = 1;
1441
	num_mac = priv->eeprom_data->n_hw_addrs;
1442 1443 1444 1445 1446 1447
	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++;
	}
1448

E
Emmanuel Grumbach 已提交
1449 1450 1451 1452 1453
	/************************
	 * 4. Setup HW constants
	 ************************/
	iwl_set_hw_params(priv);

1454
	if (!(priv->hw_params.sku & EEPROM_SKU_CAP_IPAN_ENABLE)) {
E
Emmanuel Grumbach 已提交
1455 1456 1457 1458 1459 1460 1461 1462 1463
		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;
1464 1465 1466
		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);
E
Emmanuel Grumbach 已提交
1467 1468

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

1472
	/*******************
E
Emmanuel Grumbach 已提交
1473
	 * 5. Setup priv
1474
	 *******************/
1475
	for (i = 0; i < IWL_MAX_HW_QUEUES; i++) {
1476 1477 1478 1479 1480 1481
		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);
1482 1483 1484 1485
	}

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

W
Wey-Yi Guy 已提交
1487
	if (iwl_init_drv(priv))
R
Ron Rindjunsky 已提交
1488
		goto out_free_eeprom;
W
Wey-Yi Guy 已提交
1489

1490
	/* At this point both hw and priv are initialized. */
1491 1492

	/********************
E
Emmanuel Grumbach 已提交
1493
	 * 6. Setup services
1494
	 ********************/
1495
	iwl_setup_deferred_work(priv);
1496
	iwl_setup_rx_handlers(priv);
1497
	iwl_testmode_init(priv);
1498

1499
	iwl_power_initialize(priv);
1500
	iwl_tt_initialize(priv);
J
Johannes Berg 已提交
1501

1502 1503 1504 1505 1506
	snprintf(priv->hw->wiphy->fw_version,
		 sizeof(priv->hw->wiphy->fw_version),
		 "%s", fw->fw_version);

	priv->new_scan_threshold_behaviour =
1507
		!!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
1508

1509 1510 1511 1512 1513 1514
	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 */
1515
	iwl_init_context(priv, ucode_flags);
1516 1517 1518 1519

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

W
Wey-Yi Guy 已提交
1525
	if (iwl_dbgfs_register(priv, DRV_NAME))
1526
		IWL_ERR(priv,
W
Wey-Yi Guy 已提交
1527
			"failed to create debugfs files. Ignoring error\n");
1528

1529
	return op_mode;
Z
Zhu Yi 已提交
1530

1531
out_destroy_workqueue:
J
Johannes Berg 已提交
1532 1533
	destroy_workqueue(priv->workqueue);
	priv->workqueue = NULL;
T
Tomas Winkler 已提交
1534
	iwl_uninit_drv(priv);
1535 1536
out_free_eeprom_blob:
	kfree(priv->eeprom_blob);
1537
out_free_eeprom:
1538
	iwl_free_eeprom_data(priv->eeprom_data);
J
Johannes Berg 已提交
1539
out_free_hw:
1540
	ieee80211_free_hw(priv->hw);
1541
out:
1542 1543
	op_mode = NULL;
	return op_mode;
Z
Zhu Yi 已提交
1544 1545
}

1546
static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
Z
Zhu Yi 已提交
1547
{
1548 1549
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

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

1552 1553
	iwl_dbgfs_unregister(priv);

I
Ilan Peer 已提交
1554
	iwl_testmode_free(priv);
1555
	iwlagn_mac_unregister(priv);
1556

1557 1558
	iwl_tt_exit(priv);

1559
	/*This will stop the queues, move the device to low power state */
1560
	priv->ucode_loaded = false;
1561
	iwl_trans_stop_device(priv->trans);
1562

1563 1564
	kfree(priv->eeprom_blob);
	iwl_free_eeprom_data(priv->eeprom_data);
Z
Zhu Yi 已提交
1565

M
Mohamed Abbas 已提交
1566
	/*netif_stop_queue(dev); */
J
Johannes Berg 已提交
1567
	flush_workqueue(priv->workqueue);
M
Mohamed Abbas 已提交
1568

1569
	/* ieee80211_unregister_hw calls iwlagn_mac_stop, which flushes
J
Johannes Berg 已提交
1570
	 * priv->workqueue... so we can't take down the workqueue
Z
Zhu Yi 已提交
1571
	 * until now... */
J
Johannes Berg 已提交
1572 1573
	destroy_workqueue(priv->workqueue);
	priv->workqueue = NULL;
Z
Zhu Yi 已提交
1574

T
Tomas Winkler 已提交
1575
	iwl_uninit_drv(priv);
Z
Zhu Yi 已提交
1576

1577
	dev_kfree_skb(priv->beacon_skb);
Z
Zhu Yi 已提交
1578

1579
	iwl_trans_stop_hw(priv->trans, true);
Z
Zhu Yi 已提交
1580 1581 1582
	ieee80211_free_hw(priv->hw);
}

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 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653
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)
{
1654
	struct iwl_trans *trans = priv->trans;
1655 1656 1657 1658
	u32 base;
	struct iwl_error_event_table table;

	base = priv->device_pointers.error_event_table;
1659
	if (priv->cur_ucode == IWL_UCODE_INIT) {
1660
		if (!base)
1661
			base = priv->fw->init_errlog_ptr;
1662 1663
	} else {
		if (!base)
1664
			base = priv->fw->inst_errlog_ptr;
1665 1666 1667 1668 1669 1670
	}

	if (!iwlagn_hw_valid_rtc_data_addr(base)) {
		IWL_ERR(priv,
			"Not valid error log pointer 0x%08X for %s uCode\n",
			base,
1671
			(priv->cur_ucode == IWL_UCODE_INIT)
1672 1673 1674 1675 1676
					? "Init" : "RT");
		return;
	}

	/*TODO: Update dbgfs with ISR error stats obtained below */
1677
	iwl_read_targ_mem_bytes(trans, base, &table, sizeof(table));
1678 1679 1680 1681

	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 已提交
1682
			priv->status, table.valid);
1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743
	}

	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;

1744
	struct iwl_trans *trans = priv->trans;
1745 1746 1747 1748 1749

	if (num_events == 0)
		return pos;

	base = priv->device_pointers.log_event_table;
1750
	if (priv->cur_ucode == IWL_UCODE_INIT) {
1751
		if (!base)
1752
			base = priv->fw->init_evtlog_ptr;
1753 1754
	} else {
		if (!base)
1755
			base = priv->fw->inst_evtlog_ptr;
1756 1757 1758 1759 1760 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 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861
	}

	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);
	if (unlikely(!iwl_grab_nic_access(trans)))
		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 */
	iwl_release_nic_access(trans);
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;
1862
	struct iwl_trans *trans = priv->trans;
1863 1864

	base = priv->device_pointers.log_event_table;
1865
	if (priv->cur_ucode == IWL_UCODE_INIT) {
1866
		logsize = priv->fw->init_evtlog_size;
1867
		if (!base)
1868
			base = priv->fw->init_evtlog_ptr;
1869
	} else {
1870
		logsize = priv->fw->inst_evtlog_size;
1871
		if (!base)
1872
			base = priv->fw->inst_evtlog_ptr;
1873 1874 1875 1876 1877 1878
	}

	if (!iwlagn_hw_valid_rtc_data_addr(base)) {
		IWL_ERR(priv,
			"Invalid event log pointer 0x%08X for %s uCode\n",
			base,
1879
			(priv->cur_ucode == IWL_UCODE_INIT)
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 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 1954 1955
					? "Init" : "RT");
		return -EINVAL;
	}

	/* event log header */
	capacity = iwl_read_targ_mem(trans, base);
	mode = iwl_read_targ_mem(trans, base + (1 * sizeof(u32)));
	num_wraps = iwl_read_targ_mem(trans, base + (2 * sizeof(u32)));
	next_entry = iwl_read_targ_mem(trans, base + (3 * sizeof(u32)));

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

1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977
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);

1978
	wake_up(&priv->trans->wait_command_queue);
1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001

	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)) {
2002
		if (iwlwifi_mod_params.restart_fw) {
2003 2004 2005 2006 2007 2008 2009 2010 2011
			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");
	}
}

2012
static void iwl_nic_error(struct iwl_op_mode *op_mode)
2013 2014 2015
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

2016
	IWL_ERR(priv, "Loaded firmware version: %s\n",
2017
		priv->fw->fw_version);
2018 2019 2020 2021

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

2022 2023 2024
	iwlagn_fw_error(priv, false);
}

2025
static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode)
2026 2027 2028 2029 2030
{
	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");
2031
		iwlagn_fw_error(priv, false);
2032 2033 2034
	}
}

2035 2036
#define EEPROM_RF_CONFIG_TYPE_MAX      0x3

2037
static void iwl_nic_config(struct iwl_op_mode *op_mode)
J
Johannes Berg 已提交
2038 2039
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2040
	u16 radio_cfg = priv->eeprom_data->radio_cfg;
J
Johannes Berg 已提交
2041

2042 2043 2044 2045 2046 2047 2048 2049 2050
	/* SKU Control */
	iwl_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));

2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078
	/* write radio config values to register */
	if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) {
		u32 reg_val =
			EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <<
				CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE |
			EEPROM_RF_CFG_STEP_MSK(radio_cfg) <<
				CSR_HW_IF_CONFIG_REG_POS_PHY_STEP |
			EEPROM_RF_CFG_DASH_MSK(radio_cfg) <<
				CSR_HW_IF_CONFIG_REG_POS_PHY_DASH;

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

		IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n",
			 EEPROM_RF_CFG_TYPE_MSK(radio_cfg),
			 EEPROM_RF_CFG_STEP_MSK(radio_cfg),
			 EEPROM_RF_CFG_DASH_MSK(radio_cfg));
	} 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);

2079
	priv->lib->nic_config(priv);
J
Johannes Berg 已提交
2080 2081
}

2082 2083 2084 2085 2086 2087 2088 2089
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");
}

2090
static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue)
2091 2092
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2093
	int mq = priv->queue_to_mac80211[queue];
2094

2095
	if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE))
2096 2097
		return;

2098
	if (atomic_inc_return(&priv->queue_stop_count[mq]) > 1) {
2099
		IWL_DEBUG_TX_QUEUES(priv,
2100 2101
			"queue %d (mac80211 %d) already stopped\n",
			queue, mq);
2102 2103
		return;
	}
2104

2105 2106
	set_bit(mq, &priv->transport_queue_stop);
	ieee80211_stop_queue(priv->hw, mq);
2107 2108
}

2109
static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue)
2110 2111
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2112
	int mq = priv->queue_to_mac80211[queue];
2113

2114
	if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE))
2115 2116
		return;

2117
	if (atomic_dec_return(&priv->queue_stop_count[mq]) > 0) {
2118
		IWL_DEBUG_TX_QUEUES(priv,
2119 2120
			"queue %d (mac80211 %d) already awake\n",
			queue, mq);
2121 2122
		return;
	}
2123

2124
	clear_bit(mq, &priv->transport_queue_stop);
2125 2126

	if (!priv->passive_no_rx)
2127
		ieee80211_wake_queue(priv->hw, mq);
2128 2129 2130 2131
}

void iwlagn_lift_passive_no_rx(struct iwl_priv *priv)
{
2132
	int mq;
2133 2134 2135 2136

	if (!priv->passive_no_rx)
		return;

2137 2138 2139 2140
	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);
2141
		} else {
2142
			IWL_DEBUG_TX_QUEUES(priv, "Don't wake queue %d", mq);
2143
		}
2144 2145 2146 2147 2148
	}

	priv->passive_no_rx = false;
}

2149
static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
2150
{
2151
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2152 2153 2154
	struct ieee80211_tx_info *info;

	info = IEEE80211_SKB_CB(skb);
2155
	iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]);
2156 2157 2158
	dev_kfree_skb_any(skb);
}

2159
static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170
{
	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);
}

2171
static const struct iwl_op_mode_ops iwl_dvm_ops = {
2172 2173
	.start = iwl_op_mode_dvm_start,
	.stop = iwl_op_mode_dvm_stop,
2174
	.rx = iwl_rx_dispatch,
2175 2176
	.queue_full = iwl_stop_sw_queue,
	.queue_not_full = iwl_wake_sw_queue,
2177
	.hw_rf_kill = iwl_set_hw_rfkill_state,
2178
	.free_skb = iwl_free_skb,
2179
	.nic_error = iwl_nic_error,
2180
	.cmd_queue_full = iwl_cmd_queue_full,
J
Johannes Berg 已提交
2181
	.nic_config = iwl_nic_config,
2182
	.wimax_active = iwl_wimax_active,
2183
};
Z
Zhu Yi 已提交
2184 2185 2186 2187 2188 2189

/*****************************************************************************
 *
 * driver and module entry point
 *
 *****************************************************************************/
2190
static int __init iwl_init(void)
Z
Zhu Yi 已提交
2191 2192 2193
{

	int ret;
2194 2195
	pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
	pr_info(DRV_COPYRIGHT "\n");
2196

2197
	ret = iwlagn_rate_control_register();
2198
	if (ret) {
2199
		pr_err("Unable to register rate control algorithm: %d\n", ret);
2200
		return ret;
2201 2202
	}

2203 2204 2205
	ret = iwl_opmode_register("iwldvm", &iwl_dvm_ops);
	if (ret) {
		pr_err("Unable to register op_mode: %d\n", ret);
2206
		iwlagn_rate_control_unregister();
2207
	}
2208 2209

	return ret;
Z
Zhu Yi 已提交
2210
}
2211
module_init(iwl_init);
Z
Zhu Yi 已提交
2212

2213
static void __exit iwl_exit(void)
Z
Zhu Yi 已提交
2214
{
2215
	iwl_opmode_deregister("iwldvm");
2216
	iwlagn_rate_control_unregister();
Z
Zhu Yi 已提交
2217
}
2218
module_exit(iwl_exit);