Commit 90bbebb4 authored by Mike McCormack's avatar Mike McCormack Committed by David S. Miller

sky2: Create buffer alloc and free helpers

Refactor similar two sections of code that free buffers into one.
Only call tx_init if all buffer allocations succeed.
Signed-off-by: default avatarMike McCormack <mikem@ring3k.org>
Acked-by: default avatarStephen Hemminger <shemminger@vyatta.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 10547ae2
...@@ -1405,6 +1405,61 @@ nomem: ...@@ -1405,6 +1405,61 @@ nomem:
return -ENOMEM; return -ENOMEM;
} }
static int sky2_alloc_buffers(struct sky2_port *sky2)
{
struct sky2_hw *hw = sky2->hw;
/* must be power of 2 */
sky2->tx_le = pci_alloc_consistent(hw->pdev,
sky2->tx_ring_size *
sizeof(struct sky2_tx_le),
&sky2->tx_le_map);
if (!sky2->tx_le)
goto nomem;
sky2->tx_ring = kcalloc(sky2->tx_ring_size, sizeof(struct tx_ring_info),
GFP_KERNEL);
if (!sky2->tx_ring)
goto nomem;
sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
&sky2->rx_le_map);
if (!sky2->rx_le)
goto nomem;
memset(sky2->rx_le, 0, RX_LE_BYTES);
sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info),
GFP_KERNEL);
if (!sky2->rx_ring)
goto nomem;
return 0;
nomem:
return -ENOMEM;
}
static void sky2_free_buffers(struct sky2_port *sky2)
{
struct sky2_hw *hw = sky2->hw;
if (sky2->rx_le) {
pci_free_consistent(hw->pdev, RX_LE_BYTES,
sky2->rx_le, sky2->rx_le_map);
sky2->rx_le = NULL;
}
if (sky2->tx_le) {
pci_free_consistent(hw->pdev,
sky2->tx_ring_size * sizeof(struct sky2_tx_le),
sky2->tx_le, sky2->tx_le_map);
sky2->tx_le = NULL;
}
kfree(sky2->tx_ring);
kfree(sky2->rx_ring);
sky2->tx_ring = NULL;
sky2->rx_ring = NULL;
}
/* Bring up network interface. */ /* Bring up network interface. */
static int sky2_up(struct net_device *dev) static int sky2_up(struct net_device *dev)
{ {
...@@ -1412,7 +1467,7 @@ static int sky2_up(struct net_device *dev) ...@@ -1412,7 +1467,7 @@ static int sky2_up(struct net_device *dev)
struct sky2_hw *hw = sky2->hw; struct sky2_hw *hw = sky2->hw;
unsigned port = sky2->port; unsigned port = sky2->port;
u32 imask, ramsize; u32 imask, ramsize;
int cap, err = -ENOMEM; int cap, err;
struct net_device *otherdev = hw->dev[sky2->port^1]; struct net_device *otherdev = hw->dev[sky2->port^1];
/* /*
...@@ -1431,32 +1486,12 @@ static int sky2_up(struct net_device *dev) ...@@ -1431,32 +1486,12 @@ static int sky2_up(struct net_device *dev)
netif_carrier_off(dev); netif_carrier_off(dev);
/* must be power of 2 */ err = sky2_alloc_buffers(sky2);
sky2->tx_le = pci_alloc_consistent(hw->pdev, if (err)
sky2->tx_ring_size *
sizeof(struct sky2_tx_le),
&sky2->tx_le_map);
if (!sky2->tx_le)
goto err_out;
sky2->tx_ring = kcalloc(sky2->tx_ring_size, sizeof(struct tx_ring_info),
GFP_KERNEL);
if (!sky2->tx_ring)
goto err_out; goto err_out;
tx_init(sky2); tx_init(sky2);
sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
&sky2->rx_le_map);
if (!sky2->rx_le)
goto err_out;
memset(sky2->rx_le, 0, RX_LE_BYTES);
sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info),
GFP_KERNEL);
if (!sky2->rx_ring)
goto err_out;
sky2_mac_init(hw, port); sky2_mac_init(hw, port);
/* Register is number of 4K blocks on internal RAM buffer. */ /* Register is number of 4K blocks on internal RAM buffer. */
...@@ -1513,22 +1548,7 @@ static int sky2_up(struct net_device *dev) ...@@ -1513,22 +1548,7 @@ static int sky2_up(struct net_device *dev)
return 0; return 0;
err_out: err_out:
if (sky2->rx_le) { sky2_free_buffers(sky2);
pci_free_consistent(hw->pdev, RX_LE_BYTES,
sky2->rx_le, sky2->rx_le_map);
sky2->rx_le = NULL;
}
if (sky2->tx_le) {
pci_free_consistent(hw->pdev,
sky2->tx_ring_size * sizeof(struct sky2_tx_le),
sky2->tx_le, sky2->tx_le_map);
sky2->tx_le = NULL;
}
kfree(sky2->tx_ring);
kfree(sky2->rx_ring);
sky2->tx_ring = NULL;
sky2->rx_ring = NULL;
return err; return err;
} }
...@@ -1880,20 +1900,7 @@ static int sky2_down(struct net_device *dev) ...@@ -1880,20 +1900,7 @@ static int sky2_down(struct net_device *dev)
sky2_rx_clean(sky2); sky2_rx_clean(sky2);
pci_free_consistent(hw->pdev, RX_LE_BYTES, sky2_free_buffers(sky2);
sky2->rx_le, sky2->rx_le_map);
kfree(sky2->rx_ring);
pci_free_consistent(hw->pdev,
sky2->tx_ring_size * sizeof(struct sky2_tx_le),
sky2->tx_le, sky2->tx_le_map);
kfree(sky2->tx_ring);
sky2->tx_le = NULL;
sky2->rx_le = NULL;
sky2->rx_ring = NULL;
sky2->tx_ring = NULL;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment