pcmcia: CompactFlash driver for PA Semi Electra boards
[pv_ops_mirror.git] / drivers / net / wireless / p54usb.c
blob755482a5a9382793b6f942d702871ffe2ddb530f
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(0x0846, 0x4200)}, /* Netgear WG121 */
39 {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */
40 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
41 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
42 {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
43 {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */
44 {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */
45 {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */
46 {USB_DEVICE(0x2001, 0x3703)}, /* DLink DWL-G122 */
47 {USB_DEVICE(0x5041, 0x2234)}, /* Linksys WUSB54G */
48 {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */
50 /* Version 2 devices (3887) */
51 {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */
52 {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */
53 {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */
54 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
55 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
56 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */
57 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */
58 {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */
59 {USB_DEVICE(0x0baf, 0x0118)}, /* U.S. Robotics U5 802.11g Adapter*/
60 {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/
61 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */
62 {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
63 {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
64 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
65 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
66 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
67 {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
68 {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */
69 {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */
73 MODULE_DEVICE_TABLE(usb, p54u_table);
75 static void p54u_rx_cb(struct urb *urb)
77 struct sk_buff *skb = (struct sk_buff *) urb->context;
78 struct p54u_rx_info *info = (struct p54u_rx_info *)skb->cb;
79 struct ieee80211_hw *dev = info->dev;
80 struct p54u_priv *priv = dev->priv;
82 if (unlikely(urb->status)) {
83 info->urb = NULL;
84 usb_free_urb(urb);
85 return;
88 skb_unlink(skb, &priv->rx_queue);
89 skb_put(skb, urb->actual_length);
90 if (!priv->hw_type)
91 skb_pull(skb, sizeof(struct net2280_tx_hdr));
93 if (p54_rx(dev, skb)) {
94 skb = dev_alloc_skb(MAX_RX_SIZE);
95 if (unlikely(!skb)) {
96 usb_free_urb(urb);
97 /* TODO check rx queue length and refill *somewhere* */
98 return;
101 info = (struct p54u_rx_info *) skb->cb;
102 info->urb = urb;
103 info->dev = dev;
104 urb->transfer_buffer = skb_tail_pointer(skb);
105 urb->context = skb;
106 skb_queue_tail(&priv->rx_queue, skb);
107 } else {
108 skb_trim(skb, 0);
109 skb_queue_tail(&priv->rx_queue, skb);
112 usb_submit_urb(urb, GFP_ATOMIC);
115 static void p54u_tx_cb(struct urb *urb)
117 usb_free_urb(urb);
120 static void p54u_tx_free_cb(struct urb *urb)
122 kfree(urb->transfer_buffer);
123 usb_free_urb(urb);
126 static int p54u_init_urbs(struct ieee80211_hw *dev)
128 struct p54u_priv *priv = dev->priv;
129 struct urb *entry;
130 struct sk_buff *skb;
131 struct p54u_rx_info *info;
133 while (skb_queue_len(&priv->rx_queue) < 32) {
134 skb = __dev_alloc_skb(MAX_RX_SIZE, GFP_KERNEL);
135 if (!skb)
136 break;
137 entry = usb_alloc_urb(0, GFP_KERNEL);
138 if (!entry) {
139 kfree_skb(skb);
140 break;
142 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);
143 info = (struct p54u_rx_info *) skb->cb;
144 info->urb = entry;
145 info->dev = dev;
146 skb_queue_tail(&priv->rx_queue, skb);
147 usb_submit_urb(entry, GFP_KERNEL);
150 return 0;
153 static void p54u_free_urbs(struct ieee80211_hw *dev)
155 struct p54u_priv *priv = dev->priv;
156 struct p54u_rx_info *info;
157 struct sk_buff *skb;
159 while ((skb = skb_dequeue(&priv->rx_queue))) {
160 info = (struct p54u_rx_info *) skb->cb;
161 if (!info->urb)
162 continue;
164 usb_kill_urb(info->urb);
165 kfree_skb(skb);
169 static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data,
170 size_t len, int free_on_tx)
172 struct p54u_priv *priv = dev->priv;
173 struct urb *addr_urb, *data_urb;
175 addr_urb = usb_alloc_urb(0, GFP_ATOMIC);
176 if (!addr_urb)
177 return;
179 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
180 if (!data_urb) {
181 usb_free_urb(addr_urb);
182 return;
185 usb_fill_bulk_urb(addr_urb, priv->udev,
186 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), &data->req_id,
187 sizeof(data->req_id), p54u_tx_cb, dev);
188 usb_fill_bulk_urb(data_urb, priv->udev,
189 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), data, len,
190 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
192 usb_submit_urb(addr_urb, GFP_ATOMIC);
193 usb_submit_urb(data_urb, GFP_ATOMIC);
196 static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data,
197 size_t len, int free_on_tx)
199 struct p54u_priv *priv = dev->priv;
200 struct urb *int_urb, *data_urb;
201 struct net2280_tx_hdr *hdr;
202 struct net2280_reg_write *reg;
204 reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
205 if (!reg)
206 return;
208 int_urb = usb_alloc_urb(0, GFP_ATOMIC);
209 if (!int_urb) {
210 kfree(reg);
211 return;
214 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
215 if (!data_urb) {
216 kfree(reg);
217 usb_free_urb(int_urb);
218 return;
221 reg->port = cpu_to_le16(NET2280_DEV_U32);
222 reg->addr = cpu_to_le32(P54U_DEV_BASE);
223 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
225 len += sizeof(*data);
226 hdr = (void *)data - sizeof(*hdr);
227 memset(hdr, 0, sizeof(*hdr));
228 hdr->device_addr = data->req_id;
229 hdr->len = cpu_to_le16(len);
231 usb_fill_bulk_urb(int_urb, priv->udev,
232 usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
233 p54u_tx_free_cb, dev);
234 usb_submit_urb(int_urb, GFP_ATOMIC);
236 usb_fill_bulk_urb(data_urb, priv->udev,
237 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, len + sizeof(*hdr),
238 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
239 usb_submit_urb(data_urb, GFP_ATOMIC);
242 static int p54u_write(struct p54u_priv *priv,
243 struct net2280_reg_write *buf,
244 enum net2280_op_type type,
245 __le32 addr, __le32 val)
247 unsigned int ep;
248 int alen;
250 if (type & 0x0800)
251 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV);
252 else
253 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_BRG);
255 buf->port = cpu_to_le16(type);
256 buf->addr = addr;
257 buf->val = val;
259 return usb_bulk_msg(priv->udev, ep, buf, sizeof(*buf), &alen, 1000);
262 static int p54u_read(struct p54u_priv *priv, void *buf,
263 enum net2280_op_type type,
264 __le32 addr, __le32 *val)
266 struct net2280_reg_read *read = buf;
267 __le32 *reg = buf;
268 unsigned int ep;
269 int alen, err;
271 if (type & 0x0800)
272 ep = P54U_PIPE_DEV;
273 else
274 ep = P54U_PIPE_BRG;
276 read->port = cpu_to_le16(type);
277 read->addr = addr;
279 err = usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
280 read, sizeof(*read), &alen, 1000);
281 if (err)
282 return err;
284 err = usb_bulk_msg(priv->udev, usb_rcvbulkpipe(priv->udev, ep),
285 reg, sizeof(*reg), &alen, 1000);
286 if (err)
287 return err;
289 *val = *reg;
290 return 0;
293 static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
294 void *data, size_t len)
296 int alen;
297 return usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
298 data, len, &alen, 2000);
301 static int p54u_read_eeprom(struct ieee80211_hw *dev)
303 struct p54u_priv *priv = dev->priv;
304 void *buf;
305 struct p54_control_hdr *hdr;
306 int err, alen;
307 size_t offset = priv->hw_type ? 0x10 : 0x20;
309 buf = kmalloc(0x2020, GFP_KERNEL);
310 if (!buf) {
311 printk(KERN_ERR "prism54usb: cannot allocate memory for"
312 "eeprom readback!\n");
313 return -ENOMEM;
316 if (priv->hw_type) {
317 *((u32 *) buf) = priv->common.rx_start;
318 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
319 if (err) {
320 printk(KERN_ERR "prism54usb: addr send failed\n");
321 goto fail;
323 } else {
324 struct net2280_reg_write *reg = buf;
325 reg->port = cpu_to_le16(NET2280_DEV_U32);
326 reg->addr = cpu_to_le32(P54U_DEV_BASE);
327 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
328 err = p54u_bulk_msg(priv, P54U_PIPE_DEV, buf, sizeof(*reg));
329 if (err) {
330 printk(KERN_ERR "prism54usb: dev_int send failed\n");
331 goto fail;
335 hdr = buf + priv->common.tx_hdr_len;
336 p54_fill_eeprom_readback(hdr);
337 hdr->req_id = cpu_to_le32(priv->common.rx_start);
338 if (priv->common.tx_hdr_len) {
339 struct net2280_tx_hdr *tx_hdr = buf;
340 tx_hdr->device_addr = hdr->req_id;
341 tx_hdr->len = cpu_to_le16(EEPROM_READBACK_LEN);
344 /* we can just pretend to send 0x2000 bytes of nothing in the headers */
345 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf,
346 EEPROM_READBACK_LEN + priv->common.tx_hdr_len);
347 if (err) {
348 printk(KERN_ERR "prism54usb: eeprom req send failed\n");
349 goto fail;
352 err = usb_bulk_msg(priv->udev,
353 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
354 buf, 0x2020, &alen, 1000);
355 if (!err && alen > offset) {
356 p54_parse_eeprom(dev, (u8 *)buf + offset, alen - offset);
357 } else {
358 printk(KERN_ERR "prism54usb: eeprom read failed!\n");
359 err = -EINVAL;
360 goto fail;
363 fail:
364 kfree(buf);
365 return err;
368 static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
370 static char start_string[] = "~~~~<\r";
371 struct p54u_priv *priv = dev->priv;
372 const struct firmware *fw_entry = NULL;
373 int err, alen;
374 u8 carry = 0;
375 u8 *buf, *tmp, *data;
376 unsigned int left, remains, block_size;
377 struct x2_header *hdr;
378 unsigned long timeout;
380 tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
381 if (!buf) {
382 printk(KERN_ERR "p54usb: cannot allocate firmware upload buffer!\n");
383 err = -ENOMEM;
384 goto err_bufalloc;
387 memcpy(buf, start_string, 4);
388 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4);
389 if (err) {
390 printk(KERN_ERR "p54usb: reset failed! (%d)\n", err);
391 goto err_reset;
394 err = request_firmware(&fw_entry, "isl3887usb_bare", &priv->udev->dev);
395 if (err) {
396 printk(KERN_ERR "p54usb: cannot find firmware (isl3887usb_bare)!\n");
397 goto err_req_fw_failed;
400 p54_parse_firmware(dev, fw_entry);
402 left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
403 strcpy(buf, start_string);
404 left -= strlen(start_string);
405 tmp += strlen(start_string);
407 data = fw_entry->data;
408 remains = fw_entry->size;
410 hdr = (struct x2_header *)(buf + strlen(start_string));
411 memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
412 hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
413 hdr->fw_length = cpu_to_le32(fw_entry->size);
414 hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
415 sizeof(u32)*2));
416 left -= sizeof(*hdr);
417 tmp += sizeof(*hdr);
419 while (remains) {
420 while (left--) {
421 if (carry) {
422 *tmp++ = carry;
423 carry = 0;
424 remains--;
425 continue;
427 switch (*data) {
428 case '~':
429 *tmp++ = '}';
430 carry = '^';
431 break;
432 case '}':
433 *tmp++ = '}';
434 carry = ']';
435 break;
436 default:
437 *tmp++ = *data;
438 remains--;
439 break;
441 data++;
444 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size);
445 if (err) {
446 printk(KERN_ERR "prism54usb: firmware upload failed!\n");
447 goto err_upload_failed;
450 tmp = buf;
451 left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
454 *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size));
455 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
456 if (err) {
457 printk(KERN_ERR "prism54usb: firmware upload failed!\n");
458 goto err_upload_failed;
461 timeout = jiffies + msecs_to_jiffies(1000);
462 while (!(err = usb_bulk_msg(priv->udev,
463 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
464 if (alen > 2 && !memcmp(buf, "OK", 2))
465 break;
467 if (alen > 5 && !memcmp(buf, "ERROR", 5)) {
468 printk(KERN_INFO "prism54usb: firmware upload failed!\n");
469 err = -EINVAL;
470 break;
473 if (time_after(jiffies, timeout)) {
474 printk(KERN_ERR "prism54usb: firmware boot timed out!\n");
475 err = -ETIMEDOUT;
476 break;
479 if (err)
480 goto err_upload_failed;
482 buf[0] = 'g';
483 buf[1] = '\r';
484 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2);
485 if (err) {
486 printk(KERN_ERR "prism54usb: firmware boot failed!\n");
487 goto err_upload_failed;
490 timeout = jiffies + msecs_to_jiffies(1000);
491 while (!(err = usb_bulk_msg(priv->udev,
492 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
493 if (alen > 0 && buf[0] == 'g')
494 break;
496 if (time_after(jiffies, timeout)) {
497 err = -ETIMEDOUT;
498 break;
501 if (err)
502 goto err_upload_failed;
504 err_upload_failed:
505 release_firmware(fw_entry);
506 err_req_fw_failed:
507 err_reset:
508 kfree(buf);
509 err_bufalloc:
510 return err;
513 static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
515 struct p54u_priv *priv = dev->priv;
516 const struct firmware *fw_entry = NULL;
517 const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;
518 int err, alen;
519 void *buf;
520 __le32 reg;
521 unsigned int remains, offset;
522 u8 *data;
524 buf = kmalloc(512, GFP_KERNEL);
525 if (!buf) {
526 printk(KERN_ERR "p54usb: firmware buffer alloc failed!\n");
527 return -ENOMEM;
530 err = request_firmware(&fw_entry, "isl3890usb", &priv->udev->dev);
531 if (err) {
532 printk(KERN_ERR "p54usb: cannot find firmware (isl3890usb)!\n");
533 kfree(buf);
534 return err;
537 p54_parse_firmware(dev, fw_entry);
539 #define P54U_WRITE(type, addr, data) \
540 do {\
541 err = p54u_write(priv, buf, type,\
542 cpu_to_le32((u32)(unsigned long)addr), data);\
543 if (err) \
544 goto fail;\
545 } while (0)
547 #define P54U_READ(type, addr) \
548 do {\
549 err = p54u_read(priv, buf, type,\
550 cpu_to_le32((u32)(unsigned long)addr), &reg);\
551 if (err)\
552 goto fail;\
553 } while (0)
555 /* power down net2280 bridge */
556 P54U_READ(NET2280_BRG_U32, NET2280_GPIOCTL);
557 reg |= cpu_to_le32(P54U_BRG_POWER_DOWN);
558 reg &= cpu_to_le32(~P54U_BRG_POWER_UP);
559 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
561 mdelay(100);
563 /* power up bridge */
564 reg |= cpu_to_le32(P54U_BRG_POWER_UP);
565 reg &= cpu_to_le32(~P54U_BRG_POWER_DOWN);
566 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
568 mdelay(100);
570 P54U_WRITE(NET2280_BRG_U32, NET2280_DEVINIT,
571 cpu_to_le32(NET2280_CLK_30Mhz |
572 NET2280_PCI_ENABLE |
573 NET2280_PCI_SOFT_RESET));
575 mdelay(20);
577 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_COMMAND,
578 cpu_to_le32(PCI_COMMAND_MEMORY |
579 PCI_COMMAND_MASTER));
581 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_0,
582 cpu_to_le32(NET2280_BASE));
584 P54U_READ(NET2280_BRG_CFG_U16, PCI_STATUS);
585 reg |= cpu_to_le32(PCI_STATUS_REC_MASTER_ABORT);
586 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_STATUS, reg);
588 // TODO: we really need this?
589 P54U_READ(NET2280_BRG_U32, NET2280_RELNUM);
591 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_RSP,
592 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
593 P54U_WRITE(NET2280_BRG_U32, NET2280_EPC_RSP,
594 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
596 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_2,
597 cpu_to_le32(NET2280_BASE2));
599 /* finally done setting up the bridge */
601 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | PCI_COMMAND,
602 cpu_to_le32(PCI_COMMAND_MEMORY |
603 PCI_COMMAND_MASTER));
605 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | 0x40 /* TRDY timeout */, 0);
606 P54U_WRITE(NET2280_DEV_CFG_U32, 0x10000 | PCI_BASE_ADDRESS_0,
607 cpu_to_le32(P54U_DEV_BASE));
609 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
610 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
611 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
613 /* do romboot */
614 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable, 0);
616 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
617 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
618 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);
619 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
620 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
622 mdelay(20);
624 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
625 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
627 mdelay(20);
629 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
630 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
632 mdelay(100);
634 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
635 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
637 /* finally, we can upload firmware now! */
638 remains = fw_entry->size;
639 data = fw_entry->data;
640 offset = ISL38XX_DEV_FIRMWARE_ADDR;
642 while (remains) {
643 unsigned int block_len = min(remains, (unsigned int)512);
644 memcpy(buf, data, block_len);
646 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_len);
647 if (err) {
648 printk(KERN_ERR "prism54usb: firmware block upload "
649 "failed\n");
650 goto fail;
653 P54U_WRITE(NET2280_DEV_U32, &devreg->direct_mem_base,
654 cpu_to_le32(0xc0000f00));
656 P54U_WRITE(NET2280_DEV_U32,
657 0x0020 | (unsigned long)&devreg->direct_mem_win, 0);
658 P54U_WRITE(NET2280_DEV_U32,
659 0x0020 | (unsigned long)&devreg->direct_mem_win,
660 cpu_to_le32(1));
662 P54U_WRITE(NET2280_DEV_U32,
663 0x0024 | (unsigned long)&devreg->direct_mem_win,
664 cpu_to_le32(block_len));
665 P54U_WRITE(NET2280_DEV_U32,
666 0x0028 | (unsigned long)&devreg->direct_mem_win,
667 cpu_to_le32(offset));
669 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_addr,
670 cpu_to_le32(NET2280_EPA_FIFO_PCI_ADDR));
671 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_len,
672 cpu_to_le32(block_len >> 2));
673 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_ctrl,
674 cpu_to_le32(ISL38XX_DMA_MASTER_CONTROL_TRIGGER));
676 mdelay(10);
678 P54U_READ(NET2280_DEV_U32,
679 0x002C | (unsigned long)&devreg->direct_mem_win);
680 if (!(reg & cpu_to_le32(ISL38XX_DMA_STATUS_DONE)) ||
681 !(reg & cpu_to_le32(ISL38XX_DMA_STATUS_READY))) {
682 printk(KERN_ERR "prism54usb: firmware DMA transfer "
683 "failed\n");
684 goto fail;
687 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_STAT,
688 cpu_to_le32(NET2280_FIFO_FLUSH));
690 remains -= block_len;
691 data += block_len;
692 offset += block_len;
695 /* do ramboot */
696 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
697 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
698 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
699 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);
700 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
702 mdelay(20);
704 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
705 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
707 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
708 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
710 mdelay(100);
712 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
713 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
715 /* start up the firmware */
716 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable,
717 cpu_to_le32(ISL38XX_INT_IDENT_INIT));
719 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
720 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
722 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1,
723 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT_ENABLE |
724 NET2280_USB_INTERRUPT_ENABLE));
726 P54U_WRITE(NET2280_DEV_U32, &devreg->dev_int,
727 cpu_to_le32(ISL38XX_DEV_INT_RESET));
729 err = usb_interrupt_msg(priv->udev,
730 usb_rcvbulkpipe(priv->udev, P54U_PIPE_INT),
731 buf, sizeof(__le32), &alen, 1000);
732 if (err || alen != sizeof(__le32))
733 goto fail;
735 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
736 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
738 if (!(reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)))
739 err = -EINVAL;
741 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
742 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
743 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
745 #undef P54U_WRITE
746 #undef P54U_READ
748 fail:
749 release_firmware(fw_entry);
750 kfree(buf);
751 return err;
754 static int p54u_open(struct ieee80211_hw *dev)
756 struct p54u_priv *priv = dev->priv;
757 int err;
759 err = p54u_init_urbs(dev);
760 if (err) {
761 return err;
764 priv->common.open = p54u_init_urbs;
766 return 0;
769 static void p54u_stop(struct ieee80211_hw *dev)
771 /* TODO: figure out how to reliably stop the 3887 and net2280 so
772 the hardware is still usable next time we want to start it.
773 until then, we just stop listening to the hardware.. */
774 p54u_free_urbs(dev);
775 return;
778 static int __devinit p54u_probe(struct usb_interface *intf,
779 const struct usb_device_id *id)
781 struct usb_device *udev = interface_to_usbdev(intf);
782 struct ieee80211_hw *dev;
783 struct p54u_priv *priv;
784 int err;
785 unsigned int i, recognized_pipes;
786 DECLARE_MAC_BUF(mac);
788 dev = p54_init_common(sizeof(*priv));
789 if (!dev) {
790 printk(KERN_ERR "prism54usb: ieee80211 alloc failed\n");
791 return -ENOMEM;
794 priv = dev->priv;
796 SET_IEEE80211_DEV(dev, &intf->dev);
797 usb_set_intfdata(intf, dev);
798 priv->udev = udev;
800 usb_get_dev(udev);
802 /* really lazy and simple way of figuring out if we're a 3887 */
803 /* TODO: should just stick the identification in the device table */
804 i = intf->altsetting->desc.bNumEndpoints;
805 recognized_pipes = 0;
806 while (i--) {
807 switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) {
808 case P54U_PIPE_DATA:
809 case P54U_PIPE_MGMT:
810 case P54U_PIPE_BRG:
811 case P54U_PIPE_DEV:
812 case P54U_PIPE_DATA | USB_DIR_IN:
813 case P54U_PIPE_MGMT | USB_DIR_IN:
814 case P54U_PIPE_BRG | USB_DIR_IN:
815 case P54U_PIPE_DEV | USB_DIR_IN:
816 case P54U_PIPE_INT | USB_DIR_IN:
817 recognized_pipes++;
820 priv->common.open = p54u_open;
822 if (recognized_pipes < P54U_PIPE_NUMBER) {
823 priv->hw_type = P54U_3887;
824 priv->common.tx = p54u_tx_3887;
825 } else {
826 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
827 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
828 priv->common.tx = p54u_tx_net2280;
830 priv->common.stop = p54u_stop;
832 if (priv->hw_type)
833 err = p54u_upload_firmware_3887(dev);
834 else
835 err = p54u_upload_firmware_net2280(dev);
836 if (err)
837 goto err_free_dev;
839 err = p54u_read_eeprom(dev);
840 if (err)
841 goto err_free_dev;
843 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
844 u8 perm_addr[ETH_ALEN];
846 printk(KERN_WARNING "prism54usb: Invalid hwaddr! Using randomly generated MAC addr\n");
847 random_ether_addr(perm_addr);
848 SET_IEEE80211_PERM_ADDR(dev, perm_addr);
851 skb_queue_head_init(&priv->rx_queue);
853 err = ieee80211_register_hw(dev);
854 if (err) {
855 printk(KERN_ERR "prism54usb: Cannot register netdevice\n");
856 goto err_free_dev;
859 printk(KERN_INFO "%s: hwaddr %s, isl38%02x\n",
860 wiphy_name(dev->wiphy),
861 print_mac(mac, dev->wiphy->perm_addr),
862 priv->common.version);
864 return 0;
866 err_free_dev:
867 ieee80211_free_hw(dev);
868 usb_set_intfdata(intf, NULL);
869 usb_put_dev(udev);
870 return err;
873 static void __devexit p54u_disconnect(struct usb_interface *intf)
875 struct ieee80211_hw *dev = usb_get_intfdata(intf);
876 struct p54u_priv *priv;
878 if (!dev)
879 return;
881 ieee80211_unregister_hw(dev);
883 priv = dev->priv;
884 usb_put_dev(interface_to_usbdev(intf));
885 p54_free_common(dev);
886 ieee80211_free_hw(dev);
889 static struct usb_driver p54u_driver = {
890 .name = "prism54usb",
891 .id_table = p54u_table,
892 .probe = p54u_probe,
893 .disconnect = p54u_disconnect,
896 static int __init p54u_init(void)
898 return usb_register(&p54u_driver);
901 static void __exit p54u_exit(void)
903 usb_deregister(&p54u_driver);
906 module_init(p54u_init);
907 module_exit(p54u_exit);