mwl8k.c 153 KB
Newer Older
1
/*
2
3
 * drivers/net/wireless/mwl8k.c
 * Driver for Marvell TOPDOG 802.11 Wireless cards
4
 *
5
 * Copyright (C) 2008, 2009, 2010 Marvell Semiconductor Inc.
6
7
8
9
10
11
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

12
#include <linux/interrupt.h>
13
14
#include <linux/module.h>
#include <linux/kernel.h>
15
#include <linux/sched.h>
16
17
18
19
20
21
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/completion.h>
#include <linux/etherdevice.h>
22
#include <linux/slab.h>
23
24
25
26
27
28
29
#include <net/mac80211.h>
#include <linux/moduleparam.h>
#include <linux/firmware.h>
#include <linux/workqueue.h>

#define MWL8K_DESC	"Marvell TOPDOG(R) 802.11 Wireless Network Driver"
#define MWL8K_NAME	KBUILD_MODNAME
30
#define MWL8K_VERSION	"0.13"
31

32
/* Module parameters */
33
static bool ap_mode_default;
34
35
36
37
module_param(ap_mode_default, bool, 0);
MODULE_PARM_DESC(ap_mode_default,
		 "Set to 1 to make ap mode the default instead of sta mode");

38
39
/* Register definitions */
#define MWL8K_HIU_GEN_PTR			0x00000c10
40
41
#define  MWL8K_MODE_STA				 0x0000005a
#define  MWL8K_MODE_AP				 0x000000a5
42
#define MWL8K_HIU_INT_CODE			0x00000c14
43
44
45
#define  MWL8K_FWSTA_READY			 0xf0f1f2f4
#define  MWL8K_FWAP_READY			 0xf1f2f4a5
#define  MWL8K_INT_CODE_CMD_FINISHED		 0x00000005
46
47
48
49
50
51
52
53
#define MWL8K_HIU_SCRATCH			0x00000c40

/* Host->device communications */
#define MWL8K_HIU_H2A_INTERRUPT_EVENTS		0x00000c18
#define MWL8K_HIU_H2A_INTERRUPT_STATUS		0x00000c1c
#define MWL8K_HIU_H2A_INTERRUPT_MASK		0x00000c20
#define MWL8K_HIU_H2A_INTERRUPT_CLEAR_SEL	0x00000c24
#define MWL8K_HIU_H2A_INTERRUPT_STATUS_MASK	0x00000c28
54
55
56
57
#define  MWL8K_H2A_INT_DUMMY			 (1 << 20)
#define  MWL8K_H2A_INT_RESET			 (1 << 15)
#define  MWL8K_H2A_INT_DOORBELL			 (1 << 1)
#define  MWL8K_H2A_INT_PPA_READY		 (1 << 0)
58
59
60
61
62
63
64

/* Device->host communications */
#define MWL8K_HIU_A2H_INTERRUPT_EVENTS		0x00000c2c
#define MWL8K_HIU_A2H_INTERRUPT_STATUS		0x00000c30
#define MWL8K_HIU_A2H_INTERRUPT_MASK		0x00000c34
#define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL	0x00000c38
#define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK	0x00000c3c
65
#define  MWL8K_A2H_INT_DUMMY			 (1 << 20)
66
#define  MWL8K_A2H_INT_BA_WATCHDOG		 (1 << 14)
67
68
69
70
71
72
73
74
75
#define  MWL8K_A2H_INT_CHNL_SWITCHED		 (1 << 11)
#define  MWL8K_A2H_INT_QUEUE_EMPTY		 (1 << 10)
#define  MWL8K_A2H_INT_RADAR_DETECT		 (1 << 7)
#define  MWL8K_A2H_INT_RADIO_ON			 (1 << 6)
#define  MWL8K_A2H_INT_RADIO_OFF		 (1 << 5)
#define  MWL8K_A2H_INT_MAC_EVENT		 (1 << 3)
#define  MWL8K_A2H_INT_OPC_DONE			 (1 << 2)
#define  MWL8K_A2H_INT_RX_READY			 (1 << 1)
#define  MWL8K_A2H_INT_TX_DONE			 (1 << 0)
76

77
78
79
80
81
82
83
/* HW micro second timer register
 * located at offset 0xA600. This
 * will be used to timestamp tx
 * packets.
 */

#define	MWL8K_HW_TIMER_REGISTER			0x0000a600
84
85
86
#define BBU_RXRDY_CNT_REG			0x0000a860
#define NOK_CCA_CNT_REG				0x0000a6a0
#define BBU_AVG_NOISE_VAL			0x67
87

88
89
90
91
92
93
94
95
96
#define MWL8K_A2H_EVENTS	(MWL8K_A2H_INT_DUMMY | \
				 MWL8K_A2H_INT_CHNL_SWITCHED | \
				 MWL8K_A2H_INT_QUEUE_EMPTY | \
				 MWL8K_A2H_INT_RADAR_DETECT | \
				 MWL8K_A2H_INT_RADIO_ON | \
				 MWL8K_A2H_INT_RADIO_OFF | \
				 MWL8K_A2H_INT_MAC_EVENT | \
				 MWL8K_A2H_INT_OPC_DONE | \
				 MWL8K_A2H_INT_RX_READY | \
97
98
				 MWL8K_A2H_INT_TX_DONE | \
				 MWL8K_A2H_INT_BA_WATCHDOG)
99
100

#define MWL8K_RX_QUEUES		1
101
#define MWL8K_TX_WMM_QUEUES	4
102
#define MWL8K_MAX_AMPDU_QUEUES	8
103
104
#define MWL8K_MAX_TX_QUEUES	(MWL8K_TX_WMM_QUEUES + MWL8K_MAX_AMPDU_QUEUES)
#define mwl8k_tx_queues(priv)	(MWL8K_TX_WMM_QUEUES + (priv)->num_ampdu_queues)
105

106
107
108
109
110
111
112
113
114
115
116
117
/* txpriorities are mapped with hw queues.
 * Each hw queue has a txpriority.
 */
#define TOTAL_HW_TX_QUEUES	8

/* Each HW queue can have one AMPDU stream.
 * But, because one of the hw queue is reserved,
 * maximum AMPDU queues that can be created are
 * one short of total tx queues.
 */
#define MWL8K_NUM_AMPDU_STREAMS	(TOTAL_HW_TX_QUEUES - 1)

118
119
#define MWL8K_NUM_CHANS 18

120
121
122
123
struct rxd_ops {
	int rxd_size;
	void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr);
	void (*rxd_refill)(void *rxd, dma_addr_t addr, int len);
124
	int (*rxd_process)(void *rxd, struct ieee80211_rx_status *status,
125
			   __le16 *qos, s8 *noise);
126
127
};

128
struct mwl8k_device_info {
129
130
	char *part_name;
	char *helper_image;
131
132
	char *fw_image_sta;
	char *fw_image_ap;
133
	struct rxd_ops *ap_rxd_ops;
134
	u32 fw_api_ap;
135
136
};

137
struct mwl8k_rx_queue {
138
	int rxd_count;
139
140

	/* hw receives here */
141
	int head;
142
143

	/* refill descs here */
144
	int tail;
145

146
	void *rxd;
147
	dma_addr_t rxd_dma;
148
149
	struct {
		struct sk_buff *skb;
150
		DEFINE_DMA_UNMAP_ADDR(dma);
151
	} *buf;
152
153
154
155
};

struct mwl8k_tx_queue {
	/* hw transmits here */
156
	int head;
157
158

	/* sw appends here */
159
	int tail;
160

161
	unsigned int len;
162
163
164
	struct mwl8k_tx_desc *txd;
	dma_addr_t txd_dma;
	struct sk_buff **skb;
165
166
};

167
168
169
170
171
172
173
enum {
	AMPDU_NO_STREAM,
	AMPDU_STREAM_NEW,
	AMPDU_STREAM_IN_PROGRESS,
	AMPDU_STREAM_ACTIVE,
};

174
175
176
177
178
179
180
struct mwl8k_ampdu_stream {
	struct ieee80211_sta *sta;
	u8 tid;
	u8 state;
	u8 idx;
};

181
182
183
struct mwl8k_priv {
	struct ieee80211_hw *hw;
	struct pci_dev *pdev;
184
	int irq;
185

186
187
	struct mwl8k_device_info *device_info;

188
189
190
191
	void __iomem *sram;
	void __iomem *regs;

	/* firmware */
192
193
	const struct firmware *fw_helper;
	const struct firmware *fw_ucode;
194

195
196
197
	/* hardware/firmware parameters */
	bool ap_fw;
	struct rxd_ops *rxd_ops;
198
199
	struct ieee80211_supported_band band_24;
	struct ieee80211_channel channels_24[14];
200
	struct ieee80211_rate rates_24[13];
201
202
	struct ieee80211_supported_band band_50;
	struct ieee80211_channel channels_50[4];
203
	struct ieee80211_rate rates_50[8];
204
205
	u32 ap_macids_supported;
	u32 sta_macids_supported;
206

207
208
	/* Ampdu stream information */
	u8 num_ampdu_queues;
209
210
	spinlock_t stream_lock;
	struct mwl8k_ampdu_stream ampdu[MWL8K_MAX_AMPDU_QUEUES];
211
	struct work_struct watchdog_ba_handle;
212

213
214
215
	/* firmware access */
	struct mutex fw_mutex;
	struct task_struct *fw_mutex_owner;
216
	struct task_struct *hw_restart_owner;
217
218
219
	int fw_mutex_depth;
	struct completion *hostcmd_wait;

220
221
	atomic_t watchdog_event_pending;

222
223
224
	/* lock held over TX and TX reap */
	spinlock_t tx_lock;

225
226
227
	/* TX quiesce completion, protected by fw_mutex and tx_lock */
	struct completion *tx_wait;

228
	/* List of interfaces.  */
229
	u32 macids_used;
230
	struct list_head vif_list;
231
232
233
234
235
236
237

	/* power management status cookie from firmware */
	u32 *cookie;
	dma_addr_t cookie_dma;

	u16 num_mcaddrs;
	u8 hw_rev;
238
	u32 fw_rev;
239
	u32 caps;
240
241
242
243
244
245
246
247

	/*
	 * Running count of TX packets in flight, to avoid
	 * iterating over the transmit rings each time.
	 */
	int pending_tx_pkts;

	struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
248
249
	struct mwl8k_tx_queue txq[MWL8K_MAX_TX_QUEUES];
	u32 txq_offset[MWL8K_MAX_TX_QUEUES];
250

251
	bool radio_on;
252
	bool radio_short_preamble;
253
	bool sniffer_enabled;
254
	bool wmm_enabled;
255
256
257

	/* XXX need to convert this to handle multiple interfaces */
	bool capture_beacon;
258
	u8 capture_bssid[ETH_ALEN];
259
260
261
262
263
264
265
266
267
268
	struct sk_buff *beacon_skb;

	/*
	 * This FJ worker has to be global as it is scheduled from the
	 * RX handler.  At this point we don't know which interface it
	 * belongs to until the list of bssids waiting to complete join
	 * is checked.
	 */
	struct work_struct finalize_join_worker;

269
270
	/* Tasklet to perform TX reclaim.  */
	struct tasklet_struct poll_tx_task;
271
272
273

	/* Tasklet to perform RX.  */
	struct tasklet_struct poll_rx_task;
274
275
276

	/* Most recently reported noise in dBm */
	s8 noise;
277
278
279
280
281

	/*
	 * preserve the queue configurations so they can be restored if/when
	 * the firmware image is swapped.
	 */
282
	struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_WMM_QUEUES];
