// 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.
library fuchsia.hardware.ethernet;

using zx;

const ETH_MAC_SIZE uint32 = 6; // bytes
const ETH_MTU_SIZE uint32 = 1500; // bytes
const ETH_FRAME_MAX_HDR_SIZE uint32 = 18; // bytes. MAC Dest(6) + MAC Src(6) + 802.1Q tag(4) + Ethertype(2)
const ETH_FRAME_MAX_SIZE uint32 = 1518;

/// The ethernet interface supports both synchronous and asynchronous transmissions using the
/// proto->queue_tx() and ifc->complete_tx() methods.
///
/// Receive operations are supported with the ifc->recv() interface.
///
/// The FEATURE_WLAN flag indicates a device that supports wlan operations.
///
/// The FEATURE_SYNTH flag indicates a device that is not backed by hardware.
///
/// The FEATURE_DMA flag indicates that the device can copy the buffer data using DMA and will ensure
/// that physical addresses are provided in netbufs.
///
/// The FEATURE_WLAN_AP flag indicates a device operating in wlan SoftAP mode.
/// When FEATURE_WLAN_AP is enabled, the FEATURE_WLAN flag is ignored and
/// assumed to be on.
// TODO: implement netbuf-based receive operations by implementing proto->queue_rx() and
// ifc->complete_rx()
type EthernetFeature = strict enum : uint32 {
    WLAN = 0x1;
    SYNTH = 0x2;
    DMA = 0x4;
    WLAN_AP = 0x8;
};

const ETHERNET_STATUS_ONLINE uint32 = 0x1;

type EthernetInfo = struct {
    features uint32;
    mtu uint32;
    mac array<uint8, ETH_MAC_SIZE>;
    reserved0 array<uint8, 2>;
    netbuf_size uint64;
    reserved1 array<uint32, 2>;
};

/// Note that this struct may have a private section encoded after it. Allocator much call parent
/// device's |Query| to get the correct size.
type EthernetNetbuf = struct {
    /// Provided by the generic ethernet driver.
    @buffer
    data vector<uint8>;
    /// Only used if ETHERNET_FEATURE_DMA is available.
    phys zx.paddr;
    reserved uint16;
    flags uint32;
};

@transport("Banjo")
@banjo_layout("ddk-interface")
protocol EthernetIfc {
    /// Value with bits set from the |ETHERNET_STATUS_*| flags
    Status(struct {
        status uint32;
    }) -> ();

    Recv(struct {
        @buffer
        data vector<uint8>;
        flags uint32;
    }) -> ();
};

type EthDevMetadata = struct {
    vid uint32;
    pid uint32;
    did uint32;
};

/// Indicates that additional data is available to be sent after this call finishes. Allows an ethernet
/// driver to batch tx to hardware if possible.
const ETHERNET_TX_OPT_MORE uint32 = 1;

/// SETPARAM_ values identify the parameter to set. Each call to set_param()
/// takes an int32_t |value| and uint8_t* |data| which have meaning specific to
/// the parameter being set.
///
/// |value| is bool. |data| is unused.
const ETHERNET_SETPARAM_PROMISC uint32 = 1;

/// |value| is bool. |data| is unused.
const ETHERNET_SETPARAM_MULTICAST_PROMISC uint32 = 2;

const ETHERNET_MULTICAST_FILTER_OVERFLOW int32 = -1;

/// |value| is number of addresses, or ETHERNET_MULTICAST_FILTER_OVERFLOW for "too many to count."
/// |data| is |value|*6 bytes of MAC addresses. Caller retains ownership.
/// If |value| is _OVERFLOW, |data| is ignored.
const ETHERNET_SETPARAM_MULTICAST_FILTER uint32 = 3;

const ETHERNET_SETPARAM_DUMP_REGS uint32 = 4;

/// The ethernet midlayer will never call ethermac_protocol
/// methods from multiple threads simultaneously, but it
/// can call send() methods at the same time as non-send
/// methods.
@transport("Banjo")
@banjo_layout("ddk-protocol")
protocol EthernetImpl {
    /// Obtain information about the ethermac device and supported features
    /// Safe to call at any time.
    Query(struct {
        options uint32;
    }) -> (struct {
        s zx.status;
        info EthernetInfo;
    });

    /// Shut down a running ethermac
    /// Safe to call if the ethermac is already stopped.
    Stop() -> ();

    /// Start ethermac running with ifc_virt
    /// Callbacks on ifc may be invoked from now until stop() is called
    Start(resource struct {
        ifc client_end:EthernetIfc;
    }) -> (struct {
        s zx.status;
    });

    /// Request transmission of the packet in netbuf. The driver takes ownership of the netbuf and
    /// must call the completion callback passed in to return it once the enqueue is complete.
    /// The callback may be used to return the packet before transmission itself completes, and may
    /// called from within the queue_tx() implementation itself.
    ///
    /// |QueueTx| may be called at any time after start() is called including from multiple threads
    /// simultaneously.
    ///
    /// Return status indicates queue state:
    ///   ZX_OK: Packet has been enqueued.
    ///   Other: Packet could not be enqueued.
    /// Upon a return of ZX_OK, the packet has been enqueued, but no information is returned as to
    /// the completion state of the transmission itself.
    @async
    QueueTx(struct {
        options uint32;
        @in_out
        netbuf EthernetNetbuf;
    }) -> (struct {
        status zx.status;
        @mutable
        netbuf EthernetNetbuf;
    });

    /// Request a settings change for the driver. Return status indicates disposition:
    ///   ZX_OK: Request has been handled.
    ///   ZX_ERR_NOT_SUPPORTED: Driver does not support this setting.
    ///   Other: Error trying to support this request.
    ///
    /// |value| and |data| usage are defined for each |param|; see comments above.
    ///
    /// set_param() may be called at any time after start() is called including from multiple threads
    /// simultaneously.
    SetParam(struct {
        param uint32;
        value int32;
        @buffer
        data vector<uint8>;
    }) -> (struct {
        s zx.status;
    });

    /// Get the BTI handle (needed to pin DMA memory) for this device.
    /// This method is only valid on devices that advertise ETHERNET_FEATURE_DMA
    /// The caller takes ownership of the BTI handle.
    GetBti() -> (resource struct {
        bti zx.handle:BTI;
    });
};
