Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[wrt350n-kernel.git] / drivers / net / wireless / p54usb.c
blobd468eff1cc91c8e9e7ff8a304d15da60ac36e6b2
2 /*
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/firmware.h>
19 #include <linux/etherdevice.h>
20 #include <linux/delay.h>
21 #include <linux/crc32.h>
22 #include <net/mac80211.h>
24 #include "p54.h"
25 #include "p54usb.h"
27 MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
28 MODULE_DESCRIPTION("Prism54 USB wireless driver");
29 MODULE_LICENSE("GPL");
30 MODULE_ALIAS("prism54usb");
32 static struct usb_device_id p54u_table[] __devinitdata = {
33 /* Version 1 devices (pci chip + net2280) */
34 {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
35 {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
36 {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */
37 {USB_DEVICE(0x083a, 0x4502)}, /* Siemens Gigaset USB Adapter */
38 <<<<<<< HEAD:drivers/net/wireless/p54usb.c
39 =======
40 {USB_DEVICE(0x083a, 0x5501)}, /* Phillips CPWUA054 */
41 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/net/wireless/p54usb.c
42 {USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */
43 {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */
44 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
45 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
46 {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
47 {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */
48 {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */
49 {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */
50 {USB_DEVICE(0x2001, 0x3703)}, /* DLink DWL-G122 */
51 {USB_DEVICE(0x5041, 0x2234)}, /* Linksys WUSB54G */
52 {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */
54 /* Version 2 devices (3887) */
55 {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */
56 {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */
57 {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */
58 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
59 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
60 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */
61 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */
62 {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */
63 {USB_DEVICE(0x0baf, 0x0118)}, /* U.S. Robotics U5 802.11g Adapter*/
64 {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/
65 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */
66 {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
67 {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
68 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
69 <<<<<<< HEAD:drivers/net/wireless/p54usb.c
70 =======
71 {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */
72 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:drivers/net/wireless/p54usb.c
73 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
74 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
75 {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
76 {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */
77 {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */
81 MODULE_DEVICE_TABLE(usb, p54u_table);
83 static void p54u_rx_cb(struct urb *urb)
85 struct sk_buff *skb = (struct sk_buff *) urb->context;
86 struct p54u_rx_info *info = (struct p54u_rx_info *)skb->cb;
87 struct ieee80211_hw *dev = info->dev;
88 struct p54u_priv *priv = dev->priv;
90 if (unlikely(urb->status)) {
91 info->urb = NULL;
92 usb_free_urb(urb);
93 return;
96 skb_unlink(skb, &priv->rx_queue);
97 skb_put(skb, urb->actual_length);
98 if (!priv->hw_type)
99 skb_pull(skb, sizeof(struct net2280_tx_hdr));
101 if (p54_rx(dev, skb)) {
102 skb = dev_alloc_skb(MAX_RX_SIZE);
103 if (unlikely(!skb)) {
104 usb_free_urb(urb);
105 /* TODO check rx queue length and refill *somewhere* */
106 return;
109 info = (struct p54u_rx_info *) skb->cb;
110 info->urb = urb;
111 info->dev = dev;
112 urb->transfer_buffer = skb_tail_pointer(skb);
113 urb->context = skb;
114 skb_queue_tail(&priv->rx_queue, skb);
115 } else {
116 skb_trim(skb, 0);
117 skb_queue_tail(&priv->rx_queue, skb);
120 usb_submit_urb(urb, GFP_ATOMIC);
123 static void p54u_tx_cb(struct urb *urb)
125 usb_free_urb(urb);
128 static void p54u_tx_free_cb(struct urb *urb)
130 kfree(urb->transfer_buffer);
131 usb_free_urb(urb);
134 static int p54u_init_urbs(struct ieee80211_hw *dev)
136 struct p54u_priv *priv = dev->priv;
137 struct urb *entry;
138 struct sk_buff *skb;
139 struct p54u_rx_info *info;
141 while (skb_queue_len(&priv->rx_queue) < 32) {
142 skb = __dev_alloc_skb(MAX_RX_SIZE, GFP_KERNEL);
143 if (!skb)
144 break;
145 entry = usb_alloc_urb(0, GFP_KERNEL);
146 if (!entry) {
147 kfree_skb(skb);
148 break;
150 usb_fill_bulk_urb(entry, priv->udev, usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), skb_tail_pointer(skb), MAX_RX_SIZE, p54u_rx_cb, skb);
151 info = (struct p54u_rx_info *) skb->cb;
152 info->urb = entry;
153 info->dev = dev;
154 skb_queue_tail(&priv->rx_queue, skb);
155 usb_submit_urb(entry, GFP_KERNEL);
158 return 0;
161 static void p54u_free_urbs(struct ieee80211_hw *dev)
163 struct p54u_priv *priv = dev->priv;
164 struct p54u_rx_info *info;
165 struct sk_buff *skb;
167 while ((skb = skb_dequeue(&priv->rx_queue))) {
168 info = (struct p54u_rx_info *) skb->cb;
169 if (!info->urb)
170 continue;
172 usb_kill_urb(info->urb);
173 kfree_skb(skb);
177 static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data,
178 size_t len, int free_on_tx)
180 struct p54u_priv *priv = dev->priv;
181 struct urb *addr_urb, *data_urb;
183 addr_urb = usb_alloc_urb(0, GFP_ATOMIC);
184 if (!addr_urb)
185 return;
187 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
188 if (!data_urb) {
189 usb_free_urb(addr_urb);
190 return;
193 usb_fill_bulk_urb(addr_urb, priv->udev,
194 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), &data->req_id,
195 sizeof(data->req_id), p54u_tx_cb, dev);
196 usb_fill_bulk_urb(data_urb, priv->udev,
197 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), data, len,
198 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
200 usb_submit_urb(addr_urb, GFP_ATOMIC);
201 usb_submit_urb(data_urb, GFP_ATOMIC);
204 static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data,
205 size_t len, int free_on_tx)
207 struct p54u_priv *priv = dev->priv;
208 struct urb *int_urb, *data_urb;
209 struct net2280_tx_hdr *hdr;
210 struct net2280_reg_write *reg;
212 reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
213 if (!reg)
214 return;
216 int_urb = usb_alloc_urb(0, GFP_ATOMIC);
217 if (!int_urb) {
218 kfree(reg);
219 return;
222 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
223 if (!data_urb) {
224 kfree(reg);
225 usb_free_urb(int_urb);
226 return;
229 reg->port = cpu_to_le16(NET2280_DEV_U32);
230 reg->addr = cpu_to_le32(P54U_DEV_BASE);
231 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
233 len += sizeof(*data);
234 hdr = (void *)data - sizeof(*hdr);
235 memset(hdr, 0, sizeof(*hdr));
236 hdr->device_addr = data->req_id;
237 hdr->len = cpu_to_le16(len);
239 usb_fill_bulk_urb(int_urb, priv->udev,
240 usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
241 p54u_tx_free_cb, dev);
242 usb_submit_urb(int_urb, GFP_ATOMIC);
244 usb_fill_bulk_urb(data_urb, priv->udev,
245 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, len + sizeof(*hdr),
246 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
247 usb_submit_urb(data_urb, GFP_ATOMIC);
250 static int p54u_write(struct p54u_priv *priv,
251 struct net2280_reg_write *buf,
252 enum net2280_op_type type,
253 __le32 addr, __le32 val)
255 unsigned int ep;
256 int alen;
258 if (type & 0x0800)
259 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV);
260 else
261 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_BRG);
263 buf->port = cpu_to_le16(type);
264 buf->addr = addr;
265 buf->val = val;
267 return usb_bulk_msg(priv->udev, ep, buf, sizeof(*buf), &alen, 1000);
270 static int p54u_read(struct p54u_priv *priv, void *buf,
271 enum net2280_op_type type,
272 __le32 addr, __le32 *val)
274 struct net2280_reg_read *read = buf;
275 __le32 *reg = buf;
276 unsigned int ep;
277 int alen, err;
279 if (type & 0x0800)
280 ep = P54U_PIPE_DEV;
281 else
282 ep = P54U_PIPE_BRG;
284 read->port = cpu_to_le16(type);
285 read->addr = addr;
287 err = usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
288 read, sizeof(*read), &alen, 1000);
289 if (err)
290 return err;
292 err = usb_bulk_msg(priv->udev, usb_rcvbulkpipe(priv->udev, ep),
293 reg, sizeof(*reg), &alen, 1000);
294 if (err)
295 return err;
297 *val = *reg;
298 return 0;
301 static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
302 void *data, size_t len)
304 int alen;
305 return usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
306 data, len, &alen, 2000);
309 static int p54u_read_eeprom(struct ieee80211_hw *dev)
311 struct p54u_priv *priv = dev->priv;
312 void *buf;
313 struct p54_control_hdr *hdr;
314 int err, alen;
315 size_t offset = priv->hw_type ? 0x10 : 0x20;
317 buf = kmalloc(0x2020, GFP_KERNEL);
318 if (!buf) {
319 printk(KERN_ERR "prism54usb: cannot allocate memory for "
320 "eeprom readback!\n");
321 return -ENOMEM;
324 if (priv->hw_type) {
325 *((u32 *) buf) = priv->common.rx_start;
326 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
327 if (err) {
328 printk(KERN_ERR "prism54usb: addr send failed\n");
329 goto fail;
331 } else {
332 struct net2280_reg_write *reg = buf;
333 reg->port = cpu_to_le16(NET2280_DEV_U32);
334 reg->addr = cpu_to_le32(P54U_DEV_BASE);
335 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
336 err = p54u_bulk_msg(priv, P54U_PIPE_DEV, buf, sizeof(*reg));
337 if (err) {
338 printk(KERN_ERR "prism54usb: dev_int send failed\n");
339 goto fail;
343 hdr = buf + priv->common.tx_hdr_len;
344 p54_fill_eeprom_readback(hdr);
345 hdr->req_id = cpu_to_le32(priv->common.rx_start);
346 if (priv->common.tx_hdr_len) {
347 struct net2280_tx_hdr *tx_hdr = buf;
348 tx_hdr->device_addr = hdr->req_id;
349 tx_hdr->len = cpu_to_le16(EEPROM_READBACK_LEN);
352 /* we can just pretend to send 0x2000 bytes of nothing in the headers */
353 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf,
354 EEPROM_READBACK_LEN + priv->common.tx_hdr_len);
355 if (err) {
356 printk(KERN_ERR "prism54usb: eeprom req send failed\n");
357 goto fail;
360 err = usb_bulk_msg(priv->udev,
361 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
362 buf, 0x2020, &alen, 1000);
363 if (!err && alen > offset) {
364 p54_parse_eeprom(dev, (u8 *)buf + offset, alen - offset);
365 } else {
366 printk(KERN_ERR "prism54usb: eeprom read failed!\n");
367 err = -EINVAL;
368 goto fail;
371 fail:
372 kfree(buf);
373 return err;
376 static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
378 static char start_string[] = "~~~~<\r";
379 struct p54u_priv *priv = dev->priv;
380 const struct firmware *fw_entry = NULL;
381 int err, alen;
382 u8 carry = 0;
383 u8 *buf, *tmp, *data;
384 unsigned int left, remains, block_size;
385 struct x2_header *hdr;
386 unsigned long timeout;
388 tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
389 if (!buf) {
390 printk(KERN_ERR "p54usb: cannot allocate firmware upload buffer!\n");
391 err = -ENOMEM;
392 goto err_bufalloc;
395 memcpy(buf, start_string, 4);
396 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4);
397 if (err) {
398 printk(KERN_ERR "p54usb: reset failed! (%d)\n", err);
399 goto err_reset;
402 err = request_firmware(&fw_entry, "isl3887usb_bare", &priv->udev->dev);
403 if (err) {
404 printk(KERN_ERR "p54usb: cannot find firmware (isl3887usb_bare)!\n");
405 goto err_req_fw_failed;
408 p54_parse_firmware(dev, fw_entry);
410 left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
411 strcpy(buf, start_string);
412 left -= strlen(start_string);
413 tmp += strlen(start_string);
415 data = fw_entry->data;
416 remains = fw_entry->size;
418 hdr = (struct x2_header *)(buf + strlen(start_string));
419 memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
420 hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
421 hdr->fw_length = cpu_to_le32(fw_entry->size);
422 hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
423 sizeof(u32)*2));
424 left -= sizeof(*hdr);
425 tmp += sizeof(*hdr);
427 while (remains) {
428 while (left--) {
429 if (carry) {
430 *tmp++ = carry;
431 carry = 0;
432 remains--;
433 continue;
435 switch (*data) {
436 case '~':
437 *tmp++ = '}';
438 carry = '^';
439 break;
440 case '}':
441 *tmp++ = '}';
442 carry = ']';
443 break;
444 default:
445 *tmp++ = *data;
446 remains--;
447 break;
449 data++;
452 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size);
453 if (err) {
454 printk(KERN_ERR "prism54usb: firmware upload failed!\n");
455 goto err_upload_failed;
458 tmp = buf;
459 left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
462 *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size));
463 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
464 if (err) {
465 printk(KERN_ERR "prism54usb: firmware upload failed!\n");
466 goto err_upload_failed;
469 timeout = jiffies + msecs_to_jiffies(1000);
470 while (!(err = usb_bulk_msg(priv->udev,
471 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
472 if (alen > 2 && !memcmp(buf, "OK", 2))
473 break;
475 if (alen > 5 && !memcmp(buf, "ERROR", 5)) {
476 printk(KERN_INFO "prism54usb: firmware upload failed!\n");
477 err = -EINVAL;
478 break;
481 if (time_after(jiffies, timeout)) {
482 printk(KERN_ERR "prism54usb: firmware boot timed out!\n");
483 err = -ETIMEDOUT;
484 break;
487 if (err)
488 goto err_upload_failed;
490 buf[0] = 'g';
491 buf[1] = '\r';
492 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2);
493 if (err) {
494 printk(KERN_ERR "prism54usb: firmware boot failed!\n");
495 goto err_upload_failed;
498 timeout = jiffies + msecs_to_jiffies(1000);
499 while (!(err = usb_bulk_msg(priv->udev,
500 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
501 if (alen > 0 && buf[0] == 'g')
502 break;
504 if (time_after(jiffies, timeout)) {
505 err = -ETIMEDOUT;
506 break;
509 if (err)
510 goto err_upload_failed;
512 err_upload_failed:
513 release_firmware(fw_entry);
514 err_req_fw_failed:
515 err_reset:
516 kfree(buf);
517 err_bufalloc:
518 return err;
521 static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
523 struct p54u_priv *priv = dev->priv;
524 const struct firmware *fw_entry = NULL;
525 const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;
526 int err, alen;
527 void *buf;
528 __le32 reg;
529 unsigned int remains, offset;
530 u8 *data;
532 buf = kmalloc(512, GFP_KERNEL);
533 if (!buf) {
534 printk(KERN_ERR "p54usb: firmware buffer alloc failed!\n");
535 return -ENOMEM;
538 err = request_firmware(&fw_entry, "isl3890usb", &priv->udev->dev);
539 if (err) {
540 printk(KERN_ERR "p54usb: cannot find firmware (isl3890usb)!\n");
541 kfree(buf);
542 return err;
545 p54_parse_firmware(dev, fw_entry);
547 #define P54U_WRITE(type, addr, data) \
548 do {\
549 err = p54u_write(priv, buf, type,\
550 cpu_to_le32((u32)(unsigned long)addr), data);\
551 if (err) \
552 goto fail;\
553 } while (0)
555 #define P54U_READ(type, addr) \
556 do {\
557 err = p54u_read(priv, buf, type,\
558 cpu_to_le32((u32)(unsigned long)addr), &reg);\
559 if (err)\
560 goto fail;\
561 } while (0)
563 /* power down net2280 bridge */
564 P54U_READ(NET2280_BRG_U32, NET2280_GPIOCTL);
565 reg |= cpu_to_le32(P54U_BRG_POWER_DOWN);
566 reg &= cpu_to_le32(~P54U_BRG_POWER_UP);
567 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
569 mdelay(100);
571 /* power up bridge */
572 reg |= cpu_to_le32(P54U_BRG_POWER_UP);
573 reg &= cpu_to_le32(~P54U_BRG_POWER_DOWN);
574 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
576 mdelay(100);
578 P54U_WRITE(NET2280_BRG_U32, NET2280_DEVINIT,
579 cpu_to_le32(NET2280_CLK_30Mhz |
580 NET2280_PCI_ENABLE |
581 NET2280_PCI_SOFT_RESET));
583 mdelay(20);
585 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_COMMAND,
586 cpu_to_le32(PCI_COMMAND_MEMORY |
587 PCI_COMMAND_MASTER));
589 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_0,
590 cpu_to_le32(NET2280_BASE));
592 P54U_READ(NET2280_BRG_CFG_U16, PCI_STATUS);
593 reg |= cpu_to_le32(PCI_STATUS_REC_MASTER_ABORT);
594 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_STATUS, reg);
596 // TODO: we really need this?
597 P54U_READ(NET2280_BRG_U32, NET2280_RELNUM);
599 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_RSP,
600 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
601 P54U_WRITE(NET2280_BRG_U32, NET2280_EPC_RSP,
602 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
604 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_2,
605 cpu_to_le32(NET2280_BASE2));
607 /* finally done setting up the bridge */
609 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | PCI_COMMAND,
610 cpu_to_le32(PCI_COMMAND_MEMORY |
611 PCI_COMMAND_MASTER));
613 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | 0x40 /* TRDY timeout */, 0);
614 P54U_WRITE(NET2280_DEV_CFG_U32, 0x10000 | PCI_BASE_ADDRESS_0,
615 cpu_to_le32(P54U_DEV_BASE));
617 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
618 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
619 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
621 /* do romboot */
622 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable, 0);
624 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
625 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
626 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);
627 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
628 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
630 mdelay(20);
632 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
633 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
635 mdelay(20);
637 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
638 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
640 mdelay(100);
642 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
643 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
645 /* finally, we can upload firmware now! */
646 remains = fw_entry->size;
647 data = fw_entry->data;
648 offset = ISL38XX_DEV_FIRMWARE_ADDR;
650 while (remains) {
651 unsigned int block_len = min(remains, (unsigned int)512);
652 memcpy(buf, data, block_len);
654 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_len);
655 if (err) {
656 printk(KERN_ERR "prism54usb: firmware block upload "
657 "failed\n");
658 goto fail;
661 P54U_WRITE(NET2280_DEV_U32, &devreg->direct_mem_base,
662 cpu_to_le32(0xc0000f00));
664 P54U_WRITE(NET2280_DEV_U32,
665 0x0020 | (unsigned long)&devreg->direct_mem_win, 0);
666 P54U_WRITE(NET2280_DEV_U32,
667 0x0020 | (unsigned long)&devreg->direct_mem_win,
668 cpu_to_le32(1));
670 P54U_WRITE(NET2280_DEV_U32,
671 0x0024 | (unsigned long)&devreg->direct_mem_win,
672 cpu_to_le32(block_len));
673 P54U_WRITE(NET2280_DEV_U32,
674 0x0028 | (unsigned long)&devreg->direct_mem_win,
675 cpu_to_le32(offset));
677 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_addr,
678 cpu_to_le32(NET2280_EPA_FIFO_PCI_ADDR));
679 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_len,
680 cpu_to_le32(block_len >> 2));
681 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_ctrl,
682 cpu_to_le32(ISL38XX_DMA_MASTER_CONTROL_TRIGGER));
684 mdelay(10);
686 P54U_READ(NET2280_DEV_U32,
687 0x002C | (unsigned long)&devreg->direct_mem_win);
688 if (!(reg & cpu_to_le32(ISL38XX_DMA_STATUS_DONE)) ||
689 !(reg & cpu_to_le32(ISL38XX_DMA_STATUS_READY))) {
690 printk(KERN_ERR "prism54usb: firmware DMA transfer "
691 "failed\n");
692 goto fail;
695 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_STAT,
696 cpu_to_le32(NET2280_FIFO_FLUSH));
698 remains -= block_len;
699 data += block_len;
700 offset += block_len;
703 /* do ramboot */
704 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
705 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
706 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
707 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);
708 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
710 mdelay(20);
712 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
713 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
715 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
716 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
718 mdelay(100);
720 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
721 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
723 /* start up the firmware */
724 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable,
725 cpu_to_le32(ISL38XX_INT_IDENT_INIT));
727 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
728 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
730 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1,
731 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT_ENABLE |
732 NET2280_USB_INTERRUPT_ENABLE));
734 P54U_WRITE(NET2280_DEV_U32, &devreg->dev_int,
735 cpu_to_le32(ISL38XX_DEV_INT_RESET));
737 err = usb_interrupt_msg(priv->udev,
738 usb_rcvbulkpipe(priv->udev, P54U_PIPE_INT),
739 buf, sizeof(__le32), &alen, 1000);
740 if (err || alen != sizeof(__le32))
741 goto fail;
743 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
744 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
746 if (!(reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)))
747 err = -EINVAL;
749 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
750 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
751 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
753 #undef P54U_WRITE
754 #undef P54U_READ
756 fail:
757 release_firmware(fw_entry);
758 kfree(buf);
759 return err;
762 static int p54u_open(struct ieee80211_hw *dev)
764 struct p54u_priv *priv = dev->priv;
765 int err;
767 err = p54u_init_urbs(dev);
768 if (err) {
769 return err;
772 priv->common.open = p54u_init_urbs;
774 return 0;
777 static void p54u_stop(struct ieee80211_hw *dev)
779 /* TODO: figure out how to reliably stop the 3887 and net2280 so
780 the hardware is still usable next time we want to start it.
781 until then, we just stop listening to the hardware.. */
782 p54u_free_urbs(dev);
783 return;
786 static int __devinit p54u_probe(struct usb_interface *intf,
787 const struct usb_device_id *id)
789 struct usb_device *udev = interface_to_usbdev(intf);
790 struct ieee80211_hw *dev;
791 struct p54u_priv *priv;
792 int err;
793 unsigned int i, recognized_pipes;
794 DECLARE_MAC_BUF(mac);
796 dev = p54_init_common(sizeof(*priv));
797 if (!dev) {
798 printk(KERN_ERR "prism54usb: ieee80211 alloc failed\n");
799 return -ENOMEM;
802 priv = dev->priv;
804 SET_IEEE80211_DEV(dev, &intf->dev);
805 usb_set_intfdata(intf, dev);
806 priv->udev = udev;
808 usb_get_dev(udev);
810 /* really lazy and simple way of figuring out if we're a 3887 */
811 /* TODO: should just stick the identification in the device table */
812 i = intf->altsetting->desc.bNumEndpoints;
813 recognized_pipes = 0;
814 while (i--) {
815 switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) {
816 case P54U_PIPE_DATA:
817 case P54U_PIPE_MGMT:
818 case P54U_PIPE_BRG:
819 case P54U_PIPE_DEV:
820 case P54U_PIPE_DATA | USB_DIR_IN:
821 case P54U_PIPE_MGMT | USB_DIR_IN:
822 case P54U_PIPE_BRG | USB_DIR_IN:
823 case P54U_PIPE_DEV | USB_DIR_IN:
824 case P54U_PIPE_INT | USB_DIR_IN:
825 recognized_pipes++;
828 priv->common.open = p54u_open;
830 if (recognized_pipes < P54U_PIPE_NUMBER) {
831 priv->hw_type = P54U_3887;
832 priv->common.tx = p54u_tx_3887;
833 } else {
834 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
835 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
836 priv->common.tx = p54u_tx_net2280;
838 priv->common.stop = p54u_stop;
840 if (priv->hw_type)
841 err = p54u_upload_firmware_3887(dev);
842 else
843 err = p54u_upload_firmware_net2280(dev);
844 if (err)
845 goto err_free_dev;
847 err = p54u_read_eeprom(dev);
848 if (err)
849 goto err_free_dev;
851 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
852 u8 perm_addr[ETH_ALEN];
854 printk(KERN_WARNING "prism54usb: Invalid hwaddr! Using randomly generated MAC addr\n");
855 random_ether_addr(perm_addr);
856 SET_IEEE80211_PERM_ADDR(dev, perm_addr);
859 skb_queue_head_init(&priv->rx_queue);
861 err = ieee80211_register_hw(dev);
862 if (err) {
863 printk(KERN_ERR "prism54usb: Cannot register netdevice\n");
864 goto err_free_dev;
867 printk(KERN_INFO "%s: hwaddr %s, isl38%02x\n",
868 wiphy_name(dev->wiphy),
869 print_mac(mac, dev->wiphy->perm_addr),
870 priv->common.version);
872 return 0;
874 err_free_dev:
875 ieee80211_free_hw(dev);
876 usb_set_intfdata(intf, NULL);
877 usb_put_dev(udev);
878 return err;
881 static void __devexit p54u_disconnect(struct usb_interface *intf)
883 struct ieee80211_hw *dev = usb_get_intfdata(intf);
884 struct p54u_priv *priv;
886 if (!dev)
887 return;
889 ieee80211_unregister_hw(dev);
891 priv = dev->priv;
892 usb_put_dev(interface_to_usbdev(intf));
893 p54_free_common(dev);
894 ieee80211_free_hw(dev);
897 static struct usb_driver p54u_driver = {
898 .name = "prism54usb",
899 .id_table = p54u_table,
900 .probe = p54u_probe,
901 .disconnect = p54u_disconnect,
904 static int __init p54u_init(void)
906 return usb_register(&p54u_driver);
909 static void __exit p54u_exit(void)
911 usb_deregister(&p54u_driver);
914 module_init(p54u_init);
915 module_exit(p54u_exit);