📄 c5471_ethernet.c
字号:
/**************************************************************************** * arch/arm/src/c5471/c5471_ethernet.c * * Copyright (C) 2007 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Based one a C5471 Linux driver and released under this BSD license with * special permisson from the copyright holder of the Linux driver: * Todd Fischer, Cadenux, LLC. Other references: "TMS320VC547x CPU and * Peripherals Reference Guide," TI document spru038.pdf. * * 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 <nuttx/config.h>#if defined(CONFIG_NET)#include <sys/types.h>#include <stdio.h>#include <time.h>#include <string.h>#include <debug.h>#include <wdog.h>#include <errno.h>#include <nuttx/irq.h>#include <nuttx/arch.h>#include <net/ethernet.h>#include <net/uip/uip.h>#include <net/uip/uip-arp.h>#include <net/uip/uip-arch.h>#include "chip.h"#include "up_arch.h"#include "up_internal.h"/**************************************************************************** * Definitions ****************************************************************************//* Configuration ************************************************************//* CONFIG_C5471_NET_NINTERFACES determines the number of physical interfaces * that will be supported. */#ifndef CONFIG_C5471_NET_NINTERFACES# define CONFIG_C5471_NET_NINTERFACES 1#endif/* CONFIG_C5471_NET_STATS will enabled collection of driver statistics. * Default is disabled. *//* CONFIG_C5471_ETHERNET_PHY may be set to one of the following values to * select the PHY (or left undefined if there is no PHY) */#ifndef ETHERNET_PHY_LU3X31T_T64# define ETHERNET_PHY_LU3X31T_T64 1#endif#ifndef ETHERNET_PHY_AC101L# define ETHERNET_PHY_AC101L 2#endif/* Mode of operation defaults to AUTONEGOTIATION */#if defined(CONFIG_NET_C5471_AUTONEGOTIATION)# undef CONFIG_NET_C5471_BASET100# undef CONFIG_NET_C5471_BASET10#elif defined(CONFIG_NET_C5471_BASET100)# undef CONFIG_NET_C5471_AUTONEGOTIATION# undef CONFIG_NET_C5471_BASET10#elif defined(CONFIG_NET_C5471_BASET10)# undef CONFIG_NET_C5471_AUTONEGOTIATION# undef CONFIG_NET_C5471_BASET100#else# define CONFIG_NET_C5471_AUTONEGOTIATION 1# undef CONFIG_NET_C5471_BASET100# undef CONFIG_NET_C5471_BASET10#endif/* This should be disabled unless you are performing very low level debug */#undef CONFIG_C5471_NET_DUMPBUFFER//#define CONFIG_C5471_NET_DUMPBUFFER 1/* Timing values ************************************************************//* TX poll deley = 1 seconds. CLK_TCK=number of clock ticks per second */#define C5471_WDDELAY (1*CLK_TCK)#define C5471_POLLHSEC (1*2)/* TX timeout = 1 minute */#define C5471_TXTIMEOUT (60*CLK_TCK)/* Ethernet GPIO bit settings ***********************************************/#define GPIO_CIO_MDIO 0x00004000#define GPIO_IO_MDCLK 0x00008000/* Ethernet interface bit settings ******************************************//* TX descriptor, word #0 */#define EIM_TXDESC_OWN_HOST 0x80000000 /* Bit 15: Ownership bit */#define EIM_TXDESC_OWN_ENET 0x00000000#define EIM_TXDESC_WRAP_NEXT 0x40000000 /* Bit 14: Descriptor chain wrap */#define EIM_TXDESC_WRAP_FIRST 0x00000000#define EIM_TXDESC_FIF 0x20000000 /* Bit 13: First in frame */#define EIM_TXDESC_LIF 0x10000000 /* Bit 12: Last in frame */ /* Bits 8-11: Retry count status */#define EIM_TXDESC_INTRE 0x00800000 /* Bit 7: TX_IRQ int enable */#define EIM_TXDESC_STATUSMASK 0x007f0000 /* Bits 0-6: Status */#define EIM_TXDESC_RETRYERROR 0x00400000 /* Exceed retry error */#define EIM_TXDESC_HEARTBEAT 0x00200000 /* Heartbeat (SQE) */#define EIM_TXDESC_LCOLLISON 0x00100000 /* Late collision error */#define EIM_TXDESC_COLLISION 0x00080000 /* Collision */#define EIM_TXDESC_CRCERROR 0x00040000 /* CRC error */#define EIM_TXDESC_UNDERRUN 0x00020000 /* Underrun error */#define EIM_TXDESC_LOC 0x00010000 /* Loss of carrier *//* Packet bytes value used for both TX and RX descriptors */#define EIM_PACKET_BYTES 0x00000040/* Count of descriptors */#define NUM_DESC_TX 32#define NUM_DESC_RX 64/* TX descriptor, word #1 */ /* Bit 15: reserved */#define EIM_TXDESC_PADCRC 0x00004000 /* Bit 14: Enable padding small frames */ /* Bits 11-13: reserved */#define EIM_TXDESC_BYTEMASK 0x000007ff /* Bits 0-10: Descriptor byte count *//* RX descriptor, word #0 */#define EIM_RXDESC_OWN_HOST 0x80000000 /* Bit 15: Ownership bit */#define EIM_RXDESC_OWN_ENET 0x00000000#define EIM_RXDESC_WRAP_NEXT 0x40000000 /* Bit 14: Descriptor chain wrap */#define EIM_RXDESC_WRAP_FIRST 0x00000000#define EIM_RXDESC_FIF 0x20000000 /* Bit 13: First in frame */#define EIM_RXDESC_LIF 0x10000000 /* Bit 12: Last in frame */ /* Bits 8-11: reserved */#define EIM_RXDESC_INTRE 0x00800000 /* Bit 7: RX_IRQ int enable */#define EIM_RXDESC_STATUSMASK 0x007f0000 /* Bits 0-6: Status */#define EIM_RXDESC_MISS 0x00400000 /* Miss */#define EIM_RXDESC_VLAN 0x00200000 /* VLAN */#define EIM_RXDESC_LFRAME 0x00100000 /* Long frame error */#define EIM_RXDESC_SFRAME 0x00080000 /* Short frame error */#define EIM_RXDESC_CRCERROR 0x00040000 /* CRC error */#define EIM_RXDESC_OVERRUN 0x00020000 /* Overrun error */#define EIM_RXDESC_ALIGN 0x00010000 /* Non-octect align error */#define EIM_RXDESC_PADCRC 0x00004000 /* Enable padding for small frames *//* RX descriptor, word #1 */ /* Bits 11-15: reserved */#define EIM_RXDESC_BYTEMASK 0x000007ff /* Bits 0-10: Descriptor byte count *//* EIM_CPU_FILTER bit settings */ /* Bits 5-31: reserved */#define EIM_FILTER_MACLA 0x00000010 /* Bit 4: Enable logical address+multicast filtering */#define EIM_FILTER_LOGICAL 0x00000008 /* Bit 3: Enable ENET logical filtering */#define EIM_FILTER_MULTICAST 0x00000004 /* Bit 2: Enable multicast filtering */#define EIM_FILTER_BROADCAST 0x00000002 /* Bit 1: Enable broadcast matching */#define EIM_FILTER_UNICAST 0x00000001 /* Bit 0: Enable dest CPU address matching *//* EIM_CTRL bit settings */ /* Bits 16-31: Reserved */#define EIM_CTRL_ESM_EN 0x00008000 /* Bit 15: Ethernet state machine enable */ /* Bits 9-14: reserved */#define EIM_CTRL_ENET0_EN 0x00000100 /* Bit 8: Enable routing of RX packets CPU->ENET0 */ /* Bit 7: reserved */#define EIM_CTRL_ENET0_FLW 0x00000040 /* Bit 6: Enable ENET0 flow control RX threshold */#define EIM_CTRL_RXENET0_EN 0x00000020 /* Bit 5: Enable processing of ENET0 RX queue */#define EIM_CTRL_TXENET0_EN 0x00000010 /* Bit 4: Enable processing of ENET0 TX queue */ /* Bits 2-3: reserved */#define EIM_CTRL_RXCPU_EN 0x00000002 /* Bit 1: Enable processing of CPU RX queue */#define EIM_CTRL_TXCPU_EN 0x00000001 /* Bit 0: Enable processing of CPU TX queue *//* EIM_STATUS bit settings */ /* Bits 10-31: reserved */#define EIM_STATUS_CPU_TXLIF 0x00000200 /* Bit 9: Last descriptor of TX packet filled */#define EIM_STATUS_CPU_RXLIF 0x00000100 /* Bit 8: Last descriptor of RX queue processed */#define EIM_STATUS_CPU_TX 0x00000080 /* Bit 7: Descriptor filled in TX queue */#define EIM_STATUS_CPU_RX 0x00000040 /* Bit 6: Descriptor filled in RX queue */ /* Bits 3-5: reserved */#define EIM_STATUS_ENET0_ERR 0x00000004 /* Bit 2: ENET0 error interrupt */#define EIM_STATUS_ENET0_TX 0x00000002 /* Bit 1: ENET0 TX interrupt */#define EIM_STATUS_ENET0_RX 0x00000001 /* Bit 0" ENET0 RX interrupt *//* EIM_INTEN bit settings */#define EIM_INTEN_CPU_TXLIF 0x00000200 /* Bit 9: Last descriptor of TX packet filled */#define EIM_INTEN_CPU_RXLIF 0x00000100 /* Bit 8: Last descriptor of RX queue processed */#define EIM_INTEN_CPU_TX 0x00000080 /* Bit 7: Descriptor filled in TX queue */#define EIM_INTEN_CPU_RX 0x00000040 /* Bit 6: Descriptor filled in RX queue */ /* Bits 3-5: reserved */#define EIM_INTEN_ENET0_ERR 0x00000004 /* Bit 2: ENET0 error interrupt */#define EIM_INTEN_ENET0_TX 0x00000002 /* Bit 1: ENET0 TX interrupt */#define EIM_INTEN_ENET0_RX 0x00000001 /* Bit 0: ENET0 RX interrupt *//* ENET0_ADRMODE_EN bit settings */#define ENET_ADR_PROMISCUOUS 0x00000008 /* Bit 3: Enable snoop address comparison */#define ENET_ADR_BROADCAST 0x00000004 /* Bit 2: Enable broadcast address comparison */#define ENET_ADDR_LCOMPARE 0x00000002 /* Bit 1: Enable logical address comparison */#define ENET_ADDR_PCOMPARE 0x00000001 /* Bit 0: Enable physical address comparison *//* ENET0_MODE bit settings */ /* Bits 16-31: reserved */#define ENET_MODO_FIFO_EN 0x00008000 /* Bit 15: Fifo enable */ /* Bits 8-14: reserved */#define ENET_MODE_RJCT_SFE 0x00000080 /* Bit 7: Reject short frames durig receive */#define ENET_MODE_DPNET 0x00000040 /* Bit 6: Demand priority networkd vs CSMA/CD */#define ENET_MODE_MWIDTH 0x00000020 /* Bit 5: Select nibble mode MII port */#define ENET_MODE_WRAP 0x00000010 /* Bit 4: Internal MAC loopback */#define ENET_MODE_FDWRAP 0x00000008 /* Bit 3: Full duplex wrap */#define ENET_MODE_FULLDUPLEX 0x00000004 /* Bit 2: 1:Full duplex */#define ENET_MODE_HALFDUPLEX 0x00000000 /* 0:Half duplex */ /* Bit 1: reserved */#define ENET_MODE_ENABLE 0x00000001 /* Bit 0: Port enable *//* PHY registers */#define MD_PHY_CONTROL_REG 0x00#define MD_PHY_MSB_REG 0x02#define MD_PHY_LSB_REG 0x03#define MD_PHY_CTRL_STAT_REG 0x17/* Lucent LU3X31T-T64 transeiver ID */#define LU3X31_T64_PHYID 0x00437421/* PHY control register bit settings */#define MODE_AUTONEG 0x1000#define MODE_10MBIT_HALFDUP 0x0000#define MODE_10MBIT_FULLDUP 0x0100#define MODE_100MBIT_FULLDUP 0x2100#define MODE_100MBIT_HALFDUP 0x2000/* Inserts an ARM "nop" instruction */#define nop() asm(" nop");/* This is a helper pointer for accessing the contents of the Ethernet header */#define BUF ((struct uip_eth_hdr *)c5471->c_dev.d_buf)/**************************************************************************** * Private Types ****************************************************************************//* The c5471_driver_s encapsulates all state information for a single c5471 * hardware interface */struct c5471_driver_s{ boolean c_bifup; /* TRUE:ifup FALSE:ifdown */ WDOG_ID c_txpoll; /* TX poll timer */ WDOG_ID c_txtimeout; /* TX timeout timer */ /* Note: According to the C547x documentation: "The software has to maintain * two pointers to the current RX-CPU and TX-CPU descriptors. At init time, * they have to be set to the first descriptors of each queue, and they have * to be incremented each time a descriptor ownership is give to the SWITCH". */ volatile uint32 c_txcpudesc; volatile uint32 c_rxcpudesc; /* Last TX descriptor saved for error handling */ uint32 c_lastdescstart; uint32 c_lastdescend; /* Shadowed registers */ uint32 c_eimstatus;#ifdef CONFIG_C5471_NET_STATS /* TX statistics */ uint32 c_txpackets; /* Number of packets sent */ uint32 c_txmiss; /* Miss */ uint32 c_txvlan; /* VLAN */ uint32 c_txlframe; /* Long frame errors */ uint32 c_txsframe; /* Short frame errors */ uint32 c_txcrc; /* CRC errors */ uint32 c_txoverrun; /* Overrun errors */ uint32 c_txalign; /* Non-octect align errors */ uint32 c_txtimeouts; /* TX timeouts */ uint32 c_rxpackets; /* Number of packets received */ uint32 c_rxretries; /* Exceed retry errors */ uint32 c_rxheartbeat; /* Heartbeat (SQE) */ uint32 c_rxlcollision; /* Late collision errors */ uint32 c_rxcollision; /* Collision */ uint32 c_rxcrc; /* CRC errors */ uint32 c_rxunderrun; /* Underrun errors */ uint32 c_rxloc; /* Loss of carrier */ uint32 c_rxdropped; /* Packets dropped because of size */#endif /* This holds the information visible to uIP/NuttX */ struct uip_driver_s c_dev; /* Interface understood by uIP */};/**************************************************************************** * Private Data ****************************************************************************/static struct c5471_driver_s g_c5471[CONFIG_C5471_NET_NINTERFACES];/**************************************************************************** * Private Function Prototypes ****************************************************************************//* Transceiver interface */static void c5471_mdtxbit (int bit_state);static int c5471_mdrxbit (void);static void c5471_mdwrite (int adr, int reg, int data);static int c5471_mdread (int adr, int reg);static int c5471_phyinit (void);/* Support logic */static inline void c5471_inctxcpu(struct c5471_driver_s *c5471);static inline void c5471_incrxcpu(struct c5471_driver_s *c5471);/* Common TX logic */static int c5471_transmit(struct c5471_driver_s *c5471);static int c5471_uiptxpoll(struct uip_driver_s *dev);/* Interrupt handling */#ifdef CONFIG_C5471_NET_STATSstatic void c5471_rxstatus(struct c5471_driver_s *c5471);#endifstatic void c5471_receive(struct c5471_driver_s *c5471);#ifdef CONFIG_C5471_NET_STATSstatic void c5471_txstatus(struct c5471_driver_s *c5471);#endifstatic void c5471_txdone(struct c5471_driver_s *c5471);static int c5471_interrupt(int irq, FAR void *context);/* Watchdog timer expirations */static void c5471_polltimer(int argc, uint32 arg, ...);static void c5471_txtimeout(int argc, uint32 arg, ...);/* NuttX callback functions */static int c5471_ifup(struct uip_driver_s *dev);static int c5471_ifdown(struct uip_driver_s *dev);static int c5471_txavail(struct uip_driver_s *dev);/* Initialization functions */static void c5471_eimreset (struct c5471_driver_s *c5471);static void c5471_eimconfig(struct c5471_driver_s *c5471);static void c5471_reset(struct c5471_driver_s *c5471);static void c5471_macassign(struct c5471_driver_s *c5471);/**************************************************************************** * Private Functions ****************************************************************************//**************************************************************************** * Name: c5471_dumpbuffer * * Description * Debug only * ****************************************************************************/#ifdef CONFIG_C5471_NET_DUMPBUFFERstatic void c5471_dumpbuffer(const char *buffer, ssize_t nbytes){#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET) char line[128]; int ch; int i; int j; for (i = 0; i < nbytes; i += 16) { sprintf(line, "%04x: ", i); for (j = 0; j < 16; j++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -