diff options
author | Doug Brown <doug@schmorgal.com> | 2024-09-13 15:31:48 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2024-09-13 15:31:48 +0100 |
commit | 7f34aae641ce1a2654c1a950aec4eab6f371a55d (patch) | |
tree | 4ace25907755ca7de685c498f72f580b2a0f8484 /hw | |
parent | 77dcbf16d971596261ddaa910f57ccceb48227b5 (diff) | |
download | qemu-7f34aae641ce1a2654c1a950aec4eab6f371a55d.zip qemu-7f34aae641ce1a2654c1a950aec4eab6f371a55d.tar.gz qemu-7f34aae641ce1a2654c1a950aec4eab6f371a55d.tar.bz2 |
hw/net/can/xlnx-versal-canfd: Handle flags correctly
Add support for QEMU_CAN_FRMF_ESI and QEMU_CAN_FRMF_BRS flags, and
ensure frame->flags is always initialized to 0.
Note that the Xilinx IP core doesn't allow manually setting the ESI bit
during transmits, so it's only implemented for the receive case.
Signed-off-by: Doug Brown <doug@schmorgal.com>
Reviewed-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Message-id: 20240827034927.66659-5-doug@schmorgal.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/net/can/xlnx-versal-canfd.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/hw/net/can/xlnx-versal-canfd.c b/hw/net/can/xlnx-versal-canfd.c index 9e82574..9fba5b9 100644 --- a/hw/net/can/xlnx-versal-canfd.c +++ b/hw/net/can/xlnx-versal-canfd.c @@ -872,6 +872,8 @@ static void regs2frame(XlnxVersalCANFDState *s, qemu_can_frame *frame, uint32_t id_reg_val = 0; bool is_rtr = false; + frame->flags = 0; + /* Check that reg_num should be within TX register space. */ assert(reg_num <= R_TB_ID_REGISTER + (NUM_REGS_PER_MSG_SPACE * s->cfg.tx_fifo)); @@ -913,7 +915,7 @@ static void regs2frame(XlnxVersalCANFDState *s, qemu_can_frame *frame, * 15 49 - 64 */ - frame->flags = QEMU_CAN_FRMF_TYPE_FD; + frame->flags |= QEMU_CAN_FRMF_TYPE_FD; if (dlc_value < 8) { frame->can_dlc = dlc_value; @@ -921,6 +923,10 @@ static void regs2frame(XlnxVersalCANFDState *s, qemu_can_frame *frame, assert((dlc_value - 8) < ARRAY_SIZE(canfd_dlc_array)); frame->can_dlc = canfd_dlc_array[dlc_value - 8]; } + + if (FIELD_EX32(dlc_reg_val, TB0_DLC_REGISTER, BRS)) { + frame->flags |= QEMU_CAN_FRMF_BRS; + } } else { /* * FD Format bit not set that means it is a CAN Frame. @@ -1058,6 +1064,13 @@ static void store_rx_sequential(XlnxVersalCANFDState *s, dlc_reg_val = FIELD_DP32(0, RB_DLC_REGISTER, DLC, 8 + i); } } + + if (frame->flags & QEMU_CAN_FRMF_BRS) { + dlc_reg_val |= FIELD_DP32(0, RB_DLC_REGISTER, BRS, 1); + } + if (frame->flags & QEMU_CAN_FRMF_ESI) { + dlc_reg_val |= FIELD_DP32(0, RB_DLC_REGISTER, ESI, 1); + } } else { is_canfd_frame = false; |