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

📄 arcnet.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
      break;#endif    case ARC_P_DATAPOINT_BOOT:    case ARC_P_DATAPOINT_MOUNT:      break;    case ARC_P_POWERLAN_BEACON:    case ARC_P_POWERLAN_BEACON2:      break;    case ARC_P_LANSOFT: /* don't understand.  fall through. */    default:      BUGMSG(D_EXTRA,"received unknown protocol %d (%Xh) from station %d.\n",	     arcsoft[0],arcsoft[0],saddr);      lp->stats.rx_errors++;      lp->stats.rx_crc_errors++;      break;    }  /* If any worth-while packets have been received, a mark_bh(NET_BH)   * has been done by netif_rx and Linux will handle them after we   * return.   */}/* Packet receiver for "standard" RFC1201-style packets */static voidarcnetA_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 ClientData *arcsoft,*soft;  BUGMSG(D_DURING,"it's an RFC1201 packet (length=%d)\n",	 length);  /* compensate for EXTRA_CLIENTDATA (which isn't actually in the   * packet)   */  arcsoft=(struct ClientData *)(buf-EXTRA_CLIENTDATA);  length+=EXTRA_CLIENTDATA;  if (arcsoft->split_flag==0xFF)  /* Exception Packet */    {      BUGMSG(D_DURING,"compensating for exception packet\n");      /* skip over 4-byte junkola */      arcsoft=(struct ClientData *)	((u_char *)arcsoft + 4);      length-=4;    }  if (!arcsoft->split_flag)		/* not split */    {      struct Incoming *in=&lp->incoming[saddr];      BUGMSG(D_RX,"incoming is not split (splitflag=%d)\n",	     arcsoft->split_flag);      if (in->skb)	/* already assembling one! */	{	  BUGMSG(D_EXTRA,"aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n",		 in->sequence,arcsoft->split_flag,		 arcsoft->sequence);	  lp->aborted_seq=arcsoft->sequence;	  kfree_skb(in->skb);	  lp->stats.rx_errors++;	  lp->stats.rx_missed_errors++;	  in->skb=NULL;	}      in->sequence=arcsoft->sequence;      skb = alloc_skb(length, GFP_ATOMIC);      if (skb == NULL) {	BUGMSG(D_NORMAL,"Memory squeeze, dropping packet.\n");	lp->stats.rx_dropped++;	return;      }      soft=(struct ClientData *)skb->data;      skb_put(skb,length);      skb->dev = dev;      memcpy((u_char *)soft+EXTRA_CLIENTDATA,	     (u_char *)arcsoft+EXTRA_CLIENTDATA,	     length-EXTRA_CLIENTDATA);      soft->daddr=daddr;      soft->saddr=saddr;      /* ARP packets have problems when sent from DOS.       * source address is always 0 on some systems!  So we take       * the hardware source addr (which is impossible to fumble)       * and insert it ourselves.       */      if (soft->protocol_id == ARC_P_ARP)	{	  struct arphdr *arp=(struct arphdr *)	    ((char *)soft+sizeof(struct ClientData));	  /* make sure addresses are the right length */	  if (arp->ar_hln==1 && arp->ar_pln==4)	    {	      char *cptr=(char *)(arp)+sizeof(struct arphdr);	      if (!*cptr)	/* is saddr = 00? */		{		  BUGMSG(D_EXTRA,"ARP source address was 00h, set to %02Xh.\n",			 saddr);		  lp->stats.rx_crc_errors++;		  *cptr=saddr;		}	      else		{		  BUGMSG(D_DURING,"ARP source address (%Xh) is fine.\n",			 *cptr);		}	    }	  else	    {	      BUGMSG(D_NORMAL,"funny-shaped ARP packet. (%Xh, %Xh)\n",		     arp->ar_hln,arp->ar_pln);	      lp->stats.rx_errors++;	      lp->stats.rx_crc_errors++;	    }	}      BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");      lp->stats.rx_bytes += skb->len;      skb->protocol=arcnetA_type_trans(skb,dev);      netif_rx(skb);    }  else			/* split packet */    {      /* NOTE:  MSDOS ARP packet correction should only need to       * apply to unsplit packets, since ARP packets are so short.       *       * My interpretation of the RFC1201 (ARCnet) document is that       * if a packet is received out of order, the entire assembly       * process should be aborted.       *       * The RFC also mentions "it is possible for successfully       * received packets to be retransmitted."  As of 0.40 all       * previously received packets are allowed, not just the       * most recent one.       *       * We allow multiple assembly processes, one for each       * ARCnet card possible on the network.  Seems rather like       * a waste of memory.  Necessary?       */      struct Incoming *in=&lp->incoming[saddr];      BUGMSG(D_RX,"packet is split (splitflag=%d, seq=%d)\n",	     arcsoft->split_flag,in->sequence);      if (in->skb && in->sequence!=arcsoft->sequence)	{	  BUGMSG(D_EXTRA,"wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n",		 saddr,in->sequence,arcsoft->sequence,		 arcsoft->split_flag);	  kfree_skb(in->skb);	  in->skb=NULL;	  lp->stats.rx_errors++;	  lp->stats.rx_missed_errors++;	  in->lastpacket=in->numpackets=0;	}      if (arcsoft->split_flag & 1)	/* first packet in split */	{	  BUGMSG(D_RX,"brand new splitpacket (splitflag=%d)\n",		 arcsoft->split_flag);	  if (in->skb)	/* already assembling one! */	    {	      BUGMSG(D_EXTRA,"aborting previous (seq=%d) assembly (splitflag=%d, seq=%d)\n",		     in->sequence,arcsoft->split_flag,		     arcsoft->sequence);	      lp->stats.rx_errors++;	      lp->stats.rx_missed_errors++;	      kfree_skb(in->skb);	    }	  in->sequence=arcsoft->sequence;	  in->numpackets=((unsigned)arcsoft->split_flag>>1)+2;	  in->lastpacket=1;	  if (in->numpackets>16)	    {	      BUGMSG(D_EXTRA,"incoming packet more than 16 segments; dropping. (splitflag=%d)\n",		     arcsoft->split_flag);	      lp->stats.rx_errors++;	      lp->stats.rx_length_errors++;	      return;	    }	  in->skb=skb=alloc_skb(508*in->numpackets				+ sizeof(struct ClientData),				GFP_ATOMIC);	  if (skb == NULL) {	    BUGMSG(D_NORMAL,"(split) memory squeeze, dropping packet.\n");	    lp->stats.rx_dropped++;	    return;	  }	  soft=(struct ClientData *)skb->data;	  skb_put(skb,sizeof(struct ClientData));	  skb->dev=dev;	  memcpy((u_char *)soft+EXTRA_CLIENTDATA,		 (u_char *)arcsoft+EXTRA_CLIENTDATA,		 sizeof(struct ClientData)-EXTRA_CLIENTDATA);	  soft->split_flag=0; /* final packet won't be split */	}      else			/* not first packet */	{	  int packetnum=((unsigned)arcsoft->split_flag>>1) + 1;	  /* if we're not assembling, there's no point	   * trying to continue.	   */	  if (!in->skb)	    {	      if (lp->aborted_seq != arcsoft->sequence)		{		  BUGMSG(D_EXTRA,"can't continue split without starting first! (splitflag=%d, seq=%d, aborted=%d)\n",			 arcsoft->split_flag,arcsoft->sequence, lp->aborted_seq);		  lp->stats.rx_errors++;		  lp->stats.rx_missed_errors++;		}	      return;	    }	  in->lastpacket++;	  if (packetnum!=in->lastpacket) /* not the right flag! */	    {	      /* harmless duplicate? ignore. */	      if (packetnum<=in->lastpacket-1)		{		  BUGMSG(D_EXTRA,"duplicate splitpacket ignored! (splitflag=%d)\n",			 arcsoft->split_flag);		  lp->stats.rx_errors++;		  lp->stats.rx_frame_errors++;		  return;		}	      /* "bad" duplicate, kill reassembly */	      BUGMSG(D_EXTRA,"out-of-order splitpacket, reassembly (seq=%d) aborted (splitflag=%d, seq=%d)\n",		     in->sequence,arcsoft->split_flag,		     arcsoft->sequence);	      lp->aborted_seq=arcsoft->sequence;	      kfree_skb(in->skb);	      in->skb=NULL;	      lp->stats.rx_errors++;	      lp->stats.rx_missed_errors++;	      in->lastpacket=in->numpackets=0;	      return;	    }	  soft=(struct ClientData *)in->skb->data;	}      skb=in->skb;      memcpy(skb->data+skb->len,	     (u_char *)arcsoft+sizeof(struct ClientData),	     length-sizeof(struct ClientData));      skb_put(skb,length-sizeof(struct ClientData));      soft->daddr=daddr;      soft->saddr=saddr;      /* are we done? */      if (in->lastpacket == in->numpackets)	{	  if (!skb || !in->skb)	    {	      BUGMSG(D_NORMAL,"?!? done reassembling packet, no skb? (skb=%ph, in->skb=%ph)\n",		     skb,in->skb);	    }	  else	    {	      in->skb=NULL;	      in->lastpacket=in->numpackets=0;	      BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");	      lp->stats.rx_bytes += skb->len;	      skb->protocol=arcnetA_type_trans(skb,dev);	      netif_rx(skb);	    }	}    }}/**************************************************************************** *                                                                          * * Miscellaneous routines                                                   * *                                                                          * ****************************************************************************//* Get the current statistics.	This may be called with the card open or * closed. */static struct net_device_stats *arcnet_get_stats(struct device *dev){  struct arcnet_local *lp = (struct arcnet_local *)dev->priv;  return &lp->stats;}/* 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 arcnetA_header(struct sk_buff *skb,struct device *dev,			  unsigned short type,void *daddr,void *saddr,unsigned len){  struct ClientData *head = (struct ClientData *)    skb_push(skb,dev->hard_header_len);  struct arcnet_local *lp=(struct arcnet_local *)(dev->priv);  BUGMSG(D_DURING,"create header from %d to %d; protocol %d (%Xh); size %u.\n",	 saddr ? *(u_char*)saddr : -1,	 daddr ? *(u_char*)daddr : -1,	 type,type,len);  /* set the protocol ID according to RFC1201 */  switch(type)    {    case ETH_P_IP:      head->protocol_id=ARC_P_IP;      break;    case ETH_P_ARP:      head->protocol_id=ARC_P_ARP;      break;    case ETH_P_RARP:      head->protocol_id=ARC_P_RARP;      break;    case ETH_P_IPX:    case ETH_P_802_3:    case ETH_P_802_2:      head->protocol_id=ARC_P_IPX;      break;    case ETH_P_ATALK:      head->protocol_id=ARC_P_ATALK;      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];  head->split_flag=0;	/* split packets are done elsewhere */  head->sequence=0;	/* so are sequence numbers */  /* 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 arcnetA_rebuild_header(struct sk_buff *skb){  struct ClientData *head = (struct ClientData *)skb->data;  struct device *dev=skb->dev;  struct arcnet_local *lp=(struct arcnet_local *)(dev->priv);#ifdef CONFIG_INET  int status;#endif  /*   * Only ARP and IP are currently supported   *   * FIXME: Anyone want to spec IPv6 over ARCnet ?   */  if(head->protocol_id != ARC_P_IP)    {      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  BUGMSG(D_DURING,"rebuild header from %d to %d; protocol %Xh\n",	 head->saddr,head->daddr,head->protocol_id);  status=arp_find(&(head->daddr),skb)? 1 : 0;  BUGMSG(D_DURING," rebuilt: from %d to %d; protocol %Xh\n",	 head->saddr,head->daddr,head->protocol_id);  return status;#else  return 0;#endif}/* Determine a packet's protocol ID. * * With ARCnet we have to convert everything to Ethernet-style stuff. */static unsigned short arcnetA_type_trans(struct sk_buff *skb,struct device *dev){  struct 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 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:		return htons(ETH_P_IP);    case ARC_P_ARP:		return htons(ETH_P_ARP);    case ARC_P_RARP:	return htons(ETH_P_RARP);    case ARC_P_IPX:    case ARC_P_NOVELL_EC:      return htons(ETH_P_802_3);    default:      lp->stats.rx_errors++;      lp->stats.rx_crc_errors++;      return 0;    }  return htons(ETH_P_IP);}#ifdef CONFIG_ARCNET_ETH/**************************************************************************** *                                                                          * * Ethernet-Encap Support                                                   * *                                                                          * ****************************************************************************//* Initialize the arc0e device. */static int arcnetE_init(struct device *dev){  struct arcnet_local *lp = (struct arcnet_local *)dev->priv;  ether_setup(dev); /* we're emulating ether here, not ARCnet */  dev->dev_addr[0]=0;  dev->dev_addr[5]=lp->stationid;  dev->mtu=512-sizeof(struct archdr)-dev->hard_header_len-1;  dev->open=arcnetE_open_close;  dev->stop=arcnetE_open_close;  dev->hard_start_xmit=arcnetE_send_packet;  return 0;}/* Bring up/down the arc0e device - we don't actually have to do anything, * since our parent arc0 handles the card I/O itself. */static int arcnetE_open_close(struct device *dev){  return 0;}/* Called by the kernel in order to transmit an ethernet-type packet. */static intarcnetE_send_packet(struct sk_buff *skb, struct device *dev){  struct arcnet_local *lp = (struct arcnet_local *)dev->priv;  int bad,oldmask=0;

⌨️ 快捷键说明

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