iwl3945-base.c 121 KB
Newer Older
1
2
/******************************************************************************
 *
3
 * Copyright(c) 2003 - 2010 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
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 *****************************************************************************/

30
31
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

32
33
34
35
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
36
#include <linux/pci-aspm.h>
37
#include <linux/slab.h>
38
39
#include <linux/dma-mapping.h>
#include <linux/delay.h>
40
#include <linux/sched.h>
41
42
43
44
45
46
47
48
49
50
51
52
#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/ieee80211_radiotap.h>
#include <net/mac80211.h>

#include <asm/div64.h>

53
54
#define DRV_NAME	"iwl3945"

Winkler, Tomas's avatar
Winkler, Tomas committed
55
56
#include "iwl-fh.h"
#include "iwl-3945-fh.h"
57
#include "iwl-commands.h"
58
#include "iwl-sta.h"
59
#include "iwl-3945.h"
60
#include "iwl-core.h"
61
#include "iwl-helpers.h"
62
#include "iwl-dev.h"
63
#include "iwl-spectrum.h"
64
65
66
67
68
69
70
71

/*
 * module name, copyright, version, etc.
 */

#define DRV_DESCRIPTION	\
"Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux"

Samuel Ortiz's avatar
Samuel Ortiz committed
72
#ifdef CONFIG_IWLWIFI_DEBUG
73
74
75
76
77
#define VD "d"
#else
#define VD
#endif

78
79
80
81
82
83
/*
 * add "s" to indicate spectrum measurement included.
 * we add it here to be consistent with previous releases in which
 * this was configurable.
 */
#define DRV_VERSION  IWLWIFI_VERSION VD "s"
84
#define DRV_COPYRIGHT	"Copyright(c) 2003-2010 Intel Corporation"
85
#define DRV_AUTHOR     "<ilw@linux.intel.com>"
86
87
88

MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERSION);
89
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
90
91
MODULE_LICENSE("GPL");

92
93
 /* module parameters */
struct iwl_mod_params iwl3945_mod_params = {
94
	.sw_crypto = 1,
95
	.restart_fw = 1,
96
97
98
	/* the rest are 0 by default */
};

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
 * iwl3945_get_antenna_flags - Get antenna flags for RXON command
 * @priv: eeprom and antenna fields are used to determine antenna flags
 *
 * priv->eeprom39  is used to determine if antenna AUX/MAIN are reversed
 * iwl3945_mod_params.antenna specifies the antenna diversity mode:
 *
 * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself
 * IWL_ANTENNA_MAIN      - Force MAIN antenna
 * IWL_ANTENNA_AUX       - Force AUX antenna
 */
__le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
{
	struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;

	switch (iwl3945_mod_params.antenna) {
	case IWL_ANTENNA_DIVERSITY:
		return 0;

	case IWL_ANTENNA_MAIN:
		if (eeprom->antenna_switch_type)
			return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
		return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;

	case IWL_ANTENNA_AUX:
		if (eeprom->antenna_switch_type)
			return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
		return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
	}

	/* bad antenna selector value */
	IWL_ERR(priv, "Bad antenna selector value (0x%x)\n",
		iwl3945_mod_params.antenna);

	return 0;		/* "diversity" is default if error */
}

136
static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
137
138
139
140
141
				   struct ieee80211_key_conf *keyconf,
				   u8 sta_id)
{
	unsigned long flags;
	__le16 key_flags = 0;
142
143
144
145
146
147
148
149
150
151
152
	int ret;

	key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
	key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);

	if (sta_id == priv->hw_params.bcast_sta_id)
		key_flags |= STA_KEY_MULTICAST_MSK;

	keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
	keyconf->hw_key_idx = keyconf->keyidx;
	key_flags &= ~STA_KEY_FLG_INVALID;
153
154

	spin_lock_irqsave(&priv->sta_lock, flags);
155
	priv->stations[sta_id].keyinfo.cipher = keyconf->cipher;
156
157
	priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
	memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
158
159
	       keyconf->keylen);

160
	memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
161
	       keyconf->keylen);
162

163
	if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
164
			== STA_KEY_FLG_NO_ENC)
165
		priv->stations[sta_id].sta.key.key_offset =
166
167
168
169
				 iwl_get_free_ucode_key_index(priv);
	/* else, we are overriding an existing key => no need to allocated room
	* in uCode. */

170
	WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
171
172
		"no space for a new key");

173
174
175
	priv->stations[sta_id].sta.key.key_flags = key_flags;
	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
176

177
178
	IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n");

179
	ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
180

181
182
	spin_unlock_irqrestore(&priv->sta_lock, flags);

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
	return ret;
}

static int iwl3945_set_tkip_dynamic_key_info(struct iwl_priv *priv,
				  struct ieee80211_key_conf *keyconf,
				  u8 sta_id)
{
	return -EOPNOTSUPP;
}

static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv,
				  struct ieee80211_key_conf *keyconf,
				  u8 sta_id)
{
	return -EOPNOTSUPP;
198
199
}

200
static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
201
202
{
	unsigned long flags;
203
	struct iwl_addsta_cmd sta_cmd;
204
205

	spin_lock_irqsave(&priv->sta_lock, flags);
206
207
	memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
	memset(&priv->stations[sta_id].sta.key, 0,
208
		sizeof(struct iwl4965_keyinfo));
209
210
211
	priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
212
	memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
213
214
	spin_unlock_irqrestore(&priv->sta_lock, flags);

215
	IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n");
216
	return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
217
218
}

Abhijeet Kolekar's avatar
Abhijeet Kolekar committed
219
static int iwl3945_set_dynamic_key(struct iwl_priv *priv,
220
221
222
223
224
225
			struct ieee80211_key_conf *keyconf, u8 sta_id)
{
	int ret = 0;

	keyconf->hw_key_idx = HW_KEY_DYNAMIC;

226
227
	switch (keyconf->cipher) {
	case WLAN_CIPHER_SUITE_CCMP:
228
229
		ret = iwl3945_set_ccmp_dynamic_key_info(priv, keyconf, sta_id);
		break;
230
	case WLAN_CIPHER_SUITE_TKIP:
231
232
		ret = iwl3945_set_tkip_dynamic_key_info(priv, keyconf, sta_id);
		break;
233
234
	case WLAN_CIPHER_SUITE_WEP40:
	case WLAN_CIPHER_SUITE_WEP104:
235
236
237
		ret = iwl3945_set_wep_dynamic_key_info(priv, keyconf, sta_id);
		break;
	default:
238
239
		IWL_ERR(priv, "Unknown alg: %s alg=%x\n", __func__,
			keyconf->cipher);
240
241
242
		ret = -EINVAL;
	}

243
244
	IWL_DEBUG_WEP(priv, "Set dynamic key: alg=%x len=%d idx=%d sta=%d ret=%d\n",
		      keyconf->cipher, keyconf->keylen, keyconf->keyidx,
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
		      sta_id, ret);

	return ret;
}

static int iwl3945_remove_static_key(struct iwl_priv *priv)
{
	int ret = -EOPNOTSUPP;

	return ret;
}

static int iwl3945_set_static_key(struct iwl_priv *priv,
				struct ieee80211_key_conf *key)
{
260
261
	if (key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
	    key->cipher == WLAN_CIPHER_SUITE_WEP104)
262
263
		return -EOPNOTSUPP;

264
	IWL_ERR(priv, "Static key invalid: cipher %x\n", key->cipher);
265
266
267
	return -EINVAL;
}

268
static void iwl3945_clear_free_frames(struct iwl_priv *priv)
269
270
271
{
	struct list_head *element;

272
	IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n",
273
274
275
276
277
		       priv->frames_count);

	while (!list_empty(&priv->free_frames)) {
		element = priv->free_frames.next;
		list_del(element);
Christoph Hellwig's avatar
Christoph Hellwig committed
278
		kfree(list_entry(element, struct iwl3945_frame, list));
279
280
281
282
		priv->frames_count--;
	}

	if (priv->frames_count) {
283
		IWL_WARN(priv, "%d frames still in use.  Did we lose one?\n",
284
285
286
287
288
			    priv->frames_count);
		priv->frames_count = 0;
	}
}

289
static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl_priv *priv)
290
{
Christoph Hellwig's avatar
Christoph Hellwig committed
291
	struct iwl3945_frame *frame;
292
293
294
295
	struct list_head *element;
	if (list_empty(&priv->free_frames)) {
		frame = kzalloc(sizeof(*frame), GFP_KERNEL);
		if (!frame) {
296
			IWL_ERR(priv, "Could not allocate frame!\n");
297
298
299
300
301
302
303
304
305
			return NULL;
		}

		priv->frames_count++;
		return frame;
	}

	element = priv->free_frames.next;
	list_del(element);
Christoph Hellwig's avatar
Christoph Hellwig committed
306
	return list_entry(element, struct iwl3945_frame, list);
307
308
}

