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