You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
767 lines
30 KiB
767 lines
30 KiB
/* |
|
* 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),\ |
|
.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 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_ */
|
|
|