1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#include "stmmac.h"
30
31static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
32{
33 struct stmmac_priv *priv = (struct stmmac_priv *)p;
34 unsigned int txsize = priv->dma_tx_size;
35 unsigned int entry = priv->cur_tx % txsize;
36 struct dma_desc *desc;
37 unsigned int nopaged_len = skb_headlen(skb);
38 unsigned int bmax, len;
39
40 if (priv->extend_desc)
41 desc = (struct dma_desc *)(priv->dma_etx + entry);
42 else
43 desc = priv->dma_tx + entry;
44
45 if (priv->plat->enh_desc)
46 bmax = BUF_SIZE_8KiB;
47 else
48 bmax = BUF_SIZE_2KiB;
49
50 len = nopaged_len - bmax;
51
52 if (nopaged_len > BUF_SIZE_8KiB) {
53
54 desc->des2 = dma_map_single(priv->device, skb->data,
55 bmax, DMA_TO_DEVICE);
56 priv->tx_skbuff_dma[entry] = desc->des2;
57 desc->des3 = desc->des2 + BUF_SIZE_4KiB;
58 priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum,
59 STMMAC_RING_MODE);
60 wmb();
61 priv->tx_skbuff[entry] = NULL;
62 entry = (++priv->cur_tx) % txsize;
63
64 if (priv->extend_desc)
65 desc = (struct dma_desc *)(priv->dma_etx + entry);
66 else
67 desc = priv->dma_tx + entry;
68
69 desc->des2 = dma_map_single(priv->device, skb->data + bmax,
70 len, DMA_TO_DEVICE);
71 priv->tx_skbuff_dma[entry] = desc->des2;
72 desc->des3 = desc->des2 + BUF_SIZE_4KiB;
73 priv->hw->desc->prepare_tx_desc(desc, 0, len, csum,
74 STMMAC_RING_MODE);
75 wmb();
76 priv->hw->desc->set_tx_owner(desc);
77 } else {
78 desc->des2 = dma_map_single(priv->device, skb->data,
79 nopaged_len, DMA_TO_DEVICE);
80 priv->tx_skbuff_dma[entry] = desc->des2;
81 desc->des3 = desc->des2 + BUF_SIZE_4KiB;
82 priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, csum,
83 STMMAC_RING_MODE);
84 }
85
86 return entry;
87}
88
89static unsigned int stmmac_is_jumbo_frm(int len, int enh_desc)
90{
91 unsigned int ret = 0;
92
93 if (len >= BUF_SIZE_4KiB)
94 ret = 1;
95
96 return ret;
97}
98
99static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p)
100{
101 struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr;
102
103
104 if (priv->dma_buf_sz >= BUF_SIZE_8KiB)
105 p->des3 = p->des2 + BUF_SIZE_8KiB;
106}
107
108
109static void stmmac_init_desc3(struct dma_desc *p)
110{
111 p->des3 = p->des2 + BUF_SIZE_8KiB;
112}
113
114static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p)
115{
116 if (unlikely(p->des3))
117 p->des3 = 0;
118}
119
120static int stmmac_set_16kib_bfsize(int mtu)
121{
122 int ret = 0;
123 if (unlikely(mtu >= BUF_SIZE_8KiB))
124 ret = BUF_SIZE_16KiB;
125 return ret;
126}
127
128const struct stmmac_mode_ops ring_mode_ops = {
129 .is_jumbo_frm = stmmac_is_jumbo_frm,
130 .jumbo_frm = stmmac_jumbo_frm,
131 .refill_desc3 = stmmac_refill_desc3,
132 .init_desc3 = stmmac_init_desc3,
133 .clean_desc3 = stmmac_clean_desc3,
134 .set_16kib_bfsize = stmmac_set_16kib_bfsize,
135};
136