Revert "svn-1299"
[orinoco_usb.git] / drivers / net / wireless / prism_usb.c
blob7f97eb0086ef0414da348f4882d0654935969789
1 /*
2 * USB Prism driver
4 * Copyright (c) 2004 Pavel Roskin <proski@gnu.org>
6 * Copyright notice & release notes in file orinoco.c
7 */
9 #define DRIVER_NAME "prism_usb"
10 #define PFX DRIVER_NAME ": "
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/sched.h>
15 #include <linux/signal.h>
16 #include <linux/errno.h>
17 #include <linux/poll.h>
18 #include <linux/init.h>
19 #include <linux/slab.h>
20 #include <linux/fcntl.h>
21 #include <linux/spinlock.h>
22 #include <linux/list.h>
23 #include <linux/smp_lock.h>
24 #include <linux/usb.h>
25 #include <linux/timer.h>
27 #include <linux/netdevice.h>
28 #include <linux/if_arp.h>
29 #include <linux/etherdevice.h>
30 #include <linux/wireless.h>
32 #include "orinoco.h"
34 #define BULK_BUF_SIZE 2048
36 /* Frame types sent to bulk OUT */
37 #define PRISMUSB_TYPE_TXFRM 0
38 #define PRISMUSB_TYPE_CMDREQ 1
39 #define PRISMUSB_TYPE_WRIDREQ 2
40 #define PRISMUSB_TYPE_RRIDREQ 3
41 #define PRISMUSB_TYPE_WMEMREQ 4
42 #define PRISMUSB_TYPE_RMEMREQ 5
44 /* Frame types received on bulk IN */
45 #define PRISMUSB_TYPE_INFOFRM 0x8000
46 #define PRISMUSB_TYPE_CMDRESP 0x8001
47 #define PRISMUSB_TYPE_WRIDRESP 0x8002
48 #define PRISMUSB_TYPE_RRIDRESP 0x8003
49 #define PRISMUSB_TYPE_WMEMRESP 0x8004
50 #define PRISMUSB_TYPE_RMEMRESP 0x8005
51 #define PRISMUSB_TYPE_BUFAVAIL 0x8006
52 #define PRISMUSB_TYPE_ERROR 0x8007
54 static struct usb_device_id prism_usb_table[] = {
55 {USB_DEVICE(0x04bb, 0x0922)}, /* IOData AirPort WN-B11/USBS */
56 {USB_DEVICE(0x07aa, 0x0012)}, /* Corega Wireless LAN USB Stick-11 */
57 {USB_DEVICE(0x09aa, 0x3642)}, /* Prism2.x 11Mbps WLAN USB Adapter */
58 {USB_DEVICE(0x1668, 0x0408)}, /* Actiontec Prism2.5 11Mbps WLAN USB Adapter */
59 {USB_DEVICE(0x1668, 0x0421)}, /* Actiontec Prism2.5 11Mbps WLAN USB Adapter */
60 {USB_DEVICE(0x066b, 0x2212)}, /* Linksys WUSB11v2.5 11Mbps WLAN USB Adapter */
61 {USB_DEVICE(0x066b, 0x2213)}, /* Linksys WUSB12v1.1 11Mbps WLAN USB Adapter */
62 {USB_DEVICE(0x067c, 0x1022)}, /* Siemens SpeedStream 1022 11Mbps WLAN USB Adapter */
63 {USB_DEVICE(0x049f, 0x0033)}, /* Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter */
64 {USB_DEVICE(0x0411, 0x0016)}, /* Melco WLI-USB-S11 11Mbps WLAN Adapter */
65 {USB_DEVICE(0x08de, 0x7a01)}, /* PRISM25 IEEE 802.11 Mini USB Adapter */
66 {USB_DEVICE(0x8086, 0x1111)}, /* Intel PRO/Wireless 2011B LAN USB Adapter */
67 {USB_DEVICE(0x0d8e, 0x7a01)}, /* PRISM25 IEEE 802.11 Mini USB Adapter */
68 {USB_DEVICE(0x045e, 0x006e)}, /* Microsoft MN510 Wireless USB Adapter */
69 {USB_DEVICE(0x0967, 0x0204)}, /* Acer Warplink USB Adapter */
70 {USB_DEVICE(0x0cde, 0x0002)}, /* Z-Com 725/726 Prism2.5 USB/USB Integrated */
71 {USB_DEVICE(0x413c, 0x8100)}, /* Dell TrueMobile 1180 Wireless USB Adapter */
72 {USB_DEVICE(0x0b3b, 0x1601)}, /* ALLNET 0193 11Mbps WLAN USB Adapter */
73 {USB_DEVICE(0x0b3b, 0x1602)}, /* ZyXEL ZyAIR B200 Wireless USB Adapter */
74 {USB_DEVICE(0x0baf, 0x00eb)}, /* USRobotics USR1120 Wireless USB Adapter */
75 {USB_DEVICE(0x0411, 0x0027)}, /* Melco WLI-USB-KS11G 11Mbps WLAN Adapter */
76 {USB_DEVICE(0x04f1, 0x3009)}, /* JVC MP-XP7250 Builtin USB WLAN Adapter */
77 {USB_DEVICE(0x0846, 0x4110)}, /* NetGear MA111 */
78 {USB_DEVICE(0x03f3, 0x0020)}, /* Adaptec AWN-8020 USB WLAN Adapter */
79 {USB_DEVICE(0x2821, 0x3300)}, /* ASUS-WL140 Wireless USB Adapter */
80 {USB_DEVICE(0x2001, 0x3700)}, /* DWL-122 Wireless USB Adapter */
81 {USB_DEVICE(0x50c2, 0x4013)}, /* Averatec USB WLAN Adapter */
82 {USB_DEVICE(0x2c02, 0x14ea)}, /* Planex GW-US11H WLAN USB Adapter */
83 {USB_DEVICE(0x124a, 0x168b)}, /* Airvast PRISM3 WLAN USB Adapter */
84 {USB_DEVICE(0x083a, 0x3503)}, /* T-Sinus 111 USB WLAN Adapter */
85 {USB_DEVICE(0x2821, 0x3300)}, /* Hawking HighDB USB Adapter */
86 {USB_DEVICE(0x0411, 0x0044)}, /* Melco WLI-USB-KB11 11Mbps WLAN Adapter */
87 {USB_DEVICE(0x1668, 0x6106)}, /* ROPEX FreeLan 802.11b USB Adapter */
88 { /* Terminating entry */ }
91 MODULE_DEVICE_TABLE(usb, prism_usb_table);
93 /* Structure to hold all of our device specific stuff */
94 struct prism_usb_priv {
95 struct usb_device *udev;
96 struct net_device *dev;
97 struct semaphore sem;
98 u16 hermes_reg_fake[0x40];
99 u8 *bap_buf;
100 struct urb *read_urb;
101 int read_pipe;
102 int write_pipe;
105 struct prism_usb_packet {
106 u16 type;
107 u8 data[0];
108 } __attribute__ ((packed));
110 /* State of a request */
111 typedef enum {
112 CTX_START,
113 CTX_QUEUED,
114 CTX_REQ_SUBMITTED,
115 CTX_REQ_COMPLETE,
116 CTX_RESP_RECEIVED,
117 CTX_REQ_TIMEOUT,
118 CTX_REQ_FAILED,
119 CTX_RESP_TIMEOUT,
120 CTX_REQSUBMIT_FAIL,
121 CTX_COMPLETE,
122 } prism_usb_state_t;
124 /* Data associated with one particular request */
125 struct request_context {
126 struct list_head list;
127 atomic_t refcount;
128 struct completion done; /* Signals that CTX is dead */
129 int killed;
130 struct urb *outurb; /* OUT for req pkt */
131 struct prism_usb_priv *upriv;
132 struct prism_usb_packet *buf;
133 int buf_length;
134 struct timer_list timer; /* Timeout handling */
135 prism_usb_state_t state; /* Current state */
138 /* Debug functions */
139 static inline void hex_dump(const void *data_p, int size)
141 int i;
142 const u8 *data = data_p;
144 printk(KERN_DEBUG "Dump at %p, length: %d\n", data, size);
146 for (i = 0; i < size; i++) {
147 if ((i & 0xf) == 0)
148 printk(KERN_DEBUG "0x%04X: ", i);
149 if ((i & 3) == 0)
150 printk(" ");
151 printk("%02X ", data[i]);
152 if ((i & 0xf) == 0xf)
153 printk("\n");
155 if ((i & 0xf) != 0)
156 printk("\n");
159 static void prism_usb_req_timeout(unsigned long _ctx)
161 printk("prism_usb_req_timeout - dummy\n");
164 static struct request_context *prism_usb_alloc_ctx(struct prism_usb_priv *upriv)
166 struct request_context *ctx;
168 ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
169 if (!ctx) {
170 return NULL;
172 memset(ctx, 0, sizeof(*ctx));
174 ctx->buf = kmalloc(BULK_BUF_SIZE, GFP_ATOMIC);
175 if (!ctx->buf) {
176 kfree(ctx);
177 return NULL;
179 ctx->outurb = usb_alloc_urb(0, GFP_ATOMIC);
180 if (!ctx->outurb) {
181 kfree(ctx->buf);
182 kfree(ctx);
183 return NULL;
186 ctx->upriv = upriv;
187 ctx->state = CTX_START;
189 atomic_set(&ctx->refcount, 1);
190 init_completion(&ctx->done);
192 init_timer(&ctx->timer);
193 ctx->timer.function = prism_usb_req_timeout;
194 ctx->timer.data = (u_long) ctx;
195 return ctx;
198 static void prism_usb_bulkout_cb(struct urb *urb, struct pt_regs *pt_regs)
200 printk("prism_usb_bulkout_cb - dummy\n");
203 static int prism_usb_init(hermes_t *hw)
205 printk("prism_usb_init - dummy\n");
206 return 0;
209 static int prism_usb_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
210 struct hermes_response *resp)
212 struct prism_usb_priv *upriv = hw->priv;
213 struct request_context *ctx;
214 int err = 0;
216 __le16 data[] = {
217 cpu_to_le16(PRISMUSB_TYPE_CMDREQ),
218 cpu_to_le16(cmd),
219 cpu_to_le16(parm0),
220 cpu_to_le16(0),
221 cpu_to_le16(0),
224 ctx = prism_usb_alloc_ctx(upriv);
225 if (!ctx)
226 return -ENOMEM;
228 memcpy(ctx->buf, data, sizeof(data));
230 /* Fill the out packet */
231 usb_fill_bulk_urb(ctx->outurb, upriv->udev, upriv->write_pipe, ctx->buf,
232 ALIGN(sizeof(data), 64), prism_usb_bulkout_cb, ctx);
234 /* FIXME: submit URB here */
236 if (ctx->state != CTX_COMPLETE)
237 err = -EIO;
239 complete(&ctx->done);
240 kfree(ctx);
241 return err;
244 static int prism_usb_allocate(struct hermes *hw, u16 size, u16 *fid)
246 printk("prism_usb_allocate - dummy\n");
247 return 0;
250 static int prism_usb_read_ltv(hermes_t *hw, int bap, u16 rid,
251 unsigned bufsize, u16 *length, void *buf)
253 printk("prism_usb_read_ltv - dummy\n");
254 return -EOPNOTSUPP;
257 static int prism_usb_write_ltv(hermes_t *hw, int bap, u16 rid,
258 u16 length, const void *data)
260 printk("prism_usb_write_ltv - dummy\n");
261 return -EOPNOTSUPP;
264 static int prism_usb_bap_pread(struct hermes *hw, int bap,
265 void *buf, int len, u16 id, u16 offset)
267 printk("prism_usb_bap_pread - dummy\n");
268 return -EOPNOTSUPP;
271 static int prism_usb_hard_reset(struct orinoco_private *priv)
273 printk("prism_usb_hard_reset - dummy\n");
274 return 0;
277 static int prism_usb_xmit(struct sk_buff *skb, struct net_device *dev)
279 printk("prism_usb_xmit - dummy\n");
280 return -EOPNOTSUPP;
283 static inline void prism_usb_delete(struct prism_usb_priv *upriv)
285 struct net_device *dev;
287 BUG_ON(in_interrupt());
288 BUG_ON(!upriv);
290 dev = upriv->dev;
291 down(&upriv->sem);
293 upriv->udev = NULL;
295 up(&upriv->sem);
297 kfree(upriv->read_urb->transfer_buffer);
298 if (upriv->read_urb != NULL)
299 usb_free_urb(upriv->read_urb);
300 if (upriv->dev) {
301 unregister_netdev(upriv->dev);
302 free_orinocodev(upriv->dev);
306 static const struct hermes_ops prism_usb_ops = {
307 .init = prism_usb_init,
308 .docmd_wait = prism_usb_docmd_wait,
309 .allocate = prism_usb_allocate,
310 .read_ltv = prism_usb_read_ltv,
311 .write_ltv = prism_usb_write_ltv,
312 .bap_pread = prism_usb_bap_pread
315 static int prism_usb_probe(struct usb_interface *interface,
316 const struct usb_device_id *id)
318 struct usb_device *udev = interface_to_usbdev(interface);
319 struct orinoco_private *priv;
320 struct net_device *dev;
321 hermes_t *hw;
322 struct prism_usb_priv *upriv = NULL;
323 struct usb_interface_descriptor *iface_desc;
324 struct usb_endpoint_descriptor *ep;
325 int err;
327 dev = alloc_orinocodev(sizeof(*upriv), prism_usb_hard_reset);
328 if (!dev) {
329 printk(KERN_ERR PFX "Cannot allocate network device\n");
330 err = -ENOMEM;
331 goto exit;
334 priv = netdev_priv(dev);
335 hw = &priv->hw;
337 upriv = priv->card;
339 init_MUTEX(&upriv->sem);
341 upriv->udev = udev;
343 hw->iobase = (void __force __iomem *) &upriv->hermes_reg_fake;
344 hw->reg_spacing = HERMES_16BIT_REGSPACING;
345 hw->priv = upriv;
346 hw->ops = &prism_usb_ops;
347 dev->hard_start_xmit = prism_usb_xmit;
349 priv->irq_no_disable = 1;
351 /* Set up the endpoints */
352 iface_desc = &interface->altsetting[0].desc;
353 if (iface_desc->bNumEndpoints != 3) {
354 printk(KERN_ERR PFX "Unexpected number of endpoints: %d\n",
355 iface_desc->bNumEndpoints);
356 err = -ENODEV;
357 goto error;
360 /* Endpoint 1 - bulk in */
361 ep = &interface->altsetting[0].endpoint[0].desc;
362 if (le16_to_cpu(ep->wMaxPacketSize) != 64) {
363 printk(KERN_ERR PFX "Unexpected bulk IN packet size: %d\n",
364 le16_to_cpu(ep->wMaxPacketSize));
365 err = -ENODEV;
366 goto error;
369 if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN) ||
370 ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
371 != USB_ENDPOINT_XFER_BULK)) {
372 printk(KERN_ERR PFX "Endpoint 1 - not bulk IN\n");
373 err = -ENODEV;
374 goto error;
377 upriv->read_urb = usb_alloc_urb(0, GFP_KERNEL);
378 if (!upriv->read_urb) {
379 printk(KERN_ERR PFX "No free urbs available\n");
380 err = -ENOMEM;
381 goto error;
383 upriv->read_pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress);
384 upriv->read_urb->transfer_buffer = kmalloc(BULK_BUF_SIZE, GFP_KERNEL);
385 if (!upriv->read_urb->transfer_buffer) {
386 printk(KERN_ERR PFX "Cannot allocate IN buffer\n");
387 err = -ENOMEM;
388 goto error;
391 /* Endpoint 2 - bulk out */
392 ep = &interface->altsetting[0].endpoint[1].desc;
393 if (le16_to_cpu(ep->wMaxPacketSize) != 64) {
394 printk(KERN_ERR PFX "Unexpected bulk OUT packet size: %d\n",
395 le16_to_cpu(ep->wMaxPacketSize));
396 err = -ENODEV;
397 goto error;
400 if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT) ||
401 ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
402 USB_ENDPOINT_XFER_BULK)) {
403 printk(PFX "Endpoint 2 - not bulk OUT\n");
404 err = -EBUSY;
405 goto error;
408 upriv->write_pipe = usb_sndbulkpipe(udev, ep->bEndpointAddress);
409 upriv->bap_buf = kmalloc(BULK_BUF_SIZE, GFP_KERNEL);
410 if (!upriv->bap_buf) {
411 printk(KERN_ERR PFX "Cannot allocate bulk OUT buffer\n");
412 err = -ENOMEM;
413 goto error;
416 err = prism_usb_hard_reset(priv);
417 if (err) {
418 printk(KERN_ERR PFX "Cannot reset the device\n");
419 goto error;
422 err = prism_usb_init(hw);
423 if (err) {
424 printk(KERN_ERR PFX "Cannot initialize the device\n");
425 goto error;
428 SET_MODULE_OWNER(dev);
429 SET_NETDEV_DEV(dev, &interface->dev);
430 upriv->dev = dev;
431 err = register_netdev(dev);
432 if (err) {
433 upriv->dev = NULL;
434 printk(KERN_ERR PFX "Cannot register network device\n");
435 goto error;
437 goto exit;
439 error:
440 prism_usb_delete(upriv);
441 if (dev) {
442 /* upriv->dev was 0, so prism_usb_delete() didn't free it */
443 free_orinocodev(dev);
445 upriv = NULL;
446 exit:
447 usb_set_intfdata(interface, upriv);
448 return err;
451 static void prism_usb_disconnect(struct usb_interface *intf)
453 struct prism_usb_priv *upriv = usb_get_intfdata(intf);
454 usb_set_intfdata(intf, NULL);
455 prism_usb_delete(upriv);
456 printk(KERN_INFO PFX "Disconnected\n");
459 /* usb specific object needed to register this driver with the usb subsystem */
460 static struct usb_driver prism_usb_driver = {
461 .name = DRIVER_NAME,
462 .probe = prism_usb_probe,
463 .disconnect = prism_usb_disconnect,
464 .id_table = prism_usb_table,
467 /* Can't be declared "const" or the whole __initdata section will
468 * become const */
469 static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
470 " (Pavel Roskin <proski@gnu.org>)";
472 static int __init prism_usb_module_init(void)
474 int err;
476 printk(KERN_DEBUG "%s\n", version);
477 printk(KERN_WARNING "This driver DOES NOT WORK!!!");
478 printk(KERN_WARNING "Use linux-wlan-ng: http://www.linux-wlan.org/");
480 /* register this driver with the USB subsystem */
481 err = usb_register(&prism_usb_driver);
482 if (err < 0) {
483 printk(KERN_ERR PFX "usb_register failed, error %d\n", err);
484 return err;
487 return 0;
490 static void __exit prism_usb_module_exit(void)
492 /* deregister this driver with the USB subsystem */
493 usb_deregister(&prism_usb_driver);
496 module_init(prism_usb_module_init);
497 module_exit(prism_usb_module_exit);
499 MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
500 MODULE_DESCRIPTION("Driver for Prism USB based wireless devices");
501 MODULE_LICENSE("Dual MPL/GPL");