1*327b6808SNabih Estefan Diaz /* 2*327b6808SNabih Estefan Diaz * QTests for Nuvoton NPCM7xx/8xx GMAC Modules. 3*327b6808SNabih Estefan Diaz * 4*327b6808SNabih Estefan Diaz * Copyright 2024 Google LLC 5*327b6808SNabih Estefan Diaz * Authors: 6*327b6808SNabih Estefan Diaz * Hao Wu <wuhaotsh@google.com> 7*327b6808SNabih Estefan Diaz * Nabih Estefan <nabihestefan@google.com> 8*327b6808SNabih Estefan Diaz * 9*327b6808SNabih Estefan Diaz * This program is free software; you can redistribute it and/or modify it 10*327b6808SNabih Estefan Diaz * under the terms of the GNU General Public License as published by the 11*327b6808SNabih Estefan Diaz * Free Software Foundation; either version 2 of the License, or 12*327b6808SNabih Estefan Diaz * (at your option) any later version. 13*327b6808SNabih Estefan Diaz * 14*327b6808SNabih Estefan Diaz * This program is distributed in the hope that it will be useful, but WITHOUT 15*327b6808SNabih Estefan Diaz * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16*327b6808SNabih Estefan Diaz * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17*327b6808SNabih Estefan Diaz * for more details. 18*327b6808SNabih Estefan Diaz */ 19*327b6808SNabih Estefan Diaz 20*327b6808SNabih Estefan Diaz #include "qemu/osdep.h" 21*327b6808SNabih Estefan Diaz #include "libqos/libqos.h" 22*327b6808SNabih Estefan Diaz 23*327b6808SNabih Estefan Diaz /* Name of the GMAC Device */ 24*327b6808SNabih Estefan Diaz #define TYPE_NPCM_GMAC "npcm-gmac" 25*327b6808SNabih Estefan Diaz 26*327b6808SNabih Estefan Diaz typedef struct GMACModule { 27*327b6808SNabih Estefan Diaz int irq; 28*327b6808SNabih Estefan Diaz uint64_t base_addr; 29*327b6808SNabih Estefan Diaz } GMACModule; 30*327b6808SNabih Estefan Diaz 31*327b6808SNabih Estefan Diaz typedef struct TestData { 32*327b6808SNabih Estefan Diaz const GMACModule *module; 33*327b6808SNabih Estefan Diaz } TestData; 34*327b6808SNabih Estefan Diaz 35*327b6808SNabih Estefan Diaz /* Values extracted from hw/arm/npcm8xx.c */ 36*327b6808SNabih Estefan Diaz static const GMACModule gmac_module_list[] = { 37*327b6808SNabih Estefan Diaz { 38*327b6808SNabih Estefan Diaz .irq = 14, 39*327b6808SNabih Estefan Diaz .base_addr = 0xf0802000 40*327b6808SNabih Estefan Diaz }, 41*327b6808SNabih Estefan Diaz { 42*327b6808SNabih Estefan Diaz .irq = 15, 43*327b6808SNabih Estefan Diaz .base_addr = 0xf0804000 44*327b6808SNabih Estefan Diaz }, 45*327b6808SNabih Estefan Diaz { 46*327b6808SNabih Estefan Diaz .irq = 16, 47*327b6808SNabih Estefan Diaz .base_addr = 0xf0806000 48*327b6808SNabih Estefan Diaz }, 49*327b6808SNabih Estefan Diaz { 50*327b6808SNabih Estefan Diaz .irq = 17, 51*327b6808SNabih Estefan Diaz .base_addr = 0xf0808000 52*327b6808SNabih Estefan Diaz } 53*327b6808SNabih Estefan Diaz }; 54*327b6808SNabih Estefan Diaz 55*327b6808SNabih Estefan Diaz /* Returns the index of the GMAC module. */ 56*327b6808SNabih Estefan Diaz static int gmac_module_index(const GMACModule *mod) 57*327b6808SNabih Estefan Diaz { 58*327b6808SNabih Estefan Diaz ptrdiff_t diff = mod - gmac_module_list; 59*327b6808SNabih Estefan Diaz 60*327b6808SNabih Estefan Diaz g_assert_true(diff >= 0 && diff < ARRAY_SIZE(gmac_module_list)); 61*327b6808SNabih Estefan Diaz 62*327b6808SNabih Estefan Diaz return diff; 63*327b6808SNabih Estefan Diaz } 64*327b6808SNabih Estefan Diaz 65*327b6808SNabih Estefan Diaz /* 32-bit register indices. Taken from npcm_gmac.c */ 66*327b6808SNabih Estefan Diaz typedef enum NPCMRegister { 67*327b6808SNabih Estefan Diaz /* DMA Registers */ 68*327b6808SNabih Estefan Diaz NPCM_DMA_BUS_MODE = 0x1000, 69*327b6808SNabih Estefan Diaz NPCM_DMA_XMT_POLL_DEMAND = 0x1004, 70*327b6808SNabih Estefan Diaz NPCM_DMA_RCV_POLL_DEMAND = 0x1008, 71*327b6808SNabih Estefan Diaz NPCM_DMA_RCV_BASE_ADDR = 0x100c, 72*327b6808SNabih Estefan Diaz NPCM_DMA_TX_BASE_ADDR = 0x1010, 73*327b6808SNabih Estefan Diaz NPCM_DMA_STATUS = 0x1014, 74*327b6808SNabih Estefan Diaz NPCM_DMA_CONTROL = 0x1018, 75*327b6808SNabih Estefan Diaz NPCM_DMA_INTR_ENA = 0x101c, 76*327b6808SNabih Estefan Diaz NPCM_DMA_MISSED_FRAME_CTR = 0x1020, 77*327b6808SNabih Estefan Diaz NPCM_DMA_HOST_TX_DESC = 0x1048, 78*327b6808SNabih Estefan Diaz NPCM_DMA_HOST_RX_DESC = 0x104c, 79*327b6808SNabih Estefan Diaz NPCM_DMA_CUR_TX_BUF_ADDR = 0x1050, 80*327b6808SNabih Estefan Diaz NPCM_DMA_CUR_RX_BUF_ADDR = 0x1054, 81*327b6808SNabih Estefan Diaz NPCM_DMA_HW_FEATURE = 0x1058, 82*327b6808SNabih Estefan Diaz 83*327b6808SNabih Estefan Diaz /* GMAC Registers */ 84*327b6808SNabih Estefan Diaz NPCM_GMAC_MAC_CONFIG = 0x0, 85*327b6808SNabih Estefan Diaz NPCM_GMAC_FRAME_FILTER = 0x4, 86*327b6808SNabih Estefan Diaz NPCM_GMAC_HASH_HIGH = 0x8, 87*327b6808SNabih Estefan Diaz NPCM_GMAC_HASH_LOW = 0xc, 88*327b6808SNabih Estefan Diaz NPCM_GMAC_MII_ADDR = 0x10, 89*327b6808SNabih Estefan Diaz NPCM_GMAC_MII_DATA = 0x14, 90*327b6808SNabih Estefan Diaz NPCM_GMAC_FLOW_CTRL = 0x18, 91*327b6808SNabih Estefan Diaz NPCM_GMAC_VLAN_FLAG = 0x1c, 92*327b6808SNabih Estefan Diaz NPCM_GMAC_VERSION = 0x20, 93*327b6808SNabih Estefan Diaz NPCM_GMAC_WAKEUP_FILTER = 0x28, 94*327b6808SNabih Estefan Diaz NPCM_GMAC_PMT = 0x2c, 95*327b6808SNabih Estefan Diaz NPCM_GMAC_LPI_CTRL = 0x30, 96*327b6808SNabih Estefan Diaz NPCM_GMAC_TIMER_CTRL = 0x34, 97*327b6808SNabih Estefan Diaz NPCM_GMAC_INT_STATUS = 0x38, 98*327b6808SNabih Estefan Diaz NPCM_GMAC_INT_MASK = 0x3c, 99*327b6808SNabih Estefan Diaz NPCM_GMAC_MAC0_ADDR_HI = 0x40, 100*327b6808SNabih Estefan Diaz NPCM_GMAC_MAC0_ADDR_LO = 0x44, 101*327b6808SNabih Estefan Diaz NPCM_GMAC_MAC1_ADDR_HI = 0x48, 102*327b6808SNabih Estefan Diaz NPCM_GMAC_MAC1_ADDR_LO = 0x4c, 103*327b6808SNabih Estefan Diaz NPCM_GMAC_MAC2_ADDR_HI = 0x50, 104*327b6808SNabih Estefan Diaz NPCM_GMAC_MAC2_ADDR_LO = 0x54, 105*327b6808SNabih Estefan Diaz NPCM_GMAC_MAC3_ADDR_HI = 0x58, 106*327b6808SNabih Estefan Diaz NPCM_GMAC_MAC3_ADDR_LO = 0x5c, 107*327b6808SNabih Estefan Diaz NPCM_GMAC_RGMII_STATUS = 0xd8, 108*327b6808SNabih Estefan Diaz NPCM_GMAC_WATCHDOG = 0xdc, 109*327b6808SNabih Estefan Diaz NPCM_GMAC_PTP_TCR = 0x700, 110*327b6808SNabih Estefan Diaz NPCM_GMAC_PTP_SSIR = 0x704, 111*327b6808SNabih Estefan Diaz NPCM_GMAC_PTP_STSR = 0x708, 112*327b6808SNabih Estefan Diaz NPCM_GMAC_PTP_STNSR = 0x70c, 113*327b6808SNabih Estefan Diaz NPCM_GMAC_PTP_STSUR = 0x710, 114*327b6808SNabih Estefan Diaz NPCM_GMAC_PTP_STNSUR = 0x714, 115*327b6808SNabih Estefan Diaz NPCM_GMAC_PTP_TAR = 0x718, 116*327b6808SNabih Estefan Diaz NPCM_GMAC_PTP_TTSR = 0x71c, 117*327b6808SNabih Estefan Diaz } NPCMRegister; 118*327b6808SNabih Estefan Diaz 119*327b6808SNabih Estefan Diaz static uint32_t gmac_read(QTestState *qts, const GMACModule *mod, 120*327b6808SNabih Estefan Diaz NPCMRegister regno) 121*327b6808SNabih Estefan Diaz { 122*327b6808SNabih Estefan Diaz return qtest_readl(qts, mod->base_addr + regno); 123*327b6808SNabih Estefan Diaz } 124*327b6808SNabih Estefan Diaz 125*327b6808SNabih Estefan Diaz /* Check that GMAC registers are reset to default value */ 126*327b6808SNabih Estefan Diaz static void test_init(gconstpointer test_data) 127*327b6808SNabih Estefan Diaz { 128*327b6808SNabih Estefan Diaz const TestData *td = test_data; 129*327b6808SNabih Estefan Diaz const GMACModule *mod = td->module; 130*327b6808SNabih Estefan Diaz QTestState *qts = qtest_init("-machine npcm845-evb"); 131*327b6808SNabih Estefan Diaz 132*327b6808SNabih Estefan Diaz #define CHECK_REG32(regno, value) \ 133*327b6808SNabih Estefan Diaz do { \ 134*327b6808SNabih Estefan Diaz g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \ 135*327b6808SNabih Estefan Diaz } while (0) 136*327b6808SNabih Estefan Diaz 137*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100); 138*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0); 139*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_DMA_RCV_POLL_DEMAND, 0); 140*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_DMA_RCV_BASE_ADDR, 0); 141*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_DMA_TX_BASE_ADDR, 0); 142*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_DMA_STATUS, 0); 143*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_DMA_CONTROL, 0); 144*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_DMA_INTR_ENA, 0); 145*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_DMA_MISSED_FRAME_CTR, 0); 146*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_DMA_HOST_TX_DESC, 0); 147*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_DMA_HOST_RX_DESC, 0); 148*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_DMA_CUR_TX_BUF_ADDR, 0); 149*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_DMA_CUR_RX_BUF_ADDR, 0); 150*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_DMA_HW_FEATURE, 0x100d4f37); 151*327b6808SNabih Estefan Diaz 152*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_MAC_CONFIG, 0); 153*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_FRAME_FILTER, 0); 154*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_HASH_HIGH, 0); 155*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_HASH_LOW, 0); 156*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_MII_ADDR, 0); 157*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_MII_DATA, 0); 158*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_FLOW_CTRL, 0); 159*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_VLAN_FLAG, 0); 160*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_VERSION, 0x00001032); 161*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_WAKEUP_FILTER, 0); 162*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_PMT, 0); 163*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_LPI_CTRL, 0); 164*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_TIMER_CTRL, 0x03e80000); 165*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_INT_STATUS, 0); 166*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_INT_MASK, 0); 167*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_MAC0_ADDR_HI, 0x8000ffff); 168*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_MAC0_ADDR_LO, 0xffffffff); 169*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_MAC1_ADDR_HI, 0x0000ffff); 170*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_MAC1_ADDR_LO, 0xffffffff); 171*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_MAC2_ADDR_HI, 0x0000ffff); 172*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_MAC2_ADDR_LO, 0xffffffff); 173*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_MAC3_ADDR_HI, 0x0000ffff); 174*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_MAC3_ADDR_LO, 0xffffffff); 175*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_RGMII_STATUS, 0); 176*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_WATCHDOG, 0); 177*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_PTP_TCR, 0x00002000); 178*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_PTP_SSIR, 0); 179*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_PTP_STSR, 0); 180*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_PTP_STNSR, 0); 181*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_PTP_STSUR, 0); 182*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_PTP_STNSUR, 0); 183*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_PTP_TAR, 0); 184*327b6808SNabih Estefan Diaz CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0); 185*327b6808SNabih Estefan Diaz 186*327b6808SNabih Estefan Diaz qtest_quit(qts); 187*327b6808SNabih Estefan Diaz } 188*327b6808SNabih Estefan Diaz 189*327b6808SNabih Estefan Diaz static void gmac_add_test(const char *name, const TestData* td, 190*327b6808SNabih Estefan Diaz GTestDataFunc fn) 191*327b6808SNabih Estefan Diaz { 192*327b6808SNabih Estefan Diaz g_autofree char *full_name = g_strdup_printf( 193*327b6808SNabih Estefan Diaz "npcm7xx_gmac/gmac[%d]/%s", gmac_module_index(td->module), name); 194*327b6808SNabih Estefan Diaz qtest_add_data_func(full_name, td, fn); 195*327b6808SNabih Estefan Diaz } 196*327b6808SNabih Estefan Diaz 197*327b6808SNabih Estefan Diaz int main(int argc, char **argv) 198*327b6808SNabih Estefan Diaz { 199*327b6808SNabih Estefan Diaz TestData test_data_list[ARRAY_SIZE(gmac_module_list)]; 200*327b6808SNabih Estefan Diaz 201*327b6808SNabih Estefan Diaz g_test_init(&argc, &argv, NULL); 202*327b6808SNabih Estefan Diaz 203*327b6808SNabih Estefan Diaz for (int i = 0; i < ARRAY_SIZE(gmac_module_list); ++i) { 204*327b6808SNabih Estefan Diaz TestData *td = &test_data_list[i]; 205*327b6808SNabih Estefan Diaz 206*327b6808SNabih Estefan Diaz td->module = &gmac_module_list[i]; 207*327b6808SNabih Estefan Diaz 208*327b6808SNabih Estefan Diaz gmac_add_test("init", td, test_init); 209*327b6808SNabih Estefan Diaz } 210*327b6808SNabih Estefan Diaz 211*327b6808SNabih Estefan Diaz return g_test_run(); 212*327b6808SNabih Estefan Diaz } 213