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/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,
0052 .is_ip = 1,
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
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
0088
0089
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
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
0105 if (pkt->hard.dest != dev->dev_addr[0])
0106 skb->pkt_type = PACKET_OTHERHOST;
0107 }
0108
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
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) {
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
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) {
0166 arc_printk(D_RX, dev, "incoming is not split (splitflag=%d)\n",
0167 soft->split_flag);
0168
0169 if (in->skb) {
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
0193
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
0203
0204
0205
0206
0207 if (soft->proto == ARC_P_ARP) {
0208 struct arphdr *arp = (struct arphdr *)soft->payload;
0209
0210
0211 if (arp->ar_hln == 1 && arp->ar_pln == 4) {
0212 uint8_t *cptr = (uint8_t *)arp + sizeof(struct arphdr);
0213
0214 if (!*cptr) {
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 {
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
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) {
0269 arc_printk(D_RX, dev, "brand new splitpacket (splitflag=%d)\n",
0270 soft->split_flag);
0271 if (in->skb) {
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;
0307 } else {
0308 int packetnum = ((unsigned)soft->split_flag >> 1) + 1;
0309
0310
0311
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
0326 if (packetnum != in->lastpacket) {
0327
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
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
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
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
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
0416
0417
0418
0419
0420
0421 pkt->hard.source = *dev->dev_addr;
0422
0423 soft->sequence = htons(lp->rfc1201.sequence++);
0424 soft->split_flag = 0;
0425
0426
0427
0428 if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
0429
0430
0431
0432
0433
0434 pkt->hard.dest = 0;
0435 return hdr_size;
0436 }
0437
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
0449
0450 if (softlen > MinTU) {
0451 hard->offset[0] = 0;
0452 hard->offset[1] = ofs = 512 - softlen;
0453 } else if (softlen > MTU) {
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
0486 length -= ARC_HDR_SIZE;
0487 pkt->soft.rfc1201.split_flag = 0;
0488
0489
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;
0503 }
0504
0505 load_pkt(dev, &pkt->hard, &pkt->soft.rfc1201, length, bufnum);
0506
0507 return 1;
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
0524 newsoft = (struct arc_rfc1201 *)
0525 (out->pkt->soft.raw + out->length - out->dataleft);
0526
0527 if (!out->segnum)
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 }