/*
 * 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"
#include "s390-time.h"
#include "helper.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);

    if (!(vdev->guest_features[0] & VIRTIO_NET_F_MAC_BIT)) {
        puts("virtio-net device does not support the MAC address feature");
        return -1;
    }

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