|
|
@ -134,14 +134,20 @@ ramips_ring_setup(struct raeth_priv *re) |
|
|
|
memset(re->rx, 0, len); |
|
|
|
memset(re->rx, 0, len); |
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_RX_DESC; i++) { |
|
|
|
for (i = 0; i < NUM_RX_DESC; i++) { |
|
|
|
|
|
|
|
struct raeth_rx_info *rxi; |
|
|
|
|
|
|
|
struct ramips_rx_dma *rxd; |
|
|
|
dma_addr_t dma_addr; |
|
|
|
dma_addr_t dma_addr; |
|
|
|
|
|
|
|
|
|
|
|
BUG_ON(re->rx_skb[i] == NULL); |
|
|
|
rxd = &re->rx[i]; |
|
|
|
dma_addr = dma_map_single(&re->netdev->dev, re->rx_skb[i]->data, |
|
|
|
rxi = &re->rx_info[i]; |
|
|
|
|
|
|
|
BUG_ON(rxi->rx_skb == NULL); |
|
|
|
|
|
|
|
dma_addr = dma_map_single(&re->netdev->dev, rxi->rx_skb->data, |
|
|
|
MAX_RX_LENGTH, DMA_FROM_DEVICE); |
|
|
|
MAX_RX_LENGTH, DMA_FROM_DEVICE); |
|
|
|
re->rx_dma[i] = dma_addr; |
|
|
|
rxi->rx_dma = dma_addr; |
|
|
|
re->rx[i].rxd1 = (unsigned int) dma_addr; |
|
|
|
rxi->rx_desc = rxd; |
|
|
|
re->rx[i].rxd2 = RX_DMA_LSO; |
|
|
|
|
|
|
|
|
|
|
|
rxd->rxd1 = (unsigned int) dma_addr; |
|
|
|
|
|
|
|
rxd->rxd2 = RX_DMA_LSO; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* flush descriptors */ |
|
|
|
/* flush descriptors */ |
|
|
@ -153,10 +159,14 @@ ramips_ring_cleanup(struct raeth_priv *re) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int i; |
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_RX_DESC; i++) |
|
|
|
for (i = 0; i < NUM_RX_DESC; i++) { |
|
|
|
if (re->rx_skb[i]) |
|
|
|
struct raeth_rx_info *rxi; |
|
|
|
dma_unmap_single(&re->netdev->dev, re->rx_dma[i], |
|
|
|
|
|
|
|
|
|
|
|
rxi = &re->rx_info[i]; |
|
|
|
|
|
|
|
if (rxi->rx_skb) |
|
|
|
|
|
|
|
dma_unmap_single(&re->netdev->dev, rxi->rx_dma, |
|
|
|
MAX_RX_LENGTH, DMA_FROM_DEVICE); |
|
|
|
MAX_RX_LENGTH, DMA_FROM_DEVICE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_TX_DESC; i++) { |
|
|
|
for (i = 0; i < NUM_TX_DESC; i++) { |
|
|
|
struct raeth_tx_info *txi; |
|
|
|
struct raeth_tx_info *txi; |
|
|
@ -553,9 +563,16 @@ ramips_ring_free(struct raeth_priv *re) |
|
|
|
int len; |
|
|
|
int len; |
|
|
|
int i; |
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_RX_DESC; i++) |
|
|
|
if (re->rx_info) { |
|
|
|
if (re->rx_skb[i]) |
|
|
|
for (i = 0; i < NUM_RX_DESC; i++) { |
|
|
|
dev_kfree_skb_any(re->rx_skb[i]); |
|
|
|
struct raeth_rx_info *rxi; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rxi = &re->rx_info[i]; |
|
|
|
|
|
|
|
if (rxi->rx_skb) |
|
|
|
|
|
|
|
dev_kfree_skb_any(rxi->rx_skb); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
kfree(re->rx_info); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (re->rx) { |
|
|
|
if (re->rx) { |
|
|
|
len = NUM_RX_DESC * sizeof(struct ramips_rx_dma); |
|
|
|
len = NUM_RX_DESC * sizeof(struct ramips_rx_dma); |
|
|
@ -584,6 +601,11 @@ ramips_ring_alloc(struct raeth_priv *re) |
|
|
|
if (!re->tx_info) |
|
|
|
if (!re->tx_info) |
|
|
|
goto err_cleanup; |
|
|
|
goto err_cleanup; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
re->rx_info = kzalloc(NUM_RX_DESC * sizeof(struct raeth_rx_info), |
|
|
|
|
|
|
|
GFP_ATOMIC); |
|
|
|
|
|
|
|
if (!re->rx_info) |
|
|
|
|
|
|
|
goto err_cleanup; |
|
|
|
|
|
|
|
|
|
|
|
/* allocate tx ring */ |
|
|
|
/* allocate tx ring */ |
|
|
|
len = NUM_TX_DESC * sizeof(struct ramips_tx_dma); |
|
|
|
len = NUM_TX_DESC * sizeof(struct ramips_tx_dma); |
|
|
|
re->tx = dma_alloc_coherent(&re->netdev->dev, len, |
|
|
|
re->tx = dma_alloc_coherent(&re->netdev->dev, len, |
|
|
@ -605,7 +627,7 @@ ramips_ring_alloc(struct raeth_priv *re) |
|
|
|
if (!skb) |
|
|
|
if (!skb) |
|
|
|
goto err_cleanup; |
|
|
|
goto err_cleanup; |
|
|
|
|
|
|
|
|
|
|
|
re->rx_skb[i] = skb; |
|
|
|
re->rx_info[i].rx_skb = skb; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return 0; |
|
|
@ -696,23 +718,27 @@ ramips_eth_rx_hw(unsigned long ptr) |
|
|
|
int max_rx = 16; |
|
|
|
int max_rx = 16; |
|
|
|
|
|
|
|
|
|
|
|
while (max_rx) { |
|
|
|
while (max_rx) { |
|
|
|
|
|
|
|
struct raeth_rx_info *rxi; |
|
|
|
|
|
|
|
struct ramips_rx_dma *rxd; |
|
|
|
struct sk_buff *rx_skb, *new_skb; |
|
|
|
struct sk_buff *rx_skb, *new_skb; |
|
|
|
int pktlen; |
|
|
|
int pktlen; |
|
|
|
|
|
|
|
|
|
|
|
rx = (ramips_fe_rr(RAMIPS_RX_CALC_IDX0) + 1) % NUM_RX_DESC; |
|
|
|
rx = (ramips_fe_rr(RAMIPS_RX_CALC_IDX0) + 1) % NUM_RX_DESC; |
|
|
|
if (!(re->rx[rx].rxd2 & RX_DMA_DONE)) |
|
|
|
|
|
|
|
|
|
|
|
rxi = &re->rx_info[rx]; |
|
|
|
|
|
|
|
rxd = rxi->rx_desc; |
|
|
|
|
|
|
|
if (!(rxd->rxd2 & RX_DMA_DONE)) |
|
|
|
break; |
|
|
|
break; |
|
|
|
max_rx--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rx_skb = re->rx_skb[rx]; |
|
|
|
rx_skb = rxi->rx_skb; |
|
|
|
pktlen = RX_DMA_PLEN0(re->rx[rx].rxd2); |
|
|
|
pktlen = RX_DMA_PLEN0(rxd->rxd2); |
|
|
|
|
|
|
|
|
|
|
|
new_skb = ramips_alloc_skb(re); |
|
|
|
new_skb = ramips_alloc_skb(re); |
|
|
|
/* Reuse the buffer on allocation failures */ |
|
|
|
/* Reuse the buffer on allocation failures */ |
|
|
|
if (new_skb) { |
|
|
|
if (new_skb) { |
|
|
|
dma_addr_t dma_addr; |
|
|
|
dma_addr_t dma_addr; |
|
|
|
|
|
|
|
|
|
|
|
dma_unmap_single(&re->netdev->dev, re->rx_dma[rx], |
|
|
|
dma_unmap_single(&re->netdev->dev, rxi->rx_dma, |
|
|
|
MAX_RX_LENGTH, DMA_FROM_DEVICE); |
|
|
|
MAX_RX_LENGTH, DMA_FROM_DEVICE); |
|
|
|
|
|
|
|
|
|
|
|
skb_put(rx_skb, pktlen); |
|
|
|
skb_put(rx_skb, pktlen); |
|
|
@ -723,21 +749,22 @@ ramips_eth_rx_hw(unsigned long ptr) |
|
|
|
dev->stats.rx_bytes += pktlen; |
|
|
|
dev->stats.rx_bytes += pktlen; |
|
|
|
netif_rx(rx_skb); |
|
|
|
netif_rx(rx_skb); |
|
|
|
|
|
|
|
|
|
|
|
re->rx_skb[rx] = new_skb; |
|
|
|
rxi->rx_skb = new_skb; |
|
|
|
|
|
|
|
|
|
|
|
dma_addr = dma_map_single(&re->netdev->dev, |
|
|
|
dma_addr = dma_map_single(&re->netdev->dev, |
|
|
|
new_skb->data, |
|
|
|
new_skb->data, |
|
|
|
MAX_RX_LENGTH, |
|
|
|
MAX_RX_LENGTH, |
|
|
|
DMA_FROM_DEVICE); |
|
|
|
DMA_FROM_DEVICE); |
|
|
|
re->rx_dma[rx] = dma_addr; |
|
|
|
rxi->rx_dma = dma_addr; |
|
|
|
re->rx[rx].rxd1 = (unsigned int) dma_addr; |
|
|
|
rxd->rxd1 = (unsigned int) dma_addr; |
|
|
|
|
|
|
|
wmb(); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
dev->stats.rx_dropped++; |
|
|
|
dev->stats.rx_dropped++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
re->rx[rx].rxd2 &= ~RX_DMA_DONE; |
|
|
|
rxd->rxd2 = RX_DMA_LSO; |
|
|
|
wmb(); |
|
|
|
|
|
|
|
ramips_fe_wr(rx, RAMIPS_RX_CALC_IDX0); |
|
|
|
ramips_fe_wr(rx, RAMIPS_RX_CALC_IDX0); |
|
|
|
|
|
|
|
max_rx--; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (max_rx == 0) |
|
|
|
if (max_rx == 0) |
|
|
|