1 /* 2 * QTest testcase for e1000e NIC 3 * 4 * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) 5 * Developed by Daynix Computing LTD (http://www.daynix.com) 6 * 7 * Authors: 8 * Dmitry Fleytman <dmitry@daynix.com> 9 * Leonid Bloch <leonid@daynix.com> 10 * Yan Vugenfirer <yan@daynix.com> 11 * 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. 16 * 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. 21 * 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/>. 24 */ 25 26 27 #include "qemu/osdep.h" 28 #include "libqtest-single.h" 29 #include "libqos/pci-pc.h" 30 #include "qemu/sockets.h" 31 #include "qemu/iov.h" 32 #include "qemu/module.h" 33 #include "qemu/bitops.h" 34 #include "libqos/libqos-malloc.h" 35 #include "libqos/e1000e.h" 36 37 static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc) 38 { 39 struct { 40 uint64_t buffer_addr; 41 union { 42 uint32_t data; 43 struct { 44 uint16_t length; 45 uint8_t cso; 46 uint8_t cmd; 47 } flags; 48 } lower; 49 union { 50 uint32_t data; 51 struct { 52 uint8_t status; 53 uint8_t css; 54 uint16_t special; 55 } fields; 56 } upper; 57 } descr; 58 59 static const uint32_t dtyp_data = BIT(20); 60 static const uint32_t dtyp_ext = BIT(29); 61 static const uint32_t dcmd_rs = BIT(27); 62 static const uint32_t dcmd_eop = BIT(24); 63 static const uint32_t dsta_dd = BIT(0); 64 static const int data_len = 64; 65 char buffer[64]; 66 int ret; 67 uint32_t recv_len; 68 69 /* Prepare test data buffer */ 70 uint64_t data = guest_alloc(alloc, data_len); 71 memwrite(data, "TEST", 5); 72 73 /* Prepare TX descriptor */ 74 memset(&descr, 0, sizeof(descr)); 75 descr.buffer_addr = cpu_to_le64(data); 76 descr.lower.data = cpu_to_le32(dcmd_rs | 77 dcmd_eop | 78 dtyp_ext | 79 dtyp_data | 80 data_len); 81 82 /* Put descriptor to the ring */ 83 e1000e_tx_ring_push(d, &descr); 84 85 /* Wait for TX WB interrupt */ 86 e1000e_wait_isr(d, E1000E_TX0_MSG_ID); 87 88 /* Check DD bit */ 89 g_assert_cmphex(le32_to_cpu(descr.upper.data) & dsta_dd, ==, dsta_dd); 90 91 /* Check data sent to the backend */ 92 ret = recv(test_sockets[0], &recv_len, sizeof(recv_len), 0); 93 g_assert_cmpint(ret, == , sizeof(recv_len)); 94 ret = recv(test_sockets[0], buffer, 64, 0); 95 g_assert_cmpint(ret, >=, 5); 96 g_assert_cmpstr(buffer, == , "TEST"); 97 98 /* Free test data buffer */ 99 guest_free(alloc, data); 100 } 101 102 static void e1000e_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc) 103 { 104 union { 105 struct { 106 uint64_t buffer_addr; 107 uint64_t reserved; 108 } read; 109 struct { 110 struct { 111 uint32_t mrq; 112 union { 113 uint32_t rss; 114 struct { 115 uint16_t ip_id; 116 uint16_t csum; 117 } csum_ip; 118 } hi_dword; 119 } lower; 120 struct { 121 uint32_t status_error; 122 uint16_t length; 123 uint16_t vlan; 124 } upper; 125 } wb; 126 } descr; 127 128 static const uint32_t esta_dd = BIT(0); 129 130 char test[] = "TEST"; 131 int len = htonl(sizeof(test)); 132 struct iovec iov[] = { 133 { 134 .iov_base = &len, 135 .iov_len = sizeof(len), 136 },{ 137 .iov_base = test, 138 .iov_len = sizeof(test), 139 }, 140 }; 141 142 static const int data_len = 64; 143 char buffer[64]; 144 int ret; 145 146 /* Send a dummy packet to device's socket*/ 147 ret = iov_send(test_sockets[0], iov, 2, 0, sizeof(len) + sizeof(test)); 148 g_assert_cmpint(ret, == , sizeof(test) + sizeof(len)); 149 150 /* Prepare test data buffer */ 151 uint64_t data = guest_alloc(alloc, data_len); 152 153 /* Prepare RX descriptor */ 154 memset(&descr, 0, sizeof(descr)); 155 descr.read.buffer_addr = cpu_to_le64(data); 156 157 /* Put descriptor to the ring */ 158 e1000e_rx_ring_push(d, &descr); 159 160 /* Wait for TX WB interrupt */ 161 e1000e_wait_isr(d, E1000E_RX0_MSG_ID); 162 163 /* Check DD bit */ 164 g_assert_cmphex(le32_to_cpu(descr.wb.upper.status_error) & 165 esta_dd, ==, esta_dd); 166 167 /* Check data sent to the backend */ 168 memread(data, buffer, sizeof(buffer)); 169 g_assert_cmpstr(buffer, == , "TEST"); 170 171 /* Free test data buffer */ 172 guest_free(alloc, data); 173 } 174 175 static void test_e1000e_init(void *obj, void *data, QGuestAllocator * alloc) 176 { 177 /* init does nothing */ 178 } 179 180 static void test_e1000e_tx(void *obj, void *data, QGuestAllocator * alloc) 181 { 182 QE1000E_PCI *e1000e = obj; 183 QE1000E *d = &e1000e->e1000e; 184 QOSGraphObject *e_object = obj; 185 QPCIDevice *dev = e_object->get_driver(e_object, "pci-device"); 186 187 /* FIXME: add spapr support */ 188 if (qpci_check_buggy_msi(dev)) { 189 return; 190 } 191 192 e1000e_send_verify(d, data, alloc); 193 } 194 195 static void test_e1000e_rx(void *obj, void *data, QGuestAllocator * alloc) 196 { 197 QE1000E_PCI *e1000e = obj; 198 QE1000E *d = &e1000e->e1000e; 199 QOSGraphObject *e_object = obj; 200 QPCIDevice *dev = e_object->get_driver(e_object, "pci-device"); 201 202 /* FIXME: add spapr support */ 203 if (qpci_check_buggy_msi(dev)) { 204 return; 205 } 206 207 e1000e_receive_verify(d, data, alloc); 208 } 209 210 static void test_e1000e_multiple_transfers(void *obj, void *data, 211 QGuestAllocator *alloc) 212 { 213 static const long iterations = 4 * 1024; 214 long i; 215 216 QE1000E_PCI *e1000e = obj; 217 QE1000E *d = &e1000e->e1000e; 218 QOSGraphObject *e_object = obj; 219 QPCIDevice *dev = e_object->get_driver(e_object, "pci-device"); 220 221 /* FIXME: add spapr support */ 222 if (qpci_check_buggy_msi(dev)) { 223 return; 224 } 225 226 for (i = 0; i < iterations; i++) { 227 e1000e_send_verify(d, data, alloc); 228 e1000e_receive_verify(d, data, alloc); 229 } 230 231 } 232 233 static void test_e1000e_hotplug(void *obj, void *data, QGuestAllocator * alloc) 234 { 235 QTestState *qts = global_qtest; /* TODO: get rid of global_qtest here */ 236 QE1000E_PCI *dev = obj; 237 238 if (dev->pci_dev.bus->not_hotpluggable) { 239 g_test_skip("pci bus does not support hotplug"); 240 return; 241 } 242 243 qtest_qmp_device_add(qts, "e1000e", "e1000e_net", "{'addr': '0x06'}"); 244 qpci_unplug_acpi_device_test(qts, "e1000e_net", 0x06); 245 } 246 247 static void data_test_clear(void *sockets) 248 { 249 int *test_sockets = sockets; 250 251 close(test_sockets[0]); 252 qos_invalidate_command_line(); 253 close(test_sockets[1]); 254 g_free(test_sockets); 255 } 256 257 static void *data_test_init(GString *cmd_line, void *arg) 258 { 259 int *test_sockets = g_new(int, 2); 260 int ret = socketpair(PF_UNIX, SOCK_STREAM, 0, test_sockets); 261 g_assert_cmpint(ret, != , -1); 262 263 g_string_append_printf(cmd_line, " -netdev socket,fd=%d,id=hs0 ", 264 test_sockets[1]); 265 266 g_test_queue_destroy(data_test_clear, test_sockets); 267 return test_sockets; 268 } 269 270 static void register_e1000e_test(void) 271 { 272 QOSGraphTestOptions opts = { 273 .before = data_test_init, 274 }; 275 276 qos_add_test("init", "e1000e", test_e1000e_init, &opts); 277 qos_add_test("tx", "e1000e", test_e1000e_tx, &opts); 278 qos_add_test("rx", "e1000e", test_e1000e_rx, &opts); 279 qos_add_test("multiple_transfers", "e1000e", 280 test_e1000e_multiple_transfers, &opts); 281 qos_add_test("hotplug", "e1000e", test_e1000e_hotplug, &opts); 282 } 283 284 libqos_init(register_e1000e_test); 285