iwl-agn.c 100.5 KB
Newer Older
Z
Zhu Yi 已提交
1 2
/******************************************************************************
 *
3
 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
Z
Zhu Yi 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * Portions of this file are derived from the ipw3945 project, as well
 * as portions of the ieee80211 subsystem header files.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
 *
 * The full GNU General Public License is included in this distribution in the
 * file called LICENSE.
 *
 * Contact Information:
25
 *  Intel Linux Wireless <ilw@linux.intel.com>
Z
Zhu Yi 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 *****************************************************************************/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <linux/firmware.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>

#include <net/mac80211.h>

#include <asm/div64.h>

47 48
#define DRV_NAME        "iwlagn"

A
Assaf Krauss 已提交
49
#include "iwl-eeprom.h"
50
#include "iwl-dev.h"
51
#include "iwl-core.h"
52
#include "iwl-io.h"
Z
Zhu Yi 已提交
53
#include "iwl-helpers.h"
54
#include "iwl-sta.h"
55
#include "iwl-calib.h"
Z
Zhu Yi 已提交
56

57

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

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

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

75
#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
Z
Zhu Yi 已提交
76 77 78 79 80
#define VS "s"
#else
#define VS
#endif

T
Tomas Winkler 已提交
81
#define DRV_VERSION     IWLWIFI_VERSION VD VS
Z
Zhu Yi 已提交
82 83 84 85


MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERSION);
86
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
Z
Zhu Yi 已提交
87
MODULE_LICENSE("GPL");
T
Tomas Winkler 已提交
88
MODULE_ALIAS("iwl4965");
Z
Zhu Yi 已提交
89 90

/*************** STATION TABLE MANAGEMENT ****
91
 * mac80211 should be examined to determine if sta_info is duplicating
Z
Zhu Yi 已提交
92 93 94 95 96 97
 * the functionality provided here
 */

/**************************************************************/

/**
98
 * iwl_commit_rxon - commit staging_rxon to hardware
Z
Zhu Yi 已提交
99
 *
100
 * The RXON command in staging_rxon is committed to the hardware and
Z
Zhu Yi 已提交
101 102 103 104
 * the active_rxon structure is updated with the new data.  This
 * function correctly transitions out of the RXON_ASSOC_MSK state if
 * a HW tune is required based on the RXON structure changes.
 */
105
static int iwl_commit_rxon(struct iwl_priv *priv)
Z
Zhu Yi 已提交
106 107
{
	/* cast away the const for active_rxon in this function */
G
Gregory Greenman 已提交
108
	struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
109 110 111
	int ret;
	bool new_assoc =
		!!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
Z
Zhu Yi 已提交
112

113
	if (!iwl_is_alive(priv))
114
		return -EBUSY;
Z
Zhu Yi 已提交
115 116 117

	/* always get timestamp with Rx frame */
	priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
118 119 120
	/* allow CTS-to-self if possible. this is relevant only for
	 * 5000, but will not damage 4965 */
	priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
Z
Zhu Yi 已提交
121

122
	ret = iwl_check_rxon_cmd(priv);
123
	if (ret) {
124
		IWL_ERR(priv, "Invalid RXON configuration.  Not committing.\n");
Z
Zhu Yi 已提交
125 126 127 128
		return -EINVAL;
	}

	/* If we don't need to send a full RXON, we can use
129
	 * iwl_rxon_assoc_cmd which is used to reconfigure filter
Z
Zhu Yi 已提交
130
	 * and other flags for the current radio configuration. */
131
	if (!iwl_full_rxon_required(priv)) {
132 133
		ret = iwl_send_rxon_assoc(priv);
		if (ret) {
134
			IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
135
			return ret;
Z
Zhu Yi 已提交
136 137 138 139 140 141 142 143 144 145 146 147 148
		}

		memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
		return 0;
	}

	/* station table will be cleared */
	priv->assoc_station_added = 0;

	/* If we are currently associated and the new config requires
	 * an RXON_ASSOC and the new config wants the associated mask enabled,
	 * we must clear the associated from the active configuration
	 * before we apply the new config */
149
	if (iwl_is_associated(priv) && new_assoc) {
150
		IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
Z
Zhu Yi 已提交
151 152
		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;

153
		ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
G
Gregory Greenman 已提交
154
				      sizeof(struct iwl_rxon_cmd),
Z
Zhu Yi 已提交
155 156 157 158
				      &priv->active_rxon);

		/* If the mask clearing failed then we set
		 * active_rxon back to what it was previously */
159
		if (ret) {
Z
Zhu Yi 已提交
160
			active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
161
			IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
162
			return ret;
Z
Zhu Yi 已提交
163 164 165
		}
	}

166
	IWL_DEBUG_INFO(priv, "Sending RXON\n"
Z
Zhu Yi 已提交
167 168
		       "* with%s RXON_FILTER_ASSOC_MSK\n"
		       "* channel = %d\n"
J
Johannes Berg 已提交
169
		       "* bssid = %pM\n",
170
		       (new_assoc ? "" : "out"),
Z
Zhu Yi 已提交
171
		       le16_to_cpu(priv->staging_rxon.channel),
J
Johannes Berg 已提交
172
		       priv->staging_rxon.bssid_addr);
Z
Zhu Yi 已提交
173

174
	iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
175 176 177 178 179 180 181 182

	/* Apply the new configuration
	 * RXON unassoc clears the station table in uCode, send it before
	 * we add the bcast station. If assoc bit is set, we will send RXON
	 * after having added the bcast and bssid station.
	 */
	if (!new_assoc) {
		ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
G
Gregory Greenman 已提交
183
			      sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
184
		if (ret) {
185
			IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
186 187 188
			return ret;
		}
		memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
Z
Zhu Yi 已提交
189 190
	}

191
	iwl_clear_stations_table(priv);
192

Z
Zhu Yi 已提交
193 194 195 196
	if (!priv->error_recovering)
		priv->start_calib = 0;

	/* Add the broadcast address so we can send broadcast frames */
197
	if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) ==
198
						IWL_INVALID_STATION) {
199
		IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
Z
Zhu Yi 已提交
200 201 202 203 204
		return -EIO;
	}

	/* If we have set the ASSOC_MSK and we are in BSS mode then
	 * add the IWL_AP_ID to the station rate table */
205
	if (new_assoc) {
206
		if (priv->iw_mode == NL80211_IFTYPE_STATION) {
207 208 209
			ret = iwl_rxon_add_station(priv,
					   priv->active_rxon.bssid_addr, 1);
			if (ret == IWL_INVALID_STATION) {
210 211
				IWL_ERR(priv,
					"Error adding AP address for TX.\n");
212 213 214 215 216
				return -EIO;
			}
			priv->assoc_station_added = 1;
			if (priv->default_wep_key &&
			    iwl_send_static_wepkey_cmd(priv, 0))
217 218
				IWL_ERR(priv,
					"Could not send WEP static key.\n");
Z
Zhu Yi 已提交
219
		}
220 221 222 223 224 225 226

		/* Apply the new configuration
		 * RXON assoc doesn't clear the station table in uCode,
		 */
		ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
			      sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
		if (ret) {
227
			IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
228 229 230
			return ret;
		}
		memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
Z
Zhu Yi 已提交
231 232
	}

233 234 235 236 237 238
	iwl_init_sensitivity(priv);

	/* If we issue a new RXON command which required a tune then we must
	 * send a new TXPOWER command or we won't be able to Tx any frames */
	ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
	if (ret) {
239
		IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
240 241 242
		return ret;
	}

Z
Zhu Yi 已提交
243 244 245
	return 0;
}

246
void iwl_update_chain_flags(struct iwl_priv *priv)
M
Mohamed Abbas 已提交
247 248
{

R
Ron Rindjunsky 已提交
249
	iwl_set_rxon_chain(priv);
250
	iwl_commit_rxon(priv);
M
Mohamed Abbas 已提交
251 252
}

253
static void iwl_clear_free_frames(struct iwl_priv *priv)
Z
Zhu Yi 已提交
254 255 256
{
	struct list_head *element;

257
	IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n",
Z
Zhu Yi 已提交
258 259 260 261 262
		       priv->frames_count);

	while (!list_empty(&priv->free_frames)) {
		element = priv->free_frames.next;
		list_del(element);
263
		kfree(list_entry(element, struct iwl_frame, list));
Z
Zhu Yi 已提交
264 265 266 267
		priv->frames_count--;
	}

	if (priv->frames_count) {
268
		IWL_WARN(priv, "%d frames still in use.  Did we lose one?\n",
Z
Zhu Yi 已提交
269 270 271 272 273
			    priv->frames_count);
		priv->frames_count = 0;
	}
}

274
static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv)
Z
Zhu Yi 已提交
275
{
276
	struct iwl_frame *frame;
Z
Zhu Yi 已提交
277 278 279 280
	struct list_head *element;
	if (list_empty(&priv->free_frames)) {
		frame = kzalloc(sizeof(*frame), GFP_KERNEL);
		if (!frame) {
281
			IWL_ERR(priv, "Could not allocate frame!\n");
Z
Zhu Yi 已提交
282 283 284 285 286 287 288 289 290
			return NULL;
		}

		priv->frames_count++;
		return frame;
	}

	element = priv->free_frames.next;
	list_del(element);
291
	return list_entry(element, struct iwl_frame, list);
Z
Zhu Yi 已提交
292 293
}

294
static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
Z
Zhu Yi 已提交
295 296 297 298 299
{
	memset(frame, 0, sizeof(*frame));
	list_add(&frame->list, &priv->free_frames);
}

300 301
static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
					  struct ieee80211_hdr *hdr,
302
					  int left)
Z
Zhu Yi 已提交
303
{
304
	if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
305 306
	    ((priv->iw_mode != NL80211_IFTYPE_ADHOC) &&
	     (priv->iw_mode != NL80211_IFTYPE_AP)))
Z
Zhu Yi 已提交
307 308 309 310 311 312 313 314 315 316
		return 0;

	if (priv->ibss_beacon->len > left)
		return 0;

	memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len);

	return priv->ibss_beacon->len;
}

317
static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
				       struct iwl_frame *frame, u8 rate)
{
	struct iwl_tx_beacon_cmd *tx_beacon_cmd;
	unsigned int frame_size;

	tx_beacon_cmd = &frame->u.beacon;
	memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));

	tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
	tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;

	frame_size = iwl_fill_beacon_frame(priv, tx_beacon_cmd->frame,
				sizeof(frame->u) - sizeof(*tx_beacon_cmd));

	BUG_ON(frame_size > MAX_MPDU_SIZE);
	tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);

	if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))
		tx_beacon_cmd->tx.rate_n_flags =
			iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
	else
		tx_beacon_cmd->tx.rate_n_flags =
			iwl_hw_set_rate_n_flags(rate, 0);

	tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK |
				     TX_CMD_FLG_TSF_MSK |
				     TX_CMD_FLG_STA_RATE_MSK;

	return sizeof(*tx_beacon_cmd) + frame_size;
}
348
static int iwl_send_beacon_cmd(struct iwl_priv *priv)
Z
Zhu Yi 已提交
349
{
350
	struct iwl_frame *frame;
Z
Zhu Yi 已提交
351 352 353 354
	unsigned int frame_size;
	int rc;
	u8 rate;

355
	frame = iwl_get_free_frame(priv);
Z
Zhu Yi 已提交
356 357

	if (!frame) {
358
		IWL_ERR(priv, "Could not obtain free frame buffer for beacon "
Z
Zhu Yi 已提交
359 360 361 362
			  "command.\n");
		return -ENOMEM;
	}

363
	rate = iwl_rate_get_lowest_plcp(priv);
Z
Zhu Yi 已提交
364

365
	frame_size = iwl_hw_get_beacon_cmd(priv, frame, rate);
Z
Zhu Yi 已提交
366

367
	rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
Z
Zhu Yi 已提交
368 369
			      &frame->u.cmd[0]);

370
	iwl_free_frame(priv, frame);
Z
Zhu Yi 已提交
371 372 373 374

	return rc;
}

375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
{
	struct iwl_tfd_tb *tb = &tfd->tbs[idx];

	dma_addr_t addr = get_unaligned_le32(&tb->lo);
	if (sizeof(dma_addr_t) > sizeof(u32))
		addr |=
		((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;

	return addr;
}

static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
{
	struct iwl_tfd_tb *tb = &tfd->tbs[idx];

	return le16_to_cpu(tb->hi_n_len) >> 4;
}

static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
				  dma_addr_t addr, u16 len)
{
	struct iwl_tfd_tb *tb = &tfd->tbs[idx];
	u16 hi_n_len = len << 4;

	put_unaligned_le32(addr, &tb->lo);
	if (sizeof(dma_addr_t) > sizeof(u32))
		hi_n_len |= ((addr >> 16) >> 16) & 0xF;

	tb->hi_n_len = cpu_to_le16(hi_n_len);

	tfd->num_tbs = idx + 1;
}

static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
{
	return tfd->num_tbs & 0x1f;
}

/**
 * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
 * @priv - driver private data
 * @txq - tx queue
 *
 * Does NOT advance any TFD circular buffer read/write indexes
 * Does NOT free the TFD itself (which is within circular buffer)
 */
void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
{
424
	struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)txq->tfds;
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446
	struct iwl_tfd *tfd;
	struct pci_dev *dev = priv->pci_dev;
	int index = txq->q.read_ptr;
	int i;
	int num_tbs;

	tfd = &tfd_tmp[index];

	/* Sanity check on number of chunks */
	num_tbs = iwl_tfd_get_num_tbs(tfd);

	if (num_tbs >= IWL_NUM_OF_TBS) {
		IWL_ERR(priv, "Too many chunks: %i\n", num_tbs);
		/* @todo issue fatal error, it is quite serious situation */
		return;
	}

	/* Unmap tx_cmd */
	if (num_tbs)
		pci_unmap_single(dev,
				pci_unmap_addr(&txq->cmd[index]->meta, mapping),
				pci_unmap_len(&txq->cmd[index]->meta, len),
447
				PCI_DMA_BIDIRECTIONAL);
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466

	/* Unmap chunks, if any. */
	for (i = 1; i < num_tbs; i++) {
		pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
				iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);

		if (txq->txb) {
			dev_kfree_skb(txq->txb[txq->q.read_ptr].skb[i - 1]);
			txq->txb[txq->q.read_ptr].skb[i - 1] = NULL;
		}
	}
}

int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
				 struct iwl_tx_queue *txq,
				 dma_addr_t addr, u16 len,
				 u8 reset, u8 pad)
{
	struct iwl_queue *q;
467
	struct iwl_tfd *tfd, *tfd_tmp;
468 469 470
	u32 num_tbs;

	q = &txq->q;
471 472
	tfd_tmp = (struct iwl_tfd *)txq->tfds;
	tfd = &tfd_tmp[q->write_ptr];
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495

	if (reset)
		memset(tfd, 0, sizeof(*tfd));

	num_tbs = iwl_tfd_get_num_tbs(tfd);

	/* Each TFD can point to a maximum 20 Tx buffers */
	if (num_tbs >= IWL_NUM_OF_TBS) {
		IWL_ERR(priv, "Error can not send more than %d chunks\n",
			  IWL_NUM_OF_TBS);
		return -EINVAL;
	}

	BUG_ON(addr & ~DMA_BIT_MASK(36));
	if (unlikely(addr & ~IWL_TX_DMA_MASK))
		IWL_ERR(priv, "Unaligned address = %llx\n",
			  (unsigned long long)addr);

	iwl_tfd_set_tb(tfd, num_tbs, addr, len);

	return 0;
}

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
/*
 * Tell nic where to find circular buffer of Tx Frame Descriptors for
 * given Tx queue, and enable the DMA channel used for that queue.
 *
 * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
 * channels supported in hardware.
 */
int iwl_hw_tx_queue_init(struct iwl_priv *priv,
			 struct iwl_tx_queue *txq)
{
	int ret;
	unsigned long flags;
	int txq_id = txq->q.id;

	spin_lock_irqsave(&priv->lock, flags);
	ret = iwl_grab_nic_access(priv);
	if (ret) {
		spin_unlock_irqrestore(&priv->lock, flags);
		return ret;
	}

	/* Circular buffer (TFD queue in DRAM) physical base address */
	iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
			     txq->q.dma_addr >> 8);

	iwl_release_nic_access(priv);
	spin_unlock_irqrestore(&priv->lock, flags);

	return 0;
}


Z
Zhu Yi 已提交
528 529 530 531 532 533
/******************************************************************************
 *
 * Misc. internal state and helper functions
 *
 ******************************************************************************/

534
static void iwl_ht_conf(struct iwl_priv *priv,
535 536
			    struct ieee80211_bss_conf *bss_conf)
{
J
Johannes Berg 已提交
537
	struct ieee80211_sta_ht_cap *ht_conf;
538
	struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
J
Johannes Berg 已提交
539
	struct ieee80211_sta *sta;
540

541
	IWL_DEBUG_MAC80211(priv, "enter: \n");
542 543 544 545

	if (!iwl_conf->is_ht)
		return;

J
Johannes Berg 已提交
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560

	/*
	 * It is totally wrong to base global information on something
	 * that is valid only when associated, alas, this driver works
	 * that way and I don't know how to fix it.
	 */

	rcu_read_lock();
	sta = ieee80211_find_sta(priv->hw, priv->bssid);
	if (!sta) {
		rcu_read_unlock();
		return;
	}
	ht_conf = &sta->ht_cap;

561
	if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
562
		iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
563
	if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
564
		iwl_conf->sgf |= HT_SHORT_GI_40MHZ;
565 566 567 568 569 570

	iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
	iwl_conf->max_amsdu_size =
		!!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);

	iwl_conf->supported_chan_width =
J
Johannes Berg 已提交
571
		!!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
J
Johannes Berg 已提交
572

S
Sujith 已提交
573 574 575 576 577 578
	/*
	 * XXX: The HT configuration needs to be moved into iwl_mac_config()
	 *	to be done there correctly.
	 */

	iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
579
	if (conf_is_ht40_minus(&priv->hw->conf))
S
Sujith 已提交
580
		iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
581
	else if (conf_is_ht40_plus(&priv->hw->conf))
S
Sujith 已提交
582 583
		iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;

584
	/* If no above or below channel supplied disable FAT channel */
J
Johannes Berg 已提交
585
	if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE &&
S
Sujith 已提交
586
	    iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW)
587 588
		iwl_conf->supported_chan_width = 0;

589 590
	iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);

J
Johannes Berg 已提交
591
	memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16);
592

S
Sujith 已提交
593
	iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0;
594
	iwl_conf->ht_protection =
J
Johannes Berg 已提交
595
		bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
596
	iwl_conf->non_GF_STA_present =
J
Johannes Berg 已提交
597 598 599
		!!(bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);

	rcu_read_unlock();
600

601
	IWL_DEBUG_MAC80211(priv, "leave\n");
602 603
}

Z
Zhu Yi 已提交
604 605 606
/*
 * QoS  support
*/
607
static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
Z
Zhu Yi 已提交
608 609 610 611 612 613 614 615 616 617 618 619 620 621
{
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return;

	priv->qos_data.def_qos_parm.qos_flags = 0;

	if (priv->qos_data.qos_cap.q_AP.queue_request &&
	    !priv->qos_data.qos_cap.q_AP.txop_request)
		priv->qos_data.def_qos_parm.qos_flags |=
			QOS_PARAM_FLG_TXOP_TYPE_MSK;
	if (priv->qos_data.qos_active)
		priv->qos_data.def_qos_parm.qos_flags |=
			QOS_PARAM_FLG_UPDATE_EDCA_MSK;

622
	if (priv->current_ht_config.is_ht)
623 624
		priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;

625
	if (force || iwl_is_associated(priv)) {
626
		IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
627 628
				priv->qos_data.qos_active,
				priv->qos_data.def_qos_parm.qos_flags);
Z
Zhu Yi 已提交
629

630 631 632
		iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
				       sizeof(struct iwl_qosparam_cmd),
				       &priv->qos_data.def_qos_parm, NULL);
Z
Zhu Yi 已提交
633 634 635 636 637
	}
}

#define MAX_UCODE_BEACON_INTERVAL	4096

638
static u16 iwl_adjust_beacon_interval(u16 beacon_val)
Z
Zhu Yi 已提交
639 640 641 642
{
	u16 new_val = 0;
	u16 beacon_factor = 0;

643 644
	beacon_factor = (beacon_val + MAX_UCODE_BEACON_INTERVAL)
					/ MAX_UCODE_BEACON_INTERVAL;
Z
Zhu Yi 已提交
645 646
	new_val = beacon_val / beacon_factor;

647 648 649
	if (!new_val)
		new_val = MAX_UCODE_BEACON_INTERVAL;

650
	return new_val;
Z
Zhu Yi 已提交
651 652
}

653
static void iwl_setup_rxon_timing(struct iwl_priv *priv)
Z
Zhu Yi 已提交
654
{
655 656
	u64 tsf;
	s32 interval_tm, rem;
Z
Zhu Yi 已提交
657 658 659 660 661 662 663
	unsigned long flags;
	struct ieee80211_conf *conf = NULL;
	u16 beacon_int = 0;

	conf = ieee80211_get_hw_conf(priv->hw);

	spin_lock_irqsave(&priv->lock, flags);
664
	priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
665
	priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);
Z
Zhu Yi 已提交
666

667
	if (priv->iw_mode == NL80211_IFTYPE_STATION) {
668
		beacon_int = iwl_adjust_beacon_interval(priv->beacon_int);
Z
Zhu Yi 已提交
669 670
		priv->rxon_timing.atim_window = 0;
	} else {
671 672
		beacon_int = iwl_adjust_beacon_interval(conf->beacon_int);

Z
Zhu Yi 已提交
673 674 675 676 677
		/* TODO: we need to get atim_window from upper stack
		 * for now we set to 0 */
		priv->rxon_timing.atim_window = 0;
	}

678
	priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int);
Z
Zhu Yi 已提交
679

680 681 682 683 684 685
	tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
	interval_tm = beacon_int * 1024;
	rem = do_div(tsf, interval_tm);
	priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem);

	spin_unlock_irqrestore(&priv->lock, flags);
686
	IWL_DEBUG_ASSOC(priv, "beacon interval %d beacon timer %d beacon tim %d\n",
687 688 689
			le16_to_cpu(priv->rxon_timing.beacon_interval),
			le32_to_cpu(priv->rxon_timing.beacon_init_val),
			le16_to_cpu(priv->rxon_timing.atim_window));
Z
Zhu Yi 已提交
690 691
}

692
static int iwl_set_mode(struct iwl_priv *priv, int mode)
Z
Zhu Yi 已提交
693
{
694
	iwl_connection_init_rx_config(priv, mode);
695
	iwl_set_rxon_chain(priv);
Z
Zhu Yi 已提交
696 697
	memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);

698
	iwl_clear_stations_table(priv);
Z
Zhu Yi 已提交
699

700
	/* dont commit rxon if rf-kill is on*/
701
	if (!iwl_is_ready_rf(priv))
702 703 704
		return -EAGAIN;

	cancel_delayed_work(&priv->scan_check);
705
	if (iwl_scan_cancel_timeout(priv, 100)) {
706
		IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
707
		IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
708 709 710
		return -EAGAIN;
	}

711
	iwl_commit_rxon(priv);
Z
Zhu Yi 已提交
712 713 714 715 716 717 718 719 720

	return 0;
}

/******************************************************************************
 *
 * Generic RX handler implementations
 *
 ******************************************************************************/
721 722
static void iwl_rx_reply_alive(struct iwl_priv *priv,
				struct iwl_rx_mem_buffer *rxb)
Z
Zhu Yi 已提交
723
{
724
	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
725
	struct iwl_alive_resp *palive;
Z
Zhu Yi 已提交
726 727 728 729
	struct delayed_work *pwork;

	palive = &pkt->u.alive_frame;

730
	IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
Z
Zhu Yi 已提交
731 732 733 734 735
		       "0x%01X 0x%01X\n",
		       palive->is_valid, palive->ver_type,
		       palive->ver_subtype);

	if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
736
		IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
Z
Zhu Yi 已提交
737 738
		memcpy(&priv->card_alive_init,
		       &pkt->u.alive_frame,
739
		       sizeof(struct iwl_init_alive_resp));
Z
Zhu Yi 已提交
740 741
		pwork = &priv->init_alive_start;
	} else {
742
		IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
Z
Zhu Yi 已提交
743
		memcpy(&priv->card_alive, &pkt->u.alive_frame,
744
		       sizeof(struct iwl_alive_resp));
Z
Zhu Yi 已提交
745 746 747 748 749 750 751 752 753
		pwork = &priv->alive_start;
	}

	/* We delay the ALIVE response by 5ms to
	 * give the HW RF Kill time to activate... */
	if (palive->is_valid == UCODE_VALID_OK)
		queue_delayed_work(priv->workqueue, pwork,
				   msecs_to_jiffies(5));
	else
754
		IWL_WARN(priv, "uCode did not respond OK.\n");
Z
Zhu Yi 已提交
755 756
}

757
static void iwl_bg_beacon_update(struct work_struct *work)
Z
Zhu Yi 已提交
758
{
759 760
	struct iwl_priv *priv =
		container_of(work, struct iwl_priv, beacon_update);
Z
Zhu Yi 已提交
761 762 763
	struct sk_buff *beacon;

	/* Pull updated AP beacon from mac80211. will fail if not in AP mode */
764
	beacon = ieee80211_beacon_get(priv->hw, priv->vif);
Z
Zhu Yi 已提交
765 766

	if (!beacon) {
767
		IWL_ERR(priv, "update beacon failed\n");
Z
Zhu Yi 已提交
768 769 770 771 772 773 774 775 776 777 778
		return;
	}

	mutex_lock(&priv->mutex);
	/* new beacon skb is allocated every time; dispose previous.*/
	if (priv->ibss_beacon)
		dev_kfree_skb(priv->ibss_beacon);

	priv->ibss_beacon = beacon;
	mutex_unlock(&priv->mutex);

779
	iwl_send_beacon_cmd(priv);
Z
Zhu Yi 已提交
780 781
}

782
/**
783
 * iwl_bg_statistics_periodic - Timer callback to queue statistics
784 785 786 787 788 789 790 791
 *
 * 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.
 */
792
static void iwl_bg_statistics_periodic(unsigned long data)
793 794 795 796 797 798
{
	struct iwl_priv *priv = (struct iwl_priv *)data;

	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return;

799 800 801 802
	/* dont send host command if rf-kill is on */
	if (!iwl_is_ready_rf(priv))
		return;

803 804 805
	iwl_send_statistics_request(priv, CMD_ASYNC);
}

806
static void iwl_rx_beacon_notif(struct iwl_priv *priv,
807
				struct iwl_rx_mem_buffer *rxb)
Z
Zhu Yi 已提交
808
{
809
#ifdef CONFIG_IWLWIFI_DEBUG
810
	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
811 812
	struct iwl4965_beacon_notif *beacon =
		(struct iwl4965_beacon_notif *)pkt->u.raw;
813
	u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
Z
Zhu Yi 已提交
814

815
	IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d "
Z
Zhu Yi 已提交
816
		"tsf %d %d rate %d\n",
817
		le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK,
Z
Zhu Yi 已提交
818 819 820 821 822 823
		beacon->beacon_notify_hdr.failure_frame,
		le32_to_cpu(beacon->ibss_mgr_status),
		le32_to_cpu(beacon->high_tsf),
		le32_to_cpu(beacon->low_tsf), rate);
#endif

824
	if ((priv->iw_mode == NL80211_IFTYPE_AP) &&
Z
Zhu Yi 已提交
825 826 827 828 829 830
	    (!test_bit(STATUS_EXIT_PENDING, &priv->status)))
		queue_work(priv->workqueue, &priv->beacon_update);
}

/* Handle notification from uCode that card's power state is changing
 * due to software, hardware, or critical temperature RFKILL */
831
static void iwl_rx_card_state_notif(struct iwl_priv *priv,
832
				    struct iwl_rx_mem_buffer *rxb)
Z
Zhu Yi 已提交
833
{
834
	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
Z
Zhu Yi 已提交
835 836 837
	u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
	unsigned long status = priv->status;

838
	IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n",
Z
Zhu Yi 已提交
839 840 841 842 843 844
			  (flags & HW_CARD_DISABLED) ? "Kill" : "On",
			  (flags & SW_CARD_DISABLED) ? "Kill" : "On");

	if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
		     RF_CARD_DISABLED)) {

845
		iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
Z
Zhu Yi 已提交
846 847
			    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);

848 849
		if (!iwl_grab_nic_access(priv)) {
			iwl_write_direct32(
Z
Zhu Yi 已提交
850 851 852
				priv, HBUS_TARG_MBX_C,
				HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);

853
			iwl_release_nic_access(priv);
Z
Zhu Yi 已提交
854 855 856
		}

		if (!(flags & RXON_CARD_DISABLED)) {
857
			iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
Z
Zhu Yi 已提交
858
				    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
859 860
			if (!iwl_grab_nic_access(priv)) {
				iwl_write_direct32(
Z
Zhu Yi 已提交
861 862 863
					priv, HBUS_TARG_MBX_C,
					HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);

864
				iwl_release_nic_access(priv);
Z
Zhu Yi 已提交
865 866 867 868
			}
		}

		if (flags & RF_CARD_DISABLED) {
869
			iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
Z
Zhu Yi 已提交
870
				    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
871 872 873
			iwl_read32(priv, CSR_UCODE_DRV_GP1);
			if (!iwl_grab_nic_access(priv))
				iwl_release_nic_access(priv);
Z
Zhu Yi 已提交
874 875 876 877 878 879 880 881 882 883 884 885 886 887 888
		}
	}

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


	if (flags & SW_CARD_DISABLED)
		set_bit(STATUS_RF_KILL_SW, &priv->status);
	else
		clear_bit(STATUS_RF_KILL_SW, &priv->status);

	if (!(flags & RXON_CARD_DISABLED))
889
		iwl_scan_cancel(priv);
Z
Zhu Yi 已提交
890 891 892 893 894 895 896 897 898 899

	if ((test_bit(STATUS_RF_KILL_HW, &status) !=
	     test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
	    (test_bit(STATUS_RF_KILL_SW, &status) !=
	     test_bit(STATUS_RF_KILL_SW, &priv->status)))
		queue_work(priv->workqueue, &priv->rf_kill);
	else
		wake_up_interruptible(&priv->wait_command_queue);
}

900
int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
901 902 903 904 905 906 907 908 909 910
{
	int ret;
	unsigned long flags;

	spin_lock_irqsave(&priv->lock, flags);
	ret = iwl_grab_nic_access(priv);
	if (ret)
		goto err;

	if (src == IWL_PWR_SRC_VAUX) {
911
		if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
912 913 914 915 916 917 918 919 920 921 922 923 924 925 926
			iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
					       APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
					       ~APMG_PS_CTRL_MSK_PWR_SRC);
	} else {
		iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
				       APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
				       ~APMG_PS_CTRL_MSK_PWR_SRC);
	}

	iwl_release_nic_access(priv);
err:
	spin_unlock_irqrestore(&priv->lock, flags);
	return ret;
}

Z
Zhu Yi 已提交
927
/**
928
 * iwl_setup_rx_handlers - Initialize Rx handler callbacks
Z
Zhu Yi 已提交
929 930 931 932 933 934 935
 *
 * Setup the RX handlers for each of the reply types sent from the uCode
 * to the host.
 *
 * This function chains into the hardware specific files for them to setup
 * any hardware specific handlers as well.
 */
936
static void iwl_setup_rx_handlers(struct iwl_priv *priv)
Z
Zhu Yi 已提交
937
{
938
	priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
939 940 941
	priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
	priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
	priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
Z
Zhu Yi 已提交
942
	priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
943 944
	    iwl_rx_pm_debug_statistics_notif;
	priv->rx_handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif;
Z
Zhu Yi 已提交
945

946 947 948 949
	/*
	 * The same handler is used for both the REPLY to a discrete
	 * statistics request from the host as well as for the periodic
	 * statistics notifications (after received beacons) from the uCode.
Z
Zhu Yi 已提交
950
	 */
951 952
	priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics;
	priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
953

954
	iwl_setup_spectrum_handlers(priv);
955 956
	iwl_setup_rx_scan_handlers(priv);

957
	/* status change handler */
958
	priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif;
Z
Zhu Yi 已提交
959

960 961
	priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] =
	    iwl_rx_missed_beacon_notif;
962
	/* Rx handlers */
963 964
	priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy;
	priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx;
965 966
	/* block ack */
	priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl_rx_reply_compressed_ba;
967
	/* Set up hardware specific Rx handlers */
968
	priv->cfg->ops->lib->rx_handler_setup(priv);
Z
Zhu Yi 已提交
969 970 971
}

/**
972
 * iwl_rx_handle - Main entry function for receiving responses from uCode
Z
Zhu Yi 已提交
973 974 975 976 977
 *
 * Uses the priv->rx_handlers callback function array to invoke
 * the appropriate handlers, including command responses,
 * frame-received notifications, and other notifications.
 */
978
void iwl_rx_handle(struct iwl_priv *priv)
Z
Zhu Yi 已提交
979
{
980
	struct iwl_rx_mem_buffer *rxb;
981
	struct iwl_rx_packet *pkt;
982
	struct iwl_rx_queue *rxq = &priv->rxq;
Z
Zhu Yi 已提交
983 984 985
	u32 r, i;
	int reclaim;
	unsigned long flags;
986
	u8 fill_rx = 0;
M
Mohamed Abbas 已提交
987
	u32 count = 8;
Z
Zhu Yi 已提交
988

989 990
	/* uCode's read index (stored in shared DRAM) indicates the last Rx
	 * buffer that the driver may process (last buffer filled by ucode). */
991
	r = le16_to_cpu(rxq->rb_stts->closed_rb_num) &  0x0FFF;
Z
Zhu Yi 已提交
992 993 994 995
	i = rxq->read;

	/* Rx interrupt, but nothing sent from uCode */
	if (i == r)
996
		IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
Z
Zhu Yi 已提交
997

998
	if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
999 1000
		fill_rx = 1;

Z
Zhu Yi 已提交
1001 1002 1003
	while (i != r) {
		rxb = rxq->queue[i];

1004
		/* If an RXB doesn't have a Rx queue slot associated with it,
Z
Zhu Yi 已提交
1005 1006 1007 1008 1009 1010
		 * then a bug has been introduced in the queue refilling
		 * routines -- catch it here */
		BUG_ON(rxb == NULL);

		rxq->queue[i] = NULL;

J
Johannes Berg 已提交
1011 1012 1013 1014 1015
		dma_sync_single_range_for_cpu(
				&priv->pci_dev->dev, rxb->real_dma_addr,
				rxb->aligned_dma_addr - rxb->real_dma_addr,
				priv->hw_params.rx_buf_size,
				PCI_DMA_FROMDEVICE);
1016
		pkt = (struct iwl_rx_packet *)rxb->skb->data;
Z
Zhu Yi 已提交
1017 1018 1019 1020 1021 1022 1023 1024 1025

		/* Reclaim a command buffer only if this packet is a response
		 *   to a (driver-originated) command.
		 * If the packet (e.g. Rx frame) originated from uCode,
		 *   there is no command buffer to reclaim.
		 * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
		 *   but apparently a few don't get set; catch them here. */
		reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
			(pkt->hdr.cmd != REPLY_RX_PHY_CMD) &&
1026
			(pkt->hdr.cmd != REPLY_RX) &&
D
Daniel Halperin 已提交
1027
			(pkt->hdr.cmd != REPLY_RX_MPDU_CMD) &&
1028
			(pkt->hdr.cmd != REPLY_COMPRESSED_BA) &&
Z
Zhu Yi 已提交
1029 1030 1031 1032 1033
			(pkt->hdr.cmd != STATISTICS_NOTIFICATION) &&
			(pkt->hdr.cmd != REPLY_TX);

		/* Based on type of command response or notification,
		 *   handle those that need handling via function in
1034
		 *   rx_handlers table.  See iwl_setup_rx_handlers() */
Z
Zhu Yi 已提交
1035
		if (priv->rx_handlers[pkt->hdr.cmd]) {
1036
			IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
1037
				i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
Z
Zhu Yi 已提交
1038 1039 1040
			priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
		} else {
			/* No handling needed */
1041
			IWL_DEBUG_RX(priv,
Z
Zhu Yi 已提交
1042 1043 1044 1045 1046 1047
				"r %d i %d No handler needed for %s, 0x%02x\n",
				r, i, get_cmd_string(pkt->hdr.cmd),
				pkt->hdr.cmd);
		}

		if (reclaim) {
1048
			/* Invoke any callbacks, transfer the skb to caller, and
1049
			 * fire off the (possibly) blocking iwl_send_cmd()
Z
Zhu Yi 已提交
1050 1051
			 * as we reclaim the driver command queue */
			if (rxb && rxb->skb)
1052
				iwl_tx_cmd_complete(priv, rxb);
Z
Zhu Yi 已提交
1053
			else
1054
				IWL_WARN(priv, "Claim null rxb?\n");
Z
Zhu Yi 已提交
1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065
		}

		/* For now we just don't re-use anything.  We can tweak this
		 * later to try and re-use notification packets and SKBs that
		 * fail to Rx correctly */
		if (rxb->skb != NULL) {
			priv->alloc_rxb_skb--;
			dev_kfree_skb_any(rxb->skb);
			rxb->skb = NULL;
		}

J
Johannes Berg 已提交
1066 1067
		pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
				 priv->hw_params.rx_buf_size + 256,
1068
				 PCI_DMA_FROMDEVICE);
Z
Zhu Yi 已提交
1069 1070 1071 1072
		spin_lock_irqsave(&rxq->lock, flags);
		list_add_tail(&rxb->list, &priv->rxq.rx_used);
		spin_unlock_irqrestore(&rxq->lock, flags);
		i = (i + 1) & RX_QUEUE_MASK;
1073 1074 1075 1076 1077 1078
		/* If there are a lot of unused frames,
		 * restock the Rx queue so ucode wont assert. */
		if (fill_rx) {
			count++;
			if (count >= 8) {
				priv->rxq.read = i;
1079
				iwl_rx_queue_restock(priv);
1080 1081 1082
				count = 0;
			}
		}
Z
Zhu Yi 已提交
1083 1084 1085 1086
	}

	/* Backtrack one entry */
	priv->rxq.read = i;
