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

📄 arc-rimi.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	      if (lp->lasttrans_dest != 0)		{		  BUGMSG(D_EXTRA,"transmit was not acknowledged! (status=%Xh, dest=%02Xh)\n",			 status,lp->lasttrans_dest);		  lp->stats.tx_errors++;		  lp->stats.tx_carrier_errors++;		}	      else		{		  BUGMSG(D_DURING,"broadcast was not acknowledged; that's normal (status=%Xh, dest=%02Xh)\n",			 status,			 lp->lasttrans_dest);		}	    }	  /* send packet if there is one */	  arcnet_go_tx(dev,0);	  didsomething++;	  if (lp->intx)	    {	      BUGMSG(D_DURING,"TXDONE while intx! (status=%Xh, intx=%d)\n",		     ARCSTATUS,lp->intx);	      lp->in_txhandler--;	      continue;	    }	  if (!lp->outgoing.skb)	    {	      BUGMSG(D_DURING,"TX IRQ done: no split to continue.\n");	      /* inform upper layers */	      if (!lp->txready) arcnet_tx_done(dev, lp);	      lp->in_txhandler--;	      continue;	    }	  /* if more than one segment, and not all segments	   * are done, then continue xmit.	   */	  if (out->segnum<out->numsegs)	    arcnetA_continue_tx(dev);	  arcnet_go_tx(dev,0);	  /* if segnum==numsegs, the transmission is finished;	   * free the skb.	   */	  if (out->segnum>=out->numsegs)	    {	      /* transmit completed */	      out->segnum++;	      if (out->skb)		{		  lp->stats.tx_bytes += out->skb->len;		  dev_kfree_skb(out->skb);		}	      out->skb=NULL;	      /* inform upper layers */	      if (!lp->txready) arcnet_tx_done(dev, lp);	    }	  didsomething++;	  lp->in_txhandler--;	}      else if (lp->txready && !lp->sending && !lp->intx)	{	  BUGMSG(D_NORMAL,"recovery from silent TX (status=%Xh)\n",		 status);	  arcnet_go_tx(dev,0);	  didsomething++;	}#ifdef DETECT_RECONFIGS      if (status & (lp->intmask) & RECONflag)	{	  ACOMMAND(CFLAGScmd|CONFIGclear);	  lp->stats.tx_carrier_errors++;#ifdef SHOW_RECONFIGS	  BUGMSG(D_NORMAL,"Network reconfiguration detected (status=%Xh)\n",		 status);#endif /* SHOW_RECONFIGS */#ifdef RECON_THRESHOLD	  /* is the RECON info empty or old? */	  if (!lp->first_recon || !lp->last_recon ||	      jiffies-lp->last_recon > HZ*10)	    {	      if (lp->network_down)		BUGMSG(D_NORMAL,"reconfiguration detected: cabling restored?\n");	      lp->first_recon=lp->last_recon=jiffies;	      lp->num_recons=lp->network_down=0;	      BUGMSG(D_DURING,"recon: clearing counters.\n");	    }	  else /* add to current RECON counter */	    {	      lp->last_recon=jiffies;	      lp->num_recons++;	      BUGMSG(D_DURING,"recon: counter=%d, time=%lds, net=%d\n",		     lp->num_recons,		     (lp->last_recon-lp->first_recon)/HZ,		     lp->network_down);	      /* if network is marked up;	       * and first_recon and last_recon are 60+ sec	       *   apart;	       * and the average no. of recons counted is	       *   > RECON_THRESHOLD/min;	       * then print a warning message.	       */	      if (!lp->network_down		  && (lp->last_recon-lp->first_recon)<=HZ*60		  && lp->num_recons >= RECON_THRESHOLD)		{		  lp->network_down=1;		  BUGMSG(D_NORMAL,"many reconfigurations detected: cabling problem?\n");		}	      else if (!lp->network_down		       && lp->last_recon-lp->first_recon > HZ*60)		{		  /* reset counters if we've gone for		   * over a minute.		   */		  lp->first_recon=lp->last_recon;		  lp->num_recons=1;		}	    }	}      else if (lp->network_down && jiffies-lp->last_recon > HZ*10)	{	  if (lp->network_down)	    BUGMSG(D_NORMAL,"cabling restored?\n");	  lp->first_recon=lp->last_recon=0;	  lp->num_recons=lp->network_down=0;	  BUGMSG(D_DURING,"not recon: clearing counters anyway.\n");#endif	}#endif /* DETECT_RECONFIGS */    } while (--boguscount && didsomething);  BUGMSG(D_DURING,"net_interrupt complete (status=%Xh, count=%d)\n",	 ARCSTATUS,boguscount);  BUGMSG(D_DURING,"\n");  SETMASK;	/* put back interrupt mask */}/* A packet has arrived; grab it from the buffers and pass it to the generic * arcnet_rx routing to deal with it. */static voidarcrimi_rx(struct device *dev,int recbuf){  struct arcnet_local *lp = (struct arcnet_local *)dev->priv;  int ioaddr=dev->mem_start+0x800;  union ArcPacket *arcpacket=    (union ArcPacket *)phys_to_virt(dev->mem_start+recbuf*512);  u_char *arcsoft;  short length,offset;  u_char daddr,saddr;  lp->stats.rx_packets++;  saddr=arcpacket->hardheader.source;  /* if source is 0, it's a "used" packet! */  if (saddr==0)    {      BUGMSG(D_NORMAL,"discarding old packet. (status=%Xh)\n",	     ARCSTATUS);      lp->stats.rx_errors++;      return;    }  /* Set source address to zero to mark it as old */  arcpacket->hardheader.source=0;  daddr=arcpacket->hardheader.destination;  if (arcpacket->hardheader.offset1) /* Normal Packet */    {      offset=arcpacket->hardheader.offset1;      arcsoft=&arcpacket->raw[offset];      length=256-offset;    }  else		/* ExtendedPacket or ExceptionPacket */    {      offset=arcpacket->hardheader.offset2;      arcsoft=&arcpacket->raw[offset];      length=512-offset;    }  arcnet_rx(lp, arcsoft, length, saddr, daddr);  BUGLVL(D_RX) arcnet_dump_packet(lp->adev,arcpacket->raw,length>240,"rx");#ifndef SLOW_XMIT_COPY  /* clean out the page to make debugging make more sense :) */  BUGLVL(D_DURING)    memset((void *)arcpacket->raw,0x42,512);#endif}/* Given an skb, copy a packet into the ARCnet buffers for later transmission * by arcnet_go_tx. */static voidarcrimi_prepare_tx(struct device *dev,u_char *hdr,int hdrlen,		   char *data,int length,int daddr,int exceptA, int offset){  struct arcnet_local *lp = (struct arcnet_local *)dev->priv;  union ArcPacket *arcpacket =    (union ArcPacket *)phys_to_virt(dev->mem_start+512*(lp->txbuf^1));#ifdef SLOW_XMIT_COPY  char *iptr,*iend,*optr;#endif  lp->txbuf=lp->txbuf^1;	/* XOR with 1 to alternate between 2 and 3 */  length+=hdrlen;  BUGMSG(D_TX,"arcnetAS_prep_tx: hdr:%ph, length:%d, data:%ph\n",	 hdr,length,data);#ifndef SLOW_XMIT_COPY  /* clean out the page to make debugging make more sense :) */  BUGLVL(D_DURING)    memset_io(dev->mem_start+lp->txbuf*512,0x42,512);#endif  arcpacket->hardheader.destination=daddr;  /* load packet into shared memory */  if (length<=MTU)	/* Normal (256-byte) Packet */    arcpacket->hardheader.offset1=offset=offset?offset:256-length;  else if (length>=MinTU || offset)	/* Extended (512-byte) Packet */    {      arcpacket->hardheader.offset1=0;      arcpacket->hardheader.offset2=offset=offset?offset:512-length;    }  else if (exceptA)		/* RFC1201 Exception Packet */    {      arcpacket->hardheader.offset1=0;      arcpacket->hardheader.offset2=offset=512-length-4;      /* exception-specific stuff - these four bytes       * make the packet long enough to fit in a 512-byte       * frame.       */      arcpacket->raw[offset+0]=hdr[0];      arcpacket->raw[offset+1]=0xFF; /* FF flag */      arcpacket->raw[offset+2]=0xFF; /* FF padding */      arcpacket->raw[offset+3]=0xFF; /* FF padding */      offset+=4;    }  else				/* "other" Exception packet */    {      /* RFC1051 - set 4 trailing bytes to 0 */      memset(&arcpacket->raw[508],0,4);      /* now round up to MinTU */      arcpacket->hardheader.offset1=0;      arcpacket->hardheader.offset2=offset=512-MinTU;    }  /* copy the packet into ARCnet shmem   *  - the first bytes of ClientData header are skipped   */  memcpy((u_char*)arcpacket+offset, (u_char*)hdr,hdrlen);#ifdef SLOW_XMIT_COPY  for (iptr=data,iend=iptr+length-hdrlen,optr=(char *)arcpacket+offset+hdrlen;       iptr<iend; iptr++,optr++)    {      *optr=*iptr;      /*udelay(5);*/    }#else  memcpy((u_char*)arcpacket+offset+hdrlen, data,length-hdrlen);#endif  BUGMSG(D_DURING,"transmitting packet to station %02Xh (%d bytes)\n",	 daddr,length);  BUGLVL(D_TX) arcnet_dump_packet(dev,arcpacket->raw,length>MTU,"tx");  lp->lastload_dest=daddr;  lp->txready=lp->txbuf;	/* packet is ready for sending */}/**************************************************************************** *                                                                          * * Kernel Loadable Module Support                                           * *                                                                          * ****************************************************************************/#ifdef MODULEstatic char devicename[9] = "";static struct device thiscard = {  devicename, /* device name is inserted by linux/drivers/net/net_init.c */  0, 0, 0, 0,  0, 0,  /* I/O address, IRQ */  0, 0, 0, NULL, arcrimi_probe};int init_module(void){  struct device *dev=&thiscard;  if (device)    strcpy(dev->name,device);  else arcnet_makename(dev->name);  if (node && node != 0xff)    dev->dev_addr[0]=node;  dev->irq=irq;  if (dev->irq==2) dev->irq=9;  if (shmem)    {      dev->mem_start=shmem;      dev->mem_end=thiscard.mem_start+512*4-1;      dev->rmem_start=thiscard.mem_start+512*0;      dev->rmem_end=thiscard.mem_start+512*2-1;    }  if (register_netdev(dev) != 0)    return -EIO;  arcnet_use_count(1);  return 0;}void cleanup_module(void){  struct device *dev=&thiscard;  int ioaddr=dev->mem_start;  if (dev->start) (*dev->stop)(dev);  /* Flush TX and disable RX */  if (ioaddr)    {      AINTMASK(0);		/* disable IRQ's */      ACOMMAND(NOTXcmd);	/* stop transmit */      ACOMMAND(NORXcmd);	/* disable receive */    }  if (dev->irq)    {      free_irq(dev->irq,dev);    }  unregister_netdev(dev);  kfree(dev->priv);  dev->priv = NULL;  arcnet_use_count(0);}#else__initfunc(void arcrimi_setup (char *str, int *ints)){  struct device *dev;  if (arcnet_num_devs == MAX_ARCNET_DEVS)    {      printk("ARCnet RIM I: Too many ARCnet devices registered (max %d).\n",	     MAX_ARCNET_DEVS);      return;    }  dev=&arcnet_devs[arcnet_num_devs];  if (ints[0] < 3)    {      printk("ARCnet RIM I: You must give address, IRQ and node ID.\n");      return;    }  dev->init=arcrimi_probe;  switch(ints[0])    {    case 4: /* ERROR */      printk("ARCnet RIM I: Too many arguments.\n");    case 3: /* Node ID */      dev->dev_addr[0]=(u_char)ints[3];    case 2: /* IRQ */      dev->irq=ints[2];    case 1: /* Mem address */      dev->mem_start=ints[1];    }  dev->name = (char *)&arcnet_dev_names[arcnet_num_devs];  if (str)    strncpy(dev->name, str, 9);  arcnet_num_devs++;}#endif /* MODULE */

⌨️ 快捷键说明

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