1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include "qemu/osdep.h"
29#include "qemu/log.h"
30#include "chardev/char.h"
31#include "hw/irq.h"
32#include "migration/vmstate.h"
33#include "net/can_emu.h"
34
35#include "can_sja1000.h"
36
37#ifndef DEBUG_FILTER
38#define DEBUG_FILTER 0
39#endif
40
41#ifndef DEBUG_CAN
42#define DEBUG_CAN 0
43#endif
44
45#define DPRINTF(fmt, ...) \
46 do { \
47 if (DEBUG_CAN) { \
48 qemu_log("[cansja]: " fmt , ## __VA_ARGS__); \
49 } \
50 } while (0)
51
52static void can_sja_software_reset(CanSJA1000State *s)
53{
54 s->mode &= ~0x31;
55 s->mode |= 0x01;
56 s->status_pel &= ~0x37;
57 s->status_pel |= 0x34;
58
59 s->rxbuf_start = 0x00;
60 s->rxmsg_cnt = 0x00;
61 s->rx_cnt = 0x00;
62}
63
64void can_sja_hardware_reset(CanSJA1000State *s)
65{
66
67 s->mode = 0x01;
68 s->status_pel = 0x3c;
69 s->interrupt_pel = 0x00;
70 s->clock = 0x00;
71 s->rxbuf_start = 0x00;
72 s->rxmsg_cnt = 0x00;
73 s->rx_cnt = 0x00;
74
75 s->control = 0x01;
76 s->status_bas = 0x0c;
77 s->interrupt_bas = 0x00;
78
79 qemu_irq_lower(s->irq);
80}
81
82static
83void can_sja_single_filter(struct qemu_can_filter *filter,
84 const uint8_t *acr, const uint8_t *amr, int extended)
85{
86 if (extended) {
87 filter->can_id = (uint32_t)acr[0] << 21;
88 filter->can_id |= (uint32_t)acr[1] << 13;
89 filter->can_id |= (uint32_t)acr[2] << 5;
90 filter->can_id |= (uint32_t)acr[3] >> 3;
91 if (acr[3] & 4) {
92 filter->can_id |= QEMU_CAN_RTR_FLAG;
93 }
94
95 filter->can_mask = (uint32_t)amr[0] << 21;
96 filter->can_mask |= (uint32_t)amr[1] << 13;
97 filter->can_mask |= (uint32_t)amr[2] << 5;
98 filter->can_mask |= (uint32_t)amr[3] >> 3;
99 filter->can_mask = ~filter->can_mask & QEMU_CAN_EFF_MASK;
100 if (!(amr[3] & 4)) {
101 filter->can_mask |= QEMU_CAN_RTR_FLAG;
102 }
103 } else {
104 filter->can_id = (uint32_t)acr[0] << 3;
105 filter->can_id |= (uint32_t)acr[1] >> 5;
106 if (acr[1] & 0x10) {
107 filter->can_id |= QEMU_CAN_RTR_FLAG;
108 }
109
110 filter->can_mask = (uint32_t)amr[0] << 3;
111 filter->can_mask |= (uint32_t)amr[1] << 5;
112 filter->can_mask = ~filter->can_mask & QEMU_CAN_SFF_MASK;
113 if (!(amr[1] & 0x10)) {
114 filter->can_mask |= QEMU_CAN_RTR_FLAG;
115 }
116 }
117}
118
119static
120void can_sja_dual_filter(struct qemu_can_filter *filter,
121 const uint8_t *acr, const uint8_t *amr, int extended)
122{
123 if (extended) {
124 filter->can_id = (uint32_t)acr[0] << 21;
125 filter->can_id |= (uint32_t)acr[1] << 13;
126
127 filter->can_mask = (uint32_t)amr[0] << 21;
128 filter->can_mask |= (uint32_t)amr[1] << 13;
129 filter->can_mask = ~filter->can_mask & QEMU_CAN_EFF_MASK & ~0x1fff;
130 } else {
131 filter->can_id = (uint32_t)acr[0] << 3;
132 filter->can_id |= (uint32_t)acr[1] >> 5;
133 if (acr[1] & 0x10) {
134 filter->can_id |= QEMU_CAN_RTR_FLAG;
135 }
136
137 filter->can_mask = (uint32_t)amr[0] << 3;
138 filter->can_mask |= (uint32_t)amr[1] >> 5;
139 filter->can_mask = ~filter->can_mask & QEMU_CAN_SFF_MASK;
140 if (!(amr[1] & 0x10)) {
141 filter->can_mask |= QEMU_CAN_RTR_FLAG;
142 }
143 }
144}
145
146
147static
148int can_sja_accept_filter(CanSJA1000State *s,
149 const qemu_can_frame *frame)
150{
151
152 struct qemu_can_filter filter;
153
154 if (s->clock & 0x80) {
155 if (s->mode & (1 << 3)) {
156 if (frame->can_id & QEMU_CAN_EFF_FLAG) {
157 can_sja_single_filter(&filter,
158 s->code_mask + 0, s->code_mask + 4, 1);
159
160 if (!can_bus_filter_match(&filter, frame->can_id)) {
161 return 0;
162 }
163 } else {
164 can_sja_single_filter(&filter,
165 s->code_mask + 0, s->code_mask + 4, 0);
166
167 if (!can_bus_filter_match(&filter, frame->can_id)) {
168 return 0;
169 }
170
171 if (frame->can_id & QEMU_CAN_RTR_FLAG) {
172 return 1;
173 }
174
175 if (frame->can_dlc == 0) {
176 return 1;
177 }
178
179 if ((frame->data[0] & ~(s->code_mask[6])) !=
180 (s->code_mask[2] & ~(s->code_mask[6]))) {
181 return 0;
182 }
183
184 if (frame->can_dlc < 2) {
185 return 1;
186 }
187
188 if ((frame->data[1] & ~(s->code_mask[7])) ==
189 (s->code_mask[3] & ~(s->code_mask[7]))) {
190 return 1;
191 }
192
193 return 0;
194 }
195 } else {
196 if (frame->can_id & QEMU_CAN_EFF_FLAG) {
197 can_sja_dual_filter(&filter,
198 s->code_mask + 0, s->code_mask + 4, 1);
199
200 if (can_bus_filter_match(&filter, frame->can_id)) {
201 return 1;
202 }
203
204 can_sja_dual_filter(&filter,
205 s->code_mask + 2, s->code_mask + 6, 1);
206
207 if (can_bus_filter_match(&filter, frame->can_id)) {
208 return 1;
209 }
210
211 return 0;
212 } else {
213 can_sja_dual_filter(&filter,
214 s->code_mask + 0, s->code_mask + 4, 0);
215
216 if (can_bus_filter_match(&filter, frame->can_id)) {
217 uint8_t expect;
218 uint8_t mask;
219 expect = s->code_mask[1] << 4;
220 expect |= s->code_mask[3] & 0x0f;
221
222 mask = s->code_mask[5] << 4;
223 mask |= s->code_mask[7] & 0x0f;
224 mask = ~mask & 0xff;
225
226 if ((frame->data[0] & mask) ==
227 (expect & mask)) {
228 return 1;
229 }
230 }
231
232 can_sja_dual_filter(&filter,
233 s->code_mask + 2, s->code_mask + 6, 0);
234
235 if (can_bus_filter_match(&filter, frame->can_id)) {
236 return 1;
237 }
238
239 return 0;
240 }
241 }
242 }
243
244 return 1;
245}
246
247static void can_display_msg(const char *prefix, const qemu_can_frame *msg)
248{
249 int i;
250 FILE *logfile = qemu_log_lock();
251
252 qemu_log("%s%03X [%01d] %s %s",
253 prefix,
254 msg->can_id & QEMU_CAN_EFF_MASK,
255 msg->can_dlc,
256 msg->can_id & QEMU_CAN_EFF_FLAG ? "EFF" : "SFF",
257 msg->can_id & QEMU_CAN_RTR_FLAG ? "RTR" : "DAT");
258
259 for (i = 0; i < msg->can_dlc; i++) {
260 qemu_log(" %02X", msg->data[i]);
261 }
262 qemu_log("\n");
263 qemu_log_flush();
264 qemu_log_unlock(logfile);
265}
266
267static void buff2frame_pel(const uint8_t *buff, qemu_can_frame *frame)
268{
269 uint8_t i;
270
271 frame->flags = 0;
272 frame->can_id = 0;
273 if (buff[0] & 0x40) {
274 frame->can_id = QEMU_CAN_RTR_FLAG;
275 }
276 frame->can_dlc = buff[0] & 0x0f;
277
278 if (frame->can_dlc > 8) {
279 frame->can_dlc = 8;
280 }
281
282 if (buff[0] & 0x80) {
283 frame->can_id |= QEMU_CAN_EFF_FLAG;
284 frame->can_id |= buff[1] << 21;
285 frame->can_id |= buff[2] << 13;
286 frame->can_id |= buff[3] << 5;
287 frame->can_id |= buff[4] >> 3;
288 for (i = 0; i < frame->can_dlc; i++) {
289 frame->data[i] = buff[5 + i];
290 }
291 for (; i < 8; i++) {
292 frame->data[i] = 0;
293 }
294 } else {
295 frame->can_id |= buff[1] << 3;
296 frame->can_id |= buff[2] >> 5;
297 for (i = 0; i < frame->can_dlc; i++) {
298 frame->data[i] = buff[3 + i];
299 }
300 for (; i < 8; i++) {
301 frame->data[i] = 0;
302 }
303 }
304}
305
306
307static void buff2frame_bas(const uint8_t *buff, qemu_can_frame *frame)
308{
309 uint8_t i;
310
311 frame->flags = 0;
312 frame->can_id = ((buff[0] << 3) & (0xff << 3)) + ((buff[1] >> 5) & 0x07);
313 if (buff[1] & 0x10) {
314 frame->can_id = QEMU_CAN_RTR_FLAG;
315 }
316 frame->can_dlc = buff[1] & 0x0f;
317
318 if (frame->can_dlc > 8) {
319 frame->can_dlc = 8;
320 }
321
322 for (i = 0; i < frame->can_dlc; i++) {
323 frame->data[i] = buff[2 + i];
324 }
325 for (; i < 8; i++) {
326 frame->data[i] = 0;
327 }
328}
329
330
331static int frame2buff_pel(const qemu_can_frame *frame, uint8_t *buff)
332{
333 int i;
334 int dlen = frame->can_dlc;
335
336 if (frame->can_id & QEMU_CAN_ERR_FLAG) {
337 return -1;
338 }
339
340 if (dlen > 8) {
341 return -1;
342 }
343
344 buff[0] = 0x0f & frame->can_dlc;
345 if (frame->can_id & QEMU_CAN_RTR_FLAG) {
346 buff[0] |= (1 << 6);
347 }
348 if (frame->can_id & QEMU_CAN_EFF_FLAG) {
349 buff[0] |= (1 << 7);
350 buff[1] = extract32(frame->can_id, 21, 8);
351 buff[2] = extract32(frame->can_id, 13, 8);
352 buff[3] = extract32(frame->can_id, 5, 8);
353 buff[4] = extract32(frame->can_id, 0, 5) << 3;
354 for (i = 0; i < dlen; i++) {
355 buff[5 + i] = frame->data[i];
356 }
357 return dlen + 5;
358 } else {
359 buff[1] = extract32(frame->can_id, 3, 8);
360 buff[2] = extract32(frame->can_id, 0, 3) << 5;
361 for (i = 0; i < dlen; i++) {
362 buff[3 + i] = frame->data[i];
363 }
364
365 return dlen + 3;
366 }
367
368 return -1;
369}
370
371static int frame2buff_bas(const qemu_can_frame *frame, uint8_t *buff)
372{
373 int i;
374 int dlen = frame->can_dlc;
375
376
377
378
379
380
381 if ((frame->can_id & QEMU_CAN_EFF_FLAG) ||
382 (frame->can_id & QEMU_CAN_ERR_FLAG)) {
383 return -1;
384 }
385
386 if (dlen > 8) {
387 return -1;
388 }
389
390 buff[0] = extract32(frame->can_id, 3, 8);
391 buff[1] = extract32(frame->can_id, 0, 3) << 5;
392 if (frame->can_id & QEMU_CAN_RTR_FLAG) {
393 buff[1] |= (1 << 4);
394 }
395 buff[1] |= frame->can_dlc & 0x0f;
396 for (i = 0; i < dlen; i++) {
397 buff[2 + i] = frame->data[i];
398 }
399
400 return dlen + 2;
401}
402
403static void can_sja_update_pel_irq(CanSJA1000State *s)
404{
405 if (s->interrupt_en & s->interrupt_pel) {
406 qemu_irq_raise(s->irq);
407 } else {
408 qemu_irq_lower(s->irq);
409 }
410}
411
412static void can_sja_update_bas_irq(CanSJA1000State *s)
413{
414 if ((s->control >> 1) & s->interrupt_bas) {
415 qemu_irq_raise(s->irq);
416 } else {
417 qemu_irq_lower(s->irq);
418 }
419}
420
421void can_sja_mem_write(CanSJA1000State *s, hwaddr addr, uint64_t val,
422 unsigned size)
423{
424 qemu_can_frame frame;
425 uint32_t tmp;
426 uint8_t tmp8, count;
427
428
429 DPRINTF("write 0x%02llx addr 0x%02x\n",
430 (unsigned long long)val, (unsigned int)addr);
431
432 if (addr > CAN_SJA_MEM_SIZE) {
433 return ;
434 }
435
436 if (s->clock & 0x80) {
437 switch (addr) {
438 case SJA_MOD:
439 s->mode = 0x1f & val;
440 if ((s->mode & 0x01) && ((val & 0x01) == 0)) {
441
442 if (s->mode & (1 << 3)) {
443
444 can_sja_single_filter(&s->filter[0],
445 s->code_mask + 0, s->code_mask + 4, 1);
446
447
448 can_sja_single_filter(&s->filter[1],
449 s->code_mask + 0, s->code_mask + 4, 0);
450
451 can_bus_client_set_filters(&s->bus_client, s->filter, 2);
452 } else {
453
454 can_sja_dual_filter(&s->filter[0],
455 s->code_mask + 0, s->code_mask + 4, 1);
456
457 can_sja_dual_filter(&s->filter[1],
458 s->code_mask + 2, s->code_mask + 6, 1);
459
460
461 can_sja_dual_filter(&s->filter[2],
462 s->code_mask + 0, s->code_mask + 4, 0);
463
464 can_sja_dual_filter(&s->filter[3],
465 s->code_mask + 2, s->code_mask + 6, 0);
466
467 can_bus_client_set_filters(&s->bus_client, s->filter, 4);
468 }
469
470 s->rxmsg_cnt = 0;
471 s->rx_cnt = 0;
472 }
473 break;
474
475 case SJA_CMR:
476 if (0x01 & val) {
477 buff2frame_pel(s->tx_buff, &frame);
478 if (DEBUG_FILTER) {
479 can_display_msg("[cansja]: Tx request " , &frame);
480 }
481
482
483
484
485
486
487 s->status_pel &= ~(3 << 2);
488
489 can_bus_client_send(&s->bus_client, &frame, 1);
490
491
492
493
494
495 s->status_pel |= (3 << 2);
496
497
498 s->status_pel &= ~(1 << 5);
499 s->interrupt_pel |= 0x02;
500 can_sja_update_pel_irq(s);
501 }
502 if (0x04 & val) {
503 if (s->rxmsg_cnt <= 0) {
504 break;
505 }
506
507 tmp8 = s->rx_buff[s->rxbuf_start]; count = 0;
508 if (tmp8 & (1 << 7)) {
509 count += 2;
510 }
511 count += 3;
512 if (!(tmp8 & (1 << 6))) {
513 count += (tmp8 & 0x0f);
514 }
515
516 if (DEBUG_FILTER) {
517 qemu_log("[cansja]: message released from "
518 "Rx FIFO cnt=%d, count=%d\n", s->rx_cnt, count);
519 }
520
521 s->rxbuf_start += count;
522 s->rxbuf_start %= SJA_RCV_BUF_LEN;
523
524 s->rx_cnt -= count;
525 s->rxmsg_cnt--;
526 if (s->rxmsg_cnt == 0) {
527 s->status_pel &= ~(1 << 0);
528 s->interrupt_pel &= ~(1 << 0);
529 can_sja_update_pel_irq(s);
530 }
531 }
532 if (0x08 & val) {
533 s->status_pel &= ~(1 << 1);
534 s->interrupt_pel &= ~(1 << 3);
535 can_sja_update_pel_irq(s);
536 }
537 break;
538 case SJA_SR:
539 case SJA_IR:
540 break;
541 case SJA_IER:
542 s->interrupt_en = val;
543 break;
544 case 16:
545 s->status_pel |= (1 << 5);
546
547 case 17 ... 28:
548 if (s->mode & 0x01) {
549 if (addr < 24) {
550 s->code_mask[addr - 16] = val;
551 }
552 } else {
553 s->tx_buff[addr - 16] = val;
554 }
555 break;
556 case SJA_CDR:
557 s->clock = val;
558 break;
559 }
560 } else {
561 switch (addr) {
562 case SJA_BCAN_CTR:
563 if ((s->control & 0x01) && ((val & 0x01) == 0)) {
564
565 s->filter[0].can_id = (s->code << 3) & (0xff << 3);
566 tmp = (~(s->mask << 3)) & (0xff << 3);
567 tmp |= QEMU_CAN_EFF_FLAG;
568 s->filter[0].can_mask = tmp;
569 can_bus_client_set_filters(&s->bus_client, s->filter, 1);
570
571 s->rxmsg_cnt = 0;
572 s->rx_cnt = 0;
573 } else if (!(s->control & 0x01) && !(val & 0x01)) {
574 can_sja_software_reset(s);
575 }
576
577 s->control = 0x1f & val;
578 break;
579 case SJA_BCAN_CMR:
580 if (0x01 & val) {
581 buff2frame_bas(s->tx_buff, &frame);
582 if (DEBUG_FILTER) {
583 can_display_msg("[cansja]: Tx request " , &frame);
584 }
585
586
587
588
589
590 s->status_bas &= ~(3 << 2);
591
592
593 can_bus_client_send(&s->bus_client, &frame, 1);
594
595
596
597
598
599 s->status_bas |= (3 << 2);
600
601
602 s->status_bas &= ~(1 << 5);
603 s->interrupt_bas |= 0x02;
604 can_sja_update_bas_irq(s);
605 }
606 if (0x04 & val) {
607 if (s->rxmsg_cnt <= 0) {
608 break;
609 }
610
611 tmp8 = s->rx_buff[(s->rxbuf_start + 1) % SJA_RCV_BUF_LEN];
612 count = 2 + (tmp8 & 0x0f);
613
614 if (DEBUG_FILTER) {
615 qemu_log("[cansja]: message released from "
616 "Rx FIFO cnt=%d, count=%d\n", s->rx_cnt, count);
617 }
618
619 s->rxbuf_start += count;
620 s->rxbuf_start %= SJA_RCV_BUF_LEN;
621 s->rx_cnt -= count;
622 s->rxmsg_cnt--;
623
624 if (s->rxmsg_cnt == 0) {
625 s->status_bas &= ~(1 << 0);
626 s->interrupt_bas &= ~(1 << 0);
627 can_sja_update_bas_irq(s);
628 }
629 }
630 if (0x08 & val) {
631 s->status_bas &= ~(1 << 1);
632 s->interrupt_bas &= ~(1 << 3);
633 can_sja_update_bas_irq(s);
634 }
635 break;
636 case 4:
637 s->code = val;
638 break;
639 case 5:
640 s->mask = val;
641 break;
642 case 10:
643 s->status_bas |= (1 << 5);
644
645 case 11 ... 19:
646 if ((s->control & 0x01) == 0) {
647 s->tx_buff[addr - 10] = val;
648 }
649 break;
650 case SJA_CDR:
651 s->clock = val;
652 break;
653 }
654 }
655}
656
657uint64_t can_sja_mem_read(CanSJA1000State *s, hwaddr addr, unsigned size)
658{
659 uint64_t temp = 0;
660
661 DPRINTF("read addr 0x%02x ...\n", (unsigned int)addr);
662
663 if (addr > CAN_SJA_MEM_SIZE) {
664 return 0;
665 }
666
667 if (s->clock & 0x80) {
668 switch (addr) {
669 case SJA_MOD:
670 temp = s->mode;
671 break;
672 case SJA_CMR:
673 temp = 0x00;
674 break;
675 case SJA_SR:
676 temp = s->status_pel;
677 break;
678 case SJA_IR:
679 temp = s->interrupt_pel;
680 s->interrupt_pel = 0;
681 if (s->rxmsg_cnt) {
682 s->interrupt_pel |= (1 << 0);
683 }
684 can_sja_update_pel_irq(s);
685 break;
686 case SJA_IER:
687 temp = s->interrupt_en;
688 break;
689 case 5:
690 case 6:
691 case 7:
692 case 8:
693
694
695
696 case 9:
697 case 10 ... 15:
698 temp = 0x00;
699 break;
700
701 case 16 ... 28:
702 if (s->mode & 0x01) {
703 if (addr < 24) {
704 temp = s->code_mask[addr - 16];
705 } else {
706 temp = 0x00;
707 }
708 } else {
709 temp = s->rx_buff[(s->rxbuf_start + addr - 16) %
710 SJA_RCV_BUF_LEN];
711 }
712 break;
713 case SJA_CDR:
714 temp = s->clock;
715 break;
716 default:
717 temp = 0xff;
718 }
719 } else {
720 switch (addr) {
721 case SJA_BCAN_CTR:
722 temp = s->control;
723 break;
724 case SJA_BCAN_SR:
725 temp = s->status_bas;
726 break;
727 case SJA_BCAN_IR:
728 temp = s->interrupt_bas;
729 s->interrupt_bas = 0;
730 if (s->rxmsg_cnt) {
731 s->interrupt_bas |= (1 << 0);
732 }
733 can_sja_update_bas_irq(s);
734 break;
735 case 4:
736 temp = s->code;
737 break;
738 case 5:
739 temp = s->mask;
740 break;
741 case 20 ... 29:
742 temp = s->rx_buff[(s->rxbuf_start + addr - 20) % SJA_RCV_BUF_LEN];
743 break;
744 case 31:
745 temp = s->clock;
746 break;
747 default:
748 temp = 0xff;
749 break;
750 }
751 }
752 DPRINTF("read addr 0x%02x, %d bytes, content 0x%02lx\n",
753 (int)addr, size, (long unsigned int)temp);
754
755 return temp;
756}
757
758bool can_sja_can_receive(CanBusClientState *client)
759{
760 CanSJA1000State *s = container_of(client, CanSJA1000State, bus_client);
761
762 if (s->clock & 0x80) {
763 if (s->mode & 0x01) {
764 return false;
765 }
766 } else {
767 if (s->control & 0x01) {
768 return false;
769 }
770 }
771
772 return true;
773}
774
775ssize_t can_sja_receive(CanBusClientState *client, const qemu_can_frame *frames,
776 size_t frames_cnt)
777{
778 CanSJA1000State *s = container_of(client, CanSJA1000State, bus_client);
779 static uint8_t rcv[SJA_MSG_MAX_LEN];
780 int i;
781 int ret = -1;
782 const qemu_can_frame *frame = frames;
783
784 if (frames_cnt <= 0) {
785 return 0;
786 }
787 if (frame->flags & QEMU_CAN_FRMF_TYPE_FD) {
788 if (DEBUG_FILTER) {
789 can_display_msg("[cansja]: ignor fd frame ", frame);
790 }
791 return 1;
792 }
793
794 if (DEBUG_FILTER) {
795 can_display_msg("[cansja]: receive ", frame);
796 }
797
798 if (s->clock & 0x80) {
799
800
801 s->status_pel |= (1 << 4);
802
803 if (can_sja_accept_filter(s, frame) == 0) {
804 s->status_pel &= ~(1 << 4);
805 if (DEBUG_FILTER) {
806 qemu_log("[cansja]: filter rejects message\n");
807 }
808 return ret;
809 }
810
811 ret = frame2buff_pel(frame, rcv);
812 if (ret < 0) {
813 s->status_pel &= ~(1 << 4);
814 if (DEBUG_FILTER) {
815 qemu_log("[cansja]: message store failed\n");
816 }
817 return ret;
818 }
819
820 if (s->rx_cnt + ret > SJA_RCV_BUF_LEN) {
821 s->status_pel |= (1 << 1);
822 s->interrupt_pel |= (1 << 3);
823 s->status_pel &= ~(1 << 4);
824 if (DEBUG_FILTER) {
825 qemu_log("[cansja]: receive FIFO overrun\n");
826 }
827 can_sja_update_pel_irq(s);
828 return ret;
829 }
830 s->rx_cnt += ret;
831 s->rxmsg_cnt++;
832 if (DEBUG_FILTER) {
833 qemu_log("[cansja]: message stored in receive FIFO\n");
834 }
835
836 for (i = 0; i < ret; i++) {
837 s->rx_buff[(s->rx_ptr++) % SJA_RCV_BUF_LEN] = rcv[i];
838 }
839 s->rx_ptr %= SJA_RCV_BUF_LEN;
840
841 s->status_pel |= 0x01;
842 s->interrupt_pel |= 0x01;
843 s->status_pel &= ~(1 << 4);
844 s->status_pel |= (1 << 0);
845 can_sja_update_pel_irq(s);
846 } else {
847
848
849 s->status_bas |= (1 << 4);
850
851 ret = frame2buff_bas(frame, rcv);
852 if (ret < 0) {
853 s->status_bas &= ~(1 << 4);
854 if (DEBUG_FILTER) {
855 qemu_log("[cansja]: message store failed\n");
856 }
857 return ret;
858 }
859
860 if (s->rx_cnt + ret > SJA_RCV_BUF_LEN) {
861 s->status_bas |= (1 << 1);
862 s->status_bas &= ~(1 << 4);
863 s->interrupt_bas |= (1 << 3);
864 can_sja_update_bas_irq(s);
865 if (DEBUG_FILTER) {
866 qemu_log("[cansja]: receive FIFO overrun\n");
867 }
868 return ret;
869 }
870 s->rx_cnt += ret;
871 s->rxmsg_cnt++;
872
873 if (DEBUG_FILTER) {
874 qemu_log("[cansja]: message stored\n");
875 }
876
877 for (i = 0; i < ret; i++) {
878 s->rx_buff[(s->rx_ptr++) % SJA_RCV_BUF_LEN] = rcv[i];
879 }
880 s->rx_ptr %= SJA_RCV_BUF_LEN;
881
882 s->status_bas |= 0x01;
883 s->status_bas &= ~(1 << 4);
884 s->interrupt_bas |= (1 << 0);
885 can_sja_update_bas_irq(s);
886 }
887 return 1;
888}
889
890static CanBusClientInfo can_sja_bus_client_info = {
891 .can_receive = can_sja_can_receive,
892 .receive = can_sja_receive,
893};
894
895
896int can_sja_connect_to_bus(CanSJA1000State *s, CanBusState *bus)
897{
898 s->bus_client.info = &can_sja_bus_client_info;
899
900 if (!bus) {
901 return -EINVAL;
902 }
903
904 if (can_bus_insert_client(bus, &s->bus_client) < 0) {
905 return -1;
906 }
907
908 return 0;
909}
910
911void can_sja_disconnect(CanSJA1000State *s)
912{
913 can_bus_remove_client(&s->bus_client);
914}
915
916int can_sja_init(CanSJA1000State *s, qemu_irq irq)
917{
918 s->irq = irq;
919
920 qemu_irq_lower(s->irq);
921
922 can_sja_hardware_reset(s);
923
924 return 0;
925}
926
927const VMStateDescription vmstate_qemu_can_filter = {
928 .name = "qemu_can_filter",
929 .version_id = 1,
930 .minimum_version_id = 1,
931 .minimum_version_id_old = 1,
932 .fields = (VMStateField[]) {
933 VMSTATE_UINT32(can_id, qemu_can_filter),
934 VMSTATE_UINT32(can_mask, qemu_can_filter),
935 VMSTATE_END_OF_LIST()
936 }
937};
938
939static int can_sja_post_load(void *opaque, int version_id)
940{
941 CanSJA1000State *s = opaque;
942 if (s->clock & 0x80) {
943 can_sja_update_pel_irq(s);
944 } else {
945 can_sja_update_bas_irq(s);
946 }
947 return 0;
948}
949
950
951const VMStateDescription vmstate_can_sja = {
952 .name = "can_sja",
953 .version_id = 1,
954 .minimum_version_id = 1,
955 .minimum_version_id_old = 1,
956 .post_load = can_sja_post_load,
957 .fields = (VMStateField[]) {
958 VMSTATE_UINT8(mode, CanSJA1000State),
959
960 VMSTATE_UINT8(status_pel, CanSJA1000State),
961 VMSTATE_UINT8(interrupt_pel, CanSJA1000State),
962 VMSTATE_UINT8(interrupt_en, CanSJA1000State),
963 VMSTATE_UINT8(rxmsg_cnt, CanSJA1000State),
964 VMSTATE_UINT8(rxbuf_start, CanSJA1000State),
965 VMSTATE_UINT8(clock, CanSJA1000State),
966
967 VMSTATE_BUFFER(code_mask, CanSJA1000State),
968 VMSTATE_BUFFER(tx_buff, CanSJA1000State),
969
970 VMSTATE_BUFFER(rx_buff, CanSJA1000State),
971
972 VMSTATE_UINT32(rx_ptr, CanSJA1000State),
973 VMSTATE_UINT32(rx_cnt, CanSJA1000State),
974
975 VMSTATE_UINT8(control, CanSJA1000State),
976
977 VMSTATE_UINT8(status_bas, CanSJA1000State),
978 VMSTATE_UINT8(interrupt_bas, CanSJA1000State),
979 VMSTATE_UINT8(code, CanSJA1000State),
980 VMSTATE_UINT8(mask, CanSJA1000State),
981
982 VMSTATE_STRUCT_ARRAY(filter, CanSJA1000State, 4, 0,
983 vmstate_qemu_can_filter, qemu_can_filter),
984
985
986 VMSTATE_END_OF_LIST()
987 }
988};
989