// Copyright 2018 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 "dwmac.h"
#include "dw-gmac-dma.h"
#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/metadata.h>
#include <ddk/platform-defs.h>
#include <ddk/protocol/ethernet/mac.h>
#include <ddk/protocol/platform-device-lib.h>
#include <ddk/protocol/platform/device.h>
#include <fbl/algorithm.h>
#include <fbl/auto_call.h>
#include <fbl/auto_lock.h>
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <hw/arch_ops.h>
#include <hw/reg.h>
#include <lib/fzl/vmar-manager.h>
#include <stdio.h>
#include <string.h>
#include <zircon/compiler.h>

namespace eth {

namespace {

// MMIO Indexes.
constexpr uint32_t kEthMacMmio = 0;

} // namespace

template <typename T, typename U>
static inline T* offset_ptr(U* ptr, size_t offset) {
    return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(ptr) + offset);
}

int DWMacDevice::Thread() {
    zxlogf(INFO, "ethmac started\n");

    zx_status_t status;
    while (true) {
        status = dma_irq_.wait(nullptr);
        if (!running_.load()) {
            status = ZX_OK;
            break;
        }
        if (status != ZX_OK) {
            zxlogf(ERROR, "dwmac: Interrupt error\n");
            break;
        }
        uint32_t stat = dwdma_regs_->status;
        dwdma_regs_->status = stat;

        if (stat & DMA_STATUS_GLI) {
            fbl::AutoLock lock(&lock_); //Note: limited scope of autolock
            UpdateLinkStatus();
        }
        if (stat & DMA_STATUS_RI) {
            ProcRxBuffer(stat);
        }
        if (stat & DMA_STATUS_AIS) {
            bus_errors_++;
            zxlogf(ERROR, "dwmac: abnormal interrupt %08x\n", stat);
        }
    }
    return status;
}

int DWMacDevice::WorkerThread() {

    // Note: Need to wait here for all PHY's to register
    //       their callbacks before proceeding further.
    //       Currently only supporting single PHY, we can add
    //       support for multiple PHY's easily when needed.
    sync_completion_wait(&cb_registered_signal_, ZX_TIME_INFINITE);

    // Configure the phy.
    cbs_.config_phy(cbs_.ctx, mac_);

    InitDevice();

    auto thunk = [](void* arg) -> int { return reinterpret_cast<DWMacDevice*>(arg)->Thread(); };

    running_.store(true);
    int ret = thrd_create_with_name(&thread_, thunk,
                                    this,
                                    "mac-thread");
    ZX_DEBUG_ASSERT(ret == thrd_success);

    zx_status_t status = DdkAdd("Designware MAC");
    if (status != ZX_OK) {
        zxlogf(ERROR, "dwmac: Could not create eth device: %d\n", status);
        return status;
    } else {
        zxlogf(INFO, "dwmac: Added dwMac device\n");
    }
    return status;
}

void DWMacDevice::UpdateLinkStatus() {
    bool temp = dwmac_regs_->rgmiistatus & GMAC_RGMII_STATUS_LNKSTS;
    if (temp != online_) {
        online_ = temp;
        if (ethmac_client_.is_valid()) {
            ethmac_client_.Status(online_ ? ETHMAC_STATUS_ONLINE : 0u);
        } else {
            zxlogf(ERROR, "dwmac: System not ready\n");
        }
    }
    if (online_) {
        dwmac_regs_->conf |= GMAC_CONF_TE | GMAC_CONF_RE;
    } else {
        dwmac_regs_->conf &= ~(GMAC_CONF_TE | GMAC_CONF_RE);
    }
    zxlogf(INFO, "dwmac: Link is now %s\n", online_ ? "up" : "down");
}