309
static void iwl3945_free_frame(struct iwl_priv *priv, struct iwl3945_frame *frame)
310
311
312
313
314
{
	memset(frame, 0, sizeof(*frame));
	list_add(&frame->list, &priv->free_frames);
}

315
unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
316
				struct ieee80211_hdr *hdr,
317
				int left)
318
319
{

320
	if (!iwl_is_associated(priv) || !priv->ibss_beacon)
321
322
323
324
325
326
327
328
329
330
		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;
}

331
static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
332
{
Christoph Hellwig's avatar
Christoph Hellwig committed
333
	struct iwl3945_frame *frame;
334
335
336
337
	unsigned int frame_size;
	int rc;
	u8 rate;

Christoph Hellwig's avatar
Christoph Hellwig committed
338
	frame = iwl3945_get_free_frame(priv);
339
340

	if (!frame) {
341
		IWL_ERR(priv, "Could not obtain free frame buffer for beacon "
342
343
344
345
			  "command.\n");
		return -ENOMEM;
	}

346
	rate = iwl_rate_get_lowest_plcp(priv);
347

Christoph Hellwig's avatar
Christoph Hellwig committed
348
	frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
349

350
	rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
351
352
			      &frame->u.cmd[0]);

Christoph Hellwig's avatar
Christoph Hellwig committed
353
	iwl3945_free_frame(priv, frame);
354
355
356
357

	return rc;
}

358
static void iwl3945_unset_hw_params(struct iwl_priv *priv)
359
{
360
	if (priv->_3945.shared_virt)
361
362
		dma_free_coherent(&priv->pci_dev->dev,
				  sizeof(struct iwl3945_shared),
363
364
				  priv->_3945.shared_virt,
				  priv->_3945.shared_phys);
365
366
}

367
static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
368
				      struct ieee80211_tx_info *info,
369
				      struct iwl_device_cmd *cmd,
370
				      struct sk_buff *skb_frag,
371
				      int sta_id)
372
{
373
	struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
374
	struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo;
375

376
377
378
379
	tx_cmd->sec_ctl = 0;

	switch (keyinfo->cipher) {
	case WLAN_CIPHER_SUITE_CCMP:
380
381
		tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
		memcpy(tx_cmd->key, keyinfo->key, keyinfo->keylen);
382
		IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
383
384
		break;

385
	case WLAN_CIPHER_SUITE_TKIP:
386
387
		break;

388
389
390
391
392
	case WLAN_CIPHER_SUITE_WEP104:
		tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
		/* fall through */
	case WLAN_CIPHER_SUITE_WEP40:
		tx_cmd->sec_ctl |= TX_CMD_SEC_WEP |
393
		    (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
394

395
		memcpy(&tx_cmd->key[3], keyinfo->key, keyinfo->keylen);
396

397
		IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
398
			     "with key %d\n", info->control.hw_key->hw_key_idx);
399
400
401
		break;

	default:
402
		IWL_ERR(priv, "Unknown encode cipher %x\n", keyinfo->cipher);
403
404
405
406
407
408
409
		break;
	}
}

/*
 * handle build REPLY_TX command notification.
 */
410
static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
411
				  struct iwl_device_cmd *cmd,
412
				  struct ieee80211_tx_info *info,
413
				  struct ieee80211_hdr *hdr, u8 std_id)
414
{
415
416
	struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
	__le32 tx_flags = tx_cmd->tx_flags;
417
	__le16 fc = hdr->frame_control;
418

419
	tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
420
	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
421
		tx_flags |= TX_CMD_FLG_ACK_MSK;
422
		if (ieee80211_is_mgmt(fc))
423
			tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
424
		if (ieee80211_is_probe_resp(fc) &&
425
426
427
428
429
430
431
		    !(le16_to_cpu(hdr->seq_ctrl) & 0xf))
			tx_flags |= TX_CMD_FLG_TSF_MSK;
	} else {
		tx_flags &= (~TX_CMD_FLG_ACK_MSK);
		tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
	}

432
	tx_cmd->sta_id = std_id;
433
	if (ieee80211_has_morefrags(fc))
434
435
		tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;

436
437
	if (ieee80211_is_data_qos(fc)) {
		u8 *qc = ieee80211_get_qos_ctl(hdr);
438
		tx_cmd->tid_tspec = qc[0] & 0xf;
439
		tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
440
	} else {
441
		tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
442
	}
443

Johannes Berg's avatar
Johannes Berg committed
444
	priv->cfg->ops->utils->tx_cmd_protection(priv, info, fc, &tx_flags);
445
446

	tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
447
448
	if (ieee80211_is_mgmt(fc)) {
		if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
449
			tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3);
450
		else
451
			tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2);
Mohamed Abbas's avatar
Mohamed Abbas committed
452
	} else {
453
		tx_cmd->timeout.pm_frame_timeout = 0;
Mohamed Abbas's avatar
Mohamed Abbas committed
454
	}
455

456
457
458
	tx_cmd->driver_txop = 0;
	tx_cmd->tx_flags = tx_flags;
	tx_cmd->next_frame_len = 0;
459
460
461
462
463
}

/*
 * start REPLY_TX command process
 */
464
static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
465
466
{
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
467
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
468
	struct iwl3945_tx_cmd *tx_cmd;
469
	struct iwl_tx_queue *txq = NULL;
470
	struct iwl_queue *q = NULL;
471
472
	struct iwl_device_cmd *out_cmd;
	struct iwl_cmd_meta *out_meta;
473
474
	dma_addr_t phys_addr;
	dma_addr_t txcmd_phys;
475
	int txq_id = skb_get_queue_mapping(skb);
Reinette Chatre's avatar
Reinette Chatre committed
476
	u16 len, idx, len_org, hdr_len; /* TODO: len_org is not used */
477
478
	u8 id;
	u8 unicast;
479
	u8 sta_id;
480
	u8 tid = 0;
481
	__le16 fc;
482
483
484
485
	u8 wait_write_ptr = 0;
	unsigned long flags;

	spin_lock_irqsave(&priv->lock, flags);
486
	if (iwl_is_rfkill(priv)) {
487
		IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
488
489
490
		goto drop_unlock;
	}

491
	if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) {
492
		IWL_ERR(priv, "ERROR: No TX rate available.\n");
493
494
495
496
497
498
		goto drop_unlock;
	}

	unicast = !is_multicast_ether_addr(hdr->addr1);
	id = 0;

499
	fc = hdr->frame_control;
500

Samuel Ortiz's avatar
Samuel Ortiz committed
501
#ifdef CONFIG_IWLWIFI_DEBUG
502
	if (ieee80211_is_auth(fc))
503
		IWL_DEBUG_TX(priv, "Sending AUTH frame\n");
504
	else if (ieee80211_is_assoc_req(fc))
505
		IWL_DEBUG_TX(priv, "Sending ASSOC frame\n");
506
	else if (ieee80211_is_reassoc_req(fc))
507
		IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
508
509
510
511
#endif

	spin_unlock_irqrestore(&priv->lock, flags);

512
	hdr_len = ieee80211_hdrlen(fc);
513

514
	/* Find index into station table for destination station */
515
	sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta);
516
	if (sta_id == IWL_INVALID_STATION) {
517
		IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
Johannes Berg's avatar
Johannes Berg committed
518
			       hdr->addr1);
519
520
521
		goto drop;
	}

522
	IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id);
523

524
	if (ieee80211_is_data_qos(fc)) {
525
		u8 *qc = ieee80211_get_qos_ctl(hdr);
526
		tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
527
528
		if (unlikely(tid >= MAX_TID_COUNT))
			goto drop;
529
	}
530
531

	/* Descriptor for chosen Tx queue */
532
	txq = &priv->txq[txq_id];
533
534
	q = &txq->q;

Zhu Yi's avatar
Zhu Yi committed
535
536
537
	if ((iwl_queue_space(q) < q->high_mark))
		goto drop;

538
539
	spin_lock_irqsave(&priv->lock, flags);

540
	idx = get_cmd_index(q, q->write_ptr, 0);
541

542
	/* Set up driver data for this TFD */
Winkler, Tomas's avatar
Winkler, Tomas committed
543
	memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
544
	txq->txb[q->write_ptr].skb = skb;
545
546

	/* Init first empty entry in queue's array of Tx/cmd buffers */
547
	out_cmd = txq->cmd[idx];
548
	out_meta = &txq->meta[idx];
549
	tx_cmd = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload;
550
	memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
551
	memset(tx_cmd, 0, sizeof(*tx_cmd));
552
553
554
555
556
557
558

	/*
	 * Set up the Tx-command (not MAC!) header.
	 * Store the chosen Tx queue and TFD index within the sequence field;
	 * after Tx, uCode's Tx response will return this value so driver can
	 * locate the frame within the tx queue and do post-tx processing.
	 */
559
560
	out_cmd->hdr.cmd = REPLY_TX;
	out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
561
				INDEX_TO_SEQ(q->write_ptr)));
562
563

	/* Copy MAC header from skb into command buffer */
564
	memcpy(tx_cmd->hdr, hdr, hdr_len);
565

Reinette Chatre's avatar
Reinette Chatre committed
566
567
568
569
570
571
572
573
574
575
576
577

	if (info->control.hw_key)
		iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id);

	/* TODO need this for burst mode later on */
	iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id);

	/* set is_hcca to 0; it probably will never be implemented */
	iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0);

	/* Total # bytes to be transmitted */
	len = (u16)skb->len;
578
	tx_cmd->len = cpu_to_le16(len);
Reinette Chatre's avatar
Reinette Chatre committed
579

580
	iwl_dbg_log_tx_data_frame(priv, len, hdr);
581
	iwl_update_stats(priv, true, fc, len);
582
583
	tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
	tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
Reinette Chatre's avatar
Reinette Chatre committed
584
585
586
587
588
589
590
591

	if (!ieee80211_has_morefrags(hdr->frame_control)) {
		txq->need_update = 1;
	} else {
		wait_write_ptr = 1;
		txq->need_update = 0;
	}

592
	IWL_DEBUG_TX(priv, "sequence nr = 0X%x\n",
Reinette Chatre's avatar
Reinette Chatre committed
593
		     le16_to_cpu(out_cmd->hdr.sequence));
594
	IWL_DEBUG_TX(priv, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
595
596
	iwl_print_hex_dump(priv, IWL_DL_TX, tx_cmd, sizeof(*tx_cmd));
	iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr,
Reinette Chatre's avatar
Reinette Chatre committed
597
598
			   ieee80211_hdrlen(fc));

599
600
601
602
603
604
605
606
607
	/*
	 * Use the first empty entry in this queue's command buffer array
	 * to contain the Tx command and MAC header concatenated together
	 * (payload data will be in another buffer).
	 * Size of this varies, due to varying MAC header length.
	 * If end is not dword aligned, we'll have 2 extra bytes at the end
	 * of the MAC header (device reads on dword boundaries).
	 * We'll tell device about this padding later.
	 */
608
	len = sizeof(struct iwl3945_tx_cmd) +
609
			sizeof(struct iwl_cmd_header) + hdr_len;
610
611
612
613
614
615
616
617
618

	len_org = len;
	len = (len + 3) & ~3;

	if (len_org != len)
		len_org = 1;
	else
		len_org = 0;

619
620
	/* Physical address of this Tx command's header (not MAC header!),
	 * within command buffer array. */
Reinette Chatre's avatar
Reinette Chatre committed
621
622
623
624
	txcmd_phys = pci_map_single(priv->pci_dev, &out_cmd->hdr,
				    len, PCI_DMA_TODEVICE);
	/* we do not map meta data ... so we can safely access address to
	 * provide to unmap command*/
625
626
	dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
	dma_unmap_len_set(out_meta, len, len);
627

628
629
	/* Add buffer containing Tx command and MAC(!) header to TFD's
	 * first entry */
630
631
	priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
						   txcmd_phys, len, 1, 0);
632
633


634
635
	/* Set up TFD's 2nd entry to point directly to remainder of skb,
	 * if any (802.11 null frames have no payload). */
636
637
638
639
	len = skb->len - hdr_len;
	if (len) {
		phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
					   len, PCI_DMA_TODEVICE);
640
641
642
		priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
							   phys_addr, len,
							   0, U32_PAD(len));
643
644
645
	}


646
	/* Tell device the write index *just past* this latest filled TFD */
647
	q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
648
	iwl_txq_update_write_ptr(priv, txq);
649
650
	spin_unlock_irqrestore(&priv->lock, flags);

651
	if ((iwl_queue_space(q) < q->high_mark)
652
653
654
655
	    && priv->mac80211_registered) {
		if (wait_write_ptr) {
			spin_lock_irqsave(&priv->lock, flags);
			txq->need_update = 1;
656
			iwl_txq_update_write_ptr(priv, txq);
657
658
659
			spin_unlock_irqrestore(&priv->lock, flags);
		}

660
		iwl_stop_queue(priv, skb_get_queue_mapping(skb));
661
662
663
664
665
666
667
668
669
670
	}

	return 0;

