aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ioc3-eth.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2007-07-25 07:31:57 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:50:20 -0400
commitbbfb86c5776ff481d246fcd5d8deb67701e05c00 (patch)
treed9fb6c8931bf59049bf72d9bca18c2a216ab7fd6 /drivers/net/ioc3-eth.c
parentc54f5c240239fb8391a3b541f916764dd496f2e6 (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.c48
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
526static void ioc3_tcpudp_checksum(struct sk_buff *skb, uint32_t hwsum, int len) 522static 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
595static inline void ioc3_rx(struct ioc3_private *ip) 590static 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
1627static 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
1634static 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
1636static const struct ethtool_ops ioc3_ethtool_ops = { 1648static 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
1644static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 1660static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)