Commit | Line | Data |
---|---|---|
4bd43f50 LR |
1 | /* |
2 | * Copyright (c) 2007-2008 Atheros Communications Inc. | |
3 | * | |
4 | * Permission to use, copy, modify, and/or distribute this software for any | |
5 | * purpose with or without fee is hereby granted, provided that the above | |
6 | * copyright notice and this permission notice appear in all copies. | |
7 | * | |
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | */ | |
16 | /* */ | |
17 | /* Module Name : zdusb.c */ | |
18 | /* */ | |
19 | /* Abstract */ | |
20 | /* This module contains plug and play handling for USB device driver*/ | |
21 | /* */ | |
22 | /* NOTES */ | |
23 | /* Platform dependent. */ | |
24 | /* */ | |
25 | /************************************************************************/ | |
26 | ||
4bd43f50 LR |
27 | #ifdef MODVERSIONS |
28 | #include <linux/modversions.h> | |
29 | #endif | |
30 | ||
31 | #include <linux/module.h> | |
5a0e3ad6 | 32 | #include <linux/slab.h> |
4bd43f50 LR |
33 | #include <linux/usb.h> |
34 | ||
35 | #include "usbdrv.h" | |
36 | #include "zdusb.h" | |
37 | ||
38 | int zfLnxAllocAllUrbs(struct usbdrv_private *macp); | |
39 | void zfLnxFreeAllUrbs(struct usbdrv_private *macp); | |
40 | void zfLnxUnlinkAllUrbs(struct usbdrv_private *macp); | |
41 | ||
42 | MODULE_AUTHOR("Atheros Communications"); | |
43 | MODULE_DESCRIPTION("Atheros 802.11n Wireless LAN adapter"); | |
44 | MODULE_LICENSE("Dual BSD/GPL"); | |
45 | ||
46 | static const char driver_name[] = "Otus"; | |
47 | ||
48 | /* table of devices that work with this driver */ | |
a457732b | 49 | static const struct usb_device_id zd1221_ids[] = { |
4bd43f50 LR |
50 | { USB_DEVICE(VENDOR_ATHR, PRODUCT_AR9170) }, |
51 | { USB_DEVICE(VENDOR_DLINK, PRODUCT_DWA160A) }, | |
5672487d DN |
52 | { USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WNDA3100) }, |
53 | { USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WN111v2) }, | |
4bd43f50 LR |
54 | { } /* Terminating entry */ |
55 | }; | |
56 | ||
57 | MODULE_DEVICE_TABLE(usb, zd1221_ids); | |
58 | ||
59 | extern u8_t zfLnxInitSetup(struct net_device *dev, struct usbdrv_private *macp); | |
60 | extern int usbdrv_close(struct net_device *dev); | |
61 | extern u8_t zfLnxClearStructs(struct net_device *dev); | |
62 | extern int zfWdsClose(struct net_device *dev); | |
63 | extern int zfUnregisterWdsDev(struct net_device* parentDev, u16_t wdsId); | |
64 | extern int zfLnxVapClose(struct net_device *dev); | |
65 | extern int zfLnxUnregisterVapDev(struct net_device* parentDev, u16_t vapId); | |
66 | ||
67 | /* WDS */ | |
68 | extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER]; | |
69 | ||
70 | /* VAP */ | |
71 | extern struct zsVapStruct vap[ZM_VAP_PORT_NUMBER]; | |
72 | ||
4bd43f50 LR |
73 | static int zfLnxProbe(struct usb_interface *interface, |
74 | const struct usb_device_id *id) | |
75 | { | |
76 | struct usb_device *dev = interface_to_usbdev(interface); | |
4bd43f50 LR |
77 | |
78 | struct net_device *net = NULL; | |
79 | struct usbdrv_private *macp = NULL; | |
80 | int vendor_id, product_id; | |
81 | int result = 0; | |
82 | ||
4bd43f50 | 83 | usb_get_dev(dev); |
4bd43f50 LR |
84 | |
85 | vendor_id = dev->descriptor.idVendor; | |
86 | product_id = dev->descriptor.idProduct; | |
87 | ||
88 | #ifdef HMAC_DEBUG | |
89 | printk(KERN_NOTICE "vendor_id = %04x\n", vendor_id); | |
90 | printk(KERN_NOTICE "product_id = %04x\n", product_id); | |
91 | ||
92 | if (dev->speed == USB_SPEED_HIGH) | |
93 | printk(KERN_NOTICE "USB 2.0 Host\n"); | |
94 | else | |
95 | printk(KERN_NOTICE "USB 1.1 Host\n"); | |
96 | #endif | |
97 | ||
4bd43f50 LR |
98 | if (!(macp = kmalloc(sizeof(struct usbdrv_private), GFP_KERNEL))) |
99 | { | |
100 | printk(KERN_ERR "out of memory allocating device structure\n"); | |
101 | result = -ENOMEM; | |
102 | goto fail; | |
103 | } | |
104 | ||
105 | /* Zero the memory */ | |
106 | memset(macp, 0, sizeof(struct usbdrv_private)); | |
107 | ||
4bd43f50 LR |
108 | net = alloc_etherdev(0); |
109 | ||
110 | if (net == NULL) | |
111 | { | |
112 | printk(KERN_ERR "zfLnxProbe: Not able to alloc etherdev struct\n"); | |
113 | result = -ENOMEM; | |
114 | goto fail1; | |
115 | } | |
116 | ||
117 | strcpy(net->name, "ath%d"); | |
118 | ||
da3e8908 | 119 | net->ml_priv = macp; //kernel 2.6 |
4bd43f50 LR |
120 | macp->udev = dev; |
121 | macp->device = net; | |
122 | ||
123 | /* set up the endpoint information */ | |
124 | /* check out the endpoints */ | |
125 | macp->interface = interface; | |
126 | ||
127 | //init_waitqueue_head(&macp->regSet_wait); | |
128 | //init_waitqueue_head(&macp->iorwRsp_wait); | |
129 | //init_waitqueue_head(&macp->term_wait); | |
130 | ||
131 | if (!zfLnxAllocAllUrbs(macp)) | |
132 | { | |
133 | result = -ENOMEM; | |
134 | goto fail2; | |
135 | } | |
136 | ||
137 | if (!zfLnxInitSetup(net, macp)) | |
138 | { | |
139 | result = -EIO; | |
140 | goto fail3; | |
141 | } | |
142 | else | |
143 | { | |
4bd43f50 LR |
144 | usb_set_intfdata(interface, macp); |
145 | SET_NETDEV_DEV(net, &interface->dev); | |
4bd43f50 LR |
146 | |
147 | if (register_netdev(net) != 0) | |
148 | { | |
4bd43f50 | 149 | usb_set_intfdata(interface, NULL); |
4bd43f50 LR |
150 | goto fail3; |
151 | } | |
152 | } | |
153 | ||
154 | netif_carrier_off(net); | |
155 | goto done; | |
156 | ||
157 | fail3: | |
158 | zfLnxFreeAllUrbs(macp); | |
159 | fail2: | |
160 | free_netdev(net); //kernel 2.6 | |
161 | fail1: | |
162 | kfree(macp); | |
163 | ||
164 | fail: | |
4bd43f50 | 165 | usb_put_dev(dev); |
4bd43f50 LR |
166 | macp = NULL; |
167 | ||
168 | done: | |
4bd43f50 | 169 | return result; |
4bd43f50 LR |
170 | } |
171 | ||
4bd43f50 | 172 | static void zfLnxDisconnect(struct usb_interface *interface) |
4bd43f50 | 173 | { |
4bd43f50 | 174 | struct usbdrv_private *macp = (struct usbdrv_private *) usb_get_intfdata(interface); |
4bd43f50 LR |
175 | |
176 | printk(KERN_DEBUG "zfLnxDisconnect\n"); | |
177 | ||
178 | if (!macp) | |
179 | { | |
180 | printk(KERN_ERR "unregistering non-existant device\n"); | |
181 | return; | |
182 | } | |
183 | ||
184 | if (macp->driver_isolated) | |
185 | { | |
186 | if (macp->device->flags & IFF_UP) | |
187 | usbdrv_close(macp->device); | |
188 | } | |
189 | ||
190 | #if 0 | |
191 | /* Close WDS */ | |
192 | //zfWdsClose(wds[0].dev); | |
193 | /* Unregister WDS */ | |
194 | //zfUnregisterWdsDev(macp->device, 0); | |
195 | ||
196 | /* Close VAP */ | |
197 | zfLnxVapClose(vap[0].dev); | |
198 | /* Unregister VAP */ | |
199 | zfLnxUnregisterVapDev(macp->device, 0); | |
200 | #endif | |
201 | ||
202 | zfLnxClearStructs(macp->device); | |
203 | ||
204 | unregister_netdev(macp->device); | |
205 | ||
4bd43f50 | 206 | usb_put_dev(interface_to_usbdev(interface)); |
4bd43f50 LR |
207 | |
208 | //printk(KERN_ERR "3. zfLnxUnlinkAllUrbs\n"); | |
209 | //zfLnxUnlinkAllUrbs(macp); | |
210 | ||
211 | /* Free network interface */ | |
212 | free_netdev(macp->device); | |
213 | ||
214 | zfLnxFreeAllUrbs(macp); | |
215 | //zfLnxClearStructs(macp->device); | |
216 | kfree(macp); | |
217 | macp = NULL; | |
218 | ||
4bd43f50 | 219 | usb_set_intfdata(interface, NULL); |
4bd43f50 LR |
220 | } |
221 | ||
222 | static struct usb_driver zd1221_driver = { | |
4bd43f50 LR |
223 | .name = driver_name, |
224 | .probe = zfLnxProbe, | |
225 | .disconnect = zfLnxDisconnect, | |
226 | .id_table = zd1221_ids, | |
227 | }; | |
228 | ||
229 | int __init zfLnxIinit(void) | |
230 | { | |
231 | printk(KERN_NOTICE "%s - version %s\n", DRIVER_NAME, VERSIONID); | |
232 | return usb_register(&zd1221_driver); | |
233 | } | |
234 | ||
235 | void __exit zfLnxExit(void) | |
236 | { | |
237 | usb_deregister(&zd1221_driver); | |
238 | } | |
239 | ||
240 | module_init(zfLnxIinit); | |
241 | module_exit(zfLnxExit); |