xref: /linux/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c (revision 48dea9a700c8728cc31a1dd44588b97578de86ee)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* 10G controller driver for Samsung SoCs
3  *
4  * Copyright (C) 2013 Samsung Electronics Co., Ltd.
5  *		http://www.samsung.com
6  *
7  * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
8  */
9 
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11 
12 #include <linux/bitops.h>
13 #include <linux/export.h>
14 #include <linux/io.h>
15 #include <linux/netdevice.h>
16 #include <linux/phy.h>
17 
18 #include "sxgbe_common.h"
19 #include "sxgbe_dma.h"
20 #include "sxgbe_desc.h"
21 
22 /* DMA TX descriptor ring initialization */
23 static void sxgbe_init_tx_desc(struct sxgbe_tx_norm_desc *p)
24 {
25 	p->tdes23.tx_rd_des23.own_bit = 0;
26 }
27 
28 static void sxgbe_tx_desc_enable_tse(struct sxgbe_tx_norm_desc *p, u8 is_tse,
29 				     u32 total_hdr_len, u32 tcp_hdr_len,
30 				     u32 tcp_payload_len)
31 {
32 	p->tdes23.tx_rd_des23.tse_bit = is_tse;
33 	p->tdes23.tx_rd_des23.buf1_size = total_hdr_len;
34 	p->tdes23.tx_rd_des23.tcp_hdr_len = tcp_hdr_len / 4;
35 	p->tdes23.tx_rd_des23.tx_pkt_len.tcp_payload_len  = tcp_payload_len;
36 }
37 
38 /* Assign buffer lengths for descriptor */
39 static void sxgbe_prepare_tx_desc(struct sxgbe_tx_norm_desc *p, u8 is_fd,
40 				  int buf1_len, int pkt_len, int cksum)
41 {
42 	p->tdes23.tx_rd_des23.first_desc = is_fd;
43 	p->tdes23.tx_rd_des23.buf1_size = buf1_len;
44 
45 	p->tdes23.tx_rd_des23.tx_pkt_len.pkt_len.total_pkt_len = pkt_len;
46 
47 	if (cksum)
48 		p->tdes23.tx_rd_des23.cksum_ctl = cic_full;
49 }
50 
51 /* Set VLAN control information */
52 static void sxgbe_tx_vlanctl_desc(struct sxgbe_tx_norm_desc *p, int vlan_ctl)
53 {
54 	p->tdes23.tx_rd_des23.vlan_tag_ctl = vlan_ctl;
55 }
56 
57 /* Set the owner of Normal descriptor */
58 static void sxgbe_set_tx_owner(struct sxgbe_tx_norm_desc *p)
59 {
60 	p->tdes23.tx_rd_des23.own_bit = 1;
61 }
62 
63 /* Get the owner of Normal descriptor */
64 static int sxgbe_get_tx_owner(struct sxgbe_tx_norm_desc *p)
65 {
66 	return p->tdes23.tx_rd_des23.own_bit;
67 }
68 
69 /* Invoked by the xmit function to close the tx descriptor */
70 static void sxgbe_close_tx_desc(struct sxgbe_tx_norm_desc *p)
71 {
72 	p->tdes23.tx_rd_des23.last_desc = 1;
73 	p->tdes23.tx_rd_des23.int_on_com = 1;
74 }
75 
76 /* Clean the tx descriptor as soon as the tx irq is received */
77 static void sxgbe_release_tx_desc(struct sxgbe_tx_norm_desc *p)
78 {
79 	memset(p, 0, sizeof(*p));
80 }
81 
82 /* Clear interrupt on tx frame completion. When this bit is
83  * set an interrupt happens as soon as the frame is transmitted
84  */
85 static void sxgbe_clear_tx_ic(struct sxgbe_tx_norm_desc *p)
86 {
87 	p->tdes23.tx_rd_des23.int_on_com = 0;
88 }
89 
90 /* Last tx segment reports the transmit status */
91 static int sxgbe_get_tx_ls(struct sxgbe_tx_norm_desc *p)
92 {
93 	return p->tdes23.tx_rd_des23.last_desc;
94 }
95 
96 /* Get the buffer size from the descriptor */
97 static int sxgbe_get_tx_len(struct sxgbe_tx_norm_desc *p)
98 {
99 	return p->tdes23.tx_rd_des23.buf1_size;
100 }
101 
102 /* Set tx timestamp enable bit */
103 static void sxgbe_tx_enable_tstamp(struct sxgbe_tx_norm_desc *p)
104 {
105 	p->tdes23.tx_rd_des23.timestmp_enable = 1;
106 }
107 
108 /* get tx timestamp status */
109 static int sxgbe_get_tx_timestamp_status(struct sxgbe_tx_norm_desc *p)
110 {
111 	return p->tdes23.tx_rd_des23.timestmp_enable;
112 }
113 
114 /* TX Context Descripto Specific */
115 static void sxgbe_tx_ctxt_desc_set_ctxt(struct sxgbe_tx_ctxt_desc *p)
116 {
117 	p->ctxt_bit = 1;
118 }
119 
120 /* Set the owner of TX context descriptor */
121 static void sxgbe_tx_ctxt_desc_set_owner(struct sxgbe_tx_ctxt_desc *p)
122 {
123 	p->own_bit = 1;
124 }
125 
126 /* Get the owner of TX context descriptor */
127 static int sxgbe_tx_ctxt_desc_get_owner(struct sxgbe_tx_ctxt_desc *p)
128 {
129 	return p->own_bit;
130 }
131 
132 /* Set TX mss in TX context Descriptor */
133 static void sxgbe_tx_ctxt_desc_set_mss(struct sxgbe_tx_ctxt_desc *p, u16 mss)
134 {
135 	p->maxseg_size = mss;
136 }
137 
138 /* Get TX mss from TX context Descriptor */
139 static int sxgbe_tx_ctxt_desc_get_mss(struct sxgbe_tx_ctxt_desc *p)
140 {
141 	return p->maxseg_size;
142 }
143 
144 /* Set TX tcmssv in TX context Descriptor */
145 static void sxgbe_tx_ctxt_desc_set_tcmssv(struct sxgbe_tx_ctxt_desc *p)
146 {
147 	p->tcmssv = 1;
148 }
149 
150 /* Reset TX ostc in TX context Descriptor */
151 static void sxgbe_tx_ctxt_desc_reset_ostc(struct sxgbe_tx_ctxt_desc *p)
152 {
153 	p->ostc = 0;
154 }
155 
156 /* Set IVLAN information */
157 static void sxgbe_tx_ctxt_desc_set_ivlantag(struct sxgbe_tx_ctxt_desc *p,
158 					    int is_ivlanvalid, int ivlan_tag,
159 					    int ivlan_ctl)
160 {
161 	if (is_ivlanvalid) {
162 		p->ivlan_tag_valid = is_ivlanvalid;
163 		p->ivlan_tag = ivlan_tag;
164 		p->ivlan_tag_ctl = ivlan_ctl;
165 	}
166 }
167 
168 /* Return IVLAN Tag */
169 static int sxgbe_tx_ctxt_desc_get_ivlantag(struct sxgbe_tx_ctxt_desc *p)
170 {
171 	return p->ivlan_tag;
172 }
173 
174 /* Set VLAN Tag */
175 static void sxgbe_tx_ctxt_desc_set_vlantag(struct sxgbe_tx_ctxt_desc *p,
176 					   int is_vlanvalid, int vlan_tag)
177 {
178 	if (is_vlanvalid) {
179 		p->vltag_valid = is_vlanvalid;
180 		p->vlan_tag = vlan_tag;
181 	}
182 }
183 
184 /* Return VLAN Tag */
185 static int sxgbe_tx_ctxt_desc_get_vlantag(struct sxgbe_tx_ctxt_desc *p)
186 {
187 	return p->vlan_tag;
188 }
189 
190 /* Set Time stamp */
191 static void sxgbe_tx_ctxt_desc_set_tstamp(struct sxgbe_tx_ctxt_desc *p,
192 					  u8 ostc_enable, u64 tstamp)
193 {
194 	if (ostc_enable) {
195 		p->ostc = ostc_enable;
196 		p->tstamp_lo = (u32) tstamp;
197 		p->tstamp_hi = (u32) (tstamp>>32);
198 	}
199 }
200 /* Close TX context descriptor */
201 static void sxgbe_tx_ctxt_desc_close(struct sxgbe_tx_ctxt_desc *p)
202 {
203 	p->own_bit = 1;
204 }
205 
206 /* WB status of context descriptor */
207 static int sxgbe_tx_ctxt_desc_get_cde(struct sxgbe_tx_ctxt_desc *p)
208 {
209 	return p->ctxt_desc_err;
210 }
211 
212 /* DMA RX descriptor ring initialization */
213 static void sxgbe_init_rx_desc(struct sxgbe_rx_norm_desc *p, int disable_rx_ic,
214 			       int mode, int end)
215 {
216 	p->rdes23.rx_rd_des23.own_bit = 1;
217 	if (disable_rx_ic)
218 		p->rdes23.rx_rd_des23.int_on_com = disable_rx_ic;
219 }
220 
221 /* Get RX own bit */
222 static int sxgbe_get_rx_owner(struct sxgbe_rx_norm_desc *p)
223 {
224 	return p->rdes23.rx_rd_des23.own_bit;
225 }
226 
227 /* Set RX own bit */
228 static void sxgbe_set_rx_owner(struct sxgbe_rx_norm_desc *p)
229 {
230 	p->rdes23.rx_rd_des23.own_bit = 1;
231 }
232 
233 /* Set Interrupt on completion bit */
234 static void sxgbe_set_rx_int_on_com(struct sxgbe_rx_norm_desc *p)
235 {
236 	p->rdes23.rx_rd_des23.int_on_com = 1;
237 }
238 
239 /* Get the receive frame size */
240 static int sxgbe_get_rx_frame_len(struct sxgbe_rx_norm_desc *p)
241 {
242 	return p->rdes23.rx_wb_des23.pkt_len;
243 }
244 
245 /* Return first Descriptor status */
246 static int sxgbe_get_rx_fd_status(struct sxgbe_rx_norm_desc *p)
247 {
248 	return p->rdes23.rx_wb_des23.first_desc;
249 }
250 
251 /* Return Last Descriptor status */
252 static int sxgbe_get_rx_ld_status(struct sxgbe_rx_norm_desc *p)
253 {
254 	return p->rdes23.rx_wb_des23.last_desc;
255 }
256 
257 
258 /* Return the RX status looking at the WB fields */
259 static int sxgbe_rx_wbstatus(struct sxgbe_rx_norm_desc *p,
260 			     struct sxgbe_extra_stats *x, int *checksum)
261 {
262 	int status = 0;
263 
264 	*checksum = CHECKSUM_UNNECESSARY;
265 	if (p->rdes23.rx_wb_des23.err_summary) {
266 		switch (p->rdes23.rx_wb_des23.err_l2_type) {
267 		case RX_GMII_ERR:
268 			status = -EINVAL;
269 			x->rx_code_gmii_err++;
270 			break;
271 		case RX_WATCHDOG_ERR:
272 			status = -EINVAL;
273 			x->rx_watchdog_err++;
274 			break;
275 		case RX_CRC_ERR:
276 			status = -EINVAL;
277 			x->rx_crc_err++;
278 			break;
279 		case RX_GAINT_ERR:
280 			status = -EINVAL;
281 			x->rx_gaint_pkt_err++;
282 			break;
283 		case RX_IP_HDR_ERR:
284 			*checksum = CHECKSUM_NONE;
285 			x->ip_hdr_err++;
286 			break;
287 		case RX_PAYLOAD_ERR:
288 			*checksum = CHECKSUM_NONE;
289 			x->ip_payload_err++;
290 			break;
291 		case RX_OVERFLOW_ERR:
292 			status = -EINVAL;
293 			x->overflow_error++;
294 			break;
295 		default:
296 			pr_err("Invalid Error type\n");
297 			break;
298 		}
299 	} else {
300 		switch (p->rdes23.rx_wb_des23.err_l2_type) {
301 		case RX_LEN_PKT:
302 			x->len_pkt++;
303 			break;
304 		case RX_MACCTL_PKT:
305 			x->mac_ctl_pkt++;
306 			break;
307 		case RX_DCBCTL_PKT:
308 			x->dcb_ctl_pkt++;
309 			break;
310 		case RX_ARP_PKT:
311 			x->arp_pkt++;
312 			break;
313 		case RX_OAM_PKT:
314 			x->oam_pkt++;
315 			break;
316 		case RX_UNTAG_PKT:
317 			x->untag_okt++;
318 			break;
319 		case RX_OTHER_PKT:
320 			x->other_pkt++;
321 			break;
322 		case RX_SVLAN_PKT:
323 			x->svlan_tag_pkt++;
324 			break;
325 		case RX_CVLAN_PKT:
326 			x->cvlan_tag_pkt++;
327 			break;
328 		case RX_DVLAN_OCVLAN_ICVLAN_PKT:
329 			x->dvlan_ocvlan_icvlan_pkt++;
330 			break;
331 		case RX_DVLAN_OSVLAN_ISVLAN_PKT:
332 			x->dvlan_osvlan_isvlan_pkt++;
333 			break;
334 		case RX_DVLAN_OSVLAN_ICVLAN_PKT:
335 			x->dvlan_osvlan_icvlan_pkt++;
336 			break;
337 		case RX_DVLAN_OCVLAN_ISVLAN_PKT:
338 			x->dvlan_ocvlan_icvlan_pkt++;
339 			break;
340 		default:
341 			pr_err("Invalid L2 Packet type\n");
342 			break;
343 		}
344 	}
345 
346 	/* L3/L4 Pkt type */
347 	switch (p->rdes23.rx_wb_des23.layer34_pkt_type) {
348 	case RX_NOT_IP_PKT:
349 		x->not_ip_pkt++;
350 		break;
351 	case RX_IPV4_TCP_PKT:
352 		x->ip4_tcp_pkt++;
353 		break;
354 	case RX_IPV4_UDP_PKT:
355 		x->ip4_udp_pkt++;
356 		break;
357 	case RX_IPV4_ICMP_PKT:
358 		x->ip4_icmp_pkt++;
359 		break;
360 	case RX_IPV4_UNKNOWN_PKT:
361 		x->ip4_unknown_pkt++;
362 		break;
363 	case RX_IPV6_TCP_PKT:
364 		x->ip6_tcp_pkt++;
365 		break;
366 	case RX_IPV6_UDP_PKT:
367 		x->ip6_udp_pkt++;
368 		break;
369 	case RX_IPV6_ICMP_PKT:
370 		x->ip6_icmp_pkt++;
371 		break;
372 	case RX_IPV6_UNKNOWN_PKT:
373 		x->ip6_unknown_pkt++;
374 		break;
375 	default:
376 		pr_err("Invalid L3/L4 Packet type\n");
377 		break;
378 	}
379 
380 	/* Filter */
381 	if (p->rdes23.rx_wb_des23.vlan_filter_match)
382 		x->vlan_filter_match++;
383 
384 	if (p->rdes23.rx_wb_des23.sa_filter_fail) {
385 		status = -EINVAL;
386 		x->sa_filter_fail++;
387 	}
388 	if (p->rdes23.rx_wb_des23.da_filter_fail) {
389 		status = -EINVAL;
390 		x->da_filter_fail++;
391 	}
392 	if (p->rdes23.rx_wb_des23.hash_filter_pass)
393 		x->hash_filter_pass++;
394 
395 	if (p->rdes23.rx_wb_des23.l3_filter_match)
396 		x->l3_filter_match++;
397 
398 	if (p->rdes23.rx_wb_des23.l4_filter_match)
399 		x->l4_filter_match++;
400 
401 	return status;
402 }
403 
404 /* Get own bit of context descriptor */
405 static int sxgbe_get_rx_ctxt_owner(struct sxgbe_rx_ctxt_desc *p)
406 {
407 	return p->own_bit;
408 }
409 
410 /* Set own bit for context descriptor */
411 static void sxgbe_set_ctxt_rx_owner(struct sxgbe_rx_ctxt_desc *p)
412 {
413 	p->own_bit = 1;
414 }
415 
416 
417 /* Return the reception status looking at Context control information */
418 static void sxgbe_rx_ctxt_wbstatus(struct sxgbe_rx_ctxt_desc *p,
419 				   struct sxgbe_extra_stats *x)
420 {
421 	if (p->tstamp_dropped)
422 		x->timestamp_dropped++;
423 
424 	/* ptp */
425 	if (p->ptp_msgtype == RX_NO_PTP)
426 		x->rx_msg_type_no_ptp++;
427 	else if (p->ptp_msgtype == RX_PTP_SYNC)
428 		x->rx_ptp_type_sync++;
429 	else if (p->ptp_msgtype == RX_PTP_FOLLOW_UP)
430 		x->rx_ptp_type_follow_up++;
431 	else if (p->ptp_msgtype == RX_PTP_DELAY_REQ)
432 		x->rx_ptp_type_delay_req++;
433 	else if (p->ptp_msgtype == RX_PTP_DELAY_RESP)
434 		x->rx_ptp_type_delay_resp++;
435 	else if (p->ptp_msgtype == RX_PTP_PDELAY_REQ)
436 		x->rx_ptp_type_pdelay_req++;
437 	else if (p->ptp_msgtype == RX_PTP_PDELAY_RESP)
438 		x->rx_ptp_type_pdelay_resp++;
439 	else if (p->ptp_msgtype == RX_PTP_PDELAY_FOLLOW_UP)
440 		x->rx_ptp_type_pdelay_follow_up++;
441 	else if (p->ptp_msgtype == RX_PTP_ANNOUNCE)
442 		x->rx_ptp_announce++;
443 	else if (p->ptp_msgtype == RX_PTP_MGMT)
444 		x->rx_ptp_mgmt++;
445 	else if (p->ptp_msgtype == RX_PTP_SIGNAL)
446 		x->rx_ptp_signal++;
447 	else if (p->ptp_msgtype == RX_PTP_RESV_MSG)
448 		x->rx_ptp_resv_msg_type++;
449 }
450 
451 /* Get rx timestamp status */
452 static int sxgbe_get_rx_ctxt_tstamp_status(struct sxgbe_rx_ctxt_desc *p)
453 {
454 	if ((p->tstamp_hi == 0xffffffff) && (p->tstamp_lo == 0xffffffff)) {
455 		pr_err("Time stamp corrupted\n");
456 		return 0;
457 	}
458 
459 	return p->tstamp_available;
460 }
461 
462 
463 static u64 sxgbe_get_rx_timestamp(struct sxgbe_rx_ctxt_desc *p)
464 {
465 	u64 ns;
466 
467 	ns = p->tstamp_lo;
468 	ns |= ((u64)p->tstamp_hi) << 32;
469 
470 	return ns;
471 }
472 
473 static const struct sxgbe_desc_ops desc_ops = {
474 	.init_tx_desc			= sxgbe_init_tx_desc,
475 	.tx_desc_enable_tse		= sxgbe_tx_desc_enable_tse,
476 	.prepare_tx_desc		= sxgbe_prepare_tx_desc,
477 	.tx_vlanctl_desc		= sxgbe_tx_vlanctl_desc,
478 	.set_tx_owner			= sxgbe_set_tx_owner,
479 	.get_tx_owner			= sxgbe_get_tx_owner,
480 	.close_tx_desc			= sxgbe_close_tx_desc,
481 	.release_tx_desc		= sxgbe_release_tx_desc,
482 	.clear_tx_ic			= sxgbe_clear_tx_ic,
483 	.get_tx_ls			= sxgbe_get_tx_ls,
484 	.get_tx_len			= sxgbe_get_tx_len,
485 	.tx_enable_tstamp		= sxgbe_tx_enable_tstamp,
486 	.get_tx_timestamp_status	= sxgbe_get_tx_timestamp_status,
487 	.tx_ctxt_desc_set_ctxt		= sxgbe_tx_ctxt_desc_set_ctxt,
488 	.tx_ctxt_desc_set_owner		= sxgbe_tx_ctxt_desc_set_owner,
489 	.get_tx_ctxt_owner		= sxgbe_tx_ctxt_desc_get_owner,
490 	.tx_ctxt_desc_set_mss		= sxgbe_tx_ctxt_desc_set_mss,
491 	.tx_ctxt_desc_get_mss		= sxgbe_tx_ctxt_desc_get_mss,
492 	.tx_ctxt_desc_set_tcmssv	= sxgbe_tx_ctxt_desc_set_tcmssv,
493 	.tx_ctxt_desc_reset_ostc	= sxgbe_tx_ctxt_desc_reset_ostc,
494 	.tx_ctxt_desc_set_ivlantag	= sxgbe_tx_ctxt_desc_set_ivlantag,
495 	.tx_ctxt_desc_get_ivlantag	= sxgbe_tx_ctxt_desc_get_ivlantag,
496 	.tx_ctxt_desc_set_vlantag	= sxgbe_tx_ctxt_desc_set_vlantag,
497 	.tx_ctxt_desc_get_vlantag	= sxgbe_tx_ctxt_desc_get_vlantag,
498 	.tx_ctxt_set_tstamp		= sxgbe_tx_ctxt_desc_set_tstamp,
499 	.close_tx_ctxt_desc		= sxgbe_tx_ctxt_desc_close,
500 	.get_tx_ctxt_cde		= sxgbe_tx_ctxt_desc_get_cde,
501 	.init_rx_desc			= sxgbe_init_rx_desc,
502 	.get_rx_owner			= sxgbe_get_rx_owner,
503 	.set_rx_owner			= sxgbe_set_rx_owner,
504 	.set_rx_int_on_com		= sxgbe_set_rx_int_on_com,
505 	.get_rx_frame_len		= sxgbe_get_rx_frame_len,
506 	.get_rx_fd_status		= sxgbe_get_rx_fd_status,
507 	.get_rx_ld_status		= sxgbe_get_rx_ld_status,
508 	.rx_wbstatus			= sxgbe_rx_wbstatus,
509 	.get_rx_ctxt_owner		= sxgbe_get_rx_ctxt_owner,
510 	.set_rx_ctxt_owner		= sxgbe_set_ctxt_rx_owner,
511 	.rx_ctxt_wbstatus		= sxgbe_rx_ctxt_wbstatus,
512 	.get_rx_ctxt_tstamp_status	= sxgbe_get_rx_ctxt_tstamp_status,
513 	.get_timestamp			= sxgbe_get_rx_timestamp,
514 };
515 
516 const struct sxgbe_desc_ops *sxgbe_get_desc_ops(void)
517 {
518 	return &desc_ops;
519 }
520