fix typo from last sysupgrade commit
[openwrt.git] / package / p54 / src / p54usb.c
1
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
27 MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
28 MODULE_DESCRIPTION("Prism54 USB wireless driver");
29 MODULE_LICENSE("GPL");
30 MODULE_ALIAS("prism54usb");
31
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 */
49
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 */
70 {}
71 };
72
73 MODULE_DEVICE_TABLE(usb, p54u_table);
74
75 static void p54u_rx_cb(struct urb *urb)
76 {
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;
81
82 if (unlikely(urb->status)) {
83 info->urb = NULL;
84 usb_free_urb(urb);
85 return;
86 }
87
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));
92
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;
99 }
100
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);
110 }
111
112 usb_submit_urb(urb, GFP_ATOMIC);
113 }
114
115 static void p54u_tx_cb(struct urb *urb)
116 {
117 usb_free_urb(urb);
118 }
119
120 static void p54u_tx_free_cb(struct urb *urb)
121 {
122 kfree(urb->transfer_buffer);
123 usb_free_urb(urb);
124 }
125
126 static int p54u_init_urbs(struct ieee80211_hw *dev)
127 {
128 struct p54u_priv *priv = dev->priv;
129 struct urb *entry;
130 struct sk_buff *skb;
131 struct p54u_rx_info *info;
132
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;
141 }
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);
148 }
149
150 return 0;
151 }
152
153 static void p54u_free_urbs(struct ieee80211_hw *dev)
154 {
155 struct p54u_priv *priv = dev->priv;
156 struct p54u_rx_info *info;
157 struct sk_buff *skb;
158
159 while ((skb = skb_dequeue(&priv->rx_queue))) {
160 info = (struct p54u_rx_info *) skb->cb;
161 if (!info->urb)
162 continue;
163
164 usb_kill_urb(info->urb);
165 kfree_skb(skb);
166 }
167 }
168
169 static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data,
170 size_t len, int free_on_tx)
171 {
172 struct p54u_priv *priv = dev->priv;
173 struct urb *addr_urb, *data_urb;
174
175 addr_urb = usb_alloc_urb(0, GFP_ATOMIC);
176 if (!addr_urb)
177 return;
178
179 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
180 if (!data_urb) {
181 usb_free_urb(addr_urb);
182 return;
183 }
184
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);
191
192 usb_submit_urb(addr_urb, GFP_ATOMIC);
193 usb_submit_urb(data_urb, GFP_ATOMIC);
194 }
195
196 static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data,
197 size_t len, int free_on_tx)
198 {
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;
203
204 reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
205 if (!reg)
206 return;
207
208 int_urb = usb_alloc_urb(0, GFP_ATOMIC);
209 if (!int_urb) {
210 kfree(reg);
211 return;
212 }
213
214 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
215 if (!data_urb) {
216 kfree(reg);
217 usb_free_urb(int_urb);
218 return;
219 }
220
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);
224
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);
230
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);
235
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);
240 }
241
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)
246 {
247 unsigned int ep;
248 int alen;
249
250 if (type & 0x0800)
251 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV);
252 else
253 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_BRG);
254
255 buf->port = cpu_to_le16(type);
256 buf->addr = addr;
257 buf->val = val;
258
259 return usb_bulk_msg(priv->udev, ep, buf, sizeof(*buf), &alen, 1000);
260 }
261
262 static int p54u_read(struct p54u_priv *priv, void *buf,
263 enum net2280_op_type type,
264 __le32 addr, __le32 *val)
265 {
266 struct net2280_reg_read *read = buf;
267 __le32 *reg = buf;
268 unsigned int ep;
269 int alen, err;
270
271 if (type & 0x0800)
272 ep = P54U_PIPE_DEV;
273 else
274 ep = P54U_PIPE_BRG;
275
276 read->port = cpu_to_le16(type);
277 read->addr = addr;
278
279 err = usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
280 read, sizeof(*read), &alen, 1000);
281 if (err)
282 return err;
283
284 err = usb_bulk_msg(priv->udev, usb_rcvbulkpipe(priv->udev, ep),
285 reg, sizeof(*reg), &alen, 1000);
286 if (err)
287 return err;
288
289 *val = *reg;
290 return 0;
291 }
292
293 static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
294 void *data, size_t len)
295 {
296 int alen;
297 return usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
298 data, len, &alen, 2000);
299 }
300
301 static int p54u_read_eeprom(struct ieee80211_hw *dev)
302 {
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;
308
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;
314 }
315
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;
322 }
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;
332 }
333 }
334
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);
342 }
343
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;
350 }
351
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;
361 }
362
363 fail:
364 kfree(buf);
365 return err;
366 }
367
368 static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
369 {
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;
379
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;
385 }
386
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;
392 }
393
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;
398 }
399
400 p54_parse_firmware(dev, fw_entry);
401
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);
406
407 data = fw_entry->data;
408 remains = fw_entry->size;
409
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);
418
419 while (remains) {
420 while (left--) {
421 if (carry) {
422 *tmp++ = carry;
423 carry = 0;
424 remains--;
425 continue;
426 }
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;
440 }
441 data++;
442 }
443
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;
448 }
449
450 tmp = buf;
451 left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
452 }
453
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;
459 }
460
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;
466
467 if (alen > 5 && !memcmp(buf, "ERROR", 5)) {
468 printk(KERN_INFO "prism54usb: firmware upload failed!\n");
469 err = -EINVAL;
470 break;
471 }
472
473 if (time_after(jiffies, timeout)) {
474 printk(KERN_ERR "prism54usb: firmware boot timed out!\n");
475 err = -ETIMEDOUT;
476 break;
477 }
478 }
479 if (err)
480 goto err_upload_failed;
481
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;
488 }
489
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;
495
496 if (time_after(jiffies, timeout)) {
497 err = -ETIMEDOUT;
498 break;
499 }
500 }
501 if (err)
502 goto err_upload_failed;
503
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;
511 }
512
513 static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
514 {
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;
523
524 buf = kmalloc(512, GFP_KERNEL);
525 if (!buf) {
526 printk(KERN_ERR "p54usb: firmware buffer alloc failed!\n");
527 return -ENOMEM;
528 }
529
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;
535 }
536
537 p54_parse_firmware(dev, fw_entry);
538
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)
546
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)
554
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);
560
561 mdelay(100);
562
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);
567
568 mdelay(100);
569
570 P54U_WRITE(NET2280_BRG_U32, NET2280_DEVINIT,
571 cpu_to_le32(NET2280_CLK_30Mhz |
572 NET2280_PCI_ENABLE |
573 NET2280_PCI_SOFT_RESET));
574
575 mdelay(20);
576
577 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_COMMAND,
578 cpu_to_le32(PCI_COMMAND_MEMORY |
579 PCI_COMMAND_MASTER));
580
581 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_0,
582 cpu_to_le32(NET2280_BASE));
583
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);
587
588 // TODO: we really need this?
589 P54U_READ(NET2280_BRG_U32, NET2280_RELNUM);
590
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));
595
596 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_2,
597 cpu_to_le32(NET2280_BASE2));
598
599 /* finally done setting up the bridge */
600
601 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | PCI_COMMAND,
602 cpu_to_le32(PCI_COMMAND_MEMORY |
603 PCI_COMMAND_MASTER));
604
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));
608
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));
612
613 /* do romboot */
614 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable, 0);
615
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);
621
622 mdelay(20);
623
624 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
625 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
626
627 mdelay(20);
628
629 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
630 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
631
632 mdelay(100);
633
634 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
635 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
636
637 /* finally, we can upload firmware now! */
638 remains = fw_entry->size;
639 data = fw_entry->data;
640 offset = ISL38XX_DEV_FIRMWARE_ADDR;
641
642 while (remains) {
643 unsigned int block_len = min(remains, (unsigned int)512);
644 memcpy(buf, data, block_len);
645
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;
651 }
652
653 P54U_WRITE(NET2280_DEV_U32, &devreg->direct_mem_base,
654 cpu_to_le32(0xc0000f00));
655
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));
661
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));
668
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));
675
676 mdelay(10);
677
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;
685 }
686
687 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_STAT,
688 cpu_to_le32(NET2280_FIFO_FLUSH));
689
690 remains -= block_len;
691 data += block_len;
692 offset += block_len;
693 }
694
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);
701
702 mdelay(20);
703
704 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
705 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
706
707 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
708 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
709
710 mdelay(100);
711
712 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
713 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
714
715 /* start up the firmware */
716 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable,
717 cpu_to_le32(ISL38XX_INT_IDENT_INIT));
718
719 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
720 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
721
722 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1,
723 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT_ENABLE |
724 NET2280_USB_INTERRUPT_ENABLE));
725
726 P54U_WRITE(NET2280_DEV_U32, &devreg->dev_int,
727 cpu_to_le32(ISL38XX_DEV_INT_RESET));
728
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;
734
735 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
736 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
737
738 if (!(reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)))
739 err = -EINVAL;
740
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));
744
745 #undef P54U_WRITE
746 #undef P54U_READ
747
748 fail:
749 release_firmware(fw_entry);
750 kfree(buf);
751 return err;
752 }
753
754 static int p54u_open(struct ieee80211_hw *dev)
755 {
756 struct p54u_priv *priv = dev->priv;
757 int err;
758
759 err = p54u_init_urbs(dev);
760 if (err) {
761 return err;
762 }
763
764 priv->common.open = p54u_init_urbs;
765
766 return 0;
767 }
768
769 static void p54u_stop(struct ieee80211_hw *dev)
770 {
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;
776 }
777
778 static int __devinit p54u_probe(struct usb_interface *intf,
779 const struct usb_device_id *id)
780 {
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
787 dev = p54_init_common(sizeof(*priv));
788 if (!dev) {
789 printk(KERN_ERR "prism54usb: ieee80211 alloc failed\n");
790 return -ENOMEM;
791 }
792
793 priv = dev->priv;
794
795 SET_IEEE80211_DEV(dev, &intf->dev);
796 usb_set_intfdata(intf, dev);
797 priv->udev = udev;
798
799 usb_get_dev(udev);
800
801 /* really lazy and simple way of figuring out if we're a 3887 */
802 /* TODO: should just stick the identification in the device table */
803 i = intf->altsetting->desc.bNumEndpoints;
804 recognized_pipes = 0;
805 while (i--) {
806 switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) {
807 case P54U_PIPE_DATA:
808 case P54U_PIPE_MGMT:
809 case P54U_PIPE_BRG:
810 case P54U_PIPE_DEV:
811 case P54U_PIPE_DATA | USB_DIR_IN:
812 case P54U_PIPE_MGMT | USB_DIR_IN:
813 case P54U_PIPE_BRG | USB_DIR_IN:
814 case P54U_PIPE_DEV | USB_DIR_IN:
815 case P54U_PIPE_INT | USB_DIR_IN:
816 recognized_pipes++;
817 }
818 }
819 priv->common.open = p54u_open;
820
821 if (recognized_pipes < P54U_PIPE_NUMBER) {
822 priv->hw_type = P54U_3887;
823 priv->common.tx = p54u_tx_3887;
824 } else {
825 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
826 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
827 priv->common.tx = p54u_tx_net2280;
828 }
829 priv->common.stop = p54u_stop;
830
831 if (priv->hw_type)
832 err = p54u_upload_firmware_3887(dev);
833 else
834 err = p54u_upload_firmware_net2280(dev);
835 if (err)
836 goto err_free_dev;
837
838 err = p54u_read_eeprom(dev);
839 if (err)
840 goto err_free_dev;
841
842 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
843 u8 perm_addr[ETH_ALEN];
844
845 printk(KERN_WARNING "prism54usb: Invalid hwaddr! Using randomly generated MAC addr\n");
846 random_ether_addr(perm_addr);
847 SET_IEEE80211_PERM_ADDR(dev, perm_addr);
848 }
849
850 skb_queue_head_init(&priv->rx_queue);
851
852 err = ieee80211_register_hw(dev);
853 if (err) {
854 printk(KERN_ERR "prism54usb: Cannot register netdevice\n");
855 goto err_free_dev;
856 }
857
858 printk(KERN_INFO "%s: hwaddr " MAC_FMT ", isl38%02x\n",
859 wiphy_name(dev->wiphy), MAC_ARG(dev->wiphy->perm_addr),
860 priv->common.version);
861
862 return 0;
863
864 err_free_dev:
865 ieee80211_free_hw(dev);
866 usb_set_intfdata(intf, NULL);
867 usb_put_dev(udev);
868 return err;
869 }
870
871 static void __devexit p54u_disconnect(struct usb_interface *intf)
872 {
873 struct ieee80211_hw *dev = usb_get_intfdata(intf);
874 struct p54u_priv *priv;
875
876 if (!dev)
877 return;
878
879 ieee80211_unregister_hw(dev);
880
881 priv = dev->priv;
882 usb_put_dev(interface_to_usbdev(intf));
883 p54_free_common(dev);
884 ieee80211_free_hw(dev);
885 }
886
887 static struct usb_driver p54u_driver = {
888 .name = "prism54usb",
889 .id_table = p54u_table,
890 .probe = p54u_probe,
891 .disconnect = p54u_disconnect,
892 };
893
894 static int __init p54u_init(void)
895 {
896 return usb_register(&p54u_driver);
897 }
898
899 static void __exit p54u_exit(void)
900 {
901 usb_deregister(&p54u_driver);
902 }
903
904 module_init(p54u_init);
905 module_exit(p54u_exit);
This page took 0.090805 seconds and 5 git commands to generate.