1087 1088 1089
	iwl_rx_queue_restock(priv);
}

1090 1091 1092
/* call this function to flush any scheduled tasklet */
static inline void iwl_synchronize_irq(struct iwl_priv *priv)
{
T
Tomas Winkler 已提交
1093
	/* wait to make sure we flush pending tasklet*/
1094 1095 1096 1097
	synchronize_irq(priv->pci_dev->irq);
	tasklet_kill(&priv->irq_tasklet);
}

1098
static void iwl_error_recovery(struct iwl_priv *priv)
Z
Zhu Yi 已提交
1099 1100 1101 1102 1103 1104
{
	unsigned long flags;

	memcpy(&priv->staging_rxon, &priv->recovery_rxon,
	       sizeof(priv->staging_rxon));
	priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1105
	iwl_commit_rxon(priv);
Z
Zhu Yi 已提交
1106

1107
	iwl_rxon_add_station(priv, priv->bssid, 1);
Z
Zhu Yi 已提交
1108 1109 1110 1111 1112 1113 1114

	spin_lock_irqsave(&priv->lock, flags);
	priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
	priv->error_recovering = 0;
	spin_unlock_irqrestore(&priv->lock, flags);
}

1115
static void iwl_irq_tasklet(struct iwl_priv *priv)
Z
Zhu Yi 已提交
1116 1117 1118 1119
{
	u32 inta, handled = 0;
	u32 inta_fh;
	unsigned long flags;
1120
#ifdef CONFIG_IWLWIFI_DEBUG
Z
Zhu Yi 已提交
1121 1122 1123 1124 1125 1126 1127 1128
	u32 inta_mask;
#endif

	spin_lock_irqsave(&priv->lock, flags);

	/* Ack/clear/reset pending uCode interrupts.
	 * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
	 *  and will clear only when CSR_FH_INT_STATUS gets cleared. */
1129 1130
	inta = iwl_read32(priv, CSR_INT);
	iwl_write32(priv, CSR_INT, inta);
Z
Zhu Yi 已提交
1131 1132 1133 1134

	/* Ack/clear/reset pending flow-handler (DMA) interrupts.
	 * Any new interrupts that happen after this, either while we're
	 * in this tasklet, or later, will show up in next ISR/tasklet. */
1135 1136
	inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
	iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
Z
Zhu Yi 已提交
1137

1138
#ifdef CONFIG_IWLWIFI_DEBUG
1139
	if (priv->debug_level & IWL_DL_ISR) {
1140
		/* just for debug */
1141
		inta_mask = iwl_read32(priv, CSR_INT_MASK);
1142
		IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
Z
Zhu Yi 已提交
1143 1144 1145 1146 1147 1148 1149 1150
			      inta, inta_mask, inta_fh);
	}
#endif

	/* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not
	 * atomic, make sure that inta covers all the interrupts that
	 * we've discovered, even if FH interrupt came in just after
	 * reading CSR_INT. */
T
Tomas Winkler 已提交
1151
	if (inta_fh & CSR49_FH_INT_RX_MASK)
Z
Zhu Yi 已提交
1152
		inta |= CSR_INT_BIT_FH_RX;
T
Tomas Winkler 已提交
1153
	if (inta_fh & CSR49_FH_INT_TX_MASK)
Z
Zhu Yi 已提交
1154 1155 1156 1157
		inta |= CSR_INT_BIT_FH_TX;

	/* Now service all interrupt bits discovered above. */
	if (inta & CSR_INT_BIT_HW_ERR) {
1158
		IWL_ERR(priv, "Microcode HW error detected.  Restarting.\n");
Z
Zhu Yi 已提交
1159 1160

		/* Tell the device to stop sending interrupts */
1161
		iwl_disable_interrupts(priv);
Z
Zhu Yi 已提交
1162

1163
		iwl_irq_handle_error(priv);
Z
Zhu Yi 已提交
1164 1165 1166 1167 1168 1169 1170 1171

		handled |= CSR_INT_BIT_HW_ERR;

		spin_unlock_irqrestore(&priv->lock, flags);

		return;
	}

1172
#ifdef CONFIG_IWLWIFI_DEBUG
1173
	if (priv->debug_level & (IWL_DL_ISR)) {
Z
Zhu Yi 已提交
1174
		/* NIC fires this, but we don't use it, redundant with WAKEUP */
1175
		if (inta & CSR_INT_BIT_SCD)
1176
			IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
1177
				      "the frame/frames.\n");
Z
Zhu Yi 已提交
1178 1179 1180

		/* Alive notification via Rx interrupt will do the real work */
		if (inta & CSR_INT_BIT_ALIVE)
1181
			IWL_DEBUG_ISR(priv, "Alive interrupt\n");
Z
Zhu Yi 已提交
1182 1183 1184
	}
#endif
	/* Safely ignore these bits for debug checks below */
1185
	inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
Z
Zhu Yi 已提交
1186

1187
	/* HW RF KILL switch toggled */
Z
Zhu Yi 已提交
1188 1189
	if (inta & CSR_INT_BIT_RF_KILL) {
		int hw_rf_kill = 0;
1190
		if (!(iwl_read32(priv, CSR_GP_CNTRL) &
Z
Zhu Yi 已提交
1191 1192 1193
				CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
			hw_rf_kill = 1;

1194
		IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n",
1195
				hw_rf_kill ? "disable radio" : "enable radio");
Z
Zhu Yi 已提交
1196

1197
		/* driver only loads ucode once setting the interface up.
1198 1199 1200
		 * the driver allows loading the ucode even if the radio
		 * is killed. Hence update the killswitch state here. The
		 * rfkill handler will care about restarting if needed.
1201
		 */
1202 1203 1204 1205 1206 1207
		if (!test_bit(STATUS_ALIVE, &priv->status)) {
			if (hw_rf_kill)
				set_bit(STATUS_RF_KILL_HW, &priv->status);
			else
				clear_bit(STATUS_RF_KILL_HW, &priv->status);
			queue_work(priv->workqueue, &priv->rf_kill);
1208
		}
Z
Zhu Yi 已提交
1209 1210 1211 1212

		handled |= CSR_INT_BIT_RF_KILL;
	}

1213
	/* Chip got too hot and stopped itself */
Z
Zhu Yi 已提交
1214
	if (inta & CSR_INT_BIT_CT_KILL) {
1215
		IWL_ERR(priv, "Microcode CT kill error detected.\n");
Z
Zhu Yi 已提交
1216 1217 1218 1219 1220
		handled |= CSR_INT_BIT_CT_KILL;
	}

	/* Error detected by uCode */
	if (inta & CSR_INT_BIT_SW_ERR) {
1221 1222
		IWL_ERR(priv, "Microcode SW error detected. "
			" Restarting 0x%X.\n", inta);
1223
		iwl_irq_handle_error(priv);
Z
Zhu Yi 已提交
1224 1225 1226 1227 1228
		handled |= CSR_INT_BIT_SW_ERR;
	}

	/* uCode wakes up after power-down sleep */
	if (inta & CSR_INT_BIT_WAKEUP) {
1229
		IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
1230
		iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
1231 1232 1233 1234 1235 1236
		iwl_txq_update_write_ptr(priv, &priv->txq[0]);
		iwl_txq_update_write_ptr(priv, &priv->txq[1]);
		iwl_txq_update_write_ptr(priv, &priv->txq[2]);
		iwl_txq_update_write_ptr(priv, &priv->txq[3]);
		iwl_txq_update_write_ptr(priv, &priv->txq[4]);
		iwl_txq_update_write_ptr(priv, &priv->txq[5]);
Z
Zhu Yi 已提交
1237 1238 1239 1240 1241 1242 1243 1244

		handled |= CSR_INT_BIT_WAKEUP;
	}

	/* All uCode command responses, including Tx command responses,
	 * Rx "responses" (frame-received notification), and other
	 * notifications from uCode come through here*/
	if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
1245
		iwl_rx_handle(priv);
Z
Zhu Yi 已提交
1246 1247 1248 1249
		handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
	}

	if (inta & CSR_INT_BIT_FH_TX) {
1250
		IWL_DEBUG_ISR(priv, "Tx interrupt\n");
Z
Zhu Yi 已提交
1251
		handled |= CSR_INT_BIT_FH_TX;
1252 1253 1254
		/* FH finished to write, send event */
		priv->ucode_write_complete = 1;
		wake_up_interruptible(&priv->wait_command_queue);
Z
Zhu Yi 已提交
1255 1256 1257
	}

	if (inta & ~handled)
1258
		IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
Z
Zhu Yi 已提交
1259 1260

	if (inta & ~CSR_INI_SET_MASK) {
1261
		IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
Z
Zhu Yi 已提交
1262
			 inta & ~CSR_INI_SET_MASK);
1263
		IWL_WARN(priv, "   with FH_INT = 0x%08x\n", inta_fh);
Z
Zhu Yi 已提交
1264 1265 1266
	}

	/* Re-enable all interrupts */
1267 1268
	/* only Re-enable if diabled by irq */
	if (test_bit(STATUS_INT_ENABLED, &priv->status))
1269
		iwl_enable_interrupts(priv);
Z
Zhu Yi 已提交
1270

1271
#ifdef CONFIG_IWLWIFI_DEBUG
1272
	if (priv->debug_level & (IWL_DL_ISR)) {
1273 1274 1275
		inta = iwl_read32(priv, CSR_INT);
		inta_mask = iwl_read32(priv, CSR_INT_MASK);
		inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
1276
		IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
Z
Zhu Yi 已提交
1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288
			"flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
	}
#endif
	spin_unlock_irqrestore(&priv->lock, flags);
}

/******************************************************************************
 *
 * uCode download functions
 *
 ******************************************************************************/

1289
static void iwl_dealloc_ucode_pci(struct iwl_priv *priv)
Z
Zhu Yi 已提交
1290
{
1291 1292 1293 1294 1295 1296
	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code);
	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data);
	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init);
	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data);
	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot);
Z
Zhu Yi 已提交
1297 1298
}

1299
static void iwl_nic_start(struct iwl_priv *priv)
1300 1301 1302 1303 1304 1305
{
	/* Remove all resets to allow NIC to operate */
	iwl_write32(priv, CSR_RESET, 0);
}


Z
Zhu Yi 已提交
1306
/**
1307
 * iwl_read_ucode - Read uCode images from disk file.
Z
Zhu Yi 已提交
1308 1309 1310
 *
 * Copy into buffers for card to fetch via bus-mastering
 */
1311
static int iwl_read_ucode(struct iwl_priv *priv)
Z
Zhu Yi 已提交
1312
{
1313
	struct iwl_ucode *ucode;
1314
	int ret = -EINVAL, index;
Z
Zhu Yi 已提交
1315
	const struct firmware *ucode_raw;
1316 1317 1318 1319
	const char *name_pre = priv->cfg->fw_name_pre;
	const unsigned int api_max = priv->cfg->ucode_api_max;
	const unsigned int api_min = priv->cfg->ucode_api_min;
	char buf[25];
Z
Zhu Yi 已提交
1320 1321
	u8 *src;
	size_t len;
1322
	u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size;
Z
Zhu Yi 已提交
1323 1324 1325

	/* Ask kernel firmware_class module to get the boot firmware off disk.
	 * request_firmware() is synchronous, file is in memory on return. */
1326 1327 1328 1329
	for (index = api_max; index >= api_min; index--) {
		sprintf(buf, "%s%d%s", name_pre, index, ".ucode");
		ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
		if (ret < 0) {
1330
			IWL_ERR(priv, "%s firmware file req failed: %d\n",
1331 1332 1333 1334 1335 1336 1337
				  buf, ret);
			if (ret == -ENOENT)
				continue;
			else
				goto error;
		} else {
			if (index < api_max)
1338 1339 1340
				IWL_ERR(priv, "Loaded firmware %s, "
					"which is deprecated. "
					"Please use API v%u instead.\n",
1341
					  buf, api_max);
1342

1343
			IWL_DEBUG_INFO(priv, "Got firmware '%s' file (%zd bytes) from disk\n",
1344 1345 1346
				       buf, ucode_raw->size);
			break;
		}
Z
Zhu Yi 已提交
1347 1348
	}

1349 1350
	if (ret < 0)
		goto error;
Z
Zhu Yi 已提交
1351 1352 1353

	/* Make sure that we got at least our header! */
	if (ucode_raw->size < sizeof(*ucode)) {
1354
		IWL_ERR(priv, "File size way too small!\n");
1355
		ret = -EINVAL;
Z
Zhu Yi 已提交
1356 1357 1358 1359 1360 1361
		goto err_release;
	}

	/* Data from ucode file:  header followed by uCode images */
	ucode = (void *)ucode_raw->data;

1362
	priv->ucode_ver = le32_to_cpu(ucode->ver);
1363
	api_ver = IWL_UCODE_API(priv->ucode_ver);
Z
Zhu Yi 已提交
1364 1365 1366 1367 1368 1369
	inst_size = le32_to_cpu(ucode->inst_size);
	data_size = le32_to_cpu(ucode->data_size);
	init_size = le32_to_cpu(ucode->init_size);
	init_data_size = le32_to_cpu(ucode->init_data_size);
	boot_size = le32_to_cpu(ucode->boot_size);

1370 1371 1372 1373 1374
	/* api_ver should match the api version forming part of the
	 * firmware filename ... but we don't check for that and only rely
	 * on the API version read from firware header from here on forward */

	if (api_ver < api_min || api_ver > api_max) {
1375
		IWL_ERR(priv, "Driver unable to support your firmware API. "
1376 1377 1378 1379 1380 1381 1382
			  "Driver supports v%u, firmware is v%u.\n",
			  api_max, api_ver);
		priv->ucode_ver = 0;
		ret = -EINVAL;
		goto err_release;
	}
	if (api_ver != api_max)
T
Tomas Winkler 已提交
1383
		IWL_ERR(priv, "Firmware has old API version. Expected v%u, "
1384 1385 1386 1387
			  "got v%u. New firmware can be obtained "
			  "from http://www.intellinuxwireless.org.\n",
			  api_max, api_ver);

T
Tomas Winkler 已提交
1388 1389 1390 1391 1392
	IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n",
	       IWL_UCODE_MAJOR(priv->ucode_ver),
	       IWL_UCODE_MINOR(priv->ucode_ver),
	       IWL_UCODE_API(priv->ucode_ver),
	       IWL_UCODE_SERIAL(priv->ucode_ver));
1393

1394
	IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
1395
		       priv->ucode_ver);
1396
	IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
Z
Zhu Yi 已提交
1397
		       inst_size);
1398
	IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %u\n",
Z
Zhu Yi 已提交
1399
		       data_size);
1400
	IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %u\n",
Z
Zhu Yi 已提交
1401
		       init_size);
1402
	IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %u\n",
Z
Zhu Yi 已提交
1403
		       init_data_size);
1404
	IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
Z
Zhu Yi 已提交
1405 1406 1407 1408 1409 1410 1411
		       boot_size);

	/* Verify size of file vs. image size info in file's header */
	if (ucode_raw->size < sizeof(*ucode) +
		inst_size + data_size + init_size +
		init_data_size + boot_size) {

1412
		IWL_DEBUG_INFO(priv, "uCode file size %d too small\n",
Z
Zhu Yi 已提交
1413
			       (int)ucode_raw->size);
1414
		ret = -EINVAL;
Z
Zhu Yi 已提交
1415 1416 1417 1418
		goto err_release;
	}

	/* Verify that uCode images will fit in card's SRAM */
1419
	if (inst_size > priv->hw_params.max_inst_size) {
1420
		IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n",
1421 1422
			       inst_size);
		ret = -EINVAL;
Z
Zhu Yi 已提交
1423 1424 1425
		goto err_release;
	}

1426
	if (data_size > priv->hw_params.max_data_size) {
1427
		IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n",
1428 1429
				data_size);
		ret = -EINVAL;
Z
Zhu Yi 已提交
1430 1431
		goto err_release;
	}
1432
	if (init_size > priv->hw_params.max_inst_size) {
1433 1434
		IWL_INFO(priv, "uCode init instr len %d too large to fit in\n",
			init_size);
1435
		ret = -EINVAL;
Z
Zhu Yi 已提交
1436 1437
		goto err_release;
	}
1438
	if (init_data_size > priv->hw_params.max_data_size) {
1439
		IWL_INFO(priv, "uCode init data len %d too large to fit in\n",
1440 1441
		      init_data_size);
		ret = -EINVAL;
Z
Zhu Yi 已提交
1442 1443
		goto err_release;
	}
1444
	if (boot_size > priv->hw_params.max_bsm_size) {
1445 1446
		IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n",
			boot_size);
1447
		ret = -EINVAL;
Z
Zhu Yi 已提交
1448 1449 1450 1451 1452 1453 1454 1455 1456
		goto err_release;
	}

	/* Allocate ucode buffers for card's bus-master loading ... */

	/* Runtime instructions and 2 copies of data:
	 * 1) unmodified from disk
	 * 2) backup cache for save/restore during power-downs */
	priv->ucode_code.len = inst_size;
1457
	iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code);
Z
Zhu Yi 已提交
1458 1459

	priv->ucode_data.len = data_size;
1460
	iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data);
Z
Zhu Yi 已提交
1461 1462

	priv->ucode_data_backup.len = data_size;
1463
	iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
Z
Zhu Yi 已提交
1464

1465 1466 1467 1468
	if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr ||
	    !priv->ucode_data_backup.v_addr)
		goto err_pci_alloc;

Z
Zhu Yi 已提交
1469
	/* Initialization instructions and data */
1470 1471
	if (init_size && init_data_size) {
		priv->ucode_init.len = init_size;
1472
		iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init);
1473 1474

		priv->ucode_init_data.len = init_data_size;
1475
		iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data);
1476 1477 1478 1479

		if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr)
			goto err_pci_alloc;
	}
Z
Zhu Yi 已提交
1480 1481

	/* Bootstrap (instructions only, no data) */
1482 1483
	if (boot_size) {
		priv->ucode_boot.len = boot_size;
1484
		iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot);
Z
Zhu Yi 已提交
1485

1486 1487 1488
		if (!priv->ucode_boot.v_addr)
			goto err_pci_alloc;
	}
Z
Zhu Yi 已提交
1489 1490 1491 1492 1493 1494

	/* Copy images into buffers for card's bus-master reads ... */

	/* Runtime instructions (first block of data in file) */
	src = &ucode->data[0];
	len = priv->ucode_code.len;
1495
	IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", len);
Z
Zhu Yi 已提交
1496
	memcpy(priv->ucode_code.v_addr, src, len);
1497
	IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
Z
Zhu Yi 已提交
1498 1499 1500
		priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);

	/* Runtime data (2nd block)
1501
	 * NOTE:  Copy into backup buffer will be done in iwl_up()  */
Z
Zhu Yi 已提交
1502 1503
	src = &ucode->data[inst_size];
	len = priv->ucode_data.len;
1504
	IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", len);
Z
Zhu Yi 已提交
1505 1506 1507 1508 1509 1510 1511
	memcpy(priv->ucode_data.v_addr, src, len);
	memcpy(priv->ucode_data_backup.v_addr, src, len);

	/* Initialization instructions (3rd block) */
	if (init_size) {
		src = &ucode->data[inst_size + data_size];
		len = priv->ucode_init.len;
1512
		IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
1513
				len);
Z
Zhu Yi 已提交
1514 1515 1516 1517 1518 1519 1520
		memcpy(priv->ucode_init.v_addr, src, len);
	}

	/* Initialization data (4th block) */
	if (init_data_size) {
		src = &ucode->data[inst_size + data_size + init_size];
		len = priv->ucode_init_data.len;
1521
		IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
1522
			       len);
Z
Zhu Yi 已提交
1523 1524 1525 1526 1527 1528
		memcpy(priv->ucode_init_data.v_addr, src, len);
	}

	/* Bootstrap instructions (5th block) */
	src = &ucode->data[inst_size + data_size + init_size + init_data_size];
	len = priv->ucode_boot.len;
1529
	IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
Z
Zhu Yi 已提交
1530 1531 1532 1533 1534 1535 1536
	memcpy(priv->ucode_boot.v_addr, src, len);

	/* We have our copies now, allow OS release its copies */
	release_firmware(ucode_raw);
	return 0;

 err_pci_alloc:
1537
	IWL_ERR(priv, "failed to allocate pci memory\n");
1538
	ret = -ENOMEM;
1539
	iwl_dealloc_ucode_pci(priv);
Z
Zhu Yi 已提交
1540 1541 1542 1543 1544

 err_release:
	release_firmware(ucode_raw);

 error:
1545
	return ret;
Z
Zhu Yi 已提交
1546 1547
}

1548 1549 1550 1551
/* temporary */
static int iwl_mac_beacon_update(struct ieee80211_hw *hw,
				 struct sk_buff *skb);

Z
Zhu Yi 已提交
1552
/**
1553
 * iwl_alive_start - called after REPLY_ALIVE notification received
Z
Zhu Yi 已提交
1554
 *                   from protocol/runtime uCode (initialization uCode's
1555
 *                   Alive gets handled by iwl_init_alive_start()).
Z
Zhu Yi 已提交
1556
 */
1557
static void iwl_alive_start(struct iwl_priv *priv)
Z
Zhu Yi 已提交
1558
{
1559
	int ret = 0;
Z
Zhu Yi 已提交
1560

1561
	IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
Z
Zhu Yi 已提交
1562 1563 1564 1565

	if (priv->card_alive.is_valid != UCODE_VALID_OK) {
		/* We had an error bringing up the hardware, so take it
		 * all the way back down so we can try again */
1566
		IWL_DEBUG_INFO(priv, "Alive failed.\n");
Z
Zhu Yi 已提交
1567 1568 1569 1570 1571 1572
		goto restart;
	}

	/* Initialize uCode has loaded Runtime uCode ... verify inst image.
	 * This is a paranoid check, because we would not have gotten the
	 * "runtime" alive if code weren't properly loaded.  */
1573
	if (iwl_verify_ucode(priv)) {
Z
Zhu Yi 已提交
1574 1575
		/* Runtime instruction load was bad;
		 * take it all the way back down so we can try again */
1576
		IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n");
Z
Zhu Yi 已提交
1577 1578 1579
		goto restart;
	}

1580
	iwl_clear_stations_table(priv);
1581 1582
	ret = priv->cfg->ops->lib->alive_notify(priv);
	if (ret) {
1583 1584
		IWL_WARN(priv,
			"Could not complete ALIVE transition [ntf]: %d\n", ret);
Z
Zhu Yi 已提交
1585 1586 1587
		goto restart;
	}

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

1591
	if (iwl_is_rfkill(priv))
Z
Zhu Yi 已提交
1592 1593
		return;

1594
	ieee80211_wake_queues(priv->hw);
Z
Zhu Yi 已提交
1595 1596 1597 1598

	priv->active_rate = priv->rates_mask;
	priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;

1599
	if (iwl_is_associated(priv)) {
G
Gregory Greenman 已提交
1600 1601
		struct iwl_rxon_cmd *active_rxon =
				(struct iwl_rxon_cmd *)&priv->active_rxon;
Z
Zhu Yi 已提交
1602 1603 1604 1605 1606 1607

		memcpy(&priv->staging_rxon, &priv->active_rxon,
		       sizeof(priv->staging_rxon));
		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
	} else {
		/* Initialize our rx_config data */
1608
		iwl_connection_init_rx_config(priv, priv->iw_mode);
1609
		iwl_set_rxon_chain(priv);
Z
Zhu Yi 已提交
1610 1611 1612
		memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
	}

1613
	/* Configure Bluetooth device coexistence support */
1614
	iwl_send_bt_config(priv);
Z
Zhu Yi 已提交
1615

1616 1617
	iwl_reset_run_time_calib(priv);

Z
Zhu Yi 已提交
1618
	/* Configure the adapter for unassociated operation */
1619
	iwl_commit_rxon(priv);
Z
Zhu Yi 已提交
1620 1621

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

1624 1625
	iwl_leds_register(priv);

1626
	IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
1627
	set_bit(STATUS_READY, &priv->status);
1628
	wake_up_interruptible(&priv->wait_command_queue);
Z
Zhu Yi 已提交
1629 1630

	if (priv->error_recovering)
1631
		iwl_error_recovery(priv);
Z
Zhu Yi 已提交
1632

1633
	iwl_power_update_mode(priv, 1);
1634

1635 1636 1637 1638 1639 1640 1641 1642 1643
	/* reassociate for ADHOC mode */
	if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
		struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
								priv->vif);
		if (beacon)
			iwl_mac_beacon_update(priv->hw, beacon);
	}


1644
	if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
1645
		iwl_set_mode(priv, priv->iw_mode);
1646

Z
Zhu Yi 已提交
1647 1648 1649 1650 1651 1652
	return;

 restart:
	queue_work(priv->workqueue, &priv->restart);
}

1653
static void iwl_cancel_deferred_work(struct iwl_priv *priv);
Z
Zhu Yi 已提交
1654

1655
static void __iwl_down(struct iwl_priv *priv)
Z
Zhu Yi 已提交
1656 1657 1658 1659
{
	unsigned long flags;
	int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);

1660
	IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
Z
Zhu Yi 已提交
1661 1662 1663 1664

	if (!exit_pending)
		set_bit(STATUS_EXIT_PENDING, &priv->status);

M
Mohamed Abbas 已提交
1665 1666
	iwl_leds_unregister(priv);

1667
	iwl_clear_stations_table(priv);
Z
Zhu Yi 已提交
1668 1669 1670 1671 1672 1673 1674 1675 1676 1677

	/* Unblock any waiting calls */
	wake_up_interruptible_all(&priv->wait_command_queue);

	/* Wipe out the EXIT_PENDING status bit if we are not actually
	 * exiting the module */
	if (!exit_pending)
		clear_bit(STATUS_EXIT_PENDING, &priv->status);

	/* stop and reset the on-board processor */
1678
	iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
Z
Zhu Yi 已提交
1679 1680

	/* tell the device to stop sending interrupts */
1681
	spin_lock_irqsave(&priv->lock, flags);
1682
	iwl_disable_interrupts(priv);
1683 1684
	spin_unlock_irqrestore(&priv->lock, flags);
	iwl_synchronize_irq(priv);
Z
Zhu Yi 已提交
1685 1686 1687 1688

	if (priv->mac80211_registered)
		ieee80211_stop_queues(priv->hw);

1689
	/* If we have not previously called iwl_init() then
Z
Zhu Yi 已提交
1690
	 * clear all bits but the RF Kill and SUSPEND bits and return */
1691
	if (!iwl_is_init(priv)) {
Z
Zhu Yi 已提交
1692 1693 1694 1695
		priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
					STATUS_RF_KILL_HW |
			       test_bit(STATUS_RF_KILL_SW, &priv->status) <<
					STATUS_RF_KILL_SW |
1696 1697
			       test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
					STATUS_GEO_CONFIGURED |
Z
Zhu Yi 已提交
1698
			       test_bit(STATUS_IN_SUSPEND, &priv->status) <<
1699 1700 1701
					STATUS_IN_SUSPEND |
			       test_bit(STATUS_EXIT_PENDING, &priv->status) <<
					STATUS_EXIT_PENDING;
Z
Zhu Yi 已提交
1702 1703 1704 1705 1706 1707 1708 1709 1710
		goto exit;
	}

	/* ...otherwise clear out all the status bits but the RF Kill and
	 * SUSPEND bits and continue taking the NIC down. */
	priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
				STATUS_RF_KILL_HW |
			test_bit(STATUS_RF_KILL_SW, &priv->status) <<
				STATUS_RF_KILL_SW |
1711 1712
			test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
				STATUS_GEO_CONFIGURED |
Z
Zhu Yi 已提交
1713 1714 1715
			test_bit(STATUS_IN_SUSPEND, &priv->status) <<
				STATUS_IN_SUSPEND |
			test_bit(STATUS_FW_ERROR, &priv->status) <<
1716 1717 1718
				STATUS_FW_ERROR |
		       test_bit(STATUS_EXIT_PENDING, &priv->status) <<
				STATUS_EXIT_PENDING;
Z
Zhu Yi 已提交
1719 1720

	spin_lock_irqsave(&priv->lock, flags);
1721
	iwl_clear_bit(priv, CSR_GP_CNTRL,
1722
			 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
Z
Zhu Yi 已提交
1723 1724
	spin_unlock_irqrestore(&priv->lock, flags);

1725
	iwl_txq_ctx_stop(priv);
1726
	iwl_rxq_stop(priv);
Z
Zhu Yi 已提交
1727 1728

	spin_lock_irqsave(&priv->lock, flags);
1729 1730
	if (!iwl_grab_nic_access(priv)) {
		iwl_write_prph(priv, APMG_CLK_DIS_REG,
Z
Zhu Yi 已提交
1731
					 APMG_CLK_VAL_DMA_CLK_RQT);
1732
		iwl_release_nic_access(priv);
Z
Zhu Yi 已提交
1733 1734 1735 1736 1737
	}
	spin_unlock_irqrestore(&priv->lock, flags);

	udelay(5);

1738
	/* FIXME: apm_ops.suspend(priv) */
1739 1740 1741 1742
	if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
		priv->cfg->ops->lib->apm_ops.stop(priv);
	else
		priv->cfg->ops->lib->apm_ops.reset(priv);
Z
Zhu Yi 已提交
1743
 exit:
1744
	memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
Z
Zhu Yi 已提交
1745 1746 1747 1748 1749 1750

	if (priv->ibss_beacon)
		dev_kfree_skb(priv->ibss_beacon);
	priv->ibss_beacon = NULL;

	/* clear out any free frames */
1751
	iwl_clear_free_frames(priv);
Z
Zhu Yi 已提交
1752 1753
}

1754
static void iwl_down(struct iwl_priv *priv)
Z
Zhu Yi 已提交
1755 1756
{
	mutex_lock(&priv->mutex);
1757
	__iwl_down(priv);
Z
Zhu Yi 已提交
1758
	mutex_unlock(&priv->mutex);
1759

1760
	iwl_cancel_deferred_work(priv);
Z
Zhu Yi 已提交
1761 1762 1763 1764
}

#define MAX_HW_RESTARTS 5

1765
static int __iwl_up(struct iwl_priv *priv)
Z
Zhu Yi 已提交
1766
{
1767 1768
	int i;
	int ret;
Z
Zhu Yi 已提交
1769 1770

	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
1771
		IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
Z
Zhu Yi 已提交
1772 1773 1774
		return -EIO;
	}

1775
	if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
1776
		IWL_ERR(priv, "ucode not available for device bringup\n");
1777 1778 1779
		return -EIO;
	}

1780
	/* If platform's RF_KILL switch is NOT set to KILL */
1781
	if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
1782
		clear_bit(STATUS_RF_KILL_HW, &priv->status);
1783
	else
1784
		set_bit(STATUS_RF_KILL_HW, &priv->status);
1785

1786
	if (iwl_is_rfkill(priv)) {
1787
		iwl_enable_interrupts(priv);
1788
		IWL_WARN(priv, "Radio disabled by %s RF Kill switch\n",
1789
		    test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
1790
		return 0;
Z
Zhu Yi 已提交
1791 1792
	}

1793
	iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
Z
Zhu Yi 已提交
1794

1795
	ret = iwl_hw_nic_init(priv);
1796
	if (ret) {
1797
		IWL_ERR(priv, "Unable to init nic\n");
1798
		return ret;
Z
Zhu Yi 已提交
1799 1800 1801
	}

	/* make sure rfkill handshake bits are cleared */
1802 1803
	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
Z
Zhu Yi 已提交
1804 1805 1806
		    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);

	/* clear (again), then enable host interrupts */
1807
	iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
1808
	iwl_enable_interrupts(priv);
Z
Zhu Yi 已提交
1809 1810

	/* really make sure rfkill handshake bits are cleared */
1811 1812
	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
Z
Zhu Yi 已提交
1813 1814 1815 1816 1817

	/* Copy original ucode data image from disk into backup cache.
	 * This will be used to initialize the on-board processor's
	 * data SRAM for a clean start when the runtime program first loads. */
	memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr,
1818
	       priv->ucode_data.len);
Z
Zhu Yi 已提交
1819 1820 1821

	for (i = 0; i < MAX_HW_RESTARTS; i++) {

1822
		iwl_clear_stations_table(priv);
Z
Zhu Yi 已提交
1823 1824 1825 1826

		/* load bootstrap state machine,
		 * load bootstrap program into processor's memory,
		 * prepare to load the "initialize" uCode */
1827
		ret = priv->cfg->ops->lib->load_ucode(priv);
Z
Zhu Yi 已提交
1828

1829
		if (ret) {
1830 1831
			IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n",
				ret);
Z
Zhu Yi 已提交
1832 1833 1834
			continue;
		}

1835 1836 1837
		/* Clear out the uCode error bit if it is set */
		clear_bit(STATUS_FW_ERROR, &priv->status);

Z
Zhu Yi 已提交
1838
		/* start card; "initialize" will load runtime ucode */
1839
		iwl_nic_start(priv);
Z
Zhu Yi 已提交
1840

1841
		IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n");
Z
Zhu Yi 已提交
1842 1843 1844 1845 1846

		return 0;
	}

	set_bit(STATUS_EXIT_PENDING, &priv->status);
1847
	__iwl_down(priv);
M
Mohamed Abbas 已提交
1848
	clear_bit(STATUS_EXIT_PENDING, &priv->status);
Z
Zhu Yi 已提交
1849 1850 1851

	/* tried to restart and config the device for as long as our
	 * patience could withstand */
1852
	IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i);
Z
Zhu Yi 已提交
1853 1854 1855 1856 1857 1858 1859 1860 1861 1862
	return -EIO;
}


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

1863
static void iwl_bg_init_alive_start(struct work_struct *data)
Z
Zhu Yi 已提交
1864
{
1865 1866
	struct iwl_priv *priv =
	    container_of(data, struct iwl_priv, init_alive_start.work);
Z
Zhu Yi 已提交
1867 1868 1869 1870 1871

	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return;

	mutex_lock(&priv->mutex);
1872
	priv->cfg->ops->lib->init_alive_start(priv);
Z
Zhu Yi 已提交
1873 1874 1875
	mutex_unlock(&priv->mutex);
}

1876
static void iwl_bg_alive_start(struct work_struct *data)
Z
Zhu Yi 已提交
1877
{
1878 1879
	struct iwl_priv *priv =
	    container_of(data, struct iwl_priv, alive_start.work);
Z
Zhu Yi 已提交
1880 1881 1882 1883 1884

	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return;

	mutex_lock(&priv->mutex);
1885
	iwl_alive_start(priv);
Z
Zhu Yi 已提交
1886 1887 1888
	mutex_unlock(&priv->mutex);
}

1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911
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);

	mutex_lock(&priv->mutex);

	if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
	    test_bit(STATUS_SCANNING, &priv->status)) {
		mutex_unlock(&priv->mutex);
		return;
	}

	if (priv->start_calib) {
		iwl_chain_noise_calibration(priv, &priv->statistics);

		iwl_sensitivity_calibration(priv, &priv->statistics);
	}

	mutex_unlock(&priv->mutex);
	return;
}

1912
static void iwl_bg_up(struct work_struct *data)
Z
Zhu Yi 已提交
1913
{
1914
	struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
Z
Zhu Yi 已提交
1915 1916 1917 1918 1919

	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return;

	mutex_lock(&priv->mutex);
1920
	__iwl_up(priv);
Z
Zhu Yi 已提交
1921
	mutex_unlock(&priv->mutex);
1922
	iwl_rfkill_set_hw_state(priv);
Z
Zhu Yi 已提交
1923 1924
}

1925
static void iwl_bg_restart(struct work_struct *data)
Z
Zhu Yi 已提交
1926
{
1927
	struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
Z
Zhu Yi 已提交
1928 1929 1930 1931

	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return;

1932
	iwl_down(priv);
Z
Zhu Yi 已提交
1933 1934 1935
	queue_work(priv->workqueue, &priv->up);
}

1936
static void iwl_bg_rx_replenish(struct work_struct *data)
Z
Zhu Yi 已提交
1937
{
1938 1939
	struct iwl_priv *priv =
	    container_of(data, struct iwl_priv, rx_replenish);
Z
Zhu Yi 已提交
1940 1941 1942 1943 1944

	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return;

	mutex_lock(&priv->mutex);
1945
	iwl_rx_replenish(priv);
Z
Zhu Yi 已提交
1946 1947 1948
	mutex_unlock(&priv->mutex);
}

1949 1950
#define IWL_DELAY_NEXT_SCAN (HZ*2)

1951
static void iwl_post_associate(struct iwl_priv *priv)
Z
Zhu Yi 已提交
1952 1953
{
	struct ieee80211_conf *conf = NULL;
1954
	int ret = 0;
1955
	unsigned long flags;
Z
Zhu Yi 已提交
1956

1957
	if (priv->iw_mode == NL80211_IFTYPE_AP) {
1958
		IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
Z
Zhu Yi 已提交
1959 1960 1961
		return;
	}

1962
	IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
J
Johannes Berg 已提交
1963
			priv->assoc_id, priv->active_rxon.bssid_addr);
Z
Zhu Yi 已提交
1964 1965 1966 1967 1968 1969


	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return;


1970
	if (!priv->vif || !priv->is_open)
M
Mohamed Abbas 已提交
1971
		return;
1972

1973
	iwl_power_cancel_timeout(priv);
1974
	iwl_scan_cancel_timeout(priv, 200);
1975

Z
Zhu Yi 已提交
1976 1977 1978
	conf = ieee80211_get_hw_conf(priv->hw);

	priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1979
	iwl_commit_rxon(priv);
Z
Zhu Yi 已提交
1980

1981
	iwl_setup_rxon_timing(priv);
1982
	ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
Z
Zhu Yi 已提交
1983
			      sizeof(priv->rxon_timing), &priv->rxon_timing);
1984
	if (ret)
1985
		IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
Z
Zhu Yi 已提交
1986 1987 1988 1989
			    "Attempting to continue.\n");

	priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;

1990
	iwl_set_rxon_ht(priv, &priv->current_ht_config);
1991

R
Ron Rindjunsky 已提交
1992
	iwl_set_rxon_chain(priv);
Z
Zhu Yi 已提交
1993 1994
	priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);

1995
	IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
Z
Zhu Yi 已提交
1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008
			priv->assoc_id, priv->beacon_int);

	if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
		priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
	else
		priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;

	if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
		if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
			priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
		else
			priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;

2009
		if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
Z
Zhu Yi 已提交
2010 2011 2012 2013
			priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;

	}

2014
	iwl_commit_rxon(priv);
Z
Zhu Yi 已提交
2015 2016

	switch (priv->iw_mode) {
2017
	case NL80211_IFTYPE_STATION:
Z
Zhu Yi 已提交
2018 2019
		break;

2020
	case NL80211_IFTYPE_ADHOC:
Z
Zhu Yi 已提交
2021

2022 2023
		/* assume default assoc id */
		priv->assoc_id = 1;
Z
Zhu Yi 已提交
2024

2025
		iwl_rxon_add_station(priv, priv->bssid, 0);
2026
		iwl_send_beacon_cmd(priv);
Z
Zhu Yi 已提交
2027 2028 2029 2030

		break;

	default:
2031
		IWL_ERR(priv, "%s Should not be called in %d mode\n",
2032
			  __func__, priv->iw_mode);
Z
Zhu Yi 已提交
2033 2034 2035
		break;
	}

2036
	if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
Z
Zhu Yi 已提交
2037 2038
		priv->assoc_station_added = 1;

2039 2040 2041
	spin_lock_irqsave(&priv->lock, flags);
	iwl_activate_qos(priv, 0);
	spin_unlock_irqrestore(&priv->lock, flags);
2042

2043 2044 2045 2046 2047
	/* the chain noise calibration will enabled PM upon completion
	 * If chain noise has already been run, then we need to enable
	 * power management here */
	if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
		iwl_power_enable_management(priv);
2048 2049 2050 2051 2052

	/* Enable Rx differential gain and sensitivity calibrations */
	iwl_chain_noise_reset(priv);
	priv->start_calib = 1;

2053 2054
}

Z
Zhu Yi 已提交
2055 2056 2057 2058 2059 2060
/*****************************************************************************
 *
 * mac80211 entry point functions
 *
 *****************************************************************************/

2061
#define UCODE_READY_TIMEOUT	(4 * HZ)
2062

2063
static int iwl_mac_start(struct ieee80211_hw *hw)
Z
Zhu Yi 已提交
2064
{
2065
	struct iwl_priv *priv = hw->priv;
2066
	int ret;
Z
Zhu Yi 已提交
2067

2068
	IWL_DEBUG_MAC80211(priv, "enter\n");
Z
Zhu Yi 已提交
2069 2070 2071 2072

	/* we should be verifying the device is ready to be opened */
	mutex_lock(&priv->mutex);

G
Gregory Greenman 已提交
2073
	memset(&priv->staging_rxon, 0, sizeof(struct iwl_rxon_cmd));
2074 2075
	/* fetch ucode file from disk, alloc and copy to bus-master buffers ...
	 * ucode filename and max sizes are card-specific. */
Z
Zhu Yi 已提交
2076

2077
	if (!priv->ucode_code.len) {
2078
		ret = iwl_read_ucode(priv);
2079
		if (ret) {
2080
			IWL_ERR(priv, "Could not read microcode: %d\n", ret);
2081
			mutex_unlock(&priv->mutex);
2082
			return ret;
2083 2084
		}
	}
Z
Zhu Yi 已提交
2085

2086
	ret = __iwl_up(priv);
2087

Z
Zhu Yi 已提交
2088
	mutex_unlock(&priv->mutex);
2089

2090 2091
	iwl_rfkill_set_hw_state(priv);

2092
	if (ret)
2093
		return ret;
2094

2095 2096 2097
	if (iwl_is_rfkill(priv))
		goto out;

2098
	IWL_DEBUG_INFO(priv, "Start UP work done.\n");
2099 2100 2101 2102

	if (test_bit(STATUS_IN_SUSPEND, &priv->status))
		return 0;

2103
	/* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from
2104
	 * mac80211 will not be run successfully. */
2105 2106 2107 2108 2109
	ret = wait_event_interruptible_timeout(priv->wait_command_queue,
			test_bit(STATUS_READY, &priv->status),
			UCODE_READY_TIMEOUT);
	if (!ret) {
		if (!test_bit(STATUS_READY, &priv->status)) {
2110
			IWL_ERR(priv, "START_ALIVE timeout after %dms.\n",
2111
				jiffies_to_msecs(UCODE_READY_TIMEOUT));
2112
			return -ETIMEDOUT;
2113
		}
2114
	}
T
Tomas Winkler 已提交
2115

2116
out:
T
Tomas Winkler 已提交
2117
	priv->is_open = 1;
2118
	IWL_DEBUG_MAC80211(priv, "leave\n");
Z
Zhu Yi 已提交
2119 2120 2121
	return 0;
}

2122
static void iwl_mac_stop(struct ieee80211_hw *hw)
Z
Zhu Yi 已提交
2123
{
2124
	struct iwl_priv *priv = hw->priv;
Z
Zhu Yi 已提交
2125

2126
	IWL_DEBUG_MAC80211(priv, "enter\n");
M
Mohamed Abbas 已提交
2127

2128
	if (!priv->is_open) {
2129
		IWL_DEBUG_MAC80211(priv, "leave - skip\n");
2130 2131 2132
		return;
	}

Z
Zhu Yi 已提交
2133
	priv->is_open = 0;
2134

2135
	if (iwl_is_ready_rf(priv)) {
2136 2137 2138
		/* stop mac, cancel any scan request and clear
		 * RXON_FILTER_ASSOC_MSK BIT
		 */
2139
		mutex_lock(&priv->mutex);
2140
		iwl_scan_cancel_timeout(priv, 100);
2141 2142 2143
		mutex_unlock(&priv->mutex);
	}

2144
	iwl_down(priv);
2145 2146

	flush_workqueue(priv->workqueue);
2147 2148 2149 2150

	/* enable interrupts again in order to receive rfkill changes */
	iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
	iwl_enable_interrupts(priv);
M
Mohamed Abbas 已提交
2151

2152
	IWL_DEBUG_MAC80211(priv, "leave\n");
Z
Zhu Yi 已提交
2153 2154
}

2155
static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
Z
Zhu Yi 已提交
2156
{
2157
	struct iwl_priv *priv = hw->priv;
Z
Zhu Yi 已提交
2158

2159
	IWL_DEBUG_MACDUMP(priv, "enter\n");
Z
Zhu Yi 已提交
2160

2161
	IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
2162
		     ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
Z
Zhu Yi 已提交
2163

2164
	if (iwl_tx_skb(priv, skb))
Z
Zhu Yi 已提交
2165 2166
		dev_kfree_skb_any(skb);

2167
	IWL_DEBUG_MACDUMP(priv, "leave\n");
2168
	return NETDEV_TX_OK;
Z
Zhu Yi 已提交
2169 2170
}

2171
static int iwl_mac_add_interface(struct ieee80211_hw *hw,
Z
Zhu Yi 已提交
2172 2173
				 struct ieee80211_if_init_conf *conf)
{
2174
	struct iwl_priv *priv = hw->priv;
Z
Zhu Yi 已提交
2175 2176
	unsigned long flags;

2177
	IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
Z
Zhu Yi 已提交
2178

2179
	if (priv->vif) {
2180
		IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
2181
		return -EOPNOTSUPP;
Z
Zhu Yi 已提交
2182 2183 2184
	}

	spin_lock_irqsave(&priv->lock, flags);
2185
	priv->vif = conf->vif;
2186
	priv->iw_mode = conf->type;
Z
Zhu Yi 已提交
2187 2188 2189 2190

	spin_unlock_irqrestore(&priv->lock, flags);

	mutex_lock(&priv->mutex);
2191 2192

	if (conf->mac_addr) {
2193
		IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr);
2194 2195
		memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
	}
Z
Zhu Yi 已提交
2196

2197
	if (iwl_set_mode(priv, conf->type) == -EAGAIN)
2198 2199
		/* we are not ready, will run again when ready */
		set_bit(STATUS_MODE_PENDING, &priv->status);
2200

Z
Zhu Yi 已提交
2201 2202
	mutex_unlock(&priv->mutex);

2203
	IWL_DEBUG_MAC80211(priv, "leave\n");
Z
Zhu Yi 已提交
2204 2205 2206 2207
	return 0;
}

/**
2208
 * iwl_mac_config - mac80211 config callback
Z
Zhu Yi 已提交
2209 2210 2211 2212 2213
 *
 * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to
 * be set inappropriately and the driver currently sets the hardware up to
 * use it whenever needed.
 */
2214
static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
Z
Zhu Yi 已提交
2215
{
2216
	struct iwl_priv *priv = hw->priv;
2217
	const struct iwl_channel_info *ch_info;
2218
	struct ieee80211_conf *conf = &hw->conf;
Z
Zhu Yi 已提交
2219
	unsigned long flags;
2220
	int ret = 0;
2221
	u16 channel;
Z
Zhu Yi 已提交
2222 2223

	mutex_lock(&priv->mutex);
2224
	IWL_DEBUG_MAC80211(priv, "enter to channel %d\n", conf->channel->hw_value);
Z
Zhu Yi 已提交
2225

2226
	priv->current_ht_config.is_ht = conf_is_ht(conf);
J
Johannes Berg 已提交
2227

2228
	if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) {
2229
		IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - waiting for uCode\n");
2230
		goto out;
M
Mohamed Abbas 已提交
2231 2232
	}

2233 2234 2235
	if (!conf->radio_enabled)
		iwl_radio_kill_sw_disable_radio(priv);

2236
	if (!iwl_is_ready(priv)) {
2237
		IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2238 2239
		ret = -EIO;
		goto out;
Z
Zhu Yi 已提交
2240 2241
	}

2242
	if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
Z
Zhu Yi 已提交
2243
		     test_bit(STATUS_SCANNING, &priv->status))) {
2244
		IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
Z
Zhu Yi 已提交
2245
		mutex_unlock(&priv->mutex);
2246
		return 0;
Z
Zhu Yi 已提交
2247 2248
	}

2249 2250
	channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
	ch_info = iwl_get_channel_info(priv, conf->channel->band, channel);
Z
Zhu Yi 已提交
2251
	if (!is_channel_valid(ch_info)) {
2252
		IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
2253 2254
		ret = -EINVAL;
		goto out;
Z
Zhu Yi 已提交
2255 2256
	}

2257
	if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
2258
	    !is_channel_ibss(ch_info)) {
2259
		IWL_ERR(priv, "channel %d in band %d not IBSS channel\n",
2260 2261 2262 2263 2264
			conf->channel->hw_value, conf->channel->band);
		ret = -EINVAL;
		goto out;
	}

2265 2266
	spin_lock_irqsave(&priv->lock, flags);

2267

2268
	/* if we are switching from ht to 2.4 clear flags
Z
Zhu Yi 已提交
2269 2270
	 * from any ht related info since 2.4 does not
	 * support ht */
2271
	if ((le16_to_cpu(priv->staging_rxon.channel) != channel)
Z
Zhu Yi 已提交
2272 2273 2274 2275 2276 2277
#ifdef IEEE80211_CONF_CHANNEL_SWITCH
	    && !(conf->flags & IEEE80211_CONF_CHANNEL_SWITCH)
#endif
	)
		priv->staging_rxon.flags = 0;

2278
	iwl_set_rxon_channel(priv, conf->channel);
Z
Zhu Yi 已提交
2279

2280
	iwl_set_flags_for_band(priv, conf->channel->band);
Z
Zhu Yi 已提交
2281 2282

	/* The list of supported rates and rate mask can be different
2283
	 * for each band; since the band may have changed, reset
Z
Zhu Yi 已提交
2284
	 * the rate mask to what mac80211 lists */
2285
	iwl_set_rate(priv);
Z
Zhu Yi 已提交
2286 2287 2288 2289 2290

	spin_unlock_irqrestore(&priv->lock, flags);

#ifdef IEEE80211_CONF_CHANNEL_SWITCH
	if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) {
2291
		iwl_hw_channel_switch(priv, conf->channel);
2292
		goto out;
Z
Zhu Yi 已提交
2293 2294 2295 2296
	}
#endif

	if (!conf->radio_enabled) {
2297
		IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
2298
		goto out;
Z
Zhu Yi 已提交
2299 2300
	}

2301
	if (iwl_is_rfkill(priv)) {
2302
		IWL_DEBUG_MAC80211(priv, "leave - RF kill\n");
2303 2304
		ret = -EIO;
		goto out;
Z
Zhu Yi 已提交
2305 2306
	}

2307 2308 2309 2310 2311
	if (conf->flags & IEEE80211_CONF_PS)
		ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3);
	else
		ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM);
	if (ret)
2312
		IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
2313

2314
	IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
2315 2316 2317 2318
			   priv->tx_power_user_lmt, conf->power_level);

	iwl_set_tx_power(priv, conf->power_level, false);

2319
	iwl_set_rate(priv);
Z
Zhu Yi 已提交
2320

2321 2322 2323
	/* call to ensure that 4965 rx_chain is set properly in monitor mode */
	iwl_set_rxon_chain(priv);

Z
Zhu Yi 已提交
2324 2325
	if (memcmp(&priv->active_rxon,
		   &priv->staging_rxon, sizeof(priv->staging_rxon)))
2326
		iwl_commit_rxon(priv);
Z
Zhu Yi 已提交
2327
	else
2328
		IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n");
Z
Zhu Yi 已提交
2329

2330
	IWL_DEBUG_MAC80211(priv, "leave\n");
Z
Zhu Yi 已提交
2331

2332
out:
2333
	mutex_unlock(&priv->mutex);
2334
	return ret;
Z
Zhu Yi 已提交
2335 2336
}

2337
static void iwl_config_ap(struct iwl_priv *priv)
Z
Zhu Yi 已提交
2338
{
2339
	int ret = 0;
2340
	unsigned long flags;
Z
Zhu Yi 已提交
2341

2342
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
Z
Zhu Yi 已提交
2343 2344 2345
		return;

	/* The following should be done only at AP bring up */
2346
	if (!iwl_is_associated(priv)) {
Z
Zhu Yi 已提交
2347 2348 2349

		/* RXON - unassoc (to set timing command) */
		priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2350
		iwl_commit_rxon(priv);
Z
Zhu Yi 已提交
2351 2352

		/* RXON Timing */
2353
		iwl_setup_rxon_timing(priv);
2354
		ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
Z
Zhu Yi 已提交
2355
				sizeof(priv->rxon_timing), &priv->rxon_timing);
2356
		if (ret)
2357
			IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
Z
Zhu Yi 已提交
2358 2359
					"Attempting to continue.\n");

