From 9849e22d3bd6eac24721056b68a213b3363b00dc Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 16 Mar 2015 13:51:37 -0600 Subject: [PATCH] SAMV7: Quick'n'dirty port of the SAMA5D4 Ethernet MAC driver to the SAMV7. Still some unresovled issues with DCache handling --- configs/samv71-xult/README.txt | 243 ++++++++++++++++++++++ configs/samv71-xult/src/sam_ethernet.c | 272 +++++++++++++++++++++++++ configs/samv71-xult/src/samv71-xult.h | 27 ++- 3 files changed, 541 insertions(+), 1 deletion(-) create mode 100644 configs/samv71-xult/src/sam_ethernet.c diff --git a/configs/samv71-xult/README.txt b/configs/samv71-xult/README.txt index e012f2d417..1afa25013c 100644 --- a/configs/samv71-xult/README.txt +++ b/configs/samv71-xult/README.txt @@ -15,6 +15,7 @@ Contents - Automounter - LEDs and Buttons - AT24MAC402 Serial EEPROM + - Networking - Debugging - Configurations @@ -87,6 +88,11 @@ The BASIC nsh configuration is fully function (as desribed below under drivers will port easily from either the SAM3/4 or from the SAMA5Dx. So there is still plenty to be done. + 6. There has been a quick'n'dirty port of the SAMA5D4-EK Ethernet logic + for the SAMV71-XULT. There are still some cache-related issues to + be verified. No testing has yet been performed and so the driver should + be considered non-functional. + Serial Console ============== @@ -360,6 +366,243 @@ I2C address: of the A0, A1, and A3 pins on the part. On the SAMV71-XULT board, these are all pulled high so the full, 7-bit address is 0x5f. +Networking +========== + +KSZ8061RNBVA Connections +------------------------ + + ------ --------- --------- -------------------------- + SAMV71 SAMV71 Ethernet Shared functionality + Pin Function Function + ------ --------- --------- -------------------------- + PD00 GTXCK REF_CLK Shield + PD01 GTXEN TXEN + PD02 GTX0 TXD0 + PD03 GTX1 TXD1 + PD04 GRXDV CRS_DV Trace + PD05 GRX0 RXD0 Trace + PD06 GRX1 RXD1 Trace + PD07 GRXER RXER Trace + PD08 GMDC MDC Trace + PD09 GMDIO MDIO + PA19 GPIO INTERRUPT EXT1, Shield + PA29 GPIO SIGDET + PC10 GPIO RESET + ------ --------- --------- -------------------------- + +Selecting the GMAC peripheral +----------------------------- + + System Type -> SAMV7 Peripheral Support + CONFIG_SAMV7_EMAC0=y : Enable the GMAC peripheral (aka, EMAC0) + + System Type -> EMAC device driver options + CONFIG_SAMV7_EMAC0_NRXBUFFERS=16 : Set aside some RS and TX buffers + CONFIG_SAMV7_EMAC0_NTXBUFFERS=8 + CONFIG_SAMV7_EMAC0_RMII=y : The RMII interfaces is used on the board + CONFIG_SAMV7_EMAC0_AUTONEG=y : Use autonegotiation + CONFIG_SAMV7_EMAC0_PHYADDR=1 : KSZ8061 PHY is at address 1 + CONFIG_SAMV7_EMAC0_PHYSR=30 : Address of PHY status register on KSZ8061 + CONFIG_SAMV7_EMAC0_PHYSR_ALTCONFIG=y : Needed for KSZ8061 + CONFIG_SAMV7_EMAC0_PHYSR_ALTMODE=0x7 : " " " " " " + CONFIG_SAMV7_EMAC0_PHYSR_10HD=0x1 : " " " " " " + CONFIG_SAMV7_EMAC0_PHYSR_100HD=0x2 : " " " " " " + CONFIG_SAMV7_EMAC0_PHYSR_10FD=0x5 : " " " " " " + CONFIG_SAMV7_EMAC0_PHYSR_100FD=0x6 : " " " " " " + + PHY selection. Later in the configuration steps, you will need to select + the KSZ8061 PHY for EMAC (See below) + + Networking Support + CONFIG_NET=y : Enable Neworking + CONFIG_NET_SOCKOPTS=y : Enable socket operations + CONFIG_NET_ETH_MTU=562 : Maximum packet size (MTU) 1518 is more standard + CONFIG_NET_ETH_TCP_RECVWNDO=562 : Should be the same as CONFIG_NET_ETH_MTU + CONFIG_NET_ARP=y : ARP support should be enabled + CONFIG_NET_ARP_SEND=y : Use ARP to get peer address before sending + CONFIG_NET_TCP=y : Enable TCP/IP networking + CONFIG_NET_TCPBACKLOG=y : Support TCP/IP backlog + CONFIG_NET_TCP_READAHEAD=y : Enable TCP read-ahead buffering + CONFIG_NET_TCP_WRITE_BUFFERS=y : Enable TCP write buffering + CONFIG_NET_UDP=y : Enable UDP networking + CONFIG_NET_BROADCAST=y : Support UDP broadcase packets + CONFIG_NET_ICMP=y : Enable ICMP networking + CONFIG_NET_ICMP_PING=y : Needed for NSH ping command + : Defaults should be okay for other options + Device drivers -> Network Device/PHY Support + CONFIG_NETDEVICES=y : Enabled PHY selection + CONFIG_ETH0_PHY_KSZ8061=y : Select the KSZ8061 PHY used with EMAC0 + + Application Configuration -> Network Utilities + CONFIG_NETUTILS_DNSCLIENT=y : Enable host address resolution + CONFIG_NETUTILS_TELNETD=y : Enable the Telnet daemon + CONFIG_NETUTILS_TFTPC=y : Enable TFTP data file transfers for get and put commands + CONFIG_NETUTILS_NETLIB=y : Network library support is needed + CONFIG_NETUTILS_WEBCLIENT=y : Needed for wget support + : Defaults should be okay for other options + Application Configuration -> NSH Library + CONFIG_NSH_TELNET=y : Enable NSH session via Telnet + CONFIG_NSH_IPADDR=0x0a000002 : Select an IP address + CONFIG_NSH_DRIPADDR=0x0a000001 : IP address of gateway/host PC + CONFIG_NSH_NETMASK=0xffffff00 : Netmask + CONFIG_NSH_NOMAC=y : Need to make up a bogus MAC address + : Defaults should be okay for other options + +Using the network with NSH +-------------------------- + +So what can you do with this networking support? First you see that +NSH has several new network related commands: + + ifconfig, ifdown, ifup: Commands to help manage your network + get and put: TFTP file transfers + wget: HTML file transfers + ping: Check for access to peers on the network + Telnet console: You can access the NSH remotely via telnet. + +You can also enable other add on features like full FTP or a Web +Server or XML RPC and others. There are also other features that +you can enable like DHCP client (or server) or network name +resolution. + +By default, the IP address of the SAMA4D4-EK will be 10.0.0.2 and +it will assume that your host is the gateway and has the IP address +10.0.0.1. + + nsh> ifconfig + eth0 HWaddr 00:e0:de:ad:be:ef at UP + IPaddr:10.0.0.2 DRaddr:10.0.0.1 Mask:255.255.255.0 + +You can use ping to test for connectivity to the host (Careful, +Window firewalls usually block ping-related ICMP traffic). On the +target side, you can: + + nsh> ping 10.0.0.1 + PING 10.0.0.1 56 bytes of data + 56 bytes from 10.0.0.1: icmp_seq=1 time=0 ms + 56 bytes from 10.0.0.1: icmp_seq=2 time=0 ms + 56 bytes from 10.0.0.1: icmp_seq=3 time=0 ms + 56 bytes from 10.0.0.1: icmp_seq=4 time=0 ms + 56 bytes from 10.0.0.1: icmp_seq=5 time=0 ms + 56 bytes from 10.0.0.1: icmp_seq=6 time=0 ms + 56 bytes from 10.0.0.1: icmp_seq=7 time=0 ms + 56 bytes from 10.0.0.1: icmp_seq=8 time=0 ms + 56 bytes from 10.0.0.1: icmp_seq=9 time=0 ms + 56 bytes from 10.0.0.1: icmp_seq=10 time=0 ms + 10 packets transmitted, 10 received, 0% packet loss, time 10100 ms + +NOTE: In this configuration is is normal to have packet loss > 0% +the first time you ping due to the default handling of the ARP +table. + +On the host side, you should also be able to ping the SAMA4D4-EK: + + $ ping 10.0.0.2 + +You can also log into the NSH from the host PC like this: + + $ telnet 10.0.0.2 + Trying 10.0.0.2... + Connected to 10.0.0.2. + Escape character is '^]'. + sh_telnetmain: Session [3] Started + + NuttShell (NSH) NuttX-7.9 + nsh> help + help usage: help [-v] [] + + [ echo ifconfig mkdir mw sleep + ? exec ifdown mkfatfs ping test + cat exit ifup mkfifo ps umount + cp free kill mkrd put usleep + cmp get losetup mh rm wget + dd help ls mount rmdir xd + df hexdump mb mv sh + + Builtin Apps: + nsh> + +NOTE: If you enable this feature, you experience a delay on booting. +That is because the start-up logic waits for the network connection +to be established before starting NuttX. In a real application, you +would probably want to do the network bringup on a separate thread +so that access to the NSH prompt is not delayed. + +This delay will be especially long if the board is not connected to +a network. On the order of a minute! You will probably think that +NuttX has crashed! And then, when it finally does come up, the +network will not be available. + +Network Initialization Thread +----------------------------- +There is a configuration option enabled by CONFIG_NSH_NETINIT_THREAD +that will do the NSH network bring-up asynchronously in parallel on +a separate thread. This eliminates the (visible) networking delay +altogether. This networking initialization feature by itself has +some limitations: + + - If no network is connected, the network bring-up will fail and + the network initialization thread will simply exit. There are no + retries and no mechanism to know if the network initialization was + successful. + + - Furthermore, there is no support for detecting loss of the network + connection and recovery of networking when the connection is restored. + +Both of these shortcomings can be eliminated by enabling the network +monitor: + +Network Monitor +--------------- +By default the network initialization thread will bring-up the network +then exit, freeing all of the resources that it required. This is a +good behavior for systems with limited memory. + +If the CONFIG_NSH_NETINIT_MONITOR option is selected, however, then the +network initialization thread will persist forever; it will monitor the +network status. In the event that the network goes down (for example, if +a cable is removed), then the thread will monitor the link status and +attempt to bring the network back up. In this case the resources +required for network initialization are never released. + +Pre-requisites: + + - CONFIG_NSH_NETINIT_THREAD as described above. + + - CONFIG_NETDEV_PHY_IOCTL. Enable PHY IOCTL commands in the Ethernet + device driver. Special IOCTL commands must be provided by the Ethernet + driver to support certain PHY operations that will be needed for link + management. There operations are not complex and are implemented for + the Atmel SAMV7 family. + + - CONFIG_ARCH_PHY_INTERRUPT. This is not a user selectable option. + Rather, it is set when you select a board that supports PHY interrupts. + In most architectures, the PHY interrupt is not associated with the + Ethernet driver at all. Rather, the PHY interrupt is provided via some + board-specific GPIO and the board-specific logic must provide support + for that GPIO interrupt. To do this, the board logic must do two things: + (1) It must provide the function arch_phy_irq() as described and + prototyped in the nuttx/include/nuttx/arch.h, and (2) it must select + CONFIG_ARCH_PHY_INTERRUPT in the board configuration file to advertise + that it supports arch_phy_irq(). This logic can be found at + nuttx/configs/sama5d4-ek/src/sam_ethernet.c. + + - And a few other things: UDP support is required (CONFIG_NET_UDP) and + signals must not be disabled (CONFIG_DISABLE_SIGNALS). + +Given those prerequisites, the network monitor can be selected with these +additional settings. + + Networking Support -> Networking Device Support + CONFIG_NETDEV_PHY_IOCTL=y : Enable PHY ioctl support + + Application Configuration -> NSH Library -> Networking Configuration + CONFIG_NSH_NETINIT_THREAD : Enable the network initialization thread + CONFIG_NSH_NETINIT_MONITOR=y : Enable the network monitor + CONFIG_NSH_NETINIT_RETRYMSEC=2000 : Configure the network monitor as you like + CONFIG_NSH_NETINIT_SIGNO=18 + Debugging ========= diff --git a/configs/samv71-xult/src/sam_ethernet.c b/configs/samv71-xult/src/sam_ethernet.c new file mode 100644 index 0000000000..966886ec9e --- /dev/null +++ b/configs/samv71-xult/src/sam_ethernet.c @@ -0,0 +1,272 @@ +/************************************************************************************ + * configs/samv71-xult/src/sam_ethernet.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +/* Force verbose debug on in this file only to support unit-level testing. */ + +#ifdef CONFIG_NETDEV_PHY_DEBUG +# undef CONFIG_DEBUG_VERBOSE +# define CONFIG_DEBUG_VERBOSE 1 +# undef CONFIG_DEBUG_NET +# define CONFIG_DEBUG_NET 1 +#endif + +#include +#include +#include + +#include +#include + +#include "sam_gpio.h" +#include "sam_ethernet.h" + +#include "samv71-xult.h" + +#ifdef HAVE_NETWORK + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define SAMV7_EMAC0_DEVNAME "eth0" + +/* Debug ********************************************************************/ +/* Extra, in-depth debug output that is only available if + * CONFIG_NETDEV_PHY_DEBUG us defined. + */ + +#ifdef CONFIG_NETDEV_PHY_DEBUG +# define phydbg dbg +# define phylldbg lldbg +#else +# define phydbg(x...) +# define phylldbg(x...) +#endif + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +#ifdef CONFIG_SAMV7_PIOA_IRQ +static xcpt_t g_emac0_handler; +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_emac_phy_enable and sam_gmac_enable + ************************************************************************************/ + +#ifdef CONFIG_SAMV7_PIOA_IRQ +static void sam_emac0_phy_enable(bool enable) +{ + phydbg("IRQ%d: enable=%d\n", IRQ_INT_ETH0, enable); + if (enable) + { + sam_pioirqenable(IRQ_INT_ETH0); + } + else + { + sam_pioirqdisable(IRQ_INT_ETH0); + } +} +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: sam_netinitialize + * + * Description: + * Configure board resources to support networking. + * + ************************************************************************************/ + +void weak_function sam_netinitialize(void) +{ + phydbg("Configuring %08x\n", GPIO_INT_ETH0); + sam_configgpio(GPIO_INT_ETH0); +} + +/**************************************************************************** + * Name: arch_phy_irq + * + * Description: + * This function may be called to register an interrupt handler that will + * be called when a PHY interrupt occurs. This function both attaches + * the interrupt handler and enables the interrupt if 'handler' is non- + * NULL. If handler is NULL, then the interrupt is detached and disabled + * instead. + * + * The PHY interrupt is always disabled upon return. The caller must + * call back through the enable function point to control the state of + * the interrupt. + * + * This interrupt may or may not be available on a given platform depending + * on how the network hardware architecture is implemented. In a typical + * case, the PHY interrupt is provided to board-level logic as a GPIO + * interrupt (in which case this is a board-specific interface and really + * should be called board_phy_irq()); In other cases, the PHY interrupt + * may be cause by the chip's MAC logic (in which case arch_phy_irq()) is + * an appropriate name. Other other boards, there may be no PHY interrupts + * available at all. If client attachable PHY interrupts are available + * from the board or from the chip, then CONFIG_ARCH_PHY_INTERRUPT should + * be defined to indicate that fact. + * + * Typical usage: + * a. OS service logic (not application logic*) attaches to the PHY + * PHY interrupt and enables the PHY interrupt. + * b. When the PHY interrupt occurs: (1) the interrupt should be + * disabled and () work should be scheduled on the worker thread (or + * perhaps a dedicated application thread). + * c. That worker thread should use the SIOCGMIIPHY, SIOCGMIIREG, + * and SIOCSMIIREG ioctl calls** to communicate with the PHY, + * determine what network event took place (Link Up/Down?), and + * take the appropriate actions. + * d. It should then interact the the PHY to clear any pending + * interrupts, then re-enable the PHY interrupt. + * + * * This is an OS internal interface and should not be used from + * application space. Rather applications should use the SIOCMIISIG + * ioctl to receive a signal when a PHY event occurs. + * ** This interrupt is really of no use if the Ethernet MAC driver + * does not support these ioctl calls. + * + * Input Parameters: + * intf - Identifies the network interface. For example "eth0". Only + * useful on platforms that support multiple Ethernet interfaces + * and, hence, multiple PHYs and PHY interrupts. + * handler - The client interrupt handler to be invoked when the PHY + * asserts an interrupt. Must reside in OS space, but can + * signal tasks in user space. A value of NULL can be passed + * in order to detach and disable the PHY interrupt. + * enable - A function pointer that be unsed to enable or disable the + * PHY interrupt. + * + * Returned Value: + * The previous PHY interrupt handler address is returned. This allows you + * to temporarily replace an interrupt handler, then restore the original + * interrupt handler. NULL is returned if there is was not handler in + * place when the call was made. + * + ****************************************************************************/ + +#ifdef CONFIG_SAMV7_PIOA_IRQ +xcpt_t arch_phy_irq(FAR const char *intf, xcpt_t handler, phy_enable_t *enable) +{ + irqstate_t flags; + xcpt_t *phandler; + xcpt_t oldhandler; + pio_pinset_t pinset; + phy_enable_t enabler; + int irq; + + DEBUGASSERT(intf); + + nvdbg("%s: handler=%p\n", intf, handler); + phydbg("EMAC0: devname=%s\n", SAMV7_EMAC0_DEVNAME); + phydbg("EMAC1: devname=%s\n", SAMV7_EMAC1_DEVNAME); + + if (strcmp(intf, SAMV7_EMAC0_DEVNAME) == 0) + { + phydbg("Select EMAC0\n"); + phandler = &g_emac0_handler; + pinset = GPIO_INT_ETH0; + irq = IRQ_INT_ETH0; + enabler = sam_emac0_phy_enable; + } + else + { + ndbg("Unsupported interface: %s\n", intf); + return NULL; + } + + /* Disable interrupts until we are done. This guarantees that the + * following operations are atomic. + */ + + flags = irqsave(); + + /* Get the old interrupt handler and save the new one */ + + oldhandler = *phandler; + *phandler = handler; + + /* Configure the interrupt */ + + if (handler) + { + phydbg("Configure pin: %08x\n", pinset); + sam_pioirq(pinset); + + phydbg("Attach IRQ%d\n", irq); + (void)irq_attach(irq, handler); + } + else + { + phydbg("Detach IRQ%d\n", irq); + (void)irq_detach(irq); + enabler = NULL; + } + + /* Return with the interrupt disabled in either case */ + + sam_pioirqdisable(irq); + + /* Return the enabling function pointer */ + + if (enable) + { + *enable = enabler; + } + + /* Return the old handler (so that it can be restored) */ + + irqrestore(flags); + return oldhandler; +} +#endif /* CONFIG_SAMV7_PIOA_IRQ */ + +#endif /* HAVE_NETWORK */ diff --git a/configs/samv71-xult/src/samv71-xult.h b/configs/samv71-xult/src/samv71-xult.h index 934f7294d2..db74840c6b 100644 --- a/configs/samv71-xult/src/samv71-xult.h +++ b/configs/samv71-xult/src/samv71-xult.h @@ -169,9 +169,34 @@ */ /* Ethernet MAC. - * to be provided + * + * KSZ8061RNBVA Connections + * ------------------------ + * + * ------ --------- --------- -------------------------- + * SAMV71 SAMV71 Ethernet Shared functionality + * Pin Function Function + * ------ --------- --------- -------------------------- + * PD00 GTXCK REF_CLK Shield + * PD01 GTXEN TXEN + * PD02 GTX0 TXD0 + * PD03 GTX1 TXD1 + * PD04 GRXDV CRS_DV Trace + * PD05 GRX0 RXD0 Trace + * PD06 GRX1 RXD1 Trace + * PD07 GRXER RXER Trace + * PD08 GMDC MDC Trace + * PD09 GMDIO MDIO + * PA19 GPIO INTERRUPT EXT1, Shield + * PA29 GPIO SIGDET + * PC10 GPIO RESET + * ------ --------- --------- -------------------------- */ +#define GPIO_INT_ETH0 (GPIO_INPUT | GPIO_CFG_PULLUP | GPIO_CFG_DEGLITCH | \ + GPIO_INT_FALLING | GPIO_PORT_PIOA | GPIO_PIN19) +#define IRQ_INT_ETH0 SAM_IRQ_PA19 + /* LEDs * * There are two yellow LED available on the SAM V71 Xplained Ultra board that