}
 }
 
+static int e1000_get_rxnfc(struct net_device *netdev,
+                          struct ethtool_rxnfc *info, u32 *rule_locs)
+{
+       info->data = 0;
+
+       switch (info->cmd) {
+       case ETHTOOL_GRXFH: {
+               struct e1000_adapter *adapter = netdev_priv(netdev);
+               struct e1000_hw *hw = &adapter->hw;
+               u32 mrqc = er32(MRQC);
+
+               if (!(mrqc & E1000_MRQC_RSS_FIELD_MASK))
+                       return 0;
+
+               switch (info->flow_type) {
+               case TCP_V4_FLOW:
+                       if (mrqc & E1000_MRQC_RSS_FIELD_IPV4_TCP)
+                               info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+                       /* fall through */
+               case UDP_V4_FLOW:
+               case SCTP_V4_FLOW:
+               case AH_ESP_V4_FLOW:
+               case IPV4_FLOW:
+                       if (mrqc & E1000_MRQC_RSS_FIELD_IPV4)
+                               info->data |= RXH_IP_SRC | RXH_IP_DST;
+                       break;
+               case TCP_V6_FLOW:
+                       if (mrqc & E1000_MRQC_RSS_FIELD_IPV6_TCP)
+                               info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+                       /* fall through */
+               case UDP_V6_FLOW:
+               case SCTP_V6_FLOW:
+               case AH_ESP_V6_FLOW:
+               case IPV6_FLOW:
+                       if (mrqc & E1000_MRQC_RSS_FIELD_IPV6)
+                               info->data |= RXH_IP_SRC | RXH_IP_DST;
+                       break;
+               default:
+                       break;
+               }
+               return 0;
+       }
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
 static const struct ethtool_ops e1000_ethtool_ops = {
        .get_settings           = e1000_get_settings,
        .set_settings           = e1000_set_settings,
        .get_sset_count         = e1000e_get_sset_count,
        .get_coalesce           = e1000_get_coalesce,
        .set_coalesce           = e1000_set_coalesce,
+       .get_rxnfc              = e1000_get_rxnfc,
 };
 
 void e1000e_set_ethtool_ops(struct net_device *netdev)
 
        E1000_WUC      = 0x05800, /* Wakeup Control - RW */
        E1000_WUFC     = 0x05808, /* Wakeup Filter Control - RW */
        E1000_WUS      = 0x05810, /* Wakeup Status - RO */
+       E1000_MRQC     = 0x05818, /* Multiple Receive Control - RW */
        E1000_MANC     = 0x05820, /* Management Control - RW */
        E1000_FFLT     = 0x05F00, /* Flexible Filter Length Table - RW Array */
        E1000_HOST_IF  = 0x08800, /* Host Interface */
        E1000_SWSM      = 0x05B50, /* SW Semaphore */
        E1000_FWSM      = 0x05B54, /* FW Semaphore */
        E1000_SWSM2     = 0x05B58, /* Driver-only SW semaphore */
+       E1000_RETA_BASE = 0x05C00, /* Redirection Table - RW */
+#define E1000_RETA(_n) (E1000_RETA_BASE + ((_n) * 4))
+       E1000_RSSRK_BASE = 0x05C80, /* RSS Random Key - RW */
+#define E1000_RSSRK(_n)        (E1000_RSSRK_BASE + ((_n) * 4))
        E1000_FFLT_DBG  = 0x05F04, /* Debug Register */
        E1000_PCH_RAICC_BASE = 0x05F50, /* Receive Address Initial CRC */
 #define E1000_PCH_RAICC(_n)    (E1000_PCH_RAICC_BASE + ((_n) * 4))
 
        }
 }
 
+static inline void e1000_rx_hash(struct net_device *netdev, __le32 rss,
+                                struct sk_buff *skb)
+{
+       if (netdev->features & NETIF_F_RXHASH)
+               skb->rxhash = le32_to_cpu(rss);
+}
+
 /**
  * e1000_clean_rx_irq - Send received data up the network stack; legacy
  * @adapter: board private structure
                e1000_rx_checksum(adapter, staterr,
                                  rx_desc->wb.lower.hi_dword.csum_ip.csum, skb);
 
+               e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
+
                e1000_receive_skb(adapter, netdev, skb, staterr,
                                  rx_desc->wb.upper.vlan);
 
                e1000_rx_checksum(adapter, staterr,
                                  rx_desc->wb.lower.hi_dword.csum_ip.csum, skb);
 
+               e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
+
                if (rx_desc->wb.upper.header_status &
                           cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP))
                        adapter->rx_hdr_split++;
                e1000_rx_checksum(adapter, staterr,
                                  rx_desc->wb.lower.hi_dword.csum_ip.csum, skb);
 
+               e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
+
                /* probably a little skewed due to removing CRC */
                total_rx_bytes += skb->len;
                total_rx_packets++;
                e1000e_vlan_strip_disable(adapter);
 }
 
