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