aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ar71xx/files/drivers
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2014-12-09 12:28:46 +0000
committerFelix Fietkau <nbd@openwrt.org>2014-12-09 12:28:46 +0000
commit548879cdc1da0a74d4ca998e8eaf89f37ec7b31b (patch)
treed619f0c488fbb55569d3b44804b32bf95ea71b8d /target/linux/ar71xx/files/drivers
parentce28e880c9bdb5725d6dedf7efdb7bd4970361d1 (diff)
downloadmaster-187ad058-548879cdc1da0a74d4ca998e8eaf89f37ec7b31b.tar.gz
master-187ad058-548879cdc1da0a74d4ca998e8eaf89f37ec7b31b.tar.bz2
master-187ad058-548879cdc1da0a74d4ca998e8eaf89f37ec7b31b.zip
ar71xx: improve ethernet driver cache footprint by removing an unnecessary pointer
Signed-off-by: Felix Fietkau <nbd@openwrt.org> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@43588 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/ar71xx/files/drivers')
-rw-r--r--target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h7
-rw-r--r--target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c9
-rw-r--r--target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c47
3 files changed, 36 insertions, 27 deletions
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
index 2d7c963a44..b18c20b6dd 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
@@ -90,7 +90,6 @@ struct ag71xx_buf {
struct sk_buff *skb;
void *rx_buf;
};
- struct ag71xx_desc *desc;
union {
dma_addr_t dma_addr;
unsigned long timestamp;
@@ -203,6 +202,12 @@ static inline int ag71xx_desc_empty(struct ag71xx_desc *desc)
return (desc->ctrl & DESC_EMPTY) != 0;
}
+static inline struct ag71xx_desc *
+ag71xx_ring_desc(struct ag71xx_ring *ring, int idx)
+{
+ return (struct ag71xx_desc *) &ring->descs_cpu[idx * ring->desc_size];
+}
+
/* Register offsets */
#define AG71XX_REG_MAC_CFG1 0x0000
#define AG71XX_REG_MAC_CFG2 0x0004
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c
index 757a572b00..c480121040 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_debugfs.c
@@ -183,6 +183,7 @@ static ssize_t read_file_ring(struct file *file, char __user *user_buf,
desc_hw = ag71xx_rr(ag, desc_reg);
for (i = 0; i < ring->size; i++) {
struct ag71xx_buf *ab = &ring->buf[i];
+ struct ag71xx_desc *desc = ag71xx_ring_desc(ring, i);
u32 desc_dma = ((u32) ring->descs_dma) + i * ring->desc_size;
len += snprintf(buf + len, buflen - len,
@@ -192,10 +193,10 @@ static ssize_t read_file_ring(struct file *file, char __user *user_buf,
(i == dirty) ? 'D' : ' ',
(desc_hw == desc_dma) ? 'H' : ' ',
desc_dma,
- ab->desc->next,
- ab->desc->data,
- ab->desc->ctrl,
- (ab->desc->ctrl & DESC_EMPTY) ? 'E' : '*',
+ desc->next,
+ desc->data,
+ desc->ctrl,
+ (desc->ctrl & DESC_EMPTY) ? 'E' : '*',
ab->timestamp);
}
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
index 259cc205cb..5ef324e853 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
@@ -100,7 +100,6 @@ static void ag71xx_ring_free(struct ag71xx_ring *ring)
static int ag71xx_ring_alloc(struct ag71xx_ring *ring)
{
int err;
- int i;
ring->desc_size = sizeof(struct ag71xx_desc);
if (ring->desc_size % cache_line_size()) {
@@ -124,13 +123,6 @@ static int ag71xx_ring_alloc(struct ag71xx_ring *ring)
goto err;
}
- for (i = 0; i < ring->size; i++) {
- int idx = i * ring->desc_size;
- ring->buf[i].desc = (struct ag71xx_desc *)&ring->descs_cpu[idx];
- DBG("ag71xx: ring %p, desc %d at %p\n",
- ring, i, ring->buf[i].desc);
- }
-
return 0;
err:
@@ -144,10 +136,12 @@ static void ag71xx_ring_tx_clean(struct ag71xx *ag)
u32 bytes_compl = 0, pkts_compl = 0;
while (ring->curr != ring->dirty) {
+ struct ag71xx_desc *desc;
u32 i = ring->dirty % ring->size;
- if (!ag71xx_desc_empty(ring->buf[i].desc)) {
- ring->buf[i].desc->ctrl = 0;
+ desc = ag71xx_ring_desc(ring, i);
+ if (!ag71xx_desc_empty(desc)) {
+ desc->ctrl = 0;
dev->stats.tx_errors++;
}
@@ -172,10 +166,12 @@ static void ag71xx_ring_tx_init(struct ag71xx *ag)
int i;
for (i = 0; i < ring->size; i++) {
- ring->buf[i].desc->next = (u32) (ring->descs_dma +
+ struct ag71xx_desc *desc = ag71xx_ring_desc(ring, i);
+
+ desc->next = (u32) (ring->descs_dma +
ring->desc_size * ((i + 1) % ring->size));
- ring->buf[i].desc->ctrl = DESC_EMPTY;
+ desc->ctrl = DESC_EMPTY;
ring->buf[i].skb = NULL;
}
@@ -222,6 +218,8 @@ static int ag71xx_buffer_offset(struct ag71xx *ag)
static bool ag71xx_fill_rx_buf(struct ag71xx *ag, struct ag71xx_buf *buf,
int offset)
{
+ struct ag71xx_ring *ring = &ag->rx_ring;
+ struct ag71xx_desc *desc = ag71xx_ring_desc(ring, buf - &ring->buf[0]);
void *data;
data = kmalloc(ag->rx_buf_size +
@@ -233,7 +231,7 @@ static bool ag71xx_fill_rx_buf(struct ag71xx *ag, struct ag71xx_buf *buf,
buf->rx_buf = data;
buf->dma_addr = dma_map_single(&ag->dev->dev, data, ag->rx_buf_size,
DMA_FROM_DEVICE);
- buf->desc->data = (u32) buf->dma_addr + offset;
+ desc->data = (u32) buf->dma_addr + offset;
return true;
}
@@ -246,21 +244,24 @@ static int ag71xx_ring_rx_init(struct ag71xx *ag)
ret = 0;
for (i = 0; i < ring->size; i++) {
- ring->buf[i].desc->next = (u32) (ring->descs_dma +
+ struct ag71xx_desc *desc = ag71xx_ring_desc(ring, i);
+
+ desc->next = (u32) (ring->descs_dma +
ring->desc_size * ((i + 1) % ring->size));
DBG("ag71xx: RX desc at %p, next is %08x\n",
- ring->buf[i].desc,
- ring->buf[i].desc->next);
+ desc, desc->next);
}
for (i = 0; i < ring->size; i++) {
+ struct ag71xx_desc *desc = ag71xx_ring_desc(ring, i);
+
if (!ag71xx_fill_rx_buf(ag, &ring->buf[i], offset)) {
ret = -ENOMEM;
break;
}
- ring->buf[i].desc->ctrl = DESC_EMPTY;
+ desc->ctrl = DESC_EMPTY;
}
/* flush descriptors */
@@ -280,15 +281,17 @@ static int ag71xx_ring_rx_refill(struct ag71xx *ag)
count = 0;
for (; ring->curr - ring->dirty > 0; ring->dirty++) {
+ struct ag71xx_desc *desc;
unsigned int i;
i = ring->dirty % ring->size;
+ desc = ag71xx_ring_desc(ring, i);
if (!ring->buf[i].rx_buf &&
!ag71xx_fill_rx_buf(ag, &ring->buf[i], offset))
break;
- ring->buf[i].desc->ctrl = DESC_EMPTY;
+ desc->ctrl = DESC_EMPTY;
count++;
}
@@ -697,7 +700,7 @@ static int ag71xx_fill_dma_desc(struct ag71xx_ring *ring, u32 addr, int len)
unsigned int cur_len = len;
i = (ring->curr + ndesc) % ring->size;
- desc = ring->buf[i].desc;
+ desc = ag71xx_ring_desc(ring, i);
if (!ag71xx_desc_empty(desc))
return -1;
@@ -752,7 +755,7 @@ static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb,
DMA_TO_DEVICE);
i = ring->curr % ring->size;
- desc = ring->buf[i].desc;
+ desc = ag71xx_ring_desc(ring, i);
/* setup descriptor fields */
n = ag71xx_fill_dma_desc(ring, (u32) dma_addr, skb->len & ag->desc_pktlen_mask);
@@ -907,7 +910,7 @@ static int ag71xx_tx_packets(struct ag71xx *ag)
while (ring->dirty + n != ring->curr) {
unsigned int i = (ring->dirty + n) % ring->size;
- struct ag71xx_desc *desc = ring->buf[i].desc;
+ struct ag71xx_desc *desc = ag71xx_ring_desc(ring, i);
struct sk_buff *skb = ring->buf[i].skb;
if (!ag71xx_desc_empty(desc)) {
@@ -963,7 +966,7 @@ static int ag71xx_rx_packets(struct ag71xx *ag, int limit)
while (done < limit) {
unsigned int i = ring->curr % ring->size;
- struct ag71xx_desc *desc = ring->buf[i].desc;
+ struct ag71xx_desc *desc = ag71xx_ring_desc(ring, i);
struct sk_buff *skb;
int pktlen;
int err = 0;