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
0037 #include "arcdevice.h"
0038
0039 static __be16 type_trans(struct sk_buff *skb, struct net_device *dev);
0040 static void rx(struct net_device *dev, int bufnum,
0041 struct archdr *pkthdr, int length);
0042 static int build_header(struct sk_buff *skb, struct net_device *dev,
0043 unsigned short type, uint8_t daddr);
0044 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
0045 int bufnum);
0046
0047 static struct ArcProto rfc1051_proto = {
0048 .suffix = 's',
0049 .mtu = XMTU - RFC1051_HDR_SIZE,
0050 .is_ip = 1,
0051 .rx = rx,
0052 .build_header = build_header,
0053 .prepare_tx = prepare_tx,
0054 .continue_tx = NULL,
0055 .ack_tx = NULL
0056 };
0057
0058 static int __init arcnet_rfc1051_init(void)
0059 {
0060 pr_info("%s\n", "RFC1051 \"simple standard\" (`s') encapsulation support loaded");
0061
0062 arc_proto_map[ARC_P_IP_RFC1051]
0063 = arc_proto_map[ARC_P_ARP_RFC1051]
0064 = &rfc1051_proto;
0065
0066
0067 if (arc_bcast_proto == arc_proto_default)
0068 arc_bcast_proto = &rfc1051_proto;
0069
0070 return 0;
0071 }
0072
0073 static void __exit arcnet_rfc1051_exit(void)
0074 {
0075 arcnet_unregister_proto(&rfc1051_proto);
0076 }
0077
0078 module_init(arcnet_rfc1051_init);
0079 module_exit(arcnet_rfc1051_exit);
0080
0081 MODULE_LICENSE("GPL");
0082
0083
0084
0085
0086
0087 static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
0088 {
0089 struct archdr *pkt = (struct archdr *)skb->data;
0090 struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
0091 int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
0092
0093
0094 skb_reset_mac_header(skb);
0095 skb_pull(skb, hdr_size);
0096
0097 if (pkt->hard.dest == 0) {
0098 skb->pkt_type = PACKET_BROADCAST;
0099 } else if (dev->flags & IFF_PROMISC) {
0100
0101 if (pkt->hard.dest != dev->dev_addr[0])
0102 skb->pkt_type = PACKET_OTHERHOST;
0103 }
0104
0105 switch (soft->proto) {
0106 case ARC_P_IP_RFC1051:
0107 return htons(ETH_P_IP);
0108 case ARC_P_ARP_RFC1051:
0109 return htons(ETH_P_ARP);
0110
0111 default:
0112 dev->stats.rx_errors++;
0113 dev->stats.rx_crc_errors++;
0114 return 0;
0115 }
0116
0117 return htons(ETH_P_IP);
0118 }
0119
0120
0121 static void rx(struct net_device *dev, int bufnum,
0122 struct archdr *pkthdr, int length)
0123 {
0124 struct arcnet_local *lp = netdev_priv(dev);
0125 struct sk_buff *skb;
0126 struct archdr *pkt = pkthdr;
0127 int ofs;
0128
0129 arc_printk(D_DURING, dev, "it's a raw packet (length=%d)\n", length);
0130
0131 if (length >= MinTU)
0132 ofs = 512 - length;
0133 else
0134 ofs = 256 - length;
0135
0136 skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
0137 if (!skb) {
0138 dev->stats.rx_dropped++;
0139 return;
0140 }
0141 skb_put(skb, length + ARC_HDR_SIZE);
0142 skb->dev = dev;
0143
0144 pkt = (struct archdr *)skb->data;
0145
0146
0147 memcpy(pkt, pkthdr, sizeof(struct archdr));
0148 if (length > sizeof(pkt->soft))
0149 lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
0150 pkt->soft.raw + sizeof(pkt->soft),
0151 length - sizeof(pkt->soft));
0152
0153 if (BUGLVL(D_SKB))
0154 arcnet_dump_skb(dev, skb, "rx");
0155
0156 skb->protocol = type_trans(skb, dev);
0157 netif_rx(skb);
0158 }
0159
0160
0161 static int build_header(struct sk_buff *skb, struct net_device *dev,
0162 unsigned short type, uint8_t daddr)
0163 {
0164 int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
0165 struct archdr *pkt = skb_push(skb, hdr_size);
0166 struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
0167
0168
0169 switch (type) {
0170 case ETH_P_IP:
0171 soft->proto = ARC_P_IP_RFC1051;
0172 break;
0173 case ETH_P_ARP:
0174 soft->proto = ARC_P_ARP_RFC1051;
0175 break;
0176 default:
0177 arc_printk(D_NORMAL, dev, "RFC1051: I don't understand protocol %d (%Xh)\n",
0178 type, type);
0179 dev->stats.tx_errors++;
0180 dev->stats.tx_aborted_errors++;
0181 return 0;
0182 }
0183
0184
0185
0186
0187
0188
0189
0190 pkt->hard.source = *dev->dev_addr;
0191
0192
0193
0194 if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
0195
0196
0197
0198 pkt->hard.dest = 0;
0199 return hdr_size;
0200 }
0201
0202 pkt->hard.dest = daddr;
0203
0204 return hdr_size;
0205 }
0206
0207 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
0208 int bufnum)
0209 {
0210 struct arcnet_local *lp = netdev_priv(dev);
0211 struct arc_hardware *hard = &pkt->hard;
0212 int ofs;
0213
0214 arc_printk(D_DURING, dev, "prepare_tx: txbufs=%d/%d/%d\n",
0215 lp->next_tx, lp->cur_tx, bufnum);
0216
0217
0218 length -= ARC_HDR_SIZE;
0219
0220 if (length > XMTU) {
0221
0222 arc_printk(D_NORMAL, dev, "Bug! prepare_tx with size %d (> %d)\n",
0223 length, XMTU);
0224 length = XMTU;
0225 }
0226 if (length > MinTU) {
0227 hard->offset[0] = 0;
0228 hard->offset[1] = ofs = 512 - length;
0229 } else if (length > MTU) {
0230 hard->offset[0] = 0;
0231 hard->offset[1] = ofs = 512 - length - 3;
0232 } else {
0233 hard->offset[0] = ofs = 256 - length;
0234 }
0235
0236 lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
0237 lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft, length);
0238
0239 lp->lastload_dest = hard->dest;
0240
0241 return 1;
0242 }