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: Mike McCormack <mikem@ring3k.org> Acked-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
10547ae2c0
commit
90bbebb4a8
|
@ -1405,6 +1405,61 @@ nomem:
|
|||
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. */
|
||||
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;
|
||||
unsigned port = sky2->port;
|
||||
u32 imask, ramsize;
|
||||
int cap, err = -ENOMEM;
|
||||
int cap, err;
|
||||
struct net_device *otherdev = hw->dev[sky2->port^1];
|
||||
|
||||
/*
|
||||
|
@ -1431,32 +1486,12 @@ static int sky2_up(struct net_device *dev)
|
|||
|
||||
netif_carrier_off(dev);
|
||||
|
||||
/* 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 err_out;
|
||||
|
||||
sky2->tx_ring = kcalloc(sky2->tx_ring_size, sizeof(struct tx_ring_info),
|
||||
GFP_KERNEL);
|
||||
if (!sky2->tx_ring)
|
||||
err = sky2_alloc_buffers(sky2);
|
||||
if (err)
|
||||
goto err_out;
|
||||
|
||||
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);
|
||||
|
||||
/* Register is number of 4K blocks on internal RAM buffer. */
|
||||
|
@ -1513,22 +1548,7 @@ static int sky2_up(struct net_device *dev)
|
|||
return 0;
|
||||
|
||||
err_out:
|
||||
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;
|
||||
sky2_free_buffers(sky2);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1880,20 +1900,7 @@ static int sky2_down(struct net_device *dev)
|
|||
|
||||
sky2_rx_clean(sky2);
|
||||
|
||||
pci_free_consistent(hw->pdev, RX_LE_BYTES,
|
||||
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;
|
||||
sky2_free_buffers(sky2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue