1 // SPDX-License-Identifier: GPL-2.0+
4 * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
11 #include <gdsys_fpga.h>
14 STATE_TX_PACKET_BUILDING
= 1<<0,
15 STATE_TX_TRANSMITTING
= 1<<1,
16 STATE_TX_BUFFER_FULL
= 1<<2,
18 STATE_RECEIVE_TIMEOUT
= 1<<4,
19 STATE_PROC_RX_STORE_TIMEOUT
= 1<<5,
20 STATE_PROC_RX_RECEIVE_TIMEOUT
= 1<<6,
21 STATE_RX_DIST_ERR
= 1<<7,
22 STATE_RX_LENGTH_ERR
= 1<<8,
23 STATE_RX_FRAME_CTR_ERR
= 1<<9,
24 STATE_RX_FCS_ERR
= 1<<10,
25 STATE_RX_PACKET_DROPPED
= 1<<11,
26 STATE_RX_DATA_LAST
= 1<<12,
27 STATE_RX_DATA_FIRST
= 1<<13,
28 STATE_RX_DATA_AVAILABLE
= 1<<15,
32 CTRL_PROC_RECEIVE_ENABLE
= 1<<12,
33 CTRL_FLUSH_TRANSMIT_BUFFER
= 1<<15,
37 IRQ_CPU_TRANSMITBUFFER_FREE_STATUS
= 1<<5,
38 IRQ_CPU_PACKET_TRANSMITTED_EVENT
= 1<<6,
39 IRQ_NEW_CPU_PACKET_RECEIVED_EVENT
= 1<<7,
40 IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS
= 1<<8,
43 struct io_generic_packet
{
49 } __attribute__((__packed__
));
51 unsigned long long rx_ctr
;
52 unsigned long long tx_ctr
;
53 unsigned long long err_ctr
;
55 static void io_check_status(unsigned int fpga
, u16 status
, bool silent
)
57 u16 mask
= STATE_RX_DIST_ERR
| STATE_RX_LENGTH_ERR
|
58 STATE_RX_FRAME_CTR_ERR
| STATE_RX_FCS_ERR
|
59 STATE_RX_PACKET_DROPPED
| STATE_TX_ERR
;
61 if (!(status
& mask
)) {
62 FPGA_SET_REG(fpga
, ep
.rx_tx_status
, status
);
67 FPGA_SET_REG(fpga
, ep
.rx_tx_status
, status
);
72 if (status
& STATE_RX_PACKET_DROPPED
)
73 printf("RX_PACKET_DROPPED, status %04x\n", status
);
75 if (status
& STATE_RX_DIST_ERR
)
76 printf("RX_DIST_ERR\n");
77 if (status
& STATE_RX_LENGTH_ERR
)
78 printf("RX_LENGTH_ERR\n");
79 if (status
& STATE_RX_FRAME_CTR_ERR
)
80 printf("RX_FRAME_CTR_ERR\n");
81 if (status
& STATE_RX_FCS_ERR
)
82 printf("RX_FCS_ERR\n");
84 if (status
& STATE_TX_ERR
)
88 static void io_send(unsigned int fpga
, unsigned int size
)
91 struct io_generic_packet packet
= {
94 .packet_length
= size
,
96 u16
*p
= (u16
*)&packet
;
98 for (k
= 0; k
< sizeof(packet
) / 2; ++k
)
99 FPGA_SET_REG(fpga
, ep
.transmit_data
, *p
++);
101 for (k
= 0; k
< (size
+ 1) / 2; ++k
)
102 FPGA_SET_REG(fpga
, ep
.transmit_data
, k
);
104 FPGA_SET_REG(fpga
, ep
.rx_tx_control
,
105 CTRL_PROC_RECEIVE_ENABLE
| CTRL_FLUSH_TRANSMIT_BUFFER
);
110 static void io_receive(unsigned int fpga
)
115 FPGA_GET_REG(fpga
, ep
.rx_tx_status
, &rx_tx_status
);
117 while (rx_tx_status
& STATE_RX_DATA_AVAILABLE
) {
120 if (rx_tx_status
& STATE_RX_DATA_LAST
)
123 FPGA_GET_REG(fpga
, ep
.receive_data
, &rx
);
125 FPGA_GET_REG(fpga
, ep
.rx_tx_status
, &rx_tx_status
);
131 static void io_reflect(unsigned int fpga
)
139 FPGA_GET_REG(fpga
, ep
.rx_tx_status
, &rx_tx_status
);
141 while (rx_tx_status
& STATE_RX_DATA_AVAILABLE
) {
142 FPGA_GET_REG(fpga
, ep
.receive_data
, &buffer
[k
++]);
143 if (rx_tx_status
& STATE_RX_DATA_LAST
)
146 FPGA_GET_REG(fpga
, ep
.rx_tx_status
, &rx_tx_status
);
152 for (n
= 0; n
< k
; ++n
)
153 FPGA_SET_REG(fpga
, ep
.transmit_data
, buffer
[n
]);
155 FPGA_SET_REG(fpga
, ep
.rx_tx_control
,
156 CTRL_PROC_RECEIVE_ENABLE
| CTRL_FLUSH_TRANSMIT_BUFFER
);
162 * FPGA io-endpoint reflector
165 * ioreflect {fpga} {reportrate}
167 int do_ioreflect(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
170 unsigned int rate
= 0;
171 unsigned long long last_seen
= 0;
174 return CMD_RET_USAGE
;
176 fpga
= simple_strtoul(argv
[1], NULL
, 10);
179 * If another parameter, it is the report rate in packets.
182 rate
= simple_strtoul(argv
[2], NULL
, 10);
184 /* enable receive path */
185 FPGA_SET_REG(fpga
, ep
.rx_tx_control
, CTRL_PROC_RECEIVE_ENABLE
);
187 /* set device address to dummy 1*/
188 FPGA_SET_REG(fpga
, ep
.device_address
, 1);
190 rx_ctr
= 0; tx_ctr
= 0; err_ctr
= 0;
196 FPGA_GET_REG(fpga
, top_interrupt
, &top_int
);
197 FPGA_GET_REG(fpga
, ep
.rx_tx_status
, &rx_tx_status
);
199 io_check_status(fpga
, rx_tx_status
, true);
200 if ((top_int
& IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS
) &&
201 (top_int
& IRQ_CPU_TRANSMITBUFFER_FREE_STATUS
))
205 if (!(tx_ctr
% rate
) && (tx_ctr
!= last_seen
))
206 printf("refl %llu, err %llu\n", tx_ctr
,
219 * FPGA io-endpoint looptest
222 * ioloop {fpga} {size} {rate}
224 #define DISP_LINE_LEN 16
225 int do_ioloop(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
229 unsigned int rate
= 0;
232 return CMD_RET_USAGE
;
235 * FPGA is specified since argc > 2
237 fpga
= simple_strtoul(argv
[1], NULL
, 10);
240 * packet size is specified since argc > 2
242 size
= simple_strtoul(argv
[2], NULL
, 10);
245 * If another parameter, it is the test rate in packets per second.
248 rate
= simple_strtoul(argv
[3], NULL
, 10);
250 /* enable receive path */
251 FPGA_SET_REG(fpga
, ep
.rx_tx_control
, CTRL_PROC_RECEIVE_ENABLE
);
253 /* set device address to dummy 1*/
254 FPGA_SET_REG(fpga
, ep
.device_address
, 1);
256 rx_ctr
= 0; tx_ctr
= 0; err_ctr
= 0;
262 FPGA_GET_REG(fpga
, top_interrupt
, &top_int
);
263 FPGA_GET_REG(fpga
, ep
.rx_tx_status
, &rx_tx_status
);
265 io_check_status(fpga
, rx_tx_status
, false);
266 if (top_int
& IRQ_CPU_TRANSMITBUFFER_FREE_STATUS
)
268 if (top_int
& IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS
)
274 udelay(1000000 / rate
);
275 if (!(tx_ctr
% rate
))
276 printf("d %lld, tx %llu, rx %llu, err %llu\n",
277 tx_ctr
- rx_ctr
, tx_ctr
, rx_ctr
,
286 ioloop
, 4, 0, do_ioloop
,
287 "fpga io-endpoint looptest",
288 "fpga packetsize [packets/sec]"
292 ioreflect
, 3, 0, do_ioreflect
,
293 "fpga io-endpoint reflector",