iwl-agn.c 65.0 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>

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

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

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

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

74
#define DRV_VERSION     IWLWIFI_VERSION VD
Z
Zhu Yi 已提交
75 76 77 78


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

83
void iwl_update_chain_flags(struct iwl_priv *priv)
M
Mohamed Abbas 已提交
84
{
85
	struct iwl_rxon_context *ctx;
M
Mohamed Abbas 已提交
86

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

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

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

133 134 135 136
	/*
	 * We have to set up the TX command, the TX Beacon command, and the
	 * beacon contents.
	 */
137

138
	lockdep_assert_held(&priv->mutex);
139 140 141

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

145 146 147
	if (WARN_ON(!priv->beacon_skb))
		return -EINVAL;

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

	frame_size = priv->beacon_skb->len;
156

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

164
	/* Set up TX beacon command fields */
165
	iwl_set_beacon_tim(priv, tx_beacon_cmd, priv->beacon_skb->data,
166
			   frame_size);
167

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

182
	priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
183
					      hw_params(priv).valid_tx_ant);
184
	rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
185 186 187 188 189

	/* 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)
190
		rate_flags |= RATE_MCS_CCK_MSK;
191 192 193

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

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

203
	return iwl_dvm_send_cmd(priv, &cmd);
204 205
}

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

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

218 219 220 221 222 223 224 225 226 227
	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;
	}

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

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

238
	priv->beacon_skb = beacon;
Z
Zhu Yi 已提交
239

240
	iwlagn_send_beacon_cmd(priv);
241
 out:
242
	mutex_unlock(&priv->mutex);
Z
Zhu Yi 已提交
243 244
}

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

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

259 260 261 262
static void iwl_bg_bt_full_concurrency(struct work_struct *work)
{
	struct iwl_priv *priv =
		container_of(work, struct iwl_priv, bt_full_concurrency);
263
	struct iwl_rxon_context *ctx;
264

265
	mutex_lock(&priv->mutex);
266

D
Don Fry 已提交
267
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
268
		goto out;
269 270

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

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

W
Wey-Yi Guy 已提交
287
	iwlagn_send_advance_bt_config(priv);
288
out:
289
	mutex_unlock(&priv->mutex);
290 291
}

292
/**
293
 * iwl_bg_statistics_periodic - Timer callback to queue statistics
294 295 296 297 298 299 300 301
 *
 * 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.
 */
302
static void iwl_bg_statistics_periodic(unsigned long data)
303 304 305
{
	struct iwl_priv *priv = (struct iwl_priv *)data;

D
Don Fry 已提交
306
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
307 308
		return;

309
	/* dont send host command if rf-kill is on */
D
Don Fry 已提交
310
	if (!iwl_is_ready_rf(priv))
311 312
		return;

313
	iwl_send_statistics_request(priv, CMD_ASYNC, false);
314 315
}

316 317 318

static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
					u32 start_idx, u32 num_events,
J
Johannes Berg 已提交
319
					u32 capacity, u32 mode)
320 321 322 323 324 325 326 327 328 329 330 331
{
	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 */
332
	spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags);
333
	if (unlikely(!iwl_grab_nic_access(trans(priv)))) {
334
		spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags);
335 336 337 338
		return;
	}

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

J
Johannes Berg 已提交
341 342 343 344 345 346 347 348 349
	/*
	 * 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;

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

J
Johannes Berg 已提交
371
static void iwl_continuous_event_trace(struct iwl_priv *priv)
372 373
{
	u32 capacity;   /* event log capacity in # entries */
J
Johannes Berg 已提交
374 375 376 377 378 379
	struct {
		u32 capacity;
		u32 mode;
		u32 wrap_counter;
		u32 write_counter;
	} __packed read;
380 381 382 383 384
	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 */

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

		capacity = read.capacity;
		mode = read.mode;
		num_wraps = read.wrap_counter;
		next_entry = read.write_counter;
393 394 395
	} else
		return;

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

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

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

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

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

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

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

451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
	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 已提交
467
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
468 469 470 471 472 473 474 475 476 477
		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));
	}
}

478 479 480 481 482
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 已提交
483
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
484 485 486
		return;

	/* do nothing if rf-kill is on */
D
Don Fry 已提交
487
	if (!iwl_is_ready_rf(priv))
488 489
		return;

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

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

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

#define IWLAGN_CMD_FIFO_NUM	7

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

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

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

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

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

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

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

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

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

581
static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
582 583 584 585 586 587 588
{
	int i;

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

	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;
604
	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
605 606 607 608 609 610 611 612
	priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
		BIT(NL80211_IFTYPE_ADHOC);
	priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
		BIT(NL80211_IFTYPE_STATION);
	priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
	priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
	priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
	priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
613 614 615 616
	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));
617 618 619 620 621 622 623 624 625 626 627 628 629

	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);
630 631 632 633 634 635

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

636 637 638
	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;
639 640 641 642 643
	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;
644 645 646 647

	BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
}

648 649 650 651 652 653
static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
{
	struct iwl_ct_kill_config cmd;
	struct iwl_ct_kill_throttling_config adv_cmd;
	int ret = 0;

654
	iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR,
655
		    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
J
Johannes Berg 已提交
656

657 658
	priv->thermal_throttle.ct_kill_toggle = false;

659
	if (cfg(priv)->base_params->support_ct_kill_exit) {
660
		adv_cmd.critical_temperature_enter =
661
			cpu_to_le32(hw_params(priv).ct_kill_threshold);
662
		adv_cmd.critical_temperature_exit =
663
			cpu_to_le32(hw_params(priv).ct_kill_exit_threshold);
664

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

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

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

	memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
703
	calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_RT_CFG_ALL;
704
	calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg);
705

706
	return iwl_dvm_send_cmd(priv, &cmd);
707 708 709
}


W
Wey-Yi Guy 已提交
710 711 712 713 714 715
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),
	};

716
	if (IWL_UCODE_API(priv->fw->ucode_ver) > 1) {
W
Wey-Yi Guy 已提交
717
		IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
718
		return iwl_dvm_send_cmd_pdu(priv,
W
Wey-Yi Guy 已提交
719 720 721 722 723 724 725 726 727 728
					TX_ANT_CONFIGURATION_CMD,
					CMD_SYNC,
					sizeof(struct iwl_tx_ant_config_cmd),
					&tx_ant_cmd);
	} else {
		IWL_DEBUG_HC(priv, "TX_ANT_CONFIGURATION_CMD not supported\n");
		return -EOPNOTSUPP;
	}
}

Z
Zhu Yi 已提交
729
/**
730
 * iwl_alive_start - called after REPLY_ALIVE notification received
Z
Zhu Yi 已提交
731
 *                   from protocol/runtime uCode (initialization uCode's
732
 *                   Alive gets handled by iwl_init_alive_start()).
Z
Zhu Yi 已提交
733
 */
734
int iwl_alive_start(struct iwl_priv *priv)
Z
Zhu Yi 已提交
735
{
736
	int ret = 0;
737
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
Z
Zhu Yi 已提交
738

739
	IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
740

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

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

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

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

761 762 763
		priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
		priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
		priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
W
Wey-Yi Guy 已提交
764
		iwlagn_send_advance_bt_config(priv);
765
		priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS;
766 767
		priv->cur_rssi_ctx = NULL;

768
		iwl_send_prio_tbl(priv);
769 770

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

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

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

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

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

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

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

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

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

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

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

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

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

833 834 835 836 837 838 839 840 841 842 843 844 845
/**
 * iwl_clear_driver_stations - clear knowledge of all stations from driver
 * @priv: iwl priv struct
 *
 * This is called during iwl_down() to make sure that in the case
 * we're coming there from a hardware restart mac80211 will be
 * able to reconfigure stations -- if we're getting there in the
 * normal down flow then the stations will already be cleared.
 */
static void iwl_clear_driver_stations(struct iwl_priv *priv)
{
	struct iwl_rxon_context *ctx;

846
	spin_lock_bh(&priv->sta_lock);
847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863
	memset(priv->stations, 0, sizeof(priv->stations));
	priv->num_stations = 0;

	priv->ucode_key_table = 0;

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

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

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

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

873
	lockdep_assert_held(&priv->mutex);
874

875 876
	iwl_scan_cancel_timeout(priv, 200);

877 878 879 880 881 882 883
	/*
	 * If active, scanning won't cancel it, so say it expired.
	 * No race since we hold the mutex here and a new one
	 * can't come in at this time.
	 */
	ieee80211_remain_on_channel_expired(priv->hw);

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

887
	iwl_clear_ucode_stations(priv, NULL);
888
	iwl_dealloc_bcast_stations(priv);
889
	iwl_clear_driver_stations(priv);
Z
Zhu Yi 已提交
890

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

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

908
	if (priv->mac80211_registered)
Z
Zhu Yi 已提交
909 910
		ieee80211_stop_queues(priv->hw);

911
	priv->ucode_loaded = false;
912 913
	iwl_trans_stop_device(trans(priv));

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

924
	dev_kfree_skb(priv->beacon_skb);
925
	priv->beacon_skb = NULL;
Z
Zhu Yi 已提交
926 927 928 929 930 931 932 933
}

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

934 935 936 937 938
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);

939
	mutex_lock(&priv->mutex);
940

D
Don Fry 已提交
941 942
	if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
	    test_bit(STATUS_SCANNING, &priv->status)) {
943
		mutex_unlock(&priv->mutex);
944 945 946 947
		return;
	}

	if (priv->start_calib) {
948 949
		iwl_chain_noise_calibration(priv);
		iwl_sensitivity_calibration(priv);
950 951
	}

952
	mutex_unlock(&priv->mutex);
953 954
}

955
void iwlagn_prepare_restart(struct iwl_priv *priv)
J
Johannes Berg 已提交
956 957 958 959 960 961
{
	struct iwl_rxon_context *ctx;
	bool bt_full_concurrent;
	u8 bt_ci_compliance;
	u8 bt_load;
	u8 bt_status;
962
	bool bt_is_sco;
963
	int i;
J
Johannes Berg 已提交
964

965
	lockdep_assert_held(&priv->mutex);
J
Johannes Berg 已提交
966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983

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

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

986
	iwl_down(priv);
J
Johannes Berg 已提交
987 988 989 990 991

	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;
992
	priv->bt_is_sco = bt_is_sco;
993 994 995 996 997 998 999 1000 1001

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

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

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

1004
static void iwl_bg_restart(struct work_struct *data)
Z
Zhu Yi 已提交
1005
{
1006
	struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
Z
Zhu Yi 已提交
1007

D
Don Fry 已提交
1008
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
Z
Zhu Yi 已提交
1009 1010
		return;

D
Don Fry 已提交
1011
	if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
1012
		mutex_lock(&priv->mutex);
J
Johannes Berg 已提交
1013
		iwlagn_prepare_restart(priv);
1014
		mutex_unlock(&priv->mutex);
1015
		iwl_cancel_deferred_work(priv);
J
Johannes Berg 已提交
1016 1017
		ieee80211_restart_hw(priv->hw);
	} else {
1018
		WARN_ON(1);
J
Johannes Berg 已提交
1019
	}
Z
Zhu Yi 已提交
1020 1021
}

1022 1023 1024



1025
void iwlagn_disable_roc(struct iwl_priv *priv)
1026
{
1027
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
1028

1029
	lockdep_assert_held(&priv->mutex);
1030

1031 1032
	if (!priv->hw_roc_setup)
		return;
1033

1034 1035
	ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
	ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1036

1037
	priv->hw_roc_channel = NULL;
1038

1039
	memset(ctx->staging.node_addr, 0, ETH_ALEN);
1040

1041
	iwlagn_commit_rxon(priv, ctx);
1042

1043 1044
	ctx->is_active = false;
	priv->hw_roc_setup = false;
1045 1046
}

