/*
 * Luminary Micro Stellaris Ethernet Controller
 *
 * Copyright (c) 2007 CodeSourcery.
 * Written by Paul Brook
 *
 * This code is licenced under the GPL.
 */
#include "hw.h"
#include "arm-misc.h"
#include "net.h"
#include <zlib.h>

//#define DEBUG_STELLARIS_ENET 1

#ifdef DEBUG_STELLARIS_ENET
#define DPRINTF(fmt, args...) \
do { printf("stellaris_enet: " fmt , ##args); } while (0)
#define BADF(fmt, args...) \
do { fprintf(stderr, "stellaris_enet: error: " fmt , ##args); exit(1);} while (0)
#else
#define DPRINTF(fmt, args...) do {} while(0)
#define BADF(fmt, args...) \
do { fprintf(stderr, "stellaris_enet: error: " fmt , ##args);} while (0)
#endif

#define SE_INT_RX       0x01
#define SE_INT_TXER     0x02
#define SE_INT_TXEMP    0x04
#define SE_INT_FOV      0x08
#define SE_INT_RXER     0x10
#define SE_INT_MD       0x20
#define SE_INT_PHY      0x40

#define SE_RCTL_RXEN    0x01
#define SE_RCTL_AMUL    0x02
#define SE_RCTL_PRMS    0x04
#define SE_RCTL_BADCRC  0x08
#define SE_RCTL_RSTFIFO 0x10

#define SE_TCTL_TXEN    0x01
#define SE_TCTL_PADEN   0x02
#define SE_TCTL_CRC     0x04
#define SE_TCTL_DUPLEX  0x08

typedef struct {
    uint32_t ris;
    uint32_t im;
    uint32_t rctl;
    uint32_t tctl;
    uint32_t thr;
    uint32_t mctl;
    uint32_t mdv;
    uint32_t mtxd;
    uint32_t mrxd;
    uint32_t np;
    int tx_frame_len;
    int tx_fifo_len;
    uint8_t tx_fifo[2048];
    /* Real hardware has a 2k fifo, which works out to be at most 31 packets.
       We implement a full 31 packet fifo.  */
    struct {
        uint8_t data[2048];
        int len;
    } rx[31];
    uint8_t *rx_fifo;
    int rx_fifo_len;
    int next_packet;
    VLANClientState *vc;
    qemu_irq irq;
    uint8_t macaddr[6];
    int mmio_index;
} stellaris_enet_state;

static void stellaris_enet_update(stellaris_enet_state *s)
{
    qemu_set_irq(s->irq, (s->ris & s->im) != 0);
}

/* TODO: Implement MAC address filtering.  */
static void stellaris_enet_receive(void *opaque, const uint8_t *buf, int size)
{
    stellaris_enet_state *s = (stellaris_enet_state *)opaque;
    int n;
    uint8_t *p;
    uint32_t crc;

    if ((s->rctl & SE_RCTL_RXEN) == 0)
        return;
    if (s->np >= 31) {
        DPRINTF("Packet dropped\n");
        return;
    }

    DPRINTF("Received packet len=%d\n", size);
    n = s->next_packet + s->np;
    if (n >= 31)
        n -= 31;
    s->np++;

    s->rx[n].len = size + 6;
    p = s->rx[n].data;
    *(p++) = (size + 6);
    *(p++) = (size + 6) >> 8;
    memcpy (p, buf, size);
    p += size;
    crc = crc32(~0, buf, size);
    *(p++) = crc;
    *(p++) = crc >> 8;
    *(p++) = crc >> 16;
    *(p++) = crc >> 24;
    /* Clear the remaining bytes in the last word.  */
    if ((size & 3) != 2) {
        memset(p, 0, (6 - size) & 3);
    }

    s->ris |= SE_INT_RX;
    stellaris_enet_update(s);
}

static int stellaris_enet_can_receive(void *opaque)
{
    stellaris_enet_state *s = (stellaris_enet_state *)opaque;

    if ((s->rctl & SE_RCTL_RXEN) == 0)
        return 1;

    return (s->np < 31);
}

static uint32_t stellaris_enet_read(void *opaque, target_phys_addr_t offset)
{
    stellaris_enet_state *s = (stellaris_enet_state *)opaque;
    uint32_t val;

    switch (offset) {
    case 0x00: /* RIS */
        DPRINTF("IRQ status %02x\n", s->ris);
        return s->ris;
    case 0x04: /* IM */
        return s->im;
    case 0x08: /* RCTL */
        return s->rctl;
    case 0x0c: /* TCTL */
        return s->tctl;
    case 0x10: /* DATA */
        if (s->rx_fifo_len == 0) {
            if (s->np == 0) {
                BADF("RX underflow\n");
                return 0;
            }
            s->rx_fifo_len = s->rx[s->next_packet].len;
            s->rx_fifo = s->rx[s->next_packet].data;
            DPRINTF("RX FIFO start packet len=%d\n", s->rx_fifo_len);
        }
        val = s->rx_fifo[0] | (s->rx_fifo[1] << 8) | (s->rx_fifo[2] << 16)
              | (s->rx_fifo[3] << 24);
        s->rx_fifo += 4;
        s->rx_fifo_len -= 4;
        if (s->rx_fifo_len <= 0) {
            s->rx_fifo_len = 0;
            s->next_packet++;
            if (s->next_packet >= 31)
                s->next_packet = 0;
            s->np--;
            DPRINTF("RX done np=%d\n", s->np);
        }
        return val;
    case 0x14: /* IA0 */
        return s->macaddr[0] | (s->macaddr[1] << 8)
               | (s->macaddr[2] << 16) | (s->macaddr[3] << 24);
    case 0x18: /* IA1 */
        return s->macaddr[4] | (s->macaddr[5] << 8);
    case 0x1c: /* THR */
        return s->thr;
    case 0x20: /* MCTL */
        return s->mctl;
    case 0x24: /* MDV */
        return s->mdv;
    case 0x28: /* MADD */
        return 0;
    case 0x2c: /* MTXD */
        return s->mtxd;
    case 0x30: /* MRXD */
        return s->mrxd;
    case 0x34: /* NP */
        return s->np;
    case 0x38: /* TR */
        return 0;
    case 0x3c: /* Undocuented: Timestamp? */
        return 0;
    default:
        cpu_abort (cpu_single_env, "stellaris_enet_read: Bad offset %x\n",
                   (int)offset);
        return 0;
    }
}

static void stellaris_enet_write(void *opaque, target_phys_addr_t offset,
                        uint32_t value)
{
    stellaris_enet_state *s = (stellaris_enet_state *)opaque;

    switch (offset) {
    case 0x00: /* IACK */
        s->ris &= ~value;
        DPRINTF("IRQ ack %02x/%02x\n", value, s->ris);
        stellaris_enet_update(s);
        /* Clearing TXER also resets the TX fifo.  */
        if (value & SE_INT_TXER)
            s->tx_frame_len = -1;
        break;
    case 0x04: /* IM */
        DPRINTF("IRQ mask %02x/%02x\n", value, s->ris);
        s->im = value;
        stellaris_enet_update(s);
        break;
    case 0x08: /* RCTL */
        s->rctl = value;
        if (value & SE_RCTL_RSTFIFO) {
            s->rx_fifo_len = 0;
            s->np = 0;
            stellaris_enet_update(s);
        }
        break;
    case 0x0c: /* TCTL */
        s->tctl = value;
        break;
    case 0x10: /* DATA */
        if (s->tx_frame_len == -1) {
            s->tx_frame_len = value & 0xffff;
            if (s->tx_frame_len > 2032) {
                DPRINTF("TX frame too long (%d)\n", s->tx_frame_len);
                s->tx_frame_len = 0;
                s->ris |= SE_INT_TXER;
                stellaris_enet_update(s);
            } else {
                DPRINTF("Start TX frame len=%d\n", s->tx_frame_len);
                /* The value written does not include the ethernet header.  */
                s->tx_frame_len += 14;
                if ((s->tctl & SE_TCTL_CRC) == 0)
                    s->tx_frame_len += 4;
                s->tx_fifo_len = 0;
                s->tx_fifo[s->tx_fifo_len++] = value >> 16;
                s->tx_fifo[s->tx_fifo_len++] = value >> 24;
            }
        } else {
            s->tx_fifo[s->tx_fifo_len++] = value;
            s->tx_fifo[s->tx_fifo_len++] = value >> 8;
            s->tx_fifo[s->tx_fifo_len++] = value >> 16;
            s->tx_fifo[s->tx_fifo_len++] = value >> 24;
            if (s->tx_fifo_len >= s->tx_frame_len) {
                /* We don't implement explicit CRC, so just chop it off.  */
                if ((s->tctl & SE_TCTL_CRC) == 0)
                    s->tx_frame_len -= 4;
                if ((s->tctl & SE_TCTL_PADEN) && s->tx_frame_len < 60) {
                    memset(&s->tx_fifo[s->tx_frame_len], 0, 60 - s->tx_frame_len);
                    s->tx_fifo_len = 60;
                }
                qemu_send_packet(s->vc, s->tx_fifo, s->tx_frame_len);
                s->tx_frame_len = -1;
                s->ris |= SE_INT_TXEMP;
                stellaris_enet_update(s);
                DPRINTF("Done TX\n");
            }
        }
        break;
    case 0x14: /* IA0 */
        s->macaddr[0] = value;
        s->macaddr[1] = value >> 8;
        s->macaddr[2] = value >> 16;
        s->macaddr[3] = value >> 24;
        break;
    case 0x18: /* IA1 */
        s->macaddr[4] = value;
        s->macaddr[5] = value >> 8;
        break;
    case 0x1c: /* THR */
        s->thr = value;
        break;
    case 0x20: /* MCTL */
        s->mctl = value;
        break;
    case 0x24: /* MDV */
        s->mdv = value;
        break;
    case 0x28: /* MADD */
        /* ignored.  */
        break;
    case 0x2c: /* MTXD */
        s->mtxd = value & 0xff;
        break;
    case 0x30: /* MRXD */
    case 0x34: /* NP */
    case 0x38: /* TR */
        /* Ignored.  */
    case 0x3c: /* Undocuented: Timestamp? */
        /* Ignored.  */
        break;
    default:
        cpu_abort (cpu_single_env, "stellaris_enet_write: Bad offset %x\n",
                   (int)offset);
    }
}

static CPUReadMemoryFunc *stellaris_enet_readfn[] = {
   stellaris_enet_read,
   stellaris_enet_read,
   stellaris_enet_read
};

static CPUWriteMemoryFunc *stellaris_enet_writefn[] = {
   stellaris_enet_write,
   stellaris_enet_write,
   stellaris_enet_write
};
static void stellaris_enet_reset(stellaris_enet_state *s)
{
    s->mdv = 0x80;
    s->rctl = SE_RCTL_BADCRC;
    s->im = SE_INT_PHY | SE_INT_MD | SE_INT_RXER | SE_INT_FOV | SE_INT_TXEMP
            | SE_INT_TXER | SE_INT_RX;
    s->thr = 0x3f;
    s->tx_frame_len = -1;
}

static void stellaris_enet_save(QEMUFile *f, void *opaque)
{
    stellaris_enet_state *s = (stellaris_enet_state *)opaque;
    int i;

    qemu_put_be32(f, s->ris);
    qemu_put_be32(f, s->im);
    qemu_put_be32(f, s->rctl);
    qemu_put_be32(f, s->tctl);
    qemu_put_be32(f, s->thr);
    qemu_put_be32(f, s->mctl);
    qemu_put_be32(f, s->mdv);
    qemu_put_be32(f, s->mtxd);
    qemu_put_be32(f, s->mrxd);
    qemu_put_be32(f, s->np);
    qemu_put_be32(f, s->tx_frame_len);
    qemu_put_be32(f, s->tx_fifo_len);
    qemu_put_buffer(f, s->tx_fifo, sizeof(s->tx_fifo));
    for (i = 0; i < 31; i++) {
        qemu_put_be32(f, s->rx[i].len);
        qemu_put_buffer(f, s->rx[i].data, sizeof(s->rx[i].data));

    }
    qemu_put_be32(f, s->next_packet);
    qemu_put_be32(f, s->rx_fifo - s->rx[s->next_packet].data);
    qemu_put_be32(f, s->rx_fifo_len);
}

static int stellaris_enet_load(QEMUFile *f, void *opaque, int version_id)
{
    stellaris_enet_state *s = (stellaris_enet_state *)opaque;
    int i;

    if (version_id != 1)
        return -EINVAL;

    s->ris = qemu_get_be32(f);
    s->im = qemu_get_be32(f);
    s->rctl = qemu_get_be32(f);
    s->tctl = qemu_get_be32(f);
    s->thr = qemu_get_be32(f);
    s->mctl = qemu_get_be32(f);
    s->mdv = qemu_get_be32(f);
    s->mtxd = qemu_get_be32(f);
    s->mrxd = qemu_get_be32(f);
    s->np = qemu_get_be32(f);
    s->tx_frame_len = qemu_get_be32(f);
    s->tx_fifo_len = qemu_get_be32(f);
    qemu_get_buffer(f, s->tx_fifo, sizeof(s->tx_fifo));
    for (i = 0; i < 31; i++) {
        s->rx[i].len = qemu_get_be32(f);
        qemu_get_buffer(f, s->rx[i].data, sizeof(s->rx[i].data));

    }
    s->next_packet = qemu_get_be32(f);
    s->rx_fifo = s->rx[s->next_packet].data + qemu_get_be32(f);
    s->rx_fifo_len = qemu_get_be32(f);

    return 0;
}

static void stellaris_enet_cleanup(VLANClientState *vc)
{
    stellaris_enet_state *s = vc->opaque;

    unregister_savevm("stellaris_enet", s);

    cpu_unregister_io_memory(s->mmio_index);

    qemu_free(s);
}

void stellaris_enet_init(NICInfo *nd, uint32_t base, qemu_irq irq)
{
    stellaris_enet_state *s;

    qemu_check_nic_model(nd, "stellaris");

    s = (stellaris_enet_state *)qemu_mallocz(sizeof(stellaris_enet_state));
    s->mmio_index = cpu_register_io_memory(0, stellaris_enet_readfn,
                                           stellaris_enet_writefn, s);
    cpu_register_physical_memory(base, 0x00001000, s->mmio_index);
    s->irq = irq;
    memcpy(s->macaddr, nd->macaddr, 6);

    if (nd->vlan) {
        s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
                                     stellaris_enet_receive,
                                     stellaris_enet_can_receive,
                                     stellaris_enet_cleanup, s);
        qemu_format_nic_info_str(s->vc, s->macaddr);
    }

    stellaris_enet_reset(s);
    register_savevm("stellaris_enet", -1, 1,
                    stellaris_enet_save, stellaris_enet_load, s);
}
