Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+60 −53
Original line number Diff line number Diff line
@@ -1405,6 +1405,61 @@ static int sky2_rx_start(struct sky2_port *sky2)
	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;
}