blob: f8695665c0cefcd6ce0c07c002155e98b133b317 [file] [log] [blame]
Michael Wueff1a592007-09-25 18:11:01 -07001
2/*
3 * Linux device driver for USB based Prism54
4 *
5 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
6 *
7 * Based on the islsm (softmac prism54) driver, which is:
8 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
9 *
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.
13 */
14
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>
23
24#include "p54.h"
25#include "p54usb.h"
26
27MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
28MODULE_DESCRIPTION("Prism54 USB wireless driver");
29MODULE_LICENSE("GPL");
30MODULE_ALIAS("prism54usb");
31
32static 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 */
Ivo Couckuyt1a175822008-02-20 14:58:00 -050038 {USB_DEVICE(0x083a, 0x5501)}, /* Phillips CPWUA054 */
Michael Wueff1a592007-09-25 18:11:01 -070039 {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 */
50
51 /* Version 2 devices (3887) */
52 {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */
53 {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */
54 {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */
55 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
56 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
57 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */
58 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */
59 {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */
60 {USB_DEVICE(0x0baf, 0x0118)}, /* U.S. Robotics U5 802.11g Adapter*/
61 {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/
62 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */
63 {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
64 {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
65 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
Martti Huttunenc1098102007-10-04 00:06:00 -040066 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
Michael Wueff1a592007-09-25 18:11:01 -070067 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
68 {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
69 {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */
70 {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */
71 {}
72};
73
74MODULE_DEVICE_TABLE(usb, p54u_table);
75
76static void p54u_rx_cb(struct urb *urb)
77{
78 struct sk_buff *skb = (struct sk_buff *) urb->context;
79 struct p54u_rx_info *info = (struct p54u_rx_info *)skb->cb;
80 struct ieee80211_hw *dev = info->dev;
81 struct p54u_priv *priv = dev->priv;
82
83 if (unlikely(urb->status)) {
84 info->urb = NULL;
85 usb_free_urb(urb);
86 return;
87 }
88
89 skb_unlink(skb, &priv->rx_queue);
90 skb_put(skb, urb->actual_length);
91 if (!priv->hw_type)
92 skb_pull(skb, sizeof(struct net2280_tx_hdr));
93
94 if (p54_rx(dev, skb)) {
95 skb = dev_alloc_skb(MAX_RX_SIZE);
96 if (unlikely(!skb)) {
97 usb_free_urb(urb);
98 /* TODO check rx queue length and refill *somewhere* */
99 return;
100 }
101
102 info = (struct p54u_rx_info *) skb->cb;
103 info->urb = urb;
104 info->dev = dev;
105 urb->transfer_buffer = skb_tail_pointer(skb);
106 urb->context = skb;
107 skb_queue_tail(&priv->rx_queue, skb);
108 } else {
109 skb_trim(skb, 0);
110 skb_queue_tail(&priv->rx_queue, skb);
111 }
112
113 usb_submit_urb(urb, GFP_ATOMIC);
114}
115
116static void p54u_tx_cb(struct urb *urb)
117{
118 usb_free_urb(urb);
119}
120
121static void p54u_tx_free_cb(struct urb *urb)
122{
123 kfree(urb->transfer_buffer);
124 usb_free_urb(urb);
125}
126
127static int p54u_init_urbs(struct ieee80211_hw *dev)
128{
129 struct p54u_priv *priv = dev->priv;
130 struct urb *entry;
131 struct sk_buff *skb;
132 struct p54u_rx_info *info;
133
134 while (skb_queue_len(&priv->rx_queue) < 32) {
135 skb = __dev_alloc_skb(MAX_RX_SIZE, GFP_KERNEL);
136 if (!skb)
137 break;
138 entry = usb_alloc_urb(0, GFP_KERNEL);
139 if (!entry) {
140 kfree_skb(skb);
141 break;
142 }
143 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);
144 info = (struct p54u_rx_info *) skb->cb;
145 info->urb = entry;
146 info->dev = dev;
147 skb_queue_tail(&priv->rx_queue, skb);
148 usb_submit_urb(entry, GFP_KERNEL);
149 }
150
151 return 0;
152}
153
154static void p54u_free_urbs(struct ieee80211_hw *dev)
155{
156 struct p54u_priv *priv = dev->priv;
157 struct p54u_rx_info *info;
158 struct sk_buff *skb;
159
160 while ((skb = skb_dequeue(&priv->rx_queue))) {
161 info = (struct p54u_rx_info *) skb->cb;
162 if (!info->urb)
163 continue;
164
165 usb_kill_urb(info->urb);
166 kfree_skb(skb);
167 }
168}
169
170static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data,
171 size_t len, int free_on_tx)
172{
173 struct p54u_priv *priv = dev->priv;
174 struct urb *addr_urb, *data_urb;
175
176 addr_urb = usb_alloc_urb(0, GFP_ATOMIC);
177 if (!addr_urb)
178 return;
179
180 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
181 if (!data_urb) {
182 usb_free_urb(addr_urb);
183 return;
184 }
185
186 usb_fill_bulk_urb(addr_urb, priv->udev,
187 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), &data->req_id,
188 sizeof(data->req_id), p54u_tx_cb, dev);
189 usb_fill_bulk_urb(data_urb, priv->udev,
190 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), data, len,
191 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
192
193 usb_submit_urb(addr_urb, GFP_ATOMIC);
194 usb_submit_urb(data_urb, GFP_ATOMIC);
195}
196
197static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data,
198 size_t len, int free_on_tx)
199{
200 struct p54u_priv *priv = dev->priv;
201 struct urb *int_urb, *data_urb;
202 struct net2280_tx_hdr *hdr;
203 struct net2280_reg_write *reg;
204
205 reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
206 if (!reg)
207 return;
208
209 int_urb = usb_alloc_urb(0, GFP_ATOMIC);
210 if (!int_urb) {
211 kfree(reg);
212 return;
213 }
214
215 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
216 if (!data_urb) {
217 kfree(reg);
218 usb_free_urb(int_urb);
219 return;
220 }
221
222 reg->port = cpu_to_le16(NET2280_DEV_U32);
223 reg->addr = cpu_to_le32(P54U_DEV_BASE);
224 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
225
226 len += sizeof(*data);
227 hdr = (void *)data - sizeof(*hdr);
228 memset(hdr, 0, sizeof(*hdr));
229 hdr->device_addr = data->req_id;
230 hdr->len = cpu_to_le16(len);
231
232 usb_fill_bulk_urb(int_urb, priv->udev,
233 usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
234 p54u_tx_free_cb, dev);
235 usb_submit_urb(int_urb, GFP_ATOMIC);
236
237 usb_fill_bulk_urb(data_urb, priv->udev,
238 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, len + sizeof(*hdr),
239 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
240 usb_submit_urb(data_urb, GFP_ATOMIC);
241}
242
243static int p54u_write(struct p54u_priv *priv,
244 struct net2280_reg_write *buf,
245 enum net2280_op_type type,
246 __le32 addr, __le32 val)
247{
248 unsigned int ep;
249 int alen;
250
251 if (type & 0x0800)
252 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV);
253 else
254 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_BRG);
255
256 buf->port = cpu_to_le16(type);
257 buf->addr = addr;
258 buf->val = val;
259
260 return usb_bulk_msg(priv->udev, ep, buf, sizeof(*buf), &alen, 1000);
261}
262
263static int p54u_read(struct p54u_priv *priv, void *buf,
264 enum net2280_op_type type,
265 __le32 addr, __le32 *val)
266{
267 struct net2280_reg_read *read = buf;
268 __le32 *reg = buf;
269 unsigned int ep;
270 int alen, err;
271
272 if (type & 0x0800)
273 ep = P54U_PIPE_DEV;
274 else
275 ep = P54U_PIPE_BRG;
276
277 read->port = cpu_to_le16(type);
278 read->addr = addr;
279
280 err = usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
281 read, sizeof(*read), &alen, 1000);
282 if (err)
283 return err;
284
285 err = usb_bulk_msg(priv->udev, usb_rcvbulkpipe(priv->udev, ep),
286 reg, sizeof(*reg), &alen, 1000);
287 if (err)
288 return err;
289
290 *val = *reg;
291 return 0;
292}
293
294static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
295 void *data, size_t len)
296{
297 int alen;
298 return usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
299 data, len, &alen, 2000);
300}
301
302static int p54u_read_eeprom(struct ieee80211_hw *dev)
303{
304 struct p54u_priv *priv = dev->priv;
305 void *buf;
306 struct p54_control_hdr *hdr;
307 int err, alen;
308 size_t offset = priv->hw_type ? 0x10 : 0x20;
309
310 buf = kmalloc(0x2020, GFP_KERNEL);
311 if (!buf) {
Joe Perches8376e7a2007-11-19 17:48:27 -0800312 printk(KERN_ERR "prism54usb: cannot allocate memory for "
Michael Wueff1a592007-09-25 18:11:01 -0700313 "eeprom readback!\n");
314 return -ENOMEM;
315 }
316
317 if (priv->hw_type) {
318 *((u32 *) buf) = priv->common.rx_start;
319 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
320 if (err) {
321 printk(KERN_ERR "prism54usb: addr send failed\n");
322 goto fail;
323 }
324 } else {
325 struct net2280_reg_write *reg = buf;
326 reg->port = cpu_to_le16(NET2280_DEV_U32);
327 reg->addr = cpu_to_le32(P54U_DEV_BASE);
328 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
329 err = p54u_bulk_msg(priv, P54U_PIPE_DEV, buf, sizeof(*reg));
330 if (err) {
331 printk(KERN_ERR "prism54usb: dev_int send failed\n");
332 goto fail;
333 }
334 }
335
336 hdr = buf + priv->common.tx_hdr_len;
337 p54_fill_eeprom_readback(hdr);
338 hdr->req_id = cpu_to_le32(priv->common.rx_start);
339 if (priv->common.tx_hdr_len) {
340 struct net2280_tx_hdr *tx_hdr = buf;
341 tx_hdr->device_addr = hdr->req_id;
342 tx_hdr->len = cpu_to_le16(EEPROM_READBACK_LEN);
343 }
344
345 /* we can just pretend to send 0x2000 bytes of nothing in the headers */
346 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf,
347 EEPROM_READBACK_LEN + priv->common.tx_hdr_len);
348 if (err) {
349 printk(KERN_ERR "prism54usb: eeprom req send failed\n");
350 goto fail;
351 }
352
353 err = usb_bulk_msg(priv->udev,
354 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
355 buf, 0x2020, &alen, 1000);
356 if (!err && alen > offset) {
357 p54_parse_eeprom(dev, (u8 *)buf + offset, alen - offset);
358 } else {
359 printk(KERN_ERR "prism54usb: eeprom read failed!\n");
360 err = -EINVAL;
361 goto fail;
362 }
363
364 fail:
365 kfree(buf);
366 return err;
367}
368
369static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
370{
371 static char start_string[] = "~~~~<\r";
372 struct p54u_priv *priv = dev->priv;
373 const struct firmware *fw_entry = NULL;
374 int err, alen;
375 u8 carry = 0;
376 u8 *buf, *tmp, *data;
377 unsigned int left, remains, block_size;
378 struct x2_header *hdr;
379 unsigned long timeout;
380
381 tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
382 if (!buf) {
383 printk(KERN_ERR "p54usb: cannot allocate firmware upload buffer!\n");
384 err = -ENOMEM;
385 goto err_bufalloc;
386 }
387
388 memcpy(buf, start_string, 4);
389 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4);
390 if (err) {
391 printk(KERN_ERR "p54usb: reset failed! (%d)\n", err);
392 goto err_reset;
393 }
394
395 err = request_firmware(&fw_entry, "isl3887usb_bare", &priv->udev->dev);
396 if (err) {
397 printk(KERN_ERR "p54usb: cannot find firmware (isl3887usb_bare)!\n");
398 goto err_req_fw_failed;
399 }
400
401 p54_parse_firmware(dev, fw_entry);
402
403 left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
404 strcpy(buf, start_string);
405 left -= strlen(start_string);
406 tmp += strlen(start_string);
407
408 data = fw_entry->data;
409 remains = fw_entry->size;
410
411 hdr = (struct x2_header *)(buf + strlen(start_string));
412 memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
413 hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
414 hdr->fw_length = cpu_to_le32(fw_entry->size);
415 hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
416 sizeof(u32)*2));
417 left -= sizeof(*hdr);
418 tmp += sizeof(*hdr);
419
420 while (remains) {
421 while (left--) {
422 if (carry) {
423 *tmp++ = carry;
424 carry = 0;
425 remains--;
426 continue;
427 }
428 switch (*data) {
429 case '~':
430 *tmp++ = '}';
431 carry = '^';
432 break;
433 case '}':
434 *tmp++ = '}';
435 carry = ']';
436 break;
437 default:
438 *tmp++ = *data;
439 remains--;
440 break;
441 }
442 data++;
443 }
444
445 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size);
446 if (err) {
447 printk(KERN_ERR "prism54usb: firmware upload failed!\n");
448 goto err_upload_failed;
449 }
450
451 tmp = buf;
452 left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
453 }
454
455 *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size));
456 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
457 if (err) {
458 printk(KERN_ERR "prism54usb: firmware upload failed!\n");
459 goto err_upload_failed;
460 }
461
462 timeout = jiffies + msecs_to_jiffies(1000);
463 while (!(err = usb_bulk_msg(priv->udev,
464 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
465 if (alen > 2 && !memcmp(buf, "OK", 2))
466 break;
467
468 if (alen > 5 && !memcmp(buf, "ERROR", 5)) {
469 printk(KERN_INFO "prism54usb: firmware upload failed!\n");
470 err = -EINVAL;
471 break;
472 }
473
474 if (time_after(jiffies, timeout)) {
475 printk(KERN_ERR "prism54usb: firmware boot timed out!\n");
476 err = -ETIMEDOUT;
477 break;
478 }
479 }
480 if (err)
481 goto err_upload_failed;
482
483 buf[0] = 'g';
484 buf[1] = '\r';
485 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2);
486 if (err) {
487 printk(KERN_ERR "prism54usb: firmware boot failed!\n");
488 goto err_upload_failed;
489 }
490
491 timeout = jiffies + msecs_to_jiffies(1000);
492 while (!(err = usb_bulk_msg(priv->udev,
493 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
494 if (alen > 0 && buf[0] == 'g')
495 break;
496
497 if (time_after(jiffies, timeout)) {
498 err = -ETIMEDOUT;
499 break;
500 }
501 }
502 if (err)
503 goto err_upload_failed;
504
505 err_upload_failed:
506 release_firmware(fw_entry);
507 err_req_fw_failed:
508 err_reset:
509 kfree(buf);
510 err_bufalloc:
511 return err;
512}
513
514static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
515{
516 struct p54u_priv *priv = dev->priv;
517 const struct firmware *fw_entry = NULL;
518 const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;
519 int err, alen;
520 void *buf;
521 __le32 reg;
522 unsigned int remains, offset;
523 u8 *data;
524
525 buf = kmalloc(512, GFP_KERNEL);
526 if (!buf) {
527 printk(KERN_ERR "p54usb: firmware buffer alloc failed!\n");
528 return -ENOMEM;
529 }
530
531 err = request_firmware(&fw_entry, "isl3890usb", &priv->udev->dev);
532 if (err) {
533 printk(KERN_ERR "p54usb: cannot find firmware (isl3890usb)!\n");
534 kfree(buf);
535 return err;
536 }
537
538 p54_parse_firmware(dev, fw_entry);
539
540#define P54U_WRITE(type, addr, data) \
541 do {\
542 err = p54u_write(priv, buf, type,\
543 cpu_to_le32((u32)(unsigned long)addr), data);\
544 if (err) \
545 goto fail;\
546 } while (0)
547
548#define P54U_READ(type, addr) \
549 do {\
550 err = p54u_read(priv, buf, type,\
551 cpu_to_le32((u32)(unsigned long)addr), &reg);\
552 if (err)\
553 goto fail;\
554 } while (0)
555
556 /* power down net2280 bridge */
557 P54U_READ(NET2280_BRG_U32, NET2280_GPIOCTL);
558 reg |= cpu_to_le32(P54U_BRG_POWER_DOWN);
559 reg &= cpu_to_le32(~P54U_BRG_POWER_UP);
560 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
561
562 mdelay(100);
563
564 /* power up bridge */
565 reg |= cpu_to_le32(P54U_BRG_POWER_UP);
566 reg &= cpu_to_le32(~P54U_BRG_POWER_DOWN);
567 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
568
569 mdelay(100);
570
571 P54U_WRITE(NET2280_BRG_U32, NET2280_DEVINIT,
572 cpu_to_le32(NET2280_CLK_30Mhz |
573 NET2280_PCI_ENABLE |
574 NET2280_PCI_SOFT_RESET));
575
576 mdelay(20);
577
578 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_COMMAND,
579 cpu_to_le32(PCI_COMMAND_MEMORY |
580 PCI_COMMAND_MASTER));
581
582 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_0,
583 cpu_to_le32(NET2280_BASE));
584
585 P54U_READ(NET2280_BRG_CFG_U16, PCI_STATUS);
586 reg |= cpu_to_le32(PCI_STATUS_REC_MASTER_ABORT);
587 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_STATUS, reg);
588
589 // TODO: we really need this?
590 P54U_READ(NET2280_BRG_U32, NET2280_RELNUM);
591
592 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_RSP,
593 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
594 P54U_WRITE(NET2280_BRG_U32, NET2280_EPC_RSP,
595 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
596
597 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_2,
598 cpu_to_le32(NET2280_BASE2));
599
600 /* finally done setting up the bridge */
601
602 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | PCI_COMMAND,
603 cpu_to_le32(PCI_COMMAND_MEMORY |
604 PCI_COMMAND_MASTER));
605
606 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | 0x40 /* TRDY timeout */, 0);
607 P54U_WRITE(NET2280_DEV_CFG_U32, 0x10000 | PCI_BASE_ADDRESS_0,
608 cpu_to_le32(P54U_DEV_BASE));
609
610 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
611 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
612 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
613
614 /* do romboot */
615 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable, 0);
616
617 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
618 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
619 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);
620 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
621 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
622
623 mdelay(20);
624
625 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
626 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
627
628 mdelay(20);
629
630 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
631 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
632
633 mdelay(100);
634
635 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
636 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
637
638 /* finally, we can upload firmware now! */
639 remains = fw_entry->size;
640 data = fw_entry->data;
641 offset = ISL38XX_DEV_FIRMWARE_ADDR;
642
643 while (remains) {
644 unsigned int block_len = min(remains, (unsigned int)512);
645 memcpy(buf, data, block_len);
646
647 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_len);
648 if (err) {
649 printk(KERN_ERR "prism54usb: firmware block upload "
650 "failed\n");
651 goto fail;
652 }
653
654 P54U_WRITE(NET2280_DEV_U32, &devreg->direct_mem_base,
655 cpu_to_le32(0xc0000f00));
656
657 P54U_WRITE(NET2280_DEV_U32,
658 0x0020 | (unsigned long)&devreg->direct_mem_win, 0);
659 P54U_WRITE(NET2280_DEV_U32,
660 0x0020 | (unsigned long)&devreg->direct_mem_win,
661 cpu_to_le32(1));
662
663 P54U_WRITE(NET2280_DEV_U32,
664 0x0024 | (unsigned long)&devreg->direct_mem_win,
665 cpu_to_le32(block_len));
666 P54U_WRITE(NET2280_DEV_U32,
667 0x0028 | (unsigned long)&devreg->direct_mem_win,
668 cpu_to_le32(offset));
669
670 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_addr,
671 cpu_to_le32(NET2280_EPA_FIFO_PCI_ADDR));
672 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_len,
673 cpu_to_le32(block_len >> 2));
674 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_ctrl,
675 cpu_to_le32(ISL38XX_DMA_MASTER_CONTROL_TRIGGER));
676
677 mdelay(10);
678
679 P54U_READ(NET2280_DEV_U32,
680 0x002C | (unsigned long)&devreg->direct_mem_win);
681 if (!(reg & cpu_to_le32(ISL38XX_DMA_STATUS_DONE)) ||
682 !(reg & cpu_to_le32(ISL38XX_DMA_STATUS_READY))) {
683 printk(KERN_ERR "prism54usb: firmware DMA transfer "
684 "failed\n");
685 goto fail;
686 }
687
688 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_STAT,
689 cpu_to_le32(NET2280_FIFO_FLUSH));
690
691 remains -= block_len;
692 data += block_len;
693 offset += block_len;
694 }
695
696 /* do ramboot */
697 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
698 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
699 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
700 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);
701 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
702
703 mdelay(20);
704
705 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
706 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
707
708 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
709 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
710
711 mdelay(100);
712
713 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
714 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
715
716 /* start up the firmware */
717 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable,
718 cpu_to_le32(ISL38XX_INT_IDENT_INIT));
719
720 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
721 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
722
723 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1,
724 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT_ENABLE |
725 NET2280_USB_INTERRUPT_ENABLE));
726
727 P54U_WRITE(NET2280_DEV_U32, &devreg->dev_int,
728 cpu_to_le32(ISL38XX_DEV_INT_RESET));
729
730 err = usb_interrupt_msg(priv->udev,
731 usb_rcvbulkpipe(priv->udev, P54U_PIPE_INT),
732 buf, sizeof(__le32), &alen, 1000);
733 if (err || alen != sizeof(__le32))
734 goto fail;
735
736 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
737 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
738
739 if (!(reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)))
740 err = -EINVAL;
741
742 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
743 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
744 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
745
746#undef P54U_WRITE
747#undef P54U_READ
748
749 fail:
750 release_firmware(fw_entry);
751 kfree(buf);
752 return err;
753}
754
755static int p54u_open(struct ieee80211_hw *dev)
756{
757 struct p54u_priv *priv = dev->priv;
758 int err;
759
760 err = p54u_init_urbs(dev);
761 if (err) {
762 return err;
763 }
764
765 priv->common.open = p54u_init_urbs;
766
767 return 0;
768}
769
770static void p54u_stop(struct ieee80211_hw *dev)
771{
772 /* TODO: figure out how to reliably stop the 3887 and net2280 so
773 the hardware is still usable next time we want to start it.
774 until then, we just stop listening to the hardware.. */
775 p54u_free_urbs(dev);
776 return;
777}
778
779static int __devinit p54u_probe(struct usb_interface *intf,
780 const struct usb_device_id *id)
781{
782 struct usb_device *udev = interface_to_usbdev(intf);
783 struct ieee80211_hw *dev;
784 struct p54u_priv *priv;
785 int err;
786 unsigned int i, recognized_pipes;
787 DECLARE_MAC_BUF(mac);
788
789 dev = p54_init_common(sizeof(*priv));
790 if (!dev) {
791 printk(KERN_ERR "prism54usb: ieee80211 alloc failed\n");
792 return -ENOMEM;
793 }
794
795 priv = dev->priv;
796
797 SET_IEEE80211_DEV(dev, &intf->dev);
798 usb_set_intfdata(intf, dev);
799 priv->udev = udev;
800
801 usb_get_dev(udev);
802
803 /* really lazy and simple way of figuring out if we're a 3887 */
804 /* TODO: should just stick the identification in the device table */
805 i = intf->altsetting->desc.bNumEndpoints;
806 recognized_pipes = 0;
807 while (i--) {
808 switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) {
809 case P54U_PIPE_DATA:
810 case P54U_PIPE_MGMT:
811 case P54U_PIPE_BRG:
812 case P54U_PIPE_DEV:
813 case P54U_PIPE_DATA | USB_DIR_IN:
814 case P54U_PIPE_MGMT | USB_DIR_IN:
815 case P54U_PIPE_BRG | USB_DIR_IN:
816 case P54U_PIPE_DEV | USB_DIR_IN:
817 case P54U_PIPE_INT | USB_DIR_IN:
818 recognized_pipes++;
819 }
820 }
821 priv->common.open = p54u_open;
822
823 if (recognized_pipes < P54U_PIPE_NUMBER) {
824 priv->hw_type = P54U_3887;
825 priv->common.tx = p54u_tx_3887;
826 } else {
827 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
828 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
829 priv->common.tx = p54u_tx_net2280;
830 }
831 priv->common.stop = p54u_stop;
832
833 if (priv->hw_type)
834 err = p54u_upload_firmware_3887(dev);
835 else
836 err = p54u_upload_firmware_net2280(dev);
837 if (err)
838 goto err_free_dev;
839
840 err = p54u_read_eeprom(dev);
841 if (err)
842 goto err_free_dev;
843
844 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
845 u8 perm_addr[ETH_ALEN];
846
847 printk(KERN_WARNING "prism54usb: Invalid hwaddr! Using randomly generated MAC addr\n");
848 random_ether_addr(perm_addr);
849 SET_IEEE80211_PERM_ADDR(dev, perm_addr);
850 }
851
852 skb_queue_head_init(&priv->rx_queue);
853
854 err = ieee80211_register_hw(dev);
855 if (err) {
856 printk(KERN_ERR "prism54usb: Cannot register netdevice\n");
857 goto err_free_dev;
858 }
859
860 printk(KERN_INFO "%s: hwaddr %s, isl38%02x\n",
861 wiphy_name(dev->wiphy),
862 print_mac(mac, dev->wiphy->perm_addr),
863 priv->common.version);
864
865 return 0;
866
867 err_free_dev:
868 ieee80211_free_hw(dev);
869 usb_set_intfdata(intf, NULL);
870 usb_put_dev(udev);
871 return err;
872}
873
874static void __devexit p54u_disconnect(struct usb_interface *intf)
875{
876 struct ieee80211_hw *dev = usb_get_intfdata(intf);
877 struct p54u_priv *priv;
878
879 if (!dev)
880 return;
881
882 ieee80211_unregister_hw(dev);
883
884 priv = dev->priv;
885 usb_put_dev(interface_to_usbdev(intf));
886 p54_free_common(dev);
887 ieee80211_free_hw(dev);
888}
889
890static struct usb_driver p54u_driver = {
891 .name = "prism54usb",
892 .id_table = p54u_table,
893 .probe = p54u_probe,
894 .disconnect = p54u_disconnect,
895};
896
897static int __init p54u_init(void)
898{
899 return usb_register(&p54u_driver);
900}
901
902static void __exit p54u_exit(void)
903{
904 usb_deregister(&p54u_driver);
905}
906
907module_init(p54u_init);
908module_exit(p54u_exit);