p54: more cryptographic accelerator fixes
[linux-2.6-block.git] / drivers / net / wireless / p54 / p54usb.c
CommitLineData
eff1a59c
MW
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
27MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
28MODULE_DESCRIPTION("Prism54 USB wireless driver");
29MODULE_LICENSE("GPL");
30MODULE_ALIAS("prism54usb");
9a8675d7
CL
31MODULE_FIRMWARE("isl3886usb");
32MODULE_FIRMWARE("isl3887usb");
eff1a59c
MW
33
34static 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 */
1a17582e 40 {USB_DEVICE(0x083a, 0x5501)}, /* Phillips CPWUA054 */
eff1a59c
MW
41 {USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */
42 {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */
43 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
ec366eba 44 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
eff1a59c
MW
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 */
53
54 /* Version 2 devices (3887) */
4546002c 55 {USB_DEVICE(0x0471, 0x1230)}, /* Philips CPWUA054/00 */
eff1a59c
MW
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 */
878e6a43 59 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
eff1a59c
MW
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 */
43557e15 70 {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */
ec366eba 71 {USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */
387e100a 72 {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */
c1098103 73 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
eff1a59c
MW
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 */
78 {}
79};
80
81MODULE_DEVICE_TABLE(usb, p54u_table);
82
83static void p54u_rx_cb(struct urb *urb)
84{
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;
89
dd397dc9
CL
90 skb_unlink(skb, &priv->rx_queue);
91
eff1a59c 92 if (unlikely(urb->status)) {
dd397dc9 93 dev_kfree_skb_irq(skb);
eff1a59c
MW
94 return;
95 }
96
eff1a59c 97 skb_put(skb, urb->actual_length);
2b80848e
CL
98
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);
104 }
eff1a59c
MW
105
106 if (p54_rx(dev, skb)) {
4e416a6f 107 skb = dev_alloc_skb(priv->common.rx_mtu + 32);
eff1a59c 108 if (unlikely(!skb)) {
eff1a59c
MW
109 /* TODO check rx queue length and refill *somewhere* */
110 return;
111 }
112
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;
eff1a59c 118 } else {
2b80848e
CL
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);
124 }
d47c3ceb 125 skb_reset_tail_pointer(skb);
eff1a59c 126 skb_trim(skb, 0);
d47c3ceb
CL
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);
131 }
eff1a59c 132 }
dd397dc9
CL
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);
139 }
eff1a59c
MW
140}
141
0a5ec96a 142static void p54u_tx_cb(struct urb *urb)
b92f30d6
CL
143{
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));
0a5ec96a 147 struct p54u_priv *priv = dev->priv;
b92f30d6 148
0a5ec96a
CL
149 skb_pull(skb, priv->common.tx_hdr_len);
150 if (FREE_AFTER_TX(skb))
151 p54_free_skb(dev, skb);
dd397dc9
CL
152}
153
154static void p54u_tx_dummy_cb(struct urb *urb) { }
155
156static void p54u_free_urbs(struct ieee80211_hw *dev)
157{
158 struct p54u_priv *priv = dev->priv;
159 usb_kill_anchored_urbs(&priv->submitted);
b92f30d6
CL
160}
161
eff1a59c
MW
162static int p54u_init_urbs(struct ieee80211_hw *dev)
163{
164 struct p54u_priv *priv = dev->priv;
dd397dc9 165 struct urb *entry = NULL;
eff1a59c
MW
166 struct sk_buff *skb;
167 struct p54u_rx_info *info;
dd397dc9 168 int ret = 0;
eff1a59c
MW
169
170 while (skb_queue_len(&priv->rx_queue) < 32) {
4e416a6f 171 skb = __dev_alloc_skb(priv->common.rx_mtu + 32, GFP_KERNEL);
dd397dc9
CL
172 if (!skb) {
173 ret = -ENOMEM;
174 goto err;
175 }
eff1a59c
MW
176 entry = usb_alloc_urb(0, GFP_KERNEL);
177 if (!entry) {
dd397dc9
CL
178 ret = -ENOMEM;
179 goto err;
eff1a59c 180 }
dd397dc9 181
4e416a6f
CL
182 usb_fill_bulk_urb(entry, priv->udev,
183 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
184 skb_tail_pointer(skb),
185 priv->common.rx_mtu + 32, p54u_rx_cb, skb);
eff1a59c
MW
186 info = (struct p54u_rx_info *) skb->cb;
187 info->urb = entry;
188 info->dev = dev;
189 skb_queue_tail(&priv->rx_queue, skb);
dd397dc9
CL
190
191 usb_anchor_urb(entry, &priv->submitted);
192 ret = usb_submit_urb(entry, GFP_KERNEL);
193 if (ret) {
194 skb_unlink(skb, &priv->rx_queue);
195 usb_unanchor_urb(entry);
196 goto err;
197 }
198 usb_free_urb(entry);
199 entry = NULL;
eff1a59c
MW
200 }
201
202 return 0;
eff1a59c 203
dd397dc9
CL
204 err:
205 usb_free_urb(entry);
206 kfree_skb(skb);
207 p54u_free_urbs(dev);
208 return ret;
eff1a59c
MW
209}
210
0a5ec96a 211static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb)
eff1a59c
MW
212{
213 struct p54u_priv *priv = dev->priv;
214 struct urb *addr_urb, *data_urb;
dd397dc9 215 int err = 0;
eff1a59c
MW
216
217 addr_urb = usb_alloc_urb(0, GFP_ATOMIC);
218 if (!addr_urb)
219 return;
220
221 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
222 if (!data_urb) {
223 usb_free_urb(addr_urb);
224 return;
225 }
226
227 usb_fill_bulk_urb(addr_urb, priv->udev,
b92f30d6 228 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
27df605e 229 &((struct p54_hdr *)skb->data)->req_id, 4,
dd397dc9 230 p54u_tx_dummy_cb, dev);
eff1a59c 231 usb_fill_bulk_urb(data_urb, priv->udev,
b92f30d6 232 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
0a5ec96a 233 skb->data, skb->len, p54u_tx_cb, skb);
eff1a59c 234
dd397dc9
CL
235 usb_anchor_urb(addr_urb, &priv->submitted);
236 err = usb_submit_urb(addr_urb, GFP_ATOMIC);
237 if (err) {
238 usb_unanchor_urb(addr_urb);
239 goto out;
240 }
241
242 usb_anchor_urb(addr_urb, &priv->submitted);
243 err = usb_submit_urb(data_urb, GFP_ATOMIC);
244 if (err)
245 usb_unanchor_urb(data_urb);
246
247 out:
248 usb_free_urb(addr_urb);
249 usb_free_urb(data_urb);
250
251 if (err)
252 p54_free_skb(dev, skb);
eff1a59c
MW
253}
254
c9127659 255static __le32 p54u_lm87_chksum(const __le32 *data, size_t length)
2b80848e 256{
1f1c0e33 257 u32 chk = 0;
2b80848e
CL
258
259 length >>= 2;
260 while (length--) {
c9127659 261 chk ^= le32_to_cpu(*data++);
2b80848e
CL
262 chk = (chk >> 5) ^ (chk << 3);
263 }
264
1f1c0e33 265 return cpu_to_le32(chk);
2b80848e
CL
266}
267
0a5ec96a 268static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb)
2b80848e
CL
269{
270 struct p54u_priv *priv = dev->priv;
271 struct urb *data_urb;
b92f30d6
CL
272 struct lm87_tx_hdr *hdr;
273 __le32 checksum;
27df605e 274 __le32 addr = ((struct p54_hdr *)skb->data)->req_id;
2b80848e
CL
275
276 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
277 if (!data_urb)
278 return;
279
c9127659 280 checksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);
b92f30d6
CL
281 hdr = (struct lm87_tx_hdr *)skb_push(skb, sizeof(*hdr));
282 hdr->chksum = checksum;
283 hdr->device_addr = addr;
2b80848e
CL
284
285 usb_fill_bulk_urb(data_urb, priv->udev,
b92f30d6 286 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
0a5ec96a 287 skb->data, skb->len, p54u_tx_cb, skb);
00627f22 288 data_urb->transfer_flags |= URB_ZERO_PACKET;
2b80848e 289
dd397dc9
CL
290 usb_anchor_urb(data_urb, &priv->submitted);
291 if (usb_submit_urb(data_urb, GFP_ATOMIC)) {
292 usb_unanchor_urb(data_urb);
293 skb_pull(skb, sizeof(*hdr));
294 p54_free_skb(dev, skb);
295 }
296 usb_free_urb(data_urb);
2b80848e
CL
297}
298
0a5ec96a 299static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
eff1a59c
MW
300{
301 struct p54u_priv *priv = dev->priv;
302 struct urb *int_urb, *data_urb;
303 struct net2280_tx_hdr *hdr;
304 struct net2280_reg_write *reg;
dd397dc9 305 int err = 0;
6110781a
CL
306 __le32 addr = ((struct p54_hdr *) skb->data)->req_id;
307 __le16 len = cpu_to_le16(skb->len);
eff1a59c
MW
308
309 reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
310 if (!reg)
311 return;
312
313 int_urb = usb_alloc_urb(0, GFP_ATOMIC);
314 if (!int_urb) {
315 kfree(reg);
316 return;
317 }
318
319 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
320 if (!data_urb) {
321 kfree(reg);
322 usb_free_urb(int_urb);
323 return;
324 }
325
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
b92f30d6 330 hdr = (void *)skb_push(skb, sizeof(*hdr));
eff1a59c 331 memset(hdr, 0, sizeof(*hdr));
6110781a
CL
332 hdr->len = len;
333 hdr->device_addr = addr;
eff1a59c
MW
334
335 usb_fill_bulk_urb(int_urb, priv->udev,
336 usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
dd397dc9
CL
337 p54u_tx_dummy_cb, dev);
338
339 /*
340 * This flag triggers a code path in the USB subsystem that will
341 * free what's inside the transfer_buffer after the callback routine
342 * has completed.
343 */
344 int_urb->transfer_flags |= URB_FREE_BUFFER;
eff1a59c
MW
345
346 usb_fill_bulk_urb(data_urb, priv->udev,
b92f30d6 347 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
0a5ec96a 348 skb->data, skb->len, p54u_tx_cb, skb);
dd397dc9
CL
349
350 usb_anchor_urb(int_urb, &priv->submitted);
351 err = usb_submit_urb(int_urb, GFP_ATOMIC);
352 if (err) {
353 usb_unanchor_urb(int_urb);
354 goto out;
355 }
356
357 usb_anchor_urb(data_urb, &priv->submitted);
358 err = usb_submit_urb(data_urb, GFP_ATOMIC);
359 if (err) {
360 usb_unanchor_urb(data_urb);
361 goto out;
362 }
363 out:
364 usb_free_urb(int_urb);
365 usb_free_urb(data_urb);
366
367 if (err) {
368 skb_pull(skb, sizeof(*hdr));
369 p54_free_skb(dev, skb);
370 }
eff1a59c
MW
371}
372
373static int p54u_write(struct p54u_priv *priv,
374 struct net2280_reg_write *buf,
375 enum net2280_op_type type,
376 __le32 addr, __le32 val)
377{
378 unsigned int ep;
379 int alen;
380
381 if (type & 0x0800)
382 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV);
383 else
384 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_BRG);
385
386 buf->port = cpu_to_le16(type);
387 buf->addr = addr;
388 buf->val = val;
389
390 return usb_bulk_msg(priv->udev, ep, buf, sizeof(*buf), &alen, 1000);
391}
392
393static int p54u_read(struct p54u_priv *priv, void *buf,
394 enum net2280_op_type type,
395 __le32 addr, __le32 *val)
396{
397 struct net2280_reg_read *read = buf;
398 __le32 *reg = buf;
399 unsigned int ep;
400 int alen, err;
401
402 if (type & 0x0800)
403 ep = P54U_PIPE_DEV;
404 else
405 ep = P54U_PIPE_BRG;
406
407 read->port = cpu_to_le16(type);
408 read->addr = addr;
409
410 err = usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
411 read, sizeof(*read), &alen, 1000);
412 if (err)
413 return err;
414
415 err = usb_bulk_msg(priv->udev, usb_rcvbulkpipe(priv->udev, ep),
416 reg, sizeof(*reg), &alen, 1000);
417 if (err)
418 return err;
419
420 *val = *reg;
421 return 0;
422}
423
424static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
425 void *data, size_t len)
426{
427 int alen;
428 return usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
429 data, len, &alen, 2000);
430}
431
eff1a59c
MW
432static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
433{
434 static char start_string[] = "~~~~<\r";
435 struct p54u_priv *priv = dev->priv;
436 const struct firmware *fw_entry = NULL;
437 int err, alen;
438 u8 carry = 0;
8b72eb43
DW
439 u8 *buf, *tmp;
440 const u8 *data;
eff1a59c
MW
441 unsigned int left, remains, block_size;
442 struct x2_header *hdr;
443 unsigned long timeout;
444
445 tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
446 if (!buf) {
02e37ba1
CL
447 dev_err(&priv->udev->dev, "(p54usb) cannot allocate firmware"
448 "upload buffer!\n");
eff1a59c
MW
449 err = -ENOMEM;
450 goto err_bufalloc;
451 }
452
453 memcpy(buf, start_string, 4);
454 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4);
455 if (err) {
02e37ba1 456 dev_err(&priv->udev->dev, "(p54usb) reset failed! (%d)\n", err);
eff1a59c
MW
457 goto err_reset;
458 }
459
9a8675d7 460 err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev);
eff1a59c 461 if (err) {
02e37ba1
CL
462 dev_err(&priv->udev->dev, "p54usb: cannot find firmware "
463 "(isl3887usb)\n");
9a8675d7
CL
464 err = request_firmware(&fw_entry, "isl3887usb_bare",
465 &priv->udev->dev);
466 if (err)
467 goto err_req_fw_failed;
eff1a59c
MW
468 }
469
4e416a6f
CL
470 err = p54_parse_firmware(dev, fw_entry);
471 if (err)
472 goto err_upload_failed;
eff1a59c
MW
473
474 left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
475 strcpy(buf, start_string);
476 left -= strlen(start_string);
477 tmp += strlen(start_string);
478
479 data = fw_entry->data;
480 remains = fw_entry->size;
481
482 hdr = (struct x2_header *)(buf + strlen(start_string));
483 memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
484 hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
485 hdr->fw_length = cpu_to_le32(fw_entry->size);
486 hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
487 sizeof(u32)*2));
488 left -= sizeof(*hdr);
489 tmp += sizeof(*hdr);
490
491 while (remains) {
492 while (left--) {
493 if (carry) {
494 *tmp++ = carry;
495 carry = 0;
496 remains--;
497 continue;
498 }
499 switch (*data) {
500 case '~':
501 *tmp++ = '}';
502 carry = '^';
503 break;
504 case '}':
505 *tmp++ = '}';
506 carry = ']';
507 break;
508 default:
509 *tmp++ = *data;
510 remains--;
511 break;
512 }
513 data++;
514 }
515
516 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size);
517 if (err) {
02e37ba1
CL
518 dev_err(&priv->udev->dev, "(p54usb) firmware "
519 "upload failed!\n");
eff1a59c
MW
520 goto err_upload_failed;
521 }
522
523 tmp = buf;
524 left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
525 }
526
527 *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size));
528 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
529 if (err) {
02e37ba1 530 dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n");
eff1a59c
MW
531 goto err_upload_failed;
532 }
eff1a59c
MW
533 timeout = jiffies + msecs_to_jiffies(1000);
534 while (!(err = usb_bulk_msg(priv->udev,
535 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
536 if (alen > 2 && !memcmp(buf, "OK", 2))
537 break;
538
539 if (alen > 5 && !memcmp(buf, "ERROR", 5)) {
eff1a59c
MW
540 err = -EINVAL;
541 break;
542 }
543
544 if (time_after(jiffies, timeout)) {
02e37ba1
CL
545 dev_err(&priv->udev->dev, "(p54usb) firmware boot "
546 "timed out!\n");
eff1a59c
MW
547 err = -ETIMEDOUT;
548 break;
549 }
550 }
02e37ba1
CL
551 if (err) {
552 dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n");
eff1a59c 553 goto err_upload_failed;
02e37ba1 554 }
eff1a59c
MW
555
556 buf[0] = 'g';
557 buf[1] = '\r';
558 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2);
559 if (err) {
02e37ba1 560 dev_err(&priv->udev->dev, "(p54usb) firmware boot failed!\n");
eff1a59c
MW
561 goto err_upload_failed;
562 }
563
564 timeout = jiffies + msecs_to_jiffies(1000);
565 while (!(err = usb_bulk_msg(priv->udev,
566 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
567 if (alen > 0 && buf[0] == 'g')
568 break;
569
570 if (time_after(jiffies, timeout)) {
571 err = -ETIMEDOUT;
572 break;
573 }
574 }
575 if (err)
576 goto err_upload_failed;
577
578 err_upload_failed:
579 release_firmware(fw_entry);
580 err_req_fw_failed:
581 err_reset:
582 kfree(buf);
583 err_bufalloc:
584 return err;
585}
586
587static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
588{
589 struct p54u_priv *priv = dev->priv;
590 const struct firmware *fw_entry = NULL;
591 const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;
592 int err, alen;
593 void *buf;
594 __le32 reg;
595 unsigned int remains, offset;
8b72eb43 596 const u8 *data;
eff1a59c
MW
597
598 buf = kmalloc(512, GFP_KERNEL);
599 if (!buf) {
02e37ba1
CL
600 dev_err(&priv->udev->dev, "(p54usb) firmware buffer "
601 "alloc failed!\n");
eff1a59c
MW
602 return -ENOMEM;
603 }
604
9a8675d7 605 err = request_firmware(&fw_entry, "isl3886usb", &priv->udev->dev);
eff1a59c 606 if (err) {
02e37ba1
CL
607 dev_err(&priv->udev->dev, "(p54usb) cannot find firmware "
608 "(isl3886usb)\n");
9a8675d7
CL
609 err = request_firmware(&fw_entry, "isl3890usb",
610 &priv->udev->dev);
611 if (err) {
612 kfree(buf);
613 return err;
614 }
eff1a59c
MW
615 }
616
4e416a6f
CL
617 err = p54_parse_firmware(dev, fw_entry);
618 if (err) {
619 kfree(buf);
620 release_firmware(fw_entry);
621 return err;
622 }
eff1a59c
MW
623
624#define P54U_WRITE(type, addr, data) \
625 do {\
626 err = p54u_write(priv, buf, type,\
627 cpu_to_le32((u32)(unsigned long)addr), data);\
628 if (err) \
629 goto fail;\
630 } while (0)
631
632#define P54U_READ(type, addr) \
633 do {\
634 err = p54u_read(priv, buf, type,\
635 cpu_to_le32((u32)(unsigned long)addr), &reg);\
636 if (err)\
637 goto fail;\
638 } while (0)
639
640 /* power down net2280 bridge */
641 P54U_READ(NET2280_BRG_U32, NET2280_GPIOCTL);
642 reg |= cpu_to_le32(P54U_BRG_POWER_DOWN);
643 reg &= cpu_to_le32(~P54U_BRG_POWER_UP);
644 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
645
646 mdelay(100);
647
648 /* power up bridge */
649 reg |= cpu_to_le32(P54U_BRG_POWER_UP);
650 reg &= cpu_to_le32(~P54U_BRG_POWER_DOWN);
651 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
652
653 mdelay(100);
654
655 P54U_WRITE(NET2280_BRG_U32, NET2280_DEVINIT,
656 cpu_to_le32(NET2280_CLK_30Mhz |
657 NET2280_PCI_ENABLE |
658 NET2280_PCI_SOFT_RESET));
659
660 mdelay(20);
661
662 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_COMMAND,
663 cpu_to_le32(PCI_COMMAND_MEMORY |
664 PCI_COMMAND_MASTER));
665
666 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_0,
667 cpu_to_le32(NET2280_BASE));
668
669 P54U_READ(NET2280_BRG_CFG_U16, PCI_STATUS);
670 reg |= cpu_to_le32(PCI_STATUS_REC_MASTER_ABORT);
671 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_STATUS, reg);
672
673 // TODO: we really need this?
674 P54U_READ(NET2280_BRG_U32, NET2280_RELNUM);
675
676 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_RSP,
677 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
678 P54U_WRITE(NET2280_BRG_U32, NET2280_EPC_RSP,
679 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
680
681 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_2,
682 cpu_to_le32(NET2280_BASE2));
683
684 /* finally done setting up the bridge */
685
686 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | PCI_COMMAND,
687 cpu_to_le32(PCI_COMMAND_MEMORY |
688 PCI_COMMAND_MASTER));
689
690 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | 0x40 /* TRDY timeout */, 0);
691 P54U_WRITE(NET2280_DEV_CFG_U32, 0x10000 | PCI_BASE_ADDRESS_0,
692 cpu_to_le32(P54U_DEV_BASE));
693
694 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
695 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
696 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
697
698 /* do romboot */
699 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable, 0);
700
701 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
702 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
703 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);
704 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
705 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
706
707 mdelay(20);
708
709 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
710 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
711
712 mdelay(20);
713
714 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
715 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
716
717 mdelay(100);
718
719 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
720 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
721
722 /* finally, we can upload firmware now! */
723 remains = fw_entry->size;
724 data = fw_entry->data;
725 offset = ISL38XX_DEV_FIRMWARE_ADDR;
726
727 while (remains) {
728 unsigned int block_len = min(remains, (unsigned int)512);
729 memcpy(buf, data, block_len);
730
731 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_len);
732 if (err) {
02e37ba1
CL
733 dev_err(&priv->udev->dev, "(p54usb) firmware block "
734 "upload failed\n");
eff1a59c
MW
735 goto fail;
736 }
737
738 P54U_WRITE(NET2280_DEV_U32, &devreg->direct_mem_base,
739 cpu_to_le32(0xc0000f00));
740
741 P54U_WRITE(NET2280_DEV_U32,
742 0x0020 | (unsigned long)&devreg->direct_mem_win, 0);
743 P54U_WRITE(NET2280_DEV_U32,
744 0x0020 | (unsigned long)&devreg->direct_mem_win,
745 cpu_to_le32(1));
746
747 P54U_WRITE(NET2280_DEV_U32,
748 0x0024 | (unsigned long)&devreg->direct_mem_win,
749 cpu_to_le32(block_len));
750 P54U_WRITE(NET2280_DEV_U32,
751 0x0028 | (unsigned long)&devreg->direct_mem_win,
752 cpu_to_le32(offset));
753
754 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_addr,
755 cpu_to_le32(NET2280_EPA_FIFO_PCI_ADDR));
756 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_len,
757 cpu_to_le32(block_len >> 2));
758 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_ctrl,
759 cpu_to_le32(ISL38XX_DMA_MASTER_CONTROL_TRIGGER));
760
761 mdelay(10);
762
763 P54U_READ(NET2280_DEV_U32,
764 0x002C | (unsigned long)&devreg->direct_mem_win);
765 if (!(reg & cpu_to_le32(ISL38XX_DMA_STATUS_DONE)) ||
766 !(reg & cpu_to_le32(ISL38XX_DMA_STATUS_READY))) {
02e37ba1
CL
767 dev_err(&priv->udev->dev, "(p54usb) firmware DMA "
768 "transfer failed\n");
eff1a59c
MW
769 goto fail;
770 }
771
772 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_STAT,
773 cpu_to_le32(NET2280_FIFO_FLUSH));
774
775 remains -= block_len;
776 data += block_len;
777 offset += block_len;
778 }
779
780 /* do ramboot */
781 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
782 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
783 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
784 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);
785 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
786
787 mdelay(20);
788
789 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
790 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
791
792 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
793 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
794
795 mdelay(100);
796
797 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
798 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
799
800 /* start up the firmware */
801 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable,
802 cpu_to_le32(ISL38XX_INT_IDENT_INIT));
803
804 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
805 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
806
807 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1,
808 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT_ENABLE |
809 NET2280_USB_INTERRUPT_ENABLE));
810
811 P54U_WRITE(NET2280_DEV_U32, &devreg->dev_int,
812 cpu_to_le32(ISL38XX_DEV_INT_RESET));
813
814 err = usb_interrupt_msg(priv->udev,
815 usb_rcvbulkpipe(priv->udev, P54U_PIPE_INT),
816 buf, sizeof(__le32), &alen, 1000);
817 if (err || alen != sizeof(__le32))
818 goto fail;
819
820 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
821 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
822
823 if (!(reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)))
824 err = -EINVAL;
825
826 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
827 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
828 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
829
830#undef P54U_WRITE
831#undef P54U_READ
832
833 fail:
834 release_firmware(fw_entry);
835 kfree(buf);
836 return err;
837}
838
839static int p54u_open(struct ieee80211_hw *dev)
840{
841 struct p54u_priv *priv = dev->priv;
842 int err;
843
844 err = p54u_init_urbs(dev);
845 if (err) {
846 return err;
847 }
848
849 priv->common.open = p54u_init_urbs;
850
851 return 0;
852}
853
854static void p54u_stop(struct ieee80211_hw *dev)
855{
856 /* TODO: figure out how to reliably stop the 3887 and net2280 so
857 the hardware is still usable next time we want to start it.
858 until then, we just stop listening to the hardware.. */
859 p54u_free_urbs(dev);
860 return;
861}
862
863static int __devinit p54u_probe(struct usb_interface *intf,
864 const struct usb_device_id *id)
865{
866 struct usb_device *udev = interface_to_usbdev(intf);
867 struct ieee80211_hw *dev;
868 struct p54u_priv *priv;
869 int err;
870 unsigned int i, recognized_pipes;
eff1a59c
MW
871
872 dev = p54_init_common(sizeof(*priv));
02e37ba1 873
eff1a59c 874 if (!dev) {
02e37ba1 875 dev_err(&udev->dev, "(p54usb) ieee80211 alloc failed\n");
eff1a59c
MW
876 return -ENOMEM;
877 }
878
879 priv = dev->priv;
880
881 SET_IEEE80211_DEV(dev, &intf->dev);
882 usb_set_intfdata(intf, dev);
883 priv->udev = udev;
884
885 usb_get_dev(udev);
886
887 /* really lazy and simple way of figuring out if we're a 3887 */
888 /* TODO: should just stick the identification in the device table */
889 i = intf->altsetting->desc.bNumEndpoints;
890 recognized_pipes = 0;
891 while (i--) {
892 switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) {
893 case P54U_PIPE_DATA:
894 case P54U_PIPE_MGMT:
895 case P54U_PIPE_BRG:
896 case P54U_PIPE_DEV:
897 case P54U_PIPE_DATA | USB_DIR_IN:
898 case P54U_PIPE_MGMT | USB_DIR_IN:
899 case P54U_PIPE_BRG | USB_DIR_IN:
900 case P54U_PIPE_DEV | USB_DIR_IN:
901 case P54U_PIPE_INT | USB_DIR_IN:
902 recognized_pipes++;
903 }
904 }
905 priv->common.open = p54u_open;
2b80848e 906 priv->common.stop = p54u_stop;
eff1a59c
MW
907 if (recognized_pipes < P54U_PIPE_NUMBER) {
908 priv->hw_type = P54U_3887;
2b80848e
CL
909 err = p54u_upload_firmware_3887(dev);
910 if (priv->common.fw_interface == FW_LM87) {
911 dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
912 priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr);
913 priv->common.tx = p54u_tx_lm87;
914 } else
915 priv->common.tx = p54u_tx_3887;
eff1a59c 916 } else {
2b80848e 917 priv->hw_type = P54U_NET2280;
eff1a59c
MW
918 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
919 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
920 priv->common.tx = p54u_tx_net2280;
eff1a59c 921 err = p54u_upload_firmware_net2280(dev);
2b80848e 922 }
eff1a59c
MW
923 if (err)
924 goto err_free_dev;
925
7cb77072 926 skb_queue_head_init(&priv->rx_queue);
dd397dc9 927 init_usb_anchor(&priv->submitted);
7cb77072
CL
928
929 p54u_open(dev);
930 err = p54_read_eeprom(dev);
931 p54u_stop(dev);
eff1a59c
MW
932 if (err)
933 goto err_free_dev;
934
eff1a59c
MW
935 err = ieee80211_register_hw(dev);
936 if (err) {
02e37ba1 937 dev_err(&udev->dev, "(p54usb) Cannot register netdevice\n");
eff1a59c
MW
938 goto err_free_dev;
939 }
940
eff1a59c
MW
941 return 0;
942
943 err_free_dev:
944 ieee80211_free_hw(dev);
945 usb_set_intfdata(intf, NULL);
946 usb_put_dev(udev);
947 return err;
948}
949
950static void __devexit p54u_disconnect(struct usb_interface *intf)
951{
952 struct ieee80211_hw *dev = usb_get_intfdata(intf);
953 struct p54u_priv *priv;
954
955 if (!dev)
956 return;
957
958 ieee80211_unregister_hw(dev);
959
960 priv = dev->priv;
961 usb_put_dev(interface_to_usbdev(intf));
962 p54_free_common(dev);
963 ieee80211_free_hw(dev);
964}
965
966static struct usb_driver p54u_driver = {
32ddf071 967 .name = "p54usb",
eff1a59c
MW
968 .id_table = p54u_table,
969 .probe = p54u_probe,
970 .disconnect = p54u_disconnect,
971};
972
973static int __init p54u_init(void)
974{
975 return usb_register(&p54u_driver);
976}
977
978static void __exit p54u_exit(void)
979{
980 usb_deregister(&p54u_driver);
981}
982
983module_init(p54u_init);
984module_exit(p54u_exit);