// Copyright 2017 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 <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/protocol/ethernet.h>

#include <fuchsia/hardware/ethernet/c/fidl.h>

#include <zircon/assert.h>
#include <zircon/listnode.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/thread_annotations.h>
#include <zircon/types.h>

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>

#define FIFO_DEPTH 256
#define FIFO_ESIZE sizeof(fuchsia_hardware_ethernet_FifoEntry)

#define PAGE_MASK (PAGE_SIZE - 1)

// This is used for signaling that eth_tx_thread() should exit.
static const zx_signals_t kSignalFifoTerminate = ZX_USER_SIGNAL_0;

// ensure that we will not exceed fifo capacity
static_assert((FIFO_DEPTH * FIFO_ESIZE) <= 4096, "");

// ethernet device
typedef struct ethdev0 {
    // shared state
    zx_device_t* macdev;
    ethmac_protocol_t mac;
    uint32_t state;

    mtx_t lock;

    // active and idle instances (ethdev_t)
    list_node_t list_active;
    list_node_t list_idle;

    int32_t promisc_requesters;
    int32_t multicast_promisc_requesters;

    ethmac_info_t info;
    uint32_t status;
    zx_device_t* zxdev;
} ethdev0_t;

// transmit thread has been created
#define ETHDEV_TX_THREAD (1u)

// connected to the ethmac and handling traffic
#define ETHDEV_RUNNING (2u)

// being destroyed
#define ETHDEV_DEAD (4u)

// This client should loopback tx packets to rx path
#define ETHDEV_TX_LOOPBACK (8u)

// This client wants to observe loopback tx packets
#define ETHDEV_TX_LISTEN (0x10u)

// This client has requested promisc mode
#define ETHDEV_PROMISC (0x20u)

// This client has requested multicast promisc mode
#define ETHDEV_MULTICAST_PROMISC (0x40u)

// Number of empty fifo entries to read at a time
#define FIFO_BATCH_SZ 32

// How many multicast addresses to remember before punting and turning on multicast-promiscuous
// TODO(eventually): enable deleting addresses
// If this value is changed, change the EthernetMulticastPromiscOnOverflow() test in
//   zircon/system/utest/ethernet/ethernet.cpp
#define MULTICAST_LIST_LIMIT (32)

// ethernet instance device
typedef struct ethdev {
    list_node_t node;

    ethdev0_t* edev0;

    uint32_t state;
    char name[fuchsia_hardware_ethernet_MAX_CLIENT_NAME_LEN + 1];

    // fifos are named from the perspective
    // of the packet from from the client
    // to the network interface
    zx_handle_t tx_fifo;
    uint32_t tx_depth;
    zx_handle_t rx_fifo;
    uint32_t rx_depth;
    fuchsia_hardware_ethernet_FifoEntry rx_entries[FIFO_BATCH_SZ];
    size_t rx_entry_count;

    // io buffer
    zx_handle_t io_vmo;
    void* io_buf;
    size_t io_size;
    zx_paddr_t* paddr_map;
    zx_handle_t pmt;

    // FIFO_DEPTH entries, each |tx_size| large.
    void *all_tx_bufs;
    size_t tx_size;

    mtx_t lock;               // Protects free_tx_bufs
    list_node_t free_tx_bufs; // tx_info_t elements

    // fifo thread
    thrd_t tx_thr;

    zx_device_t* zxdev;

    uint8_t multicast[MULTICAST_LIST_LIMIT][ETH_MAC_SIZE];
    uint32_t n_multicast;

    uint32_t fail_rx_read;
    uint32_t fail_rx_write;
    uint32_t fail_tx_write;
} ethdev_t;

#define FAIL_REPORT_RATE 50

typedef struct tx_info {
    struct ethdev* edev;
    uint64_t fifo_cookie;
    list_node_t node;
} tx_info_t;

static tx_info_t* netbuf_to_tx_info(ethdev0_t* edev0, ethmac_netbuf_t* netbuf) {
    return (tx_info_t*)((uintptr_t)netbuf + edev0->info.netbuf_size);
}

static ethmac_netbuf_t* tx_info_to_netbuf(ethdev0_t* edev0, tx_info_t* tx_info) {
    return (ethmac_netbuf_t*)((uintptr_t)tx_info - edev0->info.netbuf_size);
}

static ssize_t eth_promisc_helper_logic_locked(ethdev_t* edev, bool req_on, uint32_t state_bit,
                                               uint32_t param_id, int32_t* requesters_count) {
    if (state_bit == 0 || state_bit & (state_bit - 1)) {
        return ZX_ERR_INVALID_ARGS;
    }
    if (!req_on == !(edev->state & state_bit)) {
        return ZX_OK; // Duplicate request
    }
    ethdev0_t* edev0 = edev->edev0;
    zx_status_t status = ZX_OK;
    if (req_on) {
        (*requesters_count)++;
        edev->state |= state_bit;
        if (*requesters_count == 1) {
            status = ethmac_set_param(&edev0->mac, param_id, true, NULL, 0);
            if (status != ZX_OK) {
                (*requesters_count)--;
                edev->state &= ~state_bit;
            }
        }
    } else {
        (*requesters_count)--;
        edev->state &= ~state_bit;
        if (*requesters_count == 0) {
            status = ethmac_set_param(&edev0->mac, param_id, false, NULL, 0);
            if (status != ZX_OK) {
                (*requesters_count)++;
                edev->state |= state_bit;
            }
        }
    }
    return status;
}

static ssize_t eth_set_promisc_locked(ethdev_t* edev, bool req_on) {
    return eth_promisc_helper_logic_locked(edev, req_on, ETHDEV_PROMISC,
                                           ETHMAC_SETPARAM_PROMISC,
                                           &edev->edev0->promisc_requesters);
}

static ssize_t eth_set_multicast_promisc_locked(ethdev_t* edev, bool req_on) {
    return eth_promisc_helper_logic_locked(edev, req_on, ETHDEV_MULTICAST_PROMISC,
                                           ETHMAC_SETPARAM_MULTICAST_PROMISC,
                                           &edev->edev0->multicast_promisc_requesters);
}

static ssize_t eth_rebuild_multicast_filter_locked(ethdev_t* edev) {
    ethdev0_t* edev0 = edev->edev0;
    uint8_t multicast[MULTICAST_LIST_LIMIT][ETH_MAC_SIZE];
    uint32_t n_multicast = 0;
    ethdev_t* edev_i;
    list_for_every_entry(&edev0->list_active, edev_i, ethdev_t, node) {
        for (uint32_t i = 0; i < edev_i->n_multicast; i++) {
            if (n_multicast == MULTICAST_LIST_LIMIT) {
                return ethmac_set_param(&edev0->mac, ETHMAC_SETPARAM_MULTICAST_FILTER,
                                        ETHMAC_MULTICAST_FILTER_OVERFLOW, NULL, 0);
            }
            memcpy(multicast[n_multicast], edev_i->multicast[i], ETH_MAC_SIZE);
            n_multicast++;
        }
    }
    return ethmac_set_param(&edev0->mac, ETHMAC_SETPARAM_MULTICAST_FILTER, n_multicast, multicast,
                            n_multicast * ETH_MAC_SIZE);
}

static int eth_multicast_addr_index(ethdev_t* edev, const uint8_t* mac) {
    for (uint32_t i = 0; i < edev->n_multicast; i++) {
        if (!memcmp(edev->multicast[i], mac, ETH_MAC_SIZE)) {
            return i;
        }
    }
    return -1;
}

static ssize_t eth_add_multicast_address_locked(ethdev_t* edev, const uint8_t* mac) {
    if (!(mac[0] & 1)) {
        return ZX_ERR_INVALID_ARGS;
    }
    if (eth_multicast_addr_index(edev, mac) != -1) {
        return ZX_OK;
    }
    if (edev->n_multicast < MULTICAST_LIST_LIMIT) {
        memcpy(edev->multicast[edev->n_multicast], mac, ETH_MAC_SIZE);
        edev->n_multicast++;
        return eth_rebuild_multicast_filter_locked(edev);
    } else {
        ethdev0_t* edev0 = edev->edev0;
        return ethmac_set_param(&edev0->mac, ETHMAC_SETPARAM_MULTICAST_FILTER,
                                ETHMAC_MULTICAST_FILTER_OVERFLOW, NULL, 0);
    }
    return ZX_OK;
}

static ssize_t eth_del_multicast_address_locked(ethdev_t* edev, const uint8_t* mac) {
    int ix = eth_multicast_addr_index(edev, mac);
    if (ix == -1) {
        // We may have overflowed the list and not remember an address. Nothing will go wrong if
        // they try to stop listening to an address they never added.
        return ZX_OK;
    }
    edev->n_multicast--;
    memcpy(&edev->multicast[ix], &edev->multicast[edev->n_multicast], ETH_MAC_SIZE);
    return eth_rebuild_multicast_filter_locked(edev);
}

static ssize_t eth_test_clear_multicast_promisc_locked(ethdev_t* edev) {
    zx_status_t status = ZX_OK;
    ethdev_t* edev_i;
    list_for_every_entry(&edev->edev0->list_active, edev_i, ethdev_t, node) {
        if ((status = eth_set_multicast_promisc_locked(edev_i, false)) != ZX_OK) {
            return status;
        }
    }
    return status;
}

static void eth_handle_rx(ethdev_t* edev, const void* data, size_t len, uint32_t extra) {
    zx_status_t status;
    size_t count;

    if (edev->rx_entry_count == 0) {
        status = zx_fifo_read(edev->rx_fifo, sizeof(edev->rx_entries[0]), edev->rx_entries,
                              countof(edev->rx_entries), &count);
        if (status != ZX_OK) {
            if (status == ZX_ERR_SHOULD_WAIT) {
                if ((edev->fail_rx_read++ % FAIL_REPORT_RATE) == 0) {
                    zxlogf(ERROR, "eth [%s]: no rx buffers available (%u times)\n",
                           edev->name, edev->fail_rx_read);
                }
            } else {
                // Fatal, should force teardown
                zxlogf(ERROR, "eth [%s]: rx fifo read failed %d\n", edev->name, status);
            }
            return;
        }
        edev->rx_entry_count = count;
    }

    fuchsia_hardware_ethernet_FifoEntry* e = &edev->rx_entries[--edev->rx_entry_count];
    if ((e->offset >= edev->io_size) || ((e->length > (edev->io_size - e->offset)))) {
        // invalid offset/length. report error. drop packet
        e->length = 0;
        e->flags = fuchsia_hardware_ethernet_FIFO_INVALID;
    } else if (len > e->length) {
        e->length = 0;
        e->flags = fuchsia_hardware_ethernet_FIFO_INVALID;
    } else {
        // packet fits. deliver it
        memcpy(edev->io_buf + e->offset, data, len);
        e->length = len;
        e->flags = fuchsia_hardware_ethernet_FIFO_RX_OK | extra;
    }

    if ((status = zx_fifo_write(edev->rx_fifo, sizeof(*e), e, 1, NULL)) < 0) {
        if (status == ZX_ERR_SHOULD_WAIT) {
            if ((edev->fail_rx_write++ % FAIL_REPORT_RATE) == 0) {
                zxlogf(ERROR, "eth [%s]: no rx_fifo space available (%u times)\n",
                       edev->name, edev->fail_rx_write);
            }
        } else {
            // Fatal, should force teardown
            zxlogf(ERROR, "eth [%s]: rx_fifo write failed %d\n", edev->name, status);
        }
        return;
    }
}

