e1000: FIX: enable hw TSO for IPV6
authorAuke Kok <auke\-jan.h.kok@intel.com>
Wed, 1 Nov 2006 16:47:36 +0000 (08:47 -0800)
committerJeff Garzik <jeff@garzik.org>
Sat, 2 Dec 2006 05:11:58 +0000 (00:11 -0500)
Enable TSO for IPV6. All e1000 hardware supports it. This reduces CPU
utilizations by 50% when transmitting IPv6 frames.

Fix symbol naming enabling ipv6 TSO. Turn off TSO6 for 10/100.

Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
drivers/net/e1000/e1000.h
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_main.c

index 7ecce438d2586ba483f16ef19dc2837ba3590487..3f0be02e85e24e96e3fb40078491544a463a278e 100644 (file)
@@ -59,6 +59,9 @@
 #include <linux/capability.h>
 #include <linux/in.h>
 #include <linux/ip.h>
+#ifdef NETIF_F_TSO6
+#include <linux/ipv6.h>
+#endif
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <net/pkt_sched.h>
index 82d2c78e16964f579022bd361f9aa6628f4d29bc..b9c0927d79b3306e463298cc52ed535259336be7 100644 (file)
@@ -348,6 +348,13 @@ e1000_set_tso(struct net_device *netdev, uint32_t data)
        else
                netdev->features &= ~NETIF_F_TSO;
 
+#ifdef NETIF_F_TSO6
+       if (data)
+               netdev->features |= NETIF_F_TSO6;
+       else
+               netdev->features &= ~NETIF_F_TSO6;
+#endif
+
        DPRINTK(PROBE, INFO, "TSO is %s\n", data ? "Enabled" : "Disabled");
        adapter->tso_force = TRUE;
        return 0;
index 35d6d080522f8b0d2264a2eef4139bebcccbc283..38ee39e570ea33f04ffad3924f6cf9698ee97ba2 100644 (file)
@@ -844,9 +844,9 @@ e1000_probe(struct pci_dev *pdev,
           (adapter->hw.mac_type != e1000_82547))
                netdev->features |= NETIF_F_TSO;
 
-#ifdef NETIF_F_TSO_IPV6
+#ifdef NETIF_F_TSO6
        if (adapter->hw.mac_type > e1000_82547_rev_2)
-               netdev->features |= NETIF_F_TSO_IPV6;
+               netdev->features |= NETIF_F_TSO6;
 #endif
 #endif
        if (pci_using_dac)
@@ -1814,8 +1814,11 @@ e1000_setup_rctl(struct e1000_adapter *adapter)
                /* Configure extra packet-split registers */
                rfctl = E1000_READ_REG(&adapter->hw, RFCTL);
                rfctl |= E1000_RFCTL_EXTEN;
-               /* disable IPv6 packet split support */
-               rfctl |= E1000_RFCTL_IPV6_DIS;
+               /* disable packet split support for IPv6 extension headers,
+                * because some malformed IPv6 headers can hang the RX */
+               rfctl |= (E1000_RFCTL_IPV6_EX_DIS |
+                         E1000_RFCTL_NEW_IPV6_EXT_DIS);
+
                E1000_WRITE_REG(&adapter->hw, RFCTL, rfctl);
 
                rctl |= E1000_RCTL_DTYP_PS;
@@ -2473,9 +2476,15 @@ e1000_watchdog(unsigned long data)
                                        DPRINTK(PROBE,INFO,
                                        "10/100 speed: disabling TSO\n");
                                        netdev->features &= ~NETIF_F_TSO;
+#ifdef NETIF_F_TSO6
+                                       netdev->features &= ~NETIF_F_TSO6;
+#endif
                                        break;
                                case SPEED_1000:
                                        netdev->features |= NETIF_F_TSO;
+#ifdef NETIF_F_TSO6
+                                       netdev->features |= NETIF_F_TSO6;
+#endif
                                        break;
                                default:
                                        /* oops */
@@ -2610,7 +2619,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
                                                   0);
                        cmd_length = E1000_TXD_CMD_IP;
                        ipcse = skb->h.raw - skb->data - 1;
-#ifdef NETIF_F_TSO_IPV6
+#ifdef NETIF_F_TSO6
                } else if (skb->protocol == htons(ETH_P_IPV6)) {
                        skb->nh.ipv6h->payload_len = 0;
                        skb->h.th->check =