1047
static void iwlagn_disable_roc_work(struct work_struct *work)
Z
Zhu Yi 已提交
1048
{
1049 1050
	struct iwl_priv *priv = container_of(work, struct iwl_priv,
					     hw_roc_disable_work.work);
Z
Zhu Yi 已提交
1051

1052
	mutex_lock(&priv->mutex);
1053
	iwlagn_disable_roc(priv);
1054
	mutex_unlock(&priv->mutex);
Z
Zhu Yi 已提交
1055 1056
}

1057 1058 1059 1060 1061 1062 1063
/*****************************************************************************
 *
 * driver setup and teardown
 *
 *****************************************************************************/

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

1067 1068 1069 1070 1071 1072 1073 1074
	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);
1075

1076
	iwl_setup_scan_deferred_work(priv);
1077

1078 1079
	if (cfg(priv)->bt_params)
		iwlagn_bt_setup_deferred_work(priv);
1080

1081 1082 1083
	init_timer(&priv->statistics_periodic);
	priv->statistics_periodic.data = (unsigned long)priv;
	priv->statistics_periodic.function = iwl_bg_statistics_periodic;
1084

1085 1086 1087
	init_timer(&priv->ucode_trace);
	priv->ucode_trace.data = (unsigned long)priv;
	priv->ucode_trace.function = iwl_bg_ucode_trace;
Z
Zhu Yi 已提交
1088 1089
}

1090
void iwl_cancel_deferred_work(struct iwl_priv *priv)
J
Johannes Berg 已提交
1091
{
1092 1093
	if (cfg(priv)->bt_params)
		iwlagn_bt_cancel_deferred_work(priv);
J
Johannes Berg 已提交
1094

1095 1096
	cancel_work_sync(&priv->run_time_calib_work);
	cancel_work_sync(&priv->beacon_update);
J
Johannes Berg 已提交
1097

1098
	iwl_cancel_scan_deferred_work(priv);
J
Johannes Berg 已提交
1099

1100 1101 1102
	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 已提交
1103

1104 1105 1106
	del_timer_sync(&priv->statistics_periodic);
	del_timer_sync(&priv->ucode_trace);
}
J
Johannes Berg 已提交
1107

1108
static void iwl_init_hw_rates(struct ieee80211_rate *rates)
1109 1110
{
	int i;
J
Johannes Berg 已提交
1111

1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124
	for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
		rates[i].bitrate = iwl_rates[i].ieee * 5;
		rates[i].hw_value = i; /* Rate scaling will work on indexes */
		rates[i].hw_value_short = i;
		rates[i].flags = 0;
		if ((i >= IWL_FIRST_CCK_RATE) && (i <= IWL_LAST_CCK_RATE)) {
			/*
			 * If CCK != 1M then set short preamble rate flag.
			 */
			rates[i].flags |=
				(iwl_rates[i].plcp == IWL_RATE_1M_PLCP) ?
					0 : IEEE80211_RATE_SHORT_PREAMBLE;
		}
J
Johannes Berg 已提交
1125 1126 1127
	}
}

1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 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 1267 1268 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 1302 1303 1304 1305 1306 1307 1308 1309 1310
#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
static void iwl_init_ht_hw_capab(const struct iwl_priv *priv,
			      struct ieee80211_sta_ht_cap *ht_info,
			      enum ieee80211_band band)
{
	u16 max_bit_rate = 0;
	u8 rx_chains_num = hw_params(priv).rx_chains_num;
	u8 tx_chains_num = hw_params(priv).tx_chains_num;

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

	ht_info->ht_supported = true;

	if (cfg(priv)->ht_params &&
	    cfg(priv)->ht_params->ht_greenfield_support)
		ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
	ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
	max_bit_rate = MAX_BIT_RATE_20_MHZ;
	if (hw_params(priv).ht40_channel & BIT(band)) {
		ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
		ht_info->cap |= IEEE80211_HT_CAP_SGI_40;
		ht_info->mcs.rx_mask[4] = 0x01;
		max_bit_rate = MAX_BIT_RATE_40_MHZ;
	}

	if (iwlagn_mod_params.amsdu_size_8K)
		ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;

	ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
	ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF;

	ht_info->mcs.rx_mask[0] = 0xFF;
	if (rx_chains_num >= 2)
		ht_info->mcs.rx_mask[1] = 0xFF;
	if (rx_chains_num >= 3)
		ht_info->mcs.rx_mask[2] = 0xFF;

	/* Highest supported Rx data rate */
	max_bit_rate *= rx_chains_num;
	WARN_ON(max_bit_rate & ~IEEE80211_HT_MCS_RX_HIGHEST_MASK);
	ht_info->mcs.rx_highest = cpu_to_le16(max_bit_rate);

	/* Tx MCS capabilities */
	ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
	if (tx_chains_num != rx_chains_num) {
		ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
		ht_info->mcs.tx_params |= ((tx_chains_num - 1) <<
				IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
	}
}

/**
 * iwl_init_geos - Initialize mac80211's geo/channel info based from eeprom
 */
static int iwl_init_geos(struct iwl_priv *priv)
{
	struct iwl_channel_info *ch;
	struct ieee80211_supported_band *sband;
	struct ieee80211_channel *channels;
	struct ieee80211_channel *geo_ch;
	struct ieee80211_rate *rates;
	int i = 0;
	s8 max_tx_power = IWLAGN_TX_POWER_TARGET_POWER_MIN;

	if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
	    priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
		IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n");
		set_bit(STATUS_GEO_CONFIGURED, &priv->status);
		return 0;
	}

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

