/*
 * QTest testcase for Realtek 8139 NIC
 *
 * Copyright (c) 2013-2014 SUSE LINUX Products GmbH
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include <glib.h>
#include <string.h>
#include "libqtest.h"
#include "libqos/pci-pc.h"
#include "qemu/osdep.h"
#include "qemu/timer.h"
#include "qemu-common.h"

/* Tests only initialization so far. TODO: Replace with functional tests */
static void nop(void)
{
}

#define CLK 33000000

static QPCIBus *pcibus;
static QPCIDevice *dev;
static void *dev_base;

static void save_fn(QPCIDevice *dev, int devfn, void *data)
{
    QPCIDevice **pdev = (QPCIDevice **) data;

    *pdev = dev;
}

static QPCIDevice *get_device(void)
{
    QPCIDevice *dev;

    pcibus = qpci_init_pc();
    qpci_device_foreach(pcibus, 0x10ec, 0x8139, save_fn, &dev);
    g_assert(dev != NULL);

    return dev;
}

#define PORT(name, len, val) \
static unsigned __attribute__((unused)) in_##name(void) \
{ \
    unsigned res = qpci_io_read##len(dev, dev_base+(val)); \
    g_test_message("*%s -> %x\n", #name, res); \
    return res; \
} \
static void out_##name(unsigned v) \
{ \
    g_test_message("%x -> *%s\n", v, #name); \
    qpci_io_write##len(dev, dev_base+(val), v); \
}

PORT(Timer, l, 0x48)
PORT(IntrMask, w, 0x3c)
PORT(IntrStatus, w, 0x3E)
PORT(TimerInt, l, 0x54)

#define fatal(...) do { g_test_message(__VA_ARGS__); g_assert(0); } while (0)

static void test_timer(void)
{
    const unsigned from = 0.95 * CLK;
    const unsigned to = 1.6 * CLK;
    unsigned prev, curr, next;
    unsigned cnt, diff;

    out_IntrMask(0);

    in_IntrStatus();
    in_Timer();
    in_Timer();

    /* Test 1. test counter continue and continue */
    out_TimerInt(0); /* disable timer */
    out_IntrStatus(0x4000);
    out_Timer(12345); /* reset timer to 0 */
    curr = in_Timer();
    if (curr > 0.1 * CLK) {
        fatal("time too big %u\n", curr);
    }
    for (cnt = 0; ; ) {
        clock_step(1 * NSEC_PER_SEC);
        prev = curr;
        curr = in_Timer();

        /* test skip is in a specific range */
        diff = (curr-prev) & 0xffffffffu;
        if (diff < from || diff > to) {
            fatal("Invalid diff %u (%u-%u)\n", diff, from, to);
        }
        if (curr < prev && ++cnt == 3) {
            break;
        }
    }

    /* Test 2. Check we didn't get an interrupt with TimerInt == 0 */
    if (in_IntrStatus() & 0x4000) {
        fatal("got an interrupt\n");
    }

    /* Test 3. Setting TimerInt to 1 and Timer to 0 get interrupt */
    out_TimerInt(1);
    out_Timer(0);
    clock_step(40);
    if ((in_IntrStatus() & 0x4000) == 0) {
        fatal("we should have an interrupt here!\n");
    }

    /* Test 3. Check acknowledge */
    out_IntrStatus(0x4000);
    if (in_IntrStatus() & 0x4000) {
        fatal("got an interrupt\n");
    }

    /* Test. Status set after Timer reset */
    out_Timer(0);
    out_TimerInt(0);
    out_IntrStatus(0x4000);
    curr = in_Timer();
    out_TimerInt(curr + 0.5 * CLK);
    clock_step(1 * NSEC_PER_SEC);
    out_Timer(0);
    if ((in_IntrStatus() & 0x4000) == 0) {
        fatal("we should have an interrupt here!\n");
    }

    /* Test. Status set after TimerInt reset */
    out_Timer(0);
    out_TimerInt(0);
    out_IntrStatus(0x4000);
    curr = in_Timer();
    out_TimerInt(curr + 0.5 * CLK);
    clock_step(1 * NSEC_PER_SEC);
    out_TimerInt(0);
    if ((in_IntrStatus() & 0x4000) == 0) {
        fatal("we should have an interrupt here!\n");
    }

    /* Test 4. Increment TimerInt we should see an interrupt */
    curr = in_Timer();
    next = curr + 5.0 * CLK;
    out_TimerInt(next);
    for (cnt = 0; ; ) {
        clock_step(1 * NSEC_PER_SEC);
        prev = curr;
        curr = in_Timer();
        diff = (curr-prev) & 0xffffffffu;
        if (diff < from || diff > to) {
            fatal("Invalid diff %u (%u-%u)\n", diff, from, to);
        }
        if (cnt < 3 && curr > next) {
            if ((in_IntrStatus() & 0x4000) == 0) {
                fatal("we should have an interrupt here!\n");
            }
            out_IntrStatus(0x4000);
            next = curr + 5.0 * CLK;
            out_TimerInt(next);
            if (++cnt == 3) {
                out_TimerInt(1);
            }
        /* Test 5. Second time we pass from 0 should see an interrupt */
        } else if (cnt >= 3 && curr < prev) {
            /* here we should have an interrupt */
            if ((in_IntrStatus() & 0x4000) == 0) {
                fatal("we should have an interrupt here!\n");
            }
            out_IntrStatus(0x4000);
            if (++cnt == 5) {
                break;
            }
        }
    }

    g_test_message("Everythink is ok!\n");
}


static void test_init(void)
{
    uint64_t barsize;

    dev = get_device();

    dev_base = qpci_iomap(dev, 0, &barsize);

    g_assert(dev_base != NULL);

    qpci_device_enable(dev);

    test_timer();
}

int main(int argc, char **argv)
{
    int ret;

    g_test_init(&argc, &argv, NULL);
    qtest_add_func("/rtl8139/nop", nop);
    qtest_add_func("/rtl8139/timer", test_init);

    qtest_start("-device rtl8139");
    ret = g_test_run();

    qtest_end();

    return ret;
}