R
Ron Rindjunsky 已提交
2360
		iwl_set_rxon_chain(priv);
Z
Zhu Yi 已提交
2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379

		/* FIXME: what should be the assoc_id for AP? */
		priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
		if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
			priv->staging_rxon.flags |=
				RXON_FLG_SHORT_PREAMBLE_MSK;
		else
			priv->staging_rxon.flags &=
				~RXON_FLG_SHORT_PREAMBLE_MSK;

		if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
			if (priv->assoc_capability &
				WLAN_CAPABILITY_SHORT_SLOT_TIME)
				priv->staging_rxon.flags |=
					RXON_FLG_SHORT_SLOT_MSK;
			else
				priv->staging_rxon.flags &=
					~RXON_FLG_SHORT_SLOT_MSK;

2380
			if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
Z
Zhu Yi 已提交
2381 2382 2383 2384 2385
				priv->staging_rxon.flags &=
					~RXON_FLG_SHORT_SLOT_MSK;
		}
		/* restore RXON assoc */
		priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
2386
		iwl_commit_rxon(priv);
2387 2388 2389
		spin_lock_irqsave(&priv->lock, flags);
		iwl_activate_qos(priv, 1);
		spin_unlock_irqrestore(&priv->lock, flags);
2390
		iwl_rxon_add_station(priv, iwl_bcast_addr, 0);
2391
	}
2392
	iwl_send_beacon_cmd(priv);
Z
Zhu Yi 已提交
2393 2394 2395 2396 2397 2398

	/* FIXME - we need to add code here to detect a totally new
	 * configuration, reset the AP, unassoc, rxon timing, assoc,
	 * clear sta table, add BCAST sta... */
}

2399

2400
static int iwl_mac_config_interface(struct ieee80211_hw *hw,
2401
					struct ieee80211_vif *vif,
Z
Zhu Yi 已提交
2402 2403
				    struct ieee80211_if_conf *conf)
{
2404
	struct iwl_priv *priv = hw->priv;
Z
Zhu Yi 已提交
2405 2406 2407 2408 2409
	int rc;

	if (conf == NULL)
		return -EIO;

2410
	if (priv->vif != vif) {
2411
		IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
2412 2413 2414
		return 0;
	}

2415
	if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
2416 2417 2418 2419
	    conf->changed & IEEE80211_IFCC_BEACON) {
		struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
		if (!beacon)
			return -ENOMEM;
2420
		mutex_lock(&priv->mutex);
2421
		rc = iwl_mac_beacon_update(hw, beacon);
2422
		mutex_unlock(&priv->mutex);
2423 2424 2425 2426
		if (rc)
			return rc;
	}

2427
	if (!iwl_is_alive(priv))
2428 2429
		return -EAGAIN;

Z
Zhu Yi 已提交
2430 2431 2432
	mutex_lock(&priv->mutex);

	if (conf->bssid)
2433
		IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
Z
Zhu Yi 已提交
2434

2435 2436 2437
/*
 * very dubious code was here; the probe filtering flag is never set:
 *
Z
Zhu Yi 已提交
2438 2439
	if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) &&
	    !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
2440
 */
Z
Zhu Yi 已提交
2441

2442
	if (priv->iw_mode == NL80211_IFTYPE_AP) {
Z
Zhu Yi 已提交
2443 2444 2445
		if (!conf->bssid) {
			conf->bssid = priv->mac_addr;
			memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
2446
			IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
J
Johannes Berg 已提交
2447
					   conf->bssid);
Z
Zhu Yi 已提交
2448 2449 2450 2451
		}
		if (priv->ibss_beacon)
			dev_kfree_skb(priv->ibss_beacon);

2452
		priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
Z
Zhu Yi 已提交
2453 2454
	}

2455
	if (iwl_is_rfkill(priv))
2456 2457
		goto done;

Z
Zhu Yi 已提交
2458 2459 2460 2461
	if (conf->bssid && !is_zero_ether_addr(conf->bssid) &&
	    !is_multicast_ether_addr(conf->bssid)) {
		/* If there is currently a HW scan going on in the background
		 * then we need to cancel it else the RXON below will fail. */
2462
		if (iwl_scan_cancel_timeout(priv, 100)) {
2463
			IWL_WARN(priv, "Aborted scan still in progress "
Z
Zhu Yi 已提交
2464
				    "after 100ms\n");
2465
			IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
Z
Zhu Yi 已提交
2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476
			mutex_unlock(&priv->mutex);
			return -EAGAIN;
		}
		memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN);

		/* TODO: Audit driver for usage of these members and see
		 * if mac80211 deprecates them (priv->bssid looks like it
		 * shouldn't be there, but I haven't scanned the IBSS code
		 * to verify) - jpk */
		memcpy(priv->bssid, conf->bssid, ETH_ALEN);

2477
		if (priv->iw_mode == NL80211_IFTYPE_AP)
2478
			iwl_config_ap(priv);
Z
Zhu Yi 已提交
2479
		else {
2480
			rc = iwl_commit_rxon(priv);
2481
			if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
2482
				iwl_rxon_add_station(
Z
Zhu Yi 已提交
2483 2484 2485 2486
					priv, priv->active_rxon.bssid_addr, 1);
		}

	} else {
2487
		iwl_scan_cancel_timeout(priv, 100);
Z
Zhu Yi 已提交
2488
		priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2489
		iwl_commit_rxon(priv);
Z
Zhu Yi 已提交
2490 2491
	}

2492
 done:
2493
	IWL_DEBUG_MAC80211(priv, "leave\n");
Z
Zhu Yi 已提交
2494 2495 2496 2497 2498
	mutex_unlock(&priv->mutex);

	return 0;
}

2499
static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
Z
Zhu Yi 已提交
2500 2501
				     struct ieee80211_if_init_conf *conf)
{
2502
	struct iwl_priv *priv = hw->priv;
Z
Zhu Yi 已提交
2503

2504
	IWL_DEBUG_MAC80211(priv, "enter\n");
Z
Zhu Yi 已提交
2505 2506

	mutex_lock(&priv->mutex);
M
Mohamed Abbas 已提交
2507

2508
	if (iwl_is_ready_rf(priv)) {
2509
		iwl_scan_cancel_timeout(priv, 100);
2510
		priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2511
		iwl_commit_rxon(priv);
2512
	}
2513 2514
	if (priv->vif == conf->vif) {
		priv->vif = NULL;
Z
Zhu Yi 已提交
2515 2516 2517 2518
		memset(priv->bssid, 0, ETH_ALEN);
	}
	mutex_unlock(&priv->mutex);

2519
	IWL_DEBUG_MAC80211(priv, "leave\n");
Z
Zhu Yi 已提交
2520 2521

}
2522

2523
#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
2524
static void iwl_bss_info_changed(struct ieee80211_hw *hw,
2525 2526 2527
				     struct ieee80211_vif *vif,
				     struct ieee80211_bss_conf *bss_conf,
				     u32 changes)
2528
{
2529
	struct iwl_priv *priv = hw->priv;
2530

2531
	IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
2532

2533
	if (changes & BSS_CHANGED_ERP_PREAMBLE) {
2534
		IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
2535
				   bss_conf->use_short_preamble);
2536
		if (bss_conf->use_short_preamble)
2537 2538 2539 2540 2541
			priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
		else
			priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
	}

2542
	if (changes & BSS_CHANGED_ERP_CTS_PROT) {
2543
		IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
2544
		if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
2545 2546 2547 2548 2549
			priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
		else
			priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
	}

T
Tomas Winkler 已提交
2550
	if (changes & BSS_CHANGED_HT) {
2551
		iwl_ht_conf(priv, bss_conf);
R
Ron Rindjunsky 已提交
2552
		iwl_set_rxon_chain(priv);
T
Tomas Winkler 已提交
2553 2554
	}

2555
	if (changes & BSS_CHANGED_ASSOC) {
2556
		IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
2557 2558 2559 2560
		/* This should never happen as this function should
		 * never be called from interrupt context. */
		if (WARN_ON_ONCE(in_interrupt()))
			return;
2561 2562 2563
		if (bss_conf->assoc) {
			priv->assoc_id = bss_conf->aid;
			priv->beacon_int = bss_conf->beacon_int;
2564
			priv->power_data.dtim_period = bss_conf->dtim_period;
2565 2566
			priv->timestamp = bss_conf->timestamp;
			priv->assoc_capability = bss_conf->assoc_capability;
2567 2568 2569 2570

			/* we have just associated, don't start scan too early
			 * leave time for EAPOL exchange to complete
			 */
2571 2572
			priv->next_scan_jiffies = jiffies +
					IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
2573
			mutex_lock(&priv->mutex);
2574
			iwl_post_associate(priv);
2575
			mutex_unlock(&priv->mutex);
2576 2577
		} else {
			priv->assoc_id = 0;
2578
			IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc);
2579 2580
		}
	} else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
2581
			IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes);
2582
			iwl_send_rxon_assoc(priv);
2583 2584
	}

2585
}
Z
Zhu Yi 已提交
2586

2587
static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
2588 2589 2590 2591
			struct ieee80211_key_conf *keyconf, const u8 *addr,
			u32 iv32, u16 *phase1key)
{

2592
	struct iwl_priv *priv = hw->priv;
2593
	IWL_DEBUG_MAC80211(priv, "enter\n");
2594

2595
	iwl_update_tkip_key(priv, keyconf, addr, iv32, phase1key);
2596

2597
	IWL_DEBUG_MAC80211(priv, "leave\n");
2598 2599
}

2600
static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2601 2602
			   struct ieee80211_vif *vif,
			   struct ieee80211_sta *sta,
Z
Zhu Yi 已提交
2603 2604
			   struct ieee80211_key_conf *key)
{
2605
	struct iwl_priv *priv = hw->priv;
2606 2607 2608 2609
	const u8 *addr;
	int ret;
	u8 sta_id;
	bool is_default_wep_key = false;
Z
Zhu Yi 已提交
2610

2611
	IWL_DEBUG_MAC80211(priv, "enter\n");
Z
Zhu Yi 已提交
2612

2613
	if (priv->hw_params.sw_crypto) {
2614
		IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
Z
Zhu Yi 已提交
2615 2616
		return -EOPNOTSUPP;
	}
2617
	addr = sta ? sta->addr : iwl_bcast_addr;
2618
	sta_id = iwl_find_station(priv, addr);
2619
	if (sta_id == IWL_INVALID_STATION) {
2620
		IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
J
Johannes Berg 已提交
2621
				   addr);
2622
		return -EINVAL;
Z
Zhu Yi 已提交
2623

2624
	}
Z
Zhu Yi 已提交
2625

2626
	mutex_lock(&priv->mutex);
2627
	iwl_scan_cancel_timeout(priv, 100);
2628 2629 2630 2631 2632 2633
	mutex_unlock(&priv->mutex);

	/* If we are getting WEP group key and we didn't receive any key mapping
	 * so far, we are in legacy wep mode (group key only), otherwise we are
	 * in 1X mode.
	 * In legacy wep mode, we use another host command to the uCode */
T
Tomas Winkler 已提交
2634
	if (key->alg == ALG_WEP && sta_id == priv->hw_params.bcast_sta_id &&
2635
		priv->iw_mode != NL80211_IFTYPE_AP) {
2636 2637 2638
		if (cmd == SET_KEY)
			is_default_wep_key = !priv->key_mapping_key;
		else
2639 2640
			is_default_wep_key =
					(key->hw_key_idx == HW_KEY_DEFAULT);
2641
	}
2642

Z
Zhu Yi 已提交
2643
	switch (cmd) {
2644
	case SET_KEY:
2645 2646
		if (is_default_wep_key)
			ret = iwl_set_default_wep_key(priv, key);
2647
		else
2648
			ret = iwl_set_dynamic_key(priv, key, sta_id);
2649

2650
		IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n");
Z
Zhu Yi 已提交
2651 2652
		break;
	case DISABLE_KEY:
2653 2654
		if (is_default_wep_key)
			ret = iwl_remove_default_wep_key(priv, key);
2655
		else
2656
			ret = iwl_remove_dynamic_key(priv, key, sta_id);
2657

2658
		IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
Z
Zhu Yi 已提交
2659 2660
		break;
	default:
2661
		ret = -EINVAL;
Z
Zhu Yi 已提交
2662 2663
	}

2664
	IWL_DEBUG_MAC80211(priv, "leave\n");
Z
Zhu Yi 已提交
2665

2666
	return ret;
Z
Zhu Yi 已提交
2667 2668
}

2669
static int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
Z
Zhu Yi 已提交
2670 2671
			   const struct ieee80211_tx_queue_params *params)
{
2672
	struct iwl_priv *priv = hw->priv;
Z
Zhu Yi 已提交
2673 2674 2675
	unsigned long flags;
	int q;

2676
	IWL_DEBUG_MAC80211(priv, "enter\n");
Z
Zhu Yi 已提交
2677

2678
	if (!iwl_is_ready_rf(priv)) {
2679
		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
Z
Zhu Yi 已提交
2680 2681 2682 2683
		return -EIO;
	}

	if (queue >= AC_NUM) {
2684
		IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
Z
Zhu Yi 已提交
2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695
		return 0;
	}

	q = AC_NUM - 1 - queue;

	spin_lock_irqsave(&priv->lock, flags);

	priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min);
	priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
	priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
	priv->qos_data.def_qos_parm.ac[q].edca_txop =
2696
			cpu_to_le16((params->txop * 32));
Z
Zhu Yi 已提交
2697 2698 2699 2700

	priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
	priv->qos_data.qos_active = 1;

2701
	if (priv->iw_mode == NL80211_IFTYPE_AP)
2702
		iwl_activate_qos(priv, 1);
2703
	else if (priv->assoc_id && iwl_is_associated(priv))
2704
		iwl_activate_qos(priv, 0);
Z
Zhu Yi 已提交
2705

2706
	spin_unlock_irqrestore(&priv->lock, flags);
Z
Zhu Yi 已提交
2707

2708
	IWL_DEBUG_MAC80211(priv, "leave\n");
Z
Zhu Yi 已提交
2709 2710 2711
	return 0;
}

2712
static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
2713
			     enum ieee80211_ampdu_mlme_action action,
2714
			     struct ieee80211_sta *sta, u16 tid, u16 *ssn)
2715 2716 2717
{
	struct iwl_priv *priv = hw->priv;

2718
	IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
J
Johannes Berg 已提交
2719
		     sta->addr, tid);
2720 2721 2722 2723 2724 2725

	if (!(priv->cfg->sku & IWL_SKU_N))
		return -EACCES;

	switch (action) {
	case IEEE80211_AMPDU_RX_START:
2726
		IWL_DEBUG_HT(priv, "start Rx\n");
2727
		return iwl_sta_rx_agg_start(priv, sta->addr, tid, *ssn);
2728
	case IEEE80211_AMPDU_RX_STOP:
2729
		IWL_DEBUG_HT(priv, "stop Rx\n");
2730
		return iwl_sta_rx_agg_stop(priv, sta->addr, tid);
2731
	case IEEE80211_AMPDU_TX_START:
2732
		IWL_DEBUG_HT(priv, "start Tx\n");
2733
		return iwl_tx_agg_start(priv, sta->addr, tid, ssn);
2734
	case IEEE80211_AMPDU_TX_STOP:
2735
		IWL_DEBUG_HT(priv, "stop Tx\n");
2736
		return iwl_tx_agg_stop(priv, sta->addr, tid);
2737
	default:
2738
		IWL_DEBUG_HT(priv, "unknown\n");
2739 2740 2741 2742 2743
		return -EINVAL;
		break;
	}
	return 0;
}
2744

2745
static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
Z
Zhu Yi 已提交
2746 2747
				struct ieee80211_tx_queue_stats *stats)
{
2748
	struct iwl_priv *priv = hw->priv;
Z
Zhu Yi 已提交
2749
	int i, avail;
2750
	struct iwl_tx_queue *txq;
2751
	struct iwl_queue *q;
Z
Zhu Yi 已提交
2752 2753
	unsigned long flags;

2754
	IWL_DEBUG_MAC80211(priv, "enter\n");
Z
Zhu Yi 已提交
2755

2756
	if (!iwl_is_ready_rf(priv)) {
2757
		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
Z
Zhu Yi 已提交
2758 2759 2760 2761 2762 2763 2764 2765
		return -EIO;
	}

	spin_lock_irqsave(&priv->lock, flags);

	for (i = 0; i < AC_NUM; i++) {
		txq = &priv->txq[i];
		q = &txq->q;
2766
		avail = iwl_queue_space(q);
Z
Zhu Yi 已提交
2767

2768 2769 2770
		stats[i].len = q->n_window - avail;
		stats[i].limit = q->n_window - q->high_mark;
		stats[i].count = q->n_window;
Z
Zhu Yi 已提交
2771 2772 2773 2774

	}
	spin_unlock_irqrestore(&priv->lock, flags);

2775
	IWL_DEBUG_MAC80211(priv, "leave\n");
Z
Zhu Yi 已提交
2776 2777 2778 2779

	return 0;
}

2780
static int iwl_mac_get_stats(struct ieee80211_hw *hw,
Z
Zhu Yi 已提交
2781 2782
			     struct ieee80211_low_level_stats *stats)
{
2783 2784 2785
	struct iwl_priv *priv = hw->priv;

	priv = hw->priv;
2786 2787
	IWL_DEBUG_MAC80211(priv, "enter\n");
	IWL_DEBUG_MAC80211(priv, "leave\n");
Z
Zhu Yi 已提交
2788 2789 2790 2791

	return 0;
}

2792
static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
Z
Zhu Yi 已提交
2793
{
2794
	struct iwl_priv *priv = hw->priv;
Z
Zhu Yi 已提交
2795 2796 2797
	unsigned long flags;

	mutex_lock(&priv->mutex);
2798
	IWL_DEBUG_MAC80211(priv, "enter\n");
Z
Zhu Yi 已提交
2799 2800

	spin_lock_irqsave(&priv->lock, flags);
2801
	memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
Z
Zhu Yi 已提交
2802 2803
	spin_unlock_irqrestore(&priv->lock, flags);

R
Ron Rindjunsky 已提交
2804
	iwl_reset_qos(priv);
Z
Zhu Yi 已提交
2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817

	spin_lock_irqsave(&priv->lock, flags);
	priv->assoc_id = 0;
	priv->assoc_capability = 0;
	priv->assoc_station_added = 0;

	/* new association get rid of ibss beacon skb */
	if (priv->ibss_beacon)
		dev_kfree_skb(priv->ibss_beacon);

	priv->ibss_beacon = NULL;

	priv->beacon_int = priv->hw->conf.beacon_int;
2818
	priv->timestamp = 0;
2819
	if ((priv->iw_mode == NL80211_IFTYPE_STATION))
Z
Zhu Yi 已提交
2820 2821 2822 2823
		priv->beacon_int = 0;

	spin_unlock_irqrestore(&priv->lock, flags);

2824
	if (!iwl_is_ready_rf(priv)) {
2825
		IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2826 2827 2828 2829
		mutex_unlock(&priv->mutex);
		return;
	}

2830 2831 2832
	/* we are restarting association process
	 * clear RXON_FILTER_ASSOC_MSK bit
	 */
2833
	if (priv->iw_mode != NL80211_IFTYPE_AP) {
2834
		iwl_scan_cancel_timeout(priv, 100);
2835
		priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2836
		iwl_commit_rxon(priv);
2837 2838
	}

M
Mohamed Abbas 已提交
2839 2840
	iwl_power_update_mode(priv, 0);

Z
Zhu Yi 已提交
2841
	/* Per mac80211.h: This is only used in IBSS mode... */
2842
	if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
2843

2844 2845 2846 2847 2848 2849 2850 2851 2852 2853
		/* switch to CAM during association period.
		 * the ucode will block any association/authentication
		 * frome during assiciation period if it can not hear
		 * the AP because of PM. the timer enable PM back is
		 * association do not complete
		 */
		if (priv->hw->conf.channel->flags & (IEEE80211_CHAN_PASSIVE_SCAN |
						     IEEE80211_CHAN_RADAR))
				iwl_power_disable_management(priv, 3000);

2854
		IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
Z
Zhu Yi 已提交
2855 2856 2857 2858
		mutex_unlock(&priv->mutex);
		return;
	}

2859
	iwl_set_rate(priv);
Z
Zhu Yi 已提交
2860 2861 2862

	mutex_unlock(&priv->mutex);

2863
	IWL_DEBUG_MAC80211(priv, "leave\n");
Z
Zhu Yi 已提交
2864 2865
}

2866
static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
Z
Zhu Yi 已提交
2867
{
2868
	struct iwl_priv *priv = hw->priv;
Z
Zhu Yi 已提交
2869
	unsigned long flags;
A
Assaf Krauss 已提交
2870
	__le64 timestamp;
Z
Zhu Yi 已提交
2871

2872
	IWL_DEBUG_MAC80211(priv, "enter\n");
Z
Zhu Yi 已提交
2873

2874
	if (!iwl_is_ready_rf(priv)) {
2875
		IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
Z
Zhu Yi 已提交
2876 2877 2878
		return -EIO;
	}

2879
	if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
2880
		IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
Z
Zhu Yi 已提交
2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891
		return -EIO;
	}

	spin_lock_irqsave(&priv->lock, flags);

	if (priv->ibss_beacon)
		dev_kfree_skb(priv->ibss_beacon);

	priv->ibss_beacon = skb;

	priv->assoc_id = 0;
A
Assaf Krauss 已提交
2892
	timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
2893
	priv->timestamp = le64_to_cpu(timestamp);
Z
Zhu Yi 已提交
2894

2895
	IWL_DEBUG_MAC80211(priv, "leave\n");
Z
Zhu Yi 已提交
2896 2897
	spin_unlock_irqrestore(&priv->lock, flags);

R
Ron Rindjunsky 已提交
2898
	iwl_reset_qos(priv);
Z
Zhu Yi 已提交
2899

2900
	iwl_post_associate(priv);
Z
Zhu Yi 已提交
2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911


	return 0;
}

/*****************************************************************************
 *
 * sysfs attributes
 *
 *****************************************************************************/

2912
#ifdef CONFIG_IWLWIFI_DEBUG
Z
Zhu Yi 已提交
2913 2914 2915

/*
 * The following adds a new attribute to the sysfs representation
2916
 * of this device driver (i.e. a new file in /sys/class/net/wlan0/device/)
Z
Zhu Yi 已提交
2917 2918 2919 2920 2921
 * used for controlling the debug level.
 *
 * See the level definitions in iwl for details.
 */

2922 2923
static ssize_t show_debug_level(struct device *d,
				struct device_attribute *attr, char *buf)
Z
Zhu Yi 已提交
2924
{
2925 2926 2927
	struct iwl_priv *priv = d->driver_data;

	return sprintf(buf, "0x%08X\n", priv->debug_level);
Z
Zhu Yi 已提交
2928
}
2929 2930
static ssize_t store_debug_level(struct device *d,
				struct device_attribute *attr,
Z
Zhu Yi 已提交
2931 2932
				 const char *buf, size_t count)
{
2933
	struct iwl_priv *priv = d->driver_data;
2934 2935
	unsigned long val;
	int ret;
Z
Zhu Yi 已提交
2936

2937 2938
	ret = strict_strtoul(buf, 0, &val);
	if (ret)
T
Tomas Winkler 已提交
2939
		IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf);
Z
Zhu Yi 已提交
2940
	else
2941
		priv->debug_level = val;
Z
Zhu Yi 已提交
2942 2943 2944 2945

	return strnlen(buf, count);
}

2946 2947 2948
static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
			show_debug_level, store_debug_level);

Z
Zhu Yi 已提交
2949

2950
#endif /* CONFIG_IWLWIFI_DEBUG */
Z
Zhu Yi 已提交
2951 2952


2953 2954 2955 2956
static ssize_t show_version(struct device *d,
				struct device_attribute *attr, char *buf)
{
	struct iwl_priv *priv = d->driver_data;
2957
	struct iwl_alive_resp *palive = &priv->card_alive;
2958 2959
	ssize_t pos = 0;
	u16 eeprom_ver;
2960 2961

	if (palive->is_valid)
2962 2963 2964
		pos += sprintf(buf + pos,
				"fw version: 0x%01X.0x%01X.0x%01X.0x%01X\n"
				"fw type: 0x%01X 0x%01X\n",
2965 2966 2967 2968
				palive->ucode_major, palive->ucode_minor,
				palive->sw_rev[0], palive->sw_rev[1],
				palive->ver_type, palive->ver_subtype);
	else
2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979
		pos += sprintf(buf + pos, "fw not loaded\n");

	if (priv->eeprom) {
		eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
		pos += sprintf(buf + pos, "EEPROM version: 0x%x\n",
				 eeprom_ver);
	} else {
		pos += sprintf(buf + pos, "EEPROM not initialzed\n");
	}

	return pos;
2980 2981 2982 2983
}

static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL);

Z
Zhu Yi 已提交
2984 2985 2986
static ssize_t show_temperature(struct device *d,
				struct device_attribute *attr, char *buf)
{
2987
	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
Z
Zhu Yi 已提交
2988

2989
	if (!iwl_is_alive(priv))
Z
Zhu Yi 已提交
2990 2991
		return -EAGAIN;

2992
	return sprintf(buf, "%d\n", priv->temperature);
Z
Zhu Yi 已提交
2993 2994 2995 2996 2997 2998 2999
}

static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);

static ssize_t show_tx_power(struct device *d,
			     struct device_attribute *attr, char *buf)
{
3000
	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
3001 3002 3003 3004 3005

	if (!iwl_is_ready_rf(priv))
		return sprintf(buf, "off\n");
	else
		return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
Z
Zhu Yi 已提交
3006 3007 3008 3009 3010 3011
}

static ssize_t store_tx_power(struct device *d,
			      struct device_attribute *attr,
			      const char *buf, size_t count)
{
3012
	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
3013 3014
	unsigned long val;
	int ret;
Z
Zhu Yi 已提交
3015

3016 3017
	ret = strict_strtoul(buf, 10, &val);
	if (ret)
T
Tomas Winkler 已提交
3018
		IWL_INFO(priv, "%s is not in decimal form.\n", buf);
Z
Zhu Yi 已提交
3019
	else
3020
		iwl_set_tx_power(priv, val, false);
Z
Zhu Yi 已提交
3021 3022 3023 3024 3025 3026 3027 3028 3029

	return count;
}

static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);

static ssize_t show_flags(struct device *d,
			  struct device_attribute *attr, char *buf)
{
3030
	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
Z
Zhu Yi 已提交
3031 3032 3033 3034 3035 3036 3037 3038

	return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
}

static ssize_t store_flags(struct device *d,
			   struct device_attribute *attr,
			   const char *buf, size_t count)
{
3039
	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
3040 3041 3042
	unsigned long val;
	u32 flags;
	int ret = strict_strtoul(buf, 0, &val);
3043
	if (ret)
3044 3045
		return ret;
	flags = (u32)val;
Z
Zhu Yi 已提交
3046 3047 3048 3049

	mutex_lock(&priv->mutex);
	if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
		/* Cancel any currently running scans... */
3050
		if (iwl_scan_cancel_timeout(priv, 100))
3051
			IWL_WARN(priv, "Could not cancel scan.\n");
Z
Zhu Yi 已提交
3052
		else {
3053
			IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags);
Z
Zhu Yi 已提交
3054
			priv->staging_rxon.flags = cpu_to_le32(flags);
3055
			iwl_commit_rxon(priv);
Z
Zhu Yi 已提交
3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067
		}
	}
	mutex_unlock(&priv->mutex);

	return count;
}

static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags);

static ssize_t show_filter_flags(struct device *d,
				 struct device_attribute *attr, char *buf)
{
3068
	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
Z
Zhu Yi 已提交
3069 3070 3071 3072 3073 3074 3075 3076 3077

	return sprintf(buf, "0x%04X\n",
		le32_to_cpu(priv->active_rxon.filter_flags));
}

static ssize_t store_filter_flags(struct device *d,
				  struct device_attribute *attr,
				  const char *buf, size_t count)
{
3078
	struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
3079 3080 3081
	unsigned long val;
	u32 filter_flags;
	int ret = strict_strtoul(buf, 0, &val);
3082
	if (ret)
3083 3084
		return ret;
	filter_flags = (u32)val;
Z
Zhu Yi 已提交
3085 3086 3087 3088

	mutex_lock(&priv->mutex);
	if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
		/* Cancel any currently running scans... */
3089
		if (iwl_scan_cancel_timeout(priv, 100))
3090
			IWL_WARN(priv, "Could not cancel scan.\n");
Z
Zhu Yi 已提交
3091
		else {
3092
			IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = "
Z
Zhu Yi 已提交
3093 3094 3095
				       "0x%04X\n", filter_flags);
			priv->staging_rxon.filter_flags =
				cpu_to_le32(filter_flags);
3096
			iwl_commit_rxon(priv);
Z
Zhu Yi 已提交
3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110
		}
	}
	mutex_unlock(&priv->mutex);

	return count;
}

static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
		   store_filter_flags);

static ssize_t store_power_level(struct device *d,
				 struct device_attribute *attr,
				 const char *buf, size_t count)
{
3111
	struct iwl_priv *priv = dev_get_drvdata(d);
3112
	int ret;
3113 3114
	unsigned long mode;

Z
Zhu Yi 已提交
3115 3116 3117

	mutex_lock(&priv->mutex);

3118
	if (!iwl_is_ready(priv)) {
3119
		ret = -EAGAIN;
Z
Zhu Yi 已提交
3120 3121 3122
		goto out;
	}

3123
	ret = strict_strtoul(buf, 10, &mode);
3124
	if (ret)
3125 3126
		goto out;

3127 3128
	ret = iwl_power_set_user_mode(priv, mode);
	if (ret) {
3129
		IWL_DEBUG_MAC80211(priv, "failed setting power mode.\n");
M
Mohamed Abbas 已提交
3130
		goto out;
Z
Zhu Yi 已提交
3131
	}
3132
	ret = count;
Z
Zhu Yi 已提交
3133 3134 3135

 out:
	mutex_unlock(&priv->mutex);
3136
	return ret;
Z
Zhu Yi 已提交
3137 3138 3139 3140 3141
}

static ssize_t show_power_level(struct device *d,
				struct device_attribute *attr, char *buf)
{
3142
	struct iwl_priv *priv = dev_get_drvdata(d);
3143 3144
	int mode = priv->power_data.user_power_setting;
	int system = priv->power_data.system_power_setting;
M
Mohamed Abbas 已提交
3145
	int level = priv->power_data.power_mode;
Z
Zhu Yi 已提交
3146 3147
	char *p = buf;

3148 3149 3150
	switch (system) {
	case IWL_POWER_SYS_AUTO:
		p += sprintf(p, "SYSTEM:auto");
Z
Zhu Yi 已提交
3151
		break;
3152 3153 3154 3155 3156
	case IWL_POWER_SYS_AC:
		p += sprintf(p, "SYSTEM:ac");
		break;
	case IWL_POWER_SYS_BATTERY:
		p += sprintf(p, "SYSTEM:battery");
Z
Zhu Yi 已提交
3157 3158
		break;
	}
3159

3160 3161
	p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
			"fixed" : "auto");
3162 3163
	p += sprintf(p, "\tINDEX:%d", level);
	p += sprintf(p, "\n");
3164
	return p - buf + 1;
Z
Zhu Yi 已提交
3165 3166 3167 3168 3169 3170 3171 3172 3173
}

static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
		   store_power_level);


static ssize_t show_statistics(struct device *d,
			       struct device_attribute *attr, char *buf)
{
3174
	struct iwl_priv *priv = dev_get_drvdata(d);
3175
	u32 size = sizeof(struct iwl_notif_statistics);
Z
Zhu Yi 已提交
3176
	u32 len = 0, ofs = 0;
3177
	u8 *data = (u8 *)&priv->statistics;
Z
Zhu Yi 已提交
3178 3179
	int rc = 0;

3180
	if (!iwl_is_alive(priv))
Z
Zhu Yi 已提交
3181 3182 3183
		return -EAGAIN;

	mutex_lock(&priv->mutex);
3184
	rc = iwl_send_statistics_request(priv, 0);
Z
Zhu Yi 已提交
3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215
	mutex_unlock(&priv->mutex);

	if (rc) {
		len = sprintf(buf,
			      "Error sending statistics request: 0x%08X\n", rc);
		return len;
	}

	while (size && (PAGE_SIZE - len)) {
		hex_dump_to_buffer(data + ofs, size, 16, 1, buf + len,
				   PAGE_SIZE - len, 1);
		len = strlen(buf);
		if (PAGE_SIZE - len)
			buf[len++] = '\n';

		ofs += 16;
		size -= min(size, 16U);
	}

	return len;
}

static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);


/*****************************************************************************
 *
 * driver setup and teardown
 *
 *****************************************************************************/

3216
static void iwl_setup_deferred_work(struct iwl_priv *priv)
Z
Zhu Yi 已提交
3217
{
3218
	priv->workqueue = create_singlethread_workqueue(DRV_NAME);
Z
Zhu Yi 已提交
3219 3220 3221

	init_waitqueue_head(&priv->wait_command_queue);

3222 3223 3224 3225 3226
	INIT_WORK(&priv->up, iwl_bg_up);
	INIT_WORK(&priv->restart, iwl_bg_restart);
	INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
	INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
	INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
3227
	INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
3228 3229
	INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
	INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
3230 3231

	iwl_setup_scan_deferred_work(priv);
3232
	iwl_setup_power_deferred_work(priv);
C
Christoph Hellwig 已提交
3233

3234 3235 3236 3237 3238
	if (priv->cfg->ops->lib->setup_deferred_work)
		priv->cfg->ops->lib->setup_deferred_work(priv);

	init_timer(&priv->statistics_periodic);
	priv->statistics_periodic.data = (unsigned long)priv;
3239
	priv->statistics_periodic.function = iwl_bg_statistics_periodic;
Z
Zhu Yi 已提交
3240 3241

	tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3242
		     iwl_irq_tasklet, (unsigned long)priv);
Z
Zhu Yi 已提交
3243 3244
}

3245
static void iwl_cancel_deferred_work(struct iwl_priv *priv)
Z
Zhu Yi 已提交
3246
{
3247 3248
	if (priv->cfg->ops->lib->cancel_deferred_work)
		priv->cfg->ops->lib->cancel_deferred_work(priv);
Z
Zhu Yi 已提交
3249

3250
	cancel_delayed_work_sync(&priv->init_alive_start);
Z
Zhu Yi 已提交
3251
	cancel_delayed_work(&priv->scan_check);
3252
	cancel_delayed_work_sync(&priv->set_power_save);
Z
Zhu Yi 已提交
3253 3254
	cancel_delayed_work(&priv->alive_start);
	cancel_work_sync(&priv->beacon_update);
3255
	del_timer_sync(&priv->statistics_periodic);
Z
Zhu Yi 已提交
3256 3257
}

3258
static struct attribute *iwl_sysfs_entries[] = {
Z
Zhu Yi 已提交
3259 3260 3261 3262 3263 3264
	&dev_attr_flags.attr,
	&dev_attr_filter_flags.attr,
	&dev_attr_power_level.attr,
	&dev_attr_statistics.attr,
	&dev_attr_temperature.attr,
	&dev_attr_tx_power.attr,
3265 3266 3267
#ifdef CONFIG_IWLWIFI_DEBUG
	&dev_attr_debug_level.attr,
#endif
3268
	&dev_attr_version.attr,
Z
Zhu Yi 已提交
3269 3270 3271 3272

	NULL
};

3273
static struct attribute_group iwl_attribute_group = {
Z
Zhu Yi 已提交
3274
	.name = NULL,		/* put in device directory */
3275
	.attrs = iwl_sysfs_entries,
Z
Zhu Yi 已提交
3276 3277
};

3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294
static struct ieee80211_ops iwl_hw_ops = {
	.tx = iwl_mac_tx,
	.start = iwl_mac_start,
	.stop = iwl_mac_stop,
	.add_interface = iwl_mac_add_interface,
	.remove_interface = iwl_mac_remove_interface,
	.config = iwl_mac_config,
	.config_interface = iwl_mac_config_interface,
	.configure_filter = iwl_configure_filter,
	.set_key = iwl_mac_set_key,
	.update_tkip_key = iwl_mac_update_tkip_key,
	.get_stats = iwl_mac_get_stats,
	.get_tx_stats = iwl_mac_get_tx_stats,
	.conf_tx = iwl_mac_conf_tx,
	.reset_tsf = iwl_mac_reset_tsf,
	.bss_info_changed = iwl_bss_info_changed,
	.ampdu_action = iwl_mac_ampdu_action,
3295
	.hw_scan = iwl_mac_hw_scan
Z
Zhu Yi 已提交
3296 3297
};