static void eth0_status(void* cookie, uint32_t status) {
    zxlogf(TRACE, "eth: status() %08x\n", status);

    ethdev0_t* edev0 = cookie;
    mtx_lock(&edev0->lock);

    static_assert(ETHMAC_STATUS_ONLINE == fuchsia_hardware_ethernet_DEVICE_STATUS_ONLINE, "");
    edev0->status = status;

    static_assert(fuchsia_hardware_ethernet_SIGNAL_STATUS == ZX_USER_SIGNAL_0, "");
    ethdev_t* edev;
    list_for_every_entry(&edev0->list_active, edev, ethdev_t, node) {
        zx_object_signal_peer(edev->rx_fifo, 0, fuchsia_hardware_ethernet_SIGNAL_STATUS);
    }
    mtx_unlock(&edev0->lock);
}

static int tx_fifo_write(ethdev_t* edev, fuchsia_hardware_ethernet_FifoEntry* entries,
                         size_t count) {
    zx_status_t status;
    size_t actual;
    // Writing should never fail, or fail to write all entries
    status = zx_fifo_write(edev->tx_fifo, sizeof(fuchsia_hardware_ethernet_FifoEntry), entries,
                           count, &actual);
    if (status < 0) {
        zxlogf(ERROR, "eth [%s]: tx_fifo write failed %d\n", edev->name, status);
        return -1;
    }
    if (actual != count) {
        zxlogf(ERROR, "eth [%s]: tx_fifo: only wrote %zu of %zu!\n", edev->name, actual, count);
        return -1;
    }
    return 0;
}

// TODO: I think if this arrives at the wrong time during teardown we
// can deadlock with the ethermac device
static void eth0_recv(void* cookie, const void* data, size_t len, uint32_t flags) {
    ethdev0_t* edev0 = cookie;

    ethdev_t* edev;
    mtx_lock(&edev0->lock);
    list_for_every_entry(&edev0->list_active, edev, ethdev_t, node) {
        eth_handle_rx(edev, data, len, 0);
    }
    mtx_unlock(&edev0->lock);
}

// Borrows a TX buffer from the pool. Logs and returns NULL if none is available
static tx_info_t* eth_get_tx_info(ethdev_t* edev) {
    mtx_lock(&edev->lock);
    tx_info_t* tx_info = list_remove_head_type(&edev->free_tx_bufs, tx_info_t, node);
    mtx_unlock(&edev->lock);
    if (tx_info == NULL) {
        zxlogf(ERROR, "eth [%s]: tx_info pool empty\n", edev->name);
    }
    return tx_info;
}

// Returns a TX buffer to the pool
static void eth_put_tx_info(ethdev_t* edev, tx_info_t* tx_info) {
    mtx_lock(&edev->lock);
    list_add_head(&edev->free_tx_bufs, &tx_info->node);
    mtx_unlock(&edev->lock);
}

static void eth0_complete_tx(void* cookie, ethmac_netbuf_t* netbuf, zx_status_t status) {
    ethdev0_t* edev0 = cookie;
    tx_info_t* tx_info = netbuf_to_tx_info(edev0, netbuf);
    ethdev_t* edev = tx_info->edev;
    fuchsia_hardware_ethernet_FifoEntry entry = {
        .offset = netbuf->data_buffer - edev->io_buf,
        .length = netbuf->data_size,
        .flags = status == ZX_OK ? fuchsia_hardware_ethernet_FIFO_TX_OK : 0,
        .cookie = tx_info->fifo_cookie};

    // Now that we've copied all pertinent data from the netbuf, return it to the free list so
    // it is available immediately for the next request.
    eth_put_tx_info(edev, tx_info);

    // Send the entry back to the client
    tx_fifo_write(edev, &entry, 1);
}

static ethmac_ifc_ops_t ethmac_ifc = {
    .status = eth0_status,
    .recv = eth0_recv,
    .complete_tx = eth0_complete_tx,
};

static void eth_tx_echo(ethdev0_t* edev0, const void* data, size_t len) {
    ethdev_t* edev;
    mtx_lock(&edev0->lock);
    list_for_every_entry(&edev0->list_active, edev, ethdev_t, node) {
        if (edev->state & ETHDEV_TX_LISTEN) {
            eth_handle_rx(edev, data, len, fuchsia_hardware_ethernet_FIFO_RX_TX);
        }
    }
    mtx_unlock(&edev0->lock);
}

static zx_status_t eth_tx_listen_locked(ethdev_t* edev, bool yes) {
    ethdev0_t* edev0 = edev->edev0;

    // update our state
    if (yes) {
        edev->state |= ETHDEV_TX_LISTEN;
    } else {
        edev->state &= (~ETHDEV_TX_LISTEN);
    }

    // determine global state
    yes = false;
    list_for_every_entry(&edev0->list_active, edev, ethdev_t, node) {
        if (edev->state & ETHDEV_TX_LISTEN) {
            yes = true;
        }
    }

    // set everyone's echo flag based on global state
    list_for_every_entry(&edev0->list_active, edev, ethdev_t, node) {
        if (yes) {
            edev->state |= ETHDEV_TX_LOOPBACK;
        } else {
            edev->state &= (~ETHDEV_TX_LOOPBACK);
        }
    }

    return ZX_OK;
}

// The array of entries is invalidated after the call
static int eth_send(ethdev_t* edev, fuchsia_hardware_ethernet_FifoEntry* entries, uint32_t count) {
    tx_info_t* tx_info = NULL;
    ethdev0_t* edev0 = edev->edev0;
    // The entries that we can't send back to the fifo immediately are filtered
    // out in-place using a classic algorithm a-la "std::remove_if".
    // Once the loop finishes, the first 'to_write' entries in the array
    // will be written back to the fifo. The rest will be written later by
    // the eth0_complete_tx callback.
    uint32_t to_write = 0;
    for (fuchsia_hardware_ethernet_FifoEntry* e = entries; count > 0; e++) {
        if ((e->offset > edev->io_size) || ((e->length > (edev->io_size - e->offset)))) {
            e->flags = fuchsia_hardware_ethernet_FIFO_INVALID;
            entries[to_write++] = *e;
        } else {
            zx_status_t status;
            if (tx_info == NULL) {
                tx_info = eth_get_tx_info(edev);
                if (tx_info == NULL) {
                    return -1;
                }
            }
            uint32_t opts = count > 1 ? ETHMAC_TX_OPT_MORE : 0u;
            if (opts) {
                zxlogf(SPEW, "setting OPT_MORE (%u packets to go)\n", count);
            }
            ethmac_netbuf_t* netbuf = tx_info_to_netbuf(edev0, tx_info);
            netbuf->data_buffer = edev->io_buf + e->offset;
            if (edev0->info.features & ETHMAC_FEATURE_DMA) {
                netbuf->phys = edev->paddr_map[e->offset / PAGE_SIZE] +
                                       (e->offset & PAGE_MASK);
            }
            netbuf->data_size = e->length;
            tx_info->fifo_cookie = e->cookie;
            status = ethmac_queue_tx(&edev0->mac, opts, netbuf);
            if (edev->state & ETHDEV_TX_LOOPBACK) {
                eth_tx_echo(edev0, edev->io_buf + e->offset, e->length);
            }
            if (status != ZX_ERR_SHOULD_WAIT) {
                // Transmission completed. To avoid extra mutex locking/unlocking,
                // we don't return the buffer to the pool immediately, but reuse
                // it on the next iteration of the loop.
                e->flags = status == ZX_OK ? fuchsia_hardware_ethernet_FIFO_TX_OK : 0;
                entries[to_write++] = *e;
            } else {
                // The ownership of the TX buffer is transferred to mac.ops->queue_tx().
                // We can't reuse it, so clear the pointer.
                tx_info = NULL;
            }
        }
        count--;
    }
    if (tx_info) {
        eth_put_tx_info(edev, tx_info);
    }
    if (to_write) {
        tx_fifo_write(edev, entries, to_write);
    }
    return 0;
}

static int eth_tx_thread(void* arg) {
    ethdev_t* edev = (ethdev_t*)arg;
    fuchsia_hardware_ethernet_FifoEntry entries[FIFO_DEPTH / 2];
    zx_status_t status;
    size_t count;

    for (;;) {
        if ((status = zx_fifo_read(edev->tx_fifo, sizeof(entries[0]), entries,
                                   countof(entries), &count)) < 0) {
            if (status == ZX_ERR_SHOULD_WAIT) {
                zx_signals_t observed;
                if ((status = zx_object_wait_one(edev->tx_fifo,
                                                 ZX_FIFO_READABLE |
                                                 ZX_FIFO_PEER_CLOSED |
                                                 kSignalFifoTerminate,
                                                 ZX_TIME_INFINITE,
                                                 &observed)) < 0) {
                    zxlogf(ERROR, "eth [%s]: tx_fifo: error waiting: %d\n", edev->name, status);
                    break;
                }
                if (observed & kSignalFifoTerminate)
                    break;
                continue;
            } else {
                zxlogf(ERROR, "eth [%s]: tx_fifo: cannot read: %d\n", edev->name, status);
                break;
            }
        }
        if (eth_send(edev, entries, count)) {
            break;
        }
    }

    zxlogf(INFO, "eth [%s]: tx_thread: exit: %d\n", edev->name, status);
    return 0;
}

static zx_status_t eth_get_fifos_locked(ethdev_t* edev,
                                        struct fuchsia_hardware_ethernet_Fifos* fifos) {
    zx_status_t status;
    if ((status = zx_fifo_create(FIFO_DEPTH, FIFO_ESIZE, 0, &fifos->tx, &edev->tx_fifo)) < 0) {
        zxlogf(ERROR, "eth_create  [%s]: failed to create tx fifo: %d\n", edev->name, status);
        return status;
    }
    if ((status = zx_fifo_create(FIFO_DEPTH, FIFO_ESIZE, 0, &fifos->rx, &edev->rx_fifo)) < 0) {
        zxlogf(ERROR, "eth_create  [%s]: failed to create rx fifo: %d\n", edev->name, status);
        zx_handle_close(fifos->tx);
        zx_handle_close(edev->tx_fifo);
        edev->tx_fifo = ZX_HANDLE_INVALID;
        return status;
    }

    edev->tx_depth = FIFO_DEPTH;
    edev->rx_depth = FIFO_DEPTH;
    fifos->tx_depth = FIFO_DEPTH;
    fifos->rx_depth = FIFO_DEPTH;

    return ZX_OK;
}

