blob: a1787eb756973be27f72af184f28f25fe3f49d2c [file] [log] [blame]
/*
* Xilinx Processor System Gigabit Ethernet controller (GEM) driver
*
* Driver private data declarations
*
* Copyright (c) 2021, Weidmueller Interface GmbH & Co. KG
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ZEPHYR_DRIVERS_ETHERNET_ETH_XLNX_GEM_PRIV_H_
#define _ZEPHYR_DRIVERS_ETHERNET_ETH_XLNX_GEM_PRIV_H_
#define DT_DRV_COMPAT xlnx_gem
#include <zephyr/kernel.h>
#include <zephyr/types.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/irq.h>
#include "phy_xlnx_gem.h"
#define ETH_XLNX_BUFFER_ALIGNMENT 4 /* RX/TX buffer alignment (in bytes) */
/* Buffer descriptor (BD) related defines */
/* Receive Buffer Descriptor bits & masks: comp. Zynq-7000 TRM, Table 16-2. */
/*
* Receive Buffer Descriptor address word:
* [31 .. 02] Mask for effective buffer address -> excludes [1..0]
* [01] Wrap bit, last BD in RX BD ring
* [00] BD used bit
*/
#define ETH_XLNX_GEM_RXBD_WRAP_BIT 0x00000002
#define ETH_XLNX_GEM_RXBD_USED_BIT 0x00000001
#define ETH_XLNX_GEM_RXBD_BUFFER_ADDR_MASK 0xFFFFFFFC
/*
* Receive Buffer Descriptor control word:
* [31] Broadcast detected
* [30] Multicast hash match detected
* [29] Unicast hash match detected
* [27] Specific address match detected
* [26 .. 25] Bits indicating which specific address register was matched
* [24] this bit has different semantics depending on whether RX checksum
* offloading is enabled or not
* [23 .. 22] These bits have different semantics depending on whether RX check-
* sum offloading is enabled or not
* [21] VLAN tag (type ID 0x8100) detected
* [20] Priority tag: VLAN tag (type ID 0x8100) and null VLAN identifier
* detected
* [19 .. 17] VLAN priority
* [16] Canonical format indicator bit
* [15] End-of-frame bit
* [14] Start-of-frame bit
* [13] FCS status bit for FCS ignore mode
* [12 .. 00] Data length of received frame
*/
#define ETH_XLNX_GEM_RXBD_BCAST_BIT 0x80000000
#define ETH_XLNX_GEM_RXBD_MCAST_HASH_MATCH_BIT 0x40000000
#define ETH_XLNX_GEM_RXBD_UCAST_HASH_MATCH_BIT 0x20000000
#define ETH_XLNX_GEM_RXBD_SPEC_ADDR_MATCH_BIT 0x08000000
#define ETH_XLNX_GEM_RXBD_SPEC_ADDR_MASK 0x00000003
#define ETH_XLNX_GEM_RXBD_SPEC_ADDR_SHIFT 25
#define ETH_XLNX_GEM_RXBD_BIT24 0x01000000
#define ETH_XLNX_GEM_RXBD_BITS23_22_MASK 0x00000003
#define ETH_XLNX_GEM_RXBD_BITS23_22_SHIFT 22
#define ETH_XLNX_GEM_RXBD_VLAN_TAG_DETECTED_BIT 0x00200000
#define ETH_XLNX_GEM_RXBD_PRIO_TAG_DETECTED_BIT 0x00100000
#define ETH_XLNX_GEM_RXBD_VLAN_PRIORITY_MASK 0x00000007
#define ETH_XLNX_GEM_RXBD_VLAN_PRIORITY_SHIFT 17
#define ETH_XLNX_GEM_RXBD_CFI_BIT 0x00010000
#define ETH_XLNX_GEM_RXBD_END_OF_FRAME_BIT 0x00008000
#define ETH_XLNX_GEM_RXBD_START_OF_FRAME_BIT 0x00004000
#define ETH_XLNX_GEM_RXBD_FCS_STATUS_BIT 0x00002000
#define ETH_XLNX_GEM_RXBD_FRAME_LENGTH_MASK 0x00001FFF
/* Transmit Buffer Descriptor bits & masks: comp. Zynq-7000 TRM, Table 16-3. */
/*
* Transmit Buffer Descriptor control word:
* [31] BD used marker
* [30] Wrap bit, last BD in TX BD ring
* [29] Retry limit exceeded
* [27] TX frame corruption due to AHB/AXI error, HRESP errors or buffers
* exhausted mid-frame
* [26] Late collision, TX error detected
* [22 .. 20] Transmit IP/TCP/UDP checksum generation offload error bits
* [16] No CRC appended by MAC
* [15] Last buffer bit, indicates end of current TX frame
* [13 .. 00] Data length in the BD's associated buffer
*/
#define ETH_XLNX_GEM_TXBD_USED_BIT 0x80000000
#define ETH_XLNX_GEM_TXBD_WRAP_BIT 0x40000000
#define ETH_XLNX_GEM_TXBD_RETRY_BIT 0x20000000
#define ETH_XLNX_GEM_TXBD_TX_FRAME_CORRUPT_BIT 0x08000000
#define ETH_XLNX_GEM_TXBD_LATE_COLLISION_BIT 0x04000000
#define ETH_XLNX_GEM_TXBD_CKSUM_OFFLOAD_ERROR_MASK 0x00000007
#define ETH_XLNX_GEM_TXBD_CKSUM_OFFLOAD_ERROR_SHIFT 20
#define ETH_XLNX_GEM_TXBD_NO_CRC_BIT 0x00010000
#define ETH_XLNX_GEM_TXBD_LAST_BIT 0x00008000
#define ETH_XLNX_GEM_TXBD_LEN_MASK 0x00003FFF
#define ETH_XLNX_GEM_TXBD_ERR_MASK 0x3C000000
#define ETH_XLNX_GEM_CKSUM_NO_ERROR 0x00000000
#define ETH_XLNX_GEM_CKSUM_VLAN_HDR_ERROR 0x00000001
#define ETH_XLNX_GEM_CKSUM_SNAP_HDR_ERROR 0x00000002
#define ETH_XLNX_GEM_CKSUM_IP_TYPE_OR_LEN_ERROR 0x00000003
#define ETH_XLNX_GEM_CKSUM_NOT_VLAN_SNAP_IP_ERROR 0x00000004
#define ETH_XLNX_GEM_CKSUM_UNSUPP_PKT_FRAG_ERROR 0x00000005
#define ETH_XLNX_GEM_CKSUM_NOT_TCP_OR_UDP_ERROR 0x00000006
#define ETH_XLNX_GEM_CKSUM_PREMATURE_END_ERROR 0x00000007
#if defined(CONFIG_SOC_FAMILY_XILINX_ZYNQ7000)
/*
* Zynq-7000 TX clock configuration:
*
* GEMx_CLK_CTRL (SLCR) registers:
* [25 .. 20] Reference clock divisor 1
* [13 .. 08] Reference clock divisor 0
* [00] Clock active bit
*/
#define ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR_MASK 0x0000003F
#define ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR1_SHIFT 20
#define ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR0_SHIFT 8
#define ETH_XLNX_CRL_APB_GEMX_REF_CTRL_CLKACT_BIT 0x02000000
#elif defined(CONFIG_SOC_XILINX_ZYNQMP)
/*
* UltraScale TX clock configuration: comp.
* https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq-ultrascale-registers.html
*
* CRL_WPROT (CRL_APB) register:
* [00] CRL APB register space write protection bit
*
* GEMx_REF_CTRL (CRL_APB) registers:
* [30] RX channel clock active bit
* [29] Clock active bit
* [21 .. 16] Reference clock divisor 1
* [13 .. 08] Reference clock divisor 0
*/
#define ETH_XLNX_CRL_APB_WPROT_REGISTER_ADDRESS 0xFF5E001C
#define ETH_XLNX_CRL_APB_WPROT_BIT 0x00000001
#define ETH_XLNX_CRL_APB_GEMX_REF_CTRL_DIVISOR_MASK 0x0000003F
#define ETH_XLNX_CRL_APB_GEMX_REF_CTRL_DIVISOR1_SHIFT 16
#define ETH_XLNX_CRL_APB_GEMX_REF_CTRL_DIVISOR0_SHIFT 8
#define ETH_XLNX_CRL_APB_GEMX_REF_CTRL_RX_CLKACT_BIT 0x04000000
#define ETH_XLNX_CRL_APB_GEMX_REF_CTRL_CLKACT_BIT 0x02000000
#endif /* CONFIG_SOC_FAMILY_XILINX_ZYNQ7000 || CONFIG_SOC_XILINX_ZYNQMP */
/*
* Register offsets within the respective GEM's address space:
* NWCTRL = gem.net_ctrl Network Control register
* NWCFG = gem.net_cfg Network Configuration register
* NWSR = gem.net_status Network Status register
* DMACR = gem.dma_cfg DMA Control register
* TXSR = gem.tx_status TX Status register
* RXQBASE = gem.rx_qbar RXQ base address register
* TXQBASE = gem.tx_qbar TXQ base address register
* RXSR = gem.rx_status RX Status register
* ISR = gem.intr_status Interrupt status register
* IER = gem.intr_en Interrupt enable register
* IDR = gem.intr_dis Interrupt disable register
* IMR = gem.intr_mask Interrupt mask register
* PHYMNTNC = gem.phy_maint PHY maintenance register
* LADDR1L = gem.spec_addr1_bot Specific address 1 bottom register
* LADDR1H = gem.spec_addr1_top Specific address 1 top register
* LADDR2L = gem.spec_addr2_bot Specific address 2 bottom register
* LADDR2H = gem.spec_addr2_top Specific address 2 top register
* LADDR3L = gem.spec_addr3_bot Specific address 3 bottom register
* LADDR3H = gem.spec_addr3_top Specific address 3 top register
* LADDR4L = gem.spec_addr4_bot Specific address 4 bottom register
* LADDR4H = gem.spec_addr4_top Specific address 4 top register
*/
#define ETH_XLNX_GEM_NWCTRL_OFFSET 0x00000000
#define ETH_XLNX_GEM_NWCFG_OFFSET 0x00000004
#define ETH_XLNX_GEM_NWSR_OFFSET 0x00000008
#define ETH_XLNX_GEM_DMACR_OFFSET 0x00000010
#define ETH_XLNX_GEM_TXSR_OFFSET 0x00000014
#define ETH_XLNX_GEM_RXQBASE_OFFSET 0x00000018
#define ETH_XLNX_GEM_TXQBASE_OFFSET 0x0000001C
#define ETH_XLNX_GEM_RXSR_OFFSET 0x00000020
#define ETH_XLNX_GEM_ISR_OFFSET 0x00000024
#define ETH_XLNX_GEM_IER_OFFSET 0x00000028
#define ETH_XLNX_GEM_IDR_OFFSET 0x0000002C
#define ETH_XLNX_GEM_IMR_OFFSET 0x00000030
#define ETH_XLNX_GEM_PHY_MAINTENANCE_OFFSET 0x00000034
#define ETH_XLNX_GEM_LADDR1L_OFFSET 0x00000088
#define ETH_XLNX_GEM_LADDR1H_OFFSET 0x0000008C
#define ETH_XLNX_GEM_LADDR2L_OFFSET 0x00000090
#define ETH_XLNX_GEM_LADDR2H_OFFSET 0x00000094
#define ETH_XLNX_GEM_LADDR3L_OFFSET 0x00000098
#define ETH_XLNX_GEM_LADDR3H_OFFSET 0x0000009C
#define ETH_XLNX_GEM_LADDR4L_OFFSET 0x000000A0
#define ETH_XLNX_GEM_LADDR4H_OFFSET 0x000000A4
/*
* Masks for clearing registers during initialization:
* gem.net_ctrl [clear_stat_regs]
* gem.tx_status [7..0]
* gem.rx_status [3..0]
* gem.intr_dis [26..0]
*/
#define ETH_XLNX_GEM_STATCLR_MASK 0x00000020
#define ETH_XLNX_GEM_TXSRCLR_MASK 0x000000FF
#define ETH_XLNX_GEM_RXSRCLR_MASK 0x0000000F
#define ETH_XLNX_GEM_IDRCLR_MASK 0x07FFFFFF
/* (Shift) masks for individual registers' bits / bitfields */
/*
* gem.net_ctrl:
* [15] Store 1588 receive timestamp in CRC field
* [12] Transmit zero quantum pause frame
* [11] Transmit pause frame
* [10] Halt transmission after current frame
* [09] Start transmission (tx_go)
* [07] Enable writing to statistics counters
* [06] Increment statistics registers - for testing purposes only
* [05] Clear statistics registers
* [04] Enable MDIO port
* [03] Enable transmit
* [02] Enable receive
* [01] Local loopback mode
*/
#define ETH_XLNX_GEM_NWCTRL_RXTSTAMP_BIT 0x00008000
#define ETH_XLNX_GEM_NWCTRL_ZEROPAUSETX_BIT 0x00001000
#define ETH_XLNX_GEM_NWCTRL_PAUSETX_BIT 0x00000800
#define ETH_XLNX_GEM_NWCTRL_HALTTX_BIT 0x00000400
#define ETH_XLNX_GEM_NWCTRL_STARTTX_BIT 0x00000200
#define ETH_XLNX_GEM_NWCTRL_STATWEN_BIT 0x00000080
#define ETH_XLNX_GEM_NWCTRL_STATINC_BIT 0x00000040
#define ETH_XLNX_GEM_NWCTRL_STATCLR_BIT 0x00000020
#define ETH_XLNX_GEM_NWCTRL_MDEN_BIT 0x00000010
#define ETH_XLNX_GEM_NWCTRL_TXEN_BIT 0x00000008
#define ETH_XLNX_GEM_NWCTRL_RXEN_BIT 0x00000004
#define ETH_XLNX_GEM_NWCTRL_LOOPEN_BIT 0x00000002
/*
* gem.net_cfg:
* [30] Ignore IPG RX Error
* [29] Disable rejection of non-standard preamble
* [28] Enable IPG stretch
* [27] Enable SGMII mode
* [26] Disable rejection of frames with FCS errors
* [25] Enable frames to be received in HDX mode while transmitting
* [24] Enable RX checksum offload to hardware
* [23] Do not copy pause frames to memory
* [22 .. 21] Data bus width
* [20 .. 18] MDC clock division setting
* [17] Discard FCS from received frames
* [16] RX length field error frame discard enable
* [15 .. 14] Receive buffer offset, # of bytes
* [13] Enable pause TX upon 802.3 pause frame reception
* [12] Retry test - for testing purposes only
* [11] Use TBI instead of the GMII/MII interface
* [10] Gigabit mode enable
* [09] External address match enable
* [08] Enable 1536 byte frames reception
* [07] Receive unicast hash frames enable
* [06] Receive multicast hash frames enable
* [05] Disable broadcast frame reception
* [04] Copy all frames = promiscuous mode
* [02] Discard non-VLAN frames enable
* [01] Full duplex enable
* [00] Speed selection: 1 = 100Mbit/s, 0 = 10 Mbit/s, GBE mode is
* set separately in bit [10]
*/
#define ETH_XLNX_GEM_NWCFG_IGNIPGRXERR_BIT 0x40000000
#define ETH_XLNX_GEM_NWCFG_BADPREAMBEN_BIT 0x20000000
#define ETH_XLNX_GEM_NWCFG_IPG_STRETCH_BIT 0x10000000
#define ETH_XLNX_GEM_NWCFG_SGMIIEN_BIT 0x08000000
#define ETH_XLNX_GEM_NWCFG_FCSIGNORE_BIT 0x04000000
#define ETH_XLNX_GEM_NWCFG_HDRXEN_BIT 0x02000000
#define ETH_XLNX_GEM_NWCFG_RXCHKSUMEN_BIT 0x01000000
#define ETH_XLNX_GEM_NWCFG_PAUSECOPYDI_BIT 0x00800000
#define ETH_XLNX_GEM_NWCFG_DBUSW_MASK 0x3
#define ETH_XLNX_GEM_NWCFG_DBUSW_SHIFT 21
#define ETH_XLNX_GEM_NWCFG_MDC_MASK 0x7
#define ETH_XLNX_GEM_NWCFG_MDC_SHIFT 18
#define ETH_XLNX_GEM_NWCFG_MDCCLKDIV_MASK 0x001C0000
#define ETH_XLNX_GEM_NWCFG_FCSREM_BIT 0x00020000
#define ETH_XLNX_GEM_NWCFG_LENGTHERRDSCRD_BIT 0x00010000
#define ETH_XLNX_GEM_NWCFG_RXOFFS_MASK 0x00000003
#define ETH_XLNX_GEM_NWCFG_RXOFFS_SHIFT 14
#define ETH_XLNX_GEM_NWCFG_PAUSEEN_BIT 0x00002000
#define ETH_XLNX_GEM_NWCFG_RETRYTESTEN_BIT 0x00001000
#define ETH_XLNX_GEM_NWCFG_TBIINSTEAD_BIT 0x00000800
#define ETH_XLNX_GEM_NWCFG_1000_BIT 0x00000400
#define ETH_XLNX_GEM_NWCFG_EXTADDRMATCHEN_BIT 0x00000200
#define ETH_XLNX_GEM_NWCFG_1536RXEN_BIT 0x00000100
#define ETH_XLNX_GEM_NWCFG_UCASTHASHEN_BIT 0x00000080
#define ETH_XLNX_GEM_NWCFG_MCASTHASHEN_BIT 0x00000040
#define ETH_XLNX_GEM_NWCFG_BCASTDIS_BIT 0x00000020
#define ETH_XLNX_GEM_NWCFG_COPYALLEN_BIT 0x00000010
#define ETH_XLNX_GEM_NWCFG_NVLANDISC_BIT 0x00000004
#define ETH_XLNX_GEM_NWCFG_FDEN_BIT 0x00000002
#define ETH_XLNX_GEM_NWCFG_100_BIT 0x00000001
/*
* gem.dma_cfg:
* [24] Discard packets when AHB resource is unavailable
* [23 .. 16] RX buffer size, n * 64 bytes
* [11] Enable/disable TCP|UDP/IP TX checksum offload
* [10] TX buffer half/full memory size
* [09 .. 08] Receiver packet buffer memory size select
* [07] Endianness configuration
* [06] Descriptor access endianness configuration
* [04 .. 00] AHB fixed burst length for DMA data operations
*/
#define ETH_XLNX_GEM_DMACR_DISCNOAHB_BIT 0x01000000
#define ETH_XLNX_GEM_DMACR_RX_BUF_MASK 0x000000FF
#define ETH_XLNX_GEM_DMACR_RX_BUF_SHIFT 16
#define ETH_XLNX_GEM_DMACR_TCP_CHKSUM_BIT 0x00000800
#define ETH_XLNX_GEM_DMACR_TX_SIZE_BIT 0x00000400
#define ETH_XLNX_GEM_DMACR_RX_SIZE_MASK 0x00000300
#define ETH_XLNX_GEM_DMACR_RX_SIZE_SHIFT 8
#define ETH_XLNX_GEM_DMACR_ENDIAN_BIT 0x00000080
#define ETH_XLNX_GEM_DMACR_DESCR_ENDIAN_BIT 0x00000040
#define ETH_XLNX_GEM_DMACR_AHB_BURST_LENGTH_MASK 0x0000001F
/*
* gem.intr_* interrupt status/enable/disable bits:
* [25] PTP pdelay_resp frame transmitted
* [24] PTP pdelay_req frame transmitted
* [23] PTP pdelay_resp frame received
* [22] PTP delay_req frame received
* [21] PTP sync frame transmitted
* [20] PTP delay_req frame transmitted
* [19] PTP sync frame received
* [18] PTP delay_req frame received
* [17] PCS link partner page mask
* [16] Auto-negotiation completed
* [15] External interrupt
* [14] Pause frame transmitted
* [13] Pause time has reached zero
* [12] Pause frame received with non-zero pause quantum
* [11] hresp not OK
* [10] Receive overrun
* [09] Link change
* [07] Transmit complete
* [06] Transmit frame corruption due to AHB/AXI error
* [05] Retry limit exceeded or late collision
* [04] Transmit buffer underrun
* [03] Set 'used' bit in TX BD encountered
* [02] Set 'used' bit in RX BD encountered
* [01] Frame received
* [00] PHY management done
*/
#define ETH_XLNX_GEM_IXR_PTPPSTX_BIT 0x02000000
#define ETH_XLNX_GEM_IXR_PTPPDRTX_BIT 0x01000000
#define ETH_XLNX_GEM_IXR_PTPSTX_BIT 0x00800000
#define ETH_XLNX_GEM_IXR_PTPDRTX_BIT 0x00400000
#define ETH_XLNX_GEM_IXR_PTPPSRX_BIT 0x00200000
#define ETH_XLNX_GEM_IXR_PTPPDRRX_BIT 0x00100000
#define ETH_XLNX_GEM_IXR_PTPSRX_BIT 0x00080000
#define ETH_XLNX_GEM_IXR_PTPDRRX_BIT 0x00040000
#define ETH_XLNX_GEM_IXR_PARTNER_PGRX_BIT 0x00020000
#define ETH_XLNX_GEM_IXR_AUTONEG_COMPLETE_BIT 0x00010000
#define ETH_XLNX_GEM_IXR_EXTERNAL_INT_BIT 0x00008000
#define ETH_XLNX_GEM_IXR_PAUSE_TX_BIT 0x00004000
#define ETH_XLNX_GEM_IXR_PAUSE_ZERO_BIT 0x00002000
#define ETH_XLNX_GEM_IXR_PAUSE_NONZERO_BIT 0x00001000
#define ETH_XLNX_GEM_IXR_HRESP_NOT_OK_BIT 0x00000800
#define ETH_XLNX_GEM_IXR_RX_OVERRUN_BIT 0x00000400
#define ETH_XLNX_GEM_IXR_LINK_CHANGE 0x00000200
#define ETH_XLNX_GEM_IXR_TX_COMPLETE_BIT 0x00000080
#define ETH_XLNX_GEM_IXR_TX_CORRUPT_BIT 0x00000040
#define ETH_XLNX_GEM_IXR_RETRY_LIMIT_OR_LATE_COLL_BIT 0x00000020
#define ETH_XLNX_GEM_IXR_TX_UNDERRUN_BIT 0x00000010
#define ETH_XLNX_GEM_IXR_TX_USED_BIT 0x00000008
#define ETH_XLNX_GEM_IXR_RX_USED_BIT 0x00000004
#define ETH_XLNX_GEM_IXR_FRAME_RX_BIT 0x00000002
#define ETH_XLNX_GEM_IXR_PHY_MGMNT_BIT 0x00000001
#define ETH_XLNX_GEM_IXR_ALL_MASK 0x03FC7FFE
#define ETH_XLNX_GEM_IXR_ERRORS_MASK 0x00000C60
/* Bits / bit masks relating to the GEM's MDIO interface */
/*
* gem.net_status:
* [02] PHY management idle bit
* [01] MDIO input status
*/
#define ETH_XLNX_GEM_MDIO_IDLE_BIT 0x00000004
#define ETH_XLNX_GEM_MDIO_IN_STATUS_BIT 0x00000002
/*
* gem.phy_maint:
* [31 .. 30] constant values
* [17 .. 16] constant values
* [29] Read operation control bit
* [28] Write operation control bit
* [27 .. 23] PHY address
* [22 .. 18] Register address
* [15 .. 00] 16-bit data word
*/
#define ETH_XLNX_GEM_PHY_MAINT_CONST_BITS 0x40020000
#define ETH_XLNX_GEM_PHY_MAINT_READ_OP_BIT 0x20000000
#define ETH_XLNX_GEM_PHY_MAINT_WRITE_OP_BIT 0x10000000
#define ETH_XLNX_GEM_PHY_MAINT_PHY_ADDRESS_MASK 0x0000001F
#define ETH_XLNX_GEM_PHY_MAINT_PHY_ADDRESS_SHIFT 23
#define ETH_XLNX_GEM_PHY_MAINT_REGISTER_ID_MASK 0x0000001F
#define ETH_XLNX_GEM_PHY_MAINT_REGISTER_ID_SHIFT 18
#define ETH_XLNX_GEM_PHY_MAINT_DATA_MASK 0x0000FFFF
/* Device initialization macro */
#define ETH_XLNX_GEM_NET_DEV_INIT(port) \
ETH_NET_DEVICE_DT_INST_DEFINE(port,\
eth_xlnx_gem_dev_init,\
NULL,\
&eth_xlnx_gem##port##_dev_data,\
&eth_xlnx_gem##port##_dev_cfg,\
CONFIG_ETH_INIT_PRIORITY,\
&eth_xlnx_gem_apis,\
NET_ETH_MTU);
/* Device configuration data declaration macro */
#define ETH_XLNX_GEM_DEV_CONFIG(port) \
static const struct eth_xlnx_gem_dev_cfg eth_xlnx_gem##port##_dev_cfg = {\
.base_addr = DT_REG_ADDR_BY_IDX(DT_INST(port, xlnx_gem), 0),\
.config_func = eth_xlnx_gem##port##_irq_config,\
.pll_clock_frequency = DT_INST_PROP(port, clock_frequency),\
.clk_ctrl_reg_address = DT_REG_ADDR_BY_IDX(DT_INST(port, xlnx_gem), 1),\
.mdc_divider = (enum eth_xlnx_mdc_clock_divider)\
(DT_INST_PROP(port, mdc_divider)),\
.max_link_speed = (enum eth_xlnx_link_speed)\
(DT_INST_PROP(port, link_speed)),\
.init_phy = DT_INST_PROP(port, init_mdio_phy),\
.phy_mdio_addr_fix = DT_INST_PROP(port, mdio_phy_address),\
.phy_advertise_lower = DT_INST_PROP(port, advertise_lower_link_speeds),\
.phy_poll_interval = DT_INST_PROP(port, phy_poll_interval),\
.defer_rxp_to_queue = !DT_INST_PROP(port, handle_rx_in_isr),\
.defer_txd_to_queue = DT_INST_PROP(port, handle_tx_in_workq),\
.amba_dbus_width = (enum eth_xlnx_amba_dbus_width)\
(DT_INST_PROP(port, amba_ahb_dbus_width)),\
.ahb_burst_length = (enum eth_xlnx_ahb_burst_length)\
(DT_INST_PROP(port, amba_ahb_burst_length)),\
.hw_rx_buffer_size = (enum eth_xlnx_hwrx_buffer_size)\
(DT_INST_PROP(port, hw_rx_buffer_size)),\
.hw_rx_buffer_offset = (uint8_t)\
(DT_INST_PROP(port, hw_rx_buffer_offset)),\
.rxbd_count = (uint8_t)\
(DT_INST_PROP(port, rx_buffer_descriptors)),\
.txbd_count = (uint8_t)\
(DT_INST_PROP(port, tx_buffer_descriptors)),\
.rx_buffer_size = (((uint16_t)(DT_INST_PROP(port, rx_buffer_size)) +\
(ETH_XLNX_BUFFER_ALIGNMENT-1)) & ~(ETH_XLNX_BUFFER_ALIGNMENT-1)),\
.tx_buffer_size = (((uint16_t)(DT_INST_PROP(port, tx_buffer_size)) +\
(ETH_XLNX_BUFFER_ALIGNMENT-1)) & ~(ETH_XLNX_BUFFER_ALIGNMENT-1)),\
.ignore_ipg_rxer = DT_INST_PROP(port, ignore_ipg_rxer),\
.disable_reject_nsp = DT_INST_PROP(port, disable_reject_nsp),\
.enable_ipg_stretch = DT_INST_PROP(port, ipg_stretch),\
.enable_sgmii_mode = DT_INST_PROP(port, sgmii_mode),\
.disable_reject_fcs_crc_errors = DT_INST_PROP(port, disable_reject_fcs_crc_errors),\
.enable_rx_halfdup_while_tx = DT_INST_PROP(port, rx_halfdup_while_tx),\
.enable_rx_chksum_offload = DT_INST_PROP(port, rx_checksum_offload),\
.disable_pause_copy = DT_INST_PROP(port, disable_pause_copy),\
.discard_rx_fcs = DT_INST_PROP(port, discard_rx_fcs),\
.discard_rx_length_errors = DT_INST_PROP(port, discard_rx_length_errors),\
.enable_pause = DT_INST_PROP(port, pause_frame),\
.enable_tbi = DT_INST_PROP(port, tbi),\
.ext_addr_match = DT_INST_PROP(port, ext_address_match),\
.enable_1536_frames = DT_INST_PROP(port, long_frame_rx_support),\
.enable_ucast_hash = DT_INST_PROP(port, unicast_hash),\
.enable_mcast_hash = DT_INST_PROP(port, multicast_hash),\
.disable_bcast = DT_INST_PROP(port, reject_broadcast),\
.copy_all_frames = DT_INST_PROP(port, promiscuous_mode),\
.discard_non_vlan = DT_INST_PROP(port, discard_non_vlan),\
.enable_fdx = DT_INST_PROP(port, full_duplex),\
.disc_rx_ahb_unavail = DT_INST_PROP(port, discard_rx_frame_ahb_unavail),\
.enable_tx_chksum_offload = DT_INST_PROP(port, tx_checksum_offload),\
.tx_buffer_size_full = DT_INST_PROP(port, hw_tx_buffer_size_full),\
.enable_ahb_packet_endian_swap = DT_INST_PROP(port, ahb_packet_endian_swap),\
.enable_ahb_md_endian_swap = DT_INST_PROP(port, ahb_md_endian_swap)\
};
/* Device run-time data declaration macro */
#define ETH_XLNX_GEM_DEV_DATA(port) \
static struct eth_xlnx_gem_dev_data eth_xlnx_gem##port##_dev_data = {\
.mac_addr = DT_INST_PROP(port, local_mac_address),\
.started = 0,\
.eff_link_speed = LINK_DOWN,\
.phy_addr = 0,\
.phy_id = 0,\
.phy_access_api = NULL,\
.first_rx_buffer = NULL,\
.first_tx_buffer = NULL\
};
/* DMA memory area declaration macro */
#define ETH_XLNX_GEM_DMA_AREA_DECL(port) \
struct eth_xlnx_dma_area_gem##port {\
struct eth_xlnx_gem_bd rx_bd[DT_INST_PROP(port, rx_buffer_descriptors)];\
struct eth_xlnx_gem_bd tx_bd[DT_INST_PROP(port, tx_buffer_descriptors)];\
uint8_t rx_buffer\
[DT_INST_PROP(port, rx_buffer_descriptors)]\
[((DT_INST_PROP(port, rx_buffer_size)\
+ (ETH_XLNX_BUFFER_ALIGNMENT - 1))\
& ~(ETH_XLNX_BUFFER_ALIGNMENT - 1))];\
uint8_t tx_buffer\
[DT_INST_PROP(port, tx_buffer_descriptors)]\
[((DT_INST_PROP(port, tx_buffer_size)\
+ (ETH_XLNX_BUFFER_ALIGNMENT - 1))\
& ~(ETH_XLNX_BUFFER_ALIGNMENT - 1))];\
};
/* DMA memory area instantiation macro */
#define ETH_XLNX_GEM_DMA_AREA_INST(port) \
static struct eth_xlnx_dma_area_gem##port eth_xlnx_gem##port##_dma_area\
__ocm_bss_section __aligned(4096);
/* Interrupt configuration function macro */
#define ETH_XLNX_GEM_CONFIG_IRQ_FUNC(port) \
static void eth_xlnx_gem##port##_irq_config(const struct device *dev)\
{\
ARG_UNUSED(dev);\
IRQ_CONNECT(DT_INST_IRQN(port), DT_INST_IRQ(port, priority),\
eth_xlnx_gem_isr, DEVICE_DT_INST_GET(port), 0);\
irq_enable(DT_INST_IRQN(port));\
}
/* RX/TX BD Ring initialization macro */
#define ETH_XLNX_GEM_INIT_BD_RING(port) \
if (dev_conf->base_addr == DT_REG_ADDR_BY_IDX(DT_INST(port, xlnx_gem), 0)) {\
dev_data->rxbd_ring.first_bd = &(eth_xlnx_gem##port##_dma_area.rx_bd[0]);\
dev_data->txbd_ring.first_bd = &(eth_xlnx_gem##port##_dma_area.tx_bd[0]);\
dev_data->first_rx_buffer = (uint8_t *)eth_xlnx_gem##port##_dma_area.rx_buffer;\
dev_data->first_tx_buffer = (uint8_t *)eth_xlnx_gem##port##_dma_area.tx_buffer;\
}
/* Top-level device initialization macro - bundles all of the above */
#define ETH_XLNX_GEM_INITIALIZE(port) \
ETH_XLNX_GEM_CONFIG_IRQ_FUNC(port);\
ETH_XLNX_GEM_DEV_CONFIG(port);\
ETH_XLNX_GEM_DEV_DATA(port);\
ETH_XLNX_GEM_DMA_AREA_DECL(port);\
ETH_XLNX_GEM_DMA_AREA_INST(port);\
ETH_XLNX_GEM_NET_DEV_INIT(port);\
/* IRQ handler function type */
typedef void (*eth_xlnx_gem_config_irq_t)(const struct device *dev);
/* Enums for bitfields representing configuration settings */
/**
* @brief Link speed configuration enumeration type.
*
* Enumeration type for link speed indication, contains 'link down'
* plus all link speeds supported by the controller (10/100/1000).
*/
enum eth_xlnx_link_speed {
/* The values of this enum are consecutively numbered */
LINK_DOWN = 0,
LINK_10MBIT,
LINK_100MBIT,
LINK_1GBIT
};
/**
* @brief AMBA AHB data bus width configuration enumeration type.
*
* Enumeration type containing the supported width options for the
* AMBA AHB data bus. This is a configuration item in the controller's
* net_cfg register.
*/
enum eth_xlnx_amba_dbus_width {
/* The values of this enum are consecutively numbered */
AMBA_AHB_DBUS_WIDTH_32BIT = 0,
AMBA_AHB_DBUS_WIDTH_64BIT,
AMBA_AHB_DBUS_WIDTH_128BIT
};
/**
* @brief MDC clock divider configuration enumeration type.
*
* Enumeration type containing the supported clock divider values
* used to generate the MDIO interface clock (MDC) from either the
* cpu_1x clock (Zynq-7000) or the LPD LSBUS clock (UltraScale).
* This is a configuration item in the controller's net_cfg register.
*/
enum eth_xlnx_mdc_clock_divider {
/* The values of this enum are consecutively numbered */
MDC_DIVIDER_8 = 0,
MDC_DIVIDER_16,
MDC_DIVIDER_32,
MDC_DIVIDER_48,
#ifdef CONFIG_SOC_FAMILY_XILINX_ZYNQ7000
/* Dividers > 48 are only available in the Zynq-7000 */
MDC_DIVIDER_64,
MDC_DIVIDER_96,
MDC_DIVIDER_128,
MDC_DIVIDER_224
#endif
};
/**
* @brief DMA RX buffer size configuration enumeration type.
*
* Enumeration type containing the supported size options for the
* DMA receive buffer size in AHB system memory. This is a configuration
* item in the controller's dma_cfg register.
*/
enum eth_xlnx_hwrx_buffer_size {
/* The values of this enum are consecutively numbered */
HWRX_BUFFER_SIZE_1KB = 0,
HWRX_BUFFER_SIZE_2KB,
HWRX_BUFFER_SIZE_4KB,
HWRX_BUFFER_SIZE_8KB
};
/**
* @brief AHB burst length configuration enumeration type.
*
* Enumeration type containing the supported burst length options
* for the AHB fixed burst length for DMA data operations. This is a
* configuration item in the controller's dma_cfg register.
*/
enum eth_xlnx_ahb_burst_length {
/* The values of this enum are one-hot encoded */
AHB_BURST_SINGLE = 1,
/* 2 = also AHB_BURST_SINGLE */
AHB_BURST_INCR4 = 4,
AHB_BURST_INCR8 = 8,
AHB_BURST_INCR16 = 16
};
/**
* @brief DMA memory area buffer descriptor.
*
* An array of these descriptors for each RX and TX is used to
* describe the respective DMA memory area. Each address word
* points to the start of a RX or TX buffer within the DMA memory
* area, while the control word is used for buffer status exchange
* with the controller.
*/
struct eth_xlnx_gem_bd {
/* TODO for Cortex-A53: 64-bit addressing */
/* TODO: timestamping support */
/* Buffer physical address (absolute address) */
uint32_t addr;
/* Buffer control word (different contents for RX and TX) */
uint32_t ctrl;
};
/**
* @brief DMA memory area buffer descriptor ring management structure.
*
* The DMA memory area buffer descriptor ring management structure
* is used to manage either the RX or TX buffer descriptor array
* (while the buffer descriptors are just an array from the software
* point of view, the controller treats them as a ring, in which the
* last descriptor's control word has a special last-in-ring bit set).
* It contains a pointer to the start of the descriptor array, a
* semaphore as a means of preventing concurrent access, a free entry
* counter as well as indices used to determine which BD shall be used
* or evaluated for the next RX/TX operation.
*/
struct eth_xlnx_gem_bdring {
/* Concurrent modification protection */
struct k_sem ring_sem;
/* Pointer to the first BD in the list */
struct eth_xlnx_gem_bd *first_bd;
/* Index of the next BD to be used for TX */
uint8_t next_to_use;
/* Index of the next BD to be processed (both RX/TX) */
uint8_t next_to_process;
/* Number of currently available BDs in this ring */
uint8_t free_bds;
};
/**
* @brief Constant device configuration data structure.
*
* This struct contains all device configuration data for a GEM
* controller instance which is constant. The data herein is
* either acquired from the generated header file based on the
* data from Kconfig, or from header file based on the device tree
* data. Some of the data contained, in particular data relating
* to clock sources, is specific to either the Zynq-7000 or the
* UltraScale SoCs, which both contain the GEM.
*/
struct eth_xlnx_gem_dev_cfg {
uint32_t base_addr;
eth_xlnx_gem_config_irq_t config_func;
uint32_t pll_clock_frequency;
uint32_t clk_ctrl_reg_address;
enum eth_xlnx_mdc_clock_divider mdc_divider;
enum eth_xlnx_link_speed max_link_speed;
bool init_phy;
uint8_t phy_mdio_addr_fix;
uint8_t phy_advertise_lower;
uint32_t phy_poll_interval;
uint8_t defer_rxp_to_queue;
uint8_t defer_txd_to_queue;
enum eth_xlnx_amba_dbus_width amba_dbus_width;
enum eth_xlnx_ahb_burst_length ahb_burst_length;
enum eth_xlnx_hwrx_buffer_size hw_rx_buffer_size;
uint8_t hw_rx_buffer_offset;
uint8_t rxbd_count;
uint8_t txbd_count;
uint16_t rx_buffer_size;
uint16_t tx_buffer_size;
bool ignore_ipg_rxer : 1;
bool disable_reject_nsp : 1;
bool enable_ipg_stretch : 1;
bool enable_sgmii_mode : 1;
bool disable_reject_fcs_crc_errors : 1;
bool enable_rx_halfdup_while_tx : 1;
bool enable_rx_chksum_offload : 1;
bool disable_pause_copy : 1;
bool discard_rx_fcs : 1;
bool discard_rx_length_errors : 1;
bool enable_pause : 1;
bool enable_tbi : 1;
bool ext_addr_match : 1;
bool enable_1536_frames : 1;
bool enable_ucast_hash : 1;
bool enable_mcast_hash : 1;
bool disable_bcast : 1;
bool copy_all_frames : 1;
bool discard_non_vlan : 1;
bool enable_fdx : 1;
bool disc_rx_ahb_unavail : 1;
bool enable_tx_chksum_offload : 1;
bool tx_buffer_size_full : 1;
bool enable_ahb_packet_endian_swap : 1;
bool enable_ahb_md_endian_swap : 1;
};
/**
* @brief Run-time device configuration data structure.
*
* This struct contains all device configuration data for a GEM
* controller instance which is modifyable at run-time, such as
* data relating to the attached PHY or the auxiliary thread.
*/
struct eth_xlnx_gem_dev_data {
struct net_if *iface;
uint8_t mac_addr[6];
enum eth_xlnx_link_speed eff_link_speed;
struct k_work tx_done_work;
struct k_work rx_pend_work;
struct k_sem tx_done_sem;
uint8_t phy_addr;
uint32_t phy_id;
struct k_work_delayable phy_poll_delayed_work;
struct phy_xlnx_gem_api *phy_access_api;
uint8_t *first_rx_buffer;
uint8_t *first_tx_buffer;
struct eth_xlnx_gem_bdring rxbd_ring;
struct eth_xlnx_gem_bdring txbd_ring;
#ifdef CONFIG_NET_STATISTICS_ETHERNET
struct net_stats_eth stats;
#endif
bool started;
};
#endif /* _ZEPHYR_DRIVERS_ETHERNET_ETH_XLNX_GEM_PRIV_H_ */