	rates = kcalloc(IWL_RATE_COUNT_LEGACY, sizeof(struct ieee80211_rate),
			GFP_KERNEL);
	if (!rates) {
		kfree(channels);
		return -ENOMEM;
	}

	/* 5.2GHz channels start after the 2.4GHz channels */
	sband = &priv->bands[IEEE80211_BAND_5GHZ];
	sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)];
	/* just OFDM */
	sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
	sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE;

	if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)
		iwl_init_ht_hw_capab(priv, &sband->ht_cap,
					 IEEE80211_BAND_5GHZ);

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

	if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)
		iwl_init_ht_hw_capab(priv, &sband->ht_cap,
					 IEEE80211_BAND_2GHZ);

	priv->ieee_channels = channels;
	priv->ieee_rates = rates;

	for (i = 0;  i < priv->channel_count; i++) {
		ch = &priv->channel_info[i];

		/* FIXME: might be removed if scan is OK */
		if (!is_channel_valid(ch))
			continue;

		sband =  &priv->bands[ch->band];

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

		geo_ch->center_freq =
			ieee80211_channel_to_frequency(ch->channel, ch->band);
		geo_ch->max_power = ch->max_power_avg;
		geo_ch->max_antenna_gain = 0xff;
		geo_ch->hw_value = ch->channel;

		if (is_channel_valid(ch)) {
			if (!(ch->flags & EEPROM_CHANNEL_IBSS))
				geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;

			if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
				geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;

			if (ch->flags & EEPROM_CHANNEL_RADAR)
				geo_ch->flags |= IEEE80211_CHAN_RADAR;

			geo_ch->flags |= ch->ht40_extension_channel;

			if (ch->max_power_avg > max_tx_power)
				max_tx_power = ch->max_power_avg;
		} else {
			geo_ch->flags |= IEEE80211_CHAN_DISABLED;
		}

		IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
				ch->channel, geo_ch->center_freq,
				is_channel_a_band(ch) ?  "5.2" : "2.4",
				geo_ch->flags & IEEE80211_CHAN_DISABLED ?
				"restricted" : "valid",
				 geo_ch->flags);
	}

	priv->tx_power_device_lmt = max_tx_power;
	priv->tx_power_user_lmt = max_tx_power;
	priv->tx_power_next = max_tx_power;

	if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
	     hw_params(priv).sku & EEPROM_SKU_CAP_BAND_52GHZ) {
		IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
			"Please send your %s to maintainer.\n",
			trans(priv)->hw_id_str);
		hw_params(priv).sku &= ~EEPROM_SKU_CAP_BAND_52GHZ;
	}

	IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n",
		   priv->bands[IEEE80211_BAND_2GHZ].n_channels,
		   priv->bands[IEEE80211_BAND_5GHZ].n_channels);

	set_bit(STATUS_GEO_CONFIGURED, &priv->status);

	return 0;
}

/*
 * iwl_free_geos - undo allocations in iwl_init_geos
 */
static void iwl_free_geos(struct iwl_priv *priv)
{
	kfree(priv->ieee_channels);
	kfree(priv->ieee_rates);
	clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
}

1311
static int iwl_init_drv(struct iwl_priv *priv)
J
Johannes Berg 已提交
1312
{
1313
	int ret;
J
Johannes Berg 已提交
1314

1315
	spin_lock_init(&priv->sta_lock);
J
Johannes Berg 已提交
1316

1317
	mutex_init(&priv->mutex);
J
Johannes Berg 已提交
1318

1319
	INIT_LIST_HEAD(&priv->calib_results);
1320

1321 1322 1323
	priv->ieee_channels = NULL;
	priv->ieee_rates = NULL;
	priv->band = IEEE80211_BAND_2GHZ;
J
Johannes Berg 已提交
1324

1325 1326 1327
	priv->plcp_delta_threshold =
		cfg(priv)->base_params->plcp_delta_threshold;

1328 1329 1330 1331
	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 已提交
1332

1333 1334
	priv->ucode_owner = IWL_OWNERSHIP_DRIVER;

1335 1336 1337 1338 1339
	/* initialize force reset */
	priv->force_reset[IWL_RF_RESET].reset_duration =
		IWL_DELAY_NEXT_FORCE_RF_RESET;
	priv->force_reset[IWL_FW_RESET].reset_duration =
		IWL_DELAY_NEXT_FORCE_FW_RELOAD;
J
Johannes Berg 已提交
1340

1341
	priv->rx_statistics_jiffies = jiffies;
J
Johannes Berg 已提交
1342

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

1346
	iwl_init_scan_params(priv);
J
Johannes Berg 已提交
1347

1348
	/* init bt coex */
1349 1350
	if (cfg(priv)->bt_params &&
	    cfg(priv)->bt_params->advanced_bt_coexist) {
1351 1352 1353 1354 1355 1356 1357
		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 已提交
1358

1359
	ret = iwl_init_channel_map(priv);
J
Johannes Berg 已提交
1360
	if (ret) {
1361 1362
		IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
		goto err;
J
Johannes Berg 已提交
1363 1364
	}

1365 1366 1367 1368 1369
	ret = iwl_init_geos(priv);
	if (ret) {
		IWL_ERR(priv, "initializing geos failed: %d\n", ret);
		goto err_free_channel_map;
	}
1370
	iwl_init_hw_rates(priv->ieee_rates);
J
Johannes Berg 已提交
1371

1372
	return 0;
J
Johannes Berg 已提交
1373

1374 1375 1376 1377 1378
err_free_channel_map:
	iwl_free_channel_map(priv);
err:
	return ret;
}
J
Johannes Berg 已提交
1379

1380 1381 1382 1383 1384 1385 1386
static void iwl_uninit_drv(struct iwl_priv *priv)
{
	iwl_free_geos(priv);
	iwl_free_channel_map(priv);
	kfree(priv->scan_cmd);
	kfree(priv->beacon_cmd);
	kfree(rcu_dereference_raw(priv->noa_data));
1387
	iwl_calib_free_results(priv);
1388 1389 1390 1391
#ifdef CONFIG_IWLWIFI_DEBUGFS
	kfree(priv->wowlan_sram);
#endif
}
J
Johannes Berg 已提交
1392

1393
static void iwl_set_hw_params(struct iwl_priv *priv)
1394
{
1395 1396 1397 1398
	if (cfg(priv)->ht_params)
		hw_params(priv).use_rts_for_aggregation =
			cfg(priv)->ht_params->use_rts_for_aggregation;

J
Johannes Berg 已提交
1399
	if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
J
Johannes Berg 已提交
1400
		hw_params(priv).sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
1401 1402

	/* Device-specific setup */
1403
	cfg(priv)->lib->set_hw_params(priv);
1404 1405
}

1406 1407


1408 1409
static void iwl_debug_config(struct iwl_priv *priv)
{
1410
	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUG "
1411 1412 1413 1414 1415
#ifdef CONFIG_IWLWIFI_DEBUG
		"enabled\n");
#else
		"disabled\n");
