/*
 * 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
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>
 */

#include "qemu/osdep.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"
#include "qemu/sockets.h"
#include "qemu/iov.h"
#include "qemu/module.h"
#include "qemu/bitops.h"
#include "libqos-malloc.h"
#include "qgraph.h"
#include "e1000e.h"

#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)

static void e1000e_foreach_callback(QPCIDevice *dev, int devfn, void *data)
{
    QPCIDevice *res = data;
    memcpy(res, dev, sizeof(QPCIDevice));
    g_free(dev);
}

static void e1000e_pci_destructor(QOSGraphObject *obj)
{
    QE1000E_PCI *epci = (QE1000E_PCI *) obj;
    qpci_iounmap(&epci->pci_dev, epci->mac_regs);
    qpci_msix_disable(&epci->pci_dev);
}

static void igb_pci_start_hw(QOSGraphObject *obj)
{
    static const uint8_t address[] = E1000E_ADDRESS;
    QE1000E_PCI *d = (QE1000E_PCI *) obj;
    uint32_t val;

    /* Enable the device */
    qpci_device_enable(&d->pci_dev);

    /* Reset the device */
    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_IVAR0, IGB_IVAR_TEST_CFG);

    /* Check the device link status */
    val = e1000e_macreg_read(&d->e1000e, E1000_STATUS);
    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);

    e1000e_macreg_write(&d->e1000e, E1000_TDBAL(0),
                           (uint32_t) d->e1000e.tx_ring);
    e1000e_macreg_write(&d->e1000e, E1000_TDBAH(0),
                           (uint32_t) (d->e1000e.tx_ring >> 32));
    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(0),
                           (uint32_t)d->e1000e.rx_ring);
    e1000e_macreg_write(&d->e1000e, E1000_RDBAH(0),
                           (uint32_t)(d->e1000e.rx_ring >> 32));
    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);

    /* Enable all interrupts */
    e1000e_macreg_write(&d->e1000e, E1000_IMS,  0xFFFFFFFF);
    e1000e_macreg_write(&d->e1000e, E1000_EIMS, 0xFFFFFFFF);

}

static void *igb_pci_get_driver(void *obj, const char *interface)
{
    QE1000E_PCI *epci = obj;
    if (!g_strcmp0(interface, "igb-if")) {
        return &epci->e1000e;
    }

    /* implicit contains */
    if (!g_strcmp0(interface, "pci-device")) {
        return &epci->pci_dev;
    }

    fprintf(stderr, "%s not present in igb\n", interface);
    g_assert_not_reached();
}

static void *igb_pci_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
{
    QE1000E_PCI *d = g_new0(QE1000E_PCI, 1);
    QPCIBus *bus = pci_bus;
    QPCIAddress *address = addr;

    qpci_device_foreach(bus, address->vendor_id, address->device_id,
                        e1000e_foreach_callback, &d->pci_dev);

    /* Map BAR0 (mac registers) */
    d->mac_regs = qpci_iomap(&d->pci_dev, 0, NULL);

    /* Allocate and setup TX ring */
    d->e1000e.tx_ring = guest_alloc(alloc, E1000E_RING_LEN);
    g_assert(d->e1000e.tx_ring != 0);

    /* Allocate and setup RX ring */
    d->e1000e.rx_ring = guest_alloc(alloc, E1000E_RING_LEN);
    g_assert(d->e1000e.rx_ring != 0);

    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 igb_register_nodes(void)
{
    QPCIAddress addr = {
        .vendor_id = PCI_VENDOR_ID_INTEL,
        .device_id = E1000_DEV_ID_82576,
    };

    /*
     * FIXME: every test using this node needs to setup a -netdev socket,id=hs0
     * otherwise QEMU is not going to start
     */
    QOSGraphEdgeOptions opts = {
        .extra_device_opts = "netdev=hs0",
    };
    add_qpci_address(&opts, &addr);

    qos_node_create_driver("igb", igb_pci_create);
    qos_node_consumes("igb", "pci-bus", &opts);
}

libqos_init(igb_register_nodes);
