/*
 *  xen paravirt network card backend
 *
 *  (c) Gerd Hoffmann <kraxel@redhat.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; under version 2 of the License.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 *  Contributions after 2012-01-13 are licensed under the terms of the
 *  GNU GPL, version 2 or (at your option) any later version.
 */

#include "qemu/osdep.h"
#include "qemu/main-loop.h"
#include "qemu/cutils.h"
#include "qemu/log.h"
#include "qemu/qemu-print.h"
#include "qapi/qmp/qdict.h"
#include "qapi/error.h"

#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/wait.h>

#include "net/net.h"
#include "net/checksum.h"
#include "net/util.h"

#include "hw/xen/xen-backend.h"
#include "hw/xen/xen-bus-helper.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"

#include "hw/xen/interface/io/netif.h"
#include "hw/xen/interface/io/xs_wire.h"

#include "trace.h"

/* ------------------------------------------------------------- */

struct XenNetDev {
    struct XenDevice      xendev;  /* must be first */
    XenEventChannel       *event_channel;
    int                   dev;
    int                   tx_work;
    unsigned int          tx_ring_ref;
    unsigned int          rx_ring_ref;
    struct netif_tx_sring *txs;
    struct netif_rx_sring *rxs;
    netif_tx_back_ring_t  tx_ring;
    netif_rx_back_ring_t  rx_ring;
    NICConf               conf;
    NICState              *nic;
};

typedef struct XenNetDev XenNetDev;

#define TYPE_XEN_NET_DEVICE "xen-net-device"
OBJECT_DECLARE_SIMPLE_TYPE(XenNetDev, XEN_NET_DEVICE)

/* ------------------------------------------------------------- */

static void net_tx_response(struct XenNetDev *netdev, netif_tx_request_t *txp, int8_t st)
{
    RING_IDX i = netdev->tx_ring.rsp_prod_pvt;
    netif_tx_response_t *resp;
    int notify;

    resp = RING_GET_RESPONSE(&netdev->tx_ring, i);
    resp->id     = txp->id;
    resp->status = st;

#if 0
    if (txp->flags & NETTXF_extra_info) {
        RING_GET_RESPONSE(&netdev->tx_ring, ++i)->status = NETIF_RSP_NULL;
    }
#endif

    netdev->tx_ring.rsp_prod_pvt = ++i;
    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->tx_ring, notify);
    if (notify) {
        xen_device_notify_event_channel(XEN_DEVICE(netdev),
                                        netdev->event_channel, NULL);
    }

    if (i == netdev->tx_ring.req_cons) {
        int more_to_do;
        RING_FINAL_CHECK_FOR_REQUESTS(&netdev->tx_ring, more_to_do);
        if (more_to_do) {
            netdev->tx_work++;
        }
    }
}

static void net_tx_error(struct XenNetDev *netdev, netif_tx_request_t *txp, RING_IDX end)
{
#if 0
    /*
     * Hmm, why netback fails everything in the ring?
     * Should we do that even when not supporting SG and TSO?
     */
    RING_IDX cons = netdev->tx_ring.req_cons;

    do {
        make_tx_response(netif, txp, NETIF_RSP_ERROR);
        if (cons >= end) {
            break;
        }
        txp = RING_GET_REQUEST(&netdev->tx_ring, cons++);
    } while (1);
    netdev->tx_ring.req_cons = cons;
    netif_schedule_work(netif);
    netif_put(netif);
#else
    net_tx_response(netdev, txp, NETIF_RSP_ERROR);
#endif
}