3298
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
Z
Zhu Yi 已提交
3299 3300
{
	int err = 0;
3301
	struct iwl_priv *priv;
Z
Zhu Yi 已提交
3302
	struct ieee80211_hw *hw;
T
Tomas Winkler 已提交
3303
	struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
3304
	unsigned long flags;
3305
	u16 pci_cmd;
Z
Zhu Yi 已提交
3306

3307 3308 3309 3310
	/************************
	 * 1. Allocating HW data
	 ************************/

3311 3312
	/* Disabling hardware scan means that mac80211 will perform scans
	 * "the hard way", rather than using device's scan. */
3313
	if (cfg->mod_params->disable_hw_scan) {
3314 3315 3316
		if (cfg->mod_params->debug & IWL_DL_INFO)
			dev_printk(KERN_DEBUG, &(pdev->dev),
				   "Disabling hw_scan\n");
3317
		iwl_hw_ops.hw_scan = NULL;
Z
Zhu Yi 已提交
3318 3319
	}

3320
	hw = iwl_alloc_all(cfg, &iwl_hw_ops);
3321
	if (!hw) {
Z
Zhu Yi 已提交
3322 3323 3324
		err = -ENOMEM;
		goto out;
	}
3325 3326 3327
	priv = hw->priv;
	/* At this point both hw and priv are allocated. */

Z
Zhu Yi 已提交
3328 3329
	SET_IEEE80211_DEV(hw, &pdev->dev);

3330
	IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
T
Tomas Winkler 已提交
3331
	priv->cfg = cfg;
Z
Zhu Yi 已提交
3332
	priv->pci_dev = pdev;
3333

3334
#ifdef CONFIG_IWLWIFI_DEBUG
3335
	priv->debug_level = priv->cfg->mod_params->debug;
Z
Zhu Yi 已提交
3336 3337 3338
	atomic_set(&priv->restrict_refcnt, 0);
#endif

3339 3340 3341 3342 3343 3344 3345 3346 3347 3348
	/**************************
	 * 2. Initializing PCI bus
	 **************************/
	if (pci_enable_device(pdev)) {
		err = -ENODEV;
		goto out_ieee80211_free_hw;
	}

	pci_set_master(pdev);

W
Winkler, Tomas 已提交
3349
	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
3350
	if (!err)
W
Winkler, Tomas 已提交
3351
		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36));
3352
	if (err) {
W
Winkler, Tomas 已提交
3353
		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
3354
		if (!err)
W
Winkler, Tomas 已提交
3355
			err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
3356
		/* both attempts failed: */
3357
		if (err) {
T
Tomas Winkler 已提交
3358
			IWL_WARN(priv, "No suitable DMA available.\n");
3359
			goto out_pci_disable_device;
3360
		}
3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378
	}

	err = pci_request_regions(pdev, DRV_NAME);
	if (err)
		goto out_pci_disable_device;

	pci_set_drvdata(pdev, priv);


	/***********************
	 * 3. Read REV register
	 ***********************/
	priv->hw_base = pci_iomap(pdev, 0, 0);
	if (!priv->hw_base) {
		err = -ENODEV;
		goto out_pci_release_regions;
	}

3379
	IWL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n",
3380
		(unsigned long long) pci_resource_len(pdev, 0));
3381
	IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base);
3382

3383
	iwl_hw_detect(priv);
T
Tomas Winkler 已提交
3384
	IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n",
3385
		priv->cfg->name, priv->hw_rev);
3386

3387 3388 3389 3390
	/* We disable the RETRY_TIMEOUT register (0x41) to keep
	 * PCI Tx retries from interfering with C3 CPU state */
	pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);

T
Tomas Winkler 已提交
3391 3392
	/* amp init */
	err = priv->cfg->ops->lib->apm_ops.init(priv);
3393
	if (err < 0) {
3394
		IWL_DEBUG_INFO(priv, "Failed to init APMG\n");
3395 3396
		goto out_iounmap;
	}
T
Tomas Winkler 已提交
3397 3398 3399
	/*****************
	 * 4. Read EEPROM
	 *****************/
3400 3401 3402
	/* Read the EEPROM */
	err = iwl_eeprom_init(priv);
	if (err) {
3403
		IWL_ERR(priv, "Unable to init EEPROM\n");
3404 3405
		goto out_iounmap;
	}
3406 3407
	err = iwl_eeprom_check_version(priv);
	if (err)
3408
		goto out_free_eeprom;
3409

3410
	/* extract MAC Address */
3411
	iwl_eeprom_get_mac(priv, priv->mac_addr);
3412
	IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->mac_addr);
3413 3414 3415 3416 3417
	SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);

	/************************
	 * 5. Setup HW constants
	 ************************/
3418
	if (iwl_set_hw_params(priv)) {
3419
		IWL_ERR(priv, "failed to set hw parameters\n");
3420
		goto out_free_eeprom;
3421 3422 3423
	}

	/*******************
T
Tomas Winkler 已提交
3424
	 * 6. Setup priv
3425
	 *******************/
Z
Zhu Yi 已提交
3426

T
Tomas Winkler 已提交
3427
	err = iwl_init_drv(priv);
3428
	if (err)
R
Ron Rindjunsky 已提交
3429
		goto out_free_eeprom;
3430
	/* At this point both hw and priv are initialized. */
3431 3432 3433 3434 3435 3436

	/**********************************
	 * 7. Initialize module parameters
	 **********************************/

	/* Disable radio (SW RF KILL) via parameter when loading driver */
3437
	if (priv->cfg->mod_params->disable) {
3438
		set_bit(STATUS_RF_KILL_SW, &priv->status);
3439
		IWL_DEBUG_INFO(priv, "Radio disabled.\n");
3440 3441 3442 3443 3444
	}

	/********************
	 * 8. Setup services
	 ********************/
3445
	spin_lock_irqsave(&priv->lock, flags);
3446
	iwl_disable_interrupts(priv);
3447
	spin_unlock_irqrestore(&priv->lock, flags);
3448

3449 3450 3451 3452 3453 3454 3455 3456
	pci_enable_msi(priv->pci_dev);

	err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
			  DRV_NAME, priv);
	if (err) {
		IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
		goto out_disable_msi;
	}
3457
	err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group);
3458
	if (err) {
3459
		IWL_ERR(priv, "failed to create sysfs device attributes\n");
3460
		goto out_free_irq;
3461 3462
	}

3463
	iwl_setup_deferred_work(priv);
3464
	iwl_setup_rx_handlers(priv);
3465

T
Tomas Winkler 已提交
3466
	/**********************************
3467
	 * 9. Setup and register mac80211
T
Tomas Winkler 已提交
3468 3469
	 **********************************/

3470 3471 3472 3473 3474 3475 3476 3477 3478
	/* enable interrupts if needed: hw bug w/a */
	pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
	if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
		pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
		pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
	}

	iwl_enable_interrupts(priv);

T
Tomas Winkler 已提交
3479 3480 3481 3482 3483 3484
	err = iwl_setup_mac(priv);
	if (err)
		goto out_remove_sysfs;

	err = iwl_dbgfs_register(priv, DRV_NAME);
	if (err)
3485
		IWL_ERR(priv, "failed to create debugfs files\n");
T
Tomas Winkler 已提交
3486

3487 3488 3489 3490 3491
	/* If platform's RF_KILL switch is NOT set to KILL */
	if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
		clear_bit(STATUS_RF_KILL_HW, &priv->status);
	else
		set_bit(STATUS_RF_KILL_HW, &priv->status);
T
Tomas Winkler 已提交
3492

3493 3494
	err = iwl_rfkill_init(priv);
	if (err)
3495
		IWL_ERR(priv, "Unable to initialize RFKILL system. "
3496
				  "Ignoring error: %d\n", err);
3497 3498 3499
	else
		iwl_rfkill_set_hw_state(priv);

3500
	iwl_power_initialize(priv);
Z
Zhu Yi 已提交
3501 3502
	return 0;

3503
 out_remove_sysfs:
3504 3505
	destroy_workqueue(priv->workqueue);
	priv->workqueue = NULL;
3506
	sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
3507 3508
 out_free_irq:
	free_irq(priv->pci_dev->irq, priv);
3509 3510
 out_disable_msi:
	pci_disable_msi(priv->pci_dev);
T
Tomas Winkler 已提交
3511
	iwl_uninit_drv(priv);
3512 3513
 out_free_eeprom:
	iwl_eeprom_free(priv);
Z
Zhu Yi 已提交
3514 3515 3516 3517
 out_iounmap:
	pci_iounmap(pdev, priv->hw_base);
 out_pci_release_regions:
	pci_release_regions(pdev);
3518
	pci_set_drvdata(pdev, NULL);
Z
Zhu Yi 已提交
3519 3520 3521 3522 3523 3524 3525 3526
 out_pci_disable_device:
	pci_disable_device(pdev);
 out_ieee80211_free_hw:
	ieee80211_free_hw(priv->hw);
 out:
	return err;
}

3527
static void __devexit iwl_pci_remove(struct pci_dev *pdev)
Z
Zhu Yi 已提交
3528
{
3529
	struct iwl_priv *priv = pci_get_drvdata(pdev);
3530
	unsigned long flags;
Z
Zhu Yi 已提交
3531 3532 3533 3534

	if (!priv)
		return;

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

3537
	iwl_dbgfs_unregister(priv);
3538
	sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
3539

3540 3541
	/* ieee80211_unregister_hw call wil cause iwl_mac_stop to
	 * to be called and iwl_down since we are removing the device
3542 3543 3544
	 * we need to set STATUS_EXIT_PENDING bit.
	 */
	set_bit(STATUS_EXIT_PENDING, &priv->status);
3545 3546 3547
	if (priv->mac80211_registered) {
		ieee80211_unregister_hw(priv->hw);
		priv->mac80211_registered = 0;
3548
	} else {
3549
		iwl_down(priv);
3550 3551
	}

3552 3553 3554 3555
	/* make sure we flush any pending irq or
	 * tasklet for the driver
	 */
	spin_lock_irqsave(&priv->lock, flags);
3556
	iwl_disable_interrupts(priv);
3557 3558 3559 3560
	spin_unlock_irqrestore(&priv->lock, flags);

	iwl_synchronize_irq(priv);

3561
	iwl_rfkill_unregister(priv);
3562
	iwl_dealloc_ucode_pci(priv);
Z
Zhu Yi 已提交
3563 3564

	if (priv->rxq.bd)
3565
		iwl_rx_queue_free(priv, &priv->rxq);
3566
	iwl_hw_txq_ctx_free(priv);
Z
Zhu Yi 已提交
3567

3568
	iwl_clear_stations_table(priv);
3569
	iwl_eeprom_free(priv);
Z
Zhu Yi 已提交
3570 3571


M
Mohamed Abbas 已提交
3572 3573 3574
	/*netif_stop_queue(dev); */
	flush_workqueue(priv->workqueue);

3575
	/* ieee80211_unregister_hw calls iwl_mac_stop, which flushes
Z
Zhu Yi 已提交
3576 3577 3578 3579 3580
	 * priv->workqueue... so we can't take down the workqueue
	 * until now... */
	destroy_workqueue(priv->workqueue);
	priv->workqueue = NULL;

3581 3582
	free_irq(priv->pci_dev->irq, priv);
	pci_disable_msi(priv->pci_dev);
Z
Zhu Yi 已提交
3583 3584 3585 3586 3587
	pci_iounmap(pdev, priv->hw_base);
	pci_release_regions(pdev);
	pci_disable_device(pdev);
	pci_set_drvdata(pdev, NULL);

T
Tomas Winkler 已提交
3588
	iwl_uninit_drv(priv);
Z
Zhu Yi 已提交
3589 3590 3591 3592 3593 3594 3595 3596 3597

	if (priv->ibss_beacon)
		dev_kfree_skb(priv->ibss_beacon);

	ieee80211_free_hw(priv->hw);
}

#ifdef CONFIG_PM

3598
static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
Z
Zhu Yi 已提交
3599
{
3600
	struct iwl_priv *priv = pci_get_drvdata(pdev);
Z
Zhu Yi 已提交
3601

3602 3603
	if (priv->is_open) {
		set_bit(STATUS_IN_SUSPEND, &priv->status);
3604
		iwl_mac_stop(priv->hw);
3605 3606
		priv->is_open = 1;
	}
Z
Zhu Yi 已提交
3607

3608 3609
	pci_save_state(pdev);
	pci_disable_device(pdev);
Z
Zhu Yi 已提交
3610 3611 3612 3613 3614
	pci_set_power_state(pdev, PCI_D3hot);

	return 0;
}

3615
static int iwl_pci_resume(struct pci_dev *pdev)
Z
Zhu Yi 已提交
3616
{
3617
	struct iwl_priv *priv = pci_get_drvdata(pdev);
3618
	int ret;
Z
Zhu Yi 已提交
3619 3620

	pci_set_power_state(pdev, PCI_D0);
3621 3622 3623
	ret = pci_enable_device(pdev);
	if (ret)
		return ret;
3624 3625
	pci_restore_state(pdev);
	iwl_enable_interrupts(priv);
Z
Zhu Yi 已提交
3626

3627
	if (priv->is_open)
3628
		iwl_mac_start(priv->hw);
Z
Zhu Yi 已提交
3629

3630
	clear_bit(STATUS_IN_SUSPEND, &priv->status);
Z
Zhu Yi 已提交
3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641
	return 0;
}

#endif /* CONFIG_PM */

/*****************************************************************************
 *
 * driver and module entry point
 *
 *****************************************************************************/

3642 3643
/* Hardware specific file defines the PCI IDs table for that hardware module */
static struct pci_device_id iwl_hw_card_ids[] = {
T
Tomas Winkler 已提交
3644
#ifdef CONFIG_IWL4965
3645 3646
	{IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)},
	{IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)},
T
Tomas Winkler 已提交
3647
#endif /* CONFIG_IWL4965 */
3648
#ifdef CONFIG_IWL5000
3649 3650 3651 3652 3653 3654
	{IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bg_cfg)},
	{IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bg_cfg)},
	{IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)},
	{IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)},
	{IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)},
	{IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)},
3655
	{IWL_PCI_DEVICE(0x4232, PCI_ANY_ID, iwl5100_agn_cfg)},
3656 3657 3658
	{IWL_PCI_DEVICE(0x4235, PCI_ANY_ID, iwl5300_agn_cfg)},
	{IWL_PCI_DEVICE(0x4236, PCI_ANY_ID, iwl5300_agn_cfg)},
	{IWL_PCI_DEVICE(0x4237, PCI_ANY_ID, iwl5100_agn_cfg)},
3659 3660 3661 3662
/* 5350 WiFi/WiMax */
	{IWL_PCI_DEVICE(0x423A, 0x1001, iwl5350_agn_cfg)},
	{IWL_PCI_DEVICE(0x423A, 0x1021, iwl5350_agn_cfg)},
	{IWL_PCI_DEVICE(0x423B, 0x1011, iwl5350_agn_cfg)},
T
Tomas Winkler 已提交
3663 3664 3665
/* 5150 Wifi/WiMax */
	{IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)},
	{IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)},
3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677
/* 6000/6050 Series */
	{IWL_PCI_DEVICE(0x0082, 0x1102, iwl6000_2ag_cfg)},
	{IWL_PCI_DEVICE(0x0085, 0x1112, iwl6000_2ag_cfg)},
	{IWL_PCI_DEVICE(0x0082, 0x1122, iwl6000_2ag_cfg)},
	{IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)},
	{IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)},
	{IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000_2agn_cfg)},
	{IWL_PCI_DEVICE(0x0085, PCI_ANY_ID, iwl6000_3agn_cfg)},
	{IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)},
	{IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)},
	{IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)},
	{IWL_PCI_DEVICE(0x0089, PCI_ANY_ID, iwl6050_2agn_cfg)},
3678 3679 3680
/* 100 Series WiFi */
	{IWL_PCI_DEVICE(0x0083, PCI_ANY_ID, iwl100_bgn_cfg)},
	{IWL_PCI_DEVICE(0x0084, PCI_ANY_ID, iwl100_bgn_cfg)},
3681
#endif /* CONFIG_IWL5000 */
T
Tomas Winkler 已提交
3682

3683 3684 3685 3686 3687
	{0}
};
MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);

static struct pci_driver iwl_driver = {
Z
Zhu Yi 已提交
3688
	.name = DRV_NAME,
3689
	.id_table = iwl_hw_card_ids,
3690 3691
	.probe = iwl_pci_probe,
	.remove = __devexit_p(iwl_pci_remove),
Z
Zhu Yi 已提交
3692
#ifdef CONFIG_PM
3693 3694
	.suspend = iwl_pci_suspend,
	.resume = iwl_pci_resume,
Z
Zhu Yi 已提交
3695 3696 3697
#endif
};

3698
static int __init iwl_init(void)
Z
Zhu Yi 已提交
3699 3700 3701 3702 3703
{

	int ret;
	printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
	printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
3704

3705
	ret = iwlagn_rate_control_register();
3706
	if (ret) {
3707 3708
		printk(KERN_ERR DRV_NAME
		       "Unable to register rate control algorithm: %d\n", ret);
3709 3710 3711
		return ret;
	}

3712
	ret = pci_register_driver(&iwl_driver);
Z
Zhu Yi 已提交
3713
	if (ret) {
3714
		printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n");
3715
		goto error_register;
Z
Zhu Yi 已提交
3716 3717 3718
	}

	return ret;
3719 3720

error_register:
3721
	iwlagn_rate_control_unregister();
3722
	return ret;
Z
Zhu Yi 已提交
3723 3724
}

3725
static void __exit iwl_exit(void)
Z
Zhu Yi 已提交
3726
{
3727
	pci_unregister_driver(&iwl_driver);
3728
	iwlagn_rate_control_unregister();
Z
Zhu Yi 已提交
3729 3730
}

3731 3732
module_exit(iwl_exit);
module_init(iwl_init);