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

📄 cb20_cb.c

📁 vt6656驱动代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * MIC Compatable CB20 cardbus card driver      Copyright (C) 2003, 2004 Cisco Systems, Inc. All Rights Reserved.    Dec 2003 - Masukawa - fixed compatibility with newer radio firmware                          added driver version request			  added wireless-tools interface			  added RF monitor support */#ifndef __KERNEL__#define __KERNEL__#endif#ifndef MODULE#define MODULE#endif#include <linux/config.h>#include <linux/version.h>#include <linux/init.h>#include <asm/segment.h>#ifdef CONFIG_MODVERSIONS#define MODVERSIONS#include <linux/modversions.h>#endif                 #include <linux/kernel.h>#include <linux/module.h>#include <linux/proc_fs.h>#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,6)#include <linux/slab.h>#else#include <linux/malloc.h>#endif#include <linux/sched.h>#include <linux/ptrace.h>#include <linux/string.h>#include <linux/timer.h>#include <linux/interrupt.h>#include <linux/in.h>#include <linux/init.h>#include <asm/io.h>#include <asm/system.h>#include <asm/bitops.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/if_arp.h>#include <linux/ioport.h>#include <linux/config.h>#include <linux/delay.h>#include <asm/uaccess.h>#include <pcmcia/driver_ops.h>#ifdef CONFIG_PCI#include <linux/pci.h>#endif/*#include <linux/wireless.h>*/#include "aes.h"#include "cb20_cb.h"#ifndef MIN#define MIN(x,y) ((x<y)?x:y)#endif#ifndef RUN_AT#define RUN_AT(x) (jiffies+(x))#endif#if (LINUX_VERSION_CODE >= 0x20420)MODULE_LICENSE("MPL");#endifMODULE_AUTHOR("Roland Wilcher");MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11a wireless ethernet \                   cards.   Direct support for cb20 cardbus cards with MIC support");MODULE_SUPPORTED_DEVICE("Aironet Cisco CB20 802.11a cardbus card.");unsigned char iobuf[2048];static char flashbuffer[FLASHSIZE];typedef struct aironet_ioctl {  unsigned short command;	/* What to do  */  unsigned short length;	/* Len of data */  unsigned short ridnum;	/* rid number */  unsigned char *data;		/* d-data      */} aironet_ioctl;#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13))static struct proc_dir_entry cb20_entry = {    0,                            /* low ino  		*/    4,                            /* namelen		*/    PRODNAME,                     /* name               */    S_IFDIR | S_IRUGO | S_IXUGO,  /* mode               */    2,                            /* nlink              */    0, 0,                         /* uid gid            */    0,                            /* size               */    &proc_dir_inode_operations,   /* ops                */    0,                            /* get_info           */    0,                            /* fill inode         */    0,&proc_root,0                /* next parent subdir */};#elsestatic struct proc_dir_entry *cb20_entry = 0;#endif#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13))static void *pci_alloc_consistent(struct pci_dev *,size_t,dma_addr_t*);static void pci_free_consistent(struct pci_dev *,size_t,void *,dma_addr_t);#if 0#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,55)static int  pci_enable_device(struct pci_dev *);#endif#endifstatic unsigned long pci_resource_start(struct pci_dev *,int);#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,19)static unsigned long pci_resource_len(struct pci_dev *,int);#endif#endif/* * Identify the usual suspects */static char *version = "cb20_cb.c 2.1 2003/12/15"; static char *swversion = "2.1"; static int cb20_clear(struct cb20_info *);static void schednap(int);static int enable_mac(struct cb20_info *,Resp *);static struct net_device *cb20_probe(struct pci_dev *);CB20_CARDS *cb20_units = 0; /* List of found  cards *//*  * Handle kernel PCMCIA and Hotplugging on else assume pcmcia-cs  * is being used. */#if defined(CONFIG_HOTPLUG)  && defined(CONFIG_NET_PCMCIA) static int cb20_probe1(struct pci_dev *,const struct pci_device_id *);int eject_cb20_card( struct net_device *);static struct net_device *pcidev_loc(struct pci_dev *locater);void   cb20_remove(struct pci_dev *);static struct net_device *pcidev_loc(struct pci_dev *locate);#elsestatic void cb20_cleanup(struct net_device *);static struct net_device *loc_cb20(char *);static int stop_cb20_card( struct net_device *vdev);static dev_node_t *cb20_attach(dev_locator_t *);static void cb20_detach(dev_node_t *);static void cb20_suspend(dev_node_t *);static void cb20_resume(dev_node_t *);#endifstatic int  softreset(struct cb20_info * );static int  cmdreset(struct cb20_info * );static int  waitport(struct cb20_info *,int,int,int);static int  start_cb20(struct net_device *);static int  cb20_init_descriptors(struct net_device *);static int  flashcard(struct net_device *, aironet_ioctl *);static int  txreclaim(struct net_device *);#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,13))static int  send_packet(struct net_device *);static int  cb20_transmit(struct sk_buff *, struct net_device *);static void cb20txtmo(struct net_device *);#endifstatic void cb20_linkstat(struct net_device *,int );static struct net_device_stats *cb20_get_stats(struct net_device *);static int  cb20_change_mtu(struct net_device *,int);static int  cb20_close(struct net_device *);static void cb20_kick(struct cb20_info *);static unsigned short cb20in(struct cb20_info *,u16 register );static void cb20out(struct cb20_info *,u16 register,u16 value );static u16 cb20command(struct cb20_info*, Cmd *pCmd, Resp *pRsp);static struct net_device *init_cb20_card(struct pci_dev *);static int vreadrid(struct cb20_info *,unsigned short,unsigned char *, int);static int vwriterid(struct cb20_info *,unsigned short,unsigned char *,int);void   cb20_interrupt( int irq, void* dev_id, struct pt_regs    *regs);static int cb20_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);static int mac_enable(struct cb20_info *, Resp * );static void mac_disable( struct cb20_info * );static void disable_interrupts(struct cb20_info *);static void enable_interrupts(struct  cb20_info *);static int del_proc_entry( struct net_device *,struct cb20_info  *);/* Mic functions*/static void micinit(struct cb20_info *, STMIC *);static void micsetup(struct cb20_info *);static int RxSeqValid (struct cb20_info *,MICCNTX *context, u32 micSeq);static void MoveWindow(MICCNTX *, u32 );static int Encapsulate(struct cb20_info *,ETH_HEADER_STRUC *, u32 *,int );static int Decapsulate(struct cb20_info *,ETH_HEADER_STRUC *, u32 *);static void UshortByteSwap(u16 *);static void UlongByteSwap(u32 *);static ssize_t proc_read( struct file *,char *,size_t ,loff_t * );static ssize_t proc_write( struct file *,const char *,size_t ,loff_t * );static int proc_close( struct inode *, struct file * ); static int proc_ssid_open( struct inode *, struct file * );static int proc_status_open( struct inode *, struct file * );static void procsetup(struct net_device *);static void del_cb20(struct net_device *);static void add_cb20(struct net_device *);static void cb20_reap(void);#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13))static int net_send_packet(struct sk_buff *, struct net_device *);#endif/* INCLUDE_RFMONITOR - "#define" this will include RF monitor mode code for use                     with sniffers                     must have WIRELESS_EXT  (include linux/wireless.h)#define INCLUDE_RFMONITOR */#ifdef INCLUDE_RFMONITORstatic void cb20_set_rfmonitor(struct cb20_info *v_info);#endif#ifdef WIRELESS_EXTstruct iw_statistics *airo_get_wireless_stats(struct net_device *dev);#endif/*  * Proc filesystem definitions */static struct file_operations proc_ssid_ops = {  read:          proc_read,  write:         proc_write,  open:          proc_ssid_open,  release:       proc_close};static struct file_operations proc_status_ops = {	read:            proc_read,	open:            proc_status_open,	release:         proc_close};/* * Handle 2.2 /proc */#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,11))static struct inode_operations proc_inode_ssid_ops = {  &proc_ssid_ops};static struct inode_operations proc_inode_status_ops = {  &proc_status_ops};static struct proc_dir_entry ssid_entry = {  0, 4, "SSID",  S_IFREG | S_IRUGO | S_IWUSR, 2, 0, 0,  13,  &proc_inode_ssid_ops, NULL};static struct proc_dir_entry status_entry = {  0,6,"Status",  S_IFREG | S_IRUGO | S_IWUSR, 2, 0, 0,  13,  &proc_inode_status_ops,NULL};#endif/*  * Start of kernel PCMCIA/CARDBUS */#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET_PCMCIA)#undef CONFIG_PM/* * device  driver ID table and  * operations . */static struct pci_device_id cb20_pci_tbl[]  = {  { AIRONET, 0xa505,PCI_ANY_ID, PCI_ANY_ID, },  { 0,},};static struct pci_driver cb20_driver = {  name:		"cb20_cb",  id_table:	cb20_pci_tbl,  probe:	cb20_probe1,#if (LINUX_VERSION_CODE >= 0x20416 )  remove:	__devexit_p(cb20_remove),#else  remove:	cb20_remove,#endif#ifdef CONFIG_PM  suspend:	cb20_suspend,  resume:	cb20_resume,#endif /* CONFIG_PM */};MODULE_DEVICE_TABLE(pci, cb20_pci_tbl);#else/*  ** *** external pcmcia-cs driver interface */struct driver_operations cb20_ops = {  "cb20_cb", cb20_attach, cb20_suspend, cb20_resume, cb20_detach};#endifstatic int waitbusy(struct cb20_info *cb_info){  int time=0;  while ((cb20in (cb_info, V_COMMAND) & COMMAND_BUSY) & (time < 10000)) {    udelay (10);    if (++time % 20)      cb20out(cb_info, V_EVACK, EV_CLEARCOMMANDBUSY);  }  return time >= 10000 ;}/* * @New style PCI and Kernel PCMCIA + HOTPLUG * */#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET_PCMCIA) /* *@remove */void cb20_remove(struct pci_dev *pdev){  struct net_device *nd;  if((nd=pcidev_loc(pdev))!=0){    del_proc_entry(nd,nd->priv);    eject_cb20_card(nd);  }  else    printk(KERN_WARNING "Cant locate device %p\n",pdev);}/* * @eject CB20 * Card has been removed */int eject_cb20_card( struct net_device *vdev){  struct cb20_info *v_info = (struct cb20_info*)vdev->priv;  struct sk_buff    *skb=0;  /* device has been freed   * already bail   */  if(vdev == 0)    return -1;  del_proc_entry(vdev,v_info);  del_cb20(vdev);  cb20out(v_info,0,CB_FLAGBIT); /* disable cardbus ints */  netif_device_detach(vdev);#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,13))  /* Clean out tx queue    */  if(skb_queue_len(&v_info->txq)> 0 )    for(;(skb = skb_dequeue(&v_info->txq));)      dev_kfree_skb(skb);#endif  pci_free_consistent(v_info->pcip, SHAREDMEMSIZE,v_info->SharedRegion,v_info->SharedBusaddr);  iounmap(v_info->auxregmembase);  unregister_netdev(vdev);  kfree(vdev);  return 0;}/* * @probe1 Insert time probe */static int cb20_probe1(struct pci_dev *pci,const struct pci_device_id *ent){  struct net_device *ndev;  struct cb20_info *v_info ;    if((ndev=cb20_probe(pci))!=0){    schednap(10);    v_info = (struct cb20_info *)ndev->priv;    v_info->device = create_proc_entry(ndev->name,S_IFDIR|0555,cb20_entry);    procsetup(ndev);    add_cb20(ndev);    return 0;  }  else    return -ENODEV;}/* New style PCI driver routines */static int __init cb20_init_module(void){  cb20_reap();  cb20_entry = create_proc_entry(PRODNAME,S_IFDIR | S_IRUGO,proc_root_driver);  return pci_module_init(&cb20_driver);}static void __exit cb20_cleanup_module(void){  cb20_reap();  remove_proc_entry(PRODNAME, proc_root_driver);   pci_unregister_driver(&cb20_driver);}module_init(cb20_init_module);module_exit(cb20_cleanup_module);#else/*             Old style pcmcia-cs interface  * */int init_module(void){  printk(KERN_DEBUG "%s\n", version);#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,13))  cb20_entry = create_proc_entry(PRODNAME,S_IFDIR | 0555,proc_root_driver);#else  cb20_entry.ops->lookup =  proc_net->ops->lookup;  cb20_entry.ops->default_file_ops->readdir = proc_net->ops->default_file_ops->readdir;  proc_register( &proc_root,&cb20_entry);#endif  register_driver(&cb20_ops);  return 0;}void cleanup_module(void){    printk(KERN_DEBUG "cb20_cb: unloading\n");#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,13))    remove_proc_entry(PRODNAME, proc_root_driver); #else    proc_unregister(&proc_root,cb20_entry.low_ino);#endif    unregister_driver(&cb20_ops);    cb20_reap();}#endif/* * Enable MAC  * @MAC */static int enable_mac(struct cb20_info *cb_info,Resp *rsp){  Cmd command;  int tries = 6000000;  int delay,rc,flags;  delay=rc=0;      if(cb_info->flags & FLASHING )    return 0;  memset(&command,0,sizeof(command));  command.cmd = CMD_X500_EnableAll;  spin_lock_irqsave(&cb_info->cmd_lock, flags);  if(waitbusy(cb_info)){    printk(KERN_ERR "MAC: WaitBusy timeout\n");    spin_lock_irqsave(&cb_info->cmd_lock, flags);    return -1;  }  cb20out(cb_info, V_PARAM0, command.parm0);  cb20out(cb_info, V_PARAM1, command.parm1);  cb20out(cb_info, V_PARAM2, command.parm2);  cb20out(cb_info, V_COMMAND, command.cmd);  while(tries-- &&  (cb20in(cb_info, V_EVSTAT) & EV_CMD) == 0) {    if ( cb20in(cb_info, V_COMMAND) == command.cmd) {      /* didn't notice command, try again */      cb20out(cb_info, V_COMMAND, command.cmd);    }    if(tries % 20 )      udelay(10);  }  if(tries == -1 ){    printk(KERN_ERR "MAC: Max tries enabling mac\n");    spin_unlock_irqrestore(&cb_info->cmd_lock, flags);    return -1;  }  /* command completed */  rsp->status = cb20in(cb_info, V_STATUS);  rsp->rsp0 = cb20in(cb_info, V_RESP0);

⌨️ 快捷键说明

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