Skip to content

Commit

Permalink
ramips: raeth: separate ring allocation and setup
Browse files Browse the repository at this point in the history
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@30573 3c298f89-4303-0410-b956-a3cf2f4a3e73
  • Loading branch information
juhosg committed Feb 16, 2012
1 parent 5279a11 commit 013dc5a
Showing 1 changed file with 90 additions and 44 deletions.
134 changes: 90 additions & 44 deletions target/linux/ramips/files/drivers/net/ramips.c
Expand Up @@ -102,6 +102,64 @@ ramips_alloc_skb(struct raeth_priv *re)
return skb;
}

static void
ramips_ring_setup(struct raeth_priv *re)
{
int len;
int i;

len = NUM_TX_DESC * sizeof(struct ramips_tx_dma);
memset(re->tx, 0, len);

for (i = 0; i < NUM_TX_DESC; i++) {
struct ramips_tx_dma *txd;

txd = &re->tx[i];
txd->txd4 = TX_DMA_QN(3) | TX_DMA_PN(1);
txd->txd2 = TX_DMA_LSO | TX_DMA_DONE;

if (re->tx_skb[i] != NULL) {
netdev_warn(re->netdev,
"dirty skb for TX desc %d\n", i);
re->tx_skb[i] = NULL;
}
}

len = NUM_RX_DESC * sizeof(struct ramips_rx_dma);
memset(re->rx, 0, len);

for (i = 0; i < NUM_RX_DESC; i++) {
dma_addr_t dma_addr;

BUG_ON(re->rx_skb[i] == NULL);
dma_addr = dma_map_single(&re->netdev->dev, re->rx_skb[i]->data,
MAX_RX_LENGTH, DMA_FROM_DEVICE);
re->rx_dma[i] = dma_addr;
re->rx[i].rxd1 = (unsigned int) dma_addr;
re->rx[i].rxd2 = RX_DMA_LSO;
}

/* flush descriptors */
wmb();
}

static void
ramips_ring_cleanup(struct raeth_priv *re)
{
int i;

for (i = 0; i < NUM_RX_DESC; i++)
if (re->rx_skb[i])
dma_unmap_single(&re->netdev->dev, re->rx_dma[i],
MAX_RX_LENGTH, DMA_FROM_DEVICE);

for (i = 0; i < NUM_TX_DESC; i++)
if (re->tx_skb[i]) {
dev_kfree_skb_any(re->tx_skb[i]);
re->tx_skb[i] = NULL;
}
}

#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT3883)

#define RAMIPS_MDIO_RETRY 1000
Expand Down Expand Up @@ -481,77 +539,63 @@ ramips_phy_stop(struct raeth_priv *re)
#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT3883 */

static void
ramips_cleanup_dma(struct raeth_priv *re)
ramips_ring_free(struct raeth_priv *re)
{
int len;
int i;

for (i = 0; i < NUM_RX_DESC; i++)
if (re->rx_skb[i]) {
dma_unmap_single(&re->netdev->dev, re->rx_dma[i],
MAX_RX_LENGTH, DMA_FROM_DEVICE);
if (re->rx_skb[i])
dev_kfree_skb_any(re->rx_skb[i]);
}

if (re->rx)
dma_free_coherent(&re->netdev->dev,
NUM_RX_DESC * sizeof(struct ramips_rx_dma),
re->rx, re->rx_desc_dma);
if (re->rx) {
len = NUM_RX_DESC * sizeof(struct ramips_rx_dma);
dma_free_coherent(&re->netdev->dev, len, re->rx,
re->rx_desc_dma);
}

if (re->tx)
dma_free_coherent(&re->netdev->dev,
NUM_TX_DESC * sizeof(struct ramips_tx_dma),
re->tx, re->tx_desc_dma);
if (re->tx) {
len = NUM_TX_DESC * sizeof(struct ramips_tx_dma);
dma_free_coherent(&re->netdev->dev, len, re->tx,
re->tx_desc_dma);
}
}

static int
ramips_alloc_dma(struct raeth_priv *re)
ramips_ring_alloc(struct raeth_priv *re)
{
int len;
int err = -ENOMEM;
int i;

re->skb_free_idx = 0;

/* setup tx ring */
re->tx = dma_alloc_coherent(&re->netdev->dev,
NUM_TX_DESC * sizeof(struct ramips_tx_dma),
&re->tx_desc_dma, GFP_ATOMIC);
/* allocate tx ring */
len = NUM_TX_DESC * sizeof(struct ramips_tx_dma);
re->tx = dma_alloc_coherent(&re->netdev->dev, len,
&re->tx_desc_dma, GFP_ATOMIC);
if (!re->tx)
goto err_cleanup;

memset(re->tx, 0, NUM_TX_DESC * sizeof(struct ramips_tx_dma));
for (i = 0; i < NUM_TX_DESC; i++) {
re->tx[i].txd2 = TX_DMA_LSO | TX_DMA_DONE;
re->tx[i].txd4 = TX_DMA_QN(3) | TX_DMA_PN(1);
}

/* setup rx ring */
re->rx = dma_alloc_coherent(&re->netdev->dev,
NUM_RX_DESC * sizeof(struct ramips_rx_dma),
/* allocate rx ring */
len = NUM_RX_DESC * sizeof(struct ramips_rx_dma);
re->rx = dma_alloc_coherent(&re->netdev->dev, len,
&re->rx_desc_dma, GFP_ATOMIC);
if (!re->rx)
goto err_cleanup;

memset(re->rx, 0, sizeof(struct ramips_rx_dma) * NUM_RX_DESC);
for (i = 0; i < NUM_RX_DESC; i++) {
dma_addr_t dma_addr;
struct sk_buff *new_skb;
struct sk_buff *skb;

new_skb = ramips_alloc_skb(re);
if (!new_skb)
skb = ramips_alloc_skb(re);
if (!skb)
goto err_cleanup;

dma_addr = dma_map_single(&re->netdev->dev, new_skb->data,
MAX_RX_LENGTH, DMA_FROM_DEVICE);
re->rx_dma[i] = dma_addr;
re->rx[i].rxd1 = (unsigned int) re->rx_dma[i];
re->rx[i].rxd2 |= RX_DMA_LSO;
re->rx_skb[i] = new_skb;
re->rx_skb[i] = skb;
}

return 0;

err_cleanup:
ramips_cleanup_dma(re);
err_cleanup:
ramips_ring_free(re);
return err;
}

Expand Down Expand Up @@ -739,10 +783,11 @@ ramips_eth_open(struct net_device *dev)
if (err)
return err;

err = ramips_alloc_dma(re);
err = ramips_ring_alloc(re);
if (err)
goto err_free_irq;

ramips_ring_setup(re);
ramips_hw_set_macaddr(dev->dev_addr);

ramips_setup_dma(re);
Expand Down Expand Up @@ -798,7 +843,8 @@ ramips_eth_stop(struct net_device *dev)
netif_stop_queue(dev);
tasklet_kill(&re->tx_housekeeping_tasklet);
tasklet_kill(&re->rx_tasklet);
ramips_cleanup_dma(re);
ramips_ring_cleanup(re);
ramips_ring_free(re);
RADEBUG("ramips_eth: stopped\n");
return 0;
}
Expand Down

0 comments on commit 013dc5a

Please sign in to comment.