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