diff mbox series

[v2,11/13] tests/qtest/libqos/igb: Transform to igb tests

Message ID 20230114041004.36459-12-akihiko.odaki@daynix.com
State New
Headers show
Series Introduce igb | expand

Commit Message

Akihiko Odaki Jan. 14, 2023, 4:10 a.m. UTC
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 tests/qtest/fuzz/generic_fuzz_configs.h |   5 +
 tests/qtest/igb-test.c                  |  67 ++++++------
 tests/qtest/libqos/igb.c                | 139 +++++++++---------------
 tests/qtest/libqos/meson.build          |   1 +
 tests/qtest/meson.build                 |   1 +
 5 files changed, 90 insertions(+), 123 deletions(-)
diff mbox series

Patch

diff --git a/tests/qtest/fuzz/generic_fuzz_configs.h b/tests/qtest/fuzz/generic_fuzz_configs.h
index a825b78c14..50689da653 100644
--- a/tests/qtest/fuzz/generic_fuzz_configs.h
+++ b/tests/qtest/fuzz/generic_fuzz_configs.h
@@ -90,6 +90,11 @@  const generic_fuzz_config predefined_configs[] = {
         .args = "-M q35 -nodefaults "
         "-device e1000e,netdev=net0 -netdev user,id=net0",
         .objects = "e1000e",
+    },{
+        .name = "igb",
+        .args = "-M q35 -nodefaults "
+        "-device igb,netdev=net0 -netdev user,id=net0",
+        .objects = "igb",
     },{
         .name = "cirrus-vga",
         .args = "-machine q35 -nodefaults -device cirrus-vga",
diff --git a/tests/qtest/igb-test.c b/tests/qtest/igb-test.c
index 98706355e3..17d408f02a 100644
--- a/tests/qtest/igb-test.c
+++ b/tests/qtest/igb-test.c
@@ -1,10 +1,12 @@ 
 /*
- * QTest testcase for e1000e NIC
+ * QTest testcase for igb NIC
  *
+ * Copyright (c) 2022-2023 Red Hat, Inc.
  * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
  * Developed by Daynix Computing LTD (http://www.daynix.com)
  *
  * Authors:
+ * Akihiko Odaki <akihiko.odaki@daynix.com>
  * Dmitry Fleytman <dmitry@daynix.com>
  * Leonid Bloch <leonid@daynix.com>
  * Yan Vugenfirer <yan@daynix.com>
@@ -34,16 +36,16 @@ 
 #include "qemu/bitops.h"
 #include "libqos/libqos-malloc.h"
 #include "libqos/e1000e.h"
-#include "hw/net/e1000_regs.h"
+#include "hw/net/igb_regs.h"
 
 static const struct eth_header test = {
     .h_dest = E1000E_ADDRESS,
     .h_source = E1000E_ADDRESS,
 };
 
-static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc)
+static void igb_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc)
 {
-    struct e1000_tx_desc descr;
+    union e1000_adv_tx_desc descr;
     char buffer[64];
     int ret;
     uint32_t recv_len;
@@ -54,12 +56,11 @@  static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *a
 
     /* Prepare TX descriptor */
     memset(&descr, 0, sizeof(descr));
-    descr.buffer_addr = cpu_to_le64(data);
-    descr.lower.data = cpu_to_le32(E1000_TXD_CMD_RS   |
-                                   E1000_TXD_CMD_EOP  |
-                                   E1000_TXD_CMD_DEXT |
-                                   E1000_TXD_DTYP_D   |
-                                   sizeof(buffer));
+    descr.read.buffer_addr = cpu_to_le64(data);
+    descr.read.cmd_type_len = cpu_to_le32(E1000_TXD_CMD_RS   |
+                                          E1000_TXD_CMD_EOP  |
+                                          E1000_TXD_DTYP_D   |
+                                          sizeof(buffer));
 
     /* Put descriptor to the ring */
     e1000e_tx_ring_push(d, &descr);
@@ -68,7 +69,7 @@  static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *a
     e1000e_wait_isr(d, E1000E_TX0_MSG_ID);
 
     /* Check DD bit */
-    g_assert_cmphex(le32_to_cpu(descr.upper.data) & E1000_TXD_STAT_DD, ==,
+    g_assert_cmphex(le32_to_cpu(descr.wb.status) & E1000_TXD_STAT_DD, ==,
                     E1000_TXD_STAT_DD);
 
     /* Check data sent to the backend */
@@ -82,9 +83,9 @@  static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *a
     guest_free(alloc, data);
 }
 
-static void e1000e_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc)
+static void igb_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc)
 {
-    union e1000_rx_desc_extended descr;
+    union e1000_adv_rx_desc descr;
 
     struct eth_header test_iov = test;
     int len = htonl(sizeof(test));
@@ -110,7 +111,7 @@  static void e1000e_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator
 
     /* Prepare RX descriptor */
     memset(&descr, 0, sizeof(descr));
-    descr.read.buffer_addr = cpu_to_le64(data);
+    descr.read.pkt_addr = cpu_to_le64(data);
 
     /* Put descriptor to the ring */
     e1000e_rx_ring_push(d, &descr);
@@ -135,7 +136,7 @@  static void test_e1000e_init(void *obj, void *data, QGuestAllocator * alloc)
     /* init does nothing */
 }
 
