diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2007-07-25 07:31:57 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:50:20 -0400 |
commit | bbfb86c5776ff481d246fcd5d8deb67701e05c00 (patch) | |
tree | d9fb6c8931bf59049bf72d9bca18c2a216ab7fd6 /drivers/net/ioc3-eth.c | |
parent | c54f5c240239fb8391a3b541f916764dd496f2e6 (diff) |
IOC3: Switch hw checksumming to ethtool configurable.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/ioc3-eth.c')
-rw-r--r-- | drivers/net/ioc3-eth.c | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index 0834ef0eddb4..c030030e5863 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Driver for SGI's IOC3 based Ethernet cards as found in the PCI card. | 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 | * Copyright (C) 1995, 1999, 2000, 2001 by Silicon Graphics, Inc. | 9 | * Copyright (C) 1995, 1999, 2000, 2001 by Silicon Graphics, Inc. |
10 | * | 10 | * |
11 | * References: | 11 | * References: |
@@ -62,12 +62,7 @@ | |||
62 | #include <asm/pgtable.h> | 62 | #include <asm/pgtable.h> |
63 | #include <asm/uaccess.h> | 63 | #include <asm/uaccess.h> |
64 | #include <asm/sn/types.h> | 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 | #include <asm/sn/ioc3.h> | 65 | #include <asm/sn/ioc3.h> |
70 | #include <asm/sn/sn0/ip27.h> | ||
71 | #include <asm/pci/bridge.h> | 66 | #include <asm/pci/bridge.h> |
72 | 67 | ||
73 | /* | 68 | /* |
@@ -95,6 +90,9 @@ struct ioc3_private { | |||
95 | u32 emcr, ehar_h, ehar_l; | 90 | u32 emcr, ehar_h, ehar_l; |
96 | spinlock_t ioc3_lock; | 91 | spinlock_t ioc3_lock; |
97 | struct mii_if_info mii; | 92 | struct mii_if_info mii; |
93 | unsigned long flags; | ||
94 | #define IOC3_FLAG_RX_CHECKSUMS 1 | ||
95 | |||
98 | struct pci_dev *pdev; | 96 | struct pci_dev *pdev; |
99 | 97 | ||
100 | /* Members used by autonegotiation */ | 98 | /* Members used by autonegotiation */ |
@@ -521,8 +519,6 @@ static struct net_device_stats *ioc3_get_stats(struct net_device *dev) | |||
521 | return &ip->stats; | 519 | return &ip->stats; |
522 | } | 520 | } |
523 | 521 | ||
524 | #ifdef CONFIG_SGI_IOC3_ETH_HW_RX_CSUM | ||
525 | |||
526 | static void ioc3_tcpudp_checksum(struct sk_buff *skb, uint32_t hwsum, int len) | 522 | static void ioc3_tcpudp_checksum(struct sk_buff *skb, uint32_t hwsum, int len) |
527 | { | 523 | { |
528 | struct ethhdr *eh = eth_hdr(skb); | 524 | struct ethhdr *eh = eth_hdr(skb); |
@@ -590,7 +586,6 @@ static void ioc3_tcpudp_checksum(struct sk_buff *skb, uint32_t hwsum, int len) | |||
590 | if (csum == 0xffff) | 586 | if (csum == 0xffff) |
591 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 587 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
592 | } | 588 | } |
593 | #endif /* CONFIG_SGI_IOC3_ETH_HW_RX_CSUM */ | ||
594 | 589 | ||
595 | static inline void ioc3_rx(struct ioc3_private *ip) | 590 | static inline void ioc3_rx(struct ioc3_private *ip) |
596 | { | 591 | { |
@@ -625,9 +620,9 @@ static inline void ioc3_rx(struct ioc3_private *ip) | |||
625 | goto next; | 620 | goto next; |
626 | } | 621 | } |
627 | 622 | ||
628 | #ifdef CONFIG_SGI_IOC3_ETH_HW_RX_CSUM | 623 | if (likely(ip->flags & IOC3_FLAG_RX_CHECKSUMS)) |
629 | ioc3_tcpudp_checksum(skb, w0 & ERXBUF_IPCKSUM_MASK,len); | 624 | ioc3_tcpudp_checksum(skb, |
630 | #endif | 625 | w0 & ERXBUF_IPCKSUM_MASK, len); |
631 | 626 | ||
632 | netif_rx(skb); | 627 | netif_rx(skb); |
633 | 628 | ||
@@ -1338,9 +1333,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1338 | dev->set_multicast_list = ioc3_set_multicast_list; | 1333 | dev->set_multicast_list = ioc3_set_multicast_list; |
1339 | dev->set_mac_address = ioc3_set_mac_address; | 1334 | dev->set_mac_address = ioc3_set_mac_address; |
1340 | dev->ethtool_ops = &ioc3_ethtool_ops; | 1335 | dev->ethtool_ops = &ioc3_ethtool_ops; |
1341 | #ifdef CONFIG_SGI_IOC3_ETH_HW_TX_CSUM | ||
1342 | dev->features = NETIF_F_IP_CSUM; | 1336 | dev->features = NETIF_F_IP_CSUM; |
1343 | #endif | ||
1344 | 1337 | ||
1345 | sw_physid1 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID1); | 1338 | sw_physid1 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID1); |
1346 | sw_physid2 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID2); | 1339 | sw_physid2 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID2); |
@@ -1430,7 +1423,6 @@ static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1430 | uint32_t w0 = 0; | 1423 | uint32_t w0 = 0; |
1431 | int produce; | 1424 | int produce; |
1432 | 1425 | ||
1433 | #ifdef CONFIG_SGI_IOC3_ETH_HW_TX_CSUM | ||
1434 | /* | 1426 | /* |
1435 | * IOC3 has a fairly simple minded checksumming hardware which simply | 1427 | * IOC3 has a fairly simple minded checksumming hardware which simply |
1436 | * adds up the 1's complement checksum for the entire packet and | 1428 | * adds up the 1's complement checksum for the entire packet and |
@@ -1478,7 +1470,6 @@ static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1478 | 1470 | ||
1479 | w0 = ETXD_DOCHECKSUM | (csoff << ETXD_CHKOFF_SHIFT); | 1471 | w0 = ETXD_DOCHECKSUM | (csoff << ETXD_CHKOFF_SHIFT); |
1480 | } | 1472 | } |
1481 | #endif /* CONFIG_SGI_IOC3_ETH_HW_TX_CSUM */ | ||
1482 | 1473 | ||
1483 | spin_lock_irq(&ip->ioc3_lock); | 1474 | spin_lock_irq(&ip->ioc3_lock); |
1484 | 1475 | ||
@@ -1633,12 +1624,37 @@ static u32 ioc3_get_link(struct net_device *dev) | |||
1633 | return rc; | 1624 | return rc; |
1634 | } | 1625 | } |
1635 | 1626 | ||
1627 | static u32 ioc3_get_rx_csum(struct net_device *dev) | ||
1628 | { | ||
1629 | struct ioc3_private *ip = netdev_priv(dev); | ||
1630 | |||
1631 | return ip->flags & IOC3_FLAG_RX_CHECKSUMS; | ||
1632 | } | ||
1633 | |||
1634 | static int ioc3_set_rx_csum(struct net_device *dev, u32 data) | ||
1635 | { | ||
1636 | struct ioc3_private *ip = netdev_priv(dev); | ||
1637 | |||
1638 | spin_lock_bh(&ip->ioc3_lock); | ||
1639 | if (data) | ||
1640 | ip->flags |= IOC3_FLAG_RX_CHECKSUMS; | ||
1641 | else | ||
1642 | ip->flags &= ~IOC3_FLAG_RX_CHECKSUMS; | ||
1643 | spin_unlock_bh(&ip->ioc3_lock); | ||
1644 | |||
1645 | return 0; | ||
1646 | } | ||
1647 | |||
1636 | static const struct ethtool_ops ioc3_ethtool_ops = { | 1648 | static const struct ethtool_ops ioc3_ethtool_ops = { |
1637 | .get_drvinfo = ioc3_get_drvinfo, | 1649 | .get_drvinfo = ioc3_get_drvinfo, |
1638 | .get_settings = ioc3_get_settings, | 1650 | .get_settings = ioc3_get_settings, |
1639 | .set_settings = ioc3_set_settings, | 1651 | .set_settings = ioc3_set_settings, |
1640 | .nway_reset = ioc3_nway_reset, | 1652 | .nway_reset = ioc3_nway_reset, |
1641 | .get_link = ioc3_get_link, | 1653 | .get_link = ioc3_get_link, |
1654 | .get_rx_csum = ioc3_get_rx_csum, | ||
1655 | .set_rx_csum = ioc3_set_rx_csum, | ||
1656 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
1657 | .set_tx_csum = ethtool_op_set_tx_csum | ||
1642 | }; | 1658 | }; |
1643 | 1659 | ||
1644 | static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | 1660 | static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |