7 #include <event2/listener.h>
8 #include <event2/util.h>
9 #include <event2/event.h>
10 #include <json-c/json.h>
18 struct eth_packet_s
*next
;
35 unsigned long int *tx_data
;
36 unsigned long int *rx_data
;
38 unsigned int *tx_data
;
39 unsigned int *rx_data
;
50 char databuf
[ETH_LEN
];
56 struct eth_packet_s
*ethpack
;
60 static struct event_base
*base
=NULL
;
62 int litex_sim_module_get_args(char *args
, char *arg
, char **val
)
65 json_object
*jsobj
= NULL
;
66 json_object
*obj
= NULL
;
70 jsobj
= json_tokener_parse(args
);
72 fprintf(stderr
, "Error parsing json arg: %s \n", args
);
77 if(!json_object_is_type(jsobj
, json_type_object
)) {
78 fprintf(stderr
, "Arg must be type object! : %s \n", args
);
84 r
= json_object_object_get_ex(jsobj
, arg
, &obj
);
86 fprintf(stderr
, "Could not find object: \"%s\" (%s)\n", arg
, args
);
90 value
= strdup(json_object_get_string(obj
));
97 static int litex_sim_module_pads_get(struct pad_s
*pads
, char *name
, void **signal
)
103 if(!pads
|| !name
|| !signal
) {
109 while(pads
[i
].name
) {
110 if(!strcmp(pads
[i
].name
, name
)) {
111 sig
=(void*)pads
[i
].signal
;
122 static int xgmii_ethernet_start(void *b
)
124 base
= (struct event_base
*) b
;
125 printf("[xgmii_ethernet] loaded (%p)\n", base
);
129 void event_handler(int fd
, short event
, void *arg
)
131 struct session_s
*s
= (struct session_s
*)arg
;
132 struct eth_packet_s
*ep
;
133 struct eth_packet_s
*tep
;
135 if (event
& EV_READ
) {
136 ep
= malloc(sizeof(struct eth_packet_s
));
137 memset(ep
, 0, sizeof(struct eth_packet_s
));
138 ep
->len
= tapcfg_read(s
->tapcfg
, ep
->data
, ETH_LEN
);
145 for(tep
=s
->ethpack
; tep
->next
; tep
=tep
->next
);
151 static const char macadr
[6] = {0xaa, 0xb6, 0x24, 0x69, 0x77, 0x21};
153 static int xgmii_ethernet_new(void **sess
, char *args
)
157 char *c_tap_ip
= NULL
;
158 struct session_s
*s
= NULL
;
159 struct timeval tv
= {10, 0};
165 s
=(struct session_s
*)malloc(sizeof(struct session_s
));
170 memset(s
, 0, sizeof(struct session_s
));
172 ret
= litex_sim_module_get_args(args
, "interface", &c_tap
);
177 ret
= litex_sim_module_get_args(args
, "ip", &c_tap_ip
);
183 s
->tapcfg
= tapcfg_init();
184 tapcfg_start(s
->tapcfg
, c_tap
, 0);
185 s
->fd
= tapcfg_get_fd(s
->tapcfg
);
186 tapcfg_iface_set_hwaddr(s
->tapcfg
, macadr
, 6);
187 tapcfg_iface_set_ipv4(s
->tapcfg
, c_tap_ip
, 24);
188 tapcfg_iface_set_status(s
->tapcfg
, TAPCFG_STATUS_ALL_UP
);
192 s
->ev
= event_new(base
, s
->fd
, EV_READ
| EV_PERSIST
, event_handler
, s
);
193 event_add(s
->ev
, &tv
);
200 static int xgmii_ethernet_add_pads(void *sess
, struct pad_list_s
*plist
)
203 struct session_s
*s
= (struct session_s
*)sess
;
205 if(!sess
|| !plist
) {
210 if(!strcmp(plist
->name
, "eth")) {
211 litex_sim_module_pads_get(pads
, "rx_data", (void**)&s
->rx_data
);
212 litex_sim_module_pads_get(pads
, "rx_ctl", (void**)&s
->rx_ctl
);
213 litex_sim_module_pads_get(pads
, "tx_data", (void**)&s
->tx_data
);
214 litex_sim_module_pads_get(pads
, "tx_ctl", (void**)&s
->tx_ctl
);
217 if(!strcmp(plist
->name
, "sys_clk"))
218 litex_sim_module_pads_get(pads
, "sys_clk", (void**)&s
->sys_clk
);
227 unsigned long int g_mask
= 0xff;
228 unsigned long int g_idle
= 0x0707070707070707;
232 unsigned int g_mask
= 0xff;
233 unsigned int g_idle
= 0x07070707;
236 static int xgmii_ethernet_tick(void *sess
, uint64_t time_ps
)
238 static struct clk_edge_t edge
;
239 struct session_s
*s
= (struct session_s
*)sess
;
240 struct eth_packet_s
*pep
;
242 if(!clk_pos_edge(&edge
, *s
->sys_clk
)) {
255 // printf("%16lx\t\t%x\n", u, *s->tx_ctl & g_mask);
257 // printf("%16lx\t\t%x\n", u, *s->tx_ctl & g_mask);
258 // printf("preamble: %02x\n", g_preamble);
261 if ((g_preamble
== 0) && (*s
->tx_ctl
& g_mask
) == 0x1) {
262 g_preamble
= (g_dw
== 64)? 2: 1;
263 } else if (g_preamble
== 1) {
265 } else if (g_preamble
== 2) {
266 if ((*s
->tx_ctl
& g_mask
) != 0) {
267 // Intentionally ignoring errors for now (since we don't really have retransmission)
268 // So this means last word
269 // TODO: Check for end of frame mid word
270 for (int m
= 0; m
< (g_dw
>> 3); m
++) {
272 if ((*s
->tx_ctl
& mask
) == 0)
273 s
->databuf
[s
->datalen
++] = (char) ((u
& (g_mask
<< (8*m
))) >> (8*m
));
276 // Enable for debugging
277 printf("Sending: \n");
278 for(int i
=0; i
< s
->datalen
; printf("%02x ", s
->databuf
[i
++] & 0xff));
279 printf("\n%u\n", s
->datalen
);
280 printf("Sent %u\n", s
->datalen
);
281 tapcfg_write(s
->tapcfg
, s
->databuf
, s
->datalen
);
285 for (int i
= 0; i
< (g_dw
>> 3); i
++) {
286 assert(s
->datalen
<= ETH_LEN
);
287 s
->databuf
[s
->datalen
++]= (char) ((u
& (g_mask
<< (8 * i
))) >> (8*i
));
293 unsigned long int local_data
= 0x0707070707070707;
294 unsigned long int temp_data
= 0; // This is here just to avoid an ugly cast later
296 unsigned int local_data
= 0x07070707;
297 unsigned int temp_data
= 0;
302 // printf("%x ", s->rx_state);
303 if (s
->rx_state
== 0) {
304 *s
->rx_data
= 0xd5555555555555fb;
307 } else if ((s
->rx_state
== 1) && (s
->insent
+ (g_dw
>> 3) < s
->inlen
)) {
310 for (unsigned int i
= 0; i
< (g_dw
>> 3); i
++) {
311 temp_data
= (unsigned char) s
->inbuf
[s
->insent
++];
312 local_data
|= (temp_data
<< (i
<< 3));
314 *s
->rx_data
= local_data
;
315 } else if ((s
->rx_state
== 1) && (s
->insent
+ (g_dw
>> 3) >= s
->inlen
)) {
316 // printf("%d, %d\n", s->insent, s->inlen);
318 for (unsigned int i
= 0; i
< (g_dw
>> 3); i
++) {
319 if (s
->insent
< s
->inlen
) {
320 temp_data
= (unsigned char) s
->inbuf
[s
->insent
++];
321 } else if (s
->insent
== s
->inlen
) {
322 temp_data
= (unsigned char) 0xfd;
326 temp_data
= (unsigned char) 0x07;
330 local_data
|= (temp_data
<< (i
<< 3));
331 local_ctl
|= (temp_ctl
<< i
);
332 //printf("%16lx %02x\n", local_data, local_ctl);
334 *s
->rx_data
= local_data
;
335 *s
->rx_ctl
= local_ctl
;
336 if (s
->insent
== s
->inlen
)
343 } else if (s
->rx_state
== 2) {
345 *s
->rx_data
= 0x07070707070707fd;
351 *s
->rx_data
= local_data
;
353 // printf("%x, %16lx, %x\n", s->rx_state, *s->rx_data, *s->rx_ctl);
356 *s
->rx_data
= local_data
;
358 memcpy(s
->inbuf
, s
->ethpack
->data
, s
->ethpack
->len
);
359 printf("Received: %ld\n", s
->ethpack
->len
);
360 for(int i
=0; i
< s
->ethpack
->len
;) {
361 printf("%02x ", s
->inbuf
[i
++] & 0xff);
364 s
->inlen
= s
->ethpack
->len
;
365 pep
=s
->ethpack
->next
;
373 static struct ext_module_s ext_mod
= {
375 xgmii_ethernet_start
,
377 xgmii_ethernet_add_pads
,
382 int litex_sim_ext_module_init(int (*register_module
)(struct ext_module_s
*))
385 ret
= register_module(&ext_mod
);