summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2014-03-31 14:47:06 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2014-10-17 14:35:42 +0100
commit9f8008020a8293074a65f5f23ec1f40ac97d6beb (patch)
treee49d5b1a7964fd0b2540e54c6837ef1849e88977
parent1b526028590f6746a36d60ca9e51b44cfee6a6fe (diff)
net:fec: even larger rings
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c68
1 files changed, 42 insertions, 26 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 95a9fbd70f4e..95fad9862ef5 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -872,7 +872,7 @@ fec_enet_hwtstamp(struct fec_enet_private *fep, unsigned ts,
hwtstamps->hwtstamp = ns_to_ktime(ns);
}
-static void
+static void noinline
fec_enet_tx(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
@@ -2041,6 +2041,7 @@ static void fec_enet_free_buffers(struct net_device *ndev)
unsigned int i;
struct sk_buff *skb;
union bufdesc_u *bdp;
+ int rx_cbd_size, tx_cbd_size;
for (i = 0; i < fep->rx_ring_size; i++) {
bdp = fec_enet_rx_get(i, fep);
@@ -2066,7 +2067,18 @@ static void fec_enet_free_buffers(struct net_device *ndev)
dev_kfree_skb(skb);
}
- dma_free_coherent(NULL, PAGE_SIZE, fep->rx_bd_base, fep->rx_bd_dma);
+ rx_cbd_size = fep->rx_ring_size;
+ tx_cbd_size = fep->tx_ring_size;
+ if (fep->flags & FEC_FLAG_BUFDESC_EX) {
+ rx_cbd_size *= sizeof(struct bufdesc_ex);
+ tx_cbd_size *= sizeof(struct bufdesc_ex);
+ } else {
+ rx_cbd_size *= sizeof(struct bufdesc);
+ tx_cbd_size *= sizeof(struct bufdesc);
+ }
+
+ dma_free_coherent(NULL, rx_cbd_size, fep->rx_bd_base, fep->rx_bd_dma);
+ dma_free_coherent(NULL, tx_cbd_size, fep->tx_bd_base, fep->tx_bd_dma);
}
static int fec_enet_alloc_buffers(struct net_device *ndev)
@@ -2074,38 +2086,42 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
struct fec_enet_private *fep = netdev_priv(ndev);
unsigned int i;
struct sk_buff *skb;
+ union bufdesc_u *rx_cbd_cpu, *tx_cbd_cpu;
+ dma_addr_t rx_cbd_dma, tx_cbd_dma;
union bufdesc_u *bdp;
- union bufdesc_u *cbd_base;
- dma_addr_t cbd_dma;
- int bd_size;
+ int rx_cbd_size, tx_cbd_size;
- bd_size = fep->tx_ring_size + fep->rx_ring_size;
- if (fep->flags & FEC_FLAG_BUFDESC_EX)
- bd_size *= sizeof(struct bufdesc_ex);
- else
- bd_size *= sizeof(struct bufdesc);
+ rx_cbd_size = fep->rx_ring_size;
+ tx_cbd_size = fep->tx_ring_size;
+ if (fep->flags & FEC_FLAG_BUFDESC_EX) {
+ rx_cbd_size *= sizeof(struct bufdesc_ex);
+ tx_cbd_size *= sizeof(struct bufdesc_ex);
+ } else {
+ rx_cbd_size *= sizeof(struct bufdesc);
+ tx_cbd_size *= sizeof(struct bufdesc);
+ }
/* Allocate memory for buffer descriptors. */
- cbd_base = dma_alloc_coherent(NULL, bd_size, &cbd_dma, GFP_KERNEL);
- if (!cbd_base)
+ rx_cbd_cpu = dma_alloc_coherent(NULL, rx_cbd_size, &rx_cbd_dma,
+ GFP_KERNEL);
+ tx_cbd_cpu = dma_alloc_coherent(NULL, tx_cbd_size, &tx_cbd_dma,
+ GFP_KERNEL);
+ if (!rx_cbd_cpu || !tx_cbd_cpu) {
+ if (rx_cbd_cpu)
+ dma_free_coherent(NULL, rx_cbd_size, rx_cbd_cpu, rx_cbd_dma);
+ if (tx_cbd_cpu)
+ dma_free_coherent(NULL, tx_cbd_size, tx_cbd_cpu, tx_cbd_dma);
return -ENOMEM;
+ }
- memset(cbd_base, 0, PAGE_SIZE);
+ memset(rx_cbd_cpu, 0, PAGE_SIZE);
+ memset(tx_cbd_cpu, 0, PAGE_SIZE);
/* Set receive and transmit descriptor base. */
- fep->rx_bd_base = cbd_base;
- fep->rx_bd_dma = cbd_dma;
- if (fep->flags & FEC_FLAG_BUFDESC_EX) {
- fep->tx_bd_base = (union bufdesc_u *)
- (&cbd_base->ebd + fep->rx_ring_size);
- fep->tx_bd_dma = cbd_dma + sizeof(struct bufdesc_ex) *
- fep->rx_ring_size;
- } else {
- fep->tx_bd_base = (union bufdesc_u *)
- (&cbd_base->bd + fep->rx_ring_size);
- fep->tx_bd_dma = cbd_dma + sizeof(struct bufdesc) *
- fep->rx_ring_size;
- }
+ fep->rx_bd_base = rx_cbd_cpu;
+ fep->rx_bd_dma = rx_cbd_dma;
+ fep->tx_bd_base = tx_cbd_cpu;
+ fep->tx_bd_dma = tx_cbd_dma;
for (i = 0; i < fep->rx_ring_size; i++) {
dma_addr_t addr;