/*
 * Virtio-net driver for the s390-ccw firmware
 *
 * Copyright 2017 Thomas Huth, Red Hat Inc.
 *
 * This code 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; either version 2 of the License, or (at your
 * option) any later version.
 */

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <ethernet.h>
#include "s390-ccw.h"
#include "virtio.h"

#ifndef DEBUG_VIRTIO_NET
#define DEBUG_VIRTIO_NET 0
#endif

#define VIRTIO_NET_F_MAC_BIT  (1 << 5)

#define VQ_RX 0         /* Receive queue */
#define VQ_TX 1         /* Transmit queue */

struct VirtioNetHdr {
    uint8_t flags;
    uint8_t gso_type;
    uint16_t hdr_len;
    uint16_t gso_size;
    uint16_t csum_start;
    uint16_t csum_offset;
    /*uint16_t num_buffers;*/ /* Only with VIRTIO_NET_F_MRG_RXBUF or VIRTIO1 */
};
typedef struct VirtioNetHdr VirtioNetHdr;

static uint16_t rx_last_idx;  /* Last index in receive queue "used" ring */

int virtio_net_init(void *mac_addr)
{
    VDev *vdev = virtio_get_device();
    VRing *rxvq = &vdev->vrings[VQ_RX];
    void *buf;
    int i;

    vdev->guest_features[0] = VIRTIO_NET_F_MAC_BIT;
    virtio_setup_ccw(vdev);

    IPL_assert(vdev->guest_features[0] & VIRTIO_NET_F_MAC_BIT,
               "virtio-net device does not support the MAC address feature");
    memcpy(mac_addr, vdev->config.net.mac, ETH_ALEN);

    for (i = 0; i < 64; i++) {
        buf = malloc(ETH_MTU_SIZE + sizeof(VirtioNetHdr));
        IPL_assert(buf != NULL, "Can not allocate memory for receive buffers");
        vring_send_buf(rxvq, buf, ETH_MTU_SIZE + sizeof(VirtioNetHdr),
                       VRING_DESC_F_WRITE);
    }
    vring_notify(rxvq);

    return 0;
}

int send(int fd, const void *buf, int len, int flags)
{
    VirtioNetHdr tx_hdr;
    VDev *vdev = virtio_get_device();
    VRing *txvq = &vdev->vrings[VQ_TX];

    /* Set up header - we do not use anything special, so simply clear it */
    memset(&tx_hdr, 0, sizeof(tx_hdr));

    vring_send_buf(txvq, &tx_hdr, sizeof(tx_hdr), VRING_DESC_F_NEXT);
    vring_send_buf(txvq, (void *)buf, len, VRING_HIDDEN_IS_CHAIN);
    while (!vr_poll(txvq)) {
        yield();
    }
    if (drain_irqs(txvq->schid)) {
        puts("send: drain irqs failed");
        return -1;
    }

    return len;
}

int recv(int fd, void *buf, int maxlen, int flags)
{
    VDev *vdev = virtio_get_device();
    VRing *rxvq = &vdev->vrings[VQ_RX];
    int len, id;
    uint8_t *pkt;

    if (rx_last_idx == rxvq->used->idx) {
        return 0;
    }

    len = rxvq->used->ring[rx_last_idx % rxvq->num].len - sizeof(VirtioNetHdr);
    if (len > maxlen) {
        puts("virtio-net: Receive buffer too small");
        len = maxlen;
    }
    id = rxvq->used->ring[rx_last_idx % rxvq->num].id % rxvq->num;
    pkt = (uint8_t *)(rxvq->desc[id].addr + sizeof(VirtioNetHdr));

#if DEBUG_VIRTIO_NET   /* Dump packet */
    int i;
    printf("\nbuf %p: len=%i\n", (void *)rxvq->desc[id].addr, len);
    for (i = 0; i < 64; i++) {
        printf(" %02x", pkt[i]);
        if ((i % 16) == 15) {
            printf("\n");
        }
    }
    printf("\n");
#endif

    /* Copy data to destination buffer */
    memcpy(buf, pkt, len);

    /* Mark buffer as available to the host again */
    rxvq->avail->ring[rxvq->avail->idx % rxvq->num] = id;
    rxvq->avail->idx = rxvq->avail->idx + 1;
    vring_notify(rxvq);

    /* Move index to next entry */
    rx_last_idx = rx_last_idx + 1;

    return len;
}
