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