xref: /qemu/tests/qtest/npcm_gmac-test.c (revision 327b680877b79c4b5473b5d59265194f35a24c6f)
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