xref: /linux/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c (revision e7e86d7697c6ed1dbbde18d7185c35b6967945ed)
1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /*
3  * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
4  * stmmac XGMAC support.
5  */
6 
7 #include <linux/bitfield.h>
8 #include <linux/stmmac.h>
9 #include "common.h"
10 #include "dwxgmac2.h"
11 
12 static int dwxgmac2_get_tx_status(struct stmmac_extra_stats *x,
13 				  struct dma_desc *p, void __iomem *ioaddr)
14 {
15 	unsigned int tdes3 = le32_to_cpu(p->des3);
16 	int ret = tx_done;
17 
18 	if (unlikely(tdes3 & XGMAC_TDES3_OWN))
19 		return tx_dma_own;
20 	if (likely(!(tdes3 & XGMAC_TDES3_LD)))
21 		return tx_not_ls;
22 
23 	return ret;
24 }
25 
26 static int dwxgmac2_get_rx_status(struct stmmac_extra_stats *x,
27 				  struct dma_desc *p)
28 {
29 	unsigned int rdes3 = le32_to_cpu(p->des3);
30 
31 	if (unlikely(rdes3 & XGMAC_RDES3_OWN))
32 		return dma_own;
33 	if (unlikely(rdes3 & XGMAC_RDES3_CTXT))
34 		return discard_frame;
35 	if (likely(!(rdes3 & XGMAC_RDES3_LD)))
36 		return rx_not_ls;
37 	if (unlikely((rdes3 & XGMAC_RDES3_ES) && (rdes3 & XGMAC_RDES3_LD)))
38 		return discard_frame;
39 
40 	return good_frame;
41 }
42 
43 static int dwxgmac2_get_tx_len(struct dma_desc *p)
44 {
45 	return (le32_to_cpu(p->des2) & XGMAC_TDES2_B1L);
46 }
47 
48 static int dwxgmac2_get_tx_owner(struct dma_desc *p)
49 {
50 	return (le32_to_cpu(p->des3) & XGMAC_TDES3_OWN) > 0;
51 }
52 
53 static void dwxgmac2_set_tx_owner(struct dma_desc *p)
54 {
55 	p->des3 |= cpu_to_le32(XGMAC_TDES3_OWN);
56 }
57 
58 static void dwxgmac2_set_rx_owner(struct dma_desc *p, int disable_rx_ic)
59 {
60 	u32 flags = XGMAC_RDES3_OWN;
61 
62 	if (!disable_rx_ic)
63 		flags |= XGMAC_RDES3_IOC;
64 
65 	p->des3 |= cpu_to_le32(flags);
66 }
67 
68 static int dwxgmac2_get_tx_ls(struct dma_desc *p)
69 {
70 	return (le32_to_cpu(p->des3) & XGMAC_RDES3_LD) > 0;
71 }
72 
73 static u16 dwxgmac2_wrback_get_rx_vlan_tci(struct dma_desc *p)
74 {
75 	return le32_to_cpu(p->des0) & XGMAC_RDES0_VLAN_TAG_MASK;
76 }
77 
78 static bool dwxgmac2_wrback_get_rx_vlan_valid(struct dma_desc *p)
79 {
80 	u32 et_lt;
81 
82 	et_lt = FIELD_GET(XGMAC_RDES3_ET_LT, le32_to_cpu(p->des3));
83 
84 	return et_lt >= XGMAC_ET_LT_VLAN_STAG &&
85 	       et_lt <= XGMAC_ET_LT_DVLAN_STAG_CTAG;
86 }
87 
88 static int dwxgmac2_get_rx_frame_len(struct dma_desc *p, int rx_coe)
89 {
90 	return (le32_to_cpu(p->des3) & XGMAC_RDES3_PL);
91 }
92 
93 static void dwxgmac2_enable_tx_timestamp(struct dma_desc *p)
94 {
95 	p->des2 |= cpu_to_le32(XGMAC_TDES2_TTSE);
96 }
97 
98 static int dwxgmac2_get_tx_timestamp_status(struct dma_desc *p)
99 {
100 	return 0; /* Not supported */
101 }
102 
103 static inline void dwxgmac2_get_timestamp(void *desc, u32 ats, u64 *ts)
104 {
105 	struct dma_desc *p = (struct dma_desc *)desc;
106 	u64 ns = 0;
107 
108 	ns += le32_to_cpu(p->des1) * 1000000000ULL;
109 	ns += le32_to_cpu(p->des0);
110 
111 	*ts = ns;
112 }
113 
114 static int dwxgmac2_rx_check_timestamp(void *desc)
115 {
116 	struct dma_desc *p = (struct dma_desc *)desc;
117 	unsigned int rdes3 = le32_to_cpu(p->des3);
118 	bool desc_valid, ts_valid;
119 
120 	dma_rmb();
121 
122 	desc_valid = !(rdes3 & XGMAC_RDES3_OWN) && (rdes3 & XGMAC_RDES3_CTXT);
123 	ts_valid = !(rdes3 & XGMAC_RDES3_TSD) && (rdes3 & XGMAC_RDES3_TSA);
124 
125 	if (likely(desc_valid && ts_valid)) {
126 		if ((p->des0 == 0xffffffff) && (p->des1 == 0xffffffff))
127 			return -EINVAL;
128 		return 0;
129 	}
130 
131 	return -EINVAL;
132 }
133 
134 static int dwxgmac2_get_rx_timestamp_status(void *desc, void *next_desc,
135 					    u32 ats)
136 {
137 	struct dma_desc *p = (struct dma_desc *)desc;
138 	unsigned int rdes3 = le32_to_cpu(p->des3);
139 	int ret = -EBUSY;
140 
141 	if (likely(rdes3 & XGMAC_RDES3_CDA))
142 		ret = dwxgmac2_rx_check_timestamp(next_desc);
143 
144 	return !ret;
145 }
146 
147 static void dwxgmac2_init_rx_desc(struct dma_desc *p, int disable_rx_ic,
148 				  int mode, int end, int bfsize)
149 {
150 	dwxgmac2_set_rx_owner(p, disable_rx_ic);
151 }
152 
153 static void dwxgmac2_init_tx_desc(struct dma_desc *p, int mode, int end)
154 {
155 	p->des0 = 0;
156 	p->des1 = 0;
157 	p->des2 = 0;
158 	p->des3 = 0;
159 }
160 
161 static void dwxgmac2_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
162 				     bool csum_flag, int mode, bool tx_own,
163 				     bool ls, unsigned int tot_pkt_len)
164 {
165 	unsigned int tdes3 = le32_to_cpu(p->des3);
166 
167 	p->des2 |= cpu_to_le32(len & XGMAC_TDES2_B1L);
168 
169 	tdes3 |= tot_pkt_len & XGMAC_TDES3_FL;
170 	if (is_fs)
171 		tdes3 |= XGMAC_TDES3_FD;
172 	else
173 		tdes3 &= ~XGMAC_TDES3_FD;
174 
175 	if (csum_flag)
176 		tdes3 |= 0x3 << XGMAC_TDES3_CIC_SHIFT;
177 	else
178 		tdes3 &= ~XGMAC_TDES3_CIC;
179 
180 	if (ls)
181 		tdes3 |= XGMAC_TDES3_LD;
182 	else
183 		tdes3 &= ~XGMAC_TDES3_LD;
184 
185 	/* Finally set the OWN bit. Later the DMA will start! */
186 	if (tx_own)
187 		tdes3 |= XGMAC_TDES3_OWN;
188 
189 	if (is_fs && tx_own)
190 		/* When the own bit, for the first frame, has to be set, all
191 		 * descriptors for the same frame has to be set before, to
192 		 * avoid race condition.
193 		 */
194 		dma_wmb();
195 
196 	p->des3 = cpu_to_le32(tdes3);
197 }
198 
199 static void dwxgmac2_prepare_tso_tx_desc(struct dma_desc *p, int is_fs,
200 					 int len1, int len2, bool tx_own,
201 					 bool ls, unsigned int tcphdrlen,
202 					 unsigned int tcppayloadlen)
203 {
204 	unsigned int tdes3 = le32_to_cpu(p->des3);
205 
206 	if (len1)
207 		p->des2 |= cpu_to_le32(len1 & XGMAC_TDES2_B1L);
208 	if (len2)
209 		p->des2 |= cpu_to_le32((len2 << XGMAC_TDES2_B2L_SHIFT) &
210 				XGMAC_TDES2_B2L);
211 	if (is_fs) {
212 		tdes3 |= XGMAC_TDES3_FD | XGMAC_TDES3_TSE;
213 		tdes3 |= (tcphdrlen << XGMAC_TDES3_THL_SHIFT) &
214 			XGMAC_TDES3_THL;
215 		tdes3 |= tcppayloadlen & XGMAC_TDES3_TPL;
216 	} else {
217 		tdes3 &= ~XGMAC_TDES3_FD;
218 	}
219 
220 	if (ls)
221 		tdes3 |= XGMAC_TDES3_LD;
222 	else
223 		tdes3 &= ~XGMAC_TDES3_LD;
224 
225 	/* Finally set the OWN bit. Later the DMA will start! */
226 	if (tx_own)
227 		tdes3 |= XGMAC_TDES3_OWN;
228 
229 	if (is_fs && tx_own)
230 		/* When the own bit, for the first frame, has to be set, all
231 		 * descriptors for the same frame has to be set before, to
232 		 * avoid race condition.
233 		 */
234 		dma_wmb();
235 
236 	p->des3 = cpu_to_le32(tdes3);
237 }
238 
239 static void dwxgmac2_release_tx_desc(struct dma_desc *p, int mode)
240 {
241 	p->des0 = 0;
242 	p->des1 = 0;
243 	p->des2 = 0;
244 	p->des3 = 0;
245 }
246 
247 static void dwxgmac2_set_tx_ic(struct dma_desc *p)
248 {
249 	p->des2 |= cpu_to_le32(XGMAC_TDES2_IOC);
250 }
251 
252 static void dwxgmac2_set_mss(struct dma_desc *p, unsigned int mss)
253 {
254 	p->des0 = 0;
255 	p->des1 = 0;
256 	p->des2 = cpu_to_le32(mss);
257 	p->des3 = cpu_to_le32(XGMAC_TDES3_CTXT | XGMAC_TDES3_TCMSSV);
258 }
259 
260 static void dwxgmac2_set_addr(struct dma_desc *p, dma_addr_t addr)
261 {
262 	p->des0 = cpu_to_le32(lower_32_bits(addr));
263 	p->des1 = cpu_to_le32(upper_32_bits(addr));
264 }
265 
266 static void dwxgmac2_clear(struct dma_desc *p)
267 {
268 	p->des0 = 0;
269 	p->des1 = 0;
270 	p->des2 = 0;
271 	p->des3 = 0;
272 }
273 
274 static int dwxgmac2_get_rx_hash(struct dma_desc *p, u32 *hash,
275 				enum pkt_hash_types *type)
276 {
277 	unsigned int rdes3 = le32_to_cpu(p->des3);
278 	u32 ptype;
279 
280 	if (rdes3 & XGMAC_RDES3_RSV) {
281 		ptype = (rdes3 & XGMAC_RDES3_L34T) >> XGMAC_RDES3_L34T_SHIFT;
282 
283 		switch (ptype) {
284 		case XGMAC_L34T_IP4TCP:
285 		case XGMAC_L34T_IP4UDP:
286 		case XGMAC_L34T_IP6TCP:
287 		case XGMAC_L34T_IP6UDP:
288 			*type = PKT_HASH_TYPE_L4;
289 			break;
290 		default:
291 			*type = PKT_HASH_TYPE_L3;
292 			break;
293 		}
294 
295 		*hash = le32_to_cpu(p->des1);
296 		return 0;
297 	}
298 
299 	return -EINVAL;
300 }
301 
302 static void dwxgmac2_get_rx_header_len(struct dma_desc *p, unsigned int *len)
303 {
304 	if (le32_to_cpu(p->des3) & XGMAC_RDES3_L34T)
305 		*len = le32_to_cpu(p->des2) & XGMAC_RDES2_HL;
306 }
307 
308 static void dwxgmac2_set_sec_addr(struct dma_desc *p, dma_addr_t addr, bool is_valid)
309 {
310 	p->des2 = cpu_to_le32(lower_32_bits(addr));
311 	p->des3 = cpu_to_le32(upper_32_bits(addr));
312 }
313 
314 static void dwxgmac2_set_sarc(struct dma_desc *p, u32 sarc_type)
315 {
316 	sarc_type <<= XGMAC_TDES3_SAIC_SHIFT;
317 
318 	p->des3 |= cpu_to_le32(sarc_type & XGMAC_TDES3_SAIC);
319 }
320 
321 static void dwxgmac2_set_vlan_tag(struct dma_desc *p, u16 tag, u16 inner_tag,
322 				  u32 inner_type)
323 {
324 	p->des0 = 0;
325 	p->des1 = 0;
326 	p->des2 = 0;
327 	p->des3 = 0;
328 
329 	/* Inner VLAN */
330 	if (inner_type) {
331 		u32 des = inner_tag << XGMAC_TDES2_IVT_SHIFT;
332 
333 		des &= XGMAC_TDES2_IVT;
334 		p->des2 = cpu_to_le32(des);
335 
336 		des = inner_type << XGMAC_TDES3_IVTIR_SHIFT;
337 		des &= XGMAC_TDES3_IVTIR;
338 		p->des3 = cpu_to_le32(des | XGMAC_TDES3_IVLTV);
339 	}
340 
341 	/* Outer VLAN */
342 	p->des3 |= cpu_to_le32(tag & XGMAC_TDES3_VT);
343 	p->des3 |= cpu_to_le32(XGMAC_TDES3_VLTV);
344 
345 	p->des3 |= cpu_to_le32(XGMAC_TDES3_CTXT);
346 }
347 
348 static void dwxgmac2_set_vlan(struct dma_desc *p, u32 type)
349 {
350 	type <<= XGMAC_TDES2_VTIR_SHIFT;
351 	p->des2 |= cpu_to_le32(type & XGMAC_TDES2_VTIR);
352 }
353 
354 static void dwxgmac2_set_tbs(struct dma_edesc *p, u32 sec, u32 nsec)
355 {
356 	p->des4 = cpu_to_le32((sec & XGMAC_TDES0_LT) | XGMAC_TDES0_LTV);
357 	p->des5 = cpu_to_le32(nsec & XGMAC_TDES1_LT);
358 	p->des6 = 0;
359 	p->des7 = 0;
360 }
361 
362 const struct stmmac_desc_ops dwxgmac210_desc_ops = {
363 	.tx_status = dwxgmac2_get_tx_status,
364 	.rx_status = dwxgmac2_get_rx_status,
365 	.get_tx_len = dwxgmac2_get_tx_len,
366 	.get_tx_owner = dwxgmac2_get_tx_owner,
367 	.set_tx_owner = dwxgmac2_set_tx_owner,
368 	.set_rx_owner = dwxgmac2_set_rx_owner,
369 	.get_tx_ls = dwxgmac2_get_tx_ls,
370 	.get_rx_vlan_tci = dwxgmac2_wrback_get_rx_vlan_tci,
371 	.get_rx_vlan_valid = dwxgmac2_wrback_get_rx_vlan_valid,
372 	.get_rx_frame_len = dwxgmac2_get_rx_frame_len,
373 	.enable_tx_timestamp = dwxgmac2_enable_tx_timestamp,
374 	.get_tx_timestamp_status = dwxgmac2_get_tx_timestamp_status,
375 	.get_rx_timestamp_status = dwxgmac2_get_rx_timestamp_status,
376 	.get_timestamp = dwxgmac2_get_timestamp,
377 	.set_tx_ic = dwxgmac2_set_tx_ic,
378 	.prepare_tx_desc = dwxgmac2_prepare_tx_desc,
379 	.prepare_tso_tx_desc = dwxgmac2_prepare_tso_tx_desc,
380 	.release_tx_desc = dwxgmac2_release_tx_desc,
381 	.init_rx_desc = dwxgmac2_init_rx_desc,
382 	.init_tx_desc = dwxgmac2_init_tx_desc,
383 	.set_mss = dwxgmac2_set_mss,
384 	.set_addr = dwxgmac2_set_addr,
385 	.clear = dwxgmac2_clear,
386 	.get_rx_hash = dwxgmac2_get_rx_hash,
387 	.get_rx_header_len = dwxgmac2_get_rx_header_len,
388 	.set_sec_addr = dwxgmac2_set_sec_addr,
389 	.set_sarc = dwxgmac2_set_sarc,
390 	.set_vlan_tag = dwxgmac2_set_vlan_tag,
391 	.set_vlan = dwxgmac2_set_vlan,
392 	.set_tbs = dwxgmac2_set_tbs,
393 };
394