#endif
1416
	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS "
1417 1418 1419 1420 1421
#ifdef CONFIG_IWLWIFI_DEBUGFS
		"enabled\n");
#else
		"disabled\n");
#endif
1422
	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING "
1423 1424 1425 1426 1427 1428
#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
		"enabled\n");
#else
		"disabled\n");
#endif

1429
	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE "
1430
#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
1431 1432 1433
		"enabled\n");
#else
		"disabled\n");
1434
#endif
1435
	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_P2P "
1436 1437 1438 1439
#ifdef CONFIG_IWLWIFI_P2P
		"enabled\n");
#else
		"disabled\n");
1440 1441 1442
#endif
}

1443 1444
static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
						 const struct iwl_fw *fw)
1445 1446 1447
{
	struct iwl_priv *priv;
	struct ieee80211_hw *hw;
1448
	struct iwl_op_mode *op_mode;
1449
	u16 num_mac;
1450
	u32 ucode_flags;
1451
	struct iwl_trans_config trans_cfg;
1452 1453 1454 1455 1456 1457 1458 1459
	static const u8 no_reclaim_cmds[] = {
		REPLY_RX_PHY_CMD,
		REPLY_RX,
		REPLY_RX_MPDU_CMD,
		REPLY_COMPRESSED_BA,
		STATISTICS_NOTIFICATION,
		REPLY_TX,
	};
1460 1461 1462
	const u8 *q_to_ac;
	int n_q_to_ac;
	int i;
1463 1464 1465 1466

	/************************
	 * 1. Allocating HW data
	 ************************/
D
Don Fry 已提交
1467
	hw = iwl_alloc_all();
1468
	if (!hw) {
1469 1470
		pr_err("%s: Cannot allocate network device\n",
				cfg(trans)->name);
1471 1472 1473
		goto out;
	}

1474 1475 1476 1477
	op_mode = hw->priv;
	op_mode->ops = &iwl_dvm_ops;
	priv = IWL_OP_MODE_GET_DVM(op_mode);
	priv->shrd = trans->shrd;
1478
	priv->fw = fw;
1479

E
Emmanuel Grumbach 已提交
1480 1481 1482 1483 1484
	/*
	 * Populate the state variables that the transport layer needs
	 * to know about.
	 */
	trans_cfg.op_mode = op_mode;
1485 1486
	trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
	trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
1487
	trans_cfg.rx_buf_size_8k = iwlagn_mod_params.amsdu_size_8K;
1488 1489 1490 1491 1492
	if (!iwlagn_mod_params.wd_disable)
		trans_cfg.queue_watchdog_timeout =
			cfg(priv)->base_params->wd_timeout;
	else
		trans_cfg.queue_watchdog_timeout = IWL_WATCHHDOG_DISABLED;
1493 1494 1495 1496 1497 1498

	ucode_flags = fw->ucode_capa.flags;

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

1500 1501 1502
	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;
1503 1504 1505 1506 1507
		trans_cfg.queue_to_fifo = iwlagn_ipan_queue_to_tx_fifo;
		trans_cfg.n_queue_to_fifo =
			ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo);
		q_to_ac = iwlagn_pan_queue_to_ac;
		n_q_to_ac = ARRAY_SIZE(iwlagn_pan_queue_to_ac);
1508 1509 1510
	} else {
		priv->sta_key_max_num = STA_KEY_MAX_NUM;
		trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
1511 1512 1513 1514 1515
		trans_cfg.queue_to_fifo = iwlagn_default_queue_to_tx_fifo;
		trans_cfg.n_queue_to_fifo =
			ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo);
		q_to_ac = iwlagn_bss_queue_to_ac;
		n_q_to_ac = ARRAY_SIZE(iwlagn_bss_queue_to_ac);
1516 1517
	}

1518 1519
	/* Configure transport layer */
	iwl_trans_configure(trans(priv), &trans_cfg);
1520

1521
	/* At this point both hw and priv are allocated. */
1522

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

D
Don Fry 已提交
1525
	/* show what debugging capabilities we have */
1526 1527
	iwl_debug_config(priv);

1528
	IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
1529

1530 1531
	/* is antenna coupling more than 35dB ? */
	priv->bt_ant_couple_ok =
1532 1533 1534
		(iwlagn_mod_params.ant_coupling >
			IWL_BT_ANTENNA_COUPLING_THRESHOLD) ?
			true : false;
1535

1536
	/* enable/disable bt channel inhibition */
1537
	priv->bt_ch_announce = iwlagn_mod_params.bt_ch_announce;
1538 1539
	IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n",
		       (priv->bt_ch_announce) ? "On" : "Off");
1540

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

1544
	/* these spin locks will be used in apm_ops.init and EEPROM access
M
Mohamed Abbas 已提交
1545 1546
	 * we should init now
	 */