static bool net_tx_packets(struct XenNetDev *netdev)
{
    bool done_something = false;
    netif_tx_request_t txreq;
    RING_IDX rc, rp;
    void *page;
    void *tmpbuf = NULL;

    assert(qemu_mutex_iothread_locked());

    for (;;) {
        rc = netdev->tx_ring.req_cons;
        rp = netdev->tx_ring.sring->req_prod;
        xen_rmb(); /* Ensure we see queued requests up to 'rp'. */

        while ((rc != rp)) {
            if (RING_REQUEST_CONS_OVERFLOW(&netdev->tx_ring, rc)) {
                break;
            }
            memcpy(&txreq, RING_GET_REQUEST(&netdev->tx_ring, rc), sizeof(txreq));
            netdev->tx_ring.req_cons = ++rc;
            done_something = true;

#if 1
            /* should not happen in theory, we don't announce the *
             * feature-{sg,gso,whatelse} flags in xenstore (yet?) */
            if (txreq.flags & NETTXF_extra_info) {
                qemu_log_mask(LOG_UNIMP, "vif%u: FIXME: extra info flag\n",
                              netdev->dev);
                net_tx_error(netdev, &txreq, rc);
                continue;
            }
            if (txreq.flags & NETTXF_more_data) {
                qemu_log_mask(LOG_UNIMP, "vif%u: FIXME: more data flag\n",
                              netdev->dev);
                net_tx_error(netdev, &txreq, rc);
                continue;
            }
#endif

            if (txreq.size < 14) {
                qemu_log_mask(LOG_GUEST_ERROR, "vif%u: bad packet size: %d\n",
                              netdev->dev, txreq.size);
                net_tx_error(netdev, &txreq, rc);
                continue;
            }

            if ((txreq.offset + txreq.size) > XEN_PAGE_SIZE) {
                qemu_log_mask(LOG_GUEST_ERROR, "vif%u: error: page crossing\n",
                              netdev->dev);
                net_tx_error(netdev, &txreq, rc);
                continue;
            }

            trace_xen_netdev_tx(netdev->dev, txreq.gref, txreq.offset,
                                txreq.size, txreq.flags,
                                (txreq.flags & NETTXF_csum_blank)     ? " csum_blank"     : "",
                                (txreq.flags & NETTXF_data_validated) ? " data_validated" : "",
                                (txreq.flags & NETTXF_more_data)      ? " more_data"      : "",
                                (txreq.flags & NETTXF_extra_info)     ? " extra_info"     : "");

            page = xen_device_map_grant_refs(&netdev->xendev, &txreq.gref, 1,
                                             PROT_READ, NULL);
            if (page == NULL) {
                qemu_log_mask(LOG_GUEST_ERROR,
                              "vif%u: tx gref dereference failed (%d)\n",
                              netdev->dev, txreq.gref);
                net_tx_error(netdev, &txreq, rc);
                continue;
            }
            if (txreq.flags & NETTXF_csum_blank) {
                /* have read-only mapping -> can't fill checksum in-place */
                if (!tmpbuf) {
                    tmpbuf = g_malloc(XEN_PAGE_SIZE);
                }
                memcpy(tmpbuf, page + txreq.offset, txreq.size);
                net_checksum_calculate(tmpbuf, txreq.size, CSUM_ALL);
                qemu_send_packet(qemu_get_queue(netdev->nic), tmpbuf,
                                 txreq.size);
            } else {
                qemu_send_packet(qemu_get_queue(netdev->nic),
                                 page + txreq.offset, txreq.size);
            }
            xen_device_unmap_grant_refs(&netdev->xendev, page, &txreq.gref, 1,
                                        NULL);
            net_tx_response(netdev, &txreq, NETIF_RSP_OKAY);
        }
        if (!netdev->tx_work) {
            break;
        }
        netdev->tx_work = 0;
    }
    g_free(tmpbuf);
    return done_something;
}

/* ------------------------------------------------------------- */

static void net_rx_response(struct XenNetDev *netdev,
                            netif_rx_request_t *req, int8_t st,
                            uint16_t offset, uint16_t size,
                            uint16_t flags)
{
    RING_IDX i = netdev->rx_ring.rsp_prod_pvt;
    netif_rx_response_t *resp;
    int notify;

    resp = RING_GET_RESPONSE(&netdev->rx_ring, i);
    resp->offset     = offset;
    resp->flags      = flags;
    resp->id         = req->id;
    resp->status     = (int16_t)size;
    if (st < 0) {
        resp->status = (int16_t)st;
    }

    trace_xen_netdev_rx(netdev->dev, i, resp->status, resp->flags);

    netdev->rx_ring.rsp_prod_pvt = ++i;
    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->rx_ring, notify);
    if (notify) {
        xen_device_notify_event_channel(XEN_DEVICE(netdev),
                                        netdev->event_channel, NULL);
    }
}

#define NET_IP_ALIGN 2

