/*
 * 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 *pcidev;
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(pcidev, 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(pcidev, 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_not_reached(); } 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;

    pcidev = get_device();

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

    qpci_device_enable(pcidev);

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