3 * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
5 * SPDX-License-Identifier: GPL-2.0+
12 #include <gdsys_fpga.h>
15 STATE_TX_PACKET_BUILDING = 1<<0,
16 STATE_TX_TRANSMITTING = 1<<1,
17 STATE_TX_BUFFER_FULL = 1<<2,
19 STATE_RECEIVE_TIMEOUT = 1<<4,
20 STATE_PROC_RX_STORE_TIMEOUT = 1<<5,
21 STATE_PROC_RX_RECEIVE_TIMEOUT = 1<<6,
22 STATE_RX_DIST_ERR = 1<<7,
23 STATE_RX_LENGTH_ERR = 1<<8,
24 STATE_RX_FRAME_CTR_ERR = 1<<9,
25 STATE_RX_FCS_ERR = 1<<10,
26 STATE_RX_PACKET_DROPPED = 1<<11,
27 STATE_RX_DATA_LAST = 1<<12,
28 STATE_RX_DATA_FIRST = 1<<13,
29 STATE_RX_DATA_AVAILABLE = 1<<15,
33 CTRL_PROC_RECEIVE_ENABLE = 1<<12,
34 CTRL_FLUSH_TRANSMIT_BUFFER = 1<<15,
38 IRQ_CPU_TRANSMITBUFFER_FREE_STATUS = 1<<5,
39 IRQ_CPU_PACKET_TRANSMITTED_EVENT = 1<<6,
40 IRQ_NEW_CPU_PACKET_RECEIVED_EVENT = 1<<7,
41 IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS = 1<<8,
44 struct io_generic_packet {
50 } __attribute__((__packed__));
52 unsigned long long rx_ctr;
53 unsigned long long tx_ctr;
54 unsigned long long err_ctr;
56 static void io_check_status(unsigned int fpga, u16 status, bool silent)
58 u16 mask = STATE_RX_DIST_ERR | STATE_RX_LENGTH_ERR |
59 STATE_RX_FRAME_CTR_ERR | STATE_RX_FCS_ERR |
60 STATE_RX_PACKET_DROPPED | STATE_TX_ERR;
62 if (!(status & mask)) {
63 FPGA_SET_REG(fpga, ep.rx_tx_status, status);
68 FPGA_SET_REG(fpga, ep.rx_tx_status, status);
73 if (status & STATE_RX_PACKET_DROPPED)
74 printf("RX_PACKET_DROPPED, status %04x\n", status);
76 if (status & STATE_RX_DIST_ERR)
77 printf("RX_DIST_ERR\n");
78 if (status & STATE_RX_LENGTH_ERR)
79 printf("RX_LENGTH_ERR\n");
80 if (status & STATE_RX_FRAME_CTR_ERR)
81 printf("RX_FRAME_CTR_ERR\n");
82 if (status & STATE_RX_FCS_ERR)
83 printf("RX_FCS_ERR\n");
85 if (status & STATE_TX_ERR)
89 static void io_send(unsigned int fpga, unsigned int size)
92 struct io_generic_packet packet = {
95 .packet_length = size,
97 u16 *p = (u16 *)&packet;
99 for (k = 0; k < sizeof(packet) / 2; ++k)
100 FPGA_SET_REG(fpga, ep.transmit_data, *p++);
102 for (k = 0; k < (size + 1) / 2; ++k)
103 FPGA_SET_REG(fpga, ep.transmit_data, k);
105 FPGA_SET_REG(fpga, ep.rx_tx_control,
106 CTRL_PROC_RECEIVE_ENABLE | CTRL_FLUSH_TRANSMIT_BUFFER);
111 static void io_receive(unsigned int fpga)
116 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
118 while (rx_tx_status & STATE_RX_DATA_AVAILABLE) {
121 if (rx_tx_status & STATE_RX_DATA_LAST)
124 FPGA_GET_REG(fpga, ep.receive_data, &rx);
126 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
132 static void io_reflect(unsigned int fpga)
140 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
142 while (rx_tx_status & STATE_RX_DATA_AVAILABLE) {
143 FPGA_GET_REG(fpga, ep.receive_data, &buffer[k++]);
144 if (rx_tx_status & STATE_RX_DATA_LAST)
147 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
153 for (n = 0; n < k; ++n)
154 FPGA_SET_REG(fpga, ep.transmit_data, buffer[n]);
156 FPGA_SET_REG(fpga, ep.rx_tx_control,
157 CTRL_PROC_RECEIVE_ENABLE | CTRL_FLUSH_TRANSMIT_BUFFER);
163 * FPGA io-endpoint reflector
166 * ioreflect {fpga} {reportrate}
168 int do_ioreflect(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
171 unsigned int rate = 0;
172 unsigned long long last_seen = 0;
175 return CMD_RET_USAGE;
177 fpga = simple_strtoul(argv[1], NULL, 10);
180 * If another parameter, it is the report rate in packets.
183 rate = simple_strtoul(argv[2], NULL, 10);
185 /* enable receive path */
186 FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE);
188 /* set device address to dummy 1*/
189 FPGA_SET_REG(fpga, ep.device_address, 1);
191 rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
197 FPGA_GET_REG(fpga, top_interrupt, &top_int);
198 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
200 io_check_status(fpga, rx_tx_status, true);
201 if ((top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS) &&
202 (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS))
206 if (!(tx_ctr % rate) && (tx_ctr != last_seen))
207 printf("refl %llu, err %llu\n", tx_ctr,
220 * FPGA io-endpoint looptest
223 * ioloop {fpga} {size} {rate}
225 #define DISP_LINE_LEN 16
226 int do_ioloop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
230 unsigned int rate = 0;
233 return CMD_RET_USAGE;
236 * FPGA is specified since argc > 2
238 fpga = simple_strtoul(argv[1], NULL, 10);
241 * packet size is specified since argc > 2
243 size = simple_strtoul(argv[2], NULL, 10);
246 * If another parameter, it is the test rate in packets per second.
249 rate = simple_strtoul(argv[3], NULL, 10);
251 /* enable receive path */
252 FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE);
254 /* set device address to dummy 1*/
255 FPGA_SET_REG(fpga, ep.device_address, 1);
257 rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
263 FPGA_GET_REG(fpga, top_interrupt, &top_int);
264 FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
266 io_check_status(fpga, rx_tx_status, false);
267 if (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS)
269 if (top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS)
275 udelay(1000000 / rate);
276 if (!(tx_ctr % rate))
277 printf("d %lld, tx %llu, rx %llu, err %llu\n",
278 tx_ctr - rx_ctr, tx_ctr, rx_ctr,
287 ioloop, 4, 0, do_ioloop,
288 "fpga io-endpoint looptest",
289 "fpga packetsize [packets/sec]"
293 ioreflect, 3, 0, do_ioreflect,
294 "fpga io-endpoint reflector",