iwl-agn.c 85 KB
Newer Older
1
2
/******************************************************************************
 *
3
 * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
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>
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"

49
#include "iwl-eeprom.h"
50
#include "iwl-dev.h"
51
#include "iwl-core.h"
52
#include "iwl-io.h"
53
#include "iwl-helpers.h"
54
#include "iwl-sta.h"
55
#include "iwl-calib.h"
56

57

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"
68

69
#ifdef CONFIG_IWLWIFI_DEBUG
70
71
72
73
74
#define VD "d"
#else
#define VD
#endif

75
#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
76
77
78
79
80
#define VS "s"
#else
#define VS
#endif

Tomas Winkler's avatar
Tomas Winkler committed
81
#define DRV_VERSION     IWLWIFI_VERSION VD VS
82
83
84
85


MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERSION);
86
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
87
MODULE_LICENSE("GPL");
Tomas Winkler's avatar
Tomas Winkler committed
88
MODULE_ALIAS("iwl4965");
89
90

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

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

/**
98
 * iwl_commit_rxon - commit staging_rxon to hardware
99
 *
100
 * The RXON command in staging_rxon is committed to the hardware and
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
int iwl_commit_rxon(struct iwl_priv *priv)
106
107
{
	/* cast away the const for active_rxon in this function */
Gregory Greenman's avatar
Gregory Greenman committed
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);
112

113
	if (!iwl_is_alive(priv))
114
		return -EBUSY;
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;
121

122
	ret = iwl_check_rxon_cmd(priv);
123
	if (ret) {
124
		IWL_ERR(priv, "Invalid RXON configuration.  Not committing.\n");
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
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;
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");
151
152
		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;

153
		ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
Gregory Greenman's avatar
Gregory Greenman committed
154
				      sizeof(struct iwl_rxon_cmd),
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) {
160
			active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
161
			IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
162
			return ret;
163
164
165
		}
	}

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

174
	iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_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,
Gregory Greenman's avatar
Gregory Greenman committed
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));
189
190
	}

191
	iwl_clear_stations_table(priv);
192

Johannes Berg's avatar
Johannes Berg committed
193
	priv->start_calib = 0;
194
195

	/* Add the broadcast address so we can send broadcast frames */
196
	if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) ==
