diff options
Diffstat (limited to 'drivers/net/myri10ge')
-rw-r--r-- | drivers/net/myri10ge/myri10ge.c | 88 |
1 files changed, 70 insertions, 18 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index b05dc6ed7fb7..f8efe0e70a6b 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -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; |