/*
 * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
 *
 * PAPR Inter-VM Logical Lan, aka ibmveth
 *
 * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

#include "qemu/osdep.h"
#include "cpu.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "net/net.h"
#include "migration/vmstate.h"
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_vio.h"
#include "hw/qdev-properties.h"
#include "sysemu/sysemu.h"
#include "trace.h"

#include <libfdt.h>

#define ETH_ALEN        6
#define MAX_PACKET_SIZE 65536

/* Compatibility flags for migration */
#define SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT  0
#define SPAPRVLAN_FLAG_RX_BUF_POOLS      (1 << SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT)

/*
 * Virtual LAN device
 */

typedef uint64_t vlan_bd_t;

#define VLAN_BD_VALID        0x8000000000000000ULL
#define VLAN_BD_TOGGLE       0x4000000000000000ULL
#define VLAN_BD_NO_CSUM      0x0200000000000000ULL
#define VLAN_BD_CSUM_GOOD    0x0100000000000000ULL
#define VLAN_BD_LEN_MASK     0x00ffffff00000000ULL
#define VLAN_BD_LEN(bd)      (((bd) & VLAN_BD_LEN_MASK) >> 32)
#define VLAN_BD_ADDR_MASK    0x00000000ffffffffULL
#define VLAN_BD_ADDR(bd)     ((bd) & VLAN_BD_ADDR_MASK)

#define VLAN_VALID_BD(addr, len) (VLAN_BD_VALID | \
                                  (((len) << 32) & VLAN_BD_LEN_MASK) |  \
                                  (addr & VLAN_BD_ADDR_MASK))

#define VLAN_RXQC_TOGGLE     0x80
#define VLAN_RXQC_VALID      0x40
#define VLAN_RXQC_NO_CSUM    0x02
#define VLAN_RXQC_CSUM_GOOD  0x01

#define VLAN_RQ_ALIGNMENT    16
#define VLAN_RXQ_BD_OFF      0
#define VLAN_FILTER_BD_OFF   8
#define VLAN_RX_BDS_OFF      16
/*
 * The final 8 bytes of the buffer list is a counter of frames dropped
 * because there was not a buffer in the buffer list capable of holding
 * the frame. We must avoid it, or the operating system will report garbage
 * for this statistic.
 */
#define VLAN_RX_BDS_LEN      (SPAPR_TCE_PAGE_SIZE - VLAN_RX_BDS_OFF - 8)
#define VLAN_MAX_BUFS        (VLAN_RX_BDS_LEN / 8)

#define TYPE_VIO_SPAPR_VLAN_DEVICE "spapr-vlan"
#define VIO_SPAPR_VLAN_DEVICE(obj) \
     OBJECT_CHECK(SpaprVioVlan, (obj), TYPE_VIO_SPAPR_VLAN_DEVICE)

#define RX_POOL_MAX_BDS 4096
#define RX_MAX_POOLS 5

typedef struct {
    int32_t bufsize;
    int32_t count;
    vlan_bd_t bds[RX_POOL_MAX_BDS];
} RxBufPool;

typedef struct SpaprVioVlan {
    SpaprVioDevice sdev;
    NICConf nicconf;
    NICState *nic;
    MACAddr perm_mac;
    bool isopen;
    hwaddr buf_list;
    uint32_t add_buf_ptr, use_buf_ptr, rx_bufs;
    hwaddr rxq_ptr;
    QEMUTimer *rxp_timer;
    uint32_t compat_flags;             /* Compatibility flags for migration */
    RxBufPool *rx_pool[RX_MAX_POOLS];  /* Receive buffer descriptor pools */
} SpaprVioVlan;

static int spapr_vlan_can_receive(NetClientState *nc)
{
    SpaprVioVlan *dev = qemu_get_nic_opaque(nc);

    return (dev->isopen && dev->rx_bufs > 0);
}

/**
 * The last 8 bytes of the receive buffer list page (that has been
 * supplied by the guest with the H_REGISTER_LOGICAL_LAN call) contain
 * a counter for frames that have been dropped because there was no
 * suitable receive buffer available. This function is used to increase
 * this counter by one.
 */