283

284
285
286
287
	/* To perform the task of reloading the firmware */
	struct work_struct fw_reload;
	bool hw_restart_in_progress;

288
289
290
291
	/* async firmware loading state */
	unsigned fw_state;
	char *fw_pref;
	char *fw_alt;
292
	bool is_8764;
293
	struct completion firmware_loading_complete;
294
295
296

	/* bitmap of running BSSes */
	u32 running_bsses;
297
298
299

	/* ACS related */
	bool sw_scan_start;
300
301
302
	struct ieee80211_channel *acs_chan;
	unsigned long channel_time;
	struct survey_info survey[MWL8K_NUM_CHANS];
303
304
};

305
306
307
#define MAX_WEP_KEY_LEN         13
#define NUM_WEP_KEYS            4

308
309
/* Per interface specific private data */
struct mwl8k_vif {
310
311
312
	struct list_head list;
	struct ieee80211_vif *vif;

313
314
315
	/* Firmware macid for this vif.  */
	int macid;

Lennert Buytenhek's avatar
Lennert Buytenhek committed
316
	/* Non AMPDU sequence number assigned by driver.  */
317
	u16 seqno;
318
319
320
321
322
323

	/* Saved WEP keys */
	struct {
		u8 enabled;
		u8 key[sizeof(struct ieee80211_key_conf) + MAX_WEP_KEY_LEN];
	} wep_key_conf[NUM_WEP_KEYS];
324
325
326
327
328
329

	/* BSSID */
	u8 bssid[ETH_ALEN];

	/* A flag to indicate is HW crypto is enabled for this bssid */
	bool is_hw_crypto_enabled;
330
};
331
#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
332
#define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8))
333

334
335
336
337
338
339
struct tx_traffic_info {
	u32 start_time;
	u32 pkts;
};

#define MWL8K_MAX_TID 8
340
341
342
struct mwl8k_sta {
	/* Index into station database. Returned by UPDATE_STADB.  */
	u8 peer_id;
343
	u8 is_ampdu_allowed;
344
	struct tx_traffic_info tx_stats[MWL8K_MAX_TID];
345
346
347
};
#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))

348
static const struct ieee80211_channel mwl8k_channels_24[] = {
349
350
351
352
353
354
355
356
357
358
359
360
361
362
	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2412, .hw_value = 1, },
	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2417, .hw_value = 2, },
	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2422, .hw_value = 3, },
	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2427, .hw_value = 4, },
	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2432, .hw_value = 5, },
	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2437, .hw_value = 6, },
	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2442, .hw_value = 7, },
	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2447, .hw_value = 8, },
	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2452, .hw_value = 9, },
	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2457, .hw_value = 10, },
	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2462, .hw_value = 11, },
	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2467, .hw_value = 12, },
	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2472, .hw_value = 13, },
	{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2484, .hw_value = 14, },
363
364
};

365
static const struct ieee80211_rate mwl8k_rates_24[] = {
366
367
368
	{ .bitrate = 10, .hw_value = 2, },
	{ .bitrate = 20, .hw_value = 4, },
	{ .bitrate = 55, .hw_value = 11, },
369
370
	{ .bitrate = 110, .hw_value = 22, },
	{ .bitrate = 220, .hw_value = 44, },
371
372
373
374
375
376
377
378
	{ .bitrate = 60, .hw_value = 12, },
	{ .bitrate = 90, .hw_value = 18, },
	{ .bitrate = 120, .hw_value = 24, },
	{ .bitrate = 180, .hw_value = 36, },
	{ .bitrate = 240, .hw_value = 48, },
	{ .bitrate = 360, .hw_value = 72, },
	{ .bitrate = 480, .hw_value = 96, },
	{ .bitrate = 540, .hw_value = 108, },
379
380
};

381
static const struct ieee80211_channel mwl8k_channels_50[] = {
382
383
384
385
	{ .band = IEEE80211_BAND_5GHZ, .center_freq = 5180, .hw_value = 36, },
	{ .band = IEEE80211_BAND_5GHZ, .center_freq = 5200, .hw_value = 40, },
	{ .band = IEEE80211_BAND_5GHZ, .center_freq = 5220, .hw_value = 44, },
	{ .band = IEEE80211_BAND_5GHZ, .center_freq = 5240, .hw_value = 48, },
386
387
388
389
390
391
392
393
394
395
396
397
398
};

static const struct ieee80211_rate mwl8k_rates_50[] = {
	{ .bitrate = 60, .hw_value = 12, },
	{ .bitrate = 90, .hw_value = 18, },
	{ .bitrate = 120, .hw_value = 24, },
	{ .bitrate = 180, .hw_value = 36, },
	{ .bitrate = 240, .hw_value = 48, },
	{ .bitrate = 360, .hw_value = 72, },
	{ .bitrate = 480, .hw_value = 96, },
	{ .bitrate = 540, .hw_value = 108, },
};

399
400
/* Set or get info from Firmware */
#define MWL8K_CMD_GET			0x0000
401
402
#define MWL8K_CMD_SET			0x0001
#define MWL8K_CMD_SET_LIST		0x0002
403
404
405
406

