Commit b38c83dd authored by Felix Fietkau's avatar Felix Fietkau Committed by David S. Miller

bgmac: simplify tx ring index handling

Keep incrementing ring->start and ring->end instead of pointing it to
the actual ring slot entry. This simplifies the calculation of the
number of free slots.
Signed-off-by: default avatarFelix Fietkau <nbd@openwrt.org>
Acked-by: default avatarRafał Miłecki <zajec5@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e0767834
...@@ -142,11 +142,10 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, ...@@ -142,11 +142,10 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac,
{ {
struct device *dma_dev = bgmac->core->dma_dev; struct device *dma_dev = bgmac->core->dma_dev;
struct net_device *net_dev = bgmac->net_dev; struct net_device *net_dev = bgmac->net_dev;
struct bgmac_slot_info *slot = &ring->slots[ring->end]; int index = ring->end % BGMAC_TX_RING_SLOTS;
int free_slots; struct bgmac_slot_info *slot = &ring->slots[index];
int nr_frags; int nr_frags;
u32 flags; u32 flags;
int index = ring->end;
int i; int i;
if (skb->len > BGMAC_DESC_CTL1_LEN) { if (skb->len > BGMAC_DESC_CTL1_LEN) {
...@@ -159,12 +158,10 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, ...@@ -159,12 +158,10 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac,
nr_frags = skb_shinfo(skb)->nr_frags; nr_frags = skb_shinfo(skb)->nr_frags;
if (ring->start <= ring->end) /* ring->end - ring->start will return the number of valid slots,
free_slots = ring->start - ring->end + BGMAC_TX_RING_SLOTS; * even when ring->end overflows
else */
free_slots = ring->start - ring->end; if (ring->end - ring->start + nr_frags + 1 >= BGMAC_TX_RING_SLOTS) {
if (free_slots <= nr_frags + 1) {
bgmac_err(bgmac, "TX ring is full, queue should be stopped!\n"); bgmac_err(bgmac, "TX ring is full, queue should be stopped!\n");
netif_stop_queue(net_dev); netif_stop_queue(net_dev);
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
...@@ -200,7 +197,7 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, ...@@ -200,7 +197,7 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac,
} }
slot->skb = skb; slot->skb = skb;
ring->end += nr_frags + 1;
netdev_sent_queue(net_dev, skb->len); netdev_sent_queue(net_dev, skb->len);
wmb(); wmb();
...@@ -208,13 +205,12 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, ...@@ -208,13 +205,12 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac,
/* Increase ring->end to point empty slot. We tell hardware the first /* Increase ring->end to point empty slot. We tell hardware the first
* slot it should *not* read. * slot it should *not* read.
*/ */
ring->end = (index + 1) % BGMAC_TX_RING_SLOTS;
bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX, bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX,
ring->index_base + ring->index_base +
ring->end * sizeof(struct bgmac_dma_desc)); (ring->end % BGMAC_TX_RING_SLOTS) *
sizeof(struct bgmac_dma_desc));
free_slots -= nr_frags + 1; if (ring->end - ring->start >= BGMAC_TX_RING_SLOTS - 8)
if (free_slots < 8)
netif_stop_queue(net_dev); netif_stop_queue(net_dev);
return NETDEV_TX_OK; return NETDEV_TX_OK;
...@@ -256,17 +252,17 @@ static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring) ...@@ -256,17 +252,17 @@ static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
empty_slot &= BGMAC_DMA_TX_STATDPTR; empty_slot &= BGMAC_DMA_TX_STATDPTR;
empty_slot /= sizeof(struct bgmac_dma_desc); empty_slot /= sizeof(struct bgmac_dma_desc);
while (ring->start != empty_slot) { while (ring->start != ring->end) {
struct bgmac_slot_info *slot = &ring->slots[ring->start]; int slot_idx = ring->start % BGMAC_TX_RING_SLOTS;
u32 ctl1 = le32_to_cpu(ring->cpu_base[ring->start].ctl1); struct bgmac_slot_info *slot = &ring->slots[slot_idx];
int len = ctl1 & BGMAC_DESC_CTL1_LEN; u32 ctl1;
int len;
if (!slot->dma_addr) { if (slot_idx == empty_slot)
bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n", break;
ring->start, ring->end);
goto next;
}
ctl1 = le32_to_cpu(ring->cpu_base[slot_idx].ctl1);
len = ctl1 & BGMAC_DESC_CTL1_LEN;
if (ctl1 & BGMAC_DESC_CTL0_SOF) if (ctl1 & BGMAC_DESC_CTL0_SOF)
/* Unmap no longer used buffer */ /* Unmap no longer used buffer */
dma_unmap_single(dma_dev, slot->dma_addr, len, dma_unmap_single(dma_dev, slot->dma_addr, len,
...@@ -284,10 +280,8 @@ static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring) ...@@ -284,10 +280,8 @@ static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
slot->skb = NULL; slot->skb = NULL;
} }
next:
slot->dma_addr = 0; slot->dma_addr = 0;
if (++ring->start >= BGMAC_TX_RING_SLOTS) ring->start++;
ring->start = 0;
freed = true; freed = true;
} }
......
...@@ -414,10 +414,10 @@ enum bgmac_dma_ring_type { ...@@ -414,10 +414,10 @@ enum bgmac_dma_ring_type {
* empty. * empty.
*/ */
struct bgmac_dma_ring { struct bgmac_dma_ring {
u16 num_slots; u32 start;
u16 start; u32 end;
u16 end;
u16 num_slots;
u16 mmio_base; u16 mmio_base;
struct bgmac_dma_desc *cpu_base; struct bgmac_dma_desc *cpu_base;
dma_addr_t dma_base; dma_addr_t dma_base;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment