<commit_before>/*
 * Copyright (c) 2017, ETH Zurich.
 * All rights reserved.
 *
 * This file is distributed under the terms in the attached LICENSE file.
 * If you do not find this file, copies can be found by writing to:
 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
 */

// stdlib includes

// barrelfish includes

// lwip includes
#include "lwip/init.h"
#include "lwip/netif.h"
#include "lwip/ip.h"
#include "lwip/dhcp.h"
#include "lwip/prot/ethernet.h"
#include "lwip/timeouts.h"

#include <barrelfish/barrelfish.h>
#include <barrelfish/deferred.h>
#include <barrelfish/waitset.h>
#include <barrelfish/waitset_chan.h>

#include <net/net_filter.h>
#include <net_interfaces/flags.h>
#include "networking_internal.h"
#include "net_queue_internal.h"

struct net_state state = {0};
struct waitset_chanstate net_loopback_poll_channel;
struct deferred_event net_lwip_timer;

#define NETWORKING_DEFAULT_QUEUE_ID 0
#define NETWORKING_BUFFER_COUNT (4096 * 3)
#define NETWORKING_BUFFER_RX_POPULATE (4096 - 10)
#define NETWORKING_BUFFER_SIZE  2048


#define NETDEBUG_SUBSYSTEM "net"

/**
 * @brief obtains the default setting for initializaion of the driver
 *
 * @param queue     returns the queue to be used
 * @param cardname  returns the card name to be used
 *
 * @return SYS_ERR_OK on success, SKB_ERR_* on failure
 */
errval_t networking_get_defaults(uint64_t *queue, const char **cardname, uint32_t *flags)
{
    /* TODO: get the values from the SKB */

    *queue = NETWORKING_DEFAULT_QUEUE_ID;
    //*cardname = "e10k";
    *cardname = "sfn5122f";
    *flags = NET_FLAGS_POLLING | NET_FLAGS_BLOCKING_INIT;
    //*flags = NET_FLAGS_POLLING;

    return SYS_ERR_OK;
}

static void int_handler(void* args)
{
    struct net_state *st = devq_get_state(args);

    net_if_poll(&st->netif);
    net_lwip_timeout();
}

static void net_loopback_poll(void *arg)
{
    netif_poll_all();
    net_lwip_timeout();
}

void net_if_trigger_loopback(void)
{
    errval_t err;
    
    err = waitset_chan_trigger(&net_loopback_poll_channel);
    assert(err_is_ok(err));
}

void net_lwip_timeout(void)
{
    errval_t err;

    sys_check_timeouts();
    deferred_event_cancel(&net_lwip_timer);
    uint32_t delay = sys_timeouts_sleeptime();
    if (delay != 0xffffffff) {
        err = deferred_event_register(&net_lwip_timer, get_default_waitset(),
            delay * 1000, MKCLOSURE((void (*)(void *))net_lwip_timeout, NULL));
        assert(err_is_ok(err));
    }
}

/**
 * @brief creates a queue to the given card and the queueid
 *
 * @param cardname  network card to create the queue for
 * @param queueid   queueid of the network card
 * @param retqueue  returns the pointer to the queue
 *
 * @return SYS_ERR_OK on success, errval on failure
 */
errval_t networking_create_queue(const char *cardname, uint64_t* queueid,
                                 struct devq **retqueue)
{
    struct net_state *st = get_default_net_state();
    bool poll = st->flags & NET_FLAGS_POLLING;
    bool default_q = st->flags & NET_FLAGS_DEFAULT_QUEUE;
    return net_queue_internal_create(int_handler, cardname, queueid, default_q,
                                     poll, retqueue); 
}


static errval_t networking_poll_st(struct net_state *st)
{
    event_dispatch_non_block(get_default_waitset());
    if (st->flags & NET_FLAGS_POLLING) {
        return net_if_poll(&st->netif);
    } else {
        return event_dispatch_non_block(get_default_waitset());
    }
}

/**
 * @brief initializes the networking library with a given device queue
 *
 * @param st        the networking state to initialize
 * @param q         the device queue to initialize the networking on
 * @param flags     supplied initialization flags
 *<commit_msg>libnet: bugfix when using interrupts<commit_after>/*
 * Copyright (c) 2017, ETH Zurich.
 * All rights reserved.
 *
 * This file is distributed under the terms in the attached LICENSE file.
 * If you do not find this file, copies can be found by writing to:
 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
 */

