1 /* 2 * QTests for Nuvoton NPCM7xx/8xx GMAC Modules. 3 * 4 * Copyright 2024 Google LLC 5 * Authors: 6 * Hao Wu <wuhaotsh@google.com> 7 * Nabih Estefan <nabihestefan@google.com> 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by the 11 * Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, but WITHOUT 15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 * for more details. 18 */ 19 20 #include "qemu/osdep.h" 21 #include "libqos/libqos.h" 22 23 /* Name of the GMAC Device */ 24 #define TYPE_NPCM_GMAC "npcm-gmac" 25 26 /* Address of the PCS Module */ 27 #define PCS_BASE_ADDRESS 0xf0780000 28 #define NPCM_PCS_IND_AC_BA 0x1fe 29 30 typedef struct GMACModule { 31 int irq; 32 uint64_t base_addr; 33 } GMACModule; 34 35 typedef struct TestData { 36 const GMACModule *module; 37 } TestData; 38 39 /* Values extracted from hw/arm/npcm7xx.c */ 40 static const GMACModule gmac_module_list[] = { 41 { 42 .irq = 14, 43 .base_addr = 0xf0802000 44 }, 45 { 46 .irq = 15, 47 .base_addr = 0xf0804000 48 }, 49 }; 50 51 /* Returns the index of the GMAC module. */ 52 static int gmac_module_index(const GMACModule *mod) 53 { 54 ptrdiff_t diff = mod - gmac_module_list; 55 56 g_assert_true(diff >= 0 && diff < ARRAY_SIZE(gmac_module_list)); 57 58 return diff; 59 } 60 61 /* 32-bit register indices. Taken from npcm_gmac.c */ 62 typedef enum NPCMRegister { 63 /* DMA Registers */ 64 NPCM_DMA_BUS_MODE = 0x1000, 65 NPCM_DMA_XMT_POLL_DEMAND = 0x1004, 66 NPCM_DMA_RCV_POLL_DEMAND = 0x1008, 67 NPCM_DMA_RCV_BASE_ADDR = 0x100c, 68 NPCM_DMA_TX_BASE_ADDR = 0x1010, 69 NPCM_DMA_STATUS = 0x1014, 70 NPCM_DMA_CONTROL = 0x1018, 71 NPCM_DMA_INTR_ENA = 0x101c, 72 NPCM_DMA_MISSED_FRAME_CTR = 0x1020, 73 NPCM_DMA_HOST_TX_DESC = 0x1048, 74 NPCM_DMA_HOST_RX_DESC = 0x104c, 75 NPCM_DMA_CUR_TX_BUF_ADDR = 0x1050, 76 NPCM_DMA_CUR_RX_BUF_ADDR = 0x1054, 77 NPCM_DMA_HW_FEATURE = 0x1058, 78 79 /* GMAC Registers */ 80 NPCM_GMAC_MAC_CONFIG = 0x0, 81 NPCM_GMAC_FRAME_FILTER = 0x4, 82 NPCM_GMAC_HASH_HIGH = 0x8, 83 NPCM_GMAC_HASH_LOW = 0xc, 84 NPCM_GMAC_MII_ADDR = 0x10, 85 NPCM_GMAC_MII_DATA = 0x14, 86 NPCM_GMAC_FLOW_CTRL = 0x18, 87 NPCM_GMAC_VLAN_FLAG = 0x1c, 88 NPCM_GMAC_VERSION = 0x20, 89 NPCM_GMAC_WAKEUP_FILTER = 0x28, 90 NPCM_GMAC_PMT = 0x2c, 91 NPCM_GMAC_LPI_CTRL = 0x30, 92 NPCM_GMAC_TIMER_CTRL = 0x34, 93 NPCM_GMAC_INT_STATUS = 0x38, 94 NPCM_GMAC_INT_MASK = 0x3c, 95 NPCM_GMAC_MAC0_ADDR_HI = 0x40, 96 NPCM_GMAC_MAC0_ADDR_LO = 0x44, 97 NPCM_GMAC_MAC1_ADDR_HI = 0x48, 98 NPCM_GMAC_MAC1_ADDR_LO = 0x4c, 99 NPCM_GMAC_MAC2_ADDR_HI = 0x50, 100 NPCM_GMAC_MAC2_ADDR_LO = 0x54, 101 NPCM_GMAC_MAC3_ADDR_HI = 0x58, 102 NPCM_GMAC_MAC3_ADDR_LO = 0x5c, 103 NPCM_GMAC_RGMII_STATUS = 0xd8, 104 NPCM_GMAC_WATCHDOG = 0xdc, 105 NPCM_GMAC_PTP_TCR = 0x700, 106 NPCM_GMAC_PTP_SSIR = 0x704, 107 NPCM_GMAC_PTP_STSR = 0x708, 108 NPCM_GMAC_PTP_STNSR = 0x70c, 109 NPCM_GMAC_PTP_STSUR = 0x710, 110 NPCM_GMAC_PTP_STNSUR = 0x714, 111 NPCM_GMAC_PTP_TAR = 0x718, 112 NPCM_GMAC_PTP_TTSR = 0x71c, 113 114 /* PCS Registers */ 115 NPCM_PCS_SR_CTL_ID1 = 0x3c0008, 116 NPCM_PCS_SR_CTL_ID2 = 0x3c000a, 117 NPCM_PCS_SR_CTL_STS = 0x3c0010, 118 119 NPCM_PCS_SR_MII_CTRL = 0x3e0000, 120 NPCM_PCS_SR_MII_STS = 0x3e0002, 121 NPCM_PCS_SR_MII_DEV_ID1 = 0x3e0004, 122 NPCM_PCS_SR_MII_DEV_ID2 = 0x3e0006, 123 NPCM_PCS_SR_MII_AN_ADV = 0x3e0008, 124 NPCM_PCS_SR_MII_LP_BABL = 0x3e000a, 125 NPCM_PCS_SR_MII_AN_EXPN = 0x3e000c, 126 NPCM_PCS_SR_MII_EXT_STS = 0x3e001e, 127 128 NPCM_PCS_SR_TIM_SYNC_ABL = 0x3e0e10, 129 NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR = 0x3e0e12, 130 NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR = 0x3e0e14, 131 NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR = 0x3e0e16, 132 NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR = 0x3e0e18, 133 NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR = 0x3e0e1a, 134 NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR = 0x3e0e1c, 135 NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR = 0x3e0e1e, 136 NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR = 0x3e0e20, 137 138 NPCM_PCS_VR_MII_MMD_DIG_CTRL1 = 0x3f0000, 139 NPCM_PCS_VR_MII_AN_CTRL = 0x3f0002, 140 NPCM_PCS_VR_MII_AN_INTR_STS = 0x3f0004, 141 NPCM_PCS_VR_MII_TC = 0x3f0006, 142 NPCM_PCS_VR_MII_DBG_CTRL = 0x3f000a, 143 NPCM_PCS_VR_MII_EEE_MCTRL0 = 0x3f000c, 144 NPCM_PCS_VR_MII_EEE_TXTIMER = 0x3f0010, 145 NPCM_PCS_VR_MII_EEE_RXTIMER = 0x3f0012, 146 NPCM_PCS_VR_MII_LINK_TIMER_CTRL = 0x3f0014, 147 NPCM_PCS_VR_MII_EEE_MCTRL1 = 0x3f0016, 148 NPCM_PCS_VR_MII_DIG_STS = 0x3f0020, 149 NPCM_PCS_VR_MII_ICG_ERRCNT1 = 0x3f0022, 150 NPCM_PCS_VR_MII_MISC_STS = 0x3f0030, 151 NPCM_PCS_VR_MII_RX_LSTS = 0x3f0040, 152 NPCM_PCS_VR_MII_MP_TX_BSTCTRL0 = 0x3f0070, 153 NPCM_PCS_VR_MII_MP_TX_LVLCTRL0 = 0x3f0074, 154 NPCM_PCS_VR_MII_MP_TX_GENCTRL0 = 0x3f007a, 155 NPCM_PCS_VR_MII_MP_TX_GENCTRL1 = 0x3f007c, 156 NPCM_PCS_VR_MII_MP_TX_STS = 0x3f0090, 157 NPCM_PCS_VR_MII_MP_RX_GENCTRL0 = 0x3f00b0, 158 NPCM_PCS_VR_MII_MP_RX_GENCTRL1 = 0x3f00b2, 159 NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0 = 0x3f00ba, 160 NPCM_PCS_VR_MII_MP_MPLL_CTRL0 = 0x3f00f0, 161 NPCM_PCS_VR_MII_MP_MPLL_CTRL1 = 0x3f00f2, 162 NPCM_PCS_VR_MII_MP_MPLL_STS = 0x3f0110, 163 NPCM_PCS_VR_MII_MP_MISC_CTRL2 = 0x3f0126, 164 NPCM_PCS_VR_MII_MP_LVL_CTRL = 0x3f0130, 165 NPCM_PCS_VR_MII_MP_MISC_CTRL0 = 0x3f0132, 166 NPCM_PCS_VR_MII_MP_MISC_CTRL1 = 0x3f0134, 167 NPCM_PCS_VR_MII_DIG_CTRL2 = 0x3f01c2, 168 NPCM_PCS_VR_MII_DIG_ERRCNT_SEL = 0x3f01c4, 169 } NPCMRegister; 170 171 static uint32_t gmac_read(QTestState *qts, const GMACModule *mod, 172 NPCMRegister regno) 173 { 174 return qtest_readl(qts, mod->base_addr + regno); 175 } 176 177 /* Check that GMAC registers are reset to default value */ 178 static void test_init(gconstpointer test_data) 179 { 180 const TestData *td = test_data; 181 const GMACModule *mod = td->module; 182 QTestState *qts = qtest_init("-machine npcm750-evb"); 183 184 #define CHECK_REG32(regno, value) \ 185 do { \ 186 g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \ 187 } while (0) 188 189 CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100); 190 CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0); 191 CHECK_REG32(NPCM_DMA_RCV_POLL_DEMAND, 0); 192 CHECK_REG32(NPCM_DMA_RCV_BASE_ADDR, 0); 193 CHECK_REG32(NPCM_DMA_TX_BASE_ADDR, 0); 194 CHECK_REG32(NPCM_DMA_STATUS, 0); 195 CHECK_REG32(NPCM_DMA_CONTROL, 0); 196 CHECK_REG32(NPCM_DMA_INTR_ENA, 0); 197 CHECK_REG32(NPCM_DMA_MISSED_FRAME_CTR, 0); 198 CHECK_REG32(NPCM_DMA_HOST_TX_DESC, 0); 199 CHECK_REG32(NPCM_DMA_HOST_RX_DESC, 0); 200 CHECK_REG32(NPCM_DMA_CUR_TX_BUF_ADDR, 0); 201 CHECK_REG32(NPCM_DMA_CUR_RX_BUF_ADDR, 0); 202 CHECK_REG32(NPCM_DMA_HW_FEATURE, 0x100d4f37); 203 204 CHECK_REG32(NPCM_GMAC_MAC_CONFIG, 0); 205 CHECK_REG32(NPCM_GMAC_FRAME_FILTER, 0); 206 CHECK_REG32(NPCM_GMAC_HASH_HIGH, 0); 207 CHECK_REG32(NPCM_GMAC_HASH_LOW, 0); 208 CHECK_REG32(NPCM_GMAC_MII_ADDR, 0); 209 CHECK_REG32(NPCM_GMAC_MII_DATA, 0); 210 CHECK_REG32(NPCM_GMAC_FLOW_CTRL, 0); 211 CHECK_REG32(NPCM_GMAC_VLAN_FLAG, 0); 212 CHECK_REG32(NPCM_GMAC_VERSION, 0x00001032); 213 CHECK_REG32(NPCM_GMAC_WAKEUP_FILTER, 0); 214 CHECK_REG32(NPCM_GMAC_PMT, 0); 215 CHECK_REG32(NPCM_GMAC_LPI_CTRL, 0); 216 CHECK_REG32(NPCM_GMAC_TIMER_CTRL, 0x03e80000); 217 CHECK_REG32(NPCM_GMAC_INT_STATUS, 0); 218 CHECK_REG32(NPCM_GMAC_INT_MASK, 0); 219 CHECK_REG32(NPCM_GMAC_MAC0_ADDR_HI, 0x8000ffff); 220 CHECK_REG32(NPCM_GMAC_MAC0_ADDR_LO, 0xffffffff); 221 CHECK_REG32(NPCM_GMAC_MAC1_ADDR_HI, 0x0000ffff); 222 CHECK_REG32(NPCM_GMAC_MAC1_ADDR_LO, 0xffffffff); 223 CHECK_REG32(NPCM_GMAC_MAC2_ADDR_HI, 0x0000ffff); 224 CHECK_REG32(NPCM_GMAC_MAC2_ADDR_LO, 0xffffffff); 225 CHECK_REG32(NPCM_GMAC_MAC3_ADDR_HI, 0x0000ffff); 226 CHECK_REG32(NPCM_GMAC_MAC3_ADDR_LO, 0xffffffff); 227 CHECK_REG32(NPCM_GMAC_RGMII_STATUS, 0); 228 CHECK_REG32(NPCM_GMAC_WATCHDOG, 0); 229 CHECK_REG32(NPCM_GMAC_PTP_TCR, 0x00002000); 230 CHECK_REG32(NPCM_GMAC_PTP_SSIR, 0); 231 CHECK_REG32(NPCM_GMAC_PTP_STSR, 0); 232 CHECK_REG32(NPCM_GMAC_PTP_STNSR, 0); 233 CHECK_REG32(NPCM_GMAC_PTP_STSUR, 0); 234 CHECK_REG32(NPCM_GMAC_PTP_STNSUR, 0); 235 CHECK_REG32(NPCM_GMAC_PTP_TAR, 0); 236 CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0); 237 238 qtest_quit(qts); 239 } 240 241 static void gmac_add_test(const char *name, const TestData* td, 242 GTestDataFunc fn) 243 { 244 g_autofree char *full_name = g_strdup_printf( 245 "npcm7xx_gmac/gmac[%d]/%s", gmac_module_index(td->module), name); 246 qtest_add_data_func(full_name, td, fn); 247 } 248 249 int main(int argc, char **argv) 250 { 251 TestData test_data_list[ARRAY_SIZE(gmac_module_list)]; 252 253 g_test_init(&argc, &argv, NULL); 254 255 for (int i = 0; i < ARRAY_SIZE(gmac_module_list); ++i) { 256 TestData *td = &test_data_list[i]; 257 258 td->module = &gmac_module_list[i]; 259 260 gmac_add_test("init", td, test_init); 261 } 262 263 return g_test_run(); 264 } 265