static ssize_t eth_set_iobuf_locked(ethdev_t* edev, zx_handle_t vmo) {
    if (edev->io_vmo != ZX_HANDLE_INVALID || edev->io_buf != NULL) {
        return ZX_ERR_ALREADY_BOUND;
    }

    size_t size;
    zx_status_t status;

    if ((status = zx_vmo_get_size(vmo, &size)) < 0) {
        zxlogf(ERROR, "eth [%s]: could not get io_buf size: %d\n", edev->name, status);
        goto fail;
    }

    if ((status = zx_vmar_map(zx_vmar_root_self(),
                              ZX_VM_PERM_READ | ZX_VM_PERM_WRITE |
                              ZX_VM_REQUIRE_NON_RESIZABLE,
                              0, vmo, 0, size, (uintptr_t*)&edev->io_buf)) < 0) {
        zxlogf(ERROR, "eth [%s]: could not map io_buf: %d\n", edev->name, status);
        goto fail;
    }

    // If the driver indicates that it will be doing DMA to/from the vmo,
    // we pin the memory and cache the physical address list
    if (edev->edev0->info.features & ETHMAC_FEATURE_DMA) {
        size_t pages = ROUNDUP(size, PAGE_SIZE) / PAGE_SIZE;
        edev->paddr_map = malloc(pages * sizeof(zx_paddr_t));
        if (!edev->paddr_map) {
            status = ZX_ERR_NO_MEMORY;
            goto fail;
        }
        zx_handle_t bti = ZX_HANDLE_INVALID;
        ethmac_get_bti(&edev->edev0->mac, &bti);
        if (bti == ZX_HANDLE_INVALID) {
            status = ZX_ERR_INTERNAL;
            zxlogf(ERROR, "eth [%s]: ethmac_get_bti return invalid handle\n", edev->name);
            goto fail;
        }
        if ((status = zx_bti_pin(bti, ZX_BTI_PERM_READ | ZX_BTI_PERM_WRITE,
                                 vmo, 0, size, edev->paddr_map, pages, &edev->pmt)) != ZX_OK) {
            zxlogf(ERROR, "eth [%s]: bti_pin failed, can't pin vmo: %d\n",
                   edev->name, status);
            zx_handle_close(bti);
            goto fail;
        }
        zx_handle_close(bti);
    }
    edev->io_vmo = vmo;
    edev->io_size = size;

    return ZX_OK;

fail:
    if (edev->io_buf) {
        zx_status_t unmap_status =
            zx_vmar_unmap(zx_vmar_root_self(), (uintptr_t)edev->io_buf, size);
        if (unmap_status != ZX_OK) {
            zxlogf(ERROR, "eth [%s]: could not unmap io_buf: %d\n",
                   edev->name, unmap_status);
            status = unmap_status;
        }
        edev->io_buf = NULL;
    }
    free(edev->paddr_map);
    edev->paddr_map = NULL;
    zx_handle_close(vmo);
    return status;
}

// The thread safety analysis cannot reason through the aliasing of
// edev0 and edev->edev0, so disable it.
static zx_status_t eth_start_locked(ethdev_t* edev) TA_NO_THREAD_SAFETY_ANALYSIS {
    ethdev0_t* edev0 = edev->edev0;

    // Cannot start unless tx/rx rings are configured
    if ((edev->io_vmo == ZX_HANDLE_INVALID) ||
        (edev->tx_fifo == ZX_HANDLE_INVALID) ||
        (edev->rx_fifo == ZX_HANDLE_INVALID)) {
        return ZX_ERR_BAD_STATE;
    }

    if (edev->state & ETHDEV_RUNNING) {
        return ZX_OK;
    }

    if (!(edev->state & ETHDEV_TX_THREAD)) {
        int r = thrd_create_with_name(&edev->tx_thr, eth_tx_thread,
                                      edev, "eth-tx-thread");
        if (r != thrd_success) {
            zxlogf(ERROR, "eth [%s]: failed to start tx thread: %d\n", edev->name, r);
            return ZX_ERR_INTERNAL;
        }
        edev->state |= ETHDEV_TX_THREAD;
    }

    zx_status_t status;
    if (list_is_empty(&edev0->list_active)) {
        // Release the lock to allow other device operations in callback routine.
        // Re-acquire lock afterwards.
        mtx_unlock(&edev0->lock);
        status = ethmac_start(&edev->edev0->mac, edev0, &ethmac_ifc);
        mtx_lock(&edev0->lock);
        // Check whether unbind was called while we were unlocked.
        if (edev->state & ETHDEV_DEAD) {
            status = ZX_ERR_BAD_STATE;
        }
    } else {
        status = ZX_OK;
    }

    if (status == ZX_OK) {
        edev->state |= ETHDEV_RUNNING;
        list_delete(&edev->node);
        list_add_tail(&edev0->list_active, &edev->node);
        // TODO - After we get IGMP, don't automatically set multicast promisc true
        eth_set_multicast_promisc_locked(edev, true);
        // Trigger the status signal so the client will query the status at the start.
        zx_object_signal_peer(edev->rx_fifo, 0, fuchsia_hardware_ethernet_SIGNAL_STATUS);
    } else {
        zxlogf(ERROR, "eth [%s]: failed to start mac: %d\n", edev->name, status);
    }

    return status;
}

