📄 cb20_cb.c
字号:
}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,55)) SET_MODULE_OWNER(vdev);#endif vdev->do_ioctl = &cb20_ioctl; vdev->open = &cb20_open; vdev->stop = &cb20_close;#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,55 )) vdev->hard_start_xmit = &cb20_transmit;#else vdev->hard_start_xmit = &net_send_packet;#endif#ifdef WIRELESS_EXT vdev->get_wireless_stats = airo_get_wireless_stats;#endif vdev->get_stats = &cb20_get_stats; vdev->change_mtu = &cb20_change_mtu;#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,55 )) vdev->watchdog_timeo = 200; vdev->tx_timeout = cb20txtmo;#endif netif_stop_queue(vdev); v_info = (struct cb20_info *)vdev->priv; memset((char *)v_info,0,sizeof(v_info)); skb_queue_head_init(&v_info->txq); vdev->irq = vencard->irq; vdev->base_addr = pci_resource_start(vencard,0); v_info->iosize = pci_resource_len(vencard, 0); v_info->iobase = vdev->base_addr; v_info->pcip = vencard; v_info->dev = vdev; /* * Set locks */ v_info->mpi_lock = SPIN_LOCK_UNLOCKED; v_info->txlist_lock = SPIN_LOCK_UNLOCKED; v_info->txd_lock = SPIN_LOCK_UNLOCKED; v_info->aux_lock = SPIN_LOCK_UNLOCKED; v_info->cmd_lock = SPIN_LOCK_UNLOCKED; request_region(vdev->base_addr,v_info->iosize,"CB20-CARD"); /* @reset * Turn off interrupts and reset Card */ cb20out(v_info,V_EVINTEN,0); cb20out(v_info,CB_CLEARINT,CB_FLAGBIT); cb20out(v_info,CB_INTENABLE,0); /* @RAW no ints */ if(softreset(v_info)==0){ printk(KERN_CRIT "Softreset failed!! bailout \n"); unregister_netdev(vdev); kfree(vdev); vdev=0; return 0; } cb20out(v_info,V_SWS0,0); cb20out(v_info,V_SWS1,0); memset (&rsp, 0, sizeof (rsp)); memset (&cmd, 0, sizeof (cmd)); cmd.cmd = CMD_X500_NOP10; if((status = cb20command(v_info,&cmd,&rsp))!=0){ printk (KERN_CRIT "Performed NOP10 command failed!\n"); unregister_netdev(vdev); kfree(vdev); return 0; }#if DEBUG_INIT printk (KERN_DEBUG "Performed NOP10 command (in init_cb20) status=%x\n",status);#endif v_info->pci_controlbase = pci_resource_start(vencard,1); v_info->controlmembasesize = pci_resource_len (vencard, 1); v_info->pci_auxbase = pci_resource_start(vencard,2); /* Aux mem must be 256 * 1024 * for flash to work */ v_info->auxmembasesize = AUXMEMSIZE; /* Shared mem */ if((v_info->SharedRegion = pci_alloc_consistent(vencard, SHAREDMEMSIZE,&v_info->SharedBusaddr))==0){ printk(KERN_CRIT "CB20 Consistant alloc failed !\n"); unregister_netdev(vdev); kfree(vdev); return 0; } memset((void *)v_info->SharedRegion,0,SHAREDMEMSIZE); if((v_info->auxregmembase = ioremap (v_info->pci_auxbase,v_info->auxmembasesize))==0){ printk(KERN_CRIT "CB20 ioremap AUX: FAILED ! %lx = %p\n", v_info->pci_auxbase, v_info->auxregmembase); pci_free_consistent(vencard,SHAREDMEMSIZE,v_info->SharedRegion,v_info->SharedBusaddr); unregister_netdev(vdev); kfree(vdev); return 0; } /* * Setup descriptors RX,TX,CONFIG */ busaddroff = (unsigned char *)v_info->SharedBusaddr; pciaddroff = v_info->auxregmembase + 0x800; vpackoff = v_info->SharedRegion; /* RX descriptor setup */ for(i=0;i!=MAX_DESC;i++){ v_info->rxfids[i].pending = FALSE; v_info->rxfids[i].CardRamOff = pciaddroff; v_info->rxfids[i].RxDesc.PhyHostAddress =(unsigned long) busaddroff; v_info->rxfids[i].RxDesc.valid = 1; v_info->rxfids[i].RxDesc.length = HOSTBUFSIZ; v_info->rxfids[i].RxDesc.RxDone = 0; v_info->rxfids[i].VirtualHostAddress = vpackoff; pciaddroff += sizeof(CARD_RX_DESC); busaddroff += HOSTBUFSIZ; vpackoff += HOSTBUFSIZ; } /* TX descriptor setup */ for(i=0;i!=MAX_DESC;i++){ v_info->txfids[i].CardRamOff = pciaddroff; v_info->txfids[i].TxDesc.PhyHostAddress = (unsigned long)busaddroff; v_info->txfids[i].TxDesc.valid = 1; v_info->txfids[i].VirtualHostAddress = vpackoff; memcpy((char *)v_info->txfids[i].VirtualHostAddress, (char *)&txFidHdr,sizeof(txFidHdr)); pciaddroff += sizeof(CARD_TX_DESC); busaddroff +=HOSTBUFSIZ; vpackoff +=HOSTBUFSIZ; } v_info->txfids[i-1].TxDesc.eoc = 1; /* Last descriptor has EOC set */ /* Rid descriptor setup */ v_info->ConfigDesc.CardRamOff = pciaddroff; v_info->ConfigDesc.VirtualHostAddress = vpackoff; v_info->ConfigDesc.RIDDesc.PhyHostAddress = (unsigned long)busaddroff; v_info->ridbus = (unsigned long)busaddroff; v_info->ConfigDesc.RIDDesc.RID = 0; v_info->ConfigDesc.RIDDesc.length = 2048; v_info->ConfigDesc.RIDDesc.valid = 0; v_info->flags |= DEVREGISTERED; /* Tell card about descriptors */ cb20_init_descriptors(vdev); pci_set_master (vencard); return vdev;}/************************************************************* * Start card after flash or power cycle. * @start_cb20 */static int start_cb20(struct net_device *dev){ struct cb20_info *v_info = (struct cb20_info*)dev->priv; Cmd cmd; Resp rsp; int i,status; ConfigRid cfg; EXSTCAPS xcaps; /* @restart */ memset (&rsp, 0, sizeof (rsp)); memset (&cmd, 0, sizeof (cmd)); memset (&cfg,0,sizeof(cfg)); memset(&rsp,0,sizeof(rsp)); memset(&cmd,0,sizeof(cmd)); cmd.cmd = CMD_X500_NOP10; if((status = cb20command(v_info,&cmd,&rsp))!=0) return status; cb20out(v_info,CB_CLEARINT,CB_FLAGBIT); cb20out(v_info,CB_INTENABLE,0); /* @RAW no ints */ cb20out(v_info,V_EVINTEN,0); vreadrid((struct cb20_info *)dev->priv,RID_CAPABILITIES,(char *)&xcaps, sizeof(xcaps)); vreadrid((struct cb20_info *)dev->priv,RID_CONFIG,(char *)&cfg, sizeof(cfg)); /* * Find out if an extended capability rid was returned */ if(xcaps.u16RidLen >= sizeof(xcaps)){#ifdef DEBUG_MIC printk(KERN_INFO "Extended cap's\n");#endif /* Check for MIC capability */ if(xcaps.u16ExtSoftwareCapabilities & EXT_SOFT_CAPS_MIC ){#ifdef DEBUG_MIC printk(KERN_INFO "Mic capable\n");#endif cfg.opmode |= CFG_OPMODE_MIC; v_info->flags |= MIC_CAPABLE; micsetup(v_info); } } /* * Set dev macaddr */ for(i=0;i!=6;i++){ dev->dev_addr[i] = cfg.macAddr[i]; } printk( KERN_INFO "CB20 start: MAC %x:%x:%x:%x:%x:%x\n", dev->dev_addr[0],dev->dev_addr[1],dev->dev_addr[2], dev->dev_addr[3],dev->dev_addr[4],dev->dev_addr[5]); dev->addr_len = 6;#ifdef DEBUG_MAC printk(KERN_ERR "Prepare to call mac_enable()\n");#endif if((status = enable_mac(v_info,&rsp))!=0){ printk(KERN_ERR "Cannot enable MAC returning %x\n",status); } /* Write config if MIC needs to be on */ if(v_info->flags & MIC_CAPABLE) vwriterid(v_info, RID_CONFIG, (unsigned char *)&cfg,sizeof(ConfigRid)); return status;}/************************************************************* * This routine assumes that descriptors have been setup . * Run at insmod time or after reset when the decriptors * have been initialized . Returns 0 if all is well nz * otherwise . Does not allocate memory but sets up card * using previously allocated descriptors. */static int cb20_init_descriptors(struct net_device *dev){ struct cb20_info *v_info = (struct cb20_info *)dev->priv; Cmd cmd; Resp rsp; int i; /* Alloc card RX descriptors */ netif_stop_queue(dev); v_info->txdfc = MAX_DESC; memset(&rsp,0,sizeof(rsp)); memset(&cmd,0,sizeof(cmd)); cmd.cmd = CMD_X500_AllocDescriptor; cmd.parm0 = DESCRIPTOR_RX; cmd.parm1 = (v_info->rxfids[0].CardRamOff - v_info->auxregmembase); cmd.parm2 = MAX_DESC; if( (i = cb20command(v_info,&cmd,&rsp))!=0){ printk(KERN_CRIT "init_descriptors returns %d DESCRIPTOR_RX on init \n",i); return -1; } for(i=0;i!=MAX_DESC;i++){ memcpy((char *)v_info->rxfids[i].CardRamOff , (char *)&v_info->rxfids[i].RxDesc,sizeof(CARD_RX_DESC)); } /* Alloc card TX descriptors */ memset(&rsp,0,sizeof(rsp)); memset(&cmd,0,sizeof(cmd)); cmd.cmd = CMD_X500_AllocDescriptor; cmd.parm0 = DESCRIPTOR_TX; cmd.parm1 = (v_info->txfids[0].CardRamOff - v_info->auxregmembase); cmd.parm2 = MAX_DESC; if( (i = cb20command(v_info,&cmd,&rsp))!=0){ printk(KERN_CRIT "init_descriptors returns %d DESCRIPTOR_TX on init \n",i); return -1; } for(i=0;i!=MAX_DESC;i++){ v_info->txfids[i].TxDesc.valid = 1; memcpy((char *)v_info->txfids[i].CardRamOff , (char *)&v_info->txfids[i].TxDesc,sizeof(CARD_TX_DESC)); } v_info->txfids[i-1].TxDesc.eoc = 1; /* Last descriptor has EOC set */ /* Rid descriptor setup */ memcpy((char *)v_info->ConfigDesc.CardRamOff,(char *)&v_info->ConfigDesc.RIDDesc, sizeof(CARD_RID_DESC)); memset(&rsp,0,sizeof(rsp)); memset(&cmd,0,sizeof(cmd)); cmd.cmd = CMD_X500_AllocDescriptor; cmd.parm0 = DESCRIPTOR_HOSTRW; cmd.parm1 = (v_info->ConfigDesc.CardRamOff - v_info->auxregmembase); cmd.parm2 = 1; if( (i = cb20command(v_info,&cmd,&rsp))!=0){ printk(KERN_CRIT "init_descriptors returns %d on init HOSTRW\n",i); return -1; } return 0;}/* * *********************************IOCTL ACU API ***************************************** *//* @mac_ */static int mac_enable(struct cb20_info *vi, Resp *rsp ){ Cmd cmd; int i; memset(&cmd,0,sizeof(cmd)); cmd.cmd = CMD_X500_EnableAll; if(vi->macstatus == 0 ){ if((i= cb20command(vi,&cmd,rsp))) printk(KERN_ERR "Cannot enable mac err %d\n",i); vi->macstatus = 1; } else i = 0; return( i); }static void mac_disable( struct cb20_info *vi ) { Cmd cmd; Resp rsp; memset(&cmd, 0, sizeof(cmd)); memset(&rsp, 0, sizeof(rsp)); if(vi->macstatus == 1 ){ cmd.cmd = CMD_X500_DisableMAC ; cb20command(vi, &cmd, &rsp); vi->macstatus = 0; } }static void enable_interrupts(struct cb20_info *v_info){ v_info->flags &= ~(INT_DISABLE); cb20out(v_info,CB_CLEARINT,CB_FLAGBIT); cb20out(v_info,CB_INTENABLE,CB_FLAGBIT); cb20out(v_info,V_EVINTEN,STATUS_INTS);}static void disable_interrupts(struct cb20_info *v_info){ v_info->flags |= INT_DISABLE; cb20out(v_info,CB_CLEARINT,CB_FLAGBIT); cb20out(v_info,CB_INTENABLE,0); cb20out(v_info,V_EVINTEN,0);}/* * This just translates from driver IOCTL codes to the command codes to * feed to the radio's host interface. Things can be added/deleted * as needed. This represents the READ side of control I/O to * the card */static int readrids(struct net_device *dev, aironet_ioctl *comp) { unsigned short ridcode; DRVRTYPE dt; unsigned devflags=0; struct cb20_info *v_info ; v_info = (struct cb20_info *)dev->priv; if(v_info->flags & FLASHING ) /* Is busy */ return -EIO; switch(comp->command) { case AIROGCAP: ridcode = RID_CAPABILITIES; break; case AIROGCFG: ridcode = RID_CONFIG; break; case AIROGSLIST: ridcode = RID_SSID; break; case AIROGVLIST: ridcode = RID_APLIST; break; case AIROGDRVNAM: ridcode = RID_DRVNAME; break; case AIROGEHTENC: ridcode = RID_ETHERENCAP; break; case AIROGWEPKTMP: ridcode = RID_WEP_TEMP; break; case AIROGWEPKNV: ridcode = RID_WEP_PERM; break; case AIROGSTAT: ridcode = RID_STATUS; break; case AIROGSTATSD32: ridcode = RID_STATSDELTA; break; case AIROGSTATSC32: ridcode = RID_STATS; break; case AIROGMICRID: ridcode = RID_MIC; break; case AIROGMICSTATS: if(copy_to_user(comp->data,(char *)&v_info->micstats, MIN(comp->length, sizeof(STMICSTATISTICS32)))) { return -EFAULT; } else return 0; break; case AIROGFLAGS: devflags=v_info->flags; if(copy_to_user(comp->data,(char *)&devflags,MIN(comp->length,sizeof(devflags)))){ return -EFAULT; } else return 0; break; case AIROGID: /* DRIVER VERSION */ memset((char *)&dt,0,sizeof(dt)); /* @Driver version */ dt.version[0]=1; /* Major Minor version */ dt.version[1]=0; /* Minor */ dt.version[2]=15; /* vers */ dt.flashcode = 0xd8; /* Koala image firmware type */ dt.devtype = KOALA_TYPE; /* What this driver talks to */ if(copy_to_user(comp->data,(char *)&dt,MIN(comp->length,sizeof(DRVRTYPE)))){ return -EFAULT; } else return 0; break; case AIRORRID: ridcode = comp->ridnum; vreadrid((struct cb20_info *)dev->priv,ridcode,iobuf, 1024); if (copy_to_user(comp->data, iobuf, MIN (*(unsigned short *)iobuf, comp->length))) return -EFAULT; else return 0; break; default: return -EINVAL; break; } vreadrid((struct cb20_info *)dev->priv,ridcode,iobuf, 1024); if (copy_to_user(comp->data, iobuf, MIN (comp->length, sizeof(iobuf)))) return -EFAULT; return 0;}/* * Danger Vorlon death command here. */static int writerids(struct net_device *dev, aironet_ioctl *comp) { int ridcode,stat; u16 ridlen; Resp rsp; static unsigned char blargo[2048]; /* Not on kernel stack */ ConfigRid *cfg; struct cb20_info *v_info ; v_info = (struct cb20_info *)dev->priv; if(v_info->flags & FLASHING ) return -EIO; /* Cant touch this. */ memset(blargo,0,sizeof(blargo)); ridcode = 0; switch(comp->command) { case AIROPSIDS: ridcode = RID_SSID; break; case AIROPCAP: ridcode = RID_CAPABILITIES; break; case AIROPAPLIST: ridcode = RID_APLIST; break; case AIROPCFG: ridcode = RID_CONFIG; break; case AIROPWEPKEYNV: ridcode = RID_WEP_PERM; break; case AIROPLEAPUSR: ridcode = RID_LEAPUSERNAME; break; case AIROPLEAPPWD: ridcode = RID_LEAPPA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -