Pull asus into release branch
[pandora-kernel.git] / drivers / net / myri10ge / myri10ge.c
index b05dc6e..f8efe0e 100644 (file)
@@ -71,7 +71,7 @@
 #include "myri10ge_mcp.h"
 #include "myri10ge_mcp_gen_header.h"
 
-#define MYRI10GE_VERSION_STR "1.2.0"
+#define MYRI10GE_VERSION_STR "1.3.0-1.233"
 
 MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
 MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -181,6 +181,7 @@ struct myri10ge_priv {
        int intr_coal_delay;
        __be32 __iomem *intr_coal_delay_ptr;
        int mtrr;
+       int wc_enabled;
        int wake_queue;
        int stop_queue;
        int down_cnt;
@@ -233,7 +234,7 @@ static int myri10ge_msi = 1;        /* enable msi by default */
 module_param(myri10ge_msi, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n");
 
-static int myri10ge_intr_coal_delay = 25;
+static int myri10ge_intr_coal_delay = 75;
 module_param(myri10ge_intr_coal_delay, int, S_IRUGO);
 MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay\n");
 
@@ -278,7 +279,7 @@ static int myri10ge_fill_thresh = 256;
 module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n");
 
-static int myri10ge_wcfifo = 1;
+static int myri10ge_wcfifo = 0;
 module_param(myri10ge_wcfifo, int, S_IRUGO);
 MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n");
 
@@ -717,6 +718,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
        int status;
        size_t bytes;
        u32 len;
+       struct page *dmatest_page;
+       dma_addr_t dmatest_bus;
 
        /* try to send a reset command to the card to see if it
         * is alive */
@@ -726,6 +729,11 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
                dev_err(&mgp->pdev->dev, "failed reset\n");
                return -ENXIO;
        }
+       dmatest_page = alloc_page(GFP_KERNEL);
+       if (!dmatest_page)
+               return -ENOMEM;
+       dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE,
+                                  DMA_BIDIRECTIONAL);
 
        /* Now exchange information about interrupts  */
 
@@ -764,8 +772,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
 
        len = mgp->tx.boundary;
 
-       cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
-       cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+       cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+       cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
        cmd.data2 = len * 0x10000;
        status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
        if (status == 0)
@@ -774,8 +782,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
        else
                dev_warn(&mgp->pdev->dev, "DMA read benchmark failed: %d\n",
                         status);
-       cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
-       cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+       cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+       cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
        cmd.data2 = len * 0x1;
        status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
        if (status == 0)
@@ -785,8 +793,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
                dev_warn(&mgp->pdev->dev, "DMA write benchmark failed: %d\n",
                         status);
 
-       cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
-       cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+       cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+       cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
        cmd.data2 = len * 0x10001;
        status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
        if (status == 0)
@@ -796,6 +804,9 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
                dev_warn(&mgp->pdev->dev,
                         "DMA read/write benchmark failed: %d\n", status);
 
+       pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
+       put_page(dmatest_page);
+
        memset(mgp->rx_done.entry, 0, bytes);
 
        /* reset mcp/driver shared state back to 0 */
@@ -889,9 +900,7 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
        /* try to refill entire ring */
        while (rx->fill_cnt != (rx->cnt + rx->mask + 1)) {
                idx = rx->fill_cnt & rx->mask;
-
-               if ((bytes < MYRI10GE_ALLOC_SIZE / 2) &&
-                   (rx->page_offset + bytes <= MYRI10GE_ALLOC_SIZE)) {
+               if (rx->page_offset + bytes <= MYRI10GE_ALLOC_SIZE) {
                        /* we can use part of previous page */
                        get_page(rx->page);
                } else {
@@ -922,6 +931,13 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
 
                /* start next packet on a cacheline boundary */
                rx->page_offset += SKB_DATA_ALIGN(bytes);
+
+#if MYRI10GE_ALLOC_SIZE > 4096
+               /* don't cross a 4KB boundary */
+               if ((rx->page_offset >> 12) !=
+                   ((rx->page_offset + bytes - 1) >> 12))
+                       rx->page_offset = (rx->page_offset + 4096) & ~4095;
+#endif
                rx->fill_cnt++;
 
                /* copy 8 descriptors to the firmware at a time */
@@ -1375,7 +1391,7 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
                data[i] = ((unsigned long *)&mgp->stats)[i];
 
        data[i++] = (unsigned int)mgp->tx.boundary;
-       data[i++] = (unsigned int)(mgp->mtrr >= 0);
+       data[i++] = (unsigned int)mgp->wc_enabled;
        data[i++] = (unsigned int)mgp->pdev->irq;
        data[i++] = (unsigned int)mgp->msi_enabled;
        data[i++] = (unsigned int)mgp->read_dma;
@@ -1456,6 +1472,8 @@ static int myri10ge_allocate_rings(struct net_device *dev)
        status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_RING_SIZE, &cmd, 0);
        tx_ring_size = cmd.data0;
        status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0);
+       if (status != 0)
+               return status;
        rx_ring_size = cmd.data0;
 
        tx_ring_entries = tx_ring_size / sizeof(struct mcp_kreq_ether_send);
@@ -1463,6 +1481,8 @@ static int myri10ge_allocate_rings(struct net_device *dev)
        mgp->tx.mask = tx_ring_entries - 1;
        mgp->rx_small.mask = mgp->rx_big.mask = rx_ring_entries - 1;
 
+       status = -ENOMEM;
+
        /* allocate the host shadow rings */
 
        bytes = 8 + (MYRI10GE_MAX_SEND_DESC_TSO + 4)
@@ -1735,7 +1755,7 @@ static int myri10ge_open(struct net_device *dev)
                goto abort_with_irq;
        }
 
-       if (myri10ge_wcfifo && mgp->mtrr >= 0) {
+       if (myri10ge_wcfifo && mgp->wc_enabled) {
                mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4;
                mgp->rx_small.wc_fifo =
                    (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_SMALL;
@@ -1992,10 +2012,9 @@ again:
        mss = 0;
        max_segments = MXGEFW_MAX_SEND_DESC;
 
-       if (skb->len > (dev->mtu + ETH_HLEN)) {
+       if (skb_is_gso(skb)) {
                mss = skb_shinfo(skb)->gso_size;
-               if (mss != 0)
-                       max_segments = MYRI10GE_MAX_SEND_DESC_TSO;
+               max_segments = MYRI10GE_MAX_SEND_DESC_TSO;
        }
 
        if ((unlikely(avail < max_segments))) {
@@ -2468,6 +2487,12 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
 
 #define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7
 #define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa
+#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1 0x3510
+#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4 0x351b
+#define PCI_DEVICE_ID_INTEL_E3000_PCIE 0x2779
+#define PCI_DEVICE_ID_INTEL_E3010_PCIE 0x277a
+#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST 0x140
+#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST 0x142
 
 static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
 {
@@ -2499,6 +2524,24 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
                           ((bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
                             && bridge->device ==
                             PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE)
+                           /* ServerWorks HT2100 */
+                           || (bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
+                               && bridge->device >=
+                               PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST
+                               && bridge->device <=
+                               PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST)
+                           /* All Intel E3000/E3010 PCIE ports */
+                           || (bridge->vendor == PCI_VENDOR_ID_INTEL
+                               && (bridge->device ==
+                                   PCI_DEVICE_ID_INTEL_E3000_PCIE
+                                   || bridge->device ==
+                                   PCI_DEVICE_ID_INTEL_E3010_PCIE))
+                           /* All Intel 6310/6311/6321ESB PCIE ports */
+                           || (bridge->vendor == PCI_VENDOR_ID_INTEL
+                               && bridge->device >=
+                               PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1
+                               && bridge->device <=
+                               PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4)
                            /* All Intel E5000 PCIE ports */
                            || (bridge->vendor == PCI_VENDOR_ID_INTEL
                                && bridge->device >=
@@ -2510,6 +2553,12 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
                                 bridge->vendor, bridge->device);
                        mgp->tx.boundary = 4096;
                        mgp->fw_name = myri10ge_fw_aligned;
+               } else if (bridge &&
+                          bridge->vendor == PCI_VENDOR_ID_SGI &&
+                          bridge->device == 0x4002 /* TIOCE pcie-port */ ) {
+                       /* this pcie bridge does not support 4K rdma request */
+                       mgp->tx.boundary = 2048;
+                       mgp->fw_name = myri10ge_fw_aligned;
                }
        } else {
                if (myri10ge_force_firmware == 1) {
@@ -2830,9 +2879,12 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        mgp->board_span = pci_resource_len(pdev, 0);
        mgp->iomem_base = pci_resource_start(pdev, 0);
        mgp->mtrr = -1;
+       mgp->wc_enabled = 0;
 #ifdef CONFIG_MTRR
        mgp->mtrr = mtrr_add(mgp->iomem_base, mgp->board_span,
                             MTRR_TYPE_WRCOMB, 1);
+       if (mgp->mtrr >= 0)
+               mgp->wc_enabled = 1;
 #endif
        /* Hack.  need to get rid of these magic numbers */
        mgp->sram_size =
@@ -2927,7 +2979,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n",
                 (mgp->msi_enabled ? "MSI" : "xPIC"),
                 netdev->irq, mgp->tx.boundary, mgp->fw_name,
-                (mgp->mtrr >= 0 ? "Enabled" : "Disabled"));
+                (mgp->wc_enabled ? "Enabled" : "Disabled"));
 
        return 0;