Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[powerpc.git] / drivers / net / myri10ge / myri10ge.c
index e2346e8..4330197 100644 (file)
@@ -947,7 +947,7 @@ static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, u16 hw_csum)
            (vh->h_vlan_encapsulated_proto == htons(ETH_P_IP) ||
             vh->h_vlan_encapsulated_proto == htons(ETH_P_IPV6))) {
                skb->csum = hw_csum;
-               skb->ip_summed = CHECKSUM_HW;
+               skb->ip_summed = CHECKSUM_COMPLETE;
        }
 }
 
@@ -989,7 +989,7 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
                if ((skb->protocol == ntohs(ETH_P_IP)) ||
                    (skb->protocol == ntohs(ETH_P_IPV6))) {
                        skb->csum = ntohs((u16) csum);
-                       skb->ip_summed = CHECKSUM_HW;
+                       skb->ip_summed = CHECKSUM_COMPLETE;
                } else
                        myri10ge_vlan_ip_csum(skb, ntohs((u16) csum));
        }
@@ -1389,7 +1389,7 @@ static u32 myri10ge_get_msglevel(struct net_device *netdev)
        return mgp->msg_enable;
 }
 
-static struct ethtool_ops myri10ge_ethtool_ops = {
+static const struct ethtool_ops myri10ge_ethtool_ops = {
        .get_settings = myri10ge_get_settings,
        .get_drvinfo = myri10ge_get_drvinfo,
        .get_coalesce = myri10ge_get_coalesce,
@@ -1953,13 +1953,13 @@ again:
        pseudo_hdr_offset = 0;
        odd_flag = 0;
        flags = (MXGEFW_FLAGS_NO_TSO | MXGEFW_FLAGS_FIRST);
-       if (likely(skb->ip_summed == CHECKSUM_HW)) {
+       if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
                cksum_offset = (skb->h.raw - skb->data);
                pseudo_hdr_offset = (skb->h.raw + skb->csum) - skb->data;
                /* If the headers are excessively large, then we must
                 * fall back to a software checksum */
                if (unlikely(cksum_offset > 255 || pseudo_hdr_offset > 127)) {
-                       if (skb_checksum_help(skb, 0))
+                       if (skb_checksum_help(skb))
                                goto drop;
                        cksum_offset = 0;
                        pseudo_hdr_offset = 0;
@@ -2417,6 +2417,8 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
  */
 
 #define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE  0x0132
+#define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7
+#define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa
 
 static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
 {
@@ -2426,15 +2428,34 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
        mgp->fw_name = myri10ge_fw_unaligned;
 
        if (myri10ge_force_firmware == 0) {
+               int link_width, exp_cap;
+               u16 lnk;
+
+               exp_cap = pci_find_capability(mgp->pdev, PCI_CAP_ID_EXP);
+               pci_read_config_word(mgp->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk);
+               link_width = (lnk >> 4) & 0x3f;
+
                myri10ge_enable_ecrc(mgp);
 
-               /* Check to see if the upstream bridge is known to
-                * provide aligned completions */
-               if (bridge
-                   /* ServerWorks HT2000/HT1000 */
-                   && bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
-                   && bridge->device ==
-                   PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE) {
+               /* Check to see if Link is less than 8 or if the
+                * upstream bridge is known to provide aligned
+                * completions */
+               if (link_width < 8) {
+                       dev_info(&mgp->pdev->dev, "PCIE x%d Link\n",
+                                link_width);
+                       mgp->tx.boundary = 4096;
+                       mgp->fw_name = myri10ge_fw_aligned;
+               } else if (bridge &&
+                          /* ServerWorks HT2000/HT1000 */
+                          ((bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
+                            && bridge->device ==
+                            PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE)
+                           /* All Intel E5000 PCIE ports */
+                           || (bridge->vendor == PCI_VENDOR_ID_INTEL
+                               && bridge->device >=
+                               PCI_DEVICE_ID_INTEL_E5000_PCIE23
+                               && bridge->device <=
+                               PCI_DEVICE_ID_INTEL_E5000_PCIE47))) {
                        dev_info(&mgp->pdev->dev,
                                 "Assuming aligned completions (0x%x:0x%x)\n",
                                 bridge->vendor, bridge->device);