⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at76c503.c

📁 无线网卡驱动程序 802.11b无线网卡可直接移植到2.6内核中去
💻 C
📖 第 1 页 / 共 5 页
字号:
/* -*- linux-c -*- *//* $Id: at76c503.c,v 1.84 2006/06/22 21:09:23 agx Exp $ * * USB at76c503/at76c505 driver * * Copyright (c) 2002 - 2003 Oliver Kurth * Copyright (c) 2004 Joerg Albert <joerg.albert@gmx.de> * Copyright (c) 2004 Nick Jones * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com> * *	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 file is part of the Berlios driver for WLAN USB devices based on the * Atmel AT76C503A/505/505A. See at76c503.h for details. * * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed * * History: * * 2002_12_31: * - first ping, ah-hoc mode works, fw version 0.90.2 only * * 2003_01_07 0.1: * - first release * * 2003_01_08 0.2: * - moved rx code into tasklet * - added locking in keventd handler * - support big endian in ieee802_11.h * - external firmware downloader now in this module * * 2003_01_10 0.3: * - now using 8 spaces for tab indentations * - added tx rate settings (patch from Joerg Albert (jal)) * - created functions for mib settings * * 2003_01_19 0.4: * - use usbdfu for the internal firmware * * 2003_01_27 0.5: * - implemented WEP. Thanks to jal * - added frag and rts ioctl calls (jal again) * - module parameter to give names other than eth * * 2003_01_28 0.6: * - make it compile with kernel < 2.4.20 (there is no owner field *   in struct usb_driver) * - fixed a small bug for the module param eth_name * - do not use GFP_DMA, GFP_KERNEL is enough * - no down() in _tx() because that's in interrupt. Use *   spin_lock_irq() instead * - should not stop net queue on urb errors * - cleanup in ioctl(): locked it altogether, this makes it easier *   to maintain * - tried to implement promisc. mode: does not work with this device * - tried to implement setting mac address: does not *   seem to work with this device * - now use fw version 0.90.2 #140 (prev. was #93). Does not help... * * 2003_01_30 0.7: * - now works with fw 0.100.2 (solution was: wait for completion *   of commands) * - setting MAC address now works (thx to a small fix by jal) * - it turned out that promisc. mode is not possible. The firmware *   does not allow it. I hope that it will be implemented in a future *   version. * * 2003_02_13 0.8: * - scan mode implemented by jal * - infra structure mode by jal * - some small cleanups (removed dead code) * * history can now be found in the cvs log at http://at76c503a.berlios.de *  * TODO: * - monitor mode * */#include <linux/config.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/signal.h>#include <linux/errno.h>#include <linux/poll.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/fcntl.h>#include <linux/module.h>#include <linux/spinlock.h>#include <linux/list.h>#include <linux/smp_lock.h>#include <linux/devfs_fs_kernel.h>#include <linux/usb.h>#include <linux/netdevice.h>#include <linux/if_arp.h>#include <linux/etherdevice.h>#include <linux/ethtool.h>#include <asm/uaccess.h>#include <linux/wireless.h>#include <net/iw_handler.h>#include <linux/rtnetlink.h>  /* for rtnl_lock() */#include <net/iw_handler.h>#ifdef CONFIG_IPAQ_HANDHELD#include <asm/mach-types.h>#include <asm/arch-sa1100/h3600.h>#endif#include "at76c503.h"#include "at76_ieee802_11.h"#include "at76_usbdfu.h"/* timeout in seconds for the usb_control_msg in get_cmd_status * and set_card_command */#ifndef USB_CTRL_GET_TIMEOUT# define USB_CTRL_GET_TIMEOUT 5#endif/* number of endpoints of an interface */#define NUM_EP(intf) (intf)->altsetting[0].desc.bNumEndpoints#define EP(intf,nr) (intf)->altsetting[0].endpoint[(nr)].desc#define GET_DEV(udev) usb_get_dev((udev))#define PUT_DEV(udev) usb_put_dev((udev))#define SET_NETDEV_OWNER(ndev,owner) /* not needed anymore ??? */static inline int submit_urb(struct urb *urb, int mem_flags) {	return usb_submit_urb(urb, mem_flags);}static inline struct urb *alloc_urb(int iso_pk, int mem_flags) {	return usb_alloc_urb(iso_pk, mem_flags);}/* Backwards compatibility for usb_kill_urb() */#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)#  define usb_kill_urb usb_unlink_urb#endif#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9)# define eth_hdr(s) (s)->mac.ethernet# define set_eth_hdr(s,p) (s)->mac.ethernet=(p)#else# define set_eth_hdr(s,p) (s)->mac.raw=(unsigned char *)(p)#endif/* wireless extension level this source currently supports */#define WIRELESS_EXT_SUPPORTED	16#ifndef USB_ST_URB_PENDING#define USB_ST_URB_PENDING	(-EINPROGRESS)#define USB_ST_STALL		(-EPIPE)#endif#ifndef USB_ASYNC_UNLINK#ifdef URB_ASYNC_UNLINK#define USB_ASYNC_UNLINK	URB_ASYNC_UNLINK#else#define USB_ASYNC_UNLINK	0#endif#endif#ifndef FILL_BULK_URB#define FILL_BULK_URB(a,b,c,d,e,f,g) usb_fill_bulk_urb(a,b,c,d,e,f,g)#endif/* debug bits */#define DBG_PROGRESS        0x00000001 /* progress of scan-join-(auth-assoc)-connected */#define DBG_BSS_TABLE       0x00000002 /* show the bss table after scans */#define DBG_IOCTL           0x00000004 /* ioctl calls / settings */#define DBG_KEVENT          0x00000008 /* kevents */#define DBG_TX_DATA         0x00000010 /* tx header */#define DBG_TX_DATA_CONTENT 0x00000020 /* tx content */#define DBG_TX_MGMT         0x00000040#define DBG_RX_DATA         0x00000080 /* rx data header */#define DBG_RX_DATA_CONTENT 0x00000100 /* rx data content */#define DBG_RX_MGMT         0x00000200 /* rx mgmt header except beacon and probe responses */#define DBG_RX_BEACON       0x00000400 /* rx beacon */#define DBG_RX_CTRL         0x00000800 /* rx control */#define DBG_RX_MGMT_CONTENT 0x00001000 /* rx mgmt content */#define DBG_RX_FRAGS        0x00002000 /* rx data fragment handling */#define DBG_DEVSTART        0x00004000 /* fw download, device start */#define DBG_URB             0x00008000 /* rx urb status, ... */#define DBG_RX_ATMEL_HDR    0x00010000 /* the atmel specific header of each rx packet */#define DBG_PROC_ENTRY      0x00020000 /* procedure entries and exits */#define DBG_PM              0x00040000 /* power management settings */#define DBG_BSS_MATCH       0x00080000 /* show why a certain bss did not match */#define DBG_PARAMS          0x00100000 /* show the configured parameters */#define DBG_WAIT_COMPLETE   0x00200000 /* show the wait_completion progress */#define DBG_RX_FRAGS_SKB    0x00400000 /* show skb header for incoming rx fragments */#define DBG_BSS_TABLE_RM    0x00800000 /* inform on removal of old bss table entries */#define DBG_MONITOR_MODE    0x01000000 /* debugs from monitor mode */#define DBG_MIB             0x02000000 /* dump all MIBs in startup_device */#define DBG_MGMT_TIMER      0x04000000 /* dump mgmt_timer ops */#define DBG_WE_EVENTS       0x08000000 /* dump wireless events */#define DBG_DEFAULTS 0static int debug = DBG_DEFAULTS;static const u8 zeros[32];/* Use our own dbg macro */#undef dbg#define dbg(bits, format, arg...) \	do { \		if (debug & (bits)) \		printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg);\	} while (0)/* uncond. debug output */#define dbg_uc(format, arg...) \  printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg)#ifndef min#define min(x,y) ((x) < (y) ? (x) : (y))#endif#define assert(x) \  do {\   if (!(x)) \     err(__FILE__ ":%d assertion " #x " failed", __LINE__);\  } while (0)/* how often do we re-try these packets ? */#define AUTH_RETRIES  3#define ASSOC_RETRIES 3#define DISASSOC_RETRIES 3#ifdef CONFIG_IPAQ_HANDHELD#define scan_hook(x)						\	do {							\		if (machine_is_h5400()) {			\			if (x)					\				ipaq_led_blink (RED_LED, 1, 2);	\			else					\				ipaq_led_off (RED_LED);		\		}						\	} while (0)#else#define scan_hook(x)#endif#define NEW_STATE(dev,newstate) \  do {\    scan_hook(newstate == SCANNING);		\    dbg(DBG_PROGRESS, "%s: state %d -> %d (" #newstate ")",\        dev->netdev->name, dev->istate, newstate);\    dev->istate = newstate;\  } while (0)/* the beacon timeout in infra mode when we are connected (in seconds) */#define BEACON_TIMEOUT 10/* the interval in ticks we poll if scan is completed */#define SCAN_POLL_INTERVAL (HZ/4)/* Version Information */#define DRIVER_DESC "Generic Atmel at76c503/at76c505 routines"#define DRIVER_AUTHOR \"Oliver Kurth, Joerg Albert <joerg.albert@gmx.de>, Alex, Nick Jones, "\"Balint Seeber <n0_5p4m_p13453@hotmail.com>"/* Module paramaters */module_param(debug, int, 0400);MODULE_PARM_DESC(debug, "Debugging level");static int rx_copybreak = 200;module_param(rx_copybreak, int, 0400);MODULE_PARM_DESC(rx_copybreak, "rx packet copy threshold");static int scan_min_time = 10;module_param(scan_min_time, int, 0400);MODULE_PARM_DESC(scan_min_time, "scan min channel time (default: 10)");static int scan_max_time = 120;module_param(scan_max_time, int, 0400);MODULE_PARM_DESC(scan_max_time, "scan max channel time (default: 120)");static int scan_mode = SCAN_TYPE_ACTIVE;module_param(scan_mode, int, 0400);MODULE_PARM_DESC(scan_mode, "scan mode: 0 active (with ProbeReq, default), 1 passive");static int preamble_type = PREAMBLE_TYPE_LONG;module_param(preamble_type, int, 0400);MODULE_PARM_DESC(preamble_type, "preamble type: 0 long (default), 1 short");static int auth_mode = 0;module_param(auth_mode, int, 0400);MODULE_PARM_DESC(auth_mode, "authentication mode: 0 open system (default), "		 "1 shared secret");static int pm_mode = PM_ACTIVE;module_param(pm_mode, int, 0400);MODULE_PARM_DESC(pm_mode, "power management mode: 1 active (def.), 2 powersave, 3 smart save");static int pm_period = 0;module_param(pm_period, int, 0400);MODULE_PARM_DESC(pm_period, "period of waking up the device in usec");static int international_roaming = IR_OFF;module_param(international_roaming, int, 0400);MODULE_PARM_DESC(international_roaming, "enable international roaming: 0 (no, default), 1 (yes)");static int default_iw_mode = IW_MODE_INFRA;module_param(default_iw_mode, int, 0400);MODULE_PARM_DESC(default_iw_mode, "default IW mode for a new device: "		 "1 (ad-hoc), 2 (infrastructure, def.), 6 (monitor mode)");static int monitor_scan_min_time = 50;module_param(monitor_scan_min_time, int, 0400);MODULE_PARM_DESC(monitor_scan_min_time, "scan min channel time in MONITOR MODE (default: 50)");static int monitor_scan_max_time = 600;module_param(monitor_scan_max_time, int, 0400);MODULE_PARM_DESC(monitor_scan_max_time, "scan max channel time in MONITOR MODE (default: 600)");#define DEF_RTS_THRESHOLD 1536#define DEF_FRAG_THRESHOLD 1536#define DEF_SHORT_RETRY_LIMIT 8//#define DEF_LONG_RETRY_LIMIT 4#define DEF_ESSID ""#define DEF_ESSID_LEN 0#define DEF_CHANNEL 10#define MAX_RTS_THRESHOLD 2347#define MAX_FRAG_THRESHOLD 2346#define MIN_FRAG_THRESHOLD 256/* The frequency of each channel in MHz */const long channel_frequency[] = {        2412, 2417, 2422, 2427, 2432, 2437, 2442,        2447, 2452, 2457, 2462, 2467, 2472, 2484};#define NUM_CHANNELS ( sizeof(channel_frequency) / sizeof(channel_frequency[0]) )/* the broadcast address */const u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};const u8 off_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};/* the supported rates of this hardware, bit7 marks a mandantory rate */const u8 hw_rates[4] = {0x82,0x84,0x0b,0x16};/* the max padding size for tx in bytes (see calc_padding)*/#define MAX_PADDING_SIZE 53/* a ieee820.11 frame header without addr4 */struct ieee802_11_mgmt {	u16 frame_ctl;	u16 duration_id;	u8 addr1[ETH_ALEN]; /* destination addr */	u8 addr2[ETH_ALEN]; /* source addr */	u8 addr3[ETH_ALEN]; /* BSSID */	u16 seq_ctl;	u8 data[1508];	u32 fcs;} __attribute__ ((packed));/* the size of the ieee802.11 header (excl. the at76c503 tx header) */#define IEEE802_11_MGMT_HEADER_SIZE offsetof(struct ieee802_11_mgmt, data)#define BEACON_MAX_DATA_LENGTH 1500/* beacon in ieee802_11_mgmt.data */struct ieee802_11_beacon_data {	u8   timestamp[8];           // TSFTIMER	u16  beacon_interval;         // Kms between TBTTs (Target Beacon Transmission Times)	u16  capability_information;	u8   data[BEACON_MAX_DATA_LENGTH]; /* contains: SSID (tag,length,value), 					  Supported Rates (tlv), channel */} __attribute__ ((packed));/* disassoc frame in ieee802_11_mgmt.data */struct ieee802_11_disassoc_frame {	u16 reason;} __attribute__ ((packed));#define DISASSOC_FRAME_SIZE \  (AT76C503_TX_HDRLEN + IEEE802_11_MGMT_HEADER_SIZE +\   sizeof(struct ieee802_11_disassoc_frame))/* assoc request in ieee802_11_mgmt.data */struct ieee802_11_assoc_req {	u16  capability;	u16  listen_interval;	u8   data[1]; /* variable number of bytes for SSID 			 and supported rates (tlv coded) */};/* the maximum size of an AssocReq packet */#define ASSOCREQ_MAX_SIZE \  (AT76C503_TX_HDRLEN + IEEE802_11_MGMT_HEADER_SIZE +\   offsetof(struct ieee802_11_assoc_req,data) +\   1+1+IW_ESSID_MAX_SIZE + 1+1+4)/* reassoc request in ieee802_11_mgmt.data */struct ieee802_11_reassoc_req {	u16  capability;	u16  listen_interval;	u8   curr_ap[ETH_ALEN]; /* the bssid of the AP we are				   currently associated to */	u8   data[1]; /* variable number of bytes for SSID 			 and supported rates (tlv coded) */} __attribute__ ((packed));/* the maximum size of an AssocReq packet */#define REASSOCREQ_MAX_SIZE \  (AT76C503_TX_HDRLEN + IEEE802_11_MGMT_HEADER_SIZE +\   offsetof(struct ieee802_11_reassoc_req,data) +\   1+1+IW_ESSID_MAX_SIZE + 1+1+4)/* assoc/reassoc response */struct ieee802_11_assoc_resp {	u16  capability;	u16  status;	u16  assoc_id;	u8   data[1]; /* variable number of bytes for 			 supported rates (tlv coded) */} __attribute__ ((packed));/* auth. request/response in ieee802_11_mgmt.data */struct ieee802_11_auth_frame {	u16 algorithm;	u16 seq_nr;	u16 status;	u8 challenge[0];} __attribute__ ((packed));/* for shared secret auth, add the challenge text size */#define AUTH_FRAME_SIZE \  (AT76C503_TX_HDRLEN + IEEE802_11_MGMT_HEADER_SIZE +\   sizeof(struct ieee802_11_auth_frame))/* deauth frame in ieee802_11_mgmt.data */struct ieee802_11_deauth_frame {	u16 reason;} __attribute__ ((packed));#define DEAUTH_FRAME_SIZE \  (AT76C503_TX_HDRLEN + IEEE802_11_MGMT_HEADER_SIZE +\   sizeof(struct ieee802_11_disauth_frame))#define KEVENT_CTRL_HALT 1

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -