// 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 "netifc.h"

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

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

#include "inet6.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;

  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 (int i = 0; i < num_eth_buffers; ++i) {
    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 (size_t 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))) {
      printf("no ops in progress \n");
      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);
}
