0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
0028
0029 #include <linux/module.h>
0030 #include <linux/gfp.h>
0031 #include <linux/init.h>
0032 #include <linux/if_arp.h>
0033 #include <net/arp.h>
0034 #include <linux/netdevice.h>
0035 #include <linux/skbuff.h>
0036 #include "arcdevice.h"
0037
0038
0039 static void rx(struct net_device *dev, int bufnum,
0040 struct archdr *pkthdr, int length)
0041 {
0042 struct arcnet_local *lp = netdev_priv(dev);
0043 struct sk_buff *skb;
0044 struct archdr *pkt = pkthdr;
0045 int ofs;
0046
0047 arc_printk(D_DURING, dev, "it's a raw packet (length=%d)\n", length);
0048
0049 if (length > MTU)
0050 ofs = 512 - length;
0051 else
0052 ofs = 256 - length;
0053
0054 skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
0055 if (!skb) {
0056 dev->stats.rx_dropped++;
0057 return;
0058 }
0059 skb_put(skb, length + ARC_HDR_SIZE);
0060 skb->dev = dev;
0061
0062 pkt = (struct archdr *)skb->data;
0063
0064 skb_reset_mac_header(skb);
0065 skb_pull(skb, ARC_HDR_SIZE);
0066
0067
0068 memcpy(pkt, pkthdr, sizeof(struct archdr));
0069 if (length > sizeof(pkt->soft))
0070 lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
0071 pkt->soft.raw + sizeof(pkt->soft),
0072 length - sizeof(pkt->soft));
0073
0074 if (BUGLVL(D_SKB))
0075 arcnet_dump_skb(dev, skb, "rx");
0076
0077 skb->protocol = cpu_to_be16(ETH_P_ARCNET);
0078 netif_rx(skb);
0079 }
0080
0081
0082
0083
0084 static int build_header(struct sk_buff *skb, struct net_device *dev,
0085 unsigned short type, uint8_t daddr)
0086 {
0087 int hdr_size = ARC_HDR_SIZE;
0088 struct archdr *pkt = skb_push(skb, hdr_size);
0089
0090
0091
0092
0093
0094
0095
0096 pkt->hard.source = *dev->dev_addr;
0097
0098
0099
0100 if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
0101
0102
0103
0104 pkt->hard.dest = 0;
0105 return hdr_size;
0106 }
0107
0108 pkt->hard.dest = daddr;
0109
0110 return hdr_size;
0111 }
0112
0113 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
0114 int bufnum)
0115 {
0116 struct arcnet_local *lp = netdev_priv(dev);
0117 struct arc_hardware *hard = &pkt->hard;
0118 int ofs;
0119
0120 arc_printk(D_DURING, dev, "prepare_tx: txbufs=%d/%d/%d\n",
0121 lp->next_tx, lp->cur_tx, bufnum);
0122
0123
0124 length -= ARC_HDR_SIZE;
0125
0126 if (length > XMTU) {
0127
0128 arc_printk(D_NORMAL, dev, "Bug! prepare_tx with size %d (> %d)\n",
0129 length, XMTU);
0130 length = XMTU;
0131 }
0132 if (length >= MinTU) {
0133 hard->offset[0] = 0;
0134 hard->offset[1] = ofs = 512 - length;
0135 } else if (length > MTU) {
0136 hard->offset[0] = 0;
0137 hard->offset[1] = ofs = 512 - length - 3;
0138 } else {
0139 hard->offset[0] = ofs = 256 - length;
0140 }
0141
0142 arc_printk(D_DURING, dev, "prepare_tx: length=%d ofs=%d\n",
0143 length, ofs);
0144
0145 lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
0146 lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft, length);
0147
0148 lp->lastload_dest = hard->dest;
0149
0150 return 1;
0151 }
0152
0153 static struct ArcProto rawmode_proto = {
0154 .suffix = 'r',
0155 .mtu = XMTU,
0156 .rx = rx,
0157 .build_header = build_header,
0158 .prepare_tx = prepare_tx,
0159 .continue_tx = NULL,
0160 .ack_tx = NULL
0161 };
0162
0163 static int __init arcnet_raw_init(void)
0164 {
0165 int count;
0166
0167 pr_info("raw mode (`r') encapsulation support loaded\n");
0168
0169 for (count = 0; count < 256; count++)
0170 if (arc_proto_map[count] == arc_proto_default)
0171 arc_proto_map[count] = &rawmode_proto;
0172
0173
0174 if (arc_bcast_proto == arc_proto_default)
0175 arc_bcast_proto = &rawmode_proto;
0176
0177 arc_proto_default = &rawmode_proto;
0178 return 0;
0179 }
0180
0181 static void __exit arcnet_raw_exit(void)
0182 {
0183 arcnet_unregister_proto(&rawmode_proto);
0184 }
0185
0186 module_init(arcnet_raw_init);
0187 module_exit(arcnet_raw_exit);
0188
0189 MODULE_LICENSE("GPL");