aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/marvell/skge.c72
1 files changed, 52 insertions, 20 deletions
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c
index 88e5856e06db..a0a647154245 100644
--- a/drivers/net/ethernet/marvell/skge.c
+++ b/drivers/net/ethernet/marvell/skge.c
@@ -113,6 +113,7 @@ static void yukon_init(struct skge_hw *hw, int port);
113static void genesis_mac_init(struct skge_hw *hw, int port); 113static void genesis_mac_init(struct skge_hw *hw, int port);
114static void genesis_link_up(struct skge_port *skge); 114static void genesis_link_up(struct skge_port *skge);
115static void skge_set_multicast(struct net_device *dev); 115static void skge_set_multicast(struct net_device *dev);
116static irqreturn_t skge_intr(int irq, void *dev_id);
116 117
117/* Avoid conditionals by using array */ 118/* Avoid conditionals by using array */
118static const int txqaddr[] = { Q_XA1, Q_XA2 }; 119static const int txqaddr[] = { Q_XA1, Q_XA2 };
@@ -2568,6 +2569,16 @@ static int skge_up(struct net_device *dev)
2568 if (err) 2569 if (err)
2569 goto free_rx_ring; 2570 goto free_rx_ring;
2570 2571
2572 if (hw->ports == 1) {
2573 err = request_irq(hw->pdev->irq, skge_intr, IRQF_SHARED,
2574 dev->name, hw);
2575 if (err) {
2576 netdev_err(dev, "Unable to allocate interrupt %d error: %d\n",
2577 hw->pdev->irq, err);
2578 goto free_tx_ring;
2579 }
2580 }
2581
2571 /* Initialize MAC */ 2582 /* Initialize MAC */
2572 spin_lock_bh(&hw->phy_lock); 2583 spin_lock_bh(&hw->phy_lock);
2573 if (is_genesis(hw)) 2584 if (is_genesis(hw))
@@ -2595,11 +2606,14 @@ static int skge_up(struct net_device *dev)
2595 spin_lock_irq(&hw->hw_lock); 2606 spin_lock_irq(&hw->hw_lock);
2596 hw->intr_mask |= portmask[port]; 2607 hw->intr_mask |= portmask[port];
2597 skge_write32(hw, B0_IMSK, hw->intr_mask); 2608 skge_write32(hw, B0_IMSK, hw->intr_mask);
2609 skge_read32(hw, B0_IMSK);
2598 spin_unlock_irq(&hw->hw_lock); 2610 spin_unlock_irq(&hw->hw_lock);
2599 2611
2600 napi_enable(&skge->napi); 2612 napi_enable(&skge->napi);
2601 return 0; 2613 return 0;
2602 2614
2615 free_tx_ring:
2616 kfree(skge->tx_ring.start);
2603 free_rx_ring: 2617 free_rx_ring:
2604 skge_rx_clean(skge); 2618 skge_rx_clean(skge);
2605 kfree(skge->rx_ring.start); 2619 kfree(skge->rx_ring.start);
@@ -2640,9 +2654,13 @@ static int skge_down(struct net_device *dev)
2640 2654
2641 spin_lock_irq(&hw->hw_lock); 2655 spin_lock_irq(&hw->hw_lock);
2642 hw->intr_mask &= ~portmask[port]; 2656 hw->intr_mask &= ~portmask[port];
2643 skge_write32(hw, B0_IMSK, hw->intr_mask); 2657 skge_write32(hw, B0_IMSK, (hw->ports == 1) ? 0 : hw->intr_mask);
2658 skge_read32(hw, B0_IMSK);
2644 spin_unlock_irq(&hw->hw_lock); 2659 spin_unlock_irq(&hw->hw_lock);
2645 2660
2661 if (hw->ports == 1)
2662 free_irq(hw->pdev->irq, hw);
2663
2646 skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF); 2664 skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
2647 if (is_genesis(hw)) 2665 if (is_genesis(hw))
2648 genesis_stop(skge); 2666 genesis_stop(skge);
@@ -3603,7 +3621,8 @@ static int skge_reset(struct skge_hw *hw)
3603 skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100)); 3621 skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100));
3604 skge_write32(hw, B2_IRQM_CTRL, TIM_START); 3622 skge_write32(hw, B2_IRQM_CTRL, TIM_START);
3605 3623
3606 skge_write32(hw, B0_IMSK, hw->intr_mask); 3624 /* Leave irq disabled until first port is brought up. */
3625 skge_write32(hw, B0_IMSK, 0);
3607 3626
3608 for (i = 0; i < hw->ports; i++) { 3627 for (i = 0; i < hw->ports; i++) {
3609 if (is_genesis(hw)) 3628 if (is_genesis(hw))
@@ -3930,31 +3949,39 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3930 goto err_out_free_netdev; 3949 goto err_out_free_netdev;
3931 } 3950 }
3932 3951
3933 err = request_irq(pdev->irq, skge_intr, IRQF_SHARED, hw->irq_name, hw);
3934 if (err) {
3935 dev_err(&pdev->dev, "%s: cannot assign irq %d\n",
3936 dev->name, pdev->irq);
3937 goto err_out_unregister;
3938 }
3939 skge_show_addr(dev); 3952 skge_show_addr(dev);
3940 3953
3941 if (hw->ports > 1) { 3954 if (hw->ports > 1) {
3942 dev1 = skge_devinit(hw, 1, using_dac); 3955 dev1 = skge_devinit(hw, 1, using_dac);
3943 if (dev1 && register_netdev(dev1) == 0) 3956 if (!dev1) {
3944 skge_show_addr(dev1); 3957 err = -ENOMEM;
3945 else { 3958 goto err_out_unregister;
3946 /* Failure to register second port need not be fatal */
3947 dev_warn(&pdev->dev, "register of second port failed\n");
3948 hw->dev[1] = NULL;
3949 hw->ports = 1;
3950 if (dev1)
3951 free_netdev(dev1);
3952 } 3959 }
3960
3961 err = register_netdev(dev1);
3962 if (err) {
3963 dev_err(&pdev->dev, "cannot register second net device\n");
3964 goto err_out_free_dev1;
3965 }
3966
3967 err = request_irq(pdev->irq, skge_intr, IRQF_SHARED,
3968 hw->irq_name, hw);
3969 if (err) {
3970 dev_err(&pdev->dev, "cannot assign irq %d\n",
3971 pdev->irq);
3972 goto err_out_unregister_dev1;
3973 }
3974
3975 skge_show_addr(dev1);
3953 } 3976 }
3954 pci_set_drvdata(pdev, hw); 3977 pci_set_drvdata(pdev, hw);
3955 3978
3956 return 0; 3979 return 0;
3957 3980
3981err_out_unregister_dev1:
3982 unregister_netdev(dev1);
3983err_out_free_dev1:
3984 free_netdev(dev1);
3958err_out_unregister: 3985err_out_unregister:
3959 unregister_netdev(dev); 3986 unregister_netdev(dev);
3960err_out_free_netdev: 3987err_out_free_netdev:
@@ -3992,14 +4019,19 @@ static void __devexit skge_remove(struct pci_dev *pdev)
3992 4019
3993 spin_lock_irq(&hw->hw_lock); 4020 spin_lock_irq(&hw->hw_lock);
3994 hw->intr_mask = 0; 4021 hw->intr_mask = 0;
3995 skge_write32(hw, B0_IMSK, 0); 4022
3996 skge_read32(hw, B0_IMSK); 4023 if (hw->ports > 1) {
4024 skge_write32(hw, B0_IMSK, 0);
4025 skge_read32(hw, B0_IMSK);
4026 free_irq(pdev->irq, hw);
4027 }
3997 spin_unlock_irq(&hw->hw_lock); 4028 spin_unlock_irq(&hw->hw_lock);
3998 4029
3999 skge_write16(hw, B0_LED, LED_STAT_OFF); 4030 skge_write16(hw, B0_LED, LED_STAT_OFF);
4000 skge_write8(hw, B0_CTST, CS_RST_SET); 4031 skge_write8(hw, B0_CTST, CS_RST_SET);
4001 4032
4002 free_irq(pdev->irq, hw); 4033 if (hw->ports > 1)
4034 free_irq(pdev->irq, hw);
4003 pci_release_regions(pdev); 4035 pci_release_regions(pdev);
4004 pci_disable_device(pdev); 4036 pci_disable_device(pdev);
4005 if (dev1) 4037 if (dev1)