1ab5e842cSVikram Garhwal /* 2ab5e842cSVikram Garhwal * QTests for the Xilinx ZynqMP CAN controller. 3ab5e842cSVikram Garhwal * 4ab5e842cSVikram Garhwal * Copyright (c) 2020 Xilinx Inc. 5ab5e842cSVikram Garhwal * 6ab5e842cSVikram Garhwal * Written-by: Vikram Garhwal<fnu.vikram@xilinx.com> 7ab5e842cSVikram Garhwal * 8ab5e842cSVikram Garhwal * Permission is hereby granted, free of charge, to any person obtaining a copy 9ab5e842cSVikram Garhwal * of this software and associated documentation files (the "Software"), to deal 10ab5e842cSVikram Garhwal * in the Software without restriction, including without limitation the rights 11ab5e842cSVikram Garhwal * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12ab5e842cSVikram Garhwal * copies of the Software, and to permit persons to whom the Software is 13ab5e842cSVikram Garhwal * furnished to do so, subject to the following conditions: 14ab5e842cSVikram Garhwal * 15ab5e842cSVikram Garhwal * The above copyright notice and this permission notice shall be included in 16ab5e842cSVikram Garhwal * all copies or substantial portions of the Software. 17ab5e842cSVikram Garhwal * 18ab5e842cSVikram Garhwal * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19ab5e842cSVikram Garhwal * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20ab5e842cSVikram Garhwal * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21ab5e842cSVikram Garhwal * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22ab5e842cSVikram Garhwal * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23ab5e842cSVikram Garhwal * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24ab5e842cSVikram Garhwal * THE SOFTWARE. 25ab5e842cSVikram Garhwal */ 26ab5e842cSVikram Garhwal 27ab5e842cSVikram Garhwal #include "qemu/osdep.h" 28ab5e842cSVikram Garhwal #include "libqos/libqtest.h" 29ab5e842cSVikram Garhwal 30ab5e842cSVikram Garhwal /* Base address. */ 31ab5e842cSVikram Garhwal #define CAN0_BASE_ADDR 0xFF060000 32ab5e842cSVikram Garhwal #define CAN1_BASE_ADDR 0xFF070000 33ab5e842cSVikram Garhwal 34ab5e842cSVikram Garhwal /* Register addresses. */ 35ab5e842cSVikram Garhwal #define R_SRR_OFFSET 0x00 36ab5e842cSVikram Garhwal #define R_MSR_OFFSET 0x04 37ab5e842cSVikram Garhwal #define R_SR_OFFSET 0x18 38ab5e842cSVikram Garhwal #define R_ISR_OFFSET 0x1C 39ab5e842cSVikram Garhwal #define R_ICR_OFFSET 0x24 40ab5e842cSVikram Garhwal #define R_TXID_OFFSET 0x30 41ab5e842cSVikram Garhwal #define R_TXDLC_OFFSET 0x34 42ab5e842cSVikram Garhwal #define R_TXDATA1_OFFSET 0x38 43ab5e842cSVikram Garhwal #define R_TXDATA2_OFFSET 0x3C 44ab5e842cSVikram Garhwal #define R_RXID_OFFSET 0x50 45ab5e842cSVikram Garhwal #define R_RXDLC_OFFSET 0x54 46ab5e842cSVikram Garhwal #define R_RXDATA1_OFFSET 0x58 47ab5e842cSVikram Garhwal #define R_RXDATA2_OFFSET 0x5C 48ab5e842cSVikram Garhwal #define R_AFR 0x60 49ab5e842cSVikram Garhwal #define R_AFMR1 0x64 50ab5e842cSVikram Garhwal #define R_AFIR1 0x68 51ab5e842cSVikram Garhwal #define R_AFMR2 0x6C 52ab5e842cSVikram Garhwal #define R_AFIR2 0x70 53ab5e842cSVikram Garhwal #define R_AFMR3 0x74 54ab5e842cSVikram Garhwal #define R_AFIR3 0x78 55ab5e842cSVikram Garhwal #define R_AFMR4 0x7C 56ab5e842cSVikram Garhwal #define R_AFIR4 0x80 57ab5e842cSVikram Garhwal 58ab5e842cSVikram Garhwal /* CAN modes. */ 59ab5e842cSVikram Garhwal #define CONFIG_MODE 0x00 60ab5e842cSVikram Garhwal #define NORMAL_MODE 0x00 61ab5e842cSVikram Garhwal #define LOOPBACK_MODE 0x02 62ab5e842cSVikram Garhwal #define SNOOP_MODE 0x04 63ab5e842cSVikram Garhwal #define SLEEP_MODE 0x01 64ab5e842cSVikram Garhwal #define ENABLE_CAN (1 << 1) 65ab5e842cSVikram Garhwal #define STATUS_NORMAL_MODE (1 << 3) 66ab5e842cSVikram Garhwal #define STATUS_LOOPBACK_MODE (1 << 1) 67ab5e842cSVikram Garhwal #define STATUS_SNOOP_MODE (1 << 12) 68ab5e842cSVikram Garhwal #define STATUS_SLEEP_MODE (1 << 2) 69ab5e842cSVikram Garhwal #define ISR_TXOK (1 << 1) 70ab5e842cSVikram Garhwal #define ISR_RXOK (1 << 4) 71ab5e842cSVikram Garhwal 72ab5e842cSVikram Garhwal static void match_rx_tx_data(const uint32_t *buf_tx, const uint32_t *buf_rx, 73ab5e842cSVikram Garhwal uint8_t can_timestamp) 74ab5e842cSVikram Garhwal { 75ab5e842cSVikram Garhwal uint16_t size = 0; 76ab5e842cSVikram Garhwal uint8_t len = 4; 77ab5e842cSVikram Garhwal 78ab5e842cSVikram Garhwal while (size < len) { 79ab5e842cSVikram Garhwal if (R_RXID_OFFSET + 4 * size == R_RXDLC_OFFSET) { 80ab5e842cSVikram Garhwal g_assert_cmpint(buf_rx[size], ==, buf_tx[size] + can_timestamp); 81ab5e842cSVikram Garhwal } else { 82ab5e842cSVikram Garhwal g_assert_cmpint(buf_rx[size], ==, buf_tx[size]); 83ab5e842cSVikram Garhwal } 84ab5e842cSVikram Garhwal 85ab5e842cSVikram Garhwal size++; 86ab5e842cSVikram Garhwal } 87ab5e842cSVikram Garhwal } 88ab5e842cSVikram Garhwal 89ab5e842cSVikram Garhwal static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx) 90ab5e842cSVikram Garhwal { 91ab5e842cSVikram Garhwal uint32_t int_status; 92ab5e842cSVikram Garhwal 93ab5e842cSVikram Garhwal /* Read the interrupt on CAN rx. */ 94ab5e842cSVikram Garhwal int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_RXOK; 95ab5e842cSVikram Garhwal 96ab5e842cSVikram Garhwal g_assert_cmpint(int_status, ==, ISR_RXOK); 97ab5e842cSVikram Garhwal 98ab5e842cSVikram Garhwal /* Read the RX register data for CAN. */ 99ab5e842cSVikram Garhwal buf_rx[0] = qtest_readl(qts, can_base_addr + R_RXID_OFFSET); 100ab5e842cSVikram Garhwal buf_rx[1] = qtest_readl(qts, can_base_addr + R_RXDLC_OFFSET); 101ab5e842cSVikram Garhwal buf_rx[2] = qtest_readl(qts, can_base_addr + R_RXDATA1_OFFSET); 102ab5e842cSVikram Garhwal buf_rx[3] = qtest_readl(qts, can_base_addr + R_RXDATA2_OFFSET); 103ab5e842cSVikram Garhwal 104ab5e842cSVikram Garhwal /* Clear the RX interrupt. */ 105ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_ICR_OFFSET, ISR_RXOK); 106ab5e842cSVikram Garhwal } 107ab5e842cSVikram Garhwal 108ab5e842cSVikram Garhwal static void send_data(QTestState *qts, uint64_t can_base_addr, 109ab5e842cSVikram Garhwal const uint32_t *buf_tx) 110ab5e842cSVikram Garhwal { 111ab5e842cSVikram Garhwal uint32_t int_status; 112ab5e842cSVikram Garhwal 113ab5e842cSVikram Garhwal /* Write the TX register data for CAN. */ 114ab5e842cSVikram Garhwal qtest_writel(qts, can_base_addr + R_TXID_OFFSET, buf_tx[0]); 115ab5e842cSVikram Garhwal qtest_writel(qts, can_base_addr + R_TXDLC_OFFSET, buf_tx[1]); 116ab5e842cSVikram Garhwal qtest_writel(qts, can_base_addr + R_TXDATA1_OFFSET, buf_tx[2]); 117ab5e842cSVikram Garhwal qtest_writel(qts, can_base_addr + R_TXDATA2_OFFSET, buf_tx[3]); 118ab5e842cSVikram Garhwal 119ab5e842cSVikram Garhwal /* Read the interrupt on CAN for tx. */ 120ab5e842cSVikram Garhwal int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_TXOK; 121ab5e842cSVikram Garhwal 122ab5e842cSVikram Garhwal g_assert_cmpint(int_status, ==, ISR_TXOK); 123ab5e842cSVikram Garhwal 124ab5e842cSVikram Garhwal /* Clear the interrupt for tx. */ 125ab5e842cSVikram Garhwal qtest_writel(qts, CAN0_BASE_ADDR + R_ICR_OFFSET, ISR_TXOK); 126ab5e842cSVikram Garhwal } 127ab5e842cSVikram Garhwal 128ab5e842cSVikram Garhwal /* 129ab5e842cSVikram Garhwal * This test will be transferring data from CAN0 and CAN1 through canbus. CAN0 130ab5e842cSVikram Garhwal * initiate the data transfer to can-bus, CAN1 receives the data. Test compares 131ab5e842cSVikram Garhwal * the data sent from CAN0 with received on CAN1. 132ab5e842cSVikram Garhwal */ 133ab5e842cSVikram Garhwal static void test_can_bus(void) 134ab5e842cSVikram Garhwal { 135ab5e842cSVikram Garhwal const uint32_t buf_tx[4] = { 0xFF, 0x80000000, 0x12345678, 0x87654321 }; 136ab5e842cSVikram Garhwal uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 }; 137ab5e842cSVikram Garhwal uint32_t status = 0; 138ab5e842cSVikram Garhwal uint8_t can_timestamp = 1; 139ab5e842cSVikram Garhwal 140ab5e842cSVikram Garhwal QTestState *qts = qtest_init("-machine xlnx-zcu102" 141*7848023aSPaolo Bonzini " -object can-bus,id=canbus" 142*7848023aSPaolo Bonzini " -machine canbus0=canbus" 143*7848023aSPaolo Bonzini " -machine canbus1=canbus" 144ab5e842cSVikram Garhwal ); 145ab5e842cSVikram Garhwal 146ab5e842cSVikram Garhwal /* Configure the CAN0 and CAN1. */ 147ab5e842cSVikram Garhwal qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN); 148ab5e842cSVikram Garhwal qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE); 149ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN); 150ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE); 151ab5e842cSVikram Garhwal 152ab5e842cSVikram Garhwal /* Check here if CAN0 and CAN1 are in normal mode. */ 153ab5e842cSVikram Garhwal status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET); 154ab5e842cSVikram Garhwal g_assert_cmpint(status, ==, STATUS_NORMAL_MODE); 155ab5e842cSVikram Garhwal 156ab5e842cSVikram Garhwal status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET); 157ab5e842cSVikram Garhwal g_assert_cmpint(status, ==, STATUS_NORMAL_MODE); 158ab5e842cSVikram Garhwal 159ab5e842cSVikram Garhwal send_data(qts, CAN0_BASE_ADDR, buf_tx); 160ab5e842cSVikram Garhwal 161ab5e842cSVikram Garhwal read_data(qts, CAN1_BASE_ADDR, buf_rx); 162ab5e842cSVikram Garhwal match_rx_tx_data(buf_tx, buf_rx, can_timestamp); 163ab5e842cSVikram Garhwal 164ab5e842cSVikram Garhwal qtest_quit(qts); 165ab5e842cSVikram Garhwal } 166ab5e842cSVikram Garhwal 167ab5e842cSVikram Garhwal /* 168ab5e842cSVikram Garhwal * This test is performing loopback mode on CAN0 and CAN1. Data sent from TX of 169ab5e842cSVikram Garhwal * each CAN0 and CAN1 are compared with RX register data for respective CAN. 170ab5e842cSVikram Garhwal */ 171ab5e842cSVikram Garhwal static void test_can_loopback(void) 172ab5e842cSVikram Garhwal { 173ab5e842cSVikram Garhwal uint32_t buf_tx[4] = { 0xFF, 0x80000000, 0x12345678, 0x87654321 }; 174ab5e842cSVikram Garhwal uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 }; 175ab5e842cSVikram Garhwal uint32_t status = 0; 176ab5e842cSVikram Garhwal 177ab5e842cSVikram Garhwal QTestState *qts = qtest_init("-machine xlnx-zcu102" 178*7848023aSPaolo Bonzini " -object can-bus,id=canbus" 179*7848023aSPaolo Bonzini " -machine canbus0=canbus" 180*7848023aSPaolo Bonzini " -machine canbus1=canbus" 181ab5e842cSVikram Garhwal ); 182ab5e842cSVikram Garhwal 183ab5e842cSVikram Garhwal /* Configure the CAN0 in loopback mode. */ 184ab5e842cSVikram Garhwal qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE); 185ab5e842cSVikram Garhwal qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, LOOPBACK_MODE); 186ab5e842cSVikram Garhwal qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN); 187ab5e842cSVikram Garhwal 188ab5e842cSVikram Garhwal /* Check here if CAN0 is set in loopback mode. */ 189ab5e842cSVikram Garhwal status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET); 190ab5e842cSVikram Garhwal 191ab5e842cSVikram Garhwal g_assert_cmpint(status, ==, STATUS_LOOPBACK_MODE); 192ab5e842cSVikram Garhwal 193ab5e842cSVikram Garhwal send_data(qts, CAN0_BASE_ADDR, buf_tx); 194ab5e842cSVikram Garhwal read_data(qts, CAN0_BASE_ADDR, buf_rx); 195ab5e842cSVikram Garhwal match_rx_tx_data(buf_tx, buf_rx, 0); 196ab5e842cSVikram Garhwal 197ab5e842cSVikram Garhwal /* Configure the CAN1 in loopback mode. */ 198ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE); 199ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, LOOPBACK_MODE); 200ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN); 201ab5e842cSVikram Garhwal 202ab5e842cSVikram Garhwal /* Check here if CAN1 is set in loopback mode. */ 203ab5e842cSVikram Garhwal status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET); 204ab5e842cSVikram Garhwal 205ab5e842cSVikram Garhwal g_assert_cmpint(status, ==, STATUS_LOOPBACK_MODE); 206ab5e842cSVikram Garhwal 207ab5e842cSVikram Garhwal send_data(qts, CAN1_BASE_ADDR, buf_tx); 208ab5e842cSVikram Garhwal read_data(qts, CAN1_BASE_ADDR, buf_rx); 209ab5e842cSVikram Garhwal match_rx_tx_data(buf_tx, buf_rx, 0); 210ab5e842cSVikram Garhwal 211ab5e842cSVikram Garhwal qtest_quit(qts); 212ab5e842cSVikram Garhwal } 213ab5e842cSVikram Garhwal 214ab5e842cSVikram Garhwal /* 215ab5e842cSVikram Garhwal * Enable filters for CAN1. This will filter incoming messages with ID. In this 216ab5e842cSVikram Garhwal * test message will pass through filter 2. 217ab5e842cSVikram Garhwal */ 218ab5e842cSVikram Garhwal static void test_can_filter(void) 219ab5e842cSVikram Garhwal { 220ab5e842cSVikram Garhwal uint32_t buf_tx[4] = { 0x14, 0x80000000, 0x12345678, 0x87654321 }; 221ab5e842cSVikram Garhwal uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 }; 222ab5e842cSVikram Garhwal uint32_t status = 0; 223ab5e842cSVikram Garhwal uint8_t can_timestamp = 1; 224ab5e842cSVikram Garhwal 225ab5e842cSVikram Garhwal QTestState *qts = qtest_init("-machine xlnx-zcu102" 226*7848023aSPaolo Bonzini " -object can-bus,id=canbus" 227*7848023aSPaolo Bonzini " -machine canbus0=canbus" 228*7848023aSPaolo Bonzini " -machine canbus1=canbus" 229ab5e842cSVikram Garhwal ); 230ab5e842cSVikram Garhwal 231ab5e842cSVikram Garhwal /* Configure the CAN0 and CAN1. */ 232ab5e842cSVikram Garhwal qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN); 233ab5e842cSVikram Garhwal qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE); 234ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN); 235ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE); 236ab5e842cSVikram Garhwal 237ab5e842cSVikram Garhwal /* Check here if CAN0 and CAN1 are in normal mode. */ 238ab5e842cSVikram Garhwal status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET); 239ab5e842cSVikram Garhwal g_assert_cmpint(status, ==, STATUS_NORMAL_MODE); 240ab5e842cSVikram Garhwal 241ab5e842cSVikram Garhwal status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET); 242ab5e842cSVikram Garhwal g_assert_cmpint(status, ==, STATUS_NORMAL_MODE); 243ab5e842cSVikram Garhwal 244ab5e842cSVikram Garhwal /* Set filter for CAN1 for incoming messages. */ 245ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_AFR, 0x0); 246ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR1, 0xF7); 247ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR1, 0x121F); 248ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR2, 0x5431); 249ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR2, 0x14); 250ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR3, 0x1234); 251ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR3, 0x5431); 252ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR4, 0xFFF); 253ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR4, 0x1234); 254ab5e842cSVikram Garhwal 255ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_AFR, 0xF); 256ab5e842cSVikram Garhwal 257ab5e842cSVikram Garhwal send_data(qts, CAN0_BASE_ADDR, buf_tx); 258ab5e842cSVikram Garhwal 259ab5e842cSVikram Garhwal read_data(qts, CAN1_BASE_ADDR, buf_rx); 260ab5e842cSVikram Garhwal match_rx_tx_data(buf_tx, buf_rx, can_timestamp); 261ab5e842cSVikram Garhwal 262ab5e842cSVikram Garhwal qtest_quit(qts); 263ab5e842cSVikram Garhwal } 264ab5e842cSVikram Garhwal 265ab5e842cSVikram Garhwal /* Testing sleep mode on CAN0 while CAN1 is in normal mode. */ 266ab5e842cSVikram Garhwal static void test_can_sleepmode(void) 267ab5e842cSVikram Garhwal { 268ab5e842cSVikram Garhwal uint32_t buf_tx[4] = { 0x14, 0x80000000, 0x12345678, 0x87654321 }; 269ab5e842cSVikram Garhwal uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 }; 270ab5e842cSVikram Garhwal uint32_t status = 0; 271ab5e842cSVikram Garhwal uint8_t can_timestamp = 1; 272ab5e842cSVikram Garhwal 273ab5e842cSVikram Garhwal QTestState *qts = qtest_init("-machine xlnx-zcu102" 274*7848023aSPaolo Bonzini " -object can-bus,id=canbus" 275*7848023aSPaolo Bonzini " -machine canbus0=canbus" 276*7848023aSPaolo Bonzini " -machine canbus1=canbus" 277ab5e842cSVikram Garhwal ); 278ab5e842cSVikram Garhwal 279ab5e842cSVikram Garhwal /* Configure the CAN0. */ 280ab5e842cSVikram Garhwal qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE); 281ab5e842cSVikram Garhwal qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, SLEEP_MODE); 282ab5e842cSVikram Garhwal qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN); 283ab5e842cSVikram Garhwal 284ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN); 285ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE); 286ab5e842cSVikram Garhwal 287ab5e842cSVikram Garhwal /* Check here if CAN0 is in SLEEP mode and CAN1 in normal mode. */ 288ab5e842cSVikram Garhwal status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET); 289ab5e842cSVikram Garhwal g_assert_cmpint(status, ==, STATUS_SLEEP_MODE); 290ab5e842cSVikram Garhwal 291ab5e842cSVikram Garhwal status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET); 292ab5e842cSVikram Garhwal g_assert_cmpint(status, ==, STATUS_NORMAL_MODE); 293ab5e842cSVikram Garhwal 294ab5e842cSVikram Garhwal send_data(qts, CAN1_BASE_ADDR, buf_tx); 295ab5e842cSVikram Garhwal 296ab5e842cSVikram Garhwal /* 297ab5e842cSVikram Garhwal * Once CAN1 sends data on can-bus. CAN0 should exit sleep mode. 298ab5e842cSVikram Garhwal * Check the CAN0 status now. It should exit the sleep mode and receive the 299ab5e842cSVikram Garhwal * incoming data. 300ab5e842cSVikram Garhwal */ 301ab5e842cSVikram Garhwal status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET); 302ab5e842cSVikram Garhwal g_assert_cmpint(status, ==, STATUS_NORMAL_MODE); 303ab5e842cSVikram Garhwal 304ab5e842cSVikram Garhwal read_data(qts, CAN0_BASE_ADDR, buf_rx); 305ab5e842cSVikram Garhwal 306ab5e842cSVikram Garhwal match_rx_tx_data(buf_tx, buf_rx, can_timestamp); 307ab5e842cSVikram Garhwal 308ab5e842cSVikram Garhwal qtest_quit(qts); 309ab5e842cSVikram Garhwal } 310ab5e842cSVikram Garhwal 311ab5e842cSVikram Garhwal /* Testing Snoop mode on CAN0 while CAN1 is in normal mode. */ 312ab5e842cSVikram Garhwal static void test_can_snoopmode(void) 313ab5e842cSVikram Garhwal { 314ab5e842cSVikram Garhwal uint32_t buf_tx[4] = { 0x14, 0x80000000, 0x12345678, 0x87654321 }; 315ab5e842cSVikram Garhwal uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 }; 316ab5e842cSVikram Garhwal uint32_t status = 0; 317ab5e842cSVikram Garhwal uint8_t can_timestamp = 1; 318ab5e842cSVikram Garhwal 319ab5e842cSVikram Garhwal QTestState *qts = qtest_init("-machine xlnx-zcu102" 320*7848023aSPaolo Bonzini " -object can-bus,id=canbus" 321*7848023aSPaolo Bonzini " -machine canbus0=canbus" 322*7848023aSPaolo Bonzini " -machine canbus1=canbus" 323ab5e842cSVikram Garhwal ); 324ab5e842cSVikram Garhwal 325ab5e842cSVikram Garhwal /* Configure the CAN0. */ 326ab5e842cSVikram Garhwal qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE); 327ab5e842cSVikram Garhwal qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, SNOOP_MODE); 328ab5e842cSVikram Garhwal qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN); 329ab5e842cSVikram Garhwal 330ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN); 331ab5e842cSVikram Garhwal qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE); 332ab5e842cSVikram Garhwal 333ab5e842cSVikram Garhwal /* Check here if CAN0 is in SNOOP mode and CAN1 in normal mode. */ 334ab5e842cSVikram Garhwal status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET); 335ab5e842cSVikram Garhwal g_assert_cmpint(status, ==, STATUS_SNOOP_MODE); 336ab5e842cSVikram Garhwal 337ab5e842cSVikram Garhwal status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET); 338ab5e842cSVikram Garhwal g_assert_cmpint(status, ==, STATUS_NORMAL_MODE); 339ab5e842cSVikram Garhwal 340ab5e842cSVikram Garhwal send_data(qts, CAN1_BASE_ADDR, buf_tx); 341ab5e842cSVikram Garhwal 342ab5e842cSVikram Garhwal read_data(qts, CAN0_BASE_ADDR, buf_rx); 343ab5e842cSVikram Garhwal 344ab5e842cSVikram Garhwal match_rx_tx_data(buf_tx, buf_rx, can_timestamp); 345ab5e842cSVikram Garhwal 346ab5e842cSVikram Garhwal qtest_quit(qts); 347ab5e842cSVikram Garhwal } 348ab5e842cSVikram Garhwal 349ab5e842cSVikram Garhwal int main(int argc, char **argv) 350ab5e842cSVikram Garhwal { 351ab5e842cSVikram Garhwal g_test_init(&argc, &argv, NULL); 352ab5e842cSVikram Garhwal 353ab5e842cSVikram Garhwal qtest_add_func("/net/can/can_bus", test_can_bus); 354ab5e842cSVikram Garhwal qtest_add_func("/net/can/can_loopback", test_can_loopback); 355ab5e842cSVikram Garhwal qtest_add_func("/net/can/can_filter", test_can_filter); 356ab5e842cSVikram Garhwal qtest_add_func("/net/can/can_test_snoopmode", test_can_snoopmode); 357ab5e842cSVikram Garhwal qtest_add_func("/net/can/can_test_sleepmode", test_can_sleepmode); 358ab5e842cSVikram Garhwal 359ab5e842cSVikram Garhwal return g_test_run(); 360ab5e842cSVikram Garhwal } 361