static void spapr_vlan_record_dropped_rx_frame(SpaprVioVlan *dev)
{
    uint64_t cnt;

    cnt = vio_ldq(&dev->sdev, dev->buf_list + 4096 - 8);
    vio_stq(&dev->sdev, dev->buf_list + 4096 - 8, cnt + 1);
}

/**
 * Get buffer descriptor from one of our receive buffer pools
 */
static vlan_bd_t spapr_vlan_get_rx_bd_from_pool(SpaprVioVlan *dev,
                                                size_t size)
{
    vlan_bd_t bd;
    int pool;

    for (pool = 0; pool < RX_MAX_POOLS; pool++) {
        if (dev->rx_pool[pool]->count > 0 &&
            dev->rx_pool[pool]->bufsize >= size + 8) {
            break;
        }
    }
    if (pool == RX_MAX_POOLS) {
        /* Failed to find a suitable buffer */
        return 0;
    }


    trace_spapr_vlan_get_rx_bd_from_pool_found(pool,
                                               dev->rx_pool[pool]->count,
                                               dev->rx_bufs);

    /* Remove the buffer from the pool */
    dev->rx_pool[pool]->count--;
    bd = dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count];
    dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count] = 0;

    return bd;
}

/**
 * Get buffer descriptor from the receive buffer list page that has been
 * supplied by the guest with the H_REGISTER_LOGICAL_LAN call
 */
static vlan_bd_t spapr_vlan_get_rx_bd_from_page(SpaprVioVlan *dev,
                                                size_t size)
{
    int buf_ptr = dev->use_buf_ptr;
    vlan_bd_t bd;

    do {
        buf_ptr += 8;
        if (buf_ptr >= VLAN_RX_BDS_LEN + VLAN_RX_BDS_OFF) {
            buf_ptr = VLAN_RX_BDS_OFF;
        }

        bd = vio_ldq(&dev->sdev, dev->buf_list + buf_ptr);

        trace_spapr_vlan_get_rx_bd_from_page(buf_ptr, (uint64_t)bd);
    } while ((!(bd & VLAN_BD_VALID) || VLAN_BD_LEN(bd) < size + 8)
             && buf_ptr != dev->use_buf_ptr);

    if (!(bd & VLAN_BD_VALID) || VLAN_BD_LEN(bd) < size + 8) {
        /* Failed to find a suitable buffer */
        return 0;
    }

    /* Remove the buffer from the pool */
    dev->use_buf_ptr = buf_ptr;
    vio_stq(&dev->sdev, dev->buf_list + dev->use_buf_ptr, 0);

    trace_spapr_vlan_get_rx_bd_from_page_found(dev->use_buf_ptr, dev->rx_bufs);

    return bd;
}

static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
                                  size_t size)
{
    SpaprVioVlan *dev = qemu_get_nic_opaque(nc);
    SpaprVioDevice *sdev = VIO_SPAPR_DEVICE(dev);
    vlan_bd_t rxq_bd = vio_ldq(sdev, dev->buf_list + VLAN_RXQ_BD_OFF);
    vlan_bd_t bd;
    uint64_t handle;
    uint8_t control;

    trace_spapr_vlan_receive(sdev->qdev.id, dev->rx_bufs);

    if (!dev->isopen) {
        return -1;
    }

    if (!dev->rx_bufs) {
        spapr_vlan_record_dropped_rx_frame(dev);
        return 0;
    }

    if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
        bd = spapr_vlan_get_rx_bd_from_pool(dev, size);
    } else {
        bd = spapr_vlan_get_rx_bd_from_page(dev, size);
    }
    if (!bd) {
        spapr_vlan_record_dropped_rx_frame(dev);
        return 0;
    }

    dev->rx_bufs--;

    /* Transfer the packet data */
    if (spapr_vio_dma_write(sdev, VLAN_BD_ADDR(bd) + 8, buf, size) < 0) {
        return -1;
    }

    trace_spapr_vlan_receive_dma_completed();

    /* Update the receive queue */
    control = VLAN_RXQC_TOGGLE | VLAN_RXQC_VALID;
    if (rxq_bd & VLAN_BD_TOGGLE) {
        control ^= VLAN_RXQC_TOGGLE;
    }

    handle = vio_ldq(sdev, VLAN_BD_ADDR(bd));
    vio_stq(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 8, handle);
    vio_stl(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 4, size);
    vio_sth(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 2, 8);
    vio_stb(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr, control);

    trace_spapr_vlan_receive_wrote(dev->rxq_ptr,
                                   vio_ldq(sdev, VLAN_BD_ADDR(rxq_bd) +
                                                 dev->rxq_ptr),
                                   vio_ldq(sdev, VLAN_BD_ADDR(rxq_bd) +
                                                 dev->rxq_ptr + 8));

    dev->rxq_ptr += 16;
    if (dev->rxq_ptr >= VLAN_BD_LEN(rxq_bd)) {
        dev->rxq_ptr = 0;
        vio_stq(sdev, dev->buf_list + VLAN_RXQ_BD_OFF, rxq_bd ^ VLAN_BD_TOGGLE);
    }

    if (sdev->signal_state & 1) {
        spapr_vio_irq_pulse(sdev);
    }

    return size;
}