-static void test_e1000e_tx(void *obj, void *data, QGuestAllocator * alloc)
+static void test_igb_tx(void *obj, void *data, QGuestAllocator * alloc)
 {
     QE1000E_PCI *e1000e = obj;
     QE1000E *d = &e1000e->e1000e;
@@ -147,10 +148,10 @@  static void test_e1000e_tx(void *obj, void *data, QGuestAllocator * alloc)
         return;
     }
 
-    e1000e_send_verify(d, data, alloc);
+    igb_send_verify(d, data, alloc);
 }
 
-static void test_e1000e_rx(void *obj, void *data, QGuestAllocator * alloc)
+static void test_igb_rx(void *obj, void *data, QGuestAllocator * alloc)
 {
     QE1000E_PCI *e1000e = obj;
     QE1000E *d = &e1000e->e1000e;
@@ -162,11 +163,11 @@  static void test_e1000e_rx(void *obj, void *data, QGuestAllocator * alloc)
         return;
     }
 
-    e1000e_receive_verify(d, data, alloc);
+    igb_receive_verify(d, data, alloc);
 }
 
-static void test_e1000e_multiple_transfers(void *obj, void *data,
-                                           QGuestAllocator *alloc)
+static void test_igb_multiple_transfers(void *obj, void *data,
+                                        QGuestAllocator *alloc)
 {
     static const long iterations = 4 * 1024;
     long i;
@@ -182,13 +183,13 @@  static void test_e1000e_multiple_transfers(void *obj, void *data,
     }
 
     for (i = 0; i < iterations; i++) {
-        e1000e_send_verify(d, data, alloc);
-        e1000e_receive_verify(d, data, alloc);
+        igb_send_verify(d, data, alloc);
+        igb_receive_verify(d, data, alloc);
     }
 
 }
 
-static void test_e1000e_hotplug(void *obj, void *data, QGuestAllocator * alloc)
+static void test_igb_hotplug(void *obj, void *data, QGuestAllocator * alloc)
 {
     QTestState *qts = global_qtest;  /* TODO: get rid of global_qtest here */
     QE1000E_PCI *dev = obj;
@@ -198,8 +199,8 @@  static void test_e1000e_hotplug(void *obj, void *data, QGuestAllocator * alloc)
         return;
     }
 
-    qtest_qmp_device_add(qts, "e1000e", "e1000e_net", "{'addr': '0x06'}");
-    qpci_unplug_acpi_device_test(qts, "e1000e_net", 0x06);
+    qtest_qmp_device_add(qts, "igb", "igb_net", "{'addr': '0x06'}");
+    qpci_unplug_acpi_device_test(qts, "igb_net", 0x06);
 }
 
 static void data_test_clear(void *sockets)
@@ -225,18 +226,18 @@  static void *data_test_init(GString *cmd_line, void *arg)
     return test_sockets;
 }
 
-static void register_e1000e_test(void)
+static void register_igb_test(void)
 {
     QOSGraphTestOptions opts = {
         .before = data_test_init,
     };
 
-    qos_add_test("init", "e1000e", test_e1000e_init, &opts);
-    qos_add_test("tx", "e1000e", test_e1000e_tx, &opts);
-    qos_add_test("rx", "e1000e", test_e1000e_rx, &opts);
-    qos_add_test("multiple_transfers", "e1000e",
-                      test_e1000e_multiple_transfers, &opts);
-    qos_add_test("hotplug", "e1000e", test_e1000e_hotplug, &opts);
+    qos_add_test("init", "igb", test_e1000e_init, &opts);
+    qos_add_test("tx", "igb", test_igb_tx, &opts);
+    qos_add_test("rx", "igb", test_igb_rx, &opts);
+    qos_add_test("multiple_transfers", "igb",
+                 test_igb_multiple_transfers, &opts);
+    qos_add_test("hotplug", "igb", test_igb_hotplug, &opts);
 }
 
-libqos_init(register_e1000e_test);
+libqos_init(register_igb_test);
diff --git a/tests/qtest/libqos/igb.c b/tests/qtest/libqos/igb.c
index 925654c7fd..12fb531bf0 100644
--- a/tests/qtest/libqos/igb.c
+++ b/tests/qtest/libqos/igb.c
@@ -1,6 +1,7 @@ 
 /*
  * libqos driver framework
  *
+ * Copyright (c) 2022-2023 Red Hat, Inc.
  * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
  *
  * This library is free software; you can redistribute it and/or
@@ -17,7 +18,8 @@ 
  */
 
 #include "qemu/osdep.h"
-#include "hw/net/e1000_regs.h"
+#include "hw/net/igb_regs.h"
+#include "hw/net/mii.h"
 #include "hw/pci/pci_ids.h"
 #include "../libqtest.h"
 #include "pci-pc.h"
@@ -29,47 +31,12 @@ 
 #include "qgraph.h"
 #include "e1000e.h"
 
-#define E1000E_IVAR_TEST_CFG \
-    (((E1000E_RX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << E1000_IVAR_RXQ0_SHIFT) | \
-     ((E1000E_TX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << E1000_IVAR_TXQ0_SHIFT) | \
-     E1000_IVAR_TX_INT_EVERY_WB)
+#define IGB_IVAR_TEST_CFG \
+    ((E1000E_RX0_MSG_ID | E1000_IVAR_VALID) << (igb_ivar_entry_rx(0) * 8)   | \
+     ((E1000E_TX0_MSG_ID | E1000_IVAR_VALID) << (igb_ivar_entry_tx(0) * 8)))
 
 #define E1000E_RING_LEN (0x1000)
 
-void e1000e_tx_ring_push(QE1000E *d, void *descr)
-{
-    QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e);
-    uint32_t tail = e1000e_macreg_read(d, E1000_TDT);
-    uint32_t len = e1000e_macreg_read(d, E1000_TDLEN) / E1000_RING_DESC_LEN;
-
-    qtest_memwrite(d_pci->pci_dev.bus->qts,
-                   d->tx_ring + tail * E1000_RING_DESC_LEN,
-                   descr, E1000_RING_DESC_LEN);
-    e1000e_macreg_write(d, E1000_TDT, (tail + 1) % len);
-
-    /* Read WB data for the packet transmitted */
-    qtest_memread(d_pci->pci_dev.bus->qts,
-                  d->tx_ring + tail * E1000_RING_DESC_LEN,
-                  descr, E1000_RING_DESC_LEN);
-}
-
-void e1000e_rx_ring_push(QE1000E *d, void *descr)
-{
-    QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e);
-    uint32_t tail = e1000e_macreg_read(d, E1000_RDT);
-    uint32_t len = e1000e_macreg_read(d, E1000_RDLEN) / E1000_RING_DESC_LEN;
-
-    qtest_memwrite(d_pci->pci_dev.bus->qts,
-                   d->rx_ring + tail * E1000_RING_DESC_LEN,
-                   descr, E1000_RING_DESC_LEN);
-    e1000e_macreg_write(d, E1000_RDT, (tail + 1) % len);
-
-    /* Read WB data for the packet received */
-    qtest_memread(d_pci->pci_dev.bus->qts,
-                  d->rx_ring + tail * E1000_RING_DESC_LEN,
-                  descr, E1000_RING_DESC_LEN);
-}
-
 static void e1000e_foreach_callback(QPCIDevice *dev, int devfn, void *data)
 {
     QPCIDevice *res = data;
@@ -77,21 +44,6 @@  static void e1000e_foreach_callback(QPCIDevice *dev, int devfn, void *data)
     g_free(dev);
 }
 
-void e1000e_wait_isr(QE1000E *d, uint16_t msg_id)
-{
-    QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e);
-    guint64 end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
-
-    do {
-        if (qpci_msix_pending(&d_pci->pci_dev, msg_id)) {
-            return;
-        }
-        qtest_clock_step(d_pci->pci_dev.bus->qts, 10000);
-    } while (g_get_monotonic_time() < end_time);
-
-    g_error("Timeout expired");
-}
-
 static void e1000e_pci_destructor(QOSGraphObject *obj)
 {
     QE1000E_PCI *epci = (QE1000E_PCI *) obj;
@@ -99,8 +51,9 @@  static void e1000e_pci_destructor(QOSGraphObject *obj)
     qpci_msix_disable(&epci->pci_dev);
 }
 
-static void e1000e_pci_start_hw(QOSGraphObject *obj)
+static void igb_pci_start_hw(QOSGraphObject *obj)
 {
+    static const uint8_t address[] = E1000E_ADDRESS;
     QE1000E_PCI *d = (QE1000E_PCI *) obj;
     uint32_t val;
 
@@ -111,58 +64,65 @@  static void e1000e_pci_start_hw(QOSGraphObject *obj)
     val = e1000e_macreg_read(&d->e1000e, E1000_CTRL);
     e1000e_macreg_write(&d->e1000e, E1000_CTRL, val | E1000_CTRL_RST | E1000_CTRL_SLU);
 
+    /* Setup link */
+    e1000e_macreg_write(&d->e1000e, E1000_MDIC,
+                        MII_BMCR_AUTOEN | MII_BMCR_ANRESTART |
+                        (MII_BMCR << E1000_MDIC_REG_SHIFT) |
+                        (1 << E1000_MDIC_PHY_SHIFT) |
+                        E1000_MDIC_OP_WRITE);
+
+    qtest_clock_step(d->pci_dev.bus->qts, 900000000);
+
     /* Enable and configure MSI-X */
     qpci_msix_enable(&d->pci_dev);
-    e1000e_macreg_write(&d->e1000e, E1000_IVAR, E1000E_IVAR_TEST_CFG);
+    e1000e_macreg_write(&d->e1000e, E1000_IVAR0, IGB_IVAR_TEST_CFG);
 
-    /* Check the device status - link and speed */
+    /* Check the device link status */
     val = e1000e_macreg_read(&d->e1000e, E1000_STATUS);
-    g_assert_cmphex(val & (E1000_STATUS_LU | E1000_STATUS_ASDV_1000),
-        ==, E1000_STATUS_LU | E1000_STATUS_ASDV_1000);
+    g_assert_cmphex(val & E1000_STATUS_LU, ==, E1000_STATUS_LU);
 
     /* Initialize TX/RX logic */
     e1000e_macreg_write(&d->e1000e, E1000_RCTL, 0);
     e1000e_macreg_write(&d->e1000e, E1000_TCTL, 0);
 
-    /* Notify the device that the driver is ready */
-    val = e1000e_macreg_read(&d->e1000e, E1000_CTRL_EXT);
-    e1000e_macreg_write(&d->e1000e, E1000_CTRL_EXT,
-        val | E1000_CTRL_EXT_DRV_LOAD);
-
-    e1000e_macreg_write(&d->e1000e, E1000_TDBAL,
+    e1000e_macreg_write(&d->e1000e, E1000_TDBAL(0),
                            (uint32_t) d->e1000e.tx_ring);
-    e1000e_macreg_write(&d->e1000e, E1000_TDBAH,
+    e1000e_macreg_write(&d->e1000e, E1000_TDBAH(0),
                            (uint32_t) (d->e1000e.tx_ring >> 32));
-    e1000e_macreg_write(&d->e1000e, E1000_TDLEN, E1000E_RING_LEN);
-    e1000e_macreg_write(&d->e1000e, E1000_TDT, 0);
-    e1000e_macreg_write(&d->e1000e, E1000_TDH, 0);
+    e1000e_macreg_write(&d->e1000e, E1000_TDLEN(0), E1000E_RING_LEN);
+    e1000e_macreg_write(&d->e1000e, E1000_TDT(0), 0);
+    e1000e_macreg_write(&d->e1000e, E1000_TDH(0), 0);
 
     /* Enable transmit */
     e1000e_macreg_write(&d->e1000e, E1000_TCTL, E1000_TCTL_EN);
 
-    e1000e_macreg_write(&d->e1000e, E1000_RDBAL,
+    e1000e_macreg_write(&d->e1000e, E1000_RDBAL(0),
                            (uint32_t)d->e1000e.rx_ring);
-    e1000e_macreg_write(&d->e1000e, E1000_RDBAH,
+    e1000e_macreg_write(&d->e1000e, E1000_RDBAH(0),
                            (uint32_t)(d->e1000e.rx_ring >> 32));
-    e1000e_macreg_write(&d->e1000e, E1000_RDLEN, E1000E_RING_LEN);
-    e1000e_macreg_write(&d->e1000e, E1000_RDT, 0);
-    e1000e_macreg_write(&d->e1000e, E1000_RDH, 0);
+    e1000e_macreg_write(&d->e1000e, E1000_RDLEN(0), E1000E_RING_LEN);
+    e1000e_macreg_write(&d->e1000e, E1000_RDT(0), 0);
+    e1000e_macreg_write(&d->e1000e, E1000_RDH(0), 0);
+    e1000e_macreg_write(&d->e1000e, E1000_RA,
+                        le32_to_cpu(*(uint32_t *)address));
+    e1000e_macreg_write(&d->e1000e, E1000_RA + 4,
+                        E1000_RAH_AV | E1000_RAH_POOL_1 |
+                        le16_to_cpu(*(uint16_t *)(address + 4)));
 
     /* Enable receive */
     e1000e_macreg_write(&d->e1000e, E1000_RFCTL, E1000_RFCTL_EXTEN);
-    e1000e_macreg_write(&d->e1000e, E1000_RCTL, E1000_RCTL_EN  |
-                                        E1000_RCTL_UPE |
-                                        E1000_RCTL_MPE);
+    e1000e_macreg_write(&d->e1000e, E1000_RCTL, E1000_RCTL_EN);
 
     /* Enable all interrupts */
-    e1000e_macreg_write(&d->e1000e, E1000_IMS, 0xFFFFFFFF);
+    e1000e_macreg_write(&d->e1000e, E1000_IMS,  0xFFFFFFFF);
+    e1000e_macreg_write(&d->e1000e, E1000_EIMS, 0xFFFFFFFF);
 
 }
 
-static void *e1000e_pci_get_driver(void *obj, const char *interface)
+static void *igb_pci_get_driver(void *obj, const char *interface)
 {
     QE1000E_PCI *epci = obj;
-    if (!g_strcmp0(interface, "e1000e-if")) {
+    if (!g_strcmp0(interface, "igb-if")) {
         return &epci->e1000e;
     }
 
@@ -171,12 +131,11 @@  static void *e1000e_pci_get_driver(void *obj, const char *interface)
         return &epci->pci_dev;
     }
 
-    fprintf(stderr, "%s not present in e1000e\n", interface);
+    fprintf(stderr, "%s not present in igb\n", interface);
     g_assert_not_reached();
 }
 
-static void *e1000e_pci_create(void *pci_bus, QGuestAllocator *alloc,
-                               void *addr)
+static void *igb_pci_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
 {
     QE1000E_PCI *d = g_new0(QE1000E_PCI, 1);
     QPCIBus *bus = pci_bus;
@@ -196,18 +155,18 @@  static void *e1000e_pci_create(void *pci_bus, QGuestAllocator *alloc,
     d->e1000e.rx_ring = guest_alloc(alloc, E1000E_RING_LEN);
     g_assert(d->e1000e.rx_ring != 0);
 
-    d->obj.get_driver = e1000e_pci_get_driver;
-    d->obj.start_hw = e1000e_pci_start_hw;
+    d->obj.get_driver = igb_pci_get_driver;
+    d->obj.start_hw = igb_pci_start_hw;
     d->obj.destructor = e1000e_pci_destructor;
 
     return &d->obj;
 }
 
-static void e1000e_register_nodes(void)
+static void igb_register_nodes(void)
 {
     QPCIAddress addr = {
         .vendor_id = PCI_VENDOR_ID_INTEL,
-        .device_id = E1000_DEV_ID_82574L,
+        .device_id = E1000_DEV_ID_82576,
     };
 
     /*
@@ -219,8 +178,8 @@  static void e1000e_register_nodes(void)
     };
     add_qpci_address(&opts, &addr);
 
-    qos_node_create_driver("e1000e", e1000e_pci_create);
-    qos_node_consumes("e1000e", "pci-bus", &opts);
+    qos_node_create_driver("igb", igb_pci_create);
+    qos_node_consumes("igb", "pci-bus", &opts);
 }
 
-libqos_init(e1000e_register_nodes);
+libqos_init(igb_register_nodes);
diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
index 32f028872c..cc209a8de5 100644
--- a/tests/qtest/libqos/meson.build
+++ b/tests/qtest/libqos/meson.build
@@ -30,6 +30,7 @@  libqos_srcs = files(
         'i2c.c',
         'i2c-imx.c',
         'i2c-omap.c',
+        'igb.c',
         'sdhci.c',
         'tpci200.c',
         'virtio.c',
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index f0ebb5fac6..10279ed3bf 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -256,6 +256,7 @@  qos_test_ss.add(
   'virtio-serial-test.c',
   'virtio-iommu-test.c',
   'vmxnet3-test.c',
+  'igb-test.c',
 )
 if config_host.has_key('CONFIG_POSIX')
   qos_test_ss.add(files('e1000e-test.c'))