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

📄 ray_cs.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 5 页
字号:
/*============================================================================= * * A  PCMCIA client driver for the Raylink wireless LAN card. * The starting point for this module was the skeleton.c in the * PCMCIA 2.9.12 package written by David Hinds, dhinds@allegro.stanford.edu * * * Copyright (c) 1998  Corey Thomas (corey@world.std.com) * * This driver is free software; you can redistribute it and/or modify * it under the terms of version 2 only of the GNU General Public License as  * published by the Free Software Foundation. * * It is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * =============================================================================*/#include <linux/kernel.h>#include <linux/module.h>#include <linux/sched.h>#include <linux/proc_fs.h>#include <linux/ptrace.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/timer.h>#include <linux/spinlock.h>#include <asm/io.h>#include <asm/system.h>#include <asm/byteorder.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/if_arp.h>#include <linux/ioport.h>#include <linux/skbuff.h>#include <pcmcia/version.h>#include <pcmcia/cs_types.h>#include <pcmcia/cs.h>#include <pcmcia/cistpl.h>#include <pcmcia/cisreg.h>#include <pcmcia/ds.h>#include <pcmcia/mem_op.h>#ifdef CONFIG_NET_PCMCIA_RADIO#include <linux/wireless.h>#if WIRELESS_EXT < 9#warning "Wireless extension v9 or newer required"#endif	/* WIRELESS_EXT < 9 *//* Warning : these stuff will slow down the driver... */#define WIRELESS_SPY		/* Enable spying addresses *//* Definitions we need for spy */typedef struct iw_statistics	iw_stats;typedef struct iw_quality	iw_qual;typedef u_char	mac_addr[ETH_ALEN];	/* Hardware address */#endif	/* CONFIG_NET_PCMCIA_RADIO */#include "rayctl.h"#include "ray_cs.h"/* All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If   you do not define PCMCIA_DEBUG at all, all the debug code will be   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will   be present but disabled -- but it can then be enabled for specific   modules at load time with a 'pc_debug=#' option to insmod.*/#ifdef RAYLINK_DEBUG#define PCMCIA_DEBUG RAYLINK_DEBUG#endif#ifdef PCMCIA_DEBUGstatic int ray_debug = 0;static int pc_debug = PCMCIA_DEBUG;MODULE_PARM(pc_debug, "i");/* #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); */#define DEBUG(n, args...) if (pc_debug>(n)) printk(args);#else#define DEBUG(n, args...)#endif/** Prototypes based on PCMCIA skeleton driver *******************************/static void ray_config(dev_link_t *link);static void ray_release(u_long arg);static int ray_event(event_t event, int priority, event_callback_args_t *args);static dev_link_t *ray_attach(void);static void ray_detach(dev_link_t *);/***** Prototypes indicated by device structure ******************************/static int ray_dev_close(struct net_device *dev);static int ray_dev_config(struct net_device *dev, struct ifmap *map);static struct net_device_stats *ray_get_stats(struct net_device *dev);static int ray_dev_init(struct net_device *dev);static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);static int ray_open(struct net_device *dev);static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev);static void set_multicast_list(struct net_device *dev);static void ray_update_multi_list(struct net_device *dev, int all);static int translate_frame(ray_dev_t *local, struct tx_msg *ptx,                unsigned char *data, int len);static void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type,                unsigned char *data);static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len);#if WIRELESS_EXT > 7	/* If wireless extension exist in the kernel */static iw_stats * ray_get_wireless_stats(struct net_device *	dev);#endif	/* WIRELESS_EXT > 7 *//***** Prototypes for raylink functions **************************************/static int asc_to_int(char a);static void authenticate(ray_dev_t *local);static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type);static void authenticate_timeout(u_long);static int get_free_ccs(ray_dev_t *local);static int get_free_tx_ccs(ray_dev_t *local);static void init_startup_params(ray_dev_t *local);static int parse_addr(char *in_str, UCHAR *out);static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, UCHAR type);static int ray_init(struct net_device *dev);static int interrupt_ecf(ray_dev_t *local, int ccs);static void ray_reset(struct net_device *dev);static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len);static void verify_dl_startup(u_long);/* Prototypes for interrpt time functions **********************************/static void ray_interrupt (int reg, void *dev_id, struct pt_regs *regs);static void clear_interrupt(ray_dev_t *local);static void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs,                        unsigned int pkt_addr, int rx_len);static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int len);static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs);static void release_frag_chain(ray_dev_t *local, struct rcs *prcs);static void rx_authenticate(ray_dev_t *local, struct rcs *prcs,                     unsigned int pkt_addr, int rx_len);static void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr,              int rx_len);static void associate(ray_dev_t *local);/* Card command functions */static int dl_startup_params(struct net_device *dev);static void join_net(u_long local);static void start_net(u_long local);/* void start_net(ray_dev_t *local); */static int ray_cs_proc_read(char *, char **, off_t, int, int *, void *);/* Create symbol table for registering with kernel in init_module */#if (LINUX_VERSION_CODE <= VERSION(2,1,17))static struct symbol_table ray_cs_syms = {#include <linux/symtab_begin.h>#undef X#define X(sym) { (void *)&sym, SYMBOL_NAME_STR(sym) }    X(ray_rx),    X(ray_dev_ioctl),#include <linux/symtab_end.h>};#else /* (kernel > 2.1.17) Use new kernel method of registering symbols */EXPORT_SYMBOL(ray_dev_ioctl);EXPORT_SYMBOL(ray_rx);#endif/*===========================================================================*//* Parameters that can be set with 'insmod' *//* Bit map of interrupts to choose from *//* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */static u_long irq_mask = 0xdeb8;/* ADHOC=0, Infrastructure=1 */static int net_type = ADHOC;/* Hop dwell time in Kus (1024 us units defined by 802.11) */static int hop_dwell = 128;/* Beacon period in Kus */static int beacon_period = 256;/* power save mode (0 = off, 1 = save power) */static int psm = 0;/* String for network's Extended Service Set ID. 32 Characters max */static char *essid = NULL;/* Default to encapsulation unless translation requested */static int translate = 1;static int country = USA;static int sniffer = 0;static int bc = 0;/* 48 bit physical card address if overriding card's real physical * address is required.  Since IEEE 802.11 addresses are 48 bits * like ethernet, an int can't be used, so a string is used. To * allow use of addresses starting with a decimal digit, the first * character must be a letter and will be ignored. This letter is * followed by up to 12 hex digits which are the address.  If less * than 12 digits are used, the address will be left filled with 0's. * Note that bit 0 of the first byte is the broadcast bit, and evil * things will happen if it is not 0 in a card address. */static char *phy_addr = NULL;/* The dev_info variable is the "key" that is used to match up this   device driver with appropriate cards, through the card configuration   database.*/static dev_info_t dev_info = "ray_cs";/* A linked list of "instances" of the ray device.  Each actual   PCMCIA card corresponds to one device instance, and is described   by one dev_link_t structure (defined in ds.h).*/static dev_link_t *dev_list = NULL;/* A dev_link_t structure has fields for most things that are needed   to keep track of a socket, but there will usually be some device   specific information that also needs to be kept track of.  The   'priv' pointer in a dev_link_t structure can be used to point to   a device-specific private data structure, like this.*/static unsigned int ray_mem_speed = 500;MODULE_AUTHOR("Corey Thomas <corey@world.std.com>");MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver");MODULE_LICENSE("GPL");MODULE_PARM(irq_mask,"i");MODULE_PARM(net_type,"i");MODULE_PARM(hop_dwell,"i");MODULE_PARM(beacon_period,"i");MODULE_PARM(psm,"i");MODULE_PARM(essid,"s");MODULE_PARM(translate,"i");MODULE_PARM(country,"i");MODULE_PARM(sniffer,"i");MODULE_PARM(bc,"i");MODULE_PARM(phy_addr,"s");MODULE_PARM(ray_mem_speed, "i");static UCHAR b5_default_startup_parms[] = {    0,   0,                         /* Adhoc station */   'L','I','N','U','X', 0,  0,  0,  /* 32 char ESSID */    0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,    1,  0,                          /* Active scan, CA Mode */    0,  0,  0,  0,  0,  0,          /* No default MAC addr  */    0x7f, 0xff,                     /* Frag threshold */    0x00, 0x80,                     /* Hop time 128 Kus*/    0x01, 0x00,                     /* Beacon period 256 Kus */    0x01, 0x07, 0xa3,               /* DTIM, retries, ack timeout*/    0x1d, 0x82, 0x4e,               /* SIFS, DIFS, PIFS */    0x7f, 0xff,                     /* RTS threshold */    0x04, 0xe2, 0x38, 0xA4,         /* scan_dwell, max_scan_dwell */    0x05,                           /* assoc resp timeout thresh */    0x08, 0x02, 0x08,               /* adhoc, infra, super cycle max*/    0,                              /* Promiscuous mode */    0x0c, 0x0bd,                    /* Unique word */    0x32,                           /* Slot time */    0xff, 0xff,                     /* roam-low snr, low snr count */    0x05, 0xff,                     /* Infra, adhoc missed bcn thresh */    0x01, 0x0b, 0x4f,               /* USA, hop pattern, hop pat length *//* b4 - b5 differences start here */    0x00, 0x3f,                     /* CW max */    0x00, 0x0f,                     /* CW min */    0x04, 0x08,                     /* Noise gain, limit offset */    0x28, 0x28,                     /* det rssi, med busy offsets */    7,                              /* det sync thresh */    0, 2, 2,                        /* test mode, min, max */    0,                              /* allow broadcast SSID probe resp */    0, 0,                           /* privacy must start, can join */    2, 0, 0, 0, 0, 0, 0, 0          /* basic rate set */};static UCHAR b4_default_startup_parms[] = {    0,   0,                         /* Adhoc station */   'L','I','N','U','X', 0,  0,  0,  /* 32 char ESSID */    0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,    1,  0,                          /* Active scan, CA Mode */    0,  0,  0,  0,  0,  0,          /* No default MAC addr  */    0x7f, 0xff,                     /* Frag threshold */    0x02, 0x00,                     /* Hop time */    0x00, 0x01,                     /* Beacon period */    0x01, 0x07, 0xa3,               /* DTIM, retries, ack timeout*/    0x1d, 0x82, 0xce,               /* SIFS, DIFS, PIFS */    0x7f, 0xff,                     /* RTS threshold */    0xfb, 0x1e, 0xc7, 0x5c,         /* scan_dwell, max_scan_dwell */    0x05,                           /* assoc resp timeout thresh */    0x04, 0x02, 0x4,                /* adhoc, infra, super cycle max*/    0,                              /* Promiscuous mode */    0x0c, 0x0bd,                    /* Unique word */    0x4e,                           /* Slot time (TBD seems wrong)*/    0xff, 0xff,                     /* roam-low snr, low snr count */    0x05, 0xff,                     /* Infra, adhoc missed bcn thresh */    0x01, 0x0b, 0x4e,               /* USA, hop pattern, hop pat length *//* b4 - b5 differences start here */    0x3f, 0x0f,                     /* CW max, min */    0x04, 0x08,                     /* Noise gain, limit offset */    0x28, 0x28,                     /* det rssi, med busy offsets */    7,                              /* det sync thresh */    0, 2, 2                         /* test mode, min, max*/};/*===========================================================================*/static unsigned char eth2_llc[] = {0xaa, 0xaa, 3, 0, 0, 0};static char hop_pattern_length[] = { 1,	     USA_HOP_MOD,             EUROPE_HOP_MOD,	     JAPAN_HOP_MOD,           KOREA_HOP_MOD,	     SPAIN_HOP_MOD,           FRANCE_HOP_MOD,	     ISRAEL_HOP_MOD,          AUSTRALIA_HOP_MOD,	     JAPAN_TEST_HOP_MOD};static char rcsid[] = " ray_cs.c,v 1.33 2002/06/29 06:39:33 root Exp - Corey Thomas corey@world.std.com";/*===========================================================================*/static void cs_error(client_handle_t handle, int func, int ret){    error_info_t err = { func, ret };    CardServices(ReportError, handle, &err);}/*======================================================================    This bit of code is used to avoid unregistering network devices    at inappropriate times.  2.2 and later kernels are fairly picky    about when this can happen.    ======================================================================*/static void flush_stale_links(void){    dev_link_t *link, *next;    for (link = dev_list; link; link = next) {	next = link->next;	if (link->state & DEV_STALE_LINK)	    ray_detach(link);    }}/*=============================================================================    ray_attach() creates an "instance" of the driver, allocating    local data structures for one device.  The device is registered    with Card Services.    The dev_link structure is initialized, but we don't actually    configure the card at this point -- we wait until we receive a    card insertion event.=============================================================================*/static dev_link_t *ray_attach(void){    client_reg_t client_reg;    dev_link_t *link;    ray_dev_t *local;    int ret;    struct net_device *dev;        DEBUG(1, "ray_attach()\n");    flush_stale_links();    /* Initialize the dev_link_t structure */    link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);    if (link == NULL) return link;    memset(link, 0, sizeof(struct dev_link_t));    link->release.function = &ray_release;    link->release.data = (u_long)link;    /* The io structure describes IO port mapping. None used here */    link->io.NumPorts1 = 0;    link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;    link->io.IOAddrLines = 5;    /* Interrupt setup. For PCMCIA, driver takes what's given */    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;    link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;    link->irq.IRQInfo2 = irq_mask;

⌨️ 快捷键说明

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