static NetClientInfo net_spapr_vlan_info = {
    .type = NET_CLIENT_DRIVER_NIC,
    .size = sizeof(NICState),
    .can_receive = spapr_vlan_can_receive,
    .receive = spapr_vlan_receive,
};

static void spapr_vlan_flush_rx_queue(void *opaque)
{
    SpaprVioVlan *dev = opaque;

    qemu_flush_queued_packets(qemu_get_queue(dev->nic));
}

static void spapr_vlan_reset_rx_pool(RxBufPool *rxp)
{
    /*
     * Use INT_MAX as bufsize so that unused buffers are moved to the end
     * of the list during the qsort in spapr_vlan_add_rxbuf_to_pool() later.
     */
    rxp->bufsize = INT_MAX;
    rxp->count = 0;
    memset(rxp->bds, 0, sizeof(rxp->bds));
}

static void spapr_vlan_reset(SpaprVioDevice *sdev)
{
    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
    int i;

    dev->buf_list = 0;
    dev->rx_bufs = 0;
    dev->isopen = 0;

    if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
        for (i = 0; i < RX_MAX_POOLS; i++) {
            spapr_vlan_reset_rx_pool(dev->rx_pool[i]);
        }
    }

    memcpy(&dev->nicconf.macaddr.a, &dev->perm_mac.a,
           sizeof(dev->nicconf.macaddr.a));
    qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
}

static void spapr_vlan_realize(SpaprVioDevice *sdev, Error **errp)
{
    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);

    qemu_macaddr_default_if_unset(&dev->nicconf.macaddr);

    memcpy(&dev->perm_mac.a, &dev->nicconf.macaddr.a, sizeof(dev->perm_mac.a));

    dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf,
                            object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
    qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);

    dev->rxp_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, spapr_vlan_flush_rx_queue,
                                  dev);
}

static void spapr_vlan_instance_init(Object *obj)
{
    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(obj);
    int i;

    device_add_bootindex_property(obj, &dev->nicconf.bootindex,
                                  "bootindex", "",
                                  DEVICE(dev), NULL);

    if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
        for (i = 0; i < RX_MAX_POOLS; i++) {
            dev->rx_pool[i] = g_new(RxBufPool, 1);
            spapr_vlan_reset_rx_pool(dev->rx_pool[i]);
        }
    }
}

static void spapr_vlan_instance_finalize(Object *obj)
{
    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(obj);
    int i;

    if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
        for (i = 0; i < RX_MAX_POOLS; i++) {
            g_free(dev->rx_pool[i]);
            dev->rx_pool[i] = NULL;
        }
    }

    if (dev->rxp_timer) {
        timer_del(dev->rxp_timer);
        timer_free(dev->rxp_timer);
    }
}

void spapr_vlan_create(SpaprVioBus *bus, NICInfo *nd)
{
    DeviceState *dev;

    dev = qdev_create(&bus->bus, "spapr-vlan");

    qdev_set_nic_properties(dev, nd);

    qdev_init_nofail(dev);
}