// The thread safety analysis cannot reason through the aliasing of
// edev0 and edev->edev0, so disable it.
static zx_status_t eth_stop_locked(ethdev_t* edev) TA_NO_THREAD_SAFETY_ANALYSIS {
    ethdev0_t* edev0 = edev->edev0;

    if (edev->state & ETHDEV_RUNNING) {
        edev->state &= (~ETHDEV_RUNNING);
        list_delete(&edev->node);
        list_add_tail(&edev0->list_idle, &edev->node);
        // The next three lines clean up promisc, multicast-promisc, and multicast-filter, in case
        // this ethdev had any state set. Ignore failures, which may come from drivers not
        // supporting the feature. (TODO: check failure codes).
        eth_set_promisc_locked(edev, false);
        eth_set_multicast_promisc_locked(edev, false);
        eth_rebuild_multicast_filter_locked(edev);
        if (list_is_empty(&edev0->list_active)) {
            if (!(edev->state & ETHDEV_DEAD)) {
                // Release the lock to allow other device operations in callback routine.
                // Re-acquire lock afterwards.
                mtx_unlock(&edev0->lock);
                ethmac_stop(&edev->edev0->mac);
                mtx_lock(&edev0->lock);
            }
        }
    }

    return ZX_OK;
}

static ssize_t eth_set_client_name_locked(ethdev_t* edev, const void* in_buf, size_t in_len) {
    if (in_len >= sizeof(edev->name)) {
        in_len = sizeof(edev->name) - 1;
    }
    memcpy(edev->name, in_buf, in_len);
    edev->name[in_len] = '\0';
    return ZX_OK;
}

static zx_status_t eth_get_status_locked(ethdev_t* edev, void* out_buf, size_t out_len,
                                         size_t* out_actual) {
    if (out_len < sizeof(uint32_t)) {
        return ZX_ERR_INVALID_ARGS;
    }
    if (edev->rx_fifo == ZX_HANDLE_INVALID) {
        return ZX_ERR_BAD_STATE;
    }
    if (zx_object_signal_peer(edev->rx_fifo, fuchsia_hardware_ethernet_SIGNAL_STATUS, 0) != ZX_OK) {
        return ZX_ERR_INTERNAL;
    }

    uint32_t* status = out_buf;
    *status = edev->edev0->status;
    *out_actual = sizeof(*status);
    return ZX_OK;
}

#define REPLY(x) fuchsia_hardware_ethernet_Device##x##_reply

static zx_status_t fidl_GetInfo_locked(void* ctx, fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    fuchsia_hardware_ethernet_Info info;
    memset(&info, 0, sizeof(info));
    memcpy(info.mac.octets, edev->edev0->info.mac, ETH_MAC_SIZE);
    if (edev->edev0->info.features & ETHMAC_FEATURE_WLAN) {
        info.features |= fuchsia_hardware_ethernet_INFO_FEATURE_WLAN;
    }
    if (edev->edev0->info.features & ETHMAC_FEATURE_SYNTH) {
        info.features |= fuchsia_hardware_ethernet_INFO_FEATURE_SYNTH;
    }
    info.mtu = edev->edev0->info.mtu;
    return REPLY(GetInfo)(txn, &info);
}

static zx_status_t fidl_GetFifos_locked(void* ctx, fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    fuchsia_hardware_ethernet_Fifos fifos;
    return REPLY(GetFifos)(txn, eth_get_fifos_locked(edev, &fifos), &fifos);
}

static zx_status_t fidl_SetIOBuffer_locked(void* ctx, zx_handle_t h, fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    return REPLY(SetIOBuffer)(txn, eth_set_iobuf_locked(edev, h));
}

static zx_status_t fidl_Start_locked(void* ctx, fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    return REPLY(Start)(txn, eth_start_locked(edev));
}

static zx_status_t fidl_Stop_locked(void* ctx, fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    eth_stop_locked(edev);
    return REPLY(Stop)(txn);
}

static zx_status_t fidl_ListenStart_locked(void* ctx, fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    return REPLY(ListenStart)(txn, eth_tx_listen_locked(edev, true));
}

static zx_status_t fidl_ListenStop_locked(void* ctx, fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    eth_tx_listen_locked(edev, false);
    return REPLY(ListenStop)(txn);
}

static zx_status_t fidl_SetClientName_locked(void* ctx, const char* buf, size_t len,
                                             fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    return REPLY(SetClientName)(txn, eth_set_client_name_locked(edev, buf, len));
}

static zx_status_t fidl_GetStatus_locked(void* ctx, fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    if (zx_object_signal_peer(edev->rx_fifo, fuchsia_hardware_ethernet_SIGNAL_STATUS, 0) != ZX_OK) {
        return ZX_ERR_INTERNAL;
    }
    return REPLY(GetStatus)(txn, edev->edev0->status);
}

static zx_status_t fidl_SetPromisc_locked(void* ctx, bool enabled, fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    return REPLY(SetPromiscuousMode)(txn, eth_set_promisc_locked(edev, enabled));
}

static zx_status_t
fidl_ConfigMulticastAddMac_locked(void* ctx, const fuchsia_hardware_ethernet_MacAddress* mac,
                                  fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    zx_status_t status = eth_add_multicast_address_locked(edev, mac->octets);
    return REPLY(ConfigMulticastAddMac)(txn, status);
}

static zx_status_t
fidl_ConfigMulticastDeleteMac_locked(void* ctx, const fuchsia_hardware_ethernet_MacAddress* mac,
                                     fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    zx_status_t status = eth_del_multicast_address_locked(edev, mac->octets);
    return REPLY(ConfigMulticastDeleteMac)(txn, status);
}

