summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/cadence/macb.c45
-rw-r--r--drivers/net/ethernet/cadence/macb.h1
2 files changed, 38 insertions, 8 deletions
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 4465e27ba9d1..aab7bb22b1d0 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -32,7 +32,9 @@
#include "macb.h"
-#define RX_BUFFER_SIZE 128
+#define MACB_RX_BUFFER_SIZE 128
+#define GEM_RX_BUFFER_SIZE 2048
+#define RX_BUFFER_MULTIPLE 64 /* bytes */
#define RX_RING_SIZE 512 /* must be power of 2 */
#define RX_RING_BYTES (sizeof(struct macb_dma_desc) * RX_RING_SIZE)
@@ -92,7 +94,7 @@ static struct macb_dma_desc *macb_rx_desc(struct macb *bp, unsigned int index)
static void *macb_rx_buffer(struct macb *bp, unsigned int index)
{
- return bp->rx_buffers + RX_BUFFER_SIZE * macb_rx_ring_wrap(index);
+ return bp->rx_buffers + bp->rx_buffer_size * macb_rx_ring_wrap(index);
}
void macb_set_hwaddr(struct macb *bp)
@@ -575,7 +577,7 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
skb_put(skb, len);
for (frag = first_frag; ; frag++) {
- unsigned int frag_len = RX_BUFFER_SIZE;
+ unsigned int frag_len = bp->rx_buffer_size;
if (offset + frag_len > len) {
BUG_ON(frag != last_frag);
@@ -583,7 +585,7 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
}
skb_copy_to_linear_data_offset(skb, offset,
macb_rx_buffer(bp, frag), frag_len);
- offset += RX_BUFFER_SIZE;
+ offset += bp->rx_buffer_size;
desc = macb_rx_desc(bp, frag);
desc->addr &= ~MACB_BIT(RX_USED);
@@ -870,6 +872,30 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
+static void macb_init_rx_buffer_size(struct macb *bp)
+{
+ if (!macb_is_gem(bp)) {
+ bp->rx_buffer_size = MACB_RX_BUFFER_SIZE;
+ } else {
+ bp->rx_buffer_size = GEM_RX_BUFFER_SIZE;
+
+ if (bp->rx_buffer_size > PAGE_SIZE) {
+ netdev_warn(bp->dev,
+ "RX buffer cannot be bigger than PAGE_SIZE, shrinking\n");
+ bp->rx_buffer_size = PAGE_SIZE;
+ }
+ if (bp->rx_buffer_size % RX_BUFFER_MULTIPLE) {
+ netdev_warn(bp->dev,
+ "RX buffer must be multiple of %d bytes, shrinking\n",
+ RX_BUFFER_MULTIPLE);
+ bp->rx_buffer_size =
+ rounddown(bp->rx_buffer_size, RX_BUFFER_MULTIPLE);
+ }
+ bp->rx_buffer_size = max(RX_BUFFER_MULTIPLE, GEM_RX_BUFFER_SIZE);
+ }
+}
+
+
static void macb_free_consistent(struct macb *bp)
{
if (bp->tx_skb) {
@@ -888,7 +914,7 @@ static void macb_free_consistent(struct macb *bp)
}
if (bp->rx_buffers) {
dma_free_coherent(&bp->pdev->dev,
- RX_RING_SIZE * RX_BUFFER_SIZE,
+ RX_RING_SIZE * bp->rx_buffer_size,
bp->rx_buffers, bp->rx_buffers_dma);
bp->rx_buffers = NULL;
}
@@ -921,7 +947,7 @@ static int macb_alloc_consistent(struct macb *bp)
"Allocated TX ring of %d bytes at %08lx (mapped %p)\n",
size, (unsigned long)bp->tx_ring_dma, bp->tx_ring);
- size = RX_RING_SIZE * RX_BUFFER_SIZE;
+ size = RX_RING_SIZE * bp->rx_buffer_size;
bp->rx_buffers = dma_alloc_coherent(&bp->pdev->dev, size,
&bp->rx_buffers_dma, GFP_KERNEL);
if (!bp->rx_buffers)
@@ -946,7 +972,7 @@ static void macb_init_rings(struct macb *bp)
for (i = 0; i < RX_RING_SIZE; i++) {
bp->rx_ring[i].addr = addr;
bp->rx_ring[i].ctrl = 0;
- addr += RX_BUFFER_SIZE;
+ addr += bp->rx_buffer_size;
}
bp->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
@@ -1056,7 +1082,7 @@ static void macb_configure_dma(struct macb *bp)
if (macb_is_gem(bp)) {
dmacfg = gem_readl(bp, DMACFG) & ~GEM_BF(RXBS, -1L);
- dmacfg |= GEM_BF(RXBS, RX_BUFFER_SIZE / 64);
+ dmacfg |= GEM_BF(RXBS, bp->rx_buffer_size / RX_BUFFER_MULTIPLE);
dmacfg |= GEM_BF(FBLDO, 16);
dmacfg |= GEM_BIT(TXPBMS) | GEM_BF(RXBMS, -1L);
dmacfg &= ~GEM_BIT(ENDIA);
@@ -1244,6 +1270,9 @@ static int macb_open(struct net_device *dev)
if (!bp->phy_dev)
return -EAGAIN;
+ /* RX buffers initialization */
+ macb_init_rx_buffer_size(bp);
+
err = macb_alloc_consistent(bp);
if (err) {
netdev_err(dev, "Unable to allocate DMA memory (error %d)\n",
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 548c0ecae869..9b5e19f8b61d 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -551,6 +551,7 @@ struct macb {
unsigned int rx_tail;
struct macb_dma_desc *rx_ring;
void *rx_buffers;
+ size_t rx_buffer_size;
unsigned int tx_head, tx_tail;
struct macb_dma_desc *tx_ring;