/* Firmware command codes */
#define MWL8K_CMD_CODE_DNLD		0x0001
#define MWL8K_CMD_GET_HW_SPEC		0x0003
407
#define MWL8K_CMD_SET_HW_SPEC		0x0004
408
409
#define MWL8K_CMD_MAC_MULTICAST_ADR	0x0010
#define MWL8K_CMD_GET_STAT		0x0014
410
#define MWL8K_CMD_BBP_REG_ACCESS	0x001a
411
412
#define MWL8K_CMD_RADIO_CONTROL		0x001c
#define MWL8K_CMD_RF_TX_POWER		0x001e
413
#define MWL8K_CMD_TX_POWER		0x001f
414
#define MWL8K_CMD_RF_ANTENNA		0x0020
415
#define MWL8K_CMD_SET_BEACON		0x0100		/* per-vif */
416
417
#define MWL8K_CMD_SET_PRE_SCAN		0x0107
#define MWL8K_CMD_SET_POST_SCAN		0x0108
418
419
420
421
422
#define MWL8K_CMD_SET_RF_CHANNEL	0x010a
#define MWL8K_CMD_SET_AID		0x010d
#define MWL8K_CMD_SET_RATE		0x0110
#define MWL8K_CMD_SET_FINALIZE_JOIN	0x0111
#define MWL8K_CMD_RTS_THRESHOLD		0x0113
423
#define MWL8K_CMD_SET_SLOT		0x0114
424
425
#define MWL8K_CMD_SET_EDCA_PARAMS	0x0115
#define MWL8K_CMD_SET_WMM_MODE		0x0123
426
#define MWL8K_CMD_MIMO_CONFIG		0x0125
427
#define MWL8K_CMD_USE_FIXED_RATE	0x0126
428
#define MWL8K_CMD_ENABLE_SNIFFER	0x0150
429
#define MWL8K_CMD_SET_MAC_ADDR		0x0202		/* per-vif */
430
#define MWL8K_CMD_SET_RATEADAPT_MODE	0x0203
431
#define MWL8K_CMD_GET_WATCHDOG_BITMAP	0x0205
432
#define MWL8K_CMD_DEL_MAC_ADDR		0x0206		/* per-vif */
433
434
#define MWL8K_CMD_BSS_START		0x1100		/* per-vif */
#define MWL8K_CMD_SET_NEW_STN		0x1111		/* per-vif */
435
#define MWL8K_CMD_UPDATE_ENCRYPTION	0x1122		/* per-vif */
436
#define MWL8K_CMD_UPDATE_STADB		0x1123
437
#define MWL8K_CMD_BASTREAM		0x1125
438

439
static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
440
{
441
442
	u16 command = le16_to_cpu(cmd);

443
444
445
446
#define MWL8K_CMDNAME(x)	case MWL8K_CMD_##x: do {\
					snprintf(buf, bufsize, "%s", #x);\
					return buf;\
					} while (0)
447
	switch (command & ~0x8000) {
448
449
		MWL8K_CMDNAME(CODE_DNLD);
		MWL8K_CMDNAME(GET_HW_SPEC);
450
		MWL8K_CMDNAME(SET_HW_SPEC);
451
452
453
454
		MWL8K_CMDNAME(MAC_MULTICAST_ADR);
		MWL8K_CMDNAME(GET_STAT);
		MWL8K_CMDNAME(RADIO_CONTROL);
		MWL8K_CMDNAME(RF_TX_POWER);
455
		MWL8K_CMDNAME(TX_POWER);
456
		MWL8K_CMDNAME(RF_ANTENNA);
457
		MWL8K_CMDNAME(SET_BEACON);
458
459
460
		MWL8K_CMDNAME(SET_PRE_SCAN);
		MWL8K_CMDNAME(SET_POST_SCAN);
		MWL8K_CMDNAME(SET_RF_CHANNEL);
461
462
463
464
		MWL8K_CMDNAME(SET_AID);
		MWL8K_CMDNAME(SET_RATE);
		MWL8K_CMDNAME(SET_FINALIZE_JOIN);
		MWL8K_CMDNAME(RTS_THRESHOLD);
465
		MWL8K_CMDNAME(SET_SLOT);
466
467
		MWL8K_CMDNAME(SET_EDCA_PARAMS);
		MWL8K_CMDNAME(SET_WMM_MODE);
468
		MWL8K_CMDNAME(MIMO_CONFIG);
469
		MWL8K_CMDNAME(USE_FIXED_RATE);
470
		MWL8K_CMDNAME(ENABLE_SNIFFER);
471
		MWL8K_CMDNAME(SET_MAC_ADDR);
472
		MWL8K_CMDNAME(SET_RATEADAPT_MODE);
473
		MWL8K_CMDNAME(BSS_START);
474
		MWL8K_CMDNAME(SET_NEW_STN);
475
		MWL8K_CMDNAME(UPDATE_ENCRYPTION);
476
		MWL8K_CMDNAME(UPDATE_STADB);
477
		MWL8K_CMDNAME(BASTREAM);
478
		MWL8K_CMDNAME(GET_WATCHDOG_BITMAP);
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
	default:
		snprintf(buf, bufsize, "0x%x", cmd);
	}
#undef MWL8K_CMDNAME

	return buf;
}

