aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/net/Kconfig20
-rw-r--r--drivers/net/ioc3-eth.c48
2 files changed, 32 insertions, 36 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 10ed28ef3566..734f8403c806 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -486,26 +486,6 @@ config SGI_IOC3_ETH
486 the Ethernet-HOWTO, available from 486 the Ethernet-HOWTO, available from
487 <http://www.tldp.org/docs.html#howto>. 487 <http://www.tldp.org/docs.html#howto>.
488 488
489config 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
499config 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
509config MIPS_SIM_NET 489config MIPS_SIM_NET
510 tristate "MIPS simulator Network device" 490 tristate "MIPS simulator Network device"
511 depends on MIPS_SIM 491 depends on MIPS_SIM
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)