p54usb: fix nasty use after free
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / net / wireless / p54 / p54usb.c
blob4487cc5c928b3037c7c2088f5e8d5c8ff37c9221
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");
31 MODULE_FIRMWARE("isl3886usb");
32 MODULE_FIRMWARE("isl3887usb");
34 static struct usb_device_id p54u_table[] __devinitdata = {
35 /* Version 1 devices (pci chip + net2280) */
36 {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
37 {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
38 {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */
39 {USB_DEVICE(0x083a, 0x4502)}, /* Siemens Gigaset USB Adapter */
40 {USB_DEVICE(0x083a, 0x5501)}, /* Phillips CPWUA054 */
41 {USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */
42 {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */
43 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
44 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
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(0x0471, 0x1230)}, /* Philips CPWUA054/00 */
56 {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */
57 {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */
58 {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */
59 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
60 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
61 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
62 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */
63 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */
64 {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */
65 {USB_DEVICE(0x0baf, 0x0118)}, /* U.S. Robotics U5 802.11g Adapter*/
66 {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/
67 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */
68 {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
69 {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
70 {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */
71 {USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */
72 {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */
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 skb_unlink(skb, &priv->rx_queue);
92 if (unlikely(urb->status)) {
93 dev_kfree_skb_irq(skb);
94 return;
97 skb_put(skb, urb->actual_length);
99 if (priv->hw_type == P54U_NET2280)
100 skb_pull(skb, priv->common.tx_hdr_len);
101 if (priv->common.fw_interface == FW_LM87) {
102 skb_pull(skb, 4);
103 skb_put(skb, 4);
106 if (p54_rx(dev, skb)) {
107 skb = dev_alloc_skb(priv->common.rx_mtu + 32);
108 if (unlikely(!skb)) {
109 /* TODO check rx queue length and refill *somewhere* */
110 return;
113 info = (struct p54u_rx_info *) skb->cb;
114 info->urb = urb;
115 info->dev = dev;
116 urb->transfer_buffer = skb_tail_pointer(skb);
117 urb->context = skb;
118 } else {
119 if (priv->hw_type == P54U_NET2280)
120 skb_push(skb, priv->common.tx_hdr_len);
121 if (priv->common.fw_interface == FW_LM87) {
122 skb_push(skb, 4);
123 skb_put(skb, 4);
125 skb_reset_tail_pointer(skb);
126 skb_trim(skb, 0);
127 if (urb->transfer_buffer != skb_tail_pointer(skb)) {
128 /* this should not happen */
129 WARN_ON(1);
130 urb->transfer_buffer = skb_tail_pointer(skb);
133 skb_queue_tail(&priv->rx_queue, skb);
134 usb_anchor_urb(urb, &priv->submitted);
135 if (usb_submit_urb(urb, GFP_ATOMIC)) {
136 skb_unlink(skb, &priv->rx_queue);
137 usb_unanchor_urb(urb);
138 dev_kfree_skb_irq(skb);
142 static void p54u_tx_cb(struct urb *urb)
144 struct sk_buff *skb = urb->context;
145 struct ieee80211_hw *dev = (struct ieee80211_hw *)
146 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
148 p54_free_skb(dev, skb);
151 static void p54u_tx_dummy_cb(struct urb *urb) { }
153 static void p54u_free_urbs(struct ieee80211_hw *dev)
155 struct p54u_priv *priv = dev->priv;
156 usb_kill_anchored_urbs(&priv->submitted);
159 static int p54u_init_urbs(struct ieee80211_hw *dev)
161 struct p54u_priv *priv = dev->priv;
162 struct urb *entry = NULL;
163 struct sk_buff *skb;
164 struct p54u_rx_info *info;
165 int ret = 0;
167 while (skb_queue_len(&priv->rx_queue) < 32) {
168 skb = __dev_alloc_skb(priv->common.rx_mtu + 32, GFP_KERNEL);
169 if (!skb) {
170 ret = -ENOMEM;
171 goto err;
173 entry = usb_alloc_urb(0, GFP_KERNEL);
174 if (!entry) {
175 ret = -ENOMEM;
176 goto err;
179 usb_fill_bulk_urb(entry, priv->udev,
180 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
181 skb_tail_pointer(skb),
182 priv->common.rx_mtu + 32, p54u_rx_cb, skb);
183 info = (struct p54u_rx_info *) skb->cb;
184 info->urb = entry;
185 info->dev = dev;
186 skb_queue_tail(&priv->rx_queue, skb);
188 usb_anchor_urb(entry, &priv->submitted);
189 ret = usb_submit_urb(entry, GFP_KERNEL);
190 if (ret) {
191 skb_unlink(skb, &priv->rx_queue);
192 usb_unanchor_urb(entry);
193 goto err;
195 usb_free_urb(entry);
196 entry = NULL;
199 return 0;
201 err:
202 usb_free_urb(entry);
203 kfree_skb(skb);
204 p54u_free_urbs(dev);
205 return ret;
208 static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb)
210 struct p54u_priv *priv = dev->priv;
211 struct urb *addr_urb, *data_urb;
212 int err = 0;
214 addr_urb = usb_alloc_urb(0, GFP_ATOMIC);
215 if (!addr_urb)
216 return;
218 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
219 if (!data_urb) {
220 usb_free_urb(addr_urb);
221 return;
224 usb_fill_bulk_urb(addr_urb, priv->udev,
225 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
226 &((struct p54_hdr *)skb->data)->req_id, 4,
227 p54u_tx_dummy_cb, dev);
228 usb_fill_bulk_urb(data_urb, priv->udev,
229 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
230 skb->data, skb->len, FREE_AFTER_TX(skb) ?
231 p54u_tx_cb : p54u_tx_dummy_cb, skb);
233 usb_anchor_urb(addr_urb, &priv->submitted);
234 err = usb_submit_urb(addr_urb, GFP_ATOMIC);
235 if (err) {
236 usb_unanchor_urb(addr_urb);
237 goto out;
240 usb_anchor_urb(addr_urb, &priv->submitted);
241 err = usb_submit_urb(data_urb, GFP_ATOMIC);
242 if (err)
243 usb_unanchor_urb(data_urb);
245 out:
246 usb_free_urb(addr_urb);
247 usb_free_urb(data_urb);
249 if (err)
250 p54_free_skb(dev, skb);
253 static __le32 p54u_lm87_chksum(const __le32 *data, size_t length)
255 u32 chk = 0;
257 length >>= 2;
258 while (length--) {
259 chk ^= le32_to_cpu(*data++);
260 chk = (chk >> 5) ^ (chk << 3);
263 return cpu_to_le32(chk);
266 static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb)
268 struct p54u_priv *priv = dev->priv;
269 struct urb *data_urb;
270 struct lm87_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
272 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
273 if (!data_urb)
274 return;
276 hdr->chksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);
277 hdr->device_addr = ((struct p54_hdr *)skb->data)->req_id;
279 usb_fill_bulk_urb(data_urb, priv->udev,
280 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
281 hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?
282 p54u_tx_cb : p54u_tx_dummy_cb, skb);
283 data_urb->transfer_flags |= URB_ZERO_PACKET;
285 usb_anchor_urb(data_urb, &priv->submitted);
286 if (usb_submit_urb(data_urb, GFP_ATOMIC)) {
287 usb_unanchor_urb(data_urb);
288 p54_free_skb(dev, skb);
290 usb_free_urb(data_urb);
293 static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
295 struct p54u_priv *priv = dev->priv;
296 struct urb *int_urb, *data_urb;
297 struct net2280_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
298 struct net2280_reg_write *reg;
299 int err = 0;
301 reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
302 if (!reg)
303 return;
305 int_urb = usb_alloc_urb(0, GFP_ATOMIC);
306 if (!int_urb) {
307 kfree(reg);
308 return;
311 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
312 if (!data_urb) {
313 kfree(reg);
314 usb_free_urb(int_urb);
315 return;
318 reg->port = cpu_to_le16(NET2280_DEV_U32);
319 reg->addr = cpu_to_le32(P54U_DEV_BASE);
320 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
322 memset(hdr, 0, sizeof(*hdr));
323 hdr->len = cpu_to_le16(skb->len);
324 hdr->device_addr = ((struct p54_hdr *) skb->data)->req_id;
326 usb_fill_bulk_urb(int_urb, priv->udev,
327 usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
328 p54u_tx_dummy_cb, dev);
331 * This flag triggers a code path in the USB subsystem that will
332 * free what's inside the transfer_buffer after the callback routine
333 * has completed.
335 int_urb->transfer_flags |= URB_FREE_BUFFER;
337 usb_fill_bulk_urb(data_urb, priv->udev,
338 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
339 hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?
340 p54u_tx_cb : p54u_tx_dummy_cb, skb);
342 usb_anchor_urb(int_urb, &priv->submitted);
343 err = usb_submit_urb(int_urb, GFP_ATOMIC);
344 if (err) {
345 usb_unanchor_urb(int_urb);
346 goto out;
349 usb_anchor_urb(data_urb, &priv->submitted);
350 err = usb_submit_urb(data_urb, GFP_ATOMIC);
351 if (err) {
352 usb_unanchor_urb(data_urb);
353 goto out;
355 out:
356 usb_free_urb(int_urb);
357 usb_free_urb(data_urb);
359 if (err) {
360 skb_pull(skb, sizeof(*hdr));
361 p54_free_skb(dev, skb);
365 static int p54u_write(struct p54u_priv *priv,
366 struct net2280_reg_write *buf,
367 enum net2280_op_type type,
368 __le32 addr, __le32 val)
370 unsigned int ep;
371 int alen;
373 if (type & 0x0800)
374 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV);
375 else
376 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_BRG);
378 buf->port = cpu_to_le16(type);
379 buf->addr = addr;
380 buf->val = val;
382 return usb_bulk_msg(priv->udev, ep, buf, sizeof(*buf), &alen, 1000);
385 static int p54u_read(struct p54u_priv *priv, void *buf,
386 enum net2280_op_type type,
387 __le32 addr, __le32 *val)
389 struct net2280_reg_read *read = buf;
390 __le32 *reg = buf;
391 unsigned int ep;
392 int alen, err;
394 if (type & 0x0800)
395 ep = P54U_PIPE_DEV;
396 else
397 ep = P54U_PIPE_BRG;
399 read->port = cpu_to_le16(type);
400 read->addr = addr;
402 err = usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
403 read, sizeof(*read), &alen, 1000);
404 if (err)
405 return err;
407 err = usb_bulk_msg(priv->udev, usb_rcvbulkpipe(priv->udev, ep),
408 reg, sizeof(*reg), &alen, 1000);
409 if (err)
410 return err;
412 *val = *reg;
413 return 0;
416 static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
417 void *data, size_t len)
419 int alen;
420 return usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
421 data, len, &alen, 2000);
424 static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
426 static char start_string[] = "~~~~<\r";
427 struct p54u_priv *priv = dev->priv;
428 const struct firmware *fw_entry = NULL;
429 int err, alen;
430 u8 carry = 0;
431 u8 *buf, *tmp;
432 const u8 *data;
433 unsigned int left, remains, block_size;
434 struct x2_header *hdr;
435 unsigned long timeout;
437 tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
438 if (!buf) {
439 dev_err(&priv->udev->dev, "(p54usb) cannot allocate firmware"
440 "upload buffer!\n");
441 err = -ENOMEM;
442 goto err_bufalloc;
445 memcpy(buf, start_string, 4);
446 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4);
447 if (err) {
448 dev_err(&priv->udev->dev, "(p54usb) reset failed! (%d)\n", err);
449 goto err_reset;
452 err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev);
453 if (err) {
454 dev_err(&priv->udev->dev, "p54usb: cannot find firmware "
455 "(isl3887usb)\n");
456 err = request_firmware(&fw_entry, "isl3887usb_bare",
457 &priv->udev->dev);
458 if (err)
459 goto err_req_fw_failed;
462 err = p54_parse_firmware(dev, fw_entry);
463 if (err)
464 goto err_upload_failed;
466 left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
467 strcpy(buf, start_string);
468 left -= strlen(start_string);
469 tmp += strlen(start_string);
471 data = fw_entry->data;
472 remains = fw_entry->size;
474 hdr = (struct x2_header *)(buf + strlen(start_string));
475 memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
476 hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
477 hdr->fw_length = cpu_to_le32(fw_entry->size);
478 hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
479 sizeof(u32)*2));
480 left -= sizeof(*hdr);
481 tmp += sizeof(*hdr);
483 while (remains) {
484 while (left--) {
485 if (carry) {
486 *tmp++ = carry;
487 carry = 0;
488 remains--;
489 continue;
491 switch (*data) {
492 case '~':
493 *tmp++ = '}';
494 carry = '^';
495 break;
496 case '}':
497 *tmp++ = '}';
498 carry = ']';
499 break;
500 default:
501 *tmp++ = *data;
502 remains--;
503 break;
505 data++;
508 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size);
509 if (err) {
510 dev_err(&priv->udev->dev, "(p54usb) firmware "
511 "upload failed!\n");
512 goto err_upload_failed;
515 tmp = buf;
516 left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
519 *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size));
520 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
521 if (err) {
522 dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n");
523 goto err_upload_failed;
525 timeout = jiffies + msecs_to_jiffies(1000);
526 while (!(err = usb_bulk_msg(priv->udev,
527 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
528 if (alen > 2 && !memcmp(buf, "OK", 2))
529 break;
531 if (alen > 5 && !memcmp(buf, "ERROR", 5)) {
532 err = -EINVAL;
533 break;
536 if (time_after(jiffies, timeout)) {
537 dev_err(&priv->udev->dev, "(p54usb) firmware boot "
538 "timed out!\n");
539 err = -ETIMEDOUT;
540 break;
543 if (err) {
544 dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n");
545 goto err_upload_failed;
548 buf[0] = 'g';
549 buf[1] = '\r';
550 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2);
551 if (err) {
552 dev_err(&priv->udev->dev, "(p54usb) firmware boot failed!\n");
553 goto err_upload_failed;
556 timeout = jiffies + msecs_to_jiffies(1000);
557 while (!(err = usb_bulk_msg(priv->udev,
558 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
559 if (alen > 0 && buf[0] == 'g')
560 break;
562 if (time_after(jiffies, timeout)) {
563 err = -ETIMEDOUT;
564 break;
567 if (err)
568 goto err_upload_failed;
570 err_upload_failed:
571 release_firmware(fw_entry);
572 err_req_fw_failed:
573 err_reset:
574 kfree(buf);
575 err_bufalloc:
576 return err;
579 static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
581 struct p54u_priv *priv = dev->priv;
582 const struct firmware *fw_entry = NULL;
583 const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;
584 int err, alen;
585 void *buf;
586 __le32 reg;
587 unsigned int remains, offset;
588 const u8 *data;
590 buf = kmalloc(512, GFP_KERNEL);
591 if (!buf) {
592 dev_err(&priv->udev->dev, "(p54usb) firmware buffer "
593 "alloc failed!\n");
594 return -ENOMEM;
597 err = request_firmware(&fw_entry, "isl3886usb", &priv->udev->dev);
598 if (err) {
599 dev_err(&priv->udev->dev, "(p54usb) cannot find firmware "
600 "(isl3886usb)\n");
601 err = request_firmware(&fw_entry, "isl3890usb",
602 &priv->udev->dev);
603 if (err) {
604 kfree(buf);
605 return err;
609 err = p54_parse_firmware(dev, fw_entry);
610 if (err) {
611 kfree(buf);
612 release_firmware(fw_entry);
613 return err;
616 #define P54U_WRITE(type, addr, data) \
617 do {\
618 err = p54u_write(priv, buf, type,\
619 cpu_to_le32((u32)(unsigned long)addr), data);\
620 if (err) \
621 goto fail;\
622 } while (0)
624 #define P54U_READ(type, addr) \
625 do {\
626 err = p54u_read(priv, buf, type,\
627 cpu_to_le32((u32)(unsigned long)addr), &reg);\
628 if (err)\
629 goto fail;\
630 } while (0)
632 /* power down net2280 bridge */
633 P54U_READ(NET2280_BRG_U32, NET2280_GPIOCTL);
634 reg |= cpu_to_le32(P54U_BRG_POWER_DOWN);
635 reg &= cpu_to_le32(~P54U_BRG_POWER_UP);
636 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
638 mdelay(100);
640 /* power up bridge */
641 reg |= cpu_to_le32(P54U_BRG_POWER_UP);
642 reg &= cpu_to_le32(~P54U_BRG_POWER_DOWN);
643 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
645 mdelay(100);
647 P54U_WRITE(NET2280_BRG_U32, NET2280_DEVINIT,
648 cpu_to_le32(NET2280_CLK_30Mhz |
649 NET2280_PCI_ENABLE |
650 NET2280_PCI_SOFT_RESET));
652 mdelay(20);
654 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_COMMAND,
655 cpu_to_le32(PCI_COMMAND_MEMORY |
656 PCI_COMMAND_MASTER));
658 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_0,
659 cpu_to_le32(NET2280_BASE));
661 P54U_READ(NET2280_BRG_CFG_U16, PCI_STATUS);
662 reg |= cpu_to_le32(PCI_STATUS_REC_MASTER_ABORT);
663 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_STATUS, reg);
665 // TODO: we really need this?
666 P54U_READ(NET2280_BRG_U32, NET2280_RELNUM);
668 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_RSP,
669 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
670 P54U_WRITE(NET2280_BRG_U32, NET2280_EPC_RSP,
671 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
673 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_2,
674 cpu_to_le32(NET2280_BASE2));
676 /* finally done setting up the bridge */
678 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | PCI_COMMAND,
679 cpu_to_le32(PCI_COMMAND_MEMORY |
680 PCI_COMMAND_MASTER));
682 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | 0x40 /* TRDY timeout */, 0);
683 P54U_WRITE(NET2280_DEV_CFG_U32, 0x10000 | PCI_BASE_ADDRESS_0,
684 cpu_to_le32(P54U_DEV_BASE));
686 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
687 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
688 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
690 /* do romboot */
691 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable, 0);
693 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
694 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
695 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);
696 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
697 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
699 mdelay(20);
701 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
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 mdelay(100);
711 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
712 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
714 /* finally, we can upload firmware now! */
715 remains = fw_entry->size;
716 data = fw_entry->data;
717 offset = ISL38XX_DEV_FIRMWARE_ADDR;
719 while (remains) {
720 unsigned int block_len = min(remains, (unsigned int)512);
721 memcpy(buf, data, block_len);
723 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_len);
724 if (err) {
725 dev_err(&priv->udev->dev, "(p54usb) firmware block "
726 "upload failed\n");
727 goto fail;
730 P54U_WRITE(NET2280_DEV_U32, &devreg->direct_mem_base,
731 cpu_to_le32(0xc0000f00));
733 P54U_WRITE(NET2280_DEV_U32,
734 0x0020 | (unsigned long)&devreg->direct_mem_win, 0);
735 P54U_WRITE(NET2280_DEV_U32,
736 0x0020 | (unsigned long)&devreg->direct_mem_win,
737 cpu_to_le32(1));
739 P54U_WRITE(NET2280_DEV_U32,
740 0x0024 | (unsigned long)&devreg->direct_mem_win,
741 cpu_to_le32(block_len));
742 P54U_WRITE(NET2280_DEV_U32,
743 0x0028 | (unsigned long)&devreg->direct_mem_win,
744 cpu_to_le32(offset));
746 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_addr,
747 cpu_to_le32(NET2280_EPA_FIFO_PCI_ADDR));
748 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_len,
749 cpu_to_le32(block_len >> 2));
750 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_ctrl,
751 cpu_to_le32(ISL38XX_DMA_MASTER_CONTROL_TRIGGER));
753 mdelay(10);
755 P54U_READ(NET2280_DEV_U32,
756 0x002C | (unsigned long)&devreg->direct_mem_win);
757 if (!(reg & cpu_to_le32(ISL38XX_DMA_STATUS_DONE)) ||
758 !(reg & cpu_to_le32(ISL38XX_DMA_STATUS_READY))) {
759 dev_err(&priv->udev->dev, "(p54usb) firmware DMA "
760 "transfer failed\n");
761 goto fail;
764 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_STAT,
765 cpu_to_le32(NET2280_FIFO_FLUSH));
767 remains -= block_len;
768 data += block_len;
769 offset += block_len;
772 /* do ramboot */
773 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
774 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
775 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
776 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);
777 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
779 mdelay(20);
781 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
782 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
784 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
785 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
787 mdelay(100);
789 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
790 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
792 /* start up the firmware */
793 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable,
794 cpu_to_le32(ISL38XX_INT_IDENT_INIT));
796 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
797 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
799 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1,
800 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT_ENABLE |
801 NET2280_USB_INTERRUPT_ENABLE));
803 P54U_WRITE(NET2280_DEV_U32, &devreg->dev_int,
804 cpu_to_le32(ISL38XX_DEV_INT_RESET));
806 err = usb_interrupt_msg(priv->udev,
807 usb_rcvbulkpipe(priv->udev, P54U_PIPE_INT),
808 buf, sizeof(__le32), &alen, 1000);
809 if (err || alen != sizeof(__le32))
810 goto fail;
812 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
813 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
815 if (!(reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)))
816 err = -EINVAL;
818 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
819 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
820 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
822 #undef P54U_WRITE
823 #undef P54U_READ
825 fail:
826 release_firmware(fw_entry);
827 kfree(buf);
828 return err;
831 static int p54u_open(struct ieee80211_hw *dev)
833 struct p54u_priv *priv = dev->priv;
834 int err;
836 err = p54u_init_urbs(dev);
837 if (err) {
838 return err;
841 priv->common.open = p54u_init_urbs;
843 return 0;
846 static void p54u_stop(struct ieee80211_hw *dev)
848 /* TODO: figure out how to reliably stop the 3887 and net2280 so
849 the hardware is still usable next time we want to start it.
850 until then, we just stop listening to the hardware.. */
851 p54u_free_urbs(dev);
852 return;
855 static int __devinit p54u_probe(struct usb_interface *intf,
856 const struct usb_device_id *id)
858 struct usb_device *udev = interface_to_usbdev(intf);
859 struct ieee80211_hw *dev;
860 struct p54u_priv *priv;
861 int err;
862 unsigned int i, recognized_pipes;
864 dev = p54_init_common(sizeof(*priv));
866 if (!dev) {
867 dev_err(&udev->dev, "(p54usb) ieee80211 alloc failed\n");
868 return -ENOMEM;
871 priv = dev->priv;
873 SET_IEEE80211_DEV(dev, &intf->dev);
874 usb_set_intfdata(intf, dev);
875 priv->udev = udev;
877 usb_get_dev(udev);
879 /* really lazy and simple way of figuring out if we're a 3887 */
880 /* TODO: should just stick the identification in the device table */
881 i = intf->altsetting->desc.bNumEndpoints;
882 recognized_pipes = 0;
883 while (i--) {
884 switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) {
885 case P54U_PIPE_DATA:
886 case P54U_PIPE_MGMT:
887 case P54U_PIPE_BRG:
888 case P54U_PIPE_DEV:
889 case P54U_PIPE_DATA | USB_DIR_IN:
890 case P54U_PIPE_MGMT | USB_DIR_IN:
891 case P54U_PIPE_BRG | USB_DIR_IN:
892 case P54U_PIPE_DEV | USB_DIR_IN:
893 case P54U_PIPE_INT | USB_DIR_IN:
894 recognized_pipes++;
897 priv->common.open = p54u_open;
898 priv->common.stop = p54u_stop;
899 if (recognized_pipes < P54U_PIPE_NUMBER) {
900 priv->hw_type = P54U_3887;
901 err = p54u_upload_firmware_3887(dev);
902 if (priv->common.fw_interface == FW_LM87) {
903 dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
904 priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr);
905 priv->common.tx = p54u_tx_lm87;
906 } else
907 priv->common.tx = p54u_tx_3887;
908 } else {
909 priv->hw_type = P54U_NET2280;
910 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
911 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
912 priv->common.tx = p54u_tx_net2280;
913 err = p54u_upload_firmware_net2280(dev);
915 if (err)
916 goto err_free_dev;
918 skb_queue_head_init(&priv->rx_queue);
919 init_usb_anchor(&priv->submitted);
921 p54u_open(dev);
922 err = p54_read_eeprom(dev);
923 p54u_stop(dev);
924 if (err)
925 goto err_free_dev;
927 err = ieee80211_register_hw(dev);
928 if (err) {
929 dev_err(&udev->dev, "(p54usb) Cannot register netdevice\n");
930 goto err_free_dev;
933 return 0;
935 err_free_dev:
936 ieee80211_free_hw(dev);
937 usb_set_intfdata(intf, NULL);
938 usb_put_dev(udev);
939 return err;
942 static void __devexit p54u_disconnect(struct usb_interface *intf)
944 struct ieee80211_hw *dev = usb_get_intfdata(intf);
945 struct p54u_priv *priv;
947 if (!dev)
948 return;
950 ieee80211_unregister_hw(dev);
952 priv = dev->priv;
953 usb_put_dev(interface_to_usbdev(intf));
954 p54_free_common(dev);
955 ieee80211_free_hw(dev);
958 static struct usb_driver p54u_driver = {
959 .name = "p54usb",
960 .id_table = p54u_table,
961 .probe = p54u_probe,
962 .disconnect = p54u_disconnect,
965 static int __init p54u_init(void)
967 return usb_register(&p54u_driver);
970 static void __exit p54u_exit(void)
972 usb_deregister(&p54u_driver);
975 module_init(p54u_init);
976 module_exit(p54u_exit);