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 (buff[0] & 0x80) {
279 frame->can_id |= QEMU_CAN_EFF_FLAG;
280 frame->can_id |= buff[1] << 21;
281 frame->can_id |= buff[2] << 13;
282 frame->can_id |= buff[3] << 5;
283 frame->can_id |= buff[4] >> 3;
284 for (i = 0; i < frame->can_dlc; i++) {
285 frame->data[i] = buff[5 + i];
286 }
287 for (; i < 8; i++) {
288 frame->data[i] = 0;
289 }
290 } else {
291 frame->can_id |= buff[1] << 3;
292 frame->can_id |= buff[2] >> 5;
293 for (i = 0; i < frame->can_dlc; i++) {
294 frame->data[i] = buff[3 + i];
295 }
296 for (; i < 8; i++) {
297 frame->data[i] = 0;
298 }
299 }
300}
301
302
303static void buff2frame_bas(const uint8_t *buff, qemu_can_frame *frame)
304{
305 uint8_t i;
306
307 frame->flags = 0;
308 frame->can_id = ((buff[0] << 3) & (0xff << 3)) + ((buff[1] >> 5) & 0x07);
309 if (buff[1] & 0x10) {
310 frame->can_id = QEMU_CAN_RTR_FLAG;
311 }
312 frame->can_dlc = buff[1] & 0x0f;
313
314 for (i = 0; i < frame->can_dlc; i++) {
315 frame->data[i] = buff[2 + i];
316 }
317 for (; i < 8; i++) {
318 frame->data[i] = 0;
319 }
320}
321
322
323static int frame2buff_pel(const qemu_can_frame *frame, uint8_t *buff)
324{
325 int i;
326 int dlen = frame->can_dlc;
327
328 if (frame->can_id & QEMU_CAN_ERR_FLAG) {
329 return -1;
330 }
331
332 if (dlen > 8) {
333 return -1;
334 }
335
336 buff[0] = 0x0f & frame->can_dlc;
337 if (frame->can_id & QEMU_CAN_RTR_FLAG) {
338 buff[0] |= (1 << 6);
339 }
340 if (frame->can_id & QEMU_CAN_EFF_FLAG) {
341 buff[0] |= (1 << 7);
342 buff[1] = extract32(frame->can_id, 21, 8);
343 buff[2] = extract32(frame->can_id, 13, 8);
344 buff[3] = extract32(frame->can_id, 5, 8);
345 buff[4] = extract32(frame->can_id, 0, 5) << 3;
346 for (i = 0; i < dlen; i++) {
347 buff[5 + i] = frame->data[i];
348 }
349 return dlen + 5;
350 } else {
351 buff[1] = extract32(frame->can_id, 3, 8);
352 buff[2] = extract32(frame->can_id, 0, 3) << 5;
353 for (i = 0; i < dlen; i++) {
354 buff[3 + i] = frame->data[i];
355 }
356
357 return dlen + 3;
358 }
359
360 return -1;
361}
362
363static int frame2buff_bas(const qemu_can_frame *frame, uint8_t *buff)
364{
365 int i;
366 int dlen = frame->can_dlc;
367
368
369
370
371
372
373 if ((frame->can_id & QEMU_CAN_EFF_FLAG) ||
374 (frame->can_id & QEMU_CAN_ERR_FLAG)) {
375 return -1;
376 }
377
378 if (dlen > 8) {
379 return -1;
380 }
381
382 buff[0] = extract32(frame->can_id, 3, 8);
383 buff[1] = extract32(frame->can_id, 0, 3) << 5;
384 if (frame->can_id & QEMU_CAN_RTR_FLAG) {
385 buff[1] |= (1 << 4);
386 }
387 buff[1] |= frame->can_dlc & 0x0f;
388 for (i = 0; i < dlen; i++) {
389 buff[2 + i] = frame->data[i];
390 }
391
392 return dlen + 2;
393}
394
395static void can_sja_update_pel_irq(CanSJA1000State *s)
396{
397 if (s->interrupt_en & s->interrupt_pel) {
398 qemu_irq_raise(s->irq);
399 } else {
400 qemu_irq_lower(s->irq);
401 }
402}
403
404static void can_sja_update_bas_irq(CanSJA1000State *s)
405{
406 if ((s->control >> 1) & s->interrupt_bas) {
407 qemu_irq_raise(s->irq);
408 } else {
409 qemu_irq_lower(s->irq);
410 }
411}
412
413void can_sja_mem_write(CanSJA1000State *s, hwaddr addr, uint64_t val,
414 unsigned size)
415{
416 qemu_can_frame frame;
417 uint32_t tmp;
418 uint8_t tmp8, count;
419
420
421 DPRINTF("write 0x%02llx addr 0x%02x\n",
422 (unsigned long long)val, (unsigned int)addr);
423
424 if (addr > CAN_SJA_MEM_SIZE) {
425 return ;
426 }
427
428 if (s->clock & 0x80) {
429 switch (addr) {
430 case SJA_MOD:
431 s->mode = 0x1f & val;
432 if ((s->mode & 0x01) && ((val & 0x01) == 0)) {
433
434 if (s->mode & (1 << 3)) {
435
436 can_sja_single_filter(&s->filter[0],
437 s->code_mask + 0, s->code_mask + 4, 1);
438
439
440 can_sja_single_filter(&s->filter[1],
441 s->code_mask + 0, s->code_mask + 4, 0);
442
443 can_bus_client_set_filters(&s->bus_client, s->filter, 2);
444 } else {
445
446 can_sja_dual_filter(&s->filter[0],
447 s->code_mask + 0, s->code_mask + 4, 1);
448
449 can_sja_dual_filter(&s->filter[1],
450 s->code_mask + 2, s->code_mask + 6, 1);
451
452
453 can_sja_dual_filter(&s->filter[2],
454 s->code_mask + 0, s->code_mask + 4, 0);
455
456 can_sja_dual_filter(&s->filter[3],
457 s->code_mask + 2, s->code_mask + 6, 0);
458
459 can_bus_client_set_filters(&s->bus_client, s->filter, 4);
460 }
461
462 s->rxmsg_cnt = 0;
463 s->rx_cnt = 0;
464 }
465 break;
466
467 case SJA_CMR:
468 if (0x01 & val) {
469 buff2frame_pel(s->tx_buff, &frame);
470 if (DEBUG_FILTER) {
471 can_display_msg("[cansja]: Tx request " , &frame);
472 }
473
474
475
476
477
478
479 s->status_pel &= ~(3 << 2);
480
481 can_bus_client_send(&s->bus_client, &frame, 1);
482
483
484
485
486
487 s->status_pel |= (3 << 2);
488
489
490 s->status_pel &= ~(1 << 5);
491 s->interrupt_pel |= 0x02;
492 can_sja_update_pel_irq(s);
493 }
494 if (0x04 & val) {
495 if (s->rxmsg_cnt <= 0) {
496 break;
497 }
498
499 tmp8 = s->rx_buff[s->rxbuf_start]; count = 0;
500 if (tmp8 & (1 << 7)) {
501 count += 2;
502 }
503 count += 3;
504 if (!(tmp8 & (1 << 6))) {
505 count += (tmp8 & 0x0f);
506 }
507
508 if (DEBUG_FILTER) {
509 qemu_log("[cansja]: message released from "
510 "Rx FIFO cnt=%d, count=%d\n", s->rx_cnt, count);
511 }
512
513 s->rxbuf_start += count;
514 s->rxbuf_start %= SJA_RCV_BUF_LEN;
515
516 s->rx_cnt -= count;
517 s->rxmsg_cnt--;
518 if (s->rxmsg_cnt == 0) {
519 s->status_pel &= ~(1 << 0);
520 s->interrupt_pel &= ~(1 << 0);
521 can_sja_update_pel_irq(s);
522 }
523 }
524 if (0x08 & val) {
525 s->status_pel &= ~(1 << 1);
526 s->interrupt_pel &= ~(1 << 3);
527 can_sja_update_pel_irq(s);
528 }
529 break;
530 case SJA_SR:
531 case SJA_IR:
532 break;
533 case SJA_IER:
534 s->interrupt_en = val;
535 break;
536 case 16:
537 s->status_pel |= (1 << 5);
538
539 case 17 ... 28:
540 if (s->mode & 0x01) {
541 if (addr < 24) {
542 s->code_mask[addr - 16] = val;
543 }
544 } else {
545 s->tx_buff[addr - 16] = val;
546 }
547 break;
548 case SJA_CDR:
549 s->clock = val;
550 break;
551 }
552 } else {
553 switch (addr) {
554 case SJA_BCAN_CTR:
555 if ((s->control & 0x01) && ((val & 0x01) == 0)) {
556
557 s->filter[0].can_id = (s->code << 3) & (0xff << 3);
558 tmp = (~(s->mask << 3)) & (0xff << 3);
559 tmp |= QEMU_CAN_EFF_FLAG;
560 s->filter[0].can_mask = tmp;
561 can_bus_client_set_filters(&s->bus_client, s->filter, 1);
562
563 s->rxmsg_cnt = 0;
564 s->rx_cnt = 0;
565 } else if (!(s->control & 0x01) && !(val & 0x01)) {
566 can_sja_software_reset(s);
567 }
568
569 s->control = 0x1f & val;
570 break;
571 case SJA_BCAN_CMR:
572 if (0x01 & val) {
573 buff2frame_bas(s->tx_buff, &frame);
574 if (DEBUG_FILTER) {
575 can_display_msg("[cansja]: Tx request " , &frame);
576 }
577
578
579
580
581
582 s->status_bas &= ~(3 << 2);
583
584
585 can_bus_client_send(&s->bus_client, &frame, 1);
586
587
588
589
590
591 s->status_bas |= (3 << 2);
592
593
594 s->status_bas &= ~(1 << 5);
595 s->interrupt_bas |= 0x02;
596 can_sja_update_bas_irq(s);
597 }
598 if (0x04 & val) {
599 if (s->rxmsg_cnt <= 0) {
600 break;
601 }
602
603 tmp8 = s->rx_buff[(s->rxbuf_start + 1) % SJA_RCV_BUF_LEN];
604 count = 2 + (tmp8 & 0x0f);
605
606 if (DEBUG_FILTER) {
607 qemu_log("[cansja]: message released from "
608 "Rx FIFO cnt=%d, count=%d\n", s->rx_cnt, count);
609 }
610
611 s->rxbuf_start += count;
612 s->rxbuf_start %= SJA_RCV_BUF_LEN;
613 s->rx_cnt -= count;
614 s->rxmsg_cnt--;
615
616 if (s->rxmsg_cnt == 0) {
617 s->status_bas &= ~(1 << 0);
618 s->interrupt_bas &= ~(1 << 0);
619 can_sja_update_bas_irq(s);
620 }
621 }
622 if (0x08 & val) {
623 s->status_bas &= ~(1 << 1);
624 s->interrupt_bas &= ~(1 << 3);
625 can_sja_update_bas_irq(s);
626 }
627 break;
628 case 4:
629 s->code = val;
630 break;
631 case 5:
632 s->mask = val;
633 break;
634 case 10:
635 s->status_bas |= (1 << 5);
636
637 case 11 ... 19:
638 if ((s->control & 0x01) == 0) {
639 s->tx_buff[addr - 10] = val;
640 }
641 break;
642 case SJA_CDR:
643 s->clock = val;
644 break;
645 }
646 }
647}
648
649uint64_t can_sja_mem_read(CanSJA1000State *s, hwaddr addr, unsigned size)
650{
651 uint64_t temp = 0;
652
653 DPRINTF("read addr 0x%02x ...\n", (unsigned int)addr);
654
655 if (addr > CAN_SJA_MEM_SIZE) {
656 return 0;
657 }
658
659 if (s->clock & 0x80) {
660 switch (addr) {
661 case SJA_MOD:
662 temp = s->mode;
663 break;
664 case SJA_CMR:
665 temp = 0x00;
666 break;
667 case SJA_SR:
668 temp = s->status_pel;
669 break;
670 case SJA_IR:
671 temp = s->interrupt_pel;
672 s->interrupt_pel = 0;
673 if (s->rxmsg_cnt) {
674 s->interrupt_pel |= (1 << 0);
675 }
676 can_sja_update_pel_irq(s);
677 break;
678 case SJA_IER:
679 temp = s->interrupt_en;
680 break;
681 case 5:
682 case 6:
683 case 7:
684 case 8:
685
686
687
688 case 9:
689 case 10 ... 15:
690 temp = 0x00;
691 break;
692
693 case 16 ... 28:
694 if (s->mode & 0x01) {
695 if (addr < 24) {
696 temp = s->code_mask[addr - 16];
697 } else {
698 temp = 0x00;
699 }
700 } else {
701 temp = s->rx_buff[(s->rxbuf_start + addr - 16) %
702 SJA_RCV_BUF_LEN];
703 }
704 break;
705 case SJA_CDR:
706 temp = s->clock;
707 break;
708 default:
709 temp = 0xff;
710 }
711 } else {
712 switch (addr) {
713 case SJA_BCAN_CTR:
714 temp = s->control;
715 break;
716 case SJA_BCAN_SR:
717 temp = s->status_bas;
718 break;
719 case SJA_BCAN_IR:
720 temp = s->interrupt_bas;
721 s->interrupt_bas = 0;
722 if (s->rxmsg_cnt) {
723 s->interrupt_bas |= (1 << 0);
724 }
725 can_sja_update_bas_irq(s);
726 break;
727 case 4:
728 temp = s->code;
729 break;
730 case 5:
731 temp = s->mask;
732 break;
733 case 20 ... 29:
734 temp = s->rx_buff[(s->rxbuf_start + addr - 20) % SJA_RCV_BUF_LEN];
735 break;
736 case 31:
737 temp = s->clock;
738 break;
739 default:
740 temp = 0xff;
741 break;
742 }
743 }
744 DPRINTF("read addr 0x%02x, %d bytes, content 0x%02lx\n",
745 (int)addr, size, (long unsigned int)temp);
746
747 return temp;
748}
749
750bool can_sja_can_receive(CanBusClientState *client)
751{
752 CanSJA1000State *s = container_of(client, CanSJA1000State, bus_client);
753
754 if (s->clock & 0x80) {
755 if (s->mode & 0x01) {
756 return false;
757 }
758 } else {
759 if (s->control & 0x01) {
760 return false;
761 }
762 }
763
764 return true;
765}
766
767ssize_t can_sja_receive(CanBusClientState *client, const qemu_can_frame *frames,
768 size_t frames_cnt)
769{
770 CanSJA1000State *s = container_of(client, CanSJA1000State, bus_client);
771 static uint8_t rcv[SJA_MSG_MAX_LEN];
772 int i;
773 int ret = -1;
774 const qemu_can_frame *frame = frames;
775
776 if (frames_cnt <= 0) {
777 return 0;
778 }
779 if (frame->flags & QEMU_CAN_FRMF_TYPE_FD) {
780 if (DEBUG_FILTER) {
781 can_display_msg("[cansja]: ignor fd frame ", frame);
782 }
783 return 1;
784 }
785
786 if (DEBUG_FILTER) {
787 can_display_msg("[cansja]: receive ", frame);
788 }
789
790 if (s->clock & 0x80) {
791
792
793 s->status_pel |= (1 << 4);
794
795 if (can_sja_accept_filter(s, frame) == 0) {
796 s->status_pel &= ~(1 << 4);
797 if (DEBUG_FILTER) {
798 qemu_log("[cansja]: filter rejects message\n");
799 }
800 return ret;
801 }
802
803 ret = frame2buff_pel(frame, rcv);
804 if (ret < 0) {
805 s->status_pel &= ~(1 << 4);
806 if (DEBUG_FILTER) {
807 qemu_log("[cansja]: message store failed\n");
808 }
809 return ret;
810 }
811
812 if (s->rx_cnt + ret > SJA_RCV_BUF_LEN) {
813 s->status_pel |= (1 << 1);
814 s->interrupt_pel |= (1 << 3);
815 s->status_pel &= ~(1 << 4);
816 if (DEBUG_FILTER) {
817 qemu_log("[cansja]: receive FIFO overrun\n");
818 }
819 can_sja_update_pel_irq(s);
820 return ret;
821 }
822 s->rx_cnt += ret;
823 s->rxmsg_cnt++;
824 if (DEBUG_FILTER) {
825 qemu_log("[cansja]: message stored in receive FIFO\n");
826 }
827
828 for (i = 0; i < ret; i++) {
829 s->rx_buff[(s->rx_ptr++) % SJA_RCV_BUF_LEN] = rcv[i];
830 }
831 s->rx_ptr %= SJA_RCV_BUF_LEN;
832
833 s->status_pel |= 0x01;
834 s->interrupt_pel |= 0x01;
835 s->status_pel &= ~(1 << 4);
836 s->status_pel |= (1 << 0);
837 can_sja_update_pel_irq(s);
838 } else {
839
840
841 s->status_bas |= (1 << 4);
842
843 ret = frame2buff_bas(frame, rcv);
844 if (ret < 0) {
845 s->status_bas &= ~(1 << 4);
846 if (DEBUG_FILTER) {
847 qemu_log("[cansja]: message store failed\n");
848 }
849 return ret;
850 }
851
852 if (s->rx_cnt + ret > SJA_RCV_BUF_LEN) {
853 s->status_bas |= (1 << 1);
854 s->status_bas &= ~(1 << 4);
855 s->interrupt_bas |= (1 << 3);
856 can_sja_update_bas_irq(s);
857 if (DEBUG_FILTER) {
858 qemu_log("[cansja]: receive FIFO overrun\n");
859 }
860 return ret;
861 }
862 s->rx_cnt += ret;
863 s->rxmsg_cnt++;
864
865 if (DEBUG_FILTER) {
866 qemu_log("[cansja]: message stored\n");
867 }
868
869 for (i = 0; i < ret; i++) {
870 s->rx_buff[(s->rx_ptr++) % SJA_RCV_BUF_LEN] = rcv[i];
871 }
872 s->rx_ptr %= SJA_RCV_BUF_LEN;
873
874 s->status_bas |= 0x01;
875 s->status_bas &= ~(1 << 4);
876 s->interrupt_bas |= (1 << 0);
877 can_sja_update_bas_irq(s);
878 }
879 return 1;
880}
881
882static CanBusClientInfo can_sja_bus_client_info = {
883 .can_receive = can_sja_can_receive,
884 .receive = can_sja_receive,
885};
886
887
888int can_sja_connect_to_bus(CanSJA1000State *s, CanBusState *bus)
889{
890 s->bus_client.info = &can_sja_bus_client_info;
891
892 if (!bus) {
893 return -EINVAL;
894 }
895
896 if (can_bus_insert_client(bus, &s->bus_client) < 0) {
897 return -1;
898 }
899
900 return 0;
901}
902
903void can_sja_disconnect(CanSJA1000State *s)
904{
905 can_bus_remove_client(&s->bus_client);
906}
907
908int can_sja_init(CanSJA1000State *s, qemu_irq irq)
909{
910 s->irq = irq;
911
912 qemu_irq_lower(s->irq);
913
914 can_sja_hardware_reset(s);
915
916 return 0;
917}
918
919const VMStateDescription vmstate_qemu_can_filter = {
920 .name = "qemu_can_filter",
921 .version_id = 1,
922 .minimum_version_id = 1,
923 .minimum_version_id_old = 1,
924 .fields = (VMStateField[]) {
925 VMSTATE_UINT32(can_id, qemu_can_filter),
926 VMSTATE_UINT32(can_mask, qemu_can_filter),
927 VMSTATE_END_OF_LIST()
928 }
929};
930
931static int can_sja_post_load(void *opaque, int version_id)
932{
933 CanSJA1000State *s = opaque;
934 if (s->clock & 0x80) {
935 can_sja_update_pel_irq(s);
936 } else {
937 can_sja_update_bas_irq(s);
938 }
939 return 0;
940}
941
942
943const VMStateDescription vmstate_can_sja = {
944 .name = "can_sja",
945 .version_id = 1,
946 .minimum_version_id = 1,
947 .minimum_version_id_old = 1,
948 .post_load = can_sja_post_load,
949 .fields = (VMStateField[]) {
950 VMSTATE_UINT8(mode, CanSJA1000State),
951
952 VMSTATE_UINT8(status_pel, CanSJA1000State),
953 VMSTATE_UINT8(interrupt_pel, CanSJA1000State),
954 VMSTATE_UINT8(interrupt_en, CanSJA1000State),
955 VMSTATE_UINT8(rxmsg_cnt, CanSJA1000State),
956 VMSTATE_UINT8(rxbuf_start, CanSJA1000State),
957 VMSTATE_UINT8(clock, CanSJA1000State),
958
959 VMSTATE_BUFFER(code_mask, CanSJA1000State),
960 VMSTATE_BUFFER(tx_buff, CanSJA1000State),
961
962 VMSTATE_BUFFER(rx_buff, CanSJA1000State),
963
964 VMSTATE_UINT32(rx_ptr, CanSJA1000State),
965 VMSTATE_UINT32(rx_cnt, CanSJA1000State),
966
967 VMSTATE_UINT8(control, CanSJA1000State),
968
969 VMSTATE_UINT8(status_bas, CanSJA1000State),
970 VMSTATE_UINT8(interrupt_bas, CanSJA1000State),
971 VMSTATE_UINT8(code, CanSJA1000State),
972 VMSTATE_UINT8(mask, CanSJA1000State),
973
974 VMSTATE_STRUCT_ARRAY(filter, CanSJA1000State, 4, 0,
975 vmstate_qemu_can_filter, qemu_can_filter),
976
977
978 VMSTATE_END_OF_LIST()
979 }
980};
981