OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From f974e397b806f7b16d11cc1542538616291924f1 Mon Sep 17 00:00:00 2001 |
2 | From: John Crispin <john@phrozen.org> |
||
3 | Date: Sat, 23 Apr 2016 11:57:21 +0200 |
||
4 | Subject: [PATCH 27/57] net-next: mediatek: fix DQL support |
||
5 | |||
6 | The MTK ethernet core has 2 MACs both sitting on the same DMA ring. The |
||
7 | current code will assign the TX traffic of each MAC to its own DQL. This |
||
8 | results in the amount of data, that DQL says is in the queue incorrect. As |
||
9 | the data from multiple devices is infact enqueued. This makes any decision |
||
10 | based on these value non deterministic. Fix this by tracking all TX |
||
11 | traffic, regardless of the MAC it belongs to in the DQL of all devices |
||
12 | using the DMA. |
||
13 | |||
14 | Signed-off-by: John Crispin <john@phrozen.org> |
||
15 | --- |
||
16 | drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 +++++++++++++++++------------ |
||
17 | 1 file changed, 21 insertions(+), 14 deletions(-) |
||
18 | |||
19 | --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c |
||
20 | +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c |
||
21 | @@ -779,7 +779,16 @@ static int mtk_tx_map(struct sk_buff *sk |
||
22 | WRITE_ONCE(itxd->txd3, (TX_DMA_SWC | TX_DMA_PLEN0(skb_headlen(skb)) | |
||
23 | (!nr_frags * TX_DMA_LS0))); |
||
24 | |||
25 | - netdev_sent_queue(dev, skb->len); |
||
26 | + /* we have a single DMA ring so BQL needs to be updated for all devices |
||
27 | + * sitting on this ring |
||
28 | + */ |
||
29 | + for (i = 0; i < MTK_MAC_COUNT; i++) { |
||
30 | + if (!eth->netdev[i]) |
||
31 | + continue; |
||
32 | + |
||
33 | + netdev_sent_queue(eth->netdev[i], skb->len); |
||
34 | + } |
||
35 | + |
||
36 | skb_tx_timestamp(skb); |
||
37 | |||
38 | ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2); |
||
39 | @@ -1076,20 +1085,17 @@ static int mtk_poll_tx(struct mtk_eth *e |
||
40 | struct mtk_tx_dma *desc; |
||
41 | struct sk_buff *skb; |
||
42 | struct mtk_tx_buf *tx_buf; |
||
43 | - unsigned int done[MTK_MAX_DEVS]; |
||
44 | - unsigned int bytes[MTK_MAX_DEVS]; |
||
45 | + int total = 0, done = 0; |
||
46 | + unsigned int bytes = 0; |
||
47 | u32 cpu, dma; |
||
48 | - int total = 0, i; |
||
49 | - |
||
50 | - memset(done, 0, sizeof(done)); |
||
51 | - memset(bytes, 0, sizeof(bytes)); |
||
52 | + int i; |
||
53 | |||
54 | cpu = mtk_r32(eth, MTK_QTX_CRX_PTR); |
||
55 | dma = mtk_r32(eth, MTK_QTX_DRX_PTR); |
||
56 | |||
57 | desc = mtk_qdma_phys_to_virt(ring, cpu); |
||
58 | |||
59 | - while ((cpu != dma) && budget) { |
||
60 | + while ((cpu != dma) && (done < budget)) { |
||
61 | u32 next_cpu = desc->txd2; |
||
62 | int mac = 0; |
||
63 | |||
64 | @@ -1106,9 +1112,8 @@ static int mtk_poll_tx(struct mtk_eth *e |
||
65 | break; |
||
66 | |||
67 | if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) { |
||
68 | - bytes[mac] += skb->len; |
||
69 | - done[mac]++; |
||
70 | - budget--; |
||
71 | + bytes += skb->len; |
||
72 | + done++; |
||
73 | } |
||
74 | mtk_tx_unmap(eth, tx_buf); |
||
75 | |||
76 | @@ -1120,11 +1125,13 @@ static int mtk_poll_tx(struct mtk_eth *e |
||
77 | |||
78 | mtk_w32(eth, cpu, MTK_QTX_CRX_PTR); |
||
79 | |||
80 | + /* we have a single DMA ring so BQL needs to be updated for all devices |
||
81 | + * sitting on this ring |
||
82 | + */ |
||
83 | for (i = 0; i < MTK_MAC_COUNT; i++) { |
||
84 | - if (!eth->netdev[i] || !done[i]) |
||
85 | + if (!eth->netdev[i]) |
||
86 | continue; |
||
87 | - netdev_completed_queue(eth->netdev[i], done[i], bytes[i]); |
||
88 | - total += done[i]; |
||
89 | + netdev_completed_queue(eth->netdev[i], done, bytes); |
||
90 | } |
||
91 | |||
92 | if (mtk_queue_stopped(eth) && |