Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Linux ARCnet driver - RFC1201 (standard) packet encapsulation
0003  *
0004  * Written 1994-1999 by Avery Pennarun.
0005  * Derived from skeleton.c by Donald Becker.
0006  *
0007  * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
0008  *  for sponsoring the further development of this driver.
0009  *
0010  * **********************
0011  *
0012  * The original copyright of skeleton.c was as follows:
0013  *
0014  * skeleton.c Written 1993 by Donald Becker.
0015  * Copyright 1993 United States Government as represented by the
0016  * Director, National Security Agency.  This software may only be used
0017  * and distributed according to the terms of the GNU General Public License as
0018  * modified by SRC, incorporated herein by reference.
0019  *
0020  * **********************
0021  *
0022  * For more details, see drivers/net/arcnet.c
0023  *
0024  * **********************
0025  */
0026 
0027 #define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
0028 
0029 #include <linux/gfp.h>
0030 #include <linux/module.h>
0031 #include <linux/init.h>
0032 #include <linux/if_arp.h>
0033 #include <linux/netdevice.h>
0034 #include <linux/skbuff.h>
0035 
0036 #include "arcdevice.h"
0037 
0038 MODULE_LICENSE("GPL");
0039 
0040 static __be16 type_trans(struct sk_buff *skb, struct net_device *dev);
0041 static void rx(struct net_device *dev, int bufnum,
0042            struct archdr *pkthdr, int length);
0043 static int build_header(struct sk_buff *skb, struct net_device *dev,
0044             unsigned short type, uint8_t daddr);
0045 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
0046               int bufnum);
0047 static int continue_tx(struct net_device *dev, int bufnum);
0048 
0049 static struct ArcProto rfc1201_proto = {
0050     .suffix     = 'a',
0051     .mtu        = 1500, /* could be more, but some receivers can't handle it... */
0052     .is_ip          = 1,    /* This is for sending IP and ARP packages */
0053     .rx     = rx,
0054     .build_header   = build_header,
0055     .prepare_tx = prepare_tx,
0056     .continue_tx    = continue_tx,
0057     .ack_tx         = NULL
0058 };
0059 
0060 static int __init arcnet_rfc1201_init(void)
0061 {
0062     pr_info("%s\n", "RFC1201 \"standard\" (`a') encapsulation support loaded");
0063 
0064     arc_proto_map[ARC_P_IP]
0065         = arc_proto_map[ARC_P_IPV6]
0066         = arc_proto_map[ARC_P_ARP]
0067         = arc_proto_map[ARC_P_RARP]
0068         = arc_proto_map[ARC_P_IPX]
0069         = arc_proto_map[ARC_P_NOVELL_EC]
0070         = &rfc1201_proto;
0071 
0072     /* if someone else already owns the broadcast, we won't take it */
0073     if (arc_bcast_proto == arc_proto_default)
0074         arc_bcast_proto = &rfc1201_proto;
0075 
0076     return 0;
0077 }
0078 
0079 static void __exit arcnet_rfc1201_exit(void)
0080 {
0081     arcnet_unregister_proto(&rfc1201_proto);
0082 }
0083 
0084 module_init(arcnet_rfc1201_init);
0085 module_exit(arcnet_rfc1201_exit);
0086 
0087 /* Determine a packet's protocol ID.
0088  *
0089  * With ARCnet we have to convert everything to Ethernet-style stuff.
0090  */
0091 static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
0092 {
0093     struct archdr *pkt = (struct archdr *)skb->data;
0094     struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
0095     int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
0096 
0097     /* Pull off the arcnet header. */
0098     skb_reset_mac_header(skb);
0099     skb_pull(skb, hdr_size);
0100 
0101     if (pkt->hard.dest == 0) {
0102         skb->pkt_type = PACKET_BROADCAST;
0103     } else if (dev->flags & IFF_PROMISC) {
0104         /* if we're not sending to ourselves :) */
0105         if (pkt->hard.dest != dev->dev_addr[0])
0106             skb->pkt_type = PACKET_OTHERHOST;
0107     }
0108     /* now return the protocol number */
0109     switch (soft->proto) {
0110     case ARC_P_IP:
0111         return htons(ETH_P_IP);
0112     case ARC_P_IPV6:
0113         return htons(ETH_P_IPV6);
0114     case ARC_P_ARP:
0115         return htons(ETH_P_ARP);
0116     case ARC_P_RARP:
0117         return htons(ETH_P_RARP);
0118 
0119     case ARC_P_IPX:
0120     case ARC_P_NOVELL_EC:
0121         return htons(ETH_P_802_3);
0122     default:
0123         dev->stats.rx_errors++;
0124         dev->stats.rx_crc_errors++;
0125         return 0;
0126     }
0127 
0128     return htons(ETH_P_IP);
0129 }
0130 
0131 /* packet receiver */
0132 static void rx(struct net_device *dev, int bufnum,
0133            struct archdr *pkthdr, int length)
0134 {
0135     struct arcnet_local *lp = netdev_priv(dev);
0136     struct sk_buff *skb;
0137     struct archdr *pkt = pkthdr;
0138     struct arc_rfc1201 *soft = &pkthdr->soft.rfc1201;
0139     int saddr = pkt->hard.source, ofs;
0140     struct Incoming *in = &lp->rfc1201.incoming[saddr];
0141 
0142     arc_printk(D_DURING, dev, "it's an RFC1201 packet (length=%d)\n",
0143            length);
0144 
0145     if (length >= MinTU)
0146         ofs = 512 - length;
0147     else
0148         ofs = 256 - length;
0149 
0150     if (soft->split_flag == 0xFF) {     /* Exception Packet */
0151         if (length >= 4 + RFC1201_HDR_SIZE) {
0152             arc_printk(D_DURING, dev, "compensating for exception packet\n");
0153         } else {
0154             arc_printk(D_EXTRA, dev, "short RFC1201 exception packet from %02Xh",
0155                    saddr);
0156             return;
0157         }
0158 
0159         /* skip over 4-byte junkola */
0160         length -= 4;
0161         ofs += 4;
0162         lp->hw.copy_from_card(dev, bufnum, 512 - length,
0163                       soft, sizeof(pkt->soft));
0164     }
0165     if (!soft->split_flag) {    /* not split */
0166         arc_printk(D_RX, dev, "incoming is not split (splitflag=%d)\n",
0167                soft->split_flag);
0168 
0169         if (in->skb) {  /* already assembling one! */
0170             arc_printk(D_EXTRA, dev, "aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n",
0171                    in->sequence, soft->split_flag,
0172                    soft->sequence);
0173             lp->rfc1201.aborted_seq = soft->sequence;
0174             dev_kfree_skb_irq(in->skb);
0175             dev->stats.rx_errors++;
0176             dev->stats.rx_missed_errors++;
0177             in->skb = NULL;
0178         }
0179         in->sequence = soft->sequence;
0180 
0181         skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
0182         if (!skb) {
0183             dev->stats.rx_dropped++;
0184             return;
0185         }
0186         skb_put(skb, length + ARC_HDR_SIZE);
0187         skb->dev = dev;
0188 
0189         pkt = (struct archdr *)skb->data;
0190         soft = &pkt->soft.rfc1201;
0191 
0192         /* up to sizeof(pkt->soft) has already
0193          * been copied from the card
0194          */
0195         memcpy(pkt, pkthdr, sizeof(struct archdr));
0196         if (length > sizeof(pkt->soft))
0197             lp->hw.copy_from_card(dev, bufnum,
0198                           ofs + sizeof(pkt->soft),
0199                           pkt->soft.raw + sizeof(pkt->soft),
0200                           length - sizeof(pkt->soft));
0201 
0202         /* ARP packets have problems when sent from some DOS systems:
0203          * the source address is always 0!
0204          * So we take the hardware source addr (which is impossible
0205          * to fumble) and insert it ourselves.
0206          */
0207         if (soft->proto == ARC_P_ARP) {
0208             struct arphdr *arp = (struct arphdr *)soft->payload;
0209 
0210             /* make sure addresses are the right length */
0211             if (arp->ar_hln == 1 && arp->ar_pln == 4) {
0212                 uint8_t *cptr = (uint8_t *)arp + sizeof(struct arphdr);
0213 
0214                 if (!*cptr) {   /* is saddr = 00? */
0215                     arc_printk(D_EXTRA, dev,
0216                            "ARP source address was 00h, set to %02Xh\n",
0217                            saddr);
0218                     dev->stats.rx_crc_errors++;
0219                     *cptr = saddr;
0220                 } else {
0221                     arc_printk(D_DURING, dev, "ARP source address (%Xh) is fine.\n",
0222                            *cptr);
0223                 }
0224             } else {
0225                 arc_printk(D_NORMAL, dev, "funny-shaped ARP packet. (%Xh, %Xh)\n",
0226                        arp->ar_hln, arp->ar_pln);
0227                 dev->stats.rx_errors++;
0228                 dev->stats.rx_crc_errors++;
0229             }
0230         }
0231         if (BUGLVL(D_SKB))
0232             arcnet_dump_skb(dev, skb, "rx");
0233 
0234         skb->protocol = type_trans(skb, dev);
0235         netif_rx(skb);
0236     } else {        /* split packet */
0237         /* NOTE: MSDOS ARP packet correction should only need to
0238          * apply to unsplit packets, since ARP packets are so short.
0239          *
0240          * My interpretation of the RFC1201 document is that if a
0241          * packet is received out of order, the entire assembly
0242          * process should be aborted.
0243          *
0244          * The RFC also mentions "it is possible for successfully
0245          * received packets to be retransmitted." As of 0.40 all
0246          * previously received packets are allowed, not just the
0247          * most recent one.
0248          *
0249          * We allow multiple assembly processes, one for each
0250          * ARCnet card possible on the network.
0251          * Seems rather like a waste of memory, but there's no
0252          * other way to be reliable.
0253          */
0254 
0255         arc_printk(D_RX, dev, "packet is split (splitflag=%d, seq=%d)\n",
0256                soft->split_flag, in->sequence);
0257 
0258         if (in->skb && in->sequence != soft->sequence) {
0259             arc_printk(D_EXTRA, dev, "wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n",
0260                    saddr, in->sequence, soft->sequence,
0261                    soft->split_flag);
0262             dev_kfree_skb_irq(in->skb);
0263             in->skb = NULL;
0264             dev->stats.rx_errors++;
0265             dev->stats.rx_missed_errors++;
0266             in->lastpacket = in->numpackets = 0;
0267         }
0268         if (soft->split_flag & 1) { /* first packet in split */
0269             arc_printk(D_RX, dev, "brand new splitpacket (splitflag=%d)\n",
0270                    soft->split_flag);
0271             if (in->skb) {  /* already assembling one! */
0272                 arc_printk(D_EXTRA, dev, "aborting previous (seq=%d) assembly (splitflag=%d, seq=%d)\n",
0273                        in->sequence, soft->split_flag,
0274                        soft->sequence);
0275                 dev->stats.rx_errors++;
0276                 dev->stats.rx_missed_errors++;
0277                 dev_kfree_skb_irq(in->skb);
0278             }
0279             in->sequence = soft->sequence;
0280             in->numpackets = ((unsigned)soft->split_flag >> 1) + 2;
0281             in->lastpacket = 1;
0282 
0283             if (in->numpackets > 16) {
0284                 arc_printk(D_EXTRA, dev, "incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
0285                        soft->split_flag);
0286                 lp->rfc1201.aborted_seq = soft->sequence;
0287                 dev->stats.rx_errors++;
0288                 dev->stats.rx_length_errors++;
0289                 return;
0290             }
0291             in->skb = skb = alloc_skb(508 * in->numpackets + ARC_HDR_SIZE,
0292                           GFP_ATOMIC);
0293             if (!skb) {
0294                 arc_printk(D_NORMAL, dev, "(split) memory squeeze, dropping packet.\n");
0295                 lp->rfc1201.aborted_seq = soft->sequence;
0296                 dev->stats.rx_dropped++;
0297                 return;
0298             }
0299             skb->dev = dev;
0300             pkt = (struct archdr *)skb->data;
0301             soft = &pkt->soft.rfc1201;
0302 
0303             memcpy(pkt, pkthdr, ARC_HDR_SIZE + RFC1201_HDR_SIZE);
0304             skb_put(skb, ARC_HDR_SIZE + RFC1201_HDR_SIZE);
0305 
0306             soft->split_flag = 0;   /* end result won't be split */
0307         } else {    /* not first packet */
0308             int packetnum = ((unsigned)soft->split_flag >> 1) + 1;
0309 
0310             /* if we're not assembling, there's no point trying to
0311              * continue.
0312              */
0313             if (!in->skb) {
0314                 if (lp->rfc1201.aborted_seq != soft->sequence) {
0315                     arc_printk(D_EXTRA, dev, "can't continue split without starting first! (splitflag=%d, seq=%d, aborted=%d)\n",
0316                            soft->split_flag,
0317                            soft->sequence,
0318                            lp->rfc1201.aborted_seq);
0319                     dev->stats.rx_errors++;
0320                     dev->stats.rx_missed_errors++;
0321                 }
0322                 return;
0323             }
0324             in->lastpacket++;
0325             /* if not the right flag */
0326             if (packetnum != in->lastpacket) {
0327                 /* harmless duplicate? ignore. */
0328                 if (packetnum <= in->lastpacket - 1) {
0329                     arc_printk(D_EXTRA, dev, "duplicate splitpacket ignored! (splitflag=%d)\n",
0330                            soft->split_flag);
0331                     dev->stats.rx_errors++;
0332                     dev->stats.rx_frame_errors++;
0333                     return;
0334                 }
0335                 /* "bad" duplicate, kill reassembly */
0336                 arc_printk(D_EXTRA, dev, "out-of-order splitpacket, reassembly (seq=%d) aborted (splitflag=%d, seq=%d)\n",
0337                        in->sequence, soft->split_flag,
0338                        soft->sequence);
0339                 lp->rfc1201.aborted_seq = soft->sequence;
0340                 dev_kfree_skb_irq(in->skb);
0341                 in->skb = NULL;
0342                 dev->stats.rx_errors++;
0343                 dev->stats.rx_missed_errors++;
0344                 in->lastpacket = in->numpackets = 0;
0345                 return;
0346             }
0347             pkt = (struct archdr *)in->skb->data;
0348             soft = &pkt->soft.rfc1201;
0349         }
0350 
0351         skb = in->skb;
0352 
0353         lp->hw.copy_from_card(dev, bufnum, ofs + RFC1201_HDR_SIZE,
0354                       skb->data + skb->len,
0355                       length - RFC1201_HDR_SIZE);
0356         skb_put(skb, length - RFC1201_HDR_SIZE);
0357 
0358         /* are we done? */
0359         if (in->lastpacket == in->numpackets) {
0360             in->skb = NULL;
0361             in->lastpacket = in->numpackets = 0;
0362 
0363             arc_printk(D_SKB_SIZE, dev, "skb: received %d bytes from %02X (unsplit)\n",
0364                    skb->len, pkt->hard.source);
0365             arc_printk(D_SKB_SIZE, dev, "skb: received %d bytes from %02X (split)\n",
0366                    skb->len, pkt->hard.source);
0367             if (BUGLVL(D_SKB))
0368                 arcnet_dump_skb(dev, skb, "rx");
0369 
0370             skb->protocol = type_trans(skb, dev);
0371             netif_rx(skb);
0372         }
0373     }
0374 }
0375 
0376 /* Create the ARCnet hard/soft headers for RFC1201. */
0377 static int build_header(struct sk_buff *skb, struct net_device *dev,
0378             unsigned short type, uint8_t daddr)
0379 {
0380     struct arcnet_local *lp = netdev_priv(dev);
0381     int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
0382     struct archdr *pkt = skb_push(skb, hdr_size);
0383     struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
0384 
0385     /* set the protocol ID according to RFC1201 */
0386     switch (type) {
0387     case ETH_P_IP:
0388         soft->proto = ARC_P_IP;
0389         break;
0390     case ETH_P_IPV6:
0391         soft->proto = ARC_P_IPV6;
0392         break;
0393     case ETH_P_ARP:
0394         soft->proto = ARC_P_ARP;
0395         break;
0396     case ETH_P_RARP:
0397         soft->proto = ARC_P_RARP;
0398         break;
0399     case ETH_P_IPX:
0400     case ETH_P_802_3:
0401     case ETH_P_802_2:
0402         soft->proto = ARC_P_IPX;
0403         break;
0404     case ETH_P_ATALK:
0405         soft->proto = ARC_P_ATALK;
0406         break;
0407     default:
0408         arc_printk(D_NORMAL, dev, "RFC1201: I don't understand protocol %d (%Xh)\n",
0409                type, type);
0410         dev->stats.tx_errors++;
0411         dev->stats.tx_aborted_errors++;
0412         return 0;
0413     }
0414 
0415     /* Set the source hardware address.
0416      *
0417      * This is pretty pointless for most purposes, but it can help in
0418      * debugging.  ARCnet does not allow us to change the source address
0419      * in the actual packet sent.
0420      */
0421     pkt->hard.source = *dev->dev_addr;
0422 
0423     soft->sequence = htons(lp->rfc1201.sequence++);
0424     soft->split_flag = 0;   /* split packets are done elsewhere */
0425 
0426     /* see linux/net/ethernet/eth.c to see where I got the following */
0427 
0428     if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
0429         /* FIXME: fill in the last byte of the dest ipaddr here
0430          * to better comply with RFC1051 in "noarp" mode.
0431          * For now, always broadcasting will probably at least get
0432          * packets sent out :)
0433          */
0434         pkt->hard.dest = 0;
0435         return hdr_size;
0436     }
0437     /* otherwise, drop in the dest address */
0438     pkt->hard.dest = daddr;
0439     return hdr_size;
0440 }
0441 
0442 static void load_pkt(struct net_device *dev, struct arc_hardware *hard,
0443              struct arc_rfc1201 *soft, int softlen, int bufnum)
0444 {
0445     struct arcnet_local *lp = netdev_priv(dev);
0446     int ofs;
0447 
0448     /* assume length <= XMTU: someone should have handled that by now. */
0449 
0450     if (softlen > MinTU) {
0451         hard->offset[0] = 0;
0452         hard->offset[1] = ofs = 512 - softlen;
0453     } else if (softlen > MTU) { /* exception packet - add an extra header */
0454         struct arc_rfc1201 excsoft;
0455 
0456         excsoft.proto = soft->proto;
0457         excsoft.split_flag = 0xff;
0458         excsoft.sequence = htons(0xffff);
0459 
0460         hard->offset[0] = 0;
0461         ofs = 512 - softlen;
0462         hard->offset[1] = ofs - RFC1201_HDR_SIZE;
0463         lp->hw.copy_to_card(dev, bufnum, ofs - RFC1201_HDR_SIZE,
0464                     &excsoft, RFC1201_HDR_SIZE);
0465     } else {
0466         hard->offset[0] = ofs = 256 - softlen;
0467     }
0468 
0469     lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
0470     lp->hw.copy_to_card(dev, bufnum, ofs, soft, softlen);
0471 
0472     lp->lastload_dest = hard->dest;
0473 }
0474 
0475 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
0476               int bufnum)
0477 {
0478     struct arcnet_local *lp = netdev_priv(dev);
0479     const int maxsegsize = XMTU - RFC1201_HDR_SIZE;
0480     struct Outgoing *out;
0481 
0482     arc_printk(D_DURING, dev, "prepare_tx: txbufs=%d/%d/%d\n",
0483            lp->next_tx, lp->cur_tx, bufnum);
0484 
0485     /* hard header is not included in packet length */
0486     length -= ARC_HDR_SIZE;
0487     pkt->soft.rfc1201.split_flag = 0;
0488 
0489     /* need to do a split packet? */
0490     if (length > XMTU) {
0491         out = &lp->outgoing;
0492 
0493         out->length = length - RFC1201_HDR_SIZE;
0494         out->dataleft = lp->outgoing.length;
0495         out->numsegs = (out->dataleft + maxsegsize - 1) / maxsegsize;
0496         out->segnum = 0;
0497 
0498         arc_printk(D_DURING, dev, "rfc1201 prep_tx: ready for %d-segment split (%d bytes, seq=%d)\n",
0499                out->numsegs, out->length,
0500                pkt->soft.rfc1201.sequence);
0501 
0502         return 0;   /* not done */
0503     }
0504     /* just load the packet into the buffers and send it off */
0505     load_pkt(dev, &pkt->hard, &pkt->soft.rfc1201, length, bufnum);
0506 
0507     return 1;       /* done */
0508 }
0509 
0510 static int continue_tx(struct net_device *dev, int bufnum)
0511 {
0512     struct arcnet_local *lp = netdev_priv(dev);
0513     struct Outgoing *out = &lp->outgoing;
0514     struct arc_hardware *hard = &out->pkt->hard;
0515     struct arc_rfc1201 *soft = &out->pkt->soft.rfc1201, *newsoft;
0516     int maxsegsize = XMTU - RFC1201_HDR_SIZE;
0517     int seglen;
0518 
0519     arc_printk(D_DURING, dev,
0520            "rfc1201 continue_tx: loading segment %d(+1) of %d (seq=%d)\n",
0521            out->segnum, out->numsegs, soft->sequence);
0522 
0523     /* the "new" soft header comes right before the data chunk */
0524     newsoft = (struct arc_rfc1201 *)
0525         (out->pkt->soft.raw + out->length - out->dataleft);
0526 
0527     if (!out->segnum)   /* first packet; newsoft == soft */
0528         newsoft->split_flag = ((out->numsegs - 2) << 1) | 1;
0529     else {
0530         newsoft->split_flag = out->segnum << 1;
0531         newsoft->proto = soft->proto;
0532         newsoft->sequence = soft->sequence;
0533     }
0534 
0535     seglen = maxsegsize;
0536     if (seglen > out->dataleft)
0537         seglen = out->dataleft;
0538     out->dataleft -= seglen;
0539 
0540     load_pkt(dev, hard, newsoft, seglen + RFC1201_HDR_SIZE, bufnum);
0541 
0542     out->segnum++;
0543     if (out->segnum >= out->numsegs)
0544         return 1;
0545     else
0546         return 0;
0547 }