1547
	spin_lock_init(&trans(priv)->reg_lock);
1548
	spin_lock_init(&priv->statistics.lock);
1549

1550
	/***********************
E
Emmanuel Grumbach 已提交
1551
	 * 2. Read REV register
1552
	 ***********************/
1553
	IWL_INFO(priv, "Detected %s, REV=0x%X\n",
1554
		cfg(priv)->name, trans(priv)->hw_rev);
1555

W
Wey-Yi Guy 已提交
1556
	if (iwl_trans_start_hw(trans(priv)))
1557
		goto out_free_traffic_mem;
1558

T
Tomas Winkler 已提交
1559
	/*****************
E
Emmanuel Grumbach 已提交
1560
	 * 3. Read EEPROM
T
Tomas Winkler 已提交
1561
	 *****************/
W
Wey-Yi Guy 已提交
1562 1563
	/* Read the EEPROM */
	if (iwl_eeprom_init(trans(priv), trans(priv)->hw_rev)) {
1564
		IWL_ERR(priv, "Unable to init EEPROM\n");
1565
		goto out_free_traffic_mem;
1566
	}
W
Wey-Yi Guy 已提交
1567 1568 1569 1570
	/* Reset chip to save power until we load uCode during "up". */
	iwl_trans_stop_hw(trans(priv));

	if (iwl_eeprom_check_version(priv))
1571
		goto out_free_eeprom;
1572

W
Wey-Yi Guy 已提交
1573
	if (iwl_eeprom_init_hw_params(priv))
1574 1575
		goto out_free_eeprom;

1576
	/* extract MAC Address */
1577
	iwl_eeprom_get_mac(priv->shrd, priv->addresses[0].addr);
1578 1579 1580
	IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr);
	priv->hw->wiphy->addresses = priv->addresses;
	priv->hw->wiphy->n_addresses = 1;
1581
	num_mac = iwl_eeprom_query16(priv->shrd, EEPROM_NUM_MAC_ADDRESS);
1582 1583 1584 1585 1586 1587
	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++;
	}
1588

E
Emmanuel Grumbach 已提交
1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603
	/************************
	 * 4. Setup HW constants
	 ************************/
	iwl_set_hw_params(priv);

	if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE)) {
		IWL_DEBUG_INFO(priv, "Your EEPROM disabled PAN");
		ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
		/*
		 * if not PAN, then don't support P2P -- might be a uCode
		 * packaging bug or due to the eeprom check above
		 */
		ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
		priv->sta_key_max_num = STA_KEY_MAX_NUM;
		trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
1604 1605 1606 1607 1608
		trans_cfg.queue_to_fifo = iwlagn_default_queue_to_tx_fifo;
		trans_cfg.n_queue_to_fifo =
			ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo);
		q_to_ac = iwlagn_bss_queue_to_ac;
		n_q_to_ac = ARRAY_SIZE(iwlagn_bss_queue_to_ac);
E
Emmanuel Grumbach 已提交
1609 1610 1611 1612 1613

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

1614
	/*******************
E
Emmanuel Grumbach 已提交
1615
	 * 5. Setup priv
1616
	 *******************/
1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628
	for (i = 0; i < IEEE80211_NUM_ACS; i++)
		atomic_set(&priv->ac_stop_count[i], 0);

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

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

W
Wey-Yi Guy 已提交
1630
	if (iwl_init_drv(priv))
R
Ron Rindjunsky 已提交
1631
		goto out_free_eeprom;
W
Wey-Yi Guy 已提交
1632

1633
	/* At this point both hw and priv are initialized. */
1634 1635

	/********************
E
Emmanuel Grumbach 已提交
1636
	 * 6. Setup services
1637
	 ********************/
1638
	iwl_setup_deferred_work(priv);
1639
	iwl_setup_rx_handlers(priv);
1640
	iwl_testmode_init(priv);
1641

1642
	iwl_power_initialize(priv);
1643
	iwl_tt_initialize(priv);
J
Johannes Berg 已提交
1644

1645 1646 1647 1648 1649
	snprintf(priv->hw->wiphy->fw_version,
		 sizeof(priv->hw->wiphy->fw_version),
		 "%s", fw->fw_version);

	priv->new_scan_threshold_behaviour =
1650
		!!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
1651

1652 1653 1654 1655 1656 1657
	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 */
1658
	iwl_init_context(priv, ucode_flags);
1659 1660 1661 1662

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

W
Wey-Yi Guy 已提交
1668
	if (iwl_dbgfs_register(priv, DRV_NAME))
1669
		IWL_ERR(priv,
W
Wey-Yi Guy 已提交
1670
			"failed to create debugfs files. Ignoring error\n");
1671

1672
	return op_mode;
Z
Zhu Yi 已提交
1673

1674
out_destroy_workqueue:
J
Johannes Berg 已提交
1675 1676
	destroy_workqueue(priv->workqueue);
	priv->workqueue = NULL;
T
Tomas Winkler 已提交
1677
	iwl_uninit_drv(priv);
1678
out_free_eeprom:
1679
	iwl_eeprom_free(priv->shrd);
1680
out_free_traffic_mem:
1681
	iwl_free_traffic_mem(priv);
1682
	ieee80211_free_hw(priv->hw);
1683
out:
1684 1685
	op_mode = NULL;
	return op_mode;
Z
Zhu Yi 已提交
1686 1687
}

1688
static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
Z
Zhu Yi 已提交
1689
{
1690 1691
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

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

1694 1695
	iwl_dbgfs_unregister(priv);

W
Wey-Yi Guy 已提交
1696
	iwl_testmode_cleanup(priv);
1697
	iwlagn_mac_unregister(priv);
1698

1699 1700
	iwl_tt_exit(priv);

1701
	/*This will stop the queues, move the device to low power state */
1702
	priv->ucode_loaded = false;
1703
	iwl_trans_stop_device(trans(priv));
1704

1705
	iwl_eeprom_free(priv->shrd);
Z
Zhu Yi 已提交
1706

M
Mohamed Abbas 已提交
1707
	/*netif_stop_queue(dev); */
J
Johannes Berg 已提交
1708
	flush_workqueue(priv->workqueue);
M
Mohamed Abbas 已提交
1709

1710
	/* ieee80211_unregister_hw calls iwlagn_mac_stop, which flushes
J
Johannes Berg 已提交
1711
	 * priv->workqueue... so we can't take down the workqueue
Z
Zhu Yi 已提交
1712
	 * until now... */
J
Johannes Berg 已提交
1713 1714
	destroy_workqueue(priv->workqueue);
	priv->workqueue = NULL;
1715
	iwl_free_traffic_mem(priv);
Z
Zhu Yi 已提交
1716

T
Tomas Winkler 已提交
1717
	iwl_uninit_drv(priv);
Z
Zhu Yi 已提交
1718

1719
	dev_kfree_skb(priv->beacon_skb);
Z
Zhu Yi 已提交
1720 1721 1722 1723

	ieee80211_free_hw(priv->hw);
}

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 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
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)
{
	struct iwl_trans *trans = trans(priv);
	u32 base;
	struct iwl_error_event_table table;

	base = priv->device_pointers.error_event_table;
1800
	if (priv->cur_ucode == IWL_UCODE_INIT) {
1801
		if (!base)
1802
			base = priv->fw->init_errlog_ptr;
1803 1804
	} else {
		if (!base)
1805
			base = priv->fw->inst_errlog_ptr;
1806 1807 1808 1809 1810 1811
	}

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

	/*TODO: Update dbgfs with ISR error stats obtained below */
	iwl_read_targ_mem_words(trans, base, &table, sizeof(table));

	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",
			priv->shrd->status, table.valid);
	}

	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;

	struct iwl_trans *trans = trans(priv);

	if (num_events == 0)
		return pos;

	base = priv->device_pointers.log_event_table;
1891
	if (priv->cur_ucode == IWL_UCODE_INIT) {
1892
		if (!base)
1893
			base = priv->fw->init_evtlog_ptr;
1894 1895
	} else {
		if (!base)
1896
			base = priv->fw->inst_evtlog_ptr;
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 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005
	}

	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;
	struct iwl_trans *trans = trans(priv);

	base = priv->device_pointers.log_event_table;
2006
	if (priv->cur_ucode == IWL_UCODE_INIT) {
2007
		logsize = priv->fw->init_evtlog_size;
2008
		if (!base)
2009
			base = priv->fw->init_evtlog_ptr;
2010
	} else {
2011
		logsize = priv->fw->inst_evtlog_size;
2012
		if (!base)
2013
			base = priv->fw->inst_evtlog_ptr;
2014 2015 2016 2017 2018 2019
	}

	if (!iwlagn_hw_valid_rtc_data_addr(base)) {
		IWL_ERR(priv,
			"Invalid event log pointer 0x%08X for %s uCode\n",
			base,
2020
			(priv->cur_ucode == IWL_UCODE_INIT)
2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 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 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096
					? "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;
}

2097 2098 2099 2100
static void iwl_nic_error(struct iwl_op_mode *op_mode)
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

2101
	IWL_ERR(priv, "Loaded firmware version: %s\n",
2102
		priv->fw->fw_version);
2103 2104 2105 2106

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

2107 2108 2109
	iwlagn_fw_error(priv, false);
}

2110 2111 2112 2113 2114 2115
static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode)
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

	if (!iwl_check_for_ct_kill(priv)) {
		IWL_ERR(priv, "Restarting adapter queue is full\n");
2116
		iwlagn_fw_error(priv, false);
2117 2118 2119
	}
}

J
Johannes Berg 已提交
2120 2121 2122 2123 2124 2125 2126
static void iwl_nic_config(struct iwl_op_mode *op_mode)
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);

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

2127
static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue)
2128 2129
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140
	int ac = priv->queue_to_ac[queue];

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

	if (atomic_inc_return(&priv->ac_stop_count[ac]) > 1) {
		IWL_DEBUG_TX_QUEUES(priv,
			"queue %d (AC %d) already stopped\n",
			queue, ac);
		return;
	}
2141 2142 2143 2144 2145

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

2146
static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue)
2147 2148
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159
	int ac = priv->queue_to_ac[queue];

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

	if (atomic_dec_return(&priv->ac_stop_count[ac]) > 0) {
		IWL_DEBUG_TX_QUEUES(priv,
			"queue %d (AC %d) already awake\n",
			queue, ac);
		return;
	}
2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174

	clear_bit(ac, &priv->transport_queue_stop);

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

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

	if (!priv->passive_no_rx)
		return;

	for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++) {
2175 2176
		if (!test_bit(ac, &priv->transport_queue_stop)) {
			IWL_DEBUG_TX_QUEUES(priv, "Wake queue %d");
2177
			ieee80211_wake_queue(priv->hw, ac);
2178 2179 2180
		} else {
			IWL_DEBUG_TX_QUEUES(priv, "Don't wake queue %d");
		}
2181 2182 2183 2184 2185
	}

	priv->passive_no_rx = false;
}

2186 2187 2188
const struct iwl_op_mode_ops iwl_dvm_ops = {
	.start = iwl_op_mode_dvm_start,
	.stop = iwl_op_mode_dvm_stop,
2189
	.rx = iwl_rx_dispatch,
2190 2191
	.queue_full = iwl_stop_sw_queue,
	.queue_not_full = iwl_wake_sw_queue,
2192
	.hw_rf_kill = iwl_set_hw_rfkill_state,
2193
	.free_skb = iwl_free_skb,
2194
	.nic_error = iwl_nic_error,
2195
	.cmd_queue_full = iwl_cmd_queue_full,
J
Johannes Berg 已提交
2196
	.nic_config = iwl_nic_config,
2197
};
Z
Zhu Yi 已提交
2198 2199 2200 2201 2202 2203