static zx_status_t fidl_ConfigMulticastSetPromiscuousMode_locked(void* ctx, bool enabled,
                                                                 fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    zx_status_t status = eth_set_multicast_promisc_locked(edev, enabled);
    return REPLY(ConfigMulticastSetPromiscuousMode)(txn, status);
}

static zx_status_t fidl_ConfigMulticastTestFilter_locked(void* ctx, fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    zxlogf(INFO,
           "MULTICAST_TEST_FILTER invoked. Turning multicast-promisc off unconditionally.\n");
    zx_status_t status = eth_test_clear_multicast_promisc_locked(edev);
    return REPLY(ConfigMulticastTestFilter)(txn, status);
}

static zx_status_t fidl_DumpRegisters_locked(void* ctx, fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    zx_status_t status = ethmac_set_param(&edev->edev0->mac, ETHMAC_SETPARAM_DUMP_REGS, 0, NULL, 0);
    return REPLY(DumpRegisters)(txn, status);
}

#undef REPLY

fuchsia_hardware_ethernet_Device_ops_t fidl_ops = {
    .GetInfo = fidl_GetInfo_locked,
    .GetFifos = fidl_GetFifos_locked,
    .SetIOBuffer = fidl_SetIOBuffer_locked,
    .Start = fidl_Start_locked,
    .Stop = fidl_Stop_locked,
    .ListenStart = fidl_ListenStart_locked,
    .ListenStop = fidl_ListenStop_locked,
    .SetClientName = fidl_SetClientName_locked,
    .GetStatus = fidl_GetStatus_locked,
    .SetPromiscuousMode = fidl_SetPromisc_locked,
    .ConfigMulticastAddMac = fidl_ConfigMulticastAddMac_locked,
    .ConfigMulticastDeleteMac = fidl_ConfigMulticastDeleteMac_locked,
    .ConfigMulticastSetPromiscuousMode = fidl_ConfigMulticastSetPromiscuousMode_locked,
    .ConfigMulticastTestFilter = fidl_ConfigMulticastTestFilter_locked,
    .DumpRegisters = fidl_DumpRegisters_locked,
};

static zx_status_t eth_message(void* ctx, fidl_msg_t* msg, fidl_txn_t* txn) {
    ethdev_t* edev = ctx;
    mtx_lock(&edev->edev0->lock);
    if (edev->state & ETHDEV_DEAD) {
        mtx_unlock(&edev->edev0->lock);
        return ZX_ERR_BAD_STATE;
    }
    zx_status_t status = fuchsia_hardware_ethernet_Device_dispatch(ctx, txn, msg, &fidl_ops);
    mtx_unlock(&edev->edev0->lock);
    return status;
}


// kill tx thread, release buffers, etc
// called from unbind and close
static void eth_kill_locked(ethdev_t* edev) {
    if (edev->state & ETHDEV_DEAD) {
        return;
    }

    zxlogf(TRACE, "eth [%s]: kill: tearing down%s\n",
           edev->name, (edev->state & ETHDEV_TX_THREAD) ? " tx thread" : "");
    eth_set_promisc_locked(edev, false);

    // make sure any future ioctls or other ops will fail
    edev->state |= ETHDEV_DEAD;

    // try to convince clients to close us
    if (edev->rx_fifo) {
        zx_handle_close(edev->rx_fifo);
        edev->rx_fifo = ZX_HANDLE_INVALID;
    }
    if (edev->tx_fifo) {
        // Ask the TX thread to exit.
        zx_object_signal(edev->tx_fifo, 0, kSignalFifoTerminate);
    }
    if (edev->io_vmo) {
        zx_handle_close(edev->io_vmo);
        edev->io_vmo = ZX_HANDLE_INVALID;
    }

    if (edev->state & ETHDEV_TX_THREAD) {
        edev->state &= (~ETHDEV_TX_THREAD);
        int ret;
        thrd_join(edev->tx_thr, &ret);
        zxlogf(TRACE, "eth [%s]: kill: tx thread exited\n", edev->name);
    }

    if (edev->tx_fifo) {
        zx_handle_close(edev->tx_fifo);
        edev->tx_fifo = ZX_HANDLE_INVALID;
    }

    if (edev->io_buf) {
        zx_status_t status =
            zx_vmar_unmap(zx_vmar_root_self(), (uintptr_t)edev->io_buf, edev->io_size);
        ZX_DEBUG_ASSERT(status == ZX_OK);
        edev->io_buf = NULL;
    }
    if (edev->paddr_map != NULL) {
        if (zx_pmt_unpin(edev->pmt) != ZX_OK) {
            zxlogf(ERROR, "eth [%s]: cannot unpin vmo?!\n", edev->name);
        }
        free(edev->paddr_map);
        edev->paddr_map = NULL;
        edev->pmt = ZX_HANDLE_INVALID;
    }
    zxlogf(TRACE, "eth [%s]: all resources released\n", edev->name);
}

static void eth_release(void* ctx) {
    ethdev_t* edev = ctx;
    if (edev) {
        free(edev->all_tx_bufs);
        free(edev->paddr_map);
    }
    free(edev);
}

static zx_status_t eth_close(void* ctx, uint32_t flags) {
    ethdev_t* edev = ctx;

    mtx_lock(&edev->edev0->lock);
    eth_stop_locked(edev);
    eth_kill_locked(edev);
    list_delete(&edev->node);
    mtx_unlock(&edev->edev0->lock);

    return ZX_OK;
}

static zx_protocol_device_t ethdev_ops = {
    .version = DEVICE_OPS_VERSION,
    .close = eth_close,
    .message = eth_message,
    .release = eth_release,
};

