root/drivers/net/arcnet/arc-rawmode.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rx
  2. build_header
  3. prepare_tx
  4. arcnet_raw_init
  5. arcnet_raw_exit

   1 /*
   2  * Linux ARCnet driver - "raw mode" packet encapsulation (no soft headers)
   3  *
   4  * Written 1994-1999 by Avery Pennarun.
   5  * Derived from skeleton.c by Donald Becker.
   6  *
   7  * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
   8  *  for sponsoring the further development of this driver.
   9  *
  10  * **********************
  11  *
  12  * The original copyright of skeleton.c was as follows:
  13  *
  14  * skeleton.c Written 1993 by Donald Becker.
  15  * Copyright 1993 United States Government as represented by the
  16  * Director, National Security Agency.  This software may only be used
  17  * and distributed according to the terms of the GNU General Public License as
  18  * modified by SRC, incorporated herein by reference.
  19  *
  20  * **********************
  21  *
  22  * For more details, see drivers/net/arcnet.c
  23  *
  24  * **********************
  25  */
  26 
  27 #define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
  28 
  29 #include <linux/module.h>
  30 #include <linux/gfp.h>
  31 #include <linux/init.h>
  32 #include <linux/if_arp.h>
  33 #include <net/arp.h>
  34 #include <linux/netdevice.h>
  35 #include <linux/skbuff.h>
  36 #include "arcdevice.h"
  37 
  38 /* packet receiver */
  39 static void rx(struct net_device *dev, int bufnum,
  40                struct archdr *pkthdr, int length)
  41 {
  42         struct arcnet_local *lp = netdev_priv(dev);
  43         struct sk_buff *skb;
  44         struct archdr *pkt = pkthdr;
  45         int ofs;
  46 
  47         arc_printk(D_DURING, dev, "it's a raw packet (length=%d)\n", length);
  48 
  49         if (length > MTU)
  50                 ofs = 512 - length;
  51         else
  52                 ofs = 256 - length;
  53 
  54         skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
  55         if (!skb) {
  56                 dev->stats.rx_dropped++;
  57                 return;
  58         }
  59         skb_put(skb, length + ARC_HDR_SIZE);
  60         skb->dev = dev;
  61 
  62         pkt = (struct archdr *)skb->data;
  63 
  64         skb_reset_mac_header(skb);
  65         skb_pull(skb, ARC_HDR_SIZE);
  66 
  67         /* up to sizeof(pkt->soft) has already been copied from the card */
  68         memcpy(pkt, pkthdr, sizeof(struct archdr));
  69         if (length > sizeof(pkt->soft))
  70                 lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
  71                                       pkt->soft.raw + sizeof(pkt->soft),
  72                                       length - sizeof(pkt->soft));
  73 
  74         if (BUGLVL(D_SKB))
  75                 arcnet_dump_skb(dev, skb, "rx");
  76 
  77         skb->protocol = cpu_to_be16(ETH_P_ARCNET);
  78         netif_rx(skb);
  79 }
  80 
  81 /* Create the ARCnet hard/soft headers for raw mode.
  82  * There aren't any soft headers in raw mode - not even the protocol id.
  83  */
  84 static int build_header(struct sk_buff *skb, struct net_device *dev,
  85                         unsigned short type, uint8_t daddr)
  86 {
  87         int hdr_size = ARC_HDR_SIZE;
  88         struct archdr *pkt = skb_push(skb, hdr_size);
  89 
  90         /* Set the source hardware address.
  91          *
  92          * This is pretty pointless for most purposes, but it can help in
  93          * debugging.  ARCnet does not allow us to change the source address
  94          * in the actual packet sent.
  95          */
  96         pkt->hard.source = *dev->dev_addr;
  97 
  98         /* see linux/net/ethernet/eth.c to see where I got the following */
  99 
 100         if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
 101                 /* FIXME: fill in the last byte of the dest ipaddr here
 102                  * to better comply with RFC1051 in "noarp" mode.
 103                  */
 104                 pkt->hard.dest = 0;
 105                 return hdr_size;
 106         }
 107         /* otherwise, just fill it in and go! */
 108         pkt->hard.dest = daddr;
 109 
 110         return hdr_size;        /* success */
 111 }
 112 
 113 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
 114                       int bufnum)
 115 {
 116         struct arcnet_local *lp = netdev_priv(dev);
 117         struct arc_hardware *hard = &pkt->hard;
 118         int ofs;
 119 
 120         arc_printk(D_DURING, dev, "prepare_tx: txbufs=%d/%d/%d\n",
 121                    lp->next_tx, lp->cur_tx, bufnum);
 122 
 123         /* hard header is not included in packet length */
 124         length -= ARC_HDR_SIZE;
 125 
 126         if (length > XMTU) {
 127                 /* should never happen! other people already check for this. */
 128                 arc_printk(D_NORMAL, dev, "Bug!  prepare_tx with size %d (> %d)\n",
 129                            length, XMTU);
 130                 length = XMTU;
 131         }
 132         if (length >= MinTU) {
 133                 hard->offset[0] = 0;
 134                 hard->offset[1] = ofs = 512 - length;
 135         } else if (length > MTU) {
 136                 hard->offset[0] = 0;
 137                 hard->offset[1] = ofs = 512 - length - 3;
 138         } else {
 139                 hard->offset[0] = ofs = 256 - length;
 140         }
 141 
 142         arc_printk(D_DURING, dev, "prepare_tx: length=%d ofs=%d\n",
 143                    length, ofs);
 144 
 145         lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
 146         lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft, length);
 147 
 148         lp->lastload_dest = hard->dest;
 149 
 150         return 1;               /* done */
 151 }
 152 
 153 static struct ArcProto rawmode_proto = {
 154         .suffix         = 'r',
 155         .mtu            = XMTU,
 156         .rx             = rx,
 157         .build_header   = build_header,
 158         .prepare_tx     = prepare_tx,
 159         .continue_tx    = NULL,
 160         .ack_tx         = NULL
 161 };
 162 
 163 static int __init arcnet_raw_init(void)
 164 {
 165         int count;
 166 
 167         pr_info("raw mode (`r') encapsulation support loaded\n");
 168 
 169         for (count = 0; count < 256; count++)
 170                 if (arc_proto_map[count] == arc_proto_default)
 171                         arc_proto_map[count] = &rawmode_proto;
 172 
 173         /* for raw mode, we only set the bcast proto if there's no better one */
 174         if (arc_bcast_proto == arc_proto_default)
 175                 arc_bcast_proto = &rawmode_proto;
 176 
 177         arc_proto_default = &rawmode_proto;
 178         return 0;
 179 }
 180 
 181 static void __exit arcnet_raw_exit(void)
 182 {
 183         arcnet_unregister_proto(&rawmode_proto);
 184 }
 185 
 186 module_init(arcnet_raw_init);
 187 module_exit(arcnet_raw_exit);
 188 
 189 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */