]> git.proxmox.com Git - mirror_qemu.git/blame - hw/net/can/can_sja1000.c
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
[mirror_qemu.git] / hw / net / can / can_sja1000.c
CommitLineData
733210e7
PP
1/*
2 * CAN device - SJA1000 chip emulation for QEMU
3 *
4 * Copyright (c) 2013-2014 Jin Yang
5 * Copyright (c) 2014-2018 Pavel Pisa
6 *
7 * Initial development supported by Google GSoC 2013 from RTEMS project slot
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
64552b6b 27
733210e7
PP
28#include "qemu/osdep.h"
29#include "qemu/log.h"
30#include "chardev/char.h"
64552b6b 31#include "hw/irq.h"
d6454270 32#include "migration/vmstate.h"
733210e7
PP
33#include "net/can_emu.h"
34
35#include "can_sja1000.h"
36
37#ifndef DEBUG_FILTER
38#define DEBUG_FILTER 0
39#endif /*DEBUG_FILTER*/
40
41#ifndef DEBUG_CAN
42#define DEBUG_CAN 0
43#endif /*DEBUG_CAN*/
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 /* Reset by hardware, p10 */
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/* Details in DS-p22, what we need to do here is to test the data. */
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) { /* PeliCAN Mode */
155 if (s->mode & (1 << 3)) { /* Single mode. */
156 if (frame->can_id & QEMU_CAN_EFF_FLAG) { /* EFF */
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 { /* SFF */
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) { /* RTR */
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 { /* Dual mode */
196 if (frame->can_id & QEMU_CAN_EFF_FLAG) { /* EFF */
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;
fc59d2d8 250 FILE *logfile = qemu_log_lock();
733210e7 251
733210e7
PP
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();
fc59d2d8 264 qemu_log_unlock(logfile);
733210e7
PP
265}
266
267static void buff2frame_pel(const uint8_t *buff, qemu_can_frame *frame)
268{
269 uint8_t i;
270
271 frame->can_id = 0;
272 if (buff[0] & 0x40) { /* RTR */
273 frame->can_id = QEMU_CAN_RTR_FLAG;
274 }
275 frame->can_dlc = buff[0] & 0x0f;
276
277 if (buff[0] & 0x80) { /* Extended */
278 frame->can_id |= QEMU_CAN_EFF_FLAG;
279 frame->can_id |= buff[1] << 21; /* ID.28~ID.21 */
280 frame->can_id |= buff[2] << 13; /* ID.20~ID.13 */
281 frame->can_id |= buff[3] << 5;
282 frame->can_id |= buff[4] >> 3;
283 for (i = 0; i < frame->can_dlc; i++) {
284 frame->data[i] = buff[5 + i];
285 }
286 for (; i < 8; i++) {
287 frame->data[i] = 0;
288 }
289 } else {
290 frame->can_id |= buff[1] << 3;
291 frame->can_id |= buff[2] >> 5;
292 for (i = 0; i < frame->can_dlc; i++) {
293 frame->data[i] = buff[3 + i];
294 }
295 for (; i < 8; i++) {
296 frame->data[i] = 0;
297 }
298 }
299}
300
301
302static void buff2frame_bas(const uint8_t *buff, qemu_can_frame *frame)
303{
304 uint8_t i;
305
306 frame->can_id = ((buff[0] << 3) & (0xff << 3)) + ((buff[1] >> 5) & 0x07);
307 if (buff[1] & 0x10) { /* RTR */
308 frame->can_id = QEMU_CAN_RTR_FLAG;
309 }
310 frame->can_dlc = buff[1] & 0x0f;
311
312 for (i = 0; i < frame->can_dlc; i++) {
313 frame->data[i] = buff[2 + i];
314 }
315 for (; i < 8; i++) {
316 frame->data[i] = 0;
317 }
318}
319
320
321static int frame2buff_pel(const qemu_can_frame *frame, uint8_t *buff)
322{
323 int i;
324
325 if (frame->can_id & QEMU_CAN_ERR_FLAG) { /* error frame, NOT support now. */
326 return -1;
327 }
328
329 buff[0] = 0x0f & frame->can_dlc; /* DLC */
330 if (frame->can_id & QEMU_CAN_RTR_FLAG) { /* RTR */
331 buff[0] |= (1 << 6);
332 }
333 if (frame->can_id & QEMU_CAN_EFF_FLAG) { /* EFF */
334 buff[0] |= (1 << 7);
335 buff[1] = extract32(frame->can_id, 21, 8); /* ID.28~ID.21 */
336 buff[2] = extract32(frame->can_id, 13, 8); /* ID.20~ID.13 */
337 buff[3] = extract32(frame->can_id, 5, 8); /* ID.12~ID.05 */
338 buff[4] = extract32(frame->can_id, 0, 5) << 3; /* ID.04~ID.00,xxx */
339 for (i = 0; i < frame->can_dlc; i++) {
340 buff[5 + i] = frame->data[i];
341 }
342 return frame->can_dlc + 5;
343 } else { /* SFF */
344 buff[1] = extract32(frame->can_id, 3, 8); /* ID.10~ID.03 */
345 buff[2] = extract32(frame->can_id, 0, 3) << 5; /* ID.02~ID.00,xxxxx */
346 for (i = 0; i < frame->can_dlc; i++) {
347 buff[3 + i] = frame->data[i];
348 }
349
350 return frame->can_dlc + 3;
351 }
352
353 return -1;
354}
355
356static int frame2buff_bas(const qemu_can_frame *frame, uint8_t *buff)
357{
358 int i;
359
360 /*
361 * EFF, no support for BasicMode
362 * No use for Error frames now,
363 * they could be used in future to update SJA1000 error state
364 */
365 if ((frame->can_id & QEMU_CAN_EFF_FLAG) ||
366 (frame->can_id & QEMU_CAN_ERR_FLAG)) {
367 return -1;
368 }
369
370 buff[0] = extract32(frame->can_id, 3, 8); /* ID.10~ID.03 */
371 buff[1] = extract32(frame->can_id, 0, 3) << 5; /* ID.02~ID.00,xxxxx */
372 if (frame->can_id & QEMU_CAN_RTR_FLAG) { /* RTR */
373 buff[1] |= (1 << 4);
374 }
375 buff[1] |= frame->can_dlc & 0x0f;
376 for (i = 0; i < frame->can_dlc; i++) {
377 buff[2 + i] = frame->data[i];
378 }
379
380 return frame->can_dlc + 2;
381}
382
a62ed5d1
PB
383static void can_sja_update_pel_irq(CanSJA1000State *s)
384{
385 if (s->interrupt_en & s->interrupt_pel) {
386 qemu_irq_raise(s->irq);
387 } else {
388 qemu_irq_lower(s->irq);
389 }
390}
391
392static void can_sja_update_bas_irq(CanSJA1000State *s)
393{
394 if ((s->control >> 1) & s->interrupt_bas) {
395 qemu_irq_raise(s->irq);
396 } else {
397 qemu_irq_lower(s->irq);
398 }
399}
400
733210e7
PP
401void can_sja_mem_write(CanSJA1000State *s, hwaddr addr, uint64_t val,
402 unsigned size)
403{
404 qemu_can_frame frame;
405 uint32_t tmp;
406 uint8_t tmp8, count;
407
408
409 DPRINTF("write 0x%02llx addr 0x%02x\n",
410 (unsigned long long)val, (unsigned int)addr);
411
412 if (addr > CAN_SJA_MEM_SIZE) {
413 return ;
414 }
415
416 if (s->clock & 0x80) { /* PeliCAN Mode */
417 switch (addr) {
418 case SJA_MOD: /* Mode register */
419 s->mode = 0x1f & val;
420 if ((s->mode & 0x01) && ((val & 0x01) == 0)) {
421 /* Go to operation mode from reset mode. */
422 if (s->mode & (1 << 3)) { /* Single mode. */
423 /* For EFF */
424 can_sja_single_filter(&s->filter[0],
425 s->code_mask + 0, s->code_mask + 4, 1);
426
427 /* For SFF */
428 can_sja_single_filter(&s->filter[1],
429 s->code_mask + 0, s->code_mask + 4, 0);
430
431 can_bus_client_set_filters(&s->bus_client, s->filter, 2);
432 } else { /* Dual mode */
433 /* For EFF */
434 can_sja_dual_filter(&s->filter[0],
435 s->code_mask + 0, s->code_mask + 4, 1);
436
437 can_sja_dual_filter(&s->filter[1],
438 s->code_mask + 2, s->code_mask + 6, 1);
439
440 /* For SFF */
441 can_sja_dual_filter(&s->filter[2],
442 s->code_mask + 0, s->code_mask + 4, 0);
443
444 can_sja_dual_filter(&s->filter[3],
445 s->code_mask + 2, s->code_mask + 6, 0);
446
447 can_bus_client_set_filters(&s->bus_client, s->filter, 4);
448 }
449
450 s->rxmsg_cnt = 0;
451 s->rx_cnt = 0;
452 }
453 break;
454
455 case SJA_CMR: /* Command register. */
456 if (0x01 & val) { /* Send transmission request. */
457 buff2frame_pel(s->tx_buff, &frame);
458 if (DEBUG_FILTER) {
459 can_display_msg("[cansja]: Tx request " , &frame);
460 }
461
462 /*
463 * Clear transmission complete status,
464 * and Transmit Buffer Status.
465 * write to the backends.
466 */
467 s->status_pel &= ~(3 << 2);
468
469 can_bus_client_send(&s->bus_client, &frame, 1);
470
471 /*
472 * Set transmission complete status
473 * and Transmit Buffer Status.
474 */
475 s->status_pel |= (3 << 2);
476
477 /* Clear transmit status. */
478 s->status_pel &= ~(1 << 5);
479 s->interrupt_pel |= 0x02;
a62ed5d1 480 can_sja_update_pel_irq(s);
733210e7
PP
481 }
482 if (0x04 & val) { /* Release Receive Buffer */
483 if (s->rxmsg_cnt <= 0) {
484 break;
485 }
486
487 tmp8 = s->rx_buff[s->rxbuf_start]; count = 0;
488 if (tmp8 & (1 << 7)) { /* EFF */
489 count += 2;
490 }
491 count += 3;
492 if (!(tmp8 & (1 << 6))) { /* DATA */
493 count += (tmp8 & 0x0f);
494 }
495
496 if (DEBUG_FILTER) {
497 qemu_log("[cansja]: message released from "
498 "Rx FIFO cnt=%d, count=%d\n", s->rx_cnt, count);
499 }
500
501 s->rxbuf_start += count;
502 s->rxbuf_start %= SJA_RCV_BUF_LEN;
503
504 s->rx_cnt -= count;
505 s->rxmsg_cnt--;
506 if (s->rxmsg_cnt == 0) {
507 s->status_pel &= ~(1 << 0);
508 s->interrupt_pel &= ~(1 << 0);
a62ed5d1 509 can_sja_update_pel_irq(s);
733210e7
PP
510 }
511 }
512 if (0x08 & val) { /* Clear data overrun */
513 s->status_pel &= ~(1 << 1);
514 s->interrupt_pel &= ~(1 << 3);
a62ed5d1 515 can_sja_update_pel_irq(s);
733210e7
PP
516 }
517 break;
518 case SJA_SR: /* Status register */
519 case SJA_IR: /* Interrupt register */
520 break; /* Do nothing */
521 case SJA_IER: /* Interrupt enable register */
522 s->interrupt_en = val;
523 break;
524 case 16: /* RX frame information addr16-28. */
525 s->status_pel |= (1 << 5); /* Set transmit status. */
526 case 17 ... 28:
527 if (s->mode & 0x01) { /* Reset mode */
528 if (addr < 24) {
529 s->code_mask[addr - 16] = val;
530 }
531 } else { /* Operation mode */
532 s->tx_buff[addr - 16] = val; /* Store to TX buffer directly. */
533 }
534 break;
535 case SJA_CDR:
536 s->clock = val;
537 break;
538 }
539 } else { /* Basic Mode */
540 switch (addr) {
541 case SJA_BCAN_CTR: /* Control register, addr 0 */
542 if ((s->control & 0x01) && ((val & 0x01) == 0)) {
543 /* Go to operation mode from reset mode. */
544 s->filter[0].can_id = (s->code << 3) & (0xff << 3);
545 tmp = (~(s->mask << 3)) & (0xff << 3);
546 tmp |= QEMU_CAN_EFF_FLAG; /* Only Basic CAN Frame. */
547 s->filter[0].can_mask = tmp;
548 can_bus_client_set_filters(&s->bus_client, s->filter, 1);
549
550 s->rxmsg_cnt = 0;
551 s->rx_cnt = 0;
552 } else if (!(s->control & 0x01) && !(val & 0x01)) {
553 can_sja_software_reset(s);
554 }
555
556 s->control = 0x1f & val;
557 break;
558 case SJA_BCAN_CMR: /* Command register, addr 1 */
559 if (0x01 & val) { /* Send transmission request. */
560 buff2frame_bas(s->tx_buff, &frame);
561 if (DEBUG_FILTER) {
562 can_display_msg("[cansja]: Tx request " , &frame);
563 }
564
565 /*
566 * Clear transmission complete status,
567 * and Transmit Buffer Status.
568 */
569 s->status_bas &= ~(3 << 2);
570
571 /* write to the backends. */
572 can_bus_client_send(&s->bus_client, &frame, 1);
573
574 /*
575 * Set transmission complete status,
576 * and Transmit Buffer Status.
577 */
578 s->status_bas |= (3 << 2);
579
580 /* Clear transmit status. */
581 s->status_bas &= ~(1 << 5);
582 s->interrupt_bas |= 0x02;
a62ed5d1 583 can_sja_update_bas_irq(s);
733210e7
PP
584 }
585 if (0x04 & val) { /* Release Receive Buffer */
586 if (s->rxmsg_cnt <= 0) {
587 break;
588 }
589
590 tmp8 = s->rx_buff[(s->rxbuf_start + 1) % SJA_RCV_BUF_LEN];
591 count = 2 + (tmp8 & 0x0f);
592
593 if (DEBUG_FILTER) {
594 qemu_log("[cansja]: message released from "
595 "Rx FIFO cnt=%d, count=%d\n", s->rx_cnt, count);
596 }
597
598 s->rxbuf_start += count;
599 s->rxbuf_start %= SJA_RCV_BUF_LEN;
600 s->rx_cnt -= count;
601 s->rxmsg_cnt--;
602
603 if (s->rxmsg_cnt == 0) {
604 s->status_bas &= ~(1 << 0);
605 s->interrupt_bas &= ~(1 << 0);
a62ed5d1 606 can_sja_update_bas_irq(s);
733210e7
PP
607 }
608 }
609 if (0x08 & val) { /* Clear data overrun */
610 s->status_bas &= ~(1 << 1);
611 s->interrupt_bas &= ~(1 << 3);
a62ed5d1 612 can_sja_update_bas_irq(s);
733210e7
PP
613 }
614 break;
615 case 4:
616 s->code = val;
617 break;
618 case 5:
619 s->mask = val;
620 break;
621 case 10:
622 s->status_bas |= (1 << 5); /* Set transmit status. */
623 case 11 ... 19:
624 if ((s->control & 0x01) == 0) { /* Operation mode */
625 s->tx_buff[addr - 10] = val; /* Store to TX buffer directly. */
626 }
627 break;
628 case SJA_CDR:
629 s->clock = val;
630 break;
631 }
632 }
633}
634
635uint64_t can_sja_mem_read(CanSJA1000State *s, hwaddr addr, unsigned size)
636{
637 uint64_t temp = 0;
638
639 DPRINTF("read addr 0x%02x ...\n", (unsigned int)addr);
640
641 if (addr > CAN_SJA_MEM_SIZE) {
642 return 0;
643 }
644
645 if (s->clock & 0x80) { /* PeliCAN Mode */
646 switch (addr) {
647 case SJA_MOD: /* Mode register, addr 0 */
648 temp = s->mode;
649 break;
650 case SJA_CMR: /* Command register, addr 1 */
651 temp = 0x00; /* Command register, cannot be read. */
652 break;
653 case SJA_SR: /* Status register, addr 2 */
654 temp = s->status_pel;
655 break;
656 case SJA_IR: /* Interrupt register, addr 3 */
657 temp = s->interrupt_pel;
658 s->interrupt_pel = 0;
659 if (s->rxmsg_cnt) {
660 s->interrupt_pel |= (1 << 0); /* Receive interrupt. */
733210e7 661 }
a62ed5d1 662 can_sja_update_pel_irq(s);
733210e7
PP
663 break;
664 case SJA_IER: /* Interrupt enable register, addr 4 */
665 temp = s->interrupt_en;
666 break;
667 case 5: /* Reserved */
668 case 6: /* Bus timing 0, hardware related, not support now. */
669 case 7: /* Bus timing 1, hardware related, not support now. */
670 case 8: /*
671 * Output control register, hardware related,
672 * not supported for now.
673 */
674 case 9: /* Test. */
675 case 10 ... 15: /* Reserved */
676 temp = 0x00;
677 break;
678
679 case 16 ... 28:
680 if (s->mode & 0x01) { /* Reset mode */
681 if (addr < 24) {
682 temp = s->code_mask[addr - 16];
683 } else {
684 temp = 0x00;
685 }
686 } else { /* Operation mode */
687 temp = s->rx_buff[(s->rxbuf_start + addr - 16) %
688 SJA_RCV_BUF_LEN];
689 }
690 break;
691 case SJA_CDR:
692 temp = s->clock;
693 break;
694 default:
695 temp = 0xff;
696 }
697 } else { /* Basic Mode */
698 switch (addr) {
699 case SJA_BCAN_CTR: /* Control register, addr 0 */
700 temp = s->control;
701 break;
702 case SJA_BCAN_SR: /* Status register, addr 2 */
703 temp = s->status_bas;
704 break;
705 case SJA_BCAN_IR: /* Interrupt register, addr 3 */
706 temp = s->interrupt_bas;
707 s->interrupt_bas = 0;
708 if (s->rxmsg_cnt) {
709 s->interrupt_bas |= (1 << 0); /* Receive interrupt. */
733210e7 710 }
a62ed5d1 711 can_sja_update_bas_irq(s);
733210e7
PP
712 break;
713 case 4:
714 temp = s->code;
715 break;
716 case 5:
717 temp = s->mask;
718 break;
719 case 20 ... 29:
720 temp = s->rx_buff[(s->rxbuf_start + addr - 20) % SJA_RCV_BUF_LEN];
721 break;
722 case 31:
723 temp = s->clock;
724 break;
725 default:
726 temp = 0xff;
727 break;
728 }
729 }
730 DPRINTF("read addr 0x%02x, %d bytes, content 0x%02lx\n",
731 (int)addr, size, (long unsigned int)temp);
732
733 return temp;
734}
735
736int can_sja_can_receive(CanBusClientState *client)
737{
738 CanSJA1000State *s = container_of(client, CanSJA1000State, bus_client);
739
740 if (s->clock & 0x80) { /* PeliCAN Mode */
741 if (s->mode & 0x01) { /* reset mode. */
742 return 0;
743 }
744 } else { /* BasicCAN mode */
745 if (s->control & 0x01) {
746 return 0;
747 }
748 }
749
750 return 1; /* always return 1, when operation mode */
751}
752
753ssize_t can_sja_receive(CanBusClientState *client, const qemu_can_frame *frames,
754 size_t frames_cnt)
755{
756 CanSJA1000State *s = container_of(client, CanSJA1000State, bus_client);
757 static uint8_t rcv[SJA_MSG_MAX_LEN];
758 int i;
759 int ret = -1;
760 const qemu_can_frame *frame = frames;
761
762 if (frames_cnt <= 0) {
763 return 0;
764 }
765 if (DEBUG_FILTER) {
766 can_display_msg("[cansja]: receive ", frame);
767 }
768
769 if (s->clock & 0x80) { /* PeliCAN Mode */
770
771 /* the CAN controller is receiving a message */
772 s->status_pel |= (1 << 4);
773
774 if (can_sja_accept_filter(s, frame) == 0) {
775 s->status_pel &= ~(1 << 4);
776 if (DEBUG_FILTER) {
777 qemu_log("[cansja]: filter rejects message\n");
778 }
779 return ret;
780 }
781
782 ret = frame2buff_pel(frame, rcv);
783 if (ret < 0) {
784 s->status_pel &= ~(1 << 4);
785 if (DEBUG_FILTER) {
786 qemu_log("[cansja]: message store failed\n");
787 }
788 return ret; /* maybe not support now. */
789 }
790
791 if (s->rx_cnt + ret > SJA_RCV_BUF_LEN) { /* Data overrun. */
792 s->status_pel |= (1 << 1); /* Overrun status */
793 s->interrupt_pel |= (1 << 3);
733210e7
PP
794 s->status_pel &= ~(1 << 4);
795 if (DEBUG_FILTER) {
796 qemu_log("[cansja]: receive FIFO overrun\n");
797 }
a62ed5d1 798 can_sja_update_pel_irq(s);
733210e7
PP
799 return ret;
800 }
801 s->rx_cnt += ret;
802 s->rxmsg_cnt++;
803 if (DEBUG_FILTER) {
804 qemu_log("[cansja]: message stored in receive FIFO\n");
805 }
806
807 for (i = 0; i < ret; i++) {
808 s->rx_buff[(s->rx_ptr++) % SJA_RCV_BUF_LEN] = rcv[i];
809 }
810 s->rx_ptr %= SJA_RCV_BUF_LEN; /* update the pointer. */
811
812 s->status_pel |= 0x01; /* Set the Receive Buffer Status. DS-p23 */
813 s->interrupt_pel |= 0x01;
814 s->status_pel &= ~(1 << 4);
815 s->status_pel |= (1 << 0);
a62ed5d1 816 can_sja_update_pel_irq(s);
733210e7
PP
817 } else { /* BasicCAN mode */
818
819 /* the CAN controller is receiving a message */
820 s->status_bas |= (1 << 4);
821
822 ret = frame2buff_bas(frame, rcv);
823 if (ret < 0) {
824 s->status_bas &= ~(1 << 4);
825 if (DEBUG_FILTER) {
826 qemu_log("[cansja]: message store failed\n");
827 }
828 return ret; /* maybe not support now. */
829 }
830
831 if (s->rx_cnt + ret > SJA_RCV_BUF_LEN) { /* Data overrun. */
832 s->status_bas |= (1 << 1); /* Overrun status */
833 s->status_bas &= ~(1 << 4);
834 s->interrupt_bas |= (1 << 3);
a62ed5d1 835 can_sja_update_bas_irq(s);
733210e7
PP
836 if (DEBUG_FILTER) {
837 qemu_log("[cansja]: receive FIFO overrun\n");
838 }
839 return ret;
840 }
841 s->rx_cnt += ret;
842 s->rxmsg_cnt++;
843
844 if (DEBUG_FILTER) {
845 qemu_log("[cansja]: message stored\n");
846 }
847
848 for (i = 0; i < ret; i++) {
849 s->rx_buff[(s->rx_ptr++) % SJA_RCV_BUF_LEN] = rcv[i];
850 }
851 s->rx_ptr %= SJA_RCV_BUF_LEN; /* update the pointer. */
852
853 s->status_bas |= 0x01; /* Set the Receive Buffer Status. DS-p15 */
854 s->status_bas &= ~(1 << 4);
a62ed5d1
PB
855 s->interrupt_bas |= (1 << 0);
856 can_sja_update_bas_irq(s);
733210e7
PP
857 }
858 return 1;
859}
860
861static CanBusClientInfo can_sja_bus_client_info = {
862 .can_receive = can_sja_can_receive,
863 .receive = can_sja_receive,
864};
865
866
867int can_sja_connect_to_bus(CanSJA1000State *s, CanBusState *bus)
868{
869 s->bus_client.info = &can_sja_bus_client_info;
870
089eac81
TH
871 if (!bus) {
872 return -EINVAL;
873 }
874
733210e7
PP
875 if (can_bus_insert_client(bus, &s->bus_client) < 0) {
876 return -1;
877 }
878
879 return 0;
880}
881
882void can_sja_disconnect(CanSJA1000State *s)
883{
884 can_bus_remove_client(&s->bus_client);
885}
886
887int can_sja_init(CanSJA1000State *s, qemu_irq irq)
888{
889 s->irq = irq;
890
891 qemu_irq_lower(s->irq);
892
893 can_sja_hardware_reset(s);
894
895 return 0;
896}
897
898const VMStateDescription vmstate_qemu_can_filter = {
899 .name = "qemu_can_filter",
900 .version_id = 1,
901 .minimum_version_id = 1,
902 .minimum_version_id_old = 1,
903 .fields = (VMStateField[]) {
904 VMSTATE_UINT32(can_id, qemu_can_filter),
905 VMSTATE_UINT32(can_mask, qemu_can_filter),
906 VMSTATE_END_OF_LIST()
907 }
908};
909
a62ed5d1
PB
910static int can_sja_post_load(void *opaque, int version_id)
911{
912 CanSJA1000State *s = opaque;
913 if (s->clock & 0x80) { /* PeliCAN Mode */
914 can_sja_update_pel_irq(s);
915 } else {
916 can_sja_update_bas_irq(s);
917 }
918 return 0;
919}
920
733210e7
PP
921/* VMState is needed for live migration of QEMU images */
922const VMStateDescription vmstate_can_sja = {
923 .name = "can_sja",
924 .version_id = 1,
925 .minimum_version_id = 1,
926 .minimum_version_id_old = 1,
a62ed5d1 927 .post_load = can_sja_post_load,
733210e7
PP
928 .fields = (VMStateField[]) {
929 VMSTATE_UINT8(mode, CanSJA1000State),
930
931 VMSTATE_UINT8(status_pel, CanSJA1000State),
932 VMSTATE_UINT8(interrupt_pel, CanSJA1000State),
933 VMSTATE_UINT8(interrupt_en, CanSJA1000State),
934 VMSTATE_UINT8(rxmsg_cnt, CanSJA1000State),
935 VMSTATE_UINT8(rxbuf_start, CanSJA1000State),
936 VMSTATE_UINT8(clock, CanSJA1000State),
937
938 VMSTATE_BUFFER(code_mask, CanSJA1000State),
939 VMSTATE_BUFFER(tx_buff, CanSJA1000State),
940
941 VMSTATE_BUFFER(rx_buff, CanSJA1000State),
942
943 VMSTATE_UINT32(rx_ptr, CanSJA1000State),
944 VMSTATE_UINT32(rx_cnt, CanSJA1000State),
945
946 VMSTATE_UINT8(control, CanSJA1000State),
947
948 VMSTATE_UINT8(status_bas, CanSJA1000State),
949 VMSTATE_UINT8(interrupt_bas, CanSJA1000State),
950 VMSTATE_UINT8(code, CanSJA1000State),
951 VMSTATE_UINT8(mask, CanSJA1000State),
952
953 VMSTATE_STRUCT_ARRAY(filter, CanSJA1000State, 4, 0,
954 vmstate_qemu_can_filter, qemu_can_filter),
955
956
957 VMSTATE_END_OF_LIST()
958 }
959};