drop_unlock:
	spin_unlock_irqrestore(&priv->lock, flags);
drop:
	return -1;
}

671
static int iwl3945_get_measurement(struct iwl_priv *priv,
672
673
674
			       struct ieee80211_measurement_params *params,
			       u8 type)
{
675
	struct iwl_spectrum_cmd spectrum;
Zhu Yi's avatar
Zhu Yi committed
676
	struct iwl_rx_packet *pkt;
677
	struct iwl_host_cmd cmd = {
678
679
		.id = REPLY_SPECTRUM_MEASUREMENT_CMD,
		.data = (void *)&spectrum,
680
		.flags = CMD_WANT_SKB,
681
682
683
684
685
686
	};
	u32 add_time = le64_to_cpu(params->start_time);
	int rc;
	int spectrum_resp_status;
	int duration = le16_to_cpu(params->duration);

687
	if (iwl_is_associated(priv))
688
		add_time = iwl_usecs_to_beacons(priv,
689
			le64_to_cpu(params->start_time) - priv->_3945.last_tsf,
690
691
692
693
694
695
696
697
698
699
700
			le16_to_cpu(priv->rxon_timing.beacon_interval));

	memset(&spectrum, 0, sizeof(spectrum));

	spectrum.channel_count = cpu_to_le16(1);
	spectrum.flags =
	    RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK;
	spectrum.filter_flags = MEASUREMENT_FILTER_FLAG;
	cmd.len = sizeof(spectrum);
	spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));

701
	if (iwl_is_associated(priv))
702
		spectrum.start_time =
703
704
			iwl_add_beacon_time(priv,
				priv->_3945.last_beacon_time, add_time,
705
706
707
708
709
710
711
				le16_to_cpu(priv->rxon_timing.beacon_interval));
	else
		spectrum.start_time = 0;

	spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
	spectrum.channels[0].channel = params->channel;
	spectrum.channels[0].type = type;
712
	if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
713
714
715
		spectrum.flags |= RXON_FLG_BAND_24G_MSK |
		    RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;

716
	rc = iwl_send_cmd_sync(priv, &cmd);
717
718
719
	if (rc)
		return rc;

Zhu Yi's avatar
Zhu Yi committed
720
721
	pkt = (struct iwl_rx_packet *)cmd.reply_page;
	if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
722
		IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
723
724
725
		rc = -EIO;
	}

Zhu Yi's avatar
Zhu Yi committed
726
	spectrum_resp_status = le16_to_cpu(pkt->u.spectrum.status);
727
728
	switch (spectrum_resp_status) {
	case 0:		/* Command will be handled */
Zhu Yi's avatar
Zhu Yi committed
729
		if (pkt->u.spectrum.id != 0xff) {
730
			IWL_DEBUG_INFO(priv, "Replaced existing measurement: %d\n",
Zhu Yi's avatar
Zhu Yi committed
731
						pkt->u.spectrum.id);
732
733
734
735
736
737
738
739
740
741
742
			priv->measurement_status &= ~MEASUREMENT_READY;
		}
		priv->measurement_status |= MEASUREMENT_ACTIVE;
		rc = 0;
		break;

	case 1:		/* Command will not be handled */
		rc = -EAGAIN;
		break;
	}

743
	iwl_free_pages(priv, cmd.reply_page);
744
745
746
747

	return rc;
}

748
static void iwl3945_rx_reply_alive(struct iwl_priv *priv,
749
			       struct iwl_rx_mem_buffer *rxb)
750
{
Zhu Yi's avatar
Zhu Yi committed
751
	struct iwl_rx_packet *pkt = rxb_addr(rxb);
752
	struct iwl_alive_resp *palive;
753
754
755
756
	struct delayed_work *pwork;

	palive = &pkt->u.alive_frame;

757
	IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
758
759
760
761
762
		       "0x%01X 0x%01X\n",
		       palive->is_valid, palive->ver_type,
		       palive->ver_subtype);

	if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
763
		IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
764
765
		memcpy(&priv->card_alive_init, &pkt->u.alive_frame,
		       sizeof(struct iwl_alive_resp));
766
767
		pwork = &priv->init_alive_start;
	} else {
768
		IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
769
		memcpy(&priv->card_alive, &pkt->u.alive_frame,
770
		       sizeof(struct iwl_alive_resp));
771
		pwork = &priv->alive_start;
Christoph Hellwig's avatar
Christoph Hellwig committed
772
		iwl3945_disable_events(priv);
773
774
775
776
777
778
779
780
	}

	/* 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
781
		IWL_WARN(priv, "uCode did not respond OK.\n");
782
783
}

784
static void iwl3945_rx_reply_add_sta(struct iwl_priv *priv,
785
				 struct iwl_rx_mem_buffer *rxb)
786
{
787
#ifdef CONFIG_IWLWIFI_DEBUG
Zhu Yi's avatar
Zhu Yi committed
788
	struct iwl_rx_packet *pkt = rxb_addr(rxb);
789
#endif
790

791
	IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status);
792
793
}

Christoph Hellwig's avatar
Christoph Hellwig committed
794
static void iwl3945_bg_beacon_update(struct work_struct *work)
795
{
796
797
	struct iwl_priv *priv =
		container_of(work, struct iwl_priv, beacon_update);
798
799
800
	struct sk_buff *beacon;

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

	if (!beacon) {
804
		IWL_ERR(priv, "update beacon failed\n");
805
806
807
808
809
810
811
812
813
814
815
		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);

Christoph Hellwig's avatar
Christoph Hellwig committed
816
	iwl3945_send_beacon_cmd(priv);
817
818
}

819
static void iwl3945_rx_beacon_notif(struct iwl_priv *priv,
820
				struct iwl_rx_mem_buffer *rxb)
821
{
Zhu Yi's avatar
Zhu Yi committed
822
	struct iwl_rx_packet *pkt = rxb_addr(rxb);
Christoph Hellwig's avatar
Christoph Hellwig committed
823
	struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status);
824
#ifdef CONFIG_IWLWIFI_DEBUG
825
826
	u8 rate = beacon->beacon_notify_hdr.rate;

827
	IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d "
828
829
830
831
832
833
834
835
		"tsf %d %d rate %d\n",
		le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK,
		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

836
837
	priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);

838
	if ((priv->iw_mode == NL80211_IFTYPE_AP) &&
839
840
841
842
843
844
	    (!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 */
845
static void iwl3945_rx_card_state_notif(struct iwl_priv *priv,
846
				    struct iwl_rx_mem_buffer *rxb)
847
{
Zhu Yi's avatar
Zhu Yi committed
848
	struct iwl_rx_packet *pkt = rxb_addr(rxb);
849
850
851
	u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
	unsigned long status = priv->status;

852
	IWL_WARN(priv, "Card state received: HW:%s SW:%s\n",
853
854
855
			  (flags & HW_CARD_DISABLED) ? "Kill" : "On",
			  (flags & SW_CARD_DISABLED) ? "Kill" : "On");

856
	iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
857
858
859
860
861
862
863
864
		    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);

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


865
	iwl_scan_cancel(priv);
866
867

	if ((test_bit(STATUS_RF_KILL_HW, &status) !=
868
869
870
	     test_bit(STATUS_RF_KILL_HW, &priv->status)))
		wiphy_rfkill_set_hw_state(priv->hw->wiphy,
				test_bit(STATUS_RF_KILL_HW, &priv->status));
871
872
873
874
875
	else
		wake_up_interruptible(&priv->wait_command_queue);
}

/**
Christoph Hellwig's avatar
Christoph Hellwig committed
876
 * iwl3945_setup_rx_handlers - Initialize Rx handler callbacks
877
878
879
880
881
882
883
 *
 * 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.
 */
884
static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
885
{
Christoph Hellwig's avatar
Christoph Hellwig committed
886
887
	priv->rx_handlers[REPLY_ALIVE] = iwl3945_rx_reply_alive;
	priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta;
888
	priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
889
	priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
890
891
	priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
			iwl_rx_spectrum_measure_notif;
892
	priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
893
	priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
894
	    iwl_rx_pm_debug_statistics_notif;
Christoph Hellwig's avatar
Christoph Hellwig committed
895
	priv->rx_handlers[BEACON_NOTIFICATION] = iwl3945_rx_beacon_notif;
896

897
898
899
900
	/*
	 * 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.
901
	 */
902
	priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_reply_statistics;
Christoph Hellwig's avatar
Christoph Hellwig committed
903
	priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics;
904

905
	iwl_setup_rx_scan_handlers(priv);
Christoph Hellwig's avatar
Christoph Hellwig committed
906
	priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
907

908
	/* Set up hardware specific Rx handlers */
Christoph Hellwig's avatar
Christoph Hellwig committed
909
	iwl3945_hw_rx_handler_setup(priv);
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
}

/************************** RX-FUNCTIONS ****************************/
/*
 * Rx theory of operation
 *
 * The host allocates 32 DMA target addresses and passes the host address
 * to the firmware at register IWL_RFDS_TABLE_LOWER + N * RFD_SIZE where N is
 * 0 to 31
 *
 * Rx Queue Indexes
 * The host/firmware share two index registers for managing the Rx buffers.
 *
 * The READ index maps to the first position that the firmware may be writing
 * to -- the driver can read up to (but not including) this position and get
 * good data.
 * The READ index is managed by the firmware once the card is enabled.
 *
 * The WRITE index maps to the last position the driver has read from -- the
 * position preceding WRITE is the last slot the firmware can place a packet.
 *
 * The queue is empty (no good data) if WRITE = READ - 1, and is full if
 * WRITE = READ.
 *
934
 * During initialization, the host sets up the READ queue position to the first
935
936
 * INDEX position, and WRITE to the last (READ - 1 wrapped)
 *
937
 * When the firmware places a packet in a buffer, it will advance the READ index
938
939
940
941
942
943
944
 * and fire the RX interrupt.  The driver can then query the READ index and
 * process as many packets as possible, moving the WRITE index forward as it
 * resets the Rx queue buffers with new memory.
 *
 * The management in the driver is as follows:
 * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free.  When
 *   iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
945
 *   to replenish the iwl->rxq->rx_free.
Christoph Hellwig's avatar
Christoph Hellwig committed
946
 * + In iwl3945_rx_replenish (scheduled) if 'processed' != 'read' then the
947
948
949
950
951
952
953
954
955
956
957
958
 *   iwl->rxq is replenished and the READ INDEX is updated (updating the
 *   'processed' and 'read' driver indexes as well)
 * + A received packet is processed and handed to the kernel network stack,
 *   detached from the iwl->rxq.  The driver 'processed' index is updated.
 * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free
 *   list. If there are no allocated buffers in iwl->rxq->rx_free, the READ
 *   INDEX is not incremented and iwl->status(RX_STALLED) is set.  If there
 *   were enough free buffers and RX_STALLED is set it is cleared.
 *
 *
 * Driver sequence:
 *
959
 * iwl3945_rx_replenish()     Replenishes rx_free list from rx_used, and calls
Christoph Hellwig's avatar
Christoph Hellwig committed
960
 *                            iwl3945_rx_queue_restock
961
 * iwl3945_rx_queue_restock() Moves available buffers from rx_free into Rx
962
963
 *                            queue, updates firmware pointers, and updates
 *                            the WRITE index.  If insufficient rx_free buffers
Christoph Hellwig's avatar
Christoph Hellwig committed
964
 *                            are available, schedules iwl3945_rx_replenish
965
966
 *
 * -- enable interrupts --
967
 * ISR - iwl3945_rx()         Detach iwl_rx_mem_buffers from pool up to the
968
969
 *                            READ INDEX, detaching the SKB from the pool.
 *                            Moves the packet buffer from queue to rx_used.
Christoph Hellwig's avatar
Christoph Hellwig committed
970
 *                            Calls iwl3945_rx_queue_restock to refill any empty
971
972
973
974
975
976
 *                            slots.
 * ...
 *
 */

/**
977
 * iwl3945_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
978
 */
979
static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl_priv *priv,
980
981
982
983
984
985
					  dma_addr_t dma_addr)
{
	return cpu_to_le32((u32)dma_addr);
}

/**
Christoph Hellwig's avatar
Christoph Hellwig committed
986
 * iwl3945_rx_queue_restock - refill RX queue from pre-allocated pool
987
 *
988
 * If there are slots in the RX queue that need to be restocked,
989
 * and we have free pre-allocated buffers, fill the ranks as much
990
 * as we can, pulling from rx_free.
991
992
993
994
995
 *
 * This moves the 'write' index forward to catch up with 'processed', and
 * also updates the memory address in the firmware to reference the new
 * target buffer.
 */
996
static void iwl3945_rx_queue_restock(struct iwl_priv *priv)
997
{
998
	struct iwl_rx_queue *rxq = &priv->rxq;
999
	struct list_head *element;
1000
	struct iwl_rx_mem_buffer *rxb;
For faster browsing, not all history is shown. View entire blame