Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 266194
b: refs/heads/master
c: a9e9fd7
h: refs/heads/master
v: v3
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed Sep 27, 2011
1 parent cdf4b03 commit c055c61
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 04b71175f340d4081680440e1b9cbffcd3f4a13c
refs/heads/master: a9e9fd7182332d0cf5f3e601df3e71dd431b70d7
72 changes: 52 additions & 20 deletions trunk/drivers/net/ethernet/marvell/skge.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ static void yukon_init(struct skge_hw *hw, int port);
static void genesis_mac_init(struct skge_hw *hw, int port);
static void genesis_link_up(struct skge_port *skge);
static void skge_set_multicast(struct net_device *dev);
static irqreturn_t skge_intr(int irq, void *dev_id);

/* Avoid conditionals by using array */
static const int txqaddr[] = { Q_XA1, Q_XA2 };
Expand Down Expand Up @@ -2568,6 +2569,16 @@ static int skge_up(struct net_device *dev)
if (err)
goto free_rx_ring;

if (hw->ports == 1) {
err = request_irq(hw->pdev->irq, skge_intr, IRQF_SHARED,
dev->name, hw);
if (err) {
netdev_err(dev, "Unable to allocate interrupt %d error: %d\n",
hw->pdev->irq, err);
goto free_tx_ring;
}
}

/* Initialize MAC */
spin_lock_bh(&hw->phy_lock);
if (is_genesis(hw))
Expand Down Expand Up @@ -2595,11 +2606,14 @@ static int skge_up(struct net_device *dev)
spin_lock_irq(&hw->hw_lock);
hw->intr_mask |= portmask[port];
skge_write32(hw, B0_IMSK, hw->intr_mask);
skge_read32(hw, B0_IMSK);
spin_unlock_irq(&hw->hw_lock);

napi_enable(&skge->napi);
return 0;

free_tx_ring:
kfree(skge->tx_ring.start);
free_rx_ring:
skge_rx_clean(skge);
kfree(skge->rx_ring.start);
Expand Down Expand Up @@ -2640,9 +2654,13 @@ static int skge_down(struct net_device *dev)

spin_lock_irq(&hw->hw_lock);
hw->intr_mask &= ~portmask[port];
skge_write32(hw, B0_IMSK, hw->intr_mask);
skge_write32(hw, B0_IMSK, (hw->ports == 1) ? 0 : hw->intr_mask);
skge_read32(hw, B0_IMSK);
spin_unlock_irq(&hw->hw_lock);

if (hw->ports == 1)
free_irq(hw->pdev->irq, hw);

skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
if (is_genesis(hw))
genesis_stop(skge);
Expand Down Expand Up @@ -3603,7 +3621,8 @@ static int skge_reset(struct skge_hw *hw)
skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100));
skge_write32(hw, B2_IRQM_CTRL, TIM_START);

skge_write32(hw, B0_IMSK, hw->intr_mask);
/* Leave irq disabled until first port is brought up. */
skge_write32(hw, B0_IMSK, 0);

for (i = 0; i < hw->ports; i++) {
if (is_genesis(hw))
Expand Down Expand Up @@ -3930,31 +3949,39 @@ static int __devinit skge_probe(struct pci_dev *pdev,
goto err_out_free_netdev;
}

err = request_irq(pdev->irq, skge_intr, IRQF_SHARED, hw->irq_name, hw);
if (err) {
dev_err(&pdev->dev, "%s: cannot assign irq %d\n",
dev->name, pdev->irq);
goto err_out_unregister;
}
skge_show_addr(dev);

if (hw->ports > 1) {
dev1 = skge_devinit(hw, 1, using_dac);
if (dev1 && register_netdev(dev1) == 0)
skge_show_addr(dev1);
else {
/* Failure to register second port need not be fatal */
dev_warn(&pdev->dev, "register of second port failed\n");
hw->dev[1] = NULL;
hw->ports = 1;
if (dev1)
free_netdev(dev1);
if (!dev1) {
err = -ENOMEM;
goto err_out_unregister;
}

err = register_netdev(dev1);
if (err) {
dev_err(&pdev->dev, "cannot register second net device\n");
goto err_out_free_dev1;
}

err = request_irq(pdev->irq, skge_intr, IRQF_SHARED,
hw->irq_name, hw);
if (err) {
dev_err(&pdev->dev, "cannot assign irq %d\n",
pdev->irq);
goto err_out_unregister_dev1;
}

skge_show_addr(dev1);
}
pci_set_drvdata(pdev, hw);

return 0;

err_out_unregister_dev1:
unregister_netdev(dev1);
err_out_free_dev1:
free_netdev(dev1);
err_out_unregister:
unregister_netdev(dev);
err_out_free_netdev:
Expand Down Expand Up @@ -3992,14 +4019,19 @@ static void __devexit skge_remove(struct pci_dev *pdev)

spin_lock_irq(&hw->hw_lock);
hw->intr_mask = 0;
skge_write32(hw, B0_IMSK, 0);
skge_read32(hw, B0_IMSK);

if (hw->ports > 1) {
skge_write32(hw, B0_IMSK, 0);
skge_read32(hw, B0_IMSK);
free_irq(pdev->irq, hw);
}
spin_unlock_irq(&hw->hw_lock);

skge_write16(hw, B0_LED, LED_STAT_OFF);
skge_write8(hw, B0_CTST, CS_RST_SET);

free_irq(pdev->irq, hw);
if (hw->ports > 1)
free_irq(pdev->irq, hw);
pci_release_regions(pdev);
pci_disable_device(pdev);
if (dev1)
Expand Down

0 comments on commit c055c61

Please sign in to comment.