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