197
						IWL_INVALID_STATION) {
198
		IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
199
200
201
202
203
		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 */
204
	if (new_assoc) {
205
		if (priv->iw_mode == NL80211_IFTYPE_STATION) {
206
207
208
			ret = iwl_rxon_add_station(priv,
					   priv->active_rxon.bssid_addr, 1);
			if (ret == IWL_INVALID_STATION) {
209
210
				IWL_ERR(priv,
					"Error adding AP address for TX.\n");
211
212
213
214
215
				return -EIO;
			}
			priv->assoc_station_added = 1;
			if (priv->default_wep_key &&
			    iwl_send_static_wepkey_cmd(priv, 0))
216
217
				IWL_ERR(priv,
					"Could not send WEP static key.\n");
218
		}
219
220
221
222
223
224
225

		/* 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) {
226
			IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
227
228
229
			return ret;
		}
		memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
230
231
	}

232
233
234
235
236
237
	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) {
238
		IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
239
240
241
		return ret;
	}

242
243
244
	return 0;
}

245
void iwl_update_chain_flags(struct iwl_priv *priv)
246
247
{

248
249
	if (priv->cfg->ops->hcmd->set_rxon_chain)
		priv->cfg->ops->hcmd->set_rxon_chain(priv);
250
	iwlcore_commit_rxon(priv);
251
252
}

253
static void iwl_clear_free_frames(struct iwl_priv *priv)
254
255
256
{
	struct list_head *element;

257
	IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n",
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));
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",
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)
275
{
276
	struct iwl_frame *frame;
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");
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);
292
293
}

294
static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
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)
303
{
304
	if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
305
306
	    ((priv->iw_mode != NL80211_IFTYPE_ADHOC) &&
	     (priv->iw_mode != NL80211_IFTYPE_AP)))
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)
349
{
350
	struct iwl_frame *frame;
351
352
353
354
	unsigned int frame_size;
	int rc;
	u8 rate;

355
	frame = iwl_get_free_frame(priv);
356
357

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

363
	rate = iwl_rate_get_lowest_plcp(priv);
364

365
	frame_size = iwl_hw_get_beacon_cmd(priv, frame, rate);
366

367
	rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
368
369
			      &frame->u.cmd[0]);

370
	iwl_free_frame(priv, frame);
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
	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,
445
446
				pci_unmap_addr(&txq->meta[index], mapping),
				pci_unmap_len(&txq->meta[index], 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
/*
 * 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 txq_id = txq->q.id;

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

	return 0;
}

515
516
517
518
519
/******************************************************************************
 *
 * Generic RX handler implementations
 *
 ******************************************************************************/
520
521
static void iwl_rx_reply_alive(struct iwl_priv *priv,
				struct iwl_rx_mem_buffer *rxb)
522
{
523
	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
524
	struct iwl_alive_resp *palive;
525
526
527
528
	struct delayed_work *pwork;

	palive = &pkt->u.alive_frame;

529
	IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
530
531
532
533
534
		       "0x%01X 0x%01X\n",
		       palive->is_valid, palive->ver_type,
		       palive->ver_subtype);

	if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
535
		IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
536
537
		memcpy(&priv->card_alive_init,
		       &pkt->u.alive_frame,
538
		       sizeof(struct iwl_init_alive_resp));
539
540
		pwork = &priv->init_alive_start;
	} else {
541
		IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
542
		memcpy(&priv->card_alive, &pkt->u.alive_frame,
543
		       sizeof(struct iwl_alive_resp));
544
545
546
547
548
549
550
551
552
		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
553
		IWL_WARN(priv, "uCode did not respond OK.\n");
554
555
}

556
static void iwl_bg_beacon_update(struct work_struct *work)
557
{
558
559
	struct iwl_priv *priv =
		container_of(work, struct iwl_priv, beacon_update);
560
561
562
	struct sk_buff *beacon;

	/* Pull updated AP beacon from mac80211. will fail if not in AP mode */
563
	beacon = ieee80211_beacon_get(priv->hw, priv->vif);
564
565

	if (!beacon) {
566
		IWL_ERR(priv, "update beacon failed\n");
567
568
569
570
571
572
573
574
575
576
577
		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);

578
	iwl_send_beacon_cmd(priv);
579
580
}

581
/**
582
 * iwl_bg_statistics_periodic - Timer callback to queue statistics
583
584
585
586
587
588
589
590
 *
 * 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.
 */
591
static void iwl_bg_statistics_periodic(unsigned long data)
592
593
594
595
596
597
{
	struct iwl_priv *priv = (struct iwl_priv *)data;

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

598
599
600
601
	/* dont send host command if rf-kill is on */
	if (!iwl_is_ready_rf(priv))
		return;

602
603
604
	iwl_send_statistics_request(priv, CMD_ASYNC);
}

605
static void iwl_rx_beacon_notif(struct iwl_priv *priv,
606
				struct iwl_rx_mem_buffer *rxb)
607
{
608
#ifdef CONFIG_IWLWIFI_DEBUG
609
	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
610
611
	struct iwl4965_beacon_notif *beacon =
		(struct iwl4965_beacon_notif *)pkt->u.raw;
612
	u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
613

614
	IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d "
615
		"tsf %d %d rate %d\n",
616
		le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK,
617
618
619
620
621
622
		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

623
	if ((priv->iw_mode == NL80211_IFTYPE_AP) &&
624
625
626
627
628
629
	    (!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 */
630
static void iwl_rx_card_state_notif(struct iwl_priv *priv,
631
				    struct iwl_rx_mem_buffer *rxb)
632
{
633
	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
634
635
636
	u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
	unsigned long status = priv->status;

637
	IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n",
638
639
640
641
642
643
			  (flags & HW_CARD_DISABLED) ? "Kill" : "On",
			  (flags & SW_CARD_DISABLED) ? "Kill" : "On");

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

644
		iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
645
646
			    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);

Mohamed Abbas's avatar
Mohamed Abbas committed
647
648
		iwl_write_direct32(priv, HBUS_TARG_MBX_C,
					HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
649
650

		if (!(flags & RXON_CARD_DISABLED)) {
651
			iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
652
				    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
Mohamed Abbas's avatar
Mohamed Abbas committed
653
			iwl_write_direct32(priv, HBUS_TARG_MBX_C,
654
655
					HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
		}
656
657
		if (flags & RF_CARD_DISABLED)
			iwl_tt_enter_ct_kill(priv);
658
	}
659
660
	if (!(flags & RF_CARD_DISABLED))
		iwl_tt_exit_ct_kill(priv);
661
662
663
664
665
666
667
668

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


	if (!(flags & RXON_CARD_DISABLED))
669
		iwl_scan_cancel(priv);
670
671

	if ((test_bit(STATUS_RF_KILL_HW, &status) !=
672
673
674
	     test_bit(STATUS_RF_KILL_HW, &priv->status)))
		wiphy_rfkill_set_hw_state(priv->hw->wiphy,
			test_bit(STATUS_RF_KILL_HW, &priv->status));
675
676
677
678
	else
		wake_up_interruptible(&priv->wait_command_queue);
}

679
int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
680
681
{
	if (src == IWL_PWR_SRC_VAUX) {
682
		if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
683
684
685
686
687
688
689
690
691
			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);
	}

Mohamed Abbas's avatar
Mohamed Abbas committed
692
	return 0;
693
694
}

695
/**
696
 * iwl_setup_rx_handlers - Initialize Rx handler callbacks
697
698
699
700
701
702
703
 *
 * 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.
 */
704
static void iwl_setup_rx_handlers(struct iwl_priv *priv)
705
{
706
	priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
707
708
709
	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;
710
	priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
711
712
	    iwl_rx_pm_debug_statistics_notif;
	priv->rx_handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif;
713

714
715
716
717
	/*
	 * 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.
718
	 */
719
720
	priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics;
	priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
721

722
	iwl_setup_spectrum_handlers(priv);
723
724
	iwl_setup_rx_scan_handlers(priv);

725
	/* status change handler */
726
	priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif;
727

728
729
	priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] =
	    iwl_rx_missed_beacon_notif;
730
	/* Rx handlers */
731
732
	priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy;
	priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx;
733
734
	/* block ack */
	priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl_rx_reply_compressed_ba;
735
	/* Set up hardware specific Rx handlers */
736
	priv->cfg->ops->lib->rx_handler_setup(priv);
737
738
739
}

/**
740
 * iwl_rx_handle - Main entry function for receiving responses from uCode
741
742
743
744
745
 *
 * Uses the priv->rx_handlers callback function array to invoke
 * the appropriate handlers, including command responses,
 * frame-received notifications, and other notifications.
 */
746
void iwl_rx_handle(struct iwl_priv *priv)
747
{
748
	struct iwl_rx_mem_buffer *rxb;
749
	struct iwl_rx_packet *pkt;
750
	struct iwl_rx_queue *rxq = &priv->rxq;
751
752
753
	u32 r, i;
	int reclaim;
	unsigned long flags;
754
	u8 fill_rx = 0;
Mohamed Abbas's avatar
Mohamed Abbas committed
755
	u32 count = 8;
756
	int total_empty;
757

758
759
	/* uCode's read index (stored in shared DRAM) indicates the last Rx
	 * buffer that the driver may process (last buffer filled by ucode). */
760
	r = le16_to_cpu(rxq->rb_stts->closed_rb_num) &  0x0FFF;
761
762
763
764
	i = rxq->read;

	/* Rx interrupt, but nothing sent from uCode */
	if (i == r)
765
		IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
766

767
768
769
770
771
772
	/* calculate total frames need to be restock after handling RX */
	total_empty = r - priv->rxq.write_actual;
	if (total_empty < 0)
		total_empty += RX_QUEUE_SIZE;

	if (total_empty > (RX_QUEUE_SIZE / 2))
773
774
		fill_rx = 1;

775
776
777
	while (i != r) {
		rxb = rxq->queue[i];

778
		/* If an RXB doesn't have a Rx queue slot associated with it,
779
780
781
782
783
784
		 * then a bug has been introduced in the queue refilling
		 * routines -- catch it here */
		BUG_ON(rxb == NULL);

		rxq->queue[i] = NULL;

Reinette Chatre's avatar
Reinette Chatre committed
785
786
787
		pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
				 priv->hw_params.rx_buf_size + 256,
				 PCI_DMA_FROMDEVICE);
788
		pkt = (struct iwl_rx_packet *)rxb->skb->data;
789
790
791
792
793
794
795
796
797

		/* 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) &&
798
			(pkt->hdr.cmd != REPLY_RX) &&
Daniel Halperin's avatar
Daniel Halperin committed
799
			(pkt->hdr.cmd != REPLY_RX_MPDU_CMD) &&
800
			(pkt->hdr.cmd != REPLY_COMPRESSED_BA) &&
801
802
803
804
805
			(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
806
		 *   rx_handlers table.  See iwl_setup_rx_handlers() */
807
		if (priv->rx_handlers[pkt->hdr.cmd]) {
808
			IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
809
				i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
810
			priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
811
			priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
812
813
		} else {
			/* No handling needed */
814
			IWL_DEBUG_RX(priv,
815
816
817
818
819
820
				"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) {
821
			/* Invoke any callbacks, transfer the skb to caller, and
822
			 * fire off the (possibly) blocking iwl_send_cmd()
823
824
			 * as we reclaim the driver command queue */
			if (rxb && rxb->skb)
825
				iwl_tx_cmd_complete(priv, rxb);
826
			else
827
				IWL_WARN(priv, "Claim null rxb?\n");
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
		}

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

		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;
843
844
845
846
847
848
		/* 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;
849
				iwl_rx_replenish_now(priv);
850
851
852
				count = 0;
			}
		}
853
854
855
856
	}

	/* Backtrack one entry */
	priv->rxq.read = i;
857
858
859
860
	if (fill_rx)
		iwl_rx_replenish_now(priv);
	else
		iwl_rx_queue_restock(priv);
861
862
}

863
864
865
/* call this function to flush any scheduled tasklet */
static inline void iwl_synchronize_irq(struct iwl_priv *priv)
{
866
	/* wait to make sure we flush pending tasklet*/
867
868
869
870
	synchronize_irq(priv->pci_dev->irq);
	tasklet_kill(&priv->irq_tasklet);
}

Mohamed Abbas's avatar
Mohamed Abbas committed
871
static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
872
873
874
875
{
	u32 inta, handled = 0;
	u32 inta_fh;
	unsigned long flags;
876
#ifdef CONFIG_IWLWIFI_DEBUG
877
878
879
880
881
882
883
884
	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. */
885
886
	inta = iwl_read32(priv, CSR_INT);
	iwl_write32(priv, CSR_INT, inta);
887
888
889
890

	/* 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. */
891
892
	inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
	iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
893

894
#ifdef CONFIG_IWLWIFI_DEBUG
895
	if (iwl_get_debug_level(priv) & IWL_DL_ISR) {
896
		/* just for debug */
897
		inta_mask = iwl_read32(priv, CSR_INT_MASK);
898
		IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
899
900
901
902
903
904
905
906
			      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. */
Tomas Winkler's avatar
Tomas Winkler committed
907
	if (inta_fh & CSR49_FH_INT_RX_MASK)
908
		inta |= CSR_INT_BIT_FH_RX;
Tomas Winkler's avatar
Tomas Winkler committed
909
	if (inta_fh & CSR49_FH_INT_TX_MASK)
910
911
912
913
		inta |= CSR_INT_BIT_FH_TX;

	/* Now service all interrupt bits discovered above. */
	if (inta & CSR_INT_BIT_HW_ERR) {
914
		IWL_ERR(priv, "Hardware error detected.  Restarting.\n");
915
916

		/* Tell the device to stop sending interrupts */
917
		iwl_disable_interrupts(priv);
918

919
		priv->isr_stats.hw++;
920
		iwl_irq_handle_error(priv);
921
922
923
924
925
926
927
928

		handled |= CSR_INT_BIT_HW_ERR;

		spin_unlock_irqrestore(&priv->lock, flags);

		return;
	}

929
#ifdef CONFIG_IWLWIFI_DEBUG
930
	if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
931
		/* NIC fires this, but we don't use it, redundant with WAKEUP */
932
		if (inta & CSR_INT_BIT_SCD) {
933
			IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
934
				      "the frame/frames.\n");
935
936
			priv->isr_stats.sch++;
		}
937
938

		/* Alive notification via Rx interrupt will do the real work */
939
		if (inta & CSR_INT_BIT_ALIVE) {
940
			IWL_DEBUG_ISR(priv, "Alive interrupt\n");
941
942
			priv->isr_stats.alive++;
		}
943
944
945
	}
#endif
	/* Safely ignore these bits for debug checks below */
946
	inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
947

948
	/* HW RF KILL switch toggled */
949
950
	if (inta & CSR_INT_BIT_RF_KILL) {
		int hw_rf_kill = 0;
951
		if (!(iwl_read32(priv, CSR_GP_CNTRL) &
952
953
954
				CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
			hw_rf_kill = 1;

955
		IWL_WARN(priv, "RF_KILL bit toggled to %s.\n",
956
				hw_rf_kill ? "disable radio" : "enable radio");
957

958
959
		priv->isr_stats.rfkill++;

960
		/* driver only loads ucode once setting the interface up.
961
962
963
		 * 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.
964
		 */
965
966
967
968
969
		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);
970
			wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
971
		}
972
973
974
975

		handled |= CSR_INT_BIT_RF_KILL;
	}

976
	/* Chip got too hot and stopped itself */
977
	if (inta & CSR_INT_BIT_CT_KILL) {
978
		IWL_ERR(priv, "Microcode CT kill error detected.\n");
979
		priv->isr_stats.ctkill++;
980
981
982
983
984
		handled |= CSR_INT_BIT_CT_KILL;
	}

	/* Error detected by uCode */
	if (inta & CSR_INT_BIT_SW_ERR) {
985
986
		IWL_ERR(priv, "Microcode SW error detected. "
			" Restarting 0x%X.\n", inta);
987
988
		priv->isr_stats.sw++;
		priv->isr_stats.sw_err = inta;
989
		iwl_irq_handle_error(priv);
990
991
992
993
994
		handled |= CSR_INT_BIT_SW_ERR;
	}

	/* uCode wakes up after power-down sleep */
	if (inta & CSR_INT_BIT_WAKEUP) {
995
		IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
996
		iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
997
998
999
1000
1001
1002
		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]);
1003

1004
1005
		priv->isr_stats.wakeup++;

1006
1007
1008
1009
1010
1011
1012
		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)) {
1013
		iwl_rx_handle(priv);
1014
		priv->isr_stats.rx++;
1015
1016
1017
1018
		handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
	}

	if (inta & CSR_INT_BIT_FH_TX) {
1019
		IWL_DEBUG_ISR(priv, "Tx interrupt\n");
1020
		priv->isr_stats.tx++;
1021
		handled |= CSR_INT_BIT_FH_TX;
1022
1023
1024
		/* FH finished to write, send event */
		priv->ucode_write_complete = 1;
		wake_up_interruptible(&priv->wait_command_queue);
1025
1026
	}

