# HG changeset patch # User sergeig # Date 1320006792 0 # Node ID de515b96471009734d875254e52533c9697105be # Parent 50f5e89533719abfad0e432d790a95bb3b43a1a0 * New package -- Freescale ENET Ethernet driver. diff --git a/packages/devs/eth/freescale/enet/current/ChangeLog b/packages/devs/eth/freescale/enet/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/eth/freescale/enet/current/ChangeLog @@ -0,0 +1,31 @@ +2011-08-26 Ilija Kocho + + * cdl/eth_freescale_enet.cdl: + * include/if_freescale_enet_bd.h: + * include/if_freescale_enet_io.h: + * src/if_freescale_enet.c: + New package -- Freescale ENET Ethernet driver. + +//=========================================================================== +// ####GPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 or (at your option) any +// later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., 51 Franklin Street, +// Fifth Floor, Boston, MA 02110-1301, USA. +// ------------------------------------------- +// ####GPLCOPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/eth/freescale/enet/current/cdl/eth_freescale_enet.cdl b/packages/devs/eth/freescale/enet/current/cdl/eth_freescale_enet.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/eth/freescale/enet/current/cdl/eth_freescale_enet.cdl @@ -0,0 +1,416 @@ +#========================================================================== +# +# eth_freescale_enet.cdl +# +# Ethernet driver for Freescale ENET controller +# +#========================================================================== +## ####ECOSGPLCOPYRIGHTBEGIN#### +## ------------------------------------------- +## This file is part of eCos, the Embedded Configurable Operating System. +## Copyright (C) 2011 Free Software Foundation, Inc. +## +## eCos is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free +## Software Foundation; either version 2 or (at your option) any later +## version. +## +## eCos is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +## for more details. +## +## You should have received a copy of the GNU General Public License +## along with eCos; if not, write to the Free Software Foundation, Inc., +## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +## +## As a special exception, if other files instantiate templates or use +## macros or inline functions from this file, or you compile this file +## and link it with other works to produce a work based on this file, +## this file does not by itself cause the resulting work to be covered by +## the GNU General Public License. However the source code for this file +## must still be made available in accordance with section (3) of the GNU +## General Public License v2. +## +## This exception does not invalidate any other reasons why a work based +## on this file might be covered by the GNU General Public License. +## ------------------------------------------- +## ####ECOSGPLCOPYRIGHTEND#### +#========================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): Ilija Kocho +# Contributors: +# Date: 2011-06-14 +# +#####DESCRIPTIONEND#### +# +#======================================================================== + + +cdl_package CYGPKG_DEVS_ETH_FREESCALE_ENET { + display "Freescale ENET ethernet driver" + parent CYGPKG_IO_ETH_DRIVERS + active_if CYGPKG_IO_ETH_DRIVERS + + implements CYGHWR_NET_DRIVERS + implements CYGHWR_NET_DRIVER_ETH0 + + requires CYGHWR_FREESCALE_ENET_MII_MDC_HAL_CLOCK + + include_dir cyg/io/eth + description " + Ethernet driver for Freescale ENET controller. Freescale ENET + Ethernet controller is found on some Freescale families of + controllers such as Kinetis and ColdFire+." + + compile -library=libextras.a if_freescale_enet.c + + # ENET0 Configuration options -------------------------------------------- + cdl_option CYGDAT_IO_ETH_IF_FREESCALE_ENET0_NAME { + display "Device name for Freescale ENET0 interface" + flavor data + default_value { "\"eth0\"" } + description " + This option specifies the device name for Freescale ENET0 + interface." + } + + cdl_option CYGPKG_DEVS_ETH_FREESCALE_ENET0_MACADDR { + display "Ethernet station (MAC) address for eth0" + flavor data + default_value {"0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC"} + description " + The default ethernet station address." + } + + cdl_option CYGPKG_DEVS_ETH_FREESCALE_ENET0_INTPRIO { + display "Interrupt priority" + flavor data + default_value 0xE0 + description " + This option selects the interrupt priority for the EMAC + interrupts." + } + + cdl_component CYGHWR_DEVS_ETH_FREESCALE_ENET0_FLOW_CONTROL { + display "Congestion control" + flavor none + no_define + + cdl_option CYGSEM_ETH_FREESCALE_ENET0_RCR_FCE { + display "Rx Flow control enable" + flavor data + legal_values { 0 1 } + default_value 0 + description " + If enabled ENET shall regard pause frames requests from peer." + } + + cdl_option CYGNUM_ETH_FREESCALE_ENET0_OPD_PAUSE_DUR { + display "Tx flow control pause duration" + flavor data + legal_values 0 to 255 + default_value 0 + description " + Flow control pause legth in pause quanta asked from peer. + 1 pause quant equals to 512 bit time increments." + } + } + + cdl_component CYGHWR_DEVS_ETH_FREESCALE_ENET0_BUFFS { + display "Buffers" + flavor none + no_define + description "Rx and Tx buffers" + + cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET0_MAX_FRAME_LEN { + display "Maximal frame length" + flavor data + default_value 1518 + legal_values 64 to 1522 + } + + cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET0_RX_BUFS { + display "Number of RX buffers" + flavor data + default_value 8 + legal_values 2 to 64 + description " + Number of buffers for receiving. The number of receive + buffers also defines the number of descriptors in the + descriptor array." + } + + cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET0_RXBUF_SIZE { + display "Rx buffer size" + flavor data + requires { (CYGNUM_DEVS_ETH_FREESCALE_ENET0_RXBUF_SIZE % + CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBUF_ALIGN) == 0 + } + legal_values 16 to 1536 + default_value { + ((CYGNUM_DEVS_ETH_FREESCALE_ENET0_MAX_FRAME_LEN + + CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBUF_ALIGN-1)/ + (CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBUF_ALIGN ? + CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBUF_ALIGN : 1)) * + CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBUF_ALIGN + } + description "Rx buffer size must be evenly divisible by 16." + } + + cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS { + display "Number of TX descriptors (buffers)" + flavor data + default_value ( CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY ? 8 : \ + CYGPKG_IO_ETH_DRIVERS_NET ? 8 : 2 ) + legal_values 2 to 64 + description " + Number of transmit buffers or descriptors. We need one + descriptor/buffer for each element in the scatter/gather list. + If NoCopy is selected then only buffer descriptors are allocated. + If Copying is selected (NoCopy == 0) then a buffer is allocated + for every buffer descriptor." + } + + cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET0_TXBUF_SIZE { + display "Tx buffer size" + flavor data + active_if { !CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY } + requires { (CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_SIZE % + CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN) == 0 + } + + legal_values { 16 to 1536 } + default_value { + ((CYGNUM_DEVS_ETH_FREESCALE_ENET0_MAX_FRAME_LEN + + CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN-1)/ + (CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN ? + CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN : 1)) * + CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN + } + } + + } + + # END of ENET0 specific configuration options. --------------------------- + + # Common ENET options. --------------------------------------------------- + # Following configuration options are common to all ENET instances + + cdl_option CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED { + display "Enhanced buffer descriptors" + flavor bool + default_value 0 + } + + cdl_component CYGHWR_DEVS_ETH_FREESCALE_ENET_ALIGN { + display "Buffer/descriptor memory alignment" + flavor none + no_define + description " + ENET conatins internal DMA controller that + requires certain memory alighment" + + cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBD_ALIGN { + display "Rx buffer descriptor alignment" + flavor data + default_value 8 + legal_values { 8 16 } + } + + cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBUF_ALIGN { + display "Rx buffer alignment" + flavor data + default_value 16 + legal_values { 16 } + } + + cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBD_ALIGN { + display "Tx buffer descriptor alignment" + flavor data + default_value 8 + legal_values { 8 16 } + } + + cdl_option CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN { + display "Tx buffer alignment" + flavor data + default_value 8 + legal_values { 8 16 } + } + } + + cdl_component CYGSEM_DEVS_ETH_FREESCALE_ENET_PHY { + display "RMII or MII Phy" + flavor data + default_value { "RMII" } + legal_values { "RMII" "MII" } + + cdl_option CYGOPT_DEVS_ETH_FREESCALE_ENET_PHY_RXER_USE { + display "Enable PHY Rx Error signal" + flavor bool + default_value 1 + } + } + + cdl_component CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL { + display "TCP/IP acceleration" + flavor bool + default_value { is_active (CYGPKG_LWIP_CHECKSUMS) ? 1 : 0 } + description " + Freescale ENET provides for hardware TCP/IP header checksum + generation and check." + + active_if CYGPKG_NET_LWIP + requires CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + requires CYGPKG_LWIP_CHECKSUMS + + cdl_component CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_IP { + display "IP Checksum generation" + flavor bool + default_value 1 + + requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies + (CYGIMP_LWIP_CHECKSUM_GEN_IP == 0) } + + cdl_option CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_PROT { + display "TCP and UDP Checksum generation" + flavor bool + default_value 1 + + requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies + (CYGIMP_LWIP_CHECKSUM_GEN_TCP == 0) } + + requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies + (CYGIMP_LWIP_CHECKSUM_GEN_UDP == 0) } + } + } + + cdl_component CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_IP { + display "IP Checksum check" + flavor bool + default_value 1 + + requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies + (CYGIMP_LWIP_CHECKSUM_CHECK_IP == 0) } + + cdl_option CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_PROT { + display "TCP and UDP checksum check" + flavor bool + default_value 1 + + requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies + (CYGIMP_LWIP_CHECKSUM_CHECK_TCP == 0) } + + requires { is_active(CYGPKG_LWIP_CHECKSUMS) implies + (CYGIMP_LWIP_CHECKSUM_CHECK_UDP == 0) } + } + } + + cdl_option CYGSEM_ENET_LWIP_CHECKSUMS { + display "lwIP Checksum calculation" + flavor none + no_define + description " + Re-enable lwIP software checksum generation/check if + hardware generation/check is disabled." + + requires { !CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_IP implies + CYGIMP_LWIP_CHECKSUM_GEN_IP == 1 } + requires { !CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_PROT implies + CYGIMP_LWIP_CHECKSUM_GEN_TCP == 1 } + requires { !CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_PROT implies + CYGIMP_LWIP_CHECKSUM_GEN_UDP == 1 } + + requires { !CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_IP implies + CYGIMP_LWIP_CHECKSUM_CHECK_IP == 1 } + requires { !CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_PROT implies + CYGIMP_LWIP_CHECKSUM_CHECK_TCP == 1 } + requires { !CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_PROT implies + CYGIMP_LWIP_CHECKSUM_CHECK_UDP == 1 } + } + } + + cdl_component CYGSEM_DEVS_ETH_FREESCALE_ENET_1588 { + display "IEEE 1588 timers" + requires CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + flavor bool + default_value 0 + } + + cdl_component CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS { + display "ENET Error statistics" + flavor bool + default_value 0 + + cdl_option CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS_DEBUG { + display "Debug print ENET error statistics" + flavor bool + default_value 0 + } + } + + cdl_option CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY { + display "NullCopy send" + flavor bool + default_value 0 + active_if (CYGPKG_NET_LWIP) + + requires { is_active(CYGPKG_NET_LWIP) implies + (CYGNUM_LWIP_MEM_ALIGNMENT >= + CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN) } + + description " + ENET driver can send buffers 'out of place' + (wihout making a private copy), offloading CPU from + copying data and saving space for Tx buffers . This is + 'NullCopy' option, opposite to 'Copying' option where ENET + driver has private Tx buffers and requires additional copying + operation (by CPU). + On the pther hand, 'Copying' option needs no Tx IRQ which may + make it better choice than NullCopy if system dominantly sends + short messages. Also, ENET has some requiresments for buffer + alignment, therefore if upper layer networking stack / + application can not guarantee for boundary alignment then + 'Copying' should be used." + } + + cdl_option CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK { + display "Fast IRQ masking" + flavor bool + default_value 1 + + description " + Fast (un)masking operates on bits in ENET's EIR + register instead of calling cyg_drv_interrupt_(un)mask. + This allows sumultaneous (un)masking of both Tx and Rx + interrupts and is prefered mode, but case of compatibility + problems disable fast IRQ mask." + } + + cdl_option CYGPKG_DEVS_ETH_FREESCALE_ENET_DEBUG_LEVEL { + display "Driver debug output level" + flavor data + legal_values { 0 1 2 3 } + default_value 0 + description " + This option specifies the level of debug data output by + the Freescale ENET ethernet device driver. A value of 0 signifies + no debug data output; 1 signifies normal debug data + output; and 2 signifies maximum debug data output." + } + + cdl_option CYGPKG_DEVS_ETH_FREESCALE_ENET_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "-D_KERNEL -D__ECOS" } + description " + This option modifies the set of compiler flags for + building the Freescale ENET ethernet driver package. + These flags are used in addition to the set of global flags." + } +} + +# EOF eth_freescale_enet.cdl diff --git a/packages/devs/eth/freescale/enet/current/include/if_freescale_enet_bd.h b/packages/devs/eth/freescale/enet/current/include/if_freescale_enet_bd.h new file mode 100644 --- /dev/null +++ b/packages/devs/eth/freescale/enet/current/include/if_freescale_enet_bd.h @@ -0,0 +1,209 @@ +#ifndef CYGONCE_FREESCALE_ENET_BD_H +#define CYGONCE_FREESCALE_ENET_BD_H +//============================================================================= +// +// freescale_enet_bd.h +// +// Variant specific registers +// +//============================================================================= +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later +// version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with eCos; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// As a special exception, if other files instantiate templates or use +// macros or inline functions from this file, or you compile this file +// and link it with other works to produce a work based on this file, +// this file does not by itself cause the resulting work to be covered by +// the GNU General Public License. However the source code for this file +// must still be made available in accordance with section (3) of the GNU +// General Public License v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): Ilija Kocho +// Date: 2011-06-05 +// Purpose: Freescale ENET buffer descriptors +// Description: +// Usage: #include +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +//--------------------------------------------------------------------------- +// ENET Buffer Descriptors +// All mrmbers except key must be big endian +typedef volatile struct enet_bd_s { + cyg_uint16 ctrl; // 00 + cyg_uint16 len; // 02 + cyg_uint8 *buffer_p; // 04 +#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + cyg_uint32 ebd_ctrl; // 08 + cyg_uint16 hlen_proto; // 0c + cyg_uint16 payload_csum; // 0e + cyg_uint32 bdu; // 10 + cyg_uint32 timestamp_1588; // 14 + cyg_uint32 reserved[2]; // 18 +#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED +} enet_bd_t; + + +#if (CYG_BYTEORDER == CYG_LSBFIRST) +//====================================================================== +// Little Endian +//---------------------------------------------------------------------- + +// ---------------------------------------------------------------------- +// TX Buffer Descriptor Bit Definitions + +# define ENET_TXBD_R 0x0080 +# define ENET_TXBD_TO1 0x0040 +# define ENET_TXBD_W 0x0020 +# define ENET_TXBD_TO2 0x0010 +# define ENET_TXBD_L 0x0008 +# define ENET_TXBD_TC 0x0004 +# define ENET_TXBD_ABC 0x0002 + +// ---------------------------------------------------------------------- +// TX Enhanced BD Bit Definitions + +# define ENET_TXBD_INT 0x00000040 +# define ENET_TXBD_TS 0x00000020 +# define ENET_TXBD_PINS 0x00000010 +# define ENET_TXBD_IINS 0x00000008 +# define ENET_TXBD_TXE 0x00800000 +# define ENET_TXBD_UE 0x00200000 +# define ENET_TXBD_EE 0x00100000 +# define ENET_TXBD_FE 0x00080000 +# define ENET_TXBD_LCE 0x00040000 +# define ENET_TXBD_OE 0x00020000 +# define ENET_TXBD_TSE 0x00010000 + +# define ENET_TXBD_BDU 0x00000080 + +// ---------------------------------------------------------------------- +// RX Buffer Descriptor Bit Definitions +// Offset 0 flags - ctrl +# define ENET_RXBD_E 0x0080 +# define ENET_RXBD_R01 0x0040 +# define ENET_RXBD_W 0x0020 +# define ENET_RXBD_R02 0x0010 +# define ENET_RXBD_L 0x0008 +# define ENET_RXBD_M 0x0001 +# define ENET_RXBD_BC 0x8000 +# define ENET_RXBD_MC 0x4000 +# define ENET_RXBD_LG 0x2000 +# define ENET_RXBD_NO 0x1000 +# define ENET_RXBD_CR 0x0400 +# define ENET_RXBD_OV 0x0200 +# define ENET_RXBD_TR 0x0100 + +// ---------------------------------------------------------------------- +// RX Enhanced BD Bit Definitions + +# define ENET_RXBD_ME 0x00000080 +# define ENET_RXBD_PE 0x00000004 +# define ENET_RXBD_CE 0x00000002 +# define ENET_RXBD_UC 0x00000001 + +# define ENET_RXBD_INT 0x00008000 + +# define ENET_RXBD_ICE 0x20000000 +# define ENET_RXBD_PCR 0x10000000 +# define ENET_RXBD_VLAN 0x04000000 +# define ENET_RXBD_IPV6 0x02000000 +# define ENET_RXBD_FRAG 0x01000000 + +# define ENET_RXBD_BDU 0x00000080 + +#else //(CYG_BYTEORDER == CYG_LSBFIRST) +//====================================================================== +// Big Endian +//---------------------------------------------------------------------- + +// ---------------------------------------------------------------------- +// TX Buffer Descriptor Bit Definitions + +# define ENET_TXBD_R 0x8000 +# define ENET_TXBD_TO1 0x4000 +# define ENET_TXBD_W 0x2000 +# define ENET_TXBD_TO2 0x1000 +# define ENET_TXBD_L 0x0800 +# define ENET_TXBD_TC 0x0400 +# define ENET_TXBD_ABC 0x0200 + +// ---------------------------------------------------------------------- +// TX Enhanced BD Bit Definitions + +# define ENET_TXBD_INT 0x40000000 +# define ENET_TXBD_TS 0x20000000 +# define ENET_TXBD_PINS 0x10000000 +# define ENET_TXBD_IINS 0x08000000 +# define ENET_TXBD_TXE 0x00008000 +# define ENET_TXBD_UE 0x00002000 +# define ENET_TXBD_EE 0x00001000 +# define ENET_TXBD_FE 0x00000800 +# define ENET_TXBD_LCE 0x00000400 +# define ENET_TXBD_OE 0x00000200 +# define ENET_TXBD_TSE 0x00000100 + +# define ENET_TXBD_BDU 0x80000000 + +// ---------------------------------------------------------------------- +// RX Buffer Descriptor Bit Definitions +// Offset 0 flags - ctrl +# define ENET_RXBD_E 0x8000 +# define ENET_RXBD_R01 0x4000 +# define ENET_RXBD_W 0x2000 +# define ENET_RXBD_R02 0x1000 +# define ENET_RXBD_L 0x0800 +# define ENET_RXBD_M 0x0100 +# define ENET_RXBD_BC 0x0080 +# define ENET_RXBD_MC 0x0040 +# define ENET_RXBD_LG 0x0020 +# define ENET_RXBD_NO 0x0010 +# define ENET_RXBD_CR 0x0004 +# define ENET_RXBD_OV 0x0002 +# define ENET_RXBD_TR 0x0001 + +// ---------------------------------------------------------------------- +// RX Enhanced BD Bit Definitions + +# define ENET_RXBD_ME 0x80000000 +# define ENET_RXBD_PE 0x04000000 +# define ENET_RXBD_CE 0x02000000 +# define ENET_RXBD_UC 0x01000000 +# define ENET_RXBD_INT 0x00800000 +# define ENET_RXBD_ICE 0x00000020 +# define ENET_RXBD_PCR 0x00000010 +# define ENET_RXBD_VLAN 0x00000004 +# define ENET_RXBD_IPV6 0x00000002 +# define ENET_RXBD_FRAG 0x00000001 + +# define ENET_RXBD_BDU 0x80000000 + +#endif // (CYG_BYTEORDER == CYG_LSBFIRST) + +// EOF freescale_enet_bd.h +#endif // CYGONCE_FREESCALE_ENET_BD_H diff --git a/packages/devs/eth/freescale/enet/current/include/if_freescale_enet_io.h b/packages/devs/eth/freescale/enet/current/include/if_freescale_enet_io.h new file mode 100644 --- /dev/null +++ b/packages/devs/eth/freescale/enet/current/include/if_freescale_enet_io.h @@ -0,0 +1,685 @@ +#ifndef CYGONCE_IF_FREESCALE_ENET_IO_H +#define CYGONCE_IF_FREESCALE_ENET_IO_H +//============================================================================= +// +// if_freescale_enet_io.h +// +// Variant specific registers +// +//============================================================================= +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later +// version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with eCos; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// As a special exception, if other files instantiate templates or use +// macros or inline functions from this file, or you compile this file +// and link it with other works to produce a work based on this file, +// this file does not by itself cause the resulting work to be covered by +// the GNU General Public License. However the source code for this file +// must still be made available in accordance with section (3) of the GNU +// General Public License v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): Ilija Kocho +// Date: 2011-06-05 +// Purpose: Freescale ENET specific registers +// Description: +// Usage: #include +// +//####DESCRIPTIONEND#### +// +//============================================================================= + + +//============================================================================= +// Freescale ENET Ethernet controller + +// ENET Register offsets relative to CYGADDR_IO_ETH_FREESCALE_ENET_BASE +// Note: CYGADDR_IO_ETH_FREESCALE_ENET_BASE is provided by HAL. +// Typically you can find CYGADDR_IO_ETH_FREESCALE_ENET_BASE in var_io.h +//----------------------------------------------------------------------------- +// Interrupt Event Register +#define FREESCALE_ENET_REG_EIR 0x004 +// Interrupt Mask Register +#define FREESCALE_ENET_REG_EIMR 0x008 +// Receive Descriptor Active Register +#define FREESCALE_ENET_REG_RDAR 0x010 +// Transmit Descriptor Active Register +#define FREESCALE_ENET_REG_TDAR 0x014 +// Ethernet Control Register +#define FREESCALE_ENET_REG_ECR 0x024 +// MII Management Frame Register +#define FREESCALE_ENET_REG_MMFR 0x040 +// MII Speed Control Register +#define FREESCALE_ENET_REG_MSCR 0x044 +// MIB Control Register +#define FREESCALE_ENET_REG_MIBC 0x064 +// Receive Control Register +#define FREESCALE_ENET_REG_RCR 0x084 +// Transmit Control Register +#define FREESCALE_ENET_REG_TCR 0x0C4 +// Physical Address Lower Register +#define FREESCALE_ENET_REG_PALR 0x0E4 +// Physical Address Upper Register +#define FREESCALE_ENET_REG_PAUR 0x0E8 +// Opcode/Pause Duration Register +#define FREESCALE_ENET_REG_OPD 0x0EC +// Descriptor Individual Upper Address Register +#define FREESCALE_ENET_REG_IAUR 0x118 +// Descriptor Individual Lower Address Register +#define FREESCALE_ENET_REG_IALR 0x11C +// Descriptor Group Upper Address Register +#define FREESCALE_ENET_REG_GAUR 0x120 +// Descriptor Group Lower Address Register +#define FREESCALE_ENET_REG_GALR 0x124 +// Transmit FIFO Watermark Register +#define FREESCALE_ENET_REG_TFWR 0x144 +// Receive Descriptor Ring Start Register +#define FREESCALE_ENET_REG_RDSR 0x180 +// Transmit Buffer Descriptor Ring Start Register +#define FREESCALE_ENET_REG_TDSR 0x184 +// Maximum Receive Buffer Size Register +#define FREESCALE_ENET_REG_MRBR 0x188 +// Receive FIFO Section Full Threshold +#define FREESCALE_ENET_REG_RSFL 0x190 +// Receive FIFO Section Empty Threshold +#define FREESCALE_ENET_REG_RSEM 0x194 +// Receive FIFO Almost Empty Threshold +#define FREESCALE_ENET_REG_RAEM 0x198 +// Receive FIFO Almost Full Threshold +#define FREESCALE_ENET_REG_RAFL 0x19C +// Transmit FIFO Section Empty Threshold +#define FREESCALE_ENET_REG_TSEM 0x1A0 +// Transmit FIFO Almost Empty Threshold +#define FREESCALE_ENET_REG_TAEM 0x1A4 +// Transmit FIFO Almost Full Threshold +#define FREESCALE_ENET_REG_TAFL 0x1A8 +// Transmit Inter-Packet Gap +#define FREESCALE_ENET_REG_TIPG 0x1AC +// Frame Truncation Length +#define FREESCALE_ENET_REG_FTRL 0x1B0 +// Transmit Accelerator Function Configuration +#define FREESCALE_ENET_REG_TACC 0x1C0 +// Receive Accelerator Function Configuration +#define FREESCALE_ENET_REG_RACC 0x1C4 +// Count of frames not counted correctly (RMON_T_DROP). +// NOTE: Counter not implemented (read 0 always) as not applicable. +#define FREESCALE_ENET_REG_RMON_T_DROP 0x200 +// RMON Tx packet count (RMON_T_PACKETS) +#define FREESCALE_ENET_REG_RMON_T_PACKETS 0x204 +// RMON Tx Broadcast Packets (RMON_T_BC_PKT) +#define FREESCALE_ENET_REG_RMON_T_BC_PKT 0x208 +// RMON Tx Multicast Packets (RMON_T_MC_PKT) +#define FREESCALE_ENET_REG_RMON_T_MC_PKT 0x20C +// RMON Tx Packets w CRC/Align error (RMON_T_CRC_ALIGN) +#define FREESCALE_ENET_REG_RMON_T_CRC_ALIGN 0x210 +// RMON Tx Packets < 64 bytes +#define FREESCALE_ENET_REG_RMON_T_UNDERSIZE 0x214 +// RMON Tx Packets > MAX_FL bytes +#define FREESCALE_ENET_REG_RMON_T_OVERSIZE 0x218 +// RMON Tx Packets < 64 bytes +#define FREESCALE_ENET_REG_RMON_T_FRAG 0x21C +// RMON Tx Packets > MAX_FL bytes +#define FREESCALE_ENET_REG_RMON_T_JAB 0x220 +// RMON Tx collision count (RMON_T_COL) +#define FREESCALE_ENET_REG_RMON_T_COL 0x224 +// RMON Tx 64 byte packets (RMON_T_P64) +#define FREESCALE_ENET_REG_RMON_T_P64 0x228 +// RMON Tx 65 to 127 byte packets (RMON_T_P65TO127) +#define FREESCALE_ENET_REG_RMON_T_P65TO127 0x22C +// RMON Tx 128 to 255 byte packets (RMON_T_P128TO255) +#define FREESCALE_ENET_REG_RMON_T_P128TO255 0x230 +// RMON Tx 256 to 511 byte packets (RMON_T_P256TO511) +#define FREESCALE_ENET_REG_RMON_T_P256TO511 0x234 +// RMON Tx 512 to 1023 byte packets (RMON_T_P512TO1023) +#define FREESCALE_ENET_REG_RMON_T_P512TO1023 0x238 +// RMON Tx 1024 to 2047 byte packets (RMON_T_P1024TO2047) +#define FREESCALE_ENET_REG_RMON_T_P1024TO2047 0x23C +// RMON Tx packets w > 2048 bytes (RMON_T_P_GTE2048) +#define FREESCALE_ENET_REG_RMON_T_P_GTE2048 0x240 +// RMON Tx Octets (RMON_T_OCTETS) +#define FREESCALE_ENET_REG_RMON_T_OCTETS 0x244 +// Count of frames not counted correctly (IEEE_T_DROP). +// NOTE: Counter not implemented (read 0 always) as not applicable. +#define FREESCALE_ENET_REG_IEEE_T_DROP 0x248 +// Frames Transmitted OK (IEEE_T_FRAME_OK) +#define FREESCALE_ENET_REG_IEEE_T_FRAME_OK 0x24C +// Frames Transmitted with Single Collision (IEEE_T_1COL) +#define FREESCALE_ENET_REG_IEEE_T_1COL 0x250 +// Frames Transmitted with Multiple Collisions (IEEE_T_MCOL) +#define FREESCALE_ENET_REG_IEEE_T_MCOL 0x254 +// Frames Transmitted after Deferral Delay (IEEE_T_DEF) +#define FREESCALE_ENET_REG_IEEE_T_DEF 0x258 +// Frames Transmitted with Late Collision (IEEE_T_LCOL) +#define FREESCALE_ENET_REG_IEEE_T_LCOL 0x25C +// Frames Transmitted with Excessive Collisions (IEEE_T_EXCOL) +#define FREESCALE_ENET_REG_IEEE_T_EXCOL 0x260 +// Frames Transmitted with Tx FIFO Underrun (IEEE_T_MACERR) +#define FREESCALE_ENET_REG_IEEE_T_MACERR 0x264 +// Frames Transmitted with Carrier Sense Error (IEEE_T_CSERR) +#define FREESCALE_ENET_REG_IEEE_T_CSERR 0x268 +// Frames Transmitted with SQE Error (IEEE_T_SQE). +// NOTE: Counter not implemented (read 0 always) +// as no SQE information is available. +#define FREESCALE_ENET_REG_IEEE_T_SQE 0x26C +// Flow Control Pause frames transmitted (IEEE_T_FDXFC) +#define FREESCALE_ENET_REG_IEEE_T_FDXFC 0x270 +// Octet count for Frames Transmitted w/o Error (IEEE_T_OCTETS_OK). +// NOTE: Counts total octets (includes header and FCS fields). +#define FREESCALE_ENET_REG_IEEE_T_OCTETS_OK 0x274 +// RMON Rx packet count (RMON_R_PACKETS) +#define FREESCALE_ENET_REG_RMON_R_PACKETS 0x284 +// RMON Rx Broadcast Packets (RMON_R_BC_PKT) +#define FREESCALE_ENET_REG_RMON_R_BC_PKT 0x288 +// RMON Rx Multicast Packets (RMON_R_MC_PKT) +#define FREESCALE_ENET_REG_RMON_R_MC_PKT 0x28C +// RMON Rx Packets w CRC/Align error (RMON_R_CRC_ALIGN) +#define FREESCALE_ENET_REG_RMON_R_CRC_ALIGN 0x290 +// RMON Rx Packets < 64 bytes +#define FREESCALE_ENET_REG_RMON_R_UNDERSIZE 0x294 +// RMON Rx Packets > MAX_FL bytes +#define FREESCALE_ENET_REG_RMON_R_OVERSIZE 0x298 +// RMON Rx Packets < 64 bytes +#define FREESCALE_ENET_REG_RMON_R_FRAG 0x29C +// RMON Rx Packets > MAX_FL bytes +#define FREESCALE_ENET_REG_RMON_R_JAB 0x2A0 +// Reserved (RMON_R_RESVD_0) +#define FREESCALE_ENET_REG_RMON_R_RESVD_0 0x2A4 +// RMON Rx 64 byte packets (RMON_R_P64) +#define FREESCALE_ENET_REG_RMON_R_P64 0x2A8 +// RMON Rx 65 to 127 byte packets (RMON_R_P65TO127) +#define FREESCALE_ENET_REG_RMON_R_P65TO127 0x2AC +// RMON Rx 128 to 255 byte packets (RMON_R_P128TO255) +#define FREESCALE_ENET_REG_RMON_R_P128TO255 0x2B0 +// RMON Rx 256 to 511 byte packets (RMON_R_P256TO511) +#define FREESCALE_ENET_REG_RMON_R_P256TO511 0x2B4 +// RMON Rx 512 to 1023 byte packets (RMON_R_P512TO1023) +#define FREESCALE_ENET_REG_RMON_R_P512TO1023 0x2B8 +// RMON Rx 1024 to 2047 byte packets (RMON_R_P1024TO2047) +#define FREESCALE_ENET_REG_RMON_R_P1024TO2047 0x2BC +// RMON Rx packets w > 2048 bytes (RMON_R_P_GTE2048) +#define FREESCALE_ENET_REG_RMON_R_P_GTE2048 0x2C0 +// RMON Rx Octets (RMON_R_OCTETS) +#define FREESCALE_ENET_REG_RMON_R_OCTETS 0x2C4 +// Count of frames not counted correctly (IEEE_R_DROP). +// NOTE: Counter increments if a frame with valid/ +// missing SFD character is detected and has been dropped. +// None of the other counters increments if +// this counter increments. +#define FREESCALE_ENET_REG_RMON_R_DROP 0x2C8 +// Frames Received OK (IEEE_R_FRAME_OK) +#define FREESCALE_ENET_REG_RMON_R_FRAME_OK 0x2CC +// Frames Received with CRC Error (IEEE_R_CRC) +#define FREESCALE_ENET_REG_IEEE_R_CRC 0x2D0 +// Frames Received with Alignment Error (IEEE_R_ALIGN) +#define FREESCALE_ENET_REG_IEEE_R_ALIGN 0x2D4 +// Receive Fifo Overflow count (IEEE_R_MACERR) +#define FREESCALE_ENET_REG_IEEE_R_MACERR 0x2D8 +// Flow Control Pause frames received (IEEE_R_FDXFC) +#define FREESCALE_ENET_REG_IEEE_R_FDXFC 0x2DC +// Octet count for Frames Rcvd w/o Error (IEEE_R_OCTETS_OK). +// Counts total octets (includes header and FCS fields). +#define FREESCALE_ENET_REG_IEEE_R_OCTETS_OK 0x2E0 +// Timer Control Register +#define FREESCALE_ENET_REG_ATCR 0x400 +// Timer Value Register +#define FREESCALE_ENET_REG_ATVR 0x404 +// Timer Offset Register +#define FREESCALE_ENET_REG_ATOFF 0x408 +// Timer Period Register +#define FREESCALE_ENET_REG_ATPER 0x40C +// Timer Correction Register +#define FREESCALE_ENET_REG_ATCOR 0x410 +// Time-Stamping Clock Period Register +#define FREESCALE_ENET_REG_ATINC 0x414 +// Timestamp of Last Transmitted Frame +#define FREESCALE_ENET_REG_ATSTMP 0x418 +// Timer Global Status Register +#define FREESCALE_ENET_REG_TGSR 0x604 + +// IEEE 1588 Timers +// Timer 0 Control Status Register +#define FREESCALE_ENET_REG_TCSR0 0x608 +// Timer 0Control Capture Register +#define FREESCALE_ENET_REG_TCCR0 0x60c +// Timer 1 Control Status Register +#define FREESCALE_ENET_REG_TCSR1 0x610 +// Timer 1 Control Capture Register +#define FREESCALE_ENET_REG_TCCR1 0x614 +// Timer 2 Control Status Register +#define FREESCALE_ENET_REG_TCSR2 0x618 +// Timer 2 Control Capture Register +#define FREESCALE_ENET_REG_TCCR2 0x61C +// Timer 3 Control Status Register +#define FREESCALE_ENET_REG_TCSR3 0x620 +// Timer 3 Control Capture Register +#define FREESCALE_ENET_REG_TCCR3 0x624 + + + +// ---------------------------------------------------------------------------- +// ENET Register Masks + +// EIR Bit Fields +#define FREESCALE_ENET_EIR_TS_TIMER_M 0x8000 +#define FREESCALE_ENET_EIR_TS_TIMER_S 15 +#define FREESCALE_ENET_EIR_TS_AVAIL_M 0x10000 +#define FREESCALE_ENET_EIR_TS_AVAIL_S 16 +#define FREESCALE_ENET_EIR_WAKEUP_M 0x20000 +#define FREESCALE_ENET_EIR_WAKEUP_S 17 +#define FREESCALE_ENET_EIR_PLR_M 0x40000 +#define FREESCALE_ENET_EIR_PLR_S 18 +#define FREESCALE_ENET_EIR_UN_M 0x80000 +#define FREESCALE_ENET_EIR_UN_S 19 +#define FREESCALE_ENET_EIR_RL_M 0x100000 +#define FREESCALE_ENET_EIR_RL_S 20 +#define FREESCALE_ENET_EIR_LC_M 0x200000 +#define FREESCALE_ENET_EIR_LC_S 21 +#define FREESCALE_ENET_EIR_EBERR_M 0x400000 +#define FREESCALE_ENET_EIR_EBERR_S 22 +#define FREESCALE_ENET_EIR_MII_M 0x800000 +#define FREESCALE_ENET_EIR_MII_S 23 +#define FREESCALE_ENET_EIR_RXB_M 0x1000000 +#define FREESCALE_ENET_EIR_RXB_S 24 +#define FREESCALE_ENET_EIR_RXF_M 0x2000000 +#define FREESCALE_ENET_EIR_RXF_S 25 +#define FREESCALE_ENET_EIR_TXB_M 0x4000000 +#define FREESCALE_ENET_EIR_TXB_S 26 +#define FREESCALE_ENET_EIR_TXF_M 0x8000000 +#define FREESCALE_ENET_EIR_TXF_S 27 +#define FREESCALE_ENET_EIR_GRA_M 0x10000000 +#define FREESCALE_ENET_EIR_GRA_S 28 +#define FREESCALE_ENET_EIR_BABT_M 0x20000000 +#define FREESCALE_ENET_EIR_BABT_S 29 +#define FREESCALE_ENET_EIR_BABR_M 0x40000000 +#define FREESCALE_ENET_EIR_BABR_S 30 +// EIMR Bit Fields +#define FREESCALE_ENET_EIMR_TS_TIMER_M 0x8000 +#define FREESCALE_ENET_EIMR_TS_TIMER_S 15 +#define FREESCALE_ENET_EIMR_TS_AVAIL_M 0x10000 +#define FREESCALE_ENET_EIMR_TS_AVAIL_S 16 +#define FREESCALE_ENET_EIMR_WAKEUP_M 0x20000 +#define FREESCALE_ENET_EIMR_WAKEUP_S 17 +#define FREESCALE_ENET_EIMR_PLR_M 0x40000 +#define FREESCALE_ENET_EIMR_PLR_S 18 +#define FREESCALE_ENET_EIMR_UN_M 0x80000 +#define FREESCALE_ENET_EIMR_UN_S 19 +#define FREESCALE_ENET_EIMR_RL_M 0x100000 +#define FREESCALE_ENET_EIMR_RL_S 20 +#define FREESCALE_ENET_EIMR_LC_M 0x200000 +#define FREESCALE_ENET_EIMR_LC_S 21 +#define FREESCALE_ENET_EIMR_EBERR_M 0x400000 +#define FREESCALE_ENET_EIMR_EBERR_S 22 +#define FREESCALE_ENET_EIMR_MII_M 0x800000 +#define FREESCALE_ENET_EIMR_MII_S 23 +#define FREESCALE_ENET_EIMR_RXB_M 0x1000000 +#define FREESCALE_ENET_EIMR_RXB_S 24 +#define FREESCALE_ENET_EIMR_RXF_M 0x2000000 +#define FREESCALE_ENET_EIMR_RXF_S 25 +#define FREESCALE_ENET_EIMR_TXB_M 0x4000000 +#define FREESCALE_ENET_EIMR_TXB_S 26 +#define FREESCALE_ENET_EIMR_TXF_M 0x8000000 +#define FREESCALE_ENET_EIMR_TXF_S 27 +#define FREESCALE_ENET_EIMR_GRA_M 0x10000000 +#define FREESCALE_ENET_EIMR_GRA_S 28 +#define FREESCALE_ENET_EIMR_BABT_M 0x20000000 +#define FREESCALE_ENET_EIMR_BABT_S 29 +#define FREESCALE_ENET_EIMR_BABR_M 0x40000000 +#define FREESCALE_ENET_EIMR_BABR_S 30 +// RDAR Bit Fields +#define FREESCALE_ENET_RDAR_RDAR_M 0x1000000 +#define FREESCALE_ENET_RDAR_RDAR_S 24 +// TDAR Bit Fields +#define FREESCALE_ENET_TDAR_TDAR_M 0x1000000 +#define FREESCALE_ENET_TDAR_TDAR_S 24 +// ECR Bit Fields +#define FREESCALE_ENET_ECR_RESET_M 0x1 +#define FREESCALE_ENET_ECR_RESET_S 0 +#define FREESCALE_ENET_ECR_ETHEREN_M 0x2 +#define FREESCALE_ENET_ECR_ETHEREN_S 1 +#define FREESCALE_ENET_ECR_MAGICEN_M 0x4 +#define FREESCALE_ENET_ECR_MAGICEN_S 2 +#define FREESCALE_ENET_ECR_SLEEP_M 0x8 +#define FREESCALE_ENET_ECR_SLEEP_S 3 +#define FREESCALE_ENET_ECR_EN1588_M 0x10 +#define FREESCALE_ENET_ECR_EN1588_S 4 +#define FREESCALE_ENET_ECR_DBGEN_M 0x40 +#define FREESCALE_ENET_ECR_DBGEN_S 6 +#define FREESCALE_ENET_ECR_STOPEN_M 0x80 +#define FREESCALE_ENET_ECR_STOPEN_S 7 +// MMFR Bit Fields +#define FREESCALE_ENET_MMFR_DATA_M 0xFFFF +#define FREESCALE_ENET_MMFR_DATA_S 0 +#define FREESCALE_ENET_MMFR_DATA(__val) \ + VALUE_(FREESCALE_ENET_MMFR_DATA_S, __val) +#define FREESCALE_ENET_MMFR_TA_M 0x30000 +#define FREESCALE_ENET_MMFR_TA_S 16 +#define FREESCALE_ENET_MMFR_TA(__val) \ + VALUE_(FREESCALE_ENET_MMFR_TA_S, __val) +#define FREESCALE_ENET_MMFR_RA_M 0x7C0000 +#define FREESCALE_ENET_MMFR_RA_S 18 +#define FREESCALE_ENET_MMFR_RA(__val) \ + VALUE_(FREESCALE_ENET_MMFR_RA_S, __val) +#define FREESCALE_ENET_MMFR_PA_M 0xF800000 +#define FREESCALE_ENET_MMFR_PA_S 23 +#define FREESCALE_ENET_MMFR_PA(__val) \ + VALUE_(FREESCALE_ENET_MMFR_PA_S, __val) +#define FREESCALE_ENET_MMFR_OP_M 0x30000000 +#define FREESCALE_ENET_MMFR_OP_S 28 +#define FREESCALE_ENET_MMFR_OP(__val) \ + VALUE_(FREESCALE_ENET_MMFR_OP_S, __val) +#define FREESCALE_ENET_MMFR_ST_M 0xC0000000 +#define FREESCALE_ENET_MMFR_ST_S 30 +#define FREESCALE_ENET_MMFR_ST(__val) \ + VALUE_(FREESCALE_ENET_MMFR_ST_S, __val) +// MSCR Bit Fields +#define FREESCALE_ENET_MSCR_MII_SPEED_M 0x7E +#define FREESCALE_ENET_MSCR_MII_SPEED_S 1 +#define FREESCALE_ENET_MSCR_MII_SPEED(__val) \ + VALUE_(FREESCALE_ENET_MSCR_MII_SPEED_S, __val) +#define FREESCALE_ENET_MSCR_DIS_PRE_M 0x80 +#define FREESCALE_ENET_MSCR_DIS_PRE_S 7 +#define FREESCALE_ENET_MSCR_HOLDTIME_M 0x700 +#define FREESCALE_ENET_MSCR_HOLDTIME_S 8 +#define FREESCALE_ENET_MSCR_HOLDTIME(__val) \ + VALUE_(FREESCALE_ENET_MSCR_HOLDTIME_S, __val) +// MIBC Bit Fields +#define FREESCALE_ENET_MIBC_MIB_CLEAR_M 0x20000000 +#define FREESCALE_ENET_MIBC_MIB_CLEAR_S 29 +#define FREESCALE_ENET_MIBC_MIB_IDLE_M 0x40000000 +#define FREESCALE_ENET_MIBC_MIB_IDLE_S 30 +#define FREESCALE_ENET_MIBC_MIB_DIS_M 0x80000000 +#define FREESCALE_ENET_MIBC_MIB_DIS_S 31 +// RCR Bit Fields +#define FREESCALE_ENET_RCR_LOOP_M 0x1 +#define FREESCALE_ENET_RCR_LOOP_S 0 +#define FREESCALE_ENET_RCR_DRT_M 0x2 +#define FREESCALE_ENET_RCR_DRT_S 1 +#define FREESCALE_ENET_RCR_MII_MODE_M 0x4 +#define FREESCALE_ENET_RCR_MII_MODE_S 2 +#define FREESCALE_ENET_RCR_PROM_M 0x8 +#define FREESCALE_ENET_RCR_PROM_S 3 +#define FREESCALE_ENET_RCR_BC_REJ_M 0x10 +#define FREESCALE_ENET_RCR_BC_REJ_S 4 +#define FREESCALE_ENET_RCR_FCE_M 0x20 +#define FREESCALE_ENET_RCR_FCE_S 5 +#define FREESCALE_ENET_RCR_RMII_MODE_M 0x100 +#define FREESCALE_ENET_RCR_RMII_MODE_S 8 +#define FREESCALE_ENET_RCR_RMII_10T_M 0x200 +#define FREESCALE_ENET_RCR_RMII_10T_S 9 +#define FREESCALE_ENET_RCR_PADEN_M 0x1000 +#define FREESCALE_ENET_RCR_PADEN_S 12 +#define FREESCALE_ENET_RCR_PAUFWD_M 0x2000 +#define FREESCALE_ENET_RCR_PAUFWD_S 13 +#define FREESCALE_ENET_RCR_CRCFWD_M 0x4000 +#define FREESCALE_ENET_RCR_CRCFWD_S 14 +#define FREESCALE_ENET_RCR_CFEN_M 0x8000 +#define FREESCALE_ENET_RCR_CFEN_S 15 +#define FREESCALE_ENET_RCR_MAX_FL_M 0x3FFF0000 +#define FREESCALE_ENET_RCR_MAX_FL_S 16 +#define FREESCALE_ENET_RCR_MAX_FL(__val) \ + VALUE_(FREESCALE_ENET_RCR_MAX_FL_S, __val) +#define FREESCALE_ENET_RCR_NLC_M 0x40000000 +#define FREESCALE_ENET_RCR_NLC_S 30 +#define FREESCALE_ENET_RCR_GRS_M 0x80000000 +#define FREESCALE_ENET_RCR_GRS_S 31 +// TCR Bit Fields +#define FREESCALE_ENET_TCR_GTS_M 0x1 +#define FREESCALE_ENET_TCR_GTS_S 0 +#define FREESCALE_ENET_TCR_FDEN_M 0x4 +#define FREESCALE_ENET_TCR_FDEN_S 2 +#define FREESCALE_ENET_TCR_TFC_PAUSE_M 0x8 +#define FREESCALE_ENET_TCR_TFC_PAUSE_S 3 +#define FREESCALE_ENET_TCR_RFC_PAUSE_M 0x10 +#define FREESCALE_ENET_TCR_RFC_PAUSE_S 4 +#define FREESCALE_ENET_TCR_ADDSEL_M 0xE0 +#define FREESCALE_ENET_TCR_ADDSEL_S 5 +#define FREESCALE_ENET_TCR_ADDSEL(__val) \ + VALUE_(FREESCALE_ENET_TCR_ADDSEL_S, __val) +#define FREESCALE_ENET_TCR_ADDINS_M 0x100 +#define FREESCALE_ENET_TCR_ADDINS_S 8 +#define FREESCALE_ENET_TCR_CRCFWD_M 0x200 +#define FREESCALE_ENET_TCR_CRCFWD_S 9 +// PALR Bit Fields +#define FREESCALE_ENET_PALR_PADDR1_M 0xFFFFFFFF +#define FREESCALE_ENET_PALR_PADDR1_S 0 +#define FREESCALE_ENET_PALR_PADDR1(__val) \ + VALUE_(FREESCALE_ENET_PALR_PADDR1_S, __val) +// PAUR Bit Fields +#define FREESCALE_ENET_PAUR_TYPE_M 0xFFFF +#define FREESCALE_ENET_PAUR_TYPE_S 0 +#define FREESCALE_ENET_PAUR_TYPE(__val) \ + VALUE_(FREESCALE_ENET_PAUR_TYPE_S, __val) +#define FREESCALE_ENET_PAUR_PADDR2_M 0xFFFF0000 +#define FREESCALE_ENET_PAUR_PADDR2_S 16 +#define FREESCALE_ENET_PAUR_PADDR2(__val) \ + VALUE_(FREESCALE_ENET_PAUR_PADDR2_S, __val) +// OPD Bit Fields +#define FREESCALE_ENET_OPD_PAUSE_DUR_M 0xFFFF +#define FREESCALE_ENET_OPD_PAUSE_DUR_S 0 +#define FREESCALE_ENET_OPD_PAUSE_DUR(__val) \ + VALUE_(FREESCALE_ENET_OPD_PAUSE_DUR_S, __val) +#define FREESCALE_ENET_OPD_OPCODE_M 0xFFFF0000 +#define FREESCALE_ENET_OPD_OPCODE_S 16 +#define FREESCALE_ENET_OPD_OPCODE(__val) \ + VALUE_(FREESCALE_ENET_OPD_OPCODE_S, __val) +// IAUR Bit Fields +#define FREESCALE_ENET_IAUR_IADDR1_M 0xFFFFFFFF +#define FREESCALE_ENET_IAUR_IADDR1_S 0 +#define FREESCALE_ENET_IAUR_IADDR1(__val) \ + VALUE_(FREESCALE_ENET_IAUR_IADDR1_S, __val) +// IALR Bit Fields +#define FREESCALE_ENET_IALR_IADDR2_M 0xFFFFFFFF +#define FREESCALE_ENET_IALR_IADDR2_S 0 +#define FREESCALE_ENET_IALR_IADDR2(__val) \ + VALUE_(FREESCALE_ENET_IALR_IADDR2_S, __val) +// GAUR Bit Fields +#define FREESCALE_ENET_GAUR_GADDR1_M 0xFFFFFFFF +#define FREESCALE_ENET_GAUR_GADDR1_S 0 +#define FREESCALE_ENET_GAUR_GADDR1(__val) \ + VALUE_(FREESCALE_ENET_GAUR_GADDR1_S, __val) +// GALR Bit Fields +#define FREESCALE_ENET_GALR_GADDR2_M 0xFFFFFFFF +#define FREESCALE_ENET_GALR_GADDR2_S 0 +#define FREESCALE_ENET_GALR_GADDR2(__val) \ + VALUE_(FREESCALE_ENET_GALR_GADDR2_S, __val) +// TFWR Bit Fields +#define FREESCALE_ENET_TFWR_TFWR_M 0x3F +#define FREESCALE_ENET_TFWR_TFWR_S 0 +#define FREESCALE_ENET_TFWR_TFWR(__val) \ + VALUE_(FREESCALE_ENET_TFWR_TFWR_S, __val) +#define FREESCALE_ENET_TFWR_STRFWD_M 0x100 +#define FREESCALE_ENET_TFWR_STRFWD_S 8 + +#define FREESCALE_ENET_TFWR_TFWR_64 0x0 +#define FREESCALE_ENET_TFWR_TFWR_64A 0x1 +#define FREESCALE_ENET_TFWR_TFWR_128 0x2 +#define FREESCALE_ENET_TFWR_TFWR_192 0x3 +#define FREESCALE_ENET_TFWR_TFWR_4032 0x3F +// RDSR Bit Fields +#define FREESCALE_ENET_RDSR_R_DES_START_M 0xFFFFFFF8 +#define FREESCALE_ENET_RDSR_R_DES_START_S 3 +#define FREESCALE_ENET_RDSR_R_DES_START(__val) \ + VALUE_(FREESCALE_ENET_RDSR_R_DES_S, __val) +// TDSR Bit Fields +#define FREESCALE_ENET_TDSR_X_DES_START_M 0xFFFFFFF8 +#define FREESCALE_ENET_TDSR_X_DES_START_S 3 +#define FREESCALE_ENET_TDSR_X_DES_START(__val) \ + VALUE_(FREESCALE_ENET_TDSR_X_DES_S, __val) +// MRBR Bit Fields +#define FREESCALE_ENET_MRBR_R_BUF_SIZE_M 0x3FF0 +#define FREESCALE_ENET_MRBR_R_BUF_SIZE_S 4 +#define FREESCALE_ENET_MRBR_R_BUF_SIZE(__val) \ + VALUE_(FREESCALE_ENET_MRBR_R_BUF_S, __val) +// RSFL Bit Fields +#define FREESCALE_ENET_RSFL_RX_SECTION_FULL_M 0xFF +#define FREESCALE_ENET_RSFL_RX_SECTION_FULL_S 0 +#define FREESCALE_ENET_RSFL_RX_SECTION_FULL(__val) \ + VALUE_(FREESCALE_ENET_RSFL_RX_S, __val) +// RSEM Bit Fields +#define FREESCALE_ENET_RSEM_RX_SECTION_EMPTY_M 0xFF +#define FREESCALE_ENET_RSEM_RX_SECTION_EMPTY_S 0 +#define FREESCALE_ENET_RSEM_RX_SECTION_EMPTY(__val) \ + VALUE_(FREESCALE_ENET_RSEM_RX_S, __val) +// RAEM Bit Fields +#define FREESCALE_ENET_RAEM_RX_ALMOST_EMPTY_M 0xFF +#define FREESCALE_ENET_RAEM_RX_ALMOST_EMPTY_S 0 +#define FREESCALE_ENET_RAEM_RX_ALMOST_EMPTY(__val) \ + VALUE_(FREESCALE_ENET_RAEM_RX_ALMOST_EMPTY_S, __val) +// RAFL Bit Fields +#define FREESCALE_ENET_RAFL_RX_ALMOST_FULL_M 0xFF +#define FREESCALE_ENET_RAFL_RX_ALMOST_FULL_S 0 +#define FREESCALE_ENET_RAFL_RX_ALMOST_FULL(__val) \ + VALUE_(FREESCALE_ENET_RAFL_RX_ALMOST_FULL_S, __val) +// TSEM Bit Fields +#define FREESCALE_ENET_TSEM_TX_SECTION_EMPTY_M 0xFF +#define FREESCALE_ENET_TSEM_TX_SECTION_EMPTY_S 0 +#define FREESCALE_ENET_TSEM_TX_SECTION_EMPTY(__val) \ + VALUE_(FREESCALE_ENET_TSEM_TX_S, __val) +// TAEM Bit Fields +#define FREESCALE_ENET_TAEM_TX_ALMOST_EMPTY_M 0xFF +#define FREESCALE_ENET_TAEM_TX_ALMOST_EMPTY_S 0 +#define FREESCALE_ENET_TAEM_TX_ALMOST_EMPTY(__val) \ + VALUE_(FREESCALE_ENET_TAEM_TX_ALMOST_EMPTY_S, __val) +// TAFL Bit Fields +#define FREESCALE_ENET_TAFL_TX_ALMOST_FULL_M 0xFF +#define FREESCALE_ENET_TAFL_TX_ALMOST_FULL_S 0 +#define FREESCALE_ENET_TAFL_TX_ALMOST_FULL(__val) \ + VALUE_(FREESCALE_ENET_TAFL_TX_ALMOST_FULL_S, __val) +// TIPG Bit Fields +#define FREESCALE_ENET_TIPG_IPG_M 0x1F +#define FREESCALE_ENET_TIPG_IPG_S 0 +#define FREESCALE_ENET_TIPG_IPG(__val) \ + VALUE_(FREESCALE_ENET_TIPG_IPG_S, __val) +// FTRL Bit Fields +#define FREESCALE_ENET_FTRL_TRUNC_FL_M 0x3FFF +#define FREESCALE_ENET_FTRL_TRUNC_FL_S 0 +#define FREESCALE_ENET_FTRL_TRUNC_FL(__val) \ + VALUE_(FREESCALE_ENET_FTRL_TRUNC_FL_S, __val) +// TACC Bit Fields +#define FREESCALE_ENET_TACC_S16_M 0x1 +#define FREESCALE_ENET_TACC_S16_S 0 +#define FREESCALE_ENET_TACC_IPCHK_M 0x8 +#define FREESCALE_ENET_TACC_IPCHK_S 3 +#define FREESCALE_ENET_TACC_PROCHK_M 0x10 +#define FREESCALE_ENET_TACC_PROCHK_S 4 +// RACC Bit Fields +#define FREESCALE_ENET_RACC_PADREM_M 0x1 +#define FREESCALE_ENET_RACC_PADREM_S 0 +#define FREESCALE_ENET_RACC_IPDIS_M 0x2 +#define FREESCALE_ENET_RACC_IPDIS_S 1 +#define FREESCALE_ENET_RACC_PRODIS_M 0x4 +#define FREESCALE_ENET_RACC_PRODIS_S 2 +#define FREESCALE_ENET_RACC_LINEDIS_M 0x40 +#define FREESCALE_ENET_RACC_LINEDIS_S 6 +#define FREESCALE_ENET_RACC_S16_M 0x80 +#define FREESCALE_ENET_RACC_S16_S 7 +// ATCR Bit Fields +#define FREESCALE_ENET_ATCR_EN_M 0x1 +#define FREESCALE_ENET_ATCR_EN_S 0 +#define FREESCALE_ENET_ATCR_OFFEN_M 0x4 +#define FREESCALE_ENET_ATCR_OFFEN_S 2 +#define FREESCALE_ENET_ATCR_OFFRST_M 0x8 +#define FREESCALE_ENET_ATCR_OFFRST_S 3 +#define FREESCALE_ENET_ATCR_PEREN_M 0x10 +#define FREESCALE_ENET_ATCR_PEREN_S 4 +#define FREESCALE_ENET_ATCR_PINPER_M 0x80 +#define FREESCALE_ENET_ATCR_PINPER_S 7 +#define FREESCALE_ENET_ATCR_RESTART_M 0x200 +#define FREESCALE_ENET_ATCR_RESTART_S 9 +#define FREESCALE_ENET_ATCR_CAPTURE_M 0x800 +#define FREESCALE_ENET_ATCR_CAPTURE_S 11 +#define FREESCALE_ENET_ATCR_SLAVE_M 0x2000 +#define FREESCALE_ENET_ATCR_SLAVE_S 13 +// ATVR Bit Fields +#define FREESCALE_ENET_ATVR_ATIME_M 0xFFFFFFFF +#define FREESCALE_ENET_ATVR_ATIME_S 0 +#define FREESCALE_ENET_ATVR_ATIME(__val) \ + VALUE_(FREESCALE_ENET_ATVR_ATIME_S, __val) +// ATOFF Bit Fields +#define FREESCALE_ENET_ATOFF_OFFSET_M 0xFFFFFFFF +#define FREESCALE_ENET_ATOFF_OFFSET_S 0 +#define FREESCALE_ENET_ATOFF_OFFSET(__val) \ + VALUE_(FREESCALE_ENET_ATOFF_OFFSET_S, __val) +// ATPER Bit Fields +#define FREESCALE_ENET_ATPER_PERIOD_M 0xFFFFFFFF +#define FREESCALE_ENET_ATPER_PERIOD_S 0 +#define FREESCALE_ENET_ATPER_PERIOD(__val) \ + VALUE_(FREESCALE_ENET_ATPER_PERIOD_S, __val) +// ATCOR Bit Fields +#define FREESCALE_ENET_ATCOR_COR_M 0x7FFFFFFF +#define FREESCALE_ENET_ATCOR_COR_S 0 +#define FREESCALE_ENET_ATCOR_COR(__val) \ + VALUE_(FREESCALE_ENET_ATCOR_COR_S, __val) +// ATINC Bit Fields +#define FREESCALE_ENET_ATINC_INC_M 0x7F +#define FREESCALE_ENET_ATINC_INC_S 0 +#define FREESCALE_ENET_ATINC_INC(__val) \ + VALUE_(FREESCALE_ENET_ATINC_INC_S, __val) +#define FREESCALE_ENET_ATINC_INC_CORR_M 0x7F00 +#define FREESCALE_ENET_ATINC_INC_CORR_S 8 +#define FREESCALE_ENET_ATINC_INC_CORR(__val) \ + VALUE_(FREESCALE_ENET_ATINC_INC_CORR_S, __val) +// ATSTMP Bit Fields +#define FREESCALE_ENET_ATSTMP_TIMESTAMP_M 0xFFFFFFFF +#define FREESCALE_ENET_ATSTMP_TIMESTAMP_S 0 +#define FREESCALE_ENET_ATSTMP_TIMESTAMP(__val) \ + VALUE_(FREESCALE_ENET_ATSTMP_TIMESTAMP_S, __val) +// TGSR Bit Fields +#define FREESCALE_ENET_TGSR_TF0_M 0x1 +#define FREESCALE_ENET_TGSR_TF0_S 0 +#define FREESCALE_ENET_TGSR_TF1_M 0x2 +#define FREESCALE_ENET_TGSR_TF1_S 1 +#define FREESCALE_ENET_TGSR_TF2_M 0x4 +#define FREESCALE_ENET_TGSR_TF2_S 2 +#define FREESCALE_ENET_TGSR_TF3_M 0x8 +#define FREESCALE_ENET_TGSR_TF3_S 3 +// TCSR Bit Fields +#define FREESCALE_ENET_TCSR_TDRE_M 0x1 +#define FREESCALE_ENET_TCSR_TDRE_S 0 +#define FREESCALE_ENET_TCSR_TMODE_M 0x3C +#define FREESCALE_ENET_TCSR_TMODE_S 2 +#define FREESCALE_ENET_TCSR_TMODE(__val) \ + VALUE_(FREESCALE_ENET_TCSR_TMODE_S, __val) +#define FREESCALE_ENET_TCSR_TIE_M 0x40 +#define FREESCALE_ENET_TCSR_TIE_S 6 +#define FREESCALE_ENET_TCSR_TF_M 0x80 +#define FREESCALE_ENET_TCSR_TF_S 7 +// TCCR Bit Fields +#define FREESCALE_ENET_TCCR_TCC_M 0xFFFFFFFF +#define FREESCALE_ENET_TCCR_TCC_S 0 +#define FREESCALE_ENET_TCCR_TCC(__val) \ + VALUE_(FREESCALE_ENET_TCCR_TCC_S, __val) + +#define FREESCALE_ENET_EIR_ERROR \ + (FREESCALE_ENET_EIR_PLR_M | \ + FREESCALE_ENET_EIR_UN_M | \ + FREESCALE_ENET_EIR_RL_M | \ + FREESCALE_ENET_EIR_LC_M | \ + FREESCALE_ENET_EIR_EBERR_M | \ + FREESCALE_ENET_EIR_BABT_M | \ + FREESCALE_ENET_EIR_BABR_M) + +// EOF if_freescale_enet_io.h +#endif // CYGONCE_IF_FREESCALE_ENET_IO_H diff --git a/packages/devs/eth/freescale/enet/current/src/if_freescale_enet.c b/packages/devs/eth/freescale/enet/current/src/if_freescale_enet.c new file mode 100644 --- /dev/null +++ b/packages/devs/eth/freescale/enet/current/src/if_freescale_enet.c @@ -0,0 +1,1544 @@ +//========================================================================== +// +// if_freescale_enet.c +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2011 Free Software Foundation, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later +// version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with eCos; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// As a special exception, if other files instantiate templates or use +// macros or inline functions from this file, or you compile this file +// and link it with other works to produce a work based on this file, +// this file does not by itself cause the resulting work to be covered by +// the GNU General Public License. However the source code for this file +// must still be made available in accordance with section (3) of the GNU +// General Public License v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): Ilija Kocho +// Contributors: +// Date: 2011-06-04 +// Description: Hardware driver for Freescale ENET peripheral +// +// This driver was originally written for Kinetis and may +// require some modifications to work on other Freescale +// families such as ColdFire+. +// +//####DESCRIPTIONEND#### +// +//========================================================================*/ + + +#include +#include +#include +#include + +#if defined(CYGPKG_REDBOOT) +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CYGPKG_NET +# include +# include //Needed for struct ifnet +#endif + +#include +#include +#include + +// Some debugging helpers --------------------------------------------------- + +#define DEBUG_ENET CYGPKG_DEVS_ETH_FREESCALE_ENET_DEBUG_LEVEL + +#if DEBUG_ENET >= 3 +# define debug3_printf(args...) diag_printf(args) +#else +# define debug3_printf(args...) +#endif + +#if DEBUG_ENET >= 2 +# define debug2_printf(args...) diag_printf(args) +#else +# define debug2_printf(args...) +#endif + +#if DEBUG_ENET >= 1 +# define debug1_printf(args...) diag_printf(args) +#else +# define debug1_printf(args...) +#endif + + +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +#define enet_eth_send enet_eth_send_nocopy +#define enet_eth_deliver enet_eth_deliver_nocopy +#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +#define enet_eth_send enet_eth_send_copying +#define enet_eth_deliver enet_eth_deliver_copying +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + + +// Some delay macros ------------------------------------------------------ +// Busy waiting delay +#define ENET_WAIT_US(__us) HAL_DELAY_US(__us) +// Delays / Timeouts +#define FREESCALE_ENET_RESET_DELAY 1 // Enet reset [us] +#define FREESCALE_ENET_ENABLE_DELAY 1 // Enet eneble [us] + +#define FREESCALE_ENET_PHY_INIT_TOUT 100 // Phy start up [ms] +#define FREESCALE_ENET_MII_WRITE_TOUT 2000 // Phy write timeout [us] +#define FREESCALE_ENET_MII_READ_TOUT 2000 // Phy read timeout [us] + +#ifndef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +// If kernel is available ENET_ETH_WAIT should be a normal, +// not a busy-waiting delay. +# ifdef CYGFUN_KERNEL_API_C +# define ENET_ETH_WAIT(__tick) cyg_thread_delay(__tick) +# elif !defined(CYGPKG_KERNEL) +# define ENET_ETH_WAIT(__ms) HAL_DELAY_US(__ms * 1000) +# else +# error Can not define ENET_ETH_WAIT(). +# endif +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + +// Resources provided by HAL ============================================== +// Ethernet RAM and DMA configuration -------------------------------------- + +#ifdef CYGHWR_HAL_ENET_MEM_SECTION +# include +# define ENET_RAM_MEM_SECTION CYGBLD_ATTRIB_SECTION(CYGHWR_HAL_ENET_MEM_SECTION) +#else +# define ENET_RAM_MEM_SECTION +#endif // CYGHWR_HAL_ENET_MEM_SECTION + + +// IRQ masking -------------------------------------------------------------- +// + +#define FREESCALE_ENET_EIR_MASK_M (FREESCALE_ENET_EIR_TXF_M | \ + FREESCALE_ENET_EIR_TXB_M | FREESCALE_ENET_EIR_RXF_M | \ + FREESCALE_ENET_EIR_RXB_M) + +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +# define FREESCALE_ENET_EIMR_MASK_M (FREESCALE_ENET_EIMR_RXF_M | \ + FREESCALE_ENET_EIMR_TXF_M) +#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +# define FREESCALE_ENET_EIMR_MASK_M FREESCALE_ENET_EIMR_RXF_M +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + + +// Buffer configuration macros ---------------------------------------------------- +// + +#define ENET_RXBD_ALIGN \ + CYGBLD_ATTRIB_ALIGN(CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBD_ALIGN) +#define ENET_TXBD_ALIGN \ + CYGBLD_ATTRIB_ALIGN(CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBD_ALIGN) +#define ENET_RXBUF_ALIGN \ + CYGBLD_ATTRIB_ALIGN(CYGNUM_DEVS_ETH_FREESCALE_ENET_RXBUF_ALIGN) +#define ENET_TXBUF_ALIGN \ + CYGBLD_ATTRIB_ALIGN(CYGNUM_DEVS_ETH_FREESCALE_ENET_TXBUF_ALIGN) + +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +# define ENET_TXKEY_FLAG ENET_TXBD_TO2 +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + + +// ENET statistics ---------------------------------------------------- +// + +#ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS_DEBUG +# define ENET_STAT_PRINTF(args...) diag_printf(args) +#else //CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS_DEBUG +# define ENET_STAT_PRINTF(args...) +#endif // CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS_DEBUG + +#ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS +typedef struct freescale_enet_stats_s { + cyg_uint32 TR; // Truncated + cyg_uint32 CR; // CRC or frame error + cyg_uint32 OV; // Overrun + cyg_uint32 LG; // Frame length violation + cyg_uint32 NO; // Non octet aligned frame +#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + cyg_uint32 ME; // MAC error + cyg_uint32 CE; // Receive CRC error + cyg_uint32 PE; // PHY error + cyg_uint32 FRAG; // IPv4 Fragment + cyg_uint32 ICE; // IP header chechsum error + cyg_uint32 PCR; // Protocol checksum error +#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED +} freescale_enet_stats_t; + +void freescale_enet_stats_init(freescale_enet_stats_t *stats_p) { + stats_p->TR = 0; + stats_p->CR = 0; + stats_p->OV = 0; + stats_p->LG = 0; + stats_p->NO = 0; +#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + stats_p->ME = 0; + stats_p->CE = 0; + stats_p->PE = 0; + stats_p->FRAG = 0; + stats_p->ICE = 0; + stats_p->PCR = 0; +#endif //CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED +} + +# define FREESCALE_ENET_STATS_INIT(__poin) freescale_enet_stats_init(__poin) +# define FREESCALE_ENET_STAT_COUNT(__poin,__val) (__poin->enet_stats.__val++) + +# define FREESCALE_ENET_STAT_DO(__ctrl,__poin,__val) \ +CYG_MACRO_START \ + if(__ctrl & ENET_RXBD_##__val){ \ + FREESCALE_ENET_STAT_COUNT(__poin,__val); \ + ENET_STAT_PRINTF(#__val "(%d) ", __poin->enet_stats.__val); \ + } \ +CYG_MACRO_END + +#else + +# define FREESCALE_ENET_STATS_INIT(__poin) +# define FREESCALE_ENET_STAT_COUNT(_poin,_val) +# define FREESCALE_ENET_STAT_DO(__ctrl,__poin,__val) + +#endif // CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS + + +// ENET device =============================================================== +// Freescale ENET driver private data ---------------------------------------- + +typedef struct freescale_enet_priv_t { + CYG_ADDRWORD enet_base; // ENET base address + eth_phy_access_t *phy_p; // PHY access + cyg_uint16 max_frame_len; // Maximal frame length + cyg_uint8 rxbd_num; // Number of Rx buffer descriptors + cyg_uint8 txbd_num; // Number of Tx buffer descriptors + cyg_uint8 pins_n; // Number of (R)MII pins +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + cyg_uint8 txbd_avail; // Avalable Tx buffer descriptors + cyg_uint8 txkey_num; // Number of Tx key entries + cyg_uint8 txbd_can_send_min; // Minimal number of avail +#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + cyg_uint8 res0; // Reserved + cyg_uint16 txbuf_size; // Tx buffer size + cyg_uint8 *txbuf_p; // Tx buffer pool +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + cyg_uint16 rxbuf_size; // Rx buffer size + cyg_uint8 fc_pause; // Flow control pause length + cyg_uint8 flags; // Various flags + cyg_uint8 *rxbuf_p; // Rx buffer pool + enet_bd_t *rxbd_pool_p; // Rx buffer descriptor pool + enet_bd_t *txbd_pool_p; // TX buffer descriptor poll + enet_bd_t *rxbd_p; // Current Rx BD + enet_bd_t *txbd_head_p; // Current Tx BD head + enet_bd_t *txbd_tail_p; // Current Tx BD tail +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + cyg_uint32 *txkey_pool_p; // Tx key queue pool + cyg_uint32 *txkey_head_p; // Last Txkey entry + cyg_uint32 *txkey_tail_p; // Last Txkey released +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + const cyg_uint32 *pins_p; // (R)MII pin configuration data + cyg_uint8 *enaddr; // Default ethernet (MAC) address + cyg_uint32 rx_intr_vector; + cyg_uint32 rx_intr_prio; +#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED + cyg_interrupt rx_interrupt; + cyg_handle_t rx_interrupt_handle; +#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + cyg_uint32 tx_intr_vector; + cyg_uint32 tx_intr_prio; +# ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED + cyg_interrupt tx_interrupt; + cyg_handle_t tx_interrupt_handle; +# endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +#ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS + freescale_enet_stats_t enet_stats; +#endif // CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS +} freescale_enet_priv_t; + +// Forward declarations ====================================================== + +static void enet_write_phy(int reg_addr, int phy_addr, unsigned short data); +static bool enet_read_phy(int reg_addr, int phy_addr, unsigned short *data_p); +static void enet_init_phy(void); +static void enet_eth_phy_set(freescale_enet_priv_t *enet_priv_p); +static bool eth_phy_init_wait(eth_phy_access_t *phy_p, cyg_uint32 ms); +#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED +static cyg_uint32 enet_eth_isr(cyg_vector_t vector, cyg_addrword_t data); +#endif + +// Device instances =========================================================== +// + +// ENET0 ====================================================================== +// (R)MII pins - Provided by HAL ---------------------------------------------- + +static const cyg_uint32 const enet0_pins[] = { + // Both RMII and MII interface + CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_MDIO, + CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_MDC, +#ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_PHY_RXER_USE + CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_RXER, +#endif + CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_RXD1, + CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_RXD0, + CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_TXEN, + CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_TXD0, + CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_TXD1, +#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_PHY_RMII + // RMII interface only + CYGHWR_IO_FREESCALE_ENET0_PIN_RMII0_CRS_DV +#else + // MII interface only + CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_RXD3, + CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_RXD2, + CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_RXCLK, + CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_TXD2, + CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_TXCLK, + CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_TXD3, + CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_CRS, + CYGHWR_IO_FREESCALE_ENET0_PIN_MIIO_TXER, + CYGHWR_IO_FREESCALE_ENET0_PIN_MII0_COL +#endif +#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_1588 + , + // IEEE 1588 timers + CYGHWR_IO_FREESCALE_ENET0_PIN_1588_CLKIN, + + CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR0, + CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR1, + CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR2, + CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR3, + + CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR0, + CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR1, + CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR2, + CYGHWR_IO_FREESCALE_ENET0_PIN_E0_1588_TMR3 +#endif +}; + +// Buffer and buffer descriptor memory -------------------------------------- + +// Buffer descriptors +enet_bd_t enet0_rxbd_pool[CYGNUM_DEVS_ETH_FREESCALE_ENET0_RX_BUFS] +ENET_RAM_MEM_SECTION ENET_RXBD_ALIGN; +enet_bd_t enet0_txbd_pool[CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS] + ENET_RAM_MEM_SECTION ENET_TXBD_ALIGN; + +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +// Tx key queue +cyg_uint32 enet0_txkey_pool[CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS] + ENET_RAM_MEM_SECTION; +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + +// Buffers +cyg_uint8 enet0_rxbuf[CYGNUM_DEVS_ETH_FREESCALE_ENET0_RX_BUFS * + CYGNUM_DEVS_ETH_FREESCALE_ENET0_RXBUF_SIZE] + ENET_RAM_MEM_SECTION ENET_RXBUF_ALIGN; +#ifndef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +cyg_uint8 enet0_txbuf[CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS * + CYGNUM_DEVS_ETH_FREESCALE_ENET0_TXBUF_SIZE] + ENET_RAM_MEM_SECTION ENET_TXBUF_ALIGN; +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +# if CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS >= 8 +# define ENET0_TXBD_CAN_SEND_MIN 3 +# elif CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS >= 6 +# define ENET0_TXBD_CAN_SEND_MIN 2 +# else +# define ENET0_TXBD_CAN_SEND_MIN 1 +# endif +#endif + +// PHY interface entry ----------------------------------------------------- +static cyg_uint8 enet0_macaddr[16] = + {CYGPKG_DEVS_ETH_FREESCALE_ENET0_MACADDR}; + +// + +ETH_PHY_REG_LEVEL_ACCESS_FUNS(freescale_enet0_phy, + enet_init_phy, + NULL, + enet_write_phy, + enet_read_phy); + +// ENET0 device private data ------------------------------------------------- +freescale_enet_priv_t enet0_eth0_priv = { + .enet_base = CYGADDR_IO_ETH_FREESCALE_ENET0_BASE, + .phy_p = &freescale_enet0_phy, + .max_frame_len = CYGNUM_DEVS_ETH_FREESCALE_ENET0_MAX_FRAME_LEN, + .rxbd_num = CYGNUM_DEVS_ETH_FREESCALE_ENET0_RX_BUFS, + .rxbuf_size = CYGNUM_DEVS_ETH_FREESCALE_ENET0_RXBUF_SIZE, + .rxbuf_p = enet0_rxbuf, + .txbd_num = CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS, + .rxbd_pool_p = enet0_rxbd_pool, + .txbd_pool_p = enet0_txbd_pool, + .rxbd_p = NULL, + .txbd_head_p = NULL, + .txbd_tail_p = NULL, + .fc_pause = CYGNUM_ETH_FREESCALE_ENET0_OPD_PAUSE_DUR, + .flags = CYGSEM_ETH_FREESCALE_ENET0_RCR_FCE, +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + .txbd_avail = CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS, + .txkey_pool_p = enet0_txkey_pool, + .txkey_num = CYGNUM_DEVS_ETH_FREESCALE_ENET0_TX_BUFS, + .txbd_can_send_min = ENET0_TXBD_CAN_SEND_MIN, + .txkey_head_p = NULL, + .txkey_tail_p = NULL, +#else + .txbuf_size = CYGNUM_DEVS_ETH_FREESCALE_ENET0_TXBUF_SIZE, + .txbuf_p = enet0_txbuf, +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + .pins_p = enet0_pins, + .pins_n = sizeof(enet0_pins)/sizeof(enet0_pins[0]), + .enaddr = enet0_macaddr, + .rx_intr_vector = CYGNUM_FREESCALE_ENET0_RECEIVE_INT_VECTOR, + .rx_intr_prio = CYGPKG_DEVS_ETH_FREESCALE_ENET0_INTPRIO +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + , .tx_intr_vector = CYGNUM_FREESCALE_ENET0_TRANSMIT_INT_VECTOR, + .tx_intr_prio = CYGPKG_DEVS_ETH_FREESCALE_ENET0_INTPRIO +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +}; + +// Ethernet interface entry ------------------------------------------------- +ETH_DRV_SC(enet0_eth0_sc, + &enet0_eth0_priv, // Driver specific data + CYGDAT_IO_ETH_IF_FREESCALE_ENET0_NAME, // Name for this interface + enet_eth_start, + enet_eth_stop, + enet_eth_control, + enet_eth_can_send, + enet_eth_send, + enet_eth_recv, + enet_eth_deliver, + enet_eth_poll, + enet_eth_int_vector); + +NETDEVTAB_ENTRY(enet0_netdev, + "enet0_eth", + enet_eth_init, + &enet0_eth0_sc); + +// End ENET0 ================================================================= + + +// Driver code =============================================================== +// + +// Buffer and buffer descriptor (BD) macros ================================== +// BD Iterators -------------------------------------------------------------- + +// Generic BD iterator template used by Rx and Tx iterators +#define ENET_NEXT_BD(__bd_p,__priv_p,__wrap,__pool) \ +CYG_MACRO_START \ + __bd_p = __bd_p->ctrl & __wrap ? \ + __priv_p->__pool##_pool_p : __bd_p + 1; \ +CYG_MACRO_END + +// Rx BD Iterator ------------------------------------------ +#define ENET_RXBD_NEXT(__bd_p,__priv_p) \ + ENET_NEXT_BD(__bd_p, __priv_p, ENET_RXBD_W, rxbd) + +// Tx BD Iterator +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +// Tx BD Iterator - NoCopy option -------------------------- +# define ENET_BD_AVAIL_INC(__priv_p) (__priv_p->txbd_avail++) +# define ENET_BD_AVAIL_DEC(__priv_p) (__priv_p->txbd_avail--) + +# define ENET_TXBD_ALLOC(__bd_p,__priv_p) \ +CYG_MACRO_START \ + ENET_NEXT_BD(__bd_p, __priv_p, ENET_TXBD_W, txbd); \ + ENET_BD_AVAIL_DEC(__priv_p); \ +CYG_MACRO_END + +# define ENET_TXBD_FREE(__bd_p,__priv_p) \ +CYG_MACRO_START \ + ENET_NEXT_BD(__bd_p, __priv_p, ENET_TXBD_W, txbd); \ + ENET_BD_AVAIL_INC(__priv_p); \ +CYG_MACRO_END + +# define ENET_TXBD_TRYFREE(__bd_p,__priv_p) \ +CYG_MACRO_START \ + ENET_NEXT_BD(__bd_p, __priv_p, ENET_TXBD_W, txbd); \ +CYG_MACRO_END + +// Tx key iterator ----------------------------------------- +# define ENET_TXKEY_NEXT(__bd_p,__priv_p) \ +CYG_MACRO_START \ + __bd_p = (__bd_p == (__priv_p->txkey_pool_p + __priv_p->txkey_num-1)) ? \ + __priv_p->txkey_pool_p : __bd_p + 1; \ +CYG_MACRO_END + +#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + +// Tx BD Iterator - Copying option ------------------------- +# define ENET_TXBD_NEXT(__bd_p,__priv_p) \ + ENET_NEXT_BD(__bd_p, __priv_p, ENET_TXBD_W, txbd) + +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + +// Buffer descriptor initialization functions ================================ +// + +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +# define ENET_RESET_BD_TX(__priv_p) \ +CYG_MACRO_START \ + __priv_p->txbd_head_p = __priv_p->txbd_pool_p + __priv_p->txbd_num - 1; \ + __priv_p->txbd_tail_p = __priv_p->txbd_head_p; \ + __priv_p->txbd_avail = __priv_p->txbd_num; \ + __priv_p->txkey_head_p = __priv_p->txkey_pool_p + __priv_p->txkey_num - 1; \ + __priv_p->txkey_tail_p = __priv_p->txkey_head_p; \ +CYG_MACRO_END +#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +# define ENET_RESET_BD_TX(__priv_p) \ +CYG_MACRO_START \ + __priv_p->txbd_head_p = __priv_p->txbd_pool_p + __priv_p->txbd_num - 1; \ + __priv_p->txbd_tail_p = __priv_p->txbd_head_p; \ +CYG_MACRO_END +#endif // + +#define ENET_INIT_BD_TX(__priv_p) ENET_RESET_BD_TX(__priv_p) + + +// Initialize a buffer descriptor -------------------------------------------- +// Generic function for initialization of a buffer descriptor + +static void +enet_init_bd(enet_bd_t *bd_p, cyg_uint32 bd_size, cyg_uint16 cntrl_init, + cyg_uint16 cntrl_wrap, cyg_uint8 *buff_p, cyg_uint32 buf_size +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + , cyg_uint32 *key_p +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + , cyg_uint32 ebd_ctrl +#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + ) +{ + enet_bd_t *bd_end; + debug1_printf("ENET: Inint_bd:\n"); + for(bd_end = bd_p + bd_size; bd_p < bd_end; bd_p++){ + debug1_printf("ENET: %p -> ", bd_p); + bd_p->ctrl = cntrl_init; + bd_p->len = 0; + bd_p->buffer_p = (cyg_uint8 *)CYG_CPU_TO_BE32((cyg_uint32)buff_p); + debug1_printf("cntrl=0x%04x len=%d buffer=%p[%p]", + bd_p->ctrl, bd_p->len, bd_p->buffer_p, buff_p); + buff_p += (buf_size); +#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + bd_p->ebd_ctrl = ebd_ctrl; + bd_p->hlen_proto = 0; + bd_p->payload_csum = 0; + bd_p->bdu = 0; + bd_p->timestamp_1588 = 0; + bd_p->reserved[0] = 0; + bd_p->reserved[1] = 0; +#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + if(key_p) { + *key_p = 0; + debug1_printf(" tx_key[%p]=%x", key_p, *key_p); + key_p++; + } +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + debug1_printf("\n"); + } + debug1_printf("ENET: end, bd_p=%p\n", bd_p); + bd_p--; + bd_p->ctrl |= cntrl_wrap; + debug1_printf("ENET: %p -> ", bd_p); + debug1_printf("cntrl=0x%04x len=%d buffer=%p\n", + bd_p->ctrl, bd_p->len, bd_p->buffer_p); +} + + +// Initialize buffer descriptors and buffers -------------------------------- +// + +static void +enet_init_buffers(freescale_enet_priv_t *enet_priv_p) +{ + CYG_ADDRWORD enet_base = enet_priv_p->enet_base; + + // Initialize receive descriptor ring + enet_priv_p->rxbd_p = enet_priv_p->rxbd_pool_p; + enet_init_bd(enet_priv_p->rxbd_pool_p, enet_priv_p->rxbd_num, + ENET_RXBD_E, ENET_RXBD_W, enet_priv_p->rxbuf_p, enet_priv_p->rxbuf_size +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + , NULL +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + , ENET_RXBD_INT +#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + ); + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_RDSR, + (cyg_uint32)enet_priv_p->rxbd_pool_p); + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_MRBR, enet_priv_p->rxbuf_size); + + // Initialize transmit descriptor ring + ENET_INIT_BD_TX(enet_priv_p); +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + enet_init_bd(enet_priv_p->txbd_pool_p, enet_priv_p->txbd_num, 0, ENET_TXBD_W, + NULL, 0, enet_priv_p->txkey_pool_p +#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + enet_init_bd(enet_priv_p->txbd_pool_p, enet_priv_p->txbd_num, 0, ENET_TXBD_W, + enet_priv_p->txbuf_p, enet_priv_p->txbuf_size +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + , ENET_TXBD_INT +# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_IP + | ENET_TXBD_IINS +# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_IP +# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_PROT + | ENET_TXBD_PINS +# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_TX_PROT +# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_1588 + | ENET_TXBD_TS +# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_1588 +#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + ); + + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_TDSR, + (cyg_uint32)enet_priv_p->txbd_pool_p); + enet_priv_p->txbd_tail_p = enet_priv_p->txbd_head_p; +#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_TFWR, + FREESCALE_ENET_TFWR_STRFWD_M); +#else //CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_TFWR, + FREESCALE_ENET_TFWR_TFWR(FREESCALE_ENET_TFWR_TFWR_192)); +#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + +} + +// Hardware initialization functions ========================================= + +// Configure ENET (R)MII pins ------------------------------------------------ +// Note: pin acces uses services from HAL. + +static void +enet_cfg_pins(freescale_enet_priv_t *enet_priv_p) +{ + const cyg_uint32 *pin_p; + + if((pin_p = enet_priv_p->pins_p)) { + for(; + pin_p < enet_priv_p->pins_p + enet_priv_p->pins_n; + CYGHWR_IO_FREESCALE_ENET_PIN(*pin_p++)); + } +} + +// Set a MAC address match. ------------------------------------------------- +// Packets received which match this address will be passed on. + +void +enet_set_mac_addr (CYG_ADDRWORD enet_base, const cyg_uint8 *addr_p) +{ + cyg_uint32 regval; + + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_PALR, + (cyg_uint32)((addr_p[0]<<24) + (addr_p[1]<<16) + + (addr_p[2]<<8) + addr_p[3])); + HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_PAUR, regval); + regval &= 0x0000ffff; + regval |= (cyg_uint32)((addr_p[4]<<24) + (addr_p[5]<<16)); + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_PAUR, regval); +} + + +// Initialize ENET device ---------------------------------------------------- +// + +static bool +enet_eth_init(struct cyg_netdevtab_entry *tab) +{ + struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance; + freescale_enet_priv_t *enet_priv_p = + (freescale_enet_priv_t *) sc->driver_private; + CYG_ADDRWORD enet_base = enet_priv_p->enet_base; + + enet_cfg_pins(enet_priv_p); + + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIMR, 0); + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR, 0xFFFFFFFF); + + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_ECR, + FREESCALE_ENET_ECR_RESET_M); + ENET_WAIT_US(FREESCALE_ENET_RESET_DELAY); + +#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_ECR, + FREESCALE_ENET_ECR_EN1588_M); +#else // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_ECR, 0); +#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + +#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED + cyg_drv_interrupt_create(enet_priv_p->rx_intr_vector, + enet_priv_p->rx_intr_prio, + (cyg_addrword_t)sc, + (cyg_ISR_t *)enet_eth_isr, + (cyg_DSR_t *)eth_drv_dsr, + &enet_priv_p->rx_interrupt_handle, + &enet_priv_p->rx_interrupt); + cyg_drv_interrupt_attach(enet_priv_p->rx_interrupt_handle); +# ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + cyg_drv_interrupt_create(enet_priv_p->tx_intr_vector, + enet_priv_p->tx_intr_prio, + (cyg_addrword_t)sc, + (cyg_ISR_t *)enet_eth_isr, + (cyg_DSR_t *)eth_drv_dsr, + &enet_priv_p->tx_interrupt_handle, + &enet_priv_p->tx_interrupt); + cyg_drv_interrupt_attach(enet_priv_p->tx_interrupt_handle); +# endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED + + // Set the source address for the controller + enet_set_mac_addr (enet_base, enet_priv_p->enaddr); + + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_IALR, 0x00000000); + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_IAUR, 0x00000000); + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_GALR, 0x00000000); + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_GAUR, 0x00000000); + + if(eth_phy_init_wait(enet_priv_p->phy_p, FREESCALE_ENET_PHY_INIT_TOUT)) { + // Initialize upper level driver. + (sc->funs->eth_drv->init)(sc, (cyg_uint8 *)enet_priv_p->enaddr); + return true; + } else { + return false; + } +} + +// Start ENET ---------------------------------------------------------------- + +static void +enet_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr_p, int flags) +{ + freescale_enet_priv_t *enet_priv_p = + (freescale_enet_priv_t *)sc->driver_private; + CYG_ADDRWORD enet_base = enet_priv_p->enet_base; + cyg_uint32 enet_reg; + + + HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_ECR, enet_reg); + if(!(enet_reg & FREESCALE_ENET_ECR_ETHEREN_M)) { + // Set Speed, duplex, etc. + enet_eth_phy_set(enet_priv_p); + + // Init Buffers + enet_init_buffers(enet_priv_p); + + // Enable the device! + + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR, + FREESCALE_ENET_EIR_MASK_M); +#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED + cyg_drv_interrupt_unmask(enet_priv_p->rx_intr_vector); +# ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + cyg_drv_interrupt_unmask(enet_priv_p->tx_intr_vector); +# endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIMR, + FREESCALE_ENET_EIMR_MASK_M); +#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED + + // Flow controll + if(enet_priv_p->flags & CYGSEM_ETH_FREESCALE_ENET0_RCR_FCE) { + debug1_printf("ENET: Flow control: RCR enabled.\n"); + HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_RCR, enet_reg); + enet_reg |= FREESCALE_ENET_RCR_FCE_M; + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_RCR, enet_reg); + } else { + debug1_printf("ENET: Flow control: RCR disabled.\n"); + HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_RCR, enet_reg); + enet_reg &= ~FREESCALE_ENET_RCR_FCE_M; + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_RCR, enet_reg); + } + debug1_printf("ENET: Flow control: RCR 0x%08x.\n", enet_reg); + + // Flow controll pause duration + HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_OPD, enet_reg); + enet_reg &= 0xffff000; + enet_reg |= enet_priv_p->fc_pause; + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_OPD, enet_reg); + debug1_printf("ENET: Flow control: pause %08x\n", enet_reg); + + // Enable ENET... + HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_ECR, enet_reg); + enet_reg |= FREESCALE_ENET_ECR_ETHEREN_M; + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_ECR, enet_reg); + // ...and wait a bit to settle + ENET_WAIT_US(FREESCALE_ENET_ENABLE_DELAY); + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_RDAR, + FREESCALE_ENET_RDAR_RDAR_M); +#ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS + FREESCALE_ENET_STATS_INIT(&enet_priv_p->enet_stats); +#endif // CYGOPT_DEVS_ETH_FREESCALE_ENET_STATS + } +} + +// Stop ENET ---------------------------------------------------------------- + +static void +enet_eth_stop(struct eth_drv_sc *sc) +{ + freescale_enet_priv_t *enet_priv_p = + (freescale_enet_priv_t *)sc->driver_private; + CYG_ADDRWORD enet_base = enet_priv_p->enet_base; + cyg_uint32 ecr; +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + enet_bd_t *tx_bd_head_p, *tx_bd_tail_p; + cyg_uint32 *tx_key_tail_p; + void (*tx_done)(struct eth_drv_sc *sc, CYG_ADDRESS key, int status); +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + +#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED + cyg_drv_interrupt_mask(enet_priv_p->rx_intr_vector); +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + cyg_drv_interrupt_mask(enet_priv_p->tx_intr_vector); +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIMR, 0x00000000); +#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR, + FREESCALE_ENET_EIR_MASK_M); + + HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_ECR, ecr); + ecr &= ~FREESCALE_ENET_ECR_ETHEREN_M; + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_ECR, ecr); + +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + // Free eventual unsent buffers. + tx_bd_head_p = enet_priv_p->txbd_head_p; + tx_bd_tail_p = enet_priv_p->txbd_tail_p; + tx_key_tail_p = enet_priv_p->txkey_tail_p; + tx_done = sc->funs->eth_drv->tx_done; + while(tx_bd_tail_p != tx_bd_head_p) { + ENET_TXBD_FREE(tx_bd_tail_p, enet_priv_p); + if(tx_bd_tail_p->ctrl & ENET_TXKEY_FLAG) { + tx_bd_tail_p->ctrl &= ~ENET_TXKEY_FLAG; + (tx_done)(sc, *tx_key_tail_p, 0); + *tx_key_tail_p = 0; + ENET_TXKEY_NEXT(tx_key_tail_p, enet_priv_p); + } + } + enet_priv_p->txbd_tail_p = tx_bd_tail_p; + enet_priv_p->txkey_tail_p = tx_key_tail_p; +#endif //CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +} + +// ENET processing functions ================================================= +// ENET control function ----------------------------------------------------- + +static int +enet_eth_control(struct eth_drv_sc *sc, unsigned long key, + void *data_p, int length) +{ + freescale_enet_priv_t *enet_priv_p = + (freescale_enet_priv_t *)sc->driver_private; + CYG_ADDRWORD enet_base = enet_priv_p->enet_base; + int retcode = 1; + + switch (key) { + case ETH_DRV_SET_MAC_ADDRESS: + if(length >= ETHER_ADDR_LEN) { + enet_eth_stop(sc); + enet_set_mac_addr(enet_base, (cyg_uint8 *)data_p); + enet_eth_start(sc, (cyg_uint8 *)data_p, 0); + retcode = 0; + } + break; + default: + break; + } + return retcode; +} + +// Can send ------------------------------------------------------------------ +// NoCopy: returns number of free Tx buffer descriprors +// Copying: returns 1 if there is at least 1 free Tx buffer descriotor + +static int +enet_eth_can_send(struct eth_drv_sc *sc) +{ + freescale_enet_priv_t *enet_priv_p = + (freescale_enet_priv_t *)sc->driver_private; +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + cyg_int32 avail = enet_priv_p->txbd_avail; +# if DEBUG_ENET >= 2 + if(avail < enet_priv_p->txbd_can_send_min) + diag_printf("ENET can_send: available = %d buffer descriptors.\n", + avail); +# endif // DEBUG_ENET + return (int) avail < enet_priv_p->txbd_can_send_min ? 0 : avail; +#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + enet_bd_t *tx_bd_p = enet_priv_p->txbd_head_p; + + ENET_TXBD_NEXT(tx_bd_p, enet_priv_p); + debug2_printf("ENET: can send: %d\n", tx_bd_p->ctrl & ENET_TXBD_R); + if(!(tx_bd_p->ctrl & ENET_TXBD_R)) + return 1; + else + return 0; +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +} + +// Send ---------------------------------------------------------------------- +// +// Trigger ENET for sending -------------------------------------------------- + +static void inline +enet_eth_send_trigger(freescale_enet_priv_t *enet_priv_p) +{ + // Inform ENET that transmit descriptor(s) is(are) available. + HAL_WRITE_UINT32(enet_priv_p->enet_base + FREESCALE_ENET_REG_TDAR, + FREESCALE_ENET_TDAR_TDAR_M); +} + +#define ENET_ETH_SEND_RDY(__bd_p) \ +CYG_MACRO_START \ + cyg_uint16 ctrl; \ + ctrl = __bd_p->ctrl & ENET_TXBD_W; \ + ctrl |= ENET_TXBD_R | ENET_TXBD_TC; \ + __bd_p->ctrl = ctrl; \ +CYG_MACRO_END + +// There different send functios for NoCopy and Copying driver options. +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + +// Send - NoCopy version. +// This version does not copy SG buffer but writes SG buf pointer +// in ENET BD. +// Note: ENET requires that buf pointer is evenly divisible by 8. + +static void +enet_eth_send_nocopy(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, + int sg_len, int total_len, unsigned long key) +{ + freescale_enet_priv_t *enet_priv_p = + (freescale_enet_priv_t *)sc->driver_private; + enet_bd_t *tx_bd_p; + enet_bd_t *tx_bd0_p=NULL; + cyg_uint32 *tx_key_p; + struct eth_drv_sg *sg_list_z; + + if(enet_priv_p->txbd_avail < sg_len) { + debug1_printf("ENET Send: Error! sg_len %d avail %d\n", sg_len, enet_priv_p->txbd_avail); + (sc->funs->eth_drv->tx_done)(sc, key, 0); + return; + } +#if DEBUG_ENET >= 2 + if(enet_priv_p->txbd_avail < 2) { + diag_printf("ENET Send: sg_len %d avail %d\n", sg_len, enet_priv_p->txbd_avail); + } +#endif + tx_bd_p=enet_priv_p->txbd_head_p; + for(sg_list_z=sg_list+sg_len; sg_listbuffer_p=(cyg_uint8 *)CYG_CPU_TO_BE32(sg_list->buf); + tx_bd_p->len=CYG_CPU_TO_BE16(sg_list->len); + if(tx_bd0_p) { + ENET_ETH_SEND_RDY(tx_bd_p); + } else { + tx_bd0_p=tx_bd_p; + } +# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + tx_bd_p->bdu = 0; +# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + } + ENET_ETH_SEND_RDY(tx_bd0_p); + tx_bd_p->ctrl |= (ENET_TXBD_L | ENET_TXKEY_FLAG); // is last and has key + tx_key_p=enet_priv_p->txkey_head_p; + *tx_key_p = key; + ENET_TXKEY_NEXT(tx_key_p, enet_priv_p); + enet_priv_p->txkey_head_p = tx_key_p; + enet_priv_p->txbd_head_p = tx_bd_p; + enet_eth_send_trigger(enet_priv_p); +} + +#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + +// Send - Copying version. +// This version physically copies SG buf(s) in private ENET buffer(s). +// This version is usefull if upper layer stack does not guarantee +// buffers aligned to 8 byte boundary. +// Also requires no Tx interrupts. + +static void +enet_eth_send_copying(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, + int sg_len, int total_len, unsigned long key) +{ + freescale_enet_priv_t *enet_priv_p = + (freescale_enet_priv_t *)sc->driver_private; + enet_bd_t *tx_bd_p; + enet_bd_t *tx_bd_save_p; + struct eth_drv_sg *sg_list_z; + cyg_uint16 ctrl; + + tx_bd_p=enet_priv_p->txbd_head_p; + debug2_printf("ENET Send: sg_len %d\n", sg_len); + for(sg_list_z=sg_list+sg_len; sg_listctrl & ENET_TXBD_R) { + debug2_printf("ENET: Send underrun, waiting for free buf.\n"); + enet_eth_send_trigger(enet_priv_p); + ENET_ETH_WAIT(1); + if(tx_bd_p->ctrl & ENET_TXBD_R) { + ENET_ETH_WAIT(1); + if(tx_bd_p->ctrl & ENET_TXBD_R) { + debug2_printf("ENET Send: aborting packet.\n"); + enet_priv_p->txbd_head_p = tx_bd_save_p; + (sc->funs->eth_drv->tx_done)(sc, key, 0); + return; + } + } + } + + memcpy((cyg_uint8 *)CYG_CPU_TO_BE32((cyg_uint32)tx_bd_p->buffer_p), + (void *)sg_list->buf, sg_list->len); + tx_bd_p->len=CYG_CPU_TO_BE16(sg_list->len); + ctrl = tx_bd_p->ctrl & ENET_TXBD_W; + ctrl |= ENET_TXBD_R | ENET_TXBD_TC; + tx_bd_p->ctrl = ctrl; +# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + tx_bd_p->bdu = 0; +# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + } + tx_bd_p->ctrl |= (ENET_TXBD_L); // is last + enet_priv_p->txbd_head_p = tx_bd_p; + debug2_printf("ENET Send: trigger.\n"); + enet_eth_send_trigger(enet_priv_p); + (sc->funs->eth_drv->tx_done)(sc, key, 0); +} + +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + +// Receive ------------------------------------------------------------------ + +static void +enet_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len) +{ + freescale_enet_priv_t *enet_priv_p = + (freescale_enet_priv_t *)sc->driver_private; + cyg_uint8 *rxbuffer_p; + struct eth_drv_sg *sg_list_z; + enet_bd_t *rx_bd_p; + + rx_bd_p=enet_priv_p->rxbd_p; + rxbuffer_p=(cyg_uint8 *)CYG_CPU_TO_BE32((cyg_uint32)rx_bd_p->buffer_p); + for(sg_list_z=sg_list+sg_len; sg_listbuf) { + memcpy((void *)sg_list->buf, rxbuffer_p, sg_list->len); + rxbuffer_p+=sg_list->len; + } + } +} + +// Reception error check ----------------------------------------------------- + +static inline bool +enet_eth_recv_error(enet_bd_t *rx_bd_p, freescale_enet_priv_t *enet_priv_p) +{ + bool errcod=false; + cyg_uint32 ctrl = rx_bd_p->ctrl; + + if(ctrl & ENET_RXBD_TR) { + ENET_STAT_PRINTF("ENET: Ethernet trunc error ctrl = 0x%04x\n", + rx_bd_p->ctrl); + FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, TR); + errcod = true; + } else if(ctrl & ENET_RXBD_L) { + if(ctrl & (ENET_RXBD_CR | ENET_RXBD_OV | ENET_RXBD_LG | ENET_RXBD_NO)) + { + // Ethernet fault processing + ENET_STAT_PRINTF("ENET: Ethernet error ctrl = 0x%04x => ", + rx_bd_p->ctrl); + FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, CR); + FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, OV); + FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, LG); + FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, NO); + ENET_STAT_PRINTF("\n"); + errcod = true; + } + +#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + ctrl = rx_bd_p->ebd_ctrl; + if(ctrl & (ENET_RXBD_ME | ENET_RXBD_PE | ENET_RXBD_CE | ENET_RXBD_FRAG +# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_IP + | ENET_RXBD_ICE +# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_PROT + | ENET_RXBD_PCR +# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_PROT +# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_ACCEL_RX_IP + )) + { + cyg_uint32 head_len = (rx_bd_p->hlen_proto >> 11) & 0x1f; + if(head_len || (ctrl & (ENET_RXBD_ME | ENET_RXBD_PE | + ENET_RXBD_CE | ENET_RXBD_FRAG ))) + { + // Enhanced bd fault processing + ENET_STAT_PRINTF("ENET: Enhanced bd error ctrl = 0x%08x => ", + rx_bd_p->ebd_ctrl); + FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, ME); + FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, PE); + FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, CE); + FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, FRAG); + FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, ICE); + FREESCALE_ENET_STAT_DO(ctrl, enet_priv_p, PCR); + ENET_STAT_PRINTF("\n"); + ENET_STAT_PRINTF("ENET: HeadLen=%d[0x%x] Proto=%d[0x%x]\n", + head_len, head_len, + rx_bd_p->hlen_proto & 0xff, + rx_bd_p->hlen_proto & 0xff); + errcod = true; + } + } +#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + } + if(errcod) { +#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + debug2_printf("ENET: Bad msg ctrl = 0x%04x ebd_ctrl = 0x%08x\n", + rx_bd_p->ctrl, rx_bd_p->ebd_ctrl); +#else // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + debug2_printf("ENET: Bad msg ctrl = 0x%04x\n", rx_bd_p->ctrl); +#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + } + return errcod; +} + +// Deliver ------------------------------------------------------------------- +#define ENET_DELIVER_NEED_SERVICE_RX FREESCALE_ENET_EIMR_RXF_M +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +# define ENET_DELIVER_NEED_SERVICE_TX FREESCALE_ENET_EIMR_TXF_M +# define ENET_DELIVER_NEED_SERVICE (ENET_DELIVER_NEED_SERVICE_RX | \ + ENET_DELIVER_NEED_SERVICE_TX) +#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY +# define ENET_DELIVER_NEED_SERVICE (ENET_DELIVER_NEED_SERVICE_RX) +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + +#define ENET_DELIVER_NEED_SERVICE_SET(__var,__rt) \ +CYG_MACRO_START \ + __var |= ENET_DELIVER_NEED_SERVICE_##__rt; \ +CYG_MACRO_END + +#define ENET_DELIVER_NEED_SERVICE_CLEAR(__var,__rt) \ +CYG_MACRO_START \ + __var &= ~ENET_DELIVER_NEED_SERVICE_##__rt; \ +CYG_MACRO_END + +// There different deliver functios for NoCopy and Copying driver options. + +#ifdef CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + +// Deliver - NoCopy varsion +// This deliver vresion is compatible with NoCopy send version. + +static void +enet_eth_deliver_nocopy(struct eth_drv_sc * sc) +{ + freescale_enet_priv_t *enet_priv_p = + (freescale_enet_priv_t *)sc->driver_private; + CYG_ADDRWORD enet_base = enet_priv_p->enet_base; + enet_bd_t *tx_bd_tail_p, *tx_bd_tail_save_p; + cyg_uint32 *tx_key_tail_p; + enet_bd_t *rx_bd_p; + cyg_uint16 ctrl; + cyg_uint32 eir; + cyg_uint32 need_service; + void (*recv)(struct eth_drv_sc *sc, int total_len); + void (*tx_done)(struct eth_drv_sc *sc, CYG_ADDRESS key, int status); + + recv = sc->funs->eth_drv->recv; + tx_done = sc->funs->eth_drv->tx_done; + + tx_bd_tail_p = enet_priv_p->txbd_tail_p; + HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir); + need_service = ENET_DELIVER_NEED_SERVICE; + do { + //Clear all ENET Interrupt events + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR, + FREESCALE_ENET_EIR_MASK_M); + if(eir & FREESCALE_ENET_EIR_ERROR) { + debug2_printf("ENET: EIR Error 0x%08x\n", + eir & FREESCALE_ENET_EIR_ERROR); + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR, + FREESCALE_ENET_EIR_ERROR); + } + + // RX Event processing + if(need_service & ENET_DELIVER_NEED_SERVICE_RX) { + rx_bd_p=enet_priv_p->rxbd_p; + ctrl=rx_bd_p->ctrl; + if(ctrl & ENET_RXBD_E) { + ENET_DELIVER_NEED_SERVICE_CLEAR(need_service, RX); + } else { + if(!enet_eth_recv_error(rx_bd_p, enet_priv_p)) { + (recv)(sc, CYG_CPU_TO_BE16(rx_bd_p->len)); + } + ctrl &= ENET_RXBD_W; + ctrl |= ENET_RXBD_E; + rx_bd_p->ctrl = ctrl; +# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + rx_bd_p->bdu = 0; +# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + // Inform ENET that free Rx buffers have beeen freed. + HAL_WRITE_UINT32(enet_priv_p->enet_base + + FREESCALE_ENET_REG_RDAR, + FREESCALE_ENET_RDAR_RDAR_M); + + ENET_RXBD_NEXT(rx_bd_p, enet_priv_p); + enet_priv_p->rxbd_p=rx_bd_p; + + if(rx_bd_p->ctrl & ENET_RXBD_E) { + ENET_DELIVER_NEED_SERVICE_CLEAR(need_service, RX); + } + } + } + + // TX Event processing + if(need_service & ENET_DELIVER_NEED_SERVICE_TX) { + if(enet_priv_p->txbd_num == enet_priv_p->txbd_avail) { + debug2_printf("ENET: Tx nothing to send\n"); + ENET_DELIVER_NEED_SERVICE_CLEAR(need_service, TX); + } else { + tx_bd_tail_save_p=tx_bd_tail_p; + ENET_TXBD_TRYFREE(tx_bd_tail_p, enet_priv_p); + ctrl = tx_bd_tail_p->ctrl; + if(ctrl & ENET_TXBD_R){ + tx_bd_tail_p=tx_bd_tail_save_p; + ENET_DELIVER_NEED_SERVICE_CLEAR(need_service, TX); + } else { + ENET_BD_AVAIL_INC(enet_priv_p); + if(ctrl & ENET_TXKEY_FLAG){ + ctrl &= ~ENET_TXKEY_FLAG; + tx_bd_tail_p->ctrl = ctrl; + tx_key_tail_p = enet_priv_p->txkey_tail_p; + (tx_done)(sc, *tx_key_tail_p, 0); + ENET_TXKEY_NEXT(tx_key_tail_p, enet_priv_p); + enet_priv_p->txkey_tail_p = tx_key_tail_p; + } + if(enet_priv_p->txbd_avail == enet_priv_p->txbd_num) { + debug3_printf("ENET: Tx All sent.\n"); + ENET_DELIVER_NEED_SERVICE_CLEAR(need_service, TX); + } + } + } + } + + // Check if Interrupt had arrived in meantime + HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir); + need_service |= eir & ENET_DELIVER_NEED_SERVICE; + } while(need_service); + enet_priv_p->txbd_tail_p = tx_bd_tail_p; +# ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED +# ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK + //Unmask all ENET interrupts + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIMR, + FREESCALE_ENET_EIMR_MASK_M); +# else // CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK + cyg_drv_interrupt_unmask(enet_priv_p->tx_intr_vector); + cyg_drv_interrupt_unmask(enet_priv_p->rx_intr_vector); +# endif // CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK +# endif //CYGINT_IO_ETH_INT_SUPPORT_REQUIRED +} + +#else // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + +// Deliver - Copying varsion +// This deliver vresion is compatible with Copying send version. + +static void +enet_eth_deliver_copying(struct eth_drv_sc * sc) +{ + freescale_enet_priv_t *enet_priv_p = + (freescale_enet_priv_t *)sc->driver_private; + CYG_ADDRWORD enet_base = enet_priv_p->enet_base; + enet_bd_t *rx_bd_p; + cyg_uint16 ctrl; + cyg_uint32 eir; + cyg_uint32 need_service; + void (*recv)(struct eth_drv_sc *sc, int total_len); + + recv = sc->funs->eth_drv->recv; + HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir); + need_service = ENET_DELIVER_NEED_SERVICE; + do { + //Clear all ENET Interrupt events + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR, + FREESCALE_ENET_EIR_MASK_M); + if(eir & FREESCALE_ENET_EIR_ERROR) { + debug2_printf("ENET: EIR Error 0x%08x\n", + eir & FREESCALE_ENET_EIR_ERROR); + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR, + FREESCALE_ENET_EIR_ERROR); + } + + // RX Event processing + if(need_service & ENET_DELIVER_NEED_SERVICE_RX) { + rx_bd_p=enet_priv_p->rxbd_p; + ctrl=rx_bd_p->ctrl; + if(ctrl & ENET_RXBD_E) { + ENET_DELIVER_NEED_SERVICE_CLEAR(need_service, RX); + } else { + if(!enet_eth_recv_error(rx_bd_p, enet_priv_p)) { + (recv)(sc, CYG_CPU_TO_BE16(rx_bd_p->len)); + } + ctrl &= ENET_RXBD_W; + ctrl |= ENET_RXBD_E; + rx_bd_p->ctrl = ctrl; +# ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + rx_bd_p->bdu = 0; +# endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_BD_ENHANCED + // Inform ENET that free Rx buffers have beeen freed. + HAL_WRITE_UINT32(enet_priv_p->enet_base + + FREESCALE_ENET_REG_RDAR, + FREESCALE_ENET_RDAR_RDAR_M); + + ENET_RXBD_NEXT(rx_bd_p, enet_priv_p); + enet_priv_p->rxbd_p=rx_bd_p; + + if(rx_bd_p->ctrl & ENET_RXBD_E) { + ENET_DELIVER_NEED_SERVICE_CLEAR(need_service, RX); + } + } + } + + // Check if Interrupt had arrived in meantime + HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir); + need_service |= eir & ENET_DELIVER_NEED_SERVICE; + } while(need_service); + +# ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED +# ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK + //Unmask all ENET interrupts + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIMR, + FREESCALE_ENET_EIMR_MASK_M); +# else // CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK +// cyg_drv_interrupt_unmask(enet_priv_p->tx_intr_vector); + cyg_drv_interrupt_unmask(enet_priv_p->rx_intr_vector); +# endif // CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK +# endif //CYGINT_IO_ETH_INT_SUPPORT_REQUIRED +} + +#endif // CYGOPT_ETH_FREESCALE_ENET_TX_NOCOPY + +// Poll --------------------------------------------------------------------- +static void +enet_eth_poll(struct eth_drv_sc *sc) +{ + enet_eth_deliver(sc); +} + +// ISR ---------------------------------------------------------------------- +#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED +static cyg_uint32 +enet_eth_isr(cyg_vector_t vector, cyg_addrword_t data) +{ +#ifdef CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK + struct eth_drv_sc *sc = (struct eth_drv_sc *)data; + freescale_enet_priv_t *enet_priv_p = + (freescale_enet_priv_t *)sc->driver_private; + CYG_ADDRWORD enet_base = enet_priv_p->enet_base; + + //Mask ENET Interrupts + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIMR, 0x00000000); +#else // CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK + cyg_drv_interrupt_mask(vector); +#endif // CYGOPT_DEVS_ETH_FREESCALE_ENET_IRQ_FASTMASK + cyg_drv_interrupt_acknowledge(vector); + + return CYG_ISR_CALL_DSR; +} + +#endif //CYGINT_IO_ETH_INT_SUPPORT_REQUIRED + +static int +enet_eth_int_vector(struct eth_drv_sc *sc) +{ + return CYGNUM_FREESCALE_ENET0_RECEIVE_INT_VECTOR; +} + +// PHY related stuff ========================================================= +// MDIO interface + +// Polling based waiting function for MDIO transactions +static bool +freescale_enet_busywait_mii(CYG_ADDRWORD enet_base, cyg_uint32 counter) +{ + cyg_uint32 eir; + bool done=0; + + for(; counter; counter--) { + ENET_WAIT_US(2); + HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir); + if(eir & FREESCALE_ENET_EIR_MII_M) { + eir |= FREESCALE_ENET_EIR_MII_M; + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir); + done=1; + break; + } + } + return done; +} + +// Write a PHY register via the MDIO interface ------------------------------- + +static void +enet_write_phy(int reg_addr, int phy_addr, unsigned short data) +{ + CYG_ADDRWORD enet_base = enet0_eth0_priv.enet_base; + cyg_uint32 eir; + + HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir); + eir |= FREESCALE_ENET_EIR_MII_M; + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir); + + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_MMFR, + FREESCALE_ENET_MMFR_ST(01) | + FREESCALE_ENET_MMFR_OP(01) | + FREESCALE_ENET_MMFR_PA(phy_addr) | + FREESCALE_ENET_MMFR_RA(reg_addr) | + FREESCALE_ENET_MMFR_TA(02) | + FREESCALE_ENET_MMFR_DATA(data)); + freescale_enet_busywait_mii(enet_base, FREESCALE_ENET_MII_WRITE_TOUT); +} + +// Read a PHY register via the MDIO interface -------------------------------- + +static bool +enet_read_phy(int reg_addr, int phy_addr, unsigned short *data_p) +{ + bool done = 0; + volatile cyg_uint32 mmfr; + CYG_ADDRWORD enet_base = enet0_eth0_priv.enet_base; + cyg_uint32 eir; + + HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir); + eir |= FREESCALE_ENET_EIR_MII_M; + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_EIR, eir); + + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_MMFR, + FREESCALE_ENET_MMFR_ST(01) | + FREESCALE_ENET_MMFR_OP(02) | + FREESCALE_ENET_MMFR_PA(phy_addr) | + FREESCALE_ENET_MMFR_RA(reg_addr) | + FREESCALE_ENET_MMFR_TA(02)); + if((done = freescale_enet_busywait_mii(enet_base, + FREESCALE_ENET_MII_READ_TOUT))) { + HAL_READ_UINT32(enet_base + FREESCALE_ENET_REG_MMFR, mmfr); + *data_p = (unsigned short)(mmfr & FREESCALE_ENET_MMFR_DATA_M); + } + return done; +} + + +// PHY initialization functions ---------------------------------------------- +// Init ENET device for phy access ------------------------------------------- +// +static void +enet_init_phy(void) +{ + CYG_ADDRWORD enet_base = enet0_eth0_priv.enet_base; + cyg_uint32 mii_speed; + + mii_speed = (2 * CYGHWR_FREESCALE_ENET_MII_MDC_HAL_CLOCK / 5000000 + 1); + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_MSCR, + FREESCALE_ENET_MSCR_MII_SPEED(mii_speed) | + FREESCALE_ENET_MSCR_HOLDTIME(0) + ); +} + +// Set ENET device according to PHY stat ------------------------------------- +// +static void +enet_eth_phy_set(freescale_enet_priv_t *enet_priv_p) +{ + CYG_ADDRWORD enet_base = enet_priv_p->enet_base; + unsigned short phy_state = 0; + cyg_uint32 regval; + + phy_state=_eth_phy_state(enet_priv_p->phy_p); +#ifdef CYGSEM_DEVS_ETH_FREESCALE_ENET_PHY_RMII + regval = FREESCALE_ENET_RCR_MAX_FL(enet_priv_p->max_frame_len) + | FREESCALE_ENET_RCR_RMII_MODE_M | FREESCALE_ENET_RCR_MII_MODE_M; + if((phy_state & ETH_PHY_STAT_LINK) && !(phy_state & ETH_PHY_STAT_100MB)) { + // Operate in 10MB mode + regval |= FREESCALE_ENET_RCR_RMII_10T_M; + } + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_RCR, regval); +#else // CYGSEM_DEVS_ETH_FREESCALE_ENET_PHY_RMII + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_RCR, + FREESCALE_ENET_RCR_MAX_FL(enet_priv_p->max_frame_len) | + FREESCALE_ENET_RCR_MII_MODE_M); +#endif // CYGSEM_DEVS_ETH_FREESCALE_ENET_PHY_RMII + if(phy_state & ETH_PHY_STAT_FDX) { // Operate in full-duplex mode + HAL_WRITE_UINT32(enet_base + FREESCALE_ENET_REG_TCR, + FREESCALE_ENET_TCR_FDEN_M); + } +} + + +// PHY may need some start-up time ------------------------------------------- +// + +static bool +eth_phy_init_wait(eth_phy_access_t *phy_p, cyg_uint32 ms) +{ + cyg_uint32 cnt; + + for(cnt=0; cnt