/* * Linux ARCnet driver - "cap mode" packet encapsulation. * It adds sequence numbers to packets for communicating between a user space * application and the driver. After a transmit it sends a packet with protocol * byte 0 back up to the userspace containing the sequence number of the packet * plus the transmit-status on the ArcNet. * * Written 2002-4 by Esben Nielsen, Vestas Wind Systems A/S * Derived from arc-rawmode.c by Avery Pennarun. * arc-rawmode was in turned based on skeleton.c, see below. * * ********************** * * The original copyright of skeleton.c was as follows: * * skeleton.c Written 1993 by Donald Becker. * Copyright 1993 United States Government as represented by the * Director, National Security Agency. This software may only be used * and distributed according to the terms of the GNU General Public License as * modified by SRC, incorporated herein by reference. * * ********************** * * For more details, see drivers/net/arcnet.c * * **********************
*/
/* up to sizeof(pkt->soft) has already been copied from the card * squeeze in an int for the cap encapsulation * use these variables to be sure we count in bytes, not in * sizeof(struct archdr)
*/
pktbuf = (char *)pkt;
pkthdrbuf = (char *)pkthdr;
memcpy(pktbuf, pkthdrbuf, ARC_HDR_SIZE + sizeof(pkt->soft.cap.proto));
memcpy(pktbuf + ARC_HDR_SIZE + sizeof(pkt->soft.cap.proto) + sizeof(int),
pkthdrbuf + ARC_HDR_SIZE + sizeof(pkt->soft.cap.proto), sizeof(struct archdr) - ARC_HDR_SIZE - sizeof(pkt->soft.cap.proto));
/* Create the ARCnet hard/soft headers for cap mode. * There aren't any soft headers in cap mode - not even the protocol id.
*/ staticint build_header(struct sk_buff *skb, struct net_device *dev, unsignedshort type,
uint8_t daddr)
{ int hdr_size = ARC_HDR_SIZE; struct archdr *pkt = skb_push(skb, hdr_size);
arc_printk(D_PROTO, dev, "Preparing header for cap packet %x.\n",
*((int *)&pkt->soft.cap.cookie[0]));
/* Set the source hardware address. * * This is pretty pointless for most purposes, but it can help in * debugging. ARCnet does not allow us to change the source address in * the actual packet sent)
*/
pkt->hard.source = *dev->dev_addr;
/* see linux/net/ethernet/eth.c to see where I got the following */
if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) { /* FIXME: fill in the last byte of the dest ipaddr here to * better comply with RFC1051 in "noarp" mode.
*/
pkt->hard.dest = 0; return hdr_size;
} /* otherwise, just fill it in and go! */
pkt->hard.dest = daddr;
return hdr_size; /* success */
}
staticint prepare_tx(struct net_device *dev, struct archdr *pkt, int length, int bufnum)
{ struct arcnet_local *lp = netdev_priv(dev); struct arc_hardware *hard = &pkt->hard; int ofs;
/* hard header is not included in packet length */
length -= ARC_HDR_SIZE; /* And neither is the cookie field */
length -= sizeof(int);
/* Copy the arcnet-header + the protocol byte down: */
lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft.cap.proto, sizeof(pkt->soft.cap.proto));
/* Skip the extra integer we have written into it as a cookie * but write the rest of the message:
*/
lp->hw.copy_to_card(dev, bufnum, ofs + 1,
((unsignedchar *)&pkt->soft.cap.mes), length - 1);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.