diff options
author | jal2 <jal2> | 2003-03-21 20:53:30 +0000 |
---|---|---|
committer | jal2 <jal2> | 2003-03-21 20:53:30 +0000 |
commit | 5a0cd2893638c50286cb6ca4391947391390d9aa (patch) | |
tree | 579c500741d9797a28f602ef116730ce44a35451 | |
parent | f8bd6b4856785a2fcf4da19fdfc9344b9cbbb322 (diff) |
alex' version 0.8pas4version_0_8pas4
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | README | 24 | ||||
-rw-r--r-- | at76c503-i3861.c (renamed from vnet503-i3861.c) | 160 | ||||
-rw-r--r-- | at76c503-i3863.c | 166 | ||||
-rw-r--r-- | at76c503-rfmd.c (renamed from vnet503-rfmd.c) | 160 | ||||
-rw-r--r-- | at76c503.c | 126 | ||||
-rw-r--r-- | at76c503.h | 2 | ||||
-rw-r--r-- | at76c505-rfmd.c | 162 | ||||
-rw-r--r-- | usbdfu.c | 2 | ||||
-rw-r--r-- | vnet503-i3863.c | 254 | ||||
-rw-r--r-- | vnet505-rfmd.c | 250 |
11 files changed, 519 insertions, 793 deletions
@@ -1,4 +1,4 @@ -VERSION = 0.8pas3 +VERSION = 0.8pas4 CC=gcc @@ -7,9 +7,9 @@ KERNEL_VERSION = $(shell uname -r) KERNEL_SRC = /lib/modules/$(KERNEL_VERSION)/build KERNEL_HEADERS = $(KERNEL_SRC)/include -MODULES = at76c503.o usbdfu.o vnet503-rfmd.o vnet505-rfmd.o vnet503-i3861.o vnet503-i3863.o +MODULES = at76c503.o usbdfu.o at76c503-rfmd.o at76c505-rfmd.o at76c503-i3861.o at76c503-i3863.o -SRCS = at76c503.c usbdfu.c at76c503fw.c rom2h.c vnet503-rfmd.c vnet505-rfmd.c vnet503-i3861.c vnet503-i3863.c +SRCS = at76c503.c usbdfu.c at76c503fw.c rom2h.c at76c503-rfmd.c at76c505-rfmd.c at76c503-i3861.c at76c503-i3863.c HDRS = at76c503.h ieee802_11.h usbdfu.h fw-rfmd-0.90.2-140.h fw-rfmd-0.100.4-16.h fw-r505.h fw-i3861.h fw-i3863.h MODULE_DIR = $(DESTDIR)/lib/modules/$(KERNEL_VERSION)/kernel/drivers/usb/ CPPFLAGS = -D__KERNEL__ \ @@ -44,24 +44,24 @@ driver from atmelwlandriver.sourceforge.net, replug the device If you have hotplug installed, the drivers should now be loaded. If not, load them by hand: -modprobe -v vnet503-rfmd +modprobe -v at76c503-rfmd or -insmod usbdfu.o; insmod at76c503.o; insmod vnet503-rfmd.o +insmod usbdfu.o; insmod at76c503.o; insmod at76c503-rfmd.o -You can give the network device another name than eth by giving -the module the eth_name parameter. Eg. -insmod vnet503-rfmd.o eth_name=wlan%d -would give the first device the name wlan0, the second wlan1 etc... +You can give the network device another name than wlan by giving +the module the netdev_name parameter. Eg. +insmod at76c503-rfmd.o netdev_name=eth%d +would give the first device the name eth0, the second eth1 etc... Check if the modules are loaded with lsmod. It should look like this: ... -vnet503-rfmd 38656 0 (unused) -at76c503 34004 0 [vnet503-rfmd] -usbdfu 9144 0 [vnet503-rfmd] +at76c503-rfmd 38656 0 (unused) +at76c503 34004 0 [at76c503-rfmd] +usbdfu 9144 0 [at76c503-rfmd] ... -setup networking (replace <iface> with eth0, eth1, ..., <ch> with a +setup networking (replace <iface> with wlan0, wlan1, ..., <ch> with a channel number (1..14) <essid> with your network id (a string), <ip> with an IP address) @@ -69,8 +69,8 @@ iwconfig <iface> channel <ch> mode ad-hoc essid <essid> ifonfig <iface> <ip> up Example: -iwconfig eth2 mode ad-hoc channel 10 essid okuwlan -ifconfig eth2 192.168.3.1 up +iwconfig wlan2 mode ad-hoc channel 10 essid okuwlan +ifconfig wlan2 192.168.3.1 up Test it by pinging another host with a wlan adaptor. diff --git a/vnet503-i3861.c b/at76c503-i3861.c index 6c8a04c..c4ccc2c 100644 --- a/vnet503-i3861.c +++ b/at76c503-i3861.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- */ /* - * vnet503-i3861.c: + * at76c503-i3861.c: * * Driver for at76c503-based devices based on the Atmel "Fast-Vnet" reference * design using the Intersil 3861 radio chip @@ -26,9 +26,11 @@ * 2003_02_15 0.1: (alex) * - created 3861-specific driver file * + * 2003_02_18 0.2: (alex) + * - Reduced duplicated code and moved as much as possible into at76c503.c + * - Changed default netdev name to "wlan%d" */ -#include <linux/config.h> #include <linux/module.h> #include <linux/usb.h> @@ -41,7 +43,7 @@ /* Version Information */ -#define DRIVER_NAME "vnet503-i3861" +#define DRIVER_NAME "at76c503-i3861" #define DRIVER_AUTHOR "Oliver Kurth <oku@masqmail.cx>" #define DRIVER_DESC "Atmel at76c503 (Intersil 3861) Wireless LAN Driver" @@ -68,7 +70,7 @@ #define VENDOR_ID_DYNALINK 0x069a #define PRODUCT_ID_DYNALINK_WLL013_I 0x0320 /* Dynalink/Askey WLL013 (intersil) */ -static struct usb_device_id vnet_table[] = { +static struct usb_device_id dev_table[] = { { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_503I ) }, { USB_DEVICE(VENDOR_ID_LINKSYS, PRODUCT_ID_LINKSYS_WUSB11_V21) }, { USB_DEVICE(VENDOR_ID_NETGEAR, PRODUCT_ID_NETGEAR_MA101A ) }, @@ -79,8 +81,6 @@ static struct usb_device_id vnet_table[] = { { } }; -MODULE_DEVICE_TABLE (usb, vnet_table); - /* firmware / config variables */ static unsigned char fw_internal[] = FW_I3861_INTERNAL; @@ -90,151 +90,62 @@ static int board_type = BOARDTYPE_INTERSIL; /*---------------------------------------------------------------------------*/ -/* Module paramaters */ +MODULE_DEVICE_TABLE (usb, dev_table); -#ifdef CONFIG_USB_DEBUG -static int debug = 1; -#else -static int debug = 0; -#endif -MODULE_PARM(debug, "i"); -MODULE_PARM_DESC(debug, "Level of debugging messages"); +/* Module paramaters */ -static char eth_name[IFNAMSIZ+1] = "eth%d"; -MODULE_PARM(eth_name, "c" __MODULE_STRING(IFNAMSIZ)); -MODULE_PARM_DESC(eth_name, - "network device name (default is eth%d)"); +static char netdev_name[IFNAMSIZ+1] = "wlan%d"; +MODULE_PARM(netdev_name, "c" __MODULE_STRING(IFNAMSIZ)); +MODULE_PARM_DESC(netdev_name, + "network device name (default is wlan%d)"); /* local function prototypes */ -static void * vnet_probe(struct usb_device *dev, unsigned int ifnum, +static void *at76c50x_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id); -static void vnet_disconnect(struct usb_device *dev, void *ptr); -static int vnet_usbdfu_post(struct usb_device *udev); +static void at76c50x_disconnect(struct usb_device *dev, void *ptr); /* structure for registering this driver with the usb subsystem */ -static struct usb_driver vnet_driver = { +static struct usb_driver module_usb = { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) owner: THIS_MODULE, #endif name: DRIVER_NAME, - probe: vnet_probe, - disconnect: vnet_disconnect, - id_table: vnet_table, + probe: at76c50x_probe, + disconnect: at76c50x_disconnect, + id_table: dev_table, }; /* structure for registering this firmware with the usbdfu subsystem */ -static struct usbdfu_info vnet_usbdfu = { +static struct usbdfu_info module_usbdfu = { name: DRIVER_NAME, - id_table: vnet_table, + id_table: dev_table, fw_buf: fw_internal, fw_buf_len: sizeof(fw_internal), - post_download_hook: vnet_usbdfu_post, + post_download_hook: at76c503_usbdfu_post, }; -/* debug stuff */ - -#undef dbg -#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg); } while (0) +/* Module and USB entry points */ -/** - * vnet_usbdfu_post - * - * Called by usbdfu after the firmware has been downloaded to the device, - * before the final reset. - * (this is called in a usb probe (khubd) context) - */ -static int vnet_usbdfu_post(struct usb_device *udev) -{ - int result; - - dbg("Sending remap command..."); - result = at76c503_remap(udev, 1); - if (result < 0) { - err("Remap command failed (%d)", result); - return result; - } - return 0; -} - -/** - * vnet_probe - * - * Called by the usb core when a compatible device is plugged into the - * system. - */ -static void *vnet_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id) +static void *at76c50x_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id) { - int ret; - struct at76c503 *dev; - if (usbdfu_in_use(udev, ifnum)) { /* the device is in DFU mode and usbdfu.c is handling it */ return NULL; } - usb_inc_dev_use(udev); - - if ((ret = usb_get_configuration(udev)) != 0) { - err("get configuration failed: %d", ret); - goto error; - } - - if ((ret = usb_set_configuration(udev, 1)) != 0) { - err("set configuration to 1 failed: %d", ret); - goto error; - } - - ret = at76c503_download_external_fw(udev, fw_external, - sizeof(fw_external)); - if (ret < 0) { - err("Downloading external firmware failed: %d", ret); - goto error; - } - - dev = at76c503_new_device(udev, board_type, eth_name); - if (!dev) { - dbg("at76c503_new_device returned NULL"); - goto error; - } - - SET_MODULE_OWNER(dev->netdev); - ret = register_netdev(dev->netdev); - if (ret) { - err("Unable to register netdevice %s (status %d)!", - dev->netdev->name, ret); - at76c503_delete_device(dev); - goto error; - } - - return dev; - - error: - usb_dec_dev_use(udev); - return NULL; + return at76c503_do_probe(THIS_MODULE, udev, fw_external, sizeof(fw_external), board_type, netdev_name); } -/** - * vnet_disconnect - * - * Called by the usb core when the device is removed from the system. - */ -static void vnet_disconnect(struct usb_device *udev, void *ptr) +static void at76c50x_disconnect(struct usb_device *udev, void *ptr) { - struct at76c503 *dev = (struct at76c503 *)ptr; - - dbg("udev=%p, ptr=%p", udev, ptr); - - info("%s disconnected", dev->netdev->name); - - unregister_netdev(dev->netdev); - at76c503_delete_device(dev); - usb_dec_dev_use(udev); + info("%s disconnected", ((struct at76c503 *)ptr)->netdev->name); + at76c503_delete_device(ptr); } -static int __init vnet_init(void) +static int __init mod_init(void) { int result; @@ -242,32 +153,33 @@ static int __init vnet_init(void) /* register with usbdfu so that the firmware will be automatically * downloaded to the device on detection */ - result = usbdfu_register(&vnet_usbdfu); + result = usbdfu_register(&module_usbdfu); if (result < 0) { err("usbdfu_register failed (status %d)", result); return -1; } /* register this driver with the USB subsystem */ - result = usb_register(&vnet_driver); + result = usb_register(&module_usb); if (result < 0) { err("usb_register failed (status %d)", result); + usbdfu_deregister(&module_usbdfu); return -1; } return 0; } -static void __exit vnet_exit(void) +static void __exit mod_exit(void) { info(DRIVER_DESC " " DRIVER_VERSION " unloading"); /* deregister this driver with the USB subsystem */ - usbdfu_deregister(&vnet_usbdfu); - usb_deregister(&vnet_driver); + usbdfu_deregister(&module_usbdfu); + usb_deregister(&module_usb); } -module_init (vnet_init); -module_exit (vnet_exit); +module_init (mod_init); +module_exit (mod_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/at76c503-i3863.c b/at76c503-i3863.c new file mode 100644 index 0000000..2fd86a7 --- /dev/null +++ b/at76c503-i3863.c @@ -0,0 +1,166 @@ +/* -*- linux-c -*- */ +/* + * at76c503-i3863.c: + * + * Driver for at76c503-based devices based on the Atmel "Fast-Vnet" reference + * design using the Intersil 3863 radio chip + * + * Copyright (c) 2002 - 2003 Oliver Kurth <oku@masqmail.cx> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * + * This driver is derived from usb-skeleton.c + * + * This driver contains code specific to Atmel AT76C503 (USB wireless 802.11) + * devices which use the Intersil 3863 radio chip. Almost all of the actual + * driver is handled by the generic at76c503.c module, this file mostly just + * deals with the initial probes and downloading the correct firmware to the + * device before handing it off to at76c503. + * + * History: + * + * 2003_02_15 0.1: (alex) + * - created 3863-specific driver file + * + * 2003_02_18 0.2: (alex) + * - Reduced duplicated code and moved as much as possible into at76c503.c + * - Changed default netdev name to "wlan%d" + */ + +#include <linux/module.h> +#include <linux/usb.h> + +#include "at76c503.h" +#include "usbdfu.h" + +/* Include firmware data definition */ + +#include "fw-i3863.h" + +/* Version Information */ + +#define DRIVER_NAME "at76c503-i3863" +#define DRIVER_AUTHOR "Oliver Kurth <oku@masqmail.cx>" +#define DRIVER_DESC "Atmel at76c503 (Intersil 3863) Wireless LAN Driver" + +/* USB Device IDs supported by this driver */ + +#define VENDOR_ID_ATMEL 0x03eb +#define PRODUCT_ID_ATMEL_503_I3863 0x7604 /* Generic AT76C503/3863 device */ + +#define VENDOR_ID_SAMSUNG 0x055d +#define PRODUCT_ID_SAMSUNG_SWL2100U 0xa000 /* Samsung SWL-2100U */ + +static struct usb_device_id dev_table[] = { + { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_503_I3863 ) }, + { USB_DEVICE(VENDOR_ID_SAMSUNG, PRODUCT_ID_SAMSUNG_SWL2100U) }, + { } +}; + +/* firmware / config variables */ + +static unsigned char fw_internal[] = FW_I3863_INTERNAL; +static unsigned char fw_external[] = FW_I3863_EXTERNAL; + +static int board_type = BOARDTYPE_INTERSIL; + +/*---------------------------------------------------------------------------*/ + +MODULE_DEVICE_TABLE (usb, dev_table); + +/* Module paramaters */ + +static char netdev_name[IFNAMSIZ+1] = "wlan%d"; +MODULE_PARM(netdev_name, "c" __MODULE_STRING(IFNAMSIZ)); +MODULE_PARM_DESC(netdev_name, + "network device name (default is wlan%d)"); + +/* local function prototypes */ + +static void *at76c50x_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id); +static void at76c50x_disconnect(struct usb_device *dev, void *ptr); + +/* structure for registering this driver with the usb subsystem */ + +static struct usb_driver module_usb = { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) + owner: THIS_MODULE, +#endif + name: DRIVER_NAME, + probe: at76c50x_probe, + disconnect: at76c50x_disconnect, + id_table: dev_table, +}; + +/* structure for registering this firmware with the usbdfu subsystem */ + +static struct usbdfu_info module_usbdfu = { + name: DRIVER_NAME, + id_table: dev_table, + fw_buf: fw_internal, + fw_buf_len: sizeof(fw_internal), + post_download_hook: at76c503_usbdfu_post, +}; + +/* Module and USB entry points */ + +static void *at76c50x_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id) +{ + if (usbdfu_in_use(udev, ifnum)) { + /* the device is in DFU mode and usbdfu.c is handling it */ + return NULL; + } + + return at76c503_do_probe(THIS_MODULE, udev, fw_external, sizeof(fw_external), board_type, netdev_name); +} + +static void at76c50x_disconnect(struct usb_device *udev, void *ptr) +{ + info("%s disconnected", ((struct at76c503 *)ptr)->netdev->name); + at76c503_delete_device(ptr); +} + +static int __init mod_init(void) +{ + int result; + + info(DRIVER_DESC " " DRIVER_VERSION); + + /* register with usbdfu so that the firmware will be automatically + * downloaded to the device on detection */ + result = usbdfu_register(&module_usbdfu); + if (result < 0) { + err("usbdfu_register failed (status %d)", result); + return -1; + } + + /* register this driver with the USB subsystem */ + result = usb_register(&module_usb); + if (result < 0) { + err("usb_register failed (status %d)", result); + usbdfu_deregister(&module_usbdfu); + return -1; + } + + return 0; +} + +static void __exit mod_exit(void) +{ + info(DRIVER_DESC " " DRIVER_VERSION " unloading"); + /* deregister this driver with the USB subsystem */ + usbdfu_deregister(&module_usbdfu); + usb_deregister(&module_usb); +} + +module_init (mod_init); +module_exit (mod_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); diff --git a/vnet503-rfmd.c b/at76c503-rfmd.c index 553b6e7..b73c28f 100644 --- a/vnet503-rfmd.c +++ b/at76c503-rfmd.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- */ /* - * vnet503-rfmd.c: + * at76c503-rfmd.c: * * Driver for at76c503-based devices based on the Atmel "Fast-Vnet" reference * design using RFMD radio chips @@ -27,9 +27,11 @@ * - split board-specific code off from at76c503.c * - reverted to 0.90.2 firmware because 0.100.x is broken for WUSB11 * + * 2003_02_18 0.2: (alex) + * - Reduced duplicated code and moved as much as possible into at76c503.c + * - Changed default netdev name to "wlan%d" */ -#include <linux/config.h> #include <linux/module.h> #include <linux/usb.h> @@ -42,7 +44,7 @@ /* Version Information */ -#define DRIVER_NAME "vnet503-rfmd" +#define DRIVER_NAME "at76c503-rfmd" #define DRIVER_AUTHOR "Oliver Kurth <oku@masqmail.cx>" #define DRIVER_DESC "Atmel at76c503 (RFMD) Wireless LAN Driver" @@ -63,7 +65,7 @@ #define VENDOR_ID_NETGEAR 0x0864 #define PRODUCT_ID_NETGEAR_MA101B 0x4102 /* Netgear MA 101 Rev. B */ -static struct usb_device_id vnet_table[] = { +static struct usb_device_id dev_table[] = { { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_503R ) }, { USB_DEVICE(VENDOR_ID_BELKIN, PRODUCT_ID_BELKIN_F5D6050 ) }, { USB_DEVICE(VENDOR_ID_DYNALINK, PRODUCT_ID_DYNALINK_WLL013_R ) }, @@ -72,8 +74,6 @@ static struct usb_device_id vnet_table[] = { { } }; -MODULE_DEVICE_TABLE (usb, vnet_table); - /* firmware / config variables */ static unsigned char fw_internal[] = FW_503RFMD_INTERNAL; @@ -83,151 +83,62 @@ static int board_type = BOARDTYPE_RFMD; /*---------------------------------------------------------------------------*/ -/* Module paramaters */ +MODULE_DEVICE_TABLE (usb, dev_table); -#ifdef CONFIG_USB_DEBUG -static int debug = 1; -#else -static int debug = 0; -#endif -MODULE_PARM(debug, "i"); -MODULE_PARM_DESC(debug, "Level of debugging messages"); +/* Module paramaters */ -static char eth_name[IFNAMSIZ+1] = "eth%d"; -MODULE_PARM(eth_name, "c" __MODULE_STRING(IFNAMSIZ)); -MODULE_PARM_DESC(eth_name, - "network device name (default is eth%d)"); +static char netdev_name[IFNAMSIZ+1] = "wlan%d"; +MODULE_PARM(netdev_name, "c" __MODULE_STRING(IFNAMSIZ)); +MODULE_PARM_DESC(netdev_name, + "network device name (default is wlan%d)"); /* local function prototypes */ -static void * vnet_probe(struct usb_device *dev, unsigned int ifnum, +static void *at76c50x_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id); -static void vnet_disconnect(struct usb_device *dev, void *ptr); -static int vnet_usbdfu_post(struct usb_device *udev); +static void at76c50x_disconnect(struct usb_device *dev, void *ptr); /* structure for registering this driver with the usb subsystem */ -static struct usb_driver vnet_driver = { +static struct usb_driver module_usb = { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) owner: THIS_MODULE, #endif name: DRIVER_NAME, - probe: vnet_probe, - disconnect: vnet_disconnect, - id_table: vnet_table, + probe: at76c50x_probe, + disconnect: at76c50x_disconnect, + id_table: dev_table, }; /* structure for registering this firmware with the usbdfu subsystem */ -static struct usbdfu_info vnet_usbdfu = { +static struct usbdfu_info module_usbdfu = { name: DRIVER_NAME, - id_table: vnet_table, + id_table: dev_table, fw_buf: fw_internal, fw_buf_len: sizeof(fw_internal), - post_download_hook: vnet_usbdfu_post, + post_download_hook: at76c503_usbdfu_post, }; -/* debug stuff */ - -#undef dbg -#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg); } while (0) +/* Module and USB entry points */ -/** - * vnet_usbdfu_post - * - * Called by usbdfu after the firmware has been downloaded to the device, - * before the final reset. - * (this is called in a usb probe (khubd) context) - */ -static int vnet_usbdfu_post(struct usb_device *udev) -{ - int result; - - dbg("Sending remap command..."); - result = at76c503_remap(udev, 1); - if (result < 0) { - err("Remap command failed (%d)", result); - return result; - } - return 0; -} - -/** - * vnet_probe - * - * Called by the usb core when a compatible device is plugged into the - * system. - */ -static void *vnet_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id) +static void *at76c50x_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id) { - int ret; - struct at76c503 *dev; - if (usbdfu_in_use(udev, ifnum)) { /* the device is in DFU mode and usbdfu.c is handling it */ return NULL; } - usb_inc_dev_use(udev); - - if ((ret = usb_get_configuration(udev)) != 0) { - err("get configuration failed: %d", ret); - goto error; - } - - if ((ret = usb_set_configuration(udev, 1)) != 0) { - err("set configuration to 1 failed: %d", ret); - goto error; - } - - ret = at76c503_download_external_fw(udev, fw_external, - sizeof(fw_external)); - if (ret < 0) { - err("Downloading external firmware failed: %d", ret); - goto error; - } - - dev = at76c503_new_device(udev, board_type, eth_name); - if (!dev) { - dbg("at76c503_new_device returned NULL"); - goto error; - } - - SET_MODULE_OWNER(dev->netdev); - ret = register_netdev(dev->netdev); - if (ret) { - err("Unable to register netdevice %s (status %d)!", - dev->netdev->name, ret); - at76c503_delete_device(dev); - goto error; - } - - return dev; - - error: - usb_dec_dev_use(udev); - return NULL; + return at76c503_do_probe(THIS_MODULE, udev, fw_external, sizeof(fw_external), board_type, netdev_name); } -/** - * vnet_disconnect - * - * Called by the usb core when the device is removed from the system. - */ -static void vnet_disconnect(struct usb_device *udev, void *ptr) +static void at76c50x_disconnect(struct usb_device *udev, void *ptr) { - struct at76c503 *dev = (struct at76c503 *)ptr; - - dbg("udev=%p, ptr=%p", udev, ptr); - - info("%s disconnected", dev->netdev->name); - - unregister_netdev(dev->netdev); - at76c503_delete_device(dev); - usb_dec_dev_use(udev); + info("%s disconnected", ((struct at76c503 *)ptr)->netdev->name); + at76c503_delete_device(ptr); } -static int __init vnet_init(void) +static int __init mod_init(void) { int result; @@ -235,32 +146,33 @@ static int __init vnet_init(void) /* register with usbdfu so that the firmware will be automatically * downloaded to the device on detection */ - result = usbdfu_register(&vnet_usbdfu); + result = usbdfu_register(&module_usbdfu); if (result < 0) { err("usbdfu_register failed (status %d)", result); return -1; } /* register this driver with the USB subsystem */ - result = usb_register(&vnet_driver); + result = usb_register(&module_usb); if (result < 0) { err("usb_register failed (status %d)", result); + usbdfu_deregister(&module_usbdfu); return -1; } return 0; } -static void __exit vnet_exit(void) +static void __exit mod_exit(void) { info(DRIVER_DESC " " DRIVER_VERSION " unloading"); /* deregister this driver with the USB subsystem */ - usbdfu_deregister(&vnet_usbdfu); - usb_deregister(&vnet_driver); + usbdfu_deregister(&module_usbdfu); + usb_deregister(&module_usb); } -module_init (vnet_init); -module_exit (vnet_exit); +module_init (mod_init); +module_exit (mod_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); @@ -423,45 +423,50 @@ static int get_hw_config(struct at76c503 *dev) struct hwcfg_intersil i; struct hwcfg_rfmd r3; struct hwcfg_r505 r5; - } hwcfg; + } *hwcfg = kmalloc(sizeof(*hwcfg), GFP_KERNEL); + + if (!hwcfg) + return -ENOMEM; switch (dev->board_type) { case BOARDTYPE_INTERSIL: - ret = get_hw_cfg_intersil(dev->udev, (unsigned char *)&hwcfg.i, sizeof(hwcfg.i)); + ret = get_hw_cfg_intersil(dev->udev, (unsigned char *)&hwcfg->i, sizeof(hwcfg->i)); if (ret < 0) break; - memcpy(dev->mac_addr, hwcfg.i.mac_addr, ETH_ALEN); - memcpy(dev->cr31_values, hwcfg.i.cr31_values, 14); - memcpy(dev->cr58_values, hwcfg.i.cr58_values, 14); - memcpy(dev->pidvid, hwcfg.i.pidvid, 4); - dev->regulatory_domain = hwcfg.i.regulatory_domain; + memcpy(dev->mac_addr, hwcfg->i.mac_addr, ETH_ALEN); + memcpy(dev->cr31_values, hwcfg->i.cr31_values, 14); + memcpy(dev->cr58_values, hwcfg->i.cr58_values, 14); + memcpy(dev->pidvid, hwcfg->i.pidvid, 4); + dev->regulatory_domain = hwcfg->i.regulatory_domain; break; case BOARDTYPE_RFMD: - ret = get_hw_cfg_rfmd(dev->udev, (unsigned char *)&hwcfg.r3, sizeof(hwcfg.r3)); + ret = get_hw_cfg_rfmd(dev->udev, (unsigned char *)&hwcfg->r3, sizeof(hwcfg->r3)); if (ret < 0) break; - memcpy(dev->cr20_values, hwcfg.r3.cr20_values, 14); - memcpy(dev->cr21_values, hwcfg.r3.cr21_values, 14); - memcpy(dev->bb_cr, hwcfg.r3.bb_cr, 14); - memcpy(dev->pidvid, hwcfg.r3.pidvid, 4); - memcpy(dev->mac_addr, hwcfg.r3.mac_addr, ETH_ALEN); - dev->regulatory_domain = hwcfg.r3.regulatory_domain; - memcpy(dev->low_power_values, hwcfg.r3.low_power_values, 14); - memcpy(dev->normal_power_values, hwcfg.r3.normal_power_values, 14); + memcpy(dev->cr20_values, hwcfg->r3.cr20_values, 14); + memcpy(dev->cr21_values, hwcfg->r3.cr21_values, 14); + memcpy(dev->bb_cr, hwcfg->r3.bb_cr, 14); + memcpy(dev->pidvid, hwcfg->r3.pidvid, 4); + memcpy(dev->mac_addr, hwcfg->r3.mac_addr, ETH_ALEN); + dev->regulatory_domain = hwcfg->r3.regulatory_domain; + memcpy(dev->low_power_values, hwcfg->r3.low_power_values, 14); + memcpy(dev->normal_power_values, hwcfg->r3.normal_power_values, 14); break; case BOARDTYPE_R505: - ret = get_hw_cfg_rfmd(dev->udev, (unsigned char *)&hwcfg.r5, sizeof(hwcfg.r5)); + ret = get_hw_cfg_rfmd(dev->udev, (unsigned char *)&hwcfg->r5, sizeof(hwcfg->r5)); if (ret < 0) break; - memcpy(dev->cr39_values, hwcfg.r5.cr39_values, 14); - memcpy(dev->bb_cr, hwcfg.r5.bb_cr, 14); - memcpy(dev->pidvid, hwcfg.r5.pidvid, 4); - memcpy(dev->mac_addr, hwcfg.r5.mac_addr, ETH_ALEN); - dev->regulatory_domain = hwcfg.r5.regulatory_domain; - memcpy(dev->cr15_values, hwcfg.r5.cr15_values, 14); + memcpy(dev->cr39_values, hwcfg->r5.cr39_values, 14); + memcpy(dev->bb_cr, hwcfg->r5.bb_cr, 14); + memcpy(dev->pidvid, hwcfg->r5.pidvid, 4); + memcpy(dev->mac_addr, hwcfg->r5.mac_addr, ETH_ALEN); + dev->regulatory_domain = hwcfg->r5.regulatory_domain; + memcpy(dev->cr15_values, hwcfg->r5.cr15_values, 14); break; default: err("Bad board type set (%d). Unable to get hardware config.", dev->board_type); - return -EINVAL; + ret = -EINVAL; } + kfree(hwcfg); + if (ret < 0) { err("Get HW Config failed (%d)", ret); } @@ -2356,7 +2361,7 @@ int at76c503_open(struct net_device *netdev) wait_completion(dev, CMD_SCAN); -// dump_bss_table(dev); + dump_bss_table(dev); if ((dev->curr_bss = find_matching_bss(dev,0)) >= 0) { ret = join_bss(dev, dev->curr_bss); @@ -2818,6 +2823,8 @@ int at76c503_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) void at76c503_delete_device(struct at76c503 *dev) { if(dev){ + unregister_netdevice(dev->netdev); + if(dev->bulk_in_buffer != NULL) kfree(dev->bulk_in_buffer); if(dev->bulk_out_buffer != NULL) @@ -3010,6 +3017,73 @@ struct at76c503 *at76c503_new_device(struct usb_device *udev, int board_type, co } +struct at76c503 *at76c503_do_probe(struct module *mod, struct usb_device *udev, u8 *extfw, int extfw_size, int board_type, const char *netdev_name) +{ + int ret; + struct at76c503 *dev; + + usb_inc_dev_use(udev); + + if ((ret = usb_get_configuration(udev)) != 0) { + err("get configuration failed: %d", ret); + goto error; + } + + if ((ret = usb_set_configuration(udev, 1)) != 0) { + err("set configuration to 1 failed: %d", ret); + goto error; + } + + if (extfw && extfw_size) { + ret = at76c503_download_external_fw(udev, extfw, extfw_size); + if (ret < 0) { + err("Downloading external firmware failed: %d", ret); + goto error; + } + } + + dev = at76c503_new_device(udev, board_type, netdev_name); + if (!dev) { + dbg("at76c503_new_device returned NULL"); + goto error; + } + + dev->netdev->owner = mod; + ret = register_netdev(dev->netdev); + if (ret) { + err("Unable to register netdevice %s (status %d)!", + dev->netdev->name, ret); + at76c503_delete_device(dev); + goto error; + } + + return dev; + +error: + usb_dec_dev_use(udev); + return NULL; +} + +/** + * at76c503_usbdfu_post + * + * Called by usbdfu driver after the firmware has been downloaded, before + * the final reset. + * (this is called in a usb probe (khubd) context) + */ + +int at76c503_usbdfu_post(struct usb_device *udev) +{ + int result; + + dbg("Sending remap command..."); + result = at76c503_remap(udev, 1); + if (result < 0) { + err("Remap command failed (%d)", result); + return result; + } + return 0; +} /** * at76c503_init @@ -3031,9 +3105,11 @@ static void __exit at76c503_exit(void) module_init (at76c503_init); module_exit (at76c503_exit); +EXPORT_SYMBOL(at76c503_do_probe); EXPORT_SYMBOL(at76c503_download_external_fw); EXPORT_SYMBOL(at76c503_new_device); EXPORT_SYMBOL(at76c503_delete_device); +EXPORT_SYMBOL(at76c503_usbdfu_post); EXPORT_SYMBOL(at76c503_remap); MODULE_AUTHOR(DRIVER_AUTHOR); @@ -460,9 +460,11 @@ struct at76c503 { /* Function prototypes */ +struct at76c503 *at76c503_do_probe(struct module *mod, struct usb_device *udev, u8 *extfw, int extfw_size, int board_type, const char *netdev_name); int at76c503_download_external_fw(struct usb_device *udev, u8 *buf, int size); struct at76c503 *at76c503_new_device(struct usb_device *udev, int board_type, const char *netdev_name); void at76c503_delete_device(struct at76c503 *dev); +int at76c503_usbdfu_post(struct usb_device *udev); int at76c503_remap(struct usb_device *udev, int wait); #endif /* _AT76C503_H */ diff --git a/at76c505-rfmd.c b/at76c505-rfmd.c new file mode 100644 index 0000000..42a7ad6 --- /dev/null +++ b/at76c505-rfmd.c @@ -0,0 +1,162 @@ +/* -*- linux-c -*- */ +/* + * at76c505-rfmd.c: + * + * Driver for at76c505-based devices based on the Atmel "Fast-Vnet" reference + * design using RFMD radio chips + * + * Copyright (c) 2002 - 2003 Oliver Kurth <oku@masqmail.cx> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * + * This driver is derived from usb-skeleton.c + * + * This driver contains code specific to Atmel AT76C505 (USB wireless 802.11) + * devices which use radio chips from RF Micro Devices (RFMD). Almost + * all of the actual driver is handled by the generic at76c503.c module, this + * file mostly just deals with the initial probes and downloading the correct + * firmware to the device before handing it off to at76c503. + * + * History: + * + * 2003_02_15 0.1: (alex) + * - created AT76C505-specific driver file + * + * 2003_02_18 0.2: (alex) + * - Reduced duplicated code and moved as much as possible into at76c503.c + * - Changed default netdev name to "wlan%d" + */ + +#include <linux/module.h> +#include <linux/usb.h> + +#include "at76c503.h" +#include "usbdfu.h" + +/* Include firmware data definition */ + +#include "fw-r505.h" + +/* Version Information */ + +#define DRIVER_NAME "at76c505-rfmd" +#define DRIVER_AUTHOR "Oliver Kurth <oku@masqmail.cx>" +#define DRIVER_DESC "Atmel at76c505 (RFMD) Wireless LAN Driver" + +/* USB Device IDs supported by this driver */ + +#define VENDOR_ID_ATMEL 0x03eb +#define PRODUCT_ID_ATMEL_505R 0x7606 /* Generic AT76C505/RFMD device */ + +static struct usb_device_id dev_table[] = { + { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_505R ) }, + { } +}; + +/* firmware / config variables */ + +static unsigned char fw_internal[] = FW_505RFMD_INTERNAL; +static unsigned char fw_external[] = FW_505RFMD_EXTERNAL; + +static int board_type = BOARDTYPE_R505; + +/*---------------------------------------------------------------------------*/ + +MODULE_DEVICE_TABLE (usb, dev_table); + +/* Module paramaters */ + +static char netdev_name[IFNAMSIZ+1] = "wlan%d"; +MODULE_PARM(netdev_name, "c" __MODULE_STRING(IFNAMSIZ)); +MODULE_PARM_DESC(netdev_name, + "network device name (default is wlan%d)"); + +/* local function prototypes */ + +static void *at76c50x_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id); +static void at76c50x_disconnect(struct usb_device *dev, void *ptr); + +/* structure for registering this driver with the usb subsystem */ + +static struct usb_driver module_usb = { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) + owner: THIS_MODULE, +#endif + name: DRIVER_NAME, + probe: at76c50x_probe, + disconnect: at76c50x_disconnect, + id_table: dev_table, +}; + +/* structure for registering this firmware with the usbdfu subsystem */ + +static struct usbdfu_info module_usbdfu = { + name: DRIVER_NAME, + id_table: dev_table, + fw_buf: fw_internal, + fw_buf_len: sizeof(fw_internal), + post_download_hook: at76c503_usbdfu_post, +}; + +/* Module and USB entry points */ + +static void *at76c50x_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id) +{ + if (usbdfu_in_use(udev, ifnum)) { + /* the device is in DFU mode and usbdfu.c is handling it */ + return NULL; + } + + return at76c503_do_probe(THIS_MODULE, udev, fw_external, sizeof(fw_external), board_type, netdev_name); +} + +static void at76c50x_disconnect(struct usb_device *udev, void *ptr) +{ + info("%s disconnected", ((struct at76c503 *)ptr)->netdev->name); + at76c503_delete_device(ptr); +} + +static int __init mod_init(void) +{ + int result; + + info(DRIVER_DESC " " DRIVER_VERSION); + + /* register with usbdfu so that the firmware will be automatically + * downloaded to the device on detection */ + result = usbdfu_register(&module_usbdfu); + if (result < 0) { + err("usbdfu_register failed (status %d)", result); + return -1; + } + + /* register this driver with the USB subsystem */ + result = usb_register(&module_usb); + if (result < 0) { + err("usb_register failed (status %d)", result); + usbdfu_deregister(&module_usbdfu); + return -1; + } + + return 0; +} + +static void __exit mod_exit(void) +{ + info(DRIVER_DESC " " DRIVER_VERSION " unloading"); + /* deregister this driver with the USB subsystem */ + usbdfu_deregister(&module_usbdfu); + usb_deregister(&module_usb); +} + +module_init (mod_init); +module_exit (mod_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); @@ -604,7 +604,7 @@ int usbdfu_in_use(struct usb_device *udev, unsigned int ifnum) * normal behavior in some cases (at76c503 immediately after * fw-load-reset), so just continue on (and hope we didn't * screw anything up with that DFU command).. */ - dbg("Bad data length returned from DFU state query (%d)", + dbg("DFU state query returned %d-byte response", result); return 0; } diff --git a/vnet503-i3863.c b/vnet503-i3863.c deleted file mode 100644 index 61a05a2..0000000 --- a/vnet503-i3863.c +++ /dev/null @@ -1,254 +0,0 @@ -/* -*- linux-c -*- */ -/* - * vnet503-i3863.c: - * - * Driver for at76c503-based devices based on the Atmel "Fast-Vnet" reference - * design using the Intersil 3863 radio chip - * - * Copyright (c) 2002 - 2003 Oliver Kurth <oku@masqmail.cx> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * - * This driver is derived from usb-skeleton.c - * - * This driver contains code specific to Atmel AT76C503 (USB wireless 802.11) - * devices which use the Intersil 3863 radio chip. Almost all of the actual - * driver is handled by the generic at76c503.c module, this file mostly just - * deals with the initial probes and downloading the correct firmware to the - * device before handing it off to at76c503. - * - * History: - * - * 2003_02_15 0.1: (alex) - * - created 3863-specific driver file - * - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/usb.h> - -#include "at76c503.h" -#include "usbdfu.h" - -/* Include firmware data definition */ - -#include "fw-i3863.h" - -/* Version Information */ - -#define DRIVER_NAME "vnet503-i3863" -#define DRIVER_AUTHOR "Oliver Kurth <oku@masqmail.cx>" -#define DRIVER_DESC "Atmel at76c503 (Intersil 3863) Wireless LAN Driver" - -/* USB Device IDs supported by this driver */ - -#define VENDOR_ID_ATMEL 0x03eb -#define PRODUCT_ID_ATMEL_503_I3863 0x7604 /* Generic AT76C503/3863 device */ - -#define VENDOR_ID_SAMSUNG 0x055d -#define PRODUCT_ID_SAMSUNG_SWL2100U 0xa000 /* Samsung SWL-2100U */ - -static struct usb_device_id vnet_table[] = { - { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_503_I3863 ) }, - { USB_DEVICE(VENDOR_ID_SAMSUNG, PRODUCT_ID_SAMSUNG_SWL2100U) }, - { } -}; - -MODULE_DEVICE_TABLE (usb, vnet_table); - -/* firmware / config variables */ - -static unsigned char fw_internal[] = FW_I3863_INTERNAL; -static unsigned char fw_external[] = FW_I3863_EXTERNAL; - -static int board_type = BOARDTYPE_INTERSIL; - -/*---------------------------------------------------------------------------*/ - -/* Module paramaters */ - -#ifdef CONFIG_USB_DEBUG -static int debug = 1; -#else -static int debug = 0; -#endif -MODULE_PARM(debug, "i"); -MODULE_PARM_DESC(debug, "Level of debugging messages"); - -static char eth_name[IFNAMSIZ+1] = "eth%d"; -MODULE_PARM(eth_name, "c" __MODULE_STRING(IFNAMSIZ)); -MODULE_PARM_DESC(eth_name, - "network device name (default is eth%d)"); - -/* local function prototypes */ - -static void * vnet_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id); -static void vnet_disconnect(struct usb_device *dev, void *ptr); -static int vnet_usbdfu_post(struct usb_device *udev); - -/* structure for registering this driver with the usb subsystem */ - -static struct usb_driver vnet_driver = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) - owner: THIS_MODULE, -#endif - name: DRIVER_NAME, - probe: vnet_probe, - disconnect: vnet_disconnect, - id_table: vnet_table, -}; - -/* structure for registering this firmware with the usbdfu subsystem */ - -static struct usbdfu_info vnet_usbdfu = { - name: DRIVER_NAME, - id_table: vnet_table, - fw_buf: fw_internal, - fw_buf_len: sizeof(fw_internal), - post_download_hook: vnet_usbdfu_post, -}; - -/* debug stuff */ - -#undef dbg -#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg); } while (0) - -/** - * vnet_usbdfu_post - * - * Called by usbdfu after the firmware has been downloaded to the device, - * before the final reset. - * (this is called in a usb probe (khubd) context) - */ -static int vnet_usbdfu_post(struct usb_device *udev) -{ - int result; - - dbg("Sending remap command..."); - result = at76c503_remap(udev, 1); - if (result < 0) { - err("Remap command failed (%d)", result); - return result; - } - return 0; -} - -/** - * vnet_probe - * - * Called by the usb core when a compatible device is plugged into the - * system. - */ -static void *vnet_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id) -{ - int ret; - struct at76c503 *dev; - - if (usbdfu_in_use(udev, ifnum)) { - /* the device is in DFU mode and usbdfu.c is handling it */ - return NULL; - } - - usb_inc_dev_use(udev); - - if ((ret = usb_get_configuration(udev)) != 0) { - err("get configuration failed: %d", ret); - goto error; - } - - if ((ret = usb_set_configuration(udev, 1)) != 0) { - err("set configuration to 1 failed: %d", ret); - goto error; - } - - ret = at76c503_download_external_fw(udev, fw_external, - sizeof(fw_external)); - if (ret < 0) { - err("Downloading external firmware failed: %d", ret); - goto error; - } - - dev = at76c503_new_device(udev, board_type, eth_name); - if (!dev) { - dbg("at76c503_new_device returned NULL"); - goto error; - } - - SET_MODULE_OWNER(dev->netdev); - ret = register_netdev(dev->netdev); - if (ret) { - err("Unable to register netdevice %s (status %d)!", - dev->netdev->name, ret); - at76c503_delete_device(dev); - goto error; - } - - return dev; - - error: - usb_dec_dev_use(udev); - return NULL; -} - -/** - * vnet_disconnect - * - * Called by the usb core when the device is removed from the system. - */ -static void vnet_disconnect(struct usb_device *udev, void *ptr) -{ - struct at76c503 *dev = (struct at76c503 *)ptr; - - dbg("udev=%p, ptr=%p", udev, ptr); - - info("%s disconnected", dev->netdev->name); - - unregister_netdev(dev->netdev); - at76c503_delete_device(dev); - usb_dec_dev_use(udev); -} - -static int __init vnet_init(void) -{ - int result; - - info(DRIVER_DESC " " DRIVER_VERSION); - - /* register with usbdfu so that the firmware will be automatically - * downloaded to the device on detection */ - result = usbdfu_register(&vnet_usbdfu); - if (result < 0) { - err("usbdfu_register failed (status %d)", result); - return -1; - } - - /* register this driver with the USB subsystem */ - result = usb_register(&vnet_driver); - if (result < 0) { - err("usb_register failed (status %d)", result); - return -1; - } - - return 0; -} - -static void __exit vnet_exit(void) -{ - info(DRIVER_DESC " " DRIVER_VERSION " unloading"); - /* deregister this driver with the USB subsystem */ - usbdfu_deregister(&vnet_usbdfu); - usb_deregister(&vnet_driver); -} - -module_init (vnet_init); -module_exit (vnet_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/vnet505-rfmd.c b/vnet505-rfmd.c deleted file mode 100644 index cd457ce..0000000 --- a/vnet505-rfmd.c +++ /dev/null @@ -1,250 +0,0 @@ -/* -*- linux-c -*- */ -/* - * vnet505-rfmd.c: - * - * Driver for at76c505-based devices based on the Atmel "Fast-Vnet" reference - * design using RFMD radio chips - * - * Copyright (c) 2002 - 2003 Oliver Kurth <oku@masqmail.cx> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * - * This driver is derived from usb-skeleton.c - * - * This driver contains code specific to Atmel AT76C505 (USB wireless 802.11) - * devices which use radio chips from RF Micro Devices (RFMD). Almost - * all of the actual driver is handled by the generic at76c503.c module, this - * file mostly just deals with the initial probes and downloading the correct - * firmware to the device before handing it off to at76c503. - * - * History: - * - * 2003_02_15 0.1: (alex) - * - created AT76C505-specific driver file - * - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/usb.h> - -#include "at76c503.h" -#include "usbdfu.h" - -/* Include firmware data definition */ - -#include "fw-r505.h" - -/* Version Information */ - -#define DRIVER_NAME "vnet505-rfmd" -#define DRIVER_AUTHOR "Oliver Kurth <oku@masqmail.cx>" -#define DRIVER_DESC "Atmel at76c505 (RFMD) Wireless LAN Driver" - -/* USB Device IDs supported by this driver */ - -#define VENDOR_ID_ATMEL 0x03eb -#define PRODUCT_ID_ATMEL_505R 0x7606 /* Generic AT76C505/RFMD device */ - -static struct usb_device_id vnet_table[] = { - { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_505R ) }, - { } -}; - -MODULE_DEVICE_TABLE (usb, vnet_table); - -/* firmware / config variables */ - -static unsigned char fw_internal[] = FW_505RFMD_INTERNAL; -static unsigned char fw_external[] = FW_505RFMD_EXTERNAL; - -static int board_type = BOARDTYPE_R505; - -/*---------------------------------------------------------------------------*/ - -/* Module paramaters */ - -#ifdef CONFIG_USB_DEBUG -static int debug = 1; -#else -static int debug = 0; -#endif -MODULE_PARM(debug, "i"); -MODULE_PARM_DESC(debug, "Level of debugging messages"); - -static char eth_name[IFNAMSIZ+1] = "eth%d"; -MODULE_PARM(eth_name, "c" __MODULE_STRING(IFNAMSIZ)); -MODULE_PARM_DESC(eth_name, - "network device name (default is eth%d)"); - -/* local function prototypes */ - -static void * vnet_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id); -static void vnet_disconnect(struct usb_device *dev, void *ptr); -static int vnet_usbdfu_post(struct usb_device *udev); - -/* structure for registering this driver with the usb subsystem */ - -static struct usb_driver vnet_driver = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) - owner: THIS_MODULE, -#endif - name: DRIVER_NAME, - probe: vnet_probe, - disconnect: vnet_disconnect, - id_table: vnet_table, -}; - -/* structure for registering this firmware with the usbdfu subsystem */ - -static struct usbdfu_info vnet_usbdfu = { - name: DRIVER_NAME, - id_table: vnet_table, - fw_buf: fw_internal, - fw_buf_len: sizeof(fw_internal), - post_download_hook: vnet_usbdfu_post, -}; - -/* debug stuff */ - -#undef dbg -#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg); } while (0) - -/** - * vnet_usbdfu_post - * - * Called by usbdfu after the firmware has been downloaded to the device, - * before the final reset. - * (this is called in a usb probe (khubd) context) - */ -static int vnet_usbdfu_post(struct usb_device *udev) -{ - int result; - - dbg("Sending remap command..."); - result = at76c503_remap(udev, 1); - if (result < 0) { - err("Remap command failed (%d)", result); - return result; - } - return 0; -} - -/** - * vnet_probe - * - * Called by the usb core when a compatible device is plugged into the - * system. - */ -static void *vnet_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id) -{ - int ret; - struct at76c503 *dev; - - if (usbdfu_in_use(udev, ifnum)) { - /* the device is in DFU mode and usbdfu.c is handling it */ - return NULL; - } - - usb_inc_dev_use(udev); - - if ((ret = usb_get_configuration(udev)) != 0) { - err("get configuration failed: %d", ret); - goto error; - } - - if ((ret = usb_set_configuration(udev, 1)) != 0) { - err("set configuration to 1 failed: %d", ret); - goto error; - } - - ret = at76c503_download_external_fw(udev, fw_external, - sizeof(fw_external)); - if (ret < 0) { - err("Downloading external firmware failed: %d", ret); - goto error; - } - - dev = at76c503_new_device(udev, board_type, eth_name); - if (!dev) { - dbg("at76c503_new_device returned NULL"); - goto error; - } - - SET_MODULE_OWNER(dev->netdev); - ret = register_netdev(dev->netdev); - if (ret) { - err("Unable to register netdevice %s (status %d)!", - dev->netdev->name, ret); - at76c503_delete_device(dev); - goto error; - } - - return dev; - - error: - usb_dec_dev_use(udev); - return NULL; -} - -/** - * vnet_disconnect - * - * Called by the usb core when the device is removed from the system. - */ -static void vnet_disconnect(struct usb_device *udev, void *ptr) -{ - struct at76c503 *dev = (struct at76c503 *)ptr; - - dbg("udev=%p, ptr=%p", udev, ptr); - - info("%s disconnected", dev->netdev->name); - - unregister_netdev(dev->netdev); - at76c503_delete_device(dev); - usb_dec_dev_use(udev); -} - -static int __init vnet_init(void) -{ - int result; - - info(DRIVER_DESC " " DRIVER_VERSION); - - /* register with usbdfu so that the firmware will be automatically - * downloaded to the device on detection */ - result = usbdfu_register(&vnet_usbdfu); - if (result < 0) { - err("usbdfu_register failed (status %d)", result); - return -1; - } - - /* register this driver with the USB subsystem */ - result = usb_register(&vnet_driver); - if (result < 0) { - err("usb_register failed (status %d)", result); - return -1; - } - - return 0; -} - -static void __exit vnet_exit(void) -{ - info(DRIVER_DESC " " DRIVER_VERSION " unloading"); - /* deregister this driver with the USB subsystem */ - usbdfu_deregister(&vnet_usbdfu); - usb_deregister(&vnet_driver); -} - -module_init (vnet_init); -module_exit (vnet_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); |