add ethernet driver for zynqmp-r5-axu4ev
This commit is contained in:
parent
e58ea3ded4
commit
d205721462
|
@ -23,6 +23,12 @@ CONFIG_IDLE_THREAD_STACK_SIZE=512
|
|||
CONFIG_RT_USING_TIMER_SOFT=y
|
||||
CONFIG_RT_TIMER_THREAD_PRIO=4
|
||||
CONFIG_RT_TIMER_THREAD_STACK_SIZE=512
|
||||
|
||||
#
|
||||
# kservice optimization
|
||||
#
|
||||
# CONFIG_RT_KSERVICE_USING_STDLIB is not set
|
||||
# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
|
||||
CONFIG_RT_DEBUG=y
|
||||
# CONFIG_RT_DEBUG_COLOR is not set
|
||||
# CONFIG_RT_DEBUG_INIT_CONFIG is not set
|
||||
|
@ -52,8 +58,9 @@ CONFIG_RT_USING_MESSAGEQUEUE=y
|
|||
CONFIG_RT_USING_MEMPOOL=y
|
||||
# CONFIG_RT_USING_MEMHEAP is not set
|
||||
# CONFIG_RT_USING_NOHEAP is not set
|
||||
CONFIG_RT_USING_SMALL_MEM=y
|
||||
# CONFIG_RT_USING_SLAB is not set
|
||||
# CONFIG_RT_USING_SMALL_MEM is not set
|
||||
CONFIG_RT_USING_SLAB=y
|
||||
# CONFIG_RT_USING_USERHEAP is not set
|
||||
# CONFIG_RT_USING_MEMTRACE is not set
|
||||
CONFIG_RT_USING_HEAP=y
|
||||
|
||||
|
@ -66,7 +73,7 @@ CONFIG_RT_USING_DEVICE=y
|
|||
CONFIG_RT_USING_CONSOLE=y
|
||||
CONFIG_RT_CONSOLEBUF_SIZE=128
|
||||
CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
|
||||
CONFIG_RT_VER_NUM=0x40003
|
||||
CONFIG_RT_VER_NUM=0x40004
|
||||
# CONFIG_RT_USING_CPU_FFS is not set
|
||||
# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
|
||||
|
||||
|
@ -123,6 +130,11 @@ CONFIG_RT_DFS_ELM_WORD_ACCESS=y
|
|||
# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
|
||||
CONFIG_RT_DFS_ELM_USE_LFN_3=y
|
||||
CONFIG_RT_DFS_ELM_USE_LFN=3
|
||||
CONFIG_RT_DFS_ELM_LFN_UNICODE_0=y
|
||||
# CONFIG_RT_DFS_ELM_LFN_UNICODE_1 is not set
|
||||
# CONFIG_RT_DFS_ELM_LFN_UNICODE_2 is not set
|
||||
# CONFIG_RT_DFS_ELM_LFN_UNICODE_3 is not set
|
||||
CONFIG_RT_DFS_ELM_LFN_UNICODE=0
|
||||
CONFIG_RT_DFS_ELM_MAX_LFN=255
|
||||
CONFIG_RT_DFS_ELM_DRIVES=2
|
||||
CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=512
|
||||
|
@ -131,15 +143,16 @@ CONFIG_RT_DFS_ELM_REENTRANT=y
|
|||
CONFIG_RT_USING_DFS_DEVFS=y
|
||||
# CONFIG_RT_USING_DFS_ROMFS is not set
|
||||
# CONFIG_RT_USING_DFS_RAMFS is not set
|
||||
# CONFIG_RT_USING_DFS_UFFS is not set
|
||||
# CONFIG_RT_USING_DFS_JFFS2 is not set
|
||||
# CONFIG_RT_USING_DFS_NFS is not set
|
||||
|
||||
#
|
||||
# Device Drivers
|
||||
#
|
||||
CONFIG_RT_USING_DEVICE_IPC=y
|
||||
CONFIG_RT_PIPE_BUFSZ=512
|
||||
# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
|
||||
CONFIG_RT_USING_SYSTEM_WORKQUEUE=y
|
||||
CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048
|
||||
CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23
|
||||
CONFIG_RT_USING_SERIAL=y
|
||||
CONFIG_RT_SERIAL_USING_DMA=y
|
||||
CONFIG_RT_SERIAL_RB_BUFSZ=64
|
||||
|
@ -147,6 +160,7 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64
|
|||
# CONFIG_RT_USING_HWTIMER is not set
|
||||
# CONFIG_RT_USING_CPUTIME is not set
|
||||
# CONFIG_RT_USING_I2C is not set
|
||||
# CONFIG_RT_USING_PHY is not set
|
||||
CONFIG_RT_USING_PIN=y
|
||||
# CONFIG_RT_USING_ADC is not set
|
||||
# CONFIG_RT_USING_DAC is not set
|
||||
|
@ -172,11 +186,6 @@ CONFIG_RT_USING_PIN=y
|
|||
# CONFIG_RT_USING_USB_HOST is not set
|
||||
# CONFIG_RT_USING_USB_DEVICE is not set
|
||||
|
||||
#
|
||||
# Using RapidIO
|
||||
#
|
||||
# CONFIG_RT_USING_RAPIDIO is not set
|
||||
|
||||
#
|
||||
# POSIX layer and C standard library
|
||||
#
|
||||
|
@ -188,6 +197,7 @@ CONFIG_RT_USING_POSIX=y
|
|||
# CONFIG_RT_USING_POSIX_GETLINE is not set
|
||||
# CONFIG_RT_USING_POSIX_AIO is not set
|
||||
# CONFIG_RT_USING_MODULE is not set
|
||||
CONFIG_RT_LIBC_FIXED_TIMEZONE=8
|
||||
|
||||
#
|
||||
# Network
|
||||
|
@ -196,22 +206,91 @@ CONFIG_RT_USING_POSIX=y
|
|||
#
|
||||
# Socket abstraction layer
|
||||
#
|
||||
# CONFIG_RT_USING_SAL is not set
|
||||
CONFIG_RT_USING_SAL=y
|
||||
CONFIG_SAL_INTERNET_CHECK=y
|
||||
|
||||
#
|
||||
# protocol stack implement
|
||||
#
|
||||
CONFIG_SAL_USING_LWIP=y
|
||||
CONFIG_SAL_USING_POSIX=y
|
||||
|
||||
#
|
||||
# Network interface device
|
||||
#
|
||||
# CONFIG_RT_USING_NETDEV is not set
|
||||
CONFIG_RT_USING_NETDEV=y
|
||||
CONFIG_NETDEV_USING_IFCONFIG=y
|
||||
CONFIG_NETDEV_USING_PING=y
|
||||
CONFIG_NETDEV_USING_NETSTAT=y
|
||||
CONFIG_NETDEV_USING_AUTO_DEFAULT=y
|
||||
# CONFIG_NETDEV_USING_IPV6 is not set
|
||||
CONFIG_NETDEV_IPV4=1
|
||||
CONFIG_NETDEV_IPV6=0
|
||||
# CONFIG_NETDEV_IPV6_SCOPES is not set
|
||||
|
||||
#
|
||||
# light weight TCP/IP stack
|
||||
#
|
||||
# CONFIG_RT_USING_LWIP is not set
|
||||
CONFIG_RT_USING_LWIP=y
|
||||
# CONFIG_RT_USING_LWIP141 is not set
|
||||
CONFIG_RT_USING_LWIP202=y
|
||||
# CONFIG_RT_USING_LWIP212 is not set
|
||||
# CONFIG_RT_USING_LWIP_IPV6 is not set
|
||||
CONFIG_RT_LWIP_MEM_ALIGNMENT=32
|
||||
CONFIG_RT_LWIP_IGMP=y
|
||||
CONFIG_RT_LWIP_ICMP=y
|
||||
# CONFIG_RT_LWIP_SNMP is not set
|
||||
CONFIG_RT_LWIP_DNS=y
|
||||
CONFIG_RT_LWIP_DHCP=y
|
||||
CONFIG_IP_SOF_BROADCAST=1
|
||||
CONFIG_IP_SOF_BROADCAST_RECV=1
|
||||
|
||||
#
|
||||
# Static IPv4 Address
|
||||
#
|
||||
CONFIG_RT_LWIP_IPADDR="192.168.1.30"
|
||||
CONFIG_RT_LWIP_GWADDR="192.168.1.1"
|
||||
CONFIG_RT_LWIP_MSKADDR="255.255.255.0"
|
||||
CONFIG_RT_LWIP_UDP=y
|
||||
CONFIG_RT_LWIP_TCP=y
|
||||
CONFIG_RT_LWIP_RAW=y
|
||||
# CONFIG_RT_LWIP_PPP is not set
|
||||
CONFIG_RT_MEMP_NUM_NETCONN=8
|
||||
CONFIG_RT_LWIP_PBUF_NUM=256
|
||||
CONFIG_RT_LWIP_RAW_PCB_NUM=4
|
||||
CONFIG_RT_LWIP_UDP_PCB_NUM=4
|
||||
CONFIG_RT_LWIP_TCP_PCB_NUM=4
|
||||
CONFIG_RT_LWIP_TCP_SEG_NUM=40
|
||||
CONFIG_RT_LWIP_TCP_SND_BUF=8196
|
||||
CONFIG_RT_LWIP_TCP_WND=8196
|
||||
CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=10
|
||||
CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=8
|
||||
CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=2048
|
||||
# CONFIG_LWIP_NO_RX_THREAD is not set
|
||||
# CONFIG_LWIP_NO_TX_THREAD is not set
|
||||
CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=12
|
||||
CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=1024
|
||||
CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=8
|
||||
# CONFIG_RT_LWIP_REASSEMBLY_FRAG is not set
|
||||
CONFIG_LWIP_NETIF_STATUS_CALLBACK=1
|
||||
CONFIG_LWIP_NETIF_LINK_CALLBACK=1
|
||||
CONFIG_SO_REUSE=1
|
||||
CONFIG_LWIP_SO_RCVTIMEO=1
|
||||
CONFIG_LWIP_SO_SNDTIMEO=1
|
||||
CONFIG_LWIP_SO_RCVBUF=1
|
||||
CONFIG_LWIP_SO_LINGER=0
|
||||
# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set
|
||||
CONFIG_LWIP_NETIF_LOOPBACK=0
|
||||
# CONFIG_RT_LWIP_STATS is not set
|
||||
# CONFIG_RT_LWIP_USING_HW_CHECKSUM is not set
|
||||
CONFIG_RT_LWIP_USING_PING=y
|
||||
# CONFIG_RT_LWIP_DEBUG is not set
|
||||
|
||||
#
|
||||
# AT commands
|
||||
#
|
||||
# CONFIG_RT_USING_AT is not set
|
||||
# CONFIG_LWIP_USING_DHCPD is not set
|
||||
|
||||
#
|
||||
# VBUS(Virtual Software BUS)
|
||||
|
@ -225,6 +304,11 @@ CONFIG_RT_USING_POSIX=y
|
|||
# CONFIG_RT_USING_ULOG is not set
|
||||
# CONFIG_RT_USING_UTEST is not set
|
||||
|
||||
#
|
||||
# RT-Thread Utestcases
|
||||
#
|
||||
# CONFIG_RT_USING_UTESTCASES is not set
|
||||
|
||||
#
|
||||
# RT-Thread online packages
|
||||
#
|
||||
|
@ -292,8 +376,6 @@ CONFIG_RT_USING_POSIX=y
|
|||
# CONFIG_PKG_USING_LIBRWS is not set
|
||||
# CONFIG_PKG_USING_TCPSERVER is not set
|
||||
# CONFIG_PKG_USING_PROTOBUF_C is not set
|
||||
# CONFIG_PKG_USING_ONNX_PARSER is not set
|
||||
# CONFIG_PKG_USING_ONNX_BACKEND is not set
|
||||
# CONFIG_PKG_USING_DLT645 is not set
|
||||
# CONFIG_PKG_USING_QXWZ is not set
|
||||
# CONFIG_PKG_USING_SMTP_CLIENT is not set
|
||||
|
@ -307,6 +389,13 @@ CONFIG_RT_USING_POSIX=y
|
|||
# CONFIG_PKG_USING_PDULIB is not set
|
||||
# CONFIG_PKG_USING_BTSTACK is not set
|
||||
# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
|
||||
# CONFIG_PKG_USING_WAYZ_IOTKIT is not set
|
||||
# CONFIG_PKG_USING_MAVLINK is not set
|
||||
# CONFIG_PKG_USING_RAPIDJSON is not set
|
||||
# CONFIG_PKG_USING_BSAL is not set
|
||||
# CONFIG_PKG_USING_AGILE_MODBUS is not set
|
||||
# CONFIG_PKG_USING_AGILE_FTP is not set
|
||||
# CONFIG_PKG_USING_EMBEDDEDPROTO is not set
|
||||
|
||||
#
|
||||
# security packages
|
||||
|
@ -332,8 +421,11 @@ CONFIG_RT_USING_POSIX=y
|
|||
# CONFIG_PKG_USING_STEMWIN is not set
|
||||
# CONFIG_PKG_USING_WAVPLAYER is not set
|
||||
# CONFIG_PKG_USING_TJPGD is not set
|
||||
# CONFIG_PKG_USING_PDFGEN is not set
|
||||
# CONFIG_PKG_USING_HELIX is not set
|
||||
# CONFIG_PKG_USING_AZUREGUIX is not set
|
||||
# CONFIG_PKG_USING_TOUCHGFX2RTT is not set
|
||||
# CONFIG_PKG_USING_NUEMWIN is not set
|
||||
|
||||
#
|
||||
# tools packages
|
||||
|
@ -345,6 +437,8 @@ CONFIG_RT_USING_POSIX=y
|
|||
# CONFIG_PKG_USING_RDB is not set
|
||||
# CONFIG_PKG_USING_QRCODE is not set
|
||||
# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
|
||||
# CONFIG_PKG_USING_ULOG_FILE is not set
|
||||
# CONFIG_PKG_USING_LOGMGR is not set
|
||||
# CONFIG_PKG_USING_ADBD is not set
|
||||
# CONFIG_PKG_USING_COREMARK is not set
|
||||
# CONFIG_PKG_USING_DHRYSTONE is not set
|
||||
|
@ -357,6 +451,22 @@ CONFIG_RT_USING_POSIX=y
|
|||
# CONFIG_PKG_USING_URLENCODE is not set
|
||||
# CONFIG_PKG_USING_UMCN is not set
|
||||
# CONFIG_PKG_USING_LWRB2RTT is not set
|
||||
# CONFIG_PKG_USING_CPU_USAGE is not set
|
||||
# CONFIG_PKG_USING_GBK2UTF8 is not set
|
||||
# CONFIG_PKG_USING_VCONSOLE is not set
|
||||
# CONFIG_PKG_USING_KDB is not set
|
||||
# CONFIG_PKG_USING_WAMR is not set
|
||||
# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set
|
||||
# CONFIG_PKG_USING_LWLOG is not set
|
||||
# CONFIG_PKG_USING_ANV_TRACE is not set
|
||||
# CONFIG_PKG_USING_ANV_MEMLEAK is not set
|
||||
# CONFIG_PKG_USING_ANV_TESTSUIT is not set
|
||||
# CONFIG_PKG_USING_ANV_BENCH is not set
|
||||
# CONFIG_PKG_USING_DEVMEM is not set
|
||||
# CONFIG_PKG_USING_REGEX is not set
|
||||
# CONFIG_PKG_USING_MEM_SANDBOX is not set
|
||||
# CONFIG_PKG_USING_SOLAR_TERMS is not set
|
||||
# CONFIG_PKG_USING_GAN_ZHI is not set
|
||||
|
||||
#
|
||||
# system packages
|
||||
|
@ -364,7 +474,6 @@ CONFIG_RT_USING_POSIX=y
|
|||
# CONFIG_PKG_USING_GUIENGINE is not set
|
||||
# CONFIG_PKG_USING_CAIRO is not set
|
||||
# CONFIG_PKG_USING_PIXMAN is not set
|
||||
# CONFIG_PKG_USING_LWEXT4 is not set
|
||||
# CONFIG_PKG_USING_PARTITION is not set
|
||||
# CONFIG_PKG_USING_FAL is not set
|
||||
# CONFIG_PKG_USING_FLASHDB is not set
|
||||
|
@ -374,6 +483,9 @@ CONFIG_RT_USING_POSIX=y
|
|||
# CONFIG_PKG_USING_CMSIS is not set
|
||||
# CONFIG_PKG_USING_DFS_YAFFS is not set
|
||||
# CONFIG_PKG_USING_LITTLEFS is not set
|
||||
# CONFIG_PKG_USING_DFS_JFFS2 is not set
|
||||
# CONFIG_PKG_USING_DFS_UFFS is not set
|
||||
# CONFIG_PKG_USING_LWEXT4 is not set
|
||||
# CONFIG_PKG_USING_THREAD_POOL is not set
|
||||
# CONFIG_PKG_USING_ROBOTS is not set
|
||||
# CONFIG_PKG_USING_EV is not set
|
||||
|
@ -388,11 +500,21 @@ CONFIG_RT_USING_POSIX=y
|
|||
# Micrium: Micrium software products porting for RT-Thread
|
||||
#
|
||||
# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
|
||||
# CONFIG_PKG_USING_UCOSII_WRAPPER is not set
|
||||
# CONFIG_PKG_USING_UC_CRC is not set
|
||||
# CONFIG_PKG_USING_UC_CLK is not set
|
||||
# CONFIG_PKG_USING_UC_COMMON is not set
|
||||
# CONFIG_PKG_USING_UC_MODBUS is not set
|
||||
# CONFIG_PKG_USING_PPOOL is not set
|
||||
# CONFIG_PKG_USING_OPENAMP is not set
|
||||
# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
|
||||
# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
|
||||
# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set
|
||||
# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
|
||||
# CONFIG_PKG_USING_QFPLIB_M3 is not set
|
||||
# CONFIG_PKG_USING_LPM is not set
|
||||
# CONFIG_PKG_USING_TLSF is not set
|
||||
# CONFIG_PKG_USING_EVENT_RECORDER is not set
|
||||
|
||||
#
|
||||
# peripheral libraries and drivers
|
||||
|
@ -401,6 +523,7 @@ CONFIG_RT_USING_POSIX=y
|
|||
# CONFIG_PKG_USING_REALTEK_AMEBA is not set
|
||||
# CONFIG_PKG_USING_SHT2X is not set
|
||||
# CONFIG_PKG_USING_SHT3X is not set
|
||||
# CONFIG_PKG_USING_AS7341 is not set
|
||||
# CONFIG_PKG_USING_STM32_SDIO is not set
|
||||
# CONFIG_PKG_USING_ICM20608 is not set
|
||||
# CONFIG_PKG_USING_U8G2 is not set
|
||||
|
@ -449,6 +572,30 @@ CONFIG_RT_USING_POSIX=y
|
|||
# CONFIG_PKG_USING_DM9051 is not set
|
||||
# CONFIG_PKG_USING_SSD1306 is not set
|
||||
# CONFIG_PKG_USING_QKEY is not set
|
||||
# CONFIG_PKG_USING_RS485 is not set
|
||||
# CONFIG_PKG_USING_NES is not set
|
||||
# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
|
||||
# CONFIG_PKG_USING_VDEVICE is not set
|
||||
# CONFIG_PKG_USING_SGM706 is not set
|
||||
# CONFIG_PKG_USING_STM32WB55_SDK is not set
|
||||
# CONFIG_PKG_USING_RDA58XX is not set
|
||||
# CONFIG_PKG_USING_LIBNFC is not set
|
||||
# CONFIG_PKG_USING_MFOC is not set
|
||||
# CONFIG_PKG_USING_TMC51XX is not set
|
||||
# CONFIG_PKG_USING_TCA9534 is not set
|
||||
|
||||
#
|
||||
# AI packages
|
||||
#
|
||||
# CONFIG_PKG_USING_LIBANN is not set
|
||||
# CONFIG_PKG_USING_NNOM is not set
|
||||
# CONFIG_PKG_USING_ONNX_BACKEND is not set
|
||||
# CONFIG_PKG_USING_ONNX_PARSER is not set
|
||||
# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
|
||||
# CONFIG_PKG_USING_ELAPACK is not set
|
||||
# CONFIG_PKG_USING_ULAPACK is not set
|
||||
# CONFIG_PKG_USING_QUEST is not set
|
||||
# CONFIG_PKG_USING_NAXOS is not set
|
||||
|
||||
#
|
||||
# miscellaneous packages
|
||||
|
@ -458,6 +605,7 @@ CONFIG_RT_USING_POSIX=y
|
|||
# CONFIG_PKG_USING_FASTLZ is not set
|
||||
# CONFIG_PKG_USING_MINILZO is not set
|
||||
# CONFIG_PKG_USING_QUICKLZ is not set
|
||||
# CONFIG_PKG_USING_LZMA is not set
|
||||
# CONFIG_PKG_USING_MULTIBUTTON is not set
|
||||
# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
|
||||
# CONFIG_PKG_USING_CANFESTIVAL is not set
|
||||
|
@ -479,19 +627,24 @@ CONFIG_RT_USING_POSIX=y
|
|||
# CONFIG_PKG_USING_HELLO is not set
|
||||
# CONFIG_PKG_USING_VI is not set
|
||||
# CONFIG_PKG_USING_KI is not set
|
||||
# CONFIG_PKG_USING_NNOM is not set
|
||||
# CONFIG_PKG_USING_LIBANN is not set
|
||||
# CONFIG_PKG_USING_ELAPACK is not set
|
||||
# CONFIG_PKG_USING_ARMv7M_DWT is not set
|
||||
# CONFIG_PKG_USING_VT100 is not set
|
||||
# CONFIG_PKG_USING_TETRIS is not set
|
||||
# CONFIG_PKG_USING_ULAPACK is not set
|
||||
# CONFIG_PKG_USING_UKAL is not set
|
||||
# CONFIG_PKG_USING_CRCLIB is not set
|
||||
|
||||
#
|
||||
# entertainment: terminal games and other interesting software packages
|
||||
#
|
||||
# CONFIG_PKG_USING_THREES is not set
|
||||
# CONFIG_PKG_USING_2048 is not set
|
||||
# CONFIG_PKG_USING_SNAKE is not set
|
||||
# CONFIG_PKG_USING_TETRIS is not set
|
||||
# CONFIG_PKG_USING_DONUT is not set
|
||||
# CONFIG_PKG_USING_ACLOCK is not set
|
||||
# CONFIG_PKG_USING_LWGPS is not set
|
||||
# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
|
||||
# CONFIG_PKG_USING_STATE_MACHINE is not set
|
||||
# CONFIG_PKG_USING_MCURSES is not set
|
||||
# CONFIG_PKG_USING_COWSAY is not set
|
||||
CONFIG_SOC_ZYNQMP_R5=y
|
||||
|
||||
#
|
||||
|
@ -510,6 +663,16 @@ CONFIG_BSP_USING_UART0=y
|
|||
CONFIG_BSP_USING_SDIO=y
|
||||
CONFIG_BSP_USING_SD0=y
|
||||
|
||||
#
|
||||
# Please set RT_LWIP_PBUF_NUM is at least 256 if Enable Ethernet!
|
||||
#
|
||||
|
||||
#
|
||||
# Please set RT_LWIP_MEM_ALIGNMENT is at 32 if Enable Ethernet!
|
||||
#
|
||||
CONFIG_BSP_USING_ETH=y
|
||||
CONFIG_RT_LWIP_PBUF_POOL_BUFSIZE=1700
|
||||
|
||||
#
|
||||
# Board extended module Drivers
|
||||
#
|
||||
|
|
|
@ -35,6 +35,7 @@ Each peripheral supporting condition for this BSP is as follows:
|
|||
| UART | Support | UART0 |
|
||||
| TIMER | Support | TTC0 provides system clock |
|
||||
| EMMC | Support | SD0 Controller |
|
||||
| EMAC | Support | e0 Net Interface |
|
||||
|
||||
## Execution Instruction
|
||||
|
||||
|
@ -99,14 +100,31 @@ msh />
|
|||
|
||||
This BSP enables EMMC driver and DFS file system by default. If you need to use a file system, you can format and mount it by yourself.
|
||||
|
||||
This BSP is enabled and configured with net interface driver and LwIP protocol stack by default, and note the following configuration:
|
||||
|
||||
1. Note that `RT_LWIP_PBUF_NUM` is set to at least 256
|
||||
|
||||
2. Note that `RT_ LWIP_ MEM_ Alignment` is set to 32. If the version other than lwip 2.0.2 in RTT is used, the `MEM_ALIGNMENT` in `lwipopts.h` needs to be modified manually because the macro is not used in other versions.
|
||||
|
||||
## BSP Migration
|
||||
|
||||
If you need to ported the BSP to another development board of Xilinx Zynq UltraScale+ MPSOC development platform, it is also convenient. The main modifications are as follows:
|
||||
|
||||
1. Memory: `psu_r5_ddr_0_MEM_0` in `zynqmp-r5.ld` (if DDR memory is less than 2G)
|
||||
1. Memory: `psu_r5_ddr_0_MEM_0` in `zynqmp-r5.ld` and `HEAP_END` in `board.h ` (if DDR memory is less than 2G)
|
||||
2. Main Frequency: `XPAR_CPU_CORTEXR5_0_CPU_CLK_FREQ_HZ` in `zynqmp-r5.h`
|
||||
3. Pin and Frequency of Serial Port: `rxmio`, `txmio` and `XPAR_PSU_UART_0_UART_CLK_FREQ_HZ` in `drv_uart.c`
|
||||
4. Timer Frequency: `XPAR_PSU_TTC_0_TTC_CLK_FREQ_HZ` in `drv_timer.c`
|
||||
5. SD Controller: Block device driver initialization in `drv_sdcard.c`
|
||||
6. Net interface: If the PHY chip used is not in the range of driver support, it may be necessary to realize the rate identification function of the corresponding chip in `xemacpsif_physpeed.c`. You can refer to the corresponding tutorial of Alinx.
|
||||
|
||||
The parameter macro definition in `xparameters.h` does not need to be modified manually. You can directly copy the `xparameters.h` file of the development board generated in Xilinx Vitis.
|
||||
|
||||
## Attention
|
||||
|
||||
-None
|
||||
|
||||
## Contact
|
||||
|
||||
Maintainer:
|
||||
|
||||
- [Wang Huachen](https://github.com/Wang-Huachen/)
|
|
@ -32,6 +32,7 @@ AXU4EV-E 开发板是 芯驿电子科技(上海)有限公司 推出的一款
|
|||
| UART | 支持 | UART0 |
|
||||
| TIMER | 支持 | TTC0提供系统时钟 |
|
||||
| EMMC | 支持 | SD0控制器 |
|
||||
| EMAC | 支持 | e0网卡 |
|
||||
|
||||
## 使用说明
|
||||
|
||||
|
@ -107,16 +108,22 @@ msh />
|
|||
|
||||
此 BSP 默认开启了 EMMC 驱动和 DFS 文件系统,如果需要使用文件系统可以自行格式化并挂载。
|
||||
|
||||
此 BSP 默认开启并配置了网卡驱动及lwip协议栈,相关配置需要注意如下几点:
|
||||
|
||||
1. 注意将`RT_LWIP_PBUF_NUM`至少设置为256
|
||||
2. 注意将`RT_LWIP_MEM_ALIGNMENT`设置为32。若使用RTT中lwip 2.0.2以外的版本时,由于其他版本未使用该宏,需要手动修改`lwipopts.h`中的`MEM_ALIGNMENT`宏。
|
||||
|
||||
|
||||
## 板级移植
|
||||
|
||||
如果需要将BSP移植到其他 XILINX Zynq UltraScale+ MPSoCs 开发平台的开发板上也比较方便,主要修改的地方有以下几点:
|
||||
|
||||
1. 内存: 如果 DDR memory 小于 2G,需要修改`zynqmp-r5.ld`链接文件中的`psu_r5_ddr_0_MEM_0`
|
||||
1. 内存: 如果 DDR memory 小于 2G,需要修改`zynqmp-r5.ld`链接文件中的`psu_r5_ddr_0_MEM_0` 以及`board.h`中的`HEAP_END`
|
||||
2. 主频: `xparameters.h`中的`XPAR_CPU_CORTEXR5_0_CPU_CLK_FREQ_HZ`
|
||||
3. 串口引脚和频率:`drv_uart.c`中的`rxmio`, `txmio` 和`xparameters.h`中的`XPAR_PSU_UART_0_UART_CLK_FREQ_HZ`
|
||||
4. 定时器频率:`xparameters.h`中的`XPAR_PSU_TTC_0_TTC_CLK_FREQ_HZ`
|
||||
5. SD控制器:`drv_sdcard.c`中的块设备驱动初始化
|
||||
6. 网卡驱动:若使用的PHY芯片不在驱动支持范围内,可能需要在`xemacpsif_physpeed.c`中实现相应芯片的速率识别函数,可参考ALINX的相应教程。
|
||||
|
||||
以上需要修改的`xparameters.h`中的参数宏定义不需要手动修改,可以直接将Xilinx Vitis中产生的开发板的`xparameters.h`文件复制过来即可。
|
||||
|
||||
|
|
|
@ -24,6 +24,19 @@ menu "Hardware Drivers Config"
|
|||
bool "Enable SD0 EMMC"
|
||||
default y
|
||||
endif
|
||||
comment "Please set RT_LWIP_PBUF_NUM is at least 256 if Enable Ethernet!"
|
||||
comment "Please set RT_LWIP_MEM_ALIGNMENT is at 32 if Enable Ethernet!"
|
||||
menuconfig BSP_USING_ETH
|
||||
bool "Enable Ethernet"
|
||||
default n
|
||||
select RT_USING_NETDEV
|
||||
select RT_USING_LWIP
|
||||
if BSP_USING_ETH
|
||||
config RT_LWIP_PBUF_POOL_BUFSIZE
|
||||
int "The size of each pbuf in the pbuf pool"
|
||||
range 1500 2000
|
||||
default 1700
|
||||
endif
|
||||
|
||||
endmenu
|
||||
|
||||
|
|
|
@ -11,6 +11,9 @@ if GetDepend('BSP_USING_SDIO'):
|
|||
objs = objs + SConscript('sdps_v3_9/SConscript')
|
||||
if GetDepend('RT_USING_PIN'):
|
||||
objs = objs + SConscript('gpiops_v3_7/SConscript')
|
||||
if GetDepend('BSP_USING_ETH'):
|
||||
objs = objs + SConscript('emacps_v3_11/SConscript')
|
||||
objs = objs + SConscript('xemacpsif/SConscript')
|
||||
|
||||
objs = objs + group
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import rtconfig
|
||||
from building import *
|
||||
|
||||
# get current directory
|
||||
cwd = GetCurrentDir()
|
||||
CPPPATH = [cwd]
|
||||
|
||||
# The set of source files associated with this SConscript file.
|
||||
|
||||
src = Glob('*.c')
|
||||
path = cwd
|
||||
|
||||
group = DefineGroup('ZYNQMP_HAL', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
|
@ -0,0 +1,480 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2010 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xemacps.c
|
||||
* @addtogroup emacps_v3_11
|
||||
* @{
|
||||
*
|
||||
* The XEmacPs driver. Functions in this file are the minimum required functions
|
||||
* for this driver. See xemacps.h for a detailed description of the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.00a wsy 01/10/10 First release
|
||||
* 2.1 srt 07/15/14 Add support for Zynq Ultrascale Mp GEM specification and
|
||||
* 64-bit changes.
|
||||
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
* 3.0 hk 02/20/15 Added support for jumbo frames. Increase AHB burst.
|
||||
* Disable extended mode. Perform all 64 bit changes under
|
||||
* check for arch64.
|
||||
* 3.1 hk 08/10/15 Update upper 32 bit tx and rx queue ptr registers
|
||||
* 3.5 hk 08/14/17 Update cache coherency information of the interface in
|
||||
* its config structure.
|
||||
* 3.8 hk 09/17/18 Cleanup stale comments.
|
||||
* 3.8 mus 11/05/18 Support 64 bit DMA addresses for Microblaze-X platform.
|
||||
* 3.10 hk 05/16/19 Clear status registers properly in reset
|
||||
* 3.11 sd 02/14/20 Add clock support
|
||||
*
|
||||
* </pre>
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xemacps.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
void XEmacPs_StubHandler(void); /* Default handler routine */
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Initialize a specific XEmacPs instance/driver. The initialization entails:
|
||||
* - Initialize fields of the XEmacPs instance structure
|
||||
* - Reset hardware and apply default options
|
||||
* - Configure the DMA channels
|
||||
*
|
||||
* The PHY is setup independently from the device. Use the MII or whatever other
|
||||
* interface may be present for setup.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param CfgPtr is the device configuration structure containing required
|
||||
* hardware build data.
|
||||
* @param EffectiveAddress is the base address of the device. If address
|
||||
* translation is not utilized, this parameter can be passed in using
|
||||
* CfgPtr->Config.BaseAddress to specify the physical base address.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if initialization was successful
|
||||
*
|
||||
******************************************************************************/
|
||||
LONG XEmacPs_CfgInitialize(XEmacPs *InstancePtr, XEmacPs_Config * CfgPtr,
|
||||
UINTPTR EffectiveAddress)
|
||||
{
|
||||
/* Verify arguments */
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(CfgPtr != NULL);
|
||||
|
||||
/* Set device base address and ID */
|
||||
InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
|
||||
InstancePtr->Config.BaseAddress = EffectiveAddress;
|
||||
InstancePtr->Config.IsCacheCoherent = CfgPtr->IsCacheCoherent;
|
||||
#if defined (XCLOCKING)
|
||||
InstancePtr->Config.RefClk = CfgPtr->RefClk;
|
||||
#endif
|
||||
|
||||
/* Set callbacks to an initial stub routine */
|
||||
InstancePtr->SendHandler = ((XEmacPs_Handler)((void*)XEmacPs_StubHandler));
|
||||
InstancePtr->RecvHandler = ((XEmacPs_Handler)(void*)XEmacPs_StubHandler);
|
||||
InstancePtr->ErrorHandler = ((XEmacPs_ErrHandler)(void*)XEmacPs_StubHandler);
|
||||
|
||||
/* Reset the hardware and set default options */
|
||||
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
|
||||
XEmacPs_Reset(InstancePtr);
|
||||
|
||||
return (LONG)(XST_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Start the Ethernet controller as follows:
|
||||
* - Enable transmitter if XTE_TRANSMIT_ENABLE_OPTION is set
|
||||
* - Enable receiver if XTE_RECEIVER_ENABLE_OPTION is set
|
||||
* - Start the SG DMA send and receive channels and enable the device
|
||||
* interrupt
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
*
|
||||
* @return N/A
|
||||
*
|
||||
* @note
|
||||
* Hardware is configured with scatter-gather DMA, the driver expects to start
|
||||
* the scatter-gather channels and expects that the user has previously set up
|
||||
* the buffer descriptor lists.
|
||||
*
|
||||
* This function makes use of internal resources that are shared between the
|
||||
* Start, Stop, and Set/ClearOptions functions. So if one task might be setting
|
||||
* device options while another is trying to start the device, the user is
|
||||
* required to provide protection of this shared data (typically using a
|
||||
* semaphore).
|
||||
*
|
||||
* This function must not be preempted by an interrupt that may service the
|
||||
* device.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XEmacPs_Start(XEmacPs *InstancePtr)
|
||||
{
|
||||
u32 Reg;
|
||||
|
||||
/* Assert bad arguments and conditions */
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
|
||||
|
||||
#if defined (XCLOCKING)
|
||||
if (InstancePtr->IsStarted != (u32)XIL_COMPONENT_IS_STARTED) {
|
||||
Xil_ClockEnable(InstancePtr->Config.RefClk);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Start DMA */
|
||||
/* When starting the DMA channels, both transmit and receive sides
|
||||
* need an initialized BD list.
|
||||
*/
|
||||
if (InstancePtr->Version == 2) {
|
||||
Xil_AssertVoid(InstancePtr->RxBdRing.BaseBdAddr != 0);
|
||||
Xil_AssertVoid(InstancePtr->TxBdRing.BaseBdAddr != 0);
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_RXQBASE_OFFSET,
|
||||
InstancePtr->RxBdRing.BaseBdAddr);
|
||||
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_TXQBASE_OFFSET,
|
||||
InstancePtr->TxBdRing.BaseBdAddr);
|
||||
}
|
||||
|
||||
/* clear any existed int status */
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
|
||||
XEMACPS_IXR_ALL_MASK);
|
||||
|
||||
/* Enable transmitter if not already enabled */
|
||||
if ((InstancePtr->Options & (u32)XEMACPS_TRANSMITTER_ENABLE_OPTION)!=0x00000000U) {
|
||||
Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
if ((!(Reg & XEMACPS_NWCTRL_TXEN_MASK))==TRUE) {
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET,
|
||||
Reg | (u32)XEMACPS_NWCTRL_TXEN_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable receiver if not already enabled */
|
||||
if ((InstancePtr->Options & XEMACPS_RECEIVER_ENABLE_OPTION) != 0x00000000U) {
|
||||
Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
if ((!(Reg & XEMACPS_NWCTRL_RXEN_MASK))==TRUE) {
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET,
|
||||
Reg | (u32)XEMACPS_NWCTRL_RXEN_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable TX and RX interrupts */
|
||||
XEmacPs_IntEnable(InstancePtr, (XEMACPS_IXR_TX_ERR_MASK |
|
||||
XEMACPS_IXR_RX_ERR_MASK | (u32)XEMACPS_IXR_FRAMERX_MASK |
|
||||
(u32)XEMACPS_IXR_TXCOMPL_MASK));
|
||||
|
||||
/* Enable TX Q1 Interrupts */
|
||||
if (InstancePtr->Version > 2)
|
||||
XEmacPs_IntQ1Enable(InstancePtr, XEMACPS_INTQ1_IXR_ALL_MASK);
|
||||
|
||||
/* Mark as started */
|
||||
InstancePtr->IsStarted = XIL_COMPONENT_IS_STARTED;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Gracefully stop the Ethernet MAC as follows:
|
||||
* - Disable all interrupts from this device
|
||||
* - Stop DMA channels
|
||||
* - Disable the tansmitter and receiver
|
||||
*
|
||||
* Device options currently in effect are not changed.
|
||||
*
|
||||
* This function will disable all interrupts. Default interrupts settings that
|
||||
* had been enabled will be restored when XEmacPs_Start() is called.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
*
|
||||
* @note
|
||||
* This function makes use of internal resources that are shared between the
|
||||
* Start, Stop, SetOptions, and ClearOptions functions. So if one task might be
|
||||
* setting device options while another is trying to start the device, the user
|
||||
* is required to provide protection of this shared data (typically using a
|
||||
* semaphore).
|
||||
*
|
||||
* Stopping the DMA channels causes this function to block until the DMA
|
||||
* operation is complete.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XEmacPs_Stop(XEmacPs *InstancePtr)
|
||||
{
|
||||
u32 Reg;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
|
||||
|
||||
/* Disable all interrupts */
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
|
||||
XEMACPS_IXR_ALL_MASK);
|
||||
|
||||
/* Disable the receiver & transmitter */
|
||||
Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
Reg &= (u32)(~XEMACPS_NWCTRL_RXEN_MASK);
|
||||
Reg &= (u32)(~XEMACPS_NWCTRL_TXEN_MASK);
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, Reg);
|
||||
|
||||
/* Mark as stopped */
|
||||
InstancePtr->IsStarted = 0U;
|
||||
#if defined (XCLOCKING)
|
||||
Xil_ClockDisable(InstancePtr->Config.RefClk);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Perform a graceful reset of the Ethernet MAC. Resets the DMA channels, the
|
||||
* transmitter, and the receiver.
|
||||
*
|
||||
* Steps to reset
|
||||
* - Stops transmit and receive channels
|
||||
* - Stops DMA
|
||||
* - Configure transmit and receive buffer size to default
|
||||
* - Clear transmit and receive status register and counters
|
||||
* - Clear all interrupt sources
|
||||
* - Clear phy (if there is any previously detected) address
|
||||
* - Clear MAC addresses (1-4) as well as Type IDs and hash value
|
||||
*
|
||||
* All options are placed in their default state. Any frames in the
|
||||
* descriptor lists will remain in the lists. The side effect of doing
|
||||
* this is that after a reset and following a restart of the device, frames
|
||||
* were in the list before the reset may be transmitted or received.
|
||||
*
|
||||
* The upper layer software is responsible for re-configuring (if necessary)
|
||||
* and restarting the MAC after the reset. Note also that driver statistics
|
||||
* are not cleared on reset. It is up to the upper layer software to clear the
|
||||
* statistics if needed.
|
||||
*
|
||||
* When a reset is required, the driver notifies the upper layer software of
|
||||
* this need through the ErrorHandler callback and specific status codes.
|
||||
* The upper layer software is responsible for calling this Reset function
|
||||
* and then re-configuring the device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XEmacPs_Reset(XEmacPs *InstancePtr)
|
||||
{
|
||||
u32 Reg;
|
||||
u8 i;
|
||||
s8 EmacPs_zero_MAC[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
|
||||
|
||||
/* Stop the device and reset hardware */
|
||||
XEmacPs_Stop(InstancePtr);
|
||||
InstancePtr->Options = XEMACPS_DEFAULT_OPTIONS;
|
||||
|
||||
InstancePtr->Version = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, 0xFC);
|
||||
|
||||
InstancePtr->Version = (InstancePtr->Version >> 16) & 0xFFF;
|
||||
|
||||
InstancePtr->MaxMtuSize = XEMACPS_MTU;
|
||||
InstancePtr->MaxFrameSize = XEMACPS_MTU + XEMACPS_HDR_SIZE +
|
||||
XEMACPS_TRL_SIZE;
|
||||
InstancePtr->MaxVlanFrameSize = InstancePtr->MaxFrameSize +
|
||||
XEMACPS_HDR_VLAN_SIZE;
|
||||
InstancePtr->RxBufMask = XEMACPS_RXBUF_LEN_MASK;
|
||||
|
||||
/* Setup hardware with default values */
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET,
|
||||
(XEMACPS_NWCTRL_STATCLR_MASK |
|
||||
XEMACPS_NWCTRL_MDEN_MASK) &
|
||||
(u32)(~XEMACPS_NWCTRL_LOOPEN_MASK));
|
||||
|
||||
Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_NWCFG_OFFSET);
|
||||
Reg &= XEMACPS_NWCFG_MDCCLKDIV_MASK;
|
||||
|
||||
Reg = Reg | (u32)XEMACPS_NWCFG_100_MASK |
|
||||
(u32)XEMACPS_NWCFG_FDEN_MASK |
|
||||
(u32)XEMACPS_NWCFG_UCASTHASHEN_MASK;
|
||||
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_NWCFG_OFFSET, Reg);
|
||||
if (InstancePtr->Version > 2) {
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_NWCFG_OFFSET,
|
||||
(XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, XEMACPS_NWCFG_OFFSET) |
|
||||
XEMACPS_NWCFG_DWIDTH_64_MASK));
|
||||
}
|
||||
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_DMACR_OFFSET,
|
||||
(((((u32)XEMACPS_RX_BUF_SIZE / (u32)XEMACPS_RX_BUF_UNIT) +
|
||||
(((((u32)XEMACPS_RX_BUF_SIZE %
|
||||
(u32)XEMACPS_RX_BUF_UNIT))!=(u32)0) ? 1U : 0U)) <<
|
||||
(u32)(XEMACPS_DMACR_RXBUF_SHIFT)) &
|
||||
(u32)(XEMACPS_DMACR_RXBUF_MASK)) |
|
||||
(u32)XEMACPS_DMACR_RXSIZE_MASK |
|
||||
(u32)XEMACPS_DMACR_TXSIZE_MASK);
|
||||
|
||||
|
||||
if (InstancePtr->Version > 2) {
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_DMACR_OFFSET,
|
||||
(XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, XEMACPS_DMACR_OFFSET) |
|
||||
#if defined(__aarch64__) || defined(__arch64__)
|
||||
(u32)XEMACPS_DMACR_ADDR_WIDTH_64 |
|
||||
#endif
|
||||
(u32)XEMACPS_DMACR_INCR16_AHB_BURST));
|
||||
}
|
||||
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_TXSR_OFFSET, XEMACPS_SR_ALL_MASK);
|
||||
|
||||
XEmacPs_SetQueuePtr(InstancePtr, 0, 0x00U, (u16)XEMACPS_SEND);
|
||||
if (InstancePtr->Version > 2)
|
||||
XEmacPs_SetQueuePtr(InstancePtr, 0, 0x01U, (u16)XEMACPS_SEND);
|
||||
XEmacPs_SetQueuePtr(InstancePtr, 0, 0x00U, (u16)XEMACPS_RECV);
|
||||
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_RXSR_OFFSET, XEMACPS_SR_ALL_MASK);
|
||||
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
|
||||
XEMACPS_IXR_ALL_MASK);
|
||||
|
||||
Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_ISR_OFFSET);
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
|
||||
Reg);
|
||||
|
||||
XEmacPs_ClearHash(InstancePtr);
|
||||
|
||||
for (i = 1U; i < 5U; i++) {
|
||||
(void)XEmacPs_SetMacAddress(InstancePtr, EmacPs_zero_MAC, i);
|
||||
(void)XEmacPs_SetTypeIdCheck(InstancePtr, 0x00000000U, i);
|
||||
}
|
||||
|
||||
/* clear all counters */
|
||||
for (i = 0U; i < (u8)((XEMACPS_LAST_OFFSET - XEMACPS_OCTTXL_OFFSET) / 4U);
|
||||
i++) {
|
||||
(void)XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_OCTTXL_OFFSET + (u32)(((u32)i) * ((u32)4)));
|
||||
}
|
||||
|
||||
/* Disable the receiver */
|
||||
Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
Reg &= (u32)(~XEMACPS_NWCTRL_RXEN_MASK);
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, Reg);
|
||||
|
||||
/* Sync default options with hardware but leave receiver and
|
||||
* transmitter disabled. They get enabled with XEmacPs_Start() if
|
||||
* XEMACPS_TRANSMITTER_ENABLE_OPTION and
|
||||
* XEMACPS_RECEIVER_ENABLE_OPTION are set.
|
||||
*/
|
||||
(void)XEmacPs_SetOptions(InstancePtr, InstancePtr->Options &
|
||||
~((u32)XEMACPS_TRANSMITTER_ENABLE_OPTION |
|
||||
(u32)XEMACPS_RECEIVER_ENABLE_OPTION));
|
||||
|
||||
(void)XEmacPs_ClearOptions(InstancePtr, ~InstancePtr->Options);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* This is a stub for the asynchronous callbacks. The stub is here in case the
|
||||
* upper layer forgot to set the handler(s). On initialization, all handlers are
|
||||
* set to this callback. It is considered an error for this handler to be
|
||||
* invoked.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XEmacPs_StubHandler(void)
|
||||
{
|
||||
Xil_AssertVoidAlways();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function sets the start address of the transmit/receive buffer queue.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param QPtr is the address of the Queue to be written
|
||||
* @param QueueNum is the Buffer Queue Index
|
||||
* @param Direction indicates Transmit/Receive
|
||||
*
|
||||
* @note
|
||||
* The buffer queue addresses has to be set before starting the transfer, so
|
||||
* this function has to be called in prior to XEmacPs_Start()
|
||||
*
|
||||
******************************************************************************/
|
||||
void XEmacPs_SetQueuePtr(XEmacPs *InstancePtr, UINTPTR QPtr, u8 QueueNum,
|
||||
u16 Direction)
|
||||
{
|
||||
/* Assert bad arguments and conditions */
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
|
||||
|
||||
/* If already started, then there is nothing to do */
|
||||
if (InstancePtr->IsStarted == (u32)XIL_COMPONENT_IS_STARTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (QueueNum == 0x00U) {
|
||||
if (Direction == XEMACPS_SEND) {
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_TXQBASE_OFFSET,
|
||||
(QPtr & ULONG64_LO_MASK));
|
||||
} else {
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_RXQBASE_OFFSET,
|
||||
(QPtr & ULONG64_LO_MASK));
|
||||
}
|
||||
}
|
||||
else {
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_TXQ1BASE_OFFSET,
|
||||
(QPtr & ULONG64_LO_MASK));
|
||||
}
|
||||
#ifdef __aarch64__
|
||||
if (Direction == XEMACPS_SEND) {
|
||||
/* Set the MSB of TX Queue start address */
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_MSBBUF_TXQBASE_OFFSET,
|
||||
(u32)((QPtr & ULONG64_HI_MASK) >> 32U));
|
||||
} else {
|
||||
/* Set the MSB of RX Queue start address */
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_MSBBUF_RXQBASE_OFFSET,
|
||||
(u32)((QPtr & ULONG64_HI_MASK) >> 32U));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/** @} */
|
|
@ -0,0 +1,836 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2010 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xemacps.h
|
||||
* @addtogroup emacps_v3_11
|
||||
* @{
|
||||
* @details
|
||||
*
|
||||
* The Xilinx Embedded Processor Block Ethernet driver.
|
||||
*
|
||||
* For a full description of XEMACPS features, please see the hardware spec.
|
||||
* This driver supports the following features:
|
||||
* - Memory mapped access to host interface registers
|
||||
* - Statistics counter registers for RMON/MIB
|
||||
* - API for interrupt driven frame transfers for hardware configured DMA
|
||||
* - Virtual memory support
|
||||
* - Unicast, broadcast, and multicast receive address filtering
|
||||
* - Full and half duplex operation
|
||||
* - Automatic PAD & FCS insertion and stripping
|
||||
* - Flow control
|
||||
* - Support up to four 48bit addresses
|
||||
* - Address checking for four specific 48bit addresses
|
||||
* - VLAN frame support
|
||||
* - Pause frame support
|
||||
* - Large frame support up to 1536 bytes
|
||||
* - Checksum offload
|
||||
*
|
||||
* <b>Driver Description</b>
|
||||
*
|
||||
* The device driver enables higher layer software (e.g., an application) to
|
||||
* communicate to the XEmacPs. The driver handles transmission and reception
|
||||
* of Ethernet frames, as well as configuration and control. No pre or post
|
||||
* processing of frame data is performed. The driver does not validate the
|
||||
* contents of an incoming frame in addition to what has already occurred in
|
||||
* hardware.
|
||||
* A single device driver can support multiple devices even when those devices
|
||||
* have significantly different configurations.
|
||||
*
|
||||
* <b>Initialization & Configuration</b>
|
||||
*
|
||||
* The XEmacPs_Config structure is used by the driver to configure itself.
|
||||
* This configuration structure is typically created by the tool-chain based
|
||||
* on hardware build properties.
|
||||
*
|
||||
* The driver instance can be initialized in
|
||||
*
|
||||
* - XEmacPs_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddress): Uses a
|
||||
* configuration structure provided by the caller. If running in a system
|
||||
* with address translation, the provided virtual memory base address
|
||||
* replaces the physical address present in the configuration structure.
|
||||
*
|
||||
* The device supports DMA only as current development plan. No FIFO mode is
|
||||
* supported. The driver expects to start the DMA channels and expects that
|
||||
* the user has set up the buffer descriptor lists.
|
||||
*
|
||||
* <b>Interrupts and Asynchronous Callbacks</b>
|
||||
*
|
||||
* The driver has no dependencies on the interrupt controller. When an
|
||||
* interrupt occurs, the handler will perform a small amount of
|
||||
* housekeeping work, determine the source of the interrupt, and call the
|
||||
* appropriate callback function. All callbacks are registered by the user
|
||||
* level application.
|
||||
*
|
||||
* <b>Virtual Memory</b>
|
||||
*
|
||||
* All virtual to physical memory mappings must occur prior to accessing the
|
||||
* driver API.
|
||||
*
|
||||
* For DMA transactions, user buffers supplied to the driver must be in terms
|
||||
* of their physical address.
|
||||
*
|
||||
* <b>DMA</b>
|
||||
*
|
||||
* The DMA engine uses buffer descriptors (BDs) to describe Ethernet frames.
|
||||
* These BDs are typically chained together into a list the hardware follows
|
||||
* when transferring data in and out of the packet buffers. Each BD describes
|
||||
* a memory region containing either a full or partial Ethernet packet.
|
||||
*
|
||||
* Interrupt coalescing is not supported from this built-in DMA engine.
|
||||
*
|
||||
* This API requires the user to understand how the DMA operates. The
|
||||
* following paragraphs provide some explanation, but the user is encouraged
|
||||
* to read documentation in xemacps_bdring.h as well as study example code
|
||||
* that accompanies this driver.
|
||||
*
|
||||
* The API is designed to get BDs to and from the DMA engine in the most
|
||||
* efficient means possible. The first step is to establish a memory region
|
||||
* to contain all BDs for a specific channel. This is done with
|
||||
* XEmacPs_BdRingCreate(). This function sets up a BD ring that hardware will
|
||||
* follow as BDs are processed. The ring will consist of a user defined number
|
||||
* of BDs which will all be partially initialized. For example on the transmit
|
||||
* channel, the driver will initialize all BDs' so that they are configured
|
||||
* for transmit. The more fields that can be permanently setup at
|
||||
* initialization, then the fewer accesses will be needed to each BD while
|
||||
* the DMA engine is in operation resulting in better throughput and CPU
|
||||
* utilization. The best case initialization would require the user to set
|
||||
* only a frame buffer address and length prior to submitting the BD to the
|
||||
* engine.
|
||||
*
|
||||
* BDs move through the engine with the help of functions
|
||||
* XEmacPs_BdRingAlloc(), XEmacPs_BdRingToHw(), XEmacPs_BdRingFromHw(),
|
||||
* and XEmacPs_BdRingFree().
|
||||
* All these functions handle BDs that are in place. That is, there are no
|
||||
* copies of BDs kept anywhere and any BD the user interacts with is an actual
|
||||
* BD from the same ring hardware accesses.
|
||||
*
|
||||
* BDs in the ring go through a series of states as follows:
|
||||
* 1. Idle. The driver controls BDs in this state.
|
||||
* 2. The user has data to transfer. XEmacPs_BdRingAlloc() is called to
|
||||
* reserve BD(s). Once allocated, the user may setup the BD(s) with
|
||||
* frame buffer address, length, and other attributes. The user controls
|
||||
* BDs in this state.
|
||||
* 3. The user submits BDs to the DMA engine with XEmacPs_BdRingToHw. BDs
|
||||
* in this state are either waiting to be processed by hardware, are in
|
||||
* process, or have been processed. The DMA engine controls BDs in this
|
||||
* state.
|
||||
* 4. Processed BDs are retrieved with XEmacEpv_BdRingFromHw() by the
|
||||
* user. Once retrieved, the user can examine each BD for the outcome of
|
||||
* the DMA transfer. The user controls BDs in this state. After examining
|
||||
* the BDs the user calls XEmacPs_BdRingFree() which places the BDs back
|
||||
* into state 1.
|
||||
*
|
||||
* Each of the four BD accessor functions operate on a set of BDs. A set is
|
||||
* defined as a segment of the BD ring consisting of one or more BDs. The user
|
||||
* views the set as a pointer to the first BD along with the number of BDs for
|
||||
* that set. The set can be navigated by using macros XEmacPs_BdNext(). The
|
||||
* user must exercise extreme caution when changing BDs in a set as there is
|
||||
* nothing to prevent doing a mBdNext past the end of the set and modifying a
|
||||
* BD out of bounds.
|
||||
*
|
||||
* XEmacPs_BdRingAlloc() + XEmacPs_BdRingToHw(), as well as
|
||||
* XEmacPs_BdRingFromHw() + XEmacPs_BdRingFree() are designed to be used in
|
||||
* tandem. The same BD set retrieved with BdRingAlloc should be the same one
|
||||
* provided to hardware with BdRingToHw. Same goes with BdRingFromHw and
|
||||
* BdRIngFree.
|
||||
*
|
||||
* <b>Alignment & Data Cache Restrictions</b>
|
||||
*
|
||||
* Due to the design of the hardware, all RX buffers, BDs need to be 4-byte
|
||||
* aligned. Please reference xemacps_bd.h for cache related macros.
|
||||
*
|
||||
* DMA Tx:
|
||||
*
|
||||
* - If frame buffers exist in cached memory, then they must be flushed
|
||||
* prior to committing them to hardware.
|
||||
*
|
||||
* DMA Rx:
|
||||
*
|
||||
* - If frame buffers exist in cached memory, then the cache must be
|
||||
* invalidated for the memory region containing the frame prior to data
|
||||
* access
|
||||
*
|
||||
* Both cache invalidate/flush are taken care of in driver code.
|
||||
*
|
||||
* <b>Buffer Copying</b>
|
||||
*
|
||||
* The driver is designed for a zero-copy buffer scheme. That is, the driver
|
||||
* will not copy buffers. This avoids potential throughput bottlenecks within
|
||||
* the driver. If byte copying is required, then the transfer will take longer
|
||||
* to complete.
|
||||
*
|
||||
* <b>Checksum Offloading</b>
|
||||
*
|
||||
* The Embedded Processor Block Ethernet can be configured to perform IP, TCP
|
||||
* and UDP checksum offloading in both receive and transmit directions.
|
||||
*
|
||||
* IP packets contain a 16-bit checksum field, which is the 16-bit 1s
|
||||
* complement of the 1s complement sum of all 16-bit words in the header.
|
||||
* TCP and UDP packets contain a 16-bit checksum field, which is the 16-bit
|
||||
* 1s complement of the 1s complement sum of all 16-bit words in the header,
|
||||
* the data and a conceptual pseudo header.
|
||||
*
|
||||
* To calculate these checksums in software requires each byte of the packet
|
||||
* to be read. For TCP and UDP this can use a large amount of processing power.
|
||||
* Offloading the checksum calculation to hardware can result in significant
|
||||
* performance improvements.
|
||||
*
|
||||
* The transmit checksum offload is only available to use DMA in packet buffer
|
||||
* mode. This is because the complete frame to be transmitted must be read
|
||||
* into the packet buffer memory before the checksum can be calculated and
|
||||
* written to the header at the beginning of the frame.
|
||||
*
|
||||
* For IP, TCP or UDP receive checksum offload to be useful, the operating
|
||||
* system containing the protocol stack must be aware that this offload is
|
||||
* available so that it can make use of the fact that the hardware has verified
|
||||
* the checksum.
|
||||
*
|
||||
* When receive checksum offloading is enabled in the hardware, the IP header
|
||||
* checksum is checked, where the packet meets the following criteria:
|
||||
*
|
||||
* 1. If present, the VLAN header must be four octets long and the CFI bit
|
||||
* must not be set.
|
||||
* 2. Encapsulation must be RFC 894 Ethernet Type Encoding or RFC 1042 SNAP
|
||||
* encoding.
|
||||
* 3. IP v4 packet.
|
||||
* 4. IP header is of a valid length.
|
||||
* 5. Good IP header checksum.
|
||||
* 6. No IP fragmentation.
|
||||
* 7. TCP or UDP packet.
|
||||
*
|
||||
* When an IP, TCP or UDP frame is received, the receive buffer descriptor
|
||||
* gives an indication if the hardware was able to verify the checksums.
|
||||
* There is also an indication if the frame had SNAP encapsulation. These
|
||||
* indication bits will replace the type ID match indication bits when the
|
||||
* receive checksum offload is enabled.
|
||||
*
|
||||
* If any of the checksums are verified incorrect by the hardware, the packet
|
||||
* is discarded and the appropriate statistics counter incremented.
|
||||
*
|
||||
* <b>PHY Interfaces</b>
|
||||
*
|
||||
* RGMII 1.3 is the only interface supported.
|
||||
*
|
||||
* <b>Asserts</b>
|
||||
*
|
||||
* Asserts are used within all Xilinx drivers to enforce constraints on
|
||||
* parameters. Asserts can be turned off on a system-wide basis by defining,
|
||||
* at compile time, the NDEBUG identifier. By default, asserts are turned on
|
||||
* and it is recommended that users leave asserts on during development. For
|
||||
* deployment use -DNDEBUG compiler switch to remove assert code.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Xilinx drivers are typically composed of two parts, one is the driver
|
||||
* and the other is the adapter. The driver is independent of OS and processor
|
||||
* and is intended to be highly portable. The adapter is OS-specific and
|
||||
* facilitates communication between the driver and an OS.
|
||||
* This driver is intended to be RTOS and processor independent. Any needs for
|
||||
* dynamic memory management, threads or thread mutual exclusion, or cache
|
||||
* control must be satisfied bythe layer above this driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.00a wsy 01/10/10 First release
|
||||
* 1.00a asa 11/21/11 The function XEmacPs_BdRingFromHwTx in file
|
||||
* xemacps_bdring.c is modified. Earlier it was checking for
|
||||
* "BdLimit"(passed argument) number of BDs for finding out
|
||||
* which BDs are successfully processed. Now one more check
|
||||
* is added. It looks for BDs till the current BD pointer
|
||||
* reaches HwTail. By doing this processing time is saved.
|
||||
* 1.00a asa 01/24/12 The function XEmacPs_BdRingFromHwTx in file
|
||||
* xemacps_bdring.c is modified. Now start of packet is
|
||||
* searched for returning the number of BDs processed.
|
||||
* 1.02a asa 11/05/12 Added a new API for deleting an entry from the HASH
|
||||
* registers. Added a new API to set the bust length.
|
||||
* Added some new hash-defines.
|
||||
* 1.03a asa 01/23/12 Fix for CR #692702 which updates error handling for
|
||||
* Rx errors. Under heavy Rx traffic, there will be a large
|
||||
* number of errors related to receive buffer not available.
|
||||
* Because of a HW bug (SI #692601), under such heavy errors,
|
||||
* the Rx data path can become unresponsive. To reduce the
|
||||
* probabilities for hitting this HW bug, the SW writes to
|
||||
* bit 18 to flush a packet from Rx DPRAM immediately. The
|
||||
* changes for it are done in the function
|
||||
* XEmacPs_IntrHandler.
|
||||
* 1.05a asa 09/23/13 Cache operations on BDs are not required and hence
|
||||
* removed. It is expected that all BDs are allocated in
|
||||
* from uncached area.
|
||||
* 1.06a asa 11/02/13 Changed the value for XEMACPS_RXBUF_LEN_MASK from 0x3fff
|
||||
* to 0x1fff. This fixes the CR#744902.
|
||||
* Made changes in example file xemacps_example.h to fix compilation
|
||||
* issues with iarcc compiler.
|
||||
* 2.0 adk 10/12/13 Updated as per the New Tcl API's
|
||||
* 2.1 adk 11/08/14 Fixed the CR#811288. Changes are made in the driver tcl file.
|
||||
* 2.1 bss 09/08/14 Modified driver tcl to fix CR#820349 to export phy
|
||||
* address in xparameters.h when GMII to RGMII converter
|
||||
* is present in hw.
|
||||
* 2.1 srt 07/15/14 Add support for Zynq Ultrascale Mp GEM specification and 64-bit
|
||||
* changes.
|
||||
* 2.2 adk 29/10/14 Fixed CR#827686 when PCS/PMA core is configured with
|
||||
* 1000BASE-X mode export proper values to the xparameters.h
|
||||
* file. Changes are made in the driver tcl file.
|
||||
* 3.0 adk 08/1/15 Don't include gem in peripheral test when gem is
|
||||
* configured with PCS/PMA Core. Changes are made in the
|
||||
* test app tcl(CR:827686).
|
||||
* 3.0 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
* 3.0 hk 03/18/15 Added support for jumbo frames. Increase AHB burst.
|
||||
* Disable extended mode. Perform all 64 bit changes under
|
||||
* check for arch64.
|
||||
* Remove "used bit set" from TX error interrupt masks.
|
||||
* 3.1 hk 07/27/15 Do not call error handler with '0' error code when
|
||||
* there is no error. CR# 869403
|
||||
* 08/10/15 Update upper 32 bit tx and rx queue ptr registers.
|
||||
* 3.2 hk 02/22/16 Added SGMII support for Zynq Ultrascale+ MPSoC.
|
||||
* 3.4 ms 01/23/17 Modified xil_printf statement in main function for all
|
||||
* examples to ensure that "Successfully ran" and "Failed"
|
||||
* strings are available in all examples. This is a fix
|
||||
* for CR-965028.
|
||||
* ms 03/17/17 Modified text file in examples folder for doxygen
|
||||
* generation.
|
||||
* ms 04/05/17 Added tabspace for return statements in functions of
|
||||
* xemacps_ieee1588_example.c for proper documentation
|
||||
* while generating doxygen.
|
||||
* 3.5 hk 08/14/17 Update cache coherency information of the interface in
|
||||
* its config structure.
|
||||
* 3.6 rb 09/08/17 HwCnt variable (in XEmacPs_BdRing structure) is
|
||||
* changed to volatile.
|
||||
* Add API XEmacPs_BdRingPtrReset() to reset pointers
|
||||
* 3.8 hk 07/19/18 Fixed CPP, GCC and doxygen warnings - CR-1006327
|
||||
* hk 09/17/18 Fix PTP interrupt masks and cleanup comments.
|
||||
* 3.9 hk 01/23/19 Add RX watermark support
|
||||
* 3.11 sd 02/14/20 Add clock support
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef XEMACPS_H /* prevent circular inclusions */
|
||||
#define XEMACPS_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files ********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xstatus.h"
|
||||
#include "xemacps_hw.h"
|
||||
#include "xemacps_bd.h"
|
||||
#include "xemacps_bdring.h"
|
||||
#if defined (XCLOCKING)
|
||||
#include "xil_clocking.h"
|
||||
#endif
|
||||
|
||||
/************************** Constant Definitions ****************************/
|
||||
|
||||
/*
|
||||
* Device information
|
||||
*/
|
||||
#define XEMACPS_DEVICE_NAME "xemacps"
|
||||
#define XEMACPS_DEVICE_DESC "Xilinx PS 10/100/1000 MAC"
|
||||
|
||||
|
||||
/** @name Configuration options
|
||||
*
|
||||
* Device configuration options. See the XEmacPs_SetOptions(),
|
||||
* XEmacPs_ClearOptions() and XEmacPs_GetOptions() for information on how to
|
||||
* use options.
|
||||
*
|
||||
* The default state of the options are noted and are what the device and
|
||||
* driver will be set to after calling XEmacPs_Reset() or
|
||||
* XEmacPs_Initialize().
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define XEMACPS_PROMISC_OPTION 0x00000001U
|
||||
/**< Accept all incoming packets.
|
||||
* This option defaults to disabled (cleared) */
|
||||
|
||||
#define XEMACPS_FRAME1536_OPTION 0x00000002U
|
||||
/**< Frame larger than 1516 support for Tx & Rx.
|
||||
* This option defaults to disabled (cleared) */
|
||||
|
||||
#define XEMACPS_VLAN_OPTION 0x00000004U
|
||||
/**< VLAN Rx & Tx frame support.
|
||||
* This option defaults to disabled (cleared) */
|
||||
|
||||
#define XEMACPS_FLOW_CONTROL_OPTION 0x00000010U
|
||||
/**< Enable recognition of flow control frames on Rx
|
||||
* This option defaults to enabled (set) */
|
||||
|
||||
#define XEMACPS_FCS_STRIP_OPTION 0x00000020U
|
||||
/**< Strip FCS and PAD from incoming frames. Note: PAD from VLAN frames is not
|
||||
* stripped.
|
||||
* This option defaults to enabled (set) */
|
||||
|
||||
#define XEMACPS_FCS_INSERT_OPTION 0x00000040U
|
||||
/**< Generate FCS field and add PAD automatically for outgoing frames.
|
||||
* This option defaults to disabled (cleared) */
|
||||
|
||||
#define XEMACPS_LENTYPE_ERR_OPTION 0x00000080U
|
||||
/**< Enable Length/Type error checking for incoming frames. When this option is
|
||||
* set, the MAC will filter frames that have a mismatched type/length field
|
||||
* and if XEMACPS_REPORT_RXERR_OPTION is set, the user is notified when these
|
||||
* types of frames are encountered. When this option is cleared, the MAC will
|
||||
* allow these types of frames to be received.
|
||||
*
|
||||
* This option defaults to disabled (cleared) */
|
||||
|
||||
#define XEMACPS_TRANSMITTER_ENABLE_OPTION 0x00000100U
|
||||
/**< Enable the transmitter.
|
||||
* This option defaults to enabled (set) */
|
||||
|
||||
#define XEMACPS_RECEIVER_ENABLE_OPTION 0x00000200U
|
||||
/**< Enable the receiver
|
||||
* This option defaults to enabled (set) */
|
||||
|
||||
#define XEMACPS_BROADCAST_OPTION 0x00000400U
|
||||
/**< Allow reception of the broadcast address
|
||||
* This option defaults to enabled (set) */
|
||||
|
||||
#define XEMACPS_MULTICAST_OPTION 0x00000800U
|
||||
/**< Allows reception of multicast addresses programmed into hash
|
||||
* This option defaults to disabled (clear) */
|
||||
|
||||
#define XEMACPS_RX_CHKSUM_ENABLE_OPTION 0x00001000U
|
||||
/**< Enable the RX checksum offload
|
||||
* This option defaults to enabled (set) */
|
||||
|
||||
#define XEMACPS_TX_CHKSUM_ENABLE_OPTION 0x00002000U
|
||||
/**< Enable the TX checksum offload
|
||||
* This option defaults to enabled (set) */
|
||||
|
||||
#define XEMACPS_JUMBO_ENABLE_OPTION 0x00004000U
|
||||
#define XEMACPS_SGMII_ENABLE_OPTION 0x00008000U
|
||||
|
||||
#define XEMACPS_DEFAULT_OPTIONS \
|
||||
((u32)XEMACPS_FLOW_CONTROL_OPTION | \
|
||||
(u32)XEMACPS_FCS_INSERT_OPTION | \
|
||||
(u32)XEMACPS_FCS_STRIP_OPTION | \
|
||||
(u32)XEMACPS_BROADCAST_OPTION | \
|
||||
(u32)XEMACPS_LENTYPE_ERR_OPTION | \
|
||||
(u32)XEMACPS_TRANSMITTER_ENABLE_OPTION | \
|
||||
(u32)XEMACPS_RECEIVER_ENABLE_OPTION | \
|
||||
(u32)XEMACPS_RX_CHKSUM_ENABLE_OPTION | \
|
||||
(u32)XEMACPS_TX_CHKSUM_ENABLE_OPTION)
|
||||
|
||||
/**< Default options set when device is initialized or reset */
|
||||
/*@}*/
|
||||
|
||||
/** @name Callback identifiers
|
||||
*
|
||||
* These constants are used as parameters to XEmacPs_SetHandler()
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_HANDLER_DMASEND 1U
|
||||
#define XEMACPS_HANDLER_DMARECV 2U
|
||||
#define XEMACPS_HANDLER_ERROR 3U
|
||||
/*@}*/
|
||||
|
||||
/* Constants to determine the configuration of the hardware device. They are
|
||||
* used to allow the driver to verify it can operate with the hardware.
|
||||
*/
|
||||
#define XEMACPS_MDIO_DIV_DFT MDC_DIV_32 /**< Default MDIO clock divisor */
|
||||
|
||||
/* The next few constants help upper layers determine the size of memory
|
||||
* pools used for Ethernet buffers and descriptor lists.
|
||||
*/
|
||||
#define XEMACPS_MAC_ADDR_SIZE 6U /* size of Ethernet header */
|
||||
|
||||
#define XEMACPS_MTU 1500U /* max MTU size of Ethernet frame */
|
||||
#define XEMACPS_MTU_JUMBO 10240U /* max MTU size of jumbo frame */
|
||||
#define XEMACPS_HDR_SIZE 14U /* size of Ethernet header */
|
||||
#define XEMACPS_HDR_VLAN_SIZE 18U /* size of Ethernet header with VLAN */
|
||||
#define XEMACPS_TRL_SIZE 4U /* size of Ethernet trailer (FCS) */
|
||||
#define XEMACPS_MAX_FRAME_SIZE (XEMACPS_MTU + XEMACPS_HDR_SIZE + \
|
||||
XEMACPS_TRL_SIZE)
|
||||
#define XEMACPS_MAX_VLAN_FRAME_SIZE (XEMACPS_MTU + XEMACPS_HDR_SIZE + \
|
||||
XEMACPS_HDR_VLAN_SIZE + XEMACPS_TRL_SIZE)
|
||||
#define XEMACPS_MAX_VLAN_FRAME_SIZE_JUMBO (XEMACPS_MTU_JUMBO + XEMACPS_HDR_SIZE + \
|
||||
XEMACPS_HDR_VLAN_SIZE + XEMACPS_TRL_SIZE)
|
||||
|
||||
/* DMACR Bust length hash defines */
|
||||
|
||||
#define XEMACPS_SINGLE_BURST 0x00000001
|
||||
#define XEMACPS_4BYTE_BURST 0x00000004
|
||||
#define XEMACPS_8BYTE_BURST 0x00000008
|
||||
#define XEMACPS_16BYTE_BURST 0x00000010
|
||||
|
||||
|
||||
/**************************** Type Definitions ******************************/
|
||||
/** @name Typedefs for callback functions
|
||||
*
|
||||
* These callbacks are invoked in interrupt context.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* Callback invoked when frame(s) have been sent or received in interrupt
|
||||
* driven DMA mode. To set the send callback, invoke XEmacPs_SetHandler().
|
||||
*
|
||||
* @param CallBackRef is user data assigned when the callback was set.
|
||||
*
|
||||
* @note
|
||||
* See xemacps_hw.h for bitmasks definitions and the device hardware spec for
|
||||
* further information on their meaning.
|
||||
*
|
||||
*/
|
||||
typedef void (*XEmacPs_Handler) (void *CallBackRef);
|
||||
|
||||
/**
|
||||
* Callback when an asynchronous error occurs. To set this callback, invoke
|
||||
* XEmacPs_SetHandler() with XEMACPS_HANDLER_ERROR in the HandlerType
|
||||
* parameter.
|
||||
*
|
||||
* @param CallBackRef is user data assigned when the callback was set.
|
||||
* @param Direction defines either receive or transmit error(s) has occurred.
|
||||
* @param ErrorWord definition varies with Direction
|
||||
*
|
||||
*/
|
||||
typedef void (*XEmacPs_ErrHandler) (void *CallBackRef, u8 Direction,
|
||||
u32 ErrorWord);
|
||||
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* This typedef contains configuration information for a device.
|
||||
*/
|
||||
typedef struct {
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
UINTPTR BaseAddress;/**< Physical base address of IPIF registers */
|
||||
u8 IsCacheCoherent; /**< Applicable only to A53 in EL1 mode;
|
||||
* describes whether Cache Coherent or not */
|
||||
#if defined (XCLOCKING)
|
||||
u32 RefClk; /**< Input clock */
|
||||
#endif
|
||||
} XEmacPs_Config;
|
||||
|
||||
|
||||
/**
|
||||
* The XEmacPs driver instance data. The user is required to allocate a
|
||||
* structure of this type for every XEmacPs device in the system. A pointer
|
||||
* to a structure of this type is then passed to the driver API functions.
|
||||
*/
|
||||
typedef struct XEmacPs_Instance {
|
||||
XEmacPs_Config Config; /* Hardware configuration */
|
||||
u32 IsStarted; /* Device is currently started */
|
||||
u32 IsReady; /* Device is initialized and ready */
|
||||
u32 Options; /* Current options word */
|
||||
|
||||
XEmacPs_BdRing TxBdRing; /* Transmit BD ring */
|
||||
XEmacPs_BdRing RxBdRing; /* Receive BD ring */
|
||||
|
||||
XEmacPs_Handler SendHandler;
|
||||
XEmacPs_Handler RecvHandler;
|
||||
void *SendRef;
|
||||
void *RecvRef;
|
||||
|
||||
XEmacPs_ErrHandler ErrorHandler;
|
||||
void *ErrorRef;
|
||||
u32 Version;
|
||||
u32 RxBufMask;
|
||||
u32 MaxMtuSize;
|
||||
u32 MaxFrameSize;
|
||||
u32 MaxVlanFrameSize;
|
||||
|
||||
} XEmacPs;
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions ********************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Retrieve the Tx ring object. This object can be used in the various Ring
|
||||
* API functions.
|
||||
*
|
||||
* @param InstancePtr is the DMA channel to operate on.
|
||||
*
|
||||
* @return TxBdRing attribute
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* XEmacPs_BdRing XEmacPs_GetTxRing(XEmacPs *InstancePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_GetTxRing(InstancePtr) ((InstancePtr)->TxBdRing)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Retrieve the Rx ring object. This object can be used in the various Ring
|
||||
* API functions.
|
||||
*
|
||||
* @param InstancePtr is the DMA channel to operate on.
|
||||
*
|
||||
* @return RxBdRing attribute
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* XEmacPs_BdRing XEmacPs_GetRxRing(XEmacPs *InstancePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_GetRxRing(InstancePtr) ((InstancePtr)->RxBdRing)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Enable interrupts specified in <i>Mask</i>. The corresponding interrupt for
|
||||
* each bit set to 1 in <i>Mask</i>, will be enabled.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param Mask contains a bit mask of interrupts to enable. The mask can
|
||||
* be formed using a set of bitwise or'd values.
|
||||
*
|
||||
* @note
|
||||
* The state of the transmitter and receiver are not modified by this function.
|
||||
* C-style signature
|
||||
* void XEmacPs_IntEnable(XEmacPs *InstancePtr, u32 Mask)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_IntEnable(InstancePtr, Mask) \
|
||||
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_IER_OFFSET, \
|
||||
((Mask) & XEMACPS_IXR_ALL_MASK));
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Disable interrupts specified in <i>Mask</i>. The corresponding interrupt for
|
||||
* each bit set to 1 in <i>Mask</i>, will be enabled.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param Mask contains a bit mask of interrupts to disable. The mask can
|
||||
* be formed using a set of bitwise or'd values.
|
||||
*
|
||||
* @note
|
||||
* The state of the transmitter and receiver are not modified by this function.
|
||||
* C-style signature
|
||||
* void XEmacPs_IntDisable(XEmacPs *InstancePtr, u32 Mask)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_IntDisable(InstancePtr, Mask) \
|
||||
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_IDR_OFFSET, \
|
||||
((Mask) & XEMACPS_IXR_ALL_MASK));
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Enable interrupts specified in <i>Mask</i>. The corresponding interrupt for
|
||||
* each bit set to 1 in <i>Mask</i>, will be enabled.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param Mask contains a bit mask of interrupts to enable. The mask can
|
||||
* be formed using a set of bitwise or'd values.
|
||||
*
|
||||
* @note
|
||||
* The state of the transmitter and receiver are not modified by this function.
|
||||
* C-style signature
|
||||
* void XEmacPs_IntQ1Enable(XEmacPs *InstancePtr, u32 Mask)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_IntQ1Enable(InstancePtr, Mask) \
|
||||
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_INTQ1_IER_OFFSET, \
|
||||
((Mask) & XEMACPS_INTQ1_IXR_ALL_MASK));
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Disable interrupts specified in <i>Mask</i>. The corresponding interrupt for
|
||||
* each bit set to 1 in <i>Mask</i>, will be enabled.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param Mask contains a bit mask of interrupts to disable. The mask can
|
||||
* be formed using a set of bitwise or'd values.
|
||||
*
|
||||
* @note
|
||||
* The state of the transmitter and receiver are not modified by this function.
|
||||
* C-style signature
|
||||
* void XEmacPs_IntDisable(XEmacPs *InstancePtr, u32 Mask)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_IntQ1Disable(InstancePtr, Mask) \
|
||||
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_INTQ1_IDR_OFFSET, \
|
||||
((Mask) & XEMACPS_INTQ1_IXR_ALL_MASK));
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro triggers trasmit circuit to send data currently in TX buffer(s).
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: void XEmacPs_Transmit(XEmacPs *InstancePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_Transmit(InstancePtr) \
|
||||
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_NWCTRL_OFFSET, \
|
||||
(XEmacPs_ReadReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_NWCTRL_OFFSET) | XEMACPS_NWCTRL_STARTTX_MASK))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro determines if the device is configured with checksum offloading
|
||||
* on the receive channel
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Boolean TRUE if the device is configured with checksum offloading, or
|
||||
* FALSE otherwise.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: u32 XEmacPs_IsRxCsum(XEmacPs *InstancePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_IsRxCsum(InstancePtr) \
|
||||
((XEmacPs_ReadReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_NWCFG_OFFSET) & XEMACPS_NWCFG_RXCHKSUMEN_MASK) != 0U \
|
||||
? TRUE : FALSE)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro determines if the device is configured with checksum offloading
|
||||
* on the transmit channel
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* Boolean TRUE if the device is configured with checksum offloading, or
|
||||
* FALSE otherwise.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: u32 XEmacPs_IsTxCsum(XEmacPs *InstancePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_IsTxCsum(InstancePtr) \
|
||||
((XEmacPs_ReadReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_DMACR_OFFSET) & XEMACPS_DMACR_TCPCKSUM_MASK) != 0U \
|
||||
? TRUE : FALSE)
|
||||
|
||||
/************************** Function Prototypes *****************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro sets RX watermark register.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
|
||||
* @param High is the non-zero RX high watermark value. When SRAM fill level
|
||||
* is above this, a pause frame will be sent.
|
||||
* @param Low is the non-zero RX low watermark value. When SRAM fill level
|
||||
* is below this, a zero length pause frame will be sent IF the last
|
||||
* pause frame sent was non-zero.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: void XEmacPs_SetRXWatermark(XEmacPs *InstancePtr, u16 High,
|
||||
* u16 Low)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_SetRXWatermark(InstancePtr, High, Low) \
|
||||
XEmacPs_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_RXWATERMARK_OFFSET, \
|
||||
(High & XEMACPS_RXWM_HIGH_MASK) | \
|
||||
((Low << XEMACPS_RXWM_LOW_SHFT_MSK) & XEMACPS_RXWM_LOW_MASK) |)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro gets RX watermark register.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
|
||||
*
|
||||
* @return RX watermark register value
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* Signature: void XEmacPs_GetRXWatermark(XEmacPs *InstancePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_GetRXWatermark(InstancePtr) \
|
||||
XEmacPs_ReadReg((InstancePtr)->Config.BaseAddress, \
|
||||
XEMACPS_RXWATERMARK_OFFSET)
|
||||
/*
|
||||
* Initialization functions in xemacps.c
|
||||
*/
|
||||
LONG XEmacPs_CfgInitialize(XEmacPs *InstancePtr, XEmacPs_Config *CfgPtr,
|
||||
UINTPTR EffectiveAddress);
|
||||
void XEmacPs_Start(XEmacPs *InstancePtr);
|
||||
void XEmacPs_Stop(XEmacPs *InstancePtr);
|
||||
void XEmacPs_Reset(XEmacPs *InstancePtr);
|
||||
void XEmacPs_SetQueuePtr(XEmacPs *InstancePtr, UINTPTR QPtr, u8 QueueNum,
|
||||
u16 Direction);
|
||||
|
||||
/*
|
||||
* Lookup configuration in xemacps_sinit.c
|
||||
*/
|
||||
XEmacPs_Config *XEmacPs_LookupConfig(u16 DeviceId);
|
||||
|
||||
/*
|
||||
* Interrupt-related functions in xemacps_intr.c
|
||||
* DMA only and FIFO is not supported. This DMA does not support coalescing.
|
||||
*/
|
||||
LONG XEmacPs_SetHandler(XEmacPs *InstancePtr, u32 HandlerType,
|
||||
void *FuncPointer, void *CallBackRef);
|
||||
void XEmacPs_IntrHandler(void *XEmacPsPtr);
|
||||
|
||||
/*
|
||||
* MAC configuration/control functions in XEmacPs_control.c
|
||||
*/
|
||||
LONG XEmacPs_SetOptions(XEmacPs *InstancePtr, u32 Options);
|
||||
LONG XEmacPs_ClearOptions(XEmacPs *InstancePtr, u32 Options);
|
||||
u32 XEmacPs_GetOptions(XEmacPs *InstancePtr);
|
||||
|
||||
LONG XEmacPs_SetMacAddress(XEmacPs *InstancePtr, void *AddressPtr, u8 Index);
|
||||
LONG XEmacPs_DeleteHash(XEmacPs *InstancePtr, void *AddressPtr);
|
||||
void XEmacPs_GetMacAddress(XEmacPs *InstancePtr, void *AddressPtr, u8 Index);
|
||||
|
||||
LONG XEmacPs_SetHash(XEmacPs *InstancePtr, void *AddressPtr);
|
||||
void XEmacPs_ClearHash(XEmacPs *InstancePtr);
|
||||
void XEmacPs_GetHash(XEmacPs *InstancePtr, void *AddressPtr);
|
||||
|
||||
void XEmacPs_SetMdioDivisor(XEmacPs *InstancePtr,
|
||||
XEmacPs_MdcDiv Divisor);
|
||||
void XEmacPs_SetOperatingSpeed(XEmacPs *InstancePtr, u16 Speed);
|
||||
u16 XEmacPs_GetOperatingSpeed(XEmacPs *InstancePtr);
|
||||
LONG XEmacPs_PhyRead(XEmacPs *InstancePtr, u32 PhyAddress,
|
||||
u32 RegisterNum, u16 *PhyDataPtr);
|
||||
LONG XEmacPs_PhyWrite(XEmacPs *InstancePtr, u32 PhyAddress,
|
||||
u32 RegisterNum, u16 PhyData);
|
||||
LONG XEmacPs_SetTypeIdCheck(XEmacPs *InstancePtr, u32 Id_Check, u8 Index);
|
||||
|
||||
LONG XEmacPs_SendPausePacket(XEmacPs *InstancePtr);
|
||||
void XEmacPs_DMABLengthUpdate(XEmacPs *InstancePtr, s32 BLength);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
|
@ -0,0 +1,762 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2010 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xemacps_bd.h
|
||||
* @addtogroup emacps_v3_11
|
||||
* @{
|
||||
*
|
||||
* This header provides operations to manage buffer descriptors in support
|
||||
* of scatter-gather DMA.
|
||||
*
|
||||
* The API exported by this header defines abstracted macros that allow the
|
||||
* user to read/write specific BD fields.
|
||||
*
|
||||
* <b>Buffer Descriptors</b>
|
||||
*
|
||||
* A buffer descriptor (BD) defines a DMA transaction. The macros defined by
|
||||
* this header file allow access to most fields within a BD to tailor a DMA
|
||||
* transaction according to user and hardware requirements. See the hardware
|
||||
* IP DMA spec for more information on BD fields and how they affect transfers.
|
||||
*
|
||||
* The XEmacPs_Bd structure defines a BD. The organization of this structure
|
||||
* is driven mainly by the hardware for use in scatter-gather DMA transfers.
|
||||
*
|
||||
* <b>Performance</b>
|
||||
*
|
||||
* Limiting I/O to BDs can improve overall performance of the DMA channel.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.00a wsy 01/10/10 First release
|
||||
* 2.1 srt 07/15/14 Add support for Zynq Ultrascale MP GEM specification
|
||||
* and 64-bit changes.
|
||||
* 3.0 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
* 3.0 hk 02/20/15 Added support for jumbo frames.
|
||||
* Disable extended mode. Perform all 64 bit changes under
|
||||
* check for arch64.
|
||||
* 3.2 hk 11/18/15 Change BD typedef and number of words.
|
||||
* 3.8 hk 08/18/18 Remove duplicate definition of XEmacPs_BdSetLength
|
||||
* 3.8 mus 11/05/18 Support 64 bit DMA addresses for Microblaze-X platform.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* ***************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XEMACPS_BD_H /* prevent circular inclusions */
|
||||
#define XEMACPS_BD_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include <string.h>
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
#ifdef __aarch64__
|
||||
/* Minimum BD alignment */
|
||||
#define XEMACPS_DMABD_MINIMUM_ALIGNMENT 64U
|
||||
#define XEMACPS_BD_NUM_WORDS 4U
|
||||
#else
|
||||
/* Minimum BD alignment */
|
||||
#define XEMACPS_DMABD_MINIMUM_ALIGNMENT 4U
|
||||
#define XEMACPS_BD_NUM_WORDS 2U
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The XEmacPs_Bd is the type for buffer descriptors (BDs).
|
||||
*/
|
||||
typedef u32 XEmacPs_Bd[XEMACPS_BD_NUM_WORDS];
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Zero out BD fields
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @return Nothing
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XEmacPs_BdClear(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdClear(BdPtr) \
|
||||
memset((BdPtr), 0, sizeof(XEmacPs_Bd))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the given Buffer Descriptor word.
|
||||
*
|
||||
* @param BaseAddress is the base address of the BD to read
|
||||
* @param Offset is the word offset to be read
|
||||
*
|
||||
* @return The 32-bit value of the field
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* u32 XEmacPs_BdRead(UINTPTR BaseAddress, UINTPTR Offset)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdRead(BaseAddress, Offset) \
|
||||
(*(u32 *)((UINTPTR)((void*)(BaseAddress)) + (u32)(Offset)))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Write the given Buffer Descriptor word.
|
||||
*
|
||||
* @param BaseAddress is the base address of the BD to write
|
||||
* @param Offset is the word offset to be written
|
||||
* @param Data is the 32-bit value to write to the field
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XEmacPs_BdWrite(UINTPTR BaseAddress, UINTPTR Offset, UINTPTR Data)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdWrite(BaseAddress, Offset, Data) \
|
||||
(*(u32 *)((UINTPTR)(void*)(BaseAddress) + (u32)(Offset)) = (u32)(Data))
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Set the BD's Address field (word 0).
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
* @param Addr is the value to write to BD's status field.
|
||||
*
|
||||
* @note :
|
||||
*
|
||||
* C-style signature:
|
||||
* void XEmacPs_BdSetAddressTx(XEmacPs_Bd* BdPtr, UINTPTR Addr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#if defined(__aarch64__) || defined(__arch64__)
|
||||
#define XEmacPs_BdSetAddressTx(BdPtr, Addr) \
|
||||
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, \
|
||||
(u32)((Addr) & ULONG64_LO_MASK)); \
|
||||
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_HI_OFFSET, \
|
||||
(u32)(((Addr) & ULONG64_HI_MASK) >> 32U));
|
||||
#else
|
||||
#define XEmacPs_BdSetAddressTx(BdPtr, Addr) \
|
||||
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, (u32)(Addr))
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Set the BD's Address field (word 0).
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
* @param Addr is the value to write to BD's status field.
|
||||
*
|
||||
* @note : Due to some bits are mixed within receive BD's address field,
|
||||
* read-modify-write is performed.
|
||||
*
|
||||
* C-style signature:
|
||||
* void XEmacPs_BdSetAddressRx(XEmacPs_Bd* BdPtr, UINTPTR Addr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifdef __aarch64__
|
||||
#define XEmacPs_BdSetAddressRx(BdPtr, Addr) \
|
||||
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & \
|
||||
~XEMACPS_RXBUF_ADD_MASK) | ((u32)((Addr) & ULONG64_LO_MASK)))); \
|
||||
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_HI_OFFSET, \
|
||||
(u32)(((Addr) & ULONG64_HI_MASK) >> 32U));
|
||||
#else
|
||||
#define XEmacPs_BdSetAddressRx(BdPtr, Addr) \
|
||||
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & \
|
||||
~XEMACPS_RXBUF_ADD_MASK) | (UINTPTR)(Addr)))
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Set the BD's Status field (word 1).
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
* @param Data is the value to write to BD's status field.
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XEmacPs_BdSetStatus(XEmacPs_Bd* BdPtr, UINTPTR Data)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdSetStatus(BdPtr, Data) \
|
||||
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
|
||||
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) | (Data))
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Retrieve the BD's Packet DMA transfer status word (word 1).
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @return Status word
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* u32 XEmacPs_BdGetStatus(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
* Due to the BD bit layout differences in transmit and receive. User's
|
||||
* caution is required.
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdGetStatus(BdPtr) \
|
||||
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Get the address (bits 0..31) of the BD's buffer address (word 0)
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdGetBufAddr(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#if defined(__aarch64__) || defined(__arch64__)
|
||||
#define XEmacPs_BdGetBufAddr(BdPtr) \
|
||||
(XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) | \
|
||||
(XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_HI_OFFSET)) << 32U)
|
||||
#else
|
||||
#define XEmacPs_BdGetBufAddr(BdPtr) \
|
||||
(XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET))
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Set transfer length in bytes for the given BD. The length must be set each
|
||||
* time a BD is submitted to hardware.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
* @param LenBytes is the number of bytes to transfer.
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XEmacPs_BdSetLength(XEmacPs_Bd* BdPtr, u32 LenBytes)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdSetLength(BdPtr, LenBytes) \
|
||||
XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
~XEMACPS_TXBUF_LEN_MASK) | (LenBytes)))
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Retrieve the BD length field.
|
||||
*
|
||||
* For Tx channels, the returned value is the same as that written with
|
||||
* XEmacPs_BdSetLength().
|
||||
*
|
||||
* For Rx channels, the returned value is the size of the received packet.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @return Length field processed by hardware or set by
|
||||
* XEmacPs_BdSetLength().
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdGetLength(XEmacPs_Bd* BdPtr)
|
||||
* XEAMCPS_RXBUF_LEN_MASK is same as XEMACPS_TXBUF_LEN_MASK.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdGetLength(BdPtr) \
|
||||
(XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
XEMACPS_RXBUF_LEN_MASK)
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Retrieve the RX frame size.
|
||||
*
|
||||
* The returned value is the size of the received packet.
|
||||
* This API supports jumbo frame sizes if enabled.
|
||||
*
|
||||
* @param InstancePtr is the pointer to XEmacps instance
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @return Length field processed by hardware or set by
|
||||
* XEmacPs_BdSetLength().
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_GetRxFrameSize(XEmacPs* InstancePtr, XEmacPs_Bd* BdPtr)
|
||||
* RxBufMask is dependent on whether jumbo is enabled or not.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_GetRxFrameSize(InstancePtr, BdPtr) \
|
||||
(XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
(InstancePtr)->RxBufMask)
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Test whether the given BD has been marked as the last BD of a packet.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @return TRUE if BD represents the "Last" BD of a packet, FALSE otherwise
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdIsLast(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsLast(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
XEMACPS_RXBUF_EOF_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Tell the DMA engine that the given transmit BD marks the end of the current
|
||||
* packet to be processed.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XEmacPs_BdSetLast(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdSetLast(BdPtr) \
|
||||
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
|
||||
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) | \
|
||||
XEMACPS_TXBUF_LAST_MASK))
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Tell the DMA engine that the current packet does not end with the given
|
||||
* BD.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XEmacPs_BdClearLast(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdClearLast(BdPtr) \
|
||||
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
|
||||
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
~XEMACPS_TXBUF_LAST_MASK))
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Set this bit to mark the last descriptor in the receive buffer descriptor
|
||||
* list.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XEmacPs_BdSetRxWrap(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*#define XEmacPs_BdSetRxWrap(BdPtr) \
|
||||
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, \
|
||||
XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) | \
|
||||
XEMACPS_RXBUF_WRAP_MASK))
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Determine the wrap bit of the receive BD which indicates end of the
|
||||
* BD list.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* u8 XEmacPs_BdIsRxWrap(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsRxWrap(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & \
|
||||
XEMACPS_RXBUF_WRAP_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Sets this bit to mark the last descriptor in the transmit buffer
|
||||
* descriptor list.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XEmacPs_BdSetTxWrap(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*#define XEmacPs_BdSetTxWrap(BdPtr) \
|
||||
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
|
||||
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) | \
|
||||
XEMACPS_TXBUF_WRAP_MASK))
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Determine the wrap bit of the transmit BD which indicates end of the
|
||||
* BD list.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* u8 XEmacPs_BdGetTxWrap(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsTxWrap(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
XEMACPS_TXBUF_WRAP_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* Must clear this bit to enable the MAC to write data to the receive
|
||||
* buffer. Hardware sets this bit once it has successfully written a frame to
|
||||
* memory. Once set, software has to clear the bit before the buffer can be
|
||||
* used again. This macro clear the new bit of the receive BD.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XEmacPs_BdClearRxNew(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdClearRxNew(BdPtr) \
|
||||
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_ADDR_OFFSET, \
|
||||
XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & \
|
||||
~XEMACPS_RXBUF_NEW_MASK))
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Determine the new bit of the receive BD.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdIsRxNew(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsRxNew(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_ADDR_OFFSET) & \
|
||||
XEMACPS_RXBUF_NEW_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Software sets this bit to disable the buffer to be read by the hardware.
|
||||
* Hardware sets this bit for the first buffer of a frame once it has been
|
||||
* successfully transmitted. This macro sets this bit of transmit BD to avoid
|
||||
* confusion.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XEmacPs_BdSetTxUsed(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdSetTxUsed(BdPtr) \
|
||||
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
|
||||
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) | \
|
||||
XEMACPS_TXBUF_USED_MASK))
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Software clears this bit to enable the buffer to be read by the hardware.
|
||||
* Hardware sets this bit for the first buffer of a frame once it has been
|
||||
* successfully transmitted. This macro clears this bit of transmit BD.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XEmacPs_BdClearTxUsed(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdClearTxUsed(BdPtr) \
|
||||
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
|
||||
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
~XEMACPS_TXBUF_USED_MASK))
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Determine the used bit of the transmit BD.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdIsTxUsed(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsTxUsed(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
XEMACPS_TXBUF_USED_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Determine if a frame fails to be transmitted due to too many retries.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdIsTxRetry(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsTxRetry(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
XEMACPS_TXBUF_RETRY_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Determine if a frame fails to be transmitted due to data can not be
|
||||
* feteched in time or buffers are exhausted.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdIsTxUrun(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsTxUrun(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
XEMACPS_TXBUF_URUN_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Determine if a frame fails to be transmitted due to buffer is exhausted
|
||||
* mid-frame.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdIsTxExh(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsTxExh(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
XEMACPS_TXBUF_EXH_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Sets this bit, no CRC will be appended to the current frame. This control
|
||||
* bit must be set for the first buffer in a frame and will be ignored for
|
||||
* the subsequent buffers of a frame.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* This bit must be clear when using the transmit checksum generation offload,
|
||||
* otherwise checksum generation and substitution will not occur.
|
||||
*
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdSetTxNoCRC(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdSetTxNoCRC(BdPtr) \
|
||||
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
|
||||
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) | \
|
||||
XEMACPS_TXBUF_NOCRC_MASK))
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Clear this bit, CRC will be appended to the current frame. This control
|
||||
* bit must be set for the first buffer in a frame and will be ignored for
|
||||
* the subsequent buffers of a frame.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* This bit must be clear when using the transmit checksum generation offload,
|
||||
* otherwise checksum generation and substitution will not occur.
|
||||
*
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdClearTxNoCRC(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdClearTxNoCRC(BdPtr) \
|
||||
(XEmacPs_BdWrite((BdPtr), XEMACPS_BD_STAT_OFFSET, \
|
||||
XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
~XEMACPS_TXBUF_NOCRC_MASK))
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Determine the broadcast bit of the receive BD.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdIsRxBcast(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsRxBcast(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
XEMACPS_RXBUF_BCAST_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Determine the multicast hash bit of the receive BD.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdIsRxMultiHash(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsRxMultiHash(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
XEMACPS_RXBUF_MULTIHASH_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Determine the unicast hash bit of the receive BD.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdIsRxUniHash(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsRxUniHash(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
XEMACPS_RXBUF_UNIHASH_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Determine if the received frame is a VLAN Tagged frame.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdIsRxVlan(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsRxVlan(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
XEMACPS_RXBUF_VLAN_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Determine if the received frame has Type ID of 8100h and null VLAN
|
||||
* identifier(Priority tag).
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdIsRxPri(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsRxPri(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
XEMACPS_RXBUF_PRI_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Determine if the received frame's Concatenation Format Indicator (CFI) of
|
||||
* the frames VLANTCI field was set.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdIsRxCFI(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsRxCFI(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
XEMACPS_RXBUF_CFI_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Determine the End Of Frame (EOF) bit of the receive BD.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdGetRxEOF(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsRxEOF(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
XEMACPS_RXBUF_EOF_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Determine the Start Of Frame (SOF) bit of the receive BD.
|
||||
*
|
||||
* @param BdPtr is the BD pointer to operate on
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* UINTPTR XEmacPs_BdGetRxSOF(XEmacPs_Bd* BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdIsRxSOF(BdPtr) \
|
||||
((XEmacPs_BdRead((BdPtr), XEMACPS_BD_STAT_OFFSET) & \
|
||||
XEMACPS_RXBUF_SOF_MASK)!=0U ? TRUE : FALSE)
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,215 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2010 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xemacps_bdring.h
|
||||
* @addtogroup emacps_v3_11
|
||||
* @{
|
||||
*
|
||||
* The Xiline EmacPs Buffer Descriptor ring driver. This is part of EmacPs
|
||||
* DMA functionalities.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.00a wsy 01/10/10 First release
|
||||
* 2.1 srt 07/15/14 Add support for Zynq Ultrascale Mp architecture.
|
||||
* 3.0 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
* 3.6 rb 09/08/17 HwCnt variable (in XEmacPs_BdRing structure) is
|
||||
* changed to volatile.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XEMACPS_BDRING_H /* prevent curcular inclusions */
|
||||
#define XEMACPS_BDRING_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/** This is an internal structure used to maintain the DMA list */
|
||||
typedef struct {
|
||||
UINTPTR PhysBaseAddr;/**< Physical address of 1st BD in list */
|
||||
UINTPTR BaseBdAddr; /**< Virtual address of 1st BD in list */
|
||||
UINTPTR HighBdAddr; /**< Virtual address of last BD in the list */
|
||||
u32 Length; /**< Total size of ring in bytes */
|
||||
u32 RunState; /**< Flag to indicate DMA is started */
|
||||
u32 Separation; /**< Number of bytes between the starting address
|
||||
of adjacent BDs */
|
||||
XEmacPs_Bd *FreeHead;
|
||||
/**< First BD in the free group */
|
||||
XEmacPs_Bd *PreHead;/**< First BD in the pre-work group */
|
||||
XEmacPs_Bd *HwHead; /**< First BD in the work group */
|
||||
XEmacPs_Bd *HwTail; /**< Last BD in the work group */
|
||||
XEmacPs_Bd *PostHead;
|
||||
/**< First BD in the post-work group */
|
||||
XEmacPs_Bd *BdaRestart;
|
||||
/**< BDA to load when channel is started */
|
||||
|
||||
volatile u32 HwCnt; /**< Number of BDs in work group */
|
||||
u32 PreCnt; /**< Number of BDs in pre-work group */
|
||||
u32 FreeCnt; /**< Number of allocatable BDs in the free group */
|
||||
u32 PostCnt; /**< Number of BDs in post-work group */
|
||||
u32 AllCnt; /**< Total Number of BDs for channel */
|
||||
} XEmacPs_BdRing;
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Use this macro at initialization time to determine how many BDs will fit
|
||||
* in a BD list within the given memory constraints.
|
||||
*
|
||||
* The results of this macro can be provided to XEmacPs_BdRingCreate().
|
||||
*
|
||||
* @param Alignment specifies what byte alignment the BDs must fall on and
|
||||
* must be a power of 2 to get an accurate calculation (32, 64, 128,...)
|
||||
* @param Bytes is the number of bytes to be used to store BDs.
|
||||
*
|
||||
* @return Number of BDs that can fit in the given memory area
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* u32 XEmacPs_BdRingCntCalc(u32 Alignment, u32 Bytes)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XEmacPs_BdRingCntCalc(Alignment, Bytes) \
|
||||
(u32)((Bytes) / (sizeof(XEmacPs_Bd)))
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Use this macro at initialization time to determine how many bytes of memory
|
||||
* is required to contain a given number of BDs at a given alignment.
|
||||
*
|
||||
* @param Alignment specifies what byte alignment the BDs must fall on. This
|
||||
* parameter must be a power of 2 to get an accurate calculation (32, 64,
|
||||
* 128,...)
|
||||
* @param NumBd is the number of BDs to calculate memory size requirements for
|
||||
*
|
||||
* @return The number of bytes of memory required to create a BD list with the
|
||||
* given memory constraints.
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* u32 XEmacPs_BdRingMemCalc(u32 Alignment, u32 NumBd)
|
||||
*
|
||||
******************************************************************************/
|
||||
#define XEmacPs_BdRingMemCalc(Alignment, NumBd) \
|
||||
(u32)(sizeof(XEmacPs_Bd) * (NumBd))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Return the total number of BDs allocated by this channel with
|
||||
* XEmacPs_BdRingCreate().
|
||||
*
|
||||
* @param RingPtr is the DMA channel to operate on.
|
||||
*
|
||||
* @return The total number of BDs allocated for this channel.
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* u32 XEmacPs_BdRingGetCnt(XEmacPs_BdRing* RingPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdRingGetCnt(RingPtr) ((RingPtr)->AllCnt)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Return the number of BDs allocatable with XEmacPs_BdRingAlloc() for pre-
|
||||
* processing.
|
||||
*
|
||||
* @param RingPtr is the DMA channel to operate on.
|
||||
*
|
||||
* @return The number of BDs currently allocatable.
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* u32 XEmacPs_BdRingGetFreeCnt(XEmacPs_BdRing* RingPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdRingGetFreeCnt(RingPtr) ((RingPtr)->FreeCnt)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Return the next BD from BdPtr in a list.
|
||||
*
|
||||
* @param RingPtr is the DMA channel to operate on.
|
||||
* @param BdPtr is the BD to operate on.
|
||||
*
|
||||
* @return The next BD in the list relative to the BdPtr parameter.
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* XEmacPs_Bd *XEmacPs_BdRingNext(XEmacPs_BdRing* RingPtr,
|
||||
* XEmacPs_Bd *BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdRingNext(RingPtr, BdPtr) \
|
||||
(((UINTPTR)((void *)(BdPtr)) >= (RingPtr)->HighBdAddr) ? \
|
||||
(XEmacPs_Bd*)((void*)(RingPtr)->BaseBdAddr) : \
|
||||
(XEmacPs_Bd*)((UINTPTR)((void *)(BdPtr)) + (RingPtr)->Separation))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Return the previous BD from BdPtr in the list.
|
||||
*
|
||||
* @param RingPtr is the DMA channel to operate on.
|
||||
* @param BdPtr is the BD to operate on
|
||||
*
|
||||
* @return The previous BD in the list relative to the BdPtr parameter.
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* XEmacPs_Bd *XEmacPs_BdRingPrev(XEmacPs_BdRing* RingPtr,
|
||||
* XEmacPs_Bd *BdPtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_BdRingPrev(RingPtr, BdPtr) \
|
||||
(((UINTPTR)(BdPtr) <= (RingPtr)->BaseBdAddr) ? \
|
||||
(XEmacPs_Bd*)(RingPtr)->HighBdAddr : \
|
||||
(XEmacPs_Bd*)((UINTPTR)(BdPtr) - (RingPtr)->Separation))
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
* Scatter gather DMA related functions in xemacps_bdring.c
|
||||
*/
|
||||
LONG XEmacPs_BdRingCreate(XEmacPs_BdRing * RingPtr, UINTPTR PhysAddr,
|
||||
UINTPTR VirtAddr, u32 Alignment, u32 BdCount);
|
||||
LONG XEmacPs_BdRingClone(XEmacPs_BdRing * RingPtr, XEmacPs_Bd * SrcBdPtr,
|
||||
u8 Direction);
|
||||
LONG XEmacPs_BdRingAlloc(XEmacPs_BdRing * RingPtr, u32 NumBd,
|
||||
XEmacPs_Bd ** BdSetPtr);
|
||||
LONG XEmacPs_BdRingUnAlloc(XEmacPs_BdRing * RingPtr, u32 NumBd,
|
||||
XEmacPs_Bd * BdSetPtr);
|
||||
LONG XEmacPs_BdRingToHw(XEmacPs_BdRing * RingPtr, u32 NumBd,
|
||||
XEmacPs_Bd * BdSetPtr);
|
||||
LONG XEmacPs_BdRingFree(XEmacPs_BdRing * RingPtr, u32 NumBd,
|
||||
XEmacPs_Bd * BdSetPtr);
|
||||
u32 XEmacPs_BdRingFromHwTx(XEmacPs_BdRing * RingPtr, u32 BdLimit,
|
||||
XEmacPs_Bd ** BdSetPtr);
|
||||
u32 XEmacPs_BdRingFromHwRx(XEmacPs_BdRing * RingPtr, u32 BdLimit,
|
||||
XEmacPs_Bd ** BdSetPtr);
|
||||
LONG XEmacPs_BdRingCheck(XEmacPs_BdRing * RingPtr, u8 Direction);
|
||||
|
||||
void XEmacPs_BdRingPtrReset(XEmacPs_BdRing * RingPtr, void *virtaddrloc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* end of protection macros */
|
||||
/** @} */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,32 @@
|
|||
|
||||
/*******************************************************************
|
||||
*
|
||||
* CAUTION: This file is automatically generated by HSI.
|
||||
* Version: 2020.1
|
||||
* DO NOT EDIT.
|
||||
*
|
||||
* Copyright (C) 2010-2021 Xilinx, Inc. All Rights Reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
|
||||
*
|
||||
* Description: Driver configuration
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xemacps.h"
|
||||
|
||||
/*
|
||||
* The configuration table for devices
|
||||
*/
|
||||
|
||||
XEmacPs_Config XEmacPs_ConfigTable[XPAR_XEMACPS_NUM_INSTANCES] =
|
||||
{
|
||||
{
|
||||
XPAR_PSU_ETHERNET_3_DEVICE_ID,
|
||||
XPAR_PSU_ETHERNET_3_BASEADDR,
|
||||
XPAR_PSU_ETHERNET_3_IS_CACHE_COHERENT
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2010 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xemacps_hw.c
|
||||
* @addtogroup emacps_v3_11
|
||||
* @{
|
||||
*
|
||||
* This file contains the implementation of the ethernet interface reset sequence
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.05a kpc 28/06/13 First release
|
||||
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xemacps_hw.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function perform the reset sequence to the given emacps interface by
|
||||
* configuring the appropriate control bits in the emacps specific registers.
|
||||
* the emacps reset sequence involves the following steps
|
||||
* Disable all the interuupts
|
||||
* Clear the status registers
|
||||
* Disable Rx and Tx engines
|
||||
* Update the Tx and Rx descriptor queue registers with reset values
|
||||
* Update the other relevant control registers with reset value
|
||||
*
|
||||
* @param BaseAddr of the interface
|
||||
*
|
||||
* @return N/A
|
||||
*
|
||||
* @note
|
||||
* This function will not modify the slcr registers that are relevant for
|
||||
* emacps controller
|
||||
******************************************************************************/
|
||||
void XEmacPs_ResetHw(u32 BaseAddr)
|
||||
{
|
||||
u32 RegVal;
|
||||
|
||||
/* Disable the interrupts */
|
||||
XEmacPs_WriteReg(BaseAddr,XEMACPS_IDR_OFFSET,0x0U);
|
||||
|
||||
/* Stop transmission,disable loopback and Stop tx and Rx engines */
|
||||
RegVal = XEmacPs_ReadReg(BaseAddr,XEMACPS_NWCTRL_OFFSET);
|
||||
RegVal &= ~((u32)XEMACPS_NWCTRL_TXEN_MASK|
|
||||
(u32)XEMACPS_NWCTRL_RXEN_MASK|
|
||||
(u32)XEMACPS_NWCTRL_HALTTX_MASK|
|
||||
(u32)XEMACPS_NWCTRL_LOOPEN_MASK);
|
||||
/* Clear the statistic registers, flush the packets in DPRAM*/
|
||||
RegVal |= (XEMACPS_NWCTRL_STATCLR_MASK|
|
||||
XEMACPS_NWCTRL_FLUSH_DPRAM_MASK);
|
||||
XEmacPs_WriteReg(BaseAddr,XEMACPS_NWCTRL_OFFSET,RegVal);
|
||||
/* Clear the interrupt status */
|
||||
XEmacPs_WriteReg(BaseAddr,XEMACPS_ISR_OFFSET,XEMACPS_IXR_ALL_MASK);
|
||||
/* Clear the tx status */
|
||||
XEmacPs_WriteReg(BaseAddr,XEMACPS_TXSR_OFFSET,(XEMACPS_TXSR_ERROR_MASK|
|
||||
(u32)XEMACPS_TXSR_TXCOMPL_MASK|
|
||||
(u32)XEMACPS_TXSR_TXGO_MASK));
|
||||
/* Clear the rx status */
|
||||
XEmacPs_WriteReg(BaseAddr,XEMACPS_RXSR_OFFSET,
|
||||
XEMACPS_RXSR_FRAMERX_MASK);
|
||||
/* Clear the tx base address */
|
||||
XEmacPs_WriteReg(BaseAddr,XEMACPS_TXQBASE_OFFSET,0x0U);
|
||||
/* Clear the rx base address */
|
||||
XEmacPs_WriteReg(BaseAddr,XEMACPS_RXQBASE_OFFSET,0x0U);
|
||||
/* Update the network config register with reset value */
|
||||
XEmacPs_WriteReg(BaseAddr,XEMACPS_NWCFG_OFFSET,XEMACPS_NWCFG_RESET_MASK);
|
||||
/* Update the hash address registers with reset value */
|
||||
XEmacPs_WriteReg(BaseAddr,XEMACPS_HASHL_OFFSET,0x0U);
|
||||
XEmacPs_WriteReg(BaseAddr,XEMACPS_HASHH_OFFSET,0x0U);
|
||||
}
|
||||
/** @} */
|
|
@ -0,0 +1,646 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2010 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xemacps_hw.h
|
||||
* @addtogroup emacps_v3_11
|
||||
* @{
|
||||
*
|
||||
* This header file contains identifiers and low-level driver functions (or
|
||||
* macros) that can be used to access the PS Ethernet MAC (XEmacPs) device.
|
||||
* High-level driver functions are defined in xemacps.h.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.00a wsy 01/10/10 First release.
|
||||
* 1.02a asa 11/05/12 Added hash defines for DMACR burst length configuration.
|
||||
* 1.05a kpc 28/06/13 Added XEmacPs_ResetHw function prototype
|
||||
* 1.06a asa 11/02/13 Changed the value for XEMACPS_RXBUF_LEN_MASK from 0x3fff
|
||||
* to 0x1fff. This fixes the CR#744902.
|
||||
* 2.1 srt 07/15/14 Add support for Zynq Ultrascale Mp GEM specification.
|
||||
* 3.0 kvn 12/16/14 Changed name of XEMACPS_NWCFG_LENGTHERRDSCRD_MASK to
|
||||
* XEMACPS_NWCFG_LENERRDSCRD_MASK as it exceeds 31 characters.
|
||||
* 3.0 kpc 1/23/15 Corrected the extended descriptor macro values.
|
||||
* 3.0 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
* 3.0 hk 03/18/15 Added support for jumbo frames.
|
||||
* Remove "used bit set" from TX error interrupt masks.
|
||||
* 3.1 hk 08/10/15 Update upper 32 bit tx and rx queue ptr register offsets.
|
||||
* 3.2 hk 02/22/16 Added SGMII support for Zynq Ultrascale+ MPSoC.
|
||||
* 3.8 hk 09/17/18 Fix PTP interrupt masks.
|
||||
* 3.9 hk 01/23/19 Add RX watermark support
|
||||
* 3.10 hk 05/16/19 Clear status registers properly in reset
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XEMACPS_HW_H /* prevent circular inclusions */
|
||||
#define XEMACPS_HW_H /* by using protection macros */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xil_io.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
#define XEMACPS_MAX_MAC_ADDR 4U /**< Maxmum number of mac address
|
||||
supported */
|
||||
#define XEMACPS_MAX_TYPE_ID 4U /**< Maxmum number of type id supported */
|
||||
|
||||
#ifdef __aarch64__
|
||||
#define XEMACPS_BD_ALIGNMENT 64U /**< Minimum buffer descriptor alignment
|
||||
on the local bus */
|
||||
#else
|
||||
|
||||
#define XEMACPS_BD_ALIGNMENT 4U /**< Minimum buffer descriptor alignment
|
||||
on the local bus */
|
||||
#endif
|
||||
#define XEMACPS_RX_BUF_ALIGNMENT 4U /**< Minimum buffer alignment when using
|
||||
options that impose alignment
|
||||
restrictions on the buffer data on
|
||||
the local bus */
|
||||
|
||||
/** @name Direction identifiers
|
||||
*
|
||||
* These are used by several functions and callbacks that need
|
||||
* to specify whether an operation specifies a send or receive channel.
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_SEND 1U /**< send direction */
|
||||
#define XEMACPS_RECV 2U /**< receive direction */
|
||||
/*@}*/
|
||||
|
||||
/** @name MDC clock division
|
||||
* currently supporting 8, 16, 32, 48, 64, 96, 128, 224.
|
||||
* @{
|
||||
*/
|
||||
typedef enum { MDC_DIV_8 = 0U, MDC_DIV_16, MDC_DIV_32, MDC_DIV_48,
|
||||
MDC_DIV_64, MDC_DIV_96, MDC_DIV_128, MDC_DIV_224
|
||||
} XEmacPs_MdcDiv;
|
||||
|
||||
/*@}*/
|
||||
|
||||
#define XEMACPS_RX_BUF_SIZE 1536U /**< Specify the receive buffer size in
|
||||
bytes, 64, 128, ... 10240 */
|
||||
#define XEMACPS_RX_BUF_SIZE_JUMBO 10240U
|
||||
|
||||
#define XEMACPS_RX_BUF_UNIT 64U /**< Number of receive buffer bytes as a
|
||||
unit, this is HW setup */
|
||||
|
||||
#define XEMACPS_MAX_RXBD 128U /**< Size of RX buffer descriptor queues */
|
||||
#define XEMACPS_MAX_TXBD 128U /**< Size of TX buffer descriptor queues */
|
||||
|
||||
#define XEMACPS_MAX_HASH_BITS 64U /**< Maximum value for hash bits. 2**6 */
|
||||
|
||||
/* Register offset definitions. Unless otherwise noted, register access is
|
||||
* 32 bit. Names are self explained here.
|
||||
*/
|
||||
|
||||
#define XEMACPS_NWCTRL_OFFSET 0x00000000U /**< Network Control reg */
|
||||
#define XEMACPS_NWCFG_OFFSET 0x00000004U /**< Network Config reg */
|
||||
#define XEMACPS_NWSR_OFFSET 0x00000008U /**< Network Status reg */
|
||||
|
||||
#define XEMACPS_DMACR_OFFSET 0x00000010U /**< DMA Control reg */
|
||||
#define XEMACPS_TXSR_OFFSET 0x00000014U /**< TX Status reg */
|
||||
#define XEMACPS_RXQBASE_OFFSET 0x00000018U /**< RX Q Base address reg */
|
||||
#define XEMACPS_TXQBASE_OFFSET 0x0000001CU /**< TX Q Base address reg */
|
||||
#define XEMACPS_RXSR_OFFSET 0x00000020U /**< RX Status reg */
|
||||
|
||||
#define XEMACPS_ISR_OFFSET 0x00000024U /**< Interrupt Status reg */
|
||||
#define XEMACPS_IER_OFFSET 0x00000028U /**< Interrupt Enable reg */
|
||||
#define XEMACPS_IDR_OFFSET 0x0000002CU /**< Interrupt Disable reg */
|
||||
#define XEMACPS_IMR_OFFSET 0x00000030U /**< Interrupt Mask reg */
|
||||
|
||||
#define XEMACPS_PHYMNTNC_OFFSET 0x00000034U /**< Phy Maintaince reg */
|
||||
#define XEMACPS_RXPAUSE_OFFSET 0x00000038U /**< RX Pause Time reg */
|
||||
#define XEMACPS_TXPAUSE_OFFSET 0x0000003CU /**< TX Pause Time reg */
|
||||
|
||||
#define XEMACPS_JUMBOMAXLEN_OFFSET 0x00000048U /**< Jumbo max length reg */
|
||||
|
||||
#define XEMACPS_RXWATERMARK_OFFSET 0x0000007CU /**< RX watermark reg */
|
||||
|
||||
#define XEMACPS_HASHL_OFFSET 0x00000080U /**< Hash Low address reg */
|
||||
#define XEMACPS_HASHH_OFFSET 0x00000084U /**< Hash High address reg */
|
||||
|
||||
#define XEMACPS_LADDR1L_OFFSET 0x00000088U /**< Specific1 addr low reg */
|
||||
#define XEMACPS_LADDR1H_OFFSET 0x0000008CU /**< Specific1 addr high reg */
|
||||
#define XEMACPS_LADDR2L_OFFSET 0x00000090U /**< Specific2 addr low reg */
|
||||
#define XEMACPS_LADDR2H_OFFSET 0x00000094U /**< Specific2 addr high reg */
|
||||
#define XEMACPS_LADDR3L_OFFSET 0x00000098U /**< Specific3 addr low reg */
|
||||
#define XEMACPS_LADDR3H_OFFSET 0x0000009CU /**< Specific3 addr high reg */
|
||||
#define XEMACPS_LADDR4L_OFFSET 0x000000A0U /**< Specific4 addr low reg */
|
||||
#define XEMACPS_LADDR4H_OFFSET 0x000000A4U /**< Specific4 addr high reg */
|
||||
|
||||
#define XEMACPS_MATCH1_OFFSET 0x000000A8U /**< Type ID1 Match reg */
|
||||
#define XEMACPS_MATCH2_OFFSET 0x000000ACU /**< Type ID2 Match reg */
|
||||
#define XEMACPS_MATCH3_OFFSET 0x000000B0U /**< Type ID3 Match reg */
|
||||
#define XEMACPS_MATCH4_OFFSET 0x000000B4U /**< Type ID4 Match reg */
|
||||
|
||||
#define XEMACPS_STRETCH_OFFSET 0x000000BCU /**< IPG Stretch reg */
|
||||
|
||||
#define XEMACPS_OCTTXL_OFFSET 0x00000100U /**< Octects transmitted Low
|
||||
reg */
|
||||
#define XEMACPS_OCTTXH_OFFSET 0x00000104U /**< Octects transmitted High
|
||||
reg */
|
||||
|
||||
#define XEMACPS_TXCNT_OFFSET 0x00000108U /**< Error-free Frmaes
|
||||
transmitted counter */
|
||||
#define XEMACPS_TXBCCNT_OFFSET 0x0000010CU /**< Error-free Broadcast
|
||||
Frames counter*/
|
||||
#define XEMACPS_TXMCCNT_OFFSET 0x00000110U /**< Error-free Multicast
|
||||
Frame counter */
|
||||
#define XEMACPS_TXPAUSECNT_OFFSET 0x00000114U /**< Pause Frames Transmitted
|
||||
Counter */
|
||||
#define XEMACPS_TX64CNT_OFFSET 0x00000118U /**< Error-free 64 byte Frames
|
||||
Transmitted counter */
|
||||
#define XEMACPS_TX65CNT_OFFSET 0x0000011CU /**< Error-free 65-127 byte
|
||||
Frames Transmitted
|
||||
counter */
|
||||
#define XEMACPS_TX128CNT_OFFSET 0x00000120U /**< Error-free 128-255 byte
|
||||
Frames Transmitted
|
||||
counter*/
|
||||
#define XEMACPS_TX256CNT_OFFSET 0x00000124U /**< Error-free 256-511 byte
|
||||
Frames transmitted
|
||||
counter */
|
||||
#define XEMACPS_TX512CNT_OFFSET 0x00000128U /**< Error-free 512-1023 byte
|
||||
Frames transmitted
|
||||
counter */
|
||||
#define XEMACPS_TX1024CNT_OFFSET 0x0000012CU /**< Error-free 1024-1518 byte
|
||||
Frames transmitted
|
||||
counter */
|
||||
#define XEMACPS_TX1519CNT_OFFSET 0x00000130U /**< Error-free larger than
|
||||
1519 byte Frames
|
||||
transmitted counter */
|
||||
#define XEMACPS_TXURUNCNT_OFFSET 0x00000134U /**< TX under run error
|
||||
counter */
|
||||
|
||||
#define XEMACPS_SNGLCOLLCNT_OFFSET 0x00000138U /**< Single Collision Frame
|
||||
Counter */
|
||||
#define XEMACPS_MULTICOLLCNT_OFFSET 0x0000013CU /**< Multiple Collision Frame
|
||||
Counter */
|
||||
#define XEMACPS_EXCESSCOLLCNT_OFFSET 0x00000140U /**< Excessive Collision Frame
|
||||
Counter */
|
||||
#define XEMACPS_LATECOLLCNT_OFFSET 0x00000144U /**< Late Collision Frame
|
||||
Counter */
|
||||
#define XEMACPS_TXDEFERCNT_OFFSET 0x00000148U /**< Deferred Transmission
|
||||
Frame Counter */
|
||||
#define XEMACPS_TXCSENSECNT_OFFSET 0x0000014CU /**< Transmit Carrier Sense
|
||||
Error Counter */
|
||||
|
||||
#define XEMACPS_OCTRXL_OFFSET 0x00000150U /**< Octects Received register
|
||||
Low */
|
||||
#define XEMACPS_OCTRXH_OFFSET 0x00000154U /**< Octects Received register
|
||||
High */
|
||||
|
||||
#define XEMACPS_RXCNT_OFFSET 0x00000158U /**< Error-free Frames
|
||||
Received Counter */
|
||||
#define XEMACPS_RXBROADCNT_OFFSET 0x0000015CU /**< Error-free Broadcast
|
||||
Frames Received Counter */
|
||||
#define XEMACPS_RXMULTICNT_OFFSET 0x00000160U /**< Error-free Multicast
|
||||
Frames Received Counter */
|
||||
#define XEMACPS_RXPAUSECNT_OFFSET 0x00000164U /**< Pause Frames
|
||||
Received Counter */
|
||||
#define XEMACPS_RX64CNT_OFFSET 0x00000168U /**< Error-free 64 byte Frames
|
||||
Received Counter */
|
||||
#define XEMACPS_RX65CNT_OFFSET 0x0000016CU /**< Error-free 65-127 byte
|
||||
Frames Received Counter */
|
||||
#define XEMACPS_RX128CNT_OFFSET 0x00000170U /**< Error-free 128-255 byte
|
||||
Frames Received Counter */
|
||||
#define XEMACPS_RX256CNT_OFFSET 0x00000174U /**< Error-free 256-512 byte
|
||||
Frames Received Counter */
|
||||
#define XEMACPS_RX512CNT_OFFSET 0x00000178U /**< Error-free 512-1023 byte
|
||||
Frames Received Counter */
|
||||
#define XEMACPS_RX1024CNT_OFFSET 0x0000017CU /**< Error-free 1024-1518 byte
|
||||
Frames Received Counter */
|
||||
#define XEMACPS_RX1519CNT_OFFSET 0x00000180U /**< Error-free 1519-max byte
|
||||
Frames Received Counter */
|
||||
#define XEMACPS_RXUNDRCNT_OFFSET 0x00000184U /**< Undersize Frames Received
|
||||
Counter */
|
||||
#define XEMACPS_RXOVRCNT_OFFSET 0x00000188U /**< Oversize Frames Received
|
||||
Counter */
|
||||
#define XEMACPS_RXJABCNT_OFFSET 0x0000018CU /**< Jabbers Received
|
||||
Counter */
|
||||
#define XEMACPS_RXFCSCNT_OFFSET 0x00000190U /**< Frame Check Sequence
|
||||
Error Counter */
|
||||
#define XEMACPS_RXLENGTHCNT_OFFSET 0x00000194U /**< Length Field Error
|
||||
Counter */
|
||||
#define XEMACPS_RXSYMBCNT_OFFSET 0x00000198U /**< Symbol Error Counter */
|
||||
#define XEMACPS_RXALIGNCNT_OFFSET 0x0000019CU /**< Alignment Error Counter */
|
||||
#define XEMACPS_RXRESERRCNT_OFFSET 0x000001A0U /**< Receive Resource Error
|
||||
Counter */
|
||||
#define XEMACPS_RXORCNT_OFFSET 0x000001A4U /**< Receive Overrun Counter */
|
||||
#define XEMACPS_RXIPCCNT_OFFSET 0x000001A8U /**< IP header Checksum Error
|
||||
Counter */
|
||||
#define XEMACPS_RXTCPCCNT_OFFSET 0x000001ACU /**< TCP Checksum Error
|
||||
Counter */
|
||||
#define XEMACPS_RXUDPCCNT_OFFSET 0x000001B0U /**< UDP Checksum Error
|
||||
Counter */
|
||||
#define XEMACPS_LAST_OFFSET 0x000001B4U /**< Last statistic counter
|
||||
offset, for clearing */
|
||||
|
||||
#define XEMACPS_1588_SEC_OFFSET 0x000001D0U /**< 1588 second counter */
|
||||
#define XEMACPS_1588_NANOSEC_OFFSET 0x000001D4U /**< 1588 nanosecond counter */
|
||||
#define XEMACPS_1588_ADJ_OFFSET 0x000001D8U /**< 1588 nanosecond
|
||||
adjustment counter */
|
||||
#define XEMACPS_1588_INC_OFFSET 0x000001DCU /**< 1588 nanosecond
|
||||
increment counter */
|
||||
#define XEMACPS_PTP_TXSEC_OFFSET 0x000001E0U /**< 1588 PTP transmit second
|
||||
counter */
|
||||
#define XEMACPS_PTP_TXNANOSEC_OFFSET 0x000001E4U /**< 1588 PTP transmit
|
||||
nanosecond counter */
|
||||
#define XEMACPS_PTP_RXSEC_OFFSET 0x000001E8U /**< 1588 PTP receive second
|
||||
counter */
|
||||
#define XEMACPS_PTP_RXNANOSEC_OFFSET 0x000001ECU /**< 1588 PTP receive
|
||||
nanosecond counter */
|
||||
#define XEMACPS_PTPP_TXSEC_OFFSET 0x000001F0U /**< 1588 PTP peer transmit
|
||||
second counter */
|
||||
#define XEMACPS_PTPP_TXNANOSEC_OFFSET 0x000001F4U /**< 1588 PTP peer transmit
|
||||
nanosecond counter */
|
||||
#define XEMACPS_PTPP_RXSEC_OFFSET 0x000001F8U /**< 1588 PTP peer receive
|
||||
second counter */
|
||||
#define XEMACPS_PTPP_RXNANOSEC_OFFSET 0x000001FCU /**< 1588 PTP peer receive
|
||||
nanosecond counter */
|
||||
|
||||
#define XEMACPS_INTQ1_STS_OFFSET 0x00000400U /**< Interrupt Q1 Status
|
||||
reg */
|
||||
#define XEMACPS_TXQ1BASE_OFFSET 0x00000440U /**< TX Q1 Base address
|
||||
reg */
|
||||
#define XEMACPS_RXQ1BASE_OFFSET 0x00000480U /**< RX Q1 Base address
|
||||
reg */
|
||||
#define XEMACPS_MSBBUF_TXQBASE_OFFSET 0x000004C8U /**< MSB Buffer TX Q Base
|
||||
reg */
|
||||
#define XEMACPS_MSBBUF_RXQBASE_OFFSET 0x000004D4U /**< MSB Buffer RX Q Base
|
||||
reg */
|
||||
#define XEMACPS_INTQ1_IER_OFFSET 0x00000600U /**< Interrupt Q1 Enable
|
||||
reg */
|
||||
#define XEMACPS_INTQ1_IDR_OFFSET 0x00000620U /**< Interrupt Q1 Disable
|
||||
reg */
|
||||
#define XEMACPS_INTQ1_IMR_OFFSET 0x00000640U /**< Interrupt Q1 Mask
|
||||
reg */
|
||||
|
||||
/* Define some bit positions for registers. */
|
||||
|
||||
/** @name network control register bit definitions
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_NWCTRL_FLUSH_DPRAM_MASK 0x00040000U /**< Flush a packet from
|
||||
Rx SRAM */
|
||||
#define XEMACPS_NWCTRL_ZEROPAUSETX_MASK 0x00000800U /**< Transmit zero quantum
|
||||
pause frame */
|
||||
#define XEMACPS_NWCTRL_PAUSETX_MASK 0x00000800U /**< Transmit pause frame */
|
||||
#define XEMACPS_NWCTRL_HALTTX_MASK 0x00000400U /**< Halt transmission
|
||||
after current frame */
|
||||
#define XEMACPS_NWCTRL_STARTTX_MASK 0x00000200U /**< Start tx (tx_go) */
|
||||
|
||||
#define XEMACPS_NWCTRL_STATWEN_MASK 0x00000080U /**< Enable writing to
|
||||
stat counters */
|
||||
#define XEMACPS_NWCTRL_STATINC_MASK 0x00000040U /**< Increment statistic
|
||||
registers */
|
||||
#define XEMACPS_NWCTRL_STATCLR_MASK 0x00000020U /**< Clear statistic
|
||||
registers */
|
||||
#define XEMACPS_NWCTRL_MDEN_MASK 0x00000010U /**< Enable MDIO port */
|
||||
#define XEMACPS_NWCTRL_TXEN_MASK 0x00000008U /**< Enable transmit */
|
||||
#define XEMACPS_NWCTRL_RXEN_MASK 0x00000004U /**< Enable receive */
|
||||
#define XEMACPS_NWCTRL_LOOPEN_MASK 0x00000002U /**< local loopback */
|
||||
/*@}*/
|
||||
|
||||
/** @name network configuration register bit definitions
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_NWCFG_BADPREAMBEN_MASK 0x20000000U /**< disable rejection of
|
||||
non-standard preamble */
|
||||
#define XEMACPS_NWCFG_IPDSTRETCH_MASK 0x10000000U /**< enable transmit IPG */
|
||||
#define XEMACPS_NWCFG_SGMIIEN_MASK 0x08000000U /**< SGMII Enable */
|
||||
#define XEMACPS_NWCFG_FCSIGNORE_MASK 0x04000000U /**< disable rejection of
|
||||
FCS error */
|
||||
#define XEMACPS_NWCFG_HDRXEN_MASK 0x02000000U /**< RX half duplex */
|
||||
#define XEMACPS_NWCFG_RXCHKSUMEN_MASK 0x01000000U /**< enable RX checksum
|
||||
offload */
|
||||
#define XEMACPS_NWCFG_PAUSECOPYDI_MASK 0x00800000U /**< Do not copy pause
|
||||
Frames to memory */
|
||||
#define XEMACPS_NWCFG_DWIDTH_64_MASK 0x00200000U /**< 64 bit Data bus width */
|
||||
#define XEMACPS_NWCFG_MDC_SHIFT_MASK 18U /**< shift bits for MDC */
|
||||
#define XEMACPS_NWCFG_MDCCLKDIV_MASK 0x001C0000U /**< MDC Mask PCLK divisor */
|
||||
#define XEMACPS_NWCFG_FCSREM_MASK 0x00020000U /**< Discard FCS from
|
||||
received frames */
|
||||
#define XEMACPS_NWCFG_LENERRDSCRD_MASK 0x00010000U
|
||||
/**< RX length error discard */
|
||||
#define XEMACPS_NWCFG_RXOFFS_MASK 0x0000C000U /**< RX buffer offset */
|
||||
#define XEMACPS_NWCFG_PAUSEEN_MASK 0x00002000U /**< Enable pause RX */
|
||||
#define XEMACPS_NWCFG_RETRYTESTEN_MASK 0x00001000U /**< Retry test */
|
||||
#define XEMACPS_NWCFG_XTADDMACHEN_MASK 0x00000200U
|
||||
/**< External address match enable */
|
||||
#define XEMACPS_NWCFG_PCSSEL_MASK 0x00000800U /**< PCS Select */
|
||||
#define XEMACPS_NWCFG_1000_MASK 0x00000400U /**< 1000 Mbps */
|
||||
#define XEMACPS_NWCFG_1536RXEN_MASK 0x00000100U /**< Enable 1536 byte
|
||||
frames reception */
|
||||
#define XEMACPS_NWCFG_UCASTHASHEN_MASK 0x00000080U /**< Receive unicast hash
|
||||
frames */
|
||||
#define XEMACPS_NWCFG_MCASTHASHEN_MASK 0x00000040U /**< Receive multicast hash
|
||||
frames */
|
||||
#define XEMACPS_NWCFG_BCASTDI_MASK 0x00000020U /**< Do not receive
|
||||
broadcast frames */
|
||||
#define XEMACPS_NWCFG_COPYALLEN_MASK 0x00000010U /**< Copy all frames */
|
||||
#define XEMACPS_NWCFG_JUMBO_MASK 0x00000008U /**< Jumbo frames */
|
||||
#define XEMACPS_NWCFG_NVLANDISC_MASK 0x00000004U /**< Receive only VLAN
|
||||
frames */
|
||||
#define XEMACPS_NWCFG_FDEN_MASK 0x00000002U/**< full duplex */
|
||||
#define XEMACPS_NWCFG_100_MASK 0x00000001U /**< 100 Mbps */
|
||||
#define XEMACPS_NWCFG_RESET_MASK 0x00080000U/**< reset value */
|
||||
/*@}*/
|
||||
|
||||
/** @name network status register bit definitaions
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_NWSR_MDIOIDLE_MASK 0x00000004U /**< PHY management idle */
|
||||
#define XEMACPS_NWSR_MDIO_MASK 0x00000002U /**< Status of mdio_in */
|
||||
/*@}*/
|
||||
|
||||
|
||||
/** @name MAC address register word 1 mask
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_LADDR_MACH_MASK 0x0000FFFFU /**< Address bits[47:32]
|
||||
bit[31:0] are in BOTTOM */
|
||||
/*@}*/
|
||||
|
||||
|
||||
/** @name DMA control register bit definitions
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_DMACR_ADDR_WIDTH_64 0x40000000U /**< 64 bit address bus */
|
||||
#define XEMACPS_DMACR_TXEXTEND_MASK 0x20000000U /**< Tx Extended desc mode */
|
||||
#define XEMACPS_DMACR_RXEXTEND_MASK 0x10000000U /**< Rx Extended desc mode */
|
||||
#define XEMACPS_DMACR_RXBUF_MASK 0x00FF0000U /**< Mask bit for RX buffer
|
||||
size */
|
||||
#define XEMACPS_DMACR_RXBUF_SHIFT 16U /**< Shift bit for RX buffer
|
||||
size */
|
||||
#define XEMACPS_DMACR_TCPCKSUM_MASK 0x00000800U /**< enable/disable TX
|
||||
checksum offload */
|
||||
#define XEMACPS_DMACR_TXSIZE_MASK 0x00000400U /**< TX buffer memory size */
|
||||
#define XEMACPS_DMACR_RXSIZE_MASK 0x00000300U /**< RX buffer memory size */
|
||||
#define XEMACPS_DMACR_ENDIAN_MASK 0x00000080U /**< endian configuration */
|
||||
#define XEMACPS_DMACR_BLENGTH_MASK 0x0000001FU /**< buffer burst length */
|
||||
#define XEMACPS_DMACR_SINGLE_AHB_BURST 0x00000001U /**< single AHB bursts */
|
||||
#define XEMACPS_DMACR_INCR4_AHB_BURST 0x00000004U /**< 4 bytes AHB bursts */
|
||||
#define XEMACPS_DMACR_INCR8_AHB_BURST 0x00000008U /**< 8 bytes AHB bursts */
|
||||
#define XEMACPS_DMACR_INCR16_AHB_BURST 0x00000010U /**< 16 bytes AHB bursts */
|
||||
/*@}*/
|
||||
|
||||
/** @name transmit status register bit definitions
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_TXSR_HRESPNOK_MASK 0x00000100U /**< Transmit hresp not OK */
|
||||
#define XEMACPS_TXSR_URUN_MASK 0x00000040U /**< Transmit underrun */
|
||||
#define XEMACPS_TXSR_TXCOMPL_MASK 0x00000020U /**< Transmit completed OK */
|
||||
#define XEMACPS_TXSR_BUFEXH_MASK 0x00000010U /**< Transmit buffs exhausted
|
||||
mid frame */
|
||||
#define XEMACPS_TXSR_TXGO_MASK 0x00000008U /**< Status of go flag */
|
||||
#define XEMACPS_TXSR_RXOVR_MASK 0x00000004U /**< Retry limit exceeded */
|
||||
#define XEMACPS_TXSR_FRAMERX_MASK 0x00000002U /**< Collision tx frame */
|
||||
#define XEMACPS_TXSR_USEDREAD_MASK 0x00000001U /**< TX buffer used bit set */
|
||||
|
||||
#define XEMACPS_TXSR_ERROR_MASK ((u32)XEMACPS_TXSR_HRESPNOK_MASK | \
|
||||
(u32)XEMACPS_TXSR_URUN_MASK | \
|
||||
(u32)XEMACPS_TXSR_BUFEXH_MASK | \
|
||||
(u32)XEMACPS_TXSR_RXOVR_MASK | \
|
||||
(u32)XEMACPS_TXSR_FRAMERX_MASK | \
|
||||
(u32)XEMACPS_TXSR_USEDREAD_MASK)
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* @name receive status register bit definitions
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_RXSR_HRESPNOK_MASK 0x00000008U /**< Receive hresp not OK */
|
||||
#define XEMACPS_RXSR_RXOVR_MASK 0x00000004U /**< Receive overrun */
|
||||
#define XEMACPS_RXSR_FRAMERX_MASK 0x00000002U /**< Frame received OK */
|
||||
#define XEMACPS_RXSR_BUFFNA_MASK 0x00000001U /**< RX buffer used bit set */
|
||||
|
||||
#define XEMACPS_RXSR_ERROR_MASK ((u32)XEMACPS_RXSR_HRESPNOK_MASK | \
|
||||
(u32)XEMACPS_RXSR_RXOVR_MASK | \
|
||||
(u32)XEMACPS_RXSR_BUFFNA_MASK)
|
||||
|
||||
#define XEMACPS_SR_ALL_MASK 0xFFFFFFFFU /**< Mask for full register */
|
||||
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* @name Interrupt Q1 status register bit definitions
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_INTQ1SR_TXCOMPL_MASK 0x00000080U /**< Transmit completed OK */
|
||||
#define XEMACPS_INTQ1SR_TXERR_MASK 0x00000040U /**< Transmit AMBA Error */
|
||||
|
||||
#define XEMACPS_INTQ1_IXR_ALL_MASK ((u32)XEMACPS_INTQ1SR_TXCOMPL_MASK | \
|
||||
(u32)XEMACPS_INTQ1SR_TXERR_MASK)
|
||||
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* @name interrupts bit definitions
|
||||
* Bits definitions are same in XEMACPS_ISR_OFFSET,
|
||||
* XEMACPS_IER_OFFSET, XEMACPS_IDR_OFFSET, and XEMACPS_IMR_OFFSET
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_IXR_PTPPSTX_MASK 0x02000000U /**< PTP Pdelay_resp TXed */
|
||||
#define XEMACPS_IXR_PTPPDRTX_MASK 0x01000000U /**< PTP Pdelay_req TXed */
|
||||
#define XEMACPS_IXR_PTPPSRX_MASK 0x00800000U /**< PTP Pdelay_resp RXed */
|
||||
#define XEMACPS_IXR_PTPPDRRX_MASK 0x00400000U /**< PTP Pdelay_req RXed */
|
||||
|
||||
#define XEMACPS_IXR_PTPSTX_MASK 0x00200000U /**< PTP Sync TXed */
|
||||
#define XEMACPS_IXR_PTPDRTX_MASK 0x00100000U /**< PTP Delay_req TXed */
|
||||
#define XEMACPS_IXR_PTPSRX_MASK 0x00080000U /**< PTP Sync RXed */
|
||||
#define XEMACPS_IXR_PTPDRRX_MASK 0x00040000U /**< PTP Delay_req RXed */
|
||||
|
||||
#define XEMACPS_IXR_PAUSETX_MASK 0x00004000U /**< Pause frame transmitted */
|
||||
#define XEMACPS_IXR_PAUSEZERO_MASK 0x00002000U /**< Pause time has reached
|
||||
zero */
|
||||
#define XEMACPS_IXR_PAUSENZERO_MASK 0x00001000U /**< Pause frame received */
|
||||
#define XEMACPS_IXR_HRESPNOK_MASK 0x00000800U /**< hresp not ok */
|
||||
#define XEMACPS_IXR_RXOVR_MASK 0x00000400U /**< Receive overrun occurred */
|
||||
#define XEMACPS_IXR_TXCOMPL_MASK 0x00000080U /**< Frame transmitted ok */
|
||||
#define XEMACPS_IXR_TXEXH_MASK 0x00000040U /**< Transmit err occurred or
|
||||
no buffers*/
|
||||
#define XEMACPS_IXR_RETRY_MASK 0x00000020U /**< Retry limit exceeded */
|
||||
#define XEMACPS_IXR_URUN_MASK 0x00000010U /**< Transmit underrun */
|
||||
#define XEMACPS_IXR_TXUSED_MASK 0x00000008U /**< Tx buffer used bit read */
|
||||
#define XEMACPS_IXR_RXUSED_MASK 0x00000004U /**< Rx buffer used bit read */
|
||||
#define XEMACPS_IXR_FRAMERX_MASK 0x00000002U /**< Frame received ok */
|
||||
#define XEMACPS_IXR_MGMNT_MASK 0x00000001U /**< PHY management complete */
|
||||
#define XEMACPS_IXR_ALL_MASK 0x00007FFFU /**< Everything! */
|
||||
|
||||
#define XEMACPS_IXR_TX_ERR_MASK ((u32)XEMACPS_IXR_TXEXH_MASK | \
|
||||
(u32)XEMACPS_IXR_RETRY_MASK | \
|
||||
(u32)XEMACPS_IXR_URUN_MASK)
|
||||
|
||||
|
||||
#define XEMACPS_IXR_RX_ERR_MASK ((u32)XEMACPS_IXR_HRESPNOK_MASK | \
|
||||
(u32)XEMACPS_IXR_RXUSED_MASK | \
|
||||
(u32)XEMACPS_IXR_RXOVR_MASK)
|
||||
|
||||
/*@}*/
|
||||
|
||||
/** @name PHY Maintenance bit definitions
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_PHYMNTNC_OP_MASK 0x40020000U /**< operation mask bits */
|
||||
#define XEMACPS_PHYMNTNC_OP_R_MASK 0x20000000U /**< read operation */
|
||||
#define XEMACPS_PHYMNTNC_OP_W_MASK 0x10000000U /**< write operation */
|
||||
#define XEMACPS_PHYMNTNC_ADDR_MASK 0x0F800000U /**< Address bits */
|
||||
#define XEMACPS_PHYMNTNC_REG_MASK 0x007C0000U /**< register bits */
|
||||
#define XEMACPS_PHYMNTNC_DATA_MASK 0x00000FFFU /**< data bits */
|
||||
#define XEMACPS_PHYMNTNC_PHAD_SHFT_MSK 23U /**< Shift bits for PHYAD */
|
||||
#define XEMACPS_PHYMNTNC_PREG_SHFT_MSK 18U /**< Shift bits for PHREG */
|
||||
/*@}*/
|
||||
|
||||
/** @name RX watermark bit definitions
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_RXWM_HIGH_MASK 0x0000FFFFU /**< RXWM high mask */
|
||||
#define XEMACPS_RXWM_LOW_MASK 0xFFFF0000U /**< RXWM low mask */
|
||||
#define XEMACPS_RXWM_LOW_SHFT_MSK 16U /**< Shift for RXWM low */
|
||||
/*@}*/
|
||||
|
||||
/* Transmit buffer descriptor status words offset
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_BD_ADDR_OFFSET 0x00000000U /**< word 0/addr of BDs */
|
||||
#define XEMACPS_BD_STAT_OFFSET 0x00000004U /**< word 1/status of BDs */
|
||||
#define XEMACPS_BD_ADDR_HI_OFFSET 0x00000008U /**< word 2/addr of BDs */
|
||||
|
||||
/*
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Transmit buffer descriptor status words bit positions.
|
||||
* Transmit buffer descriptor consists of two 32-bit registers,
|
||||
* the first - word0 contains a 32-bit address pointing to the location of
|
||||
* the transmit data.
|
||||
* The following register - word1, consists of various information to control
|
||||
* the XEmacPs transmit process. After transmit, this is updated with status
|
||||
* information, whether the frame was transmitted OK or why it had failed.
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_TXBUF_USED_MASK 0x80000000U /**< Used bit. */
|
||||
#define XEMACPS_TXBUF_WRAP_MASK 0x40000000U /**< Wrap bit, last descriptor */
|
||||
#define XEMACPS_TXBUF_RETRY_MASK 0x20000000U /**< Retry limit exceeded */
|
||||
#define XEMACPS_TXBUF_URUN_MASK 0x10000000U /**< Transmit underrun occurred */
|
||||
#define XEMACPS_TXBUF_EXH_MASK 0x08000000U /**< Buffers exhausted */
|
||||
#define XEMACPS_TXBUF_TCP_MASK 0x04000000U /**< Late collision. */
|
||||
#define XEMACPS_TXBUF_NOCRC_MASK 0x00010000U /**< No CRC */
|
||||
#define XEMACPS_TXBUF_LAST_MASK 0x00008000U /**< Last buffer */
|
||||
#define XEMACPS_TXBUF_LEN_MASK 0x00003FFFU /**< Mask for length field */
|
||||
/*
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Receive buffer descriptor status words bit positions.
|
||||
* Receive buffer descriptor consists of two 32-bit registers,
|
||||
* the first - word0 contains a 32-bit word aligned address pointing to the
|
||||
* address of the buffer. The lower two bits make up the wrap bit indicating
|
||||
* the last descriptor and the ownership bit to indicate it has been used by
|
||||
* the XEmacPs.
|
||||
* The following register - word1, contains status information regarding why
|
||||
* the frame was received (the filter match condition) as well as other
|
||||
* useful info.
|
||||
* @{
|
||||
*/
|
||||
#define XEMACPS_RXBUF_BCAST_MASK 0x80000000U /**< Broadcast frame */
|
||||
#define XEMACPS_RXBUF_MULTIHASH_MASK 0x40000000U /**< Multicast hashed frame */
|
||||
#define XEMACPS_RXBUF_UNIHASH_MASK 0x20000000U /**< Unicast hashed frame */
|
||||
#define XEMACPS_RXBUF_EXH_MASK 0x08000000U /**< buffer exhausted */
|
||||
#define XEMACPS_RXBUF_AMATCH_MASK 0x06000000U /**< Specific address
|
||||
matched */
|
||||
#define XEMACPS_RXBUF_IDFOUND_MASK 0x01000000U /**< Type ID matched */
|
||||
#define XEMACPS_RXBUF_IDMATCH_MASK 0x00C00000U /**< ID matched mask */
|
||||
#define XEMACPS_RXBUF_VLAN_MASK 0x00200000U /**< VLAN tagged */
|
||||
#define XEMACPS_RXBUF_PRI_MASK 0x00100000U /**< Priority tagged */
|
||||
#define XEMACPS_RXBUF_VPRI_MASK 0x000E0000U /**< Vlan priority */
|
||||
#define XEMACPS_RXBUF_CFI_MASK 0x00010000U /**< CFI frame */
|
||||
#define XEMACPS_RXBUF_EOF_MASK 0x00008000U /**< End of frame. */
|
||||
#define XEMACPS_RXBUF_SOF_MASK 0x00004000U /**< Start of frame. */
|
||||
#define XEMACPS_RXBUF_LEN_MASK 0x00001FFFU /**< Mask for length field */
|
||||
#define XEMACPS_RXBUF_LEN_JUMBO_MASK 0x00003FFFU /**< Mask for jumbo length */
|
||||
|
||||
#define XEMACPS_RXBUF_WRAP_MASK 0x00000002U /**< Wrap bit, last BD */
|
||||
#define XEMACPS_RXBUF_NEW_MASK 0x00000001U /**< Used bit.. */
|
||||
#define XEMACPS_RXBUF_ADD_MASK 0xFFFFFFFCU /**< Mask for address */
|
||||
/*
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*
|
||||
* Define appropriate I/O access method to memory mapped I/O or other
|
||||
* interface if necessary.
|
||||
*/
|
||||
|
||||
#define XEmacPs_In32 Xil_In32
|
||||
#define XEmacPs_Out32 Xil_Out32
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the given register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
* @param RegOffset is the register offset to be read
|
||||
*
|
||||
* @return The 32-bit value of the register
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* u32 XEmacPs_ReadReg(u32 BaseAddress, u32 RegOffset)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_ReadReg(BaseAddress, RegOffset) \
|
||||
XEmacPs_In32((BaseAddress) + (u32)(RegOffset))
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Write the given register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device
|
||||
* @param RegOffset is the register offset to be written
|
||||
* @param Data is the 32-bit value to write to the register
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XEmacPs_WriteReg(u32 BaseAddress, u32 RegOffset,
|
||||
* u32 Data)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XEmacPs_WriteReg(BaseAddress, RegOffset, Data) \
|
||||
XEmacPs_Out32((BaseAddress) + (u32)(RegOffset), (u32)(Data))
|
||||
|
||||
/************************** Function Prototypes *****************************/
|
||||
/*
|
||||
* Perform reset operation to the emacps interface
|
||||
*/
|
||||
void XEmacPs_ResetHw(u32 BaseAddr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
||||
/** @} */
|
|
@ -0,0 +1,242 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2010 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xemacps_intr.c
|
||||
* @addtogroup emacps_v3_11
|
||||
* @{
|
||||
*
|
||||
* Functions in this file implement general purpose interrupt processing related
|
||||
* functionality. See xemacps.h for a detailed description of the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.00a wsy 01/10/10 First release
|
||||
* 1.03a asa 01/24/13 Fix for CR #692702 which updates error handling for
|
||||
* Rx errors. Under heavy Rx traffic, there will be a large
|
||||
* number of errors related to receive buffer not available.
|
||||
* Because of a HW bug (SI #692601), under such heavy errors,
|
||||
* the Rx data path can become unresponsive. To reduce the
|
||||
* probabilities for hitting this HW bug, the SW writes to
|
||||
* bit 18 to flush a packet from Rx DPRAM immediately. The
|
||||
* changes for it are done in the function
|
||||
* XEmacPs_IntrHandler.
|
||||
* 2.1 srt 07/15/14 Add support for Zynq Ultrascale Mp GEM specification
|
||||
* and 64-bit changes.
|
||||
* 3.0 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
* 3.1 hk 07/27/15 Do not call error handler with '0' error code when
|
||||
* there is no error. CR# 869403
|
||||
* </pre>
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xemacps.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Install an asynchronous handler function for the given HandlerType:
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param HandlerType indicates what interrupt handler type is.
|
||||
* XEMACPS_HANDLER_DMASEND, XEMACPS_HANDLER_DMARECV and
|
||||
* XEMACPS_HANDLER_ERROR.
|
||||
* @param FuncPointer is the pointer to the callback function
|
||||
* @param CallBackRef is the upper layer callback reference passed back when
|
||||
* when the callback function is invoked.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* @note
|
||||
* There is no assert on the CallBackRef since the driver doesn't know what
|
||||
* it is.
|
||||
*
|
||||
*****************************************************************************/
|
||||
LONG XEmacPs_SetHandler(XEmacPs *InstancePtr, u32 HandlerType,
|
||||
void *FuncPointer, void *CallBackRef)
|
||||
{
|
||||
LONG Status;
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(FuncPointer != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
|
||||
|
||||
switch (HandlerType) {
|
||||
case XEMACPS_HANDLER_DMASEND:
|
||||
Status = (LONG)(XST_SUCCESS);
|
||||
InstancePtr->SendHandler = ((XEmacPs_Handler)(void *)FuncPointer);
|
||||
InstancePtr->SendRef = CallBackRef;
|
||||
break;
|
||||
case XEMACPS_HANDLER_DMARECV:
|
||||
Status = (LONG)(XST_SUCCESS);
|
||||
InstancePtr->RecvHandler = ((XEmacPs_Handler)(void *)FuncPointer);
|
||||
InstancePtr->RecvRef = CallBackRef;
|
||||
break;
|
||||
case XEMACPS_HANDLER_ERROR:
|
||||
Status = (LONG)(XST_SUCCESS);
|
||||
InstancePtr->ErrorHandler = ((XEmacPs_ErrHandler)(void *)FuncPointer);
|
||||
InstancePtr->ErrorRef = CallBackRef;
|
||||
break;
|
||||
default:
|
||||
Status = (LONG)(XST_INVALID_PARAM);
|
||||
break;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Master interrupt handler for EMAC driver. This routine will query the
|
||||
* status of the device, bump statistics, and invoke user callbacks.
|
||||
*
|
||||
* This routine must be connected to an interrupt controller using OS/BSP
|
||||
* specific methods.
|
||||
*
|
||||
* @param XEmacPsPtr is a pointer to the XEMACPS instance that has caused the
|
||||
* interrupt.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XEmacPs_IntrHandler(void *XEmacPsPtr)
|
||||
{
|
||||
u32 RegISR;
|
||||
u32 RegSR;
|
||||
u32 RegCtrl;
|
||||
u32 RegQ1ISR = 0U;
|
||||
XEmacPs *InstancePtr = (XEmacPs *) XEmacPsPtr;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
|
||||
|
||||
/* This ISR will try to handle as many interrupts as it can in a single
|
||||
* call. However, in most of the places where the user's error handler
|
||||
* is called, this ISR exits because it is expected that the user will
|
||||
* reset the device in nearly all instances.
|
||||
*/
|
||||
RegISR = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_ISR_OFFSET);
|
||||
|
||||
/* Read Transmit Q1 ISR */
|
||||
|
||||
if (InstancePtr->Version > 2)
|
||||
RegQ1ISR = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_INTQ1_STS_OFFSET);
|
||||
|
||||
/* Clear the interrupt status register */
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
|
||||
RegISR);
|
||||
|
||||
/* Receive complete interrupt */
|
||||
if ((RegISR & XEMACPS_IXR_FRAMERX_MASK) != 0x00000000U) {
|
||||
/* Clear RX status register RX complete indication but preserve
|
||||
* error bits if there is any */
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_RXSR_OFFSET,
|
||||
((u32)XEMACPS_RXSR_FRAMERX_MASK |
|
||||
(u32)XEMACPS_RXSR_BUFFNA_MASK));
|
||||
InstancePtr->RecvHandler(InstancePtr->RecvRef);
|
||||
}
|
||||
|
||||
/* Transmit Q1 complete interrupt */
|
||||
if ((InstancePtr->Version > 2) &&
|
||||
((RegQ1ISR & XEMACPS_INTQ1SR_TXCOMPL_MASK) != 0x00000000U)) {
|
||||
/* Clear TX status register TX complete indication but preserve
|
||||
* error bits if there is any */
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_INTQ1_STS_OFFSET,
|
||||
XEMACPS_INTQ1SR_TXCOMPL_MASK);
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_TXSR_OFFSET,
|
||||
((u32)XEMACPS_TXSR_TXCOMPL_MASK |
|
||||
(u32)XEMACPS_TXSR_USEDREAD_MASK));
|
||||
InstancePtr->SendHandler(InstancePtr->SendRef);
|
||||
}
|
||||
|
||||
/* Transmit complete interrupt */
|
||||
if ((RegISR & XEMACPS_IXR_TXCOMPL_MASK) != 0x00000000U) {
|
||||
/* Clear TX status register TX complete indication but preserve
|
||||
* error bits if there is any */
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_TXSR_OFFSET,
|
||||
((u32)XEMACPS_TXSR_TXCOMPL_MASK |
|
||||
(u32)XEMACPS_TXSR_USEDREAD_MASK));
|
||||
InstancePtr->SendHandler(InstancePtr->SendRef);
|
||||
}
|
||||
|
||||
/* Receive error conditions interrupt */
|
||||
if ((RegISR & XEMACPS_IXR_RX_ERR_MASK) != 0x00000000U) {
|
||||
/* Clear RX status register */
|
||||
RegSR = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_RXSR_OFFSET);
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_RXSR_OFFSET, RegSR);
|
||||
|
||||
/* Fix for CR # 692702. Write to bit 18 of net_ctrl
|
||||
* register to flush a packet out of Rx SRAM upon
|
||||
* an error for receive buffer not available. */
|
||||
if ((RegISR & XEMACPS_IXR_RXUSED_MASK) != 0x00000000U) {
|
||||
RegCtrl =
|
||||
XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
RegCtrl |= (u32)XEMACPS_NWCTRL_FLUSH_DPRAM_MASK;
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, RegCtrl);
|
||||
}
|
||||
|
||||
if(RegSR != 0) {
|
||||
InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
|
||||
XEMACPS_RECV, RegSR);
|
||||
}
|
||||
}
|
||||
|
||||
/* When XEMACPS_IXR_TXCOMPL_MASK is flagged, XEMACPS_IXR_TXUSED_MASK
|
||||
* will be asserted the same time.
|
||||
* Have to distinguish this bit to handle the real error condition.
|
||||
*/
|
||||
/* Transmit Q1 error conditions interrupt */
|
||||
if ((InstancePtr->Version > 2) &&
|
||||
((RegQ1ISR & XEMACPS_INTQ1SR_TXERR_MASK) != 0x00000000U) &&
|
||||
((RegQ1ISR & XEMACPS_INTQ1SR_TXCOMPL_MASK) != 0x00000000U)) {
|
||||
/* Clear Interrupt Q1 status register */
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_INTQ1_STS_OFFSET, RegQ1ISR);
|
||||
InstancePtr->ErrorHandler(InstancePtr->ErrorRef, XEMACPS_SEND,
|
||||
RegQ1ISR);
|
||||
}
|
||||
|
||||
/* Transmit error conditions interrupt */
|
||||
if (((RegISR & XEMACPS_IXR_TX_ERR_MASK) != 0x00000000U) &&
|
||||
(!(RegISR & XEMACPS_IXR_TXCOMPL_MASK) != 0x00000000U)) {
|
||||
/* Clear TX status register */
|
||||
RegSR = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_TXSR_OFFSET);
|
||||
XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
|
||||
XEMACPS_TXSR_OFFSET, RegSR);
|
||||
InstancePtr->ErrorHandler(InstancePtr->ErrorRef, XEMACPS_SEND,
|
||||
RegSR);
|
||||
}
|
||||
|
||||
}
|
||||
/** @} */
|
|
@ -0,0 +1,71 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) 2010 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xemacps_sinit.c
|
||||
* @addtogroup emacps_v3_11
|
||||
* @{
|
||||
*
|
||||
* This file contains lookup method by device ID when success, it returns
|
||||
* pointer to config table to be used to initialize the device.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.00a wsy 01/10/10 New
|
||||
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xemacps.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/*************************** Variable Definitions *****************************/
|
||||
extern XEmacPs_Config XEmacPs_ConfigTable[XPAR_XEMACPS_NUM_INSTANCES];
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Lookup the device configuration based on the unique device ID. The table
|
||||
* contains the configuration info for each device in the system.
|
||||
*
|
||||
* @param DeviceId is the unique device ID of the device being looked up.
|
||||
*
|
||||
* @return
|
||||
* A pointer to the configuration table entry corresponding to the given
|
||||
* device ID, or NULL if no match is found.
|
||||
*
|
||||
******************************************************************************/
|
||||
XEmacPs_Config *XEmacPs_LookupConfig(u16 DeviceId)
|
||||
{
|
||||
XEmacPs_Config *CfgPtr = NULL;
|
||||
u32 i;
|
||||
|
||||
for (i = 0U; i < (u32)XPAR_XEMACPS_NUM_INSTANCES; i++) {
|
||||
if (XEmacPs_ConfigTable[i].DeviceId == DeviceId) {
|
||||
CfgPtr = &XEmacPs_ConfigTable[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (XEmacPs_Config *)(CfgPtr);
|
||||
}
|
||||
/** @} */
|
|
@ -21,7 +21,7 @@ static inline void usleep(unsigned long useconds)
|
|||
|
||||
static inline void sleep(unsigned int seconds)
|
||||
{
|
||||
rt_thread_delay(seconds);
|
||||
rt_thread_delay(seconds*RT_TICK_PER_SECOND);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import rtconfig
|
||||
from building import *
|
||||
|
||||
# get current directory
|
||||
cwd = GetCurrentDir()
|
||||
CPPPATH = [cwd]
|
||||
|
||||
# The set of source files associated with this SConscript file.
|
||||
|
||||
src = Glob('*.c')
|
||||
path = cwd
|
||||
|
||||
group = DefineGroup('ZYNQMP_HAL', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (C) 2007 - 2019 Xilinx, Inc.
|
||||
* Copyright (C) 2021 WangHuachen.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XADAPTER_H_
|
||||
#define __XADAPTER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lwipopts.h"
|
||||
|
||||
#if !NO_SYS
|
||||
#ifdef OS_IS_XILKERNEL
|
||||
#include "xmk.h"
|
||||
#endif
|
||||
#include "lwip/sys.h"
|
||||
#endif
|
||||
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/ip.h"
|
||||
|
||||
#include "netif/xtopology.h"
|
||||
#include <netif/ethernetif.h>
|
||||
|
||||
struct xemac_s {
|
||||
enum xemac_types type;
|
||||
int topology_index;
|
||||
void *state;
|
||||
#if 0
|
||||
sys_sem_t sem_rx_data_available;
|
||||
#else
|
||||
struct eth_device *rt_eth_device;
|
||||
#endif
|
||||
#if defined(OS_IS_FREERTOS) && defined(__arm__) && !defined(ARMR5)
|
||||
TimerHandle_t xTimer;
|
||||
#endif
|
||||
};
|
||||
|
||||
enum ethernet_link_status {
|
||||
ETH_LINK_UNDEFINED = 0,
|
||||
ETH_LINK_UP,
|
||||
ETH_LINK_DOWN,
|
||||
ETH_LINK_NEGOTIATING
|
||||
};
|
||||
|
||||
void eth_link_detect(struct netif *netif);
|
||||
void lwip_raw_init();
|
||||
int xemacif_input(struct netif *netif);
|
||||
void xemacif_input_thread(struct netif *netif);
|
||||
struct netif * xemac_add(struct netif *netif,
|
||||
ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw,
|
||||
unsigned char *mac_ethernet_address,
|
||||
unsigned mac_baseaddr);
|
||||
#if defined (__arm__) || defined (__aarch64__)
|
||||
void xemacpsif_resetrx_on_no_rxdata(struct netif *netif);
|
||||
#endif
|
||||
|
||||
/* global lwip debug variable used for debugging */
|
||||
extern int lwip_runtime_debug;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* Copyright (C) 2010 - 2019 Xilinx, Inc.
|
||||
* Copyright (C) 2021 WangHuachen.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __NETIF_XEMACPSIF_H__
|
||||
#define __NETIF_XEMACPSIF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "xlwipconfig.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "netif/xadapter.h"
|
||||
|
||||
#include "xstatus.h"
|
||||
#include "sleep.h"
|
||||
#include "xparameters.h"
|
||||
#include "xparameters_ps.h" /* defines XPAR values */
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xil_io.h"
|
||||
// #include "xil_exception.h"
|
||||
// #include "xpseudo_asm.h"
|
||||
#include "xpseudo_asm_gcc.h"
|
||||
#include "xil_cache.h"
|
||||
#include "xil_printf.h"
|
||||
// #include "xscugic.h"
|
||||
#include "xemacps.h" /* defines XEmacPs API */
|
||||
|
||||
#include "netif/xpqueue.h"
|
||||
#include "xlwipconfig.h"
|
||||
|
||||
#if EL1_NONSECURE
|
||||
#include "xil_smc.h"
|
||||
#endif
|
||||
|
||||
#define ZYNQ_EMACPS_0_BASEADDR 0xE000B000
|
||||
#define ZYNQ_EMACPS_1_BASEADDR 0xE000C000
|
||||
|
||||
#define ZYNQMP_EMACPS_0_BASEADDR 0xFF0B0000
|
||||
#define ZYNQMP_EMACPS_1_BASEADDR 0xFF0C0000
|
||||
#define ZYNQMP_EMACPS_2_BASEADDR 0xFF0D0000
|
||||
#define ZYNQMP_EMACPS_3_BASEADDR 0xFF0E0000
|
||||
|
||||
#define CRL_APB_GEM0_REF_CTRL 0xFF5E0050
|
||||
#define CRL_APB_GEM1_REF_CTRL 0xFF5E0054
|
||||
#define CRL_APB_GEM2_REF_CTRL 0xFF5E0058
|
||||
#define CRL_APB_GEM3_REF_CTRL 0xFF5E005C
|
||||
|
||||
#define CRL_APB_GEM_DIV0_MASK 0x00003F00
|
||||
#define CRL_APB_GEM_DIV0_SHIFT 8
|
||||
#define CRL_APB_GEM_DIV1_MASK 0x003F0000
|
||||
#define CRL_APB_GEM_DIV1_SHIFT 16
|
||||
|
||||
#define VERSAL_EMACPS_0_BASEADDR 0xFF0C0000
|
||||
#define VERSAL_EMACPS_1_BASEADDR 0xFF0D0000
|
||||
|
||||
#define VERSAL_CRL_GEM0_REF_CTRL 0xFF5E0118
|
||||
#define VERSAL_CRL_GEM1_REF_CTRL 0xFF5E011C
|
||||
|
||||
#define VERSAL_CRL_GEM_DIV_MASK 0x0003FF00
|
||||
#define VERSAL_CRL_APB_GEM_DIV_SHIFT 8
|
||||
|
||||
#if defined (ARMR5) || (__aarch64__) || (ARMA53_32) || (__MICROBLAZE__)
|
||||
#if defined (USE_JUMBO_FRAMES)
|
||||
#define ZYNQMP_USE_JUMBO
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define GEM_VERSION_ZYNQMP 7
|
||||
#define GEM_VERSION_VERSAL 0x107
|
||||
|
||||
#define MAX_FRAME_SIZE_JUMBO (XEMACPS_MTU_JUMBO + XEMACPS_HDR_SIZE + XEMACPS_TRL_SIZE)
|
||||
|
||||
void xemacpsif_setmac(u32_t index, u8_t *addr);
|
||||
u8_t* xemacpsif_getmac(u32_t index);
|
||||
err_t xemacpsif_init(struct netif *netif);
|
||||
s32_t xemacpsif_input(struct netif *netif);
|
||||
|
||||
/* xaxiemacif_hw.c */
|
||||
void xemacps_error_handler(XEmacPs * Temac);
|
||||
|
||||
/* structure within each netif, encapsulating all information required for
|
||||
* using a particular temac instance
|
||||
*/
|
||||
typedef struct {
|
||||
XEmacPs emacps;
|
||||
|
||||
/* queue to store overflow packets */
|
||||
pq_queue_t *recv_q;
|
||||
pq_queue_t *send_q;
|
||||
|
||||
/* pointers to memory holding buffer descriptors (used only with SDMA) */
|
||||
void *rx_bdspace;
|
||||
void *tx_bdspace;
|
||||
|
||||
unsigned int last_rx_frms_cntr;
|
||||
|
||||
} xemacpsif_s;
|
||||
|
||||
extern xemacpsif_s xemacpsif;
|
||||
|
||||
s32_t is_tx_space_available(xemacpsif_s *emac);
|
||||
|
||||
/* xemacpsif_dma.c */
|
||||
|
||||
void process_sent_bds(xemacpsif_s *xemacpsif, XEmacPs_BdRing *txring);
|
||||
u32_t phy_setup_emacps (XEmacPs *xemacpsp, u32_t phy_addr);
|
||||
void detect_phy(XEmacPs *xemacpsp);
|
||||
void emacps_send_handler(void *arg);
|
||||
XStatus emacps_sgsend(xemacpsif_s *xemacpsif, struct pbuf *p);
|
||||
void emacps_recv_handler(void *arg);
|
||||
void emacps_error_handler(void *arg,u8 Direction, u32 ErrorWord);
|
||||
void setup_rx_bds(xemacpsif_s *xemacpsif, XEmacPs_BdRing *rxring);
|
||||
void HandleTxErrors(struct xemac_s *xemac);
|
||||
void HandleEmacPsError(struct xemac_s *xemac);
|
||||
XEmacPs_Config *xemacps_lookup_config(unsigned mac_base);
|
||||
void init_emacps(xemacpsif_s *xemacps, struct netif *netif);
|
||||
void setup_isr (struct xemac_s *xemac);
|
||||
XStatus init_dma(struct xemac_s *xemac);
|
||||
void start_emacps (xemacpsif_s *xemacps);
|
||||
void free_txrx_pbufs(xemacpsif_s *xemacpsif);
|
||||
void free_onlytx_pbufs(xemacpsif_s *xemacpsif);
|
||||
void init_emacps_on_error (xemacpsif_s *xemacps, struct netif *netif);
|
||||
void clean_dma_txdescs(struct xemac_s *xemac);
|
||||
void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif);
|
||||
void reset_dma(struct xemac_s *xemac);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __NETIF_XAXIEMACIF_H__ */
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (C) 2007 - 2019 Xilinx, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LWIP_PBUF_QUEUE_H_
|
||||
#define __LWIP_PBUF_QUEUE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PQ_QUEUE_SIZE 4096
|
||||
|
||||
typedef struct {
|
||||
void *data[PQ_QUEUE_SIZE];
|
||||
int head, tail, len;
|
||||
} pq_queue_t;
|
||||
|
||||
pq_queue_t* pq_create_queue();
|
||||
int pq_enqueue(pq_queue_t *q, void *p);
|
||||
void* pq_dequeue(pq_queue_t *q);
|
||||
int pq_qlength(pq_queue_t *q);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2007 - 2019 Xilinx, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XTOPOLOGY_H_
|
||||
#define __XTOPOLOGY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum xemac_types { xemac_type_unknown = -1, xemac_type_xps_emaclite, xemac_type_xps_ll_temac, xemac_type_axi_ethernet, xemac_type_emacps };
|
||||
|
||||
struct xtopology_t {
|
||||
unsigned emac_baseaddr;
|
||||
enum xemac_types emac_type;
|
||||
unsigned intc_baseaddr;
|
||||
unsigned intc_emac_intr; /* valid only for xemac_type_xps_emaclite */
|
||||
unsigned scugic_baseaddr; /* valid only for Zynq */
|
||||
unsigned scugic_emac_intr; /* valid only for GEM */
|
||||
};
|
||||
|
||||
extern int xtopology_n_emacs;
|
||||
extern struct xtopology_t xtopology[];
|
||||
|
||||
int xtopology_find_index(unsigned base);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,432 @@
|
|||
/*
|
||||
* Copyright (C) 2007 - 2019 Xilinx, Inc.
|
||||
* Copyright (C) 2021 WangHuachen.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwipopts.h"
|
||||
#include "xlwipconfig.h"
|
||||
#include "xemac_ieee_reg.h"
|
||||
|
||||
#if !NO_SYS
|
||||
#ifdef OS_IS_XILKERNEL
|
||||
#include "xmk.h"
|
||||
#include "sys/process.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/tcp.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/priv/tcp_priv.h"
|
||||
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/xadapter.h"
|
||||
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_EMACLITE
|
||||
#include "netif/xemacliteif.h"
|
||||
#endif
|
||||
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET
|
||||
#include "netif/xaxiemacif.h"
|
||||
#endif
|
||||
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_GEM
|
||||
#include "netif/xemacpsif.h"
|
||||
#endif
|
||||
|
||||
#if !NO_SYS
|
||||
#include "lwip/tcpip.h"
|
||||
#endif
|
||||
|
||||
#ifdef OS_IS_FREERTOS
|
||||
#define THREAD_STACKSIZE 256
|
||||
#define LINK_DETECT_THREAD_INTERVAL 1000 /* one second */
|
||||
|
||||
void link_detect_thread(void *p);
|
||||
#endif
|
||||
|
||||
/* global lwip debug variable used for debugging */
|
||||
int lwip_runtime_debug = 0;
|
||||
|
||||
enum ethernet_link_status eth_link_status = ETH_LINK_UNDEFINED;
|
||||
u32_t phyaddrforemac;
|
||||
|
||||
void
|
||||
lwip_raw_init()
|
||||
{
|
||||
ip_init(); /* Doesn't do much, it should be called to handle future changes. */
|
||||
#if LWIP_UDP
|
||||
udp_init(); /* Clears the UDP PCB list. */
|
||||
#endif
|
||||
#if LWIP_TCP
|
||||
tcp_init(); /* Clears the TCP PCB list and clears some internal TCP timers. */
|
||||
/* Note: you must call tcp_fasttmr() and tcp_slowtmr() at the */
|
||||
/* predefined regular intervals after this initialization. */
|
||||
#endif
|
||||
}
|
||||
|
||||
static enum xemac_types
|
||||
find_mac_type(unsigned base)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < xtopology_n_emacs; i++) {
|
||||
if (xtopology[i].emac_baseaddr == base)
|
||||
return xtopology[i].emac_type;
|
||||
}
|
||||
|
||||
return xemac_type_unknown;
|
||||
}
|
||||
|
||||
int
|
||||
xtopology_find_index(unsigned base)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < xtopology_n_emacs; i++) {
|
||||
if (xtopology[i].emac_baseaddr == base)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* xemac_add: this is a wrapper around lwIP's netif_add function.
|
||||
* The objective is to provide portability between the different Xilinx MAC's
|
||||
* This function can be used to add both xps_ethernetlite and xps_ll_temac
|
||||
* based interfaces
|
||||
*/
|
||||
struct netif *
|
||||
xemac_add(struct netif *netif,
|
||||
ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw,
|
||||
unsigned char *mac_ethernet_address,
|
||||
unsigned mac_baseaddr)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef OS_IS_FREERTOS
|
||||
/* Start thread to detect link periodically for Hot Plug autodetect */
|
||||
sys_thread_new("link_detect_thread", link_detect_thread, netif,
|
||||
THREAD_STACKSIZE, tskIDLE_PRIORITY);
|
||||
#endif
|
||||
|
||||
/* set mac address */
|
||||
netif->hwaddr_len = 6;
|
||||
for (i = 0; i < 6; i++)
|
||||
netif->hwaddr[i] = mac_ethernet_address[i];
|
||||
|
||||
/* initialize based on MAC type */
|
||||
switch (find_mac_type(mac_baseaddr)) {
|
||||
case xemac_type_xps_emaclite:
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_EMACLITE
|
||||
return netif_add(netif, ipaddr, netmask, gw,
|
||||
(void*)(UINTPTR)mac_baseaddr,
|
||||
xemacliteif_init,
|
||||
#if NO_SYS
|
||||
ethernet_input
|
||||
#else
|
||||
tcpip_input
|
||||
#endif
|
||||
);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
case xemac_type_axi_ethernet:
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET
|
||||
return netif_add(netif, ipaddr, netmask, gw,
|
||||
(void*)(UINTPTR)mac_baseaddr,
|
||||
xaxiemacif_init,
|
||||
#if NO_SYS
|
||||
ethernet_input
|
||||
#else
|
||||
tcpip_input
|
||||
#endif
|
||||
);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
#if defined (__arm__) || defined (__aarch64__)
|
||||
case xemac_type_emacps:
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_GEM
|
||||
return netif_add(netif, ipaddr, netmask, gw,
|
||||
(void*)(UINTPTR)mac_baseaddr,
|
||||
xemacpsif_init,
|
||||
#if NO_SYS
|
||||
ethernet_input
|
||||
#else
|
||||
tcpip_input
|
||||
#endif
|
||||
|
||||
);
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
xil_printf("unable to determine type of EMAC with baseaddress 0x%08x\r\n",
|
||||
mac_baseaddr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* The input thread calls lwIP to process any received packets.
|
||||
* This thread waits until a packet is received (sem_rx_data_available),
|
||||
* and then calls xemacif_input which processes 1 packet at a time.
|
||||
*/
|
||||
void
|
||||
xemacif_input_thread(struct netif *netif)
|
||||
{
|
||||
struct xemac_s *emac = (struct xemac_s *)netif->state;
|
||||
while (1) {
|
||||
/* sleep until there are packets to process
|
||||
* This semaphore is set by the packet receive interrupt
|
||||
* routine.
|
||||
*/
|
||||
sys_sem_wait(&emac->sem_rx_data_available);
|
||||
|
||||
/* move all received packets to lwIP */
|
||||
xemacif_input(netif);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
xemacif_input(struct netif *netif)
|
||||
{
|
||||
struct xemac_s *emac = (struct xemac_s *)netif->state;
|
||||
|
||||
int n_packets = 0;
|
||||
|
||||
switch (emac->type) {
|
||||
case xemac_type_xps_emaclite:
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_EMACLITE
|
||||
n_packets = xemacliteif_input(netif);
|
||||
break;
|
||||
#else
|
||||
// print("incorrect configuration: xps_ethernetlite drivers not present?");
|
||||
while(1);
|
||||
return 0;
|
||||
#endif
|
||||
case xemac_type_axi_ethernet:
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_AXI_ETHERNET
|
||||
n_packets = xaxiemacif_input(netif);
|
||||
break;
|
||||
#else
|
||||
// print("incorrect configuration: axi_ethernet drivers not present?");
|
||||
while(1);
|
||||
return 0;
|
||||
#endif
|
||||
#if defined (__arm__) || defined (__aarch64__)
|
||||
case xemac_type_emacps:
|
||||
#ifdef XLWIP_CONFIG_INCLUDE_GEM
|
||||
n_packets = xemacpsif_input(netif);
|
||||
break;
|
||||
#else
|
||||
xil_printf("incorrect configuration: ps7_ethernet drivers not present?\r\n");
|
||||
while(1);
|
||||
return 0;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
// print("incorrect configuration: unknown temac type");
|
||||
while(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return n_packets;
|
||||
}
|
||||
|
||||
#if defined(XLWIP_CONFIG_INCLUDE_GEM)
|
||||
u32_t phy_link_detect(XEmacPs *xemacp, u32_t phy_addr)
|
||||
{
|
||||
u16_t status;
|
||||
|
||||
/* Read Phy Status register twice to get the confirmation of the current
|
||||
* link status.
|
||||
*/
|
||||
XEmacPs_PhyRead(xemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
|
||||
XEmacPs_PhyRead(xemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
|
||||
|
||||
if (status & IEEE_STAT_LINK_STATUS)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#elif defined(XLWIP_CONFIG_INCLUDE_AXI_ETHERNET)
|
||||
static u32_t phy_link_detect(XAxiEthernet *xemacp, u32_t phy_addr)
|
||||
{
|
||||
u16_t status;
|
||||
|
||||
/* Read Phy Status register twice to get the confirmation of the current
|
||||
* link status.
|
||||
*/
|
||||
XAxiEthernet_PhyRead(xemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
|
||||
XAxiEthernet_PhyRead(xemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
|
||||
|
||||
if (status & IEEE_STAT_LINK_STATUS)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#elif defined(XLWIP_CONFIG_INCLUDE_EMACLITE)
|
||||
static u32_t phy_link_detect(XEmacLite *xemacp, u32_t phy_addr)
|
||||
{
|
||||
u16_t status;
|
||||
|
||||
/* Read Phy Status register twice to get the confirmation of the current
|
||||
* link status.
|
||||
*/
|
||||
XEmacLite_PhyRead(xemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
|
||||
XEmacLite_PhyRead(xemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
|
||||
|
||||
if (status & IEEE_STAT_LINK_STATUS)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(XLWIP_CONFIG_INCLUDE_GEM)
|
||||
u32_t phy_autoneg_status(XEmacPs *xemacp, u32_t phy_addr)
|
||||
{
|
||||
u16_t status;
|
||||
|
||||
/* Read Phy Status register twice to get the confirmation of the current
|
||||
* link status.
|
||||
*/
|
||||
XEmacPs_PhyRead(xemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
|
||||
XEmacPs_PhyRead(xemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
|
||||
|
||||
if (status & IEEE_STAT_AUTONEGOTIATE_COMPLETE)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#elif defined(XLWIP_CONFIG_INCLUDE_AXI_ETHERNET)
|
||||
static u32_t phy_autoneg_status(XAxiEthernet *xemacp, u32_t phy_addr)
|
||||
{
|
||||
u16_t status;
|
||||
|
||||
/* Read Phy Status register twice to get the confirmation of the current
|
||||
* link status.
|
||||
*/
|
||||
XAxiEthernet_PhyRead(xemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
|
||||
XAxiEthernet_PhyRead(xemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
|
||||
|
||||
if (status & IEEE_STAT_AUTONEGOTIATE_COMPLETE)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#elif defined(XLWIP_CONFIG_INCLUDE_EMACLITE)
|
||||
static u32_t phy_autoneg_status(XEmacLite *xemacp, u32_t phy_addr)
|
||||
{
|
||||
u16_t status;
|
||||
|
||||
/* Read Phy Status register twice to get the confirmation of the current
|
||||
* link status.
|
||||
*/
|
||||
XEmacLite_PhyRead(xemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
|
||||
XEmacLite_PhyRead(xemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
|
||||
|
||||
if (status & IEEE_STAT_AUTONEGOTIATE_COMPLETE)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void eth_link_detect(struct netif *netif)
|
||||
{
|
||||
u32_t link_speed, phy_link_status;
|
||||
struct xemac_s *xemac = (struct xemac_s *)(netif->state);
|
||||
|
||||
#if defined(XLWIP_CONFIG_INCLUDE_GEM)
|
||||
xemacpsif_s *xemacs = (xemacpsif_s *)(xemac->state);
|
||||
XEmacPs *xemacp = &xemacs->emacps;
|
||||
#elif defined(XLWIP_CONFIG_INCLUDE_AXI_ETHERNET)
|
||||
xaxiemacif_s *xemacs = (xaxiemacif_s *)(xemac->state);
|
||||
XAxiEthernet *xemacp = &xemacs->axi_ethernet;
|
||||
#elif defined(XLWIP_CONFIG_INCLUDE_EMACLITE)
|
||||
xemacliteif_s *xemacs = (xemacliteif_s *)(xemac->state);
|
||||
XEmacLite *xemacp = xemacs->instance;
|
||||
#endif
|
||||
|
||||
if ((xemacp->IsReady != (u32)XIL_COMPONENT_IS_READY) ||
|
||||
(eth_link_status == ETH_LINK_UNDEFINED))
|
||||
return;
|
||||
|
||||
phy_link_status = phy_link_detect(xemacp, phyaddrforemac);
|
||||
|
||||
if ((eth_link_status == ETH_LINK_UP) && (!phy_link_status))
|
||||
eth_link_status = ETH_LINK_DOWN;
|
||||
|
||||
switch (eth_link_status) {
|
||||
case ETH_LINK_UNDEFINED:
|
||||
case ETH_LINK_UP:
|
||||
return;
|
||||
case ETH_LINK_DOWN:
|
||||
netif_set_link_down(netif);
|
||||
eth_link_status = ETH_LINK_NEGOTIATING;
|
||||
xil_printf("Ethernet Link down\r\n");
|
||||
break;
|
||||
case ETH_LINK_NEGOTIATING:
|
||||
if (phy_link_status &&
|
||||
phy_autoneg_status(xemacp, phyaddrforemac)) {
|
||||
|
||||
/* Initiate Phy setup to get link speed */
|
||||
#if defined(XLWIP_CONFIG_INCLUDE_GEM)
|
||||
link_speed = phy_setup_emacps(xemacp,
|
||||
phyaddrforemac);
|
||||
XEmacPs_SetOperatingSpeed(xemacp, link_speed);
|
||||
#elif defined(XLWIP_CONFIG_INCLUDE_AXI_ETHERNET)
|
||||
link_speed = phy_setup_axiemac(xemacp);
|
||||
XAxiEthernet_SetOperatingSpeed(xemacp,
|
||||
link_speed);
|
||||
#endif
|
||||
netif_set_link_up(netif);
|
||||
eth_link_status = ETH_LINK_UP;
|
||||
xil_printf("Ethernet Link up\r\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OS_IS_FREERTOS
|
||||
void link_detect_thread(void *p)
|
||||
{
|
||||
struct netif *netif = (struct netif *) p;
|
||||
|
||||
while (1) {
|
||||
/* Call eth_link_detect() every second to detect Ethernet link
|
||||
* change.
|
||||
*/
|
||||
eth_link_detect(netif);
|
||||
vTaskDelay(LINK_DETECT_THREAD_INTERVAL / portTICK_RATE_MS);
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (C) 2018 - 2019 Xilinx, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XEMAC_IEEE_REGS_H_
|
||||
#define __XEMAC_IEEE_REGS_H_
|
||||
|
||||
/* Advertisement control register. */
|
||||
#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
|
||||
#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
|
||||
#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
|
||||
#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
|
||||
#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
|
||||
#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
|
||||
#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
|
||||
#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
|
||||
#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
|
||||
|
||||
|
||||
#define ADVERTISE_100_AND_10 (ADVERTISE_10FULL | ADVERTISE_100FULL | \
|
||||
ADVERTISE_10HALF | ADVERTISE_100HALF)
|
||||
#define ADVERTISE_100 (ADVERTISE_100FULL | ADVERTISE_100HALF)
|
||||
#define ADVERTISE_10 (ADVERTISE_10FULL | ADVERTISE_10HALF)
|
||||
|
||||
#define ADVERTISE_1000 0x0300
|
||||
|
||||
|
||||
#define IEEE_CONTROL_REG_OFFSET 0
|
||||
#define IEEE_STATUS_REG_OFFSET 1
|
||||
#define IEEE_AUTONEGO_ADVERTISE_REG 4
|
||||
#define IEEE_PARTNER_ABILITIES_1_REG_OFFSET 5
|
||||
#define IEEE_PARTNER_ABILITIES_2_REG_OFFSET 8
|
||||
#define IEEE_PARTNER_ABILITIES_3_REG_OFFSET 10
|
||||
#define IEEE_1000_ADVERTISE_REG_OFFSET 9
|
||||
#define IEEE_MMD_ACCESS_CONTROL_REG 13
|
||||
#define IEEE_MMD_ACCESS_ADDRESS_DATA_REG 14
|
||||
#define IEEE_COPPER_SPECIFIC_CONTROL_REG 16
|
||||
#define IEEE_SPECIFIC_STATUS_REG 17
|
||||
#define IEEE_COPPER_SPECIFIC_STATUS_REG_2 19
|
||||
#define IEEE_EXT_PHY_SPECIFIC_CONTROL_REG 20
|
||||
#define IEEE_CONTROL_REG_MAC 21
|
||||
#define IEEE_PAGE_ADDRESS_REGISTER 22
|
||||
|
||||
#define IEEE_CTRL_1GBPS_LINKSPEED_MASK 0x2040
|
||||
#define IEEE_CTRL_LINKSPEED_MASK 0x0040
|
||||
#define IEEE_CTRL_LINKSPEED_1000M 0x0040
|
||||
#define IEEE_CTRL_LINKSPEED_100M 0x2000
|
||||
#define IEEE_CTRL_LINKSPEED_10M 0x0000
|
||||
#define IEEE_CTRL_FULL_DUPLEX 0x100
|
||||
#define IEEE_CTRL_RESET_MASK 0x8000
|
||||
#define IEEE_CTRL_AUTONEGOTIATE_ENABLE 0x1000
|
||||
#define IEEE_STAT_AUTONEGOTIATE_CAPABLE 0x0008
|
||||
#define IEEE_STAT_AUTONEGOTIATE_COMPLETE 0x0020
|
||||
#define IEEE_STAT_AUTONEGOTIATE_RESTART 0x0200
|
||||
#define IEEE_STAT_LINK_STATUS 0x0004
|
||||
#define IEEE_STAT_1GBPS_EXTENSIONS 0x0100
|
||||
#define IEEE_AN1_ABILITY_MASK 0x1FE0
|
||||
#define IEEE_AN3_ABILITY_MASK_1GBPS 0x0C00
|
||||
#define IEEE_AN1_ABILITY_MASK_100MBPS 0x0380
|
||||
#define IEEE_AN1_ABILITY_MASK_10MBPS 0x0060
|
||||
#define IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK 0x0030
|
||||
|
||||
#define IEEE_SPEED_MASK 0xC000
|
||||
#define IEEE_SPEED_1000 0x8000
|
||||
#define IEEE_SPEED_100 0x4000
|
||||
|
||||
#define IEEE_ASYMMETRIC_PAUSE_MASK 0x0800
|
||||
#define IEEE_PAUSE_MASK 0x0400
|
||||
#define IEEE_AUTONEG_ERROR_MASK 0x8000
|
||||
|
||||
#define IEEE_MMD_ACCESS_CTRL_DEVAD_MASK 0x1F
|
||||
#define IEEE_MMD_ACCESS_CTRL_PIDEVAD_MASK 0x801F
|
||||
#define IEEE_MMD_ACCESS_CTRL_NOPIDEVAD_MASK 0x401F
|
||||
|
||||
#endif /* __XEMAC_IEEE_REGS_H_ */
|
|
@ -0,0 +1,759 @@
|
|||
/*
|
||||
* Copyright (C) 2010 - 2019 Xilinx, Inc.
|
||||
* Copyright (C) 2021 WangHuachen.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <xparameters.h>
|
||||
#include "lwipopts.h"
|
||||
#include "xlwipconfig.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/igmp.h"
|
||||
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/xemacpsif.h"
|
||||
#include "netif/xadapter.h"
|
||||
#include "netif/xpqueue.h"
|
||||
#include "xparameters.h"
|
||||
// #include "xscugic.h"
|
||||
#include "xemacps.h"
|
||||
|
||||
#if LWIP_IPV6
|
||||
#include "lwip/ethip6.h"
|
||||
#endif
|
||||
|
||||
#ifdef SYS_ARCH_DECL_PROTECT
|
||||
#undef SYS_ARCH_DECL_PROTECT
|
||||
#endif
|
||||
#define SYS_ARCH_DECL_PROTECT(lev) rt_base_t lev;
|
||||
|
||||
#ifdef SYS_ARCH_PROTECT
|
||||
#undef SYS_ARCH_PROTECT
|
||||
#endif
|
||||
#define SYS_ARCH_PROTECT(lev) lev = rt_hw_interrupt_disable();
|
||||
|
||||
#ifdef SYS_ARCH_UNPROTECT
|
||||
#undef SYS_ARCH_UNPROTECT
|
||||
#endif
|
||||
#define SYS_ARCH_UNPROTECT(lev) rt_hw_interrupt_enable(lev);
|
||||
|
||||
/* Define those to better describe your network interface. */
|
||||
#define IFNAME0 't'
|
||||
#define IFNAME1 'e'
|
||||
|
||||
#if LWIP_IGMP
|
||||
static err_t xemacpsif_mac_filter_update (struct netif *netif,
|
||||
ip_addr_t *group, u8_t action);
|
||||
|
||||
static u8_t xemacps_mcast_entry_mask = 0;
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
static err_t xemacpsif_mld6_mac_filter_update (struct netif *netif,
|
||||
ip_addr_t *group, u8_t action);
|
||||
|
||||
static u8_t xemacps_mld6_mcast_entry_mask;
|
||||
#endif
|
||||
|
||||
XEmacPs_Config *mac_config;
|
||||
struct netif *NetIf;
|
||||
|
||||
#if defined(OS_IS_FREERTOS) && defined(__arm__) && !defined(ARMR5)
|
||||
int32_t lExpireCounter = 0;
|
||||
#define RESETRXTIMEOUT 10
|
||||
#endif
|
||||
|
||||
/*
|
||||
* this function is always called with interrupts off
|
||||
* this function also assumes that there are available BD's
|
||||
*/
|
||||
err_t _unbuffered_low_level_output(xemacpsif_s *xemacpsif,
|
||||
struct pbuf *p)
|
||||
{
|
||||
XStatus status = 0;
|
||||
|
||||
#if ETH_PAD_SIZE
|
||||
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
|
||||
#endif
|
||||
status = emacps_sgsend(xemacpsif, p);
|
||||
if (status != XST_SUCCESS) {
|
||||
#if LINK_STATS
|
||||
lwip_stats.link.drop++;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ETH_PAD_SIZE
|
||||
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
||||
#endif
|
||||
|
||||
#if LINK_STATS
|
||||
lwip_stats.link.xmit++;
|
||||
#endif /* LINK_STATS */
|
||||
|
||||
return ERR_OK;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* low_level_output():
|
||||
*
|
||||
* Should do the actual transmission of the packet. The packet is
|
||||
* contained in the pbuf that is passed to the function. This pbuf
|
||||
* might be chained.
|
||||
*
|
||||
*/
|
||||
|
||||
static err_t low_level_output(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
err_t err;
|
||||
s32_t freecnt;
|
||||
XEmacPs_BdRing *txring;
|
||||
|
||||
struct xemac_s *xemac = (struct xemac_s *)(netif->state);
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
|
||||
/* check if space is available to send */
|
||||
freecnt = is_tx_space_available(xemacpsif);
|
||||
if (freecnt <= 5) {
|
||||
txring = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
|
||||
process_sent_bds(xemacpsif, txring);
|
||||
}
|
||||
|
||||
if (is_tx_space_available(xemacpsif)) {
|
||||
_unbuffered_low_level_output(xemacpsif, p);
|
||||
err = ERR_OK;
|
||||
} else {
|
||||
#if LINK_STATS
|
||||
lwip_stats.link.drop++;
|
||||
#endif
|
||||
rt_kprintf("pack dropped, no space\r\n");
|
||||
err = ERR_MEM;
|
||||
}
|
||||
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* low_level_input():
|
||||
*
|
||||
* Should allocate a pbuf and transfer the bytes of the incoming
|
||||
* packet from the interface into the pbuf.
|
||||
*
|
||||
*/
|
||||
static struct pbuf * low_level_input(struct netif *netif)
|
||||
{
|
||||
struct xemac_s *xemac = (struct xemac_s *)(netif->state);
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
struct pbuf *p;
|
||||
|
||||
/* see if there is data to process */
|
||||
if (pq_qlength(xemacpsif->recv_q) == 0)
|
||||
return NULL;
|
||||
|
||||
/* return one packet from receive q */
|
||||
p = (struct pbuf *)pq_dequeue(xemacpsif->recv_q);
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* xemacpsif_output():
|
||||
*
|
||||
* This function is called by the TCP/IP stack when an IP packet
|
||||
* should be sent. It calls the function called low_level_output() to
|
||||
* do the actual transmission of the packet.
|
||||
*
|
||||
*/
|
||||
|
||||
static err_t xemacpsif_output(struct netif *netif, struct pbuf *p,
|
||||
const ip_addr_t *ipaddr)
|
||||
{
|
||||
/* resolve hardware address, then send (or queue) packet */
|
||||
return etharp_output(netif, p, ipaddr);
|
||||
}
|
||||
|
||||
/*
|
||||
* xemacpsif_input():
|
||||
*
|
||||
* This function should be called when a packet is ready to be read
|
||||
* from the interface. It uses the function low_level_input() that
|
||||
* should handle the actual reception of bytes from the network
|
||||
* interface.
|
||||
*
|
||||
* Returns the number of packets read (max 1 packet on success,
|
||||
* 0 if there are no packets)
|
||||
*
|
||||
*/
|
||||
|
||||
s32_t xemacpsif_input(struct netif *netif)
|
||||
{
|
||||
struct eth_hdr *ethhdr;
|
||||
struct pbuf *p;
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
|
||||
#ifdef OS_IS_FREERTOS
|
||||
while (1)
|
||||
#endif
|
||||
{
|
||||
/* move received packet into a new pbuf */
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
p = low_level_input(netif);
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
||||
/* no packet could be read, silently ignore this */
|
||||
if (p == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* points to packet payload, which starts with an Ethernet header */
|
||||
ethhdr = p->payload;
|
||||
|
||||
#if LINK_STATS
|
||||
lwip_stats.link.recv++;
|
||||
#endif /* LINK_STATS */
|
||||
|
||||
switch (htons(ethhdr->type)) {
|
||||
/* IP or ARP packet? */
|
||||
case ETHTYPE_IP:
|
||||
case ETHTYPE_ARP:
|
||||
#if LWIP_IPV6
|
||||
/*IPv6 Packet?*/
|
||||
case ETHTYPE_IPV6:
|
||||
#endif
|
||||
#if PPPOE_SUPPORT
|
||||
/* PPPoE packet? */
|
||||
case ETHTYPE_PPPOEDISC:
|
||||
case ETHTYPE_PPPOE:
|
||||
#endif /* PPPOE_SUPPORT */
|
||||
/* full packet send to tcpip_thread to process */
|
||||
if (netif->input(p, netif) != ERR_OK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("xemacpsif_input: IP input error\r\n"));
|
||||
pbuf_free(p);
|
||||
p = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
pbuf_free(p);
|
||||
p = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#if defined(OS_IS_FREERTOS) && defined(__arm__) && !defined(ARMR5)
|
||||
void vTimerCallback( TimerHandle_t pxTimer )
|
||||
{
|
||||
/* Do something if the pxTimer parameter is NULL */
|
||||
configASSERT(pxTimer);
|
||||
|
||||
lExpireCounter++;
|
||||
/* If the timer has expired 100 times then reset RX */
|
||||
if(lExpireCounter >= RESETRXTIMEOUT) {
|
||||
lExpireCounter = 0;
|
||||
xemacpsif_resetrx_on_no_rxdata(NetIf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static err_t low_level_init(struct netif *netif)
|
||||
{
|
||||
UINTPTR mac_address = (UINTPTR)(netif->state);
|
||||
struct xemac_s *xemac;
|
||||
xemacpsif_s *xemacpsif;
|
||||
u32 dmacrreg;
|
||||
|
||||
s32_t status = XST_SUCCESS;
|
||||
|
||||
NetIf = netif;
|
||||
|
||||
xemacpsif = mem_malloc(sizeof *xemacpsif);
|
||||
if (xemacpsif == NULL) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("xemacpsif_init: out of memory\r\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
xemac = mem_malloc(sizeof *xemac);
|
||||
if (xemac == NULL) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("xemacpsif_init: out of memory\r\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
xemac->state = (void *)xemacpsif;
|
||||
xemac->topology_index = xtopology_find_index(mac_address);
|
||||
xemac->type = xemac_type_emacps;
|
||||
|
||||
xemacpsif->send_q = NULL;
|
||||
xemacpsif->recv_q = pq_create_queue();
|
||||
if (!xemacpsif->recv_q)
|
||||
return ERR_MEM;
|
||||
|
||||
/* maximum transfer unit */
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
netif->mtu = XEMACPS_MTU_JUMBO - XEMACPS_HDR_SIZE;
|
||||
#else
|
||||
netif->mtu = XEMACPS_MTU - XEMACPS_HDR_SIZE;
|
||||
#endif
|
||||
|
||||
#if LWIP_IGMP
|
||||
netif->igmp_mac_filter = xemacpsif_mac_filter_update;
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
netif->mld_mac_filter = xemacpsif_mld6_mac_filter_update;
|
||||
#endif
|
||||
|
||||
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP |
|
||||
NETIF_FLAG_LINK_UP;
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
netif->flags |= NETIF_FLAG_MLD6;
|
||||
#endif
|
||||
|
||||
#if LWIP_IGMP
|
||||
netif->flags |= NETIF_FLAG_IGMP;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
sys_sem_new(&xemac->sem_rx_data_available, 0);
|
||||
#endif
|
||||
/* obtain config of this emac */
|
||||
mac_config = (XEmacPs_Config *)xemacps_lookup_config((unsigned)(UINTPTR)netif->state);
|
||||
|
||||
#if EL1_NONSECURE
|
||||
/* Request device to indicate that this library is using it */
|
||||
if (mac_config->BaseAddress == VERSAL_EMACPS_0_BASEADDR) {
|
||||
Xil_Smc(PM_REQUEST_DEVICE_SMC_FID, DEV_GEM_0, 1, 0, 100, 1, 0, 0);
|
||||
}
|
||||
if (mac_config->BaseAddress == VERSAL_EMACPS_0_BASEADDR) {
|
||||
Xil_Smc(PM_REQUEST_DEVICE_SMC_FID, DEV_GEM_1, 1, 0, 100, 1, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
status = XEmacPs_CfgInitialize(&xemacpsif->emacps, mac_config,
|
||||
mac_config->BaseAddress);
|
||||
if (status != XST_SUCCESS) {
|
||||
xil_printf("In %s:EmacPs Configuration Failed....\r\n", __func__);
|
||||
}
|
||||
|
||||
/* initialize the mac */
|
||||
init_emacps(xemacpsif, netif);
|
||||
|
||||
dmacrreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_DMACR_OFFSET);
|
||||
dmacrreg = dmacrreg | (0x00000010);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_DMACR_OFFSET, dmacrreg);
|
||||
|
||||
#if defined(OS_IS_FREERTOS) && defined(__arm__) && !defined(ARMR5)
|
||||
/* Freertos tick is 10ms by default; set period to the same */
|
||||
xemac->xTimer = xTimerCreate("Timer", 10, pdTRUE, ( void * ) 1, vTimerCallback);
|
||||
if (xemac->xTimer == NULL) {
|
||||
xil_printf("In %s:Timer creation failed....\r\n", __func__);
|
||||
} else {
|
||||
if(xTimerStart(xemac->xTimer, 0) != pdPASS) {
|
||||
xil_printf("In %s:Timer start failed....\r\n", __func__);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
setup_isr(xemac);
|
||||
init_dma(xemac);
|
||||
start_emacps(xemacpsif);
|
||||
|
||||
/* replace the state in netif (currently the emac baseaddress)
|
||||
* with the mac instance pointer.
|
||||
*/
|
||||
netif->state = (void *)xemac;
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void HandleEmacPsError(struct xemac_s *xemac)
|
||||
{
|
||||
xemacpsif_s *xemacpsif;
|
||||
s32_t status = XST_SUCCESS;
|
||||
u32 dmacrreg;
|
||||
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
|
||||
xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
free_txrx_pbufs(xemacpsif);
|
||||
status = XEmacPs_CfgInitialize(&xemacpsif->emacps, mac_config,
|
||||
mac_config->BaseAddress);
|
||||
if (status != XST_SUCCESS) {
|
||||
xil_printf("In %s:EmacPs Configuration Failed....\r\n", __func__);
|
||||
}
|
||||
/* initialize the mac */
|
||||
init_emacps_on_error(xemacpsif, NetIf);
|
||||
dmacrreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_DMACR_OFFSET);
|
||||
dmacrreg = dmacrreg | (0x01000000);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_DMACR_OFFSET, dmacrreg);
|
||||
setup_isr(xemac);
|
||||
init_dma(xemac);
|
||||
start_emacps(xemacpsif);
|
||||
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
}
|
||||
|
||||
void HandleTxErrors(struct xemac_s *xemac)
|
||||
{
|
||||
xemacpsif_s *xemacpsif;
|
||||
u32 netctrlreg;
|
||||
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
netctrlreg = netctrlreg & (~XEMACPS_NWCTRL_TXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, netctrlreg);
|
||||
free_onlytx_pbufs(xemacpsif);
|
||||
|
||||
clean_dma_txdescs(xemac);
|
||||
netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
netctrlreg = netctrlreg | (XEMACPS_NWCTRL_TXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, netctrlreg);
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
}
|
||||
|
||||
#if LWIP_IPV6 && LWIP_IPV6_MLD
|
||||
static u8_t xemacpsif_ip6_addr_ismulticast(ip6_addr_t* ip_addr)
|
||||
{
|
||||
if(ip6_addr_ismulticast_linklocal(ip_addr)||
|
||||
ip6_addr_ismulticast_iflocal(ip_addr) ||
|
||||
ip6_addr_ismulticast_adminlocal(ip_addr)||
|
||||
ip6_addr_ismulticast_sitelocal(ip_addr) ||
|
||||
ip6_addr_ismulticast_orglocal(ip_addr) ||
|
||||
ip6_addr_ismulticast_global(ip_addr)) {
|
||||
/*Return TRUE if IPv6 is Multicast type*/
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void xemacpsif_mld6_mac_hash_update (struct netif *netif, u8_t *ip_addr,
|
||||
u8_t action)
|
||||
{
|
||||
u8_t multicast_mac_addr[6];
|
||||
struct xemac_s *xemac = (struct xemac_s *) (netif->state);
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *) (xemac->state);
|
||||
XEmacPs_BdRing *txring;
|
||||
txring = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
|
||||
|
||||
multicast_mac_addr[0] = LL_IP6_MULTICAST_ADDR_0;
|
||||
multicast_mac_addr[1] = LL_IP6_MULTICAST_ADDR_1;
|
||||
multicast_mac_addr[2] = ip_addr[12];
|
||||
multicast_mac_addr[3] = ip_addr[13];
|
||||
multicast_mac_addr[4] = ip_addr[14];
|
||||
multicast_mac_addr[5] = ip_addr[15];
|
||||
|
||||
/* Wait till all sent packets are acknowledged from HW */
|
||||
while(txring->HwCnt);
|
||||
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
|
||||
/* Stop Ethernet */
|
||||
XEmacPs_Stop(&xemacpsif->emacps);
|
||||
|
||||
if (action == NETIF_ADD_MAC_FILTER) {
|
||||
/* Set Mulitcast mac address in hash table */
|
||||
XEmacPs_SetHash(&xemacpsif->emacps, multicast_mac_addr);
|
||||
|
||||
} else if (action == NETIF_DEL_MAC_FILTER) {
|
||||
/* Remove Mulitcast mac address in hash table */
|
||||
XEmacPs_DeleteHash(&xemacpsif->emacps, multicast_mac_addr);
|
||||
}
|
||||
|
||||
/* Reset DMA */
|
||||
reset_dma(xemac);
|
||||
|
||||
/* Start Ethernet */
|
||||
XEmacPs_Start(&xemacpsif->emacps);
|
||||
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
}
|
||||
|
||||
static err_t xemacpsif_mld6_mac_filter_update (struct netif *netif, ip_addr_t *group,
|
||||
u8_t action)
|
||||
{
|
||||
u8_t temp_mask;
|
||||
unsigned int i;
|
||||
u8_t * ip_addr = (u8_t *) group;
|
||||
|
||||
if(!(xemacpsif_ip6_addr_ismulticast((ip6_addr_t*) ip_addr))) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: The requested MAC address is not a multicast address.\r\n", __func__)); LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("Multicast address add operation failure !!\r\n"));
|
||||
return ERR_ARG;
|
||||
}
|
||||
if (action == NETIF_ADD_MAC_FILTER) {
|
||||
for (i = 0; i < XEMACPS_MAX_MAC_ADDR; i++) {
|
||||
temp_mask = (0x01) << i;
|
||||
if ((xemacps_mld6_mcast_entry_mask & temp_mask) == temp_mask) {
|
||||
continue;
|
||||
}
|
||||
xemacps_mld6_mcast_entry_mask |= temp_mask;
|
||||
|
||||
/* Update mac address in hash table */
|
||||
xemacpsif_mld6_mac_hash_update(netif, ip_addr, action);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: Multicast MAC address successfully added.\r\n", __func__));
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: No multicast address registers left.\r\n", __func__));
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("Multicast MAC address add operation failure !!\r\n"));
|
||||
return ERR_MEM;
|
||||
} else if (action == NETIF_DEL_MAC_FILTER) {
|
||||
for (i = 0; i < XEMACPS_MAX_MAC_ADDR; i++) {
|
||||
temp_mask = (0x01) << i;
|
||||
if ((xemacps_mld6_mcast_entry_mask & temp_mask) != temp_mask) {
|
||||
continue;
|
||||
}
|
||||
xemacps_mld6_mcast_entry_mask &= (~temp_mask);
|
||||
|
||||
/* Update mac address in hash table */
|
||||
xemacpsif_mld6_mac_hash_update(netif, ip_addr, action);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: Multicast MAC address successfully removed.\r\n", __func__));
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: No multicast address registers present with\r\n", __func__));
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("the requested Multicast MAC address.\r\n"));
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("Multicast MAC address removal failure!!.\r\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
return ERR_ARG;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LWIP_IGMP
|
||||
static void xemacpsif_mac_hash_update (struct netif *netif, u8_t *ip_addr,
|
||||
u8_t action)
|
||||
{
|
||||
u8_t multicast_mac_addr[6];
|
||||
struct xemac_s *xemac = (struct xemac_s *) (netif->state);
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *) (xemac->state);
|
||||
XEmacPs_BdRing *txring;
|
||||
txring = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
|
||||
|
||||
multicast_mac_addr[0] = 0x01;
|
||||
multicast_mac_addr[1] = 0x00;
|
||||
multicast_mac_addr[2] = 0x5E;
|
||||
multicast_mac_addr[3] = ip_addr[1] & 0x7F;
|
||||
multicast_mac_addr[4] = ip_addr[2];
|
||||
multicast_mac_addr[5] = ip_addr[3];
|
||||
|
||||
/* Wait till all sent packets are acknowledged from HW */
|
||||
while(txring->HwCnt);
|
||||
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
|
||||
/* Stop Ethernet */
|
||||
XEmacPs_Stop(&xemacpsif->emacps);
|
||||
|
||||
if (action == IGMP_ADD_MAC_FILTER) {
|
||||
/* Set Mulitcast mac address in hash table */
|
||||
XEmacPs_SetHash(&xemacpsif->emacps, multicast_mac_addr);
|
||||
|
||||
} else if (action == IGMP_DEL_MAC_FILTER) {
|
||||
/* Remove Mulitcast mac address in hash table */
|
||||
XEmacPs_DeleteHash(&xemacpsif->emacps, multicast_mac_addr);
|
||||
}
|
||||
|
||||
/* Reset DMA */
|
||||
reset_dma(xemac);
|
||||
|
||||
/* Start Ethernet */
|
||||
XEmacPs_Start(&xemacpsif->emacps);
|
||||
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
}
|
||||
|
||||
static err_t xemacpsif_mac_filter_update (struct netif *netif, ip_addr_t *group,
|
||||
u8_t action)
|
||||
{
|
||||
u8_t temp_mask;
|
||||
unsigned int i;
|
||||
u8_t * ip_addr = (u8_t *) group;
|
||||
|
||||
if ((ip_addr[0] < 224) && (ip_addr[0] > 239)) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: The requested MAC address is not a multicast address.\r\n", __func__));
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("Multicast address add operation failure !!\r\n"));
|
||||
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
if (action == IGMP_ADD_MAC_FILTER) {
|
||||
|
||||
for (i = 0; i < XEMACPS_MAX_MAC_ADDR; i++) {
|
||||
temp_mask = (0x01) << i;
|
||||
if ((xemacps_mcast_entry_mask & temp_mask) == temp_mask) {
|
||||
continue;
|
||||
}
|
||||
xemacps_mcast_entry_mask |= temp_mask;
|
||||
|
||||
/* Update mac address in hash table */
|
||||
xemacpsif_mac_hash_update(netif, ip_addr, action);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: Multicast MAC address successfully added.\r\n", __func__));
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
if (i == XEMACPS_MAX_MAC_ADDR) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: No multicast address registers left.\r\n", __func__));
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("Multicast MAC address add operation failure !!\r\n"));
|
||||
|
||||
return ERR_MEM;
|
||||
}
|
||||
} else if (action == IGMP_DEL_MAC_FILTER) {
|
||||
for (i = 0; i < XEMACPS_MAX_MAC_ADDR; i++) {
|
||||
temp_mask = (0x01) << i;
|
||||
if ((xemacps_mcast_entry_mask & temp_mask) != temp_mask) {
|
||||
continue;
|
||||
}
|
||||
xemacps_mcast_entry_mask &= (~temp_mask);
|
||||
|
||||
/* Update mac address in hash table */
|
||||
xemacpsif_mac_hash_update(netif, ip_addr, action);
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: Multicast MAC address successfully removed.\r\n", __func__));
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
if (i == XEMACPS_MAX_MAC_ADDR) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("%s: No multicast address registers present with\r\n", __func__));
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("the requested Multicast MAC address.\r\n"));
|
||||
LWIP_DEBUGF(NETIF_DEBUG,
|
||||
("Multicast MAC address removal failure!!.\r\n"));
|
||||
|
||||
return ERR_MEM;
|
||||
}
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* xemacpsif_init():
|
||||
*
|
||||
* Should be called at the beginning of the program to set up the
|
||||
* network interface. It calls the function low_level_init() to do the
|
||||
* actual setup of the hardware.
|
||||
*
|
||||
*/
|
||||
|
||||
err_t xemacpsif_init(struct netif *netif)
|
||||
{
|
||||
#if LWIP_SNMP
|
||||
/* ifType ethernetCsmacd(6) @see RFC1213 */
|
||||
netif->link_type = 6;
|
||||
/* your link speed here */
|
||||
netif->link_speed = ;
|
||||
netif->ts = 0;
|
||||
netif->ifinoctets = 0;
|
||||
netif->ifinucastpkts = 0;
|
||||
netif->ifinnucastpkts = 0;
|
||||
netif->ifindiscards = 0;
|
||||
netif->ifoutoctets = 0;
|
||||
netif->ifoutucastpkts = 0;
|
||||
netif->ifoutnucastpkts = 0;
|
||||
netif->ifoutdiscards = 0;
|
||||
#endif
|
||||
|
||||
netif->name[0] = IFNAME0;
|
||||
netif->name[1] = IFNAME1;
|
||||
netif->output = xemacpsif_output;
|
||||
netif->linkoutput = low_level_output;
|
||||
#if LWIP_IPV6
|
||||
netif->output_ip6 = ethip6_output;
|
||||
#endif
|
||||
|
||||
low_level_init(netif);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* xemacpsif_resetrx_on_no_rxdata():
|
||||
*
|
||||
* Should be called by the user at regular intervals, typically
|
||||
* from a timer (100 msecond). This is to provide a SW workaround
|
||||
* for the HW bug (SI #692601). Please refer to the function header
|
||||
* for the function resetrx_on_no_rxdata in xemacpsif_dma.c to
|
||||
* know more about the SI.
|
||||
*
|
||||
*/
|
||||
|
||||
void xemacpsif_resetrx_on_no_rxdata(struct netif *netif)
|
||||
{
|
||||
struct xemac_s *xemac = (struct xemac_s *)(netif->state);
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
|
||||
resetrx_on_no_rxdata(xemacpsif);
|
||||
}
|
|
@ -0,0 +1,873 @@
|
|||
/*
|
||||
* Copyright (C) 2010 - 2019 Xilinx, Inc.
|
||||
* Copyright (C) 2021 WangHuachen.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwipopts.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/inet_chksum.h"
|
||||
|
||||
#include "netif/xadapter.h"
|
||||
#include "netif/xemacpsif.h"
|
||||
#include "xstatus.h"
|
||||
|
||||
#include "xlwipconfig.h"
|
||||
#include "xparameters.h"
|
||||
#include "xparameters_ps.h"
|
||||
// #include "xil_exception.h"
|
||||
#include "xil_mmu.h"
|
||||
#if defined (ARMR5)
|
||||
#include "xreg_cortexr5.h"
|
||||
#endif
|
||||
#ifdef CONFIG_XTRACE
|
||||
#include "xtrace.h"
|
||||
#endif
|
||||
#ifdef OS_IS_FREERTOS
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "timers.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define INTC_BASE_ADDR XPAR_SCUGIC_0_CPU_BASEADDR
|
||||
#define INTC_DIST_BASE_ADDR XPAR_SCUGIC_0_DIST_BASEADDR
|
||||
|
||||
/* Byte alignment of BDs */
|
||||
#define BD_ALIGNMENT (XEMACPS_DMABD_MINIMUM_ALIGNMENT*2)
|
||||
|
||||
/* A max of 4 different ethernet interfaces are supported */
|
||||
static UINTPTR tx_pbufs_storage[4*XLWIP_CONFIG_N_TX_DESC];
|
||||
static UINTPTR rx_pbufs_storage[4*XLWIP_CONFIG_N_RX_DESC];
|
||||
|
||||
static s32_t emac_intr_num;
|
||||
|
||||
/******************************************************************************
|
||||
* Each BD is of 8 bytes of size and the BDs (BD chain) need to be put
|
||||
* at uncached memory location. If they are not put at uncached
|
||||
* locations, the user needs to flush or invalidate for each BD/packet.
|
||||
* However, the flush or invalidate can happen over a cache line which can
|
||||
* span multiple BDs. This means a flush or invalidate of one BD can actually
|
||||
* flush/invalidate multiple BDs adjacent to the targeted BD.Assuming that
|
||||
* the user and hardware both update the BD fields, this operation from user
|
||||
* can potentially overwrite the updates done by hardware or user.
|
||||
* To avoid this, it is always safe to put the BD chains for Rx and tx side
|
||||
* at uncached memory location.
|
||||
*
|
||||
* The Xilinx standalone BSP for Cortex A9 implements only primary page tables.
|
||||
* Each table entry corresponds to 1 MB of address map. This means, if a memory
|
||||
* region has to be made uncached, the minimum granularity will be of 1 MB.
|
||||
*
|
||||
* The implementation below allocates a 1 MB of u8 array aligned to 1 MB.
|
||||
* This ensures that this array is put at 1 MB aligned memory (e.g. 0x1200000)
|
||||
* and accupies memory of 1 MB. The init_dma function then changes 1 MB of this
|
||||
* region to make it uncached (strongly ordered).
|
||||
* This increases the bss section of the program significantly and can be a
|
||||
* wastage of memory. The reason beings, BDs will hardly occupy few KBs of
|
||||
* memory and the rest of 1 MB of memory will be unused.
|
||||
*
|
||||
* If a program uses other peripherals that have DMAs/bus masters and need
|
||||
* uncached memory, they may also end of following the same approach. This
|
||||
* definitely aggravates the memory wastage issue. To avoid all this, the user
|
||||
* can create a new 1 MB section in the linker script and reserve it for such
|
||||
* use cases that need uncached memory location. They can then have their own
|
||||
* memory allocation logic in their application that allocates uncached memory
|
||||
* from this 1 MB location. For such a case, changes need to be done in this
|
||||
* file and appropriate uncached memory allocated through other means can be
|
||||
* used.
|
||||
*
|
||||
* The present implementation here allocates 1 MB of uncached memory. It
|
||||
* reserves of 64 KB of memory for each BD chain. 64 KB of memory means 8192 of
|
||||
* BDs for each BD chain which is more than enough for any application.
|
||||
* Assuming that both emac0 and emac1 are present, 256 KB of memory is allocated
|
||||
* for BDs. The rest 768 KB of memory is just unused.
|
||||
*********************************************************************************/
|
||||
|
||||
#if defined __aarch64__
|
||||
u8_t bd_space[0x200000] __attribute__ ((aligned (0x200000)));
|
||||
#else
|
||||
u8_t bd_space[0x100000] __attribute__ ((aligned (0x100000)));
|
||||
#endif
|
||||
static volatile u32_t bd_space_index = 0;
|
||||
static volatile u32_t bd_space_attr_set = 0;
|
||||
|
||||
#ifdef OS_IS_FREERTOS
|
||||
long xInsideISR = 0;
|
||||
#endif
|
||||
|
||||
#define XEMACPS_BD_TO_INDEX(ringptr, bdptr) \
|
||||
(((UINTPTR)bdptr - (UINTPTR)(ringptr)->BaseBdAddr) / (ringptr)->Separation)
|
||||
|
||||
|
||||
s32_t is_tx_space_available(xemacpsif_s *emac)
|
||||
{
|
||||
XEmacPs_BdRing *txring;
|
||||
s32_t freecnt = 0;
|
||||
|
||||
txring = &(XEmacPs_GetTxRing(&emac->emacps));
|
||||
|
||||
/* tx space is available as long as there are valid BD's */
|
||||
freecnt = XEmacPs_BdRingGetFreeCnt(txring);
|
||||
return freecnt;
|
||||
}
|
||||
|
||||
|
||||
static inline
|
||||
u32_t get_base_index_txpbufsstorage (xemacpsif_s *xemacpsif)
|
||||
{
|
||||
u32_t index;
|
||||
#ifdef XPAR_XEMACPS_0_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_0_BASEADDR) {
|
||||
index = 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef XPAR_XEMACPS_1_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_1_BASEADDR) {
|
||||
index = XLWIP_CONFIG_N_TX_DESC;
|
||||
}
|
||||
#endif
|
||||
#ifdef XPAR_XEMACPS_2_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_2_BASEADDR) {
|
||||
index = 2 * XLWIP_CONFIG_N_TX_DESC;
|
||||
}
|
||||
#endif
|
||||
#ifdef XPAR_XEMACPS_3_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_3_BASEADDR) {
|
||||
index = 3 * XLWIP_CONFIG_N_TX_DESC;
|
||||
}
|
||||
#endif
|
||||
return index;
|
||||
}
|
||||
|
||||
static inline
|
||||
u32_t get_base_index_rxpbufsstorage (xemacpsif_s *xemacpsif)
|
||||
{
|
||||
u32_t index;
|
||||
#ifdef XPAR_XEMACPS_0_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_0_BASEADDR) {
|
||||
index = 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef XPAR_XEMACPS_1_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_1_BASEADDR) {
|
||||
index = XLWIP_CONFIG_N_RX_DESC;
|
||||
}
|
||||
#endif
|
||||
#ifdef XPAR_XEMACPS_2_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_2_BASEADDR) {
|
||||
index = 2 * XLWIP_CONFIG_N_RX_DESC;
|
||||
}
|
||||
#endif
|
||||
#ifdef XPAR_XEMACPS_3_BASEADDR
|
||||
if (xemacpsif->emacps.Config.BaseAddress == XPAR_XEMACPS_3_BASEADDR) {
|
||||
index = 3 * XLWIP_CONFIG_N_RX_DESC;
|
||||
}
|
||||
#endif
|
||||
return index;
|
||||
}
|
||||
|
||||
void process_sent_bds(xemacpsif_s *xemacpsif, XEmacPs_BdRing *txring)
|
||||
{
|
||||
XEmacPs_Bd *txbdset;
|
||||
XEmacPs_Bd *curbdpntr;
|
||||
s32_t n_bds;
|
||||
XStatus status;
|
||||
s32_t n_pbufs_freed = 0;
|
||||
u32_t bdindex;
|
||||
struct pbuf *p;
|
||||
u32 *temp;
|
||||
u32_t index;
|
||||
|
||||
index = get_base_index_txpbufsstorage (xemacpsif);
|
||||
|
||||
while (1) {
|
||||
/* obtain processed BD's */
|
||||
n_bds = XEmacPs_BdRingFromHwTx(txring,
|
||||
XLWIP_CONFIG_N_TX_DESC, &txbdset);
|
||||
if (n_bds == 0) {
|
||||
return;
|
||||
}
|
||||
/* free the processed BD's */
|
||||
n_pbufs_freed = n_bds;
|
||||
curbdpntr = txbdset;
|
||||
while (n_pbufs_freed > 0) {
|
||||
bdindex = XEMACPS_BD_TO_INDEX(txring, curbdpntr);
|
||||
temp = (u32 *)curbdpntr;
|
||||
*temp = 0;
|
||||
temp++;
|
||||
if (bdindex == (XLWIP_CONFIG_N_TX_DESC - 1)) {
|
||||
*temp = 0xC0000000;
|
||||
} else {
|
||||
*temp = 0x80000000;
|
||||
}
|
||||
dsb();
|
||||
p = (struct pbuf *)tx_pbufs_storage[index + bdindex];
|
||||
if (p != NULL) {
|
||||
pbuf_free(p);
|
||||
}
|
||||
tx_pbufs_storage[index + bdindex] = 0;
|
||||
curbdpntr = XEmacPs_BdRingNext(txring, curbdpntr);
|
||||
n_pbufs_freed--;
|
||||
dsb();
|
||||
}
|
||||
|
||||
status = XEmacPs_BdRingFree(txring, n_bds, txbdset);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Failure while freeing in Tx Done ISR\r\n"));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void emacps_send_handler(void *arg)
|
||||
{
|
||||
struct xemac_s *xemac;
|
||||
xemacpsif_s *xemacpsif;
|
||||
XEmacPs_BdRing *txringptr;
|
||||
u32_t regval;
|
||||
#ifdef OS_IS_FREERTOS
|
||||
xInsideISR++;
|
||||
#endif
|
||||
xemac = (struct xemac_s *)(arg);
|
||||
xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
txringptr = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
|
||||
regval = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_TXSR_OFFSET);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,XEMACPS_TXSR_OFFSET, regval);
|
||||
|
||||
/* If Transmit done interrupt is asserted, process completed BD's */
|
||||
/* Since RT-Thread does not support freeing memory in interrupts, comment it out */
|
||||
// process_sent_bds(xemacpsif, txringptr);
|
||||
#ifdef OS_IS_FREERTOS
|
||||
xInsideISR--;
|
||||
#endif
|
||||
}
|
||||
|
||||
XStatus emacps_sgsend(xemacpsif_s *xemacpsif, struct pbuf *p)
|
||||
{
|
||||
struct pbuf *q;
|
||||
s32_t n_pbufs;
|
||||
XEmacPs_Bd *txbdset, *txbd, *last_txbd = NULL;
|
||||
XEmacPs_Bd *temp_txbd;
|
||||
XStatus status;
|
||||
XEmacPs_BdRing *txring;
|
||||
u32_t bdindex;
|
||||
u32_t lev;
|
||||
u32_t index;
|
||||
u32_t max_fr_size;
|
||||
|
||||
lev = mfcpsr();
|
||||
mtcpsr(lev | 0x000000C0);
|
||||
|
||||
txring = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
|
||||
|
||||
index = get_base_index_txpbufsstorage (xemacpsif);
|
||||
|
||||
/* first count the number of pbufs */
|
||||
for (q = p, n_pbufs = 0; q != NULL; q = q->next)
|
||||
n_pbufs++;
|
||||
|
||||
/* obtain as many BD's */
|
||||
status = XEmacPs_BdRingAlloc(txring, n_pbufs, &txbdset);
|
||||
if (status != XST_SUCCESS) {
|
||||
mtcpsr(lev);
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("sgsend: Error allocating TxBD\r\n"));
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
for(q = p, txbd = txbdset; q != NULL; q = q->next) {
|
||||
bdindex = XEMACPS_BD_TO_INDEX(txring, txbd);
|
||||
if (tx_pbufs_storage[index + bdindex] != 0) {
|
||||
mtcpsr(lev);
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("PBUFS not available\r\n"));
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/* Send the data from the pbuf to the interface, one pbuf at a
|
||||
time. The size of the data in each pbuf is kept in the ->len
|
||||
variable. */
|
||||
if (xemacpsif->emacps.Config.IsCacheCoherent == 0) {
|
||||
Xil_DCacheFlushRange((UINTPTR)q->payload, (UINTPTR)q->len);
|
||||
}
|
||||
|
||||
XEmacPs_BdSetAddressTx(txbd, (UINTPTR)q->payload);
|
||||
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
max_fr_size = MAX_FRAME_SIZE_JUMBO - 18;
|
||||
#else
|
||||
max_fr_size = XEMACPS_MAX_FRAME_SIZE - 18;
|
||||
#endif
|
||||
if (q->len > max_fr_size)
|
||||
XEmacPs_BdSetLength(txbd, max_fr_size & 0x3FFF);
|
||||
else
|
||||
XEmacPs_BdSetLength(txbd, q->len & 0x3FFF);
|
||||
|
||||
tx_pbufs_storage[index + bdindex] = (UINTPTR)q;
|
||||
|
||||
pbuf_ref(q);
|
||||
last_txbd = txbd;
|
||||
XEmacPs_BdClearLast(txbd);
|
||||
txbd = XEmacPs_BdRingNext(txring, txbd);
|
||||
}
|
||||
XEmacPs_BdSetLast(last_txbd);
|
||||
/* For fragmented packets, remember the 1st BD allocated for the 1st
|
||||
packet fragment. The used bit for this BD should be cleared at the end
|
||||
after clearing out used bits for other fragments. For packets without
|
||||
just remember the allocated BD. */
|
||||
temp_txbd = txbdset;
|
||||
txbd = txbdset;
|
||||
txbd = XEmacPs_BdRingNext(txring, txbd);
|
||||
q = p->next;
|
||||
for(; q != NULL; q = q->next) {
|
||||
XEmacPs_BdClearTxUsed(txbd);
|
||||
dsb();
|
||||
txbd = XEmacPs_BdRingNext(txring, txbd);
|
||||
}
|
||||
XEmacPs_BdClearTxUsed(temp_txbd);
|
||||
dsb();
|
||||
|
||||
status = XEmacPs_BdRingToHw(txring, n_pbufs, txbdset);
|
||||
if (status != XST_SUCCESS) {
|
||||
mtcpsr(lev);
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("sgsend: Error submitting TxBD\r\n"));
|
||||
return XST_FAILURE;
|
||||
}
|
||||
/* Start transmit */
|
||||
XEmacPs_WriteReg((xemacpsif->emacps).Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET,
|
||||
(XEmacPs_ReadReg((xemacpsif->emacps).Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET) | XEMACPS_NWCTRL_STARTTX_MASK));
|
||||
|
||||
mtcpsr(lev);
|
||||
return status;
|
||||
}
|
||||
|
||||
void setup_rx_bds(xemacpsif_s *xemacpsif, XEmacPs_BdRing *rxring)
|
||||
{
|
||||
XEmacPs_Bd *rxbd;
|
||||
XStatus status;
|
||||
struct pbuf *p;
|
||||
u32_t freebds;
|
||||
u32_t bdindex;
|
||||
u32 *temp;
|
||||
u32_t index;
|
||||
|
||||
index = get_base_index_rxpbufsstorage (xemacpsif);
|
||||
|
||||
freebds = XEmacPs_BdRingGetFreeCnt (rxring);
|
||||
while (freebds > 0) {
|
||||
freebds--;
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
p = pbuf_alloc(PBUF_RAW, MAX_FRAME_SIZE_JUMBO, PBUF_POOL);
|
||||
#else
|
||||
p = pbuf_alloc(PBUF_RAW, XEMACPS_MAX_FRAME_SIZE, PBUF_POOL);
|
||||
#endif
|
||||
if (!p) {
|
||||
#if LINK_STATS
|
||||
lwip_stats.link.memerr++;
|
||||
lwip_stats.link.drop++;
|
||||
#endif
|
||||
rt_kprintf("unable to alloc pbuf in recv_handler\r\n");
|
||||
return;
|
||||
}
|
||||
status = XEmacPs_BdRingAlloc(rxring, 1, &rxbd);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("setup_rx_bds: Error allocating RxBD\r\n"));
|
||||
pbuf_free(p);
|
||||
return;
|
||||
}
|
||||
status = XEmacPs_BdRingToHw(rxring, 1, rxbd);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Error committing RxBD to hardware: "));
|
||||
if (status == XST_DMA_SG_LIST_ERROR) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("XST_DMA_SG_LIST_ERROR: this function was called out of sequence with XEmacPs_BdRingAlloc()\r\n"));
|
||||
}
|
||||
else {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("set of BDs was rejected because the first BD did not have its start-of-packet bit set, or the last BD did not have its end-of-packet bit set, or any one of the BD set has 0 as length value\r\n"));
|
||||
}
|
||||
|
||||
pbuf_free(p);
|
||||
XEmacPs_BdRingUnAlloc(rxring, 1, rxbd);
|
||||
return;
|
||||
}
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
if (xemacpsif->emacps.Config.IsCacheCoherent == 0) {
|
||||
Xil_DCacheInvalidateRange((UINTPTR)p->payload, (UINTPTR)MAX_FRAME_SIZE_JUMBO);
|
||||
}
|
||||
#else
|
||||
if (xemacpsif->emacps.Config.IsCacheCoherent == 0) {
|
||||
Xil_DCacheInvalidateRange((UINTPTR)p->payload, (UINTPTR)XEMACPS_MAX_FRAME_SIZE);
|
||||
}
|
||||
#endif
|
||||
bdindex = XEMACPS_BD_TO_INDEX(rxring, rxbd);
|
||||
temp = (u32 *)rxbd;
|
||||
if (bdindex == (XLWIP_CONFIG_N_RX_DESC - 1)) {
|
||||
*temp = 0x00000002;
|
||||
} else {
|
||||
*temp = 0;
|
||||
}
|
||||
temp++;
|
||||
*temp = 0;
|
||||
dsb();
|
||||
|
||||
XEmacPs_BdSetAddressRx(rxbd, (UINTPTR)p->payload);
|
||||
rx_pbufs_storage[index + bdindex] = (UINTPTR)p;
|
||||
}
|
||||
}
|
||||
|
||||
void emacps_recv_handler(void *arg)
|
||||
{
|
||||
struct pbuf *p;
|
||||
XEmacPs_Bd *rxbdset, *curbdptr;
|
||||
struct xemac_s *xemac;
|
||||
xemacpsif_s *xemacpsif;
|
||||
XEmacPs_BdRing *rxring;
|
||||
volatile s32_t bd_processed;
|
||||
s32_t rx_bytes, k;
|
||||
u32_t bdindex;
|
||||
u32_t regval;
|
||||
u32_t index;
|
||||
u32_t gigeversion;
|
||||
|
||||
xemac = (struct xemac_s *)(arg);
|
||||
xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
rxring = &XEmacPs_GetRxRing(&xemacpsif->emacps);
|
||||
|
||||
#ifdef OS_IS_FREERTOS
|
||||
xInsideISR++;
|
||||
#endif
|
||||
|
||||
gigeversion = ((Xil_In32(xemacpsif->emacps.Config.BaseAddress + 0xFC)) >> 16) & 0xFFF;
|
||||
index = get_base_index_rxpbufsstorage (xemacpsif);
|
||||
/*
|
||||
* If Reception done interrupt is asserted, call RX call back function
|
||||
* to handle the processed BDs and then raise the according flag.
|
||||
*/
|
||||
regval = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET, regval);
|
||||
if (gigeversion <= 2) {
|
||||
resetrx_on_no_rxdata(xemacpsif);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
|
||||
bd_processed = XEmacPs_BdRingFromHwRx(rxring, XLWIP_CONFIG_N_RX_DESC, &rxbdset);
|
||||
if (bd_processed <= 0) {
|
||||
break;
|
||||
}
|
||||
for (k = 0, curbdptr=rxbdset; k < bd_processed; k++) {
|
||||
|
||||
bdindex = XEMACPS_BD_TO_INDEX(rxring, curbdptr);
|
||||
p = (struct pbuf *)rx_pbufs_storage[index + bdindex];
|
||||
/*
|
||||
* Adjust the buffer size to the actual number of bytes received.
|
||||
*/
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
rx_bytes = XEmacPs_GetRxFrameSize(&xemacpsif->emacps, curbdptr);
|
||||
#else
|
||||
rx_bytes = XEmacPs_BdGetLength(curbdptr);
|
||||
#endif
|
||||
pbuf_realloc(p, rx_bytes);
|
||||
/* Invalidate RX frame before queuing to handle
|
||||
* L1 cache prefetch conditions on any architecture.
|
||||
*/
|
||||
Xil_DCacheInvalidateRange((UINTPTR)p->payload, rx_bytes);
|
||||
/* store it in the receive queue,
|
||||
* where it'll be processed by a different handler
|
||||
*/
|
||||
if (pq_enqueue(xemacpsif->recv_q, (void*)p) < 0) {
|
||||
#if LINK_STATS
|
||||
lwip_stats.link.memerr++;
|
||||
lwip_stats.link.drop++;
|
||||
#endif
|
||||
pbuf_free(p);
|
||||
}
|
||||
curbdptr = XEmacPs_BdRingNext( rxring, curbdptr);
|
||||
}
|
||||
/* free up the BD's */
|
||||
XEmacPs_BdRingFree(rxring, bd_processed, rxbdset);
|
||||
setup_rx_bds(xemacpsif, rxring);
|
||||
#if 0
|
||||
sys_sem_signal(&xemac->sem_rx_data_available);
|
||||
#else
|
||||
eth_device_ready(xemac->rt_eth_device);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef OS_IS_FREERTOS
|
||||
xInsideISR--;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void clean_dma_txdescs(struct xemac_s *xemac)
|
||||
{
|
||||
XEmacPs_Bd bdtemplate;
|
||||
XEmacPs_BdRing *txringptr;
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
|
||||
txringptr = &XEmacPs_GetTxRing(&xemacpsif->emacps);
|
||||
|
||||
XEmacPs_BdClear(&bdtemplate);
|
||||
XEmacPs_BdSetStatus(&bdtemplate, XEMACPS_TXBUF_USED_MASK);
|
||||
|
||||
/*
|
||||
* Create the TxBD ring
|
||||
*/
|
||||
XEmacPs_BdRingCreate(txringptr, (UINTPTR) xemacpsif->tx_bdspace,
|
||||
(UINTPTR) xemacpsif->tx_bdspace, BD_ALIGNMENT,
|
||||
XLWIP_CONFIG_N_TX_DESC);
|
||||
XEmacPs_BdRingClone(txringptr, &bdtemplate, XEMACPS_SEND);
|
||||
}
|
||||
|
||||
XStatus init_dma(struct xemac_s *xemac)
|
||||
{
|
||||
XEmacPs_Bd bdtemplate;
|
||||
XEmacPs_BdRing *rxringptr, *txringptr;
|
||||
XEmacPs_Bd *rxbd;
|
||||
struct pbuf *p;
|
||||
XStatus status;
|
||||
s32_t i;
|
||||
u32_t bdindex;
|
||||
volatile UINTPTR tempaddress;
|
||||
u32_t index;
|
||||
u32_t gigeversion;
|
||||
XEmacPs_Bd *bdtxterminate;
|
||||
XEmacPs_Bd *bdrxterminate;
|
||||
u32 *temp;
|
||||
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
struct xtopology_t *xtopologyp = &xtopology[xemac->topology_index];
|
||||
|
||||
index = get_base_index_rxpbufsstorage (xemacpsif);
|
||||
gigeversion = ((Xil_In32(xemacpsif->emacps.Config.BaseAddress + 0xFC)) >> 16) & 0xFFF;
|
||||
/*
|
||||
* The BDs need to be allocated in uncached memory. Hence the 1 MB
|
||||
* address range allocated for Bd_Space is made uncached
|
||||
* by setting appropriate attributes in the translation table.
|
||||
* The Bd_Space is aligned to 1MB and has a size of 1 MB. This ensures
|
||||
* a reserved uncached area used only for BDs.
|
||||
*/
|
||||
if (bd_space_attr_set == 0) {
|
||||
#if defined (ARMR5)
|
||||
Xil_SetTlbAttributes((s32_t)bd_space, STRONG_ORDERD_SHARED | PRIV_RW_USER_RW); // addr, attr
|
||||
#else
|
||||
#if defined __aarch64__
|
||||
Xil_SetTlbAttributes((u64)bd_space, NORM_NONCACHE | INNER_SHAREABLE);
|
||||
#else
|
||||
Xil_SetTlbAttributes((s32_t)bd_space, DEVICE_MEMORY); // addr, attr
|
||||
#endif
|
||||
#endif
|
||||
bd_space_attr_set = 1;
|
||||
}
|
||||
|
||||
rxringptr = &XEmacPs_GetRxRing(&xemacpsif->emacps);
|
||||
txringptr = &XEmacPs_GetTxRing(&xemacpsif->emacps);
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("rxringptr: 0x%08x\r\n", rxringptr));
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("txringptr: 0x%08x\r\n", txringptr));
|
||||
|
||||
/* Allocate 64k for Rx and Tx bds each to take care of extreme cases */
|
||||
tempaddress = (UINTPTR)&(bd_space[bd_space_index]);
|
||||
xemacpsif->rx_bdspace = (void *)tempaddress;
|
||||
bd_space_index += 0x10000;
|
||||
tempaddress = (UINTPTR)&(bd_space[bd_space_index]);
|
||||
xemacpsif->tx_bdspace = (void *)tempaddress;
|
||||
bd_space_index += 0x10000;
|
||||
if (gigeversion > 2) {
|
||||
tempaddress = (UINTPTR)&(bd_space[bd_space_index]);
|
||||
bdrxterminate = (XEmacPs_Bd *)tempaddress;
|
||||
bd_space_index += 0x10000;
|
||||
tempaddress = (UINTPTR)&(bd_space[bd_space_index]);
|
||||
bdtxterminate = (XEmacPs_Bd *)tempaddress;
|
||||
bd_space_index += 0x10000;
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("rx_bdspace: %p \r\n", xemacpsif->rx_bdspace));
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("tx_bdspace: %p \r\n", xemacpsif->tx_bdspace));
|
||||
|
||||
if (!xemacpsif->rx_bdspace || !xemacpsif->tx_bdspace) {
|
||||
xil_printf("%s@%d: Error: Unable to allocate memory for TX/RX buffer descriptors",
|
||||
__FILE__, __LINE__);
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup RxBD space.
|
||||
*
|
||||
* Setup a BD template for the Rx channel. This template will be copied to
|
||||
* every RxBD. We will not have to explicitly set these again.
|
||||
*/
|
||||
XEmacPs_BdClear(&bdtemplate);
|
||||
|
||||
/*
|
||||
* Create the RxBD ring
|
||||
*/
|
||||
|
||||
status = XEmacPs_BdRingCreate(rxringptr, (UINTPTR) xemacpsif->rx_bdspace,
|
||||
(UINTPTR) xemacpsif->rx_bdspace, BD_ALIGNMENT,
|
||||
XLWIP_CONFIG_N_RX_DESC);
|
||||
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Error setting up RxBD space\r\n"));
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
status = XEmacPs_BdRingClone(rxringptr, &bdtemplate, XEMACPS_RECV);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Error initializing RxBD space\r\n"));
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
XEmacPs_BdClear(&bdtemplate);
|
||||
XEmacPs_BdSetStatus(&bdtemplate, XEMACPS_TXBUF_USED_MASK);
|
||||
/*
|
||||
* Create the TxBD ring
|
||||
*/
|
||||
status = XEmacPs_BdRingCreate(txringptr, (UINTPTR) xemacpsif->tx_bdspace,
|
||||
(UINTPTR) xemacpsif->tx_bdspace, BD_ALIGNMENT,
|
||||
XLWIP_CONFIG_N_TX_DESC);
|
||||
|
||||
if (status != XST_SUCCESS) {
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
/* We reuse the bd template, as the same one will work for both rx and tx. */
|
||||
status = XEmacPs_BdRingClone(txringptr, &bdtemplate, XEMACPS_SEND);
|
||||
if (status != XST_SUCCESS) {
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate RX descriptors, 1 RxBD at a time.
|
||||
*/
|
||||
for (i = 0; i < XLWIP_CONFIG_N_RX_DESC; i++) {
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
p = pbuf_alloc(PBUF_RAW, MAX_FRAME_SIZE_JUMBO, PBUF_POOL);
|
||||
#else
|
||||
p = pbuf_alloc(PBUF_RAW, XEMACPS_MAX_FRAME_SIZE, PBUF_POOL);
|
||||
#endif
|
||||
if (!p) {
|
||||
#if LINK_STATS
|
||||
lwip_stats.link.memerr++;
|
||||
lwip_stats.link.drop++;
|
||||
#endif
|
||||
rt_kprintf("unable to alloc pbuf in init_dma\r\n");
|
||||
return ERR_IF;
|
||||
}
|
||||
status = XEmacPs_BdRingAlloc(rxringptr, 1, &rxbd);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("init_dma: Error allocating RxBD\r\n"));
|
||||
pbuf_free(p);
|
||||
return ERR_IF;
|
||||
}
|
||||
/* Enqueue to HW */
|
||||
status = XEmacPs_BdRingToHw(rxringptr, 1, rxbd);
|
||||
if (status != XST_SUCCESS) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Error: committing RxBD to HW\r\n"));
|
||||
pbuf_free(p);
|
||||
XEmacPs_BdRingUnAlloc(rxringptr, 1, rxbd);
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
bdindex = XEMACPS_BD_TO_INDEX(rxringptr, rxbd);
|
||||
temp = (u32 *)rxbd;
|
||||
*temp = 0;
|
||||
if (bdindex == (XLWIP_CONFIG_N_RX_DESC - 1)) {
|
||||
*temp = 0x00000002;
|
||||
}
|
||||
temp++;
|
||||
*temp = 0;
|
||||
dsb();
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
if (xemacpsif->emacps.Config.IsCacheCoherent == 0) {
|
||||
Xil_DCacheInvalidateRange((UINTPTR)p->payload, (UINTPTR)MAX_FRAME_SIZE_JUMBO);
|
||||
}
|
||||
#else
|
||||
if (xemacpsif->emacps.Config.IsCacheCoherent == 0) {
|
||||
Xil_DCacheInvalidateRange((UINTPTR)p->payload, (UINTPTR)XEMACPS_MAX_FRAME_SIZE);
|
||||
}
|
||||
#endif
|
||||
XEmacPs_BdSetAddressRx(rxbd, (UINTPTR)p->payload);
|
||||
|
||||
rx_pbufs_storage[index + bdindex] = (UINTPTR)p;
|
||||
}
|
||||
XEmacPs_SetQueuePtr(&(xemacpsif->emacps), xemacpsif->emacps.RxBdRing.BaseBdAddr, 0, XEMACPS_RECV);
|
||||
if (gigeversion > 2) {
|
||||
XEmacPs_SetQueuePtr(&(xemacpsif->emacps), xemacpsif->emacps.TxBdRing.BaseBdAddr, 1, XEMACPS_SEND);
|
||||
}else {
|
||||
XEmacPs_SetQueuePtr(&(xemacpsif->emacps), xemacpsif->emacps.TxBdRing.BaseBdAddr, 0, XEMACPS_SEND);
|
||||
}
|
||||
if (gigeversion > 2)
|
||||
{
|
||||
/*
|
||||
* This version of GEM supports priority queuing and the current
|
||||
* driver is using tx priority queue 1 and normal rx queue for
|
||||
* packet transmit and receive. The below code ensure that the
|
||||
* other queue pointers are parked to known state for avoiding
|
||||
* the controller to malfunction by fetching the descriptors
|
||||
* from these queues.
|
||||
*/
|
||||
XEmacPs_BdClear(bdrxterminate);
|
||||
XEmacPs_BdSetAddressRx(bdrxterminate, (XEMACPS_RXBUF_NEW_MASK |
|
||||
XEMACPS_RXBUF_WRAP_MASK));
|
||||
XEmacPs_Out32((xemacpsif->emacps.Config.BaseAddress + XEMACPS_RXQ1BASE_OFFSET),
|
||||
(UINTPTR)bdrxterminate);
|
||||
XEmacPs_BdClear(bdtxterminate);
|
||||
XEmacPs_BdSetStatus(bdtxterminate, (XEMACPS_TXBUF_USED_MASK |
|
||||
XEMACPS_TXBUF_WRAP_MASK));
|
||||
XEmacPs_Out32((xemacpsif->emacps.Config.BaseAddress + XEMACPS_TXQBASE_OFFSET),
|
||||
(UINTPTR)bdtxterminate);
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect the device driver handler that will be called when an
|
||||
* interrupt for the device occurs, the handler defined above performs
|
||||
* the specific interrupt processing for the device.
|
||||
*/
|
||||
// XScuGic_RegisterHandler(INTC_BASE_ADDR, xtopologyp->scugic_emac_intr,
|
||||
// (Xil_ExceptionHandler)XEmacPs_IntrHandler,
|
||||
// (void *)&xemacpsif->emacps);
|
||||
/*
|
||||
* Enable the interrupt for emacps.
|
||||
*/
|
||||
// XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, (u32) xtopologyp->scugic_emac_intr);
|
||||
emac_intr_num = (u32) xtopologyp->scugic_emac_intr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* resetrx_on_no_rxdata():
|
||||
*
|
||||
* It is called at regular intervals through the API xemacpsif_resetrx_on_no_rxdata
|
||||
* called by the user.
|
||||
* The EmacPs has a HW bug (SI# 692601) on the Rx path for heavy Rx traffic.
|
||||
* Under heavy Rx traffic because of the HW bug there are times when the Rx path
|
||||
* becomes unresponsive. The workaround for it is to check for the Rx path for
|
||||
* traffic (by reading the stats registers regularly). If the stats register
|
||||
* does not increment for sometime (proving no Rx traffic), the function resets
|
||||
* the Rx data path.
|
||||
*
|
||||
*/
|
||||
|
||||
void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif)
|
||||
{
|
||||
u32_t regctrl;
|
||||
u32_t tempcntr;
|
||||
u32_t gigeversion;
|
||||
|
||||
gigeversion = ((Xil_In32(xemacpsif->emacps.Config.BaseAddress + 0xFC)) >> 16) & 0xFFF;
|
||||
if (gigeversion == 2) {
|
||||
tempcntr = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXCNT_OFFSET);
|
||||
if ((!tempcntr) && (!(xemacpsif->last_rx_frms_cntr))) {
|
||||
regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
regctrl &= (~XEMACPS_NWCTRL_RXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, regctrl);
|
||||
regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET);
|
||||
regctrl |= (XEMACPS_NWCTRL_RXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET, regctrl);
|
||||
}
|
||||
xemacpsif->last_rx_frms_cntr = tempcntr;
|
||||
}
|
||||
}
|
||||
|
||||
void free_txrx_pbufs(xemacpsif_s *xemacpsif)
|
||||
{
|
||||
s32_t index;
|
||||
s32_t index1;
|
||||
struct pbuf *p;
|
||||
|
||||
index1 = get_base_index_txpbufsstorage (xemacpsif);
|
||||
|
||||
for (index = index1; index < (index1 + XLWIP_CONFIG_N_TX_DESC); index++) {
|
||||
if (tx_pbufs_storage[index] != 0) {
|
||||
p = (struct pbuf *)tx_pbufs_storage[index];
|
||||
pbuf_free(p);
|
||||
tx_pbufs_storage[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (index = index1; index < (index1 + XLWIP_CONFIG_N_TX_DESC); index++) {
|
||||
p = (struct pbuf *)rx_pbufs_storage[index];
|
||||
pbuf_free(p);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void free_onlytx_pbufs(xemacpsif_s *xemacpsif)
|
||||
{
|
||||
s32_t index;
|
||||
s32_t index1;
|
||||
struct pbuf *p;
|
||||
|
||||
index1 = get_base_index_txpbufsstorage (xemacpsif);
|
||||
for (index = index1; index < (index1 + XLWIP_CONFIG_N_TX_DESC); index++) {
|
||||
if (tx_pbufs_storage[index] != 0) {
|
||||
p = (struct pbuf *)tx_pbufs_storage[index];
|
||||
pbuf_free(p);
|
||||
tx_pbufs_storage[index] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* reset Tx and Rx DMA pointers after XEmacPs_Stop */
|
||||
void reset_dma(struct xemac_s *xemac)
|
||||
{
|
||||
u8 txqueuenum;
|
||||
u32_t gigeversion;
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
XEmacPs_BdRing *txringptr = &XEmacPs_GetTxRing(&xemacpsif->emacps);
|
||||
XEmacPs_BdRing *rxringptr = &XEmacPs_GetRxRing(&xemacpsif->emacps);
|
||||
|
||||
XEmacPs_BdRingPtrReset(txringptr, xemacpsif->tx_bdspace);
|
||||
XEmacPs_BdRingPtrReset(rxringptr, xemacpsif->rx_bdspace);
|
||||
|
||||
gigeversion = ((Xil_In32(xemacpsif->emacps.Config.BaseAddress + 0xFC)) >> 16) & 0xFFF;
|
||||
if (gigeversion > 2) {
|
||||
txqueuenum = 1;
|
||||
} else {
|
||||
txqueuenum = 0;
|
||||
}
|
||||
|
||||
XEmacPs_SetQueuePtr(&(xemacpsif->emacps), xemacpsif->emacps.RxBdRing.BaseBdAddr, 0, XEMACPS_RECV);
|
||||
XEmacPs_SetQueuePtr(&(xemacpsif->emacps), xemacpsif->emacps.TxBdRing.BaseBdAddr, txqueuenum, XEMACPS_SEND);
|
||||
}
|
||||
|
||||
void emac_disable_intr(void)
|
||||
{
|
||||
// XScuGic_DisableIntr(INTC_DIST_BASE_ADDR, emac_intr_num);
|
||||
rt_hw_interrupt_mask(emac_intr_num);
|
||||
}
|
||||
|
||||
void emac_enable_intr(void)
|
||||
{
|
||||
// XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, emac_intr_num);
|
||||
rt_hw_interrupt_umask(emac_intr_num);
|
||||
}
|
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
* Copyright (C) 2010 - 2019 Xilinx, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "netif/xemacpsif.h"
|
||||
#include "lwipopts.h"
|
||||
|
||||
#if XPAR_GIGE_PCS_PMA_1000BASEX_CORE_PRESENT == 1 || \
|
||||
XPAR_GIGE_PCS_PMA_SGMII_CORE_PRESENT == 1
|
||||
#define PCM_PMA_CORE_PRESENT
|
||||
#else
|
||||
#undef PCM_PMA_CORE_PRESENT
|
||||
#endif
|
||||
|
||||
u32_t link_speed = 100;
|
||||
extern XEmacPs_Config XEmacPs_ConfigTable[];
|
||||
extern u32_t phymapemac0[32];
|
||||
extern u32_t phymapemac1[32];
|
||||
extern u32_t phyaddrforemac;
|
||||
extern enum ethernet_link_status eth_link_status;
|
||||
|
||||
#ifdef OS_IS_FREERTOS
|
||||
extern long xInsideISR;
|
||||
#endif
|
||||
|
||||
XEmacPs_Config *xemacps_lookup_config(unsigned mac_base)
|
||||
{
|
||||
XEmacPs_Config *cfgptr = NULL;
|
||||
s32_t i;
|
||||
|
||||
for (i = 0; i < XPAR_XEMACPS_NUM_INSTANCES; i++) {
|
||||
if (XEmacPs_ConfigTable[i].BaseAddress == mac_base) {
|
||||
cfgptr = &XEmacPs_ConfigTable[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (cfgptr);
|
||||
}
|
||||
|
||||
void init_emacps(xemacpsif_s *xemacps, struct netif *netif)
|
||||
{
|
||||
XEmacPs *xemacpsp;
|
||||
s32_t status = XST_SUCCESS;
|
||||
u32_t i;
|
||||
u32_t phyfoundforemac0 = FALSE;
|
||||
u32_t phyfoundforemac1 = FALSE;
|
||||
|
||||
xemacpsp = &xemacps->emacps;
|
||||
|
||||
#ifdef ZYNQMP_USE_JUMBO
|
||||
XEmacPs_SetOptions(xemacpsp, XEMACPS_JUMBO_ENABLE_OPTION);
|
||||
#endif
|
||||
|
||||
#ifdef LWIP_IGMP
|
||||
XEmacPs_SetOptions(xemacpsp, XEMACPS_MULTICAST_OPTION);
|
||||
#endif
|
||||
|
||||
/* set mac address */
|
||||
status = XEmacPs_SetMacAddress(xemacpsp, (void*)(netif->hwaddr), 1);
|
||||
if (status != XST_SUCCESS) {
|
||||
xil_printf("In %s:Emac Mac Address set failed...\r\n",__func__);
|
||||
}
|
||||
|
||||
XEmacPs_SetMdioDivisor(xemacpsp, MDC_DIV_224);
|
||||
|
||||
/* Please refer to file header comments for the file xemacpsif_physpeed.c
|
||||
* to know more about the PHY programming sequence.
|
||||
* For PCS PMA core, phy_setup_emacps is called with the predefined PHY address
|
||||
* exposed through xaparemeters.h
|
||||
* For RGMII case, assuming multiple PHYs can be present on the MDIO bus,
|
||||
* detect_phy is called to get the addresses of the PHY present on
|
||||
* a particular MDIO bus (emac0 or emac1). This address map is populated
|
||||
* in phymapemac0 or phymapemac1.
|
||||
* phy_setup_emacps is then called for each PHY present on the MDIO bus.
|
||||
*/
|
||||
#ifdef PCM_PMA_CORE_PRESENT
|
||||
#ifdef XPAR_GIGE_PCS_PMA_1000BASEX_CORE_PRESENT
|
||||
link_speed = phy_setup_emacps(xemacpsp, XPAR_PCSPMA_1000BASEX_PHYADDR);
|
||||
#elif XPAR_GIGE_PCS_PMA_SGMII_CORE_PRESENT
|
||||
link_speed = phy_setup_emacps(xemacpsp, XPAR_PCSPMA_SGMII_PHYADDR);
|
||||
#endif
|
||||
#else
|
||||
detect_phy(xemacpsp);
|
||||
for (i = 31; i > 0; i--) {
|
||||
if (xemacpsp->Config.BaseAddress == XPAR_XEMACPS_0_BASEADDR) {
|
||||
if (phymapemac0[i] == TRUE) {
|
||||
link_speed = phy_setup_emacps(xemacpsp, i);
|
||||
phyfoundforemac0 = TRUE;
|
||||
phyaddrforemac = i;
|
||||
}
|
||||
} else {
|
||||
if (phymapemac1[i] == TRUE) {
|
||||
link_speed = phy_setup_emacps(xemacpsp, i);
|
||||
phyfoundforemac1 = TRUE;
|
||||
phyaddrforemac = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If no PHY was detected, use broadcast PHY address of 0 */
|
||||
if (xemacpsp->Config.BaseAddress == XPAR_XEMACPS_0_BASEADDR) {
|
||||
if (phyfoundforemac0 == FALSE)
|
||||
link_speed = phy_setup_emacps(xemacpsp, 0);
|
||||
} else {
|
||||
if (phyfoundforemac1 == FALSE)
|
||||
link_speed = phy_setup_emacps(xemacpsp, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (link_speed == XST_FAILURE) {
|
||||
eth_link_status = ETH_LINK_DOWN;
|
||||
xil_printf("Phy setup failure %s \n\r",__func__);
|
||||
return;
|
||||
} else {
|
||||
eth_link_status = ETH_LINK_UP;
|
||||
}
|
||||
|
||||
XEmacPs_SetOperatingSpeed(xemacpsp, link_speed);
|
||||
/* Setting the operating speed of the MAC needs a delay. */
|
||||
{
|
||||
volatile s32_t wait;
|
||||
for (wait=0; wait < 20000; wait++);
|
||||
}
|
||||
}
|
||||
|
||||
void init_emacps_on_error (xemacpsif_s *xemacps, struct netif *netif)
|
||||
{
|
||||
XEmacPs *xemacpsp;
|
||||
s32_t status = XST_SUCCESS;
|
||||
|
||||
xemacpsp = &xemacps->emacps;
|
||||
|
||||
/* set mac address */
|
||||
status = XEmacPs_SetMacAddress(xemacpsp, (void*)(netif->hwaddr), 1);
|
||||
if (status != XST_SUCCESS) {
|
||||
xil_printf("In %s:Emac Mac Address set failed...\r\n",__func__);
|
||||
}
|
||||
|
||||
XEmacPs_SetOperatingSpeed(xemacpsp, link_speed);
|
||||
|
||||
/* Setting the operating speed of the MAC needs a delay. */
|
||||
{
|
||||
volatile s32_t wait;
|
||||
for (wait=0; wait < 20000; wait++);
|
||||
}
|
||||
}
|
||||
|
||||
void setup_isr (struct xemac_s *xemac)
|
||||
{
|
||||
xemacpsif_s *xemacpsif;
|
||||
|
||||
xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
/*
|
||||
* Setup callbacks
|
||||
*/
|
||||
XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMASEND,
|
||||
(void *) emacps_send_handler,
|
||||
(void *) xemac);
|
||||
|
||||
XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMARECV,
|
||||
(void *) emacps_recv_handler,
|
||||
(void *) xemac);
|
||||
|
||||
XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_ERROR,
|
||||
(void *) emacps_error_handler,
|
||||
(void *) xemac);
|
||||
}
|
||||
|
||||
void start_emacps (xemacpsif_s *xemacps)
|
||||
{
|
||||
/* start the temac */
|
||||
XEmacPs_Start(&xemacps->emacps);
|
||||
}
|
||||
|
||||
void restart_emacps_transmitter (xemacpsif_s *xemacps) {
|
||||
u32_t Reg;
|
||||
Reg = XEmacPs_ReadReg(xemacps->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
Reg = Reg & (~XEMACPS_NWCTRL_TXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacps->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, Reg);
|
||||
|
||||
Reg = XEmacPs_ReadReg(xemacps->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET);
|
||||
Reg = Reg | (XEMACPS_NWCTRL_TXEN_MASK);
|
||||
XEmacPs_WriteReg(xemacps->emacps.Config.BaseAddress,
|
||||
XEMACPS_NWCTRL_OFFSET, Reg);
|
||||
}
|
||||
|
||||
void emacps_error_handler(void *arg,u8 Direction, u32 ErrorWord)
|
||||
{
|
||||
struct xemac_s *xemac;
|
||||
xemacpsif_s *xemacpsif;
|
||||
XEmacPs_BdRing *rxring;
|
||||
XEmacPs_BdRing *txring;
|
||||
#ifdef OS_IS_FREERTOS
|
||||
xInsideISR++;
|
||||
#endif
|
||||
|
||||
xemac = (struct xemac_s *)(arg);
|
||||
xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
rxring = &XEmacPs_GetRxRing(&xemacpsif->emacps);
|
||||
txring = &XEmacPs_GetTxRing(&xemacpsif->emacps);
|
||||
|
||||
if (ErrorWord != 0) {
|
||||
switch (Direction) {
|
||||
case XEMACPS_RECV:
|
||||
if (ErrorWord & XEMACPS_RXSR_HRESPNOK_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Receive DMA error\r\n"));
|
||||
HandleEmacPsError(xemac);
|
||||
}
|
||||
if (ErrorWord & XEMACPS_RXSR_RXOVR_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Receive over run\r\n"));
|
||||
emacps_recv_handler(arg);
|
||||
setup_rx_bds(xemacpsif, rxring);
|
||||
}
|
||||
if (ErrorWord & XEMACPS_RXSR_BUFFNA_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Receive buffer not available\r\n"));
|
||||
emacps_recv_handler(arg);
|
||||
setup_rx_bds(xemacpsif, rxring);
|
||||
}
|
||||
break;
|
||||
case XEMACPS_SEND:
|
||||
if (ErrorWord & XEMACPS_TXSR_HRESPNOK_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Transmit DMA error\r\n"));
|
||||
HandleEmacPsError(xemac);
|
||||
}
|
||||
if (ErrorWord & XEMACPS_TXSR_URUN_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Transmit under run\r\n"));
|
||||
HandleTxErrors(xemac);
|
||||
}
|
||||
if (ErrorWord & XEMACPS_TXSR_BUFEXH_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Transmit buffer exhausted\r\n"));
|
||||
HandleTxErrors(xemac);
|
||||
}
|
||||
if (ErrorWord & XEMACPS_TXSR_RXOVR_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Transmit retry excessed limits\r\n"));
|
||||
HandleTxErrors(xemac);
|
||||
}
|
||||
if (ErrorWord & XEMACPS_TXSR_FRAMERX_MASK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Transmit collision\r\n"));
|
||||
// process_sent_bds(xemacpsif, txring);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef OS_IS_FREERTOS
|
||||
xInsideISR--;
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2010 - 2019 Xilinx, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XEMACPSIF_HW_H_
|
||||
#define __XEMACPSIF_HW_H_
|
||||
|
||||
#include "netif/xemacpsif.h"
|
||||
#include "lwip/netif.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
XEmacPs_Config * lookup_config(unsigned mac_base);
|
||||
|
||||
void init_emacps(xemacpsif_s *xemacpsif, struct netif *netif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
|
||||
* Copyright (C) 2007 - 2018 Xilinx, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef __XLWIPCONFIG_H_
|
||||
#define __XLWIPCONFIG_H_
|
||||
|
||||
|
||||
/* This is a generated file - do not edit */
|
||||
|
||||
#define XLWIP_CONFIG_INCLUDE_GEM 1
|
||||
#define XLWIP_CONFIG_EMAC_NUMBER 0
|
||||
#define XLWIP_CONFIG_N_TX_DESC 64
|
||||
#define XLWIP_CONFIG_N_RX_DESC 64
|
||||
|
||||
#endif
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (C) 2007 - 2019 Xilinx, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "netif/xpqueue.h"
|
||||
#include "xil_printf.h"
|
||||
|
||||
#define NUM_QUEUES 2
|
||||
|
||||
pq_queue_t pq_queue[NUM_QUEUES];
|
||||
|
||||
pq_queue_t *
|
||||
pq_create_queue()
|
||||
{
|
||||
static int i;
|
||||
pq_queue_t *q = NULL;
|
||||
|
||||
if (i >= NUM_QUEUES) {
|
||||
xil_printf("ERR: Max Queues allocated\n\r");
|
||||
return q;
|
||||
}
|
||||
|
||||
q = &pq_queue[i++];
|
||||
|
||||
if (!q)
|
||||
return q;
|
||||
|
||||
q->head = q->tail = q->len = 0;
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
int
|
||||
pq_enqueue(pq_queue_t *q, void *p)
|
||||
{
|
||||
if (q->len == PQ_QUEUE_SIZE)
|
||||
return -1;
|
||||
|
||||
q->data[q->head] = p;
|
||||
q->head = (q->head + 1)%PQ_QUEUE_SIZE;
|
||||
q->len++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void*
|
||||
pq_dequeue(pq_queue_t *q)
|
||||
{
|
||||
int ptail;
|
||||
|
||||
if (q->len == 0)
|
||||
return NULL;
|
||||
|
||||
ptail = q->tail;
|
||||
q->tail = (q->tail + 1)%PQ_QUEUE_SIZE;
|
||||
q->len--;
|
||||
|
||||
return q->data[ptail];
|
||||
}
|
||||
|
||||
int
|
||||
pq_qlength(pq_queue_t *q)
|
||||
{
|
||||
return q->len;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#include "netif/xtopology.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
struct xtopology_t xtopology[] = {
|
||||
{
|
||||
0xFF0E0000,
|
||||
xemac_type_emacps,
|
||||
0x0,
|
||||
0x0,
|
||||
0xF8F00100,
|
||||
XPAR_XEMACPS_3_INTR,
|
||||
},
|
||||
};
|
||||
|
||||
int xtopology_n_emacs = 1;
|
|
@ -54,6 +54,9 @@ typedef long LONG;
|
|||
typedef unsigned long ULONG;
|
||||
#endif
|
||||
|
||||
#define ULONG64_HI_MASK 0xFFFFFFFF00000000U
|
||||
#define ULONG64_LO_MASK ~ULONG64_HI_MASK
|
||||
|
||||
/** @{ */
|
||||
/**
|
||||
* This data type defines an interrupt handler for a device.
|
||||
|
|
|
@ -0,0 +1,349 @@
|
|||
/*
|
||||
* Copyright (c) 2021, WangHuachen
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-5-10 WangHuachen the first version
|
||||
*/
|
||||
|
||||
|
||||
#include "board.h"
|
||||
#include <netif/ethernetif.h>
|
||||
#include "lwipopts.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "drv_eth.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "netif/xadapter.h"
|
||||
#include "netif/xemacpsif.h"
|
||||
#include "xparameters.h"
|
||||
#include "xemacps.h"
|
||||
|
||||
#define DBG_TAG "drv.emac"
|
||||
#define DBG_LEVEL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
|
||||
#define MAC_BASE_ADDR XPAR_PSU_ETHERNET_3_BASEADDR
|
||||
#define MAX_ADDR_LEN 6
|
||||
|
||||
struct rt_zynqmp_eth
|
||||
{
|
||||
/* inherit from ethernet device */
|
||||
struct eth_device parent;
|
||||
|
||||
/* interface address info, hw address */
|
||||
rt_uint8_t dev_addr[MAX_ADDR_LEN];
|
||||
|
||||
struct xemac_s *xemac;
|
||||
};
|
||||
|
||||
static struct rt_zynqmp_eth zynqmp_eth_device;
|
||||
extern XEmacPs_Config *mac_config;
|
||||
extern struct netif *NetIf;
|
||||
|
||||
static void rt_hw_eth_isr(int irqno, void *param)
|
||||
{
|
||||
struct rt_zynqmp_eth *eth_dev = (struct rt_zynqmp_eth *)param;
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *)eth_dev->xemac->state;
|
||||
XEmacPs_IntrHandler(&xemacpsif->emacps);
|
||||
}
|
||||
|
||||
extern enum ethernet_link_status eth_link_status;
|
||||
extern u32_t phy_link_detect(XEmacPs *xemacp, u32_t phy_addr);
|
||||
extern u32_t phy_autoneg_status(XEmacPs *xemacp, u32_t phy_addr);
|
||||
extern u32_t phyaddrforemac;
|
||||
|
||||
void rt_zynqmp_eth_link_detect(struct rt_zynqmp_eth *eth_dev)
|
||||
{
|
||||
u32_t link_speed, phy_link_status;
|
||||
struct xemac_s *xemac = eth_dev->xemac;
|
||||
xemacpsif_s *xemacs = (xemacpsif_s *)(xemac->state);
|
||||
XEmacPs *xemacp = &xemacs->emacps;
|
||||
|
||||
if ((xemacp->IsReady != (u32)XIL_COMPONENT_IS_READY) ||
|
||||
(eth_link_status == ETH_LINK_UNDEFINED))
|
||||
return;
|
||||
|
||||
phy_link_status = phy_link_detect(xemacp, phyaddrforemac);
|
||||
|
||||
if ((eth_link_status == ETH_LINK_UP) && (!phy_link_status))
|
||||
eth_link_status = ETH_LINK_DOWN;
|
||||
|
||||
switch (eth_link_status) {
|
||||
case ETH_LINK_UNDEFINED:
|
||||
case ETH_LINK_UP:
|
||||
return;
|
||||
case ETH_LINK_DOWN:
|
||||
eth_device_linkchange(&zynqmp_eth_device.parent, RT_FALSE);
|
||||
eth_link_status = ETH_LINK_NEGOTIATING;
|
||||
LOG_D("Ethernet Link down");
|
||||
break;
|
||||
case ETH_LINK_NEGOTIATING:
|
||||
if (phy_link_status &&
|
||||
phy_autoneg_status(xemacp, phyaddrforemac)) {
|
||||
|
||||
/* Initiate Phy setup to get link speed */
|
||||
link_speed = phy_setup_emacps(xemacp,
|
||||
phyaddrforemac);
|
||||
XEmacPs_SetOperatingSpeed(xemacp, link_speed);
|
||||
|
||||
eth_device_linkchange(&zynqmp_eth_device.parent, RT_TRUE);
|
||||
eth_link_status = ETH_LINK_UP;
|
||||
LOG_D("Ethernet Link up");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void phy_monitor_thread(void *parameter)
|
||||
{
|
||||
struct rt_zynqmp_eth *eth_dev = (struct rt_zynqmp_eth *)parameter;
|
||||
|
||||
while (1)
|
||||
{
|
||||
rt_zynqmp_eth_link_detect(eth_dev);
|
||||
rt_thread_delay(RT_TICK_PER_SECOND);
|
||||
}
|
||||
}
|
||||
|
||||
static rt_err_t rt_zynqmp_eth_init(rt_device_t dev)
|
||||
{
|
||||
struct rt_zynqmp_eth *eth_dev = (struct rt_zynqmp_eth *)dev->user_data;
|
||||
struct netif *netif = eth_dev->parent.netif;
|
||||
struct xemac_s *xemac;
|
||||
xemacpsif_s *xemacpsif;
|
||||
u32 dmacrreg;
|
||||
s32_t status = XST_SUCCESS;
|
||||
struct xtopology_t *xtopologyp;
|
||||
|
||||
if (eth_dev->xemac != RT_NULL)
|
||||
{
|
||||
LOG_W("rt_zynqmp_eth_init: device has been initialized");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
NetIf = netif;
|
||||
|
||||
xemacpsif = rt_malloc(sizeof *xemacpsif);
|
||||
if (xemacpsif == NULL)
|
||||
{
|
||||
LOG_E("rt_zynqmp_eth_init: out of memory");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
xemac = rt_malloc(sizeof *xemac);
|
||||
if (xemac == NULL)
|
||||
{
|
||||
LOG_E("rt_zynqmp_eth_init: out of memory");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
xemac->state = (void *)xemacpsif;
|
||||
xemac->topology_index = xtopology_find_index(MAC_BASE_ADDR);
|
||||
xemac->type = xemac_type_emacps;
|
||||
xemac->rt_eth_device = ð_dev->parent;
|
||||
|
||||
xemacpsif->send_q = NULL;
|
||||
xemacpsif->recv_q = pq_create_queue();
|
||||
if (!xemacpsif->recv_q)
|
||||
return -RT_ENOMEM;
|
||||
|
||||
eth_dev->xemac = xemac;
|
||||
|
||||
/* obtain config of this emac */
|
||||
mac_config = (XEmacPs_Config *)xemacps_lookup_config(MAC_BASE_ADDR);
|
||||
|
||||
status = XEmacPs_CfgInitialize(&xemacpsif->emacps, mac_config,
|
||||
mac_config->BaseAddress);
|
||||
if (status != XST_SUCCESS)
|
||||
{
|
||||
LOG_W("In %s:EmacPs Configuration Failed....", __func__);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
/* initialize the mac */
|
||||
init_emacps(xemacpsif, netif);
|
||||
|
||||
dmacrreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_DMACR_OFFSET);
|
||||
dmacrreg = dmacrreg | (0x00000010);
|
||||
XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
|
||||
XEMACPS_DMACR_OFFSET, dmacrreg);
|
||||
|
||||
setup_isr(xemac);
|
||||
init_dma(xemac);
|
||||
|
||||
xtopologyp = &xtopology[xemac->topology_index];
|
||||
/*
|
||||
* Connect the device driver handler that will be called when an
|
||||
* interrupt for the device occurs, the handler defined above performs
|
||||
* the specific interrupt processing for the device.
|
||||
*/
|
||||
rt_hw_interrupt_install(xtopologyp->scugic_emac_intr, rt_hw_eth_isr, (void *)eth_dev, "eth");
|
||||
/*
|
||||
* Enable the interrupt for emacps.
|
||||
*/
|
||||
rt_hw_interrupt_umask(xtopologyp->scugic_emac_intr);
|
||||
|
||||
start_emacps(xemacpsif);
|
||||
|
||||
if (eth_link_status == ETH_LINK_UP)
|
||||
eth_device_linkchange(ð_dev->parent, RT_TRUE);
|
||||
|
||||
rt_thread_t tid;
|
||||
tid = rt_thread_create("phylnk",
|
||||
phy_monitor_thread,
|
||||
eth_dev,
|
||||
1024,
|
||||
RT_THREAD_PRIORITY_MAX - 2,
|
||||
2);
|
||||
if (tid != RT_NULL)
|
||||
rt_thread_startup(tid);
|
||||
else
|
||||
return -RT_ERROR;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t rt_zynqmp_eth_open(rt_device_t dev, rt_uint16_t oflag)
|
||||
{
|
||||
LOG_D("emac open");
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t rt_zynqmp_eth_close(rt_device_t dev)
|
||||
{
|
||||
LOG_D("emac close");
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_size_t rt_zynqmp_eth_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
|
||||
{
|
||||
LOG_D("emac read");
|
||||
rt_set_errno(-RT_ENOSYS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static rt_size_t rt_zynqmp_eth_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
|
||||
{
|
||||
LOG_D("emac write");
|
||||
rt_set_errno(-RT_ENOSYS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static rt_err_t rt_zynqmp_eth_control(rt_device_t dev, int cmd, void *args)
|
||||
{
|
||||
struct rt_zynqmp_eth *eth_dev = (struct rt_zynqmp_eth *)dev->user_data;
|
||||
switch (cmd)
|
||||
{
|
||||
case NIOCTL_GADDR:
|
||||
/* get mac address */
|
||||
if (args) rt_memcpy(args, eth_dev->dev_addr, 6);
|
||||
else return -RT_ERROR;
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
extern err_t _unbuffered_low_level_output(xemacpsif_s *xemacpsif, struct pbuf *p);
|
||||
rt_err_t rt_zynqmp_eth_tx(rt_device_t dev, struct pbuf *p)
|
||||
{
|
||||
rt_base_t lev;
|
||||
rt_err_t err;
|
||||
XEmacPs_BdRing *txring;
|
||||
|
||||
struct rt_zynqmp_eth *eth_dev = (struct rt_zynqmp_eth *)dev->user_data;
|
||||
struct xemac_s *xemac = eth_dev->xemac;
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
|
||||
lev = rt_hw_interrupt_disable();
|
||||
|
||||
txring = &(XEmacPs_GetTxRing(&xemacpsif->emacps));
|
||||
process_sent_bds(xemacpsif, txring);
|
||||
|
||||
if (is_tx_space_available(xemacpsif))
|
||||
{
|
||||
_unbuffered_low_level_output(xemacpsif, p);
|
||||
err = RT_EOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LINK_STATS
|
||||
lwip_stats.link.drop++;
|
||||
#endif
|
||||
LOG_D("pack dropped, no space");
|
||||
err = -RT_ENOMEM;
|
||||
}
|
||||
|
||||
rt_hw_interrupt_enable(lev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
struct pbuf *rt_zynqmp_eth_rx(rt_device_t dev)
|
||||
{
|
||||
rt_base_t lev;
|
||||
struct rt_zynqmp_eth *eth_dev = (struct rt_zynqmp_eth *)dev->user_data;
|
||||
struct xemac_s *xemac = eth_dev->xemac;
|
||||
xemacpsif_s *xemacpsif = (xemacpsif_s *)(xemac->state);
|
||||
struct pbuf *p;
|
||||
|
||||
lev = rt_hw_interrupt_disable();
|
||||
|
||||
/* see if there is data to process */
|
||||
if (pq_qlength(xemacpsif->recv_q) == 0)
|
||||
return NULL;
|
||||
|
||||
/* return one packet from receive q */
|
||||
p = (struct pbuf *)pq_dequeue(xemacpsif->recv_q);
|
||||
|
||||
rt_hw_interrupt_enable(lev);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static int rt_hw_zynqmp_eth_init(void)
|
||||
{
|
||||
rt_err_t state = RT_EOK;
|
||||
|
||||
zynqmp_eth_device.xemac = RT_NULL;
|
||||
|
||||
zynqmp_eth_device.dev_addr[0] = 0x00;
|
||||
zynqmp_eth_device.dev_addr[1] = 0x0A;
|
||||
zynqmp_eth_device.dev_addr[2] = 0x35;
|
||||
zynqmp_eth_device.dev_addr[3] = 0x00;
|
||||
zynqmp_eth_device.dev_addr[4] = 0x01;
|
||||
zynqmp_eth_device.dev_addr[5] = 0x02;
|
||||
|
||||
zynqmp_eth_device.parent.parent.init = rt_zynqmp_eth_init;
|
||||
zynqmp_eth_device.parent.parent.open = rt_zynqmp_eth_open;
|
||||
zynqmp_eth_device.parent.parent.close = rt_zynqmp_eth_close;
|
||||
zynqmp_eth_device.parent.parent.read = rt_zynqmp_eth_read;
|
||||
zynqmp_eth_device.parent.parent.write = rt_zynqmp_eth_write;
|
||||
zynqmp_eth_device.parent.parent.control = rt_zynqmp_eth_control;
|
||||
zynqmp_eth_device.parent.parent.user_data = &zynqmp_eth_device;
|
||||
|
||||
zynqmp_eth_device.parent.eth_rx = rt_zynqmp_eth_rx;
|
||||
zynqmp_eth_device.parent.eth_tx = rt_zynqmp_eth_tx;
|
||||
|
||||
/* register eth device */
|
||||
state = eth_device_init(&(zynqmp_eth_device.parent), "e0");
|
||||
if (RT_EOK == state)
|
||||
{
|
||||
LOG_D("emac device init success");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("emac device init faild: %d", state);
|
||||
state = -RT_ERROR;
|
||||
return state;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(rt_hw_zynqmp_eth_init);
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef __DRV_ETH_H__
|
||||
#define __DRV_ETH_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -19,6 +19,9 @@
|
|||
#define RT_USING_TIMER_SOFT
|
||||
#define RT_TIMER_THREAD_PRIO 4
|
||||
#define RT_TIMER_THREAD_STACK_SIZE 512
|
||||
|
||||
/* kservice optimization */
|
||||
|
||||
#define RT_DEBUG
|
||||
|
||||
/* Inter-Thread communication */
|
||||
|
@ -32,7 +35,7 @@
|
|||
/* Memory Management */
|
||||
|
||||
#define RT_USING_MEMPOOL
|
||||
#define RT_USING_SMALL_MEM
|
||||
#define RT_USING_SLAB
|
||||
#define RT_USING_HEAP
|
||||
|
||||
/* Kernel Device Object */
|
||||
|
@ -41,7 +44,7 @@
|
|||
#define RT_USING_CONSOLE
|
||||
#define RT_CONSOLEBUF_SIZE 128
|
||||
#define RT_CONSOLE_DEVICE_NAME "uart0"
|
||||
#define RT_VER_NUM 0x40003
|
||||
#define RT_VER_NUM 0x40004
|
||||
|
||||
/* RT-Thread Components */
|
||||
|
||||
|
@ -83,6 +86,8 @@
|
|||
#define RT_DFS_ELM_WORD_ACCESS
|
||||
#define RT_DFS_ELM_USE_LFN_3
|
||||
#define RT_DFS_ELM_USE_LFN 3
|
||||
#define RT_DFS_ELM_LFN_UNICODE_0
|
||||
#define RT_DFS_ELM_LFN_UNICODE 0
|
||||
#define RT_DFS_ELM_MAX_LFN 255
|
||||
#define RT_DFS_ELM_DRIVES 2
|
||||
#define RT_DFS_ELM_MAX_SECTOR_SIZE 512
|
||||
|
@ -93,6 +98,9 @@
|
|||
|
||||
#define RT_USING_DEVICE_IPC
|
||||
#define RT_PIPE_BUFSZ 512
|
||||
#define RT_USING_SYSTEM_WORKQUEUE
|
||||
#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048
|
||||
#define RT_SYSTEM_WORKQUEUE_PRIORITY 23
|
||||
#define RT_USING_SERIAL
|
||||
#define RT_SERIAL_USING_DMA
|
||||
#define RT_SERIAL_RB_BUFSZ 64
|
||||
|
@ -101,24 +109,77 @@
|
|||
/* Using USB */
|
||||
|
||||
|
||||
/* Using RapidIO */
|
||||
|
||||
|
||||
/* POSIX layer and C standard library */
|
||||
|
||||
#define RT_USING_LIBC
|
||||
#define RT_USING_POSIX
|
||||
#define RT_LIBC_FIXED_TIMEZONE 8
|
||||
|
||||
/* Network */
|
||||
|
||||
/* Socket abstraction layer */
|
||||
|
||||
#define RT_USING_SAL
|
||||
#define SAL_INTERNET_CHECK
|
||||
|
||||
/* protocol stack implement */
|
||||
|
||||
#define SAL_USING_LWIP
|
||||
#define SAL_USING_POSIX
|
||||
|
||||
/* Network interface device */
|
||||
|
||||
#define RT_USING_NETDEV
|
||||
#define NETDEV_USING_IFCONFIG
|
||||
#define NETDEV_USING_PING
|
||||
#define NETDEV_USING_NETSTAT
|
||||
#define NETDEV_USING_AUTO_DEFAULT
|
||||
#define NETDEV_IPV4 1
|
||||
#define NETDEV_IPV6 0
|
||||
|
||||
/* light weight TCP/IP stack */
|
||||
|
||||
#define RT_USING_LWIP
|
||||
#define RT_USING_LWIP202
|
||||
#define RT_LWIP_MEM_ALIGNMENT 32
|
||||
#define RT_LWIP_IGMP
|
||||
#define RT_LWIP_ICMP
|
||||
#define RT_LWIP_DNS
|
||||
#define RT_LWIP_DHCP
|
||||
#define IP_SOF_BROADCAST 1
|
||||
#define IP_SOF_BROADCAST_RECV 1
|
||||
|
||||
/* Static IPv4 Address */
|
||||
|
||||
#define RT_LWIP_IPADDR "192.168.1.30"
|
||||
#define RT_LWIP_GWADDR "192.168.1.1"
|
||||
#define RT_LWIP_MSKADDR "255.255.255.0"
|
||||
#define RT_LWIP_UDP
|
||||
#define RT_LWIP_TCP
|
||||
#define RT_LWIP_RAW
|
||||
#define RT_MEMP_NUM_NETCONN 8
|
||||
#define RT_LWIP_PBUF_NUM 256
|
||||
#define RT_LWIP_RAW_PCB_NUM 4
|
||||
#define RT_LWIP_UDP_PCB_NUM 4
|
||||
#define RT_LWIP_TCP_PCB_NUM 4
|
||||
#define RT_LWIP_TCP_SEG_NUM 40
|
||||
#define RT_LWIP_TCP_SND_BUF 8196
|
||||
#define RT_LWIP_TCP_WND 8196
|
||||
#define RT_LWIP_TCPTHREAD_PRIORITY 10
|
||||
#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8
|
||||
#define RT_LWIP_TCPTHREAD_STACKSIZE 2048
|
||||
#define RT_LWIP_ETHTHREAD_PRIORITY 12
|
||||
#define RT_LWIP_ETHTHREAD_STACKSIZE 1024
|
||||
#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8
|
||||
#define LWIP_NETIF_STATUS_CALLBACK 1
|
||||
#define LWIP_NETIF_LINK_CALLBACK 1
|
||||
#define SO_REUSE 1
|
||||
#define LWIP_SO_RCVTIMEO 1
|
||||
#define LWIP_SO_SNDTIMEO 1
|
||||
#define LWIP_SO_RCVBUF 1
|
||||
#define LWIP_SO_LINGER 0
|
||||
#define LWIP_NETIF_LOOPBACK 0
|
||||
#define RT_LWIP_USING_PING
|
||||
|
||||
/* AT commands */
|
||||
|
||||
|
@ -129,6 +190,9 @@
|
|||
/* Utilities */
|
||||
|
||||
|
||||
/* RT-Thread Utestcases */
|
||||
|
||||
|
||||
/* RT-Thread online packages */
|
||||
|
||||
/* IoT - internet of things */
|
||||
|
@ -166,11 +230,17 @@
|
|||
/* peripheral libraries and drivers */
|
||||
|
||||
|
||||
/* AI packages */
|
||||
|
||||
|
||||
/* miscellaneous packages */
|
||||
|
||||
|
||||
/* samples: kernel and components samples */
|
||||
|
||||
|
||||
/* entertainment: terminal games and other interesting software packages */
|
||||
|
||||
#define SOC_ZYNQMP_R5
|
||||
|
||||
/* Hardware Drivers Config */
|
||||
|
@ -184,6 +254,13 @@
|
|||
#define BSP_USING_SDIO
|
||||
#define BSP_USING_SD0
|
||||
|
||||
/* Please set RT_LWIP_PBUF_NUM is at least 256 if Enable Ethernet! */
|
||||
|
||||
/* Please set RT_LWIP_MEM_ALIGNMENT is at 32 if Enable Ethernet! */
|
||||
|
||||
#define BSP_USING_ETH
|
||||
#define RT_LWIP_PBUF_POOL_BUFSIZE 1700
|
||||
|
||||
/* Board extended module Drivers */
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (c) 2014 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (c) 2021 WangHuachen. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-03-19 WangHuachen first version
|
||||
* 2021-05-10 WangHuachen add more functions
|
||||
*/
|
||||
#include <rthw.h>
|
||||
#include <rtdef.h>
|
||||
|
@ -44,41 +46,85 @@ typedef rt_uint32_t u32;
|
|||
XREG_CP15_INVAL_IC_LINE_MVA_POU :: "r" (param))
|
||||
#endif
|
||||
|
||||
void Xil_DCacheEnable(void);
|
||||
void Xil_DCacheDisable(void);
|
||||
void Xil_DCacheInvalidate(void);
|
||||
void Xil_DCacheInvalidateRange(INTPTR adr, u32 len);
|
||||
void Xil_DCacheFlush(void);
|
||||
void Xil_DCacheFlushRange(INTPTR adr, u32 len);
|
||||
void Xil_DCacheInvalidateLine(INTPTR adr);
|
||||
void Xil_DCacheFlushLine(INTPTR adr);
|
||||
void Xil_DCacheStoreLine(INTPTR adr);
|
||||
void Xil_ICacheEnable(void);
|
||||
void Xil_ICacheDisable(void);
|
||||
void Xil_ICacheInvalidate(void);
|
||||
void Xil_ICacheInvalidateRange(INTPTR adr, u32 len);
|
||||
void Xil_ICacheInvalidateLine(INTPTR adr);
|
||||
|
||||
void Xil_ICacheInvalidateRange(INTPTR adr, u32 len)
|
||||
void Xil_DCacheEnable(void)
|
||||
{
|
||||
register u32 CtrlReg;
|
||||
|
||||
/* enable caches only if they are disabled */
|
||||
#if defined (__GNUC__)
|
||||
CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
|
||||
#elif defined (__ICCARM__)
|
||||
mfcp(XREG_CP15_SYS_CONTROL,CtrlReg);
|
||||
#endif
|
||||
if ((CtrlReg & XREG_CP15_CONTROL_C_BIT)==0x00000000U) {
|
||||
/* invalidate the Data cache */
|
||||
Xil_DCacheInvalidate();
|
||||
|
||||
/* enable the Data cache */
|
||||
CtrlReg |= (XREG_CP15_CONTROL_C_BIT);
|
||||
|
||||
mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
|
||||
}
|
||||
}
|
||||
|
||||
void Xil_DCacheDisable(void)
|
||||
{
|
||||
register u32 CtrlReg;
|
||||
|
||||
/* clean and invalidate the Data cache */
|
||||
Xil_DCacheFlush();
|
||||
|
||||
/* disable the Data cache */
|
||||
#if defined (__GNUC__)
|
||||
CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
|
||||
#elif defined (__ICCARM__)
|
||||
mfcp(XREG_CP15_SYS_CONTROL,CtrlReg);
|
||||
#endif
|
||||
|
||||
CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT);
|
||||
|
||||
mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
|
||||
}
|
||||
|
||||
void Xil_DCacheInvalidate(void)
|
||||
{
|
||||
u32 LocalAddr = adr;
|
||||
const u32 cacheline = 32U;
|
||||
u32 end;
|
||||
u32 currmask;
|
||||
|
||||
currmask = mfcpsr();
|
||||
mtcpsr(currmask | IRQ_FIQ_MASK);
|
||||
if (len != 0x00000000U) {
|
||||
/* Back the starting address up to the start of a cache line
|
||||
* perform cache operations until adr+len
|
||||
*/
|
||||
end = LocalAddr + len;
|
||||
LocalAddr = LocalAddr & ~(cacheline - 1U);
|
||||
|
||||
/* Select cache L0 I-cache in CSSR */
|
||||
mtcp(XREG_CP15_CACHE_SIZE_SEL, 1U);
|
||||
#if 0
|
||||
stack_end = (u32 )&_stack_end;
|
||||
stack_start = (u32 )&__undef_stack;
|
||||
stack_size = stack_start-stack_end;
|
||||
|
||||
while (LocalAddr < end) {
|
||||
/* Flush stack memory to save return address */
|
||||
Xil_DCacheFlushRange(stack_end, stack_size);
|
||||
#endif
|
||||
mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
|
||||
|
||||
/* Invalidate L1 I-cache line */
|
||||
asm_inval_ic_line_mva_pou(LocalAddr);
|
||||
/*invalidate all D cache*/
|
||||
mtcp(XREG_CP15_INVAL_DC_ALL, 0);
|
||||
|
||||
LocalAddr += cacheline;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for invalidate to complete */
|
||||
dsb();
|
||||
mtcpsr(currmask);
|
||||
}
|
||||
|
||||
void Xil_DCacheFlushLine(INTPTR adr)
|
||||
void Xil_DCacheInvalidateLine(INTPTR adr)
|
||||
{
|
||||
u32 currmask;
|
||||
|
||||
|
@ -86,11 +132,11 @@ void Xil_DCacheFlushLine(INTPTR adr)
|
|||
mtcpsr(currmask | IRQ_FIQ_MASK);
|
||||
|
||||
mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
|
||||
mtcp(XREG_CP15_INVAL_DC_LINE_MVA_POC, (adr & (~0x1F)));
|
||||
|
||||
mtcp(XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC, (adr & (~0x1F)));
|
||||
|
||||
/* Wait for flush to complete */
|
||||
/* Wait for invalidate to complete */
|
||||
dsb();
|
||||
|
||||
mtcpsr(currmask);
|
||||
}
|
||||
|
||||
|
@ -135,6 +181,79 @@ void Xil_DCacheInvalidateRange(INTPTR adr, u32 len)
|
|||
mtcpsr(currmask);
|
||||
}
|
||||
|
||||
void Xil_DCacheFlush(void)
|
||||
{
|
||||
register u32 CsidReg, C7Reg;
|
||||
u32 CacheSize, LineSize, NumWays;
|
||||
u32 Way, WayIndex, Set, SetIndex, NumSet;
|
||||
u32 currmask;
|
||||
|
||||
currmask = mfcpsr();
|
||||
mtcpsr(currmask | IRQ_FIQ_MASK);
|
||||
|
||||
/* Select cache level 0 and D cache in CSSR */
|
||||
mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
|
||||
|
||||
#if defined (__GNUC__)
|
||||
CsidReg = mfcp(XREG_CP15_CACHE_SIZE_ID);
|
||||
#elif defined (__ICCARM__)
|
||||
mfcp(XREG_CP15_CACHE_SIZE_ID,CsidReg);
|
||||
#endif
|
||||
/* Determine Cache Size */
|
||||
|
||||
CacheSize = (CsidReg >> 13U) & 0x000001FFU;
|
||||
CacheSize += 0x00000001U;
|
||||
CacheSize *= (u32)128; /* to get number of bytes */
|
||||
|
||||
/* Number of Ways */
|
||||
NumWays = (CsidReg & 0x000003ffU) >> 3U;
|
||||
NumWays += 0x00000001U;
|
||||
|
||||
/* Get the cacheline size, way size, index size from csidr */
|
||||
LineSize = (CsidReg & 0x00000007U) + 0x00000004U;
|
||||
|
||||
NumSet = CacheSize/NumWays;
|
||||
NumSet /= (0x00000001U << LineSize);
|
||||
|
||||
Way = 0U;
|
||||
Set = 0U;
|
||||
|
||||
/* Invalidate all the cachelines */
|
||||
for (WayIndex = 0U; WayIndex < NumWays; WayIndex++) {
|
||||
for (SetIndex = 0U; SetIndex < NumSet; SetIndex++) {
|
||||
C7Reg = Way | Set;
|
||||
/* Flush by Set/Way */
|
||||
asm_clean_inval_dc_line_sw(C7Reg);
|
||||
|
||||
Set += (0x00000001U << LineSize);
|
||||
}
|
||||
Set = 0U;
|
||||
Way += 0x40000000U;
|
||||
}
|
||||
|
||||
/* Wait for flush to complete */
|
||||
dsb();
|
||||
mtcpsr(currmask);
|
||||
|
||||
mtcpsr(currmask);
|
||||
}
|
||||
|
||||
void Xil_DCacheFlushLine(INTPTR adr)
|
||||
{
|
||||
u32 currmask;
|
||||
|
||||
currmask = mfcpsr();
|
||||
mtcpsr(currmask | IRQ_FIQ_MASK);
|
||||
|
||||
mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
|
||||
|
||||
mtcp(XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC, (adr & (~0x1F)));
|
||||
|
||||
/* Wait for flush to complete */
|
||||
dsb();
|
||||
mtcpsr(currmask);
|
||||
}
|
||||
|
||||
void Xil_DCacheFlushRange(INTPTR adr, u32 len)
|
||||
{
|
||||
u32 LocalAddr = adr;
|
||||
|
@ -163,6 +282,130 @@ void Xil_DCacheFlushRange(INTPTR adr, u32 len)
|
|||
mtcpsr(currmask);
|
||||
}
|
||||
|
||||
void Xil_DCacheStoreLine(INTPTR adr)
|
||||
{
|
||||
u32 currmask;
|
||||
|
||||
currmask = mfcpsr();
|
||||
mtcpsr(currmask | IRQ_FIQ_MASK);
|
||||
|
||||
mtcp(XREG_CP15_CACHE_SIZE_SEL, 0);
|
||||
mtcp(XREG_CP15_CLEAN_DC_LINE_MVA_POC, (adr & (~0x1F)));
|
||||
|
||||
/* Wait for store to complete */
|
||||
dsb();
|
||||
isb();
|
||||
|
||||
mtcpsr(currmask);
|
||||
}
|
||||
|
||||
void Xil_ICacheEnable(void)
|
||||
{
|
||||
register u32 CtrlReg;
|
||||
|
||||
/* enable caches only if they are disabled */
|
||||
#if defined (__GNUC__)
|
||||
CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
|
||||
#elif defined (__ICCARM__)
|
||||
mfcp(XREG_CP15_SYS_CONTROL, CtrlReg);
|
||||
#endif
|
||||
if ((CtrlReg & XREG_CP15_CONTROL_I_BIT)==0x00000000U) {
|
||||
/* invalidate the instruction cache */
|
||||
mtcp(XREG_CP15_INVAL_IC_POU, 0);
|
||||
|
||||
/* enable the instruction cache */
|
||||
CtrlReg |= (XREG_CP15_CONTROL_I_BIT);
|
||||
|
||||
mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
|
||||
}
|
||||
}
|
||||
|
||||
void Xil_ICacheDisable(void)
|
||||
{
|
||||
register u32 CtrlReg;
|
||||
|
||||
dsb();
|
||||
|
||||
/* invalidate the instruction cache */
|
||||
mtcp(XREG_CP15_INVAL_IC_POU, 0);
|
||||
|
||||
/* disable the instruction cache */
|
||||
#if defined (__GNUC__)
|
||||
CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
|
||||
#elif defined (__ICCARM__)
|
||||
mfcp(XREG_CP15_SYS_CONTROL,CtrlReg);
|
||||
#endif
|
||||
|
||||
CtrlReg &= ~(XREG_CP15_CONTROL_I_BIT);
|
||||
|
||||
mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
|
||||
}
|
||||
|
||||
void Xil_ICacheInvalidate(void)
|
||||
{
|
||||
u32 currmask;
|
||||
|
||||
currmask = mfcpsr();
|
||||
mtcpsr(currmask | IRQ_FIQ_MASK);
|
||||
|
||||
mtcp(XREG_CP15_CACHE_SIZE_SEL, 1);
|
||||
|
||||
/* invalidate the instruction cache */
|
||||
mtcp(XREG_CP15_INVAL_IC_POU, 0);
|
||||
|
||||
/* Wait for invalidate to complete */
|
||||
dsb();
|
||||
mtcpsr(currmask);
|
||||
}
|
||||
|
||||
void Xil_ICacheInvalidateLine(INTPTR adr)
|
||||
{
|
||||
u32 currmask;
|
||||
|
||||
currmask = mfcpsr();
|
||||
mtcpsr(currmask | IRQ_FIQ_MASK);
|
||||
|
||||
mtcp(XREG_CP15_CACHE_SIZE_SEL, 1);
|
||||
mtcp(XREG_CP15_INVAL_IC_LINE_MVA_POU, (adr & (~0x1F)));
|
||||
|
||||
/* Wait for invalidate to complete */
|
||||
dsb();
|
||||
mtcpsr(currmask);
|
||||
}
|
||||
|
||||
void Xil_ICacheInvalidateRange(INTPTR adr, u32 len)
|
||||
{
|
||||
u32 LocalAddr = adr;
|
||||
const u32 cacheline = 32U;
|
||||
u32 end;
|
||||
u32 currmask;
|
||||
|
||||
currmask = mfcpsr();
|
||||
mtcpsr(currmask | IRQ_FIQ_MASK);
|
||||
if (len != 0x00000000U) {
|
||||
/* Back the starting address up to the start of a cache line
|
||||
* perform cache operations until adr+len
|
||||
*/
|
||||
end = LocalAddr + len;
|
||||
LocalAddr = LocalAddr & ~(cacheline - 1U);
|
||||
|
||||
/* Select cache L0 I-cache in CSSR */
|
||||
mtcp(XREG_CP15_CACHE_SIZE_SEL, 1U);
|
||||
|
||||
while (LocalAddr < end) {
|
||||
|
||||
/* Invalidate L1 I-cache line */
|
||||
asm_inval_ic_line_mva_pou(LocalAddr);
|
||||
|
||||
LocalAddr += cacheline;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for invalidate to complete */
|
||||
dsb();
|
||||
mtcpsr(currmask);
|
||||
}
|
||||
|
||||
void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
|
||||
{
|
||||
if (ops == RT_HW_CACHE_INVALIDATE)
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2020-03-19 WangHuachen first version
|
||||
* 2021-05-11 WangHuachen Added call to Xil_InitializeExistingMPURegConfig to
|
||||
* initialize the MPU configuration table with the MPU
|
||||
* configurations already set in Init_Mpu function.
|
||||
*/
|
||||
|
||||
.equ Mode_USR, 0x10
|
||||
|
@ -234,6 +237,7 @@ ctor_loop:
|
|||
b ctor_loop
|
||||
ctor_end:
|
||||
|
||||
bl Xil_InitializeExistingMPURegConfig /* Initialize MPU config */
|
||||
/* start RT-Thread Kernel */
|
||||
ldr pc, _entry
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2015 - 2020 Xilinx, Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @file xil_mmu.h
|
||||
* This file only includes xil_mpu.h which contains Xil_SetTlbAttributes API
|
||||
* defined for MPU in R5. R5 does not have mmu and for usage of similar API
|
||||
* the file has been created.
|
||||
*
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- ---------------------------------------------------
|
||||
* 5.0 pkp 2/12/15 Initial version
|
||||
* </pre>
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XIL_MMU_H
|
||||
#define XIL_MMU_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_mpu.h"
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* XIL_MMU_H */
|
|
@ -0,0 +1,637 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 - 2017 Xilinx, Inc. All rights reserved.
|
||||
* Copyright (C) 2021 WangHuachen. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @file xil_mpu.c
|
||||
*
|
||||
* This file provides APIs for enabling/disabling MPU and setting the memory
|
||||
* attributes for sections, in the MPU translation table.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- ---------------------------------------------------
|
||||
* 5.00 pkp 02/10/14 Initial version
|
||||
* 6.2 mus 01/27/17 Updated to support IAR compiler
|
||||
* 6.4 asa 08/16/17 Added many APIs for MPU access to make MPU usage
|
||||
* user-friendly. The APIs added are: Xil_UpdateMPUConfig,
|
||||
* Xil_GetMPUConfig, Xil_GetNumOfFreeRegions,
|
||||
* Xil_GetNextMPURegion, Xil_DisableMPURegionByRegNum,
|
||||
* Xil_GetMPUFreeRegMask, Xil_SetMPURegionByRegNum, and
|
||||
* Xil_InitializeExistingMPURegConfig.
|
||||
* Added a new array of structure of type XMpuConfig to
|
||||
* represent the MPU configuration table.
|
||||
* 6.8 aru 07/02/18 Returned the pointer instead of address
|
||||
* of that pointer in Xil_MemMap().
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_cache.h"
|
||||
#include "xpseudo_asm_gcc.h"
|
||||
#include "xil_types.h"
|
||||
#include "xil_mpu.h"
|
||||
// #include "xdebug.h"
|
||||
#include "xreg_cortexr5.h"
|
||||
#include "xstatus.h"
|
||||
|
||||
#include <rtthread.h>
|
||||
#define DBG_TAG "xil_mpu"
|
||||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
|
||||
extern void Xil_DCacheFlush(void);
|
||||
extern void Xil_ICacheInvalidate(void);
|
||||
extern void Xil_DCacheDisable(void);
|
||||
extern void Xil_ICacheDisable(void);
|
||||
extern void Xil_DCacheEnable(void);
|
||||
extern void Xil_ICacheEnable(void);
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
#define MPU_REGION_SIZE_MIN 0x20
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
static const struct {
|
||||
u64 size;
|
||||
unsigned int encoding;
|
||||
}region_size[] = {
|
||||
{ 0x20, REGION_32B },
|
||||
{ 0x40, REGION_64B },
|
||||
{ 0x80, REGION_128B },
|
||||
{ 0x100, REGION_256B },
|
||||
{ 0x200, REGION_512B },
|
||||
{ 0x400, REGION_1K },
|
||||
{ 0x800, REGION_2K },
|
||||
{ 0x1000, REGION_4K },
|
||||
{ 0x2000, REGION_8K },
|
||||
{ 0x4000, REGION_16K },
|
||||
{ 0x8000, REGION_32K },
|
||||
{ 0x10000, REGION_64K },
|
||||
{ 0x20000, REGION_128K },
|
||||
{ 0x40000, REGION_256K },
|
||||
{ 0x80000, REGION_512K },
|
||||
{ 0x100000, REGION_1M },
|
||||
{ 0x200000, REGION_2M },
|
||||
{ 0x400000, REGION_4M },
|
||||
{ 0x800000, REGION_8M },
|
||||
{ 0x1000000, REGION_16M },
|
||||
{ 0x2000000, REGION_32M },
|
||||
{ 0x4000000, REGION_64M },
|
||||
{ 0x8000000, REGION_128M },
|
||||
{ 0x10000000, REGION_256M },
|
||||
{ 0x20000000, REGION_512M },
|
||||
{ 0x40000000, REGION_1G },
|
||||
{ 0x80000000, REGION_2G },
|
||||
{ 0x100000000, REGION_4G },
|
||||
};
|
||||
|
||||
XMpu_Config Mpu_Config;
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
void Xil_InitializeExistingMPURegConfig(void);
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief This function sets the memory attributes for a section covering
|
||||
* 1MB, of memory in the translation table.
|
||||
*
|
||||
* @param Addr: 32-bit address for which memory attributes need to be set.
|
||||
* @param attrib: Attribute for the given memory region.
|
||||
* @return None.
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
void Xil_SetTlbAttributes(INTPTR addr, u32 attrib)
|
||||
{
|
||||
INTPTR Localaddr = addr;
|
||||
Localaddr &= (~(0xFFFFFU));
|
||||
/* Setting the MPU region with given attribute with 1MB size */
|
||||
Xil_SetMPURegion(Localaddr, 0x100000, attrib);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Set the memory attributes for a section of memory in the
|
||||
* translation table.
|
||||
*
|
||||
* @param Addr: 32-bit address for which memory attributes need to be set..
|
||||
* @param size: size is the size of the region.
|
||||
* @param attrib: Attribute for the given memory region.
|
||||
* @return None.
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
u32 Xil_SetMPURegion(INTPTR addr, u64 size, u32 attrib)
|
||||
{
|
||||
u32 Regionsize = 0;
|
||||
INTPTR Localaddr = addr;
|
||||
u32 NextAvailableMemRegion;
|
||||
unsigned int i;
|
||||
|
||||
NextAvailableMemRegion = Xil_GetNextMPURegion();
|
||||
if (NextAvailableMemRegion == 0xFF) {
|
||||
LOG_E("No regions available\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Xil_DCacheFlush();
|
||||
Xil_ICacheInvalidate();
|
||||
|
||||
mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,NextAvailableMemRegion);
|
||||
isb();
|
||||
|
||||
/* Lookup the size. */
|
||||
for (i = 0; i < sizeof region_size / sizeof region_size[0]; i++) {
|
||||
if (size <= region_size[i].size) {
|
||||
Regionsize = region_size[i].encoding;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Localaddr &= ~(region_size[i].size - 1);
|
||||
|
||||
Regionsize <<= 1;
|
||||
Regionsize |= REGION_EN;
|
||||
dsb();
|
||||
mtcp(XREG_CP15_MPU_REG_BASEADDR, Localaddr); /* Set base address of a region */
|
||||
mtcp(XREG_CP15_MPU_REG_ACCESS_CTRL, attrib); /* Set the control attribute */
|
||||
mtcp(XREG_CP15_MPU_REG_SIZE_EN, Regionsize); /* set the region size and enable it*/
|
||||
dsb();
|
||||
isb();
|
||||
Xil_UpdateMPUConfig(NextAvailableMemRegion, Localaddr, Regionsize, attrib);
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Enable MPU for Cortex R5 processor. This function invalidates I
|
||||
* cache and flush the D Caches, and then enables the MPU.
|
||||
*
|
||||
*
|
||||
* @param None.
|
||||
* @return None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void Xil_EnableMPU(void)
|
||||
{
|
||||
u32 CtrlReg, Reg;
|
||||
s32 DCacheStatus=0, ICacheStatus=0;
|
||||
/* enable caches only if they are disabled */
|
||||
#if defined (__GNUC__)
|
||||
CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
|
||||
#elif defined (__ICCARM__)
|
||||
mfcp(XREG_CP15_SYS_CONTROL,CtrlReg);
|
||||
#endif
|
||||
if ((CtrlReg & XREG_CP15_CONTROL_C_BIT) != 0x00000000U) {
|
||||
DCacheStatus=1;
|
||||
}
|
||||
if ((CtrlReg & XREG_CP15_CONTROL_I_BIT) != 0x00000000U) {
|
||||
ICacheStatus=1;
|
||||
}
|
||||
|
||||
if(DCacheStatus != 0) {
|
||||
Xil_DCacheDisable();
|
||||
}
|
||||
if(ICacheStatus != 0){
|
||||
Xil_ICacheDisable();
|
||||
}
|
||||
#if defined (__GNUC__)
|
||||
Reg = mfcp(XREG_CP15_SYS_CONTROL);
|
||||
#elif defined (__ICCARM__)
|
||||
mfcp(XREG_CP15_SYS_CONTROL,Reg);
|
||||
#endif
|
||||
Reg |= 0x00000001U;
|
||||
dsb();
|
||||
mtcp(XREG_CP15_SYS_CONTROL, Reg);
|
||||
isb();
|
||||
/* enable caches only if they are disabled in routine*/
|
||||
if(DCacheStatus != 0) {
|
||||
Xil_DCacheEnable();
|
||||
}
|
||||
if(ICacheStatus != 0) {
|
||||
Xil_ICacheEnable();
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Disable MPU for Cortex R5 processors. This function invalidates I
|
||||
* cache and flush the D Caches, and then disabes the MPU.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void Xil_DisableMPU(void)
|
||||
{
|
||||
u32 CtrlReg, Reg;
|
||||
s32 DCacheStatus=0, ICacheStatus=0;
|
||||
/* enable caches only if they are disabled */
|
||||
|
||||
#if defined (__GNUC__)
|
||||
CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);
|
||||
#elif defined (__ICCARM__)
|
||||
mfcp(XREG_CP15_SYS_CONTROL,CtrlReg);
|
||||
#endif
|
||||
if ((CtrlReg & XREG_CP15_CONTROL_C_BIT) != 0x00000000U) {
|
||||
DCacheStatus=1;
|
||||
}
|
||||
if ((CtrlReg & XREG_CP15_CONTROL_I_BIT) != 0x00000000U) {
|
||||
ICacheStatus=1;
|
||||
}
|
||||
|
||||
if(DCacheStatus != 0) {
|
||||
Xil_DCacheDisable();
|
||||
}
|
||||
if(ICacheStatus != 0){
|
||||
Xil_ICacheDisable();
|
||||
}
|
||||
|
||||
mtcp(XREG_CP15_INVAL_BRANCH_ARRAY, 0);
|
||||
#if defined (__GNUC__)
|
||||
Reg = mfcp(XREG_CP15_SYS_CONTROL);
|
||||
#elif defined (__ICCARM__)
|
||||
mfcp(XREG_CP15_SYS_CONTROL,Reg);
|
||||
#endif
|
||||
Reg &= ~(0x00000001U);
|
||||
dsb();
|
||||
mtcp(XREG_CP15_SYS_CONTROL, Reg);
|
||||
isb();
|
||||
/* enable caches only if they are disabled in routine*/
|
||||
if(DCacheStatus != 0) {
|
||||
Xil_DCacheEnable();
|
||||
}
|
||||
if(ICacheStatus != 0) {
|
||||
Xil_ICacheEnable();
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Update the MPU configuration for the requested region number in
|
||||
* the global MPU configuration table.
|
||||
*
|
||||
* @param reg_num: The requested region number to be updated information for.
|
||||
* @param address: 32 bit address for start of the region.
|
||||
* @param size: Requested size of the region.
|
||||
* @param attrib: Attribute for the corresponding region.
|
||||
* @return XST_FAILURE: When the requested region number if 16 or more.
|
||||
* XST_SUCCESS: When the MPU configuration table is updated.
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
u32 Xil_UpdateMPUConfig(u32 reg_num, INTPTR address, u32 size, u32 attrib)
|
||||
{
|
||||
u32 ReturnVal = XST_SUCCESS;
|
||||
u32 Tempsize = size;
|
||||
u32 Index;
|
||||
|
||||
if (reg_num >= MAX_POSSIBLE_MPU_REGS) {
|
||||
LOG_E("Invalid region number\r\n");
|
||||
ReturnVal = XST_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (size & REGION_EN) {
|
||||
Mpu_Config[reg_num].RegionStatus = MPU_REG_ENABLED;
|
||||
Mpu_Config[reg_num].BaseAddress = address;
|
||||
Tempsize &= (~REGION_EN);
|
||||
Tempsize >>= 1;
|
||||
/* Lookup the size. */
|
||||
for (Index = 0; Index <
|
||||
sizeof region_size / sizeof region_size[0]; Index++) {
|
||||
if (Tempsize <= region_size[Index].encoding) {
|
||||
Mpu_Config[reg_num].Size = region_size[Index].size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Mpu_Config[reg_num].Attribute = attrib;
|
||||
} else {
|
||||
Mpu_Config[reg_num].RegionStatus = 0U;
|
||||
Mpu_Config[reg_num].BaseAddress = 0U;
|
||||
Mpu_Config[reg_num].Size = 0U;
|
||||
Mpu_Config[reg_num].Attribute = 0U;
|
||||
}
|
||||
|
||||
exit:
|
||||
return ReturnVal;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief The MPU configuration table is passed to the caller.
|
||||
*
|
||||
* @param mpuconfig: This is of type XMpu_Config which is an array of
|
||||
* 16 entries of type structure representing the MPU config table
|
||||
* @return none
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
void Xil_GetMPUConfig (XMpu_Config mpuconfig) {
|
||||
u32 Index = 0U;
|
||||
|
||||
while (Index < MAX_POSSIBLE_MPU_REGS) {
|
||||
mpuconfig[Index].RegionStatus = Mpu_Config[Index].RegionStatus;
|
||||
mpuconfig[Index].BaseAddress = Mpu_Config[Index].BaseAddress;
|
||||
mpuconfig[Index].Attribute = Mpu_Config[Index].Attribute;
|
||||
mpuconfig[Index].Size = Mpu_Config[Index].Size;
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Returns the total number of free MPU regions available.
|
||||
*
|
||||
* @param none
|
||||
* @return Number of free regions available to users
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
u32 Xil_GetNumOfFreeRegions (void) {
|
||||
u32 Index = 0U;
|
||||
int NumofFreeRegs = 0U;
|
||||
|
||||
while (Index < MAX_POSSIBLE_MPU_REGS) {
|
||||
if (MPU_REG_DISABLED == Mpu_Config[Index].RegionStatus) {
|
||||
NumofFreeRegs++;
|
||||
}
|
||||
Index++;
|
||||
}
|
||||
return NumofFreeRegs;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Returns the total number of free MPU regions available in the form
|
||||
* of a mask. A bit of 1 in the returned 16 bit value represents the
|
||||
* corresponding region number to be available.
|
||||
* For example, if this function returns 0xC0000, this would mean, the
|
||||
* regions 14 and 15 are available to users.
|
||||
*
|
||||
* @param none
|
||||
* @return The free region mask as a 16 bit value
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
u16 Xil_GetMPUFreeRegMask (void) {
|
||||
u32 Index = 0U;
|
||||
u16 FreeRegMask = 0U;
|
||||
|
||||
while (Index < MAX_POSSIBLE_MPU_REGS) {
|
||||
if (MPU_REG_DISABLED == Mpu_Config[Index].RegionStatus) {
|
||||
FreeRegMask |= (1U << Index);
|
||||
}
|
||||
Index++;
|
||||
}
|
||||
return FreeRegMask;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Disables the corresponding region number as passed by the user.
|
||||
*
|
||||
* @param reg_num: The region number to be disabled
|
||||
* @return XST_SUCCESS: If the region could be disabled successfully
|
||||
* XST_FAILURE: If the requested region number is 16 or more.
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
u32 Xil_DisableMPURegionByRegNum (u32 reg_num) {
|
||||
u32 Temp = 0U;
|
||||
u32 ReturnVal = XST_FAILURE;
|
||||
|
||||
if (reg_num >= 16U) {
|
||||
LOG_E("Invalid region number\r\n");
|
||||
goto exit1;
|
||||
}
|
||||
Xil_DCacheFlush();
|
||||
Xil_ICacheInvalidate();
|
||||
|
||||
mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,reg_num);
|
||||
#if defined (__GNUC__)
|
||||
Temp = mfcp(XREG_CP15_MPU_REG_SIZE_EN);
|
||||
#elif defined (__ICCARM__)
|
||||
mfcp(XREG_CP15_MPU_REG_SIZE_EN,Temp);
|
||||
#endif
|
||||
Temp &= (~REGION_EN);
|
||||
dsb();
|
||||
mtcp(XREG_CP15_MPU_REG_SIZE_EN,Temp);
|
||||
dsb();
|
||||
isb();
|
||||
Xil_UpdateMPUConfig(reg_num, 0U, 0U, 0U);
|
||||
ReturnVal = XST_SUCCESS;
|
||||
|
||||
exit1:
|
||||
return ReturnVal;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Enables the corresponding region number as passed by the user.
|
||||
*
|
||||
* @param reg_num: The region number to be enabled
|
||||
* @param address: 32 bit address for start of the region.
|
||||
* @param size: Requested size of the region.
|
||||
* @param attrib: Attribute for the corresponding region.
|
||||
* @return XST_SUCCESS: If the region could be created successfully
|
||||
* XST_FAILURE: If the requested region number is 16 or more.
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
u32 Xil_SetMPURegionByRegNum (u32 reg_num, INTPTR addr, u64 size, u32 attrib)
|
||||
{
|
||||
u32 ReturnVal = XST_SUCCESS;
|
||||
INTPTR Localaddr = addr;
|
||||
u32 Regionsize = 0;
|
||||
u32 Index;
|
||||
|
||||
if (reg_num >= 16U) {
|
||||
LOG_E("Invalid region number\r\n");
|
||||
ReturnVal = XST_FAILURE;
|
||||
goto exit2;
|
||||
}
|
||||
|
||||
if (Mpu_Config[reg_num].RegionStatus == MPU_REG_ENABLED) {
|
||||
LOG_E("Region already enabled\r\n");
|
||||
ReturnVal = XST_FAILURE;
|
||||
goto exit2;
|
||||
}
|
||||
|
||||
Xil_DCacheFlush();
|
||||
Xil_ICacheInvalidate();
|
||||
mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,reg_num);
|
||||
isb();
|
||||
|
||||
/* Lookup the size. */
|
||||
for (Index = 0; Index <
|
||||
sizeof region_size / sizeof region_size[0]; Index++) {
|
||||
if (size <= region_size[Index].size) {
|
||||
Regionsize = region_size[Index].encoding;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Localaddr &= ~(region_size[Index].size - 1);
|
||||
Regionsize <<= 1;
|
||||
Regionsize |= REGION_EN;
|
||||
dsb();
|
||||
mtcp(XREG_CP15_MPU_REG_BASEADDR, Localaddr);
|
||||
mtcp(XREG_CP15_MPU_REG_ACCESS_CTRL, attrib);
|
||||
mtcp(XREG_CP15_MPU_REG_SIZE_EN, Regionsize);
|
||||
dsb();
|
||||
isb();
|
||||
Xil_UpdateMPUConfig(reg_num, Localaddr, Regionsize, attrib);
|
||||
exit2:
|
||||
return ReturnVal;
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Initializes the MPU configuration table that are setup in the
|
||||
* R5 boot code in the Init_Mpu function called before C main.
|
||||
*
|
||||
* @param none
|
||||
* @return none
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
void Xil_InitializeExistingMPURegConfig(void)
|
||||
{
|
||||
u32 Index = 0U;
|
||||
u32 Index1 = 0U;
|
||||
u32 MPURegSize;
|
||||
INTPTR MPURegBA;
|
||||
u32 MPURegAttrib;
|
||||
u32 Tempsize;
|
||||
|
||||
while (Index < MAX_POSSIBLE_MPU_REGS) {
|
||||
mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,Index);
|
||||
#if defined (__GNUC__)
|
||||
MPURegSize = mfcp(XREG_CP15_MPU_REG_SIZE_EN);
|
||||
MPURegBA = mfcp(XREG_CP15_MPU_REG_BASEADDR);
|
||||
MPURegAttrib = mfcp(XREG_CP15_MPU_REG_ACCESS_CTRL);
|
||||
#elif defined (__ICCARM__)
|
||||
mfcp(XREG_CP15_MPU_REG_SIZE_EN,MPURegSize);
|
||||
mfcp(XREG_CP15_MPU_REG_BASEADDR, MPURegBA);
|
||||
mfcp(XREG_CP15_MPU_REG_ACCESS_CTRL, MPURegAttrib);
|
||||
#endif
|
||||
if (MPURegSize & REGION_EN) {
|
||||
Mpu_Config[Index].RegionStatus = MPU_REG_ENABLED;
|
||||
Mpu_Config[Index].BaseAddress = MPURegBA;
|
||||
Mpu_Config[Index].Attribute = MPURegAttrib;
|
||||
Tempsize = MPURegSize & (~REGION_EN);
|
||||
Tempsize >>= 1;
|
||||
for (Index1 = 0; Index1 <
|
||||
(sizeof (region_size) / sizeof (region_size[0])); Index1++) {
|
||||
if (Tempsize <= region_size[Index1].encoding) {
|
||||
Mpu_Config[Index].Size = region_size[Index1].size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Index++;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Returns the next available free MPU region
|
||||
*
|
||||
* @param none
|
||||
* @return The free MPU region available
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
u32 Xil_GetNextMPURegion(void)
|
||||
{
|
||||
u32 Index = 0U;
|
||||
u32 NextAvailableReg = 0xFF;
|
||||
while (Index < MAX_POSSIBLE_MPU_REGS) {
|
||||
if (Mpu_Config[Index].RegionStatus != MPU_REG_ENABLED) {
|
||||
NextAvailableReg = Index;
|
||||
break;
|
||||
}
|
||||
Index++;
|
||||
}
|
||||
return NextAvailableReg;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Memory mapping for Cortex r5.
|
||||
*
|
||||
* @param Physaddr is base physical address at which to start mapping.
|
||||
* NULL in Physaddr masks possible mapping errors.
|
||||
* @param size of region to be mapped.
|
||||
* @param flags used to set translation table.
|
||||
*
|
||||
* @return Physaddr on success, NULL on error. Ambiguous if Physaddr==NULL
|
||||
*
|
||||
* @note: u32overflow() is defined for readability and (for __GNUC__) to
|
||||
* - force the type of the check to be the same as the first argument
|
||||
* - hide the otherwise unused third argument of the builtin
|
||||
* - improve safety by choosing the explicit _uadd_ version.
|
||||
* Consider __builtin_add_overflow_p() when available.
|
||||
* Use an alternative (less optimal?) for compilers w/o the builtin.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifdef __GNUC__
|
||||
#define u32overflow(a, b) ({typeof(a) s; __builtin_uadd_overflow(a, b, &s); })
|
||||
#else
|
||||
#define u32overflow(a, b) ((a) > ((a) + (b)))
|
||||
#endif /* __GNUC__ */
|
||||
void *Xil_MemMap(UINTPTR Physaddr, size_t size, u32 flags)
|
||||
{
|
||||
size_t Regionsize = MPU_REGION_SIZE_MIN;
|
||||
UINTPTR Basephysaddr = 0, end = Physaddr + size;
|
||||
|
||||
if (!flags)
|
||||
return (void *)Physaddr;
|
||||
if (u32overflow(Physaddr, size))
|
||||
return NULL;
|
||||
for ( ; Regionsize != 0; Regionsize <<= 1) {
|
||||
if (Regionsize >= size) {
|
||||
Basephysaddr = Physaddr & ~(Regionsize - 1);
|
||||
if (u32overflow(Basephysaddr, Regionsize))
|
||||
break;
|
||||
if ((Basephysaddr + Regionsize) >= end)
|
||||
return Xil_SetMPURegion(Basephysaddr,
|
||||
Regionsize, flags) == XST_SUCCESS ?
|
||||
(void *)Physaddr : NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 - 2017 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @file xil_mmu.h
|
||||
*
|
||||
* @addtogroup r5_mpu_apis Cortex R5 Processor MPU specific APIs
|
||||
*
|
||||
* MPU functions provides access to MPU operations such as enable MPU, disable
|
||||
* MPU and set attribute for section of memory.
|
||||
* Boot code invokes Init_MPU function to configure the MPU. A total of 10 MPU
|
||||
* regions are allocated with another 6 being free for users. Overview of the
|
||||
* memory attributes for different MPU regions is as given below,
|
||||
*
|
||||
*| | Memory Range | Attributes of MPURegion |
|
||||
*|-----------------------|-------------------------|-----------------------------|
|
||||
*| DDR | 0x00000000 - 0x7FFFFFFF | Normal write-back Cacheable |
|
||||
*| PL | 0x80000000 - 0xBFFFFFFF | Strongly Ordered |
|
||||
*| QSPI | 0xC0000000 - 0xDFFFFFFF | Device Memory |
|
||||
*| PCIe | 0xE0000000 - 0xEFFFFFFF | Device Memory |
|
||||
*| STM_CORESIGHT | 0xF8000000 - 0xF8FFFFFF | Device Memory |
|
||||
*| RPU_R5_GIC | 0xF9000000 - 0xF90FFFFF | Device memory |
|
||||
*| FPS | 0xFD000000 - 0xFDFFFFFF | Device Memory |
|
||||
*| LPS | 0xFE000000 - 0xFFFFFFFF | Device Memory |
|
||||
*| OCM | 0xFFFC0000 - 0xFFFFFFFF | Normal write-back Cacheable |
|
||||
*
|
||||
*
|
||||
* @note
|
||||
* For a system where DDR is less than 2GB, region after DDR and before PL is
|
||||
* marked as undefined in translation table. Memory range 0xFE000000-0xFEFFFFFF is
|
||||
* allocated for upper LPS slaves, where as memory region 0xFF000000-0xFFFFFFFF is
|
||||
* allocated for lower LPS slaves.
|
||||
*
|
||||
* @{
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- ---------------------------------------------------
|
||||
* 5.00 pkp 02/10/14 Initial version
|
||||
* 6.4 asa 08/16/17 Added many APIs for MPU access to make MPU usage
|
||||
* user-friendly. The APIs added are: Xil_UpdateMPUConfig,
|
||||
* Xil_GetMPUConfig, Xil_GetNumOfFreeRegions,
|
||||
* Xil_GetNextMPURegion, Xil_DisableMPURegionByRegNum,
|
||||
* Xil_GetMPUFreeRegMask, Xil_SetMPURegionByRegNum, and
|
||||
* Xil_InitializeExistingMPURegConfig.
|
||||
* Added a new array of structure of type XMpuConfig to
|
||||
* represent the MPU configuration table.
|
||||
* </pre>
|
||||
*
|
||||
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XIL_MPU_H
|
||||
#define XIL_MPU_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#include "xil_types.h"
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
#define MPU_REG_DISABLED 0U
|
||||
#define MPU_REG_ENABLED 1U
|
||||
#define MAX_POSSIBLE_MPU_REGS 16U
|
||||
/**************************** Type Definitions *******************************/
|
||||
struct XMpuConfig{
|
||||
u32 RegionStatus; /* Enabled or disabled */
|
||||
INTPTR BaseAddress;/* MPU region base address */
|
||||
u64 Size; /* MPU region size address */
|
||||
u32 Attribute; /* MPU region size attribute */
|
||||
};
|
||||
|
||||
typedef struct XMpuConfig XMpu_Config[MAX_POSSIBLE_MPU_REGS];
|
||||
|
||||
extern XMpu_Config Mpu_Config;
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
void Xil_SetTlbAttributes(INTPTR Addr, u32 attrib);
|
||||
void Xil_EnableMPU(void);
|
||||
void Xil_DisableMPU(void);
|
||||
u32 Xil_SetMPURegion(INTPTR addr, u64 size, u32 attrib);
|
||||
u32 Xil_UpdateMPUConfig(u32 reg_num, INTPTR address, u32 size, u32 attrib);
|
||||
void Xil_GetMPUConfig (XMpu_Config mpuconfig);
|
||||
u32 Xil_GetNumOfFreeRegions (void);
|
||||
u32 Xil_GetNextMPURegion(void);
|
||||
u32 Xil_DisableMPURegionByRegNum (u32 reg_num);
|
||||
u16 Xil_GetMPUFreeRegMask (void);
|
||||
u32 Xil_SetMPURegionByRegNum (u32 reg_num, INTPTR addr, u64 size, u32 attrib);
|
||||
void* Xil_MemMap(UINTPTR Physaddr, size_t size, u32 flags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* XIL_MPU_H */
|
||||
/**
|
||||
* @} End of "addtogroup r5_mpu_apis".
|
||||
*/
|
Loading…
Reference in New Issue