1224 lines
47 KiB
Tcl
Executable file
1224 lines
47 KiB
Tcl
Executable file
set use_axieth_on_zynq 0
|
|
set use_emaclite_on_zynq 0
|
|
|
|
# emaclite hw requirements - interrupt needs to be connected
|
|
proc lwip_elite_hw_drc {libhandle emac} {
|
|
set emacname [common::get_property NAME $emac]
|
|
set intr_port [hsi::get_pins -of_objects [hsi::get_cells $emac] IP2INTC_Irpt]
|
|
if {[string compare -nocase $intr_port ""] == 0} {
|
|
error "ERROR: xps_ethernetlite core $emacname does not have its interrupt connected to interrupt controller. \
|
|
lwIP operates only in interrupt mode, so please connect the interrupt port to \
|
|
the interrupt controller.\n" "" "MDT_ERROR"
|
|
}
|
|
set tx_csum [common::get_property CONFIG.tcp_tx_checksum_offload $libhandle]
|
|
set rx_csum [common::get_property CONFIG.tcp_rx_checksum_offload $libhandle]
|
|
|
|
set tx_full_csum [common::get_property CONFIG.tcp_ip_tx_checksum_offload $libhandle]
|
|
set rx_full_csum [common::get_property CONFIG.tcp_ip_rx_checksum_offload $libhandle]
|
|
|
|
set igmp_val [common::get_property CONFIG.igmp_options $libhandle]
|
|
|
|
if {$tx_full_csum} {
|
|
error "ERROR: Full TCP/IP checksum offload on Tx path is not supported for emaclite" "" "MDT_ERROR"
|
|
}
|
|
|
|
if {$rx_full_csum} {
|
|
error "ERROR: Full TCP/IP checksum offload on Rx path is not supported for emaclite" "" "MDT_ERROR"
|
|
}
|
|
if {$tx_csum} {
|
|
error "ERROR: Partial TCP checksum offload on Tx path is not supported for emaclite" "" "MDT_ERROR"
|
|
}
|
|
if {$rx_csum} {
|
|
error "ERROR: Partial TCP checksum offload on Rx path is not supported for emaclite" "" "MDT_ERROR"
|
|
}
|
|
if {$igmp_val == true} {
|
|
error "ERROR: IGMP is not supported for emaclite" "" "MDT_ERROR"
|
|
}
|
|
}
|
|
|
|
# temac support requires the following interrupts to be connected
|
|
# - temac intr
|
|
# - if sdma, sdma tx&rx intr (not verified)
|
|
# - if fifo, fifo intr (not verified)
|
|
proc lwip_temac_channel_hw_drc {libhandle emac irpt_name llink_name tx_csum_name rx_csum_name} {
|
|
set emacname [common::get_property NAME $emac]
|
|
set mhs_handle [hsi::get_cells $emac]
|
|
|
|
set intr_port [hsi::get_pins -of_objects [hsi::get_cells $emac] irpt_name]
|
|
if {[string compare -nocase $intr_port ""] == 0} {
|
|
error "ERROR: xps_ll_temac core $emacname does not have its interrupt connected to interrupt controller. \
|
|
lwIP requires that this interrupt line be connected to \
|
|
the interrupt controller.\n" "" "MDT_ERROR"
|
|
}
|
|
|
|
# find out what is connected to llink0
|
|
set connected_bus [xget_hw_busif_handle $emac $llink_name]
|
|
if {[string compare -nocase $intr_port ""] == 0} {
|
|
error "ERROR: xps_ll_temac core $emacname does not have its local link port (LLINK0) connected" \
|
|
"" "MDT_ERROR"
|
|
}
|
|
|
|
set connected_bus_name [common::get_property NAME $connected_bus]
|
|
set target_handle [xget_hw_connected_busifs_handle $mhs_handle $connected_bus_name "TARGET"]
|
|
set parent_handle [hsi::get_cells -of_objects $target_handle]
|
|
set parent_name [common::get_property NAME $parent_handle]
|
|
|
|
set tx_csum [common::get_property CONFIG.tcp_tx_checksum_offload $libhandle]
|
|
set rx_csum [common::get_property CONFIG.tcp_rx_checksum_offload $libhandle]
|
|
|
|
set tx_full_csum [common::get_property CONFIG.tcp_ip_tx_checksum_offload $libhandle]
|
|
set rx_full_csum [common::get_property CONFIG.tcp_ip_rx_checksum_offload $libhandle]
|
|
|
|
|
|
if {$tx_full_csum} {
|
|
error "ERROR: Full TCP/IP checksum offload on Tx path is not supported for xps-ll-temac" "" "MDT_ERROR"
|
|
}
|
|
|
|
if {$rx_full_csum} {
|
|
error "ERROR: Full TCP/IP checksum offload on Rx path is not supported for xps-ll-temac" "" "MDT_ERROR"
|
|
}
|
|
|
|
# check checksum parameters
|
|
if {$tx_csum} {
|
|
if {$parent_name == "xps_ll_fifo"} {
|
|
error "ERROR: Checksum offload is possible only with a DMA engine" "" "MDT_ERROR"
|
|
}
|
|
set hw_tx_csum [common::get_property CONFIG.$tx_csum_name $emac]
|
|
if {!$hw_tx_csum} {
|
|
error "ERROR: lwIP cannot offload TX checksum calculation since hardware \
|
|
does not support TX checksum offload" "" "MDT_ERROR"
|
|
}
|
|
}
|
|
|
|
if {$rx_csum} {
|
|
if {$parent_name == "xps_ll_fifo"} {
|
|
error "ERROR: Checksum offload is possible only with a DMA engine" "" "MDT_ERROR"
|
|
}
|
|
set hw_rx_csum [common::get_property CONFIG.$rx_csum_name $emac]
|
|
if {!$hw_rx_csum} {
|
|
error "ERROR: lwIP cannot offload RX checksum calculation since hardware \
|
|
does not support RX checksum offload" "" "MDT_ERROR"
|
|
}
|
|
}
|
|
}
|
|
|
|
proc lwip_temac_hw_drc {libhandle emac} {
|
|
set emac_intr_port [hsi::get_pins -of_objects [hsi::get_cells $emac] TemacIntc0_Irpt]
|
|
set emac0_enabled "0"
|
|
if {$emac_intr_port != ""} { set emac0_enabled "1" }
|
|
if {$emac0_enabled == "1"} {
|
|
lwip_temac_channel_hw_drc $libhandle $emac "TemacIntc0_Irpt" "LLINK0" "C_TEMAC0_TXCSUM" "C_TEMAC0_RXCSUM"
|
|
}
|
|
|
|
set emac1_enabled [common::get_property CONFIG.C_TEMAC1_ENABLED $emac]
|
|
if {$emac1_enabled == "1"} {
|
|
lwip_temac_channel_hw_drc $libhandle $emac "TemacIntc1_Irpt" "LLINK1" "C_TEMAC1_TXCSUM" "C_TEMAC1_RXCSUM"
|
|
}
|
|
}
|
|
|
|
# AXI temac support requires the following interrupts to be connected
|
|
# - temac intr
|
|
# - if AXI DMA, dma tx&rx intr (not verified)
|
|
# - if fifo, fifo intr (not verified)
|
|
proc lwip_axi_ethernet_hw_drc {libhandle emac} {
|
|
|
|
set emacname [common::get_property NAME $emac]
|
|
set mhs_handle [hsi::get_cells $emac]
|
|
|
|
set intr_port [hsi::get_pins -of_objects [hsi::get_cells $emac] INTERRUPT]
|
|
if {[string compare -nocase $intr_port ""] == 0} {
|
|
error "ERROR: axi_ethernet core $emacname does not have its interrupt connected to interrupt controller. \
|
|
lwIP requires that this interrupt line be connected to \
|
|
the interrupt controller.\n" "" "MDT_ERROR"
|
|
}
|
|
|
|
# find out what is connected to AXI
|
|
set connected_bus [xget_hw_busif_handle $emac "S_AXI"]
|
|
if {[string compare -nocase $connected_bus ""] == 0} {
|
|
error "ERROR: axi_ethernet core $emacname does not have its AXI port (S_AXI) connected" \
|
|
"" "MDT_ERROR"
|
|
}
|
|
|
|
set tx_csum [common::get_property CONFIG.tcp_tx_checksum_offload $libhandle]
|
|
set rx_csum [common::get_property CONFIG.tcp_rx_checksum_offload $libhandle]
|
|
|
|
set tx_full_csum [common::get_property CONFIG.tcp_ip_tx_checksum_offload $libhandle]
|
|
set rx_full_csum [common::get_property CONFIG.tcp_ip_rx_checksum_offload $libhandle]
|
|
|
|
if {$tx_csum && $tx_full_csum} {
|
|
error "ERROR: Both partial and full checksums on Tx path can not be enabled at the same time" "" "MDT_ERROR"
|
|
}
|
|
|
|
if {$rx_csum && $rx_full_csum} {
|
|
error "ERROR: Both partial and full checksums on Rx path can not be enabled at the same time" "" "MDT_ERROR"
|
|
}
|
|
|
|
# Find the AXI FIFO or AXI DMA that this emac is connected to.
|
|
set connected_bus [xget_hw_busif_handle $emac "AXI_STR_RXD"]
|
|
set connected_bus_name [common::get_property NAME $connected_bus]
|
|
set target_handle [xget_hw_connected_busifs_handle $mhs_handle $connected_bus_name "TARGET"]
|
|
set parent_handle [hsi::get_cells -of_objects $port $target_handle]
|
|
set parent_name [common::get_property NAME $parent_handle]
|
|
|
|
# check checksum parameters
|
|
if {$tx_csum || $tx_full_csum} {
|
|
if {$parent_name == "axi_fifo_mm_s"} {
|
|
error "ERROR: Checksum offload is possible only with a DMA engine" "" "MDT_ERROR"
|
|
}
|
|
set hw_tx_csum [common::get_property CONFIG.C_TXCSUM $emac]
|
|
if {$hw_tx_csum == "1" && $tx_full_csum } {
|
|
error "ERROR: lwIP cannot offload full TX checksum calculation since hardware \
|
|
supports partial TX checksum offload" "" "MDT_ERROR"
|
|
}
|
|
if {!$hw_tx_csum && $tx_full_csum } {
|
|
error "ERROR: lwIP cannot offload full TX checksum calculation since hardware \
|
|
does not support TX checksum offload" "" "MDT_ERROR"
|
|
}
|
|
if {$hw_tx_csum == "2" && $tx_csum } {
|
|
error "ERROR: lwIP cannot offload partial TX checksum calculation since hardware \
|
|
supports full TX checksum offload" "" "MDT_ERROR"
|
|
}
|
|
if {!$hw_tx_csum && $tx_csum } {
|
|
error "ERROR: lwIP cannot offload partial TX checksum calculation since hardware \
|
|
does not support partial TX checksum offload" "" "MDT_ERROR"
|
|
}
|
|
}
|
|
|
|
if {$rx_csum || $rx_full_csum} {
|
|
if {$parent_name == "axi_fifo_mm_s"} {
|
|
error "ERROR: Checksum offload is possible only with a DMA engine" "" "MDT_ERROR"
|
|
}
|
|
set hw_rx_csum [common::get_property CONFIG.C_RXCSUM $emac]
|
|
if {$hw_rx_csum == "1" && $rx_full_csum } {
|
|
error "ERROR: lwIP cannot offload full RX checksum calculation since hardware \
|
|
supports partial RX checksum offload" "" "MDT_ERROR"
|
|
}
|
|
if {!$hw_rx_csum && $rx_full_csum } {
|
|
error "ERROR: lwIP cannot offload full RX checksum calculation since hardware \
|
|
does not support RX checksum offload" "" "MDT_ERROR"
|
|
}
|
|
if {$hw_rx_csum == "2" && $rx_csum } {
|
|
error "ERROR: lwIP cannot offload partial RX checksum calculation since hardware \
|
|
supports full RX checksum offload" "" "MDT_ERROR"
|
|
}
|
|
if {!$hw_rx_csum && $rx_csum } {
|
|
error "ERROR: lwIP cannot offload partial RX checksum calculation since hardware \
|
|
does not support partial RX checksum offload" "" "MDT_ERROR"
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#---
|
|
# perform basic sanity checks:
|
|
# - interrupts are connected
|
|
# - for csum offload, sdma should be present
|
|
#--
|
|
proc lwip_hw_drc {libhandle emacs_list} {
|
|
foreach ip $emacs_list {
|
|
set iptype [common::get_property NAME $ip]
|
|
if {$iptype == "xps_ethernetlite" || $iptype == "axi_ethernetlite"} {
|
|
lwip_elite_hw_drc $libhandle $ip
|
|
} elseif {$iptype == "xps_ll_temac"} {
|
|
lwip_temac_hw_drc $libhandle $ip
|
|
} elseif {$iptype == "axi_ethernet" || $iptype == "axi_ethernet_buffer"} {
|
|
lwip_axi_ethernet_hw_drc $libhandle $ip
|
|
}
|
|
}
|
|
}
|
|
|
|
#--------
|
|
# Check the following s/w requirements for lwIP:
|
|
# 1. in SOCKET API is used, then xilkernel is required
|
|
#--------
|
|
proc lwip_sw_drc {libhandle emacs_list} {
|
|
set api_mode [common::get_property CONFIG.api_mode $libhandle]
|
|
set api_mode [string toupper $api_mode]
|
|
if { [string compare -nocase "SOCKET_API" $api_mode] == 0} {
|
|
set sw_proc_handle [hsi::get_sw_processor]
|
|
set os_handle [hsi::get_os]
|
|
set os_name [common::get_property NAME $os_handle]
|
|
if { [string compare -nocase "xilkernel" $os_name] != 0} {
|
|
if { [string compare -nocase "freertos_zynq" $os_name] != 0} {
|
|
error "ERROR: lwIP with Sockets requires \"xilkernel or freertos\" OS" "" "mdt_error"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
proc get_emac_periphs {processor} {
|
|
set periphs_list [::hsm::utils::get_proc_slave_periphs $processor]
|
|
set emac_periphs_list {}
|
|
|
|
foreach periph $periphs_list {
|
|
set periphname [common::get_property IP_NAME $periph]
|
|
if {$periphname == "xps_ethernetlite"
|
|
|| $periphname == "opb_ethernetlite"
|
|
|| $periphname == "axi_ethernet"
|
|
|| $periphname == "axi_ethernet_buffer"
|
|
|| $periphname == "axi_ethernetlite"
|
|
|| $periphname == "ps7_ethernet"} {
|
|
lappend emac_periphs_list $periph
|
|
} elseif {$periphname == "xps_ll_temac"} {
|
|
set emac0_enabled "0"
|
|
set emac1_enabled "0"
|
|
set emac_name [common::get_property NAME $periph]
|
|
|
|
# emac 0 is always enabled. just check for its interrupt port
|
|
set emac_intr_port [hsi::get_pins -of_objects [hsi::get_cells $periph] TemacIntc0_Irpt]
|
|
if {$emac_intr_port != ""} {
|
|
set emac0_enabled "1"
|
|
} else {
|
|
puts "Channel 0 of $emac_name cannot be used with lwIP \
|
|
since it does not have its interrupt pin connected."
|
|
}
|
|
|
|
# for emac 1, check C_TEMAC1_ENABLED and then its interrupt port
|
|
set emac1_on [common::get_property CONFIG.C_TEMAC1_ENABLED $periph "PARAMETER"]
|
|
if {$emac1_on == "1"} {
|
|
set emac_intr_port2 [hsi::get_pins -of_objects [hsi::get_cells $periph] TemacIntc1_Irpt]
|
|
if {$emac_intr_port2 != ""} {
|
|
set emac1_enabled "1"
|
|
} else {
|
|
puts "Channel 1 of $emac_name cannot be used with lwIP \
|
|
since it does not have its interrupt pin connected."
|
|
}
|
|
}
|
|
|
|
# we can use this emac if either of its channels are usable
|
|
if {$emac0_enabled == "1" || $emac1_enabled == "1"} {
|
|
lappend emac_periphs_list $periph
|
|
}
|
|
}
|
|
}
|
|
|
|
return $emac_periphs_list
|
|
}
|
|
|
|
#---------------------------------------------
|
|
# lwip_drc - check system configuration and make sure
|
|
# all components to run lwIP are available.
|
|
#---------------------------------------------
|
|
proc lwip_drc {libhandle} {
|
|
#puts "Runnning DRC for lwIP library... \n"
|
|
|
|
# find the list of xps_ethernetlite, xps_ll_temac, or axi_ethernet cores
|
|
set sw_processor [hsi::get_sw_processor]
|
|
set processor [hsi::get_cells [common::get_property HW_INSTANCE $sw_processor]]
|
|
|
|
set emac_periphs_list [get_emac_periphs $processor]
|
|
|
|
if { [llength $emac_periphs_list] == 0 } {
|
|
set cpuname [common::get_property NAME $processor]
|
|
error "ERROR: No Ethernet MAC cores are addressable from processor $cpuname. \
|
|
lwIP requires atleast one EMAC (xps_ethernetlite | xps_ll_temac | axi_ethernet | axi_ethernet_buffer | axi_ethernetlite | ps7_ethernet) core \
|
|
with its interrupt pin connected to the interrupt controller.\n" "" "MDT_ERROR"
|
|
return
|
|
} else {
|
|
set emac_names_list {}
|
|
|
|
foreach emac $emac_periphs_list {
|
|
lappend emac_names_list [common::get_property NAME $emac]
|
|
}
|
|
#puts "lwIP can be used with the following EMAC peripherals found in your system: $emac_names_list"
|
|
}
|
|
|
|
#----
|
|
# check each MAC for correctness conditions
|
|
#----
|
|
|
|
lwip_hw_drc $libhandle $emac_periphs_list
|
|
lwip_sw_drc $libhandle $emac_periphs_list
|
|
}
|
|
|
|
proc generate_lwip_opts {libhandle} {
|
|
global use_axieth_on_zynq
|
|
global use_emaclite_on_zynq
|
|
set lwipopts_file "src/contrib/ports/xilinx/include/lwipopts.h"
|
|
set sw_processor [hsi::get_sw_processor]
|
|
set processor [hsi::get_cells [common::get_property HW_INSTANCE $sw_processor]]
|
|
set processor_type [common::get_property IP_NAME $processor]
|
|
set emac_periphs_list [get_emac_periphs $processor]
|
|
|
|
set have_emaclite 0
|
|
foreach emac $emac_periphs_list {
|
|
set iptype [common::get_property IP_NAME $emac]
|
|
if {$iptype == "xps_ethernetlite" || $iptype == "opb_ethernetlite" || $iptype == "axi_ethernetlite"} {
|
|
set have_emaclite 1
|
|
}
|
|
}
|
|
|
|
file delete $lwipopts_file
|
|
set lwipopts_fd [open $lwipopts_file w]
|
|
|
|
puts $lwipopts_fd "\#ifndef __LWIPOPTS_H_"
|
|
puts $lwipopts_fd "\#define __LWIPOPTS_H_"
|
|
puts $lwipopts_fd ""
|
|
|
|
set proctype [common::get_property IP_NAME $processor]
|
|
switch -regexp $proctype {
|
|
"microblaze" {
|
|
# AXI systems are Little Endian
|
|
# 0 = BE, 1 = LE
|
|
set endian [common::get_property CONFIG.C_ENDIANNESS $processor]
|
|
if {$endian != 0} {
|
|
puts $lwipopts_fd "\#ifndef PROCESSOR_LITTLE_ENDIAN"
|
|
puts $lwipopts_fd "\#define PROCESSOR_LITTLE_ENDIAN"
|
|
puts $lwipopts_fd "\#endif\n"
|
|
} else {
|
|
puts $lwipopts_fd "\#ifndef PROCESSOR_BIG_ENDIAN"
|
|
puts $lwipopts_fd "\#define PROCESSOR_BIG_ENDIAN"
|
|
puts $lwipopts_fd "\#endif\n"
|
|
}
|
|
}
|
|
|
|
"ps7_cortexa9" {
|
|
puts $lwipopts_fd "\#ifndef PROCESSOR_LITTLE_ENDIAN"
|
|
puts $lwipopts_fd "\#define PROCESSOR_LITTLE_ENDIAN"
|
|
puts $lwipopts_fd "\#endif\n"
|
|
}
|
|
default {
|
|
puts $lwipopts_fd "\#ifndef PROCESSOR_BIG_ENDIAN"
|
|
puts $lwipopts_fd "\#define PROCESSOR_BIG_ENDIAN"
|
|
puts $lwipopts_fd "\#endif\n"
|
|
}
|
|
}
|
|
|
|
# always use lightweight prot mechanism for critical regions
|
|
puts $lwipopts_fd "\#define SYS_LIGHTWEIGHT_PROT 1"
|
|
puts $lwipopts_fd ""
|
|
|
|
set api_mode [common::get_property CONFIG.api_mode $libhandle]
|
|
if {$api_mode == "RAW_API"} {
|
|
puts $lwipopts_fd "\#define NO_SYS 1"
|
|
puts $lwipopts_fd "\#define LWIP_SOCKET 0"
|
|
puts $lwipopts_fd "\#define LWIP_COMPAT_SOCKETS 0"
|
|
puts $lwipopts_fd "\#define LWIP_NETCONN 0"
|
|
}
|
|
puts $lwipopts_fd ""
|
|
|
|
set thread_prio [common::get_property CONFIG.socket_mode_thread_prio $libhandle]
|
|
if {$api_mode == "SOCKET_API"} {
|
|
set sw_proc_handle [hsi::get_sw_processor]
|
|
set os_handle [hsi::get_os]
|
|
set os_name [common::get_property NAME $os_handle]
|
|
if { [string compare -nocase "xilkernel" $os_name] == 0} {
|
|
puts $lwipopts_fd "\#define OS_IS_XILKERNEL"
|
|
puts $lwipopts_fd "\#define TCPIP_THREAD_PRIO $thread_prio"
|
|
puts $lwipopts_fd "\#define DEFAULT_THREAD_PRIO $thread_prio"
|
|
puts $lwipopts_fd "\#define TCPIP_THREAD_STACKSIZE 32768"
|
|
puts $lwipopts_fd ""
|
|
}
|
|
if { [string compare -nocase "freertos_zynq" $os_name] == 0} {
|
|
puts $lwipopts_fd "\#define OS_IS_FREERTOS"
|
|
puts $lwipopts_fd "\#define DEFAULT_THREAD_PRIO $thread_prio"
|
|
puts $lwipopts_fd "\#define TCPIP_THREAD_PRIO (DEFAULT_THREAD_PRIO+1)"
|
|
puts $lwipopts_fd "\#define TCPIP_THREAD_STACKSIZE 32768"
|
|
puts $lwipopts_fd "\#define DEFAULT_TCP_RECVMBOX_SIZE 300"
|
|
puts $lwipopts_fd "\#define DEFAULT_ACCEPTMBOX_SIZE 5"
|
|
puts $lwipopts_fd "\#define TCPIP_MBOX_SIZE 30"
|
|
puts $lwipopts_fd "\#define DEFAULT_UDP_RECVMBOX_SIZE 100"
|
|
puts $lwipopts_fd "\#define DEFAULT_RAW_RECVMBOX_SIZE 100"
|
|
puts $lwipopts_fd ""
|
|
}
|
|
}
|
|
|
|
set use_axieth_on_zynq [common::get_property CONFIG.use_axieth_on_zynq $libhandle]
|
|
set use_emaclite_on_zynq [common::get_property CONFIG.use_emaclite_on_zynq $libhandle]
|
|
|
|
# memory options
|
|
set mem_size [common::get_property CONFIG.mem_size $libhandle]
|
|
set memp_n_pbuf [common::get_property CONFIG.memp_n_pbuf $libhandle]
|
|
set memp_n_udp_pcb [common::get_property CONFIG.memp_n_udp_pcb $libhandle]
|
|
set memp_n_tcp_pcb [common::get_property CONFIG.memp_n_tcp_pcb $libhandle]
|
|
set memp_n_tcp_pcb_listen [common::get_property CONFIG.memp_n_tcp_pcb_listen $libhandle]
|
|
set memp_n_tcp_seg [common::get_property CONFIG.memp_n_tcp_seg $libhandle]
|
|
set memp_n_sys_timeout [common::get_property CONFIG.memp_n_sys_timeout $libhandle]
|
|
set memp_num_netbuf [common::get_property CONFIG.memp_num_netbuf $libhandle]
|
|
set memp_num_netconn [common::get_property CONFIG.memp_num_netconn $libhandle]
|
|
set memp_num_api_msg [common::get_property CONFIG.memp_num_api_msg $libhandle]
|
|
set memp_num_tcpip_msg [common::get_property CONFIG.memp_num_tcpip_msg $libhandle]
|
|
|
|
puts $lwipopts_fd "\#define MEM_ALIGNMENT 64"
|
|
puts $lwipopts_fd "\#define MEM_SIZE $mem_size"
|
|
puts $lwipopts_fd "\#define MEMP_NUM_PBUF $memp_n_pbuf"
|
|
puts $lwipopts_fd "\#define MEMP_NUM_UDP_PCB $memp_n_udp_pcb"
|
|
puts $lwipopts_fd "\#define MEMP_NUM_TCP_PCB $memp_n_tcp_pcb"
|
|
puts $lwipopts_fd "\#define MEMP_NUM_TCP_PCB_LISTEN $memp_n_tcp_pcb_listen"
|
|
puts $lwipopts_fd "\#define MEMP_NUM_TCP_SEG $memp_n_tcp_seg"
|
|
puts $lwipopts_fd "\#define MEMP_NUM_SYS_TIMEOUT $memp_n_sys_timeout"
|
|
puts $lwipopts_fd "\#define MEMP_NUM_NETBUF $memp_num_netbuf"
|
|
puts $lwipopts_fd "\#define MEMP_NUM_NETCONN $memp_num_netconn"
|
|
puts $lwipopts_fd "\#define MEMP_NUM_TCPIP_MSG_API $memp_num_api_msg"
|
|
puts $lwipopts_fd "\#define MEMP_NUM_TCPIP_MSG_INPKT $memp_num_tcpip_msg"
|
|
|
|
# workaround for lwip mem_malloc bug
|
|
# puts $lwipopts_fd "\#define MEM_LIBC_MALLOC 1"
|
|
puts $lwipopts_fd ""
|
|
|
|
# seq api
|
|
if {$api_mode == "SOCKET_API"} {
|
|
puts $lwipopts_fd "\#define MEMP_NUM_NETBUF $memp_num_netbuf"
|
|
puts $lwipopts_fd "\#define MEMP_NUM_NETCONN $memp_num_netconn"
|
|
puts $lwipopts_fd "\#define LWIP_PROVIDE_ERRNO 1"
|
|
}
|
|
puts $lwipopts_fd "\#define MEMP_NUM_SYS_TIMEOUT $memp_n_sys_timeout"
|
|
|
|
# pbuf options
|
|
set pbuf_pool_size [common::get_property CONFIG.pbuf_pool_size $libhandle]
|
|
set pbuf_pool_bufsize [common::get_property CONFIG.pbuf_pool_bufsize $libhandle]
|
|
set pbuf_link_hlen [common::get_property CONFIG.pbuf_link_hlen $libhandle]
|
|
|
|
puts $lwipopts_fd "\#define PBUF_POOL_SIZE $pbuf_pool_size"
|
|
puts $lwipopts_fd "\#define PBUF_POOL_BUFSIZE $pbuf_pool_bufsize"
|
|
puts $lwipopts_fd "\#define PBUF_LINK_HLEN $pbuf_link_hlen"
|
|
puts $lwipopts_fd ""
|
|
|
|
# ARP options
|
|
set arp_table_size [common::get_property CONFIG.arp_table_size $libhandle]
|
|
set arp_queueing [common::get_property CONFIG.arp_queueing $libhandle]
|
|
puts $lwipopts_fd "\#define ARP_TABLE_SIZE $arp_table_size"
|
|
puts $lwipopts_fd "\#define ARP_QUEUEING $arp_queueing"
|
|
puts $lwipopts_fd ""
|
|
|
|
# ICMP options
|
|
set icmp_ttl [common::get_property CONFIG.icmp_ttl $libhandle]
|
|
puts $lwipopts_fd "\#define ICMP_TTL $icmp_ttl"
|
|
puts $lwipopts_fd ""
|
|
|
|
# IGMP options
|
|
set igmp_val [common::get_property CONFIG.igmp_options $libhandle]
|
|
if {$igmp_val == true} {
|
|
puts $lwipopts_fd "\#define LWIP_IGMP 1"
|
|
puts $lwipopts_fd ""
|
|
}
|
|
|
|
# IP options
|
|
set ip_forward [common::get_property CONFIG.ip_forward $libhandle]
|
|
set ip_options [common::get_property CONFIG.ip_options $libhandle]
|
|
set ip_reassembly [common::get_property CONFIG.ip_reassembly $libhandle]
|
|
set ip_frag [common::get_property CONFIG.ip_frag $libhandle]
|
|
set ip_reass_max_pbufs [common::get_property CONFIG.ip_reass_max_pbufs $libhandle]
|
|
set ip_frag_max_mtu [common::get_property CONFIG.ip_frag_max_mtu $libhandle]
|
|
set ip_default_ttl [common::get_property CONFIG.ip_default_ttl $libhandle]
|
|
|
|
puts $lwipopts_fd "\#define IP_OPTIONS $ip_options"
|
|
puts $lwipopts_fd "\#define IP_FORWARD $ip_forward"
|
|
puts $lwipopts_fd "\#define IP_REASSEMBLY $ip_reassembly"
|
|
puts $lwipopts_fd "\#define IP_FRAG $ip_frag"
|
|
puts $lwipopts_fd "\#define IP_REASS_MAX_PBUFS $ip_reass_max_pbufs"
|
|
puts $lwipopts_fd "\#define IP_FRAG_MAX_MTU $ip_frag_max_mtu"
|
|
puts $lwipopts_fd "\#define IP_DEFAULT_TTL $ip_default_ttl"
|
|
puts $lwipopts_fd "\#define LWIP_CHKSUM_ALGORITHM 3"
|
|
puts $lwipopts_fd ""
|
|
|
|
# UDP options
|
|
set lwip_udp [expr [common::get_property CONFIG.lwip_udp $libhandle] == true]
|
|
set udp_ttl [common::get_property CONFIG.udp_ttl $libhandle]
|
|
puts $lwipopts_fd "\#define LWIP_UDP $lwip_udp"
|
|
puts $lwipopts_fd "\#define UDP_TTL $udp_ttl"
|
|
puts $lwipopts_fd ""
|
|
|
|
# TCP options
|
|
set lwip_tcp [expr [common::get_property CONFIG.lwip_tcp $libhandle] == true]
|
|
set tcp_mss [common::get_property CONFIG.tcp_mss $libhandle]
|
|
set tcp_snd_buf [common::get_property CONFIG.tcp_snd_buf $libhandle]
|
|
set tcp_wnd [common::get_property CONFIG.tcp_wnd $libhandle]
|
|
set tcp_ttl [common::get_property CONFIG.tcp_ttl $libhandle]
|
|
set tcp_maxrtx [common::get_property CONFIG.tcp_maxrtx $libhandle]
|
|
set tcp_synmaxrtx [common::get_property CONFIG.tcp_synmaxrtx $libhandle]
|
|
set tcp_queue_ooseq [common::get_property CONFIG.tcp_queue_ooseq $libhandle]
|
|
|
|
puts $lwipopts_fd "\#define LWIP_TCP $lwip_tcp"
|
|
puts $lwipopts_fd "\#define TCP_MSS $tcp_mss"
|
|
puts $lwipopts_fd "\#define TCP_SND_BUF $tcp_snd_buf"
|
|
puts $lwipopts_fd "\#define TCP_WND $tcp_wnd"
|
|
puts $lwipopts_fd "\#define TCP_TTL $tcp_ttl"
|
|
puts $lwipopts_fd "\#define TCP_MAXRTX $tcp_maxrtx"
|
|
puts $lwipopts_fd "\#define TCP_SYNMAXRTX $tcp_synmaxrtx"
|
|
puts $lwipopts_fd "\#define TCP_QUEUE_OOSEQ $tcp_queue_ooseq"
|
|
puts $lwipopts_fd "\#define TCP_SND_QUEUELEN 16 * TCP_SND_BUF/TCP_MSS"
|
|
|
|
set have_ethonzynq 0
|
|
foreach emac $emac_periphs_list {
|
|
set iptype [common::get_property IP_NAME $emac]
|
|
if {$iptype == "axi_ethernet" || $iptype == "axi_ethernet_buffer" } {
|
|
set have_ethonzynq 1
|
|
}
|
|
}
|
|
|
|
if { $have_ethonzynq != 1} {
|
|
set use_axieth_on_zynq 0
|
|
}
|
|
|
|
if {$proctype != "ps7_cortexa9" || $use_axieth_on_zynq == 1} {
|
|
set tx_full_csum_temp [common::get_property CONFIG.tcp_ip_tx_checksum_offload $libhandle]
|
|
set rx_full_csum_temp [common::get_property CONFIG.tcp_ip_rx_checksum_offload $libhandle]
|
|
|
|
set tx_csum_temp [common::get_property CONFIG.tcp_tx_checksum_offload $libhandle]
|
|
set rx_csum_temp [common::get_property CONFIG.tcp_rx_checksum_offload $libhandle]
|
|
|
|
if {$tx_csum_temp || $rx_csum_temp} {
|
|
set tx_csum [expr ![common::get_property CONFIG.tcp_tx_checksum_offload $libhandle]]
|
|
puts $lwipopts_fd "\#define CHECKSUM_GEN_TCP $tx_csum"
|
|
set rx_csum [expr ![common::get_property CONFIG.tcp_rx_checksum_offload $libhandle]]
|
|
puts $lwipopts_fd "\#define CHECKSUM_CHECK_TCP $rx_csum"
|
|
}
|
|
if {$tx_full_csum_temp || $rx_full_csum_temp} {
|
|
set tx_full_csum [expr ![common::get_property CONFIG.tcp_ip_tx_checksum_offload $libhandle]]
|
|
puts $lwipopts_fd "\#define CHECKSUM_GEN_TCP $tx_full_csum"
|
|
puts $lwipopts_fd "\#define CHECKSUM_GEN_UDP $tx_full_csum"
|
|
puts $lwipopts_fd "\#define CHECKSUM_GEN_IP $tx_full_csum"
|
|
set rx_full_csum [expr ![common::get_property CONFIG.tcp_ip_rx_checksum_offload $libhandle]]
|
|
puts $lwipopts_fd "\#define CHECKSUM_CHECK_TCP $rx_full_csum"
|
|
puts $lwipopts_fd "\#define CHECKSUM_CHECK_UDP $rx_full_csum"
|
|
puts $lwipopts_fd "\#define CHECKSUM_CHECK_IP $rx_full_csum"
|
|
}
|
|
} else {
|
|
if {$have_emaclite == 1} {
|
|
puts $lwipopts_fd "\#define CHECKSUM_GEN_TCP 1"
|
|
puts $lwipopts_fd "\#define CHECKSUM_GEN_UDP 1"
|
|
puts $lwipopts_fd "\#define CHECKSUM_GEN_IP 1"
|
|
puts $lwipopts_fd "\#define CHECKSUM_CHECK_TCP 1"
|
|
puts $lwipopts_fd "\#define CHECKSUM_CHECK_UDP 1"
|
|
puts $lwipopts_fd "\#define CHECKSUM_CHECK_IP 1"
|
|
} else {
|
|
puts $lwipopts_fd "\#define CHECKSUM_GEN_TCP 0"
|
|
puts $lwipopts_fd "\#define CHECKSUM_GEN_UDP 0"
|
|
puts $lwipopts_fd "\#define CHECKSUM_GEN_IP 0"
|
|
puts $lwipopts_fd "\#define CHECKSUM_CHECK_TCP 0"
|
|
puts $lwipopts_fd "\#define CHECKSUM_CHECK_UDP 0"
|
|
puts $lwipopts_fd "\#define CHECKSUM_CHECK_IP 0"
|
|
}
|
|
|
|
}
|
|
|
|
puts $lwipopts_fd ""
|
|
|
|
|
|
puts $lwipopts_fd "\#define NO_SYS_NO_TIMERS 1"
|
|
puts $lwipopts_fd "\#define MEMP_SEPARATE_POOLS 1"
|
|
puts $lwipopts_fd "\#define MEMP_NUM_FRAG_PBUF 256"
|
|
puts $lwipopts_fd "\#define IP_OPTIONS_ALLOWED 0"
|
|
if {$proctype != "ps7_cortexa9"} {
|
|
puts $lwipopts_fd "\#define TCP_OVERSIZE 0"
|
|
} else {
|
|
puts $lwipopts_fd "\#define TCP_OVERSIZE TCP_MSS"
|
|
}
|
|
if {$proctype != "ps7_cortexa9"} {
|
|
puts $lwipopts_fd "\#define LWIP_COMPAT_MUTEX 1"
|
|
puts $lwipopts_fd "\#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0"
|
|
} else {
|
|
puts $lwipopts_fd "\#define LWIP_COMPAT_MUTEX 0"
|
|
puts $lwipopts_fd "\#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 1"
|
|
}
|
|
puts $lwipopts_fd ""
|
|
|
|
set jumbo_frames [common::get_property CONFIG.temac_use_jumbo_frames $libhandle]
|
|
if {$jumbo_frames} {
|
|
puts $lwipopts_fd "\#define USE_JUMBO_FRAMES 1"
|
|
puts $lwipopts_fd ""
|
|
}
|
|
|
|
# DHCP options
|
|
set lwip_dhcp [expr [common::get_property CONFIG.lwip_dhcp $libhandle] == true]
|
|
set dhcp_does_arp_check [expr [common::get_property CONFIG.dhcp_does_arp_check $libhandle] == true]
|
|
puts $lwipopts_fd "\#define LWIP_DHCP $lwip_dhcp"
|
|
puts $lwipopts_fd "\#define DHCP_DOES_ARP_CHECK $dhcp_does_arp_check"
|
|
puts $lwipopts_fd ""
|
|
|
|
|
|
# temac adapter options
|
|
set linkspeed [common::get_property CONFIG.phy_link_speed $libhandle]
|
|
puts $lwipopts_fd "\#define $linkspeed 1"
|
|
puts $lwipopts_fd ""
|
|
|
|
# lwIP stats
|
|
set lwip_stats [common::get_property CONFIG.lwip_stats $libhandle]
|
|
if {$lwip_stats} {
|
|
puts $lwipopts_fd "\#define LWIP_STATS 1"
|
|
puts $lwipopts_fd "\#define LWIP_STATS_DISPLAY 1"
|
|
puts $lwipopts_fd ""
|
|
}
|
|
|
|
# lwIP debug
|
|
set lwip_debug [expr [common::get_property CONFIG.lwip_debug $libhandle] == true]
|
|
set ip_debug [expr [common::get_property CONFIG.ip_debug $libhandle] == true]
|
|
set tcp_debug [expr [common::get_property CONFIG.tcp_debug $libhandle] == true]
|
|
set udp_debug [expr [common::get_property CONFIG.udp_debug $libhandle] == true]
|
|
set icmp_debug [expr [common::get_property CONFIG.icmp_debug $libhandle] == true]
|
|
set igmp_debug [expr [common::get_property CONFIG.igmp_debug $libhandle] == true]
|
|
set netif_debug [expr [common::get_property CONFIG.netif_debug $libhandle] == true]
|
|
set sys_debug [expr [common::get_property CONFIG.sys_debug $libhandle] == true]
|
|
set pbuf_debug [expr [common::get_property CONFIG.pbuf_debug $libhandle] == true]
|
|
|
|
if {$lwip_debug == 1} {
|
|
puts $lwipopts_fd "\#define LWIP_DEBUG 1"
|
|
puts $lwipopts_fd "\#define DBG_TYPES_ON DBG_LEVEL_WARNING"
|
|
if {$ip_debug} { puts $lwipopts_fd "\#define IP_DEBUG (LWIP_DBG_LEVEL_SEVERE | LWIP_DBG_ON)" }
|
|
if {$tcp_debug} {
|
|
puts $lwipopts_fd "\#define TCP_DEBUG (LWIP_DBG_LEVEL_SEVERE | LWIP_DBG_ON)"
|
|
puts $lwipopts_fd "\#define TCP_DEBUG (LWIP_DBG_LEVEL_SEVERE | LWIP_DBG_ON)"
|
|
puts $lwipopts_fd "\#define TCP_INPUT_DEBUG (LWIP_DBG_LEVEL_SEVERE | LWIP_DBG_ON)"
|
|
puts $lwipopts_fd "\#define TCP_OUTPUT_DEBUG (LWIP_DBG_LEVEL_SEVERE | LWIP_DBG_ON)"
|
|
puts $lwipopts_fd "\#define TCPIP_DEBUG (LWIP_DBG_LEVEL_SEVERE | LWIP_DBG_ON)"
|
|
}
|
|
if {$udp_debug} { puts $lwipopts_fd "\#define UDP_DEBUG (LWIP_DBG_LEVEL_SEVERE | LWIP_DBG_ON)" }
|
|
if {$icmp_debug} { puts $lwipopts_fd "\#define ICMP_DEBUG (LWIP_DBG_LEVEL_SEVERE | LWIP_DBG_ON)" }
|
|
if {$igmp_debug} { puts $lwipopts_fd "\#define IGMP_DEBUG (LWIP_DBG_LEVEL_SEVERE | LWIP_DBG_ON)" }
|
|
if {$netif_debug} { puts $lwipopts_fd "\#define NETIF_DEBUG (LWIP_DBG_LEVEL_SEVERE | LWIP_DBG_ON)" }
|
|
if {$sys_debug} {
|
|
puts $lwipopts_fd "\#define SYS_DEBUG (LWIP_DBG_LEVEL_SEVERE | LWIP_DBG_ON)"
|
|
puts $lwipopts_fd "\#define API_MSG_DEBUG (LWIP_DBG_LEVEL_SEVERE | LWIP_DBG_ON)"
|
|
}
|
|
if {$pbuf_debug} {
|
|
puts $lwipopts_fd "\#define PBUF_DEBUG (LWIP_DBG_LEVEL_SEVERE | LWIP_DBG_ON)"
|
|
}
|
|
puts $lwipopts_fd "\#define MEMP_DEBUG (LWIP_DBG_LEVEL_SEVERE | LWIP_DBG_ON)"
|
|
puts $lwipopts_fd ""
|
|
}
|
|
|
|
puts $lwipopts_fd "\#endif"
|
|
close $lwipopts_fd
|
|
}
|
|
|
|
|
|
proc update_temac_topology {emac processor topologyvar} {
|
|
upvar $topologyvar topology
|
|
|
|
set topology(emac_baseaddr) [common::get_property CONFIG.C_BASEADDR $emac]
|
|
set topology(emac_type) "xemac_type_xps_ll_temac"
|
|
|
|
# find intc to which the interrupt line is connected
|
|
set emac_intr_port [hsi::get_pins -of_objects [hsi::get_cells $emac] TemacIntc0_Irpt]
|
|
set intr_ports [::hsm::utils::get_sink_pins [hsi::get_pins -of_objects [hsi::get_cells $emac] TemacIntc0_Irpt]]
|
|
|
|
set l [llength $intr_ports]
|
|
|
|
if { [llength $intr_ports] != 1 } {
|
|
set emac_name [common::get_property NAME $emac]
|
|
error "ERROR: xps_ll_temac ($emac_name) interrupt port connected to more than one IP.\
|
|
lwIP requires that the interrupt line be connected only to the interrupt controller"
|
|
"" "mdt_error"
|
|
}
|
|
|
|
set intr_port [lindex $intr_ports 0]
|
|
set intc_handle [hsi::get_cells -of_objects $intr_port]
|
|
|
|
# can we address this intc from the processor?
|
|
set proc_connected_periphs [::hsm::utils::get_proc_slave_periphs $processor]
|
|
if { [lsearch -exact $proc_connected_periphs $intc_handle] == -1 } {
|
|
set intc_name [common::get_property NAME $intc_handle]
|
|
set proc_name [common::get_property NAME $processor]
|
|
error "ERROR: $intc_name to which xps_ll_temac interrupt is connected is not addressable \
|
|
from processor $proc_name" "" "mdt_error"
|
|
}
|
|
|
|
set topology(intc_baseaddr) [common::get_property CONFIG.C_BASEADDR $intc_handle]
|
|
set topology(intc_baseaddr) [::hsm::utils::format_addr_string $topology(intc_baseaddr) "C_BASEADDR"]
|
|
set topology(scugic_baseaddr) "0x0"
|
|
set topology(scugic_emac_intr) "0x0"
|
|
}
|
|
|
|
# redundant code
|
|
# repeat the same steps as update_temac_topology, but for temac1
|
|
proc update_temac1_topology {emac processor topologyvar} {
|
|
upvar $topologyvar topology
|
|
|
|
set topology(emac_baseaddr) [format 0x%x [expr [common::get_property CONFIG.C_BASEADDR $emac] + 0x40]]
|
|
set topology(emac_type) "xemac_type_xps_ll_temac"
|
|
|
|
# find intc to which the interrupt line is connected
|
|
set emac_intr_port [hsi::get_pins -of_objects [hsi::get_cells $emac] TemacIntc1_Irpt]
|
|
set mhs_handle [hsi::get_cells $emac]
|
|
set intr_ports [xget_connected_ports_handle $mhs_handle $emac_intr_port "sink"]
|
|
|
|
if { [llength $intr_ports] != 1 } {
|
|
set emac_name [common::get_property NAME $emac]
|
|
error "ERROR: xps_ll_temac ($emac_name) interrupt port connected to more than one IP.\
|
|
lwIP requires that the interrupt line be connected only to the interrupt controller"
|
|
"" "mdt_error"
|
|
}
|
|
|
|
set intr_port [lindex $intr_ports 0]
|
|
set intc_handle [hsi::get_cells -of_objects $intr_port]
|
|
|
|
# can we address this intc from the processor?
|
|
set proc_connected_periphs [::hsm::utils::get_proc_slave_periphs $processor]
|
|
if { [lsearch -exact $proc_connected_periphs $intc_handle] == -1 } {
|
|
set intc_name [common::get_property NAME $intc_handle]
|
|
set proc_name [common::get_property NAME $processor]
|
|
error "ERROR: $intc_name to which xps_ll_temac interrupt is connected is not addressable \
|
|
from processor $proc_name" "" "mdt_error"
|
|
}
|
|
|
|
set topology(intc_baseaddr) [common::get_property CONFIG.C_BASEADDR $intc_handle]
|
|
set topology(intc_baseaddr) [::hsm::utils::format_addr_string $topology(intc_baseaddr) "C_BASEADDR"]
|
|
set topology(scugic_baseaddr) "0x0"
|
|
set topology(scugic_emac_intr) "0x0"
|
|
}
|
|
|
|
proc update_emaclite_topology {emac processor topologyvar} {
|
|
global use_emaclite_on_zynq
|
|
upvar $topologyvar topology
|
|
set sw_processor [hsi::get_sw_processor]
|
|
set processor [hsi::get_cells [common::get_property HW_INSTANCE $sw_processor]]
|
|
set processor_type [common::get_property IP_NAME $processor]
|
|
set force_emaclite_on_zynq 0
|
|
|
|
if {$processor_type == "ps7_cortexa9" && $use_emaclite_on_zynq == 1} {
|
|
set force_emaclite_on_zynq 1
|
|
}
|
|
|
|
# get emac baseaddr
|
|
set topology(emac_baseaddr) [common::get_property CONFIG.C_BASEADDR $emac]
|
|
set topology(emac_type) "xemac_type_xps_emaclite"
|
|
|
|
if {$force_emaclite_on_zynq == 1} {
|
|
set topology(intc_baseaddr) "0x0"
|
|
set topology(scugic_baseaddr) "0xF8F00100"
|
|
set topology(scugic_emac_intr) "0x0"
|
|
set topology(emac_intr_id) "XPAR_FABRIC_AXI_ETHERNETLITE_0_IP2INTC_IRPT_INTR"
|
|
} else {
|
|
|
|
# find intc to which the interrupt line is connected
|
|
set emac_intr_port [hsi::get_pins -of_objects [hsi::get_cells $emac] IP2INTC_Irpt]
|
|
set mhs_handle [hsi::get_cells $emac]
|
|
set intr_ports [::hsm::utils::get_sink_pins [hsi::get_pins -of_objects [hsi::get_cells $emac] IP2INTC_Irpt]]
|
|
|
|
if { [llength $intr_ports] != 1 } {
|
|
set emac_name [common::get_property NAME $emac]
|
|
error "ERROR: emaclite ($emac_name) interrupt port connected to more than one IP.\
|
|
lwIP requires that the interrupt line be connected only to the interrupt controller"
|
|
"" "mdt_error"
|
|
}
|
|
|
|
set intr_port [lindex $intr_ports 0]
|
|
set intc_handle [hsi::get_cells -of_objects $intr_port]
|
|
|
|
# can we address this intc from the processor?
|
|
set proc_connected_periphs [::hsm::utils::get_proc_slave_periphs $processor]
|
|
if { [lsearch -exact $proc_connected_periphs $intc_handle] == -1 } {
|
|
set intc_name [common::get_property NAME $intc_handle]
|
|
set proc_name [common::get_property NAME $processor]
|
|
error "ERROR: $intc_name to which ethernetlite interrupt is connected is not addressable \
|
|
from processor $proc_name" "" "mdt_error"
|
|
}
|
|
|
|
set topology(intc_baseaddr) [common::get_property CONFIG.C_BASEADDR $intc_handle]
|
|
|
|
# find interrupt pin number
|
|
set topology(emac_intr_id) [xget_port_interrupt_id $emac $emac_intr_port]
|
|
set topology(scugic_baseaddr) "0x0"
|
|
set topology(scugic_emac_intr) "0x0"
|
|
}
|
|
}
|
|
|
|
proc update_axi_ethernet_topology {emac processor topologyvar} {
|
|
upvar $topologyvar topology
|
|
set topology(emac_baseaddr) [common::get_property CONFIG.C_BASEADDR $emac]
|
|
set topology(emac_type) "xemac_type_axi_ethernet"
|
|
|
|
# find intc to which the interrupt line is connected
|
|
set emac_intr_port [hsi::get_pins -of_objects [hsi::get_cells $emac] INTERRUPT]
|
|
set intr_ports [::hsm::utils::get_sink_pins [hsi::get_pins -of_objects [hsi::get_cells $emac] INTERRUPT]]
|
|
set intr_cnt 0
|
|
foreach intr_sink $intr_ports {
|
|
set phandle [hsi::get_cells -of_objects $intr_sink]
|
|
set pname_type [common::get_property NAME $phandle]
|
|
if {$pname_type != "chipscope_ila"} {
|
|
incr intr_cnt
|
|
set intc_handle [hsi::get_cells -of_objects $intr_sink]
|
|
set intc_periph_type [common::get_property IP_NAME $intc_handle]
|
|
set intc_name [common::get_property NAME $intc_handle]
|
|
# can we address this intc from the processor?
|
|
set proc_connected_periphs [::hsm::utils::get_proc_slave_periphs $processor]
|
|
if { [lsearch -exact $proc_connected_periphs $intc_handle] == -1 } {
|
|
set proc_name [common::get_property NAME $processor]
|
|
error "ERROR: $intc_name to which axi_ethernet interrupt is connected is not addressable \
|
|
from processor $proc_name" "" "mdt_error"
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if { $intr_cnt != 1 } {
|
|
set emac_name [common::get_property NAME $emac]
|
|
error "ERROR: axi_ethernet ($emac_name) interrupt port connected to more than one IP.\
|
|
lwIP requires that the interrupt line be connected only to the interrupt controller"
|
|
"" "mdt_error"
|
|
}
|
|
|
|
if { $intc_periph_type != [format "ps7_scugic"] } {
|
|
set topology(intc_baseaddr) [common::get_property CONFIG.C_BASEADDR $intc_handle]
|
|
set topology(intc_baseaddr) [::hsm::utils::format_addr_string $topology(intc_baseaddr) "C_BASEADDR"]
|
|
set topology(scugic_baseaddr) "0x0"
|
|
set topology(scugic_emac_intr) "0x0"
|
|
} else {
|
|
set topology(intc_baseaddr) "0x0"
|
|
set topology(scugic_baseaddr) "0xF8F00100"
|
|
set topology(scugic_emac_intr) "0x0"
|
|
}
|
|
|
|
}
|
|
|
|
proc update_ps7_ethernet_topology {emac processor topologyvar} {
|
|
upvar $topologyvar topology
|
|
set topology(emac_baseaddr) [common::get_property CONFIG.C_S_AXI_BASEADDR $emac]
|
|
set topology(emac_type) "xemac_type_emacps"
|
|
set topology(intc_baseaddr) "0x0"
|
|
set topology(emac_intr_id) "0x0"
|
|
set topology(scugic_baseaddr) "0xF8F00100"
|
|
set topology(scugic_emac_intr) "0x0"
|
|
set ethernet_instance [common::get_property NAME $emac]
|
|
if {$ethernet_instance == "ps7_ethernet_0" || $ethernet_instance == "ps7_enet0"} {
|
|
set topology(scugic_emac_intr) "0x36"
|
|
} elseif {$ethernet_instance == "ps7_ethernet_1" || $ethernet_instance == "ps7_enet1"} {
|
|
set topology(scugic_emac_intr) "0x4D"
|
|
}
|
|
}
|
|
|
|
proc generate_topology_per_emac {fd topologyvar} {
|
|
upvar $topologyvar topology
|
|
|
|
puts $fd " {"
|
|
puts $fd " $topology(emac_baseaddr),"
|
|
puts $fd " $topology(emac_type),"
|
|
puts $fd " $topology(intc_baseaddr),"
|
|
puts $fd " $topology(emac_intr_id),"
|
|
puts $fd " $topology(scugic_baseaddr),"
|
|
puts $fd " $topology(scugic_emac_intr),"
|
|
puts $fd " },"
|
|
}
|
|
|
|
proc generate_topology {libhandle} {
|
|
set sw_processor [hsi::get_sw_processor]
|
|
set processor [hsi::get_cells [common::get_property HW_INSTANCE $sw_processor]]
|
|
set emac_periphs_list [get_emac_periphs $processor]
|
|
set tempcntr 0
|
|
|
|
|
|
set topology_file "src/contrib/ports/xilinx/netif/xtopology_g.c"
|
|
set topology_size 0
|
|
|
|
file delete $topology_file
|
|
set tfd [open $topology_file w]
|
|
|
|
puts $tfd "#include \"netif/xtopology.h\""
|
|
puts $tfd "#include \"xparameters.h\""
|
|
puts $tfd ""
|
|
|
|
puts $tfd "struct xtopology_t xtopology\[\] = {"
|
|
|
|
foreach emac $emac_periphs_list {
|
|
# initialize topology variables
|
|
set topology(emac_baseaddr) -1
|
|
set topology(emac_type) "xemac_type_unknown"
|
|
set topology(intc_baseaddr) -1
|
|
set topology(emac_intr_id) -1
|
|
|
|
# get topology for the emac
|
|
set iptype [common::get_property IP_NAME $emac]
|
|
if {$iptype == "xps_ethernetlite" || $iptype == "opb_ethernetlite" || $iptype == "axi_ethernetlite"} {
|
|
update_emaclite_topology $emac $processor topology
|
|
generate_topology_per_emac $tfd topology
|
|
incr topology_size 1
|
|
} elseif {$iptype == "xps_ll_temac"} {
|
|
set emac_intr_port [hsi::get_pins -of_objects [hsi::get_cells $emac] TemacIntc0_Irpt]
|
|
set temac0 "0"
|
|
if {$emac_intr_port != ""} { set temac0 "1" }
|
|
if {$temac0 == "1"} {
|
|
update_temac_topology $emac $processor topology
|
|
generate_topology_per_emac $tfd topology
|
|
incr topology_size 1
|
|
}
|
|
|
|
set temac1 [common::get_property CONFIG.C_TEMAC1_ENABLED $emac]
|
|
if {$temac1 == "1"} {
|
|
update_temac1_topology $emac $processor topology
|
|
generate_topology_per_emac $tfd topology
|
|
incr topology_size 1
|
|
}
|
|
} elseif {$iptype == "axi_ethernet" || $iptype == "axi_ethernet_buffer"} {
|
|
update_axi_ethernet_topology $emac $processor topology
|
|
generate_topology_per_emac $tfd topology
|
|
incr topology_size 1
|
|
} elseif {$iptype == "ps7_ethernet"} {
|
|
update_ps7_ethernet_topology $emac $processor topology
|
|
generate_topology_per_emac $tfd topology
|
|
incr topology_size 1
|
|
}
|
|
}
|
|
|
|
puts $tfd "};"
|
|
puts $tfd ""
|
|
|
|
puts $tfd "int xtopology_n_emacs = $topology_size;"
|
|
|
|
|
|
close $tfd
|
|
}
|
|
|
|
proc generate_adapterconfig_makefile {libhandle} {
|
|
global use_axieth_on_zynq
|
|
global use_emaclite_on_zynq
|
|
set sw_processor [hsi::get_sw_processor]
|
|
set processor [hsi::get_cells [common::get_property HW_INSTANCE $sw_processor]]
|
|
set processor_type [common::get_property IP_NAME $processor]
|
|
set emac_periphs_list [get_emac_periphs $processor]
|
|
|
|
set have_emaclite 0
|
|
set have_temac 0
|
|
set have_axi_ethernet 0
|
|
set have_axi_ethernet_fifo 0
|
|
set have_axi_ethernet_dma 0
|
|
set have_ps7_ethernet 0
|
|
set force_axieth_on_zynq 0
|
|
set force_emaclite_on_zynq 0
|
|
|
|
if {$processor_type == "ps7_cortexa9" && $use_axieth_on_zynq == 1} {
|
|
set force_axieth_on_zynq 1
|
|
}
|
|
if {$processor_type == "ps7_cortexa9" && $use_emaclite_on_zynq == 1} {
|
|
set force_emaclite_on_zynq 1
|
|
}
|
|
|
|
foreach emac $emac_periphs_list {
|
|
set iptype [common::get_property IP_NAME $emac]
|
|
if {$iptype == "xps_ethernetlite" || $iptype == "opb_ethernetlite" || $iptype == "axi_ethernetlite"} {
|
|
set have_emaclite 1
|
|
} elseif {$iptype == "xps_ll_temac"} {
|
|
set have_temac 1
|
|
} elseif {$iptype == "axi_ethernet" || $iptype == "axi_ethernet_buffer"} {
|
|
set have_axi_ethernet 1
|
|
# Find the AXI FIFO or AXI DMA that this emac is connected to.
|
|
set connected_bus_name [::hsm::utils::get_connected_intf $emac AXI_STR_RXD]
|
|
set parent_handle [hsi::get_cells -of_objects $connected_bus_name]
|
|
set parent_name [common::get_property IP_NAME $parent_handle]
|
|
if {$parent_name == "axi_fifo_mm_s"} {
|
|
set have_axi_ethernet_fifo 1
|
|
} else {
|
|
set have_axi_ethernet_dma 1
|
|
}
|
|
} elseif {$iptype == "ps7_ethernet"} {
|
|
set have_ps7_ethernet 1
|
|
}
|
|
}
|
|
if {$force_axieth_on_zynq == 1 && $have_axi_ethernet == 1} {
|
|
set have_ps7_ethernet 0
|
|
set have_axi_ethernet 1
|
|
}
|
|
if {$force_emaclite_on_zynq == 1 && $have_emaclite == 1} {
|
|
set have_ps7_ethernet 0
|
|
set have_axi_ethernet 0
|
|
}
|
|
|
|
set makeconfig "src/Makefile.config"
|
|
file delete $makeconfig
|
|
set fd [open $makeconfig w]
|
|
|
|
# determine the processor type so that we know the compiler to use
|
|
set proctype [common::get_property IP_NAME $processor]
|
|
switch -regexp $proctype {
|
|
"microblaze" {
|
|
puts $fd "GCC_COMPILER=mb-gcc"
|
|
|
|
# AXI systems are Little Endian
|
|
# 0 = BE, 1 = LE
|
|
set endian [common::get_property CONFIG.C_ENDIANNESS $processor]
|
|
if {$endian != 0} {
|
|
#puts "Little Endian system"
|
|
puts $fd "CONFIG_PROCESSOR_LITTLE_ENDIAN=y"
|
|
} else {
|
|
#puts "Big Endian system"
|
|
puts $fd "CONFIG_PROCESSOR_BIG_ENDIAN=y"
|
|
}
|
|
}
|
|
ppc* {
|
|
puts $fd "GCC_COMPILER=powerpc-eabi-gcc"
|
|
}
|
|
"ps7_cortexa9" {
|
|
puts $fd "GCC_COMPILER=arm-xilinx-eabi-gcc"
|
|
#puts "Little Endian system"
|
|
puts $fd "CONFIG_PROCESSOR_LITTLE_ENDIAN=y"
|
|
}
|
|
default {
|
|
puts "unknown processor type $proctype\n"
|
|
}
|
|
}
|
|
|
|
if {$have_emaclite == 1} {
|
|
puts $fd "CONFIG_XEMACLITE=y"
|
|
}
|
|
|
|
if {$have_temac == 1} {
|
|
puts $fd "CONFIG_XLLTEMAC=y"
|
|
}
|
|
|
|
if {$force_axieth_on_zynq == 1 || $have_ps7_ethernet == 0 } {
|
|
if {$have_axi_ethernet == 1} {
|
|
puts $fd "CONFIG_AXI_ETHERNET=y"
|
|
}
|
|
if {$have_axi_ethernet_dma == 1} {
|
|
puts $fd "CONFIG_AXI_ETHERNET_DMA=y"
|
|
}
|
|
if {$have_axi_ethernet_fifo == 1} {
|
|
puts $fd "CONFIG_AXI_ETHERNET_FIFO=y"
|
|
}
|
|
} elseif {$have_ps7_ethernet == 1} {
|
|
puts $fd "CONFIG_PS7_ETHERNET=y"
|
|
}
|
|
|
|
set api_mode [common::get_property CONFIG.api_mode $libhandle]
|
|
if {$api_mode == "SOCKET_API"} {
|
|
puts $fd "CONFIG_SOCKETS=y"
|
|
}
|
|
|
|
close $fd
|
|
}
|
|
|
|
proc generate_adapterconfig_include {libhandle} {
|
|
global use_axieth_on_zynq
|
|
global use_emaclite_on_zynq
|
|
set sw_processor [hsi::get_sw_processor]
|
|
set processor [hsi::get_cells [common::get_property HW_INSTANCE $sw_processor]]
|
|
set processor_type [common::get_property IP_NAME $processor]
|
|
set emac_periphs_list [get_emac_periphs $processor]
|
|
|
|
set have_emaclite 0
|
|
set have_temac 0
|
|
set have_axi_ethernet 0
|
|
set have_axi_ethernet_fifo 0
|
|
set have_axi_ethernet_dma 0
|
|
set have_ps7_ethernet 0
|
|
set force_axieth_on_zynq 0
|
|
set force_emaclite_on_zynq 0
|
|
|
|
if {$processor_type == "ps7_cortexa9" && $use_axieth_on_zynq == 1} {
|
|
set force_axieth_on_zynq 1
|
|
}
|
|
if {$processor_type == "ps7_cortexa9" && $use_emaclite_on_zynq == 1} {
|
|
set force_emaclite_on_zynq 1
|
|
}
|
|
|
|
foreach emac $emac_periphs_list {
|
|
set iptype [common::get_property IP_NAME $emac]
|
|
if {$iptype == "xps_ethernetlite" || $iptype == "opb_ethernetlite" || $iptype == "axi_ethernetlite"} {
|
|
set have_emaclite 1
|
|
} elseif {$iptype == "xps_ll_temac"} {
|
|
set have_temac 1
|
|
} elseif {$iptype == "axi_ethernet" || $iptype == "axi_ethernet_buffer"} {
|
|
# Find the AXI FIFO or AXI DMA that this emac is connected to.
|
|
set connected_bus_name [::hsm::utils::get_connected_intf $emac AXI_STR_RXD]
|
|
set parent_handle [hsi::get_cells -of_objects $connected_bus_name]
|
|
set parent_name [common::get_property IP_NAME $parent_handle]
|
|
if {$parent_name == "axi_fifo_mm_s"} {
|
|
set have_axi_ethernet_fifo 1
|
|
} else {
|
|
set have_axi_ethernet_dma 1
|
|
}
|
|
set have_axi_ethernet 1
|
|
} elseif {$iptype == "ps7_ethernet"} {
|
|
set have_ps7_ethernet 1
|
|
}
|
|
}
|
|
if {$force_emaclite_on_zynq == 1 && $have_emaclite == 1} {
|
|
set have_ps7_ethernet 0
|
|
set have_axi_ethernet 0
|
|
}
|
|
|
|
if {$force_axieth_on_zynq == 1 && $have_axi_ethernet == 1} {
|
|
set have_ps7_ethernet 0
|
|
set have_emaclite 0
|
|
set have_axi_ethernet 1
|
|
}
|
|
set adapterconfig "src/contrib/ports/xilinx/include/xlwipconfig.h"
|
|
file delete $adapterconfig
|
|
set fd [open $adapterconfig w]
|
|
|
|
puts $fd "\#ifndef __XLWIPCONFIG_H_"
|
|
puts $fd "\#define __XLWIPCONFIG_H_\n\n"
|
|
puts $fd "/* This is a generated file - do not edit */"
|
|
puts $fd ""
|
|
|
|
if {$force_axieth_on_zynq == 1 && $have_axi_ethernet == 1} {
|
|
puts $fd "\#define XLWIP_CONFIG_INCLUDE_AXIETH_ON_ZYNQ 1"
|
|
}
|
|
if {$force_emaclite_on_zynq == 1 && $have_emaclite == 1} {
|
|
puts $fd "\#define XLWIP_CONFIG_INCLUDE_EMACLITE_ON_ZYNQ 1"
|
|
}
|
|
if {$have_emaclite == 1} {
|
|
puts $fd "\#define XLWIP_CONFIG_INCLUDE_EMACLITE 1"
|
|
}
|
|
|
|
if {$have_temac == 1} {
|
|
puts $fd "\#define XLWIP_CONFIG_INCLUDE_TEMAC 1"
|
|
}
|
|
|
|
if {$force_axieth_on_zynq == 1 || $have_ps7_ethernet == 0 } {
|
|
if {$have_axi_ethernet == 1} {
|
|
puts $fd "\#define XLWIP_CONFIG_INCLUDE_AXI_ETHERNET 1"
|
|
}
|
|
if {$have_axi_ethernet_dma == 1} {
|
|
puts $fd "\#define XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_DMA 1"
|
|
}
|
|
if {$have_axi_ethernet_fifo == 1} {
|
|
puts $fd "\#define XLWIP_CONFIG_INCLUDE_AXI_ETHERNET_FIFO 1"
|
|
}
|
|
} elseif {$have_ps7_ethernet == 1} {
|
|
puts $fd "\#define XLWIP_CONFIG_INCLUDE_GEM 1"
|
|
}
|
|
|
|
if {$have_temac == 1 || $have_axi_ethernet == 1} {
|
|
set ndesc [common::get_property CONFIG.n_tx_descriptors $libhandle]
|
|
puts $fd "\#define XLWIP_CONFIG_N_TX_DESC $ndesc"
|
|
set ndesc [common::get_property CONFIG.n_rx_descriptors $libhandle]
|
|
puts $fd "\#define XLWIP_CONFIG_N_RX_DESC $ndesc"
|
|
puts $fd ""
|
|
|
|
set ncoalesce [common::get_property CONFIG.n_tx_coalesce $libhandle]
|
|
puts $fd "\#define XLWIP_CONFIG_N_TX_COALESCE $ncoalesce"
|
|
set ncoalesce [common::get_property CONFIG.n_rx_coalesce $libhandle]
|
|
puts $fd "\#define XLWIP_CONFIG_N_RX_COALESCE $ncoalesce"
|
|
puts $fd ""
|
|
}
|
|
if {$have_ps7_ethernet == 1} {
|
|
set emacnum [common::get_property CONFIG.emac_number $libhandle]
|
|
puts $fd "\#define XLWIP_CONFIG_EMAC_NUMBER $emacnum"
|
|
set ndesc [common::get_property CONFIG.n_tx_descriptors $libhandle]
|
|
puts $fd "\#define XLWIP_CONFIG_N_TX_DESC $ndesc"
|
|
set ndesc [common::get_property CONFIG.n_rx_descriptors $libhandle]
|
|
puts $fd "\#define XLWIP_CONFIG_N_RX_DESC $ndesc"
|
|
puts $fd ""
|
|
}
|
|
|
|
puts $fd "\#endif"
|
|
|
|
close $fd
|
|
}
|
|
|
|
#-------
|
|
# generate: called after OS and library files are copied into project dir
|
|
# we need to generate the following:
|
|
# 1. Makefile options
|
|
# 2. System Arch settings for lwIP to use
|
|
#-------
|
|
proc generate {libhandle} {
|
|
generate_lwip_opts $libhandle
|
|
generate_topology $libhandle
|
|
generate_adapterconfig_makefile $libhandle
|
|
generate_adapterconfig_include $libhandle
|
|
}
|
|
|
|
#-------
|
|
# post_generate: called after generate called on all libraries
|
|
#-------
|
|
proc post_generate {libhandle} {
|
|
}
|
|
|
|
#-------
|
|
# execs_generate: called after BSP's, libraries and drivers have been compiled
|
|
# This procedure builds the liblwip4.a library
|
|
#-------
|
|
proc execs_generate {libhandle} {
|
|
}
|