/*
 *  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, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <inttypes.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/wait.h>

#include <xs.h>
#include <xenctrl.h>
#include <xen/io/xenbus.h>
#include <xen/io/netif.h>

#include "hw.h"
#include "net.h"
#include "qemu-char.h"
#include "xen_backend.h"

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

struct XenNetDev {
    struct XenDevice      xendev;  /* must be first */
    char                  *mac;
    int                   tx_work;
    int                   tx_ring_ref;
    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;
    VLANClientState       *vs;
};

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

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_be_send_notify(&netdev->xendev);

    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 void net_tx_packets(struct XenNetDev *netdev)
{
    netif_tx_request_t txreq;
    RING_IDX rc, rp;
    void *page;
    void *tmpbuf = NULL;

    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;

#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) {
		xen_be_printf(&netdev->xendev, 0, "FIXME: extra info flag\n");
		net_tx_error(netdev, &txreq, rc);
		continue;
	    }
	    if (txreq.flags & NETTXF_more_data) {
		xen_be_printf(&netdev->xendev, 0, "FIXME: more data flag\n");
		net_tx_error(netdev, &txreq, rc);
		continue;
	    }
#endif

	    if (txreq.size < 14) {
		xen_be_printf(&netdev->xendev, 0, "bad packet size: %d\n", txreq.size);
		net_tx_error(netdev, &txreq, rc);
		continue;
	    }

	    if ((txreq.offset + txreq.size) > XC_PAGE_SIZE) {
		xen_be_printf(&netdev->xendev, 0, "error: page crossing\n");
		net_tx_error(netdev, &txreq, rc);
		continue;
	    }

	    xen_be_printf(&netdev->xendev, 3, "tx packet ref %d, off %d, len %d, flags 0x%x%s%s%s%s\n",
			  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 = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
					   netdev->xendev.dom,
					   txreq.gref, PROT_READ);
	    if (page == NULL) {
		xen_be_printf(&netdev->xendev, 0, "error: tx gref dereference failed (%d)\n",
                              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 = qemu_malloc(XC_PAGE_SIZE);
                memcpy(tmpbuf, page + txreq.offset, txreq.size);
		net_checksum_calculate(tmpbuf, txreq.size);
                qemu_send_packet(netdev->vs, tmpbuf, txreq.size);
            } else {
                qemu_send_packet(netdev->vs, page + txreq.offset, txreq.size);
            }
	    xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
	    net_tx_response(netdev, &txreq, NETIF_RSP_OKAY);
	}
	if (!netdev->tx_work)
	    break;
	netdev->tx_work = 0;
    }
    qemu_free(tmpbuf);
}

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

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;

    xen_be_printf(&netdev->xendev, 3, "rx response: idx %d, status %d, flags 0x%x\n",
		  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_be_send_notify(&netdev->xendev);
}

#define NET_IP_ALIGN 2

static int net_rx_ok(VLANClientState *vc)
{
    struct XenNetDev *netdev = vc->opaque;
    RING_IDX rc, rp;

    if (netdev->xendev.be_state != XenbusStateConnected)
	return 0;

    rc = netdev->rx_ring.req_cons;
    rp = netdev->rx_ring.sring->req_prod;
    xen_rmb();

    if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {
	xen_be_printf(&netdev->xendev, 2, "%s: no rx buffers (%d/%d)\n",
		      __FUNCTION__, rc, rp);
	return 0;
    }
    return 1;
}

static ssize_t net_rx_packet(VLANClientState *vc, const uint8_t *buf, size_t size)
{
    struct XenNetDev *netdev = vc->opaque;
    netif_rx_request_t rxreq;
    RING_IDX rc, rp;
    void *page;

    if (netdev->xendev.be_state != 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)) {
	xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n");
	return -1;
    }
    if (size > XC_PAGE_SIZE - NET_IP_ALIGN) {
	xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
		      (unsigned long)size, XC_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 = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
				   netdev->xendev.dom,
				   rxreq.gref, PROT_WRITE);
    if (page == NULL) {
	xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n",
                      rxreq.gref);
	net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);
	return -1;
    }
    memcpy(page + NET_IP_ALIGN, buf, size);
    xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
    net_rx_response(netdev, &rxreq, NETIF_RSP_OKAY, NET_IP_ALIGN, size, 0);

    return size;
}

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

static int net_init(struct XenDevice *xendev)
{
    struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
    VLANState *vlan;

    /* read xenstore entries */
    if (netdev->mac == NULL)
	netdev->mac = xenstore_read_be_str(&netdev->xendev, "mac");

    /* do we have all we need? */
    if (netdev->mac == NULL)
	return -1;

    vlan = qemu_find_vlan(netdev->xendev.dev);
    netdev->vs = qemu_new_vlan_client(vlan, "xen", NULL,
                                      net_rx_ok, net_rx_packet, NULL,
                                      NULL, netdev);
    snprintf(netdev->vs->info_str, sizeof(netdev->vs->info_str),
             "nic: xenbus vif macaddr=%s", netdev->mac);

    /* fill info */
    xenstore_write_be_int(&netdev->xendev, "feature-rx-copy", 1);
    xenstore_write_be_int(&netdev->xendev, "feature-rx-flip", 0);

    return 0;
}

static int net_connect(struct XenDevice *xendev)
{
    struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
    int rx_copy;

    if (xenstore_read_fe_int(&netdev->xendev, "tx-ring-ref",
				   &netdev->tx_ring_ref) == -1)
	return -1;
    if (xenstore_read_fe_int(&netdev->xendev, "rx-ring-ref",
				   &netdev->rx_ring_ref) == -1)
	return 1;
    if (xenstore_read_fe_int(&netdev->xendev, "event-channel",
				   &netdev->xendev.remote_port) == -1)
	return -1;

    if (xenstore_read_fe_int(&netdev->xendev, "request-rx-copy", &rx_copy) == -1)
	rx_copy = 0;
    if (rx_copy == 0) {
	xen_be_printf(&netdev->xendev, 0, "frontend doesn't support rx-copy.\n");
	return -1;
    }

    netdev->txs = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
					  netdev->xendev.dom,
					  netdev->tx_ring_ref,
					  PROT_READ | PROT_WRITE);
    netdev->rxs = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
					  netdev->xendev.dom,
					  netdev->rx_ring_ref,
					  PROT_READ | PROT_WRITE);
    if (!netdev->txs || !netdev->rxs)
	return -1;
    BACK_RING_INIT(&netdev->tx_ring, netdev->txs, XC_PAGE_SIZE);
    BACK_RING_INIT(&netdev->rx_ring, netdev->rxs, XC_PAGE_SIZE);

    xen_be_bind_evtchn(&netdev->xendev);

    xen_be_printf(&netdev->xendev, 1, "ok: tx-ring-ref %d, rx-ring-ref %d, "
		  "remote port %d, local port %d\n",
		  netdev->tx_ring_ref, netdev->rx_ring_ref,
		  netdev->xendev.remote_port, netdev->xendev.local_port);

    net_tx_packets(netdev);
    return 0;
}

static void net_disconnect(struct XenDevice *xendev)
{
    struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);

    xen_be_unbind_evtchn(&netdev->xendev);

    if (netdev->txs) {
	xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->txs, 1);
	netdev->txs = NULL;
    }
    if (netdev->rxs) {
	xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->rxs, 1);
	netdev->rxs = NULL;
    }
    if (netdev->vs) {
        qemu_del_vlan_client(netdev->vs);
        netdev->vs = NULL;
    }
}

static void net_event(struct XenDevice *xendev)
{
    struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
    net_tx_packets(netdev);
}

static int net_free(struct XenDevice *xendev)
{
    struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);

    qemu_free(netdev->mac);
    return 0;
}

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

struct XenDevOps xen_netdev_ops = {
    .size       = sizeof(struct XenNetDev),
    .flags      = DEVOPS_FLAG_NEED_GNTDEV,
    .init       = net_init,
    .connect    = net_connect,
    .event      = net_event,
    .disconnect = net_disconnect,
    .free       = net_free,
};