+static void e1000e_setup_rss_hash(struct e1000_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       u32 mrqc, rxcsum;
+       int i;
+       static const u32 rsskey[10] = {
+               0xda565a6d, 0xc20e5b25, 0x3d256741, 0xb08fa343, 0xcb2bcad0,
+               0xb4307bae, 0xa32dcb77, 0x0cf23080, 0x3bb7426a, 0xfa01acbe
+       };
+
+       /* Fill out hash function seed */
+       for (i = 0; i < 10; i++)
+               ew32(RSSRK(i), rsskey[i]);
+
+       /* Direct all traffic to queue 0 */
+       for (i = 0; i < 32; i++)
+               ew32(RETA(i), 0);
+
+       /*
+        * Disable raw packet checksumming so that RSS hash is placed in
+        * descriptor on writeback.
+        */
+       rxcsum = er32(RXCSUM);
+       rxcsum |= E1000_RXCSUM_PCSD;
+
+       ew32(RXCSUM, rxcsum);
+
+       mrqc = (E1000_MRQC_RSS_FIELD_IPV4 |
+               E1000_MRQC_RSS_FIELD_IPV4_TCP |
+               E1000_MRQC_RSS_FIELD_IPV6 |
+               E1000_MRQC_RSS_FIELD_IPV6_TCP |
+               E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
+
+       ew32(MRQC, mrqc);
+}
+
 /**
  * e1000_configure - configure the hardware for Rx and Tx
  * @adapter: private board structure
        e1000_init_manageability_pt(adapter);
 
        e1000_configure_tx(adapter);
+
+       if (adapter->netdev->features & NETIF_F_RXHASH)
+               e1000e_setup_rss_hash(adapter);
        e1000_setup_rctl(adapter);
        e1000_configure_rx(adapter);
        adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring),
        int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
 
        /* Jumbo frame support */
-       if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
-           !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
-               e_err("Jumbo Frames not supported.\n");
-               return -EINVAL;
+       if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {
+               if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
+                       e_err("Jumbo Frames not supported.\n");
+                       return -EINVAL;
+               }
+
+               /*
+                * IP payload checksum (enabled with jumbos/packet-split when
+                * Rx checksum is enabled) and generation of RSS hash is
+                * mutually exclusive in the hardware.
+                */
+               if ((netdev->features & NETIF_F_RXCSUM) &&
+                   (netdev->features & NETIF_F_RXHASH)) {
+                       e_err("Jumbo frames cannot be enabled when both receive checksum offload and receive hashing are enabled.  Disable one of the receive offload features before enabling jumbos.\n");
+                       return -EINVAL;
+               }
        }
 
        /* Supported frame sizes */
 }
 
 static int e1000_set_features(struct net_device *netdev,
-       netdev_features_t features)
+                             netdev_features_t features)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        netdev_features_t changed = features ^ netdev->features;
                adapter->flags |= FLAG_TSO_FORCE;
 
        if (!(changed & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX |
-                        NETIF_F_RXCSUM)))
+                        NETIF_F_RXCSUM | NETIF_F_RXHASH)))
                return 0;
 
+       /*
+        * IP payload checksum (enabled with jumbos/packet-split when Rx
+        * checksum is enabled) and generation of RSS hash is mutually
+        * exclusive in the hardware.
+        */
+       if (adapter->rx_ps_pages &&
+           (features & NETIF_F_RXCSUM) && (features & NETIF_F_RXHASH)) {
+               e_err("Enabling both receive checksum offload and receive hashing is not possible with jumbo frames.  Disable jumbos or enable only one of the receive offload features.\n");
+               return -EINVAL;
+       }
+
+       netdev->features = features;
+
        if (netif_running(netdev))
                e1000e_reinit_locked(adapter);
        else
                            NETIF_F_HW_VLAN_TX |
                            NETIF_F_TSO |
                            NETIF_F_TSO6 |
+                           NETIF_F_RXHASH |
                            NETIF_F_RXCSUM |
                            NETIF_F_HW_CSUM);