menu "Ethernet"

    # Invisible item that is enabled if any Ethernet selection is made
    config ETH_ENABLED
        bool

    menuconfig ETH_USE_ESP32_EMAC
        depends on SOC_EMAC_SUPPORTED
        bool "Support ESP32 internal EMAC controller"
        default y
        select ETH_ENABLED
        help
            ESP32 integrates a 10/100M Ethernet MAC controller.

    if ETH_USE_ESP32_EMAC
        config ETH_DMA_BUFFER_SIZE
            int "Ethernet DMA buffer size (Byte)"
            range 256 1600
            default 512
            help
                Set the size of each buffer used by Ethernet MAC DMA.
                When the buffers are accessed through a data cache (internal RAM on
                ESP32-P4, or PSRAM if ETH_DMA_USE_PSRAM is enabled), this size must
                be a multiple of the data cache line size. Cache line size is
                typically 64 bytes, hence 256, 512, 1536, for example.

        config ETH_DMA_RX_BUFFER_NUM
            int "Amount of Ethernet DMA Rx buffers"
            range 3 30
            default 10 if IDF_TARGET_ESP32 #ESP32 has bigger internal Rx FIFO
            default 20
            help
                Number of DMA receive buffers. Each buffer's size is ETH_DMA_BUFFER_SIZE.
                Larger number of buffers could increase throughput somehow.

        config ETH_DMA_TX_BUFFER_NUM
            int "Amount of Ethernet DMA Tx buffers"
            range 3 30
            default 10
            help
                Number of DMA transmit buffers. Each buffer's size is ETH_DMA_BUFFER_SIZE.
                Larger number of buffers could increase throughput somehow.

        config ETH_DMA_USE_PSRAM
            bool "Allocate Ethernet DMA buffers in PSRAM"
            depends on SPIRAM && SOC_PSRAM_DMA_CAPABLE
            default n
            help
                Place EMAC DMA Tx/Rx buffers in PSRAM instead of internal SRAM.
                This reduces internal RAM usage at the cost of higher DMA access latency.
                The DMA descriptors are always kept in internal SRAM.
                DMA buffers must still be cache-line aligned (see ETH_DMA_BUFFER_SIZE).

        if ETH_DMA_RX_BUFFER_NUM > 15
            config ETH_SOFT_FLOW_CONTROL
                bool "Enable software flow control"
                default n
                help
                    Ethernet MAC engine on ESP32 doesn't feature a flow control logic.
                    The MAC driver can perform a software flow control if you enable this option.
                    Note that, if the RX buffer number is small, enabling software flow control will
                    cause obvious performance loss.
        endif

        config ETH_IRAM_OPTIMIZATION
            bool "Enable IRAM optimization"
            default n
            help
                If enabled, functions related to RX/TX are placed into IRAM. It can improve Ethernet throughput.
                If disabled, all functions are placed into FLASH.

        menu "Ethernet Time"
            depends on SOC_EMAC_IEEE1588V2_SUPPORTED

            config ETH_CLOCK_ADJTIME_PERIOD_MS
                int "Period over which adjtime() applies corrections (ms)"
                default 1000
                range 100 10000
                help
                    The time period over which a clock_adjtime() correction is applied
                    by adjusting the hardware clock rate. The PTP clock's tick rate (ppb)
                    is computed as: ppb = delta_ns * 1000 / ETH_CLOCK_ADJTIME_PERIOD_MS.

            config ETH_CLOCK_ADJTIME_SLEWLIMIT_PPB
                int "Maximum clock slew rate (ppb)"
                default 500000
                range 1000 5000000
                help
                    Drift estimates exceeding this limit (in ppb) are rejected as
                    out of range. Typical crystal oscillators drift less than 50 ppm
                    (50000 ppb).
        endmenu

        menu "Ethernet Clock"
            choice ETH_EMAC_PHY_REF_CLK_SRC
                prompt "PHY reference clock source"
                depends on !SOC_EMAC_RMII_CLK_OUT_INTERNAL_LOOPBACK
                default ETH_EMAC_PHY_REF_CLK_SRC_AUTO
                help
                    Select the PLL clock source used to drive the PHY reference clock output
                    (PLL_F50M).
                    This applies to two scenarios: RMII mode with EMAC_CLK_OUT when
                    the output clock is looped back externally, and RGMII mode when an optional
                    50 MHz PHY_REF_CLK output is enabled (clock_phy_ref_gpio != -1).

                config ETH_EMAC_PHY_REF_CLK_SRC_AUTO
                    bool "Auto"
                    help
                        Let the driver select the clock source automatically based on the
                        hardware abstraction layer defaults.
                config ETH_EMAC_PHY_REF_CLK_SRC_MPLL
                    bool "MPLL"
                    depends on IDF_TARGET_ESP32S31
                    help
                        Use MPLL as the PHY reference clock source.
                config ETH_EMAC_PHY_REF_CLK_SRC_CPLL
                    bool "CPLL"
                    depends on IDF_TARGET_ESP32S31
                    help
                        Use CPLL as the PHY reference clock source.
            endchoice

            choice ETH_EMAC_INTERNAL_OUT_CLK_SRC
                prompt "Internal EMAC REF clock source"
                depends on SOC_EMAC_SUPPORT_1000M
                default ETH_EMAC_INTERNAL_OUT_CLK_SRC_AUTO
                help
                    Select the PLL clock source used to generate the internal EMAC REF RMII clock
                    output (internally looped-back) in RMII mode or RGMII Tx clock output in RGMII mode.
                    This applies to two scenarios: when RGMII is used, or RMII clock source mode
                    is selected and the output clock is NOT looped back externally.

                config ETH_EMAC_INTERNAL_OUT_CLK_SRC_AUTO
                    bool "Auto"
                    help
                        Let the driver select the clock source automatically based on the
                        hardware abstraction layer defaults.
                config ETH_EMAC_INTERNAL_OUT_CLK_SRC_MPLL
                    bool "MPLL"
                    depends on IDF_TARGET_ESP32S31
                    help
                        Use MPLL as the internal clock source.
                config ETH_EMAC_INTERNAL_OUT_CLK_SRC_CPLL
                    bool "CPLL"
                    depends on IDF_TARGET_ESP32S31
                    help
                        Use CPLL as the internal clock source.
                config ETH_EMAC_INTERNAL_OUT_CLK_SRC_APLL
                    bool "APLL"
                    depends on IDF_TARGET_ESP32S31
                    help
                        Use Audio PLL (APLL) as the internal clock source.
            endchoice

        endmenu

    endif # ETH_USE_ESP32_EMAC
    menuconfig ETH_USE_SPI_ETHERNET
        bool "Support SPI to Ethernet Module"
        default y
        select ETH_ENABLED
        help
            ESP-IDF can also support SPI-Ethernet. Actual chip drivers are available as components in
            Component Registry.

    menuconfig ETH_USE_OPENETH
        bool "Support OpenCores Ethernet MAC (for use with QEMU)"
        default n
        select ETH_ENABLED
        help
            OpenCores Ethernet MAC driver can be used when an ESP-IDF application
            is executed in QEMU. This driver is not supported when running on a
            real chip.

    if ETH_USE_OPENETH
        config ETH_OPENETH_DMA_RX_BUFFER_NUM
            int "Number of Ethernet DMA Rx buffers"
            range 1 64
            default 4
            help
                Number of DMA receive buffers, each buffer is 1600 bytes.

        config ETH_OPENETH_DMA_TX_BUFFER_NUM
            int "Number of Ethernet DMA Tx buffers"
            range 1 64
            default 1
            help
                Number of DMA transmit buffers, each buffer is 1600 bytes.
    endif # ETH_USE_OPENETH

    config ETH_TRANSMIT_MUTEX
        depends on ETH_ENABLED
        bool "Enable Transmit Mutex"
        default y if ESP_NETIF_L2_TAP
        default n
        help
            Prevents multiple accesses when Ethernet interface is used as shared resource and multiple
            functionalities might try to access it at a time.

    config ETH_SUBLAYER_SUPPORT
        bool "Support Ethernet netif sublayer (EXPERIMENTAL)"
        depends on ETH_ENABLED && IDF_EXPERIMENTAL_FEATURES
        default n
        help
            Enable the experimental Ethernet sublayer API (esp_eth_sublayer.h).

            The sublayer is the coupling point between one physical Ethernet driver and one or more
            esp_netif instances, with optional 802.1Q VLAN demux/mux, integrated switch, and L2TAP integration.

            This API is experimental and may change in future ESP-IDF releases.

    if ETH_SUBLAYER_SUPPORT

        config ETH_SUBLAYER_IODRIVER_PROVIDER
            bool "Expose the sublayer as an IO driver provider"
            default y if ESP_NETIF_L2_TAP
            default n
            help
                Build the sublayer's IO driver provider implementation : a generic virtual table
                (transmit / transmit_wrap / free_rx_buffer / get_ll_driver) that resolves a
                base, VLAN child, or integrated switch port into its transmit/free functions.

                This is required for L2 TAP integration and is enabled automatically when
                ESP_NETIF_L2_TAP is selected. It can also be enabled independently so that other upper
                layers can obtain IO functions for a specific sublayer endpoint.

        config ETH_SUBLAYER_TRANSMIT_MUTEX
            bool "Enable Ethernet sublayer Transmit Mutex"
            default y if ETH_SUBLAYER_IODRIVER_PROVIDER
            default n
            help
                Serializes the whole Ethernet sublayer TX path (TX hook, integrated switch mux, and the
                actual driver transmit call) per sublayer instance with a dedicated mutex.

                This is needed whenever more than one task can end up transmitting through the same
                sublayer concurrently (e.g. multiple L2TAP sockets bound to different switch/VLAN ports,
                each potentially owned by a different task), since TX hooks and integrated switch drivers
                may keep small amounts of mutable state (e.g. tag/padding scratch buffers) that are only
                safe to access from one task at a time.

                This option is independent of ETH_TRANSMIT_MUTEX: enabling one does not disable the other.
                If every esp_eth_handle_t used by the application is exclusively driven through a
                sublayer, ETH_TRANSMIT_MUTEX can usually be left disabled to avoid the extra locking, since
                this option already serializes the complete TX path leading up to the driver transmit
                call. However, if any Ethernet handle is also transmitted to directly (bypassing the
                sublayer), ETH_TRANSMIT_MUTEX is still required for that handle - this option only
                protects traffic that goes through eth_sublayer_transmit().

        config ETH_SUBLAYER_VLAN_SUPPORT
            bool "Enable 802.1Q VLAN support in the sublayer"
            default n
            help
                Allow tagged 802.1Q VLAN netifs to be created on top of the sublayer, in addition
                to the plain untagged one.

                Disabling this option restricts the sublayer to a single, untagged netif per
                Ethernet driver (or per integrated switch port), reducing code size and RAM usage.

        config ETH_SUBLAYER_SWITCH_SUPPORT
            bool "Enable integrated Ethernet switch support in the sublayer"
            default n
            help
                Enable support for attaching an integrated Ethernet switch to the sublayer,
                including switch-specific frame mux/demux and per-port IO driver handling.

                This is intended for Ethernet switch drivers that require host-interface frame
                tagging. Leave this option disabled to reduce code size and RAM usage when the
                sublayer is used without a switch.

        config ETH_SUBLAYER_TX_BUF_DESC_CAP_RANGE_MIN
            int
            default 3 if ETH_SUBLAYER_VLAN_SUPPORT && ETH_SUBLAYER_SWITCH_SUPPORT
            default 2 if ETH_SUBLAYER_VLAN_SUPPORT || ETH_SUBLAYER_SWITCH_SUPPORT
            default 1

        config ETH_SUBLAYER_TX_BUF_DESC_CAPACITY
            int "Sublayer TX buffer descriptor capacity"
            range ETH_SUBLAYER_TX_BUF_DESC_CAP_RANGE_MIN 16
            default ETH_SUBLAYER_TX_BUF_DESC_CAP_RANGE_MIN
            help
                Maximum number of esp_eth_buf_desc_t entries available to the
                Ethernet sublayer TX path (including TX hook edits).

                If TX hook needs to add more frame segments without memcpying the entire frame,
                it can do so by adding more entries to the descriptor array.

                The descriptor array is stack-allocated on hot TX paths, so larger
                values increase stack usage but allow hooks to add more frame
                segments without allocating a new descriptor array.

    endif # ETH_SUBLAYER_SUPPORT

endmenu
