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