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