diff options
author | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-29 13:03:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-29 13:03:54 -0500 |
commit | 6c722e90d7ede7db2d2b28a3cc69a8545db67ea1 (patch) | |
tree | 2473530190795c11f841db37b7d74df9bcc0416b /drivers/net/myri10ge/myri10ge.c | |
parent | 007fb598b4674de82492a9961e82826875012229 (diff) | |
parent | 81f4e6c190a0fa016fd7eecaf76a5f95d121afc2 (diff) |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (42 commits)
r8169: extraneous Cmd{Tx/Rx}Enb write
forcedeth: modified comment header
NetXen: Reducing ring sizes for IOMMU issue.
NetXen: Fix for PPC machines.
NetXen: work queue fixes.
NetXen: Link status message correction for quad port cards.
NetXen: Multiple adapter fix.
NetXen: Using correct CHECKSUM flag.
NetXen: driver reload fix for newer firmware.
NetXen: Adding new device ids.
PHY probe not working properly for ibm_emac (PPC4xx)
ep93xx: some minor cleanups to the ep93xx eth driver
sky2: phy power down needs PCI config write enabled
sky2: power management/MSI workaround
sky2: dual port NAPI problem
via-velocity uses INET interfaces
e1000: Do not truncate TSO TCP header with 82544 workaround
myri10ge: handle failures in suspend and resume
myri10ge: no need to save MSI and PCIe state in the driver
myri10ge: make msi configurable at runtime through sysfs
...
Diffstat (limited to 'drivers/net/myri10ge/myri10ge.c')
-rw-r--r-- | drivers/net/myri10ge/myri10ge.c | 163 |
1 files changed, 77 insertions, 86 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 94ac168be593..07cf574197e5 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -199,8 +199,6 @@ struct myri10ge_priv { | |||
199 | unsigned long serial_number; | 199 | unsigned long serial_number; |
200 | int vendor_specific_offset; | 200 | int vendor_specific_offset; |
201 | int fw_multicast_support; | 201 | int fw_multicast_support; |
202 | u32 devctl; | ||
203 | u16 msi_flags; | ||
204 | u32 read_dma; | 202 | u32 read_dma; |
205 | u32 write_dma; | 203 | u32 write_dma; |
206 | u32 read_write_dma; | 204 | u32 read_write_dma; |
@@ -228,7 +226,7 @@ module_param(myri10ge_small_bytes, int, S_IRUGO | S_IWUSR); | |||
228 | MODULE_PARM_DESC(myri10ge_small_bytes, "Threshold of small packets\n"); | 226 | MODULE_PARM_DESC(myri10ge_small_bytes, "Threshold of small packets\n"); |
229 | 227 | ||
230 | static int myri10ge_msi = 1; /* enable msi by default */ | 228 | static int myri10ge_msi = 1; /* enable msi by default */ |
231 | module_param(myri10ge_msi, int, S_IRUGO); | 229 | module_param(myri10ge_msi, int, S_IRUGO | S_IWUSR); |
232 | MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n"); | 230 | MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n"); |
233 | 231 | ||
234 | static int myri10ge_intr_coal_delay = 25; | 232 | static int myri10ge_intr_coal_delay = 25; |
@@ -721,12 +719,10 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) | |||
721 | status |= | 719 | status |= |
722 | myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0); | 720 | myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0); |
723 | mgp->irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0); | 721 | mgp->irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0); |
724 | if (!mgp->msi_enabled) { | 722 | status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, |
725 | status |= myri10ge_send_cmd | 723 | &cmd, 0); |
726 | (mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET, &cmd, 0); | 724 | mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0); |
727 | mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0); | ||
728 | 725 | ||
729 | } | ||
730 | status |= myri10ge_send_cmd | 726 | status |= myri10ge_send_cmd |
731 | (mgp, MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, &cmd, 0); | 727 | (mgp, MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, &cmd, 0); |
732 | mgp->intr_coal_delay_ptr = (__iomem __be32 *) (mgp->sram + cmd.data0); | 728 | mgp->intr_coal_delay_ptr = (__iomem __be32 *) (mgp->sram + cmd.data0); |
@@ -1619,6 +1615,41 @@ static void myri10ge_free_rings(struct net_device *dev) | |||
1619 | mgp->tx.req_list = NULL; | 1615 | mgp->tx.req_list = NULL; |
1620 | } | 1616 | } |
1621 | 1617 | ||
1618 | static int myri10ge_request_irq(struct myri10ge_priv *mgp) | ||
1619 | { | ||
1620 | struct pci_dev *pdev = mgp->pdev; | ||
1621 | int status; | ||
1622 | |||
1623 | if (myri10ge_msi) { | ||
1624 | status = pci_enable_msi(pdev); | ||
1625 | if (status != 0) | ||
1626 | dev_err(&pdev->dev, | ||
1627 | "Error %d setting up MSI; falling back to xPIC\n", | ||
1628 | status); | ||
1629 | else | ||
1630 | mgp->msi_enabled = 1; | ||
1631 | } else { | ||
1632 | mgp->msi_enabled = 0; | ||
1633 | } | ||
1634 | status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED, | ||
1635 | mgp->dev->name, mgp); | ||
1636 | if (status != 0) { | ||
1637 | dev_err(&pdev->dev, "failed to allocate IRQ\n"); | ||
1638 | if (mgp->msi_enabled) | ||
1639 | pci_disable_msi(pdev); | ||
1640 | } | ||
1641 | return status; | ||
1642 | } | ||
1643 | |||
1644 | static void myri10ge_free_irq(struct myri10ge_priv *mgp) | ||
1645 | { | ||
1646 | struct pci_dev *pdev = mgp->pdev; | ||
1647 | |||
1648 | free_irq(pdev->irq, mgp); | ||
1649 | if (mgp->msi_enabled) | ||
1650 | pci_disable_msi(pdev); | ||
1651 | } | ||
1652 | |||
1622 | static int myri10ge_open(struct net_device *dev) | 1653 | static int myri10ge_open(struct net_device *dev) |
1623 | { | 1654 | { |
1624 | struct myri10ge_priv *mgp; | 1655 | struct myri10ge_priv *mgp; |
@@ -1634,10 +1665,13 @@ static int myri10ge_open(struct net_device *dev) | |||
1634 | status = myri10ge_reset(mgp); | 1665 | status = myri10ge_reset(mgp); |
1635 | if (status != 0) { | 1666 | if (status != 0) { |
1636 | printk(KERN_ERR "myri10ge: %s: failed reset\n", dev->name); | 1667 | printk(KERN_ERR "myri10ge: %s: failed reset\n", dev->name); |
1637 | mgp->running = MYRI10GE_ETH_STOPPED; | 1668 | goto abort_with_nothing; |
1638 | return -ENXIO; | ||
1639 | } | 1669 | } |
1640 | 1670 | ||
1671 | status = myri10ge_request_irq(mgp); | ||
1672 | if (status != 0) | ||
1673 | goto abort_with_nothing; | ||
1674 | |||
1641 | /* decide what small buffer size to use. For good TCP rx | 1675 | /* decide what small buffer size to use. For good TCP rx |
1642 | * performance, it is important to not receive 1514 byte | 1676 | * performance, it is important to not receive 1514 byte |
1643 | * frames into jumbo buffers, as it confuses the socket buffer | 1677 | * frames into jumbo buffers, as it confuses the socket buffer |
@@ -1677,7 +1711,7 @@ static int myri10ge_open(struct net_device *dev) | |||
1677 | "myri10ge: %s: failed to get ring sizes or locations\n", | 1711 | "myri10ge: %s: failed to get ring sizes or locations\n", |
1678 | dev->name); | 1712 | dev->name); |
1679 | mgp->running = MYRI10GE_ETH_STOPPED; | 1713 | mgp->running = MYRI10GE_ETH_STOPPED; |
1680 | return -ENXIO; | 1714 | goto abort_with_irq; |
1681 | } | 1715 | } |
1682 | 1716 | ||
1683 | if (mgp->mtrr >= 0) { | 1717 | if (mgp->mtrr >= 0) { |
@@ -1708,7 +1742,7 @@ static int myri10ge_open(struct net_device *dev) | |||
1708 | 1742 | ||
1709 | status = myri10ge_allocate_rings(dev); | 1743 | status = myri10ge_allocate_rings(dev); |
1710 | if (status != 0) | 1744 | if (status != 0) |
1711 | goto abort_with_nothing; | 1745 | goto abort_with_irq; |
1712 | 1746 | ||
1713 | /* now give firmware buffers sizes, and MTU */ | 1747 | /* now give firmware buffers sizes, and MTU */ |
1714 | cmd.data0 = dev->mtu + ETH_HLEN + VLAN_HLEN; | 1748 | cmd.data0 = dev->mtu + ETH_HLEN + VLAN_HLEN; |
@@ -1771,6 +1805,9 @@ static int myri10ge_open(struct net_device *dev) | |||
1771 | abort_with_rings: | 1805 | abort_with_rings: |
1772 | myri10ge_free_rings(dev); | 1806 | myri10ge_free_rings(dev); |
1773 | 1807 | ||
1808 | abort_with_irq: | ||
1809 | myri10ge_free_irq(mgp); | ||
1810 | |||
1774 | abort_with_nothing: | 1811 | abort_with_nothing: |
1775 | mgp->running = MYRI10GE_ETH_STOPPED; | 1812 | mgp->running = MYRI10GE_ETH_STOPPED; |
1776 | return -ENOMEM; | 1813 | return -ENOMEM; |
@@ -1807,7 +1844,7 @@ static int myri10ge_close(struct net_device *dev) | |||
1807 | printk(KERN_ERR "myri10ge: %s never got down irq\n", dev->name); | 1844 | printk(KERN_ERR "myri10ge: %s never got down irq\n", dev->name); |
1808 | 1845 | ||
1809 | netif_tx_disable(dev); | 1846 | netif_tx_disable(dev); |
1810 | 1847 | myri10ge_free_irq(mgp); | |
1811 | myri10ge_free_rings(dev); | 1848 | myri10ge_free_rings(dev); |
1812 | 1849 | ||
1813 | mgp->running = MYRI10GE_ETH_STOPPED; | 1850 | mgp->running = MYRI10GE_ETH_STOPPED; |
@@ -2481,34 +2518,6 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) | |||
2481 | } | 2518 | } |
2482 | } | 2519 | } |
2483 | 2520 | ||
2484 | static void myri10ge_save_state(struct myri10ge_priv *mgp) | ||
2485 | { | ||
2486 | struct pci_dev *pdev = mgp->pdev; | ||
2487 | int cap; | ||
2488 | |||
2489 | pci_save_state(pdev); | ||
2490 | /* now save PCIe and MSI state that Linux will not | ||
2491 | * save for us */ | ||
2492 | cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); | ||
2493 | pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL, &mgp->devctl); | ||
2494 | cap = pci_find_capability(pdev, PCI_CAP_ID_MSI); | ||
2495 | pci_read_config_word(pdev, cap + PCI_MSI_FLAGS, &mgp->msi_flags); | ||
2496 | } | ||
2497 | |||
2498 | static void myri10ge_restore_state(struct myri10ge_priv *mgp) | ||
2499 | { | ||
2500 | struct pci_dev *pdev = mgp->pdev; | ||
2501 | int cap; | ||
2502 | |||
2503 | /* restore PCIe and MSI state that linux will not */ | ||
2504 | cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); | ||
2505 | pci_write_config_dword(pdev, cap + PCI_CAP_ID_EXP, mgp->devctl); | ||
2506 | cap = pci_find_capability(pdev, PCI_CAP_ID_MSI); | ||
2507 | pci_write_config_word(pdev, cap + PCI_MSI_FLAGS, mgp->msi_flags); | ||
2508 | |||
2509 | pci_restore_state(pdev); | ||
2510 | } | ||
2511 | |||
2512 | #ifdef CONFIG_PM | 2521 | #ifdef CONFIG_PM |
2513 | 2522 | ||
2514 | static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state) | 2523 | static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state) |
@@ -2529,11 +2538,10 @@ static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2529 | rtnl_unlock(); | 2538 | rtnl_unlock(); |
2530 | } | 2539 | } |
2531 | myri10ge_dummy_rdma(mgp, 0); | 2540 | myri10ge_dummy_rdma(mgp, 0); |
2532 | free_irq(pdev->irq, mgp); | 2541 | pci_save_state(pdev); |
2533 | myri10ge_save_state(mgp); | ||
2534 | pci_disable_device(pdev); | 2542 | pci_disable_device(pdev); |
2535 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 2543 | |
2536 | return 0; | 2544 | return pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
2537 | } | 2545 | } |
2538 | 2546 | ||
2539 | static int myri10ge_resume(struct pci_dev *pdev) | 2547 | static int myri10ge_resume(struct pci_dev *pdev) |
@@ -2555,34 +2563,33 @@ static int myri10ge_resume(struct pci_dev *pdev) | |||
2555 | mgp->dev->name); | 2563 | mgp->dev->name); |
2556 | return -EIO; | 2564 | return -EIO; |
2557 | } | 2565 | } |
2558 | myri10ge_restore_state(mgp); | 2566 | |
2567 | status = pci_restore_state(pdev); | ||
2568 | if (status) | ||
2569 | return status; | ||
2559 | 2570 | ||
2560 | status = pci_enable_device(pdev); | 2571 | status = pci_enable_device(pdev); |
2561 | if (status < 0) { | 2572 | if (status) { |
2562 | dev_err(&pdev->dev, "failed to enable device\n"); | 2573 | dev_err(&pdev->dev, "failed to enable device\n"); |
2563 | return -EIO; | 2574 | return status; |
2564 | } | 2575 | } |
2565 | 2576 | ||
2566 | pci_set_master(pdev); | 2577 | pci_set_master(pdev); |
2567 | 2578 | ||
2568 | status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED, | ||
2569 | netdev->name, mgp); | ||
2570 | if (status != 0) { | ||
2571 | dev_err(&pdev->dev, "failed to allocate IRQ\n"); | ||
2572 | goto abort_with_enabled; | ||
2573 | } | ||
2574 | |||
2575 | myri10ge_reset(mgp); | 2579 | myri10ge_reset(mgp); |
2576 | myri10ge_dummy_rdma(mgp, 1); | 2580 | myri10ge_dummy_rdma(mgp, 1); |
2577 | 2581 | ||
2578 | /* Save configuration space to be restored if the | 2582 | /* Save configuration space to be restored if the |
2579 | * nic resets due to a parity error */ | 2583 | * nic resets due to a parity error */ |
2580 | myri10ge_save_state(mgp); | 2584 | pci_save_state(pdev); |
2581 | 2585 | ||
2582 | if (netif_running(netdev)) { | 2586 | if (netif_running(netdev)) { |
2583 | rtnl_lock(); | 2587 | rtnl_lock(); |
2584 | myri10ge_open(netdev); | 2588 | status = myri10ge_open(netdev); |
2585 | rtnl_unlock(); | 2589 | rtnl_unlock(); |
2590 | if (status != 0) | ||
2591 | goto abort_with_enabled; | ||
2592 | |||
2586 | } | 2593 | } |
2587 | netif_device_attach(netdev); | 2594 | netif_device_attach(netdev); |
2588 | 2595 | ||
@@ -2640,7 +2647,11 @@ static void myri10ge_watchdog(struct work_struct *work) | |||
2640 | * when the driver was loaded, or the last time the | 2647 | * when the driver was loaded, or the last time the |
2641 | * nic was resumed from power saving mode. | 2648 | * nic was resumed from power saving mode. |
2642 | */ | 2649 | */ |
2643 | myri10ge_restore_state(mgp); | 2650 | pci_restore_state(mgp->pdev); |
2651 | |||
2652 | /* save state again for accounting reasons */ | ||
2653 | pci_save_state(mgp->pdev); | ||
2654 | |||
2644 | } else { | 2655 | } else { |
2645 | /* if we get back -1's from our slot, perhaps somebody | 2656 | /* if we get back -1's from our slot, perhaps somebody |
2646 | * powered off our card. Don't try to reset it in | 2657 | * powered off our card. Don't try to reset it in |
@@ -2856,23 +2867,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2856 | goto abort_with_firmware; | 2867 | goto abort_with_firmware; |
2857 | } | 2868 | } |
2858 | 2869 | ||
2859 | if (myri10ge_msi) { | ||
2860 | status = pci_enable_msi(pdev); | ||
2861 | if (status != 0) | ||
2862 | dev_err(&pdev->dev, | ||
2863 | "Error %d setting up MSI; falling back to xPIC\n", | ||
2864 | status); | ||
2865 | else | ||
2866 | mgp->msi_enabled = 1; | ||
2867 | } | ||
2868 | |||
2869 | status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED, | ||
2870 | netdev->name, mgp); | ||
2871 | if (status != 0) { | ||
2872 | dev_err(&pdev->dev, "failed to allocate IRQ\n"); | ||
2873 | goto abort_with_firmware; | ||
2874 | } | ||
2875 | |||
2876 | pci_set_drvdata(pdev, mgp); | 2870 | pci_set_drvdata(pdev, mgp); |
2877 | if ((myri10ge_initial_mtu + ETH_HLEN) > MYRI10GE_MAX_ETHER_MTU) | 2871 | if ((myri10ge_initial_mtu + ETH_HLEN) > MYRI10GE_MAX_ETHER_MTU) |
2878 | myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN; | 2872 | myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN; |
@@ -2896,7 +2890,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2896 | 2890 | ||
2897 | /* Save configuration space to be restored if the | 2891 | /* Save configuration space to be restored if the |
2898 | * nic resets due to a parity error */ | 2892 | * nic resets due to a parity error */ |
2899 | myri10ge_save_state(mgp); | 2893 | pci_save_state(pdev); |
2900 | 2894 | ||
2901 | /* Setup the watchdog timer */ | 2895 | /* Setup the watchdog timer */ |
2902 | setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer, | 2896 | setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer, |
@@ -2907,19 +2901,16 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2907 | status = register_netdev(netdev); | 2901 | status = register_netdev(netdev); |
2908 | if (status != 0) { | 2902 | if (status != 0) { |
2909 | dev_err(&pdev->dev, "register_netdev failed: %d\n", status); | 2903 | dev_err(&pdev->dev, "register_netdev failed: %d\n", status); |
2910 | goto abort_with_irq; | 2904 | goto abort_with_state; |
2911 | } | 2905 | } |
2912 | dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n", | 2906 | dev_info(dev, "%d, tx bndry %d, fw %s, WC %s\n", |
2913 | (mgp->msi_enabled ? "MSI" : "xPIC"), | ||
2914 | pdev->irq, mgp->tx.boundary, mgp->fw_name, | 2907 | pdev->irq, mgp->tx.boundary, mgp->fw_name, |
2915 | (mgp->mtrr >= 0 ? "Enabled" : "Disabled")); | 2908 | (mgp->mtrr >= 0 ? "Enabled" : "Disabled")); |
2916 | 2909 | ||
2917 | return 0; | 2910 | return 0; |
2918 | 2911 | ||
2919 | abort_with_irq: | 2912 | abort_with_state: |
2920 | free_irq(pdev->irq, mgp); | 2913 | pci_restore_state(pdev); |
2921 | if (mgp->msi_enabled) | ||
2922 | pci_disable_msi(pdev); | ||
2923 | 2914 | ||
2924 | abort_with_firmware: | 2915 | abort_with_firmware: |
2925 | myri10ge_dummy_rdma(mgp, 0); | 2916 | myri10ge_dummy_rdma(mgp, 0); |
@@ -2970,12 +2961,12 @@ static void myri10ge_remove(struct pci_dev *pdev) | |||
2970 | flush_scheduled_work(); | 2961 | flush_scheduled_work(); |
2971 | netdev = mgp->dev; | 2962 | netdev = mgp->dev; |
2972 | unregister_netdev(netdev); | 2963 | unregister_netdev(netdev); |
2973 | free_irq(pdev->irq, mgp); | ||
2974 | if (mgp->msi_enabled) | ||
2975 | pci_disable_msi(pdev); | ||
2976 | 2964 | ||
2977 | myri10ge_dummy_rdma(mgp, 0); | 2965 | myri10ge_dummy_rdma(mgp, 0); |
2978 | 2966 | ||
2967 | /* avoid a memory leak */ | ||
2968 | pci_restore_state(pdev); | ||
2969 | |||
2979 | bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); | 2970 | bytes = myri10ge_max_intr_slots * sizeof(*mgp->rx_done.entry); |
2980 | dma_free_coherent(&pdev->dev, bytes, | 2971 | dma_free_coherent(&pdev->dev, bytes, |
2981 | mgp->rx_done.entry, mgp->rx_done.bus); | 2972 | mgp->rx_done.entry, mgp->rx_done.bus); |