/* Hardware and firmware reset */
static void mwl8k_hw_reset(struct mwl8k_priv *priv)
{
	iowrite32(MWL8K_H2A_INT_RESET,
		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
	iowrite32(MWL8K_H2A_INT_RESET,
		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
	msleep(20);
}

/* Release fw image */
498
static void mwl8k_release_fw(const struct firmware **fw)
499
500
501
502
503
504
505
506
507
{
	if (*fw == NULL)
		return;
	release_firmware(*fw);
	*fw = NULL;
}

static void mwl8k_release_firmware(struct mwl8k_priv *priv)
{
508
509
	mwl8k_release_fw(&priv->fw_ucode);
	mwl8k_release_fw(&priv->fw_helper);
510
511
}

512
513
514
515
516
517
518
519
520
/* states for asynchronous f/w loading */
static void mwl8k_fw_state_machine(const struct firmware *fw, void *context);
enum {
	FW_STATE_INIT = 0,
	FW_STATE_LOADING_PREF,
	FW_STATE_LOADING_ALT,
	FW_STATE_ERROR,
};

521
522
/* Request fw image */
static int mwl8k_request_fw(struct mwl8k_priv *priv,
523
			    const char *fname, const struct firmware **fw,
524
			    bool nowait)
525
526
527
528
529
{
	/* release current image */
	if (*fw != NULL)
		mwl8k_release_fw(fw);

530
531
532
533
534
	if (nowait)
		return request_firmware_nowait(THIS_MODULE, 1, fname,
					       &priv->pdev->dev, GFP_KERNEL,
					       priv, mwl8k_fw_state_machine);
	else
535
		return request_firmware(fw, fname, &priv->pdev->dev);
536
537
}

538
539
static int mwl8k_request_firmware(struct mwl8k_priv *priv, char *fw_image,
				  bool nowait)
540
{
541
	struct mwl8k_device_info *di = priv->device_info;
542
543
	int rc;

544
	if (di->helper_image != NULL) {
545
546
547
548
549
550
551
552
553
554
555
		if (nowait)
			rc = mwl8k_request_fw(priv, di->helper_image,
					      &priv->fw_helper, true);
		else
			rc = mwl8k_request_fw(priv, di->helper_image,
					      &priv->fw_helper, false);
		if (rc)
			printk(KERN_ERR "%s: Error requesting helper fw %s\n",
			       pci_name(priv->pdev), di->helper_image);

		if (rc || nowait)
556
			return rc;
557
558
	}

559
560
561
562
563
564
565
566
567
568
569
570
	if (nowait) {
		/*
		 * if we get here, no helper image is needed.  Skip the
		 * FW_STATE_INIT state.
		 */
		priv->fw_state = FW_STATE_LOADING_PREF;
		rc = mwl8k_request_fw(priv, fw_image,
				      &priv->fw_ucode,
				      true);
	} else
		rc = mwl8k_request_fw(priv, fw_image,
				      &priv->fw_ucode, false);
571
	if (rc) {
572
		printk(KERN_ERR "%s: Error requesting firmware file %s\n",
573
		       pci_name(priv->pdev), fw_image);
574
		mwl8k_release_fw(&priv->fw_helper);
575
576
577
578
579
580
581
582
583
		return rc;
	}

	return 0;
}

struct mwl8k_cmd_pkt {
	__le16	code;
	__le16	length;
584
585
	__u8	seq_num;
	__u8	macid;
586
587
	__le16	result;
	char	payload[0];
588
} __packed;
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613

/*
 * Firmware loading.
 */
static int
mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
{
	void __iomem *regs = priv->regs;
	dma_addr_t dma_addr;
	int loops;

	dma_addr = pci_map_single(priv->pdev, data, length, PCI_DMA_TODEVICE);
	if (pci_dma_mapping_error(priv->pdev, dma_addr))
		return -ENOMEM;

	iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
	iowrite32(0, regs + MWL8K_HIU_INT_CODE);
	iowrite32(MWL8K_H2A_INT_DOORBELL,
		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
	iowrite32(MWL8K_H2A_INT_DUMMY,
		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);

	loops = 1000;
	do {
		u32 int_code;
614
615
616
617
618
619
620
621
622
623
624
		if (priv->is_8764) {
			int_code = ioread32(regs +
					    MWL8K_HIU_H2A_INTERRUPT_STATUS);
			if (int_code == 0)
				break;
		} else {
			int_code = ioread32(regs + MWL8K_HIU_INT_CODE);
			if (int_code == MWL8K_INT_CODE_CMD_FINISHED) {
				iowrite32(0, regs + MWL8K_HIU_INT_CODE);
				break;
			}
625
		}
626
		cond_resched();
627
628
629
630
631
		udelay(1);
	} while (--loops);

	pci_unmap_single(priv->pdev, dma_addr, length, PCI_DMA_TODEVICE);

632
	return loops ? 0 : -ETIMEDOUT;
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
}

static int mwl8k_load_fw_image(struct mwl8k_priv *priv,
				const u8 *data, size_t length)
{
	struct mwl8k_cmd_pkt *cmd;
	int done;
	int rc = 0;

	cmd = kmalloc(sizeof(*cmd) + 256, GFP_KERNEL);
	if (cmd == NULL)
		return -ENOMEM;

	cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD);
	cmd->seq_num = 0;
648
	cmd->macid = 0;
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
	cmd->result = 0;

	done = 0;
	while (length) {
		int block_size = length > 256 ? 256 : length;

		memcpy(cmd->payload, data + done, block_size);
		cmd->length = cpu_to_le16(block_size);

		rc = mwl8k_send_fw_load_cmd(priv, cmd,
						sizeof(*cmd) + block_size);
		if (rc)
			break;

		done += block_size;
		length -= block_size;
	}

	if (!rc) {
		cmd->length = 0;
		rc = mwl8k_send_fw_load_cmd(priv, cmd, sizeof(*cmd));
	}

	kfree(cmd);

	return rc;
}

static int mwl8k_feed_fw_image(struct mwl8k_priv *priv,
				const u8 *data, size_t length)
{
	unsigned char *buffer;
	int may_continue, rc = 0;
	u32 done, prev_block_size;

	buffer = kmalloc(1024, GFP_KERNEL);
	if (buffer == NULL)
		return -ENOMEM;

	done = 0;
	prev_block_size = 0;
	may_continue = 1000;
	while (may_continue > 0) {
		u32 block_size;

		block_size = ioread32(priv->regs + MWL8K_HIU_SCRATCH);
		if (block_size & 1) {
			block_size &= ~1;
			may_continue--;
		} else {
			done += prev_block_size;
			length -= prev_block_size;
		}

		if (block_size > 1024 || block_size > length) {
			rc = -EOVERFLOW;
			break;
		}

		if (length == 0) {
			rc = 0;
			break;
		}

		if (block_size == 0) {
			rc = -EPROTO;
			may_continue--;
			udelay(1);
			continue;
		}

		prev_block_size = block_size;
		memcpy(buffer, data + done, block_size);

		rc = mwl8k_send_fw_load_cmd(priv, buffer, block_size);
		if (rc)
			break;
	}

	if (!rc && length != 0)
		rc = -EREMOTEIO;

	kfree(buffer);

	return rc;
}

736
static int mwl8k_load_firmware(struct ieee80211_hw *hw)
737
{
738
	struct mwl8k_priv *priv = hw->priv;
739
	const struct firmware *fw = priv->fw_ucode;
740
741
742
	int rc;
	int loops;

743
	if (!memcmp(fw->data, "\x01\x00\x00\x00", 4) && !priv->is_8764) {
744
		const struct firmware *helper = priv->fw_helper;
745

746
747
748
749
750
		if (helper == NULL) {
			printk(KERN_ERR "%s: helper image needed but none "
			       "given\n", pci_name(priv->pdev));
			return -EINVAL;
		}
751

752
		rc = mwl8k_load_fw_image(priv, helper->data, helper->size);
753
754
		if (rc) {
			printk(KERN_ERR "%s: unable to load firmware "
755
			       "helper image\n", pci_name(priv->pdev));
756
757
			return rc;
		}
758
		msleep(20);
759

760
		rc = mwl8k_feed_fw_image(priv, fw->data, fw->size);
761
	} else {
762
763
764
765
		if (priv->is_8764)
			rc = mwl8k_feed_fw_image(priv, fw->data, fw->size);
		else
			rc = mwl8k_load_fw_image(priv, fw->data, fw->size);
766
767
768
	}

	if (rc) {
769
770
		printk(KERN_ERR "%s: unable to load firmware image\n",
		       pci_name(priv->pdev));
771
772
773
		return rc;
	}

774
	iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
775

776
	loops = 500000;
777
	do {
778
779
780
781
		u32 ready_code;

		ready_code = ioread32(priv->regs + MWL8K_HIU_INT_CODE);
		if (ready_code == MWL8K_FWAP_READY) {
782
			priv->ap_fw = true;
783
784
			break;
		} else if (ready_code == MWL8K_FWSTA_READY) {
785
			priv->ap_fw = false;
786
			break;
787
788
789
		}

		cond_resched();
790
791
792
793
794
795
796
797
798
799
800
		udelay(1);
	} while (--loops);

	return loops ? 0 : -ETIMEDOUT;
}


/* DMA header used by firmware and hardware.  */
struct mwl8k_dma_data {
	__le16 fwlen;
	struct ieee80211_hdr wh;
801
	char data[0];
802
} __packed;
803
804

/* Routines to add/remove DMA header from skb.  */
805
static inline void mwl8k_remove_dma_header(struct sk_buff *skb, __le16 qos)
806
{
807
808
809
810
811
812
813
814
815
816
817
818
819
	struct mwl8k_dma_data *tr;
	int hdrlen;

	tr = (struct mwl8k_dma_data *)skb->data;
	hdrlen = ieee80211_hdrlen(tr->wh.frame_control);

	if (hdrlen != sizeof(tr->wh)) {
		if (ieee80211_is_data_qos(tr->wh.frame_control)) {
			memmove(tr->data - hdrlen, &tr->wh, hdrlen - 2);
			*((__le16 *)(tr->data - 2)) = qos;
		} else {
			memmove(tr->data - hdrlen, &tr->wh, hdrlen);
		}
820
	}
821
822
823

	if (hdrlen != sizeof(*tr))
		skb_pull(skb, sizeof(*tr) - hdrlen);
824
825
}

826
827
#define REDUCED_TX_HEADROOM	8

828
static void
829
830
mwl8k_add_dma_header(struct mwl8k_priv *priv, struct sk_buff *skb,
						int head_pad, int tail_pad)
831
832
{
	struct ieee80211_hdr *wh;
833
	int hdrlen;
834
	int reqd_hdrlen;
835
836
	struct mwl8k_dma_data *tr;

837
838
839
840
841
842
	/*
	 * Add a firmware DMA header; the firmware requires that we
	 * present a 2-byte payload length followed by a 4-address
	 * header (without QoS field), followed (optionally) by any
	 * WEP/ExtIV header (but only filled in for CCMP).
	 */
843
	wh = (struct ieee80211_hdr *)skb->data;
844

845
	hdrlen = ieee80211_hdrlen(wh->frame_control);
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861

	/*
	 * Check if skb_resize is required because of
	 * tx_headroom adjustment.
	 */
	if (priv->ap_fw && (hdrlen < (sizeof(struct ieee80211_cts)
						+ REDUCED_TX_HEADROOM))) {
		if (pskb_expand_head(skb, REDUCED_TX_HEADROOM, 0, GFP_ATOMIC)) {

			wiphy_err(priv->hw->wiphy,
					"Failed to reallocate TX buffer\n");
			return;
		}
		skb->truesize += REDUCED_TX_HEADROOM;
	}

862
	reqd_hdrlen = sizeof(*tr) + head_pad;
863
864
865

	if (hdrlen != reqd_hdrlen)
		skb_push(skb, reqd_hdrlen - hdrlen);
866

867
	if (ieee80211_is_data_qos(wh->frame_control))
868
		hdrlen -= IEEE80211_QOS_CTL_LEN;
869
870
871
872

	tr = (struct mwl8k_dma_data *)skb->data;
	if (wh != &tr->wh)
		memmove(&tr->wh, wh, hdrlen);
873
874
	if (hdrlen != sizeof(tr->wh))
		memset(((void *)&tr->wh) + hdrlen, 0, sizeof(tr->wh) - hdrlen);
875
876
877
878
879
880

	/*
	 * Firmware length is the length of the fully formed "802.11
	 * payload".  That is, everything except for the 802.11 header.
	 * This includes all crypto material including the MIC.
	 */
881
	tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad);
882
883
}

884
885
static void mwl8k_encapsulate_tx_frame(struct mwl8k_priv *priv,
		struct sk_buff *skb)
886
887
888
889
890
{
	struct ieee80211_hdr *wh;
	struct ieee80211_tx_info *tx_info;
	struct ieee80211_key_conf *key_conf;
	int data_pad;
891
	int head_pad = 0;
892
893
894
895
896
897
898
899
900
901
902

	wh = (struct ieee80211_hdr *)skb->data;

	tx_info = IEEE80211_SKB_CB(skb);

	key_conf = NULL;
	if (ieee80211_is_data(wh->frame_control))
		key_conf = tx_info->control.hw_key;

	/*
	 * Make sure the packet header is in the DMA header format (4-address
903
	 * without QoS), and add head & tail padding when HW crypto is enabled.
904
905
906
907
908
909
910
911
	 *
	 * We have the following trailer padding requirements:
	 * - WEP: 4 trailer bytes (ICV)
	 * - TKIP: 12 trailer bytes (8 MIC + 4 ICV)
	 * - CCMP: 8 trailer bytes (MIC)
	 */
	data_pad = 0;
	if (key_conf != NULL) {
912
		head_pad = key_conf->iv_len;
913
914
915
916
917
918
919
920
921
922
923
924
925
		switch (key_conf->cipher) {
		case WLAN_CIPHER_SUITE_WEP40:
		case WLAN_CIPHER_SUITE_WEP104:
			data_pad = 4;
			break;
		case WLAN_CIPHER_SUITE_TKIP:
			data_pad = 12;
			break;
		case WLAN_CIPHER_SUITE_CCMP:
			data_pad = 8;
			break;
		}
	}
926
	mwl8k_add_dma_header(priv, skb, head_pad, data_pad);
927
}
928
929

/*
930
 * Packet reception for 88w8366/88w8764 AP firmware.
931
 */
932
struct mwl8k_rxd_ap {
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
	__le16 pkt_len;
	__u8 sq2;
	__u8 rate;
	__le32 pkt_phys_addr;
	__le32 next_rxd_phys_addr;
	__le16 qos_control;
	__le16 htsig2;
	__le32 hw_rssi_info;
	__le32 hw_noise_floor_info;
	__u8 noise_floor;
	__u8 pad0[3];
	__u8 rssi;
	__u8 rx_status;
	__u8 channel;
	__u8 rx_ctrl;
948
} __packed;
949

950
951
952
#define MWL8K_AP_RATE_INFO_MCS_FORMAT		0x80
#define MWL8K_AP_RATE_INFO_40MHZ		0x40
#define MWL8K_AP_RATE_INFO_RATEID(x)		((x) & 0x3f)
953

954
#define MWL8K_AP_RX_CTRL_OWNED_BY_HOST		0x80
955

956
957
958
959
960
961
/* 8366/8764 AP rx_status bits */
#define MWL8K_AP_RXSTAT_DECRYPT_ERR_MASK		0x80
#define MWL8K_AP_RXSTAT_GENERAL_DECRYPT_ERR		0xFF
#define MWL8K_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR		0x02
#define MWL8K_AP_RXSTAT_WEP_DECRYPT_ICV_ERR		0x04
#define MWL8K_AP_RXSTAT_TKIP_DECRYPT_ICV_ERR		0x08
962

963
static void mwl8k_rxd_ap_init(void *_rxd, dma_addr_t next_dma_addr)
964
{
965
	struct mwl8k_rxd_ap *rxd = _rxd;
966
967

	rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
968
	rxd->rx_ctrl = MWL8K_AP_RX_CTRL_OWNED_BY_HOST;
969
970
}

971
static void mwl8k_rxd_ap_refill(void *_rxd, dma_addr_t addr, int len)
972
{
973
	struct mwl8k_rxd_ap *rxd = _rxd;
974
975
976
977
978
979
980
981

	rxd->pkt_len = cpu_to_le16(len);
	rxd->pkt_phys_addr = cpu_to_le32(addr);
	wmb();
	rxd->rx_ctrl = 0;
}

static int
982
983
mwl8k_rxd_ap_process(void *_rxd, struct ieee80211_rx_status *status,
		     __le16 *qos, s8 *noise)
984
{
985
	struct mwl8k_rxd_ap *rxd = _rxd;
986

987
	if (!(rxd->rx_ctrl & MWL8K_AP_RX_CTRL_OWNED_BY_HOST))
988
989
990
991
992
993
		return -1;
	rmb();

	memset(status, 0, sizeof(*status));

	status->signal = -rxd->rssi;
994
	*noise = -rxd->noise_floor;
995

996
	if (rxd->rate & MWL8K_AP_RATE_INFO_MCS_FORMAT) {
997
		status->flag |= RX_FLAG_HT;
998
		if (rxd->rate & MWL8K_AP_RATE_INFO_40MHZ)
999
			status->flag |= RX_FLAG_40MHZ;
1000
		status->rate_idx = MWL8K_AP_RATE_INFO_RATEID(rxd->rate);
1001
1002
1003
	} else {
		int i;

1004
1005
		for (i = 0; i < ARRAY_SIZE(mwl8k_rates_24); i++) {
			if (mwl8k_rates_24[i].hw_value == rxd->rate) {
1006
1007
1008
1009
1010
1011
				status->rate_idx = i;
				break;
			}
		}
	}

1012
1013
1014
1015
1016
1017
1018
	if (rxd->channel > 14) {
		status->band = IEEE80211_BAND_5GHZ;
		if (!(status->flag & RX_FLAG_HT))
			status->rate_idx -= 5;
	} else {
		status->band = IEEE80211_BAND_2GHZ;
	}
1019
1020
	status->freq = ieee80211_channel_to_frequency(rxd->channel,
						      status->band);
1021

1022
1023
	*qos = rxd->qos_control;

1024
1025
1026
	if ((rxd->rx_status != MWL8K_AP_RXSTAT_GENERAL_DECRYPT_ERR) &&
	    (rxd->rx_status & MWL8K_AP_RXSTAT_DECRYPT_ERR_MASK) &&
	    (rxd->rx_status & MWL8K_AP_RXSTAT_TKIP_DECRYPT_MIC_ERR))
1027
1028
		status->flag |= RX_FLAG_MMIC_ERROR;

1029
1030
1031
	return le16_to_cpu(rxd->pkt_len);
}

1032
1033
1034
1035
1036
static struct rxd_ops rxd_ap_ops = {
	.rxd_size	= sizeof(struct mwl8k_rxd_ap),
	.rxd_init	= mwl8k_rxd_ap_init,
	.rxd_refill	= mwl8k_rxd_ap_refill,
	.rxd_process	= mwl8k_rxd_ap_process,
1037
1038
1039
};

/*
1040
 * Packet reception for STA firmware.
1041
 */
1042
struct mwl8k_rxd_sta {
1043
1044
1045
1046
	__le16 pkt_len;
	__u8 link_quality;
	__u8 noise_level;
	__le32 pkt_phys_addr;
1047
	__le32 next_rxd_phys_addr;
1048
1049
1050
1051
1052
1053
1054
1055
1056
	__le16 qos_control;
	__le16 rate_info;
	__le32 pad0[4];
	__u8 rssi;
	__u8 channel;
	__le16 pad1;
	__u8 rx_ctrl;
	__u8 rx_status;
	__u8 pad2[2];
1057
} __packed;
1058

1059
1060
1061
1062
1063
1064
#define MWL8K_STA_RATE_INFO_SHORTPRE		0x8000
#define MWL8K_STA_RATE_INFO_ANTSELECT(x)	(((x) >> 11) & 0x3)
#define MWL8K_STA_RATE_INFO_RATEID(x)		(((x) >> 3) & 0x3f)
#define MWL8K_STA_RATE_INFO_40MHZ		0x0004
#define MWL8K_STA_RATE_INFO_SHORTGI		0x0002
#define MWL8K_STA_RATE_INFO_MCS_FORMAT		0x0001
1065

1066
#define MWL8K_STA_RX_CTRL_OWNED_BY_HOST		0x02
1067
1068
1069
1070
1071
#define MWL8K_STA_RX_CTRL_DECRYPT_ERROR		0x04
/* ICV=0 or MIC=1 */
#define MWL8K_STA_RX_CTRL_DEC_ERR_TYPE		0x08
/* Key is uploaded only in failure case */
#define MWL8K_STA_RX_CTRL_KEY_INDEX			0x30
1072

1073
static void mwl8k_rxd_sta_init(void *_rxd, dma_addr_t next_dma_addr)
1074
{
1075
	struct mwl8k_rxd_sta *rxd = _rxd;
1076
1077

	rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
1078
	rxd->rx_ctrl = MWL8K_STA_RX_CTRL_OWNED_BY_HOST;
1079
1080
}

1081
static void mwl8k_rxd_sta_refill(void *_rxd, dma_addr_t addr, int len)
1082
{
1083
	struct mwl8k_rxd_sta *rxd = _rxd;
1084
1085
1086
1087
1088
1089
1090
1091

	rxd->pkt_len = cpu_to_le16(len);
	rxd->pkt_phys_addr = cpu_to_le32(addr);
	wmb();
	rxd->rx_ctrl = 0;
}

static int
1092
mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
1093
		       __le16 *qos, s8 *noise)
1094
{
1095
	struct mwl8k_rxd_sta *rxd = _rxd;
1096
1097
	u16 rate_info;

1098
	if (!(rxd->rx_ctrl & MWL8K_STA_RX_CTRL_OWNED_BY_HOST))
1099
1100
1101
1102
1103
1104
1105
1106
		return -1;
	rmb();

	rate_info = le16_to_cpu(rxd->rate_info);

	memset(status, 0, sizeof(*status));

	status->signal = -rxd->rssi;
1107
	*noise = -rxd->noise_level;
1108
1109
	status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info);
	status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info);
1110

1111
	if (rate_info & MWL8K_STA_RATE_INFO_SHORTPRE)
1112
		status->flag |= RX_FLAG_SHORTPRE;
1113
	if (rate_info & MWL8K_STA_RATE_INFO_40MHZ)
1114
		status->flag |= RX_FLAG_40MHZ;
1115
	if (rate_info & MWL8K_STA_RATE_INFO_SHORTGI)
1116
		status->flag |= RX_FLAG_SHORT_GI;
1117
	if (rate_info & MWL8K_STA_RATE_INFO_MCS_FORMAT)
1118
1119
		status->flag |= RX_FLAG_HT;

1120
1121
1122
1123
1124
1125
1126
	if (rxd->channel > 14) {
		status->band = IEEE80211_BAND_5GHZ;
		if (!(status->flag & RX_FLAG_HT))
			status->rate_idx -= 5;
	} else {
		status->band = IEEE80211_BAND_2GHZ;
	}
1127
1128
	status->freq = ieee80211_channel_to_frequency(rxd->channel,
						      status->band);
1129

1130
	*qos = rxd->qos_control;
1131
1132
1133
	if ((rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DECRYPT_ERROR) &&
	    (rxd->rx_ctrl & MWL8K_STA_RX_CTRL_DEC_ERR_TYPE))
		status->flag |= RX_FLAG_MMIC_ERROR;
1134

1135
1136
1137
	return le16_to_cpu(rxd->pkt_len);
}

1138
1139
1140
1141
1142
static struct rxd_ops rxd_sta_ops = {
	.rxd_size	= sizeof(struct mwl8k_rxd_sta),
	.rxd_init	= mwl8k_rxd_sta_init,
	.rxd_refill	= mwl8k_rxd_sta_refill,
	.rxd_process	= mwl8k_rxd_sta_process,
1143
1144
1145
};


1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
#define MWL8K_RX_DESCS		256
#define MWL8K_RX_MAXSZ		3800

static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
{
	struct mwl8k_priv *priv = hw->priv;
	struct mwl8k_rx_que