1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2014
4  * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
5  */
6 
7 #include <common.h>
8 #include <command.h>
9 #include <console.h>
10 #include <linux/bitops.h>
11 #include <linux/delay.h>
12 
13 #include <gdsys_fpga.h>
14 
15 #ifndef CONFIG_GDSYS_LEGACY_DRIVERS
16 #include <dm.h>
17 #include <misc.h>
18 #include <regmap.h>
19 #include <sysinfo.h>
20 
21 #include "../../../drivers/misc/gdsys_soc.h"
22 #include "../../../drivers/misc/gdsys_ioep.h"
23 #include "../../../drivers/misc/ihs_fpga.h"
24 
25 const int HEADER_WORDS = sizeof(struct io_generic_packet) / 2;
26 #endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
27 
28 enum status_print_type {
29 	STATUS_LOUD = 0,
30 	STATUS_SILENT = 1,
31 };
32 
33 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
34 enum {
35 	STATE_TX_PACKET_BUILDING = BIT(0),
36 	STATE_TX_TRANSMITTING = BIT(1),
37 	STATE_TX_BUFFER_FULL = BIT(2),
38 	STATE_TX_ERR = BIT(3),
39 	STATE_RECEIVE_TIMEOUT = BIT(4),
40 	STATE_PROC_RX_STORE_TIMEOUT = BIT(5),
41 	STATE_PROC_RX_RECEIVE_TIMEOUT = BIT(6),
42 	STATE_RX_DIST_ERR = BIT(7),
43 	STATE_RX_LENGTH_ERR = BIT(8),
44 	STATE_RX_FRAME_CTR_ERR = BIT(9),
45 	STATE_RX_FCS_ERR = BIT(10),
46 	STATE_RX_PACKET_DROPPED = BIT(11),
47 	STATE_RX_DATA_LAST = BIT(12),
48 	STATE_RX_DATA_FIRST = BIT(13),
49 	STATE_RX_DATA_AVAILABLE = BIT(15),
50 };
51 
52 enum {
53 	IRQ_CPU_TRANSMITBUFFER_FREE_STATUS = BIT(5),
54 	IRQ_CPU_PACKET_TRANSMITTED_EVENT = BIT(6),
55 	IRQ_NEW_CPU_PACKET_RECEIVED_EVENT = BIT(7),
56 	IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS = BIT(8),
57 };
58 
59 enum {
60 	CTRL_PROC_RECEIVE_ENABLE = BIT(12),
61 	CTRL_FLUSH_TRANSMIT_BUFFER = BIT(15),
62 };
63 
64 struct io_generic_packet {
65 	u16 target_address;
66 	u16 source_address;
67 	u8 packet_type;
68 	u8 bc;
69 	u16 packet_length;
70 } __attribute__((__packed__));
71 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
72 
73 unsigned long long rx_ctr;
74 unsigned long long tx_ctr;
75 unsigned long long err_ctr;
76 #ifndef CONFIG_GDSYS_LEGACY_DRIVERS
77 struct udevice *dev;
78 #endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
79 
80 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
io_check_status(uint fpga,u16 status,enum status_print_type type)81 static void io_check_status(uint fpga, u16 status, enum status_print_type type)
82 {
83 	u16 mask = STATE_RX_DIST_ERR | STATE_RX_LENGTH_ERR |
84 		   STATE_RX_FRAME_CTR_ERR | STATE_RX_FCS_ERR |
85 		   STATE_RX_PACKET_DROPPED | STATE_TX_ERR;
86 
87 	if (!(status & mask)) {
88 		FPGA_SET_REG(fpga, ep.rx_tx_status, status);
89 		return;
90 	}
91 
92 	err_ctr++;
93 	FPGA_SET_REG(fpga, ep.rx_tx_status, status);
94 
95 	if (type == STATUS_SILENT)
96 		return;
97 
98 	if (status & STATE_RX_PACKET_DROPPED)
99 		printf("RX_PACKET_DROPPED, status %04x\n", status);
100 
101 	if (status & STATE_RX_DIST_ERR)
102 		printf("RX_DIST_ERR\n");
103 	if (status & STATE_RX_LENGTH_ERR)
104 		printf("RX_LENGTH_ERR\n");
105 	if (status & STATE_RX_FRAME_CTR_ERR)
106 		printf("RX_FRAME_CTR_ERR\n");
107 	if (status & STATE_RX_FCS_ERR)
108 		printf("RX_FCS_ERR\n");
109 
110 	if (status & STATE_TX_ERR)
111 		printf("TX_ERR\n");
112 }
113 #else
io_check_status(struct udevice * dev,enum status_print_type type)114 static void io_check_status(struct udevice *dev, enum status_print_type type)
115 {
116 	u16 status = 0;
117 	int ret;
118 
119 	ret = misc_call(dev, 0, NULL, 0, &status, 0);
120 	if (!ret)
121 		return;
122 
123 	err_ctr++;
124 
125 	if (type != STATUS_LOUD)
126 		return;
127 
128 	if (status & STATE_RX_PACKET_DROPPED)
129 		printf("RX_PACKET_DROPPED, status %04x\n", status);
130 
131 	if (status & STATE_RX_DIST_ERR)
132 		printf("RX_DIST_ERR\n");
133 	if (status & STATE_RX_LENGTH_ERR)
134 		printf("RX_LENGTH_ERR\n");
135 	if (status & STATE_RX_FRAME_CTR_ERR)
136 		printf("RX_FRAME_CTR_ERR\n");
137 	if (status & STATE_RX_FCS_ERR)
138 		printf("RX_FCS_ERR\n");
139 
140 	if (status & STATE_TX_ERR)
141 		printf("TX_ERR\n");
142 }
143 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
144 
145 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
io_send(uint fpga,uint size)146 static void io_send(uint fpga, uint size)
147 {
148 	uint k;
149 	struct io_generic_packet packet = {
150 		.source_address = 1,
151 		.packet_type = 1,
152 		.packet_length = size,
153 	};
154 	u16 *p = (u16 *)&packet;
155 
156 	for (k = 0; k < sizeof(packet) / 2; ++k)
157 		FPGA_SET_REG(fpga, ep.transmit_data, *p++);
158 
159 	for (k = 0; k < (size + 1) / 2; ++k)
160 		FPGA_SET_REG(fpga, ep.transmit_data, k);
161 
162 	FPGA_SET_REG(fpga, ep.rx_tx_control,
163 		     CTRL_PROC_RECEIVE_ENABLE | CTRL_FLUSH_TRANSMIT_BUFFER);
164 
165 	tx_ctr++;
166 }
167 #else
io_send(struct udevice * dev,uint size)168 static void io_send(struct udevice *dev, uint size)
169 {
170 	uint k;
171 	u16 buffer[HEADER_WORDS + 128];
172 	struct io_generic_packet header = {
173 		.source_address = 1,
174 		.packet_type = 1,
175 		.packet_length = size,
176 	};
177 	const uint words = (size + 1) / 2;
178 
179 	memcpy(buffer, &header, 2 * HEADER_WORDS);
180 	for (k = 0; k < words; ++k)
181 		buffer[k + HEADER_WORDS] = (2 * k + 1) + ((2 * k) << 8);
182 
183 	misc_write(dev, 0, buffer, HEADER_WORDS + words);
184 
185 	tx_ctr++;
186 }
187 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
188 
189 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
io_receive(uint fpga)190 static void io_receive(uint fpga)
191 {
192 	u16 rx_tx_status;
193 
194 	FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
195 
196 	while (rx_tx_status & STATE_RX_DATA_AVAILABLE) {
197 		u16 rx;
198 
199 		if (rx_tx_status & STATE_RX_DATA_LAST)
200 			rx_ctr++;
201 
202 		FPGA_GET_REG(fpga, ep.receive_data, &rx);
203 
204 		FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
205 	}
206 }
207 #else
io_receive(struct udevice * dev)208 static void io_receive(struct udevice *dev)
209 {
210 	u16 buffer[HEADER_WORDS + 128];
211 
212 	if (!misc_read(dev, 0, buffer, 0))
213 		rx_ctr++;
214 }
215 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
216 
217 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
io_reflect(uint fpga)218 static void io_reflect(uint fpga)
219 {
220 	u16 buffer[128];
221 
222 	uint k = 0;
223 	uint n;
224 	u16 rx_tx_status;
225 
226 	FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
227 
228 	while (rx_tx_status & STATE_RX_DATA_AVAILABLE) {
229 		FPGA_GET_REG(fpga, ep.receive_data, &buffer[k++]);
230 		if (rx_tx_status & STATE_RX_DATA_LAST)
231 			break;
232 
233 		FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
234 	}
235 
236 	if (!k)
237 		return;
238 
239 	for (n = 0; n < k; ++n)
240 		FPGA_SET_REG(fpga, ep.transmit_data, buffer[n]);
241 
242 	FPGA_SET_REG(fpga, ep.rx_tx_control,
243 		     CTRL_PROC_RECEIVE_ENABLE | CTRL_FLUSH_TRANSMIT_BUFFER);
244 
245 	tx_ctr++;
246 }
247 #else
io_reflect(struct udevice * dev)248 static void io_reflect(struct udevice *dev)
249 {
250 	u16 buffer[HEADER_WORDS + 128];
251 	struct io_generic_packet *header;
252 
253 	if (misc_read(dev, 0, buffer, 0))
254 		return;
255 
256 	header = (struct io_generic_packet *)&buffer;
257 
258 	misc_write(dev, 0, buffer, HEADER_WORDS + header->packet_length);
259 }
260 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
261 
262 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
263 /*
264  * FPGA io-endpoint reflector
265  *
266  * Syntax:
267  *	ioreflect {fpga} {reportrate}
268  */
do_ioreflect(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])269 int do_ioreflect(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
270 {
271 	uint fpga;
272 	uint rate = 0;
273 	unsigned long long last_seen = 0;
274 
275 	if (argc < 2)
276 		return CMD_RET_USAGE;
277 
278 	fpga = simple_strtoul(argv[1], NULL, 10);
279 
280 	/*
281 	 * If another parameter, it is the report rate in packets.
282 	 */
283 	if (argc > 2)
284 		rate = simple_strtoul(argv[2], NULL, 10);
285 
286 	/* Enable receive path */
287 	FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE);
288 
289 	/* Set device address to dummy 1*/
290 	FPGA_SET_REG(fpga, ep.device_address, 1);
291 
292 	rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
293 
294 	while (1) {
295 		u16 top_int;
296 		u16 rx_tx_status;
297 
298 		FPGA_GET_REG(fpga, top_interrupt, &top_int);
299 		FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
300 
301 		io_check_status(fpga, rx_tx_status, STATUS_SILENT);
302 		if ((top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS) &&
303 		    (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS))
304 			io_reflect(fpga);
305 
306 		if (rate) {
307 			if (!(tx_ctr % rate) && (tx_ctr != last_seen))
308 				printf("refl %llu, err %llu\n", tx_ctr,
309 				       err_ctr);
310 			last_seen = tx_ctr;
311 		}
312 
313 		if (ctrlc())
314 			break;
315 	}
316 
317 	return 0;
318 }
319 #else
320 /*
321  * FPGA io-endpoint reflector
322  *
323  * Syntax:
324  *	ioreflect {reportrate}
325  */
do_ioreflect(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])326 int do_ioreflect(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
327 {
328 	struct udevice *fpga;
329 	struct regmap *map;
330 	uint rate = 0;
331 	unsigned long long last_seen = 0;
332 
333 	if (!dev) {
334 		printf("No device selected\n");
335 		return 1;
336 	}
337 
338 	gdsys_soc_get_fpga(dev, &fpga);
339 	regmap_init_mem(dev_ofnode(dev), &map);
340 
341 	/* Enable receive path */
342 	misc_set_enabled(dev, true);
343 
344 	rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
345 
346 	while (1) {
347 		uint top_int;
348 
349 		ihs_fpga_get(map, top_interrupt, &top_int);
350 		io_check_status(dev, STATUS_SILENT);
351 		if ((top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS) &&
352 		    (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS))
353 			io_reflect(dev);
354 
355 		if (rate) {
356 			if (!(tx_ctr % rate) && (tx_ctr != last_seen))
357 				printf("refl %llu, err %llu\n", tx_ctr,
358 				       err_ctr);
359 			last_seen = tx_ctr;
360 		}
361 
362 		if (ctrlc())
363 			break;
364 	}
365 
366 	return 0;
367 }
368 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
369 
370 #define DISP_LINE_LEN	16
371 
372 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
373 /*
374  * FPGA io-endpoint looptest
375  *
376  * Syntax:
377  *	ioloop {fpga} {size} {rate}
378  */
do_ioloop(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])379 int do_ioloop(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
380 {
381 	uint fpga;
382 	uint size;
383 	uint rate = 0;
384 
385 	if (argc < 3)
386 		return CMD_RET_USAGE;
387 
388 	/*
389 	 * FPGA is specified since argc > 2
390 	 */
391 	fpga = simple_strtoul(argv[1], NULL, 10);
392 
393 	/*
394 	 * packet size is specified since argc > 2
395 	 */
396 	size = simple_strtoul(argv[2], NULL, 10);
397 
398 	/*
399 	 * If another parameter, it is the test rate in packets per second.
400 	 */
401 	if (argc > 3)
402 		rate = simple_strtoul(argv[3], NULL, 10);
403 
404 	/* enable receive path */
405 	FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE);
406 
407 	/* set device address to dummy 1*/
408 	FPGA_SET_REG(fpga, ep.device_address, 1);
409 
410 	rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
411 
412 	while (1) {
413 		u16 top_int;
414 		u16 rx_tx_status;
415 
416 		FPGA_GET_REG(fpga, top_interrupt, &top_int);
417 		FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
418 
419 		io_check_status(fpga, rx_tx_status, STATUS_LOUD);
420 		if (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS)
421 			io_send(fpga, size);
422 		if (top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS)
423 			io_receive(fpga);
424 
425 		if (rate) {
426 			if (ctrlc())
427 				break;
428 			udelay(1000000 / rate);
429 			if (!(tx_ctr % rate))
430 				printf("d %llu, tx %llu, rx %llu, err %llu\n",
431 				       tx_ctr - rx_ctr, tx_ctr, rx_ctr,
432 				       err_ctr);
433 		}
434 	}
435 
436 	return 0;
437 }
438 #else
439 /*
440  * FPGA io-endpoint looptest
441  *
442  * Syntax:
443  *	ioloop {size} {rate}
444  */
do_ioloop(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])445 int do_ioloop(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
446 {
447 	uint size;
448 	uint rate = 0;
449 	struct udevice *fpga;
450 	struct regmap *map;
451 
452 	if (!dev) {
453 		printf("No device selected\n");
454 		return 1;
455 	}
456 
457 	gdsys_soc_get_fpga(dev, &fpga);
458 	regmap_init_mem(dev_ofnode(dev), &map);
459 
460 	if (argc < 2)
461 		return CMD_RET_USAGE;
462 
463 	/*
464 	 * packet size is specified since argc > 1
465 	 */
466 	size = simple_strtoul(argv[2], NULL, 10);
467 
468 	/*
469 	 * If another parameter, it is the test rate in packets per second.
470 	 */
471 	if (argc > 2)
472 		rate = simple_strtoul(argv[3], NULL, 10);
473 
474 	/* Enable receive path */
475 	misc_set_enabled(dev, true);
476 
477 	rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
478 
479 	while (1) {
480 		uint top_int;
481 
482 		if (ctrlc())
483 			break;
484 
485 		ihs_fpga_get(map, top_interrupt, &top_int);
486 
487 		io_check_status(dev, STATUS_LOUD);
488 		if (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS)
489 			io_send(dev, size);
490 		if (top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS)
491 			io_receive(dev);
492 
493 		if (rate) {
494 			udelay(1000000 / rate);
495 			if (!(tx_ctr % rate))
496 				printf("d %llu, tx %llu, rx %llu, err %llu\n",
497 				       tx_ctr - rx_ctr, tx_ctr, rx_ctr,
498 				       err_ctr);
499 		}
500 	}
501 	return 0;
502 }
503 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
504 
505 #ifndef CONFIG_GDSYS_LEGACY_DRIVERS
do_iodev(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])506 int do_iodev(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
507 {
508 	struct udevice *ioep = NULL;
509 	struct udevice *sysinfo;
510 	char name[8];
511 	int ret;
512 
513 	if (sysinfo_get(&sysinfo))
514 		return CMD_RET_FAILURE;
515 
516 	if (argc > 1) {
517 		int i = simple_strtoul(argv[1], NULL, 10);
518 
519 		snprintf(name, sizeof(name), "ioep%d", i);
520 
521 		ret = uclass_get_device_by_phandle(UCLASS_MISC, sysinfo, name,
522 						   &ioep);
523 
524 		if (ret || !ioep) {
525 			printf("Invalid IOEP %d\n", i);
526 			return CMD_RET_FAILURE;
527 		}
528 
529 		dev = ioep;
530 	} else {
531 		int i = 0;
532 
533 		while (1) {
534 			snprintf(name, sizeof(name), "ioep%d", i);
535 
536 			ret = uclass_get_device_by_phandle(UCLASS_MISC, sysinfo,
537 							   name, &ioep);
538 
539 			if (ret || !ioep)
540 				break;
541 
542 			printf("IOEP %d:\t%s\n", i++, ioep->name);
543 		}
544 
545 		if (dev)
546 			printf("\nSelected IOEP: %s\n", dev->name);
547 		else
548 			puts("\nNo IOEP selected.\n");
549 	}
550 
551 	return 0;
552 }
553 #endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
554 
555 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
556 U_BOOT_CMD(
557 	ioloop,	4,	0,	do_ioloop,
558 	"fpga io-endpoint looptest",
559 	"fpga packetsize [packets/sec]"
560 );
561 
562 U_BOOT_CMD(
563 	ioreflect, 3,	0,	do_ioreflect,
564 	"fpga io-endpoint reflector",
565 	"fpga reportrate"
566 );
567 #else
568 U_BOOT_CMD(
569 	ioloop,	3,	0,	do_ioloop,
570 	"fpga io-endpoint looptest",
571 	"packetsize [packets/sec]"
572 );
573 
574 U_BOOT_CMD(
575 	ioreflect, 2,	0,	do_ioreflect,
576 	"fpga io-endpoint reflector",
577 	"reportrate"
578 );
579 
580 U_BOOT_CMD(
581 	iodev, 2,	0,	do_iodev,
582 	"fpga io-endpoint listing/selection",
583 	"[ioep device to select]"
584 );
585 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
586