static zx_status_t eth0_open(void* ctx, zx_device_t** out, uint32_t flags) {
    ethdev0_t* edev0 = ctx;

    ethdev_t* edev;
    if ((edev = calloc(1, sizeof(ethdev_t))) == NULL) {
        return ZX_ERR_NO_MEMORY;
    }
    edev->edev0 = edev0;

    edev->tx_size = ROUNDUP(sizeof(tx_info_t) + edev0->info.netbuf_size, 8);
    if ((edev->all_tx_bufs = calloc(FIFO_DEPTH, edev->tx_size)) == NULL) {
        free(edev);
        return ZX_ERR_NO_MEMORY;
    }

    list_initialize(&edev->free_tx_bufs);
    for (size_t ndx = 0; ndx < FIFO_DEPTH; ndx++) {
        ethmac_netbuf_t* netbuf =
                (ethmac_netbuf_t*)((uintptr_t)edev->all_tx_bufs + (edev->tx_size * ndx));
        tx_info_t* tx_info = netbuf_to_tx_info(edev0, netbuf);
        tx_info->edev = edev;
        list_add_tail(&edev->free_tx_bufs, &tx_info->node);
    }
    mtx_init(&edev->lock, mtx_plain);

    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "ethernet",
        .ctx = edev,
        .ops = &ethdev_ops,
        .proto_id = ZX_PROTOCOL_ETHERNET,
        .flags = DEVICE_ADD_INSTANCE,
    };

    zx_status_t status;
    if ((status = device_add(edev0->zxdev, &args, &edev->zxdev)) < 0) {
        free(edev->all_tx_bufs);
        free(edev);
        return status;
    }

    mtx_lock(&edev0->lock);
    list_add_tail(&edev0->list_idle, &edev->node);
    mtx_unlock(&edev0->lock);

    *out = edev->zxdev;
    return ZX_OK;
}

static void eth0_unbind(void* ctx) {
    ethdev0_t* edev0 = ctx;

    mtx_lock(&edev0->lock);

    // tear down shared memory, fifos, and threads
    // to encourage any open instances to close
    ethdev_t* edev;
    list_for_every_entry(&edev0->list_active, edev, ethdev_t, node) {
        eth_kill_locked(edev);
    }
    list_for_every_entry(&edev0->list_idle, edev, ethdev_t, node) {
        eth_kill_locked(edev);
    }

    mtx_unlock(&edev0->lock);

    device_remove(edev0->zxdev);
}

static void eth0_release(void* ctx) {
    ethdev0_t* edev0 = ctx;
    free(edev0);
}

static zx_protocol_device_t ethdev0_ops = {
    .version = DEVICE_OPS_VERSION,
    .open = eth0_open,
    .unbind = eth0_unbind,
    .release = eth0_release,
};

static zx_status_t eth_bind(void* ctx, zx_device_t* dev) {
    ethdev0_t* edev0;
    if ((edev0 = calloc(1, sizeof(ethdev0_t))) == NULL) {
        return ZX_ERR_NO_MEMORY;
    }

    zx_status_t status;
    if (device_get_protocol(dev, ZX_PROTOCOL_ETHMAC, &edev0->mac)) {
        zxlogf(ERROR, "eth: bind: no ethermac protocol\n");
        status = ZX_ERR_INTERNAL;
        goto fail;
    }

    ethmac_protocol_ops_t* ops = edev0->mac.ops;
    if (ops->query == NULL || ops->stop == NULL || ops->start == NULL || ops->queue_tx == NULL ||
        ops->set_param == NULL) {
        zxlogf(ERROR, "eth: bind: device '%s': incomplete ethermac protocol\n",
               device_get_name(dev));
        status = ZX_ERR_NOT_SUPPORTED;
        goto fail;
    }

    if ((status = ethmac_query(&edev0->mac, 0, &edev0->info)) < 0) {
        zxlogf(ERROR, "eth: bind: ethermac query failed: %d\n", status);
        goto fail;
    }

    if ((edev0->info.features & ETHMAC_FEATURE_DMA) &&
        (ops->get_bti == NULL)) {
        zxlogf(ERROR, "eth: bind: device '%s': does not implement ops->get_bti()\n",
               device_get_name(dev));
        status = ZX_ERR_NOT_SUPPORTED;
        goto fail;
    }

    if (edev0->info.netbuf_size < sizeof(ethmac_netbuf_t)) {
        zxlogf(ERROR, "eth: bind: device '%s': invalid buffer size %ld\n",
               device_get_name(dev), edev0->info.netbuf_size);
        status = ZX_ERR_NOT_SUPPORTED;
        goto fail;
    }
    edev0->info.netbuf_size = ROUNDUP(edev0->info.netbuf_size, 8);

    mtx_init(&edev0->lock, mtx_plain);
    list_initialize(&edev0->list_active);
    list_initialize(&edev0->list_idle);

    edev0->macdev = dev;

    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "ethernet",
        .ctx = edev0,
        .ops = &ethdev0_ops,
        .proto_id = ZX_PROTOCOL_ETHERNET,
    };

    if ((status = device_add(dev, &args, &edev0->zxdev)) < 0) {
        goto fail;
    }

    return ZX_OK;

fail:
    free(edev0);
    return status;
}

static zx_driver_ops_t eth_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .bind = eth_bind,
};

// clang-format off
ZIRCON_DRIVER_BEGIN(ethernet, eth_driver_ops, "zircon", "0.1", 1)
    BI_MATCH_IF(EQ, BIND_PROTOCOL, ZX_PROTOCOL_ETHMAC),
ZIRCON_DRIVER_END(ethernet)
// clang-format on