zx_status_t DWMacDevice::InitPdev() {

    zx_status_t status = device_get_protocol(parent_,
                                             ZX_PROTOCOL_PDEV,
                                             &pdev_);
    if (status != ZX_OK) {
        return status;
    }

    // Map mac control registers and dma control registers.
    status = pdev_.MapMmio(kEthMacMmio, &dwmac_regs_iobuff_);
    if (status != ZX_OK) {
        zxlogf(ERROR, "dwmac: could not map dwmac mmio: %d\n", status);
        return status;
    }

    dwmac_regs_ = static_cast<dw_mac_regs_t*>(dwmac_regs_iobuff_->get());
    dwdma_regs_ = offset_ptr<dw_dma_regs_t>(dwmac_regs_, DW_DMA_BASE_OFFSET);

    // Map dma interrupt.
    status = pdev_.GetInterrupt(0, &dma_irq_);
    if (status != ZX_OK) {
        zxlogf(ERROR, "dwmac: could not map dma interrupt\n");
        return status;
    }

    // Get our bti.
    status = pdev_.GetBti(0, &bti_);
    if (status != ZX_OK) {
        zxlogf(ERROR, "dwmac: could not obtain bti: %d\n", status);
        return status;
    }

    // Get ETH_BOARD protocol.
    if (!eth_board_.is_valid()) {
        zxlogf(ERROR, "dwmac: could not obtain ETH_BOARD protocol: %d\n", status);
        return status;
    }

    return status;
}


zx_status_t DWMacDevice::Create(zx_device_t* device) {
    auto mac_device = fbl::make_unique<DWMacDevice>(device);

    zx_status_t status = mac_device->InitPdev();
    if (status != ZX_OK) {
        return status;
    }

    // Reset the phy.
    mac_device->eth_board_.ResetPhy();

    // Get and cache the mac address.
    mac_device->GetMAC(device);

    // Reset the dma peripheral.
    mac_device->dwdma_regs_->busmode |= DMAMAC_SRST;
    uint32_t loop_count = 10;
    do {
        zx_nanosleep(zx_deadline_after(ZX_MSEC(10)));
        loop_count--;
    } while ((mac_device->dwdma_regs_->busmode & DMAMAC_SRST) && loop_count);
    if (!loop_count) {
        return ZX_ERR_TIMED_OUT;
    }

    // Mac address register was erased by the reset; set it!
    mac_device->dwmac_regs_->macaddr0hi = (mac_device->mac_[5] << 8) | (mac_device->mac_[4] << 0);
    mac_device->dwmac_regs_->macaddr0lo = (mac_device->mac_[3] << 24) | (mac_device->mac_[2] << 16)
    | (mac_device->mac_[1] << 8) | (mac_device->mac_[0] << 0);

    auto cleanup = fbl::MakeAutoCall([&]() { mac_device->ShutDown(); });

    status = mac_device->InitBuffers();
    if (status != ZX_OK)
        return status;

    sync_completion_reset(&mac_device->cb_registered_signal_);

    // Populate board specific information
    eth_dev_metadata_t phy_info;
    size_t actual;
    status = device_get_metadata(device, DEVICE_METADATA_PRIVATE, &phy_info,
                                 sizeof(eth_dev_metadata_t), &actual);
    if (status != ZX_OK || actual != sizeof(eth_dev_metadata_t)) {
        zxlogf(ERROR, "dwmac: Could not get PHY metadata %d\n", status);
        return status;
    }

    zx_device_prop_t props[] = {
        {BIND_PLATFORM_DEV_VID, 0, phy_info.vid},
        {BIND_PLATFORM_DEV_DID, 0, phy_info.did},
        {BIND_PLATFORM_DEV_PID, 0, phy_info.pid},
    };

    device_add_args_t phy_device_args = {};
    phy_device_args.version = DEVICE_ADD_ARGS_VERSION;
    phy_device_args.name = "eth_phy";
    phy_device_args.ops = &mac_device->ddk_device_proto_,
    phy_device_args.proto_id = ZX_PROTOCOL_ETH_MAC;
    phy_device_args.props = props;
    phy_device_args.prop_count = countof(props);
    phy_device_args.ctx = mac_device.get();
    phy_device_args.proto_ops = &mac_device->eth_mac_protocol_ops_;

    // TODO(braval): use proper device pointer, depending on how
    //               many PHY devices we have to load, from the metadata.
    zx_device_t* dev;
    status = device_add(device, &phy_device_args, &dev);
    if (status != ZX_OK) {
        zxlogf(ERROR, "dwmac: Could not create phy device: %d\n", status);

        return status;
    }

    auto worker_thunk = [](void* arg) -> int {
        return reinterpret_cast<DWMacDevice*>(arg)->WorkerThread();
    };

    int ret = thrd_create_with_name(&mac_device->worker_thread_, worker_thunk,
                                    reinterpret_cast<void*>(mac_device.get()),
                                    "mac-worker-thread");
    ZX_DEBUG_ASSERT(ret == thrd_success);

    cleanup.cancel();

    // mac_device intentionally leaked as it is now held by DevMgr.
    __UNUSED auto ptr = mac_device.release();
    return ZX_OK;
} // namespace eth

