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

📄 cb20_cb.c

📁 vt6656驱动代码
💻 C
📖 第 1 页 / 共 5 页
字号:
   */  for(i=0;i!=READLINE_DEL;i++)    dummy = *(u32 *)sendbuf;    /* Do the right thing (TM) for mic */  if(v_info->flags & MIC_CAPABLE){    adhoc = (v_info->flags & ADHOC) ? 1:0;    if(Encapsulate(v_info,(ETH_HEADER_STRUC *)sendbuf,&miclen , adhoc))  {      *payloadlen = (s16 ) (miclen - sizeof(HDR_802_3));      txd.length = miclen + sizeof(HDR_802_11); /*1/15/2003 */    }    else      {#ifdef DEBUG_MIC	printk(KERN_DEBUG "Dumped tx packet\n");#endif	goto dumptx;      }        }  v_info->txdfc=0;  memcpy((char *)v_info->txfids[0].CardRamOff,	 (char *)&txd, sizeof(CARD_TX_DESC));  v_info->stats.tx_bytes += len + sizeof(HDR_802_11);  cb20out(v_info,V_EVACK,EV_XMIT);  /* Send packet */ dumptx:  if(in_irq())    dev_kfree_skb_irq(skb);  else    dev_kfree_skb(skb);  return 1;}#endif/* * Wait given value to appear on given port. * return 0 if it did in waitms ms else -1 * if not. */static  int waitport(struct cb20_info *v_info,int port,int value,int waitms){  u16 inword;  int i;  for(i=0;i!=waitms;i++){    inword = cb20in(v_info,port);    if(inword == value)      return 0;    mdelay(1);  }  return -1;}/* * Softreset for cb20 */ int softreset(struct cb20_info *v){  int shakehands=0;  cb20out(v ,V_EVINTEN,0);  if(!waitport(v,V_SWS0,BB_HANDSHAKE_0,4000)){    if(!waitport(v,V_SWS1,BB_HANDSHAKE_1,4000))      shakehands = 1;    else      printk(KERN_CRIT "Boot block wait timeout SWS1!!\n");  }  else    printk(KERN_CRIT "Boot block wait timeout SWS0!!\n");  if(!shakehands){    cb20out (v, V_CNFCTRL, 0x0504);    cb20out (v, V_CNFCTRL, 0x8000);    udelay (300);    cb20out (v, V_CNFCTRL, 0x0504);    mdelay (30); /* Jeff adams says this should be here */  }  return shakehands;}static  void cb20_linkstat(struct net_device *dev,int linkstatus){  struct   cb20_info *v_info  = (struct cb20_info*)dev->priv;#if ASSOCDEBUG  printk(KERN_INFO "Link stat int ls=%x\n",linkstatus);#endif  if(linkstatus & 0x8000 ){#ifdef ASSOCDEBUG    printk(KERN_INFO "No carrier\n");#endif    v_info->flags &= ~(ASSOC);    netif_carrier_off(  dev);    netif_stop_queue( dev );  }  else     if(linkstatus & 0x400){      v_info->flags |= ASSOC;#ifdef ASSOCDEBUG      printk(KERN_INFO "Carrier On\n");#endif      /* Update sequence numbers        * upon assoc        */      v_info->updateMultiSeq = TRUE;           v_info->updateUniSeq = TRUE;      netif_carrier_on( dev);      netif_wake_queue(dev);    }}/* * @interrupt */void cb20_interrupt ( int irq, void *dev_id, struct pt_regs *regs) {  struct net_device *dev = (struct net_device *)dev_id;  u16 stat1,stat=0,len;  struct cb20_info *v_info = (struct cb20_info *)dev->priv;  CARD_RX_DESC rxd;  u32    len32;  struct sk_buff *skb;  STMIC  mic;#ifdef INCLUDE_RFMONITOR  unsigned char *buffer;  int i;#endif  if (!netif_device_present(dev))    return;  spin_lock(&v_info->mpi_lock ); /* CB20 Globl lock */  memset((char *)&rxd,0,sizeof(rxd));  stat1  = cb20in(v_info,V_EVSTAT);  if(stat1 == 0 || stat1==0xffff){    spin_unlock(&v_info->mpi_lock ); /* Bogus interrupt */    return;  }  disable_interrupts(v_info);  if(stat1 & EV_MIC){#ifdef DEBUG_MIC    printk(KERN_INFO "MIC interrupt\n");#endif    cb20out(v_info,V_EVACK,EV_MIC);    vreadrid((struct cb20_info *)dev->priv,RID_MIC,(char *)&mic, sizeof(mic));    micinit(v_info,&mic);    stat1 &= ~(EV_MIC);  }  if(stat1 & EV_LINK){    stat = cb20in(v_info,V_LINKSTAT);    cb20_linkstat(dev,stat);    cb20out(v_info,V_EVACK,EV_LINK);    stat1 &= ~(EV_LINK);  }  if(stat1 & EV_AWAKE ){    stat1 &= ~(EV_AWAKE);    cb20out(v_info, V_EVACK, EV_AWAKE);      cb20out(v_info, V_EVACK, EV_AWAKE);    }  if(stat1 & EV_CMD ){    cb20out(v_info, V_EVACK, EV_CMD);  #ifdef DEBUG_CMD    printk(KERN_ERR "Command int!\n");#endif    stat1 &= ~(EV_CMD);  }  if(stat1 & EV_RX){    memcpy((char *)&rxd, v_info->rxfids[0].CardRamOff,sizeof(rxd));    /* Make sure we got something */    if(rxd.RxDone && rxd.valid ==0 ){#ifdef INCLUDE_RFMONITOR      if (v_info->rfMonitor) {        if (v_info->rxfids[0].VirtualHostAddress[4] & 0x2) { /* CRC error */          len = 0;        } else {          len = *(u16*)((u16*)(v_info->rxfids[0].VirtualHostAddress)+3)+30;        }        if (len && len < 2312) {          v_info->stats.rx_packets++;          v_info->stats.rx_bytes += len;          skb = dev_alloc_skb( len );          buffer = skb_put(skb, len);          memcpy(buffer, v_info->rxfids[0].VirtualHostAddress+20, 30);          /* gap length */          i = *(u16*)((u16*)(v_info->rxfids[0].VirtualHostAddress)+25);          if (i+len+52 > rxd.length) {            i = 0;          }          /* skip the gap */          memcpy(buffer+30, v_info->rxfids[0].VirtualHostAddress+52+i,len-30);          skb->mac.raw = skb->data;          skb->pkt_type = PACKET_OTHERHOST;          skb->protocol = htons(ETH_P_802_2);          skb->dev = dev;          skb->ip_summed = CHECKSUM_NONE;          dev->last_rx = jiffies;          netif_rx( skb );        }      } else#endif      {      len = rxd.length + 12;      if( len > 12 && len < 2048 ){	skb = dev_alloc_skb( len  );		if(v_info->flags &  MIC_CAPABLE){ 	/* Check for MIC */	  len32 = (u32)len;	  if(Decapsulate(v_info ,			 (ETH_HEADER_STRUC *)v_info->rxfids[0].VirtualHostAddress, 			 &len32 ))	    {#ifdef DEBUG_MIC	      printk(KERN_ERR "Dumping packet from decap\n");#endif	      dev_kfree_skb_irq(skb);	      goto dumpit;	    }	  len = len32 ;	}	v_info->stats.rx_bytes += len;	v_info->stats.rx_packets++;		memcpy(skb_put(skb,len),v_info->rxfids[0].VirtualHostAddress,len);	skb->dev = dev;	skb->ip_summed = CHECKSUM_NONE;	skb->protocol = eth_type_trans( skb, dev );	dev->last_rx = jiffies;	netif_rx( skb );      }    }    }  dumpit:    if(rxd.valid == 0){      rxd.valid = 1;      rxd.RxDone= 0;      rxd.length= HOSTBUFSIZ;        memcpy(v_info->rxfids[0].CardRamOff,(char *)&rxd,sizeof(rxd));    }    cb20out(v_info, V_EVACK, EV_RX);      stat1 &= ~(EV_RX);  }  if(stat1 & EV_TXCPY){    stat1 &= ~(EV_TXCPY);    ++v_info->stats.tx_packets;    v_info->txdfc =1;#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,55 ))    if(skb_queue_len(&v_info->txq) !=0){      v_info->flags |= TXBUSY;      send_packet(dev);    }    else{	v_info->flags &= ~(TXBUSY);	netif_wake_queue(dev);      }#else    dev->tbusy=0; /* Reenable queueing */#endif    cb20out(v_info, V_EVACK, EV_TXCPY);    }  if(stat1){    printk(KERN_ERR "Unhandled event %x \n",stat1);    cb20out(v_info,V_EVACK,stat1);  }  if((INT_DISABLE & v_info->flags) == 0){    cb20out(v_info,CB_CLEARINT,CB_FLAGBIT);    cb20out(v_info,CB_INTENABLE,CB_FLAGBIT);  }  spin_unlock(&v_info->mpi_lock ); /* CB20 Globl lock */  enable_interrupts(v_info);  return;}/* * @open */static  int cb20_open(struct net_device *vdev){    struct cb20_info *v_info;  MOD_INC_USE_COUNT;  v_info = (struct cb20_info *)vdev->priv;  if(v_info->flags & REAP)    return -ENODEV;  if(!v_info->open){    request_irq(vdev->irq,cb20_interrupt,SA_SHIRQ,vdev->name,vdev);    v_info->flags &= ~(INT_DISABLE);    netif_start_queue(vdev);    enable_interrupts(v_info);  }  v_info->open++;  return 0;}/* * @close */static  int cb20_close(struct net_device *dev) {   struct cb20_info *vi = (struct cb20_info*)dev->priv;  vi->open--;  vi->flags |= INT_DISABLE;  if ( !vi->open ) {    disable_interrupts(vi);    netif_stop_queue(dev);    free_irq( dev->irq, dev );  }  MOD_DEC_USE_COUNT;  return 0;}static  struct net_device_stats *cb20_get_stats(struct net_device *dev){  return &(((struct cb20_info *)dev->priv)->stats);}static  int  cb20_change_mtu(struct net_device *dev, int new_mtu){  if ((new_mtu < 68) || (new_mtu > 2400))    return -EINVAL;  dev->mtu = new_mtu;  return 0;}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,55 ))/* * @cb20_transmit */static  int cb20_transmit(struct sk_buff *skb, struct net_device *dev) {  int    flags,npacks;  struct cb20_info *v_info  = (struct cb20_info*)dev->priv;    if ( skb == NULL ) {    printk( KERN_ERR "CB20 :  skb == NULL!!!\n" );    return 0;  }  disable_interrupts(v_info);  spin_lock_irqsave(&v_info->mpi_lock,flags);    npacks = skb_queue_len(&v_info->txq);  if(npacks >= MAXTXQ ){    netif_stop_queue(dev);    skb_queue_tail(&v_info->txq,skb);    dev_kfree_skb(skb); /* Throw on floor */    v_info->stats.tx_dropped++;    enable_interrupts(v_info);    spin_unlock_irqrestore(&v_info->mpi_lock,flags);    return 0;  }  if(npacks >= MAXTXQ - 10 ){    netif_stop_queue(dev);    skb_queue_tail(&v_info->txq,skb);    enable_interrupts(v_info);    spin_unlock_irqrestore(&v_info->mpi_lock,flags);    return 0;  }    skb_queue_tail(&v_info->txq, skb);     netif_wake_queue(dev);  if((v_info->flags & TXBUSY) == 0){    send_packet(dev);    }  enable_interrupts(v_info);  spin_unlock_irqrestore(&v_info->mpi_lock,flags);  return 0;}#endif/* * Multiple card list handling reaping and locating etc * @devlist */static void cb20_reap(void){  struct cb20_info *v_info;  struct net_device *devp;  CB20_CARDS **p = &cb20_units;  while( *p  ){        devp = (*p)->dev;    v_info = (struct cb20_info *)devp->priv;    /* If found then reap it and      * remove it from the list      */    if(v_info->flags & REAP && !v_info->open ){      unregister_netdev(devp);      kfree(devp);      *p = (*p)->next;      continue;    }    p = &(*p)->next;      }}static void add_cb20( struct net_device *dev ) {  CB20_CARDS *node = (CB20_CARDS *)kmalloc( sizeof( *node ), GFP_KERNEL );  if ( !node ) {    printk( KERN_ERR "CB20:  Out of memory\n" );  }   else {    node->dev   = dev;    node->next  = cb20_units ;    cb20_units  = node;  }}#if  !defined(CONFIG_NET_PCMCIA) /* * Return netdevice struct pointer for  * specified interface null if not found * @loc_cb20 */static struct net_device *loc_cb20(char *devname){  CB20_CARDS **p = &cb20_units;  struct net_device *devp ;  while( *p ){    devp = (*p)->dev ;    if(!strcmp(devp->name,devname))      return devp;    p = &(*p)->next;  }  return NULL;}#endif#if  defined(CONFIG_NET_PCMCIA) /* * Return the struct net_device * used by struct pci_dev *locate * return null if none found and b*tch as something is seriously * hosed. */static struct net_device *pcidev_loc(struct pci_dev *locate){   CB20_CARDS **p = &cb20_units;   struct net_device *devp ;   struct cb20_info *vp;   struct pci_dev *pcid;   while( *p ){     devp = (*p)->dev ;     vp= (struct cb20_info *)devp->priv;     pcid = vp->pcip;     if(!memcmp((void*)pcid,(void *)locate,sizeof(*locate)))	return devp;     p = &(*p)->next;   }   printk(KERN_ERR "Can not find %p\n",locate);   return NULL;}    #endifvoid del_cb20( struct net_device *dev ) {  CB20_CARDS **p = &cb20_units;  struct cb20_info *v_info;  struct net_device *devp;  v_info = (struct cb20_info *)dev->priv ;#if !defined(CONFIG_NET_PCMCIA)   if(v_info->flags & REAP ){#ifdef DEBUG_DEL    printk(KERN_DEBUG "REAP BIT SET not deleted!!\n");#endif    return;  }#endif  while( *p &&  (*p)->dev != dev  ){    devp = (*p)->dev;    p = &(*p)->next;  }  if ( *p && (*p)->dev == dev ){    v_info = (struct cb20_info *)(*p)->dev->priv;    v_info = (struct cb20_info *)(*p)->dev->priv;    *p = (*p)->next;   }}/*  * Proc filesystem processing   *//* @del_proc */static  int del_proc_entry( struct net_device *dev,struct cb20_info *apriv ) {  struct cb20_info *v_info ;  v_info = (struct cb20_info *)dev->priv;#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,55))

⌨️ 快捷键说明

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