2 * libqos driver framework
4 * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License version 2.1 as published by the Free Software Foundation.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see <http://www.gnu.org/licenses/>
19 #include "qemu/osdep.h"
20 #include "hw/net/e1000_regs.h"
21 #include "hw/pci/pci_ids.h"
22 #include "../libqtest.h"
24 #include "qemu/sockets.h"
26 #include "qemu/module.h"
27 #include "qemu/bitops.h"
28 #include "libqos-malloc.h"
32 #define E1000E_IVAR_TEST_CFG \
33 (((E1000E_RX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << E1000_IVAR_RXQ0_SHIFT) | \
34 ((E1000E_TX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << E1000_IVAR_TXQ0_SHIFT) | \
35 E1000_IVAR_TX_INT_EVERY_WB)
37 #define E1000E_RING_LEN (0x1000)
39 void e1000e_tx_ring_push(QE1000E
*d
, void *descr
)
41 QE1000E_PCI
*d_pci
= container_of(d
, QE1000E_PCI
, e1000e
);
42 uint32_t tail
= e1000e_macreg_read(d
, E1000_TDT
);
43 uint32_t len
= e1000e_macreg_read(d
, E1000_TDLEN
) / E1000_RING_DESC_LEN
;
45 qtest_memwrite(d_pci
->pci_dev
.bus
->qts
,
46 d
->tx_ring
+ tail
* E1000_RING_DESC_LEN
,
47 descr
, E1000_RING_DESC_LEN
);
48 e1000e_macreg_write(d
, E1000_TDT
, (tail
+ 1) % len
);
50 /* Read WB data for the packet transmitted */
51 qtest_memread(d_pci
->pci_dev
.bus
->qts
,
52 d
->tx_ring
+ tail
* E1000_RING_DESC_LEN
,
53 descr
, E1000_RING_DESC_LEN
);
56 void e1000e_rx_ring_push(QE1000E
*d
, void *descr
)
58 QE1000E_PCI
*d_pci
= container_of(d
, QE1000E_PCI
, e1000e
);
59 uint32_t tail
= e1000e_macreg_read(d
, E1000_RDT
);
60 uint32_t len
= e1000e_macreg_read(d
, E1000_RDLEN
) / E1000_RING_DESC_LEN
;
62 qtest_memwrite(d_pci
->pci_dev
.bus
->qts
,
63 d
->rx_ring
+ tail
* E1000_RING_DESC_LEN
,
64 descr
, E1000_RING_DESC_LEN
);
65 e1000e_macreg_write(d
, E1000_RDT
, (tail
+ 1) % len
);
67 /* Read WB data for the packet received */
68 qtest_memread(d_pci
->pci_dev
.bus
->qts
,
69 d
->rx_ring
+ tail
* E1000_RING_DESC_LEN
,
70 descr
, E1000_RING_DESC_LEN
);
73 static void e1000e_foreach_callback(QPCIDevice
*dev
, int devfn
, void *data
)
75 QPCIDevice
*res
= data
;
76 memcpy(res
, dev
, sizeof(QPCIDevice
));
80 void e1000e_wait_isr(QE1000E
*d
, uint16_t msg_id
)
82 QE1000E_PCI
*d_pci
= container_of(d
, QE1000E_PCI
, e1000e
);
83 guint64 end_time
= g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND
;
86 if (qpci_msix_pending(&d_pci
->pci_dev
, msg_id
)) {
89 qtest_clock_step(d_pci
->pci_dev
.bus
->qts
, 10000);
90 } while (g_get_monotonic_time() < end_time
);
92 g_error("Timeout expired");
95 static void e1000e_pci_destructor(QOSGraphObject
*obj
)
97 QE1000E_PCI
*epci
= (QE1000E_PCI
*) obj
;
98 qpci_iounmap(&epci
->pci_dev
, epci
->mac_regs
);
99 qpci_msix_disable(&epci
->pci_dev
);
102 static void e1000e_pci_start_hw(QOSGraphObject
*obj
)
104 QE1000E_PCI
*d
= (QE1000E_PCI
*) obj
;
107 /* Enable the device */
108 qpci_device_enable(&d
->pci_dev
);
110 /* Reset the device */
111 val
= e1000e_macreg_read(&d
->e1000e
, E1000_CTRL
);
112 e1000e_macreg_write(&d
->e1000e
, E1000_CTRL
, val
| E1000_CTRL_RST
| E1000_CTRL_SLU
);
114 /* Enable and configure MSI-X */
115 qpci_msix_enable(&d
->pci_dev
);
116 e1000e_macreg_write(&d
->e1000e
, E1000_IVAR
, E1000E_IVAR_TEST_CFG
);
118 /* Check the device status - link and speed */
119 val
= e1000e_macreg_read(&d
->e1000e
, E1000_STATUS
);
120 g_assert_cmphex(val
& (E1000_STATUS_LU
| E1000_STATUS_ASDV_1000
),
121 ==, E1000_STATUS_LU
| E1000_STATUS_ASDV_1000
);
123 /* Initialize TX/RX logic */
124 e1000e_macreg_write(&d
->e1000e
, E1000_RCTL
, 0);
125 e1000e_macreg_write(&d
->e1000e
, E1000_TCTL
, 0);
127 /* Notify the device that the driver is ready */
128 val
= e1000e_macreg_read(&d
->e1000e
, E1000_CTRL_EXT
);
129 e1000e_macreg_write(&d
->e1000e
, E1000_CTRL_EXT
,
130 val
| E1000_CTRL_EXT_DRV_LOAD
);
132 e1000e_macreg_write(&d
->e1000e
, E1000_TDBAL
,
133 (uint32_t) d
->e1000e
.tx_ring
);
134 e1000e_macreg_write(&d
->e1000e
, E1000_TDBAH
,
135 (uint32_t) (d
->e1000e
.tx_ring
>> 32));
136 e1000e_macreg_write(&d
->e1000e
, E1000_TDLEN
, E1000E_RING_LEN
);
137 e1000e_macreg_write(&d
->e1000e
, E1000_TDT
, 0);
138 e1000e_macreg_write(&d
->e1000e
, E1000_TDH
, 0);
140 /* Enable transmit */
141 e1000e_macreg_write(&d
->e1000e
, E1000_TCTL
, E1000_TCTL_EN
);
143 e1000e_macreg_write(&d
->e1000e
, E1000_RDBAL
,
144 (uint32_t)d
->e1000e
.rx_ring
);
145 e1000e_macreg_write(&d
->e1000e
, E1000_RDBAH
,
146 (uint32_t)(d
->e1000e
.rx_ring
>> 32));
147 e1000e_macreg_write(&d
->e1000e
, E1000_RDLEN
, E1000E_RING_LEN
);
148 e1000e_macreg_write(&d
->e1000e
, E1000_RDT
, 0);
149 e1000e_macreg_write(&d
->e1000e
, E1000_RDH
, 0);
152 e1000e_macreg_write(&d
->e1000e
, E1000_RFCTL
, E1000_RFCTL_EXTEN
);
153 e1000e_macreg_write(&d
->e1000e
, E1000_RCTL
, E1000_RCTL_EN
|
157 /* Enable all interrupts */
158 e1000e_macreg_write(&d
->e1000e
, E1000_IMS
, 0xFFFFFFFF);
162 static void *e1000e_pci_get_driver(void *obj
, const char *interface
)
164 QE1000E_PCI
*epci
= obj
;
165 if (!g_strcmp0(interface
, "e1000e-if")) {
166 return &epci
->e1000e
;
169 /* implicit contains */
170 if (!g_strcmp0(interface
, "pci-device")) {
171 return &epci
->pci_dev
;
174 fprintf(stderr
, "%s not present in e1000e\n", interface
);
175 g_assert_not_reached();
178 static void *e1000e_pci_create(void *pci_bus
, QGuestAllocator
*alloc
,
181 QE1000E_PCI
*d
= g_new0(QE1000E_PCI
, 1);
182 QPCIBus
*bus
= pci_bus
;
183 QPCIAddress
*address
= addr
;
185 qpci_device_foreach(bus
, address
->vendor_id
, address
->device_id
,
186 e1000e_foreach_callback
, &d
->pci_dev
);
188 /* Map BAR0 (mac registers) */
189 d
->mac_regs
= qpci_iomap(&d
->pci_dev
, 0, NULL
);
191 /* Allocate and setup TX ring */
192 d
->e1000e
.tx_ring
= guest_alloc(alloc
, E1000E_RING_LEN
);
193 g_assert(d
->e1000e
.tx_ring
!= 0);
195 /* Allocate and setup RX ring */
196 d
->e1000e
.rx_ring
= guest_alloc(alloc
, E1000E_RING_LEN
);
197 g_assert(d
->e1000e
.rx_ring
!= 0);
199 d
->obj
.get_driver
= e1000e_pci_get_driver
;
200 d
->obj
.start_hw
= e1000e_pci_start_hw
;
201 d
->obj
.destructor
= e1000e_pci_destructor
;
206 static void e1000e_register_nodes(void)
209 .vendor_id
= PCI_VENDOR_ID_INTEL
,
210 .device_id
= E1000_DEV_ID_82574L
,
214 * FIXME: every test using this node needs to setup a -netdev socket,id=hs0
215 * otherwise QEMU is not going to start
217 QOSGraphEdgeOptions opts
= {
218 .extra_device_opts
= "netdev=hs0",
220 add_qpci_address(&opts
, &addr
);
222 qos_node_create_driver("e1000e", e1000e_pci_create
);
223 qos_node_consumes("e1000e", "pci-bus", &opts
);
226 libqos_init(e1000e_register_nodes
);