mwl8k: dma header manipulations can't fail
[pandora-kernel.git] / drivers / net / wireless / mwl8k.c
1 /*
2  * drivers/net/wireless/mwl8k.c
3  * Driver for Marvell TOPDOG 802.11 Wireless cards
4  *
5  * Copyright (C) 2008 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/spinlock.h>
16 #include <linux/list.h>
17 #include <linux/pci.h>
18 #include <linux/delay.h>
19 #include <linux/completion.h>
20 #include <linux/etherdevice.h>
21 #include <net/mac80211.h>
22 #include <linux/moduleparam.h>
23 #include <linux/firmware.h>
24 #include <linux/workqueue.h>
25
26 #define MWL8K_DESC      "Marvell TOPDOG(R) 802.11 Wireless Network Driver"
27 #define MWL8K_NAME      KBUILD_MODNAME
28 #define MWL8K_VERSION   "0.9.1"
29
30 MODULE_DESCRIPTION(MWL8K_DESC);
31 MODULE_VERSION(MWL8K_VERSION);
32 MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com>");
33 MODULE_LICENSE("GPL");
34
35 static DEFINE_PCI_DEVICE_TABLE(mwl8k_table) = {
36         { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = 8687, },
37         { PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = 8687, },
38         { }
39 };
40 MODULE_DEVICE_TABLE(pci, mwl8k_table);
41
42 /* Register definitions */
43 #define MWL8K_HIU_GEN_PTR                       0x00000c10
44 #define  MWL8K_MODE_STA                          0x0000005a
45 #define  MWL8K_MODE_AP                           0x000000a5
46 #define MWL8K_HIU_INT_CODE                      0x00000c14
47 #define  MWL8K_FWSTA_READY                       0xf0f1f2f4
48 #define  MWL8K_FWAP_READY                        0xf1f2f4a5
49 #define  MWL8K_INT_CODE_CMD_FINISHED             0x00000005
50 #define MWL8K_HIU_SCRATCH                       0x00000c40
51
52 /* Host->device communications */
53 #define MWL8K_HIU_H2A_INTERRUPT_EVENTS          0x00000c18
54 #define MWL8K_HIU_H2A_INTERRUPT_STATUS          0x00000c1c
55 #define MWL8K_HIU_H2A_INTERRUPT_MASK            0x00000c20
56 #define MWL8K_HIU_H2A_INTERRUPT_CLEAR_SEL       0x00000c24
57 #define MWL8K_HIU_H2A_INTERRUPT_STATUS_MASK     0x00000c28
58 #define  MWL8K_H2A_INT_DUMMY                     (1 << 20)
59 #define  MWL8K_H2A_INT_RESET                     (1 << 15)
60 #define  MWL8K_H2A_INT_DOORBELL                  (1 << 1)
61 #define  MWL8K_H2A_INT_PPA_READY                 (1 << 0)
62
63 /* Device->host communications */
64 #define MWL8K_HIU_A2H_INTERRUPT_EVENTS          0x00000c2c
65 #define MWL8K_HIU_A2H_INTERRUPT_STATUS          0x00000c30
66 #define MWL8K_HIU_A2H_INTERRUPT_MASK            0x00000c34
67 #define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL       0x00000c38
68 #define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK     0x00000c3c
69 #define  MWL8K_A2H_INT_DUMMY                     (1 << 20)
70 #define  MWL8K_A2H_INT_CHNL_SWITCHED             (1 << 11)
71 #define  MWL8K_A2H_INT_QUEUE_EMPTY               (1 << 10)
72 #define  MWL8K_A2H_INT_RADAR_DETECT              (1 << 7)
73 #define  MWL8K_A2H_INT_RADIO_ON                  (1 << 6)
74 #define  MWL8K_A2H_INT_RADIO_OFF                 (1 << 5)
75 #define  MWL8K_A2H_INT_MAC_EVENT                 (1 << 3)
76 #define  MWL8K_A2H_INT_OPC_DONE                  (1 << 2)
77 #define  MWL8K_A2H_INT_RX_READY                  (1 << 1)
78 #define  MWL8K_A2H_INT_TX_DONE                   (1 << 0)
79
80 #define MWL8K_A2H_EVENTS        (MWL8K_A2H_INT_DUMMY | \
81                                  MWL8K_A2H_INT_CHNL_SWITCHED | \
82                                  MWL8K_A2H_INT_QUEUE_EMPTY | \
83                                  MWL8K_A2H_INT_RADAR_DETECT | \
84                                  MWL8K_A2H_INT_RADIO_ON | \
85                                  MWL8K_A2H_INT_RADIO_OFF | \
86                                  MWL8K_A2H_INT_MAC_EVENT | \
87                                  MWL8K_A2H_INT_OPC_DONE | \
88                                  MWL8K_A2H_INT_RX_READY | \
89                                  MWL8K_A2H_INT_TX_DONE)
90
91 /* WME stream classes */
92 #define WME_AC_BE       0               /* best effort */
93 #define WME_AC_BK       1               /* background */
94 #define WME_AC_VI       2               /* video */
95 #define WME_AC_VO       3               /* voice */
96
97 #define MWL8K_RX_QUEUES         1
98 #define MWL8K_TX_QUEUES         4
99
100 struct mwl8k_rx_queue {
101         int rx_desc_count;
102
103         /* hw receives here */
104         int rx_head;
105
106         /* refill descs here */
107         int rx_tail;
108
109         struct mwl8k_rx_desc *rx_desc_area;
110         dma_addr_t rx_desc_dma;
111         struct sk_buff **rx_skb;
112 };
113
114 struct mwl8k_tx_queue {
115         /* hw transmits here */
116         int tx_head;
117
118         /* sw appends here */
119         int tx_tail;
120
121         struct ieee80211_tx_queue_stats tx_stats;
122         struct mwl8k_tx_desc *tx_desc_area;
123         dma_addr_t tx_desc_dma;
124         struct sk_buff **tx_skb;
125 };
126
127 /* Pointers to the firmware data and meta information about it.  */
128 struct mwl8k_firmware {
129         /* Microcode */
130         struct firmware *ucode;
131
132         /* Boot helper code */
133         struct firmware *helper;
134 };
135
136 struct mwl8k_priv {
137         void __iomem *regs;
138         struct ieee80211_hw *hw;
139
140         struct pci_dev *pdev;
141         u8 name[16];
142         /* firmware access lock */
143         spinlock_t fw_lock;
144
145         /* firmware files and meta data */
146         struct mwl8k_firmware fw;
147         u32 part_num;
148
149         /* lock held over TX and TX reap */
150         spinlock_t tx_lock;
151
152         struct ieee80211_vif *vif;
153
154         struct ieee80211_channel *current_channel;
155
156         /* power management status cookie from firmware */
157         u32 *cookie;
158         dma_addr_t cookie_dma;
159
160         u16 num_mcaddrs;
161         u8 hw_rev;
162         __le32 fw_rev;
163
164         /*
165          * Running count of TX packets in flight, to avoid
166          * iterating over the transmit rings each time.
167          */
168         int pending_tx_pkts;
169
170         struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
171         struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES];
172
173         /* PHY parameters */
174         struct ieee80211_supported_band band;
175         struct ieee80211_channel channels[14];
176         struct ieee80211_rate rates[12];
177
178         bool radio_on;
179         bool radio_short_preamble;
180         bool wmm_enabled;
181
182         /* Set if PHY config is in progress */
183         bool inconfig;
184
185         /* XXX need to convert this to handle multiple interfaces */
186         bool capture_beacon;
187         u8 capture_bssid[ETH_ALEN];
188         struct sk_buff *beacon_skb;
189
190         /*
191          * This FJ worker has to be global as it is scheduled from the
192          * RX handler.  At this point we don't know which interface it
193          * belongs to until the list of bssids waiting to complete join
194          * is checked.
195          */
196         struct work_struct finalize_join_worker;
197
198         /* Tasklet to reclaim TX descriptors and buffers after tx */
199         struct tasklet_struct tx_reclaim_task;
200
201         /* Work thread to serialize configuration requests */
202         struct workqueue_struct *config_wq;
203         struct completion *hostcmd_wait;
204         struct completion *tx_wait;
205 };
206
207 /* Per interface specific private data */
208 struct mwl8k_vif {
209         /* backpointer to parent config block */
210         struct mwl8k_priv *priv;
211
212         /* BSS config of AP or IBSS from mac80211*/
213         struct ieee80211_bss_conf bss_info;
214
215         /* BSSID of AP or IBSS */
216         u8      bssid[ETH_ALEN];
217         u8      mac_addr[ETH_ALEN];
218
219         /*
220          * Subset of supported legacy rates.
221          * Intersection of AP and STA supported rates.
222          */
223         struct ieee80211_rate legacy_rates[12];
224
225         /* number of supported legacy rates */
226         u8      legacy_nrates;
227
228          /* Index into station database.Returned by update_sta_db call */
229         u8      peer_id;
230
231         /* Non AMPDU sequence number assigned by driver */
232         u16     seqno;
233 };
234
235 #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
236
237 static const struct ieee80211_channel mwl8k_channels[] = {
238         { .center_freq = 2412, .hw_value = 1, },
239         { .center_freq = 2417, .hw_value = 2, },
240         { .center_freq = 2422, .hw_value = 3, },
241         { .center_freq = 2427, .hw_value = 4, },
242         { .center_freq = 2432, .hw_value = 5, },
243         { .center_freq = 2437, .hw_value = 6, },
244         { .center_freq = 2442, .hw_value = 7, },
245         { .center_freq = 2447, .hw_value = 8, },
246         { .center_freq = 2452, .hw_value = 9, },
247         { .center_freq = 2457, .hw_value = 10, },
248         { .center_freq = 2462, .hw_value = 11, },
249 };
250
251 static const struct ieee80211_rate mwl8k_rates[] = {
252         { .bitrate = 10, .hw_value = 2, },
253         { .bitrate = 20, .hw_value = 4, },
254         { .bitrate = 55, .hw_value = 11, },
255         { .bitrate = 60, .hw_value = 12, },
256         { .bitrate = 90, .hw_value = 18, },
257         { .bitrate = 110, .hw_value = 22, },
258         { .bitrate = 120, .hw_value = 24, },
259         { .bitrate = 180, .hw_value = 36, },
260         { .bitrate = 240, .hw_value = 48, },
261         { .bitrate = 360, .hw_value = 72, },
262         { .bitrate = 480, .hw_value = 96, },
263         { .bitrate = 540, .hw_value = 108, },
264 };
265
266 /* Set or get info from Firmware */
267 #define MWL8K_CMD_SET                   0x0001
268 #define MWL8K_CMD_GET                   0x0000
269
270 /* Firmware command codes */
271 #define MWL8K_CMD_CODE_DNLD             0x0001
272 #define MWL8K_CMD_GET_HW_SPEC           0x0003
273 #define MWL8K_CMD_MAC_MULTICAST_ADR     0x0010
274 #define MWL8K_CMD_GET_STAT              0x0014
275 #define MWL8K_CMD_RADIO_CONTROL         0x001c
276 #define MWL8K_CMD_RF_TX_POWER           0x001e
277 #define MWL8K_CMD_SET_PRE_SCAN          0x0107
278 #define MWL8K_CMD_SET_POST_SCAN         0x0108
279 #define MWL8K_CMD_SET_RF_CHANNEL        0x010a
280 #define MWL8K_CMD_SET_AID               0x010d
281 #define MWL8K_CMD_SET_RATE              0x0110
282 #define MWL8K_CMD_SET_FINALIZE_JOIN     0x0111
283 #define MWL8K_CMD_RTS_THRESHOLD         0x0113
284 #define MWL8K_CMD_SET_SLOT              0x0114
285 #define MWL8K_CMD_SET_EDCA_PARAMS       0x0115
286 #define MWL8K_CMD_SET_WMM_MODE          0x0123
287 #define MWL8K_CMD_MIMO_CONFIG           0x0125
288 #define MWL8K_CMD_USE_FIXED_RATE        0x0126
289 #define MWL8K_CMD_ENABLE_SNIFFER        0x0150
290 #define MWL8K_CMD_SET_RATEADAPT_MODE    0x0203
291 #define MWL8K_CMD_UPDATE_STADB          0x1123
292
293 static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
294 {
295 #define MWL8K_CMDNAME(x)        case MWL8K_CMD_##x: do {\
296                                         snprintf(buf, bufsize, "%s", #x);\
297                                         return buf;\
298                                         } while (0)
299         switch (cmd & ~0x8000) {
300                 MWL8K_CMDNAME(CODE_DNLD);
301                 MWL8K_CMDNAME(GET_HW_SPEC);
302                 MWL8K_CMDNAME(MAC_MULTICAST_ADR);
303                 MWL8K_CMDNAME(GET_STAT);
304                 MWL8K_CMDNAME(RADIO_CONTROL);
305                 MWL8K_CMDNAME(RF_TX_POWER);
306                 MWL8K_CMDNAME(SET_PRE_SCAN);
307                 MWL8K_CMDNAME(SET_POST_SCAN);
308                 MWL8K_CMDNAME(SET_RF_CHANNEL);
309                 MWL8K_CMDNAME(SET_AID);
310                 MWL8K_CMDNAME(SET_RATE);
311                 MWL8K_CMDNAME(SET_FINALIZE_JOIN);
312                 MWL8K_CMDNAME(RTS_THRESHOLD);
313                 MWL8K_CMDNAME(SET_SLOT);
314                 MWL8K_CMDNAME(SET_EDCA_PARAMS);
315                 MWL8K_CMDNAME(SET_WMM_MODE);
316                 MWL8K_CMDNAME(MIMO_CONFIG);
317                 MWL8K_CMDNAME(USE_FIXED_RATE);
318                 MWL8K_CMDNAME(ENABLE_SNIFFER);
319                 MWL8K_CMDNAME(SET_RATEADAPT_MODE);
320                 MWL8K_CMDNAME(UPDATE_STADB);
321         default:
322                 snprintf(buf, bufsize, "0x%x", cmd);
323         }
324 #undef MWL8K_CMDNAME
325
326         return buf;
327 }
328
329 /* Hardware and firmware reset */
330 static void mwl8k_hw_reset(struct mwl8k_priv *priv)
331 {
332         iowrite32(MWL8K_H2A_INT_RESET,
333                 priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
334         iowrite32(MWL8K_H2A_INT_RESET,
335                 priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
336         msleep(20);
337 }
338
339 /* Release fw image */
340 static void mwl8k_release_fw(struct firmware **fw)
341 {
342         if (*fw == NULL)
343                 return;
344         release_firmware(*fw);
345         *fw = NULL;
346 }
347
348 static void mwl8k_release_firmware(struct mwl8k_priv *priv)
349 {
350         mwl8k_release_fw(&priv->fw.ucode);
351         mwl8k_release_fw(&priv->fw.helper);
352 }
353
354 /* Request fw image */
355 static int mwl8k_request_fw(struct mwl8k_priv *priv,
356                                 const char *fname, struct firmware **fw)
357 {
358         /* release current image */
359         if (*fw != NULL)
360                 mwl8k_release_fw(fw);
361
362         return request_firmware((const struct firmware **)fw,
363                                                 fname, &priv->pdev->dev);
364 }
365
366 static int mwl8k_request_firmware(struct mwl8k_priv *priv, u32 part_num)
367 {
368         u8 filename[64];
369         int rc;
370
371         priv->part_num = part_num;
372
373         snprintf(filename, sizeof(filename),
374                  "mwl8k/helper_%u.fw", priv->part_num);
375
376         rc = mwl8k_request_fw(priv, filename, &priv->fw.helper);
377         if (rc) {
378                 printk(KERN_ERR
379                         "%s Error requesting helper firmware file %s\n",
380                         pci_name(priv->pdev), filename);
381                 return rc;
382         }
383
384         snprintf(filename, sizeof(filename),
385                  "mwl8k/fmimage_%u.fw", priv->part_num);
386
387         rc = mwl8k_request_fw(priv, filename, &priv->fw.ucode);
388         if (rc) {
389                 printk(KERN_ERR "%s Error requesting firmware file %s\n",
390                                         pci_name(priv->pdev), filename);
391                 mwl8k_release_fw(&priv->fw.helper);
392                 return rc;
393         }
394
395         return 0;
396 }
397
398 struct mwl8k_cmd_pkt {
399         __le16  code;
400         __le16  length;
401         __le16  seq_num;
402         __le16  result;
403         char    payload[0];
404 } __attribute__((packed));
405
406 /*
407  * Firmware loading.
408  */
409 static int
410 mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
411 {
412         void __iomem *regs = priv->regs;
413         dma_addr_t dma_addr;
414         int rc;
415         int loops;
416
417         dma_addr = pci_map_single(priv->pdev, data, length, PCI_DMA_TODEVICE);
418         if (pci_dma_mapping_error(priv->pdev, dma_addr))
419                 return -ENOMEM;
420
421         iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
422         iowrite32(0, regs + MWL8K_HIU_INT_CODE);
423         iowrite32(MWL8K_H2A_INT_DOORBELL,
424                 regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
425         iowrite32(MWL8K_H2A_INT_DUMMY,
426                 regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
427
428         rc = -ETIMEDOUT;
429         loops = 1000;
430         do {
431                 u32 int_code;
432
433                 int_code = ioread32(regs + MWL8K_HIU_INT_CODE);
434                 if (int_code == MWL8K_INT_CODE_CMD_FINISHED) {
435                         iowrite32(0, regs + MWL8K_HIU_INT_CODE);
436                         rc = 0;
437                         break;
438                 }
439
440                 udelay(1);
441         } while (--loops);
442
443         pci_unmap_single(priv->pdev, dma_addr, length, PCI_DMA_TODEVICE);
444
445         /*
446          * Clear 'command done' interrupt bit.
447          */
448         loops = 1000;
449         do {
450                 u32 status;
451
452                 status = ioread32(priv->regs +
453                                 MWL8K_HIU_A2H_INTERRUPT_STATUS);
454                 if (status & MWL8K_A2H_INT_OPC_DONE) {
455                         iowrite32(~MWL8K_A2H_INT_OPC_DONE,
456                                 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
457                         ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
458                         break;
459                 }
460
461                 udelay(1);
462         } while (--loops);
463
464         return rc;
465 }
466
467 static int mwl8k_load_fw_image(struct mwl8k_priv *priv,
468                                 const u8 *data, size_t length)
469 {
470         struct mwl8k_cmd_pkt *cmd;
471         int done;
472         int rc = 0;
473
474         cmd = kmalloc(sizeof(*cmd) + 256, GFP_KERNEL);
475         if (cmd == NULL)
476                 return -ENOMEM;
477
478         cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD);
479         cmd->seq_num = 0;
480         cmd->result = 0;
481
482         done = 0;
483         while (length) {
484                 int block_size = length > 256 ? 256 : length;
485
486                 memcpy(cmd->payload, data + done, block_size);
487                 cmd->length = cpu_to_le16(block_size);
488
489                 rc = mwl8k_send_fw_load_cmd(priv, cmd,
490                                                 sizeof(*cmd) + block_size);
491                 if (rc)
492                         break;
493
494                 done += block_size;
495                 length -= block_size;
496         }
497
498         if (!rc) {
499                 cmd->length = 0;
500                 rc = mwl8k_send_fw_load_cmd(priv, cmd, sizeof(*cmd));
501         }
502
503         kfree(cmd);
504
505         return rc;
506 }
507
508 static int mwl8k_feed_fw_image(struct mwl8k_priv *priv,
509                                 const u8 *data, size_t length)
510 {
511         unsigned char *buffer;
512         int may_continue, rc = 0;
513         u32 done, prev_block_size;
514
515         buffer = kmalloc(1024, GFP_KERNEL);
516         if (buffer == NULL)
517                 return -ENOMEM;
518
519         done = 0;
520         prev_block_size = 0;
521         may_continue = 1000;
522         while (may_continue > 0) {
523                 u32 block_size;
524
525                 block_size = ioread32(priv->regs + MWL8K_HIU_SCRATCH);
526                 if (block_size & 1) {
527                         block_size &= ~1;
528                         may_continue--;
529                 } else {
530                         done += prev_block_size;
531                         length -= prev_block_size;
532                 }
533
534                 if (block_size > 1024 || block_size > length) {
535                         rc = -EOVERFLOW;
536                         break;
537                 }
538
539                 if (length == 0) {
540                         rc = 0;
541                         break;
542                 }
543
544                 if (block_size == 0) {
545                         rc = -EPROTO;
546                         may_continue--;
547                         udelay(1);
548                         continue;
549                 }
550
551                 prev_block_size = block_size;
552                 memcpy(buffer, data + done, block_size);
553
554                 rc = mwl8k_send_fw_load_cmd(priv, buffer, block_size);
555                 if (rc)
556                         break;
557         }
558
559         if (!rc && length != 0)
560                 rc = -EREMOTEIO;
561
562         kfree(buffer);
563
564         return rc;
565 }
566
567 static int mwl8k_load_firmware(struct mwl8k_priv *priv)
568 {
569         int loops, rc;
570
571         const u8 *ucode = priv->fw.ucode->data;
572         size_t ucode_len = priv->fw.ucode->size;
573         const u8 *helper = priv->fw.helper->data;
574         size_t helper_len = priv->fw.helper->size;
575
576         if (!memcmp(ucode, "\x01\x00\x00\x00", 4)) {
577                 rc = mwl8k_load_fw_image(priv, helper, helper_len);
578                 if (rc) {
579                         printk(KERN_ERR "%s: unable to load firmware "
580                                 "helper image\n", pci_name(priv->pdev));
581                         return rc;
582                 }
583                 msleep(1);
584
585                 rc = mwl8k_feed_fw_image(priv, ucode, ucode_len);
586         } else {
587                 rc = mwl8k_load_fw_image(priv, ucode, ucode_len);
588         }
589
590         if (rc) {
591                 printk(KERN_ERR "%s: unable to load firmware data\n",
592                         pci_name(priv->pdev));
593                 return rc;
594         }
595
596         iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
597         msleep(1);
598
599         loops = 200000;
600         do {
601                 if (ioread32(priv->regs + MWL8K_HIU_INT_CODE)
602                                                 == MWL8K_FWSTA_READY)
603                         break;
604                 udelay(1);
605         } while (--loops);
606
607         return loops ? 0 : -ETIMEDOUT;
608 }
609
610
611 /*
612  * Defines shared between transmission and reception.
613  */
614 /* HT control fields for firmware */
615 struct ewc_ht_info {
616         __le16  control1;
617         __le16  control2;
618         __le16  control3;
619 } __attribute__((packed));
620
621 /* Firmware Station database operations */
622 #define MWL8K_STA_DB_ADD_ENTRY          0
623 #define MWL8K_STA_DB_MODIFY_ENTRY       1
624 #define MWL8K_STA_DB_DEL_ENTRY          2
625 #define MWL8K_STA_DB_FLUSH              3
626
627 /* Peer Entry flags - used to define the type of the peer node */
628 #define MWL8K_PEER_TYPE_ACCESSPOINT     2
629
630 #define MWL8K_IEEE_LEGACY_DATA_RATES    12
631 #define MWL8K_MCS_BITMAP_SIZE           16
632
633 struct peer_capability_info {
634         /* Peer type - AP vs. STA.  */
635         __u8    peer_type;
636
637         /* Basic 802.11 capabilities from assoc resp.  */
638         __le16  basic_caps;
639
640         /* Set if peer supports 802.11n high throughput (HT).  */
641         __u8    ht_support;
642
643         /* Valid if HT is supported.  */
644         __le16  ht_caps;
645         __u8    extended_ht_caps;
646         struct ewc_ht_info      ewc_info;
647
648         /* Legacy rate table. Intersection of our rates and peer rates.  */
649         __u8    legacy_rates[MWL8K_IEEE_LEGACY_DATA_RATES];
650
651         /* HT rate table. Intersection of our rates and peer rates.  */
652         __u8    ht_rates[MWL8K_MCS_BITMAP_SIZE];
653         __u8    pad[16];
654
655         /* If set, interoperability mode, no proprietary extensions.  */
656         __u8    interop;
657         __u8    pad2;
658         __u8    station_id;
659         __le16  amsdu_enabled;
660 } __attribute__((packed));
661
662 /* Inline functions to manipulate QoS field in data descriptor.  */
663 static inline u16 mwl8k_qos_setbit_eosp(u16 qos)
664 {
665         u16 val_mask = 1 << 4;
666
667         /* End of Service Period Bit 4 */
668         return qos | val_mask;
669 }
670
671 static inline u16 mwl8k_qos_setbit_ack(u16 qos, u8 ack_policy)
672 {
673         u16 val_mask = 0x3;
674         u8      shift = 5;
675         u16 qos_mask = ~(val_mask << shift);
676
677         /* Ack Policy Bit 5-6 */
678         return (qos & qos_mask) | ((ack_policy & val_mask) << shift);
679 }
680
681 static inline u16 mwl8k_qos_setbit_amsdu(u16 qos)
682 {
683         u16 val_mask = 1 << 7;
684
685         /* AMSDU present Bit 7 */
686         return qos | val_mask;
687 }
688
689 static inline u16 mwl8k_qos_setbit_qlen(u16 qos, u8 len)
690 {
691         u16 val_mask = 0xff;
692         u8      shift = 8;
693         u16 qos_mask = ~(val_mask << shift);
694
695         /* Queue Length Bits 8-15 */
696         return (qos & qos_mask) | ((len & val_mask) << shift);
697 }
698
699 /* DMA header used by firmware and hardware.  */
700 struct mwl8k_dma_data {
701         __le16 fwlen;
702         struct ieee80211_hdr wh;
703 } __attribute__((packed));
704
705 /* Routines to add/remove DMA header from skb.  */
706 static inline void mwl8k_remove_dma_header(struct sk_buff *skb)
707 {
708         struct mwl8k_dma_data *tr = (struct mwl8k_dma_data *)skb->data;
709         void *dst, *src = &tr->wh;
710         int hdrlen = ieee80211_hdrlen(tr->wh.frame_control);
711         u16 space = sizeof(struct mwl8k_dma_data) - hdrlen;
712
713         dst = (void *)tr + space;
714         if (dst != src) {
715                 memmove(dst, src, hdrlen);
716                 skb_pull(skb, space);
717         }
718 }
719
720 static inline void mwl8k_add_dma_header(struct sk_buff *skb)
721 {
722         struct ieee80211_hdr *wh;
723         u32 hdrlen, pktlen;
724         struct mwl8k_dma_data *tr;
725
726         wh = (struct ieee80211_hdr *)skb->data;
727         hdrlen = ieee80211_hdrlen(wh->frame_control);
728         pktlen = skb->len;
729
730         /*
731          * Copy up/down the 802.11 header; the firmware requires
732          * we present a 2-byte payload length followed by a
733          * 4-address header (w/o QoS), followed (optionally) by
734          * any WEP/ExtIV header (but only filled in for CCMP).
735          */
736         if (hdrlen != sizeof(struct mwl8k_dma_data))
737                 skb_push(skb, sizeof(struct mwl8k_dma_data) - hdrlen);
738
739         tr = (struct mwl8k_dma_data *)skb->data;
740         if (wh != &tr->wh)
741                 memmove(&tr->wh, wh, hdrlen);
742
743         /* Clear addr4 */
744         memset(tr->wh.addr4, 0, ETH_ALEN);
745
746         /*
747          * Firmware length is the length of the fully formed "802.11
748          * payload".  That is, everything except for the 802.11 header.
749          * This includes all crypto material including the MIC.
750          */
751         tr->fwlen = cpu_to_le16(pktlen - hdrlen);
752 }
753
754
755 /*
756  * Packet reception.
757  */
758 #define MWL8K_RX_CTRL_OWNED_BY_HOST     0x02
759
760 struct mwl8k_rx_desc {
761         __le16 pkt_len;
762         __u8 link_quality;
763         __u8 noise_level;
764         __le32 pkt_phys_addr;
765         __le32 next_rx_desc_phys_addr;
766         __le16 qos_control;
767         __le16 rate_info;
768         __le32 pad0[4];
769         __u8 rssi;
770         __u8 channel;
771         __le16 pad1;
772         __u8 rx_ctrl;
773         __u8 rx_status;
774         __u8 pad2[2];
775 } __attribute__((packed));
776
777 #define MWL8K_RX_DESCS          256
778 #define MWL8K_RX_MAXSZ          3800
779
780 static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
781 {
782         struct mwl8k_priv *priv = hw->priv;
783         struct mwl8k_rx_queue *rxq = priv->rxq + index;
784         int size;
785         int i;
786
787         rxq->rx_desc_count = 0;
788         rxq->rx_head = 0;
789         rxq->rx_tail = 0;
790
791         size = MWL8K_RX_DESCS * sizeof(struct mwl8k_rx_desc);
792
793         rxq->rx_desc_area =
794                 pci_alloc_consistent(priv->pdev, size, &rxq->rx_desc_dma);
795         if (rxq->rx_desc_area == NULL) {
796                 printk(KERN_ERR "%s: failed to alloc RX descriptors\n",
797                        priv->name);
798                 return -ENOMEM;
799         }
800         memset(rxq->rx_desc_area, 0, size);
801
802         rxq->rx_skb = kmalloc(MWL8K_RX_DESCS *
803                                 sizeof(*rxq->rx_skb), GFP_KERNEL);
804         if (rxq->rx_skb == NULL) {
805                 printk(KERN_ERR "%s: failed to alloc RX skbuff list\n",
806                         priv->name);
807                 pci_free_consistent(priv->pdev, size,
808                                     rxq->rx_desc_area, rxq->rx_desc_dma);
809                 return -ENOMEM;
810         }
811         memset(rxq->rx_skb, 0, MWL8K_RX_DESCS * sizeof(*rxq->rx_skb));
812
813         for (i = 0; i < MWL8K_RX_DESCS; i++) {
814                 struct mwl8k_rx_desc *rx_desc;
815                 int nexti;
816
817                 rx_desc = rxq->rx_desc_area + i;
818                 nexti = (i + 1) % MWL8K_RX_DESCS;
819
820                 rx_desc->next_rx_desc_phys_addr =
821                         cpu_to_le32(rxq->rx_desc_dma
822                                                 + nexti * sizeof(*rx_desc));
823                 rx_desc->rx_ctrl = MWL8K_RX_CTRL_OWNED_BY_HOST;
824         }
825
826         return 0;
827 }
828
829 static int rxq_refill(struct ieee80211_hw *hw, int index, int limit)
830 {
831         struct mwl8k_priv *priv = hw->priv;
832         struct mwl8k_rx_queue *rxq = priv->rxq + index;
833         int refilled;
834
835         refilled = 0;
836         while (rxq->rx_desc_count < MWL8K_RX_DESCS && limit--) {
837                 struct sk_buff *skb;
838                 int rx;
839
840                 skb = dev_alloc_skb(MWL8K_RX_MAXSZ);
841                 if (skb == NULL)
842                         break;
843
844                 rxq->rx_desc_count++;
845
846                 rx = rxq->rx_tail;
847                 rxq->rx_tail = (rx + 1) % MWL8K_RX_DESCS;
848
849                 rxq->rx_desc_area[rx].pkt_phys_addr =
850                         cpu_to_le32(pci_map_single(priv->pdev, skb->data,
851                                         MWL8K_RX_MAXSZ, DMA_FROM_DEVICE));
852
853                 rxq->rx_desc_area[rx].pkt_len = cpu_to_le16(MWL8K_RX_MAXSZ);
854                 rxq->rx_skb[rx] = skb;
855                 wmb();
856                 rxq->rx_desc_area[rx].rx_ctrl = 0;
857
858                 refilled++;
859         }
860
861         return refilled;
862 }
863
864 /* Must be called only when the card's reception is completely halted */
865 static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index)
866 {
867         struct mwl8k_priv *priv = hw->priv;
868         struct mwl8k_rx_queue *rxq = priv->rxq + index;
869         int i;
870
871         for (i = 0; i < MWL8K_RX_DESCS; i++) {
872                 if (rxq->rx_skb[i] != NULL) {
873                         unsigned long addr;
874
875                         addr = le32_to_cpu(rxq->rx_desc_area[i].pkt_phys_addr);
876                         pci_unmap_single(priv->pdev, addr, MWL8K_RX_MAXSZ,
877                                          PCI_DMA_FROMDEVICE);
878                         kfree_skb(rxq->rx_skb[i]);
879                         rxq->rx_skb[i] = NULL;
880                 }
881         }
882
883         kfree(rxq->rx_skb);
884         rxq->rx_skb = NULL;
885
886         pci_free_consistent(priv->pdev,
887                             MWL8K_RX_DESCS * sizeof(struct mwl8k_rx_desc),
888                             rxq->rx_desc_area, rxq->rx_desc_dma);
889         rxq->rx_desc_area = NULL;
890 }
891
892
893 /*
894  * Scan a list of BSSIDs to process for finalize join.
895  * Allows for extension to process multiple BSSIDs.
896  */
897 static inline int
898 mwl8k_capture_bssid(struct mwl8k_priv *priv, struct ieee80211_hdr *wh)
899 {
900         return priv->capture_beacon &&
901                 ieee80211_is_beacon(wh->frame_control) &&
902                 !compare_ether_addr(wh->addr3, priv->capture_bssid);
903 }
904
905 static inline void mwl8k_save_beacon(struct mwl8k_priv *priv,
906                                                         struct sk_buff *skb)
907 {
908         priv->capture_beacon = false;
909         memset(priv->capture_bssid, 0, ETH_ALEN);
910
911         /*
912          * Use GFP_ATOMIC as rxq_process is called from
913          * the primary interrupt handler, memory allocation call
914          * must not sleep.
915          */
916         priv->beacon_skb = skb_copy(skb, GFP_ATOMIC);
917         if (priv->beacon_skb != NULL)
918                 queue_work(priv->config_wq,
919                                 &priv->finalize_join_worker);
920 }
921
922 static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
923 {
924         struct mwl8k_priv *priv = hw->priv;
925         struct mwl8k_rx_queue *rxq = priv->rxq + index;
926         int processed;
927
928         processed = 0;
929         while (rxq->rx_desc_count && limit--) {
930                 struct mwl8k_rx_desc *rx_desc;
931                 struct sk_buff *skb;
932                 struct ieee80211_rx_status status;
933                 unsigned long addr;
934                 struct ieee80211_hdr *wh;
935
936                 rx_desc = rxq->rx_desc_area + rxq->rx_head;
937                 if (!(rx_desc->rx_ctrl & MWL8K_RX_CTRL_OWNED_BY_HOST))
938                         break;
939                 rmb();
940
941                 skb = rxq->rx_skb[rxq->rx_head];
942                 if (skb == NULL)
943                         break;
944                 rxq->rx_skb[rxq->rx_head] = NULL;
945
946                 rxq->rx_head = (rxq->rx_head + 1) % MWL8K_RX_DESCS;
947                 rxq->rx_desc_count--;
948
949                 addr = le32_to_cpu(rx_desc->pkt_phys_addr);
950                 pci_unmap_single(priv->pdev, addr,
951                                         MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
952
953                 skb_put(skb, le16_to_cpu(rx_desc->pkt_len));
954                 mwl8k_remove_dma_header(skb);
955
956                 wh = (struct ieee80211_hdr *)skb->data;
957
958                 /*
959                  * Check for pending join operation. save a copy of
960                  * the beacon and schedule a tasklet to send finalize
961                  * join command to the firmware.
962                  */
963                 if (mwl8k_capture_bssid(priv, wh))
964                         mwl8k_save_beacon(priv, skb);
965
966                 memset(&status, 0, sizeof(status));
967                 status.mactime = 0;
968                 status.signal = -rx_desc->rssi;
969                 status.noise = -rx_desc->noise_level;
970                 status.qual = rx_desc->link_quality;
971                 status.antenna = 1;
972                 status.rate_idx = 1;
973                 status.flag = 0;
974                 status.band = IEEE80211_BAND_2GHZ;
975                 status.freq = ieee80211_channel_to_frequency(rx_desc->channel);
976                 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
977                 ieee80211_rx_irqsafe(hw, skb);
978
979                 processed++;
980         }
981
982         return processed;
983 }
984
985
986 /*
987  * Packet transmission.
988  */
989
990 /* Transmit queue assignment.  */
991 enum {
992         MWL8K_WME_AC_BK = 0,            /* background access */
993         MWL8K_WME_AC_BE = 1,            /* best effort access */
994         MWL8K_WME_AC_VI = 2,            /* video access */
995         MWL8K_WME_AC_VO = 3,            /* voice access */
996 };
997
998 /* Transmit packet ACK policy */
999 #define MWL8K_TXD_ACK_POLICY_NORMAL             0
1000 #define MWL8K_TXD_ACK_POLICY_BLOCKACK           3
1001
1002 #define GET_TXQ(_ac) (\
1003                 ((_ac) == WME_AC_VO) ? MWL8K_WME_AC_VO : \
1004                 ((_ac) == WME_AC_VI) ? MWL8K_WME_AC_VI : \
1005                 ((_ac) == WME_AC_BK) ? MWL8K_WME_AC_BK : \
1006                 MWL8K_WME_AC_BE)
1007
1008 #define MWL8K_TXD_STATUS_OK                     0x00000001
1009 #define MWL8K_TXD_STATUS_OK_RETRY               0x00000002
1010 #define MWL8K_TXD_STATUS_OK_MORE_RETRY          0x00000004
1011 #define MWL8K_TXD_STATUS_MULTICAST_TX           0x00000008
1012 #define MWL8K_TXD_STATUS_FW_OWNED               0x80000000
1013
1014 struct mwl8k_tx_desc {
1015         __le32 status;
1016         __u8 data_rate;
1017         __u8 tx_priority;
1018         __le16 qos_control;
1019         __le32 pkt_phys_addr;
1020         __le16 pkt_len;
1021         __u8 dest_MAC_addr[ETH_ALEN];
1022         __le32 next_tx_desc_phys_addr;
1023         __le32 reserved;
1024         __le16 rate_info;
1025         __u8 peer_id;
1026         __u8 tx_frag_cnt;
1027 } __attribute__((packed));
1028
1029 #define MWL8K_TX_DESCS          128
1030
1031 static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
1032 {
1033         struct mwl8k_priv *priv = hw->priv;
1034         struct mwl8k_tx_queue *txq = priv->txq + index;
1035         int size;
1036         int i;
1037
1038         memset(&txq->tx_stats, 0, sizeof(struct ieee80211_tx_queue_stats));
1039         txq->tx_stats.limit = MWL8K_TX_DESCS;
1040         txq->tx_head = 0;
1041         txq->tx_tail = 0;
1042
1043         size = MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc);
1044
1045         txq->tx_desc_area =
1046                 pci_alloc_consistent(priv->pdev, size, &txq->tx_desc_dma);
1047         if (txq->tx_desc_area == NULL) {
1048                 printk(KERN_ERR "%s: failed to alloc TX descriptors\n",
1049                        priv->name);
1050                 return -ENOMEM;
1051         }
1052         memset(txq->tx_desc_area, 0, size);
1053
1054         txq->tx_skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->tx_skb),
1055                                                                 GFP_KERNEL);
1056         if (txq->tx_skb == NULL) {
1057                 printk(KERN_ERR "%s: failed to alloc TX skbuff list\n",
1058                        priv->name);
1059                 pci_free_consistent(priv->pdev, size,
1060                                     txq->tx_desc_area, txq->tx_desc_dma);
1061                 return -ENOMEM;
1062         }
1063         memset(txq->tx_skb, 0, MWL8K_TX_DESCS * sizeof(*txq->tx_skb));
1064
1065         for (i = 0; i < MWL8K_TX_DESCS; i++) {
1066                 struct mwl8k_tx_desc *tx_desc;
1067                 int nexti;
1068
1069                 tx_desc = txq->tx_desc_area + i;
1070                 nexti = (i + 1) % MWL8K_TX_DESCS;
1071
1072                 tx_desc->status = 0;
1073                 tx_desc->next_tx_desc_phys_addr =
1074                         cpu_to_le32(txq->tx_desc_dma +
1075                                                 nexti * sizeof(*tx_desc));
1076         }
1077
1078         return 0;
1079 }
1080
1081 static inline void mwl8k_tx_start(struct mwl8k_priv *priv)
1082 {
1083         iowrite32(MWL8K_H2A_INT_PPA_READY,
1084                 priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
1085         iowrite32(MWL8K_H2A_INT_DUMMY,
1086                 priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
1087         ioread32(priv->regs + MWL8K_HIU_INT_CODE);
1088 }
1089
1090 static inline int mwl8k_txq_busy(struct mwl8k_priv *priv)
1091 {
1092         return priv->pending_tx_pkts;
1093 }
1094
1095 struct mwl8k_txq_info {
1096         u32 fw_owned;
1097         u32 drv_owned;
1098         u32 unused;
1099         u32 len;
1100         u32 head;
1101         u32 tail;
1102 };
1103
1104 static int mwl8k_scan_tx_ring(struct mwl8k_priv *priv,
1105                                 struct mwl8k_txq_info txinfo[],
1106                                 u32 num_queues)
1107 {
1108         int count, desc, status;
1109         struct mwl8k_tx_queue *txq;
1110         struct mwl8k_tx_desc *tx_desc;
1111         int ndescs = 0;
1112
1113         memset(txinfo, 0, num_queues * sizeof(struct mwl8k_txq_info));
1114         spin_lock_bh(&priv->tx_lock);
1115         for (count = 0; count < num_queues; count++) {
1116                 txq = priv->txq + count;
1117                 txinfo[count].len = txq->tx_stats.len;
1118                 txinfo[count].head = txq->tx_head;
1119                 txinfo[count].tail = txq->tx_tail;
1120                 for (desc = 0; desc < MWL8K_TX_DESCS; desc++) {
1121                         tx_desc = txq->tx_desc_area + desc;
1122                         status = le32_to_cpu(tx_desc->status);
1123
1124                         if (status & MWL8K_TXD_STATUS_FW_OWNED)
1125                                 txinfo[count].fw_owned++;
1126                         else
1127                                 txinfo[count].drv_owned++;
1128
1129                         if (tx_desc->pkt_len == 0)
1130                                 txinfo[count].unused++;
1131                 }
1132         }
1133         spin_unlock_bh(&priv->tx_lock);
1134
1135         return ndescs;
1136 }
1137
1138 static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw, u32 delay_ms)
1139 {
1140         struct mwl8k_priv *priv = hw->priv;
1141         DECLARE_COMPLETION_ONSTACK(cmd_wait);
1142         u32 count;
1143         unsigned long timeout;
1144
1145         might_sleep();
1146
1147         if (priv->tx_wait != NULL)
1148                 printk(KERN_ERR "WARNING Previous TXWaitEmpty instance\n");
1149
1150         spin_lock_bh(&priv->tx_lock);
1151         count = mwl8k_txq_busy(priv);
1152         if (count) {
1153                 priv->tx_wait = &cmd_wait;
1154                 if (priv->radio_on)
1155                         mwl8k_tx_start(priv);
1156         }
1157         spin_unlock_bh(&priv->tx_lock);
1158
1159         if (count) {
1160                 struct mwl8k_txq_info txinfo[4];
1161                 int index;
1162                 int newcount;
1163
1164                 timeout = wait_for_completion_timeout(&cmd_wait,
1165                                         msecs_to_jiffies(delay_ms));
1166                 if (timeout)
1167                         return 0;
1168
1169                 spin_lock_bh(&priv->tx_lock);
1170                 priv->tx_wait = NULL;
1171                 newcount = mwl8k_txq_busy(priv);
1172                 spin_unlock_bh(&priv->tx_lock);
1173
1174                 printk(KERN_ERR "%s(%u) TIMEDOUT:%ums Pend:%u-->%u\n",
1175                        __func__, __LINE__, delay_ms, count, newcount);
1176
1177                 mwl8k_scan_tx_ring(priv, txinfo, 4);
1178                 for (index = 0; index < 4; index++)
1179                         printk(KERN_ERR
1180                                 "TXQ:%u L:%u H:%u T:%u FW:%u DRV:%u U:%u\n",
1181                                         index,
1182                                         txinfo[index].len,
1183                                         txinfo[index].head,
1184                                         txinfo[index].tail,
1185                                         txinfo[index].fw_owned,
1186                                         txinfo[index].drv_owned,
1187                                         txinfo[index].unused);
1188
1189                 return -ETIMEDOUT;
1190         }
1191
1192         return 0;
1193 }
1194
1195 #define MWL8K_TXD_SUCCESS(status)                               \
1196         ((status) & (MWL8K_TXD_STATUS_OK |                      \
1197                      MWL8K_TXD_STATUS_OK_RETRY |                \
1198                      MWL8K_TXD_STATUS_OK_MORE_RETRY))
1199
1200 static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
1201 {
1202         struct mwl8k_priv *priv = hw->priv;
1203         struct mwl8k_tx_queue *txq = priv->txq + index;
1204         int wake = 0;
1205
1206         while (txq->tx_stats.len > 0) {
1207                 int tx;
1208                 struct mwl8k_tx_desc *tx_desc;
1209                 unsigned long addr;
1210                 int size;
1211                 struct sk_buff *skb;
1212                 struct ieee80211_tx_info *info;
1213                 u32 status;
1214
1215                 tx = txq->tx_head;
1216                 tx_desc = txq->tx_desc_area + tx;
1217
1218                 status = le32_to_cpu(tx_desc->status);
1219
1220                 if (status & MWL8K_TXD_STATUS_FW_OWNED) {
1221                         if (!force)
1222                                 break;
1223                         tx_desc->status &=
1224                                 ~cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED);
1225                 }
1226
1227                 txq->tx_head = (tx + 1) % MWL8K_TX_DESCS;
1228                 BUG_ON(txq->tx_stats.len == 0);
1229                 txq->tx_stats.len--;
1230                 priv->pending_tx_pkts--;
1231
1232                 addr = le32_to_cpu(tx_desc->pkt_phys_addr);
1233                 size = le16_to_cpu(tx_desc->pkt_len);
1234                 skb = txq->tx_skb[tx];
1235                 txq->tx_skb[tx] = NULL;
1236
1237                 BUG_ON(skb == NULL);
1238                 pci_unmap_single(priv->pdev, addr, size, PCI_DMA_TODEVICE);
1239
1240                 mwl8k_remove_dma_header(skb);
1241
1242                 /* Mark descriptor as unused */
1243                 tx_desc->pkt_phys_addr = 0;
1244                 tx_desc->pkt_len = 0;
1245
1246                 info = IEEE80211_SKB_CB(skb);
1247                 ieee80211_tx_info_clear_status(info);
1248                 if (MWL8K_TXD_SUCCESS(status))
1249                         info->flags |= IEEE80211_TX_STAT_ACK;
1250
1251                 ieee80211_tx_status_irqsafe(hw, skb);
1252
1253                 wake = !priv->inconfig && priv->radio_on;
1254         }
1255
1256         if (wake)
1257                 ieee80211_wake_queue(hw, index);
1258 }
1259
1260 /* must be called only when the card's transmit is completely halted */
1261 static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
1262 {
1263         struct mwl8k_priv *priv = hw->priv;
1264         struct mwl8k_tx_queue *txq = priv->txq + index;
1265
1266         mwl8k_txq_reclaim(hw, index, 1);
1267
1268         kfree(txq->tx_skb);
1269         txq->tx_skb = NULL;
1270
1271         pci_free_consistent(priv->pdev,
1272                             MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc),
1273                             txq->tx_desc_area, txq->tx_desc_dma);
1274         txq->tx_desc_area = NULL;
1275 }
1276
1277 static int
1278 mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1279 {
1280         struct mwl8k_priv *priv = hw->priv;
1281         struct ieee80211_tx_info *tx_info;
1282         struct ieee80211_hdr *wh;
1283         struct mwl8k_tx_queue *txq;
1284         struct mwl8k_tx_desc *tx;
1285         struct mwl8k_dma_data *tr;
1286         struct mwl8k_vif *mwl8k_vif;
1287         dma_addr_t dma;
1288         u16 qos = 0;
1289         bool qosframe = false, ampduframe = false;
1290         bool mcframe = false, eapolframe = false;
1291         bool amsduframe = false;
1292         __le16 fc;
1293
1294         txq = priv->txq + index;
1295         tx = txq->tx_desc_area + txq->tx_tail;
1296
1297         BUG_ON(txq->tx_skb[txq->tx_tail] != NULL);
1298
1299         /*
1300          * Append HW DMA header to start of packet.
1301          */
1302         mwl8k_add_dma_header(skb);
1303
1304         tx_info = IEEE80211_SKB_CB(skb);
1305         mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
1306         tr = (struct mwl8k_dma_data *)skb->data;
1307         wh = &tr->wh;
1308         fc = wh->frame_control;
1309         qosframe = ieee80211_is_data_qos(fc);
1310         mcframe = is_multicast_ether_addr(wh->addr1);
1311         ampduframe = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
1312
1313         if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1314                 u16 seqno = mwl8k_vif->seqno;
1315                 wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
1316                 wh->seq_ctrl |= cpu_to_le16(seqno << 4);
1317                 mwl8k_vif->seqno = seqno++ % 4096;
1318         }
1319
1320         if (qosframe)
1321                 qos = le16_to_cpu(*((__le16 *)ieee80211_get_qos_ctl(wh)));
1322
1323         dma = pci_map_single(priv->pdev, skb->data,
1324                                 skb->len, PCI_DMA_TODEVICE);
1325
1326         if (pci_dma_mapping_error(priv->pdev, dma)) {
1327                 printk(KERN_DEBUG "%s: failed to dma map skb, "
1328                         "dropping TX frame.\n", priv->name);
1329
1330                 if (skb != NULL)
1331                         dev_kfree_skb(skb);
1332                 return NETDEV_TX_OK;
1333         }
1334
1335         /* Set desc header, cpu bit order.  */
1336         tx->status = 0;
1337         tx->data_rate = 0;
1338         tx->tx_priority = index;
1339         tx->qos_control = 0;
1340         tx->rate_info = 0;
1341         tx->peer_id = mwl8k_vif->peer_id;
1342
1343         amsduframe = !!(qos & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT);
1344
1345         /* Setup firmware control bit fields for each frame type.  */
1346         if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) {
1347                 tx->data_rate = 0;
1348                 qos = mwl8k_qos_setbit_eosp(qos);
1349                 /* Set Queue size to unspecified */
1350                 qos = mwl8k_qos_setbit_qlen(qos, 0xff);
1351         } else if (ieee80211_is_data(fc)) {
1352                 tx->data_rate = 1;
1353                 if (mcframe)
1354                         tx->status |= MWL8K_TXD_STATUS_MULTICAST_TX;
1355
1356                 /*
1357                  * Tell firmware to not send EAPOL pkts in an
1358                  * aggregate.  Verify against mac80211 tx path.  If
1359                  * stack turns off AMPDU for an EAPOL frame this
1360                  * check will be removed.
1361                  */
1362                 if (eapolframe) {
1363                         qos = mwl8k_qos_setbit_ack(qos,
1364                                 MWL8K_TXD_ACK_POLICY_NORMAL);
1365                 } else {
1366                         /* Send pkt in an aggregate if AMPDU frame.  */
1367                         if (ampduframe)
1368                                 qos = mwl8k_qos_setbit_ack(qos,
1369                                         MWL8K_TXD_ACK_POLICY_BLOCKACK);
1370                         else
1371                                 qos = mwl8k_qos_setbit_ack(qos,
1372                                         MWL8K_TXD_ACK_POLICY_NORMAL);
1373
1374                         if (amsduframe)
1375                                 qos = mwl8k_qos_setbit_amsdu(qos);
1376                 }
1377         }
1378
1379         /* Convert to little endian */
1380         tx->qos_control = cpu_to_le16(qos);
1381         tx->status = cpu_to_le32(tx->status);
1382         tx->pkt_phys_addr = cpu_to_le32(dma);
1383         tx->pkt_len = cpu_to_le16(skb->len);
1384
1385         txq->tx_skb[txq->tx_tail] = skb;
1386
1387         spin_lock_bh(&priv->tx_lock);
1388
1389         tx->status = cpu_to_le32(MWL8K_TXD_STATUS_OK |
1390                                         MWL8K_TXD_STATUS_FW_OWNED);
1391         wmb();
1392         txq->tx_stats.len++;
1393         priv->pending_tx_pkts++;
1394         txq->tx_stats.count++;
1395         txq->tx_tail++;
1396
1397         if (txq->tx_tail == MWL8K_TX_DESCS)
1398                 txq->tx_tail = 0;
1399         if (txq->tx_head == txq->tx_tail)
1400                 ieee80211_stop_queue(hw, index);
1401
1402         if (priv->inconfig) {
1403                 /*
1404                  * Silently queue packet when we are in the middle of
1405                  * a config cycle.  Notify firmware only if we are
1406                  * waiting for TXQs to empty.  If a packet is sent
1407                  * before .config() is complete, perhaps it is better
1408                  * to drop the packet, as the channel is being changed
1409                  * and the packet will end up on the wrong channel.
1410                  */
1411                 printk(KERN_ERR "%s(): WARNING TX activity while "
1412                         "in config\n", __func__);
1413
1414                 if (priv->tx_wait != NULL)
1415                         mwl8k_tx_start(priv);
1416         } else
1417                 mwl8k_tx_start(priv);
1418
1419         spin_unlock_bh(&priv->tx_lock);
1420
1421         return NETDEV_TX_OK;
1422 }
1423
1424
1425 /*
1426  * Command processing.
1427  */
1428
1429 /* Timeout firmware commands after 2000ms */
1430 #define MWL8K_CMD_TIMEOUT_MS    2000
1431
1432 static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
1433 {
1434         DECLARE_COMPLETION_ONSTACK(cmd_wait);
1435         struct mwl8k_priv *priv = hw->priv;
1436         void __iomem *regs = priv->regs;
1437         dma_addr_t dma_addr;
1438         unsigned int dma_size;
1439         int rc;
1440         unsigned long timeout = 0;
1441         u8 buf[32];
1442
1443         cmd->result = 0xFFFF;
1444         dma_size = le16_to_cpu(cmd->length);
1445         dma_addr = pci_map_single(priv->pdev, cmd, dma_size,
1446                                   PCI_DMA_BIDIRECTIONAL);
1447         if (pci_dma_mapping_error(priv->pdev, dma_addr))
1448                 return -ENOMEM;
1449
1450         if (priv->hostcmd_wait != NULL)
1451                 printk(KERN_ERR "WARNING host command in progress\n");
1452
1453         spin_lock_irq(&priv->fw_lock);
1454         priv->hostcmd_wait = &cmd_wait;
1455         iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
1456         iowrite32(MWL8K_H2A_INT_DOORBELL,
1457                 regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
1458         iowrite32(MWL8K_H2A_INT_DUMMY,
1459                 regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
1460         spin_unlock_irq(&priv->fw_lock);
1461
1462         timeout = wait_for_completion_timeout(&cmd_wait,
1463                                 msecs_to_jiffies(MWL8K_CMD_TIMEOUT_MS));
1464
1465         pci_unmap_single(priv->pdev, dma_addr, dma_size,
1466                                         PCI_DMA_BIDIRECTIONAL);
1467
1468         if (!timeout) {
1469                 spin_lock_irq(&priv->fw_lock);
1470                 priv->hostcmd_wait = NULL;
1471                 spin_unlock_irq(&priv->fw_lock);
1472                 printk(KERN_ERR "%s: Command %s timeout after %u ms\n",
1473                        priv->name,
1474                        mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
1475                        MWL8K_CMD_TIMEOUT_MS);
1476                 rc = -ETIMEDOUT;
1477         } else {
1478                 rc = cmd->result ? -EINVAL : 0;
1479                 if (rc)
1480                         printk(KERN_ERR "%s: Command %s error 0x%x\n",
1481                                priv->name,
1482                                mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
1483                                cmd->result);
1484         }
1485
1486         return rc;
1487 }
1488
1489 /*
1490  * GET_HW_SPEC.
1491  */
1492 struct mwl8k_cmd_get_hw_spec {
1493         struct mwl8k_cmd_pkt header;
1494         __u8 hw_rev;
1495         __u8 host_interface;
1496         __le16 num_mcaddrs;
1497         __u8 perm_addr[ETH_ALEN];
1498         __le16 region_code;
1499         __le32 fw_rev;
1500         __le32 ps_cookie;
1501         __le32 caps;
1502         __u8 mcs_bitmap[16];
1503         __le32 rx_queue_ptr;
1504         __le32 num_tx_queues;
1505         __le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
1506         __le32 caps2;
1507         __le32 num_tx_desc_per_queue;
1508         __le32 total_rx_desc;
1509 } __attribute__((packed));
1510
1511 static int mwl8k_cmd_get_hw_spec(struct ieee80211_hw *hw)
1512 {
1513         struct mwl8k_priv *priv = hw->priv;
1514         struct mwl8k_cmd_get_hw_spec *cmd;
1515         int rc;
1516         int i;
1517
1518         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1519         if (cmd == NULL)
1520                 return -ENOMEM;
1521
1522         cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC);
1523         cmd->header.length = cpu_to_le16(sizeof(*cmd));
1524
1525         memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
1526         cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
1527         cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rx_desc_dma);
1528         cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
1529         for (i = 0; i < MWL8K_TX_QUEUES; i++)
1530                 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].tx_desc_dma);
1531         cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
1532         cmd->total_rx_desc = cpu_to_le32(MWL8K_RX_DESCS);
1533
1534         rc = mwl8k_post_cmd(hw, &cmd->header);
1535
1536         if (!rc) {
1537                 SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
1538                 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
1539                 priv->fw_rev = le32_to_cpu(cmd->fw_rev);
1540                 priv->hw_rev = cmd->hw_rev;
1541         }
1542
1543         kfree(cmd);
1544         return rc;
1545 }
1546
1547 /*
1548  * CMD_MAC_MULTICAST_ADR.
1549  */
1550 struct mwl8k_cmd_mac_multicast_adr {
1551         struct mwl8k_cmd_pkt header;
1552         __le16 action;
1553         __le16 numaddr;
1554         __u8 addr[0][ETH_ALEN];
1555 };
1556
1557 #define MWL8K_ENABLE_RX_MULTICAST 0x000F
1558
1559 static struct mwl8k_cmd_pkt *
1560 __mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw,
1561                               int mc_count, struct dev_addr_list *mclist)
1562 {
1563         struct mwl8k_priv *priv = hw->priv;
1564         struct mwl8k_cmd_mac_multicast_adr *cmd;
1565         int size;
1566         int i;
1567
1568         if (mc_count > priv->num_mcaddrs)
1569                 mc_count = priv->num_mcaddrs;
1570
1571         size = sizeof(*cmd) + mc_count * ETH_ALEN;
1572
1573         cmd = kzalloc(size, GFP_ATOMIC);
1574         if (cmd == NULL)
1575                 return NULL;
1576
1577         cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR);
1578         cmd->header.length = cpu_to_le16(size);
1579         cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST);
1580         cmd->numaddr = cpu_to_le16(mc_count);
1581
1582         for (i = 0; i < mc_count && mclist; i++) {
1583                 if (mclist->da_addrlen != ETH_ALEN) {
1584                         kfree(cmd);
1585                         return NULL;
1586                 }
1587                 memcpy(cmd->addr[i], mclist->da_addr, ETH_ALEN);
1588                 mclist = mclist->next;
1589         }
1590
1591         return &cmd->header;
1592 }
1593
1594 /*
1595  * CMD_802_11_GET_STAT.
1596  */
1597 struct mwl8k_cmd_802_11_get_stat {
1598         struct mwl8k_cmd_pkt header;
1599         __le16 action;
1600         __le32 stats[64];
1601 } __attribute__((packed));
1602
1603 #define MWL8K_STAT_ACK_FAILURE  9
1604 #define MWL8K_STAT_RTS_FAILURE  12
1605 #define MWL8K_STAT_FCS_ERROR    24
1606 #define MWL8K_STAT_RTS_SUCCESS  11
1607
1608 static int mwl8k_cmd_802_11_get_stat(struct ieee80211_hw *hw,
1609                                 struct ieee80211_low_level_stats *stats)
1610 {
1611         struct mwl8k_cmd_802_11_get_stat *cmd;
1612         int rc;
1613
1614         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1615         if (cmd == NULL)
1616                 return -ENOMEM;
1617
1618         cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_STAT);
1619         cmd->header.length = cpu_to_le16(sizeof(*cmd));
1620         cmd->action = cpu_to_le16(MWL8K_CMD_GET);
1621
1622         rc = mwl8k_post_cmd(hw, &cmd->header);
1623         if (!rc) {
1624                 stats->dot11ACKFailureCount =
1625                         le32_to_cpu(cmd->stats[MWL8K_STAT_ACK_FAILURE]);
1626                 stats->dot11RTSFailureCount =
1627                         le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_FAILURE]);
1628                 stats->dot11FCSErrorCount =
1629                         le32_to_cpu(cmd->stats[MWL8K_STAT_FCS_ERROR]);
1630                 stats->dot11RTSSuccessCount =
1631                         le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_SUCCESS]);
1632         }
1633         kfree(cmd);
1634
1635         return rc;
1636 }
1637
1638 /*
1639  * CMD_802_11_RADIO_CONTROL.
1640  */
1641 struct mwl8k_cmd_802_11_radio_control {
1642         struct mwl8k_cmd_pkt header;
1643         __le16 action;
1644         __le16 control;
1645         __le16 radio_on;
1646 } __attribute__((packed));
1647
1648 static int
1649 mwl8k_cmd_802_11_radio_control(struct ieee80211_hw *hw, bool enable, bool force)
1650 {
1651         struct mwl8k_priv *priv = hw->priv;
1652         struct mwl8k_cmd_802_11_radio_control *cmd;
1653         int rc;
1654
1655         if (enable == priv->radio_on && !force)
1656                 return 0;
1657
1658         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1659         if (cmd == NULL)
1660                 return -ENOMEM;
1661
1662         cmd->header.code = cpu_to_le16(MWL8K_CMD_RADIO_CONTROL);
1663         cmd->header.length = cpu_to_le16(sizeof(*cmd));
1664         cmd->action = cpu_to_le16(MWL8K_CMD_SET);
1665         cmd->control = cpu_to_le16(priv->radio_short_preamble ? 3 : 1);
1666         cmd->radio_on = cpu_to_le16(enable ? 0x0001 : 0x0000);
1667
1668         rc = mwl8k_post_cmd(hw, &cmd->header);
1669         kfree(cmd);
1670
1671         if (!rc)
1672                 priv->radio_on = enable;
1673
1674         return rc;
1675 }
1676
1677 static int mwl8k_cmd_802_11_radio_disable(struct ieee80211_hw *hw)
1678 {
1679         return mwl8k_cmd_802_11_radio_control(hw, 0, 0);
1680 }
1681
1682 static int mwl8k_cmd_802_11_radio_enable(struct ieee80211_hw *hw)
1683 {
1684         return mwl8k_cmd_802_11_radio_control(hw, 1, 0);
1685 }
1686
1687 static int
1688 mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
1689 {
1690         struct mwl8k_priv *priv;
1691
1692         if (hw == NULL || hw->priv == NULL)
1693                 return -EINVAL;
1694         priv = hw->priv;
1695
1696         priv->radio_short_preamble = short_preamble;
1697
1698         return mwl8k_cmd_802_11_radio_control(hw, 1, 1);
1699 }
1700
1701 /*
1702  * CMD_802_11_RF_TX_POWER.
1703  */
1704 #define MWL8K_TX_POWER_LEVEL_TOTAL      8
1705
1706 struct mwl8k_cmd_802_11_rf_tx_power {
1707         struct mwl8k_cmd_pkt header;
1708         __le16 action;
1709         __le16 support_level;
1710         __le16 current_level;
1711         __le16 reserved;
1712         __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
1713 } __attribute__((packed));
1714
1715 static int mwl8k_cmd_802_11_rf_tx_power(struct ieee80211_hw *hw, int dBm)
1716 {
1717         struct mwl8k_cmd_802_11_rf_tx_power *cmd;
1718         int rc;
1719
1720         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1721         if (cmd == NULL)
1722                 return -ENOMEM;
1723
1724         cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_TX_POWER);
1725         cmd->header.length = cpu_to_le16(sizeof(*cmd));
1726         cmd->action = cpu_to_le16(MWL8K_CMD_SET);
1727         cmd->support_level = cpu_to_le16(dBm);
1728
1729         rc = mwl8k_post_cmd(hw, &cmd->header);
1730         kfree(cmd);
1731
1732         return rc;
1733 }
1734
1735 /*
1736  * CMD_SET_PRE_SCAN.
1737  */
1738 struct mwl8k_cmd_set_pre_scan {
1739         struct mwl8k_cmd_pkt header;
1740 } __attribute__((packed));
1741
1742 static int mwl8k_cmd_set_pre_scan(struct ieee80211_hw *hw)
1743 {
1744         struct mwl8k_cmd_set_pre_scan *cmd;
1745         int rc;
1746
1747         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1748         if (cmd == NULL)
1749                 return -ENOMEM;
1750
1751         cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_PRE_SCAN);
1752         cmd->header.length = cpu_to_le16(sizeof(*cmd));
1753
1754         rc = mwl8k_post_cmd(hw, &cmd->header);
1755         kfree(cmd);
1756
1757         return rc;
1758 }
1759
1760 /*
1761  * CMD_SET_POST_SCAN.
1762  */
1763 struct mwl8k_cmd_set_post_scan {
1764         struct mwl8k_cmd_pkt header;
1765         __le32 isibss;
1766         __u8 bssid[ETH_ALEN];
1767 } __attribute__((packed));
1768
1769 static int
1770 mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, __u8 *mac)
1771 {
1772         struct mwl8k_cmd_set_post_scan *cmd;
1773         int rc;
1774
1775         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1776         if (cmd == NULL)
1777                 return -ENOMEM;
1778
1779         cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_POST_SCAN);
1780         cmd->header.length = cpu_to_le16(sizeof(*cmd));
1781         cmd->isibss = 0;
1782         memcpy(cmd->bssid, mac, ETH_ALEN);
1783
1784         rc = mwl8k_post_cmd(hw, &cmd->header);
1785         kfree(cmd);
1786
1787         return rc;
1788 }
1789
1790 /*
1791  * CMD_SET_RF_CHANNEL.
1792  */
1793 struct mwl8k_cmd_set_rf_channel {
1794         struct mwl8k_cmd_pkt header;
1795         __le16 action;
1796         __u8 current_channel;
1797         __le32 channel_flags;
1798 } __attribute__((packed));
1799
1800 static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
1801                                     struct ieee80211_channel *channel)
1802 {
1803         struct mwl8k_cmd_set_rf_channel *cmd;
1804         int rc;
1805
1806         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1807         if (cmd == NULL)
1808                 return -ENOMEM;
1809
1810         cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RF_CHANNEL);
1811         cmd->header.length = cpu_to_le16(sizeof(*cmd));
1812         cmd->action = cpu_to_le16(MWL8K_CMD_SET);
1813         cmd->current_channel = channel->hw_value;
1814         if (channel->band == IEEE80211_BAND_2GHZ)
1815                 cmd->channel_flags = cpu_to_le32(0x00000081);
1816         else
1817                 cmd->channel_flags = cpu_to_le32(0x00000000);
1818
1819         rc = mwl8k_post_cmd(hw, &cmd->header);
1820         kfree(cmd);
1821
1822         return rc;
1823 }
1824
1825 /*
1826  * CMD_SET_SLOT.
1827  */
1828 struct mwl8k_cmd_set_slot {
1829         struct mwl8k_cmd_pkt header;
1830         __le16 action;
1831         __u8 short_slot;
1832 } __attribute__((packed));
1833
1834 static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, bool short_slot_time)
1835 {
1836         struct mwl8k_cmd_set_slot *cmd;
1837         int rc;
1838
1839         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1840         if (cmd == NULL)
1841                 return -ENOMEM;
1842
1843         cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT);
1844         cmd->header.length = cpu_to_le16(sizeof(*cmd));
1845         cmd->action = cpu_to_le16(MWL8K_CMD_SET);
1846         cmd->short_slot = short_slot_time;
1847
1848         rc = mwl8k_post_cmd(hw, &cmd->header);
1849         kfree(cmd);
1850
1851         return rc;
1852 }
1853
1854 /*
1855  * CMD_MIMO_CONFIG.
1856  */
1857 struct mwl8k_cmd_mimo_config {
1858         struct mwl8k_cmd_pkt header;
1859         __le32 action;
1860         __u8 rx_antenna_map;
1861         __u8 tx_antenna_map;
1862 } __attribute__((packed));
1863
1864 static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx)
1865 {
1866         struct mwl8k_cmd_mimo_config *cmd;
1867         int rc;
1868
1869         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1870         if (cmd == NULL)
1871                 return -ENOMEM;
1872
1873         cmd->header.code = cpu_to_le16(MWL8K_CMD_MIMO_CONFIG);
1874         cmd->header.length = cpu_to_le16(sizeof(*cmd));
1875         cmd->action = cpu_to_le32((u32)MWL8K_CMD_SET);
1876         cmd->rx_antenna_map = rx;
1877         cmd->tx_antenna_map = tx;
1878
1879         rc = mwl8k_post_cmd(hw, &cmd->header);
1880         kfree(cmd);
1881
1882         return rc;
1883 }
1884
1885 /*
1886  * CMD_ENABLE_SNIFFER.
1887  */
1888 struct mwl8k_cmd_enable_sniffer {
1889         struct mwl8k_cmd_pkt header;
1890         __le32 action;
1891 } __attribute__((packed));
1892
1893 static int mwl8k_enable_sniffer(struct ieee80211_hw *hw, bool enable)
1894 {
1895         struct mwl8k_cmd_enable_sniffer *cmd;
1896         int rc;
1897
1898         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1899         if (cmd == NULL)
1900                 return -ENOMEM;
1901
1902         cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER);
1903         cmd->header.length = cpu_to_le16(sizeof(*cmd));
1904         cmd->action = cpu_to_le32(!!enable);
1905
1906         rc = mwl8k_post_cmd(hw, &cmd->header);
1907         kfree(cmd);
1908
1909         return rc;
1910 }
1911
1912 /*
1913  * CMD_SET_RATEADAPT_MODE.
1914  */
1915 struct mwl8k_cmd_set_rate_adapt_mode {
1916         struct mwl8k_cmd_pkt header;
1917         __le16 action;
1918         __le16 mode;
1919 } __attribute__((packed));
1920
1921 static int mwl8k_cmd_setrateadaptmode(struct ieee80211_hw *hw, __u16 mode)
1922 {
1923         struct mwl8k_cmd_set_rate_adapt_mode *cmd;
1924         int rc;
1925
1926         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1927         if (cmd == NULL)
1928                 return -ENOMEM;
1929
1930         cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATEADAPT_MODE);
1931         cmd->header.length = cpu_to_le16(sizeof(*cmd));
1932         cmd->action = cpu_to_le16(MWL8K_CMD_SET);
1933         cmd->mode = cpu_to_le16(mode);
1934
1935         rc = mwl8k_post_cmd(hw, &cmd->header);
1936         kfree(cmd);
1937
1938         return rc;
1939 }
1940
1941 /*
1942  * CMD_SET_WMM_MODE.
1943  */
1944 struct mwl8k_cmd_set_wmm {
1945         struct mwl8k_cmd_pkt header;
1946         __le16 action;
1947 } __attribute__((packed));
1948
1949 static int mwl8k_set_wmm(struct ieee80211_hw *hw, bool enable)
1950 {
1951         struct mwl8k_priv *priv = hw->priv;
1952         struct mwl8k_cmd_set_wmm *cmd;
1953         int rc;
1954
1955         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1956         if (cmd == NULL)
1957                 return -ENOMEM;
1958
1959         cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE);
1960         cmd->header.length = cpu_to_le16(sizeof(*cmd));
1961         cmd->action = cpu_to_le16(!!enable);
1962
1963         rc = mwl8k_post_cmd(hw, &cmd->header);
1964         kfree(cmd);
1965
1966         if (!rc)
1967                 priv->wmm_enabled = enable;
1968
1969         return rc;
1970 }
1971
1972 /*
1973  * CMD_SET_RTS_THRESHOLD.
1974  */
1975 struct mwl8k_cmd_rts_threshold {
1976         struct mwl8k_cmd_pkt header;
1977         __le16 action;
1978         __le16 threshold;
1979 } __attribute__((packed));
1980
1981 static int mwl8k_rts_threshold(struct ieee80211_hw *hw,
1982                                u16 action, u16 *threshold)
1983 {
1984         struct mwl8k_cmd_rts_threshold *cmd;
1985         int rc;
1986
1987         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1988         if (cmd == NULL)
1989                 return -ENOMEM;
1990
1991         cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD);
1992         cmd->header.length = cpu_to_le16(sizeof(*cmd));
1993         cmd->action = cpu_to_le16(action);
1994         cmd->threshold = cpu_to_le16(*threshold);
1995
1996         rc = mwl8k_post_cmd(hw, &cmd->header);
1997         kfree(cmd);
1998
1999         return rc;
2000 }
2001
2002 /*
2003  * CMD_SET_EDCA_PARAMS.
2004  */
2005 struct mwl8k_cmd_set_edca_params {
2006         struct mwl8k_cmd_pkt header;
2007
2008         /* See MWL8K_SET_EDCA_XXX below */
2009         __le16 action;
2010
2011         /* TX opportunity in units of 32 us */
2012         __le16 txop;
2013
2014         /* Log exponent of max contention period: 0...15*/
2015         __u8 log_cw_max;
2016
2017         /* Log exponent of min contention period: 0...15 */
2018         __u8 log_cw_min;
2019
2020         /* Adaptive interframe spacing in units of 32us */
2021         __u8 aifs;
2022
2023         /* TX queue to configure */
2024         __u8 txq;
2025 } __attribute__((packed));
2026
2027 #define MWL8K_SET_EDCA_CW       0x01
2028 #define MWL8K_SET_EDCA_TXOP     0x02
2029 #define MWL8K_SET_EDCA_AIFS     0x04
2030
2031 #define MWL8K_SET_EDCA_ALL      (MWL8K_SET_EDCA_CW | \
2032                                  MWL8K_SET_EDCA_TXOP | \
2033                                  MWL8K_SET_EDCA_AIFS)
2034
2035 static int
2036 mwl8k_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
2037                 __u16 cw_min, __u16 cw_max,
2038                 __u8 aifs, __u16 txop)
2039 {
2040         struct mwl8k_cmd_set_edca_params *cmd;
2041         int rc;
2042
2043         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2044         if (cmd == NULL)
2045                 return -ENOMEM;
2046
2047         cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS);
2048         cmd->header.length = cpu_to_le16(sizeof(*cmd));
2049         cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL);
2050         cmd->txop = cpu_to_le16(txop);
2051         cmd->log_cw_max = (u8)ilog2(cw_max + 1);
2052         cmd->log_cw_min = (u8)ilog2(cw_min + 1);
2053         cmd->aifs = aifs;
2054         cmd->txq = qnum;
2055
2056         rc = mwl8k_post_cmd(hw, &cmd->header);
2057         kfree(cmd);
2058
2059         return rc;
2060 }
2061
2062 /*
2063  * CMD_FINALIZE_JOIN.
2064  */
2065
2066 /* FJ beacon buffer size is compiled into the firmware.  */
2067 #define MWL8K_FJ_BEACON_MAXLEN  128
2068
2069 struct mwl8k_cmd_finalize_join {
2070         struct mwl8k_cmd_pkt header;
2071         __le32 sleep_interval;  /* Number of beacon periods to sleep */
2072         __u8 beacon_data[MWL8K_FJ_BEACON_MAXLEN];
2073 } __attribute__((packed));
2074
2075 static int mwl8k_finalize_join(struct ieee80211_hw *hw, void *frame,
2076                                 __u16 framelen, __u16 dtim)
2077 {
2078         struct mwl8k_cmd_finalize_join *cmd;
2079         struct ieee80211_mgmt *payload = frame;
2080         u16 hdrlen;
2081         u32 payload_len;
2082         int rc;
2083
2084         if (frame == NULL)
2085                 return -EINVAL;
2086
2087         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2088         if (cmd == NULL)
2089                 return -ENOMEM;
2090
2091         cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN);
2092         cmd->header.length = cpu_to_le16(sizeof(*cmd));
2093         cmd->sleep_interval = cpu_to_le32(dtim ? dtim : 1);
2094
2095         hdrlen = ieee80211_hdrlen(payload->frame_control);
2096
2097         payload_len = framelen > hdrlen ? framelen - hdrlen : 0;
2098
2099         /* XXX TBD Might just have to abort and return an error */
2100         if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
2101                 printk(KERN_ERR "%s(): WARNING: Incomplete beacon "
2102                         "sent to firmware. Sz=%u MAX=%u\n", __func__,
2103                         payload_len, MWL8K_FJ_BEACON_MAXLEN);
2104
2105         if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
2106                 payload_len = MWL8K_FJ_BEACON_MAXLEN;
2107
2108         if (payload && payload_len)
2109                 memcpy(cmd->beacon_data, &payload->u.beacon, payload_len);
2110
2111         rc = mwl8k_post_cmd(hw, &cmd->header);
2112         kfree(cmd);
2113         return rc;
2114 }
2115
2116 /*
2117  * CMD_UPDATE_STADB.
2118  */
2119 struct mwl8k_cmd_update_sta_db {
2120         struct mwl8k_cmd_pkt header;
2121
2122         /* See STADB_ACTION_TYPE */
2123         __le32  action;
2124
2125         /* Peer MAC address */
2126         __u8    peer_addr[ETH_ALEN];
2127
2128         __le32  reserved;
2129
2130         /* Peer info - valid during add/update.  */
2131         struct peer_capability_info     peer_info;
2132 } __attribute__((packed));
2133
2134 static int mwl8k_cmd_update_sta_db(struct ieee80211_hw *hw,
2135                 struct ieee80211_vif *vif, __u32 action)
2136 {
2137         struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
2138         struct ieee80211_bss_conf *info = &mv_vif->bss_info;
2139         struct mwl8k_cmd_update_sta_db *cmd;
2140         struct peer_capability_info *peer_info;
2141         struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
2142         int rc;
2143         __u8 count, *rates;
2144
2145         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2146         if (cmd == NULL)
2147                 return -ENOMEM;
2148
2149         cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
2150         cmd->header.length = cpu_to_le16(sizeof(*cmd));
2151
2152         cmd->action = cpu_to_le32(action);
2153         peer_info = &cmd->peer_info;
2154         memcpy(cmd->peer_addr, mv_vif->bssid, ETH_ALEN);
2155
2156         switch (action) {
2157         case MWL8K_STA_DB_ADD_ENTRY:
2158         case MWL8K_STA_DB_MODIFY_ENTRY:
2159                 /* Build peer_info block */
2160                 peer_info->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT;
2161                 peer_info->basic_caps = cpu_to_le16(info->assoc_capability);
2162                 peer_info->interop = 1;
2163                 peer_info->amsdu_enabled = 0;
2164
2165                 rates = peer_info->legacy_rates;
2166                 for (count = 0; count < mv_vif->legacy_nrates; count++)
2167                         rates[count] = bitrates[count].hw_value;
2168
2169                 rc = mwl8k_post_cmd(hw, &cmd->header);
2170                 if (rc == 0)
2171                         mv_vif->peer_id = peer_info->station_id;
2172
2173                 break;
2174
2175         case MWL8K_STA_DB_DEL_ENTRY:
2176         case MWL8K_STA_DB_FLUSH:
2177         default:
2178                 rc = mwl8k_post_cmd(hw, &cmd->header);
2179                 if (rc == 0)
2180                         mv_vif->peer_id = 0;
2181                 break;
2182         }
2183         kfree(cmd);
2184
2185         return rc;
2186 }
2187
2188 /*
2189  * CMD_SET_AID.
2190  */
2191 #define MWL8K_RATE_INDEX_MAX_ARRAY                      14
2192
2193 #define MWL8K_FRAME_PROT_DISABLED                       0x00
2194 #define MWL8K_FRAME_PROT_11G                            0x07
2195 #define MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY              0x02
2196 #define MWL8K_FRAME_PROT_11N_HT_ALL                     0x06
2197
2198 struct mwl8k_cmd_update_set_aid {
2199         struct  mwl8k_cmd_pkt header;
2200         __le16  aid;
2201
2202          /* AP's MAC address (BSSID) */
2203         __u8    bssid[ETH_ALEN];
2204         __le16  protection_mode;
2205         __u8    supp_rates[MWL8K_RATE_INDEX_MAX_ARRAY];
2206 } __attribute__((packed));
2207
2208 static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
2209                                         struct ieee80211_vif *vif)
2210 {
2211         struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
2212         struct ieee80211_bss_conf *info = &mv_vif->bss_info;
2213         struct mwl8k_cmd_update_set_aid *cmd;
2214         struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
2215         int count;
2216         u16 prot_mode;
2217         int rc;
2218
2219         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2220         if (cmd == NULL)
2221                 return -ENOMEM;
2222
2223         cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_AID);
2224         cmd->header.length = cpu_to_le16(sizeof(*cmd));
2225         cmd->aid = cpu_to_le16(info->aid);
2226
2227         memcpy(cmd->bssid, mv_vif->bssid, ETH_ALEN);
2228
2229         if (info->use_cts_prot) {
2230                 prot_mode = MWL8K_FRAME_PROT_11G;
2231         } else {
2232                 switch (info->ht_operation_mode &
2233                         IEEE80211_HT_OP_MODE_PROTECTION) {
2234                 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
2235                         prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY;
2236                         break;
2237                 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
2238                         prot_mode = MWL8K_FRAME_PROT_11N_HT_ALL;
2239                         break;
2240                 default:
2241                         prot_mode = MWL8K_FRAME_PROT_DISABLED;
2242                         break;
2243                 }
2244         }
2245         cmd->protection_mode = cpu_to_le16(prot_mode);
2246
2247         for (count = 0; count < mv_vif->legacy_nrates; count++)
2248                 cmd->supp_rates[count] = bitrates[count].hw_value;
2249
2250         rc = mwl8k_post_cmd(hw, &cmd->header);
2251         kfree(cmd);
2252
2253         return rc;
2254 }
2255
2256 /*
2257  * CMD_SET_RATE.
2258  */
2259 struct mwl8k_cmd_update_rateset {
2260         struct  mwl8k_cmd_pkt header;
2261         __u8    legacy_rates[MWL8K_RATE_INDEX_MAX_ARRAY];
2262
2263         /* Bitmap for supported MCS codes.  */
2264         __u8    mcs_set[MWL8K_IEEE_LEGACY_DATA_RATES];
2265         __u8    reserved[MWL8K_IEEE_LEGACY_DATA_RATES];
2266 } __attribute__((packed));
2267
2268 static int mwl8k_update_rateset(struct ieee80211_hw *hw,
2269                 struct ieee80211_vif *vif)
2270 {
2271         struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
2272         struct mwl8k_cmd_update_rateset *cmd;
2273         struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
2274         int count;
2275         int rc;
2276
2277         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2278         if (cmd == NULL)
2279                 return -ENOMEM;
2280
2281         cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE);
2282         cmd->header.length = cpu_to_le16(sizeof(*cmd));
2283
2284         for (count = 0; count < mv_vif->legacy_nrates; count++)
2285                 cmd->legacy_rates[count] = bitrates[count].hw_value;
2286
2287         rc = mwl8k_post_cmd(hw, &cmd->header);
2288         kfree(cmd);
2289
2290         return rc;
2291 }
2292
2293 /*
2294  * CMD_USE_FIXED_RATE.
2295  */
2296 #define MWL8K_RATE_TABLE_SIZE   8
2297 #define MWL8K_UCAST_RATE        0
2298 #define MWL8K_USE_AUTO_RATE     0x0002
2299
2300 struct mwl8k_rate_entry {
2301         /* Set to 1 if HT rate, 0 if legacy.  */
2302         __le32  is_ht_rate;
2303
2304         /* Set to 1 to use retry_count field.  */
2305         __le32  enable_retry;
2306
2307         /* Specified legacy rate or MCS.  */
2308         __le32  rate;
2309
2310         /* Number of allowed retries.  */
2311         __le32  retry_count;
2312 } __attribute__((packed));
2313
2314 struct mwl8k_rate_table {
2315         /* 1 to allow specified rate and below */
2316         __le32  allow_rate_drop;
2317         __le32  num_rates;
2318         struct mwl8k_rate_entry rate_entry[MWL8K_RATE_TABLE_SIZE];
2319 } __attribute__((packed));
2320
2321 struct mwl8k_cmd_use_fixed_rate {
2322         struct  mwl8k_cmd_pkt header;
2323         __le32  action;
2324         struct mwl8k_rate_table rate_table;
2325
2326         /* Unicast, Broadcast or Multicast */
2327         __le32  rate_type;
2328         __le32  reserved1;
2329         __le32  reserved2;
2330 } __attribute__((packed));
2331
2332 static int mwl8k_cmd_use_fixed_rate(struct ieee80211_hw *hw,
2333         u32 action, u32 rate_type, struct mwl8k_rate_table *rate_table)
2334 {
2335         struct mwl8k_cmd_use_fixed_rate *cmd;
2336         int count;
2337         int rc;
2338
2339         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2340         if (cmd == NULL)
2341                 return -ENOMEM;
2342
2343         cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE);
2344         cmd->header.length = cpu_to_le16(sizeof(*cmd));
2345
2346         cmd->action = cpu_to_le32(action);
2347         cmd->rate_type = cpu_to_le32(rate_type);
2348
2349         if (rate_table != NULL) {
2350                 /* Copy over each field manually so
2351                 * that bitflipping can be done
2352                 */
2353                 cmd->rate_table.allow_rate_drop =
2354                                 cpu_to_le32(rate_table->allow_rate_drop);
2355                 cmd->rate_table.num_rates =
2356                                 cpu_to_le32(rate_table->num_rates);
2357
2358                 for (count = 0; count < rate_table->num_rates; count++) {
2359                         struct mwl8k_rate_entry *dst =
2360                                 &cmd->rate_table.rate_entry[count];
2361                         struct mwl8k_rate_entry *src =
2362                                 &rate_table->rate_entry[count];
2363
2364                         dst->is_ht_rate = cpu_to_le32(src->is_ht_rate);
2365                         dst->enable_retry = cpu_to_le32(src->enable_retry);
2366                         dst->rate = cpu_to_le32(src->rate);
2367                         dst->retry_count = cpu_to_le32(src->retry_count);
2368                 }
2369         }
2370
2371         rc = mwl8k_post_cmd(hw, &cmd->header);
2372         kfree(cmd);
2373
2374         return rc;
2375 }
2376
2377
2378 /*
2379  * Interrupt handling.
2380  */
2381 static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
2382 {
2383         struct ieee80211_hw *hw = dev_id;
2384         struct mwl8k_priv *priv = hw->priv;
2385         u32 status;
2386
2387         status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
2388         iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
2389
2390         if (!status)
2391                 return IRQ_NONE;
2392
2393         if (status & MWL8K_A2H_INT_TX_DONE)
2394                 tasklet_schedule(&priv->tx_reclaim_task);
2395
2396         if (status & MWL8K_A2H_INT_RX_READY) {
2397                 while (rxq_process(hw, 0, 1))
2398                         rxq_refill(hw, 0, 1);
2399         }
2400
2401         if (status & MWL8K_A2H_INT_OPC_DONE) {
2402                 if (priv->hostcmd_wait != NULL) {
2403                         complete(priv->hostcmd_wait);
2404                         priv->hostcmd_wait = NULL;
2405                 }
2406         }
2407
2408         if (status & MWL8K_A2H_INT_QUEUE_EMPTY) {
2409                 if (!priv->inconfig &&
2410                         priv->radio_on &&
2411                         mwl8k_txq_busy(priv))
2412                                 mwl8k_tx_start(priv);
2413         }
2414
2415         return IRQ_HANDLED;
2416 }
2417
2418
2419 /*
2420  * Core driver operations.
2421  */
2422 static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2423 {
2424         struct mwl8k_priv *priv = hw->priv;
2425         int index = skb_get_queue_mapping(skb);
2426         int rc;
2427
2428         if (priv->current_channel == NULL) {
2429                 printk(KERN_DEBUG "%s: dropped TX frame since radio "
2430                        "disabled\n", priv->name);
2431                 dev_kfree_skb(skb);
2432                 return NETDEV_TX_OK;
2433         }
2434
2435         rc = mwl8k_txq_xmit(hw, index, skb);
2436
2437         return rc;
2438 }
2439
2440 struct mwl8k_work_struct {
2441         /* Initialized by mwl8k_queue_work().  */
2442         struct work_struct wt;
2443
2444         /* Required field passed in to mwl8k_queue_work().  */
2445         struct ieee80211_hw *hw;
2446
2447         /* Required field passed in to mwl8k_queue_work().  */
2448         int (*wfunc)(struct work_struct *w);
2449
2450         /* Initialized by mwl8k_queue_work().  */
2451         struct completion *cmd_wait;
2452
2453         /* Result code.  */
2454         int rc;
2455
2456         /*
2457          * Optional field. Refer to explanation of MWL8K_WQ_XXX_XXX
2458          * flags for explanation.  Defaults to MWL8K_WQ_DEFAULT_OPTIONS.
2459          */
2460         u32 options;
2461
2462         /* Optional field.  Defaults to MWL8K_CONFIG_TIMEOUT_MS.  */
2463         unsigned long timeout_ms;
2464
2465         /* Optional field.  Defaults to MWL8K_WQ_TXWAIT_ATTEMPTS.  */
2466         u32 txwait_attempts;
2467
2468         /* Optional field.  Defaults to MWL8K_TXWAIT_MS.  */
2469         u32 tx_timeout_ms;
2470         u32 step;
2471 };
2472
2473 /* Flags controlling behavior of config queue requests */
2474
2475 /* Caller spins while waiting for completion.  */
2476 #define MWL8K_WQ_SPIN                   0x00000001
2477
2478 /* Wait for TX queues to empty before proceeding with configuration.  */
2479 #define MWL8K_WQ_TX_WAIT_EMPTY          0x00000002
2480
2481 /* Queue request and return immediately.  */
2482 #define MWL8K_WQ_POST_REQUEST           0x00000004
2483
2484 /*
2485  * Caller sleeps and waits for task complete notification.
2486  * Do not use in atomic context.
2487  */
2488 #define MWL8K_WQ_SLEEP                  0x00000008
2489
2490 /* Free work struct when task is done.  */
2491 #define MWL8K_WQ_FREE_WORKSTRUCT        0x00000010
2492
2493 /*
2494  * Config request is queued and returns to caller imediately.  Use
2495  * this in atomic context. Work struct is freed by mwl8k_queue_work()
2496  * when this flag is set.
2497  */
2498 #define MWL8K_WQ_QUEUE_ONLY     (MWL8K_WQ_POST_REQUEST | \
2499                                  MWL8K_WQ_FREE_WORKSTRUCT)
2500
2501 /* Default work queue behavior is to sleep and wait for tx completion.  */
2502 #define MWL8K_WQ_DEFAULT_OPTIONS (MWL8K_WQ_SLEEP | MWL8K_WQ_TX_WAIT_EMPTY)
2503
2504 /*
2505  * Default config request timeout.  Add adjustments to make sure the
2506  * config thread waits long enough for both tx wait and cmd wait before
2507  * timing out.
2508  */
2509
2510 /* Time to wait for all TXQs to drain.  TX Doorbell is pressed each time.  */
2511 #define MWL8K_TXWAIT_TIMEOUT_MS         1000
2512
2513 /* Default number of TX wait attempts.  */
2514 #define MWL8K_WQ_TXWAIT_ATTEMPTS        4
2515
2516 /* Total time to wait for TXQ to drain.  */
2517 #define MWL8K_TXWAIT_MS                 (MWL8K_TXWAIT_TIMEOUT_MS * \
2518                                                 MWL8K_WQ_TXWAIT_ATTEMPTS)
2519
2520 /* Scheduling slop.  */
2521 #define MWL8K_OS_SCHEDULE_OVERHEAD_MS   200
2522
2523 #define MWL8K_CONFIG_TIMEOUT_MS (MWL8K_CMD_TIMEOUT_MS + \
2524                                  MWL8K_TXWAIT_MS + \
2525                                  MWL8K_OS_SCHEDULE_OVERHEAD_MS)
2526
2527 static void mwl8k_config_thread(struct work_struct *wt)
2528 {
2529         struct mwl8k_work_struct *worker = (struct mwl8k_work_struct *)wt;
2530         struct ieee80211_hw *hw = worker->hw;
2531         struct mwl8k_priv *priv = hw->priv;
2532         int rc = 0;
2533
2534         spin_lock_irq(&priv->tx_lock);
2535         priv->inconfig = true;
2536         spin_unlock_irq(&priv->tx_lock);
2537
2538         ieee80211_stop_queues(hw);
2539
2540         /*
2541          * Wait for host queues to drain before doing PHY
2542          * reconfiguration. This avoids interrupting any in-flight
2543          * DMA transfers to the hardware.
2544          */
2545         if (worker->options & MWL8K_WQ_TX_WAIT_EMPTY) {
2546                 u32 timeout;
2547                 u32 time_remaining;
2548                 u32 iter;
2549                 u32 tx_wait_attempts = worker->txwait_attempts;
2550
2551                 time_remaining = worker->tx_timeout_ms;
2552                 if (!tx_wait_attempts)
2553                         tx_wait_attempts = 1;
2554
2555                 timeout = worker->tx_timeout_ms/tx_wait_attempts;
2556                 if (!timeout)
2557                         timeout = 1;
2558
2559                 iter = tx_wait_attempts;
2560                 do {
2561                         int wait_time;
2562
2563                         if (time_remaining > timeout) {
2564                                 time_remaining -= timeout;
2565                                 wait_time = timeout;
2566                         } else
2567                                 wait_time = time_remaining;
2568
2569                         if (!wait_time)
2570                                 wait_time = 1;
2571
2572                         rc = mwl8k_tx_wait_empty(hw, wait_time);
2573                         if (rc)
2574                                 printk(KERN_ERR "%s() txwait timeout=%ums "
2575                                         "Retry:%u/%u\n", __func__, timeout,
2576                                         tx_wait_attempts - iter + 1,
2577                                         tx_wait_attempts);
2578
2579                 } while (rc && --iter);
2580
2581                 rc = iter ? 0 : -ETIMEDOUT;
2582         }
2583         if (!rc)
2584                 rc = worker->wfunc(wt);
2585
2586         spin_lock_irq(&priv->tx_lock);
2587         priv->inconfig = false;
2588         if (priv->pending_tx_pkts && priv->radio_on)
2589                 mwl8k_tx_start(priv);
2590         spin_unlock_irq(&priv->tx_lock);
2591         ieee80211_wake_queues(hw);
2592
2593         worker->rc = rc;
2594         if (worker->options & MWL8K_WQ_SLEEP)
2595                 complete(worker->cmd_wait);
2596
2597         if (worker->options & MWL8K_WQ_FREE_WORKSTRUCT)
2598                 kfree(wt);
2599 }
2600
2601 static int mwl8k_queue_work(struct ieee80211_hw *hw,
2602                                 struct mwl8k_work_struct *worker,
2603                                 struct workqueue_struct *wqueue,
2604                                 int (*wfunc)(struct work_struct *w))
2605 {
2606         unsigned long timeout = 0;
2607         int rc = 0;
2608
2609         DECLARE_COMPLETION_ONSTACK(cmd_wait);
2610
2611         if (!worker->timeout_ms)
2612                 worker->timeout_ms = MWL8K_CONFIG_TIMEOUT_MS;
2613
2614         if (!worker->options)
2615                 worker->options = MWL8K_WQ_DEFAULT_OPTIONS;
2616
2617         if (!worker->txwait_attempts)
2618                 worker->txwait_attempts = MWL8K_WQ_TXWAIT_ATTEMPTS;
2619
2620         if (!worker->tx_timeout_ms)
2621                 worker->tx_timeout_ms = MWL8K_TXWAIT_MS;
2622
2623         worker->hw = hw;
2624         worker->cmd_wait = &cmd_wait;
2625         worker->rc = 1;
2626         worker->wfunc = wfunc;
2627
2628         INIT_WORK(&worker->wt, mwl8k_config_thread);
2629         queue_work(wqueue, &worker->wt);
2630
2631         if (worker->options & MWL8K_WQ_POST_REQUEST) {
2632                 rc = 0;
2633         } else {
2634                 if (worker->options & MWL8K_WQ_SPIN) {
2635                         timeout = worker->timeout_ms;
2636                         while (timeout && (worker->rc > 0)) {
2637                                 mdelay(1);
2638                                 timeout--;
2639                         }
2640                 } else if (worker->options & MWL8K_WQ_SLEEP)
2641                         timeout = wait_for_completion_timeout(&cmd_wait,
2642                                 msecs_to_jiffies(worker->timeout_ms));
2643
2644                 if (timeout)
2645                         rc = worker->rc;
2646                 else {
2647                         cancel_work_sync(&worker->wt);
2648                         rc = -ETIMEDOUT;
2649                 }
2650         }
2651
2652         return rc;
2653 }
2654
2655 struct mwl8k_start_worker {
2656         struct mwl8k_work_struct header;
2657 };
2658
2659 static int mwl8k_start_wt(struct work_struct *wt)
2660 {
2661         struct mwl8k_start_worker *worker = (struct mwl8k_start_worker *)wt;
2662         struct ieee80211_hw *hw = worker->header.hw;
2663         struct mwl8k_priv *priv = hw->priv;
2664         int rc = 0;
2665
2666         if (priv->vif != NULL) {
2667                 rc = -EIO;
2668                 goto mwl8k_start_exit;
2669         }
2670
2671         /* Turn on radio */
2672         if (mwl8k_cmd_802_11_radio_enable(hw)) {
2673                 rc = -EIO;
2674                 goto mwl8k_start_exit;
2675         }
2676
2677         /* Purge TX/RX HW queues */
2678         if (mwl8k_cmd_set_pre_scan(hw)) {
2679                 rc = -EIO;
2680                 goto mwl8k_start_exit;
2681         }
2682
2683         if (mwl8k_cmd_set_post_scan(hw, "\x00\x00\x00\x00\x00\x00")) {
2684                 rc = -EIO;
2685                 goto mwl8k_start_exit;
2686         }
2687
2688         /* Enable firmware rate adaptation */
2689         if (mwl8k_cmd_setrateadaptmode(hw, 0)) {
2690                 rc = -EIO;
2691                 goto mwl8k_start_exit;
2692         }
2693
2694         /* Disable WMM. WMM gets enabled when stack sends WMM parms */
2695         if (mwl8k_set_wmm(hw, 0)) {
2696                 rc = -EIO;
2697                 goto mwl8k_start_exit;
2698         }
2699
2700         /* Disable sniffer mode */
2701         if (mwl8k_enable_sniffer(hw, 0))
2702                 rc = -EIO;
2703
2704 mwl8k_start_exit:
2705         return rc;
2706 }
2707
2708 static int mwl8k_start(struct ieee80211_hw *hw)
2709 {
2710         struct mwl8k_start_worker *worker;
2711         struct mwl8k_priv *priv = hw->priv;
2712         int rc;
2713
2714         /* Enable tx reclaim tasklet */
2715         tasklet_enable(&priv->tx_reclaim_task);
2716
2717         rc = request_irq(priv->pdev->irq, &mwl8k_interrupt,
2718                          IRQF_SHARED, MWL8K_NAME, hw);
2719         if (rc) {
2720                 printk(KERN_ERR "%s: failed to register IRQ handler\n",
2721                        priv->name);
2722                 rc = -EIO;
2723                 goto mwl8k_start_disable_tasklet;
2724         }
2725
2726         /* Enable interrupts */
2727         iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
2728
2729         worker = kzalloc(sizeof(*worker), GFP_KERNEL);
2730         if (worker == NULL) {
2731                 rc = -ENOMEM;
2732                 goto mwl8k_start_disable_irq;
2733         }
2734
2735         rc = mwl8k_queue_work(hw, &worker->header,
2736                               priv->config_wq, mwl8k_start_wt);
2737         kfree(worker);
2738         if (!rc)
2739                 return rc;
2740
2741         if (rc == -ETIMEDOUT)
2742                 printk(KERN_ERR "%s() timed out\n", __func__);
2743
2744         rc = -EIO;
2745
2746 mwl8k_start_disable_irq:
2747         spin_lock_irq(&priv->tx_lock);
2748         iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
2749         spin_unlock_irq(&priv->tx_lock);
2750         free_irq(priv->pdev->irq, hw);
2751
2752 mwl8k_start_disable_tasklet:
2753         tasklet_disable(&priv->tx_reclaim_task);
2754
2755         return rc;
2756 }
2757
2758 struct mwl8k_stop_worker {
2759         struct mwl8k_work_struct header;
2760 };
2761
2762 static int mwl8k_stop_wt(struct work_struct *wt)
2763 {
2764         struct mwl8k_stop_worker *worker = (struct mwl8k_stop_worker *)wt;
2765         struct ieee80211_hw *hw = worker->header.hw;
2766
2767         return mwl8k_cmd_802_11_radio_disable(hw);
2768 }
2769
2770 static void mwl8k_stop(struct ieee80211_hw *hw)
2771 {
2772         int rc;
2773         struct mwl8k_stop_worker *worker;
2774         struct mwl8k_priv *priv = hw->priv;
2775         int i;
2776
2777         if (priv->vif != NULL)
2778                 return;
2779
2780         ieee80211_stop_queues(hw);
2781
2782         worker = kzalloc(sizeof(*worker), GFP_KERNEL);
2783         if (worker == NULL)
2784                 return;
2785
2786         rc = mwl8k_queue_work(hw, &worker->header,
2787                               priv->config_wq, mwl8k_stop_wt);
2788         kfree(worker);
2789         if (rc == -ETIMEDOUT)
2790                 printk(KERN_ERR "%s() timed out\n", __func__);
2791
2792         /* Disable interrupts */
2793         spin_lock_irq(&priv->tx_lock);
2794         iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
2795         spin_unlock_irq(&priv->tx_lock);
2796         free_irq(priv->pdev->irq, hw);
2797
2798         /* Stop finalize join worker */
2799         cancel_work_sync(&priv->finalize_join_worker);
2800         if (priv->beacon_skb != NULL)
2801                 dev_kfree_skb(priv->beacon_skb);
2802
2803         /* Stop tx reclaim tasklet */
2804         tasklet_disable(&priv->tx_reclaim_task);
2805
2806         /* Stop config thread */
2807         flush_workqueue(priv->config_wq);
2808
2809         /* Return all skbs to mac80211 */
2810         for (i = 0; i < MWL8K_TX_QUEUES; i++)
2811                 mwl8k_txq_reclaim(hw, i, 1);
2812 }
2813
2814 static int mwl8k_add_interface(struct ieee80211_hw *hw,
2815                                 struct ieee80211_if_init_conf *conf)
2816 {
2817         struct mwl8k_priv *priv = hw->priv;
2818         struct mwl8k_vif *mwl8k_vif;
2819
2820         /*
2821          * We only support one active interface at a time.
2822          */
2823         if (priv->vif != NULL)
2824                 return -EBUSY;
2825
2826         /*
2827          * We only support managed interfaces for now.
2828          */
2829         if (conf->type != NL80211_IFTYPE_STATION)
2830                 return -EINVAL;
2831
2832         /* Clean out driver private area */
2833         mwl8k_vif = MWL8K_VIF(conf->vif);
2834         memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
2835
2836         /* Save the mac address */
2837         memcpy(mwl8k_vif->mac_addr, conf->mac_addr, ETH_ALEN);
2838
2839         /* Back pointer to parent config block */
2840         mwl8k_vif->priv = priv;
2841
2842         /* Setup initial PHY parameters */
2843         memcpy(mwl8k_vif->legacy_rates,
2844                 priv->rates, sizeof(mwl8k_vif->legacy_rates));
2845         mwl8k_vif->legacy_nrates = ARRAY_SIZE(priv->rates);
2846
2847         /* Set Initial sequence number to zero */
2848         mwl8k_vif->seqno = 0;
2849
2850         priv->vif = conf->vif;
2851         priv->current_channel = NULL;
2852
2853         return 0;
2854 }
2855
2856 static void mwl8k_remove_interface(struct ieee80211_hw *hw,
2857                                    struct ieee80211_if_init_conf *conf)
2858 {
2859         struct mwl8k_priv *priv = hw->priv;
2860
2861         if (priv->vif == NULL)
2862                 return;
2863
2864         priv->vif = NULL;
2865 }
2866
2867 struct mwl8k_config_worker {
2868         struct mwl8k_work_struct header;
2869         u32 changed;
2870 };
2871
2872 static int mwl8k_config_wt(struct work_struct *wt)
2873 {
2874         struct mwl8k_config_worker *worker =
2875                 (struct mwl8k_config_worker *)wt;
2876         struct ieee80211_hw *hw = worker->header.hw;
2877         struct ieee80211_conf *conf = &hw->conf;
2878         struct mwl8k_priv *priv = hw->priv;
2879         int rc = 0;
2880
2881         if (mwl8k_cmd_802_11_radio_enable(hw)) {
2882                 rc = -EINVAL;
2883                 goto mwl8k_config_exit;
2884         }
2885
2886         priv->current_channel = conf->channel;
2887
2888         if (mwl8k_cmd_set_rf_channel(hw, conf->channel)) {
2889                 rc = -EINVAL;
2890                 goto mwl8k_config_exit;
2891         }
2892
2893         if (conf->power_level > 18)
2894                 conf->power_level = 18;
2895         if (mwl8k_cmd_802_11_rf_tx_power(hw, conf->power_level)) {
2896                 rc = -EINVAL;
2897                 goto mwl8k_config_exit;
2898         }
2899
2900         if (mwl8k_cmd_mimo_config(hw, 0x7, 0x7))
2901                 rc = -EINVAL;
2902
2903 mwl8k_config_exit:
2904         return rc;
2905 }
2906
2907 static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
2908 {
2909         int rc = 0;
2910         struct mwl8k_config_worker *worker;
2911         struct mwl8k_priv *priv = hw->priv;
2912
2913         worker = kzalloc(sizeof(*worker), GFP_KERNEL);
2914         if (worker == NULL)
2915                 return -ENOMEM;
2916
2917         worker->changed = changed;
2918         rc = mwl8k_queue_work(hw, &worker->header,
2919                               priv->config_wq, mwl8k_config_wt);
2920         if (rc == -ETIMEDOUT) {
2921                 printk(KERN_ERR "%s() timed out.\n", __func__);
2922                 rc = -EINVAL;
2923         }
2924
2925         kfree(worker);
2926
2927         /*
2928          * mac80211 will crash on anything other than -EINVAL on
2929          * error. Looks like wireless extensions which calls mac80211
2930          * may be the actual culprit...
2931          */
2932         return rc ? -EINVAL : 0;
2933 }
2934
2935 struct mwl8k_bss_info_changed_worker {
2936         struct mwl8k_work_struct header;
2937         struct ieee80211_vif *vif;
2938         struct ieee80211_bss_conf *info;
2939         u32 changed;
2940 };
2941
2942 static int mwl8k_bss_info_changed_wt(struct work_struct *wt)
2943 {
2944         struct mwl8k_bss_info_changed_worker *worker =
2945                 (struct mwl8k_bss_info_changed_worker *)wt;
2946         struct ieee80211_hw *hw = worker->header.hw;
2947         struct ieee80211_vif *vif = worker->vif;
2948         struct ieee80211_bss_conf *info = worker->info;
2949         u32 changed;
2950         int rc;
2951
2952         struct mwl8k_priv *priv = hw->priv;
2953         struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
2954
2955         changed = worker->changed;
2956         priv->capture_beacon = false;
2957
2958         if (info->assoc) {
2959                 memcpy(&mwl8k_vif->bss_info, info,
2960                         sizeof(struct ieee80211_bss_conf));
2961
2962                 /* Install rates */
2963                 if (mwl8k_update_rateset(hw, vif))
2964                         goto mwl8k_bss_info_changed_exit;
2965
2966                 /* Turn on rate adaptation */
2967                 if (mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE,
2968                         MWL8K_UCAST_RATE, NULL))
2969                         goto mwl8k_bss_info_changed_exit;
2970
2971                 /* Set radio preamble */
2972                 if (mwl8k_set_radio_preamble(hw, info->use_short_preamble))
2973                         goto mwl8k_bss_info_changed_exit;
2974
2975                 /* Set slot time */
2976                 if (mwl8k_cmd_set_slot(hw, info->use_short_slot))
2977                         goto mwl8k_bss_info_changed_exit;
2978
2979                 /* Update peer rate info */
2980                 if (mwl8k_cmd_update_sta_db(hw, vif,
2981                                 MWL8K_STA_DB_MODIFY_ENTRY))
2982                         goto mwl8k_bss_info_changed_exit;
2983
2984                 /* Set AID */
2985                 if (mwl8k_cmd_set_aid(hw, vif))
2986                         goto mwl8k_bss_info_changed_exit;
2987
2988                 /*
2989                  * Finalize the join.  Tell rx handler to process
2990                  * next beacon from our BSSID.
2991                  */
2992                 memcpy(priv->capture_bssid, mwl8k_vif->bssid, ETH_ALEN);
2993                 priv->capture_beacon = true;
2994         } else {
2995                 mwl8k_cmd_update_sta_db(hw, vif, MWL8K_STA_DB_DEL_ENTRY);
2996                 memset(&mwl8k_vif->bss_info, 0,
2997                         sizeof(struct ieee80211_bss_conf));
2998                 memset(mwl8k_vif->bssid, 0, ETH_ALEN);
2999         }
3000
3001 mwl8k_bss_info_changed_exit:
3002         rc = 0;
3003         return rc;
3004 }
3005
3006 static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
3007                                    struct ieee80211_vif *vif,
3008                                    struct ieee80211_bss_conf *info,
3009                                    u32 changed)
3010 {
3011         struct mwl8k_bss_info_changed_worker *worker;
3012         struct mwl8k_priv *priv = hw->priv;
3013         struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
3014         int rc;
3015
3016         if (changed & BSS_CHANGED_BSSID)
3017                 memcpy(mv_vif->bssid, info->bssid, ETH_ALEN);
3018
3019         if ((changed & BSS_CHANGED_ASSOC) == 0)
3020                 return;
3021
3022         worker = kzalloc(sizeof(*worker), GFP_KERNEL);
3023         if (worker == NULL)
3024                 return;
3025
3026         worker->vif = vif;
3027         worker->info = info;
3028         worker->changed = changed;
3029         rc = mwl8k_queue_work(hw, &worker->header,
3030                               priv->config_wq,
3031                               mwl8k_bss_info_changed_wt);
3032         kfree(worker);
3033         if (rc == -ETIMEDOUT)
3034                 printk(KERN_ERR "%s() timed out\n", __func__);
3035 }
3036
3037 static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
3038                                    int mc_count, struct dev_addr_list *mclist)
3039 {
3040         struct mwl8k_cmd_pkt *cmd;
3041
3042         cmd = __mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist);
3043
3044         return (unsigned long)cmd;
3045 }
3046
3047 struct mwl8k_configure_filter_worker {
3048         struct mwl8k_work_struct header;
3049         unsigned int changed_flags;
3050         unsigned int total_flags;
3051         struct mwl8k_cmd_pkt *multicast_adr_cmd;
3052 };
3053
3054 #define MWL8K_SUPPORTED_IF_FLAGS        FIF_BCN_PRBRESP_PROMISC
3055
3056 static int mwl8k_configure_filter_wt(struct work_struct *wt)
3057 {
3058         struct mwl8k_configure_filter_worker *worker =
3059                 (struct mwl8k_configure_filter_worker *)wt;
3060         struct ieee80211_hw *hw = worker->header.hw;
3061         struct mwl8k_priv *priv = hw->priv;
3062         int rc = 0;
3063
3064         if (worker->changed_flags & FIF_BCN_PRBRESP_PROMISC) {
3065                 if (worker->total_flags & FIF_BCN_PRBRESP_PROMISC)
3066                         rc = mwl8k_cmd_set_pre_scan(hw);
3067                 else {
3068                         u8 *bssid;
3069
3070                         bssid = "\x00\x00\x00\x00\x00\x00";
3071                         if (priv->vif != NULL)
3072                                 bssid = MWL8K_VIF(priv->vif)->bssid;
3073
3074                         rc = mwl8k_cmd_set_post_scan(hw, bssid);
3075                 }
3076         }
3077
3078         if (!rc && worker->multicast_adr_cmd != NULL)
3079                 rc = mwl8k_post_cmd(hw, worker->multicast_adr_cmd);
3080         kfree(worker->multicast_adr_cmd);
3081
3082         return rc;
3083 }
3084
3085 static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3086                                    unsigned int changed_flags,
3087                                    unsigned int *total_flags,
3088                                    u64 multicast)
3089 {
3090         struct mwl8k_priv *priv = hw->priv;
3091         struct mwl8k_configure_filter_worker *worker;
3092
3093         /* Clear unsupported feature flags */
3094         *total_flags &= MWL8K_SUPPORTED_IF_FLAGS;
3095
3096         if (!(changed_flags & MWL8K_SUPPORTED_IF_FLAGS))
3097                 return;
3098
3099         worker = kzalloc(sizeof(*worker), GFP_ATOMIC);
3100         if (worker == NULL)
3101                 return;
3102
3103         worker->changed_flags = changed_flags;
3104         worker->total_flags = *total_flags;
3105         worker->multicast_adr_cmd = (void *)(unsigned long)multicast;
3106
3107         mwl8k_queue_work(hw, &worker->header, priv->config_wq,
3108                          mwl8k_configure_filter_wt);
3109 }
3110
3111 struct mwl8k_set_rts_threshold_worker {
3112         struct mwl8k_work_struct header;
3113         u32 value;
3114 };
3115
3116 static int mwl8k_set_rts_threshold_wt(struct work_struct *wt)
3117 {
3118         struct mwl8k_set_rts_threshold_worker *worker =
3119                 (struct mwl8k_set_rts_threshold_worker *)wt;
3120
3121         struct ieee80211_hw *hw = worker->header.hw;
3122         u16 threshold = (u16)(worker->value);
3123         int rc;
3124
3125         rc = mwl8k_rts_threshold(hw, MWL8K_CMD_SET, &threshold);
3126
3127         return rc;
3128 }
3129
3130 static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
3131 {
3132         int rc;
3133         struct mwl8k_set_rts_threshold_worker *worker;
3134         struct mwl8k_priv *priv = hw->priv;
3135
3136         worker = kzalloc(sizeof(*worker), GFP_KERNEL);
3137         if (worker == NULL)
3138                 return -ENOMEM;
3139
3140         worker->value = value;
3141
3142         rc = mwl8k_queue_work(hw, &worker->header,
3143                               priv->config_wq,
3144                               mwl8k_set_rts_threshold_wt);
3145         kfree(worker);
3146
3147         if (rc == -ETIMEDOUT) {
3148                 printk(KERN_ERR "%s() timed out\n", __func__);
3149                 rc = -EINVAL;
3150         }
3151
3152         return rc;
3153 }
3154
3155 struct mwl8k_conf_tx_worker {
3156         struct mwl8k_work_struct header;
3157         u16 queue;
3158         const struct ieee80211_tx_queue_params *params;
3159 };
3160
3161 static int mwl8k_conf_tx_wt(struct work_struct *wt)
3162 {
3163         struct mwl8k_conf_tx_worker *worker =
3164         (struct mwl8k_conf_tx_worker *)wt;
3165
3166         struct ieee80211_hw *hw = worker->header.hw;
3167         u16 queue = worker->queue;
3168         const struct ieee80211_tx_queue_params *params = worker->params;
3169
3170         struct mwl8k_priv *priv = hw->priv;
3171         int rc = 0;
3172
3173         if (!priv->wmm_enabled) {
3174                 if (mwl8k_set_wmm(hw, 1)) {
3175                         rc = -EINVAL;
3176                         goto mwl8k_conf_tx_exit;
3177                 }
3178         }
3179
3180         if (mwl8k_set_edca_params(hw, GET_TXQ(queue), params->cw_min,
3181                 params->cw_max, params->aifs, params->txop))
3182                         rc = -EINVAL;
3183 mwl8k_conf_tx_exit:
3184         return rc;
3185 }
3186
3187 static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
3188                          const struct ieee80211_tx_queue_params *params)
3189 {
3190         int rc;
3191         struct mwl8k_conf_tx_worker *worker;
3192         struct mwl8k_priv *priv = hw->priv;
3193
3194         worker = kzalloc(sizeof(*worker), GFP_KERNEL);
3195         if (worker == NULL)
3196                 return -ENOMEM;
3197
3198         worker->queue = queue;
3199         worker->params = params;
3200         rc = mwl8k_queue_work(hw, &worker->header,
3201                               priv->config_wq, mwl8k_conf_tx_wt);
3202         kfree(worker);
3203         if (rc == -ETIMEDOUT) {
3204                 printk(KERN_ERR "%s() timed out\n", __func__);
3205                 rc = -EINVAL;
3206         }
3207         return rc;
3208 }
3209
3210 static int mwl8k_get_tx_stats(struct ieee80211_hw *hw,
3211                               struct ieee80211_tx_queue_stats *stats)
3212 {
3213         struct mwl8k_priv *priv = hw->priv;
3214         struct mwl8k_tx_queue *txq;
3215         int index;
3216
3217         spin_lock_bh(&priv->tx_lock);
3218         for (index = 0; index < MWL8K_TX_QUEUES; index++) {
3219                 txq = priv->txq + index;
3220                 memcpy(&stats[index], &txq->tx_stats,
3221                         sizeof(struct ieee80211_tx_queue_stats));
3222         }
3223         spin_unlock_bh(&priv->tx_lock);
3224         return 0;
3225 }
3226
3227 struct mwl8k_get_stats_worker {
3228         struct mwl8k_work_struct header;
3229         struct ieee80211_low_level_stats *stats;
3230 };
3231
3232 static int mwl8k_get_stats_wt(struct work_struct *wt)
3233 {
3234         struct mwl8k_get_stats_worker *worker =
3235                 (struct mwl8k_get_stats_worker *)wt;
3236
3237         return mwl8k_cmd_802_11_get_stat(worker->header.hw, worker->stats);
3238 }
3239
3240 static int mwl8k_get_stats(struct ieee80211_hw *hw,
3241                            struct ieee80211_low_level_stats *stats)
3242 {
3243         int rc;
3244         struct mwl8k_get_stats_worker *worker;
3245