p54usb: support LM87 firmwares
[linux-2.6/kvm.git] / drivers / net / wireless / p54 / p54usb.c
blob7444f37297793de7d819c1a95768ad77a90da1bb
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 {USB_DEVICE(0x083a, 0x5501)}, /* Phillips CPWUA054 */
39 {USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */
40 {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */
41 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
42 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
43 {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
44 {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */
45 {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */
46 {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */
47 {USB_DEVICE(0x2001, 0x3703)}, /* DLink DWL-G122 */
48 {USB_DEVICE(0x5041, 0x2234)}, /* Linksys WUSB54G */
49 {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */
51 /* Version 2 devices (3887) */
52 {USB_DEVICE(0x0471, 0x1230)}, /* Philips CPWUA054/00 */
53 {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */
54 {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */
55 {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */
56 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
57 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
58 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */
59 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */
60 {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */
61 {USB_DEVICE(0x0baf, 0x0118)}, /* U.S. Robotics U5 802.11g Adapter*/
62 {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/
63 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */
64 {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
65 {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
66 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
67 {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */
68 {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */
69 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
70 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
71 {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
72 {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */
73 {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */
77 MODULE_DEVICE_TABLE(usb, p54u_table);
79 static void p54u_rx_cb(struct urb *urb)
81 struct sk_buff *skb = (struct sk_buff *) urb->context;
82 struct p54u_rx_info *info = (struct p54u_rx_info *)skb->cb;
83 struct ieee80211_hw *dev = info->dev;
84 struct p54u_priv *priv = dev->priv;
86 if (unlikely(urb->status)) {
87 info->urb = NULL;
88 usb_free_urb(urb);
89 return;
92 skb_unlink(skb, &priv->rx_queue);
93 skb_put(skb, urb->actual_length);
95 if (priv->hw_type == P54U_NET2280)
96 skb_pull(skb, priv->common.tx_hdr_len);
97 if (priv->common.fw_interface == FW_LM87) {
98 skb_pull(skb, 4);
99 skb_put(skb, 4);
102 if (p54_rx(dev, skb)) {
103 skb = dev_alloc_skb(priv->common.rx_mtu + 32);
104 if (unlikely(!skb)) {
105 usb_free_urb(urb);
106 /* TODO check rx queue length and refill *somewhere* */
107 return;
110 info = (struct p54u_rx_info *) skb->cb;
111 info->urb = urb;
112 info->dev = dev;
113 urb->transfer_buffer = skb_tail_pointer(skb);
114 urb->context = skb;
115 skb_queue_tail(&priv->rx_queue, skb);
116 } else {
117 if (priv->hw_type == P54U_NET2280)
118 skb_push(skb, priv->common.tx_hdr_len);
119 if (priv->common.fw_interface == FW_LM87) {
120 skb_push(skb, 4);
121 skb_put(skb, 4);
123 skb_reset_tail_pointer(skb);
124 skb_trim(skb, 0);
125 if (urb->transfer_buffer != skb_tail_pointer(skb)) {
126 /* this should not happen */
127 WARN_ON(1);
128 urb->transfer_buffer = skb_tail_pointer(skb);
131 skb_queue_tail(&priv->rx_queue, skb);
134 usb_submit_urb(urb, GFP_ATOMIC);
137 static void p54u_tx_cb(struct urb *urb)
139 usb_free_urb(urb);
142 static void p54u_tx_free_cb(struct urb *urb)
144 kfree(urb->transfer_buffer);
145 usb_free_urb(urb);
148 static int p54u_init_urbs(struct ieee80211_hw *dev)
150 struct p54u_priv *priv = dev->priv;
151 struct urb *entry;
152 struct sk_buff *skb;
153 struct p54u_rx_info *info;
155 while (skb_queue_len(&priv->rx_queue) < 32) {
156 skb = __dev_alloc_skb(priv->common.rx_mtu + 32, GFP_KERNEL);
157 if (!skb)
158 break;
159 entry = usb_alloc_urb(0, GFP_KERNEL);
160 if (!entry) {
161 kfree_skb(skb);
162 break;
164 usb_fill_bulk_urb(entry, priv->udev,
165 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
166 skb_tail_pointer(skb),
167 priv->common.rx_mtu + 32, p54u_rx_cb, skb);
168 info = (struct p54u_rx_info *) skb->cb;
169 info->urb = entry;
170 info->dev = dev;
171 skb_queue_tail(&priv->rx_queue, skb);
172 usb_submit_urb(entry, GFP_KERNEL);
175 return 0;
178 static void p54u_free_urbs(struct ieee80211_hw *dev)
180 struct p54u_priv *priv = dev->priv;
181 struct p54u_rx_info *info;
182 struct sk_buff *skb;
184 while ((skb = skb_dequeue(&priv->rx_queue))) {
185 info = (struct p54u_rx_info *) skb->cb;
186 if (!info->urb)
187 continue;
189 usb_kill_urb(info->urb);
190 kfree_skb(skb);
194 static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data,
195 size_t len, int free_on_tx)
197 struct p54u_priv *priv = dev->priv;
198 struct urb *addr_urb, *data_urb;
200 addr_urb = usb_alloc_urb(0, GFP_ATOMIC);
201 if (!addr_urb)
202 return;
204 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
205 if (!data_urb) {
206 usb_free_urb(addr_urb);
207 return;
210 usb_fill_bulk_urb(addr_urb, priv->udev,
211 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), &data->req_id,
212 sizeof(data->req_id), p54u_tx_cb, dev);
213 usb_fill_bulk_urb(data_urb, priv->udev,
214 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), data, len,
215 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
217 usb_submit_urb(addr_urb, GFP_ATOMIC);
218 usb_submit_urb(data_urb, GFP_ATOMIC);
221 __le32 p54u_lm87_chksum(const u32 *data, size_t length)
223 __le32 chk = 0;
225 length >>= 2;
226 while (length--) {
227 chk ^= cpu_to_le32(*data++);
228 chk = (chk >> 5) ^ (chk << 3);
231 return chk;
234 static void p54u_tx_lm87(struct ieee80211_hw *dev,
235 struct p54_control_hdr *data,
236 size_t len, int free_on_tx)
238 struct p54u_priv *priv = dev->priv;
239 struct urb *data_urb;
240 struct lm87_tx_hdr *hdr = (void *)data - sizeof(*hdr);
242 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
243 if (!data_urb)
244 return;
246 hdr->chksum = p54u_lm87_chksum((u32 *)data, len);
247 hdr->device_addr = data->req_id;
249 usb_fill_bulk_urb(data_urb, priv->udev,
250 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr,
251 len + sizeof(*hdr), free_on_tx ? p54u_tx_free_cb : p54u_tx_cb,
252 dev);
254 usb_submit_urb(data_urb, GFP_ATOMIC);
257 static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data,
258 size_t len, int free_on_tx)
260 struct p54u_priv *priv = dev->priv;
261 struct urb *int_urb, *data_urb;
262 struct net2280_tx_hdr *hdr;
263 struct net2280_reg_write *reg;
265 reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
266 if (!reg)
267 return;
269 int_urb = usb_alloc_urb(0, GFP_ATOMIC);
270 if (!int_urb) {
271 kfree(reg);
272 return;
275 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
276 if (!data_urb) {
277 kfree(reg);
278 usb_free_urb(int_urb);
279 return;
282 reg->port = cpu_to_le16(NET2280_DEV_U32);
283 reg->addr = cpu_to_le32(P54U_DEV_BASE);
284 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
286 len += sizeof(*data);
287 hdr = (void *)data - sizeof(*hdr);
288 memset(hdr, 0, sizeof(*hdr));
289 hdr->device_addr = data->req_id;
290 hdr->len = cpu_to_le16(len);
292 usb_fill_bulk_urb(int_urb, priv->udev,
293 usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
294 p54u_tx_free_cb, dev);
295 usb_submit_urb(int_urb, GFP_ATOMIC);
297 usb_fill_bulk_urb(data_urb, priv->udev,
298 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, len + sizeof(*hdr),
299 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
300 usb_submit_urb(data_urb, GFP_ATOMIC);
303 static int p54u_write(struct p54u_priv *priv,
304 struct net2280_reg_write *buf,
305 enum net2280_op_type type,
306 __le32 addr, __le32 val)
308 unsigned int ep;
309 int alen;
311 if (type & 0x0800)
312 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV);
313 else
314 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_BRG);
316 buf->port = cpu_to_le16(type);
317 buf->addr = addr;
318 buf->val = val;
320 return usb_bulk_msg(priv->udev, ep, buf, sizeof(*buf), &alen, 1000);
323 static int p54u_read(struct p54u_priv *priv, void *buf,
324 enum net2280_op_type type,
325 __le32 addr, __le32 *val)
327 struct net2280_reg_read *read = buf;
328 __le32 *reg = buf;
329 unsigned int ep;
330 int alen, err;
332 if (type & 0x0800)
333 ep = P54U_PIPE_DEV;
334 else
335 ep = P54U_PIPE_BRG;
337 read->port = cpu_to_le16(type);
338 read->addr = addr;
340 err = usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
341 read, sizeof(*read), &alen, 1000);
342 if (err)
343 return err;
345 err = usb_bulk_msg(priv->udev, usb_rcvbulkpipe(priv->udev, ep),
346 reg, sizeof(*reg), &alen, 1000);
347 if (err)
348 return err;
350 *val = *reg;
351 return 0;
354 static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
355 void *data, size_t len)
357 int alen;
358 return usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
359 data, len, &alen, 2000);
362 static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
364 static char start_string[] = "~~~~<\r";
365 struct p54u_priv *priv = dev->priv;
366 const struct firmware *fw_entry = NULL;
367 int err, alen;
368 u8 carry = 0;
369 u8 *buf, *tmp;
370 const u8 *data;
371 unsigned int left, remains, block_size;
372 struct x2_header *hdr;
373 unsigned long timeout;
375 tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
376 if (!buf) {
377 printk(KERN_ERR "p54usb: cannot allocate firmware upload buffer!\n");
378 err = -ENOMEM;
379 goto err_bufalloc;
382 memcpy(buf, start_string, 4);
383 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4);
384 if (err) {
385 printk(KERN_ERR "p54usb: reset failed! (%d)\n", err);
386 goto err_reset;
389 err = request_firmware(&fw_entry, "isl3887usb_bare", &priv->udev->dev);
390 if (err) {
391 printk(KERN_ERR "p54usb: cannot find firmware (isl3887usb_bare)!\n");
392 goto err_req_fw_failed;
395 err = p54_parse_firmware(dev, fw_entry);
396 if (err)
397 goto err_upload_failed;
399 left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
400 strcpy(buf, start_string);
401 left -= strlen(start_string);
402 tmp += strlen(start_string);
404 data = fw_entry->data;
405 remains = fw_entry->size;
407 hdr = (struct x2_header *)(buf + strlen(start_string));
408 memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
409 hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
410 hdr->fw_length = cpu_to_le32(fw_entry->size);
411 hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
412 sizeof(u32)*2));
413 left -= sizeof(*hdr);
414 tmp += sizeof(*hdr);
416 while (remains) {
417 while (left--) {
418 if (carry) {
419 *tmp++ = carry;
420 carry = 0;
421 remains--;
422 continue;
424 switch (*data) {
425 case '~':
426 *tmp++ = '}';
427 carry = '^';
428 break;
429 case '}':
430 *tmp++ = '}';
431 carry = ']';
432 break;
433 default:
434 *tmp++ = *data;
435 remains--;
436 break;
438 data++;
441 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size);
442 if (err) {
443 printk(KERN_ERR "p54usb: firmware upload failed!\n");
444 goto err_upload_failed;
447 tmp = buf;
448 left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
451 *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size));
452 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
453 if (err) {
454 printk(KERN_ERR "p54usb: firmware upload failed!\n");
455 goto err_upload_failed;
458 timeout = jiffies + msecs_to_jiffies(1000);
459 while (!(err = usb_bulk_msg(priv->udev,
460 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
461 if (alen > 2 && !memcmp(buf, "OK", 2))
462 break;
464 if (alen > 5 && !memcmp(buf, "ERROR", 5)) {
465 printk(KERN_INFO "p54usb: firmware upload failed!\n");
466 err = -EINVAL;
467 break;
470 if (time_after(jiffies, timeout)) {
471 printk(KERN_ERR "p54usb: firmware boot timed out!\n");
472 err = -ETIMEDOUT;
473 break;
476 if (err)
477 goto err_upload_failed;
479 buf[0] = 'g';
480 buf[1] = '\r';
481 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2);
482 if (err) {
483 printk(KERN_ERR "p54usb: firmware boot failed!\n");
484 goto err_upload_failed;
487 timeout = jiffies + msecs_to_jiffies(1000);
488 while (!(err = usb_bulk_msg(priv->udev,
489 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
490 if (alen > 0 && buf[0] == 'g')
491 break;
493 if (time_after(jiffies, timeout)) {
494 err = -ETIMEDOUT;
495 break;
498 if (err)
499 goto err_upload_failed;
501 err_upload_failed:
502 release_firmware(fw_entry);
503 err_req_fw_failed:
504 err_reset:
505 kfree(buf);
506 err_bufalloc:
507 return err;
510 static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
512 struct p54u_priv *priv = dev->priv;
513 const struct firmware *fw_entry = NULL;
514 const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;
515 int err, alen;
516 void *buf;
517 __le32 reg;
518 unsigned int remains, offset;
519 const u8 *data;
521 buf = kmalloc(512, GFP_KERNEL);
522 if (!buf) {
523 printk(KERN_ERR "p54usb: firmware buffer alloc failed!\n");
524 return -ENOMEM;
527 err = request_firmware(&fw_entry, "isl3890usb", &priv->udev->dev);
528 if (err) {
529 printk(KERN_ERR "p54usb: cannot find firmware (isl3890usb)!\n");
530 kfree(buf);
531 return err;
534 err = p54_parse_firmware(dev, fw_entry);
535 if (err) {
536 kfree(buf);
537 release_firmware(fw_entry);
538 return err;
541 #define P54U_WRITE(type, addr, data) \
542 do {\
543 err = p54u_write(priv, buf, type,\
544 cpu_to_le32((u32)(unsigned long)addr), data);\
545 if (err) \
546 goto fail;\
547 } while (0)
549 #define P54U_READ(type, addr) \
550 do {\
551 err = p54u_read(priv, buf, type,\
552 cpu_to_le32((u32)(unsigned long)addr), &reg);\
553 if (err)\
554 goto fail;\
555 } while (0)
557 /* power down net2280 bridge */
558 P54U_READ(NET2280_BRG_U32, NET2280_GPIOCTL);
559 reg |= cpu_to_le32(P54U_BRG_POWER_DOWN);
560 reg &= cpu_to_le32(~P54U_BRG_POWER_UP);
561 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
563 mdelay(100);
565 /* power up bridge */
566 reg |= cpu_to_le32(P54U_BRG_POWER_UP);
567 reg &= cpu_to_le32(~P54U_BRG_POWER_DOWN);
568 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
570 mdelay(100);
572 P54U_WRITE(NET2280_BRG_U32, NET2280_DEVINIT,
573 cpu_to_le32(NET2280_CLK_30Mhz |
574 NET2280_PCI_ENABLE |
575 NET2280_PCI_SOFT_RESET));
577 mdelay(20);
579 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_COMMAND,
580 cpu_to_le32(PCI_COMMAND_MEMORY |
581 PCI_COMMAND_MASTER));
583 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_0,
584 cpu_to_le32(NET2280_BASE));
586 P54U_READ(NET2280_BRG_CFG_U16, PCI_STATUS);
587 reg |= cpu_to_le32(PCI_STATUS_REC_MASTER_ABORT);
588 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_STATUS, reg);
590 // TODO: we really need this?
591 P54U_READ(NET2280_BRG_U32, NET2280_RELNUM);
593 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_RSP,
594 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
595 P54U_WRITE(NET2280_BRG_U32, NET2280_EPC_RSP,
596 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
598 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_2,
599 cpu_to_le32(NET2280_BASE2));
601 /* finally done setting up the bridge */
603 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | PCI_COMMAND,
604 cpu_to_le32(PCI_COMMAND_MEMORY |
605 PCI_COMMAND_MASTER));
607 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | 0x40 /* TRDY timeout */, 0);
608 P54U_WRITE(NET2280_DEV_CFG_U32, 0x10000 | PCI_BASE_ADDRESS_0,
609 cpu_to_le32(P54U_DEV_BASE));
611 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
612 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
613 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
615 /* do romboot */
616 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable, 0);
618 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
619 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
620 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);
621 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
622 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
624 mdelay(20);
626 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
627 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
629 mdelay(20);
631 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
632 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
634 mdelay(100);
636 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
637 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
639 /* finally, we can upload firmware now! */
640 remains = fw_entry->size;
641 data = fw_entry->data;
642 offset = ISL38XX_DEV_FIRMWARE_ADDR;
644 while (remains) {
645 unsigned int block_len = min(remains, (unsigned int)512);
646 memcpy(buf, data, block_len);
648 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_len);
649 if (err) {
650 printk(KERN_ERR "p54usb: firmware block upload "
651 "failed\n");
652 goto fail;
655 P54U_WRITE(NET2280_DEV_U32, &devreg->direct_mem_base,
656 cpu_to_le32(0xc0000f00));
658 P54U_WRITE(NET2280_DEV_U32,
659 0x0020 | (unsigned long)&devreg->direct_mem_win, 0);
660 P54U_WRITE(NET2280_DEV_U32,
661 0x0020 | (unsigned long)&devreg->direct_mem_win,
662 cpu_to_le32(1));
664 P54U_WRITE(NET2280_DEV_U32,
665 0x0024 | (unsigned long)&devreg->direct_mem_win,
666 cpu_to_le32(block_len));
667 P54U_WRITE(NET2280_DEV_U32,
668 0x0028 | (unsigned long)&devreg->direct_mem_win,
669 cpu_to_le32(offset));
671 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_addr,
672 cpu_to_le32(NET2280_EPA_FIFO_PCI_ADDR));
673 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_len,
674 cpu_to_le32(block_len >> 2));
675 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_ctrl,
676 cpu_to_le32(ISL38XX_DMA_MASTER_CONTROL_TRIGGER));
678 mdelay(10);
680 P54U_READ(NET2280_DEV_U32,
681 0x002C | (unsigned long)&devreg->direct_mem_win);
682 if (!(reg & cpu_to_le32(ISL38XX_DMA_STATUS_DONE)) ||
683 !(reg & cpu_to_le32(ISL38XX_DMA_STATUS_READY))) {
684 printk(KERN_ERR "p54usb: firmware DMA transfer "
685 "failed\n");
686 goto fail;
689 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_STAT,
690 cpu_to_le32(NET2280_FIFO_FLUSH));
692 remains -= block_len;
693 data += block_len;
694 offset += block_len;
697 /* do ramboot */
698 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
699 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
700 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
701 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);
702 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
704 mdelay(20);
706 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
707 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
709 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
710 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
712 mdelay(100);
714 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
715 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
717 /* start up the firmware */
718 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable,
719 cpu_to_le32(ISL38XX_INT_IDENT_INIT));
721 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
722 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
724 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1,
725 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT_ENABLE |
726 NET2280_USB_INTERRUPT_ENABLE));
728 P54U_WRITE(NET2280_DEV_U32, &devreg->dev_int,
729 cpu_to_le32(ISL38XX_DEV_INT_RESET));
731 err = usb_interrupt_msg(priv->udev,
732 usb_rcvbulkpipe(priv->udev, P54U_PIPE_INT),
733 buf, sizeof(__le32), &alen, 1000);
734 if (err || alen != sizeof(__le32))
735 goto fail;
737 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
738 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
740 if (!(reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)))
741 err = -EINVAL;
743 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
744 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
745 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
747 #undef P54U_WRITE
748 #undef P54U_READ
750 fail:
751 release_firmware(fw_entry);
752 kfree(buf);
753 return err;
756 static int p54u_open(struct ieee80211_hw *dev)
758 struct p54u_priv *priv = dev->priv;
759 int err;
761 err = p54u_init_urbs(dev);
762 if (err) {
763 return err;
766 priv->common.open = p54u_init_urbs;
768 return 0;
771 static void p54u_stop(struct ieee80211_hw *dev)
773 /* TODO: figure out how to reliably stop the 3887 and net2280 so
774 the hardware is still usable next time we want to start it.
775 until then, we just stop listening to the hardware.. */
776 p54u_free_urbs(dev);
777 return;
780 static int __devinit p54u_probe(struct usb_interface *intf,
781 const struct usb_device_id *id)
783 struct usb_device *udev = interface_to_usbdev(intf);
784 struct ieee80211_hw *dev;
785 struct p54u_priv *priv;
786 int err;
787 unsigned int i, recognized_pipes;
788 DECLARE_MAC_BUF(mac);
790 dev = p54_init_common(sizeof(*priv));
791 if (!dev) {
792 printk(KERN_ERR "p54usb: ieee80211 alloc failed\n");
793 return -ENOMEM;
796 priv = dev->priv;
798 SET_IEEE80211_DEV(dev, &intf->dev);
799 usb_set_intfdata(intf, dev);
800 priv->udev = udev;
802 usb_get_dev(udev);
804 /* really lazy and simple way of figuring out if we're a 3887 */
805 /* TODO: should just stick the identification in the device table */
806 i = intf->altsetting->desc.bNumEndpoints;
807 recognized_pipes = 0;
808 while (i--) {
809 switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) {
810 case P54U_PIPE_DATA:
811 case P54U_PIPE_MGMT:
812 case P54U_PIPE_BRG:
813 case P54U_PIPE_DEV:
814 case P54U_PIPE_DATA | USB_DIR_IN:
815 case P54U_PIPE_MGMT | USB_DIR_IN:
816 case P54U_PIPE_BRG | USB_DIR_IN:
817 case P54U_PIPE_DEV | USB_DIR_IN:
818 case P54U_PIPE_INT | USB_DIR_IN:
819 recognized_pipes++;
822 priv->common.open = p54u_open;
823 priv->common.stop = p54u_stop;
824 if (recognized_pipes < P54U_PIPE_NUMBER) {
825 priv->hw_type = P54U_3887;
826 err = p54u_upload_firmware_3887(dev);
827 if (priv->common.fw_interface == FW_LM87) {
828 dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
829 priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr);
830 priv->common.tx = p54u_tx_lm87;
831 } else
832 priv->common.tx = p54u_tx_3887;
833 } else {
834 priv->hw_type = P54U_NET2280;
835 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
836 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
837 priv->common.tx = p54u_tx_net2280;
838 err = p54u_upload_firmware_net2280(dev);
840 if (err)
841 goto err_free_dev;
843 skb_queue_head_init(&priv->rx_queue);
845 p54u_open(dev);
846 err = p54_read_eeprom(dev);
847 p54u_stop(dev);
848 if (err)
849 goto err_free_dev;
851 err = ieee80211_register_hw(dev);
852 if (err) {
853 printk(KERN_ERR "p54usb: Cannot register netdevice\n");
854 goto err_free_dev;
857 return 0;
859 err_free_dev:
860 ieee80211_free_hw(dev);
861 usb_set_intfdata(intf, NULL);
862 usb_put_dev(udev);
863 return err;
866 static void __devexit p54u_disconnect(struct usb_interface *intf)
868 struct ieee80211_hw *dev = usb_get_intfdata(intf);
869 struct p54u_priv *priv;
871 if (!dev)
872 return;
874 ieee80211_unregister_hw(dev);
876 priv = dev->priv;
877 usb_put_dev(interface_to_usbdev(intf));
878 p54_free_common(dev);
879 ieee80211_free_hw(dev);
882 static struct usb_driver p54u_driver = {
883 .name = "p54usb",
884 .id_table = p54u_table,
885 .probe = p54u_probe,
886 .disconnect = p54u_disconnect,
889 static int __init p54u_init(void)
891 return usb_register(&p54u_driver);
894 static void __exit p54u_exit(void)
896 usb_deregister(&p54u_driver);
899 module_init(p54u_init);
900 module_exit(p54u_exit);