Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Linux ARCnet driver - "cap mode" packet encapsulation.
0003  * It adds sequence numbers to packets for communicating between a user space
0004  * application and the driver. After a transmit it sends a packet with protocol
0005  * byte 0 back up to the userspace containing the sequence number of the packet
0006  * plus the transmit-status on the ArcNet.
0007  *
0008  * Written 2002-4 by Esben Nielsen, Vestas Wind Systems A/S
0009  * Derived from arc-rawmode.c by Avery Pennarun.
0010  * arc-rawmode was in turned based on skeleton.c, see below.
0011  *
0012  * **********************
0013  *
0014  * The original copyright of skeleton.c was as follows:
0015  *
0016  * skeleton.c Written 1993 by Donald Becker.
0017  * Copyright 1993 United States Government as represented by the
0018  * Director, National Security Agency.  This software may only be used
0019  * and distributed according to the terms of the GNU General Public License as
0020  * modified by SRC, incorporated herein by reference.
0021  *
0022  * **********************
0023  *
0024  * For more details, see drivers/net/arcnet.c
0025  *
0026  * **********************
0027  */
0028 
0029 #define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
0030 
0031 #include <linux/module.h>
0032 #include <linux/gfp.h>
0033 #include <linux/init.h>
0034 #include <linux/if_arp.h>
0035 #include <net/arp.h>
0036 #include <linux/netdevice.h>
0037 #include <linux/skbuff.h>
0038 
0039 #include "arcdevice.h"
0040 
0041 /* packet receiver */
0042 static void rx(struct net_device *dev, int bufnum,
0043            struct archdr *pkthdr, int length)
0044 {
0045     struct arcnet_local *lp = netdev_priv(dev);
0046     struct sk_buff *skb;
0047     struct archdr *pkt;
0048     char *pktbuf, *pkthdrbuf;
0049     int ofs;
0050 
0051     arc_printk(D_DURING, dev, "it's a raw(cap) packet (length=%d)\n",
0052            length);
0053 
0054     if (length >= MinTU)
0055         ofs = 512 - length;
0056     else
0057         ofs = 256 - length;
0058 
0059     skb = alloc_skb(length + ARC_HDR_SIZE + sizeof(int), GFP_ATOMIC);
0060     if (!skb) {
0061         dev->stats.rx_dropped++;
0062         return;
0063     }
0064     skb_put(skb, length + ARC_HDR_SIZE + sizeof(int));
0065     skb->dev = dev;
0066     skb_reset_mac_header(skb);
0067     pkt = (struct archdr *)skb_mac_header(skb);
0068     skb_pull(skb, ARC_HDR_SIZE);
0069 
0070     /* up to sizeof(pkt->soft) has already been copied from the card
0071      * squeeze in an int for the cap encapsulation
0072      * use these variables to be sure we count in bytes, not in
0073      * sizeof(struct archdr)
0074      */
0075     pktbuf = (char *)pkt;
0076     pkthdrbuf = (char *)pkthdr;
0077     memcpy(pktbuf, pkthdrbuf, ARC_HDR_SIZE + sizeof(pkt->soft.cap.proto));
0078     memcpy(pktbuf + ARC_HDR_SIZE + sizeof(pkt->soft.cap.proto) + sizeof(int),
0079            pkthdrbuf + ARC_HDR_SIZE + sizeof(pkt->soft.cap.proto),
0080            sizeof(struct archdr) - ARC_HDR_SIZE - sizeof(pkt->soft.cap.proto));
0081 
0082     if (length > sizeof(pkt->soft))
0083         lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
0084                       pkt->soft.raw + sizeof(pkt->soft)
0085                       + sizeof(int),
0086                       length - sizeof(pkt->soft));
0087 
0088     if (BUGLVL(D_SKB))
0089         arcnet_dump_skb(dev, skb, "rx");
0090 
0091     skb->protocol = cpu_to_be16(ETH_P_ARCNET);
0092     netif_rx(skb);
0093 }
0094 
0095 /* Create the ARCnet hard/soft headers for cap mode.
0096  * There aren't any soft headers in cap mode - not even the protocol id.
0097  */
0098 static int build_header(struct sk_buff *skb,
0099             struct net_device *dev,
0100             unsigned short type,
0101             uint8_t daddr)
0102 {
0103     int hdr_size = ARC_HDR_SIZE;
0104     struct archdr *pkt = skb_push(skb, hdr_size);
0105 
0106     arc_printk(D_PROTO, dev, "Preparing header for cap packet %x.\n",
0107            *((int *)&pkt->soft.cap.cookie[0]));
0108 
0109     /* Set the source hardware address.
0110      *
0111      * This is pretty pointless for most purposes, but it can help in
0112      * debugging.  ARCnet does not allow us to change the source address in
0113      * the actual packet sent)
0114      */
0115     pkt->hard.source = *dev->dev_addr;
0116 
0117     /* see linux/net/ethernet/eth.c to see where I got the following */
0118 
0119     if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
0120         /* FIXME: fill in the last byte of the dest ipaddr here to
0121          * better comply with RFC1051 in "noarp" mode.
0122          */
0123         pkt->hard.dest = 0;
0124         return hdr_size;
0125     }
0126     /* otherwise, just fill it in and go! */
0127     pkt->hard.dest = daddr;
0128 
0129     return hdr_size;    /* success */
0130 }
0131 
0132 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
0133               int bufnum)
0134 {
0135     struct arcnet_local *lp = netdev_priv(dev);
0136     struct arc_hardware *hard = &pkt->hard;
0137     int ofs;
0138 
0139     /* hard header is not included in packet length */
0140     length -= ARC_HDR_SIZE;
0141     /* And neither is the cookie field */
0142     length -= sizeof(int);
0143 
0144     arc_printk(D_DURING, dev, "prepare_tx: txbufs=%d/%d/%d\n",
0145            lp->next_tx, lp->cur_tx, bufnum);
0146 
0147     arc_printk(D_PROTO, dev, "Sending for cap packet %x.\n",
0148            *((int *)&pkt->soft.cap.cookie[0]));
0149 
0150     if (length > XMTU) {
0151         /* should never happen! other people already check for this. */
0152         arc_printk(D_NORMAL, dev, "Bug!  prepare_tx with size %d (> %d)\n",
0153                length, XMTU);
0154         length = XMTU;
0155     }
0156     if (length > MinTU) {
0157         hard->offset[0] = 0;
0158         hard->offset[1] = ofs = 512 - length;
0159     } else if (length > MTU) {
0160         hard->offset[0] = 0;
0161         hard->offset[1] = ofs = 512 - length - 3;
0162     } else {
0163         hard->offset[0] = ofs = 256 - length;
0164     }
0165 
0166     arc_printk(D_DURING, dev, "prepare_tx: length=%d ofs=%d\n",
0167            length, ofs);
0168 
0169     /* Copy the arcnet-header + the protocol byte down: */
0170     lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
0171     lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft.cap.proto,
0172                 sizeof(pkt->soft.cap.proto));
0173 
0174     /* Skip the extra integer we have written into it as a cookie
0175      * but write the rest of the message:
0176      */
0177     lp->hw.copy_to_card(dev, bufnum, ofs + 1,
0178                 ((unsigned char *)&pkt->soft.cap.mes), length - 1);
0179 
0180     lp->lastload_dest = hard->dest;
0181 
0182     return 1;   /* done */
0183 }
0184 
0185 static int ack_tx(struct net_device *dev, int acked)
0186 {
0187     struct arcnet_local *lp = netdev_priv(dev);
0188     struct sk_buff *ackskb;
0189     struct archdr *ackpkt;
0190     int length = sizeof(struct arc_cap);
0191 
0192     arc_printk(D_DURING, dev, "capmode: ack_tx: protocol: %x: result: %d\n",
0193            lp->outgoing.skb->protocol, acked);
0194 
0195     if (BUGLVL(D_SKB))
0196         arcnet_dump_skb(dev, lp->outgoing.skb, "ack_tx");
0197 
0198     /* Now alloc a skb to send back up through the layers: */
0199     ackskb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
0200     if (!ackskb)
0201         goto free_outskb;
0202 
0203     skb_put(ackskb, length + ARC_HDR_SIZE);
0204     ackskb->dev = dev;
0205 
0206     skb_reset_mac_header(ackskb);
0207     ackpkt = (struct archdr *)skb_mac_header(ackskb);
0208     /* skb_pull(ackskb, ARC_HDR_SIZE); */
0209 
0210     skb_copy_from_linear_data(lp->outgoing.skb, ackpkt,
0211                   ARC_HDR_SIZE + sizeof(struct arc_cap));
0212     ackpkt->soft.cap.proto = 0; /* using protocol 0 for acknowledge */
0213     ackpkt->soft.cap.mes.ack = acked;
0214 
0215     arc_printk(D_PROTO, dev, "Acknowledge for cap packet %x.\n",
0216            *((int *)&ackpkt->soft.cap.cookie[0]));
0217 
0218     ackskb->protocol = cpu_to_be16(ETH_P_ARCNET);
0219 
0220     if (BUGLVL(D_SKB))
0221         arcnet_dump_skb(dev, ackskb, "ack_tx_recv");
0222     netif_rx(ackskb);
0223 
0224 free_outskb:
0225     dev_kfree_skb_irq(lp->outgoing.skb);
0226     lp->outgoing.proto = NULL;
0227             /* We are always finished when in this protocol */
0228 
0229     return 0;
0230 }
0231 
0232 static struct ArcProto capmode_proto = {
0233     .suffix     = 'r',
0234     .mtu        = XMTU,
0235     .rx     = rx,
0236     .build_header   = build_header,
0237     .prepare_tx = prepare_tx,
0238     .ack_tx     = ack_tx
0239 };
0240 
0241 static int __init capmode_module_init(void)
0242 {
0243     int count;
0244 
0245     pr_info("cap mode (`c') encapsulation support loaded\n");
0246 
0247     for (count = 1; count <= 8; count++)
0248         if (arc_proto_map[count] == arc_proto_default)
0249             arc_proto_map[count] = &capmode_proto;
0250 
0251     /* for cap mode, we only set the bcast proto if there's no better one */
0252     if (arc_bcast_proto == arc_proto_default)
0253         arc_bcast_proto = &capmode_proto;
0254 
0255     arc_proto_default = &capmode_proto;
0256     arc_raw_proto = &capmode_proto;
0257 
0258     return 0;
0259 }
0260 
0261 static void __exit capmode_module_exit(void)
0262 {
0263     arcnet_unregister_proto(&capmode_proto);
0264 }
0265 module_init(capmode_module_init);
0266 module_exit(capmode_module_exit);
0267 
0268 MODULE_LICENSE("GPL");