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

📄 arcnet.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
  u_char daddr;  short offset,length=skb->len+1;  u_char proto=ARC_P_ETHER;  lp->intx++;  oldmask |= lp->intmask;  lp->intmask=0;  SETMASK;  bad=arcnet_send_packet_bad(skb,dev);  if (bad)    {      lp->intx--;      lp->intmask=oldmask;      SETMASK;      return bad;    }  /* arcnet_send_packet_pad has already set tbusy - don't bother here. */  lp->intmask=oldmask;  SETMASK;  if (length>XMTU)    {      BUGMSG(D_NORMAL,"MTU must be <= 493 for ethernet encap (length=%d).\n",	     length);      BUGMSG(D_NORMAL,"transmit aborted.\n");      dev_kfree_skb(skb);      lp->intx--;      return 0;    }  BUGMSG(D_DURING,"starting tx sequence...\n");  /* broadcasts have address FF:FF:FF:FF:FF:FF in etherspeak */  if (((struct ethhdr*)(skb->data))->h_dest[0] == 0xFF)    daddr=0;  else    daddr=((struct ethhdr*)(skb->data))->h_dest[5];  /* load packet into shared memory */  offset=512-length;  if (length>MTU)		/* long/exception packet */    {      if (length<MinTU) offset-=3;    }  else			/* short packet */    {      offset-=256;    }  BUGMSG(D_DURING," length=%Xh, offset=%Xh\n",	 length,offset);  (*lp->prepare_tx)(dev, &proto, 1, skb->data, length-1, daddr, 0,			   offset);  dev_kfree_skb(skb);  if (arcnet_go_tx(dev,1))    {      /* inform upper layers */      arcnet_tx_done(lp->adev, lp);    }	dev->trans_start=jiffies;	lp->intx--;	/* make sure we didn't ignore a TX IRQ while we were in here */	lp->intmask |= TXFREEflag;	SETMASK;	return 0;}/* Packet receiver for ethernet-encap packets. */static voidarcnetE_rx(struct device *dev,u_char *arcsoft,	int length,u_char saddr, u_char daddr){	struct arcnet_local *lp = (struct arcnet_local *)dev->priv;	struct sk_buff *skb;	BUGMSG(D_DURING,"it's an ethernet-encap packet (length=%d)\n",			length);       	skb = alloc_skb(length, GFP_ATOMIC);       	if (skb == NULL) {       		BUGMSG(D_NORMAL,"Memory squeeze, dropping packet.\n");       		lp->stats.rx_dropped++;       		return;       	}       	skb_put(skb,length);       	skb->dev = dev;       	memcpy(skb->data,(u_char *)arcsoft+1,length-1);        BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");	lp->stats.rx_bytes += skb->len;	skb->protocol=eth_type_trans(skb,dev);        netif_rx(skb);}#endif /* CONFIG_ARCNET_ETH */#ifdef CONFIG_ARCNET_1051/**************************************************************************** *                                                                          * * RFC1051 Support                                                          * *                                                                          * ****************************************************************************//* Initialize the arc0s device. */static int arcnetS_init(struct device *dev){  struct arcnet_local *lp = (struct arcnet_local *)dev->priv;  arcnet_setup(dev);  /* And now fill particular fields with arcnet values */  dev->dev_addr[0]=lp->stationid;  dev->hard_header_len=sizeof(struct S_ClientData);  dev->mtu=512-sizeof(struct archdr)-dev->hard_header_len    + S_EXTRA_CLIENTDATA;  dev->open=arcnetS_open_close;  dev->stop=arcnetS_open_close;  dev->hard_start_xmit=arcnetS_send_packet;  dev->hard_header=arcnetS_header;  dev->rebuild_header=arcnetS_rebuild_header;  return 0;}/* Bring up/down the arc0s device - we don't actually have to do anything, * since our parent arc0 handles the card I/O itself. */static int arcnetS_open_close(struct device *dev){  return 0;}/* Called by the kernel in order to transmit an RFC1051-type packet. */static intarcnetS_send_packet(struct sk_buff *skb, struct device *dev){  struct arcnet_local *lp = (struct arcnet_local *)dev->priv;  int bad,length;  struct S_ClientData *hdr=(struct S_ClientData *)skb->data;  lp->intx++;  bad=arcnet_send_packet_bad(skb,dev);  if (bad)    {      lp->intx--;      return bad;    }  /* arcnet_send_packet_pad has already set tbusy - don't bother here. */  length = 1 < skb->len ? skb->len : 1;  BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"tx");  /* fits in one packet? */  if (length-S_EXTRA_CLIENTDATA<=XMTU)    {      (*lp->prepare_tx)(dev,			skb->data+S_EXTRA_CLIENTDATA,			sizeof(struct S_ClientData)-S_EXTRA_CLIENTDATA,			skb->data+sizeof(struct S_ClientData),			length-sizeof(struct S_ClientData),			hdr->daddr,0,0);      /* done right away */      dev_kfree_skb(skb);      if (arcnet_go_tx(dev,1))	{	  /* inform upper layers */	  arcnet_tx_done(lp->adev, lp);	}    }  else			/* too big for one - not accepted */    {      BUGMSG(D_NORMAL,"packet too long (length=%d)\n",	     length);      dev_kfree_skb(skb);      lp->stats.tx_dropped++;      arcnet_tx_done(lp->adev, lp);    }  dev->trans_start=jiffies;  lp->intx--;  /* make sure we didn't ignore a TX IRQ while we were in here */  lp->intmask |= TXFREEflag;  SETMASK;  return 0;}/* Packet receiver for RFC1051 packets; */static voidarcnetS_rx(struct device *dev,u_char *buf,	   int length,u_char saddr, u_char daddr){  struct arcnet_local *lp = (struct arcnet_local *)dev->priv;  struct sk_buff *skb;  struct S_ClientData *arcsoft,*soft;  arcsoft=(struct S_ClientData *)(buf-S_EXTRA_CLIENTDATA);  length+=S_EXTRA_CLIENTDATA;  BUGMSG(D_DURING,"it's an RFC1051 packet (length=%d)\n",	 length);  {    /* was "if not split" in A protocol, S is never split */    skb = alloc_skb(length, GFP_ATOMIC);    if (skb == NULL) {      BUGMSG(D_NORMAL,"Memory squeeze, dropping packet.\n");      lp->stats.rx_dropped++;      return;    }    soft=(struct S_ClientData *)skb->data;    skb_put(skb,length);    memcpy((u_char *)soft + sizeof(struct S_ClientData) - S_EXTRA_CLIENTDATA,	   (u_char *)arcsoft + sizeof(struct S_ClientData) -S_EXTRA_CLIENTDATA,	   length - sizeof(struct S_ClientData) + S_EXTRA_CLIENTDATA);    soft->protocol_id=arcsoft->protocol_id;    soft->daddr=daddr;    soft->saddr=saddr;    skb->dev = dev;  /* is already lp->sdev */    BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");    lp->stats.rx_bytes += skb->len;    skb->protocol=arcnetS_type_trans(skb,dev);    netif_rx(skb);  }}/* Create the ARCnet ClientData header for an arbitrary protocol layer * * saddr=NULL	means use device source address (always will anyway) * daddr=NULL	means leave destination address (eg unresolved arp) */static int arcnetS_header(struct sk_buff *skb,struct device *dev,			  unsigned short type,void *daddr,void *saddr,unsigned len){  struct S_ClientData *head = (struct S_ClientData *)    skb_push(skb,dev->hard_header_len);  struct arcnet_local *lp=(struct arcnet_local *)(dev->priv);  /* set the protocol ID according to RFC1051 */  switch(type)    {    case ETH_P_IP:      head->protocol_id=ARC_P_IP_RFC1051;      BUGMSG(D_DURING,"S_header: IP_RFC1051 packet.\n");      break;    case ETH_P_ARP:      head->protocol_id=ARC_P_ARP_RFC1051;      BUGMSG(D_DURING,"S_header: ARP_RFC1051 packet.\n");      break;    default:      BUGMSG(D_NORMAL,"I don't understand protocol %d (%Xh)\n",	     type,type);      lp->stats.tx_errors++;      lp->stats.tx_aborted_errors++;      return 0;    }  /*   * Set the source hardware address.   *   * This is pretty pointless for most purposes, but it can help   * in debugging.  saddr is stored in the ClientData header and   * removed before sending the packet (since ARCnet does not allow   * us to change the source address in the actual packet sent)   */  if(saddr)    head->saddr=((u_char*)saddr)[0];  else    head->saddr=((u_char*)(dev->dev_addr))[0];  /* supposedly if daddr is NULL, we should ignore it... */  if(daddr)    {		head->daddr=((u_char*)daddr)[0];		return dev->hard_header_len;    }  else    head->daddr=0;	/* better fill one in anyway */  return -dev->hard_header_len;}/* Rebuild the ARCnet ClientData header. This is called after an ARP * (or in future other address resolution) has completed on this * sk_buff. We now let ARP fill in the other fields. */static int arcnetS_rebuild_header(struct sk_buff *skb){  struct device *dev=skb->dev;  struct S_ClientData *head = (struct S_ClientData *)skb->data;  struct arcnet_local *lp=(struct arcnet_local *)(dev->priv);  /*   * Only ARP and IP are currently supported   */  if(head->protocol_id != ARC_P_IP_RFC1051)    {      BUGMSG(D_NORMAL,"I don't understand protocol type %d (%Xh) addresses!\n",	     head->protocol_id,head->protocol_id);      lp->stats.tx_errors++;      lp->stats.tx_aborted_errors++;      head->daddr=0;      /*memcpy(eth->h_source, dev->dev_addr, dev->addr_len);*/      return 0;    }  /*   * Try to get ARP to resolve the header.   */#ifdef CONFIG_INET  return arp_find(&(head->daddr),skb)? 1 : 0;#else  return 0;#endif}/* Determine a packet's protocol ID. * * With ARCnet we have to convert everything to Ethernet-style stuff. */unsigned short arcnetS_type_trans(struct sk_buff *skb,struct device *dev){  struct S_ClientData *head;  struct arcnet_local *lp=(struct arcnet_local *) (dev->priv);  /* Pull off the arcnet header. */  skb->mac.raw=skb->data;  skb_pull(skb,dev->hard_header_len);  head=(struct S_ClientData *)skb->mac.raw;  if (head->daddr==0)    skb->pkt_type=PACKET_BROADCAST;  else if (dev->flags&IFF_PROMISC)    {      /* if we're not sending to ourselves :) */      if (head->daddr != dev->dev_addr[0])	skb->pkt_type=PACKET_OTHERHOST;    }  /* now return the protocol number */  switch (head->protocol_id)    {    case ARC_P_IP_RFC1051:	return htons(ETH_P_IP);    case ARC_P_ARP_RFC1051:	return htons(ETH_P_ARP);    case ARC_P_ATALK:   return htons(ETH_P_ATALK); /* untested appletalk */    default:      lp->stats.rx_errors++;      lp->stats.rx_crc_errors++;      return 0;    }  return htons(ETH_P_IP);}#endif	/* CONFIG_ARCNET_1051 *//**************************************************************************** *                                                                          * * Kernel Loadable Module Support                                           * *                                                                          * ****************************************************************************/#ifdef MODULEvoid cleanup_module(void){  printk("Generic arcnet support removed.\n");}void arcnet_use_count(int open){  if (open)    MOD_INC_USE_COUNT;  else    MOD_DEC_USE_COUNT;}#elsevoid arcnet_use_count(int open){}struct device arcnet_devs[MAX_ARCNET_DEVS];int arcnet_num_devs=0;char arcnet_dev_names[MAX_ARCNET_DEVS][10];__initfunc(void arcnet_init(void)){  int c;  init_module();  /* Don't register_netdev here. The chain hasn't been initialised. */#ifdef CONFIG_ARCNET_COM90xx  if ((!com90xx_explicit) && arcnet_num_devs < MAX_ARCNET_DEVS)    {      arcnet_devs[arcnet_num_devs].init=arc90xx_probe;      arcnet_devs[arcnet_num_devs].name=	(char *)&arcnet_dev_names[arcnet_num_devs];      arcnet_num_devs++;    }#endif  if (!arcnet_num_devs)    {      printk("Don't forget to load the chipset driver.\n");      return;    }  /* Link into the device chain */  /* Q: Should we put ourselves at the beginning or the end of the chain? */  /* Probably the end, because we're not so fast, but... */  for (c=0; c< (arcnet_num_devs-1); c++)    arcnet_devs[c].next=&arcnet_devs[c+1];  arcnet_devs[c].next=dev_base;  dev_base=&arcnet_devs[0];  /* Give names to those without them */  for (c=0; c< arcnet_num_devs; c++)    if (!arcnet_dev_names[c][0])      arcnet_makename((char *)&arcnet_dev_names[c]);}#endif /* MODULE */#ifdef MODULEint init_module(void)#else__initfunc(static int init_module(void))#endif{#ifdef ALPHA_WARNING  BUGLVL(D_EXTRA)    {      printk("arcnet: ***\n");      printk("arcnet: * Read arcnet.txt for important release notes!\n");      printk("arcnet: *\n");      printk("arcnet: * This is an ALPHA version!  (Last stable release: v2.56)  E-mail me if\n");      printk("arcnet: * you have any questions, comments, or bug reports.\n");      printk("arcnet: ***\n");    }#endif  printk("%sAvailable protocols: ARCnet RFC1201"#ifdef CONFIG_ARCNET_ETH	 ", Ethernet-Encap"#endif#ifdef CONFIG_ARCNET_1051	 ", ARCnet RFC1051"#endif#ifdef MODULE	 ".\nDon't forget to load the chipset driver"#endif	".\n",version);  return 0;}void arcnet_makename(char *device){  struct device *dev;  int arcnum;  arcnum = 0;  for (;;)    {      sprintf(device, "arc%d", arcnum);      for (dev = dev_base; dev; dev=dev->next)	if (dev->name != device && !strcmp(dev->name, device))	  break;      if (!dev)	return;      arcnum++;    }}

⌨️ 快捷键说明

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