Add a pci-id to the mwl8k driver
[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"
d8c92107 25#include "lmac.h"
eff1a59c
MW
26#include "p54usb.h"
27
28MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
29MODULE_DESCRIPTION("Prism54 USB wireless driver");
30MODULE_LICENSE("GPL");
31MODULE_ALIAS("prism54usb");
9a8675d7
CL
32MODULE_FIRMWARE("isl3886usb");
33MODULE_FIRMWARE("isl3887usb");
eff1a59c
MW
34
35static struct usb_device_id p54u_table[] __devinitdata = {
36 /* Version 1 devices (pci chip + net2280) */
37 {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
38 {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
15a69a81 39 {USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */
eff1a59c
MW
40 {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */
41 {USB_DEVICE(0x083a, 0x4502)}, /* Siemens Gigaset USB Adapter */
1a17582e 42 {USB_DEVICE(0x083a, 0x5501)}, /* Phillips CPWUA054 */
eff1a59c
MW
43 {USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */
44 {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */
45 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
ec366eba 46 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
eff1a59c
MW
47 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
48 {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
49 {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */
50 {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */
51 {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */
52 {USB_DEVICE(0x2001, 0x3703)}, /* DLink DWL-G122 */
53 {USB_DEVICE(0x5041, 0x2234)}, /* Linksys WUSB54G */
54 {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */
55
56 /* Version 2 devices (3887) */
4546002c 57 {USB_DEVICE(0x0471, 0x1230)}, /* Philips CPWUA054/00 */
eff1a59c
MW
58 {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */
59 {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */
60 {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */
878e6a43 61 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
eff1a59c
MW
62 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
63 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
5b9a919a 64 {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */
eff1a59c
MW
65 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */
66 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */
67 {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */
68 {USB_DEVICE(0x0baf, 0x0118)}, /* U.S. Robotics U5 802.11g Adapter*/
69 {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/
70 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */
71 {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
f7f71173 72 {USB_DEVICE(0x0cde, 0x0015)}, /* Zcomax XG-705A */
eff1a59c 73 {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
43557e15 74 {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */
ec366eba 75 {USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */
387e100a 76 {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */
c1098103 77 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
e3062403 78 {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */
eff1a59c
MW
79 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
80 {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
81 {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */
82 {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */
83 {}
84};
85
86MODULE_DEVICE_TABLE(usb, p54u_table);
87
1ca5f2e9
CL
88static const struct {
89 u32 intf;
90 enum p54u_hw_type type;
328d84fb
SO
91 const char *fw;
92 const char *fw_legacy;
1ca5f2e9
CL
93 char hw[20];
94} p54u_fwlist[__NUM_P54U_HWTYPES] = {
95 {
96 .type = P54U_NET2280,
97 .intf = FW_LM86,
98 .fw = "isl3886usb",
99 .fw_legacy = "isl3890usb",
100 .hw = "ISL3886 + net2280",
101 },
102 {
103 .type = P54U_3887,
104 .intf = FW_LM87,
105 .fw = "isl3887usb",
106 .fw_legacy = "isl3887usb_bare",
107 .hw = "ISL3887",
108 },
109};
110
eff1a59c
MW
111static void p54u_rx_cb(struct urb *urb)
112{
113 struct sk_buff *skb = (struct sk_buff *) urb->context;
114 struct p54u_rx_info *info = (struct p54u_rx_info *)skb->cb;
115 struct ieee80211_hw *dev = info->dev;
116 struct p54u_priv *priv = dev->priv;
117
dd397dc9
CL
118 skb_unlink(skb, &priv->rx_queue);
119
eff1a59c 120 if (unlikely(urb->status)) {
dd397dc9 121 dev_kfree_skb_irq(skb);
eff1a59c
MW
122 return;
123 }
124
eff1a59c 125 skb_put(skb, urb->actual_length);
2b80848e
CL
126
127 if (priv->hw_type == P54U_NET2280)
128 skb_pull(skb, priv->common.tx_hdr_len);
129 if (priv->common.fw_interface == FW_LM87) {
130 skb_pull(skb, 4);
131 skb_put(skb, 4);
132 }
eff1a59c
MW
133
134 if (p54_rx(dev, skb)) {
4e416a6f 135 skb = dev_alloc_skb(priv->common.rx_mtu + 32);
eff1a59c 136 if (unlikely(!skb)) {
eff1a59c
MW
137 /* TODO check rx queue length and refill *somewhere* */
138 return;
139 }
140
141 info = (struct p54u_rx_info *) skb->cb;
142 info->urb = urb;
143 info->dev = dev;
144 urb->transfer_buffer = skb_tail_pointer(skb);
145 urb->context = skb;
eff1a59c 146 } else {
2b80848e
CL
147 if (priv->hw_type == P54U_NET2280)
148 skb_push(skb, priv->common.tx_hdr_len);
149 if (priv->common.fw_interface == FW_LM87) {
150 skb_push(skb, 4);
151 skb_put(skb, 4);
152 }
d47c3ceb 153 skb_reset_tail_pointer(skb);
eff1a59c 154 skb_trim(skb, 0);
1ca5f2e9 155 urb->transfer_buffer = skb_tail_pointer(skb);
eff1a59c 156 }
dd397dc9
CL
157 skb_queue_tail(&priv->rx_queue, skb);
158 usb_anchor_urb(urb, &priv->submitted);
159 if (usb_submit_urb(urb, GFP_ATOMIC)) {
160 skb_unlink(skb, &priv->rx_queue);
161 usb_unanchor_urb(urb);
162 dev_kfree_skb_irq(skb);
163 }
eff1a59c
MW
164}
165
0a5ec96a 166static void p54u_tx_cb(struct urb *urb)
b92f30d6
CL
167{
168 struct sk_buff *skb = urb->context;
169 struct ieee80211_hw *dev = (struct ieee80211_hw *)
170 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
171
e2fe154e 172 p54_free_skb(dev, skb);
dd397dc9
CL
173}
174
175static void p54u_tx_dummy_cb(struct urb *urb) { }
176
177static void p54u_free_urbs(struct ieee80211_hw *dev)
178{
179 struct p54u_priv *priv = dev->priv;
180 usb_kill_anchored_urbs(&priv->submitted);
b92f30d6
CL
181}
182
eff1a59c
MW
183static int p54u_init_urbs(struct ieee80211_hw *dev)
184{
185 struct p54u_priv *priv = dev->priv;
dd397dc9 186 struct urb *entry = NULL;
eff1a59c
MW
187 struct sk_buff *skb;
188 struct p54u_rx_info *info;
dd397dc9 189 int ret = 0;
eff1a59c
MW
190
191 while (skb_queue_len(&priv->rx_queue) < 32) {
4e416a6f 192 skb = __dev_alloc_skb(priv->common.rx_mtu + 32, GFP_KERNEL);
dd397dc9
CL
193 if (!skb) {
194 ret = -ENOMEM;
195 goto err;
196 }
eff1a59c
MW
197 entry = usb_alloc_urb(0, GFP_KERNEL);
198 if (!entry) {
dd397dc9
CL
199 ret = -ENOMEM;
200 goto err;
eff1a59c 201 }
dd397dc9 202
4e416a6f
CL
203 usb_fill_bulk_urb(entry, priv->udev,
204 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
205 skb_tail_pointer(skb),
206 priv->common.rx_mtu + 32, p54u_rx_cb, skb);
eff1a59c
MW
207 info = (struct p54u_rx_info *) skb->cb;
208 info->urb = entry;
209 info->dev = dev;
210 skb_queue_tail(&priv->rx_queue, skb);
dd397dc9
CL
211
212 usb_anchor_urb(entry, &priv->submitted);
213 ret = usb_submit_urb(entry, GFP_KERNEL);
214 if (ret) {
215 skb_unlink(skb, &priv->rx_queue);
216 usb_unanchor_urb(entry);
217 goto err;
218 }
219 usb_free_urb(entry);
220 entry = NULL;
eff1a59c
MW
221 }
222
223 return 0;
eff1a59c 224
dd397dc9
CL
225 err:
226 usb_free_urb(entry);
227 kfree_skb(skb);
228 p54u_free_urbs(dev);
229 return ret;
eff1a59c
MW
230}
231
c9127659 232static __le32 p54u_lm87_chksum(const __le32 *data, size_t length)
2b80848e 233{
1f1c0e33 234 u32 chk = 0;
2b80848e
CL
235
236 length >>= 2;
237 while (length--) {
c9127659 238 chk ^= le32_to_cpu(*data++);
2b80848e
CL
239 chk = (chk >> 5) ^ (chk << 3);
240 }
241
1f1c0e33 242 return cpu_to_le32(chk);
2b80848e
CL
243}
244
0a5ec96a 245static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb)
2b80848e
CL
246{
247 struct p54u_priv *priv = dev->priv;
248 struct urb *data_urb;
e2fe154e 249 struct lm87_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
2b80848e
CL
250
251 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
6d541a68
CL
252 if (!data_urb) {
253 p54_free_skb(dev, skb);
2b80848e 254 return;
6d541a68 255 }
2b80848e 256
e2fe154e
CL
257 hdr->chksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);
258 hdr->device_addr = ((struct p54_hdr *)skb->data)->req_id;
2b80848e
CL
259
260 usb_fill_bulk_urb(data_urb, priv->udev,
b92f30d6 261 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
e2fe154e
CL
262 hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?
263 p54u_tx_cb : p54u_tx_dummy_cb, skb);
00627f22 264 data_urb->transfer_flags |= URB_ZERO_PACKET;
2b80848e 265
dd397dc9
CL
266 usb_anchor_urb(data_urb, &priv->submitted);
267 if (usb_submit_urb(data_urb, GFP_ATOMIC)) {
268 usb_unanchor_urb(data_urb);
dd397dc9
CL
269 p54_free_skb(dev, skb);
270 }
271 usb_free_urb(data_urb);
2b80848e
CL
272}
273
0a5ec96a 274static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
eff1a59c
MW
275{
276 struct p54u_priv *priv = dev->priv;
6d541a68 277 struct urb *int_urb = NULL, *data_urb = NULL;
e2fe154e 278 struct net2280_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
6d541a68
CL
279 struct net2280_reg_write *reg = NULL;
280 int err = -ENOMEM;
eff1a59c
MW
281
282 reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
283 if (!reg)
6d541a68 284 goto out;
eff1a59c
MW
285
286 int_urb = usb_alloc_urb(0, GFP_ATOMIC);
6d541a68
CL
287 if (!int_urb)
288 goto out;
eff1a59c
MW
289
290 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
6d541a68
CL
291 if (!data_urb)
292 goto out;
eff1a59c
MW
293
294 reg->port = cpu_to_le16(NET2280_DEV_U32);
295 reg->addr = cpu_to_le32(P54U_DEV_BASE);
296 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
297
eff1a59c 298 memset(hdr, 0, sizeof(*hdr));
e2fe154e
CL
299 hdr->len = cpu_to_le16(skb->len);
300 hdr->device_addr = ((struct p54_hdr *) skb->data)->req_id;
eff1a59c
MW
301
302 usb_fill_bulk_urb(int_urb, priv->udev,
303 usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
dd397dc9
CL
304 p54u_tx_dummy_cb, dev);
305
306 /*
6d541a68
CL
307 * URB_FREE_BUFFER triggers a code path in the USB subsystem that will
308 * free what is inside the transfer_buffer after the last reference to
309 * the int_urb is dropped.
dd397dc9 310 */
b4068a80 311 int_urb->transfer_flags |= URB_FREE_BUFFER | URB_ZERO_PACKET;
6d541a68 312 reg = NULL;
eff1a59c
MW
313
314 usb_fill_bulk_urb(data_urb, priv->udev,
b92f30d6 315 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
e2fe154e
CL
316 hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?
317 p54u_tx_cb : p54u_tx_dummy_cb, skb);
b4068a80 318 data_urb->transfer_flags |= URB_ZERO_PACKET;
dd397dc9
CL
319
320 usb_anchor_urb(int_urb, &priv->submitted);
321 err = usb_submit_urb(int_urb, GFP_ATOMIC);
322 if (err) {
323 usb_unanchor_urb(int_urb);
324 goto out;
325 }
326
327 usb_anchor_urb(data_urb, &priv->submitted);
328 err = usb_submit_urb(data_urb, GFP_ATOMIC);
329 if (err) {
330 usb_unanchor_urb(data_urb);
331 goto out;
332 }
6d541a68 333out:
dd397dc9
CL
334 usb_free_urb(int_urb);
335 usb_free_urb(data_urb);
336
337 if (err) {
6d541a68 338 kfree(reg);
dd397dc9
CL
339 p54_free_skb(dev, skb);
340 }
eff1a59c
MW
341}
342
343static int p54u_write(struct p54u_priv *priv,
344 struct net2280_reg_write *buf,
345 enum net2280_op_type type,
346 __le32 addr, __le32 val)
347{
348 unsigned int ep;
349 int alen;
350
351 if (type & 0x0800)
352 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV);
353 else
354 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_BRG);
355
356 buf->port = cpu_to_le16(type);
357 buf->addr = addr;
358 buf->val = val;
359
360 return usb_bulk_msg(priv->udev, ep, buf, sizeof(*buf), &alen, 1000);
361}
362
363static int p54u_read(struct p54u_priv *priv, void *buf,
364 enum net2280_op_type type,
365 __le32 addr, __le32 *val)
366{
367 struct net2280_reg_read *read = buf;
368 __le32 *reg = buf;
369 unsigned int ep;
370 int alen, err;
371
372 if (type & 0x0800)
373 ep = P54U_PIPE_DEV;
374 else
375 ep = P54U_PIPE_BRG;
376
377 read->port = cpu_to_le16(type);
378 read->addr = addr;
379
380 err = usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
381 read, sizeof(*read), &alen, 1000);
382 if (err)
383 return err;
384
385 err = usb_bulk_msg(priv->udev, usb_rcvbulkpipe(priv->udev, ep),
386 reg, sizeof(*reg), &alen, 1000);
387 if (err)
388 return err;
389
390 *val = *reg;
391 return 0;
392}
393
394static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
395 void *data, size_t len)
396{
397 int alen;
398 return usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
399 data, len, &alen, 2000);
400}
401
1ca5f2e9 402static int p54u_device_reset(struct ieee80211_hw *dev)
6982869d
CL
403{
404 struct p54u_priv *priv = dev->priv;
c88a768d 405 int ret, lock = (priv->intf->condition != USB_INTERFACE_BINDING);
6982869d 406
c88a768d
CL
407 if (lock) {
408 ret = usb_lock_device_for_reset(priv->udev, priv->intf);
409 if (ret < 0) {
410 dev_err(&priv->udev->dev, "(p54usb) unable to lock "
1ca5f2e9 411 "device for reset (%d)!\n", ret);
c88a768d
CL
412 return ret;
413 }
6982869d
CL
414 }
415
416 ret = usb_reset_device(priv->udev);
417 if (lock)
418 usb_unlock_device(priv->udev);
419
1ca5f2e9 420 if (ret)
6982869d 421 dev_err(&priv->udev->dev, "(p54usb) unable to reset "
1ca5f2e9
CL
422 "device (%d)!\n", ret);
423
424 return ret;
425}
426
427static const char p54u_romboot_3887[] = "~~~~";
428static int p54u_firmware_reset_3887(struct ieee80211_hw *dev)
429{
430 struct p54u_priv *priv = dev->priv;
21d6c270 431 u8 *buf;
1ca5f2e9 432 int ret;
6982869d 433
21d6c270
LF
434 buf = kmalloc(4, GFP_KERNEL);
435 if (!buf)
436 return -ENOMEM;
437 memcpy(buf, p54u_romboot_3887, 4);
6982869d 438 ret = p54u_bulk_msg(priv, P54U_PIPE_DATA,
21d6c270
LF
439 buf, 4);
440 kfree(buf);
6982869d
CL
441 if (ret)
442 dev_err(&priv->udev->dev, "(p54usb) unable to jump to "
1ca5f2e9 443 "boot ROM (%d)!\n", ret);
6982869d
CL
444
445 return ret;
446}
447
1ca5f2e9 448static const char p54u_firmware_upload_3887[] = "<\r";
eff1a59c
MW
449static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
450{
eff1a59c 451 struct p54u_priv *priv = dev->priv;
eff1a59c
MW
452 int err, alen;
453 u8 carry = 0;
8b72eb43
DW
454 u8 *buf, *tmp;
455 const u8 *data;
eff1a59c
MW
456 unsigned int left, remains, block_size;
457 struct x2_header *hdr;
458 unsigned long timeout;
459
1ca5f2e9
CL
460 err = p54u_firmware_reset_3887(dev);
461 if (err)
462 return err;
463
eff1a59c
MW
464 tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
465 if (!buf) {
02e37ba1
CL
466 dev_err(&priv->udev->dev, "(p54usb) cannot allocate firmware"
467 "upload buffer!\n");
1ca5f2e9 468 return -ENOMEM;
e365f160
CL
469 }
470
1ca5f2e9 471 left = block_size = min((size_t)P54U_FW_BLOCK, priv->fw->size);
6982869d
CL
472 strcpy(buf, p54u_firmware_upload_3887);
473 left -= strlen(p54u_firmware_upload_3887);
474 tmp += strlen(p54u_firmware_upload_3887);
eff1a59c 475
1ca5f2e9
CL
476 data = priv->fw->data;
477 remains = priv->fw->size;
eff1a59c 478
6982869d 479 hdr = (struct x2_header *)(buf + strlen(p54u_firmware_upload_3887));
eff1a59c
MW
480 memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
481 hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
1ca5f2e9 482 hdr->fw_length = cpu_to_le32(priv->fw->size);
eff1a59c
MW
483 hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
484 sizeof(u32)*2));
485 left -= sizeof(*hdr);
486 tmp += sizeof(*hdr);
487
488 while (remains) {
489 while (left--) {
490 if (carry) {
491 *tmp++ = carry;
492 carry = 0;
493 remains--;
494 continue;
495 }
496 switch (*data) {
497 case '~':
498 *tmp++ = '}';
499 carry = '^';
500 break;
501 case '}':
502 *tmp++ = '}';
503 carry = ']';
504 break;
505 default:
506 *tmp++ = *data;
507 remains--;
508 break;
509 }
510 data++;
511 }
512
513 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size);
514 if (err) {
02e37ba1
CL
515 dev_err(&priv->udev->dev, "(p54usb) firmware "
516 "upload failed!\n");
eff1a59c
MW
517 goto err_upload_failed;
518 }
519
520 tmp = buf;
521 left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
522 }
523
1ca5f2e9
CL
524 *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, priv->fw->data,
525 priv->fw->size));
eff1a59c
MW
526 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
527 if (err) {
02e37ba1 528 dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n");
eff1a59c
MW
529 goto err_upload_failed;
530 }
eff1a59c
MW
531 timeout = jiffies + msecs_to_jiffies(1000);
532 while (!(err = usb_bulk_msg(priv->udev,
533 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
534 if (alen > 2 && !memcmp(buf, "OK", 2))
535 break;
536
537 if (alen > 5 && !memcmp(buf, "ERROR", 5)) {
eff1a59c
MW
538 err = -EINVAL;
539 break;
540 }
541
542 if (time_after(jiffies, timeout)) {
02e37ba1
CL
543 dev_err(&priv->udev->dev, "(p54usb) firmware boot "
544 "timed out!\n");
eff1a59c
MW
545 err = -ETIMEDOUT;
546 break;
547 }
548 }
02e37ba1
CL
549 if (err) {
550 dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n");
eff1a59c 551 goto err_upload_failed;
02e37ba1 552 }
eff1a59c
MW
553
554 buf[0] = 'g';
555 buf[1] = '\r';
556 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2);
557 if (err) {
02e37ba1 558 dev_err(&priv->udev->dev, "(p54usb) firmware boot failed!\n");
eff1a59c
MW
559 goto err_upload_failed;
560 }
561
562 timeout = jiffies + msecs_to_jiffies(1000);
563 while (!(err = usb_bulk_msg(priv->udev,
564 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
565 if (alen > 0 && buf[0] == 'g')
566 break;
567
568 if (time_after(jiffies, timeout)) {
569 err = -ETIMEDOUT;
570 break;
571 }
572 }
573 if (err)
574 goto err_upload_failed;
575
1ca5f2e9 576err_upload_failed:
eff1a59c 577 kfree(buf);
eff1a59c
MW
578 return err;
579}
580
581static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
582{
583 struct p54u_priv *priv = dev->priv;
eff1a59c
MW
584 const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;
585 int err, alen;
586 void *buf;
587 __le32 reg;
588 unsigned int remains, offset;
8b72eb43 589 const u8 *data;
eff1a59c
MW
590
591 buf = kmalloc(512, GFP_KERNEL);
592 if (!buf) {
02e37ba1
CL
593 dev_err(&priv->udev->dev, "(p54usb) firmware buffer "
594 "alloc failed!\n");
eff1a59c
MW
595 return -ENOMEM;
596 }
597
eff1a59c
MW
598#define P54U_WRITE(type, addr, data) \
599 do {\
600 err = p54u_write(priv, buf, type,\
601 cpu_to_le32((u32)(unsigned long)addr), data);\
602 if (err) \
603 goto fail;\
604 } while (0)
605
606#define P54U_READ(type, addr) \
607 do {\
608 err = p54u_read(priv, buf, type,\
609 cpu_to_le32((u32)(unsigned long)addr), &reg);\
610 if (err)\
611 goto fail;\
612 } while (0)
613
614 /* power down net2280 bridge */
615 P54U_READ(NET2280_BRG_U32, NET2280_GPIOCTL);
616 reg |= cpu_to_le32(P54U_BRG_POWER_DOWN);
617 reg &= cpu_to_le32(~P54U_BRG_POWER_UP);
618 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
619
620 mdelay(100);
621
622 /* power up bridge */
623 reg |= cpu_to_le32(P54U_BRG_POWER_UP);
624 reg &= cpu_to_le32(~P54U_BRG_POWER_DOWN);
625 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
626
627 mdelay(100);
628
629 P54U_WRITE(NET2280_BRG_U32, NET2280_DEVINIT,
630 cpu_to_le32(NET2280_CLK_30Mhz |
631 NET2280_PCI_ENABLE |
632 NET2280_PCI_SOFT_RESET));
633
634 mdelay(20);
635
636 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_COMMAND,
637 cpu_to_le32(PCI_COMMAND_MEMORY |
638 PCI_COMMAND_MASTER));
639
640 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_0,
641 cpu_to_le32(NET2280_BASE));
642
643 P54U_READ(NET2280_BRG_CFG_U16, PCI_STATUS);
644 reg |= cpu_to_le32(PCI_STATUS_REC_MASTER_ABORT);
645 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_STATUS, reg);
646
647 // TODO: we really need this?
648 P54U_READ(NET2280_BRG_U32, NET2280_RELNUM);
649
650 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_RSP,
651 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
652 P54U_WRITE(NET2280_BRG_U32, NET2280_EPC_RSP,
653 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
654
655 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_2,
656 cpu_to_le32(NET2280_BASE2));
657
658 /* finally done setting up the bridge */
659
660 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | PCI_COMMAND,
661 cpu_to_le32(PCI_COMMAND_MEMORY |
662 PCI_COMMAND_MASTER));
663
664 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | 0x40 /* TRDY timeout */, 0);
665 P54U_WRITE(NET2280_DEV_CFG_U32, 0x10000 | PCI_BASE_ADDRESS_0,
666 cpu_to_le32(P54U_DEV_BASE));
667
668 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
669 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
670 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
671
672 /* do romboot */
673 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable, 0);
674
675 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
676 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
677 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);
678 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
679 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
680
681 mdelay(20);
682
683 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
684 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
685
686 mdelay(20);
687
688 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
689 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
690
691 mdelay(100);
692
693 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
694 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
695
696 /* finally, we can upload firmware now! */
1ca5f2e9
CL
697 remains = priv->fw->size;
698 data = priv->fw->data;
eff1a59c
MW
699 offset = ISL38XX_DEV_FIRMWARE_ADDR;
700
701 while (remains) {
702 unsigned int block_len = min(remains, (unsigned int)512);
703 memcpy(buf, data, block_len);
704
705 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_len);
706 if (err) {
02e37ba1
CL
707 dev_err(&priv->udev->dev, "(p54usb) firmware block "
708 "upload failed\n");
eff1a59c
MW
709 goto fail;
710 }
711
712 P54U_WRITE(NET2280_DEV_U32, &devreg->direct_mem_base,
713 cpu_to_le32(0xc0000f00));
714
715 P54U_WRITE(NET2280_DEV_U32,
716 0x0020 | (unsigned long)&devreg->direct_mem_win, 0);
717 P54U_WRITE(NET2280_DEV_U32,
718 0x0020 | (unsigned long)&devreg->direct_mem_win,
719 cpu_to_le32(1));
720
721 P54U_WRITE(NET2280_DEV_U32,
722 0x0024 | (unsigned long)&devreg->direct_mem_win,
723 cpu_to_le32(block_len));
724 P54U_WRITE(NET2280_DEV_U32,
725 0x0028 | (unsigned long)&devreg->direct_mem_win,
726 cpu_to_le32(offset));
727
728 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_addr,
729 cpu_to_le32(NET2280_EPA_FIFO_PCI_ADDR));
730 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_len,
731 cpu_to_le32(block_len >> 2));
732 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_ctrl,
733 cpu_to_le32(ISL38XX_DMA_MASTER_CONTROL_TRIGGER));
734
735 mdelay(10);
736
737 P54U_READ(NET2280_DEV_U32,
738 0x002C | (unsigned long)&devreg->direct_mem_win);
739 if (!(reg & cpu_to_le32(ISL38XX_DMA_STATUS_DONE)) ||
740 !(reg & cpu_to_le32(ISL38XX_DMA_STATUS_READY))) {
02e37ba1
CL
741 dev_err(&priv->udev->dev, "(p54usb) firmware DMA "
742 "transfer failed\n");
eff1a59c
MW
743 goto fail;
744 }
745
746 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_STAT,
747 cpu_to_le32(NET2280_FIFO_FLUSH));
748
749 remains -= block_len;
750 data += block_len;
751 offset += block_len;
752 }
753
754 /* do ramboot */
755 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
756 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
757 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
758 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);
759 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
760
761 mdelay(20);
762
763 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
764 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
765
766 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
767 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
768
769 mdelay(100);
770
771 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
772 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
773
774 /* start up the firmware */
775 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable,
776 cpu_to_le32(ISL38XX_INT_IDENT_INIT));
777
778 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
779 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
780
781 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1,
782 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT_ENABLE |
783 NET2280_USB_INTERRUPT_ENABLE));
784
785 P54U_WRITE(NET2280_DEV_U32, &devreg->dev_int,
786 cpu_to_le32(ISL38XX_DEV_INT_RESET));
787
788 err = usb_interrupt_msg(priv->udev,
789 usb_rcvbulkpipe(priv->udev, P54U_PIPE_INT),
790 buf, sizeof(__le32), &alen, 1000);
791 if (err || alen != sizeof(__le32))
792 goto fail;
793
794 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
795 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
796
797 if (!(reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)))
798 err = -EINVAL;
799
800 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
801 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
802 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
803
804#undef P54U_WRITE
805#undef P54U_READ
806
1ca5f2e9 807fail:
eff1a59c
MW
808 kfree(buf);
809 return err;
810}
811
1ca5f2e9
CL
812static int p54u_load_firmware(struct ieee80211_hw *dev)
813{
814 struct p54u_priv *priv = dev->priv;
815 int err, i;
816
817 BUILD_BUG_ON(ARRAY_SIZE(p54u_fwlist) != __NUM_P54U_HWTYPES);
818
819 for (i = 0; i < __NUM_P54U_HWTYPES; i++)
820 if (p54u_fwlist[i].type == priv->hw_type)
821 break;
822
823 if (i == __NUM_P54U_HWTYPES)
824 return -EOPNOTSUPP;
825
826 err = request_firmware(&priv->fw, p54u_fwlist[i].fw, &priv->udev->dev);
827 if (err) {
828 dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s "
829 "(%d)!\n", p54u_fwlist[i].fw, err);
830
831 err = request_firmware(&priv->fw, p54u_fwlist[i].fw_legacy,
832 &priv->udev->dev);
833 if (err)
834 return err;
835 }
836
837 err = p54_parse_firmware(dev, priv->fw);
838 if (err)
839 goto out;
840
841 if (priv->common.fw_interface != p54u_fwlist[i].intf) {
842 dev_err(&priv->udev->dev, "wrong firmware, please get "
843 "a firmware for \"%s\" and try again.\n",
844 p54u_fwlist[i].hw);
845 err = -EINVAL;
846 }
847
848out:
849 if (err)
850 release_firmware(priv->fw);
851
852 return err;
853}
854
eff1a59c
MW
855static int p54u_open(struct ieee80211_hw *dev)
856{
857 struct p54u_priv *priv = dev->priv;
858 int err;
859
860 err = p54u_init_urbs(dev);
861 if (err) {
862 return err;
863 }
864
865 priv->common.open = p54u_init_urbs;
866
867 return 0;
868}
869
870static void p54u_stop(struct ieee80211_hw *dev)
871{
872 /* TODO: figure out how to reliably stop the 3887 and net2280 so
873 the hardware is still usable next time we want to start it.
874 until then, we just stop listening to the hardware.. */
875 p54u_free_urbs(dev);
876 return;
877}
878
879static int __devinit p54u_probe(struct usb_interface *intf,
880 const struct usb_device_id *id)
881{
882 struct usb_device *udev = interface_to_usbdev(intf);
883 struct ieee80211_hw *dev;
884 struct p54u_priv *priv;
885 int err;
886 unsigned int i, recognized_pipes;
eff1a59c
MW
887
888 dev = p54_init_common(sizeof(*priv));
02e37ba1 889
eff1a59c 890 if (!dev) {
02e37ba1 891 dev_err(&udev->dev, "(p54usb) ieee80211 alloc failed\n");
eff1a59c
MW
892 return -ENOMEM;
893 }
894
895 priv = dev->priv;
1ca5f2e9 896 priv->hw_type = P54U_INVALID_HW;
eff1a59c
MW
897
898 SET_IEEE80211_DEV(dev, &intf->dev);
899 usb_set_intfdata(intf, dev);
900 priv->udev = udev;
6982869d
CL
901 priv->intf = intf;
902 skb_queue_head_init(&priv->rx_queue);
903 init_usb_anchor(&priv->submitted);
eff1a59c
MW
904
905 usb_get_dev(udev);
906
907 /* really lazy and simple way of figuring out if we're a 3887 */
908 /* TODO: should just stick the identification in the device table */
909 i = intf->altsetting->desc.bNumEndpoints;
910 recognized_pipes = 0;
911 while (i--) {
912 switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) {
913 case P54U_PIPE_DATA:
914 case P54U_PIPE_MGMT:
915 case P54U_PIPE_BRG:
916 case P54U_PIPE_DEV:
917 case P54U_PIPE_DATA | USB_DIR_IN:
918 case P54U_PIPE_MGMT | USB_DIR_IN:
919 case P54U_PIPE_BRG | USB_DIR_IN:
920 case P54U_PIPE_DEV | USB_DIR_IN:
921 case P54U_PIPE_INT | USB_DIR_IN:
922 recognized_pipes++;
923 }
924 }
925 priv->common.open = p54u_open;
2b80848e 926 priv->common.stop = p54u_stop;
eff1a59c 927 if (recognized_pipes < P54U_PIPE_NUMBER) {
13792578 928#ifdef CONFIG_PM
1ca5f2e9
CL
929 /* ISL3887 needs a full reset on resume */
930 udev->reset_resume = 1;
931 err = p54u_device_reset(dev);
13792578 932#endif
1ca5f2e9 933
eff1a59c 934 priv->hw_type = P54U_3887;
a406ac0d
CL
935 dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
936 priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr);
937 priv->common.tx = p54u_tx_lm87;
1ca5f2e9 938 priv->upload_fw = p54u_upload_firmware_3887;
eff1a59c 939 } else {
2b80848e 940 priv->hw_type = P54U_NET2280;
eff1a59c
MW
941 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
942 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
943 priv->common.tx = p54u_tx_net2280;
1ca5f2e9 944 priv->upload_fw = p54u_upload_firmware_net2280;
2b80848e 945 }
1ca5f2e9 946 err = p54u_load_firmware(dev);
eff1a59c
MW
947 if (err)
948 goto err_free_dev;
949
1ca5f2e9
CL
950 err = priv->upload_fw(dev);
951 if (err)
952 goto err_free_fw;
953
7cb77072
CL
954 p54u_open(dev);
955 err = p54_read_eeprom(dev);
956 p54u_stop(dev);
eff1a59c 957 if (err)
1ca5f2e9 958 goto err_free_fw;
eff1a59c 959
2ac71072
CL
960 err = p54_register_common(dev, &udev->dev);
961 if (err)
1ca5f2e9 962 goto err_free_fw;
eff1a59c 963
eff1a59c
MW
964 return 0;
965
1ca5f2e9
CL
966err_free_fw:
967 release_firmware(priv->fw);
968
969err_free_dev:
d8c92107 970 p54_free_common(dev);
eff1a59c
MW
971 usb_set_intfdata(intf, NULL);
972 usb_put_dev(udev);
973 return err;
974}
975
976static void __devexit p54u_disconnect(struct usb_interface *intf)
977{
978 struct ieee80211_hw *dev = usb_get_intfdata(intf);
979 struct p54u_priv *priv;
980
981 if (!dev)
982 return;
983
d8c92107 984 p54_unregister_common(dev);
eff1a59c
MW
985
986 priv = dev->priv;
987 usb_put_dev(interface_to_usbdev(intf));
1ca5f2e9 988 release_firmware(priv->fw);
eff1a59c 989 p54_free_common(dev);
eff1a59c
MW
990}
991
6982869d
CL
992static int p54u_pre_reset(struct usb_interface *intf)
993{
1ca5f2e9
CL
994 struct ieee80211_hw *dev = usb_get_intfdata(intf);
995
996 if (!dev)
997 return -ENODEV;
998
999 p54u_stop(dev);
6982869d
CL
1000 return 0;
1001}
1002
1ca5f2e9
CL
1003static int p54u_resume(struct usb_interface *intf)
1004{
1005 struct ieee80211_hw *dev = usb_get_intfdata(intf);
1006 struct p54u_priv *priv;
1007
1008 if (!dev)
1009 return -ENODEV;
1010
1011 priv = dev->priv;
1012 if (unlikely(!(priv->upload_fw && priv->fw)))
1013 return 0;
1014
1015 return priv->upload_fw(dev);
1016}
1017
6982869d
CL
1018static int p54u_post_reset(struct usb_interface *intf)
1019{
1ca5f2e9
CL
1020 struct ieee80211_hw *dev = usb_get_intfdata(intf);
1021 struct p54u_priv *priv;
1022 int err;
1023
1024 err = p54u_resume(intf);
1025 if (err)
1026 return err;
1027
1028 /* reinitialize old device state */
1029 priv = dev->priv;
1030 if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED)
1031 ieee80211_restart_hw(dev);
1032
6982869d
CL
1033 return 0;
1034}
1035
1ca5f2e9
CL
1036#ifdef CONFIG_PM
1037
1038static int p54u_suspend(struct usb_interface *intf, pm_message_t message)
1039{
1040 return p54u_pre_reset(intf);
1041}
1042
1043#endif /* CONFIG_PM */
1044
eff1a59c 1045static struct usb_driver p54u_driver = {
32ddf071 1046 .name = "p54usb",
eff1a59c
MW
1047 .id_table = p54u_table,
1048 .probe = p54u_probe,
1049 .disconnect = p54u_disconnect,
6982869d
CL
1050 .pre_reset = p54u_pre_reset,
1051 .post_reset = p54u_post_reset,
1ca5f2e9
CL
1052#ifdef CONFIG_PM
1053 .suspend = p54u_suspend,
1054 .resume = p54u_resume,
1055 .reset_resume = p54u_resume,
1056#endif /* CONFIG_PM */
fbf95296 1057 .soft_unbind = 1,
eff1a59c
MW
1058};
1059
1060static int __init p54u_init(void)
1061{
1062 return usb_register(&p54u_driver);
1063}
1064
1065static void __exit p54u_exit(void)
1066{
1067 usb_deregister(&p54u_driver);
1068}
1069
1070module_init(p54u_init);
1071module_exit(p54u_exit);