zx_status_t DWMacDevice::InitBuffers() {

    constexpr size_t kDescSize = ROUNDUP(2 * kNumDesc * sizeof(dw_dmadescr_t), PAGE_SIZE);

    constexpr size_t kBufSize = 2 * kNumDesc * kTxnBufSize;

    txn_buffer_ = PinnedBuffer::Create(kBufSize, bti_, ZX_CACHE_POLICY_CACHED);
    desc_buffer_ = PinnedBuffer::Create(kDescSize, bti_, ZX_CACHE_POLICY_UNCACHED);

    tx_buffer_ = static_cast<uint8_t*>(txn_buffer_->GetBaseAddress());
    zx_cache_flush(tx_buffer_, kBufSize, ZX_CACHE_FLUSH_DATA | ZX_CACHE_FLUSH_INVALIDATE);
    //rx buffer right after tx
    rx_buffer_ = &tx_buffer_[kBufSize / 2];

    tx_descriptors_ = static_cast<dw_dmadescr_t*>(desc_buffer_->GetBaseAddress());
    //rx descriptors right after tx
    rx_descriptors_ = &tx_descriptors_[kNumDesc];

    zx_paddr_t tmpaddr;

    // Initialize descriptors. Doing tx and rx all at once
    for (uint i = 0; i < kNumDesc; i++) {

        desc_buffer_->LookupPhys(((i + 1) % kNumDesc) * sizeof(dw_dmadescr_t), &tmpaddr);
        tx_descriptors_[i].dmamac_next = static_cast<uint32_t>(tmpaddr);

        txn_buffer_->LookupPhys(i * kTxnBufSize, &tmpaddr);
        tx_descriptors_[i].dmamac_addr = static_cast<uint32_t>(tmpaddr);
        tx_descriptors_[i].txrx_status = 0;
        tx_descriptors_[i].dmamac_cntl = DESC_TXCTRL_TXCHAIN;

        desc_buffer_->LookupPhys((((i + 1) % kNumDesc) + kNumDesc) * sizeof(dw_dmadescr_t),
                                 &tmpaddr);
        rx_descriptors_[i].dmamac_next = static_cast<uint32_t>(tmpaddr);

        txn_buffer_->LookupPhys((i + kNumDesc) * kTxnBufSize, &tmpaddr);
        rx_descriptors_[i].dmamac_addr = static_cast<uint32_t>(tmpaddr);
        rx_descriptors_[i].dmamac_cntl =
            (MAC_MAX_FRAME_SZ & DESC_RXCTRL_SIZE1MASK) |
            DESC_RXCTRL_RXCHAIN;

        rx_descriptors_[i].txrx_status = DESC_RXSTS_OWNBYDMA;
    }

    desc_buffer_->LookupPhys(0, &tmpaddr);
    dwdma_regs_->txdesclistaddr = static_cast<uint32_t>(tmpaddr);

    desc_buffer_->LookupPhys(kNumDesc * sizeof(dw_dmadescr_t), &tmpaddr);
    dwdma_regs_->rxdesclistaddr = static_cast<uint32_t>(tmpaddr);
    return ZX_OK;
}

