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

📄 at76c503.c

📁 这是atmel公司的无线网卡驱动, 基于linux的驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* -*- linux-c -*- *//* $Id: at76c503.c,v 1.35 2003/07/30 06:31:51 jal2 Exp $ * * USB at76c503/at76c505 driver * * 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. * * * 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 <linux/rtnetlink.h>  /* for rtnl_lock() */#include "at76c503.h"#include "ieee802_11.h"/* debug bits */#define DBG_PROGRESS        0x000001 /* progress of scan-join-(auth-assoc)-connected */#define DBG_BSS_TABLE       0x000002 /* show the bss table after scans */#define DBG_IOCTL           0x000004 /* ioctl calls / settings */#define DBG_KEVENT          0x000008 /* kevents */#define DBG_TX_DATA         0x000010 /* tx header */#define DBG_TX_DATA_CONTENT 0x000020 /* tx content */#define DBG_TX_MGMT         0x000040#define DBG_RX_DATA         0x000080 /* rx data header */#define DBG_RX_DATA_CONTENT 0x000100 /* rx data content */#define DBG_RX_MGMT         0x000200 /* rx mgmt header except beacon and probe responses */#define DBG_RX_BEACON       0x000400 /* rx beacon */#define DBG_RX_CTRL         0x000800 /* rx control */#define DBG_RX_MGMT_CONTENT 0x001000 /* rx mgmt content */#define DBG_RX_FRAGS        0x002000 /* rx data fragment handling */#define DBG_DEVSTART        0x004000 /* fw download, device start */#define DBG_URB             0x008000 /* rx urb status, ... */#define DBG_RX_ATMEL_HDR    0x010000 /* the atmel specific header of each rx packet */#define DBG_PROC_ENTRY      0x020000 /* procedure entries and exits */#define DBG_PM              0x040000 /* power management settings */#define DBG_BSS_MATCH       0x080000 /* show why a certain bss did not match */#define DBG_PARAMS          0x100000 /* show the configured parameters */#define DBG_WAIT_COMPLETE   0x200000 /* show the wait_completion progress */#define DBG_RX_FRAGS_SKB    0x400000 /* show skb header for incoming rx fragments */#define DBG_BSS_TABLE_RM    0x800000 /* inform on removal of old bss table entries */#ifdef CONFIG_USB_DEBUG#define DBG_DEFAULTS (DBG_PROGRESS | DBG_PARAMS | DBG_BSS_TABLE)#else#define DBG_DEFAULTS 0#endifstatic 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#define NEW_STATE(dev,newstate) \  do {\    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/* after how many seconds do we re-scan the channels in infra mode */#define RESCAN_TIME 10/* Version Information */#define DRIVER_DESC "Generic Atmel at76c503/at76c505 routines"/* Module paramaters */MODULE_PARM(debug, "i");#define DRIVER_AUTHOR \"Oliver Kurth <oku@masqmail.cx>, Joerg Albert <joerg.albert@gmx.de>, Alex <alex@foogod.com>"MODULE_PARM_DESC(debug, "Debugging level");static int rx_copybreak = 200;MODULE_PARM(rx_copybreak, "i");MODULE_PARM_DESC(rx_copybreak, "rx packet copy threshold");static int scan_min_time = 10;MODULE_PARM(scan_min_time, "i");MODULE_PARM_DESC(scan_min_time, "scan min channel time (default: 10)");static int scan_max_time = 120;MODULE_PARM(scan_max_time, "i");MODULE_PARM_DESC(scan_max_time, "scan max channel time (default: 120)");static int scan_mode = SCAN_TYPE_ACTIVE;MODULE_PARM(scan_mode, "i");MODULE_PARM_DESC(scan_mode, "scan mode: 0 active (with ProbeReq, default), 1 passive");static int preamble_type = PREAMBLE_TYPE_LONG;MODULE_PARM(preamble_type, "i");MODULE_PARM_DESC(preamble_type, "preamble type: 0 long (default), 1 short");static int auth_mode = 0;MODULE_PARM(auth_mode, "i");MODULE_PARM_DESC(auth_mode, "authentication mode: 0 open system (default), "		 "1 shared secret");static int pm_mode = PM_ACTIVE;MODULE_PARM(pm_mode, "i");MODULE_PARM_DESC(pm_mode, "power management mode: 1 active (def.), 2 powersave, 3 smart save");static int pm_period = 0;MODULE_PARM(pm_period, "i");MODULE_PARM_DESC(pm_period, "period of waking up the device in usec");struct header_struct {        /* 802.3 */        u8 dest[ETH_ALEN];        u8 src[ETH_ALEN];        u16 len;        /* 802.2 */        u8 dsap;        u8 ssap;        u8 ctrl;        /* SNAP */        u8 oui[3];        u16 ethertype;} __attribute__ ((packed));#define DEF_RTS_THRESHOLD 1536#define DEF_FRAG_THRESHOLD 1536#define DEF_ESSID "okuwlan"#define DEF_ESSID_LEN 7#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};/* 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)/* 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[1500]; /* 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#define KEVENT_NEW_BSS 2#define KEVENT_SET_PROMISC 3#define KEVENT_MGMT_TIMEOUT 4#define KEVENT_SCAN 5 #define KEVENT_JOIN 6#define KEVENT_STARTIBSS 7#define KEVENT_SUBMIT_RX 8#define KEVENT_RESTART 9 /* restart the device */#define KEVENT_ASSOC_DONE  10 /* execute the power save settings:			     listen interval, pm mode, assoc id */static DECLARE_WAIT_QUEUE_HEAD(wait_queue);static u8 snapsig[] = {0xaa, 0xaa, 0x03};#ifdef COLLAPSE_RFC1042/* RFC 1042 encapsulates Ethernet frames in 802.2 SNAP (0xaa, 0xaa, 0x03) with * a SNAP OID of 0 (0x00, 0x00, 0x00) */static u8 rfc1042sig[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};#endif /* COLLAPSE_RFC1042 *//* local function prototypes */	#if IW_MAX_SPY > 0static void iwspy_update(struct at76c503 *dev, struct at76c503_rx_buffer *buf);#endifstatic void at76c503_read_bulk_callback (struct urb *urb);static void at76c503_write_bulk_callback(struct urb *urb);static void defer_kevent (struct at76c503 *dev, int flag);static struct bss_info *find_matching_bss(struct at76c503 *dev,					  struct bss_info *curr);static int auth_req(struct at76c503 *dev, struct bss_info *bss, int seq_nr,		    u8 *challenge);static int disassoc_req(struct at76c503 *dev, struct bss_info *bss);static int assoc_req(struct at76c503 *dev, struct bss_info *bss);static int reassoc_req(struct at76c503 *dev, struct bss_info *curr,		       struct bss_info *new);static void dump_bss_table(struct at76c503 *dev, int force_output);static int submit_rx_urb(struct at76c503 *dev);static int startup_device(struct at76c503 *dev);/* hexdump len many bytes from buf into obuf, separated by delim,   add a trailing \0 into obuf */static char *hex2str(char *obuf, u8 *buf, int len, char delim){#define BIN2HEX(x) ((x) < 10 ? '0'+(x) : (x)+'A'-10)  char *ret = obuf;  while (len--) {    *obuf++ = BIN2HEX(*buf>>4);    *obuf++ = BIN2HEX(*buf&0xf);    if (delim != '\0')      *obuf++ = delim;    buf++;  }  if (delim != '\0' && obuf > ret)	  obuf--; // remove last inserted delimiter  *obuf = '\0';  return ret;}static inline void free_bss_list(struct at76c503 *dev){	struct list_head *next, *ptr;	unsigned long flags;	spin_lock_irqsave(&dev->bss_list_spinlock, flags);	dev->curr_bss = dev->new_bss = NULL;	list_for_each_safe(ptr, next, &dev->bss_list) {		list_del(ptr);		kfree(list_entry(ptr, struct bss_info, list));	}	spin_unlock_irqrestore(&dev->bss_list_spinlock, flags);}static inline char *mac2str(u8 *mac){	static char str [6*3];  	sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",		mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);	return str;}static inline void usb_debug_data (const char *function, const unsigned char *data, int size){	int i;	if (!debug)		return;		printk (KERN_DEBUG __FILE__": %s - length = %d, data = ", 		function, size);	for (i = 0; i < size; ++i) {		if((i % 8) == 0)			printk ("\n");		printk ("%.2x ", data[i]);

⌨️ 快捷键说明

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