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