/*
 * 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 "qemu/osdep.h"
#include "libqtest-single.h"
#include "libqos/pci-pc.h"
#include "qemu/timer.h"

static int verbosity_level;

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

#define CLK 33333333

static QPCIBus *pcibus;
static QPCIDevice *dev;
static QPCIBar dev_bar;

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_new_pc(global_qtest, NULL);
    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_bar, (val));     \
    if (verbosity_level >= 2) { \
        g_test_message("*%s -> %x", #name, res); \
    } \
    return res; \
} \
static void out_##name(unsigned v) \
{ \
    if (verbosity_level >= 2) { \
        g_test_message("%x -> *%s", v, #name); \
    } \
    qpci_io_write##len(dev, dev_bar, (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 * NANOSECONDS_PER_SECOND);
        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 * NANOSECONDS_PER_SECOND);
    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 * NANOSECONDS_PER_SECOND);
    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 * NANOSECONDS_PER_SECOND);
        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!");
}


static void test_init(void)
{
    uint64_t barsize;

    dev = get_device();

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

    qpci_device_enable(dev);

    test_timer();
}

int main(int argc, char **argv)
{
    int ret;
    char *v_env = getenv("V");

    if (v_env) {
        verbosity_level = atoi(v_env);
    }

    g_test_init(&argc, &argv, NULL);

    if (!qtest_has_device("rtl8139")) {
        return 0;
    }

    qtest_start("-device rtl8139");

    qtest_add_func("/rtl8139/nop", nop);
    qtest_add_func("/rtl8139/timer", test_init);

    ret = g_test_run();

    qtest_end();

    return ret;
}
