/*
 *  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/>.
 */

#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, 1);
    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,
};
