OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From: Felix Fietkau <nbd@nbd.name> |
2 | Date: Sun, 12 Apr 2015 09:58:56 +0200 |
||
3 | Subject: [PATCH] bgmac: simplify tx ring index handling |
||
4 | |||
5 | Keep incrementing ring->start and ring->end instead of pointing it to |
||
6 | the actual ring slot entry. This simplifies the calculation of the |
||
7 | number of free slots. |
||
8 | |||
9 | Signed-off-by: Felix Fietkau <nbd@nbd.name> |
||
10 | --- |
||
11 | |||
12 | --- a/drivers/net/ethernet/broadcom/bgmac.c |
||
13 | +++ b/drivers/net/ethernet/broadcom/bgmac.c |
||
14 | @@ -142,11 +142,10 @@ static netdev_tx_t bgmac_dma_tx_add(stru |
||
15 | { |
||
16 | struct device *dma_dev = bgmac->core->dma_dev; |
||
17 | struct net_device *net_dev = bgmac->net_dev; |
||
18 | - struct bgmac_slot_info *slot = &ring->slots[ring->end]; |
||
19 | - int free_slots; |
||
20 | + int index = ring->end % BGMAC_TX_RING_SLOTS; |
||
21 | + struct bgmac_slot_info *slot = &ring->slots[index]; |
||
22 | int nr_frags; |
||
23 | u32 flags; |
||
24 | - int index = ring->end; |
||
25 | int i; |
||
26 | |||
27 | if (skb->len > BGMAC_DESC_CTL1_LEN) { |
||
28 | @@ -159,12 +158,10 @@ static netdev_tx_t bgmac_dma_tx_add(stru |
||
29 | |||
30 | nr_frags = skb_shinfo(skb)->nr_frags; |
||
31 | |||
32 | - if (ring->start <= ring->end) |
||
33 | - free_slots = ring->start - ring->end + BGMAC_TX_RING_SLOTS; |
||
34 | - else |
||
35 | - free_slots = ring->start - ring->end; |
||
36 | - |
||
37 | - if (free_slots <= nr_frags + 1) { |
||
38 | + /* ring->end - ring->start will return the number of valid slots, |
||
39 | + * even when ring->end overflows |
||
40 | + */ |
||
41 | + if (ring->end - ring->start + nr_frags + 1 >= BGMAC_TX_RING_SLOTS) { |
||
42 | bgmac_err(bgmac, "TX ring is full, queue should be stopped!\n"); |
||
43 | netif_stop_queue(net_dev); |
||
44 | return NETDEV_TX_BUSY; |
||
45 | @@ -200,7 +197,7 @@ static netdev_tx_t bgmac_dma_tx_add(stru |
||
46 | } |
||
47 | |||
48 | slot->skb = skb; |
||
49 | - |
||
50 | + ring->end += nr_frags + 1; |
||
51 | netdev_sent_queue(net_dev, skb->len); |
||
52 | |||
53 | wmb(); |
||
54 | @@ -208,13 +205,12 @@ static netdev_tx_t bgmac_dma_tx_add(stru |
||
55 | /* Increase ring->end to point empty slot. We tell hardware the first |
||
56 | * slot it should *not* read. |
||
57 | */ |
||
58 | - ring->end = (index + 1) % BGMAC_TX_RING_SLOTS; |
||
59 | bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX, |
||
60 | ring->index_base + |
||
61 | - ring->end * sizeof(struct bgmac_dma_desc)); |
||
62 | + (ring->end % BGMAC_TX_RING_SLOTS) * |
||
63 | + sizeof(struct bgmac_dma_desc)); |
||
64 | |||
65 | - free_slots -= nr_frags + 1; |
||
66 | - if (free_slots < 8) |
||
67 | + if (ring->end - ring->start >= BGMAC_TX_RING_SLOTS - 8) |
||
68 | netif_stop_queue(net_dev); |
||
69 | |||
70 | return NETDEV_TX_OK; |
||
71 | @@ -256,17 +252,17 @@ static void bgmac_dma_tx_free(struct bgm |
||
72 | empty_slot &= BGMAC_DMA_TX_STATDPTR; |
||
73 | empty_slot /= sizeof(struct bgmac_dma_desc); |
||
74 | |||
75 | - while (ring->start != empty_slot) { |
||
76 | - struct bgmac_slot_info *slot = &ring->slots[ring->start]; |
||
77 | - u32 ctl1 = le32_to_cpu(ring->cpu_base[ring->start].ctl1); |
||
78 | - int len = ctl1 & BGMAC_DESC_CTL1_LEN; |
||
79 | + while (ring->start != ring->end) { |
||
80 | + int slot_idx = ring->start % BGMAC_TX_RING_SLOTS; |
||
81 | + struct bgmac_slot_info *slot = &ring->slots[slot_idx]; |
||
82 | + u32 ctl1; |
||
83 | + int len; |
||
84 | |||
85 | - if (!slot->dma_addr) { |
||
86 | - bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n", |
||
87 | - ring->start, ring->end); |
||
88 | - goto next; |
||
89 | - } |
||
90 | + if (slot_idx == empty_slot) |
||
91 | + break; |
||
92 | |||
93 | + ctl1 = le32_to_cpu(ring->cpu_base[slot_idx].ctl1); |
||
94 | + len = ctl1 & BGMAC_DESC_CTL1_LEN; |
||
95 | if (ctl1 & BGMAC_DESC_CTL0_SOF) |
||
96 | /* Unmap no longer used buffer */ |
||
97 | dma_unmap_single(dma_dev, slot->dma_addr, len, |
||
98 | @@ -284,10 +280,8 @@ static void bgmac_dma_tx_free(struct bgm |
||
99 | slot->skb = NULL; |
||
100 | } |
||
101 | |||
102 | -next: |
||
103 | slot->dma_addr = 0; |
||
104 | - if (++ring->start >= BGMAC_TX_RING_SLOTS) |
||
105 | - ring->start = 0; |
||
106 | + ring->start++; |
||
107 | freed = true; |
||
108 | } |
||
109 | |||
110 | --- a/drivers/net/ethernet/broadcom/bgmac.h |
||
111 | +++ b/drivers/net/ethernet/broadcom/bgmac.h |
||
112 | @@ -414,10 +414,10 @@ enum bgmac_dma_ring_type { |
||
113 | * empty. |
||
114 | */ |
||
115 | struct bgmac_dma_ring { |
||
116 | - u16 num_slots; |
||
117 | - u16 start; |
||
118 | - u16 end; |
||
119 | + u32 start; |
||
120 | + u32 end; |
||
121 | |||
122 | + u16 num_slots; |
||
123 | u16 mmio_base; |
||
124 | struct bgmac_dma_desc *cpu_base; |
||
125 | dma_addr_t dma_base; |