static int spapr_vlan_devnode(SpaprVioDevice *dev, void *fdt, int node_off)
{
    SpaprVioVlan *vdev = VIO_SPAPR_VLAN_DEVICE(dev);
    uint8_t padded_mac[8] = {0, 0};
    int ret;

    /* Some old phyp versions give the mac address in an 8-byte
     * property.  The kernel driver (before 3.10) has an insane workaround;
     * rather than doing the obvious thing and checking the property
     * length, it checks whether the first byte has 0b10 in the low
     * bits.  If a correct 6-byte property has a different first byte
     * the kernel will get the wrong mac address, overrunning its
     * buffer in the process (read only, thank goodness).
     *
     * Here we return a 6-byte address unless that would break a pre-3.10
     * driver.  In that case we return a padded 8-byte address to allow the old
     * workaround to succeed. */
    if ((vdev->nicconf.macaddr.a[0] & 0x3) == 0x2) {
        ret = fdt_setprop(fdt, node_off, "local-mac-address",
                          &vdev->nicconf.macaddr, ETH_ALEN);
    } else {
        memcpy(&padded_mac[2], &vdev->nicconf.macaddr, ETH_ALEN);
        ret = fdt_setprop(fdt, node_off, "local-mac-address",
                          padded_mac, sizeof(padded_mac));
    }
    if (ret < 0) {
        return ret;
    }

    ret = fdt_setprop_cell(fdt, node_off, "ibm,mac-address-filters", 0);
    if (ret < 0) {
        return ret;
    }

    return 0;
}

static int check_bd(SpaprVioVlan *dev, vlan_bd_t bd,
                    target_ulong alignment)
{
    if ((VLAN_BD_ADDR(bd) % alignment)
        || (VLAN_BD_LEN(bd) % alignment)) {
        return -1;
    }

    if (!spapr_vio_dma_valid(&dev->sdev, VLAN_BD_ADDR(bd),
                             VLAN_BD_LEN(bd), DMA_DIRECTION_FROM_DEVICE)
        || !spapr_vio_dma_valid(&dev->sdev, VLAN_BD_ADDR(bd),
                                VLAN_BD_LEN(bd), DMA_DIRECTION_TO_DEVICE)) {
        return -1;
    }

    return 0;
}

static target_ulong h_register_logical_lan(PowerPCCPU *cpu,
                                           SpaprMachineState *spapr,
                                           target_ulong opcode,
                                           target_ulong *args)
{
    target_ulong reg = args[0];
    target_ulong buf_list = args[1];
    target_ulong rec_queue = args[2];
    target_ulong filter_list = args[3];
    SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
    vlan_bd_t filter_list_bd;

    if (!dev) {
        return H_PARAMETER;
    }

    if (dev->isopen) {
        hcall_dprintf("H_REGISTER_LOGICAL_LAN called twice without "
                      "H_FREE_LOGICAL_LAN\n");
        return H_RESOURCE;
    }

    if (check_bd(dev, VLAN_VALID_BD(buf_list, SPAPR_TCE_PAGE_SIZE),
                 SPAPR_TCE_PAGE_SIZE) < 0) {
        hcall_dprintf("Bad buf_list 0x" TARGET_FMT_lx "\n", buf_list);
        return H_PARAMETER;
    }

    filter_list_bd = VLAN_VALID_BD(filter_list, SPAPR_TCE_PAGE_SIZE);
    if (check_bd(dev, filter_list_bd, SPAPR_TCE_PAGE_SIZE) < 0) {
        hcall_dprintf("Bad filter_list 0x" TARGET_FMT_lx "\n", filter_list);
        return H_PARAMETER;
    }

    if (!(rec_queue & VLAN_BD_VALID)
        || (check_bd(dev, rec_queue, VLAN_RQ_ALIGNMENT) < 0)) {
        hcall_dprintf("Bad receive queue\n");
        return H_PARAMETER;
    }

    dev->buf_list = buf_list;
    sdev->signal_state = 0;

    rec_queue &= ~VLAN_BD_TOGGLE;

    /* Initialize the buffer list */
    vio_stq(sdev, buf_list, rec_queue);
    vio_stq(sdev, buf_list + 8, filter_list_bd);
    spapr_vio_dma_set(sdev, buf_list + VLAN_RX_BDS_OFF, 0,
                      SPAPR_TCE_PAGE_SIZE - VLAN_RX_BDS_OFF);
    dev->add_buf_ptr = VLAN_RX_BDS_OFF - 8;
    dev->use_buf_ptr = VLAN_RX_BDS_OFF - 8;
    dev->rx_bufs = 0;
    dev->rxq_ptr = 0;

    /* Initialize the receive queue */
    spapr_vio_dma_set(sdev, VLAN_BD_ADDR(rec_queue), 0, VLAN_BD_LEN(rec_queue));

    dev->isopen = 1;
    qemu_flush_queued_packets(qemu_get_queue(dev->nic));

    return H_SUCCESS;
}


static target_ulong h_free_logical_lan(PowerPCCPU *cpu,
                                       SpaprMachineState *spapr,
                                       target_ulong opcode, target_ulong *args)
{
    target_ulong reg = args[0];
    SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);

    if (!dev) {
        return H_PARAMETER;
    }

    if (!dev->isopen) {
        hcall_dprintf("H_FREE_LOGICAL_LAN called without "
                      "H_REGISTER_LOGICAL_LAN\n");
        return H_RESOURCE;
    }

    spapr_vlan_reset(sdev);
    return H_SUCCESS;
}

/**
 * Used for qsort, this function compares two RxBufPools by size.
 */
static int rx_pool_size_compare(const void *p1, const void *p2)
{
    const RxBufPool *pool1 = *(RxBufPool **)p1;
    const RxBufPool *pool2 = *(RxBufPool **)p2;

    if (pool1->bufsize < pool2->bufsize) {
        return -1;
    }
    return pool1->bufsize > pool2->bufsize;
}

/**
 * Search for a matching buffer pool with exact matching size,
 * or return -1 if no matching pool has been found.
 */
static int spapr_vlan_get_rx_pool_id(SpaprVioVlan *dev, int size)
{
    int pool;

    for (pool = 0; pool < RX_MAX_POOLS; pool++) {
        if (dev->rx_pool[pool]->bufsize == size) {
            return pool;
        }
    }

    return -1;
}

/**
 * Enqueuing receive buffer by adding it to one of our receive buffer pools
 */
static target_long spapr_vlan_add_rxbuf_to_pool(SpaprVioVlan *dev,
                                                target_ulong buf)
{
    int size = VLAN_BD_LEN(buf);
    int pool;

    pool = spapr_vlan_get_rx_pool_id(dev, size);
    if (pool < 0) {
        /*
         * No matching pool found? Try to use a new one. If the guest used all
         * pools before, but changed the size of one pool in the meantime, we might
         * need to recycle that pool here (if it's empty already). Thus scan
         * all buffer pools now, starting with the last (likely empty) one.
         */
        for (pool = RX_MAX_POOLS - 1; pool >= 0 ; pool--) {
            if (dev->rx_pool[pool]->count == 0) {
                dev->rx_pool[pool]->bufsize = size;
                /*
                 * Sort pools by size so that spapr_vlan_receive()
                 * can later find the smallest buffer pool easily.
                 */
                qsort(dev->rx_pool, RX_MAX_POOLS, sizeof(dev->rx_pool[0]),
                      rx_pool_size_compare);
                pool = spapr_vlan_get_rx_pool_id(dev, size);
                trace_spapr_vlan_add_rxbuf_to_pool_create(pool,
                                                          VLAN_BD_LEN(buf));
                break;
            }
        }
    }
    /* Still no usable pool? Give up */
    if (pool < 0 || dev->rx_pool[pool]->count >= RX_POOL_MAX_BDS) {
        return H_RESOURCE;
    }

    trace_spapr_vlan_add_rxbuf_to_pool(pool, VLAN_BD_LEN(buf),
                                       dev->rx_pool[pool]->count);

    dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count++] = buf;

    return 0;
}

/**
 * This is the old way of enqueuing receive buffers: Add it to the rx queue
 * page that has been supplied by the guest (which is quite limited in size).
 */
static target_long spapr_vlan_add_rxbuf_to_page(SpaprVioVlan *dev,
                                                target_ulong buf)
{
    vlan_bd_t bd;

    if (dev->rx_bufs >= VLAN_MAX_BUFS) {
        return H_RESOURCE;
    }

    do {
        dev->add_buf_ptr += 8;
        if (dev->add_buf_ptr >= VLAN_RX_BDS_LEN + VLAN_RX_BDS_OFF) {
            dev->add_buf_ptr = VLAN_RX_BDS_OFF;
        }

        bd = vio_ldq(&dev->sdev, dev->buf_list + dev->add_buf_ptr);
    } while (bd & VLAN_BD_VALID);

    vio_stq(&dev->sdev, dev->buf_list + dev->add_buf_ptr, buf);

    trace_spapr_vlan_add_rxbuf_to_page(dev->add_buf_ptr, dev->rx_bufs, buf);

    return 0;
}

static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu,
                                             SpaprMachineState *spapr,
                                             target_ulong opcode,
                                             target_ulong *args)
{
    target_ulong reg = args[0];
    target_ulong buf = args[1];
    SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
    target_long ret;

    trace_spapr_vlan_h_add_logical_lan_buffer(reg, buf);

    if (!sdev) {
        hcall_dprintf("Bad device\n");
        return H_PARAMETER;
    }

    if ((check_bd(dev, buf, 4) < 0)
        || (VLAN_BD_LEN(buf) < 16)) {
        hcall_dprintf("Bad buffer enqueued\n");
        return H_PARAMETER;
    }

    if (!dev->isopen) {
        return H_RESOURCE;
    }

    if (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) {
        ret = spapr_vlan_add_rxbuf_to_pool(dev, buf);
    } else {
        ret = spapr_vlan_add_rxbuf_to_page(dev, buf);
    }
    if (ret) {
        return ret;
    }

    dev->rx_bufs++;

    /*
     * Give guest some more time to add additional RX buffers before we
     * flush the receive queue, so that e.g. fragmented IP packets can
     * be passed to the guest in one go later (instead of passing single
     * fragments if there is only one receive buffer available).
     */
    timer_mod(dev->rxp_timer, qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 500);

    return H_SUCCESS;
}

static target_ulong h_send_logical_lan(PowerPCCPU *cpu,
                                       SpaprMachineState *spapr,
                                       target_ulong opcode, target_ulong *args)
{
    target_ulong reg = args[0];
    target_ulong *bufs = args + 1;
    target_ulong continue_token = args[7];
    SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
    unsigned total_len;
    uint8_t *lbuf, *p;
    int i, nbufs;
    int ret;

    trace_spapr_vlan_h_send_logical_lan(reg, continue_token);

    if (!sdev) {
        return H_PARAMETER;
    }

    trace_spapr_vlan_h_send_logical_lan_rxbufs(dev->rx_bufs);

    if (!dev->isopen) {
        return H_DROPPED;
    }

    if (continue_token) {
        return H_HARDWARE; /* FIXME actually handle this */
    }

    total_len = 0;
    for (i = 0; i < 6; i++) {
        trace_spapr_vlan_h_send_logical_lan_buf_desc(bufs[i]);
        if (!(bufs[i] & VLAN_BD_VALID)) {
            break;
        }
        total_len += VLAN_BD_LEN(bufs[i]);
    }

    nbufs = i;
    trace_spapr_vlan_h_send_logical_lan_total(nbufs, total_len);

    if (total_len == 0) {
        return H_SUCCESS;
    }

    if (total_len > MAX_PACKET_SIZE) {
        /* Don't let the guest force too large an allocation */
        return H_RESOURCE;
    }

    lbuf = alloca(total_len);
    p = lbuf;
    for (i = 0; i < nbufs; i++) {
        ret = spapr_vio_dma_read(sdev, VLAN_BD_ADDR(bufs[i]),
                                 p, VLAN_BD_LEN(bufs[i]));
        if (ret < 0) {
            return ret;
        }

        p += VLAN_BD_LEN(bufs[i]);
    }

    qemu_send_packet(qemu_get_queue(dev->nic), lbuf, total_len);

    return H_SUCCESS;
}

static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, SpaprMachineState *spapr,
                                     target_ulong opcode, target_ulong *args)
{
    target_ulong reg = args[0];
    SpaprVioDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);

    if (!dev) {
        return H_PARAMETER;
    }

    return H_SUCCESS;
}

static target_ulong h_change_logical_lan_mac(PowerPCCPU *cpu,
                                             SpaprMachineState *spapr,
                                             target_ulong opcode,
                                             target_ulong *args)
{
    target_ulong reg = args[0];
    target_ulong macaddr = args[1];
    SpaprVioDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
    SpaprVioVlan *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
    int i;

    for (i = 0; i < ETH_ALEN; i++) {
        dev->nicconf.macaddr.a[ETH_ALEN - i - 1] = macaddr & 0xff;
        macaddr >>= 8;
    }

    qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);

    return H_SUCCESS;
}

static Property spapr_vlan_properties[] = {
    DEFINE_SPAPR_PROPERTIES(SpaprVioVlan, sdev),
    DEFINE_NIC_PROPERTIES(SpaprVioVlan, nicconf),
    DEFINE_PROP_BIT("use-rx-buffer-pools", SpaprVioVlan,
                    compat_flags, SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT, true),
    DEFINE_PROP_END_OF_LIST(),
};

static bool spapr_vlan_rx_buffer_pools_needed(void *opaque)
{
    SpaprVioVlan *dev = opaque;

    return (dev->compat_flags & SPAPRVLAN_FLAG_RX_BUF_POOLS) != 0;
}

static const VMStateDescription vmstate_rx_buffer_pool = {
    .name = "spapr_llan/rx_buffer_pool",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = spapr_vlan_rx_buffer_pools_needed,
    .fields = (VMStateField[]) {
        VMSTATE_INT32(bufsize, RxBufPool),
        VMSTATE_INT32(count, RxBufPool),
        VMSTATE_UINT64_ARRAY(bds, RxBufPool, RX_POOL_MAX_BDS),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_rx_pools = {
    .name = "spapr_llan/rx_pools",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = spapr_vlan_rx_buffer_pools_needed,
    .fields = (VMStateField[]) {
        VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(rx_pool, SpaprVioVlan,
                                           RX_MAX_POOLS, 1,
                                           vmstate_rx_buffer_pool, RxBufPool),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_spapr_llan = {
    .name = "spapr_llan",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_SPAPR_VIO(sdev, SpaprVioVlan),
        /* LLAN state */
        VMSTATE_BOOL(isopen, SpaprVioVlan),
        VMSTATE_UINT64(buf_list, SpaprVioVlan),
        VMSTATE_UINT32(add_buf_ptr, SpaprVioVlan),
        VMSTATE_UINT32(use_buf_ptr, SpaprVioVlan),
        VMSTATE_UINT32(rx_bufs, SpaprVioVlan),
        VMSTATE_UINT64(rxq_ptr, SpaprVioVlan),

        VMSTATE_END_OF_LIST()
    },
    .subsections = (const VMStateDescription * []) {
        &vmstate_rx_pools,
        NULL
    }
};

static void spapr_vlan_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);

    k->realize = spapr_vlan_realize;
    k->reset = spapr_vlan_reset;
    k->devnode = spapr_vlan_devnode;
    k->dt_name = "l-lan";
    k->dt_type = "network";
    k->dt_compatible = "IBM,l-lan";
    k->signal_mask = 0x1;
    set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
    dc->props = spapr_vlan_properties;
    k->rtce_window_size = 0x10000000;
    dc->vmsd = &vmstate_spapr_llan;
}

static const TypeInfo spapr_vlan_info = {
    .name          = TYPE_VIO_SPAPR_VLAN_DEVICE,
    .parent        = TYPE_VIO_SPAPR_DEVICE,
    .instance_size = sizeof(SpaprVioVlan),
    .class_init    = spapr_vlan_class_init,
    .instance_init = spapr_vlan_instance_init,
    .instance_finalize = spapr_vlan_instance_finalize,
};

static void spapr_vlan_register_types(void)
{
    spapr_register_hypercall(H_REGISTER_LOGICAL_LAN, h_register_logical_lan);
    spapr_register_hypercall(H_FREE_LOGICAL_LAN, h_free_logical_lan);
    spapr_register_hypercall(H_SEND_LOGICAL_LAN, h_send_logical_lan);
    spapr_register_hypercall(H_ADD_LOGICAL_LAN_BUFFER,
                             h_add_logical_lan_buffer);
    spapr_register_hypercall(H_MULTICAST_CTRL, h_multicast_ctrl);
    spapr_register_hypercall(H_CHANGE_LOGICAL_LAN_MAC,
                             h_change_logical_lan_mac);
    type_register_static(&spapr_vlan_info);
}

type_init(spapr_vlan_register_types)