void DWMacDevice::EthmacGetBti(zx::bti* bti) {
    bti_.duplicate(ZX_RIGHT_SAME_RIGHTS, bti);
}

zx_status_t DWMacDevice::EthMacMdioWrite(uint32_t reg, uint32_t val) {
    dwmac_regs_->miidata = val;

    uint32_t miiaddr = (mii_addr_ << MIIADDRSHIFT) |
                       (reg << MIIREGSHIFT) |
                       MII_WRITE;

    dwmac_regs_->miiaddr = miiaddr | MII_CLKRANGE_150_250M | MII_BUSY;

    zx_time_t deadline = zx_deadline_after(ZX_MSEC(3));
    do {
        if (!(dwmac_regs_->miiaddr & MII_BUSY)) {
            return ZX_OK;
        }
        zx_nanosleep(zx_deadline_after(ZX_USEC(10)));
    } while (zx_clock_get_monotonic() < deadline);
    return ZX_ERR_TIMED_OUT;
}

zx_status_t DWMacDevice::EthMacMdioRead(uint32_t reg, uint32_t* val) {
    uint32_t miiaddr = (mii_addr_ << MIIADDRSHIFT) |
                       (reg << MIIREGSHIFT);

    dwmac_regs_->miiaddr = miiaddr | MII_CLKRANGE_150_250M | MII_BUSY;

    zx_time_t deadline = zx_deadline_after(ZX_MSEC(3));
    do {
        if (!(dwmac_regs_->miiaddr & MII_BUSY)) {
            *val = dwmac_regs_->miidata;
            return ZX_OK;
        }
        zx_nanosleep(zx_deadline_after(ZX_USEC(10)));
    } while (zx_clock_get_monotonic() < deadline);
    return ZX_ERR_TIMED_OUT;
}

zx_status_t DWMacDevice::EthMacRegisterCallbacks(const eth_mac_callbacks_t* cbs) {
    if (cbs == nullptr) {
        return ZX_ERR_INVALID_ARGS;
    }

    cbs_ = *cbs;

    sync_completion_signal(&cb_registered_signal_);
    return ZX_OK;
}

DWMacDevice::DWMacDevice(zx_device_t* device)
    : ddk::Device<DWMacDevice, ddk::Unbindable>(device), pdev_(device), eth_board_(device) {}

void DWMacDevice::ReleaseBuffers() {
    //Unpin the memory used for the dma buffers
    if (txn_buffer_->UnPin() != ZX_OK) {
        zxlogf(ERROR, "dwmac: Error unpinning transaction buffers\n");
    }
    if (desc_buffer_->UnPin() != ZX_OK) {
        zxlogf(ERROR, "dwmac: Error unpinning description buffers\n");
    }
}

void DWMacDevice::DdkRelease() {
    zxlogf(INFO, "Ethmac release...\n");
    delete this;
}

void DWMacDevice::DdkUnbind() {
    zxlogf(INFO, "Ethmac DdkUnbind\n");
    ShutDown();
    DdkRemove();
}

zx_status_t DWMacDevice::ShutDown() {
    running_.store(false);
    dma_irq_.destroy();
    thrd_join(thread_, NULL);
    fbl::AutoLock lock(&lock_);
    online_ = false;
    ethmac_client_.clear();
    DeInitDevice();
    ReleaseBuffers();
    return ZX_OK;
}

