3 * Linux device driver for USB based Prism54
5 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
7 * Based on the islsm (softmac prism54) driver, which is:
8 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
15 #include <linux/init.h>
16 #include <linux/usb.h>
17 #include <linux/pci.h>
18 #include <linux/slab.h>
19 #include <linux/firmware.h>
20 #include <linux/etherdevice.h>
21 #include <linux/delay.h>
22 #include <linux/crc32.h>
23 #include <net/mac80211.h>
29 MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
30 MODULE_DESCRIPTION("Prism54 USB wireless driver");
31 MODULE_LICENSE("GPL");
32 MODULE_ALIAS("prism54usb");
33 MODULE_FIRMWARE("isl3886usb");
34 MODULE_FIRMWARE("isl3887usb");
39 * Always update our wiki's device list (located at:
40 * http://wireless.kernel.org/en/users/Drivers/p54/devices ),
41 * whenever you add a new device.
44 static struct usb_device_id p54u_table[] __devinitdata = {
45 /* Version 1 devices (pci chip + net2280) */
46 {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */
47 {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
48 {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */
49 {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
50 {USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */
51 {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */
52 {USB_DEVICE(0x083a, 0x4502)}, /* Siemens Gigaset USB Adapter */
53 {USB_DEVICE(0x083a, 0x5501)}, /* Phillips CPWUA054 */
54 {USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */
55 {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */
56 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
57 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
58 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
59 {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */
60 {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
61 {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */
62 {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */
63 {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */
64 {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */
65 {USB_DEVICE(0x2001, 0x3703)}, /* DLink DWL-G122 */
66 {USB_DEVICE(0x5041, 0x2234)}, /* Linksys WUSB54G */
67 {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */
69 /* Version 2 devices (3887) */
70 {USB_DEVICE(0x0471, 0x1230)}, /* Philips CPWUA054/00 */
71 {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */
72 {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */
73 {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */
74 {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */
75 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
76 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
77 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
78 {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */
79 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */
80 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */
81 {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */
82 {USB_DEVICE(0x0baf, 0x0118)}, /* U.S. Robotics U5 802.11g Adapter*/
83 {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/
84 /* {USB_DEVICE(0x0cde, 0x0006)}, * Medion MD40900 already listed above,
85 * just noting it here for clarity */
86 {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
87 {USB_DEVICE(0x0cde, 0x0015)}, /* Zcomax XG-705A */
88 {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
89 {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */
90 {USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */
91 {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */
92 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
93 {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */
94 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
95 {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */
96 {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
97 {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */
98 {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */
99 {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */
103 MODULE_DEVICE_TABLE(usb, p54u_table);
105 static const struct {
107 enum p54u_hw_type type;
109 const char *fw_legacy;
111 } p54u_fwlist[__NUM_P54U_HWTYPES] = {
113 .type = P54U_NET2280,
116 .fw_legacy = "isl3890usb",
117 .hw = "ISL3886 + net2280",
123 .fw_legacy = "isl3887usb_bare",
128 static void p54u_rx_cb(struct urb *urb)
130 struct sk_buff *skb = (struct sk_buff *) urb->context;
131 struct p54u_rx_info *info = (struct p54u_rx_info *)skb->cb;
132 struct ieee80211_hw *dev = info->dev;
133 struct p54u_priv *priv = dev->priv;
135 skb_unlink(skb, &priv->rx_queue);
137 if (unlikely(urb->status)) {
138 dev_kfree_skb_irq(skb);
142 skb_put(skb, urb->actual_length);
144 if (priv->hw_type == P54U_NET2280)
145 skb_pull(skb, priv->common.tx_hdr_len);
146 if (priv->common.fw_interface == FW_LM87) {
151 if (p54_rx(dev, skb)) {
152 skb = dev_alloc_skb(priv->common.rx_mtu + 32);
153 if (unlikely(!skb)) {
154 /* TODO check rx queue length and refill *somewhere* */
158 info = (struct p54u_rx_info *) skb->cb;
161 urb->transfer_buffer = skb_tail_pointer(skb);
164 if (priv->hw_type == P54U_NET2280)
165 skb_push(skb, priv->common.tx_hdr_len);
166 if (priv->common.fw_interface == FW_LM87) {
170 skb_reset_tail_pointer(skb);
172 urb->transfer_buffer = skb_tail_pointer(skb);
174 skb_queue_tail(&priv->rx_queue, skb);
175 usb_anchor_urb(urb, &priv->submitted);
176 if (usb_submit_urb(urb, GFP_ATOMIC)) {
177 skb_unlink(skb, &priv->rx_queue);
178 usb_unanchor_urb(urb);
179 dev_kfree_skb_irq(skb);
183 static void p54u_tx_cb(struct urb *urb)
185 struct sk_buff *skb = urb->context;
186 struct ieee80211_hw *dev = (struct ieee80211_hw *)
187 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
189 p54_free_skb(dev, skb);
192 static void p54u_tx_dummy_cb(struct urb *urb) { }
194 static void p54u_free_urbs(struct ieee80211_hw *dev)
196 struct p54u_priv *priv = dev->priv;
197 usb_kill_anchored_urbs(&priv->submitted);
200 static int p54u_init_urbs(struct ieee80211_hw *dev)
202 struct p54u_priv *priv = dev->priv;
203 struct urb *entry = NULL;
205 struct p54u_rx_info *info;
208 while (skb_queue_len(&priv->rx_queue) < 32) {
209 skb = __dev_alloc_skb(priv->common.rx_mtu + 32, GFP_KERNEL);
214 entry = usb_alloc_urb(0, GFP_KERNEL);
220 usb_fill_bulk_urb(entry, priv->udev,
221 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
222 skb_tail_pointer(skb),
223 priv->common.rx_mtu + 32, p54u_rx_cb, skb);
224 info = (struct p54u_rx_info *) skb->cb;
227 skb_queue_tail(&priv->rx_queue, skb);
229 usb_anchor_urb(entry, &priv->submitted);
230 ret = usb_submit_urb(entry, GFP_KERNEL);
232 skb_unlink(skb, &priv->rx_queue);
233 usb_unanchor_urb(entry);
249 static __le32 p54u_lm87_chksum(const __le32 *data, size_t length)
255 chk ^= le32_to_cpu(*data++);
256 chk = (chk >> 5) ^ (chk << 3);
259 return cpu_to_le32(chk);
262 static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb)
264 struct p54u_priv *priv = dev->priv;
265 struct urb *data_urb;
266 struct lm87_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
268 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
270 p54_free_skb(dev, skb);
274 hdr->chksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);
275 hdr->device_addr = ((struct p54_hdr *)skb->data)->req_id;
277 usb_fill_bulk_urb(data_urb, priv->udev,
278 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
279 hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?
280 p54u_tx_cb : p54u_tx_dummy_cb, skb);
281 data_urb->transfer_flags |= URB_ZERO_PACKET;
283 usb_anchor_urb(data_urb, &priv->submitted);
284 if (usb_submit_urb(data_urb, GFP_ATOMIC)) {
285 usb_unanchor_urb(data_urb);
286 p54_free_skb(dev, skb);
288 usb_free_urb(data_urb);
291 static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
293 struct p54u_priv *priv = dev->priv;
294 struct urb *int_urb = NULL, *data_urb = NULL;
295 struct net2280_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
296 struct net2280_reg_write *reg = NULL;
299 reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
303 int_urb = usb_alloc_urb(0, GFP_ATOMIC);
307 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
311 reg->port = cpu_to_le16(NET2280_DEV_U32);
312 reg->addr = cpu_to_le32(P54U_DEV_BASE);
313 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
315 memset(hdr, 0, sizeof(*hdr));
316 hdr->len = cpu_to_le16(skb->len);
317 hdr->device_addr = ((struct p54_hdr *) skb->data)->req_id;
319 usb_fill_bulk_urb(int_urb, priv->udev,
320 usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
321 p54u_tx_dummy_cb, dev);
324 * URB_FREE_BUFFER triggers a code path in the USB subsystem that will
325 * free what is inside the transfer_buffer after the last reference to
326 * the int_urb is dropped.
328 int_urb->transfer_flags |= URB_FREE_BUFFER | URB_ZERO_PACKET;
331 usb_fill_bulk_urb(data_urb, priv->udev,
332 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
333 hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?
334 p54u_tx_cb : p54u_tx_dummy_cb, skb);
335 data_urb->transfer_flags |= URB_ZERO_PACKET;
337 usb_anchor_urb(int_urb, &priv->submitted);
338 err = usb_submit_urb(int_urb, GFP_ATOMIC);
340 usb_unanchor_urb(int_urb);
344 usb_anchor_urb(data_urb, &priv->submitted);
345 err = usb_submit_urb(data_urb, GFP_ATOMIC);
347 usb_unanchor_urb(data_urb);
351 usb_free_urb(int_urb);
352 usb_free_urb(data_urb);
356 p54_free_skb(dev, skb);
360 static int p54u_write(struct p54u_priv *priv,
361 struct net2280_reg_write *buf,
362 enum net2280_op_type type,
363 __le32 addr, __le32 val)
369 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV);
371 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_BRG);
373 buf->port = cpu_to_le16(type);
377 return usb_bulk_msg(priv->udev, ep, buf, sizeof(*buf), &alen, 1000);
380 static int p54u_read(struct p54u_priv *priv, void *buf,
381 enum net2280_op_type type,
382 __le32 addr, __le32 *val)
384 struct net2280_reg_read *read = buf;
394 read->port = cpu_to_le16(type);
397 err = usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
398 read, sizeof(*read), &alen, 1000);
402 err = usb_bulk_msg(priv->udev, usb_rcvbulkpipe(priv->udev, ep),
403 reg, sizeof(*reg), &alen, 1000);
411 static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
412 void *data, size_t len)
415 return usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
416 data, len, &alen, 2000);
419 static int p54u_device_reset(struct ieee80211_hw *dev)
421 struct p54u_priv *priv = dev->priv;
422 int ret, lock = (priv->intf->condition != USB_INTERFACE_BINDING);
425 ret = usb_lock_device_for_reset(priv->udev, priv->intf);
427 dev_err(&priv->udev->dev, "(p54usb) unable to lock "
428 "device for reset (%d)!\n", ret);
433 ret = usb_reset_device(priv->udev);
435 usb_unlock_device(priv->udev);
438 dev_err(&priv->udev->dev, "(p54usb) unable to reset "
439 "device (%d)!\n", ret);
444 static const char p54u_romboot_3887[] = "~~~~";
445 static int p54u_firmware_reset_3887(struct ieee80211_hw *dev)
447 struct p54u_priv *priv = dev->priv;
451 buf = kmemdup(p54u_romboot_3887, 4, GFP_KERNEL);
454 ret = p54u_bulk_msg(priv, P54U_PIPE_DATA,
458 dev_err(&priv->udev->dev, "(p54usb) unable to jump to "
459 "boot ROM (%d)!\n", ret);
464 static const char p54u_firmware_upload_3887[] = "<\r";
465 static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
467 struct p54u_priv *priv = dev->priv;
472 unsigned int left, remains, block_size;
473 struct x2_header *hdr;
474 unsigned long timeout;
476 err = p54u_firmware_reset_3887(dev);
480 tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
482 dev_err(&priv->udev->dev, "(p54usb) cannot allocate firmware"
487 left = block_size = min((size_t)P54U_FW_BLOCK, priv->fw->size);
488 strcpy(buf, p54u_firmware_upload_3887);
489 left -= strlen(p54u_firmware_upload_3887);
490 tmp += strlen(p54u_firmware_upload_3887);
492 data = priv->fw->data;
493 remains = priv->fw->size;
495 hdr = (struct x2_header *)(buf + strlen(p54u_firmware_upload_3887));
496 memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
497 hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
498 hdr->fw_length = cpu_to_le32(priv->fw->size);
499 hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
501 left -= sizeof(*hdr);
529 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size);
531 dev_err(&priv->udev->dev, "(p54usb) firmware "
533 goto err_upload_failed;
537 left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
540 *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, priv->fw->data,
542 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
544 dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n");
545 goto err_upload_failed;
547 timeout = jiffies + msecs_to_jiffies(1000);
548 while (!(err = usb_bulk_msg(priv->udev,
549 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
550 if (alen > 2 && !memcmp(buf, "OK", 2))
553 if (alen > 5 && !memcmp(buf, "ERROR", 5)) {
558 if (time_after(jiffies, timeout)) {
559 dev_err(&priv->udev->dev, "(p54usb) firmware boot "
566 dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n");
567 goto err_upload_failed;
572 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2);
574 dev_err(&priv->udev->dev, "(p54usb) firmware boot failed!\n");
575 goto err_upload_failed;
578 timeout = jiffies + msecs_to_jiffies(1000);
579 while (!(err = usb_bulk_msg(priv->udev,
580 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
581 if (alen > 0 && buf[0] == 'g')
584 if (time_after(jiffies, timeout)) {
590 goto err_upload_failed;
597 static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
599 struct p54u_priv *priv = dev->priv;
600 const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;
604 unsigned int remains, offset;
607 buf = kmalloc(512, GFP_KERNEL);
609 dev_err(&priv->udev->dev, "(p54usb) firmware buffer "
614 #define P54U_WRITE(type, addr, data) \
616 err = p54u_write(priv, buf, type,\
617 cpu_to_le32((u32)(unsigned long)addr), data);\
622 #define P54U_READ(type, addr) \
624 err = p54u_read(priv, buf, type,\
625 cpu_to_le32((u32)(unsigned long)addr), ®);\
630 /* power down net2280 bridge */
631 P54U_READ(NET2280_BRG_U32, NET2280_GPIOCTL);
632 reg |= cpu_to_le32(P54U_BRG_POWER_DOWN);
633 reg &= cpu_to_le32(~P54U_BRG_POWER_UP);
634 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
638 /* power up bridge */
639 reg |= cpu_to_le32(P54U_BRG_POWER_UP);
640 reg &= cpu_to_le32(~P54U_BRG_POWER_DOWN);
641 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
645 P54U_WRITE(NET2280_BRG_U32, NET2280_DEVINIT,
646 cpu_to_le32(NET2280_CLK_30Mhz |
648 NET2280_PCI_SOFT_RESET));
652 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_COMMAND,
653 cpu_to_le32(PCI_COMMAND_MEMORY |
654 PCI_COMMAND_MASTER));
656 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_0,
657 cpu_to_le32(NET2280_BASE));
659 P54U_READ(NET2280_BRG_CFG_U16, PCI_STATUS);
660 reg |= cpu_to_le32(PCI_STATUS_REC_MASTER_ABORT);
661 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_STATUS, reg);
663 // TODO: we really need this?
664 P54U_READ(NET2280_BRG_U32, NET2280_RELNUM);
666 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_RSP,
667 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
668 P54U_WRITE(NET2280_BRG_U32, NET2280_EPC_RSP,
669 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
671 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_2,
672 cpu_to_le32(NET2280_BASE2));
674 /* finally done setting up the bridge */
676 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | PCI_COMMAND,
677 cpu_to_le32(PCI_COMMAND_MEMORY |
678 PCI_COMMAND_MASTER));
680 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | 0x40 /* TRDY timeout */, 0);
681 P54U_WRITE(NET2280_DEV_CFG_U32, 0x10000 | PCI_BASE_ADDRESS_0,
682 cpu_to_le32(P54U_DEV_BASE));
684 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
685 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
686 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
689 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable, 0);
691 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
692 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
693 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);
694 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
695 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
699 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
700 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
704 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
705 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
709 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
710 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
712 /* finally, we can upload firmware now! */
713 remains = priv->fw->size;
714 data = priv->fw->data;
715 offset = ISL38XX_DEV_FIRMWARE_ADDR;
718 unsigned int block_len = min(remains, (unsigned int)512);
719 memcpy(buf, data, block_len);
721 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_len);
723 dev_err(&priv->udev->dev, "(p54usb) firmware block "
728 P54U_WRITE(NET2280_DEV_U32, &devreg->direct_mem_base,
729 cpu_to_le32(0xc0000f00));
731 P54U_WRITE(NET2280_DEV_U32,
732 0x0020 | (unsigned long)&devreg->direct_mem_win, 0);
733 P54U_WRITE(NET2280_DEV_U32,
734 0x0020 | (unsigned long)&devreg->direct_mem_win,
737 P54U_WRITE(NET2280_DEV_U32,
738 0x0024 | (unsigned long)&devreg->direct_mem_win,
739 cpu_to_le32(block_len));
740 P54U_WRITE(NET2280_DEV_U32,
741 0x0028 | (unsigned long)&devreg->direct_mem_win,
742 cpu_to_le32(offset));
744 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_addr,
745 cpu_to_le32(NET2280_EPA_FIFO_PCI_ADDR));
746 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_len,
747 cpu_to_le32(block_len >> 2));
748 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_ctrl,
749 cpu_to_le32(ISL38XX_DMA_MASTER_CONTROL_TRIGGER));
753 P54U_READ(NET2280_DEV_U32,
754 0x002C | (unsigned long)&devreg->direct_mem_win);
755 if (!(reg & cpu_to_le32(ISL38XX_DMA_STATUS_DONE)) ||
756 !(reg & cpu_to_le32(ISL38XX_DMA_STATUS_READY))) {
757 dev_err(&priv->udev->dev, "(p54usb) firmware DMA "
758 "transfer failed\n");
762 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_STAT,
763 cpu_to_le32(NET2280_FIFO_FLUSH));
765 remains -= block_len;
771 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
772 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
773 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
774 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);
775 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
779 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
780 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
782 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
783 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
787 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
788 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
790 /* start up the firmware */
791 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable,
792 cpu_to_le32(ISL38XX_INT_IDENT_INIT));
794 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
795 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
797 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1,
798 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT_ENABLE |
799 NET2280_USB_INTERRUPT_ENABLE));
801 P54U_WRITE(NET2280_DEV_U32, &devreg->dev_int,
802 cpu_to_le32(ISL38XX_DEV_INT_RESET));
804 err = usb_interrupt_msg(priv->udev,
805 usb_rcvbulkpipe(priv->udev, P54U_PIPE_INT),
806 buf, sizeof(__le32), &alen, 1000);
807 if (err || alen != sizeof(__le32))
810 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
811 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
813 if (!(reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)))
816 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
817 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
818 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
828 static int p54u_load_firmware(struct ieee80211_hw *dev)
830 struct p54u_priv *priv = dev->priv;
833 BUILD_BUG_ON(ARRAY_SIZE(p54u_fwlist) != __NUM_P54U_HWTYPES);
835 for (i = 0; i < __NUM_P54U_HWTYPES; i++)
836 if (p54u_fwlist[i].type == priv->hw_type)
839 if (i == __NUM_P54U_HWTYPES)
842 err = request_firmware(&priv->fw, p54u_fwlist[i].fw, &priv->udev->dev);
844 dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s "
845 "(%d)!\n", p54u_fwlist[i].fw, err);
847 err = request_firmware(&priv->fw, p54u_fwlist[i].fw_legacy,
853 err = p54_parse_firmware(dev, priv->fw);
857 if (priv->common.fw_interface != p54u_fwlist[i].intf) {
858 dev_err(&priv->udev->dev, "wrong firmware, please get "
859 "a firmware for \"%s\" and try again.\n",
866 release_firmware(priv->fw);
871 static int p54u_open(struct ieee80211_hw *dev)
873 struct p54u_priv *priv = dev->priv;
876 err = p54u_init_urbs(dev);
881 priv->common.open = p54u_init_urbs;
886 static void p54u_stop(struct ieee80211_hw *dev)
888 /* TODO: figure out how to reliably stop the 3887 and net2280 so
889 the hardware is still usable next time we want to start it.
890 until then, we just stop listening to the hardware.. */
894 static int __devinit p54u_probe(struct usb_interface *intf,
895 const struct usb_device_id *id)
897 struct usb_device *udev = interface_to_usbdev(intf);
898 struct ieee80211_hw *dev;
899 struct p54u_priv *priv;
901 unsigned int i, recognized_pipes;
903 dev = p54_init_common(sizeof(*priv));
906 dev_err(&udev->dev, "(p54usb) ieee80211 alloc failed\n");
911 priv->hw_type = P54U_INVALID_HW;
913 SET_IEEE80211_DEV(dev, &intf->dev);
914 usb_set_intfdata(intf, dev);
917 skb_queue_head_init(&priv->rx_queue);
918 init_usb_anchor(&priv->submitted);
922 /* really lazy and simple way of figuring out if we're a 3887 */
923 /* TODO: should just stick the identification in the device table */
924 i = intf->altsetting->desc.bNumEndpoints;
925 recognized_pipes = 0;
927 switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) {
932 case P54U_PIPE_DATA | USB_DIR_IN:
933 case P54U_PIPE_MGMT | USB_DIR_IN:
934 case P54U_PIPE_BRG | USB_DIR_IN:
935 case P54U_PIPE_DEV | USB_DIR_IN:
936 case P54U_PIPE_INT | USB_DIR_IN:
940 priv->common.open = p54u_open;
941 priv->common.stop = p54u_stop;
942 if (recognized_pipes < P54U_PIPE_NUMBER) {
944 /* ISL3887 needs a full reset on resume */
945 udev->reset_resume = 1;
946 #endif /* CONFIG_PM */
947 err = p54u_device_reset(dev);
949 priv->hw_type = P54U_3887;
950 dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
951 priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr);
952 priv->common.tx = p54u_tx_lm87;
953 priv->upload_fw = p54u_upload_firmware_3887;
955 priv->hw_type = P54U_NET2280;
956 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
957 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
958 priv->common.tx = p54u_tx_net2280;
959 priv->upload_fw = p54u_upload_firmware_net2280;
961 err = p54u_load_firmware(dev);
965 err = priv->upload_fw(dev);
970 err = p54_read_eeprom(dev);
975 err = p54_register_common(dev, &udev->dev);
982 release_firmware(priv->fw);
985 p54_free_common(dev);
986 usb_set_intfdata(intf, NULL);
991 static void __devexit p54u_disconnect(struct usb_interface *intf)
993 struct ieee80211_hw *dev = usb_get_intfdata(intf);
994 struct p54u_priv *priv;
999 p54_unregister_common(dev);
1002 usb_put_dev(interface_to_usbdev(intf));
1003 release_firmware(priv->fw);
1004 p54_free_common(dev);
1007 static int p54u_pre_reset(struct usb_interface *intf)
1009 struct ieee80211_hw *dev = usb_get_intfdata(intf);
1018 static int p54u_resume(struct usb_interface *intf)
1020 struct ieee80211_hw *dev = usb_get_intfdata(intf);
1021 struct p54u_priv *priv;
1027 if (unlikely(!(priv->upload_fw && priv->fw)))
1030 return priv->upload_fw(dev);
1033 static int p54u_post_reset(struct usb_interface *intf)
1035 struct ieee80211_hw *dev = usb_get_intfdata(intf);
1036 struct p54u_priv *priv;
1039 err = p54u_resume(intf);
1043 /* reinitialize old device state */
1045 if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED)
1046 ieee80211_restart_hw(dev);
1053 static int p54u_suspend(struct usb_interface *intf, pm_message_t message)
1055 return p54u_pre_reset(intf);
1058 #endif /* CONFIG_PM */
1060 static struct usb_driver p54u_driver = {
1062 .id_table = p54u_table,
1063 .probe = p54u_probe,
1064 .disconnect = p54u_disconnect,
1065 .pre_reset = p54u_pre_reset,
1066 .post_reset = p54u_post_reset,
1068 .suspend = p54u_suspend,
1069 .resume = p54u_resume,
1070 .reset_resume = p54u_resume,
1071 #endif /* CONFIG_PM */
1075 static int __init p54u_init(void)
1077 return usb_register(&p54u_driver);
1080 static void __exit p54u_exit(void)
1082 usb_deregister(&p54u_driver);
1085 module_init(p54u_init);
1086 module_exit(p54u_exit);