178bdc4afc
Change automated searching for files using "IRQ_CONNECT()" API not including <zephyr/irq.h>. Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
770 lines
30 KiB
C
770 lines
30 KiB
C
/*
|
|
* 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,\
|
|
ð_xlnx_gem##port##_dev_data,\
|
|
ð_xlnx_gem##port##_dev_cfg,\
|
|
CONFIG_ETH_INIT_PRIORITY,\
|
|
ð_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_ */
|