// stdlib includes

// barrelfish includes

// lwip includes
#include "lwip/init.h"
#include "lwip/netif.h"
#include "lwip/ip.h"
#include "lwip/dhcp.h"
#include "lwip/prot/ethernet.h"
#include "lwip/timeouts.h"

#include <barrelfish/barrelfish.h>
#include <barrelfish/deferred.h>
#include <barrelfish/waitset.h>
#include <barrelfish/waitset_chan.h>

#include <net/net_filter.h>
#include <net_interfaces/flags.h>
#include "networking_internal.h"
#include "net_queue_internal.h"

struct net_state state = {0};
struct waitset_chanstate net_loopback_poll_channel;
struct deferred_event net_lwip_timer;

#define NETWORKING_DEFAULT_QUEUE_ID 0
#define NETWORKING_BUFFER_COUNT (4096 * 3)
#define NETWORKING_BUFFER_RX_POPULATE (4096 - 10)
#define NETWORKING_BUFFER_SIZE  2048


#define NETDEBUG_SUBSYSTEM "net"

/**
 * @brief obtains the default setting for initializaion of the driver
 *
 * @param queue     returns the queue to be used
 * @param cardname  returns the card name to be used
 *
 * @return SYS_ERR_OK on success, SKB_ERR_* on failure
 */
errval_t networking_get_defaults(uint64_t *queue, const char **cardname, uint32_t *flags)
{
    /* TODO: get the values from the SKB */

    *queue = NETWORKING_DEFAULT_QUEUE_ID;
    //*cardname = "e10k";
    *cardname = "sfn5122f";
    *flags = NET_FLAGS_POLLING | NET_FLAGS_BLOCKING_INIT;
    //*flags = NET_FLAGS_POLLING;

    return SYS_ERR_OK;
}

static void int_handler(void* args)
{
    struct net_state *st = devq_get_state(args);

    net_if_poll(&st->netif);
    net_lwip_timeout();
}

static void net_loopback_poll(void *arg)
{
    netif_poll_all();
    net_lwip_timeout();
}

void net_if_trigger_loopback(void)
{
    errval_t err;
    
    err = waitset_chan_trigger(&net_loopback_poll_channel);
    assert(err_is_ok(err));
}

void net_lwip_timeout(void)
{
    errval_t err;

    sys_check_timeouts();
    deferred_event_cancel(&net_lwip_timer);
    uint32_t delay = sys_timeouts_sleeptime();
    if (delay != 0xffffffff) {
        err = deferred_event_register(&net_lwip_timer, get_default_waitset(),
            delay * 1000, MKCLOSURE((void (*)(void *))net_lwip_timeout, NULL));
        assert(err_is_ok(err));
    }
}

/**
 * @brief creates a queue to the given card and the queueid
 *
 * @param cardname  network card to create the queue for
 * @param queueid   queueid of the network card
 * @param retqueue  returns the pointer to the queue
 *
 * @return SYS_ERR_OK on success, errval on failure
 */
errval_t networking_create_queue(const char *cardname, uint64_t* queueid,
                                 struct devq **retqueue)
{
    struct net_state *st = get_default_net_state();
    bool poll = st->flags & NET_FLAGS_POLLING;
    bool default_q = st->flags & NET_FLAGS_DEFAULT_QUEUE;
    return net_queue_internal_create(int_handler, cardname, queueid, default_q,
                                     poll, retqueue); 
}


static errval_t networking_poll_st(struct net_state *st)
{
    event_dispatch_non_block(get_default_waitset());
    if (st->flags & NET_FLAGS_POLLING) {
        return net_if_poll(&st->netif);
    } else {
        return event_dispatch(get_default_waitset());
    }
}

/**
 * @brief initializes the networking library with a given device queue
 *
 * @param st        the networking state to initialize
 * @param q         the device queue to initialize the networking on
 * @param flags     supplied initialization flags
 *
{'fraction_non_alphanumeric': 0.09790861862261889, 'fraction_numerical': 0.011988810443585986, 'mean_word_length': 3.8035828534868843, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7339498', 'n_tokens_mistral': 2655, 'n_tokens_neox': 2580, 'n_words': 662}