/*****************************************************************************
 *
 * driver and module entry point
 *
 *****************************************************************************/
2204 2205 2206

struct kmem_cache *iwl_tx_cmd_pool;

2207
static int __init iwl_init(void)
Z
Zhu Yi 已提交
2208 2209 2210
{

	int ret;
2211 2212
	pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
	pr_info(DRV_COPYRIGHT "\n");
2213

2214 2215 2216 2217 2218 2219
	iwl_tx_cmd_pool = kmem_cache_create("iwl_dev_cmd",
					    sizeof(struct iwl_device_cmd),
					    sizeof(void *), 0, NULL);
	if (!iwl_tx_cmd_pool)
		return -ENOMEM;

2220
	ret = iwlagn_rate_control_register();
2221
	if (ret) {
2222
		pr_err("Unable to register rate control algorithm: %d\n", ret);
2223
		goto error_rc_register;
2224 2225
	}

2226 2227
	ret = iwl_pci_register_driver();
	if (ret)
2228
		goto error_pci_register;
Z
Zhu Yi 已提交
2229
	return ret;
2230

2231
error_pci_register:
2232
	iwlagn_rate_control_unregister();
2233 2234
error_rc_register:
	kmem_cache_destroy(iwl_tx_cmd_pool);
2235
	return ret;
Z
Zhu Yi 已提交
2236 2237
}

2238
static void __exit iwl_exit(void)
Z
Zhu Yi 已提交
2239
{
2240
	iwl_pci_unregister_driver();
2241
	iwlagn_rate_control_unregister();
2242
	kmem_cache_destroy(iwl_tx_cmd_pool);
Z
Zhu Yi 已提交
2243 2244
}

2245 2246
module_exit(iwl_exit);
module_init(iwl_init);
2247 2248

#ifdef CONFIG_IWLWIFI_DEBUG
2249 2250
module_param_named(debug, iwlagn_mod_params.debug_level, uint,
		   S_IRUGO | S_IWUSR);
2251 2252 2253
MODULE_PARM_DESC(debug, "debug output mask");
#endif

2254 2255
module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO);
MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
J
Johannes Berg 已提交
2256 2257 2258
module_param_named(11n_disable, iwlagn_mod_params.disable_11n, uint, S_IRUGO);
MODULE_PARM_DESC(11n_disable,
	"disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX");
2259 2260 2261 2262 2263
module_param_named(amsdu_size_8K, iwlagn_mod_params.amsdu_size_8K,
		   int, S_IRUGO);
MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO);
MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
2264

2265 2266 2267
module_param_named(ucode_alternative,
		   iwlagn_mod_params.wanted_ucode_alternative,
		   int, S_IRUGO);
2268 2269
MODULE_PARM_DESC(ucode_alternative,
		 "specify ucode alternative to use from ucode file");
2270

2271 2272
module_param_named(antenna_coupling, iwlagn_mod_params.ant_coupling,
		   int, S_IRUGO);
2273 2274
MODULE_PARM_DESC(antenna_coupling,
		 "specify antenna coupling in dB (defualt: 0 dB)");
2275

2276 2277
module_param_named(bt_ch_inhibition, iwlagn_mod_params.bt_ch_announce,
		   bool, S_IRUGO);
2278
MODULE_PARM_DESC(bt_ch_inhibition,
2279
		 "Enable BT channel inhibition (default: enable)");
2280 2281 2282 2283 2284 2285

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

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

2287
module_param_named(wd_disable, iwlagn_mod_params.wd_disable, int, S_IRUGO);
2288
MODULE_PARM_DESC(wd_disable,
2289 2290
		"Disable stuck queue watchdog timer 0=system default, "
		"1=disable, 2=enable (default: 0)");
2291

2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310
/*
 * set bt_coex_active to true, uCode will do kill/defer
 * every time the priority line is asserted (BT is sending signals on the
 * priority line in the PCIx).
 * set bt_coex_active to false, uCode will ignore the BT activity and
 * perform the normal operation
 *
 * User might experience transmit issue on some platform due to WiFi/BT
 * co-exist problem. The possible behaviors are:
 *   Able to scan and finding all the available AP
 *   Not able to associate with any AP
 * On those platforms, WiFi communication can be restored by set
 * "bt_coex_active" module parameter to "false"
 *
 * default: bt_coex_active = true (BT_COEX_ENABLE)
 */
module_param_named(bt_coex_active, iwlagn_mod_params.bt_coex_active,
		bool, S_IRUGO);
MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)");
2311 2312 2313

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

2316 2317 2318 2319 2320
module_param_named(power_save, iwlagn_mod_params.power_save,
		bool, S_IRUGO);
MODULE_PARM_DESC(power_save,
		 "enable WiFi power management (default: disable)");

2321 2322 2323 2324 2325
module_param_named(power_level, iwlagn_mod_params.power_level,
		int, S_IRUGO);
MODULE_PARM_DESC(power_level,
		 "default power save level (range from 1 - 5, default: 1)");

2326 2327 2328 2329 2330
module_param_named(auto_agg, iwlagn_mod_params.auto_agg,
		bool, S_IRUGO);
MODULE_PARM_DESC(auto_agg,
		 "enable agg w/o check traffic load (default: enable)");

2331 2332 2333 2334 2335 2336 2337 2338 2339
/*
 * For now, keep using power level 1 instead of automatically
 * adjusting ...
 */
module_param_named(no_sleep_autoadjust, iwlagn_mod_params.no_sleep_autoadjust,
		bool, S_IRUGO);
MODULE_PARM_DESC(no_sleep_autoadjust,
		 "don't automatically adjust sleep level "
		 "according to maximum network latency (default: true)");