4 * Copyright (c) 2004 Pavel Roskin <proski@gnu.org>
6 * Copyright notice & release notes in file orinoco.c
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>
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
;
98 u16 hermes_reg_fake
[0x40];
100 struct urb
*read_urb
;
105 struct prism_usb_packet
{
108 } __attribute__ ((packed
));
110 /* State of a request */
124 /* Data associated with one particular request */
125 struct request_context
{
126 struct list_head list
;
128 struct completion done
; /* Signals that CTX is dead */
130 struct urb
*outurb
; /* OUT for req pkt */
131 struct prism_usb_priv
*upriv
;
132 struct prism_usb_packet
*buf
;
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
)
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
++) {
148 printk(KERN_DEBUG
"0x%04X: ", i
);
151 printk("%02X ", data
[i
]);
152 if ((i
& 0xf) == 0xf)
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
);
172 memset(ctx
, 0, sizeof(*ctx
));
174 ctx
->buf
= kmalloc(BULK_BUF_SIZE
, GFP_ATOMIC
);
179 ctx
->outurb
= usb_alloc_urb(0, GFP_ATOMIC
);
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
;
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");
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
;
217 cpu_to_le16(PRISMUSB_TYPE_CMDREQ
),
224 ctx
= prism_usb_alloc_ctx(upriv
);
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
)
239 complete(&ctx
->done
);
244 static int prism_usb_allocate(struct hermes
*hw
, u16 size
, u16
*fid
)
246 printk("prism_usb_allocate - dummy\n");
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");
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");
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");
271 static int prism_usb_hard_reset(struct orinoco_private
*priv
)
273 printk("prism_usb_hard_reset - dummy\n");
277 static int prism_usb_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
279 printk("prism_usb_xmit - dummy\n");
283 static inline void prism_usb_delete(struct prism_usb_priv
*upriv
)
285 struct net_device
*dev
;
287 BUG_ON(in_interrupt());
297 kfree(upriv
->read_urb
->transfer_buffer
);
298 if (upriv
->read_urb
!= NULL
)
299 usb_free_urb(upriv
->read_urb
);
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
;
322 struct prism_usb_priv
*upriv
= NULL
;
323 struct usb_interface_descriptor
*iface_desc
;
324 struct usb_endpoint_descriptor
*ep
;
327 dev
= alloc_orinocodev(sizeof(*upriv
), prism_usb_hard_reset
);
329 printk(KERN_ERR PFX
"Cannot allocate network device\n");
334 priv
= netdev_priv(dev
);
339 init_MUTEX(&upriv
->sem
);
343 hw
->iobase
= (void __force __iomem
*) &upriv
->hermes_reg_fake
;
344 hw
->reg_spacing
= HERMES_16BIT_REGSPACING
;
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
);
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
));
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");
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");
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");
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
));
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");
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");
416 err
= prism_usb_hard_reset(priv
);
418 printk(KERN_ERR PFX
"Cannot reset the device\n");
422 err
= prism_usb_init(hw
);
424 printk(KERN_ERR PFX
"Cannot initialize the device\n");
428 SET_NETDEV_DEV(dev
, &interface
->dev
);
430 err
= register_netdev(dev
);
433 printk(KERN_ERR PFX
"Cannot register network device\n");
439 prism_usb_delete(upriv
);
441 /* upriv->dev was 0, so prism_usb_delete() didn't free it */
442 free_orinocodev(dev
);
446 usb_set_intfdata(interface
, upriv
);
450 static void prism_usb_disconnect(struct usb_interface
*intf
)
452 struct prism_usb_priv
*upriv
= usb_get_intfdata(intf
);
453 usb_set_intfdata(intf
, NULL
);
454 prism_usb_delete(upriv
);
455 printk(KERN_INFO PFX
"Disconnected\n");
458 /* usb specific object needed to register this driver with the usb subsystem */
459 static struct usb_driver prism_usb_driver
= {
461 .probe
= prism_usb_probe
,
462 .disconnect
= prism_usb_disconnect
,
463 .id_table
= prism_usb_table
,
466 /* Can't be declared "const" or the whole __initdata section will
468 static char version
[] __initdata
= DRIVER_NAME
" " DRIVER_VERSION
469 " (Pavel Roskin <proski@gnu.org>)";
471 static int __init
prism_usb_module_init(void)
475 printk(KERN_DEBUG
"%s\n", version
);
476 printk(KERN_WARNING
"This driver DOES NOT WORK!!!");
477 printk(KERN_WARNING
"Use linux-wlan-ng: http://www.linux-wlan.org/");
479 /* register this driver with the USB subsystem */
480 err
= usb_register(&prism_usb_driver
);
482 printk(KERN_ERR PFX
"usb_register failed, error %d\n", err
);
489 static void __exit
prism_usb_module_exit(void)
491 /* deregister this driver with the USB subsystem */
492 usb_deregister(&prism_usb_driver
);
495 module_init(prism_usb_module_init
);
496 module_exit(prism_usb_module_exit
);
498 MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
499 MODULE_DESCRIPTION("Driver for Prism USB based wireless devices");
500 MODULE_LICENSE("Dual MPL/GPL");