static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size)
{
    struct XenNetDev *netdev = qemu_get_nic_opaque(nc);
    netif_rx_request_t rxreq;
    RING_IDX rc, rp;
    void *page;

    assert(qemu_mutex_iothread_locked());

    if (xen_device_backend_get_state(&netdev->xendev) != XenbusStateConnected) {
        return -1;
    }

    rc = netdev->rx_ring.req_cons;
    rp = netdev->rx_ring.sring->req_prod;
    xen_rmb(); /* Ensure we see queued requests up to 'rp'. */

    if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {
        return 0;
    }
    if (size > XEN_PAGE_SIZE - NET_IP_ALIGN) {
        qemu_log_mask(LOG_GUEST_ERROR, "vif%u: packet too big (%lu > %ld)",
                      netdev->dev, (unsigned long)size,
                      XEN_PAGE_SIZE - NET_IP_ALIGN);
        return -1;
    }

    memcpy(&rxreq, RING_GET_REQUEST(&netdev->rx_ring, rc), sizeof(rxreq));
    netdev->rx_ring.req_cons = ++rc;

    page = xen_device_map_grant_refs(&netdev->xendev, &rxreq.gref, 1,
                                     PROT_WRITE, NULL);
    if (page == NULL) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "vif%u: rx gref dereference failed (%d)\n",
                      netdev->dev, rxreq.gref);
        net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);
        return -1;
    }
    memcpy(page + NET_IP_ALIGN, buf, size);
    xen_device_unmap_grant_refs(&netdev->xendev, page, &rxreq.gref, 1, NULL);
    net_rx_response(netdev, &rxreq, NETIF_RSP_OKAY, NET_IP_ALIGN, size, 0);

    return size;
}

/* ------------------------------------------------------------- */

static NetClientInfo net_xen_info = {
    .type = NET_CLIENT_DRIVER_NIC,
    .size = sizeof(NICState),
    .receive = net_rx_packet,
};

static void xen_netdev_realize(XenDevice *xendev, Error **errp)
{
    ERRP_GUARD();
    XenNetDev *netdev = XEN_NET_DEVICE(xendev);
    NetClientState *nc;

    qemu_macaddr_default_if_unset(&netdev->conf.macaddr);

    xen_device_frontend_printf(xendev, "mac", "%02x:%02x:%02x:%02x:%02x:%02x",
                               netdev->conf.macaddr.a[0],
                               netdev->conf.macaddr.a[1],
                               netdev->conf.macaddr.a[2],
                               netdev->conf.macaddr.a[3],
                               netdev->conf.macaddr.a[4],
                               netdev->conf.macaddr.a[5]);

    netdev->nic = qemu_new_nic(&net_xen_info, &netdev->conf,
                               object_get_typename(OBJECT(xendev)),
                               DEVICE(xendev)->id,
                               &xendev->qdev.mem_reentrancy_guard, netdev);

    nc = qemu_get_queue(netdev->nic);
    qemu_format_nic_info_str(nc, netdev->conf.macaddr.a);

    /* fill info */
    xen_device_backend_printf(xendev, "feature-rx-copy", "%u", 1);
    xen_device_backend_printf(xendev, "feature-rx-flip", "%u", 0);

    trace_xen_netdev_realize(netdev->dev, nc->info_str, nc->peer ?
                             nc->peer->name : "(none)");
}

static bool net_event(void *_xendev)
{
    XenNetDev *netdev = XEN_NET_DEVICE(_xendev);
    bool done_something;

    done_something = net_tx_packets(netdev);
    qemu_flush_queued_packets(qemu_get_queue(netdev->nic));
    return done_something;
}

static bool xen_netdev_connect(XenDevice *xendev, Error **errp)
{
    XenNetDev *netdev = XEN_NET_DEVICE(xendev);
    unsigned int port, rx_copy;

    assert(qemu_mutex_iothread_locked());

    if (xen_device_frontend_scanf(xendev, "tx-ring-ref", "%u",
                                  &netdev->tx_ring_ref) != 1) {
        error_setg(errp, "failed to read tx-ring-ref");
        return false;
    }

    if (xen_device_frontend_scanf(xendev, "rx-ring-ref", "%u",
                                  &netdev->rx_ring_ref) != 1) {
        error_setg(errp, "failed to read rx-ring-ref");
        return false;
    }

    if (xen_device_frontend_scanf(xendev, "event-channel", "%u",
                                  &port) != 1) {
        error_setg(errp, "failed to read event-channel");
        return false;
    }

    if (xen_device_frontend_scanf(xendev, "request-rx-copy", "%u",
                                  &rx_copy) != 1) {
        rx_copy = 0;
    }
    if (rx_copy == 0) {
        error_setg(errp, "frontend doesn't support rx-copy");
        return false;
    }

    netdev->txs = xen_device_map_grant_refs(xendev,
                                            &netdev->tx_ring_ref, 1,
                                            PROT_READ | PROT_WRITE,
                                            errp);
    if (!netdev->txs) {
        error_prepend(errp, "failed to map tx grant ref: ");
        return false;
    }

    netdev->rxs = xen_device_map_grant_refs(xendev,
                                            &netdev->rx_ring_ref, 1,
                                            PROT_READ | PROT_WRITE,
                                            errp);
    if (!netdev->rxs) {
        error_prepend(errp, "failed to map rx grant ref: ");
        return false;
    }

    BACK_RING_INIT(&netdev->tx_ring, netdev->txs, XEN_PAGE_SIZE);
    BACK_RING_INIT(&netdev->rx_ring, netdev->rxs, XEN_PAGE_SIZE);

    netdev->event_channel = xen_device_bind_event_channel(xendev, port,
                                                          net_event,
                                                          netdev,
                                                          errp);
    if (!netdev->event_channel) {
        return false;
    }

    trace_xen_netdev_connect(netdev->dev, netdev->tx_ring_ref,
                             netdev->rx_ring_ref, port);

    net_tx_packets(netdev);
    return true;
}

static void xen_netdev_disconnect(XenDevice *xendev, Error **errp)
{
    XenNetDev *netdev = XEN_NET_DEVICE(xendev);

    trace_xen_netdev_disconnect(netdev->dev);

    assert(qemu_mutex_iothread_locked());

    netdev->tx_ring.sring = NULL;
    netdev->rx_ring.sring = NULL;

    if (netdev->event_channel) {
        xen_device_unbind_event_channel(xendev, netdev->event_channel,
                                        errp);
        netdev->event_channel = NULL;
    }
    if (netdev->txs) {
        xen_device_unmap_grant_refs(xendev, netdev->txs,
                                    &netdev->tx_ring_ref, 1, errp);
        netdev->txs = NULL;
    }
    if (netdev->rxs) {
        xen_device_unmap_grant_refs(xendev, netdev->rxs,
                                    &netdev->rx_ring_ref, 1, errp);
        netdev->rxs = NULL;
    }
}

/* -------------------------------------------------------------------- */


static void xen_netdev_frontend_changed(XenDevice *xendev,
                                       enum xenbus_state frontend_state,
                                       Error **errp)
{
    ERRP_GUARD();
    enum xenbus_state backend_state = xen_device_backend_get_state(xendev);

    trace_xen_netdev_frontend_changed(xendev->name, frontend_state);

    switch (frontend_state) {
    case XenbusStateConnected:
        if (backend_state == XenbusStateConnected) {
            break;
        }

        xen_netdev_disconnect(xendev, errp);
        if (*errp) {
            break;
        }

        if (!xen_netdev_connect(xendev, errp)) {
            xen_netdev_disconnect(xendev, NULL);
            xen_device_backend_set_state(xendev, XenbusStateClosing);
            break;
        }

        xen_device_backend_set_state(xendev, XenbusStateConnected);
        break;

    case XenbusStateClosing:
        xen_device_backend_set_state(xendev, XenbusStateClosing);
        break;

    case XenbusStateClosed:
    case XenbusStateUnknown:
        xen_netdev_disconnect(xendev, errp);
        if (*errp) {
            break;
        }

        xen_device_backend_set_state(xendev, XenbusStateClosed);
        break;

    case XenbusStateInitialised:
        /*
         * Linux netback does nothing on the frontend going (back) to
         * XenbusStateInitialised, so do the same here.
         */
    default:
        break;
    }
}

static char *xen_netdev_get_name(XenDevice *xendev, Error **errp)
{
    XenNetDev *netdev = XEN_NET_DEVICE(xendev);

    if (netdev->dev == -1) {
        XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
        char fe_path[XENSTORE_ABS_PATH_MAX + 1];
        int idx = (xen_mode == XEN_EMULATE) ? 0 : 1;
        char *value;

        /* Theoretically we could go up to INT_MAX here but that's overkill */
        while (idx < 100) {
            snprintf(fe_path, sizeof(fe_path),
                     "/local/domain/%u/device/vif/%u",
                     xendev->frontend_id, idx);
            value = qemu_xen_xs_read(xenbus->xsh, XBT_NULL, fe_path, NULL);
            if (!value) {
                if (errno == ENOENT) {
                    netdev->dev = idx;
                    goto found;
                }
                error_setg(errp, "cannot read %s: %s", fe_path,
                           strerror(errno));
                return NULL;
            }
            free(value);
            idx++;
        }
        error_setg(errp, "cannot find device index for netdev device");
        return NULL;
    }
 found:
    return g_strdup_printf("%u", netdev->dev);
}

static void xen_netdev_unrealize(XenDevice *xendev)
{
    XenNetDev *netdev = XEN_NET_DEVICE(xendev);

    trace_xen_netdev_unrealize(netdev->dev);

    /* Disconnect from the frontend in case this has not already happened */
    xen_netdev_disconnect(xendev, NULL);

    if (netdev->nic) {
        qemu_del_nic(netdev->nic);
    }
}

/* ------------------------------------------------------------- */

static Property xen_netdev_properties[] = {
    DEFINE_NIC_PROPERTIES(XenNetDev, conf),
    DEFINE_PROP_INT32("idx", XenNetDev, dev, -1),
    DEFINE_PROP_END_OF_LIST(),
};

static void xen_netdev_class_init(ObjectClass *class, void *data)
{
    DeviceClass *dev_class = DEVICE_CLASS(class);
    XenDeviceClass *xendev_class = XEN_DEVICE_CLASS(class);

    xendev_class->backend = "qnic";
    xendev_class->device = "vif";
    xendev_class->get_name = xen_netdev_get_name;
    xendev_class->realize = xen_netdev_realize;
    xendev_class->frontend_changed = xen_netdev_frontend_changed;
    xendev_class->unrealize = xen_netdev_unrealize;
    set_bit(DEVICE_CATEGORY_NETWORK, dev_class->categories);
    dev_class->user_creatable = true;

    device_class_set_props(dev_class, xen_netdev_properties);
}

static const TypeInfo xen_net_type_info = {
    .name = TYPE_XEN_NET_DEVICE,
    .parent = TYPE_XEN_DEVICE,
    .instance_size = sizeof(XenNetDev),
    .class_init = xen_netdev_class_init,
};

static void xen_net_register_types(void)
{
    type_register_static(&xen_net_type_info);
}

type_init(xen_net_register_types)

/* Called to instantiate a XenNetDev when the backend is detected. */
static void xen_net_device_create(XenBackendInstance *backend,
                                  QDict *opts, Error **errp)
{
    ERRP_GUARD();
    XenBus *xenbus = xen_backend_get_bus(backend);
    const char *name = xen_backend_get_name(backend);
    XenDevice *xendev = NULL;
    unsigned long number;
    const char *macstr;
    XenNetDev *net;
    MACAddr mac;

    if (qemu_strtoul(name, NULL, 10, &number) || number >= INT_MAX) {
        error_setg(errp, "failed to parse name '%s'", name);
        goto fail;
    }

    trace_xen_netdev_create(number);

    macstr = qdict_get_try_str(opts, "mac");
    if (macstr == NULL) {
        error_setg(errp, "no MAC address found");
        goto fail;
    }

    if (net_parse_macaddr(mac.a, macstr) < 0) {
        error_setg(errp, "failed to parse MAC address");
        goto fail;
    }

    xendev = XEN_DEVICE(qdev_new(TYPE_XEN_NET_DEVICE));
    net = XEN_NET_DEVICE(xendev);

    net->dev = number;
    memcpy(&net->conf.macaddr, &mac, sizeof(mac));

    if (qdev_realize_and_unref(DEVICE(xendev), BUS(xenbus), errp)) {
        xen_backend_set_device(backend, xendev);
        return;
    }

    error_prepend(errp, "realization of net device %lu failed: ",
                  number);

 fail:
    if (xendev) {
        object_unparent(OBJECT(xendev));
    }
}

static void xen_net_device_destroy(XenBackendInstance *backend,
                                   Error **errp)
{
    ERRP_GUARD();
    XenDevice *xendev = xen_backend_get_device(backend);
    XenNetDev *netdev = XEN_NET_DEVICE(xendev);

    trace_xen_netdev_destroy(netdev->dev);

    object_unparent(OBJECT(xendev));
}

static const XenBackendInfo xen_net_backend_info  = {
    .type = "qnic",
    .create = xen_net_device_create,
    .destroy = xen_net_device_destroy,
};

static void xen_net_register_backend(void)
{
    xen_backend_register(&xen_net_backend_info);
}

xen_backend_init(xen_net_register_backend);
