aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrice Goglin <brice@myri.com>2007-05-07 17:52:22 -0400
committerJeff Garzik <jeff@garzik.org>2007-05-08 01:15:15 -0400
commit5443e9ead4f53fd7a43e6846cf10fdc0c5366a93 (patch)
treef0fd7a9599aab29c5f609fd86b7ad49e2bd6b6ac
parent0d6ac257ab556838c3c5b1437a36251c2802285e (diff)
myri10ge: replace the chipset whitelist with firmware autodetection
Remove the aligned-completion whitelist, and replace it by using the 1.4.16 firmware's auto-detection features to choose which firmware to load. The driver now loads the aligned firmware, performs a MXGEFW_CMD_UNALIGNED_TEST, and falls back to using the unaligned firmware if: - The firmware is too old (ie, MXGEFW_CMD_UNALIGNED_TEST is an unknown command). - The MXGEFW_CMD_UNALIGNED_TEST returns MXGEFW_CMD_ERROR_UNALIGNED, meaning that it has seen an unaligned completion during the DMA test. Signed-off-by: Brice Goglin <brice@myri.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/myri10ge/myri10ge.c121
1 files changed, 65 insertions, 56 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index f53b0dad65ab..5d14be7405a3 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -355,6 +355,8 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
355 return 0; 355 return 0;
356 } else if (result == MXGEFW_CMD_UNKNOWN) { 356 } else if (result == MXGEFW_CMD_UNKNOWN) {
357 return -ENOSYS; 357 return -ENOSYS;
358 } else if (result == MXGEFW_CMD_ERROR_UNALIGNED) {
359 return -E2BIG;
358 } else { 360 } else {
359 dev_err(&mgp->pdev->dev, 361 dev_err(&mgp->pdev->dev,
360 "command %d failed, result = %d\n", 362 "command %d failed, result = %d\n",
@@ -2483,8 +2485,6 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
2483 err_cap |= PCI_ERR_CAP_ECRC_GENE; 2485 err_cap |= PCI_ERR_CAP_ECRC_GENE;
2484 pci_write_config_dword(bridge, cap + PCI_ERR_CAP, err_cap); 2486 pci_write_config_dword(bridge, cap + PCI_ERR_CAP, err_cap);
2485 dev_info(dev, "Enabled ECRC on upstream bridge %s\n", pci_name(bridge)); 2487 dev_info(dev, "Enabled ECRC on upstream bridge %s\n", pci_name(bridge));
2486 mgp->tx.boundary = 4096;
2487 mgp->fw_name = myri10ge_fw_aligned;
2488} 2488}
2489 2489
2490/* 2490/*
@@ -2506,22 +2506,70 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
2506 * firmware image, and set tx.boundary to 4KB. 2506 * firmware image, and set tx.boundary to 4KB.
2507 */ 2507 */
2508 2508
2509#define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7 2509static void myri10ge_firmware_probe(struct myri10ge_priv *mgp)
2510#define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa
2511#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1 0x3510
2512#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4 0x351b
2513#define PCI_DEVICE_ID_INTEL_E3000_PCIE 0x2779
2514#define PCI_DEVICE_ID_INTEL_E3010_PCIE 0x277a
2515#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST 0x140
2516#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST 0x142
2517
2518static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
2519{ 2510{
2520 struct pci_dev *bridge = mgp->pdev->bus->self; 2511 struct pci_dev *pdev = mgp->pdev;
2512 struct device *dev = &pdev->dev;
2513 int cap, status;
2514 u16 val;
2521 2515
2516 mgp->tx.boundary = 4096;
2517 /*
2518 * Verify the max read request size was set to 4KB
2519 * before trying the test with 4KB.
2520 */
2521 cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
2522 if (cap < 64) {
2523 dev_err(dev, "Bad PCI_CAP_ID_EXP location %d\n", cap);
2524 goto abort;
2525 }
2526 status = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &val);
2527 if (status != 0) {
2528 dev_err(dev, "Couldn't read max read req size: %d\n", status);
2529 goto abort;
2530 }
2531 if ((val & (5 << 12)) != (5 << 12)) {
2532 dev_warn(dev, "Max Read Request size != 4096 (0x%x)\n", val);
2533 mgp->tx.boundary = 2048;
2534 }
2535 /*
2536 * load the optimized firmware (which assumes aligned PCIe
2537 * completions) in order to see if it works on this host.
2538 */
2539 mgp->fw_name = myri10ge_fw_aligned;
2540 status = myri10ge_load_firmware(mgp);
2541 if (status != 0) {
2542 goto abort;
2543 }
2544
2545 /*
2546 * Enable ECRC if possible
2547 */
2548 myri10ge_enable_ecrc(mgp);
2549
2550 /*
2551 * Run a DMA test which watches for unaligned completions and
2552 * aborts on the first one seen.
2553 */
2554
2555 status = myri10ge_dma_test(mgp, MXGEFW_CMD_UNALIGNED_TEST);
2556 if (status == 0)
2557 return; /* keep the aligned firmware */
2558
2559 if (status != -E2BIG)
2560 dev_warn(dev, "DMA test failed: %d\n", status);
2561 if (status == -ENOSYS)
2562 dev_warn(dev, "Falling back to ethp! "
2563 "Please install up to date fw\n");
2564abort:
2565 /* fall back to using the unaligned firmware */
2522 mgp->tx.boundary = 2048; 2566 mgp->tx.boundary = 2048;
2523 mgp->fw_name = myri10ge_fw_unaligned; 2567 mgp->fw_name = myri10ge_fw_unaligned;
2524 2568
2569}
2570
2571static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
2572{
2525 if (myri10ge_force_firmware == 0) { 2573 if (myri10ge_force_firmware == 0) {
2526 int link_width, exp_cap; 2574 int link_width, exp_cap;
2527 u16 lnk; 2575 u16 lnk;
@@ -2530,8 +2578,6 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
2530 pci_read_config_word(mgp->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk); 2578 pci_read_config_word(mgp->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk);
2531 link_width = (lnk >> 4) & 0x3f; 2579 link_width = (lnk >> 4) & 0x3f;
2532 2580
2533 myri10ge_enable_ecrc(mgp);
2534
2535 /* Check to see if Link is less than 8 or if the 2581 /* Check to see if Link is less than 8 or if the
2536 * upstream bridge is known to provide aligned 2582 * upstream bridge is known to provide aligned
2537 * completions */ 2583 * completions */
@@ -2540,46 +2586,8 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
2540 link_width); 2586 link_width);
2541 mgp->tx.boundary = 4096; 2587 mgp->tx.boundary = 4096;
2542 mgp->fw_name = myri10ge_fw_aligned; 2588 mgp->fw_name = myri10ge_fw_aligned;
2543 } else if (bridge && 2589 } else {
2544 /* ServerWorks HT2000/HT1000 */ 2590 myri10ge_firmware_probe(mgp);
2545 ((bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
2546 && bridge->device ==
2547 PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE)
2548 /* ServerWorks HT2100 */
2549 || (bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
2550 && bridge->device >=
2551 PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST
2552 && bridge->device <=
2553 PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST)
2554 /* All Intel E3000/E3010 PCIE ports */
2555 || (bridge->vendor == PCI_VENDOR_ID_INTEL
2556 && (bridge->device ==
2557 PCI_DEVICE_ID_INTEL_E3000_PCIE
2558 || bridge->device ==
2559 PCI_DEVICE_ID_INTEL_E3010_PCIE))
2560 /* All Intel 6310/6311/6321ESB PCIE ports */
2561 || (bridge->vendor == PCI_VENDOR_ID_INTEL
2562 && bridge->device >=
2563 PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1
2564 && bridge->device <=
2565 PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4)
2566 /* All Intel E5000 PCIE ports */
2567 || (bridge->vendor == PCI_VENDOR_ID_INTEL
2568 && bridge->device >=
2569 PCI_DEVICE_ID_INTEL_E5000_PCIE23
2570 && bridge->device <=
2571 PCI_DEVICE_ID_INTEL_E5000_PCIE47))) {
2572 dev_info(&mgp->pdev->dev,
2573 "Assuming aligned completions (0x%x:0x%x)\n",
2574 bridge->vendor, bridge->device);
2575 mgp->tx.boundary = 4096;
2576 mgp->fw_name = myri10ge_fw_aligned;
2577 } else if (bridge &&
2578 bridge->vendor == PCI_VENDOR_ID_SGI &&
2579 bridge->device == 0x4002 /* TIOCE pcie-port */ ) {
2580 /* this pcie bridge does not support 4K rdma request */
2581 mgp->tx.boundary = 2048;
2582 mgp->fw_name = myri10ge_fw_aligned;
2583 } 2591 }
2584 } else { 2592 } else {
2585 if (myri10ge_force_firmware == 1) { 2593 if (myri10ge_force_firmware == 1) {
@@ -2847,7 +2855,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2847 status = -ENODEV; 2855 status = -ENODEV;
2848 goto abort_with_netdev; 2856 goto abort_with_netdev;
2849 } 2857 }
2850 myri10ge_select_firmware(mgp);
2851 2858
2852 /* Find the vendor-specific cap so we can check 2859 /* Find the vendor-specific cap so we can check
2853 * the reboot register later on */ 2860 * the reboot register later on */
@@ -2941,6 +2948,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2941 goto abort_with_ioremap; 2948 goto abort_with_ioremap;
2942 memset(mgp->rx_done.entry, 0, bytes); 2949 memset(mgp->rx_done.entry, 0, bytes);
2943 2950
2951 myri10ge_select_firmware(mgp);
2952
2944 status = myri10ge_load_firmware(mgp); 2953 status = myri10ge_load_firmware(mgp);
2945 if (status != 0) { 2954 if (status != 0) {
2946 dev_err(&pdev->dev, "failed to load firmware\n"); 2955 dev_err(&pdev->dev, "failed to load firmware\n");