133
133
* RX_CHECKSUM turns on card-generated receive checksum generation for
134
134
* TCP and UDP packets. Otherwise the upper layers do the calculation.
135
* TX_CHECKSUM won't do anything too useful, even if it works. There's no
136
* easy mechanism by which to tell the TCP/UDP stack that it need not
137
* generate checksums for this device. But if somebody can find a way
138
* to get that to work, most of the card work is in here already.
139
135
* 3/10/1999 Pete Wyckoff <wyckoff@ca.sandia.gov>
142
137
#define RX_CHECKSUM
144
139
/* Operational parameters that usually are not changed. */
631
626
SET_NETDEV_DEV(dev, &pdev->dev);
634
printk("check that skbcopy in ip_queue_xmit isn't happening\n");
635
dev->hard_header_len += 8; /* for cksum tag */
638
628
for (i = 0; i < 6; i++)
639
629
dev->dev_addr[i] = 1 ? read_eeprom(ioaddr, 4 + i)
640
630
: readb(ioaddr + StationAddr + i);
938
928
/* always 1, takes no more time to do it */
939
929
writew(0x0001, ioaddr + RxChecksum);
941
writew(0x0001, ioaddr + TxChecksum);
943
930
writew(0x0000, ioaddr + TxChecksum);
945
931
writew(0x8000, ioaddr + MACCnfg); /* Soft reset the MAC */
946
932
writew(0x215F, ioaddr + MACCnfg);
947
933
writew(0x000C, ioaddr + FrameGap0);
1230
#define csum_add(it, val) \
1232
it += (u16) (val); \
1233
if (it & 0xffff0000) { \
1238
/* printk("add %04x --> %04x\n", val, it); \ */
1240
/* uh->len already network format, do not swap */
1241
#define pseudo_csum_udp(sum,ih,uh) do { \
1243
csum_add(sum, (ih)->saddr >> 16); \
1244
csum_add(sum, (ih)->saddr & 0xffff); \
1245
csum_add(sum, (ih)->daddr >> 16); \
1246
csum_add(sum, (ih)->daddr & 0xffff); \
1247
csum_add(sum, cpu_to_be16(IPPROTO_UDP)); \
1248
csum_add(sum, (uh)->len); \
1252
#define pseudo_csum_tcp(sum,ih,len) do { \
1254
csum_add(sum, (ih)->saddr >> 16); \
1255
csum_add(sum, (ih)->saddr & 0xffff); \
1256
csum_add(sum, (ih)->daddr >> 16); \
1257
csum_add(sum, (ih)->daddr & 0xffff); \
1258
csum_add(sum, cpu_to_be16(IPPROTO_TCP)); \
1259
csum_add(sum, htons(len)); \
1263
1215
static netdev_tx_t hamachi_start_xmit(struct sk_buff *skb,
1264
1216
struct net_device *dev)
1293
1245
hmp->tx_skbuff[entry] = skb;
1297
/* tack on checksum tag */
1299
struct ethhdr *eh = (struct ethhdr *)skb->data;
1300
if (eh->h_proto == cpu_to_be16(ETH_P_IP)) {
1301
struct iphdr *ih = (struct iphdr *)((char *)eh + ETH_HLEN);
1302
if (ih->protocol == IPPROTO_UDP) {
1304
= (struct udphdr *)((char *)ih + ih->ihl*4);
1305
u32 offset = ((unsigned char *)uh + 6) - skb->data;
1307
pseudo_csum_udp(pseudo, ih, uh);
1308
pseudo = htons(pseudo);
1309
printk("udp cksum was %04x, sending pseudo %04x\n",
1311
uh->check = 0; /* zero out uh->check before card calc */
1313
* start at 14 (skip ethhdr), store at offset (uh->check),
1314
* use pseudo value given.
1316
tagval = (14 << 24) | (offset << 16) | pseudo;
1317
} else if (ih->protocol == IPPROTO_TCP) {
1318
printk("tcp, no auto cksum\n");
1321
*(u32 *)skb_push(skb, 8) = tagval;
1325
1247
hmp->tx_ring[entry].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
1326
1248
skb->data, skb->len, PCI_DMA_TODEVICE));