1 // SPDX-License-Identifier: GPL-2.0+
4 * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
10 #include <linux/bitops.h>
11 #include <linux/delay.h>
13 #include <gdsys_fpga.h>
15 #ifndef CONFIG_GDSYS_LEGACY_DRIVERS
21 #include "../../../drivers/misc/gdsys_soc.h"
22 #include "../../../drivers/misc/gdsys_ioep.h"
23 #include "../../../drivers/misc/ihs_fpga.h"
25 const int HEADER_WORDS = sizeof(struct io_generic_packet) / 2;
26 #endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
28 enum status_print_type {
33 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
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),
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),
60 CTRL_PROC_RECEIVE_ENABLE = BIT(12),
61 CTRL_FLUSH_TRANSMIT_BUFFER = BIT(15),
64 struct io_generic_packet {
70 } __attribute__((__packed__));
71 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
73 unsigned long long rx_ctr;
74 unsigned long long tx_ctr;
75 unsigned long long err_ctr;
76 #ifndef CONFIG_GDSYS_LEGACY_DRIVERS
78 #endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
80 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
81 static void io_check_status(uint fpga, u16 status, enum status_print_type type)
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;
87 if (!(status & mask)) {
88 FPGA_SET_REG(fpga, ep.rx_tx_status, status);
93 FPGA_SET_REG(fpga, ep.rx_tx_status, status);
95 if (type == STATUS_SILENT)
98 if (status & STATE_RX_PACKET_DROPPED)
99 printf("RX_PACKET_DROPPED, status %04x\n", status);
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");
110 if (status & STATE_TX_ERR)
114 static void io_check_status(struct udevice *dev, enum status_print_type type)
119 ret = misc_call(dev, 0, NULL, 0, &status, 0);
125 if (type != STATUS_LOUD)
128 if (status & STATE_RX_PACKET_DROPPED)
129 printf("RX_PACKET_DROPPED, status %04x\n", status);
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");
140 if (status & STATE_TX_ERR)
143 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
145 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
146 static void io_send(uint fpga, uint size)
149 struct io_generic_packet packet = {
152 .packet_length = size,
154 u16 *p = (u16 *)&packet;
156 for (k = 0; k < sizeof(packet) / 2; ++k)
157 FPGA_SET_REG(fpga, ep.transmit_data, *p++);
159 for (k = 0; k < (size + 1) / 2; ++k)
160 FPGA_SET_REG(fpga, ep.transmit_data, k);
162 FPGA_SET_REG(fpga, ep.rx_tx_control,
163 CTRL_PROC_RECEIVE_ENABLE | CTRL_FLUSH_TRANSMIT_BUFFER);
168 static void io_send(struct udevice *dev, uint size)
171 u16 buffer[HEADER_WORDS + 128];
172 struct io_generic_packet header = {
175 .packet_length = size,
177 const uint words = (size + 1) / 2;
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);
183 misc_write(dev, 0, buffer, HEADER_WORDS + words);
187 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
189 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
190 static void io_receive(uint fpga)
194 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
196 while (rx_tx_status & STATE_RX_DATA_AVAILABLE) {
199 if (rx_tx_status & STATE_RX_DATA_LAST)
202 FPGA_GET_REG(fpga, ep.receive_data, &rx);
204 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
208 static void io_receive(struct udevice *dev)
210 u16 buffer[HEADER_WORDS + 128];
212 if (!misc_read(dev, 0, buffer, 0))
215 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
217 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
218 static void io_reflect(uint fpga)
226 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
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)
233 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
239 for (n = 0; n < k; ++n)
240 FPGA_SET_REG(fpga, ep.transmit_data, buffer[n]);
242 FPGA_SET_REG(fpga, ep.rx_tx_control,
243 CTRL_PROC_RECEIVE_ENABLE | CTRL_FLUSH_TRANSMIT_BUFFER);
248 static void io_reflect(struct udevice *dev)
250 u16 buffer[HEADER_WORDS + 128];
251 struct io_generic_packet *header;
253 if (misc_read(dev, 0, buffer, 0))
256 header = (struct io_generic_packet *)&buffer;
258 misc_write(dev, 0, buffer, HEADER_WORDS + header->packet_length);
260 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
262 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
264 * FPGA io-endpoint reflector
267 * ioreflect {fpga} {reportrate}
269 int do_ioreflect(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
273 unsigned long long last_seen = 0;
276 return CMD_RET_USAGE;
278 fpga = simple_strtoul(argv[1], NULL, 10);
281 * If another parameter, it is the report rate in packets.
284 rate = simple_strtoul(argv[2], NULL, 10);
286 /* Enable receive path */
287 FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE);
289 /* Set device address to dummy 1*/
290 FPGA_SET_REG(fpga, ep.device_address, 1);
292 rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
298 FPGA_GET_REG(fpga, top_interrupt, &top_int);
299 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
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))
307 if (!(tx_ctr % rate) && (tx_ctr != last_seen))
308 printf("refl %llu, err %llu\n", tx_ctr,
321 * FPGA io-endpoint reflector
324 * ioreflect {reportrate}
326 int do_ioreflect(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
328 struct udevice *fpga;
331 unsigned long long last_seen = 0;
334 printf("No device selected\n");
338 gdsys_soc_get_fpga(dev, &fpga);
339 regmap_init_mem(dev_ofnode(dev), &map);
341 /* Enable receive path */
342 misc_set_enabled(dev, true);
344 rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
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))
356 if (!(tx_ctr % rate) && (tx_ctr != last_seen))
357 printf("refl %llu, err %llu\n", tx_ctr,
368 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
370 #define DISP_LINE_LEN 16
372 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
374 * FPGA io-endpoint looptest
377 * ioloop {fpga} {size} {rate}
379 int do_ioloop(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
386 return CMD_RET_USAGE;
389 * FPGA is specified since argc > 2
391 fpga = simple_strtoul(argv[1], NULL, 10);
394 * packet size is specified since argc > 2
396 size = simple_strtoul(argv[2], NULL, 10);
399 * If another parameter, it is the test rate in packets per second.
402 rate = simple_strtoul(argv[3], NULL, 10);
404 /* enable receive path */
405 FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE);
407 /* set device address to dummy 1*/
408 FPGA_SET_REG(fpga, ep.device_address, 1);
410 rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
416 FPGA_GET_REG(fpga, top_interrupt, &top_int);
417 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
419 io_check_status(fpga, rx_tx_status, STATUS_LOUD);
420 if (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS)
422 if (top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS)
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,
440 * FPGA io-endpoint looptest
443 * ioloop {size} {rate}
445 int do_ioloop(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
449 struct udevice *fpga;
453 printf("No device selected\n");
457 gdsys_soc_get_fpga(dev, &fpga);
458 regmap_init_mem(dev_ofnode(dev), &map);
461 return CMD_RET_USAGE;
464 * packet size is specified since argc > 1
466 size = simple_strtoul(argv[2], NULL, 10);
469 * If another parameter, it is the test rate in packets per second.
472 rate = simple_strtoul(argv[3], NULL, 10);
474 /* Enable receive path */
475 misc_set_enabled(dev, true);
477 rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
485 ihs_fpga_get(map, top_interrupt, &top_int);
487 io_check_status(dev, STATUS_LOUD);
488 if (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS)
490 if (top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS)
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,
503 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
505 #ifndef CONFIG_GDSYS_LEGACY_DRIVERS
506 int do_iodev(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
508 struct udevice *ioep = NULL;
509 struct udevice *board;
513 if (board_get(&board))
514 return CMD_RET_FAILURE;
517 int i = simple_strtoul(argv[1], NULL, 10);
519 snprintf(name, sizeof(name), "ioep%d", i);
521 ret = uclass_get_device_by_phandle(UCLASS_MISC, board, name, &ioep);
524 printf("Invalid IOEP %d\n", i);
525 return CMD_RET_FAILURE;
533 snprintf(name, sizeof(name), "ioep%d", i);
535 ret = uclass_get_device_by_phandle(UCLASS_MISC, board, name, &ioep);
540 printf("IOEP %d:\t%s\n", i++, ioep->name);
544 printf("\nSelected IOEP: %s\n", dev->name);
546 puts("\nNo IOEP selected.\n");
551 #endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
553 #ifdef CONFIG_GDSYS_LEGACY_DRIVERS
555 ioloop, 4, 0, do_ioloop,
556 "fpga io-endpoint looptest",
557 "fpga packetsize [packets/sec]"
561 ioreflect, 3, 0, do_ioreflect,
562 "fpga io-endpoint reflector",
567 ioloop, 3, 0, do_ioloop,
568 "fpga io-endpoint looptest",
569 "packetsize [packets/sec]"
573 ioreflect, 2, 0, do_ioreflect,
574 "fpga io-endpoint reflector",
579 iodev, 2, 0, do_iodev,
580 "fpga io-endpoint listing/selection",
581 "[ioep device to select]"
583 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */