/*
 *  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, 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);
