2 * QTest testcase for e1000e NIC
4 * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
5 * Developed by Daynix Computing LTD (http://www.daynix.com)
8 * Dmitry Fleytman <dmitry@daynix.com>
9 * Leonid Bloch <leonid@daynix.com>
10 * Yan Vugenfirer <yan@daynix.com>
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
27 #include "qemu/osdep.h"
28 #include "libqtest-single.h"
29 #include "libqos/pci-pc.h"
31 #include "qemu/sockets.h"
33 #include "qemu/module.h"
34 #include "qemu/bitops.h"
35 #include "libqos/libqos-malloc.h"
36 #include "libqos/e1000e.h"
37 #include "hw/net/e1000_regs.h"
39 static const struct eth_header packet
= {
40 .h_dest
= E1000E_ADDRESS
,
41 .h_source
= E1000E_ADDRESS
,
44 static void e1000e_send_verify(QE1000E
*d
, int *test_sockets
, QGuestAllocator
*alloc
)
46 struct e1000_tx_desc descr
;
51 /* Prepare test data buffer */
52 uint64_t data
= guest_alloc(alloc
, sizeof(buffer
));
53 memwrite(data
, &packet
, sizeof(packet
));
55 /* Prepare TX descriptor */
56 memset(&descr
, 0, sizeof(descr
));
57 descr
.buffer_addr
= cpu_to_le64(data
);
58 descr
.lower
.data
= cpu_to_le32(E1000_TXD_CMD_RS
|
64 /* Put descriptor to the ring */
65 e1000e_tx_ring_push(d
, &descr
);
67 /* Wait for TX WB interrupt */
68 e1000e_wait_isr(d
, E1000E_TX0_MSG_ID
);
71 g_assert_cmphex(le32_to_cpu(descr
.upper
.data
) & E1000_TXD_STAT_DD
, ==,
74 /* Check data sent to the backend */
75 ret
= recv(test_sockets
[0], &recv_len
, sizeof(recv_len
), 0);
76 g_assert_cmpint(ret
, == , sizeof(recv_len
));
77 ret
= recv(test_sockets
[0], buffer
, sizeof(buffer
), 0);
78 g_assert_cmpint(ret
, ==, sizeof(buffer
));
79 g_assert_false(memcmp(buffer
, &packet
, sizeof(packet
)));
81 /* Free test data buffer */
82 guest_free(alloc
, data
);
85 static void e1000e_receive_verify(QE1000E
*d
, int *test_sockets
, QGuestAllocator
*alloc
)
87 union e1000_rx_desc_extended descr
;
89 struct eth_header test_iov
= packet
;
90 int len
= htonl(sizeof(packet
));
91 struct iovec iov
[] = {
94 .iov_len
= sizeof(len
),
96 .iov_base
= &test_iov
,
97 .iov_len
= sizeof(packet
),
104 /* Send a dummy packet to device's socket*/
105 ret
= iov_send(test_sockets
[0], iov
, 2, 0, sizeof(len
) + sizeof(packet
));
106 g_assert_cmpint(ret
, == , sizeof(packet
) + sizeof(len
));
108 /* Prepare test data buffer */
109 uint64_t data
= guest_alloc(alloc
, sizeof(buffer
));
111 /* Prepare RX descriptor */
112 memset(&descr
, 0, sizeof(descr
));
113 descr
.read
.buffer_addr
= cpu_to_le64(data
);
115 /* Put descriptor to the ring */
116 e1000e_rx_ring_push(d
, &descr
);
118 /* Wait for TX WB interrupt */
119 e1000e_wait_isr(d
, E1000E_RX0_MSG_ID
);
122 g_assert_cmphex(le32_to_cpu(descr
.wb
.upper
.status_error
) &
123 E1000_RXD_STAT_DD
, ==, E1000_RXD_STAT_DD
);
125 /* Check data sent to the backend */
126 memread(data
, buffer
, sizeof(buffer
));
127 g_assert_false(memcmp(buffer
, &packet
, sizeof(packet
)));
129 /* Free test data buffer */
130 guest_free(alloc
, data
);
133 static void test_e1000e_init(void *obj
, void *data
, QGuestAllocator
* alloc
)
135 /* init does nothing */
138 static void test_e1000e_tx(void *obj
, void *data
, QGuestAllocator
* alloc
)
140 QE1000E_PCI
*e1000e
= obj
;
141 QE1000E
*d
= &e1000e
->e1000e
;
142 QOSGraphObject
*e_object
= obj
;
143 QPCIDevice
*dev
= e_object
->get_driver(e_object
, "pci-device");
145 /* FIXME: add spapr support */
146 if (qpci_check_buggy_msi(dev
)) {
150 e1000e_send_verify(d
, data
, alloc
);
153 static void test_e1000e_rx(void *obj
, void *data
, QGuestAllocator
* alloc
)
155 QE1000E_PCI
*e1000e
= obj
;
156 QE1000E
*d
= &e1000e
->e1000e
;
157 QOSGraphObject
*e_object
= obj
;
158 QPCIDevice
*dev
= e_object
->get_driver(e_object
, "pci-device");
160 /* FIXME: add spapr support */
161 if (qpci_check_buggy_msi(dev
)) {
165 e1000e_receive_verify(d
, data
, alloc
);
168 static void test_e1000e_multiple_transfers(void *obj
, void *data
,
169 QGuestAllocator
*alloc
)
171 static const long iterations
= 4 * 1024;
174 QE1000E_PCI
*e1000e
= obj
;
175 QE1000E
*d
= &e1000e
->e1000e
;
176 QOSGraphObject
*e_object
= obj
;
177 QPCIDevice
*dev
= e_object
->get_driver(e_object
, "pci-device");
179 /* FIXME: add spapr support */
180 if (qpci_check_buggy_msi(dev
)) {
184 for (i
= 0; i
< iterations
; i
++) {
185 e1000e_send_verify(d
, data
, alloc
);
186 e1000e_receive_verify(d
, data
, alloc
);
191 static void test_e1000e_hotplug(void *obj
, void *data
, QGuestAllocator
* alloc
)
193 QTestState
*qts
= global_qtest
; /* TODO: get rid of global_qtest here */
194 QE1000E_PCI
*dev
= obj
;
196 if (dev
->pci_dev
.bus
->not_hotpluggable
) {
197 g_test_skip("pci bus does not support hotplug");
201 qtest_qmp_device_add(qts
, "e1000e", "e1000e_net", "{'addr': '0x06'}");
202 qpci_unplug_acpi_device_test(qts
, "e1000e_net", 0x06);
205 static void data_test_clear(void *sockets
)
207 int *test_sockets
= sockets
;
209 close(test_sockets
[0]);
210 qos_invalidate_command_line();
211 close(test_sockets
[1]);
212 g_free(test_sockets
);
215 static void *data_test_init(GString
*cmd_line
, void *arg
)
217 int *test_sockets
= g_new(int, 2);
218 int ret
= socketpair(PF_UNIX
, SOCK_STREAM
, 0, test_sockets
);
219 g_assert_cmpint(ret
, != , -1);
221 g_string_append_printf(cmd_line
, " -netdev socket,fd=%d,id=hs0 ",
224 g_test_queue_destroy(data_test_clear
, test_sockets
);
228 static void register_e1000e_test(void)
230 QOSGraphTestOptions opts
= {
231 .before
= data_test_init
,
234 qos_add_test("init", "e1000e", test_e1000e_init
, &opts
);
235 qos_add_test("tx", "e1000e", test_e1000e_tx
, &opts
);
236 qos_add_test("rx", "e1000e", test_e1000e_rx
, &opts
);
237 qos_add_test("multiple_transfers", "e1000e",
238 test_e1000e_multiple_transfers
, &opts
);
239 qos_add_test("hotplug", "e1000e", test_e1000e_hotplug
, &opts
);
242 libqos_init(register_e1000e_test
);