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 27#ifdef MODVERSIONS 28#include <linux/modversions.h> 29#endif 30 31#include <linux/module.h> 32#include <linux/slab.h> 33#include <linux/usb.h> 34 35#include "usbdrv.h" 36#include "zdusb.h" 37 38int zfLnxAllocAllUrbs(struct usbdrv_private *macp); 39void zfLnxFreeAllUrbs(struct usbdrv_private *macp); 40void zfLnxUnlinkAllUrbs(struct usbdrv_private *macp); 41 42MODULE_AUTHOR("Atheros Communications"); 43MODULE_DESCRIPTION("Atheros 802.11n Wireless LAN adapter"); 44MODULE_LICENSE("Dual BSD/GPL"); 45 46static const char driver_name[] = "Otus"; 47 48/* table of devices that work with this driver */ 49static const struct usb_device_id zd1221_ids[] = { 50 { USB_DEVICE(VENDOR_ATHR, PRODUCT_AR9170) }, 51 { USB_DEVICE(VENDOR_DLINK, PRODUCT_DWA160A) }, 52 { USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WNDA3100) }, 53 { USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WN111v2) }, 54 { } /* Terminating entry */ 55}; 56 57MODULE_DEVICE_TABLE(usb, zd1221_ids); 58 59extern u8_t zfLnxInitSetup(struct net_device *dev, struct usbdrv_private *macp); 60extern int usbdrv_close(struct net_device *dev); 61extern u8_t zfLnxClearStructs(struct net_device *dev); 62extern int zfWdsClose(struct net_device *dev); 63extern int zfUnregisterWdsDev(struct net_device *parentDev, u16_t wdsId); 64extern int zfLnxVapClose(struct net_device *dev); 65extern int zfLnxUnregisterVapDev(struct net_device *parentDev, u16_t vapId); 66 67/* WDS */ 68extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER]; 69 70/* VAP */ 71extern struct zsVapStruct vap[ZM_VAP_PORT_NUMBER]; 72 73static int zfLnxProbe(struct usb_interface *interface, 74 const struct usb_device_id *id) 75{ 76 struct usb_device *dev = interface_to_usbdev(interface); 77 78 struct net_device *net = NULL; 79 struct usbdrv_private *macp = NULL; 80 int vendor_id, product_id; 81 int result = 0; 82 83 usb_get_dev(dev); 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 98 macp = kzalloc(sizeof(struct usbdrv_private), GFP_KERNEL); 99 if (!macp) { 100 printk(KERN_ERR "out of memory allocating device structure\n"); 101 result = -ENOMEM; 102 goto fail; 103 } 104 105 net = alloc_etherdev(0); 106 107 if (net == NULL) { 108 printk(KERN_ERR "zfLnxProbe: Not able to alloc etherdev struct\n"); 109 result = -ENOMEM; 110 goto fail1; 111 } 112 113 strcpy(net->name, "ath%d"); 114 115 net->ml_priv = macp; /* kernel 2.6 */ 116 macp->udev = dev; 117 macp->device = net; 118 119 /* set up the endpoint information */ 120 /* check out the endpoints */ 121 macp->interface = interface; 122 123 /* init_waitqueue_head(&macp->regSet_wait); */ 124 /* init_waitqueue_head(&macp->iorwRsp_wait); */ 125 /* init_waitqueue_head(&macp->term_wait); */ 126 127 if (!zfLnxAllocAllUrbs(macp)) { 128 result = -ENOMEM; 129 goto fail2; 130 } 131 132 if (!zfLnxInitSetup(net, macp)) { 133 result = -EIO; 134 goto fail3; 135 } else { 136 usb_set_intfdata(interface, macp); 137 SET_NETDEV_DEV(net, &interface->dev); 138 139 if (register_netdev(net) != 0) { 140 usb_set_intfdata(interface, NULL); 141 goto fail3; 142 } 143 } 144 145 netif_carrier_off(net); 146 goto done; 147fail3: 148 zfLnxFreeAllUrbs(macp); 149fail2: 150 free_netdev(net); /* kernel 2.6 */ 151fail1: 152 kfree(macp); 153fail: 154 usb_put_dev(dev); 155 macp = NULL; 156done: 157 return result; 158} 159 160static void zfLnxDisconnect(struct usb_interface *interface) 161{ 162 struct usbdrv_private *macp = (struct usbdrv_private *) usb_get_intfdata(interface); 163 164 printk(KERN_DEBUG "zfLnxDisconnect\n"); 165 166 if (!macp) { 167 printk(KERN_ERR "unregistering non-existant device\n"); 168 return; 169 } 170 171 if (macp->driver_isolated) 172 if (macp->device->flags & IFF_UP) 173 usbdrv_close(macp->device); 174 175 176 zfLnxClearStructs(macp->device); 177 178 unregister_netdev(macp->device); 179 180 usb_put_dev(interface_to_usbdev(interface)); 181 182 /* printk(KERN_ERR "3. zfLnxUnlinkAllUrbs\n"); */ 183 /* zfLnxUnlinkAllUrbs(macp); */ 184 185 /* Free network interface */ 186 free_netdev(macp->device); 187 188 zfLnxFreeAllUrbs(macp); 189 /* zfLnxClearStructs(macp->device); */ 190 kfree(macp); 191 macp = NULL; 192 193 usb_set_intfdata(interface, NULL); 194} 195 196static struct usb_driver zd1221_driver = { 197 .name = driver_name, 198 .probe = zfLnxProbe, 199 .disconnect = zfLnxDisconnect, 200 .id_table = zd1221_ids, 201}; 202 203int __init zfLnxIinit(void) 204{ 205 printk(KERN_NOTICE "%s - version %s\n", DRIVER_NAME, VERSIONID); 206 return usb_register(&zd1221_driver); 207} 208 209void __exit zfLnxExit(void) 210{ 211 usb_deregister(&zd1221_driver); 212} 213 214module_init(zfLnxIinit); 215module_exit(zfLnxExit); 216