ramips: raeth: separate ring allocation and setup
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@30573 3c298f89-4303-0410-b956-a3cf2f4a3e73master
parent
0449978493
commit
33bf9bc63b
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue