1 // SPDX-License-Identifier: GPL-2.0+
4 * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
10 #include <linux/delay.h>
12 #include <gdsys_fpga.h>
14 #ifndef CONFIG_GDSYS_LEGACY_DRIVERS
20 #include "../../../drivers/misc/gdsys_soc.h"
21 #include "../../../drivers/misc/gdsys_ioep.h"
22 #include "../../../drivers/misc/ihs_fpga.h"
24 const int HEADER_WORDS = sizeof(struct io_generic_packet) / 2;
25 #endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
27 enum status_print_type {
32 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
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),
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),
59 CTRL_PROC_RECEIVE_ENABLE = BIT(12),
60 CTRL_FLUSH_TRANSMIT_BUFFER = BIT(15),
63 struct io_generic_packet {
69 } __attribute__((__packed__));
70 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
72 unsigned long long rx_ctr;
73 unsigned long long tx_ctr;
74 unsigned long long err_ctr;
75 #ifndef CONFIG_GDSYS_LEGACY_DRIVERS
77 #endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
79 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
80 static void io_check_status(uint fpga, u16 status, enum status_print_type type)
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;
86 if (!(status & mask)) {
87 FPGA_SET_REG(fpga, ep.rx_tx_status, status);
92 FPGA_SET_REG(fpga, ep.rx_tx_status, status);
94 if (type == STATUS_SILENT)
97 if (status & STATE_RX_PACKET_DROPPED)
98 printf("RX_PACKET_DROPPED, status %04x\n", status);
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");
109 if (status & STATE_TX_ERR)
113 static void io_check_status(struct udevice *dev, enum status_print_type type)
118 ret = misc_call(dev, 0, NULL, 0, &status, 0);
124 if (type != STATUS_LOUD)
127 if (status & STATE_RX_PACKET_DROPPED)
128 printf("RX_PACKET_DROPPED, status %04x\n", status);
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");
139 if (status & STATE_TX_ERR)
142 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
144 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
145 static void io_send(uint fpga, uint size)
148 struct io_generic_packet packet = {
151 .packet_length = size,
153 u16 *p = (u16 *)&packet;
155 for (k = 0; k < sizeof(packet) / 2; ++k)
156 FPGA_SET_REG(fpga, ep.transmit_data, *p++);
158 for (k = 0; k < (size + 1) / 2; ++k)
159 FPGA_SET_REG(fpga, ep.transmit_data, k);
161 FPGA_SET_REG(fpga, ep.rx_tx_control,
162 CTRL_PROC_RECEIVE_ENABLE | CTRL_FLUSH_TRANSMIT_BUFFER);
167 static void io_send(struct udevice *dev, uint size)
170 u16 buffer[HEADER_WORDS + 128];
171 struct io_generic_packet header = {
174 .packet_length = size,
176 const uint words = (size + 1) / 2;
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);
182 misc_write(dev, 0, buffer, HEADER_WORDS + words);
186 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
188 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
189 static void io_receive(uint fpga)
193 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
195 while (rx_tx_status & STATE_RX_DATA_AVAILABLE) {
198 if (rx_tx_status & STATE_RX_DATA_LAST)
201 FPGA_GET_REG(fpga, ep.receive_data, &rx);
203 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
207 static void io_receive(struct udevice *dev)
209 u16 buffer[HEADER_WORDS + 128];
211 if (!misc_read(dev, 0, buffer, 0))
214 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
216 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
217 static void io_reflect(uint fpga)
225 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
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)
232 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
238 for (n = 0; n < k; ++n)
239 FPGA_SET_REG(fpga, ep.transmit_data, buffer[n]);
241 FPGA_SET_REG(fpga, ep.rx_tx_control,
242 CTRL_PROC_RECEIVE_ENABLE | CTRL_FLUSH_TRANSMIT_BUFFER);
247 static void io_reflect(struct udevice *dev)
249 u16 buffer[HEADER_WORDS + 128];
250 struct io_generic_packet *header;
252 if (misc_read(dev, 0, buffer, 0))
255 header = (struct io_generic_packet *)&buffer;
257 misc_write(dev, 0, buffer, HEADER_WORDS + header->packet_length);
259 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
261 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
263 * FPGA io-endpoint reflector
266 * ioreflect {fpga} {reportrate}
268 int do_ioreflect(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
272 unsigned long long last_seen = 0;
275 return CMD_RET_USAGE;
277 fpga = simple_strtoul(argv[1], NULL, 10);
280 * If another parameter, it is the report rate in packets.
283 rate = simple_strtoul(argv[2], NULL, 10);
285 /* Enable receive path */
286 FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE);
288 /* Set device address to dummy 1*/
289 FPGA_SET_REG(fpga, ep.device_address, 1);
291 rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
297 FPGA_GET_REG(fpga, top_interrupt, &top_int);
298 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
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))
306 if (!(tx_ctr % rate) && (tx_ctr != last_seen))
307 printf("refl %llu, err %llu\n", tx_ctr,
320 * FPGA io-endpoint reflector
323 * ioreflect {reportrate}
325 int do_ioreflect(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
327 struct udevice *fpga;
330 unsigned long long last_seen = 0;
333 printf("No device selected\n");
337 gdsys_soc_get_fpga(dev, &fpga);
338 regmap_init_mem(dev_ofnode(dev), &map);
340 /* Enable receive path */
341 misc_set_enabled(dev, true);
343 rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
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))
355 if (!(tx_ctr % rate) && (tx_ctr != last_seen))
356 printf("refl %llu, err %llu\n", tx_ctr,
367 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
369 #define DISP_LINE_LEN 16
371 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
373 * FPGA io-endpoint looptest
376 * ioloop {fpga} {size} {rate}
378 int do_ioloop(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
385 return CMD_RET_USAGE;
388 * FPGA is specified since argc > 2
390 fpga = simple_strtoul(argv[1], NULL, 10);
393 * packet size is specified since argc > 2
395 size = simple_strtoul(argv[2], NULL, 10);
398 * If another parameter, it is the test rate in packets per second.
401 rate = simple_strtoul(argv[3], NULL, 10);
403 /* enable receive path */
404 FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE);
406 /* set device address to dummy 1*/
407 FPGA_SET_REG(fpga, ep.device_address, 1);
409 rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
415 FPGA_GET_REG(fpga, top_interrupt, &top_int);
416 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
418 io_check_status(fpga, rx_tx_status, STATUS_LOUD);
419 if (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS)
421 if (top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS)
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,
439 * FPGA io-endpoint looptest
442 * ioloop {size} {rate}
444 int do_ioloop(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
448 struct udevice *fpga;
452 printf("No device selected\n");
456 gdsys_soc_get_fpga(dev, &fpga);
457 regmap_init_mem(dev_ofnode(dev), &map);
460 return CMD_RET_USAGE;
463 * packet size is specified since argc > 1
465 size = simple_strtoul(argv[2], NULL, 10);
468 * If another parameter, it is the test rate in packets per second.
471 rate = simple_strtoul(argv[3], NULL, 10);
473 /* Enable receive path */
474 misc_set_enabled(dev, true);
476 rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
484 ihs_fpga_get(map, top_interrupt, &top_int);
486 io_check_status(dev, STATUS_LOUD);
487 if (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS)
489 if (top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS)
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,
502 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
504 #ifndef CONFIG_GDSYS_LEGACY_DRIVERS
505 int do_iodev(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
507 struct udevice *ioep = NULL;
508 struct udevice *board;
512 if (board_get(&board))
513 return CMD_RET_FAILURE;
516 int i = simple_strtoul(argv[1], NULL, 10);
518 snprintf(name, sizeof(name), "ioep%d", i);
520 ret = uclass_get_device_by_phandle(UCLASS_MISC, board, name, &ioep);
523 printf("Invalid IOEP %d\n", i);
524 return CMD_RET_FAILURE;
532 snprintf(name, sizeof(name), "ioep%d", i);
534 ret = uclass_get_device_by_phandle(UCLASS_MISC, board, name, &ioep);
539 printf("IOEP %d:\t%s\n", i++, ioep->name);
543 printf("\nSelected IOEP: %s\n", dev->name);
545 puts("\nNo IOEP selected.\n");
550 #endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
552 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
554 ioloop, 4, 0, do_ioloop,
555 "fpga io-endpoint looptest",
556 "fpga packetsize [packets/sec]"
560 ioreflect, 3, 0, do_ioreflect,
561 "fpga io-endpoint reflector",
566 ioloop, 3, 0, do_ioloop,
567 "fpga io-endpoint looptest",
568 "packetsize [packets/sec]"
572 ioreflect, 2, 0, do_ioreflect,
573 "fpga io-endpoint reflector",
578 iodev, 2, 0, do_iodev,
579 "fpga io-endpoint listing/selection",
580 "[ioep device to select]"
582 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */