// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <efi/protocol/simple-network.h>

#include <inttypes.h>
#include <stdio.h>
#include <string.h>

#include <xefi.h>

#include "inet6.h"
#include "netifc.h"
#include "osboot.h"

static efi_simple_network_protocol* snp;

#define MAX_FILTER 8
static efi_mac_addr mcast_filters[MAX_FILTER];
static unsigned mcast_filter_count = 0;

// if nonzero, drop 1 in DROP_PACKETS packets at random
#define DROP_PACKETS 0

#if DROP_PACKETS > 0

//TODO: use libc random() once it's actually random

// Xorshift32 prng
typedef struct {
    uint32_t n;
} rand32_t;

static inline uint32_t rand32(rand32_t* state) {
    uint32_t n = state->n;
    n ^= (n << 13);
    n ^= (n >> 17);
    n ^= (n << 5);
    return (state->n = n);
}

rand32_t rstate = {.n = 0x8716253};
#define random() rand32(&rstate)

static int txc;
static int rxc;
#endif

#define NUM_BUFFER_PAGES 8
#define ETH_BUFFER_SIZE 1516
#define ETH_HEADER_SIZE 16
#define ETH_BUFFER_MAGIC 0x424201020304A7A7UL

typedef struct eth_buffer_t eth_buffer;
struct eth_buffer_t {
    uint64_t magic;
    eth_buffer* next;
    uint8_t data[0];
};

static efi_physical_addr eth_buffers_base = 0;
static eth_buffer* eth_buffers = NULL;
static int num_eth_buffers = 0;
static int eth_buffers_avail = 0;

void* eth_get_buffer(size_t sz) {
    eth_buffer* buf;
    if (sz > ETH_BUFFER_SIZE) {
        return NULL;
    }
    if (eth_buffers == NULL) {
        return NULL;
    }
    buf = eth_buffers;
    eth_buffers = buf->next;
    buf->next = NULL;
    eth_buffers_avail--;
    return buf->data;
}

void eth_put_buffer(void* data) {
    efi_physical_addr buf_paddr = (efi_physical_addr)data;
    if ((buf_paddr < eth_buffers_base)
        || (buf_paddr >= (eth_buffers_base + (NUM_BUFFER_PAGES * PAGE_SIZE)))) {
        printf("fatal: attempt to use buffer outside of allocated range\n");
        for (;;)
            ;
    }

    eth_buffer* buf = (void*)(buf_paddr & (~2047));
    if (buf->magic != ETH_BUFFER_MAGIC) {
        printf("fatal: eth buffer %p (from %p) bad magic %" PRIx64 "\n",
               buf, data, buf->magic);
        for (;;)
            ;
    }

    buf->next = eth_buffers;
    eth_buffers_avail++;
    eth_buffers = buf;
}

int eth_send(void* data, size_t len) {
#if DROP_PACKETS
    txc++;
    if ((random() % DROP_PACKETS) == 0) {
        printf("tx drop %d\n", txc);
        eth_put_buffer(data);
        return 0;
    }
#endif
    efi_status r;
    if ((r = snp->Transmit(snp, 0, len, (void*)data, NULL, NULL, NULL))) {
        eth_put_buffer(data);
        return -1;
    } else {
        return 0;
    }
}

void eth_dump_status(void) {
#ifdef VERBOSE
    printf("State/HwAdSz/HdrSz/MaxSz %d %d %d %d\n",
           snp->Mode->State, snp->Mode->HwAddressSize,
           snp->Mode->MediaHeaderSize, snp->Mode->MaxPacketSize);
    printf("RcvMask/RcvCfg/MaxMcast/NumMcast %d %d %d %d\n",
           snp->Mode->ReceiveFilterMask, snp->Mode->ReceiveFilterSetting,
           snp->Mode->MaxMCastFilterCount, snp->Mode->MCastFilterCount);
    uint8_t* x = snp->Mode->CurrentAddress.addr;
    printf("MacAddr %02x:%02x:%02x:%02x:%02x:%02x\n",
           x[0], x[1], x[2], x[3], x[4], x[5]);
    printf("SetMac/MultiTx/LinkDetect/Link %d %d %d %d\n",
           snp->Mode->MacAddressChangeable, snp->Mode->MultipleTxSupported,
           snp->Mode->MediaPresentSupported, snp->Mode->MediaPresent);
#endif
}

int eth_add_mcast_filter(const mac_addr* addr) {
    if (mcast_filter_count >= MAX_FILTER)
        return -1;
    if (mcast_filter_count >= snp->Mode->MaxMCastFilterCount)
        return -1;
    memcpy(mcast_filters + mcast_filter_count, addr, ETH_ADDR_LEN);
    mcast_filter_count++;
    return 0;
}

static efi_event net_timer = NULL;

#define TIMER_MS(n) (((uint64_t)(n)) * 10000UL)

void netifc_set_timer(uint32_t ms) {
    if (net_timer == 0) {
        return;
    }
    gBS->SetTimer(net_timer, TimerRelative, TIMER_MS(ms));
}

int netifc_timer_expired(void) {
    if (net_timer == 0) {
        return 0;
    }
    if (gBS->CheckEvent(net_timer) == EFI_SUCCESS) {
        return 1;
    }
    return 0;
}

/* Search the available network interfaces via SimpleNetworkProtocol handles
 * and find the first valid one with a Link detected */
efi_simple_network_protocol* netifc_find_available(void) {
    efi_boot_services* bs = gSys->BootServices;
    efi_status ret;
    efi_simple_network_protocol* cur_snp = NULL;
    efi_handle handles[32];
    char16_t *paths[32];
    size_t nic_cnt = 0;
    size_t sz = sizeof(handles);
    uint32_t last_parent = 0;
    uint32_t int_sts;
    void *tx_buf;

    /* Get the handles of all devices that provide SimpleNetworkProtocol interfaces */
    ret = bs->LocateHandle(ByProtocol, &SimpleNetworkProtocol, NULL, &sz, handles);
    if (ret != EFI_SUCCESS) {
        printf("Failed to locate network interfaces (%s)\n", xefi_strerror(ret));
        return NULL;
    }

    nic_cnt = sz / sizeof(efi_handle);
    for (size_t i = 0; i < nic_cnt; i++) {
        paths[i] = xefi_handle_to_str(handles[i]);
    }

    /* Iterate over our SNP list until we find one with an established link */
    for (size_t i = 0; i < nic_cnt; i++) {
         /* Check each interface once, but ignore any additional device paths a given interface
          * may provide. e1000 tends to add a path for ipv4 and ipv6 configuration information
          * for instance */
        if (i != last_parent) {
            if (memcmp(paths[i], paths[last_parent], strlen_16(paths[last_parent])) == 0) {
                continue;
            } else {
                last_parent = i;
            }
        }

        puts16(paths[i]);
        printf(": ");
        ret = bs->HandleProtocol(handles[i], &SimpleNetworkProtocol, (void**)&cur_snp);
        if (ret) {
            printf("Failed to open (%s)\n", xefi_strerror(ret));
            continue;
        }

        /* If a driver is provided by the firmware then it should be started already, but check
         * to make sure. This also covers the case where we're providing the AX88772 driver in-line
         * during this boot itself */
        ret = cur_snp->Start(cur_snp);
        if (EFI_ERROR(ret) && ret != EFI_ALREADY_STARTED) {
            printf("Failed to start (%s)", xefi_strerror(ret));
            goto link_fail;
        }

        if (ret != EFI_ALREADY_STARTED) {
            ret = cur_snp->Initialize(cur_snp, 0, 0);
            if (EFI_ERROR(ret)) {
                printf("Failed to initialize (%s)\n", xefi_strerror(ret));
                goto link_fail;
            }
        }

        /* Prod the driver to cache its current status. We don't need the status or buffer,
         * but some drivers appear to require the OPTIONAL parameters. */
        ret = cur_snp->GetStatus(cur_snp, &int_sts, &tx_buf);
        if (EFI_ERROR(ret)) {
            printf("Failed to read status (%s)\n", xefi_strerror(ret));
            goto link_fail;
        }

        /* With status cached, do we have a Link detected on the netifc? */
        if (!cur_snp->Mode->MediaPresent) {
            printf("No link detected\n");
            goto link_fail;
        }

        printf("Link detected!\n");
        return cur_snp;

link_fail:
        bs->CloseProtocol(handles[i], &SimpleNetworkProtocol, gImg, NULL);
        cur_snp = NULL;
    }

    return NULL;
}

int netifc_open(void) {
    efi_boot_services* bs = gSys->BootServices;
    efi_status ret;
    int j;

    bs->CreateEvent(EVT_TIMER, TPL_CALLBACK, NULL, NULL, &net_timer);

    snp = netifc_find_available();
    if (!snp) {
        printf("Failed to find a usable network interface\n");
        return -1;
    }

    if (bs->AllocatePages(AllocateAnyPages, EfiLoaderData, NUM_BUFFER_PAGES, &eth_buffers_base)) {
        printf("Failed to allocate net buffers\n");
        return -1;
    }

    num_eth_buffers = NUM_BUFFER_PAGES * 2;
    uint8_t* ptr = (void*)eth_buffers_base;
    for (ret = 0; ret < num_eth_buffers; ret++) {
        eth_buffer* buf = (void*)ptr;
        buf->magic = ETH_BUFFER_MAGIC;
        eth_put_buffer(buf);
        ptr += 2048;
    }

    ip6_init(snp->Mode->CurrentAddress.addr);

    ret = snp->ReceiveFilters(snp,
                            EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
                                EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST,
                            0, 0, mcast_filter_count, (void*)mcast_filters);
    if (ret) {
        printf("Failed to install multicast filters %s\n", xefi_strerror(ret));
        return -1;
    }

    eth_dump_status();

    if (snp->Mode->MCastFilterCount != mcast_filter_count) {
        printf("OOPS: expected %d filters, found %d\n",
               mcast_filter_count, snp->Mode->MCastFilterCount);
        goto force_promisc;
    }
    for (size_t i = 0; i < mcast_filter_count; i++) {
        //uint8_t *m = (void*) &mcast_filters[i];
        //printf("i=%d %02x %02x %02x %02x %02x %02x\n", i, m[0], m[1], m[2], m[3], m[4], m[5]);
        for (j = 0; j < mcast_filter_count; j++) {
            //m = (void*) &snp->Mode->MCastFilter[j];
            //printf("j=%d %02x %02x %02x %02x %02x %02x\n", j, m[0], m[1], m[2], m[3], m[4], m[5]);
            if (!memcmp(mcast_filters + i, &snp->Mode->MCastFilter[j], 6)) {
                goto found_it;
            }
        }
        printf("OOPS: filter #%zu missing\n", i);
        goto force_promisc;
    found_it:;
    }

    return 0;

force_promisc:
    ret = snp->ReceiveFilters(snp,
                            EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
                                EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS |
                                EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST,
                            0, 0, 0, NULL);
    if (ret) {
        printf("Failed to set promiscuous mode (%s)\n", xefi_strerror(ret));
        return -1;
    }
    return 0;
}

void netifc_close(void) {
    gBS->SetTimer(net_timer, TimerCancel, 0);
    gBS->CloseEvent(net_timer);
    snp->Shutdown(snp);
    snp->Stop(snp);
}

int netifc_active(void) {
    return (snp != 0);
}

void netifc_poll(void) {
    uint8_t data[1514];
    efi_status r;
    size_t hsz, bsz;
    uint32_t irq;
    void* txdone;

    if (eth_buffers_avail < num_eth_buffers) {
        // Only check for completion if we have operations in progress.
        // Otherwise, the result of GetStatus is unreliable. See ZX-759.
        if ((r = snp->GetStatus(snp, &irq, &txdone))) {
            return;
        }
        if (txdone) {
            // Check to make sure this is one of our buffers (see ZX-1516)
            efi_physical_addr buf_paddr = (efi_physical_addr)txdone;
            if ((buf_paddr >= eth_buffers_base)
                && (buf_paddr < (eth_buffers_base + (NUM_BUFFER_PAGES * PAGE_SIZE)))) {
                eth_put_buffer(txdone);
            }
        }
    }

    hsz = 0;
    bsz = sizeof(data);
    r = snp->Receive(snp, &hsz, &bsz, data, NULL, NULL, NULL);
    if (r != EFI_SUCCESS) {
        return;
    }

#if DROP_PACKETS
    rxc++;
    if ((random() % DROP_PACKETS) == 0) {
        printf("rx drop %d\n", rxc);
        return;
    }
#endif

#if TRACE
    printf("RX %02x:%02x:%02x:%02x:%02x:%02x < %02x:%02x:%02x:%02x:%02x:%02x %02x%02x %d\n",
            data[0], data[1], data[2], data[3], data[4], data[5],
            data[6], data[7], data[8], data[9], data[10], data[11],
            data[12], data[13], (int)(bsz - hsz));
#endif
    eth_recv(data, bsz);
}
