mwl8k.c revision e53d9b964e2568172149d41b3157af9cde9accaf
1/*
2 * drivers/net/wireless/mwl8k.c
3 * Driver for Marvell TOPDOG 802.11 Wireless cards
4 *
5 * Copyright (C) 2008, 2009, 2010 Marvell Semiconductor Inc.
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2.  This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/sched.h>
16#include <linux/spinlock.h>
17#include <linux/list.h>
18#include <linux/pci.h>
19#include <linux/delay.h>
20#include <linux/completion.h>
21#include <linux/etherdevice.h>
22#include <linux/slab.h>
23#include <net/mac80211.h>
24#include <linux/moduleparam.h>
25#include <linux/firmware.h>
26#include <linux/workqueue.h>
27
28#define MWL8K_DESC	"Marvell TOPDOG(R) 802.11 Wireless Network Driver"
29#define MWL8K_NAME	KBUILD_MODNAME
30#define MWL8K_VERSION	"0.12"
31
32/* Module parameters */
33static unsigned ap_mode_default;
34module_param(ap_mode_default, bool, 0);
35MODULE_PARM_DESC(ap_mode_default,
36		 "Set to 1 to make ap mode the default instead of sta mode");
37
38/* Register definitions */
39#define MWL8K_HIU_GEN_PTR			0x00000c10
40#define  MWL8K_MODE_STA				 0x0000005a
41#define  MWL8K_MODE_AP				 0x000000a5
42#define MWL8K_HIU_INT_CODE			0x00000c14
43#define  MWL8K_FWSTA_READY			 0xf0f1f2f4
44#define  MWL8K_FWAP_READY			 0xf1f2f4a5
45#define  MWL8K_INT_CODE_CMD_FINISHED		 0x00000005
46#define MWL8K_HIU_SCRATCH			0x00000c40
47
48/* Host->device communications */
49#define MWL8K_HIU_H2A_INTERRUPT_EVENTS		0x00000c18
50#define MWL8K_HIU_H2A_INTERRUPT_STATUS		0x00000c1c
51#define MWL8K_HIU_H2A_INTERRUPT_MASK		0x00000c20
52#define MWL8K_HIU_H2A_INTERRUPT_CLEAR_SEL	0x00000c24
53#define MWL8K_HIU_H2A_INTERRUPT_STATUS_MASK	0x00000c28
54#define  MWL8K_H2A_INT_DUMMY			 (1 << 20)
55#define  MWL8K_H2A_INT_RESET			 (1 << 15)
56#define  MWL8K_H2A_INT_DOORBELL			 (1 << 1)
57#define  MWL8K_H2A_INT_PPA_READY		 (1 << 0)
58
59/* Device->host communications */
60#define MWL8K_HIU_A2H_INTERRUPT_EVENTS		0x00000c2c
61#define MWL8K_HIU_A2H_INTERRUPT_STATUS		0x00000c30
62#define MWL8K_HIU_A2H_INTERRUPT_MASK		0x00000c34
63#define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL	0x00000c38
64#define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK	0x00000c3c
65#define  MWL8K_A2H_INT_DUMMY			 (1 << 20)
66#define  MWL8K_A2H_INT_CHNL_SWITCHED		 (1 << 11)
67#define  MWL8K_A2H_INT_QUEUE_EMPTY		 (1 << 10)
68#define  MWL8K_A2H_INT_RADAR_DETECT		 (1 << 7)
69#define  MWL8K_A2H_INT_RADIO_ON			 (1 << 6)
70#define  MWL8K_A2H_INT_RADIO_OFF		 (1 << 5)
71#define  MWL8K_A2H_INT_MAC_EVENT		 (1 << 3)
72#define  MWL8K_A2H_INT_OPC_DONE			 (1 << 2)
73#define  MWL8K_A2H_INT_RX_READY			 (1 << 1)
74#define  MWL8K_A2H_INT_TX_DONE			 (1 << 0)
75
76#define MWL8K_A2H_EVENTS	(MWL8K_A2H_INT_DUMMY | \
77				 MWL8K_A2H_INT_CHNL_SWITCHED | \
78				 MWL8K_A2H_INT_QUEUE_EMPTY | \
79				 MWL8K_A2H_INT_RADAR_DETECT | \
80				 MWL8K_A2H_INT_RADIO_ON | \
81				 MWL8K_A2H_INT_RADIO_OFF | \
82				 MWL8K_A2H_INT_MAC_EVENT | \
83				 MWL8K_A2H_INT_OPC_DONE | \
84				 MWL8K_A2H_INT_RX_READY | \
85				 MWL8K_A2H_INT_TX_DONE)
86
87#define MWL8K_RX_QUEUES		1
88#define MWL8K_TX_QUEUES		4
89
90struct rxd_ops {
91	int rxd_size;
92	void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr);
93	void (*rxd_refill)(void *rxd, dma_addr_t addr, int len);
94	int (*rxd_process)(void *rxd, struct ieee80211_rx_status *status,
95			   __le16 *qos, s8 *noise);
96};
97
98struct mwl8k_device_info {
99	char *part_name;
100	char *helper_image;
101	char *fw_image_sta;
102	char *fw_image_ap;
103	struct rxd_ops *ap_rxd_ops;
104	u32 fw_api_ap;
105};
106
107struct mwl8k_rx_queue {
108	int rxd_count;
109
110	/* hw receives here */
111	int head;
112
113	/* refill descs here */
114	int tail;
115
116	void *rxd;
117	dma_addr_t rxd_dma;
118	struct {
119		struct sk_buff *skb;
120		DEFINE_DMA_UNMAP_ADDR(dma);
121	} *buf;
122};
123
124struct mwl8k_tx_queue {
125	/* hw transmits here */
126	int head;
127
128	/* sw appends here */
129	int tail;
130
131	unsigned int len;
132	struct mwl8k_tx_desc *txd;
133	dma_addr_t txd_dma;
134	struct sk_buff **skb;
135};
136
137struct mwl8k_priv {
138	struct ieee80211_hw *hw;
139	struct pci_dev *pdev;
140
141	struct mwl8k_device_info *device_info;
142
143	void __iomem *sram;
144	void __iomem *regs;
145
146	/* firmware */
147	const struct firmware *fw_helper;
148	const struct firmware *fw_ucode;
149
150	/* hardware/firmware parameters */
151	bool ap_fw;
152	struct rxd_ops *rxd_ops;
153	struct ieee80211_supported_band band_24;
154	struct ieee80211_channel channels_24[14];
155	struct ieee80211_rate rates_24[14];
156	struct ieee80211_supported_band band_50;
157	struct ieee80211_channel channels_50[4];
158	struct ieee80211_rate rates_50[9];
159	u32 ap_macids_supported;
160	u32 sta_macids_supported;
161
162	/* firmware access */
163	struct mutex fw_mutex;
164	struct task_struct *fw_mutex_owner;
165	int fw_mutex_depth;
166	struct completion *hostcmd_wait;
167
168	/* lock held over TX and TX reap */
169	spinlock_t tx_lock;
170
171	/* TX quiesce completion, protected by fw_mutex and tx_lock */
172	struct completion *tx_wait;
173
174	/* List of interfaces.  */
175	u32 macids_used;
176	struct list_head vif_list;
177
178	/* power management status cookie from firmware */
179	u32 *cookie;
180	dma_addr_t cookie_dma;
181
182	u16 num_mcaddrs;
183	u8 hw_rev;
184	u32 fw_rev;
185
186	/*
187	 * Running count of TX packets in flight, to avoid
188	 * iterating over the transmit rings each time.
189	 */
190	int pending_tx_pkts;
191
192	struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
193	struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES];
194
195	bool radio_on;
196	bool radio_short_preamble;
197	bool sniffer_enabled;
198	bool wmm_enabled;
199
200	/* XXX need to convert this to handle multiple interfaces */
201	bool capture_beacon;
202	u8 capture_bssid[ETH_ALEN];
203	struct sk_buff *beacon_skb;
204
205	/*
206	 * This FJ worker has to be global as it is scheduled from the
207	 * RX handler.  At this point we don't know which interface it
208	 * belongs to until the list of bssids waiting to complete join
209	 * is checked.
210	 */
211	struct work_struct finalize_join_worker;
212
213	/* Tasklet to perform TX reclaim.  */
214	struct tasklet_struct poll_tx_task;
215
216	/* Tasklet to perform RX.  */
217	struct tasklet_struct poll_rx_task;
218
219	/* Most recently reported noise in dBm */
220	s8 noise;
221
222	/*
223	 * preserve the queue configurations so they can be restored if/when
224	 * the firmware image is swapped.
225	 */
226	struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_QUEUES];
227
228	/* async firmware loading state */
229	unsigned fw_state;
230	char *fw_pref;
231	char *fw_alt;
232	struct completion firmware_loading_complete;
233};
234
235#define MAX_WEP_KEY_LEN         13
236#define NUM_WEP_KEYS            4
237
238/* Per interface specific private data */
239struct mwl8k_vif {
240	struct list_head list;
241	struct ieee80211_vif *vif;
242
243	/* Firmware macid for this vif.  */
244	int macid;
245
246	/* Non AMPDU sequence number assigned by driver.  */
247	u16 seqno;
248
249	/* Saved WEP keys */
250	struct {
251		u8 enabled;
252		u8 key[sizeof(struct ieee80211_key_conf) + MAX_WEP_KEY_LEN];
253	} wep_key_conf[NUM_WEP_KEYS];
254};
255#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
256
257struct mwl8k_sta {
258	/* Index into station database. Returned by UPDATE_STADB.  */
259	u8 peer_id;
260};
261#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
262
263static const struct ieee80211_channel mwl8k_channels_24[] = {
264	{ .center_freq = 2412, .hw_value = 1, },
265	{ .center_freq = 2417, .hw_value = 2, },
266	{ .center_freq = 2422, .hw_value = 3, },
267	{ .center_freq = 2427, .hw_value = 4, },
268	{ .center_freq = 2432, .hw_value = 5, },
269	{ .center_freq = 2437, .hw_value = 6, },
270	{ .center_freq = 2442, .hw_value = 7, },
271	{ .center_freq = 2447, .hw_value = 8, },
272	{ .center_freq = 2452, .hw_value = 9, },
273	{ .center_freq = 2457, .hw_value = 10, },
274	{ .center_freq = 2462, .hw_value = 11, },
275	{ .center_freq = 2467, .hw_value = 12, },
276	{ .center_freq = 2472, .hw_value = 13, },
277	{ .center_freq = 2484, .hw_value = 14, },
278};
279
280static const struct ieee80211_rate mwl8k_rates_24[] = {
281	{ .bitrate = 10, .hw_value = 2, },
282	{ .bitrate = 20, .hw_value = 4, },
283	{ .bitrate = 55, .hw_value = 11, },
284	{ .bitrate = 110, .hw_value = 22, },
285	{ .bitrate = 220, .hw_value = 44, },
286	{ .bitrate = 60, .hw_value = 12, },
287	{ .bitrate = 90, .hw_value = 18, },
288	{ .bitrate = 120, .hw_value = 24, },
289	{ .bitrate = 180, .hw_value = 36, },
290	{ .bitrate = 240, .hw_value = 48, },
291	{ .bitrate = 360, .hw_value = 72, },
292	{ .bitrate = 480, .hw_value = 96, },
293	{ .bitrate = 540, .hw_value = 108, },
294	{ .bitrate = 720, .hw_value = 144, },
295};
296
297static const struct ieee80211_channel mwl8k_channels_50[] = {
298	{ .center_freq = 5180, .hw_value = 36, },
299	{ .center_freq = 5200, .hw_value = 40, },
300	{ .center_freq = 5220, .hw_value = 44, },
301	{ .center_freq = 5240, .hw_value = 48, },
302};
303
304static const struct ieee80211_rate mwl8k_rates_50[] = {
305	{ .bitrate = 60, .hw_value = 12, },
306	{ .bitrate = 90, .hw_value = 18, },
307	{ .bitrate = 120, .hw_value = 24, },
308	{ .bitrate = 180, .hw_value = 36, },
309	{ .bitrate = 240, .hw_value = 48, },
310	{ .bitrate = 360, .hw_value = 72, },
311	{ .bitrate = 480, .hw_value = 96, },
312	{ .bitrate = 540, .hw_value = 108, },
313	{ .bitrate = 720, .hw_value = 144, },
314};
315
316/* Set or get info from Firmware */
317#define MWL8K_CMD_GET			0x0000
318#define MWL8K_CMD_SET			0x0001
319#define MWL8K_CMD_SET_LIST		0x0002
320
321/* Firmware command codes */
322#define MWL8K_CMD_CODE_DNLD		0x0001
323#define MWL8K_CMD_GET_HW_SPEC		0x0003
324#define MWL8K_CMD_SET_HW_SPEC		0x0004
325#define MWL8K_CMD_MAC_MULTICAST_ADR	0x0010
326#define MWL8K_CMD_GET_STAT		0x0014
327#define MWL8K_CMD_RADIO_CONTROL		0x001c
328#define MWL8K_CMD_RF_TX_POWER		0x001e
329#define MWL8K_CMD_TX_POWER		0x001f
330#define MWL8K_CMD_RF_ANTENNA		0x0020
331#define MWL8K_CMD_SET_BEACON		0x0100		/* per-vif */
332#define MWL8K_CMD_SET_PRE_SCAN		0x0107
333#define MWL8K_CMD_SET_POST_SCAN		0x0108
334#define MWL8K_CMD_SET_RF_CHANNEL	0x010a
335#define MWL8K_CMD_SET_AID		0x010d
336#define MWL8K_CMD_SET_RATE		0x0110
337#define MWL8K_CMD_SET_FINALIZE_JOIN	0x0111
338#define MWL8K_CMD_RTS_THRESHOLD		0x0113
339#define MWL8K_CMD_SET_SLOT		0x0114
340#define MWL8K_CMD_SET_EDCA_PARAMS	0x0115
341#define MWL8K_CMD_SET_WMM_MODE		0x0123
342#define MWL8K_CMD_MIMO_CONFIG		0x0125
343#define MWL8K_CMD_USE_FIXED_RATE	0x0126
344#define MWL8K_CMD_ENABLE_SNIFFER	0x0150
345#define MWL8K_CMD_SET_MAC_ADDR		0x0202		/* per-vif */
346#define MWL8K_CMD_SET_RATEADAPT_MODE	0x0203
347#define MWL8K_CMD_BSS_START		0x1100		/* per-vif */
348#define MWL8K_CMD_SET_NEW_STN		0x1111		/* per-vif */
349#define MWL8K_CMD_UPDATE_STADB		0x1123
350
351static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
352{
353	u16 command = le16_to_cpu(cmd);
354
355#define MWL8K_CMDNAME(x)	case MWL8K_CMD_##x: do {\
356					snprintf(buf, bufsize, "%s", #x);\
357					return buf;\
358					} while (0)
359	switch (command & ~0x8000) {
360		MWL8K_CMDNAME(CODE_DNLD);
361		MWL8K_CMDNAME(GET_HW_SPEC);
362		MWL8K_CMDNAME(SET_HW_SPEC);
363		MWL8K_CMDNAME(MAC_MULTICAST_ADR);
364		MWL8K_CMDNAME(GET_STAT);
365		MWL8K_CMDNAME(RADIO_CONTROL);
366		MWL8K_CMDNAME(RF_TX_POWER);
367		MWL8K_CMDNAME(TX_POWER);
368		MWL8K_CMDNAME(RF_ANTENNA);
369		MWL8K_CMDNAME(SET_BEACON);
370		MWL8K_CMDNAME(SET_PRE_SCAN);
371		MWL8K_CMDNAME(SET_POST_SCAN);
372		MWL8K_CMDNAME(SET_RF_CHANNEL);
373		MWL8K_CMDNAME(SET_AID);
374		MWL8K_CMDNAME(SET_RATE);
375		MWL8K_CMDNAME(SET_FINALIZE_JOIN);
376		MWL8K_CMDNAME(RTS_THRESHOLD);
377		MWL8K_CMDNAME(SET_SLOT);
378		MWL8K_CMDNAME(SET_EDCA_PARAMS);
379		MWL8K_CMDNAME(SET_WMM_MODE);
380		MWL8K_CMDNAME(MIMO_CONFIG);
381		MWL8K_CMDNAME(USE_FIXED_RATE);
382		MWL8K_CMDNAME(ENABLE_SNIFFER);
383		MWL8K_CMDNAME(SET_MAC_ADDR);
384		MWL8K_CMDNAME(SET_RATEADAPT_MODE);
385		MWL8K_CMDNAME(BSS_START);
386		MWL8K_CMDNAME(SET_NEW_STN);
387		MWL8K_CMDNAME(UPDATE_STADB);
388	default:
389		snprintf(buf, bufsize, "0x%x", cmd);
390	}
391#undef MWL8K_CMDNAME
392
393	return buf;
394}
395
396/* Hardware and firmware reset */
397static void mwl8k_hw_reset(struct mwl8k_priv *priv)
398{
399	iowrite32(MWL8K_H2A_INT_RESET,
400		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
401	iowrite32(MWL8K_H2A_INT_RESET,
402		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
403	msleep(20);
404}
405
406/* Release fw image */
407static void mwl8k_release_fw(const struct firmware **fw)
408{
409	if (*fw == NULL)
410		return;
411	release_firmware(*fw);
412	*fw = NULL;
413}
414
415static void mwl8k_release_firmware(struct mwl8k_priv *priv)
416{
417	mwl8k_release_fw(&priv->fw_ucode);
418	mwl8k_release_fw(&priv->fw_helper);
419}
420
421/* states for asynchronous f/w loading */
422static void mwl8k_fw_state_machine(const struct firmware *fw, void *context);
423enum {
424	FW_STATE_INIT = 0,
425	FW_STATE_LOADING_PREF,
426	FW_STATE_LOADING_ALT,
427	FW_STATE_ERROR,
428};
429
430/* Request fw image */
431static int mwl8k_request_fw(struct mwl8k_priv *priv,
432			    const char *fname, const struct firmware **fw,
433			    bool nowait)
434{
435	/* release current image */
436	if (*fw != NULL)
437		mwl8k_release_fw(fw);
438
439	if (nowait)
440		return request_firmware_nowait(THIS_MODULE, 1, fname,
441					       &priv->pdev->dev, GFP_KERNEL,
442					       priv, mwl8k_fw_state_machine);
443	else
444		return request_firmware(fw, fname, &priv->pdev->dev);
445}
446
447static int mwl8k_request_firmware(struct mwl8k_priv *priv, char *fw_image,
448				  bool nowait)
449{
450	struct mwl8k_device_info *di = priv->device_info;
451	int rc;
452
453	if (di->helper_image != NULL) {
454		if (nowait)
455			rc = mwl8k_request_fw(priv, di->helper_image,
456					      &priv->fw_helper, true);
457		else
458			rc = mwl8k_request_fw(priv, di->helper_image,
459					      &priv->fw_helper, false);
460		if (rc)
461			printk(KERN_ERR "%s: Error requesting helper fw %s\n",
462			       pci_name(priv->pdev), di->helper_image);
463
464		if (rc || nowait)
465			return rc;
466	}
467
468	if (nowait) {
469		/*
470		 * if we get here, no helper image is needed.  Skip the
471		 * FW_STATE_INIT state.
472		 */
473		priv->fw_state = FW_STATE_LOADING_PREF;
474		rc = mwl8k_request_fw(priv, fw_image,
475				      &priv->fw_ucode,
476				      true);
477	} else
478		rc = mwl8k_request_fw(priv, fw_image,
479				      &priv->fw_ucode, false);
480	if (rc) {
481		printk(KERN_ERR "%s: Error requesting firmware file %s\n",
482		       pci_name(priv->pdev), fw_image);
483		mwl8k_release_fw(&priv->fw_helper);
484		return rc;
485	}
486
487	return 0;
488}
489
490struct mwl8k_cmd_pkt {
491	__le16	code;
492	__le16	length;
493	__u8	seq_num;
494	__u8	macid;
495	__le16	result;
496	char	payload[0];
497} __packed;
498
499/*
500 * Firmware loading.
501 */
502static int
503mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
504{
505	void __iomem *regs = priv->regs;
506	dma_addr_t dma_addr;
507	int loops;
508
509	dma_addr = pci_map_single(priv->pdev, data, length, PCI_DMA_TODEVICE);
510	if (pci_dma_mapping_error(priv->pdev, dma_addr))
511		return -ENOMEM;
512
513	iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
514	iowrite32(0, regs + MWL8K_HIU_INT_CODE);
515	iowrite32(MWL8K_H2A_INT_DOORBELL,
516		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
517	iowrite32(MWL8K_H2A_INT_DUMMY,
518		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
519
520	loops = 1000;
521	do {
522		u32 int_code;
523
524		int_code = ioread32(regs + MWL8K_HIU_INT_CODE);
525		if (int_code == MWL8K_INT_CODE_CMD_FINISHED) {
526			iowrite32(0, regs + MWL8K_HIU_INT_CODE);
527			break;
528		}
529
530		cond_resched();
531		udelay(1);
532	} while (--loops);
533
534	pci_unmap_single(priv->pdev, dma_addr, length, PCI_DMA_TODEVICE);
535
536	return loops ? 0 : -ETIMEDOUT;
537}
538
539static int mwl8k_load_fw_image(struct mwl8k_priv *priv,
540				const u8 *data, size_t length)
541{
542	struct mwl8k_cmd_pkt *cmd;
543	int done;
544	int rc = 0;
545
546	cmd = kmalloc(sizeof(*cmd) + 256, GFP_KERNEL);
547	if (cmd == NULL)
548		return -ENOMEM;
549
550	cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD);
551	cmd->seq_num = 0;
552	cmd->macid = 0;
553	cmd->result = 0;
554
555	done = 0;
556	while (length) {
557		int block_size = length > 256 ? 256 : length;
558
559		memcpy(cmd->payload, data + done, block_size);
560		cmd->length = cpu_to_le16(block_size);
561
562		rc = mwl8k_send_fw_load_cmd(priv, cmd,
563						sizeof(*cmd) + block_size);
564		if (rc)
565			break;
566
567		done += block_size;
568		length -= block_size;
569	}
570
571	if (!rc) {
572		cmd->length = 0;
573		rc = mwl8k_send_fw_load_cmd(priv, cmd, sizeof(*cmd));
574	}
575
576	kfree(cmd);
577
578	return rc;
579}
580
581static int mwl8k_feed_fw_image(struct mwl8k_priv *priv,
582				const u8 *data, size_t length)
583{
584	unsigned char *buffer;
585	int may_continue, rc = 0;
586	u32 done, prev_block_size;
587
588	buffer = kmalloc(1024, GFP_KERNEL);
589	if (buffer == NULL)
590		return -ENOMEM;
591
592	done = 0;
593	prev_block_size = 0;
594	may_continue = 1000;
595	while (may_continue > 0) {
596		u32 block_size;
597
598		block_size = ioread32(priv->regs + MWL8K_HIU_SCRATCH);
599		if (block_size & 1) {
600			block_size &= ~1;
601			may_continue--;
602		} else {
603			done += prev_block_size;
604			length -= prev_block_size;
605		}
606
607		if (block_size > 1024 || block_size > length) {
608			rc = -EOVERFLOW;
609			break;
610		}
611
612		if (length == 0) {
613			rc = 0;
614			break;
615		}
616
617		if (block_size == 0) {
618			rc = -EPROTO;
619			may_continue--;
620			udelay(1);
621			continue;
622		}
623
624		prev_block_size = block_size;
625		memcpy(buffer, data + done, block_size);
626
627		rc = mwl8k_send_fw_load_cmd(priv, buffer, block_size);
628		if (rc)
629			break;
630	}
631
632	if (!rc && length != 0)
633		rc = -EREMOTEIO;
634
635	kfree(buffer);
636
637	return rc;
638}
639
640static int mwl8k_load_firmware(struct ieee80211_hw *hw)
641{
642	struct mwl8k_priv *priv = hw->priv;
643	const struct firmware *fw = priv->fw_ucode;
644	int rc;
645	int loops;
646
647	if (!memcmp(fw->data, "\x01\x00\x00\x00", 4)) {
648		const struct firmware *helper = priv->fw_helper;
649
650		if (helper == NULL) {
651			printk(KERN_ERR "%s: helper image needed but none "
652			       "given\n", pci_name(priv->pdev));
653			return -EINVAL;
654		}
655
656		rc = mwl8k_load_fw_image(priv, helper->data, helper->size);
657		if (rc) {
658			printk(KERN_ERR "%s: unable to load firmware "
659			       "helper image\n", pci_name(priv->pdev));
660			return rc;
661		}
662		msleep(5);
663
664		rc = mwl8k_feed_fw_image(priv, fw->data, fw->size);
665	} else {
666		rc = mwl8k_load_fw_image(priv, fw->data, fw->size);
667	}
668
669	if (rc) {
670		printk(KERN_ERR "%s: unable to load firmware image\n",
671		       pci_name(priv->pdev));
672		return rc;
673	}
674
675	iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
676
677	loops = 500000;
678	do {
679		u32 ready_code;
680
681		ready_code = ioread32(priv->regs + MWL8K_HIU_INT_CODE);
682		if (ready_code == MWL8K_FWAP_READY) {
683			priv->ap_fw = 1;
684			break;
685		} else if (ready_code == MWL8K_FWSTA_READY) {
686			priv->ap_fw = 0;
687			break;
688		}
689
690		cond_resched();
691		udelay(1);
692	} while (--loops);
693
694	return loops ? 0 : -ETIMEDOUT;
695}
696
697
698/* DMA header used by firmware and hardware.  */
699struct mwl8k_dma_data {
700	__le16 fwlen;
701	struct ieee80211_hdr wh;
702	char data[0];
703} __packed;
704
705/* Routines to add/remove DMA header from skb.  */
706static inline void mwl8k_remove_dma_header(struct sk_buff *skb, __le16 qos)
707{
708	struct mwl8k_dma_data *tr;
709	int hdrlen;
710
711	tr = (struct mwl8k_dma_data *)skb->data;
712	hdrlen = ieee80211_hdrlen(tr->wh.frame_control);
713
714	if (hdrlen != sizeof(tr->wh)) {
715		if (ieee80211_is_data_qos(tr->wh.frame_control)) {
716			memmove(tr->data - hdrlen, &tr->wh, hdrlen - 2);
717			*((__le16 *)(tr->data - 2)) = qos;
718		} else {
719			memmove(tr->data - hdrlen, &tr->wh, hdrlen);
720		}
721	}
722
723	if (hdrlen != sizeof(*tr))
724		skb_pull(skb, sizeof(*tr) - hdrlen);
725}
726
727static void
728mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad)
729{
730	struct ieee80211_hdr *wh;
731	int hdrlen;
732	int reqd_hdrlen;
733	struct mwl8k_dma_data *tr;
734
735	/*
736	 * Add a firmware DMA header; the firmware requires that we
737	 * present a 2-byte payload length followed by a 4-address
738	 * header (without QoS field), followed (optionally) by any
739	 * WEP/ExtIV header (but only filled in for CCMP).
740	 */
741	wh = (struct ieee80211_hdr *)skb->data;
742
743	hdrlen = ieee80211_hdrlen(wh->frame_control);
744	reqd_hdrlen = sizeof(*tr);
745
746	if (hdrlen != reqd_hdrlen)
747		skb_push(skb, reqd_hdrlen - hdrlen);
748
749	if (ieee80211_is_data_qos(wh->frame_control))
750		hdrlen -= IEEE80211_QOS_CTL_LEN;
751
752	tr = (struct mwl8k_dma_data *)skb->data;
753	if (wh != &tr->wh)
754		memmove(&tr->wh, wh, hdrlen);
755	if (hdrlen != sizeof(tr->wh))
756		memset(((void *)&tr->wh) + hdrlen, 0, sizeof(tr->wh) - hdrlen);
757
758	/*
759	 * Firmware length is the length of the fully formed "802.11
760	 * payload".  That is, everything except for the 802.11 header.
761	 * This includes all crypto material including the MIC.
762	 */
763	tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad);
764}
765
766static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
767{
768	struct ieee80211_hdr *wh;
769	struct ieee80211_tx_info *tx_info;
770	struct ieee80211_key_conf *key_conf;
771	int data_pad;
772
773	wh = (struct ieee80211_hdr *)skb->data;
774
775	tx_info = IEEE80211_SKB_CB(skb);
776
777	key_conf = NULL;
778	if (ieee80211_is_data(wh->frame_control))
779		key_conf = tx_info->control.hw_key;
780
781	/*
782	 * Make sure the packet header is in the DMA header format (4-address
783	 * without QoS), the necessary crypto padding between the header and the
784	 * payload has already been provided by mac80211, but it doesn't add tail
785	 * padding when HW crypto is enabled.
786	 *
787	 * We have the following trailer padding requirements:
788	 * - WEP: 4 trailer bytes (ICV)
789	 * - TKIP: 12 trailer bytes (8 MIC + 4 ICV)
790	 * - CCMP: 8 trailer bytes (MIC)
791	 */
792	data_pad = 0;
793	if (key_conf != NULL) {
794		switch (key_conf->cipher) {
795		case WLAN_CIPHER_SUITE_WEP40:
796		case WLAN_CIPHER_SUITE_WEP104:
797			data_pad = 4;
798			break;
799		case WLAN_CIPHER_SUITE_TKIP:
800			data_pad = 12;
801			break;
802		case WLAN_CIPHER_SUITE_CCMP:
803			data_pad = 8;
804			break;
805		}
806	}
807	mwl8k_add_dma_header(skb, data_pad);
808}
809
810/*
811 * Packet reception for 88w8366 AP firmware.
812 */
813struct mwl8k_rxd_8366_ap {
814	__le16 pkt_len;
815	__u8 sq2;
816	__u8 rate;
817	__le32 pkt_phys_addr;
818	__le32 next_rxd_phys_addr;
819	__le16 qos_control;
820	__le16 htsig2;
821	__le32 hw_rssi_info;
822	__le32 hw_noise_floor_info;
823	__u8 noise_floor;
824	__u8 pad0[3];
825	__u8 rssi;
826	__u8 rx_status;
827	__u8 channel;
828	__u8 rx_ctrl;
829} __packed;
830
831#define MWL8K_8366_AP_RATE_INFO_MCS_FORMAT	0x80
832#define MWL8K_8366_AP_RATE_INFO_40MHZ		0x40
833#define MWL8K_8366_AP_RATE_INFO_RATEID(x)	((x) & 0x3f)
834
835#define MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST	0x80
836
837static void mwl8k_rxd_8366_ap_init(void *_rxd, dma_addr_t next_dma_addr)
838{
839	struct mwl8k_rxd_8366_ap *rxd = _rxd;
840
841	rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
842	rxd->rx_ctrl = MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST;
843}
844
845static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len)
846{
847	struct mwl8k_rxd_8366_ap *rxd = _rxd;
848
849	rxd->pkt_len = cpu_to_le16(len);
850	rxd->pkt_phys_addr = cpu_to_le32(addr);
851	wmb();
852	rxd->rx_ctrl = 0;
853}
854
855static int
856mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
857			  __le16 *qos, s8 *noise)
858{
859	struct mwl8k_rxd_8366_ap *rxd = _rxd;
860
861	if (!(rxd->rx_ctrl & MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST))
862		return -1;
863	rmb();
864
865	memset(status, 0, sizeof(*status));
866
867	status->signal = -rxd->rssi;
868	*noise = -rxd->noise_floor;
869
870	if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) {
871		status->flag |= RX_FLAG_HT;
872		if (rxd->rate & MWL8K_8366_AP_RATE_INFO_40MHZ)
873			status->flag |= RX_FLAG_40MHZ;
874		status->rate_idx = MWL8K_8366_AP_RATE_INFO_RATEID(rxd->rate);
875	} else {
876		int i;
877
878		for (i = 0; i < ARRAY_SIZE(mwl8k_rates_24); i++) {
879			if (mwl8k_rates_24[i].hw_value == rxd->rate) {
880				status->rate_idx = i;
881				break;
882			}
883		}
884	}
885
886	if (rxd->channel > 14) {
887		status->band = IEEE80211_BAND_5GHZ;
888		if (!(status->flag & RX_FLAG_HT))
889			status->rate_idx -= 5;
890	} else {
891		status->band = IEEE80211_BAND_2GHZ;
892	}
893	status->freq = ieee80211_channel_to_frequency(rxd->channel);
894
895	*qos = rxd->qos_control;
896
897	return le16_to_cpu(rxd->pkt_len);
898}
899
900static struct rxd_ops rxd_8366_ap_ops = {
901	.rxd_size	= sizeof(struct mwl8k_rxd_8366_ap),
902	.rxd_init	= mwl8k_rxd_8366_ap_init,
903	.rxd_refill	= mwl8k_rxd_8366_ap_refill,
904	.rxd_process	= mwl8k_rxd_8366_ap_process,
905};
906
907/*
908 * Packet reception for STA firmware.
909 */
910struct mwl8k_rxd_sta {
911	__le16 pkt_len;
912	__u8 link_quality;
913	__u8 noise_level;
914	__le32 pkt_phys_addr;
915	__le32 next_rxd_phys_addr;
916	__le16 qos_control;
917	__le16 rate_info;
918	__le32 pad0[4];
919	__u8 rssi;
920	__u8 channel;
921	__le16 pad1;
922	__u8 rx_ctrl;
923	__u8 rx_status;
924	__u8 pad2[2];
925} __packed;
926
927#define MWL8K_STA_RATE_INFO_SHORTPRE		0x8000
928#define MWL8K_STA_RATE_INFO_ANTSELECT(x)	(((x) >> 11) & 0x3)
929#define MWL8K_STA_RATE_INFO_RATEID(x)		(((x) >> 3) & 0x3f)
930#define MWL8K_STA_RATE_INFO_40MHZ		0x0004
931#define MWL8K_STA_RATE_INFO_SHORTGI		0x0002
932#define MWL8K_STA_RATE_INFO_MCS_FORMAT		0x0001
933
934#define MWL8K_STA_RX_CTRL_OWNED_BY_HOST		0x02
935
936static void mwl8k_rxd_sta_init(void *_rxd, dma_addr_t next_dma_addr)
937{
938	struct mwl8k_rxd_sta *rxd = _rxd;
939
940	rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr);
941	rxd->rx_ctrl = MWL8K_STA_RX_CTRL_OWNED_BY_HOST;
942}
943
944static void mwl8k_rxd_sta_refill(void *_rxd, dma_addr_t addr, int len)
945{
946	struct mwl8k_rxd_sta *rxd = _rxd;
947
948	rxd->pkt_len = cpu_to_le16(len);
949	rxd->pkt_phys_addr = cpu_to_le32(addr);
950	wmb();
951	rxd->rx_ctrl = 0;
952}
953
954static int
955mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
956		       __le16 *qos, s8 *noise)
957{
958	struct mwl8k_rxd_sta *rxd = _rxd;
959	u16 rate_info;
960
961	if (!(rxd->rx_ctrl & MWL8K_STA_RX_CTRL_OWNED_BY_HOST))
962		return -1;
963	rmb();
964
965	rate_info = le16_to_cpu(rxd->rate_info);
966
967	memset(status, 0, sizeof(*status));
968
969	status->signal = -rxd->rssi;
970	*noise = -rxd->noise_level;
971	status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info);
972	status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info);
973
974	if (rate_info & MWL8K_STA_RATE_INFO_SHORTPRE)
975		status->flag |= RX_FLAG_SHORTPRE;
976	if (rate_info & MWL8K_STA_RATE_INFO_40MHZ)
977		status->flag |= RX_FLAG_40MHZ;
978	if (rate_info & MWL8K_STA_RATE_INFO_SHORTGI)
979		status->flag |= RX_FLAG_SHORT_GI;
980	if (rate_info & MWL8K_STA_RATE_INFO_MCS_FORMAT)
981		status->flag |= RX_FLAG_HT;
982
983	if (rxd->channel > 14) {
984		status->band = IEEE80211_BAND_5GHZ;
985		if (!(status->flag & RX_FLAG_HT))
986			status->rate_idx -= 5;
987	} else {
988		status->band = IEEE80211_BAND_2GHZ;
989	}
990	status->freq = ieee80211_channel_to_frequency(rxd->channel);
991
992	*qos = rxd->qos_control;
993
994	return le16_to_cpu(rxd->pkt_len);
995}
996
997static struct rxd_ops rxd_sta_ops = {
998	.rxd_size	= sizeof(struct mwl8k_rxd_sta),
999	.rxd_init	= mwl8k_rxd_sta_init,
1000	.rxd_refill	= mwl8k_rxd_sta_refill,
1001	.rxd_process	= mwl8k_rxd_sta_process,
1002};
1003
1004
1005#define MWL8K_RX_DESCS		256
1006#define MWL8K_RX_MAXSZ		3800
1007
1008static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
1009{
1010	struct mwl8k_priv *priv = hw->priv;
1011	struct mwl8k_rx_queue *rxq = priv->rxq + index;
1012	int size;
1013	int i;
1014
1015	rxq->rxd_count = 0;
1016	rxq->head = 0;
1017	rxq->tail = 0;
1018
1019	size = MWL8K_RX_DESCS * priv->rxd_ops->rxd_size;
1020
1021	rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma);
1022	if (rxq->rxd == NULL) {
1023		wiphy_err(hw->wiphy, "failed to alloc RX descriptors\n");
1024		return -ENOMEM;
1025	}
1026	memset(rxq->rxd, 0, size);
1027
1028	rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL);
1029	if (rxq->buf == NULL) {
1030		wiphy_err(hw->wiphy, "failed to alloc RX skbuff list\n");
1031		pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma);
1032		return -ENOMEM;
1033	}
1034	memset(rxq->buf, 0, MWL8K_RX_DESCS * sizeof(*rxq->buf));
1035
1036	for (i = 0; i < MWL8K_RX_DESCS; i++) {
1037		int desc_size;
1038		void *rxd;
1039		int nexti;
1040		dma_addr_t next_dma_addr;
1041
1042		desc_size = priv->rxd_ops->rxd_size;
1043		rxd = rxq->rxd + (i * priv->rxd_ops->rxd_size);
1044
1045		nexti = i + 1;
1046		if (nexti == MWL8K_RX_DESCS)
1047			nexti = 0;
1048		next_dma_addr = rxq->rxd_dma + (nexti * desc_size);
1049
1050		priv->rxd_ops->rxd_init(rxd, next_dma_addr);
1051	}
1052
1053	return 0;
1054}
1055
1056static int rxq_refill(struct ieee80211_hw *hw, int index, int limit)
1057{
1058	struct mwl8k_priv *priv = hw->priv;
1059	struct mwl8k_rx_queue *rxq = priv->rxq + index;
1060	int refilled;
1061
1062	refilled = 0;
1063	while (rxq->rxd_count < MWL8K_RX_DESCS && limit--) {
1064		struct sk_buff *skb;
1065		dma_addr_t addr;
1066		int rx;
1067		void *rxd;
1068
1069		skb = dev_alloc_skb(MWL8K_RX_MAXSZ);
1070		if (skb == NULL)
1071			break;
1072
1073		addr = pci_map_single(priv->pdev, skb->data,
1074				      MWL8K_RX_MAXSZ, DMA_FROM_DEVICE);
1075
1076		rxq->rxd_count++;
1077		rx = rxq->tail++;
1078		if (rxq->tail == MWL8K_RX_DESCS)
1079			rxq->tail = 0;
1080		rxq->buf[rx].skb = skb;
1081		dma_unmap_addr_set(&rxq->buf[rx], dma, addr);
1082
1083		rxd = rxq->rxd + (rx * priv->rxd_ops->rxd_size);
1084		priv->rxd_ops->rxd_refill(rxd, addr, MWL8K_RX_MAXSZ);
1085
1086		refilled++;
1087	}
1088
1089	return refilled;
1090}
1091
1092/* Must be called only when the card's reception is completely halted */
1093static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index)
1094{
1095	struct mwl8k_priv *priv = hw->priv;
1096	struct mwl8k_rx_queue *rxq = priv->rxq + index;
1097	int i;
1098
1099	for (i = 0; i < MWL8K_RX_DESCS; i++) {
1100		if (rxq->buf[i].skb != NULL) {
1101			pci_unmap_single(priv->pdev,
1102					 dma_unmap_addr(&rxq->buf[i], dma),
1103					 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
1104			dma_unmap_addr_set(&rxq->buf[i], dma, 0);
1105
1106			kfree_skb(rxq->buf[i].skb);
1107			rxq->buf[i].skb = NULL;
1108		}
1109	}
1110
1111	kfree(rxq->buf);
1112	rxq->buf = NULL;
1113
1114	pci_free_consistent(priv->pdev,
1115			    MWL8K_RX_DESCS * priv->rxd_ops->rxd_size,
1116			    rxq->rxd, rxq->rxd_dma);
1117	rxq->rxd = NULL;
1118}
1119
1120
1121/*
1122 * Scan a list of BSSIDs to process for finalize join.
1123 * Allows for extension to process multiple BSSIDs.
1124 */
1125static inline int
1126mwl8k_capture_bssid(struct mwl8k_priv *priv, struct ieee80211_hdr *wh)
1127{
1128	return priv->capture_beacon &&
1129		ieee80211_is_beacon(wh->frame_control) &&
1130		!compare_ether_addr(wh->addr3, priv->capture_bssid);
1131}
1132
1133static inline void mwl8k_save_beacon(struct ieee80211_hw *hw,
1134				     struct sk_buff *skb)
1135{
1136	struct mwl8k_priv *priv = hw->priv;
1137
1138	priv->capture_beacon = false;
1139	memset(priv->capture_bssid, 0, ETH_ALEN);
1140
1141	/*
1142	 * Use GFP_ATOMIC as rxq_process is called from
1143	 * the primary interrupt handler, memory allocation call
1144	 * must not sleep.
1145	 */
1146	priv->beacon_skb = skb_copy(skb, GFP_ATOMIC);
1147	if (priv->beacon_skb != NULL)
1148		ieee80211_queue_work(hw, &priv->finalize_join_worker);
1149}
1150
1151static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
1152{
1153	struct mwl8k_priv *priv = hw->priv;
1154	struct mwl8k_rx_queue *rxq = priv->rxq + index;
1155	int processed;
1156
1157	processed = 0;
1158	while (rxq->rxd_count && limit--) {
1159		struct sk_buff *skb;
1160		void *rxd;
1161		int pkt_len;
1162		struct ieee80211_rx_status status;
1163		__le16 qos;
1164
1165		skb = rxq->buf[rxq->head].skb;
1166		if (skb == NULL)
1167			break;
1168
1169		rxd = rxq->rxd + (rxq->head * priv->rxd_ops->rxd_size);
1170
1171		pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos,
1172							&priv->noise);
1173		if (pkt_len < 0)
1174			break;
1175
1176		rxq->buf[rxq->head].skb = NULL;
1177
1178		pci_unmap_single(priv->pdev,
1179				 dma_unmap_addr(&rxq->buf[rxq->head], dma),
1180				 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
1181		dma_unmap_addr_set(&rxq->buf[rxq->head], dma, 0);
1182
1183		rxq->head++;
1184		if (rxq->head == MWL8K_RX_DESCS)
1185			rxq->head = 0;
1186
1187		rxq->rxd_count--;
1188
1189		skb_put(skb, pkt_len);
1190		mwl8k_remove_dma_header(skb, qos);
1191
1192		/*
1193		 * Check for a pending join operation.  Save a
1194		 * copy of the beacon and schedule a tasklet to
1195		 * send a FINALIZE_JOIN command to the firmware.
1196		 */
1197		if (mwl8k_capture_bssid(priv, (void *)skb->data))
1198			mwl8k_save_beacon(hw, skb);
1199
1200		memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
1201		ieee80211_rx_irqsafe(hw, skb);
1202
1203		processed++;
1204	}
1205
1206	return processed;
1207}
1208
1209
1210/*
1211 * Packet transmission.
1212 */
1213
1214#define MWL8K_TXD_STATUS_OK			0x00000001
1215#define MWL8K_TXD_STATUS_OK_RETRY		0x00000002
1216#define MWL8K_TXD_STATUS_OK_MORE_RETRY		0x00000004
1217#define MWL8K_TXD_STATUS_MULTICAST_TX		0x00000008
1218#define MWL8K_TXD_STATUS_FW_OWNED		0x80000000
1219
1220#define MWL8K_QOS_QLEN_UNSPEC			0xff00
1221#define MWL8K_QOS_ACK_POLICY_MASK		0x0060
1222#define MWL8K_QOS_ACK_POLICY_NORMAL		0x0000
1223#define MWL8K_QOS_ACK_POLICY_BLOCKACK		0x0060
1224#define MWL8K_QOS_EOSP				0x0010
1225
1226struct mwl8k_tx_desc {
1227	__le32 status;
1228	__u8 data_rate;
1229	__u8 tx_priority;
1230	__le16 qos_control;
1231	__le32 pkt_phys_addr;
1232	__le16 pkt_len;
1233	__u8 dest_MAC_addr[ETH_ALEN];
1234	__le32 next_txd_phys_addr;
1235	__le32 reserved;
1236	__le16 rate_info;
1237	__u8 peer_id;
1238	__u8 tx_frag_cnt;
1239} __packed;
1240
1241#define MWL8K_TX_DESCS		128
1242
1243static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
1244{
1245	struct mwl8k_priv *priv = hw->priv;
1246	struct mwl8k_tx_queue *txq = priv->txq + index;
1247	int size;
1248	int i;
1249
1250	txq->len = 0;
1251	txq->head = 0;
1252	txq->tail = 0;
1253
1254	size = MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc);
1255
1256	txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma);
1257	if (txq->txd == NULL) {
1258		wiphy_err(hw->wiphy, "failed to alloc TX descriptors\n");
1259		return -ENOMEM;
1260	}
1261	memset(txq->txd, 0, size);
1262
1263	txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL);
1264	if (txq->skb == NULL) {
1265		wiphy_err(hw->wiphy, "failed to alloc TX skbuff list\n");
1266		pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma);
1267		return -ENOMEM;
1268	}
1269	memset(txq->skb, 0, MWL8K_TX_DESCS * sizeof(*txq->skb));
1270
1271	for (i = 0; i < MWL8K_TX_DESCS; i++) {
1272		struct mwl8k_tx_desc *tx_desc;
1273		int nexti;
1274
1275		tx_desc = txq->txd + i;
1276		nexti = (i + 1) % MWL8K_TX_DESCS;
1277
1278		tx_desc->status = 0;
1279		tx_desc->next_txd_phys_addr =
1280			cpu_to_le32(txq->txd_dma + nexti * sizeof(*tx_desc));
1281	}
1282
1283	return 0;
1284}
1285
1286static inline void mwl8k_tx_start(struct mwl8k_priv *priv)
1287{
1288	iowrite32(MWL8K_H2A_INT_PPA_READY,
1289		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
1290	iowrite32(MWL8K_H2A_INT_DUMMY,
1291		priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
1292	ioread32(priv->regs + MWL8K_HIU_INT_CODE);
1293}
1294
1295static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw)
1296{
1297	struct mwl8k_priv *priv = hw->priv;
1298	int i;
1299
1300	for (i = 0; i < MWL8K_TX_QUEUES; i++) {
1301		struct mwl8k_tx_queue *txq = priv->txq + i;
1302		int fw_owned = 0;
1303		int drv_owned = 0;
1304		int unused = 0;
1305		int desc;
1306
1307		for (desc = 0; desc < MWL8K_TX_DESCS; desc++) {
1308			struct mwl8k_tx_desc *tx_desc = txq->txd + desc;
1309			u32 status;
1310
1311			status = le32_to_cpu(tx_desc->status);
1312			if (status & MWL8K_TXD_STATUS_FW_OWNED)
1313				fw_owned++;
1314			else
1315				drv_owned++;
1316
1317			if (tx_desc->pkt_len == 0)
1318				unused++;
1319		}
1320
1321		wiphy_err(hw->wiphy,
1322			  "txq[%d] len=%d head=%d tail=%d "
1323			  "fw_owned=%d drv_owned=%d unused=%d\n",
1324			  i,
1325			  txq->len, txq->head, txq->tail,
1326			  fw_owned, drv_owned, unused);
1327	}
1328}
1329
1330/*
1331 * Must be called with priv->fw_mutex held and tx queues stopped.
1332 */
1333#define MWL8K_TX_WAIT_TIMEOUT_MS	5000
1334
1335static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1336{
1337	struct mwl8k_priv *priv = hw->priv;
1338	DECLARE_COMPLETION_ONSTACK(tx_wait);
1339	int retry;
1340	int rc;
1341
1342	might_sleep();
1343
1344	/*
1345	 * The TX queues are stopped at this point, so this test
1346	 * doesn't need to take ->tx_lock.
1347	 */
1348	if (!priv->pending_tx_pkts)
1349		return 0;
1350
1351	retry = 0;
1352	rc = 0;
1353
1354	spin_lock_bh(&priv->tx_lock);
1355	priv->tx_wait = &tx_wait;
1356	while (!rc) {
1357		int oldcount;
1358		unsigned long timeout;
1359
1360		oldcount = priv->pending_tx_pkts;
1361
1362		spin_unlock_bh(&priv->tx_lock);
1363		timeout = wait_for_completion_timeout(&tx_wait,
1364			    msecs_to_jiffies(MWL8K_TX_WAIT_TIMEOUT_MS));
1365		spin_lock_bh(&priv->tx_lock);
1366
1367		if (timeout) {
1368			WARN_ON(priv->pending_tx_pkts);
1369			if (retry) {
1370				wiphy_notice(hw->wiphy, "tx rings drained\n");
1371			}
1372			break;
1373		}
1374
1375		if (priv->pending_tx_pkts < oldcount) {
1376			wiphy_notice(hw->wiphy,
1377				     "waiting for tx rings to drain (%d -> %d pkts)\n",
1378				     oldcount, priv->pending_tx_pkts);
1379			retry = 1;
1380			continue;
1381		}
1382
1383		priv->tx_wait = NULL;
1384
1385		wiphy_err(hw->wiphy, "tx rings stuck for %d ms\n",
1386			  MWL8K_TX_WAIT_TIMEOUT_MS);
1387		mwl8k_dump_tx_rings(hw);
1388
1389		rc = -ETIMEDOUT;
1390	}
1391	spin_unlock_bh(&priv->tx_lock);
1392
1393	return rc;
1394}
1395
1396#define MWL8K_TXD_SUCCESS(status)				\
1397	((status) & (MWL8K_TXD_STATUS_OK |			\
1398		     MWL8K_TXD_STATUS_OK_RETRY |		\
1399		     MWL8K_TXD_STATUS_OK_MORE_RETRY))
1400
1401static int
1402mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1403{
1404	struct mwl8k_priv *priv = hw->priv;
1405	struct mwl8k_tx_queue *txq = priv->txq + index;
1406	int processed;
1407
1408	processed = 0;
1409	while (txq->len > 0 && limit--) {
1410		int tx;
1411		struct mwl8k_tx_desc *tx_desc;
1412		unsigned long addr;
1413		int size;
1414		struct sk_buff *skb;
1415		struct ieee80211_tx_info *info;
1416		u32 status;
1417
1418		tx = txq->head;
1419		tx_desc = txq->txd + tx;
1420
1421		status = le32_to_cpu(tx_desc->status);
1422
1423		if (status & MWL8K_TXD_STATUS_FW_OWNED) {
1424			if (!force)
1425				break;
1426			tx_desc->status &=
1427				~cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED);
1428		}
1429
1430		txq->head = (tx + 1) % MWL8K_TX_DESCS;
1431		BUG_ON(txq->len == 0);
1432		txq->len--;
1433		priv->pending_tx_pkts--;
1434
1435		addr = le32_to_cpu(tx_desc->pkt_phys_addr);
1436		size = le16_to_cpu(tx_desc->pkt_len);
1437		skb = txq->skb[tx];
1438		txq->skb[tx] = NULL;
1439
1440		BUG_ON(skb == NULL);
1441		pci_unmap_single(priv->pdev, addr, size, PCI_DMA_TODEVICE);
1442
1443		mwl8k_remove_dma_header(skb, tx_desc->qos_control);
1444
1445		/* Mark descriptor as unused */
1446		tx_desc->pkt_phys_addr = 0;
1447		tx_desc->pkt_len = 0;
1448
1449		info = IEEE80211_SKB_CB(skb);
1450		ieee80211_tx_info_clear_status(info);
1451		if (MWL8K_TXD_SUCCESS(status))
1452			info->flags |= IEEE80211_TX_STAT_ACK;
1453
1454		ieee80211_tx_status_irqsafe(hw, skb);
1455
1456		processed++;
1457	}
1458
1459	if (processed && priv->radio_on && !mutex_is_locked(&priv->fw_mutex))
1460		ieee80211_wake_queue(hw, index);
1461
1462	return processed;
1463}
1464
1465/* must be called only when the card's transmit is completely halted */
1466static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
1467{
1468	struct mwl8k_priv *priv = hw->priv;
1469	struct mwl8k_tx_queue *txq = priv->txq + index;
1470
1471	mwl8k_txq_reclaim(hw, index, INT_MAX, 1);
1472
1473	kfree(txq->skb);
1474	txq->skb = NULL;
1475
1476	pci_free_consistent(priv->pdev,
1477			    MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc),
1478			    txq->txd, txq->txd_dma);
1479	txq->txd = NULL;
1480}
1481
1482static int
1483mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1484{
1485	struct mwl8k_priv *priv = hw->priv;
1486	struct ieee80211_tx_info *tx_info;
1487	struct mwl8k_vif *mwl8k_vif;
1488	struct ieee80211_hdr *wh;
1489	struct mwl8k_tx_queue *txq;
1490	struct mwl8k_tx_desc *tx;
1491	dma_addr_t dma;
1492	u32 txstatus;
1493	u8 txdatarate;
1494	u16 qos;
1495
1496	wh = (struct ieee80211_hdr *)skb->data;
1497	if (ieee80211_is_data_qos(wh->frame_control))
1498		qos = le16_to_cpu(*((__le16 *)ieee80211_get_qos_ctl(wh)));
1499	else
1500		qos = 0;
1501
1502	mwl8k_encapsulate_tx_frame(skb);
1503	wh = &((struct mwl8k_dma_data *)skb->data)->wh;
1504
1505	tx_info = IEEE80211_SKB_CB(skb);
1506	mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
1507
1508	if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1509		wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
1510		wh->seq_ctrl |= cpu_to_le16(mwl8k_vif->seqno);
1511		mwl8k_vif->seqno += 0x10;
1512	}
1513
1514	/* Setup firmware control bit fields for each frame type.  */
1515	txstatus = 0;
1516	txdatarate = 0;
1517	if (ieee80211_is_mgmt(wh->frame_control) ||
1518	    ieee80211_is_ctl(wh->frame_control)) {
1519		txdatarate = 0;
1520		qos |= MWL8K_QOS_QLEN_UNSPEC | MWL8K_QOS_EOSP;
1521	} else if (ieee80211_is_data(wh->frame_control)) {
1522		txdatarate = 1;
1523		if (is_multicast_ether_addr(wh->addr1))
1524			txstatus |= MWL8K_TXD_STATUS_MULTICAST_TX;
1525
1526		qos &= ~MWL8K_QOS_ACK_POLICY_MASK;
1527		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
1528			qos |= MWL8K_QOS_ACK_POLICY_BLOCKACK;
1529		else
1530			qos |= MWL8K_QOS_ACK_POLICY_NORMAL;
1531	}
1532
1533	dma = pci_map_single(priv->pdev, skb->data,
1534				skb->len, PCI_DMA_TODEVICE);
1535
1536	if (pci_dma_mapping_error(priv->pdev, dma)) {
1537		wiphy_debug(hw->wiphy,
1538			    "failed to dma map skb, dropping TX frame.\n");
1539		dev_kfree_skb(skb);
1540		return NETDEV_TX_OK;
1541	}
1542
1543	spin_lock_bh(&priv->tx_lock);
1544
1545	txq = priv->txq + index;
1546
1547	BUG_ON(txq->skb[txq->tail] != NULL);
1548	txq->skb[txq->tail] = skb;
1549
1550	tx = txq->txd + txq->tail;
1551	tx->data_rate = txdatarate;
1552	tx->tx_priority = index;
1553	tx->qos_control = cpu_to_le16(qos);
1554	tx->pkt_phys_addr = cpu_to_le32(dma);
1555	tx->pkt_len = cpu_to_le16(skb->len);
1556	tx->rate_info = 0;
1557	if (!priv->ap_fw && tx_info->control.sta != NULL)
1558		tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id;
1559	else
1560		tx->peer_id = 0;
1561	wmb();
1562	tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
1563
1564	txq->len++;
1565	priv->pending_tx_pkts++;
1566
1567	txq->tail++;
1568	if (txq->tail == MWL8K_TX_DESCS)
1569		txq->tail = 0;
1570
1571	if (txq->head == txq->tail)
1572		ieee80211_stop_queue(hw, index);
1573
1574	mwl8k_tx_start(priv);
1575
1576	spin_unlock_bh(&priv->tx_lock);
1577
1578	return NETDEV_TX_OK;
1579}
1580
1581
1582/*
1583 * Firmware access.
1584 *
1585 * We have the following requirements for issuing firmware commands:
1586 * - Some commands require that the packet transmit path is idle when
1587 *   the command is issued.  (For simplicity, we'll just quiesce the
1588 *   transmit path for every command.)
1589 * - There are certain sequences of commands that need to be issued to
1590 *   the hardware sequentially, with no other intervening commands.
1591 *
1592 * This leads to an implementation of a "firmware lock" as a mutex that
1593 * can be taken recursively, and which is taken by both the low-level
1594 * command submission function (mwl8k_post_cmd) as well as any users of
1595 * that function that require issuing of an atomic sequence of commands,
1596 * and quiesces the transmit path whenever it's taken.
1597 */
1598static int mwl8k_fw_lock(struct ieee80211_hw *hw)
1599{
1600	struct mwl8k_priv *priv = hw->priv;
1601
1602	if (priv->fw_mutex_owner != current) {
1603		int rc;
1604
1605		mutex_lock(&priv->fw_mutex);
1606		ieee80211_stop_queues(hw);
1607
1608		rc = mwl8k_tx_wait_empty(hw);
1609		if (rc) {
1610			ieee80211_wake_queues(hw);
1611			mutex_unlock(&priv->fw_mutex);
1612
1613			return rc;
1614		}
1615
1616		priv->fw_mutex_owner = current;
1617	}
1618
1619	priv->fw_mutex_depth++;
1620
1621	return 0;
1622}
1623
1624static void mwl8k_fw_unlock(struct ieee80211_hw *hw)
1625{
1626	struct mwl8k_priv *priv = hw->priv;
1627
1628	if (!--priv->fw_mutex_depth) {
1629		ieee80211_wake_queues(hw);
1630		priv->fw_mutex_owner = NULL;
1631		mutex_unlock(&priv->fw_mutex);
1632	}
1633}
1634
1635
1636/*
1637 * Command processing.
1638 */
1639
1640/* Timeout firmware commands after 10s */
1641#define MWL8K_CMD_TIMEOUT_MS	10000
1642
1643static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
1644{
1645	DECLARE_COMPLETION_ONSTACK(cmd_wait);
1646	struct mwl8k_priv *priv = hw->priv;
1647	void __iomem *regs = priv->regs;
1648	dma_addr_t dma_addr;
1649	unsigned int dma_size;
1650	int rc;
1651	unsigned long timeout = 0;
1652	u8 buf[32];
1653
1654	cmd->result = (__force __le16) 0xffff;
1655	dma_size = le16_to_cpu(cmd->length);
1656	dma_addr = pci_map_single(priv->pdev, cmd, dma_size,
1657				  PCI_DMA_BIDIRECTIONAL);
1658	if (pci_dma_mapping_error(priv->pdev, dma_addr))
1659		return -ENOMEM;
1660
1661	rc = mwl8k_fw_lock(hw);
1662	if (rc) {
1663		pci_unmap_single(priv->pdev, dma_addr, dma_size,
1664						PCI_DMA_BIDIRECTIONAL);
1665		return rc;
1666	}
1667
1668	priv->hostcmd_wait = &cmd_wait;
1669	iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
1670	iowrite32(MWL8K_H2A_INT_DOORBELL,
1671		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
1672	iowrite32(MWL8K_H2A_INT_DUMMY,
1673		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
1674
1675	timeout = wait_for_completion_timeout(&cmd_wait,
1676				msecs_to_jiffies(MWL8K_CMD_TIMEOUT_MS));
1677
1678	priv->hostcmd_wait = NULL;
1679
1680	mwl8k_fw_unlock(hw);
1681
1682	pci_unmap_single(priv->pdev, dma_addr, dma_size,
1683					PCI_DMA_BIDIRECTIONAL);
1684
1685	if (!timeout) {
1686		wiphy_err(hw->wiphy, "Command %s timeout after %u ms\n",
1687			  mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
1688			  MWL8K_CMD_TIMEOUT_MS);
1689		rc = -ETIMEDOUT;
1690	} else {
1691		int ms;
1692
1693		ms = MWL8K_CMD_TIMEOUT_MS - jiffies_to_msecs(timeout);
1694
1695		rc = cmd->result ? -EINVAL : 0;
1696		if (rc)
1697			wiphy_err(hw->wiphy, "Command %s error 0x%x\n",
1698				  mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
1699				  le16_to_cpu(cmd->result));
1700		else if (ms > 2000)
1701			wiphy_notice(hw->wiphy, "Command %s took %d ms\n",
1702				     mwl8k_cmd_name(cmd->code,
1703						    buf, sizeof(buf)),
1704				     ms);
1705	}
1706
1707	return rc;
1708}
1709
1710static int mwl8k_post_pervif_cmd(struct ieee80211_hw *hw,
1711				 struct ieee80211_vif *vif,
1712				 struct mwl8k_cmd_pkt *cmd)
1713{
1714	if (vif != NULL)
1715		cmd->macid = MWL8K_VIF(vif)->macid;
1716	return mwl8k_post_cmd(hw, cmd);
1717}
1718
1719/*
1720 * Setup code shared between STA and AP firmware images.
1721 */
1722static void mwl8k_setup_2ghz_band(struct ieee80211_hw *hw)
1723{
1724	struct mwl8k_priv *priv = hw->priv;
1725
1726	BUILD_BUG_ON(sizeof(priv->channels_24) != sizeof(mwl8k_channels_24));
1727	memcpy(priv->channels_24, mwl8k_channels_24, sizeof(mwl8k_channels_24));
1728
1729	BUILD_BUG_ON(sizeof(priv->rates_24) != sizeof(mwl8k_rates_24));
1730	memcpy(priv->rates_24, mwl8k_rates_24, sizeof(mwl8k_rates_24));
1731
1732	priv->band_24.band = IEEE80211_BAND_2GHZ;
1733	priv->band_24.channels = priv->channels_24;
1734	priv->band_24.n_channels = ARRAY_SIZE(mwl8k_channels_24);
1735	priv->band_24.bitrates = priv->rates_24;
1736	priv->band_24.n_bitrates = ARRAY_SIZE(mwl8k_rates_24);
1737
1738	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band_24;
1739}
1740
1741static void mwl8k_setup_5ghz_band(struct ieee80211_hw *hw)
1742{
1743	struct mwl8k_priv *priv = hw->priv;
1744
1745	BUILD_BUG_ON(sizeof(priv->channels_50) != sizeof(mwl8k_channels_50));
1746	memcpy(priv->channels_50, mwl8k_channels_50, sizeof(mwl8k_channels_50));
1747
1748	BUILD_BUG_ON(sizeof(priv->rates_50) != sizeof(mwl8k_rates_50));
1749	memcpy(priv->rates_50, mwl8k_rates_50, sizeof(mwl8k_rates_50));
1750
1751	priv->band_50.band = IEEE80211_BAND_5GHZ;
1752	priv->band_50.channels = priv->channels_50;
1753	priv->band_50.n_channels = ARRAY_SIZE(mwl8k_channels_50);
1754	priv->band_50.bitrates = priv->rates_50;
1755	priv->band_50.n_bitrates = ARRAY_SIZE(mwl8k_rates_50);
1756
1757	hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->band_50;
1758}
1759
1760/*
1761 * CMD_GET_HW_SPEC (STA version).
1762 */
1763struct mwl8k_cmd_get_hw_spec_sta {
1764	struct mwl8k_cmd_pkt header;
1765	__u8 hw_rev;
1766	__u8 host_interface;
1767	__le16 num_mcaddrs;
1768	__u8 perm_addr[ETH_ALEN];
1769	__le16 region_code;
1770	__le32 fw_rev;
1771	__le32 ps_cookie;
1772	__le32 caps;
1773	__u8 mcs_bitmap[16];
1774	__le32 rx_queue_ptr;
1775	__le32 num_tx_queues;
1776	__le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
1777	__le32 caps2;
1778	__le32 num_tx_desc_per_queue;
1779	__le32 total_rxd;
1780} __packed;
1781
1782#define MWL8K_CAP_MAX_AMSDU		0x20000000
1783#define MWL8K_CAP_GREENFIELD		0x08000000
1784#define MWL8K_CAP_AMPDU			0x04000000
1785#define MWL8K_CAP_RX_STBC		0x01000000
1786#define MWL8K_CAP_TX_STBC		0x00800000
1787#define MWL8K_CAP_SHORTGI_40MHZ		0x00400000
1788#define MWL8K_CAP_SHORTGI_20MHZ		0x00200000
1789#define MWL8K_CAP_RX_ANTENNA_MASK	0x000e0000
1790#define MWL8K_CAP_TX_ANTENNA_MASK	0x0001c000
1791#define MWL8K_CAP_DELAY_BA		0x00003000
1792#define MWL8K_CAP_MIMO			0x00000200
1793#define MWL8K_CAP_40MHZ			0x00000100
1794#define MWL8K_CAP_BAND_MASK		0x00000007
1795#define MWL8K_CAP_5GHZ			0x00000004
1796#define MWL8K_CAP_2GHZ4			0x00000001
1797
1798static void
1799mwl8k_set_ht_caps(struct ieee80211_hw *hw,
1800		  struct ieee80211_supported_band *band, u32 cap)
1801{
1802	int rx_streams;
1803	int tx_streams;
1804
1805	band->ht_cap.ht_supported = 1;
1806
1807	if (cap & MWL8K_CAP_MAX_AMSDU)
1808		band->ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
1809	if (cap & MWL8K_CAP_GREENFIELD)
1810		band->ht_cap.cap |= IEEE80211_HT_CAP_GRN_FLD;
1811	if (cap & MWL8K_CAP_AMPDU) {
1812		hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
1813		band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
1814		band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
1815	}
1816	if (cap & MWL8K_CAP_RX_STBC)
1817		band->ht_cap.cap |= IEEE80211_HT_CAP_RX_STBC;
1818	if (cap & MWL8K_CAP_TX_STBC)
1819		band->ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
1820	if (cap & MWL8K_CAP_SHORTGI_40MHZ)
1821		band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
1822	if (cap & MWL8K_CAP_SHORTGI_20MHZ)
1823		band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
1824	if (cap & MWL8K_CAP_DELAY_BA)
1825		band->ht_cap.cap |= IEEE80211_HT_CAP_DELAY_BA;
1826	if (cap & MWL8K_CAP_40MHZ)
1827		band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1828
1829	rx_streams = hweight32(cap & MWL8K_CAP_RX_ANTENNA_MASK);
1830	tx_streams = hweight32(cap & MWL8K_CAP_TX_ANTENNA_MASK);
1831
1832	band->ht_cap.mcs.rx_mask[0] = 0xff;
1833	if (rx_streams >= 2)
1834		band->ht_cap.mcs.rx_mask[1] = 0xff;
1835	if (rx_streams >= 3)
1836		band->ht_cap.mcs.rx_mask[2] = 0xff;
1837	band->ht_cap.mcs.rx_mask[4] = 0x01;
1838	band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
1839
1840	if (rx_streams != tx_streams) {
1841		band->ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
1842		band->ht_cap.mcs.tx_params |= (tx_streams - 1) <<
1843				IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
1844	}
1845}
1846
1847static void
1848mwl8k_set_caps(struct ieee80211_hw *hw, u32 caps)
1849{
1850	struct mwl8k_priv *priv = hw->priv;
1851
1852	if ((caps & MWL8K_CAP_2GHZ4) || !(caps & MWL8K_CAP_BAND_MASK)) {
1853		mwl8k_setup_2ghz_band(hw);
1854		if (caps & MWL8K_CAP_MIMO)
1855			mwl8k_set_ht_caps(hw, &priv->band_24, caps);
1856	}
1857
1858	if (caps & MWL8K_CAP_5GHZ) {
1859		mwl8k_setup_5ghz_band(hw);
1860		if (caps & MWL8K_CAP_MIMO)
1861			mwl8k_set_ht_caps(hw, &priv->band_50, caps);
1862	}
1863}
1864
1865static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
1866{
1867	struct mwl8k_priv *priv = hw->priv;
1868	struct mwl8k_cmd_get_hw_spec_sta *cmd;
1869	int rc;
1870	int i;
1871
1872	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1873	if (cmd == NULL)
1874		return -ENOMEM;
1875
1876	cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC);
1877	cmd->header.length = cpu_to_le16(sizeof(*cmd));
1878
1879	memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
1880	cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
1881	cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
1882	cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
1883	for (i = 0; i < MWL8K_TX_QUEUES; i++)
1884		cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
1885	cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
1886	cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
1887
1888	rc = mwl8k_post_cmd(hw, &cmd->header);
1889
1890	if (!rc) {
1891		SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
1892		priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
1893		priv->fw_rev = le32_to_cpu(cmd->fw_rev);
1894		priv->hw_rev = cmd->hw_rev;
1895		mwl8k_set_caps(hw, le32_to_cpu(cmd->caps));
1896		priv->ap_macids_supported = 0x00000000;
1897		priv->sta_macids_supported = 0x00000001;
1898	}
1899
1900	kfree(cmd);
1901	return rc;
1902}
1903
1904/*
1905 * CMD_GET_HW_SPEC (AP version).
1906 */
1907struct mwl8k_cmd_get_hw_spec_ap {
1908	struct mwl8k_cmd_pkt header;
1909	__u8 hw_rev;
1910	__u8 host_interface;
1911	__le16 num_wcb;
1912	__le16 num_mcaddrs;
1913	__u8 perm_addr[ETH_ALEN];
1914	__le16 region_code;
1915	__le16 num_antenna;
1916	__le32 fw_rev;
1917	__le32 wcbbase0;
1918	__le32 rxwrptr;
1919	__le32 rxrdptr;
1920	__le32 ps_cookie;
1921	__le32 wcbbase1;
1922	__le32 wcbbase2;
1923	__le32 wcbbase3;
1924	__le32 fw_api_version;
1925} __packed;
1926
1927static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
1928{
1929	struct mwl8k_priv *priv = hw->priv;
1930	struct mwl8k_cmd_get_hw_spec_ap *cmd;
1931	int rc;
1932	u32 api_version;
1933
1934	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1935	if (cmd == NULL)
1936		return -ENOMEM;
1937
1938	cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC);
1939	cmd->header.length = cpu_to_le16(sizeof(*cmd));
1940
1941	memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
1942	cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
1943
1944	rc = mwl8k_post_cmd(hw, &cmd->header);
1945
1946	if (!rc) {
1947		int off;
1948
1949		api_version = le32_to_cpu(cmd->fw_api_version);
1950		if (priv->device_info->fw_api_ap != api_version) {
1951			printk(KERN_ERR "%s: Unsupported fw API version for %s."
1952			       "  Expected %d got %d.\n", MWL8K_NAME,
1953			       priv->device_info->part_name,
1954			       priv->device_info->fw_api_ap,
1955			       api_version);
1956			rc = -EINVAL;
1957			goto done;
1958		}
1959		SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
1960		priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
1961		priv->fw_rev = le32_to_cpu(cmd->fw_rev);
1962		priv->hw_rev = cmd->hw_rev;
1963		mwl8k_setup_2ghz_band(hw);
1964		priv->ap_macids_supported = 0x000000ff;
1965		priv->sta_macids_supported = 0x00000000;
1966
1967		off = le32_to_cpu(cmd->wcbbase0) & 0xffff;
1968		iowrite32(priv->txq[0].txd_dma, priv->sram + off);
1969
1970		off = le32_to_cpu(cmd->rxwrptr) & 0xffff;
1971		iowrite32(priv->rxq[0].rxd_dma, priv->sram + off);
1972
1973		off = le32_to_cpu(cmd->rxrdptr) & 0xffff;
1974		iowrite32(priv->rxq[0].rxd_dma, priv->sram + off);
1975
1976		off = le32_to_cpu(cmd->wcbbase1) & 0xffff;
1977		iowrite32(priv->txq[1].txd_dma, priv->sram + off);
1978
1979		off = le32_to_cpu(cmd->wcbbase2) & 0xffff;
1980		iowrite32(priv->txq[2].txd_dma, priv->sram + off);
1981
1982		off = le32_to_cpu(cmd->wcbbase3) & 0xffff;
1983		iowrite32(priv->txq[3].txd_dma, priv->sram + off);
1984	}
1985
1986done:
1987	kfree(cmd);
1988	return rc;
1989}
1990
1991/*
1992 * CMD_SET_HW_SPEC.
1993 */
1994struct mwl8k_cmd_set_hw_spec {
1995	struct mwl8k_cmd_pkt header;
1996	__u8 hw_rev;
1997	__u8 host_interface;
1998	__le16 num_mcaddrs;
1999	__u8 perm_addr[ETH_ALEN];
2000	__le16 region_code;
2001	__le32 fw_rev;
2002	__le32 ps_cookie;
2003	__le32 caps;
2004	__le32 rx_queue_ptr;
2005	__le32 num_tx_queues;
2006	__le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
2007	__le32 flags;
2008	__le32 num_tx_desc_per_queue;
2009	__le32 total_rxd;
2010} __packed;
2011
2012#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT		0x00000080
2013#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP	0x00000020
2014#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON		0x00000010
2015
2016static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
2017{
2018	struct mwl8k_priv *priv = hw->priv;
2019	struct mwl8k_cmd_set_hw_spec *cmd;
2020	int rc;
2021	int i;
2022
2023	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2024	if (cmd == NULL)
2025		return -ENOMEM;
2026
2027	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_HW_SPEC);
2028	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2029
2030	cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
2031	cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
2032	cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
2033	for (i = 0; i < MWL8K_TX_QUEUES; i++)
2034		cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
2035	cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT |
2036				 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP |
2037				 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON);
2038	cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
2039	cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
2040
2041	rc = mwl8k_post_cmd(hw, &cmd->header);
2042	kfree(cmd);
2043
2044	return rc;
2045}
2046
2047/*
2048 * CMD_MAC_MULTICAST_ADR.
2049 */
2050struct mwl8k_cmd_mac_multicast_adr {
2051	struct mwl8k_cmd_pkt header;
2052	__le16 action;
2053	__le16 numaddr;
2054	__u8 addr[0][ETH_ALEN];
2055};
2056
2057#define MWL8K_ENABLE_RX_DIRECTED	0x0001
2058#define MWL8K_ENABLE_RX_MULTICAST	0x0002
2059#define MWL8K_ENABLE_RX_ALL_MULTICAST	0x0004
2060#define MWL8K_ENABLE_RX_BROADCAST	0x0008
2061
2062static struct mwl8k_cmd_pkt *
2063__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, int allmulti,
2064			      struct netdev_hw_addr_list *mc_list)
2065{
2066	struct mwl8k_priv *priv = hw->priv;
2067	struct mwl8k_cmd_mac_multicast_adr *cmd;
2068	int size;
2069	int mc_count = 0;
2070
2071	if (mc_list)
2072		mc_count = netdev_hw_addr_list_count(mc_list);
2073
2074	if (allmulti || mc_count > priv->num_mcaddrs) {
2075		allmulti = 1;
2076		mc_count = 0;
2077	}
2078
2079	size = sizeof(*cmd) + mc_count * ETH_ALEN;
2080
2081	cmd = kzalloc(size, GFP_ATOMIC);
2082	if (cmd == NULL)
2083		return NULL;
2084
2085	cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR);
2086	cmd->header.length = cpu_to_le16(size);
2087	cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_DIRECTED |
2088				  MWL8K_ENABLE_RX_BROADCAST);
2089
2090	if (allmulti) {
2091		cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_ALL_MULTICAST);
2092	} else if (mc_count) {
2093		struct netdev_hw_addr *ha;
2094		int i = 0;
2095
2096		cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST);
2097		cmd->numaddr = cpu_to_le16(mc_count);
2098		netdev_hw_addr_list_for_each(ha, mc_list) {
2099			memcpy(cmd->addr[i], ha->addr, ETH_ALEN);
2100		}
2101	}
2102
2103	return &cmd->header;
2104}
2105
2106/*
2107 * CMD_GET_STAT.
2108 */
2109struct mwl8k_cmd_get_stat {
2110	struct mwl8k_cmd_pkt header;
2111	__le32 stats[64];
2112} __packed;
2113
2114#define MWL8K_STAT_ACK_FAILURE	9
2115#define MWL8K_STAT_RTS_FAILURE	12
2116#define MWL8K_STAT_FCS_ERROR	24
2117#define MWL8K_STAT_RTS_SUCCESS	11
2118
2119static int mwl8k_cmd_get_stat(struct ieee80211_hw *hw,
2120			      struct ieee80211_low_level_stats *stats)
2121{
2122	struct mwl8k_cmd_get_stat *cmd;
2123	int rc;
2124
2125	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2126	if (cmd == NULL)
2127		return -ENOMEM;
2128
2129	cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_STAT);
2130	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2131
2132	rc = mwl8k_post_cmd(hw, &cmd->header);
2133	if (!rc) {
2134		stats->dot11ACKFailureCount =
2135			le32_to_cpu(cmd->stats[MWL8K_STAT_ACK_FAILURE]);
2136		stats->dot11RTSFailureCount =
2137			le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_FAILURE]);
2138		stats->dot11FCSErrorCount =
2139			le32_to_cpu(cmd->stats[MWL8K_STAT_FCS_ERROR]);
2140		stats->dot11RTSSuccessCount =
2141			le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_SUCCESS]);
2142	}
2143	kfree(cmd);
2144
2145	return rc;
2146}
2147
2148/*
2149 * CMD_RADIO_CONTROL.
2150 */
2151struct mwl8k_cmd_radio_control {
2152	struct mwl8k_cmd_pkt header;
2153	__le16 action;
2154	__le16 control;
2155	__le16 radio_on;
2156} __packed;
2157
2158static int
2159mwl8k_cmd_radio_control(struct ieee80211_hw *hw, bool enable, bool force)
2160{
2161	struct mwl8k_priv *priv = hw->priv;
2162	struct mwl8k_cmd_radio_control *cmd;
2163	int rc;
2164
2165	if (enable == priv->radio_on && !force)
2166		return 0;
2167
2168	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2169	if (cmd == NULL)
2170		return -ENOMEM;
2171
2172	cmd->header.code = cpu_to_le16(MWL8K_CMD_RADIO_CONTROL);
2173	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2174	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
2175	cmd->control = cpu_to_le16(priv->radio_short_preamble ? 3 : 1);
2176	cmd->radio_on = cpu_to_le16(enable ? 0x0001 : 0x0000);
2177
2178	rc = mwl8k_post_cmd(hw, &cmd->header);
2179	kfree(cmd);
2180
2181	if (!rc)
2182		priv->radio_on = enable;
2183
2184	return rc;
2185}
2186
2187static int mwl8k_cmd_radio_disable(struct ieee80211_hw *hw)
2188{
2189	return mwl8k_cmd_radio_control(hw, 0, 0);
2190}
2191
2192static int mwl8k_cmd_radio_enable(struct ieee80211_hw *hw)
2193{
2194	return mwl8k_cmd_radio_control(hw, 1, 0);
2195}
2196
2197static int
2198mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
2199{
2200	struct mwl8k_priv *priv = hw->priv;
2201
2202	priv->radio_short_preamble = short_preamble;
2203
2204	return mwl8k_cmd_radio_control(hw, 1, 1);
2205}
2206
2207/*
2208 * CMD_RF_TX_POWER.
2209 */
2210#define MWL8K_RF_TX_POWER_LEVEL_TOTAL	8
2211
2212struct mwl8k_cmd_rf_tx_power {
2213	struct mwl8k_cmd_pkt header;
2214	__le16 action;
2215	__le16 support_level;
2216	__le16 current_level;
2217	__le16 reserved;
2218	__le16 power_level_list[MWL8K_RF_TX_POWER_LEVEL_TOTAL];
2219} __packed;
2220
2221static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm)
2222{
2223	struct mwl8k_cmd_rf_tx_power *cmd;
2224	int rc;
2225
2226	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2227	if (cmd == NULL)
2228		return -ENOMEM;
2229
2230	cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_TX_POWER);
2231	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2232	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
2233	cmd->support_level = cpu_to_le16(dBm);
2234
2235	rc = mwl8k_post_cmd(hw, &cmd->header);
2236	kfree(cmd);
2237
2238	return rc;
2239}
2240
2241/*
2242 * CMD_TX_POWER.
2243 */
2244#define MWL8K_TX_POWER_LEVEL_TOTAL      12
2245
2246struct mwl8k_cmd_tx_power {
2247	struct mwl8k_cmd_pkt header;
2248	__le16 action;
2249	__le16 band;
2250	__le16 channel;
2251	__le16 bw;
2252	__le16 sub_ch;
2253	__le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
2254} __attribute__((packed));
2255
2256static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw,
2257				     struct ieee80211_conf *conf,
2258				     unsigned short pwr)
2259{
2260	struct ieee80211_channel *channel = conf->channel;
2261	struct mwl8k_cmd_tx_power *cmd;
2262	int rc;
2263	int i;
2264
2265	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2266	if (cmd == NULL)
2267		return -ENOMEM;
2268
2269	cmd->header.code = cpu_to_le16(MWL8K_CMD_TX_POWER);
2270	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2271	cmd->action = cpu_to_le16(MWL8K_CMD_SET_LIST);
2272
2273	if (channel->band == IEEE80211_BAND_2GHZ)
2274		cmd->band = cpu_to_le16(0x1);
2275	else if (channel->band == IEEE80211_BAND_5GHZ)
2276		cmd->band = cpu_to_le16(0x4);
2277
2278	cmd->channel = channel->hw_value;
2279
2280	if (conf->channel_type == NL80211_CHAN_NO_HT ||
2281	    conf->channel_type == NL80211_CHAN_HT20) {
2282		cmd->bw = cpu_to_le16(0x2);
2283	} else {
2284		cmd->bw = cpu_to_le16(0x4);
2285		if (conf->channel_type == NL80211_CHAN_HT40MINUS)
2286			cmd->sub_ch = cpu_to_le16(0x3);
2287		else if (conf->channel_type == NL80211_CHAN_HT40PLUS)
2288			cmd->sub_ch = cpu_to_le16(0x1);
2289	}
2290
2291	for (i = 0; i < MWL8K_TX_POWER_LEVEL_TOTAL; i++)
2292		cmd->power_level_list[i] = cpu_to_le16(pwr);
2293
2294	rc = mwl8k_post_cmd(hw, &cmd->header);
2295	kfree(cmd);
2296
2297	return rc;
2298}
2299
2300/*
2301 * CMD_RF_ANTENNA.
2302 */
2303struct mwl8k_cmd_rf_antenna {
2304	struct mwl8k_cmd_pkt header;
2305	__le16 antenna;
2306	__le16 mode;
2307} __packed;
2308
2309#define MWL8K_RF_ANTENNA_RX		1
2310#define MWL8K_RF_ANTENNA_TX		2
2311
2312static int
2313mwl8k_cmd_rf_antenna(struct ieee80211_hw *hw, int antenna, int mask)
2314{
2315	struct mwl8k_cmd_rf_antenna *cmd;
2316	int rc;
2317
2318	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2319	if (cmd == NULL)
2320		return -ENOMEM;
2321
2322	cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_ANTENNA);
2323	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2324	cmd->antenna = cpu_to_le16(antenna);
2325	cmd->mode = cpu_to_le16(mask);
2326
2327	rc = mwl8k_post_cmd(hw, &cmd->header);
2328	kfree(cmd);
2329
2330	return rc;
2331}
2332
2333/*
2334 * CMD_SET_BEACON.
2335 */
2336struct mwl8k_cmd_set_beacon {
2337	struct mwl8k_cmd_pkt header;
2338	__le16 beacon_len;
2339	__u8 beacon[0];
2340};
2341
2342static int mwl8k_cmd_set_beacon(struct ieee80211_hw *hw,
2343				struct ieee80211_vif *vif, u8 *beacon, int len)
2344{
2345	struct mwl8k_cmd_set_beacon *cmd;
2346	int rc;
2347
2348	cmd = kzalloc(sizeof(*cmd) + len, GFP_KERNEL);
2349	if (cmd == NULL)
2350		return -ENOMEM;
2351
2352	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_BEACON);
2353	cmd->header.length = cpu_to_le16(sizeof(*cmd) + len);
2354	cmd->beacon_len = cpu_to_le16(len);
2355	memcpy(cmd->beacon, beacon, len);
2356
2357	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2358	kfree(cmd);
2359
2360	return rc;
2361}
2362
2363/*
2364 * CMD_SET_PRE_SCAN.
2365 */
2366struct mwl8k_cmd_set_pre_scan {
2367	struct mwl8k_cmd_pkt header;
2368} __packed;
2369
2370static int mwl8k_cmd_set_pre_scan(struct ieee80211_hw *hw)
2371{
2372	struct mwl8k_cmd_set_pre_scan *cmd;
2373	int rc;
2374
2375	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2376	if (cmd == NULL)
2377		return -ENOMEM;
2378
2379	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_PRE_SCAN);
2380	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2381
2382	rc = mwl8k_post_cmd(hw, &cmd->header);
2383	kfree(cmd);
2384
2385	return rc;
2386}
2387
2388/*
2389 * CMD_SET_POST_SCAN.
2390 */
2391struct mwl8k_cmd_set_post_scan {
2392	struct mwl8k_cmd_pkt header;
2393	__le32 isibss;
2394	__u8 bssid[ETH_ALEN];
2395} __packed;
2396
2397static int
2398mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, const __u8 *mac)
2399{
2400	struct mwl8k_cmd_set_post_scan *cmd;
2401	int rc;
2402
2403	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2404	if (cmd == NULL)
2405		return -ENOMEM;
2406
2407	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_POST_SCAN);
2408	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2409	cmd->isibss = 0;
2410	memcpy(cmd->bssid, mac, ETH_ALEN);
2411
2412	rc = mwl8k_post_cmd(hw, &cmd->header);
2413	kfree(cmd);
2414
2415	return rc;
2416}
2417
2418/*
2419 * CMD_SET_RF_CHANNEL.
2420 */
2421struct mwl8k_cmd_set_rf_channel {
2422	struct mwl8k_cmd_pkt header;
2423	__le16 action;
2424	__u8 current_channel;
2425	__le32 channel_flags;
2426} __packed;
2427
2428static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
2429				    struct ieee80211_conf *conf)
2430{
2431	struct ieee80211_channel *channel = conf->channel;
2432	struct mwl8k_cmd_set_rf_channel *cmd;
2433	int rc;
2434
2435	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2436	if (cmd == NULL)
2437		return -ENOMEM;
2438
2439	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RF_CHANNEL);
2440	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2441	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
2442	cmd->current_channel = channel->hw_value;
2443
2444	if (channel->band == IEEE80211_BAND_2GHZ)
2445		cmd->channel_flags |= cpu_to_le32(0x00000001);
2446	else if (channel->band == IEEE80211_BAND_5GHZ)
2447		cmd->channel_flags |= cpu_to_le32(0x00000004);
2448
2449	if (conf->channel_type == NL80211_CHAN_NO_HT ||
2450	    conf->channel_type == NL80211_CHAN_HT20)
2451		cmd->channel_flags |= cpu_to_le32(0x00000080);
2452	else if (conf->channel_type == NL80211_CHAN_HT40MINUS)
2453		cmd->channel_flags |= cpu_to_le32(0x000001900);
2454	else if (conf->channel_type == NL80211_CHAN_HT40PLUS)
2455		cmd->channel_flags |= cpu_to_le32(0x000000900);
2456
2457	rc = mwl8k_post_cmd(hw, &cmd->header);
2458	kfree(cmd);
2459
2460	return rc;
2461}
2462
2463/*
2464 * CMD_SET_AID.
2465 */
2466#define MWL8K_FRAME_PROT_DISABLED			0x00
2467#define MWL8K_FRAME_PROT_11G				0x07
2468#define MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY		0x02
2469#define MWL8K_FRAME_PROT_11N_HT_ALL			0x06
2470
2471struct mwl8k_cmd_update_set_aid {
2472	struct	mwl8k_cmd_pkt header;
2473	__le16	aid;
2474
2475	 /* AP's MAC address (BSSID) */
2476	__u8	bssid[ETH_ALEN];
2477	__le16	protection_mode;
2478	__u8	supp_rates[14];
2479} __packed;
2480
2481static void legacy_rate_mask_to_array(u8 *rates, u32 mask)
2482{
2483	int i;
2484	int j;
2485
2486	/*
2487	 * Clear nonstandard rates 4 and 13.
2488	 */
2489	mask &= 0x1fef;
2490
2491	for (i = 0, j = 0; i < 14; i++) {
2492		if (mask & (1 << i))
2493			rates[j++] = mwl8k_rates_24[i].hw_value;
2494	}
2495}
2496
2497static int
2498mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
2499		  struct ieee80211_vif *vif, u32 legacy_rate_mask)
2500{
2501	struct mwl8k_cmd_update_set_aid *cmd;
2502	u16 prot_mode;
2503	int rc;
2504
2505	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2506	if (cmd == NULL)
2507		return -ENOMEM;
2508
2509	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_AID);
2510	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2511	cmd->aid = cpu_to_le16(vif->bss_conf.aid);
2512	memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
2513
2514	if (vif->bss_conf.use_cts_prot) {
2515		prot_mode = MWL8K_FRAME_PROT_11G;
2516	} else {
2517		switch (vif->bss_conf.ht_operation_mode &
2518			IEEE80211_HT_OP_MODE_PROTECTION) {
2519		case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
2520			prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY;
2521			break;
2522		case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
2523			prot_mode = MWL8K_FRAME_PROT_11N_HT_ALL;
2524			break;
2525		default:
2526			prot_mode = MWL8K_FRAME_PROT_DISABLED;
2527			break;
2528		}
2529	}
2530	cmd->protection_mode = cpu_to_le16(prot_mode);
2531
2532	legacy_rate_mask_to_array(cmd->supp_rates, legacy_rate_mask);
2533
2534	rc = mwl8k_post_cmd(hw, &cmd->header);
2535	kfree(cmd);
2536
2537	return rc;
2538}
2539
2540/*
2541 * CMD_SET_RATE.
2542 */
2543struct mwl8k_cmd_set_rate {
2544	struct	mwl8k_cmd_pkt header;
2545	__u8	legacy_rates[14];
2546
2547	/* Bitmap for supported MCS codes.  */
2548	__u8	mcs_set[16];
2549	__u8	reserved[16];
2550} __packed;
2551
2552static int
2553mwl8k_cmd_set_rate(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2554		   u32 legacy_rate_mask, u8 *mcs_rates)
2555{
2556	struct mwl8k_cmd_set_rate *cmd;
2557	int rc;
2558
2559	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2560	if (cmd == NULL)
2561		return -ENOMEM;
2562
2563	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE);
2564	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2565	legacy_rate_mask_to_array(cmd->legacy_rates, legacy_rate_mask);
2566	memcpy(cmd->mcs_set, mcs_rates, 16);
2567
2568	rc = mwl8k_post_cmd(hw, &cmd->header);
2569	kfree(cmd);
2570
2571	return rc;
2572}
2573
2574/*
2575 * CMD_FINALIZE_JOIN.
2576 */
2577#define MWL8K_FJ_BEACON_MAXLEN	128
2578
2579struct mwl8k_cmd_finalize_join {
2580	struct mwl8k_cmd_pkt header;
2581	__le32 sleep_interval;	/* Number of beacon periods to sleep */
2582	__u8 beacon_data[MWL8K_FJ_BEACON_MAXLEN];
2583} __packed;
2584
2585static int mwl8k_cmd_finalize_join(struct ieee80211_hw *hw, void *frame,
2586				   int framelen, int dtim)
2587{
2588	struct mwl8k_cmd_finalize_join *cmd;
2589	struct ieee80211_mgmt *payload = frame;
2590	int payload_len;
2591	int rc;
2592
2593	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2594	if (cmd == NULL)
2595		return -ENOMEM;
2596
2597	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN);
2598	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2599	cmd->sleep_interval = cpu_to_le32(dtim ? dtim : 1);
2600
2601	payload_len = framelen - ieee80211_hdrlen(payload->frame_control);
2602	if (payload_len < 0)
2603		payload_len = 0;
2604	else if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
2605		payload_len = MWL8K_FJ_BEACON_MAXLEN;
2606
2607	memcpy(cmd->beacon_data, &payload->u.beacon, payload_len);
2608
2609	rc = mwl8k_post_cmd(hw, &cmd->header);
2610	kfree(cmd);
2611
2612	return rc;
2613}
2614
2615/*
2616 * CMD_SET_RTS_THRESHOLD.
2617 */
2618struct mwl8k_cmd_set_rts_threshold {
2619	struct mwl8k_cmd_pkt header;
2620	__le16 action;
2621	__le16 threshold;
2622} __packed;
2623
2624static int
2625mwl8k_cmd_set_rts_threshold(struct ieee80211_hw *hw, int rts_thresh)
2626{
2627	struct mwl8k_cmd_set_rts_threshold *cmd;
2628	int rc;
2629
2630	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2631	if (cmd == NULL)
2632		return -ENOMEM;
2633
2634	cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD);
2635	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2636	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
2637	cmd->threshold = cpu_to_le16(rts_thresh);
2638
2639	rc = mwl8k_post_cmd(hw, &cmd->header);
2640	kfree(cmd);
2641
2642	return rc;
2643}
2644
2645/*
2646 * CMD_SET_SLOT.
2647 */
2648struct mwl8k_cmd_set_slot {
2649	struct mwl8k_cmd_pkt header;
2650	__le16 action;
2651	__u8 short_slot;
2652} __packed;
2653
2654static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, bool short_slot_time)
2655{
2656	struct mwl8k_cmd_set_slot *cmd;
2657	int rc;
2658
2659	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2660	if (cmd == NULL)
2661		return -ENOMEM;
2662
2663	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT);
2664	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2665	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
2666	cmd->short_slot = short_slot_time;
2667
2668	rc = mwl8k_post_cmd(hw, &cmd->header);
2669	kfree(cmd);
2670
2671	return rc;
2672}
2673
2674/*
2675 * CMD_SET_EDCA_PARAMS.
2676 */
2677struct mwl8k_cmd_set_edca_params {
2678	struct mwl8k_cmd_pkt header;
2679
2680	/* See MWL8K_SET_EDCA_XXX below */
2681	__le16 action;
2682
2683	/* TX opportunity in units of 32 us */
2684	__le16 txop;
2685
2686	union {
2687		struct {
2688			/* Log exponent of max contention period: 0...15 */
2689			__le32 log_cw_max;
2690
2691			/* Log exponent of min contention period: 0...15 */
2692			__le32 log_cw_min;
2693
2694			/* Adaptive interframe spacing in units of 32us */
2695			__u8 aifs;
2696
2697			/* TX queue to configure */
2698			__u8 txq;
2699		} ap;
2700		struct {
2701			/* Log exponent of max contention period: 0...15 */
2702			__u8 log_cw_max;
2703
2704			/* Log exponent of min contention period: 0...15 */
2705			__u8 log_cw_min;
2706
2707			/* Adaptive interframe spacing in units of 32us */
2708			__u8 aifs;
2709
2710			/* TX queue to configure */
2711			__u8 txq;
2712		} sta;
2713	};
2714} __packed;
2715
2716#define MWL8K_SET_EDCA_CW	0x01
2717#define MWL8K_SET_EDCA_TXOP	0x02
2718#define MWL8K_SET_EDCA_AIFS	0x04
2719
2720#define MWL8K_SET_EDCA_ALL	(MWL8K_SET_EDCA_CW | \
2721				 MWL8K_SET_EDCA_TXOP | \
2722				 MWL8K_SET_EDCA_AIFS)
2723
2724static int
2725mwl8k_cmd_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
2726			  __u16 cw_min, __u16 cw_max,
2727			  __u8 aifs, __u16 txop)
2728{
2729	struct mwl8k_priv *priv = hw->priv;
2730	struct mwl8k_cmd_set_edca_params *cmd;
2731	int rc;
2732
2733	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2734	if (cmd == NULL)
2735		return -ENOMEM;
2736
2737	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS);
2738	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2739	cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL);
2740	cmd->txop = cpu_to_le16(txop);
2741	if (priv->ap_fw) {
2742		cmd->ap.log_cw_max = cpu_to_le32(ilog2(cw_max + 1));
2743		cmd->ap.log_cw_min = cpu_to_le32(ilog2(cw_min + 1));
2744		cmd->ap.aifs = aifs;
2745		cmd->ap.txq = qnum;
2746	} else {
2747		cmd->sta.log_cw_max = (u8)ilog2(cw_max + 1);
2748		cmd->sta.log_cw_min = (u8)ilog2(cw_min + 1);
2749		cmd->sta.aifs = aifs;
2750		cmd->sta.txq = qnum;
2751	}
2752
2753	rc = mwl8k_post_cmd(hw, &cmd->header);
2754	kfree(cmd);
2755
2756	return rc;
2757}
2758
2759/*
2760 * CMD_SET_WMM_MODE.
2761 */
2762struct mwl8k_cmd_set_wmm_mode {
2763	struct mwl8k_cmd_pkt header;
2764	__le16 action;
2765} __packed;
2766
2767static int mwl8k_cmd_set_wmm_mode(struct ieee80211_hw *hw, bool enable)
2768{
2769	struct mwl8k_priv *priv = hw->priv;
2770	struct mwl8k_cmd_set_wmm_mode *cmd;
2771	int rc;
2772
2773	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2774	if (cmd == NULL)
2775		return -ENOMEM;
2776
2777	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE);
2778	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2779	cmd->action = cpu_to_le16(!!enable);
2780
2781	rc = mwl8k_post_cmd(hw, &cmd->header);
2782	kfree(cmd);
2783
2784	if (!rc)
2785		priv->wmm_enabled = enable;
2786
2787	return rc;
2788}
2789
2790/*
2791 * CMD_MIMO_CONFIG.
2792 */
2793struct mwl8k_cmd_mimo_config {
2794	struct mwl8k_cmd_pkt header;
2795	__le32 action;
2796	__u8 rx_antenna_map;
2797	__u8 tx_antenna_map;
2798} __packed;
2799
2800static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx)
2801{
2802	struct mwl8k_cmd_mimo_config *cmd;
2803	int rc;
2804
2805	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2806	if (cmd == NULL)
2807		return -ENOMEM;
2808
2809	cmd->header.code = cpu_to_le16(MWL8K_CMD_MIMO_CONFIG);
2810	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2811	cmd->action = cpu_to_le32((u32)MWL8K_CMD_SET);
2812	cmd->rx_antenna_map = rx;
2813	cmd->tx_antenna_map = tx;
2814
2815	rc = mwl8k_post_cmd(hw, &cmd->header);
2816	kfree(cmd);
2817
2818	return rc;
2819}
2820
2821/*
2822 * CMD_USE_FIXED_RATE (STA version).
2823 */
2824struct mwl8k_cmd_use_fixed_rate_sta {
2825	struct mwl8k_cmd_pkt header;
2826	__le32 action;
2827	__le32 allow_rate_drop;
2828	__le32 num_rates;
2829	struct {
2830		__le32 is_ht_rate;
2831		__le32 enable_retry;
2832		__le32 rate;
2833		__le32 retry_count;
2834	} rate_entry[8];
2835	__le32 rate_type;
2836	__le32 reserved1;
2837	__le32 reserved2;
2838} __packed;
2839
2840#define MWL8K_USE_AUTO_RATE	0x0002
2841#define MWL8K_UCAST_RATE	0
2842
2843static int mwl8k_cmd_use_fixed_rate_sta(struct ieee80211_hw *hw)
2844{
2845	struct mwl8k_cmd_use_fixed_rate_sta *cmd;
2846	int rc;
2847
2848	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2849	if (cmd == NULL)
2850		return -ENOMEM;
2851
2852	cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE);
2853	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2854	cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE);
2855	cmd->rate_type = cpu_to_le32(MWL8K_UCAST_RATE);
2856
2857	rc = mwl8k_post_cmd(hw, &cmd->header);
2858	kfree(cmd);
2859
2860	return rc;
2861}
2862
2863/*
2864 * CMD_USE_FIXED_RATE (AP version).
2865 */
2866struct mwl8k_cmd_use_fixed_rate_ap {
2867	struct mwl8k_cmd_pkt header;
2868	__le32 action;
2869	__le32 allow_rate_drop;
2870	__le32 num_rates;
2871	struct mwl8k_rate_entry_ap {
2872		__le32 is_ht_rate;
2873		__le32 enable_retry;
2874		__le32 rate;
2875		__le32 retry_count;
2876	} rate_entry[4];
2877	u8 multicast_rate;
2878	u8 multicast_rate_type;
2879	u8 management_rate;
2880} __packed;
2881
2882static int
2883mwl8k_cmd_use_fixed_rate_ap(struct ieee80211_hw *hw, int mcast, int mgmt)
2884{
2885	struct mwl8k_cmd_use_fixed_rate_ap *cmd;
2886	int rc;
2887
2888	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2889	if (cmd == NULL)
2890		return -ENOMEM;
2891
2892	cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE);
2893	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2894	cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE);
2895	cmd->multicast_rate = mcast;
2896	cmd->management_rate = mgmt;
2897
2898	rc = mwl8k_post_cmd(hw, &cmd->header);
2899	kfree(cmd);
2900
2901	return rc;
2902}
2903
2904/*
2905 * CMD_ENABLE_SNIFFER.
2906 */
2907struct mwl8k_cmd_enable_sniffer {
2908	struct mwl8k_cmd_pkt header;
2909	__le32 action;
2910} __packed;
2911
2912static int mwl8k_cmd_enable_sniffer(struct ieee80211_hw *hw, bool enable)
2913{
2914	struct mwl8k_cmd_enable_sniffer *cmd;
2915	int rc;
2916
2917	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2918	if (cmd == NULL)
2919		return -ENOMEM;
2920
2921	cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER);
2922	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2923	cmd->action = cpu_to_le32(!!enable);
2924
2925	rc = mwl8k_post_cmd(hw, &cmd->header);
2926	kfree(cmd);
2927
2928	return rc;
2929}
2930
2931/*
2932 * CMD_SET_MAC_ADDR.
2933 */
2934struct mwl8k_cmd_set_mac_addr {
2935	struct mwl8k_cmd_pkt header;
2936	union {
2937		struct {
2938			__le16 mac_type;
2939			__u8 mac_addr[ETH_ALEN];
2940		} mbss;
2941		__u8 mac_addr[ETH_ALEN];
2942	};
2943} __packed;
2944
2945#define MWL8K_MAC_TYPE_PRIMARY_CLIENT		0
2946#define MWL8K_MAC_TYPE_SECONDARY_CLIENT		1
2947#define MWL8K_MAC_TYPE_PRIMARY_AP		2
2948#define MWL8K_MAC_TYPE_SECONDARY_AP		3
2949
2950static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw,
2951				  struct ieee80211_vif *vif, u8 *mac)
2952{
2953	struct mwl8k_priv *priv = hw->priv;
2954	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
2955	struct mwl8k_cmd_set_mac_addr *cmd;
2956	int mac_type;
2957	int rc;
2958
2959	mac_type = MWL8K_MAC_TYPE_PRIMARY_AP;
2960	if (vif != NULL && vif->type == NL80211_IFTYPE_STATION) {
2961		if (mwl8k_vif->macid + 1 == ffs(priv->sta_macids_supported))
2962			mac_type = MWL8K_MAC_TYPE_PRIMARY_CLIENT;
2963		else
2964			mac_type = MWL8K_MAC_TYPE_SECONDARY_CLIENT;
2965	} else if (vif != NULL && vif->type == NL80211_IFTYPE_AP) {
2966		if (mwl8k_vif->macid + 1 == ffs(priv->ap_macids_supported))
2967			mac_type = MWL8K_MAC_TYPE_PRIMARY_AP;
2968		else
2969			mac_type = MWL8K_MAC_TYPE_SECONDARY_AP;
2970	}
2971
2972	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2973	if (cmd == NULL)
2974		return -ENOMEM;
2975
2976	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR);
2977	cmd->header.length = cpu_to_le16(sizeof(*cmd));
2978	if (priv->ap_fw) {
2979		cmd->mbss.mac_type = cpu_to_le16(mac_type);
2980		memcpy(cmd->mbss.mac_addr, mac, ETH_ALEN);
2981	} else {
2982		memcpy(cmd->mac_addr, mac, ETH_ALEN);
2983	}
2984
2985	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2986	kfree(cmd);
2987
2988	return rc;
2989}
2990
2991/*
2992 * CMD_SET_RATEADAPT_MODE.
2993 */
2994struct mwl8k_cmd_set_rate_adapt_mode {
2995	struct mwl8k_cmd_pkt header;
2996	__le16 action;
2997	__le16 mode;
2998} __packed;
2999
3000static int mwl8k_cmd_set_rateadapt_mode(struct ieee80211_hw *hw, __u16 mode)
3001{
3002	struct mwl8k_cmd_set_rate_adapt_mode *cmd;
3003	int rc;
3004
3005	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3006	if (cmd == NULL)
3007		return -ENOMEM;
3008
3009	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATEADAPT_MODE);
3010	cmd->header.length = cpu_to_le16(sizeof(*cmd));
3011	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
3012	cmd->mode = cpu_to_le16(mode);
3013
3014	rc = mwl8k_post_cmd(hw, &cmd->header);
3015	kfree(cmd);
3016
3017	return rc;
3018}
3019
3020/*
3021 * CMD_BSS_START.
3022 */
3023struct mwl8k_cmd_bss_start {
3024	struct mwl8k_cmd_pkt header;
3025	__le32 enable;
3026} __packed;
3027
3028static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
3029			       struct ieee80211_vif *vif, int enable)
3030{
3031	struct mwl8k_cmd_bss_start *cmd;
3032	int rc;
3033
3034	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3035	if (cmd == NULL)
3036		return -ENOMEM;
3037
3038	cmd->header.code = cpu_to_le16(MWL8K_CMD_BSS_START);
3039	cmd->header.length = cpu_to_le16(sizeof(*cmd));
3040	cmd->enable = cpu_to_le32(enable);
3041
3042	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
3043	kfree(cmd);
3044
3045	return rc;
3046}
3047
3048/*
3049 * CMD_SET_NEW_STN.
3050 */
3051struct mwl8k_cmd_set_new_stn {
3052	struct mwl8k_cmd_pkt header;
3053	__le16 aid;
3054	__u8 mac_addr[6];
3055	__le16 stn_id;
3056	__le16 action;
3057	__le16 rsvd;
3058	__le32 legacy_rates;
3059	__u8 ht_rates[4];
3060	__le16 cap_info;
3061	__le16 ht_capabilities_info;
3062	__u8 mac_ht_param_info;
3063	__u8 rev;
3064	__u8 control_channel;
3065	__u8 add_channel;
3066	__le16 op_mode;
3067	__le16 stbc;
3068	__u8 add_qos_info;
3069	__u8 is_qos_sta;
3070	__le32 fw_sta_ptr;
3071} __packed;
3072
3073#define MWL8K_STA_ACTION_ADD		0
3074#define MWL8K_STA_ACTION_REMOVE		2
3075
3076static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw,
3077				     struct ieee80211_vif *vif,
3078				     struct ieee80211_sta *sta)
3079{
3080	struct mwl8k_cmd_set_new_stn *cmd;
3081	u32 rates;
3082	int rc;
3083
3084	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3085	if (cmd == NULL)
3086		return -ENOMEM;
3087
3088	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
3089	cmd->header.length = cpu_to_le16(sizeof(*cmd));
3090	cmd->aid = cpu_to_le16(sta->aid);
3091	memcpy(cmd->mac_addr, sta->addr, ETH_ALEN);
3092	cmd->stn_id = cpu_to_le16(sta->aid);
3093	cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD);
3094	if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
3095		rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
3096	else
3097		rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
3098	cmd->legacy_rates = cpu_to_le32(rates);
3099	if (sta->ht_cap.ht_supported) {
3100		cmd->ht_rates[0] = sta->ht_cap.mcs.rx_mask[0];
3101		cmd->ht_rates[1] = sta->ht_cap.mcs.rx_mask[1];
3102		cmd->ht_rates[2] = sta->ht_cap.mcs.rx_mask[2];
3103		cmd->ht_rates[3] = sta->ht_cap.mcs.rx_mask[3];
3104		cmd->ht_capabilities_info = cpu_to_le16(sta->ht_cap.cap);
3105		cmd->mac_ht_param_info = (sta->ht_cap.ampdu_factor & 3) |
3106			((sta->ht_cap.ampdu_density & 7) << 2);
3107		cmd->is_qos_sta = 1;
3108	}
3109
3110	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
3111	kfree(cmd);
3112
3113	return rc;
3114}
3115
3116static int mwl8k_cmd_set_new_stn_add_self(struct ieee80211_hw *hw,
3117					  struct ieee80211_vif *vif)
3118{
3119	struct mwl8k_cmd_set_new_stn *cmd;
3120	int rc;
3121
3122	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3123	if (cmd == NULL)
3124		return -ENOMEM;
3125
3126	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
3127	cmd->header.length = cpu_to_le16(sizeof(*cmd));
3128	memcpy(cmd->mac_addr, vif->addr, ETH_ALEN);
3129
3130	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
3131	kfree(cmd);
3132
3133	return rc;
3134}
3135
3136static int mwl8k_cmd_set_new_stn_del(struct ieee80211_hw *hw,
3137				     struct ieee80211_vif *vif, u8 *addr)
3138{
3139	struct mwl8k_cmd_set_new_stn *cmd;
3140	int rc;
3141
3142	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3143	if (cmd == NULL)
3144		return -ENOMEM;
3145
3146	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
3147	cmd->header.length = cpu_to_le16(sizeof(*cmd));
3148	memcpy(cmd->mac_addr, addr, ETH_ALEN);
3149	cmd->action = cpu_to_le16(MWL8K_STA_ACTION_REMOVE);
3150
3151	rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
3152	kfree(cmd);
3153
3154	return rc;
3155}
3156
3157/*
3158 * CMD_UPDATE_STADB.
3159 */
3160struct ewc_ht_info {
3161	__le16	control1;
3162	__le16	control2;
3163	__le16	control3;
3164} __packed;
3165
3166struct peer_capability_info {
3167	/* Peer type - AP vs. STA.  */
3168	__u8	peer_type;
3169
3170	/* Basic 802.11 capabilities from assoc resp.  */
3171	__le16	basic_caps;
3172
3173	/* Set if peer supports 802.11n high throughput (HT).  */
3174	__u8	ht_support;
3175
3176	/* Valid if HT is supported.  */
3177	__le16	ht_caps;
3178	__u8	extended_ht_caps;
3179	struct ewc_ht_info	ewc_info;
3180
3181	/* Legacy rate table. Intersection of our rates and peer rates.  */
3182	__u8	legacy_rates[12];
3183
3184	/* HT rate table. Intersection of our rates and peer rates.  */
3185	__u8	ht_rates[16];
3186	__u8	pad[16];
3187
3188	/* If set, interoperability mode, no proprietary extensions.  */
3189	__u8	interop;
3190	__u8	pad2;
3191	__u8	station_id;
3192	__le16	amsdu_enabled;
3193} __packed;
3194
3195struct mwl8k_cmd_update_stadb {
3196	struct mwl8k_cmd_pkt header;
3197
3198	/* See STADB_ACTION_TYPE */
3199	__le32	action;
3200
3201	/* Peer MAC address */
3202	__u8	peer_addr[ETH_ALEN];
3203
3204	__le32	reserved;
3205
3206	/* Peer info - valid during add/update.  */
3207	struct peer_capability_info	peer_info;
3208} __packed;
3209
3210#define MWL8K_STA_DB_MODIFY_ENTRY	1
3211#define MWL8K_STA_DB_DEL_ENTRY		2
3212
3213/* Peer Entry flags - used to define the type of the peer node */
3214#define MWL8K_PEER_TYPE_ACCESSPOINT	2
3215
3216static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw,
3217				      struct ieee80211_vif *vif,
3218				      struct ieee80211_sta *sta)
3219{
3220	struct mwl8k_cmd_update_stadb *cmd;
3221	struct peer_capability_info *p;
3222	u32 rates;
3223	int rc;
3224
3225	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3226	if (cmd == NULL)
3227		return -ENOMEM;
3228
3229	cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
3230	cmd->header.length = cpu_to_le16(sizeof(*cmd));
3231	cmd->action = cpu_to_le32(MWL8K_STA_DB_MODIFY_ENTRY);
3232	memcpy(cmd->peer_addr, sta->addr, ETH_ALEN);
3233
3234	p = &cmd->peer_info;
3235	p->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT;
3236	p->basic_caps = cpu_to_le16(vif->bss_conf.assoc_capability);
3237	p->ht_support = sta->ht_cap.ht_supported;
3238	p->ht_caps = cpu_to_le16(sta->ht_cap.cap);
3239	p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) |
3240		((sta->ht_cap.ampdu_density & 7) << 2);
3241	if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
3242		rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
3243	else
3244		rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
3245	legacy_rate_mask_to_array(p->legacy_rates, rates);
3246	memcpy(p->ht_rates, sta->ht_cap.mcs.rx_mask, 16);
3247	p->interop = 1;
3248	p->amsdu_enabled = 0;
3249
3250	rc = mwl8k_post_cmd(hw, &cmd->header);
3251	kfree(cmd);
3252
3253	return rc ? rc : p->station_id;
3254}
3255
3256static int mwl8k_cmd_update_stadb_del(struct ieee80211_hw *hw,
3257				      struct ieee80211_vif *vif, u8 *addr)
3258{
3259	struct mwl8k_cmd_update_stadb *cmd;
3260	int rc;
3261
3262	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
3263	if (cmd == NULL)
3264		return -ENOMEM;
3265
3266	cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
3267	cmd->header.length = cpu_to_le16(sizeof(*cmd));
3268	cmd->action = cpu_to_le32(MWL8K_STA_DB_DEL_ENTRY);
3269	memcpy(cmd->peer_addr, addr, ETH_ALEN);
3270
3271	rc = mwl8k_post_cmd(hw, &cmd->header);
3272	kfree(cmd);
3273
3274	return rc;
3275}
3276
3277
3278/*
3279 * Interrupt handling.
3280 */
3281static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
3282{
3283	struct ieee80211_hw *hw = dev_id;
3284	struct mwl8k_priv *priv = hw->priv;
3285	u32 status;
3286
3287	status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3288	if (!status)
3289		return IRQ_NONE;
3290
3291	if (status & MWL8K_A2H_INT_TX_DONE) {
3292		status &= ~MWL8K_A2H_INT_TX_DONE;
3293		tasklet_schedule(&priv->poll_tx_task);
3294	}
3295
3296	if (status & MWL8K_A2H_INT_RX_READY) {
3297		status &= ~MWL8K_A2H_INT_RX_READY;
3298		tasklet_schedule(&priv->poll_rx_task);
3299	}
3300
3301	if (status)
3302		iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3303
3304	if (status & MWL8K_A2H_INT_OPC_DONE) {
3305		if (priv->hostcmd_wait != NULL)
3306			complete(priv->hostcmd_wait);
3307	}
3308
3309	if (status & MWL8K_A2H_INT_QUEUE_EMPTY) {
3310		if (!mutex_is_locked(&priv->fw_mutex) &&
3311		    priv->radio_on && priv->pending_tx_pkts)
3312			mwl8k_tx_start(priv);
3313	}
3314
3315	return IRQ_HANDLED;
3316}
3317
3318static void mwl8k_tx_poll(unsigned long data)
3319{
3320	struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
3321	struct mwl8k_priv *priv = hw->priv;
3322	int limit;
3323	int i;
3324
3325	limit = 32;
3326
3327	spin_lock_bh(&priv->tx_lock);
3328
3329	for (i = 0; i < MWL8K_TX_QUEUES; i++)
3330		limit -= mwl8k_txq_reclaim(hw, i, limit, 0);
3331
3332	if (!priv->pending_tx_pkts && priv->tx_wait != NULL) {
3333		complete(priv->tx_wait);
3334		priv->tx_wait = NULL;
3335	}
3336
3337	spin_unlock_bh(&priv->tx_lock);
3338
3339	if (limit) {
3340		writel(~MWL8K_A2H_INT_TX_DONE,
3341		       priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3342	} else {
3343		tasklet_schedule(&priv->poll_tx_task);
3344	}
3345}
3346
3347static void mwl8k_rx_poll(unsigned long data)
3348{
3349	struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
3350	struct mwl8k_priv *priv = hw->priv;
3351	int limit;
3352
3353	limit = 32;
3354	limit -= rxq_process(hw, 0, limit);
3355	limit -= rxq_refill(hw, 0, limit);
3356
3357	if (limit) {
3358		writel(~MWL8K_A2H_INT_RX_READY,
3359		       priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3360	} else {
3361		tasklet_schedule(&priv->poll_rx_task);
3362	}
3363}
3364
3365
3366/*
3367 * Core driver operations.
3368 */
3369static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3370{
3371	struct mwl8k_priv *priv = hw->priv;
3372	int index = skb_get_queue_mapping(skb);
3373	int rc;
3374
3375	if (!priv->radio_on) {
3376		wiphy_debug(hw->wiphy,
3377			    "dropped TX frame since radio disabled\n");
3378		dev_kfree_skb(skb);
3379		return NETDEV_TX_OK;
3380	}
3381
3382	rc = mwl8k_txq_xmit(hw, index, skb);
3383
3384	return rc;
3385}
3386
3387static int mwl8k_start(struct ieee80211_hw *hw)
3388{
3389	struct mwl8k_priv *priv = hw->priv;
3390	int rc;
3391
3392	rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
3393			 IRQF_SHARED, MWL8K_NAME, hw);
3394	if (rc) {
3395		wiphy_err(hw->wiphy, "failed to register IRQ handler\n");
3396		return -EIO;
3397	}
3398
3399	/* Enable TX reclaim and RX tasklets.  */
3400	tasklet_enable(&priv->poll_tx_task);
3401	tasklet_enable(&priv->poll_rx_task);
3402
3403	/* Enable interrupts */
3404	iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
3405
3406	rc = mwl8k_fw_lock(hw);
3407	if (!rc) {
3408		rc = mwl8k_cmd_radio_enable(hw);
3409
3410		if (!priv->ap_fw) {
3411			if (!rc)
3412				rc = mwl8k_cmd_enable_sniffer(hw, 0);
3413
3414			if (!rc)
3415				rc = mwl8k_cmd_set_pre_scan(hw);
3416
3417			if (!rc)
3418				rc = mwl8k_cmd_set_post_scan(hw,
3419						"\x00\x00\x00\x00\x00\x00");
3420		}
3421
3422		if (!rc)
3423			rc = mwl8k_cmd_set_rateadapt_mode(hw, 0);
3424
3425		if (!rc)
3426			rc = mwl8k_cmd_set_wmm_mode(hw, 0);
3427
3428		mwl8k_fw_unlock(hw);
3429	}
3430
3431	if (rc) {
3432		iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
3433		free_irq(priv->pdev->irq, hw);
3434		tasklet_disable(&priv->poll_tx_task);
3435		tasklet_disable(&priv->poll_rx_task);
3436	}
3437
3438	return rc;
3439}
3440
3441static void mwl8k_stop(struct ieee80211_hw *hw)
3442{
3443	struct mwl8k_priv *priv = hw->priv;
3444	int i;
3445
3446	mwl8k_cmd_radio_disable(hw);
3447
3448	ieee80211_stop_queues(hw);
3449
3450	/* Disable interrupts */
3451	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
3452	free_irq(priv->pdev->irq, hw);
3453
3454	/* Stop finalize join worker */
3455	cancel_work_sync(&priv->finalize_join_worker);
3456	if (priv->beacon_skb != NULL)
3457		dev_kfree_skb(priv->beacon_skb);
3458
3459	/* Stop TX reclaim and RX tasklets.  */
3460	tasklet_disable(&priv->poll_tx_task);
3461	tasklet_disable(&priv->poll_rx_task);
3462
3463	/* Return all skbs to mac80211 */
3464	for (i = 0; i < MWL8K_TX_QUEUES; i++)
3465		mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
3466}
3467
3468static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image);
3469
3470static int mwl8k_add_interface(struct ieee80211_hw *hw,
3471			       struct ieee80211_vif *vif)
3472{
3473	struct mwl8k_priv *priv = hw->priv;
3474	struct mwl8k_vif *mwl8k_vif;
3475	u32 macids_supported;
3476	int macid, rc;
3477	struct mwl8k_device_info *di;
3478
3479	/*
3480	 * Reject interface creation if sniffer mode is active, as
3481	 * STA operation is mutually exclusive with hardware sniffer
3482	 * mode.  (Sniffer mode is only used on STA firmware.)
3483	 */
3484	if (priv->sniffer_enabled) {
3485		wiphy_info(hw->wiphy,
3486			   "unable to create STA interface because sniffer mode is enabled\n");
3487		return -EINVAL;
3488	}
3489
3490	di = priv->device_info;
3491	switch (vif->type) {
3492	case NL80211_IFTYPE_AP:
3493		if (!priv->ap_fw && di->fw_image_ap) {
3494			/* we must load the ap fw to meet this request */
3495			if (!list_empty(&priv->vif_list))
3496				return -EBUSY;
3497			rc = mwl8k_reload_firmware(hw, di->fw_image_ap);
3498			if (rc)
3499				return rc;
3500		}
3501		macids_supported = priv->ap_macids_supported;
3502		break;
3503	case NL80211_IFTYPE_STATION:
3504		if (priv->ap_fw && di->fw_image_sta) {
3505			/* we must load the sta fw to meet this request */
3506			if (!list_empty(&priv->vif_list))
3507				return -EBUSY;
3508			rc = mwl8k_reload_firmware(hw, di->fw_image_sta);
3509			if (rc)
3510				return rc;
3511		}
3512		macids_supported = priv->sta_macids_supported;
3513		break;
3514	default:
3515		return -EINVAL;
3516	}
3517
3518	macid = ffs(macids_supported & ~priv->macids_used);
3519	if (!macid--)
3520		return -EBUSY;
3521
3522	/* Setup driver private area. */
3523	mwl8k_vif = MWL8K_VIF(vif);
3524	memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
3525	mwl8k_vif->vif = vif;
3526	mwl8k_vif->macid = macid;
3527	mwl8k_vif->seqno = 0;
3528
3529	/* Set the mac address.  */
3530	mwl8k_cmd_set_mac_addr(hw, vif, vif->addr);
3531
3532	if (priv->ap_fw)
3533		mwl8k_cmd_set_new_stn_add_self(hw, vif);
3534
3535	priv->macids_used |= 1 << mwl8k_vif->macid;
3536	list_add_tail(&mwl8k_vif->list, &priv->vif_list);
3537
3538	return 0;
3539}
3540
3541static void mwl8k_remove_interface(struct ieee80211_hw *hw,
3542				   struct ieee80211_vif *vif)
3543{
3544	struct mwl8k_priv *priv = hw->priv;
3545	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
3546
3547	if (priv->ap_fw)
3548		mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr);
3549
3550	mwl8k_cmd_set_mac_addr(hw, vif, "\x00\x00\x00\x00\x00\x00");
3551
3552	priv->macids_used &= ~(1 << mwl8k_vif->macid);
3553	list_del(&mwl8k_vif->list);
3554}
3555
3556static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
3557{
3558	struct ieee80211_conf *conf = &hw->conf;
3559	struct mwl8k_priv *priv = hw->priv;
3560	int rc;
3561
3562	if (conf->flags & IEEE80211_CONF_IDLE) {
3563		mwl8k_cmd_radio_disable(hw);
3564		return 0;
3565	}
3566
3567	rc = mwl8k_fw_lock(hw);
3568	if (rc)
3569		return rc;
3570
3571	rc = mwl8k_cmd_radio_enable(hw);
3572	if (rc)
3573		goto out;
3574
3575	rc = mwl8k_cmd_set_rf_channel(hw, conf);
3576	if (rc)
3577		goto out;
3578
3579	if (conf->power_level > 18)
3580		conf->power_level = 18;
3581
3582	if (priv->ap_fw) {
3583		rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level);
3584		if (rc)
3585			goto out;
3586
3587		rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x7);
3588		if (!rc)
3589			rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_TX, 0x7);
3590	} else {
3591		rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level);
3592		if (rc)
3593			goto out;
3594		rc = mwl8k_cmd_mimo_config(hw, 0x7, 0x7);
3595	}
3596
3597out:
3598	mwl8k_fw_unlock(hw);
3599
3600	return rc;
3601}
3602
3603static void
3604mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3605			   struct ieee80211_bss_conf *info, u32 changed)
3606{
3607	struct mwl8k_priv *priv = hw->priv;
3608	u32 ap_legacy_rates;
3609	u8 ap_mcs_rates[16];
3610	int rc;
3611
3612	if (mwl8k_fw_lock(hw))
3613		return;
3614
3615	/*
3616	 * No need to capture a beacon if we're no longer associated.
3617	 */
3618	if ((changed & BSS_CHANGED_ASSOC) && !vif->bss_conf.assoc)
3619		priv->capture_beacon = false;
3620
3621	/*
3622	 * Get the AP's legacy and MCS rates.
3623	 */
3624	if (vif->bss_conf.assoc) {
3625		struct ieee80211_sta *ap;
3626
3627		rcu_read_lock();
3628
3629		ap = ieee80211_find_sta(vif, vif->bss_conf.bssid);
3630		if (ap == NULL) {
3631			rcu_read_unlock();
3632			goto out;
3633		}
3634
3635		if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
3636			ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ];
3637		} else {
3638			ap_legacy_rates =
3639				ap->supp_rates[IEEE80211_BAND_5GHZ] << 5;
3640		}
3641		memcpy(ap_mcs_rates, ap->ht_cap.mcs.rx_mask, 16);
3642
3643		rcu_read_unlock();
3644	}
3645
3646	if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc) {
3647		rc = mwl8k_cmd_set_rate(hw, vif, ap_legacy_rates, ap_mcs_rates);
3648		if (rc)
3649			goto out;
3650
3651		rc = mwl8k_cmd_use_fixed_rate_sta(hw);
3652		if (rc)
3653			goto out;
3654	}
3655
3656	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
3657		rc = mwl8k_set_radio_preamble(hw,
3658				vif->bss_conf.use_short_preamble);
3659		if (rc)
3660			goto out;
3661	}
3662
3663	if (changed & BSS_CHANGED_ERP_SLOT) {
3664		rc = mwl8k_cmd_set_slot(hw, vif->bss_conf.use_short_slot);
3665		if (rc)
3666			goto out;
3667	}
3668
3669	if (vif->bss_conf.assoc &&
3670	    (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_CTS_PROT |
3671			BSS_CHANGED_HT))) {
3672		rc = mwl8k_cmd_set_aid(hw, vif, ap_legacy_rates);
3673		if (rc)
3674			goto out;
3675	}
3676
3677	if (vif->bss_conf.assoc &&
3678	    (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BEACON_INT))) {
3679		/*
3680		 * Finalize the join.  Tell rx handler to process
3681		 * next beacon from our BSSID.
3682		 */
3683		memcpy(priv->capture_bssid, vif->bss_conf.bssid, ETH_ALEN);
3684		priv->capture_beacon = true;
3685	}
3686
3687out:
3688	mwl8k_fw_unlock(hw);
3689}
3690
3691static void
3692mwl8k_bss_info_changed_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3693			  struct ieee80211_bss_conf *info, u32 changed)
3694{
3695	int rc;
3696
3697	if (mwl8k_fw_lock(hw))
3698		return;
3699
3700	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
3701		rc = mwl8k_set_radio_preamble(hw,
3702				vif->bss_conf.use_short_preamble);
3703		if (rc)
3704			goto out;
3705	}
3706
3707	if (changed & BSS_CHANGED_BASIC_RATES) {
3708		int idx;
3709		int rate;
3710
3711		/*
3712		 * Use lowest supported basic rate for multicasts
3713		 * and management frames (such as probe responses --
3714		 * beacons will always go out at 1 Mb/s).
3715		 */
3716		idx = ffs(vif->bss_conf.basic_rates);
3717		if (idx)
3718			idx--;
3719
3720		if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
3721			rate = mwl8k_rates_24[idx].hw_value;
3722		else
3723			rate = mwl8k_rates_50[idx].hw_value;
3724
3725		mwl8k_cmd_use_fixed_rate_ap(hw, rate, rate);
3726	}
3727
3728	if (changed & (BSS_CHANGED_BEACON_INT | BSS_CHANGED_BEACON)) {
3729		struct sk_buff *skb;
3730
3731		skb = ieee80211_beacon_get(hw, vif);
3732		if (skb != NULL) {
3733			mwl8k_cmd_set_beacon(hw, vif, skb->data, skb->len);
3734			kfree_skb(skb);
3735		}
3736	}
3737
3738	if (changed & BSS_CHANGED_BEACON_ENABLED)
3739		mwl8k_cmd_bss_start(hw, vif, info->enable_beacon);
3740
3741out:
3742	mwl8k_fw_unlock(hw);
3743}
3744
3745static void
3746mwl8k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3747		       struct ieee80211_bss_conf *info, u32 changed)
3748{
3749	struct mwl8k_priv *priv = hw->priv;
3750
3751	if (!priv->ap_fw)
3752		mwl8k_bss_info_changed_sta(hw, vif, info, changed);
3753	else
3754		mwl8k_bss_info_changed_ap(hw, vif, info, changed);
3755}
3756
3757static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
3758				   struct netdev_hw_addr_list *mc_list)
3759{
3760	struct mwl8k_cmd_pkt *cmd;
3761
3762	/*
3763	 * Synthesize and return a command packet that programs the
3764	 * hardware multicast address filter.  At this point we don't
3765	 * know whether FIF_ALLMULTI is being requested, but if it is,
3766	 * we'll end up throwing this packet away and creating a new
3767	 * one in mwl8k_configure_filter().
3768	 */
3769	cmd = __mwl8k_cmd_mac_multicast_adr(hw, 0, mc_list);
3770
3771	return (unsigned long)cmd;
3772}
3773
3774static int
3775mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw,
3776			       unsigned int changed_flags,
3777			       unsigned int *total_flags)
3778{
3779	struct mwl8k_priv *priv = hw->priv;
3780
3781	/*
3782	 * Hardware sniffer mode is mutually exclusive with STA
3783	 * operation, so refuse to enable sniffer mode if a STA
3784	 * interface is active.
3785	 */
3786	if (!list_empty(&priv->vif_list)) {
3787		if (net_ratelimit())
3788			wiphy_info(hw->wiphy,
3789				   "not enabling sniffer mode because STA interface is active\n");
3790		return 0;
3791	}
3792
3793	if (!priv->sniffer_enabled) {
3794		if (mwl8k_cmd_enable_sniffer(hw, 1))
3795			return 0;
3796		priv->sniffer_enabled = true;
3797	}
3798
3799	*total_flags &=	FIF_PROMISC_IN_BSS | FIF_ALLMULTI |
3800			FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL |
3801			FIF_OTHER_BSS;
3802
3803	return 1;
3804}
3805
3806static struct mwl8k_vif *mwl8k_first_vif(struct mwl8k_priv *priv)
3807{
3808	if (!list_empty(&priv->vif_list))
3809		return list_entry(priv->vif_list.next, struct mwl8k_vif, list);
3810
3811	return NULL;
3812}
3813
3814static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3815				   unsigned int changed_flags,
3816				   unsigned int *total_flags,
3817				   u64 multicast)
3818{
3819	struct mwl8k_priv *priv = hw->priv;
3820	struct mwl8k_cmd_pkt *cmd = (void *)(unsigned long)multicast;
3821
3822	/*
3823	 * AP firmware doesn't allow fine-grained control over
3824	 * the receive filter.
3825	 */
3826	if (priv->ap_fw) {
3827		*total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC;
3828		kfree(cmd);
3829		return;
3830	}
3831
3832	/*
3833	 * Enable hardware sniffer mode if FIF_CONTROL or
3834	 * FIF_OTHER_BSS is requested.
3835	 */
3836	if (*total_flags & (FIF_CONTROL | FIF_OTHER_BSS) &&
3837	    mwl8k_configure_filter_sniffer(hw, changed_flags, total_flags)) {
3838		kfree(cmd);
3839		return;
3840	}
3841
3842	/* Clear unsupported feature flags */
3843	*total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC;
3844
3845	if (mwl8k_fw_lock(hw)) {
3846		kfree(cmd);
3847		return;
3848	}
3849
3850	if (priv->sniffer_enabled) {
3851		mwl8k_cmd_enable_sniffer(hw, 0);
3852		priv->sniffer_enabled = false;
3853	}
3854
3855	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
3856		if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
3857			/*
3858			 * Disable the BSS filter.
3859			 */
3860			mwl8k_cmd_set_pre_scan(hw);
3861		} else {
3862			struct mwl8k_vif *mwl8k_vif;
3863			const u8 *bssid;
3864
3865			/*
3866			 * Enable the BSS filter.
3867			 *
3868			 * If there is an active STA interface, use that
3869			 * interface's BSSID, otherwise use a dummy one
3870			 * (where the OUI part needs to be nonzero for
3871			 * the BSSID to be accepted by POST_SCAN).
3872			 */
3873			mwl8k_vif = mwl8k_first_vif(priv);
3874			if (mwl8k_vif != NULL)
3875				bssid = mwl8k_vif->vif->bss_conf.bssid;
3876			else
3877				bssid = "\x01\x00\x00\x00\x00\x00";
3878
3879			mwl8k_cmd_set_post_scan(hw, bssid);
3880		}
3881	}
3882
3883	/*
3884	 * If FIF_ALLMULTI is being requested, throw away the command
3885	 * packet that ->prepare_multicast() built and replace it with
3886	 * a command packet that enables reception of all multicast
3887	 * packets.
3888	 */
3889	if (*total_flags & FIF_ALLMULTI) {
3890		kfree(cmd);
3891		cmd = __mwl8k_cmd_mac_multicast_adr(hw, 1, NULL);
3892	}
3893
3894	if (cmd != NULL) {
3895		mwl8k_post_cmd(hw, cmd);
3896		kfree(cmd);
3897	}
3898
3899	mwl8k_fw_unlock(hw);
3900}
3901
3902static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
3903{
3904	return mwl8k_cmd_set_rts_threshold(hw, value);
3905}
3906
3907static int mwl8k_sta_remove(struct ieee80211_hw *hw,
3908			    struct ieee80211_vif *vif,
3909			    struct ieee80211_sta *sta)
3910{
3911	struct mwl8k_priv *priv = hw->priv;
3912
3913	if (priv->ap_fw)
3914		return mwl8k_cmd_set_new_stn_del(hw, vif, sta->addr);
3915	else
3916		return mwl8k_cmd_update_stadb_del(hw, vif, sta->addr);
3917}
3918
3919static int mwl8k_sta_add(struct ieee80211_hw *hw,
3920			 struct ieee80211_vif *vif,
3921			 struct ieee80211_sta *sta)
3922{
3923	struct mwl8k_priv *priv = hw->priv;
3924	int ret;
3925
3926	if (!priv->ap_fw) {
3927		ret = mwl8k_cmd_update_stadb_add(hw, vif, sta);
3928		if (ret >= 0) {
3929			MWL8K_STA(sta)->peer_id = ret;
3930			return 0;
3931		}
3932
3933		return ret;
3934	}
3935
3936	return mwl8k_cmd_set_new_stn_add(hw, vif, sta);
3937}
3938
3939static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
3940			 const struct ieee80211_tx_queue_params *params)
3941{
3942	struct mwl8k_priv *priv = hw->priv;
3943	int rc;
3944
3945	rc = mwl8k_fw_lock(hw);
3946	if (!rc) {
3947		BUG_ON(queue > MWL8K_TX_QUEUES - 1);
3948		memcpy(&priv->wmm_params[queue], params, sizeof(*params));
3949
3950		if (!priv->wmm_enabled)
3951			rc = mwl8k_cmd_set_wmm_mode(hw, 1);
3952
3953		if (!rc)
3954			rc = mwl8k_cmd_set_edca_params(hw, queue,
3955						       params->cw_min,
3956						       params->cw_max,
3957						       params->aifs,
3958						       params->txop);
3959
3960		mwl8k_fw_unlock(hw);
3961	}
3962
3963	return rc;
3964}
3965
3966static int mwl8k_get_stats(struct ieee80211_hw *hw,
3967			   struct ieee80211_low_level_stats *stats)
3968{
3969	return mwl8k_cmd_get_stat(hw, stats);
3970}
3971
3972static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx,
3973				struct survey_info *survey)
3974{
3975	struct mwl8k_priv *priv = hw->priv;
3976	struct ieee80211_conf *conf = &hw->conf;
3977
3978	if (idx != 0)
3979		return -ENOENT;
3980
3981	survey->channel = conf->channel;
3982	survey->filled = SURVEY_INFO_NOISE_DBM;
3983	survey->noise = priv->noise;
3984
3985	return 0;
3986}
3987
3988static int
3989mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3990		   enum ieee80211_ampdu_mlme_action action,
3991		   struct ieee80211_sta *sta, u16 tid, u16 *ssn)
3992{
3993	switch (action) {
3994	case IEEE80211_AMPDU_RX_START:
3995	case IEEE80211_AMPDU_RX_STOP:
3996		if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
3997			return -ENOTSUPP;
3998		return 0;
3999	default:
4000		return -ENOTSUPP;
4001	}
4002}
4003
4004static const struct ieee80211_ops mwl8k_ops = {
4005	.tx			= mwl8k_tx,
4006	.start			= mwl8k_start,
4007	.stop			= mwl8k_stop,
4008	.add_interface		= mwl8k_add_interface,
4009	.remove_interface	= mwl8k_remove_interface,
4010	.config			= mwl8k_config,
4011	.bss_info_changed	= mwl8k_bss_info_changed,
4012	.prepare_multicast	= mwl8k_prepare_multicast,
4013	.configure_filter	= mwl8k_configure_filter,
4014	.set_rts_threshold	= mwl8k_set_rts_threshold,
4015	.sta_add		= mwl8k_sta_add,
4016	.sta_remove		= mwl8k_sta_remove,
4017	.conf_tx		= mwl8k_conf_tx,
4018	.get_stats		= mwl8k_get_stats,
4019	.get_survey		= mwl8k_get_survey,
4020	.ampdu_action		= mwl8k_ampdu_action,
4021};
4022
4023static void mwl8k_finalize_join_worker(struct work_struct *work)
4024{
4025	struct mwl8k_priv *priv =
4026		container_of(work, struct mwl8k_priv, finalize_join_worker);
4027	struct sk_buff *skb = priv->beacon_skb;
4028	struct ieee80211_mgmt *mgmt = (void *)skb->data;
4029	int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
4030	const u8 *tim = cfg80211_find_ie(WLAN_EID_TIM,
4031					 mgmt->u.beacon.variable, len);
4032	int dtim_period = 1;
4033
4034	if (tim && tim[1] >= 2)
4035		dtim_period = tim[3];
4036
4037	mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period);
4038
4039	dev_kfree_skb(skb);
4040	priv->beacon_skb = NULL;
4041}
4042
4043enum {
4044	MWL8363 = 0,
4045	MWL8687,
4046	MWL8366,
4047};
4048
4049#define MWL8K_8366_AP_FW_API 1
4050#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
4051#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
4052
4053static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = {
4054	[MWL8363] = {
4055		.part_name	= "88w8363",
4056		.helper_image	= "mwl8k/helper_8363.fw",
4057		.fw_image_sta	= "mwl8k/fmimage_8363.fw",
4058	},
4059	[MWL8687] = {
4060		.part_name	= "88w8687",
4061		.helper_image	= "mwl8k/helper_8687.fw",
4062		.fw_image_sta	= "mwl8k/fmimage_8687.fw",
4063	},
4064	[MWL8366] = {
4065		.part_name	= "88w8366",
4066		.helper_image	= "mwl8k/helper_8366.fw",
4067		.fw_image_sta	= "mwl8k/fmimage_8366.fw",
4068		.fw_image_ap	= MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API),
4069		.fw_api_ap	= MWL8K_8366_AP_FW_API,
4070		.ap_rxd_ops	= &rxd_8366_ap_ops,
4071	},
4072};
4073
4074MODULE_FIRMWARE("mwl8k/helper_8363.fw");
4075MODULE_FIRMWARE("mwl8k/fmimage_8363.fw");
4076MODULE_FIRMWARE("mwl8k/helper_8687.fw");
4077MODULE_FIRMWARE("mwl8k/fmimage_8687.fw");
4078MODULE_FIRMWARE("mwl8k/helper_8366.fw");
4079MODULE_FIRMWARE("mwl8k/fmimage_8366.fw");
4080MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
4081
4082static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
4083	{ PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
4084	{ PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },
4085	{ PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, },
4086	{ PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, },
4087	{ PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = MWL8687, },
4088	{ PCI_VDEVICE(MARVELL, 0x2a40), .driver_data = MWL8366, },
4089	{ PCI_VDEVICE(MARVELL, 0x2a43), .driver_data = MWL8366, },
4090	{ },
4091};
4092MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table);
4093
4094static int mwl8k_request_alt_fw(struct mwl8k_priv *priv)
4095{
4096	int rc;
4097	printk(KERN_ERR "%s: Error requesting preferred fw %s.\n"
4098	       "Trying alternative firmware %s\n", pci_name(priv->pdev),
4099	       priv->fw_pref, priv->fw_alt);
4100	rc = mwl8k_request_fw(priv, priv->fw_alt, &priv->fw_ucode, true);
4101	if (rc) {
4102		printk(KERN_ERR "%s: Error requesting alt fw %s\n",
4103		       pci_name(priv->pdev), priv->fw_alt);
4104		return rc;
4105	}
4106	return 0;
4107}
4108
4109static int mwl8k_firmware_load_success(struct mwl8k_priv *priv);
4110static void mwl8k_fw_state_machine(const struct firmware *fw, void *context)
4111{
4112	struct mwl8k_priv *priv = context;
4113	struct mwl8k_device_info *di = priv->device_info;
4114	int rc;
4115
4116	switch (priv->fw_state) {
4117	case FW_STATE_INIT:
4118		if (!fw) {
4119			printk(KERN_ERR "%s: Error requesting helper fw %s\n",
4120			       pci_name(priv->pdev), di->helper_image);
4121			goto fail;
4122		}
4123		priv->fw_helper = fw;
4124		rc = mwl8k_request_fw(priv, priv->fw_pref, &priv->fw_ucode,
4125				      true);
4126		if (rc && priv->fw_alt) {
4127			rc = mwl8k_request_alt_fw(priv);
4128			if (rc)
4129				goto fail;
4130			priv->fw_state = FW_STATE_LOADING_ALT;
4131		} else if (rc)
4132			goto fail;
4133		else
4134			priv->fw_state = FW_STATE_LOADING_PREF;
4135		break;
4136
4137	case FW_STATE_LOADING_PREF:
4138		if (!fw) {
4139			if (priv->fw_alt) {
4140				rc = mwl8k_request_alt_fw(priv);
4141				if (rc)
4142					goto fail;
4143				priv->fw_state = FW_STATE_LOADING_ALT;
4144			} else
4145				goto fail;
4146		} else {
4147			priv->fw_ucode = fw;
4148			rc = mwl8k_firmware_load_success(priv);
4149			if (rc)
4150				goto fail;
4151			else
4152				complete(&priv->firmware_loading_complete);
4153		}
4154		break;
4155
4156	case FW_STATE_LOADING_ALT:
4157		if (!fw) {
4158			printk(KERN_ERR "%s: Error requesting alt fw %s\n",
4159			       pci_name(priv->pdev), di->helper_image);
4160			goto fail;
4161		}
4162		priv->fw_ucode = fw;
4163		rc = mwl8k_firmware_load_success(priv);
4164		if (rc)
4165			goto fail;
4166		else
4167			complete(&priv->firmware_loading_complete);
4168		break;
4169
4170	default:
4171		printk(KERN_ERR "%s: Unexpected firmware loading state: %d\n",
4172		       MWL8K_NAME, priv->fw_state);
4173		BUG_ON(1);
4174	}
4175
4176	return;
4177
4178fail:
4179	priv->fw_state = FW_STATE_ERROR;
4180	complete(&priv->firmware_loading_complete);
4181	device_release_driver(&priv->pdev->dev);
4182	mwl8k_release_firmware(priv);
4183}
4184
4185static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image,
4186			       bool nowait)
4187{
4188	struct mwl8k_priv *priv = hw->priv;
4189	int rc;
4190
4191	/* Reset firmware and hardware */
4192	mwl8k_hw_reset(priv);
4193
4194	/* Ask userland hotplug daemon for the device firmware */
4195	rc = mwl8k_request_firmware(priv, fw_image, nowait);
4196	if (rc) {
4197		wiphy_err(hw->wiphy, "Firmware files not found\n");
4198		return rc;
4199	}
4200
4201	if (nowait)
4202		return rc;
4203
4204	/* Load firmware into hardware */
4205	rc = mwl8k_load_firmware(hw);
4206	if (rc)
4207		wiphy_err(hw->wiphy, "Cannot start firmware\n");
4208
4209	/* Reclaim memory once firmware is successfully loaded */
4210	mwl8k_release_firmware(priv);
4211
4212	return rc;
4213}
4214
4215/* initialize hw after successfully loading a firmware image */
4216static int mwl8k_probe_hw(struct ieee80211_hw *hw)
4217{
4218	struct mwl8k_priv *priv = hw->priv;
4219	int rc = 0;
4220	int i;
4221
4222	if (priv->ap_fw) {
4223		priv->rxd_ops = priv->device_info->ap_rxd_ops;
4224		if (priv->rxd_ops == NULL) {
4225			wiphy_err(hw->wiphy,
4226				  "Driver does not have AP firmware image support for this hardware\n");
4227			goto err_stop_firmware;
4228		}
4229	} else {
4230		priv->rxd_ops = &rxd_sta_ops;
4231	}
4232
4233	priv->sniffer_enabled = false;
4234	priv->wmm_enabled = false;
4235	priv->pending_tx_pkts = 0;
4236
4237	rc = mwl8k_rxq_init(hw, 0);
4238	if (rc)
4239		goto err_stop_firmware;
4240	rxq_refill(hw, 0, INT_MAX);
4241
4242	for (i = 0; i < MWL8K_TX_QUEUES; i++) {
4243		rc = mwl8k_txq_init(hw, i);
4244		if (rc)
4245			goto err_free_queues;
4246	}
4247
4248	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
4249	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
4250	iowrite32(MWL8K_A2H_INT_TX_DONE | MWL8K_A2H_INT_RX_READY,
4251		  priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
4252	iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
4253
4254	rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
4255			 IRQF_SHARED, MWL8K_NAME, hw);
4256	if (rc) {
4257		wiphy_err(hw->wiphy, "failed to register IRQ handler\n");
4258		goto err_free_queues;
4259	}
4260
4261	/*
4262	 * Temporarily enable interrupts.  Initial firmware host
4263	 * commands use interrupts and avoid polling.  Disable
4264	 * interrupts when done.
4265	 */
4266	iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
4267
4268	/* Get config data, mac addrs etc */
4269	if (priv->ap_fw) {
4270		rc = mwl8k_cmd_get_hw_spec_ap(hw);
4271		if (!rc)
4272			rc = mwl8k_cmd_set_hw_spec(hw);
4273	} else {
4274		rc = mwl8k_cmd_get_hw_spec_sta(hw);
4275	}
4276	if (rc) {
4277		wiphy_err(hw->wiphy, "Cannot initialise firmware\n");
4278		goto err_free_irq;
4279	}
4280
4281	/* Turn radio off */
4282	rc = mwl8k_cmd_radio_disable(hw);
4283	if (rc) {
4284		wiphy_err(hw->wiphy, "Cannot disable\n");
4285		goto err_free_irq;
4286	}
4287
4288	/* Clear MAC address */
4289	rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00");
4290	if (rc) {
4291		wiphy_err(hw->wiphy, "Cannot clear MAC address\n");
4292		goto err_free_irq;
4293	}
4294
4295	/* Disable interrupts */
4296	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
4297	free_irq(priv->pdev->irq, hw);
4298
4299	wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n",
4300		   priv->device_info->part_name,
4301		   priv->hw_rev, hw->wiphy->perm_addr,
4302		   priv->ap_fw ? "AP" : "STA",
4303		   (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff,
4304		   (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff);
4305
4306	return 0;
4307
4308err_free_irq:
4309	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
4310	free_irq(priv->pdev->irq, hw);
4311
4312err_free_queues:
4313	for (i = 0; i < MWL8K_TX_QUEUES; i++)
4314		mwl8k_txq_deinit(hw, i);
4315	mwl8k_rxq_deinit(hw, 0);
4316
4317err_stop_firmware:
4318	mwl8k_hw_reset(priv);
4319
4320	return rc;
4321}
4322
4323/*
4324 * invoke mwl8k_reload_firmware to change the firmware image after the device
4325 * has already been registered
4326 */
4327static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image)
4328{
4329	int i, rc = 0;
4330	struct mwl8k_priv *priv = hw->priv;
4331
4332	mwl8k_stop(hw);
4333	mwl8k_rxq_deinit(hw, 0);
4334
4335	for (i = 0; i < MWL8K_TX_QUEUES; i++)
4336		mwl8k_txq_deinit(hw, i);
4337
4338	rc = mwl8k_init_firmware(hw, fw_image, false);
4339	if (rc)
4340		goto fail;
4341
4342	rc = mwl8k_probe_hw(hw);
4343	if (rc)
4344		goto fail;
4345
4346	rc = mwl8k_start(hw);
4347	if (rc)
4348		goto fail;
4349
4350	rc = mwl8k_config(hw, ~0);
4351	if (rc)
4352		goto fail;
4353
4354	for (i = 0; i < MWL8K_TX_QUEUES; i++) {
4355		rc = mwl8k_conf_tx(hw, i, &priv->wmm_params[i]);
4356		if (rc)
4357			goto fail;
4358	}
4359
4360	return rc;
4361
4362fail:
4363	printk(KERN_WARNING "mwl8k: Failed to reload firmware image.\n");
4364	return rc;
4365}
4366
4367static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
4368{
4369	struct ieee80211_hw *hw = priv->hw;
4370	int i, rc;
4371
4372	rc = mwl8k_load_firmware(hw);
4373	mwl8k_release_firmware(priv);
4374	if (rc) {
4375		wiphy_err(hw->wiphy, "Cannot start firmware\n");
4376		return rc;
4377	}
4378
4379	/*
4380	 * Extra headroom is the size of the required DMA header
4381	 * minus the size of the smallest 802.11 frame (CTS frame).
4382	 */
4383	hw->extra_tx_headroom =
4384		sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts);
4385
4386	hw->channel_change_time = 10;
4387
4388	hw->queues = MWL8K_TX_QUEUES;
4389
4390	/* Set rssi values to dBm */
4391	hw->flags |= IEEE80211_HW_SIGNAL_DBM;
4392	hw->vif_data_size = sizeof(struct mwl8k_vif);
4393	hw->sta_data_size = sizeof(struct mwl8k_sta);
4394
4395	priv->macids_used = 0;
4396	INIT_LIST_HEAD(&priv->vif_list);
4397
4398	/* Set default radio state and preamble */
4399	priv->radio_on = 0;
4400	priv->radio_short_preamble = 0;
4401
4402	/* Finalize join worker */
4403	INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
4404
4405	/* TX reclaim and RX tasklets.  */
4406	tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
4407	tasklet_disable(&priv->poll_tx_task);
4408	tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw);
4409	tasklet_disable(&priv->poll_rx_task);
4410
4411	/* Power management cookie */
4412	priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
4413	if (priv->cookie == NULL)
4414		return -ENOMEM;
4415
4416	mutex_init(&priv->fw_mutex);
4417	priv->fw_mutex_owner = NULL;
4418	priv->fw_mutex_depth = 0;
4419	priv->hostcmd_wait = NULL;
4420
4421	spin_lock_init(&priv->tx_lock);
4422
4423	priv->tx_wait = NULL;
4424
4425	rc = mwl8k_probe_hw(hw);
4426	if (rc)
4427		goto err_free_cookie;
4428
4429	hw->wiphy->interface_modes = 0;
4430	if (priv->ap_macids_supported || priv->device_info->fw_image_ap)
4431		hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
4432	if (priv->sta_macids_supported || priv->device_info->fw_image_sta)
4433		hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
4434
4435	rc = ieee80211_register_hw(hw);
4436	if (rc) {
4437		wiphy_err(hw->wiphy, "Cannot register device\n");
4438		goto err_unprobe_hw;
4439	}
4440
4441	return 0;
4442
4443err_unprobe_hw:
4444	for (i = 0; i < MWL8K_TX_QUEUES; i++)
4445		mwl8k_txq_deinit(hw, i);
4446	mwl8k_rxq_deinit(hw, 0);
4447
4448err_free_cookie:
4449	if (priv->cookie != NULL)
4450		pci_free_consistent(priv->pdev, 4,
4451				priv->cookie, priv->cookie_dma);
4452
4453	return rc;
4454}
4455static int __devinit mwl8k_probe(struct pci_dev *pdev,
4456				 const struct pci_device_id *id)
4457{
4458	static int printed_version;
4459	struct ieee80211_hw *hw;
4460	struct mwl8k_priv *priv;
4461	struct mwl8k_device_info *di;
4462	int rc;
4463
4464	if (!printed_version) {
4465		printk(KERN_INFO "%s version %s\n", MWL8K_DESC, MWL8K_VERSION);
4466		printed_version = 1;
4467	}
4468
4469
4470	rc = pci_enable_device(pdev);
4471	if (rc) {
4472		printk(KERN_ERR "%s: Cannot enable new PCI device\n",
4473		       MWL8K_NAME);
4474		return rc;
4475	}
4476
4477	rc = pci_request_regions(pdev, MWL8K_NAME);
4478	if (rc) {
4479		printk(KERN_ERR "%s: Cannot obtain PCI resources\n",
4480		       MWL8K_NAME);
4481		goto err_disable_device;
4482	}
4483
4484	pci_set_master(pdev);
4485
4486
4487	hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops);
4488	if (hw == NULL) {
4489		printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME);
4490		rc = -ENOMEM;
4491		goto err_free_reg;
4492	}
4493
4494	SET_IEEE80211_DEV(hw, &pdev->dev);
4495	pci_set_drvdata(pdev, hw);
4496
4497	priv = hw->priv;
4498	priv->hw = hw;
4499	priv->pdev = pdev;
4500	priv->device_info = &mwl8k_info_tbl[id->driver_data];
4501
4502
4503	priv->sram = pci_iomap(pdev, 0, 0x10000);
4504	if (priv->sram == NULL) {
4505		wiphy_err(hw->wiphy, "Cannot map device SRAM\n");
4506		goto err_iounmap;
4507	}
4508
4509	/*
4510	 * If BAR0 is a 32 bit BAR, the register BAR will be BAR1.
4511	 * If BAR0 is a 64 bit BAR, the register BAR will be BAR2.
4512	 */
4513	priv->regs = pci_iomap(pdev, 1, 0x10000);
4514	if (priv->regs == NULL) {
4515		priv->regs = pci_iomap(pdev, 2, 0x10000);
4516		if (priv->regs == NULL) {
4517			wiphy_err(hw->wiphy, "Cannot map device registers\n");
4518			goto err_iounmap;
4519		}
4520	}
4521
4522	/*
4523	 * Choose the initial fw image depending on user input.  If a second
4524	 * image is available, make it the alternative image that will be
4525	 * loaded if the first one fails.
4526	 */
4527	init_completion(&priv->firmware_loading_complete);
4528	di = priv->device_info;
4529	if (ap_mode_default && di->fw_image_ap) {
4530		priv->fw_pref = di->fw_image_ap;
4531		priv->fw_alt = di->fw_image_sta;
4532	} else if (!ap_mode_default && di->fw_image_sta) {
4533		priv->fw_pref = di->fw_image_sta;
4534		priv->fw_alt = di->fw_image_ap;
4535	} else if (ap_mode_default && !di->fw_image_ap && di->fw_image_sta) {
4536		printk(KERN_WARNING "AP fw is unavailable.  Using STA fw.");
4537		priv->fw_pref = di->fw_image_sta;
4538	} else if (!ap_mode_default && !di->fw_image_sta && di->fw_image_ap) {
4539		printk(KERN_WARNING "STA fw is unavailable.  Using AP fw.");
4540		priv->fw_pref = di->fw_image_ap;
4541	}
4542	rc = mwl8k_init_firmware(hw, priv->fw_pref, true);
4543	if (rc)
4544		goto err_stop_firmware;
4545	return rc;
4546
4547err_stop_firmware:
4548	mwl8k_hw_reset(priv);
4549
4550err_iounmap:
4551	if (priv->regs != NULL)
4552		pci_iounmap(pdev, priv->regs);
4553
4554	if (priv->sram != NULL)
4555		pci_iounmap(pdev, priv->sram);
4556
4557	pci_set_drvdata(pdev, NULL);
4558	ieee80211_free_hw(hw);
4559
4560err_free_reg:
4561	pci_release_regions(pdev);
4562
4563err_disable_device:
4564	pci_disable_device(pdev);
4565
4566	return rc;
4567}
4568
4569static void __devexit mwl8k_shutdown(struct pci_dev *pdev)
4570{
4571	printk(KERN_ERR "===>%s(%u)\n", __func__, __LINE__);
4572}
4573
4574static void __devexit mwl8k_remove(struct pci_dev *pdev)
4575{
4576	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
4577	struct mwl8k_priv *priv;
4578	int i;
4579
4580	if (hw == NULL)
4581		return;
4582	priv = hw->priv;
4583
4584	wait_for_completion(&priv->firmware_loading_complete);
4585
4586	if (priv->fw_state == FW_STATE_ERROR) {
4587		mwl8k_hw_reset(priv);
4588		goto unmap;
4589	}
4590
4591	ieee80211_stop_queues(hw);
4592
4593	ieee80211_unregister_hw(hw);
4594
4595	/* Remove TX reclaim and RX tasklets.  */
4596	tasklet_kill(&priv->poll_tx_task);
4597	tasklet_kill(&priv->poll_rx_task);
4598
4599	/* Stop hardware */
4600	mwl8k_hw_reset(priv);
4601
4602	/* Return all skbs to mac80211 */
4603	for (i = 0; i < MWL8K_TX_QUEUES; i++)
4604		mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
4605
4606	for (i = 0; i < MWL8K_TX_QUEUES; i++)
4607		mwl8k_txq_deinit(hw, i);
4608
4609	mwl8k_rxq_deinit(hw, 0);
4610
4611	pci_free_consistent(priv->pdev, 4, priv->cookie, priv->cookie_dma);
4612
4613unmap:
4614	pci_iounmap(pdev, priv->regs);
4615	pci_iounmap(pdev, priv->sram);
4616	pci_set_drvdata(pdev, NULL);
4617	ieee80211_free_hw(hw);
4618	pci_release_regions(pdev);
4619	pci_disable_device(pdev);
4620}
4621
4622static struct pci_driver mwl8k_driver = {
4623	.name		= MWL8K_NAME,
4624	.id_table	= mwl8k_pci_id_table,
4625	.probe		= mwl8k_probe,
4626	.remove		= __devexit_p(mwl8k_remove),
4627	.shutdown	= __devexit_p(mwl8k_shutdown),
4628};
4629
4630static int __init mwl8k_init(void)
4631{
4632	return pci_register_driver(&mwl8k_driver);
4633}
4634
4635static void __exit mwl8k_exit(void)
4636{
4637	pci_unregister_driver(&mwl8k_driver);
4638}
4639
4640module_init(mwl8k_init);
4641module_exit(mwl8k_exit);
4642
4643MODULE_DESCRIPTION(MWL8K_DESC);
4644MODULE_VERSION(MWL8K_VERSION);
4645MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com>");
4646MODULE_LICENSE("GPL");
4647