diff options
author | Felix Fietkau <nbd@openwrt.org> | 2015-04-14 06:07:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-04-14 14:57:10 -0400 |
commit | b38c83dd08665a93e439c4ffd9eef31bc098a6ea (patch) | |
tree | e35af7b479d02c713b303d24bbf60442e0f52bc8 /drivers/net/ethernet/broadcom | |
parent | e07678341b612bbf98c2bf205c3f26f3ef5f8e93 (diff) |
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: Felix Fietkau <nbd@openwrt.org>
Acked-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom')
-rw-r--r-- | drivers/net/ethernet/broadcom/bgmac.c | 46 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bgmac.h | 6 |
2 files changed, 23 insertions, 29 deletions
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index fa8f9e147c34..b9e02e484d72 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c | |||
@@ -142,11 +142,10 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, | |||
142 | { | 142 | { |
143 | struct device *dma_dev = bgmac->core->dma_dev; | 143 | struct device *dma_dev = bgmac->core->dma_dev; |
144 | struct net_device *net_dev = bgmac->net_dev; | 144 | struct net_device *net_dev = bgmac->net_dev; |
145 | struct bgmac_slot_info *slot = &ring->slots[ring->end]; | 145 | int index = ring->end % BGMAC_TX_RING_SLOTS; |
146 | int free_slots; | 146 | struct bgmac_slot_info *slot = &ring->slots[index]; |
147 | int nr_frags; | 147 | int nr_frags; |
148 | u32 flags; | 148 | u32 flags; |
149 | int index = ring->end; | ||
150 | int i; | 149 | int i; |
151 | 150 | ||
152 | if (skb->len > BGMAC_DESC_CTL1_LEN) { | 151 | if (skb->len > BGMAC_DESC_CTL1_LEN) { |
@@ -159,12 +158,10 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, | |||
159 | 158 | ||
160 | nr_frags = skb_shinfo(skb)->nr_frags; | 159 | nr_frags = skb_shinfo(skb)->nr_frags; |
161 | 160 | ||
162 | if (ring->start <= ring->end) | 161 | /* ring->end - ring->start will return the number of valid slots, |
163 | free_slots = ring->start - ring->end + BGMAC_TX_RING_SLOTS; | 162 | * even when ring->end overflows |
164 | else | 163 | */ |
165 | free_slots = ring->start - ring->end; | 164 | if (ring->end - ring->start + nr_frags + 1 >= BGMAC_TX_RING_SLOTS) { |
166 | |||
167 | if (free_slots <= nr_frags + 1) { | ||
168 | bgmac_err(bgmac, "TX ring is full, queue should be stopped!\n"); | 165 | bgmac_err(bgmac, "TX ring is full, queue should be stopped!\n"); |
169 | netif_stop_queue(net_dev); | 166 | netif_stop_queue(net_dev); |
170 | return NETDEV_TX_BUSY; | 167 | return NETDEV_TX_BUSY; |
@@ -200,7 +197,7 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, | |||
200 | } | 197 | } |
201 | 198 | ||
202 | slot->skb = skb; | 199 | slot->skb = skb; |
203 | 200 | ring->end += nr_frags + 1; | |
204 | netdev_sent_queue(net_dev, skb->len); | 201 | netdev_sent_queue(net_dev, skb->len); |
205 | 202 | ||
206 | wmb(); | 203 | wmb(); |
@@ -208,13 +205,12 @@ static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac, | |||
208 | /* Increase ring->end to point empty slot. We tell hardware the first | 205 | /* Increase ring->end to point empty slot. We tell hardware the first |
209 | * slot it should *not* read. | 206 | * slot it should *not* read. |
210 | */ | 207 | */ |
211 | ring->end = (index + 1) % BGMAC_TX_RING_SLOTS; | ||
212 | bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX, | 208 | bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX, |
213 | ring->index_base + | 209 | ring->index_base + |
214 | ring->end * sizeof(struct bgmac_dma_desc)); | 210 | (ring->end % BGMAC_TX_RING_SLOTS) * |
211 | sizeof(struct bgmac_dma_desc)); | ||
215 | 212 | ||
216 | free_slots -= nr_frags + 1; | 213 | if (ring->end - ring->start >= BGMAC_TX_RING_SLOTS - 8) |
217 | if (free_slots < 8) | ||
218 | netif_stop_queue(net_dev); | 214 | netif_stop_queue(net_dev); |
219 | 215 | ||
220 | return NETDEV_TX_OK; | 216 | return NETDEV_TX_OK; |
@@ -256,17 +252,17 @@ static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring) | |||
256 | empty_slot &= BGMAC_DMA_TX_STATDPTR; | 252 | empty_slot &= BGMAC_DMA_TX_STATDPTR; |
257 | empty_slot /= sizeof(struct bgmac_dma_desc); | 253 | empty_slot /= sizeof(struct bgmac_dma_desc); |
258 | 254 | ||
259 | while (ring->start != empty_slot) { | 255 | while (ring->start != ring->end) { |
260 | struct bgmac_slot_info *slot = &ring->slots[ring->start]; | 256 | int slot_idx = ring->start % BGMAC_TX_RING_SLOTS; |
261 | u32 ctl1 = le32_to_cpu(ring->cpu_base[ring->start].ctl1); | 257 | struct bgmac_slot_info *slot = &ring->slots[slot_idx]; |
262 | int len = ctl1 & BGMAC_DESC_CTL1_LEN; | 258 | u32 ctl1; |
259 | int len; | ||
263 | 260 | ||
264 | if (!slot->dma_addr) { | 261 | if (slot_idx == empty_slot) |
265 | bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n", | 262 | break; |
266 | ring->start, ring->end); | ||
267 | goto next; | ||
268 | } | ||
269 | 263 | ||
264 | ctl1 = le32_to_cpu(ring->cpu_base[slot_idx].ctl1); | ||
265 | len = ctl1 & BGMAC_DESC_CTL1_LEN; | ||
270 | if (ctl1 & BGMAC_DESC_CTL0_SOF) | 266 | if (ctl1 & BGMAC_DESC_CTL0_SOF) |
271 | /* Unmap no longer used buffer */ | 267 | /* Unmap no longer used buffer */ |
272 | dma_unmap_single(dma_dev, slot->dma_addr, len, | 268 | 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 | slot->skb = NULL; | 280 | slot->skb = NULL; |
285 | } | 281 | } |
286 | 282 | ||
287 | next: | ||
288 | slot->dma_addr = 0; | 283 | slot->dma_addr = 0; |
289 | if (++ring->start >= BGMAC_TX_RING_SLOTS) | 284 | ring->start++; |
290 | ring->start = 0; | ||
291 | freed = true; | 285 | freed = true; |
292 | } | 286 | } |
293 | 287 | ||
diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h index 3ad965fe7fcc..5a198d56f3e7 100644 --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h | |||
@@ -414,10 +414,10 @@ enum bgmac_dma_ring_type { | |||
414 | * empty. | 414 | * empty. |
415 | */ | 415 | */ |
416 | struct bgmac_dma_ring { | 416 | struct bgmac_dma_ring { |
417 | u16 num_slots; | 417 | u32 start; |
418 | u16 start; | 418 | u32 end; |
419 | u16 end; | ||
420 | 419 | ||
420 | u16 num_slots; | ||
421 | u16 mmio_base; | 421 | u16 mmio_base; |
422 | struct bgmac_dma_desc *cpu_base; | 422 | struct bgmac_dma_desc *cpu_base; |
423 | dma_addr_t dma_base; | 423 | dma_addr_t dma_base; |