/*
 *  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 <linux/if.h>
#include <linux/if_tun.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 = malloc(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;
    }
    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(void *opaque)
{
    struct XenNetDev *netdev = 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 void net_rx_packet(void *opaque, const uint8_t *buf, int size)
{
    struct XenNetDev *netdev = opaque;
    netif_rx_request_t rxreq;
    RING_IDX rc, rp;
    void *page;

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

    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;
    }
    if (size > XC_PAGE_SIZE - NET_IP_ALIGN) {
	xen_be_printf(&netdev->xendev, 0, "packet too big (%d > %ld)",
		      size, XC_PAGE_SIZE - NET_IP_ALIGN);
	return;
    }

    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;
    }
    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);
}

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

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_packet, net_rx_ok, 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);
    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,
};
