Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IOC3: Switch hw checksumming to ethtool configurable.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

authored by

Ralf Baechle and committed by
David S. Miller
bbfb86c5 c54f5c24

+32 -36
-20
drivers/net/Kconfig
··· 486 486 the Ethernet-HOWTO, available from 487 487 <http://www.tldp.org/docs.html#howto>. 488 488 489 - config SGI_IOC3_ETH_HW_RX_CSUM 490 - bool "Receive hardware checksums" 491 - depends on SGI_IOC3_ETH && INET 492 - default y 493 - help 494 - The SGI IOC3 network adapter supports TCP and UDP checksums in 495 - hardware to offload processing of these checksums from the CPU. At 496 - the moment only acceleration of IPv4 is supported. This option 497 - enables offloading for checksums on receive. If unsure, say Y. 498 - 499 - config SGI_IOC3_ETH_HW_TX_CSUM 500 - bool "Transmit hardware checksums" 501 - depends on SGI_IOC3_ETH && INET 502 - default y 503 - help 504 - The SGI IOC3 network adapter supports TCP and UDP checksums in 505 - hardware to offload processing of these checksums from the CPU. At 506 - the moment only acceleration of IPv4 is supported. This option 507 - enables offloading for checksums on transmit. If unsure, say Y. 508 - 509 489 config MIPS_SIM_NET 510 490 tristate "MIPS simulator Network device" 511 491 depends on MIPS_SIM
+32 -16
drivers/net/ioc3-eth.c
··· 5 5 * 6 6 * Driver for SGI's IOC3 based Ethernet cards as found in the PCI card. 7 7 * 8 - * Copyright (C) 1999, 2000, 2001, 2003 Ralf Baechle 8 + * Copyright (C) 1999, 2000, 01, 03, 06 Ralf Baechle 9 9 * Copyright (C) 1995, 1999, 2000, 2001 by Silicon Graphics, Inc. 10 10 * 11 11 * References: ··· 62 62 #include <asm/pgtable.h> 63 63 #include <asm/uaccess.h> 64 64 #include <asm/sn/types.h> 65 - #include <asm/sn/sn0/addrs.h> 66 - #include <asm/sn/sn0/hubni.h> 67 - #include <asm/sn/sn0/hubio.h> 68 - #include <asm/sn/klconfig.h> 69 65 #include <asm/sn/ioc3.h> 70 - #include <asm/sn/sn0/ip27.h> 71 66 #include <asm/pci/bridge.h> 72 67 73 68 /* ··· 90 95 u32 emcr, ehar_h, ehar_l; 91 96 spinlock_t ioc3_lock; 92 97 struct mii_if_info mii; 98 + unsigned long flags; 99 + #define IOC3_FLAG_RX_CHECKSUMS 1 100 + 93 101 struct pci_dev *pdev; 94 102 95 103 /* Members used by autonegotiation */ ··· 519 521 return &ip->stats; 520 522 } 521 523 522 - #ifdef CONFIG_SGI_IOC3_ETH_HW_RX_CSUM 523 - 524 524 static void ioc3_tcpudp_checksum(struct sk_buff *skb, uint32_t hwsum, int len) 525 525 { 526 526 struct ethhdr *eh = eth_hdr(skb); ··· 586 590 if (csum == 0xffff) 587 591 skb->ip_summed = CHECKSUM_UNNECESSARY; 588 592 } 589 - #endif /* CONFIG_SGI_IOC3_ETH_HW_RX_CSUM */ 590 593 591 594 static inline void ioc3_rx(struct ioc3_private *ip) 592 595 { ··· 620 625 goto next; 621 626 } 622 627 623 - #ifdef CONFIG_SGI_IOC3_ETH_HW_RX_CSUM 624 - ioc3_tcpudp_checksum(skb, w0 & ERXBUF_IPCKSUM_MASK,len); 625 - #endif 628 + if (likely(ip->flags & IOC3_FLAG_RX_CHECKSUMS)) 629 + ioc3_tcpudp_checksum(skb, 630 + w0 & ERXBUF_IPCKSUM_MASK, len); 626 631 627 632 netif_rx(skb); 628 633 ··· 1333 1338 dev->set_multicast_list = ioc3_set_multicast_list; 1334 1339 dev->set_mac_address = ioc3_set_mac_address; 1335 1340 dev->ethtool_ops = &ioc3_ethtool_ops; 1336 - #ifdef CONFIG_SGI_IOC3_ETH_HW_TX_CSUM 1337 1341 dev->features = NETIF_F_IP_CSUM; 1338 - #endif 1339 1342 1340 1343 sw_physid1 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID1); 1341 1344 sw_physid2 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID2); ··· 1423 1430 uint32_t w0 = 0; 1424 1431 int produce; 1425 1432 1426 - #ifdef CONFIG_SGI_IOC3_ETH_HW_TX_CSUM 1427 1433 /* 1428 1434 * IOC3 has a fairly simple minded checksumming hardware which simply 1429 1435 * adds up the 1's complement checksum for the entire packet and ··· 1470 1478 1471 1479 w0 = ETXD_DOCHECKSUM | (csoff << ETXD_CHKOFF_SHIFT); 1472 1480 } 1473 - #endif /* CONFIG_SGI_IOC3_ETH_HW_TX_CSUM */ 1474 1481 1475 1482 spin_lock_irq(&ip->ioc3_lock); 1476 1483 ··· 1624 1633 return rc; 1625 1634 } 1626 1635 1636 + static u32 ioc3_get_rx_csum(struct net_device *dev) 1637 + { 1638 + struct ioc3_private *ip = netdev_priv(dev); 1639 + 1640 + return ip->flags & IOC3_FLAG_RX_CHECKSUMS; 1641 + } 1642 + 1643 + static int ioc3_set_rx_csum(struct net_device *dev, u32 data) 1644 + { 1645 + struct ioc3_private *ip = netdev_priv(dev); 1646 + 1647 + spin_lock_bh(&ip->ioc3_lock); 1648 + if (data) 1649 + ip->flags |= IOC3_FLAG_RX_CHECKSUMS; 1650 + else 1651 + ip->flags &= ~IOC3_FLAG_RX_CHECKSUMS; 1652 + spin_unlock_bh(&ip->ioc3_lock); 1653 + 1654 + return 0; 1655 + } 1656 + 1627 1657 static const struct ethtool_ops ioc3_ethtool_ops = { 1628 1658 .get_drvinfo = ioc3_get_drvinfo, 1629 1659 .get_settings = ioc3_get_settings, 1630 1660 .set_settings = ioc3_set_settings, 1631 1661 .nway_reset = ioc3_nway_reset, 1632 1662 .get_link = ioc3_get_link, 1663 + .get_rx_csum = ioc3_get_rx_csum, 1664 + .set_rx_csum = ioc3_set_rx_csum, 1665 + .get_tx_csum = ethtool_op_get_tx_csum, 1666 + .set_tx_csum = ethtool_op_set_tx_csum 1633 1667 }; 1634 1668 1635 1669 static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)