zx_status_t DWMacDevice::GetMAC(zx_device_t* dev) {
    // look for MAC address device metadata
    // metadata is padded so we need buffer size > 6 bytes
    uint8_t buffer[16];
    size_t actual;
    zx_status_t status = device_get_metadata(dev, DEVICE_METADATA_MAC_ADDRESS, buffer,
                                             sizeof(buffer), &actual);
    if (status != ZX_OK || actual < 6) {
        zxlogf(ERROR, "dwmac: MAC address metadata load failed. Falling back on HW setting.");
        // read MAC address from hardware register
        uint32_t hi = dwmac_regs_->macaddr0hi;
        uint32_t lo = dwmac_regs_->macaddr0lo;

        /* Extract the MAC address from the high and low words */
        buffer[0] = static_cast<uint8_t>(lo & 0xff);
        buffer[1] = static_cast<uint8_t>((lo >> 8) & 0xff);
        buffer[2] = static_cast<uint8_t>((lo >> 16) & 0xff);
        buffer[3] = static_cast<uint8_t>((lo >> 24) & 0xff);
        buffer[4] = static_cast<uint8_t>(hi & 0xff);
        buffer[5] = static_cast<uint8_t>((hi >> 8) & 0xff);
    }

    zxlogf(INFO, "dwmac: MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
           buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
    memcpy(mac_, buffer, sizeof mac_);
    return ZX_OK;
}

zx_status_t DWMacDevice::EthmacQuery(uint32_t options, ethmac_info_t* info) {
    memset(info, 0, sizeof(*info));
    info->features = ETHMAC_FEATURE_DMA;
    info->mtu = 1500;
    memcpy(info->mac, mac_, sizeof info->mac);
    info->netbuf_size = sizeof(ethmac_netbuf_t);
    return ZX_OK;
}

void DWMacDevice::EthmacStop() {
    zxlogf(INFO, "Stopping Ethermac\n");
    fbl::AutoLock lock(&lock_);
    ethmac_client_.clear();
}

zx_status_t DWMacDevice::EthmacStart(const ethmac_ifc_t* ifc) {
    fbl::AutoLock lock(&lock_);

    if (ethmac_client_.is_valid()) {
        zxlogf(ERROR, "dwmac:  Already bound!!!");
        return ZX_ERR_ALREADY_BOUND;
    } else {
        ethmac_client_ = ddk::EthmacIfcClient(ifc);
        UpdateLinkStatus();
        zxlogf(INFO, "dwmac: Started\n");
    }
    return ZX_OK;
}

zx_status_t DWMacDevice::InitDevice() {

    dwdma_regs_->intenable = 0;
    dwdma_regs_->busmode = X8PBL | DMA_PBL;

    dwdma_regs_->opmode = DMA_OPMODE_TSF | DMA_OPMODE_RSF;

    dwdma_regs_->opmode |= DMA_OPMODE_SR | DMA_OPMODE_ST; //start tx and rx

    //Clear all the interrupt flags
    dwdma_regs_->status = ~0;

    //Enable Interrupts
    dwdma_regs_->intenable = DMA_INT_NIE | DMA_INT_AIE | DMA_INT_FBE |
                             DMA_INT_RIE | DMA_INT_RUE | DMA_INT_OVE |
                             DMA_INT_UNE | DMA_INT_TSE | DMA_INT_RSE;

    dwmac_regs_->macaddr1lo = 0;
    dwmac_regs_->macaddr1hi = 0;
    dwmac_regs_->hashtablehigh = 0xffffffff;
    dwmac_regs_->hashtablelow = 0xffffffff;

    //TODO - configure filters
    zxlogf(INFO, "macaddr0hi = %08x\n", dwmac_regs_->macaddr0hi);
    zxlogf(INFO, "macaddr0lo = %08x\n", dwmac_regs_->macaddr0lo);

    dwmac_regs_->framefilt |= (1 << 10) | (1 << 4) | (1 << 0); //promiscuous

    dwmac_regs_->conf = GMAC_CORE_INIT;

    return ZX_OK;
}

zx_status_t DWMacDevice::DeInitDevice() {
    //Disable Interrupts
    dwdma_regs_->intenable = 0;
    //Disable Transmit and Receive
    dwmac_regs_->conf &= ~(GMAC_CONF_TE | GMAC_CONF_RE);

    //reset the phy (hold in reset)
    //gpio_write(&gpios_[PHY_RESET], 0);

    //transmit and receive are not disables, safe to null descriptor list ptrs
    dwdma_regs_->txdesclistaddr = 0;
    dwdma_regs_->rxdesclistaddr = 0;

    return ZX_OK;
}

uint32_t DWMacDevice::DmaRxStatus() {
    return (dwdma_regs_->status & DMA_STATUS_RS_MASK) >> DMA_STATUS_RS_POS;
}

void DWMacDevice::ProcRxBuffer(uint32_t int_status) {
    while (true) {
        uint32_t pkt_stat = rx_descriptors_[curr_rx_buf_].txrx_status;

        if (pkt_stat & DESC_RXSTS_OWNBYDMA) {
            return;
        }
        size_t fr_len = (pkt_stat & DESC_RXSTS_FRMLENMSK) >> DESC_RXSTS_FRMLENSHFT;
        if (fr_len > kTxnBufSize) {
            zxlogf(ERROR, "dwmac: unsupported packet size received\n");
            return;
        }

        uint8_t* temptr = &rx_buffer_[curr_rx_buf_ * kTxnBufSize];

        zx_cache_flush(temptr, kTxnBufSize, ZX_CACHE_FLUSH_DATA | ZX_CACHE_FLUSH_INVALIDATE);

        { // limit scope of autolock
            fbl::AutoLock lock(&lock_);
            if ((ethmac_client_.is_valid())) {

                ethmac_client_.Recv(temptr, fr_len, 0);

            } else {
                zxlogf(ERROR, "Dropping bad packet\n");
            }
        };

        rx_descriptors_[curr_rx_buf_].txrx_status = DESC_RXSTS_OWNBYDMA;
        rx_packet_++;

        curr_rx_buf_ = (curr_rx_buf_ + 1) % kNumDesc;
        if (curr_rx_buf_ == 0) {
            loop_count_++;
        }
        dwdma_regs_->rxpolldemand = ~0;
    }
}

zx_status_t DWMacDevice::EthmacQueueTx(uint32_t options, ethmac_netbuf_t* netbuf) {

    { //Check to make sure we are ready to accept packets
        fbl::AutoLock lock(&lock_);
        if (!online_) {
            return ZX_ERR_UNAVAILABLE;
        }
    }

    if (netbuf->data_size > kTxnBufSize) {
        return ZX_ERR_INVALID_ARGS;
    }
    if (tx_descriptors_[curr_tx_buf_].txrx_status & DESC_TXSTS_OWNBYDMA) {
        zxlogf(ERROR, "TX buffer overrun@ %u\n", curr_tx_buf_);
        return ZX_ERR_UNAVAILABLE;
    }
    uint8_t* temptr = &tx_buffer_[curr_tx_buf_ * kTxnBufSize];

    memcpy(temptr, netbuf->data_buffer, netbuf->data_size);
    hw_mb();

    zx_cache_flush(temptr, netbuf->data_size, ZX_CACHE_FLUSH_DATA);

    // Descriptors are pre-iniitialized with the paddr of their corresponding
    // buffers, only need to setup the control and status fields.
    tx_descriptors_[curr_tx_buf_].dmamac_cntl =
        DESC_TXCTRL_TXINT |
        DESC_TXCTRL_TXLAST |
        DESC_TXCTRL_TXFIRST |
        DESC_TXCTRL_TXCHAIN |
        ((uint32_t)netbuf->data_size & DESC_TXCTRL_SIZE1MASK);

    tx_descriptors_[curr_tx_buf_].txrx_status = DESC_TXSTS_OWNBYDMA;
    curr_tx_buf_ = (curr_tx_buf_ + 1) % kNumDesc;

    hw_mb();
    dwdma_regs_->txpolldemand = ~0;
    tx_counter_++;
    return ZX_OK;
}

zx_status_t DWMacDevice::EthmacSetParam(uint32_t param, int32_t value, const void* data,
                                        size_t data_size) {
    zxlogf(INFO, "SetParam called  %x  %x\n", param, value);
    return ZX_OK;
}

} // namespace eth

extern "C" zx_status_t dwmac_bind(void* ctx, zx_device_t* device, void** cookie) {
    return eth::DWMacDevice::Create(device);
}