1027
	if (inta & ~handled) {
1028
		IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
1029
1030
		priv->isr_stats.unhandled++;
	}
1031

1032
	if (inta & ~(priv->inta_mask)) {
1033
		IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
1034
			 inta & ~priv->inta_mask);
1035
		IWL_WARN(priv, "   with FH_INT = 0x%08x\n", inta_fh);
1036
1037
1038
	}

	/* Re-enable all interrupts */
1039
1040
	/* only Re-enable if diabled by irq */
	if (test_bit(STATUS_INT_ENABLED, &priv->status))
1041
		iwl_enable_interrupts(priv);
1042

1043
#ifdef CONFIG_IWLWIFI_DEBUG
1044
	if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
1045
1046
1047
		inta = iwl_read32(priv, CSR_INT);
		inta_mask = iwl_read32(priv, CSR_INT_MASK);
		inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
1048
		IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
1049
1050
1051
1052
1053
1054
			"flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
	}
#endif
	spin_unlock_irqrestore(&priv->lock, flags);
}

Mohamed Abbas's avatar
Mohamed Abbas committed
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
/* tasklet for iwlagn interrupt */
static void iwl_irq_tasklet(struct iwl_priv *priv)
{
	u32 inta = 0;
	u32 handled = 0;
	unsigned long flags;
#ifdef CONFIG_IWLWIFI_DEBUG
	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,
	 */
	iwl_write32(priv, CSR_INT, priv->inta);

	inta = priv->inta;

#ifdef CONFIG_IWLWIFI_DEBUG
1075
	if (iwl_get_debug_level(priv) & IWL_DL_ISR) {
Mohamed Abbas's avatar
Mohamed Abbas committed
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
		/* just for debug */
		inta_mask = iwl_read32(priv, CSR_INT_MASK);
		IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x\n ",
				inta, inta_mask);
	}
#endif
	/* saved interrupt in inta variable now we can reset priv->inta */
	priv->inta = 0;

	/* Now service all interrupt bits discovered above. */
	if (inta & CSR_INT_BIT_HW_ERR) {
1087
		IWL_ERR(priv, "Hardware error detected.  Restarting.\n");
Mohamed Abbas's avatar
Mohamed Abbas committed
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102

		/* Tell the device to stop sending interrupts */
		iwl_disable_interrupts(priv);

		priv->isr_stats.hw++;
		iwl_irq_handle_error(priv);

		handled |= CSR_INT_BIT_HW_ERR;

		spin_unlock_irqrestore(&priv->lock, flags);

		return;
	}

#ifdef CONFIG_IWLWIFI_DEBUG
1103
	if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
Mohamed Abbas's avatar
Mohamed Abbas committed
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
		/* NIC fires this, but we don't use it, redundant with WAKEUP */
		if (inta & CSR_INT_BIT_SCD) {
			IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
				      "the frame/frames.\n");
			priv->isr_stats.sch++;
		}

		/* Alive notification via Rx interrupt will do the real work */
		if (inta & CSR_INT_BIT_ALIVE) {
			IWL_DEBUG_ISR(priv, "Alive interrupt\n");
			priv->isr_stats.alive++;
		}
	}
#endif
	/* Safely ignore these bits for debug checks below */
	inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);

	/* HW RF KILL switch toggled */
	if (inta & CSR_INT_BIT_RF_KILL) {
		int hw_rf_kill = 0;
		if (!(iwl_read32(priv, CSR_GP_CNTRL) &
				CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
			hw_rf_kill = 1;

1128
		IWL_WARN(priv, "RF_KILL bit toggled to %s.\n",
Mohamed Abbas's avatar
Mohamed Abbas committed
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
				hw_rf_kill ? "disable radio" : "enable radio");

		priv->isr_stats.rfkill++;

		/* driver only loads ucode once setting the interface up.
		 * 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.
		 */
		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);