diff options
Diffstat (limited to 'qemu/roms/u-boot/drivers/net')
135 files changed, 0 insertions, 63088 deletions
diff --git a/qemu/roms/u-boot/drivers/net/4xx_enet.c b/qemu/roms/u-boot/drivers/net/4xx_enet.c deleted file mode 100644 index 381ec4286..000000000 --- a/qemu/roms/u-boot/drivers/net/4xx_enet.c +++ /dev/null @@ -1,2059 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0 IBM-pibs - */ -/*-----------------------------------------------------------------------------+ - * - * File Name: enetemac.c - * - * Function: Device driver for the ethernet EMAC3 macro on the 405GP. - * - * Author: Mark Wisner - * - * Change Activity- - * - * Date Description of Change BY - * --------- --------------------- --- - * 05-May-99 Created MKW - * 27-Jun-99 Clean up JWB - * 16-Jul-99 Added MAL error recovery and better IP packet handling MKW - * 29-Jul-99 Added Full duplex support MKW - * 06-Aug-99 Changed names for Mal CR reg MKW - * 23-Aug-99 Turned off SYE when running at 10Mbs MKW - * 24-Aug-99 Marked descriptor empty after call_xlc MKW - * 07-Sep-99 Set MAL RX buffer size reg to ENET_MAX_MTU_ALIGNED / 16 MCG - * to avoid chaining maximum sized packets. Push starting - * RX descriptor address up to the next cache line boundary. - * 16-Jan-00 Added support for booting with IP of 0x0 MKW - * 15-Mar-00 Updated enetInit() to enable broadcast addresses in the - * EMAC0_RXM register. JWB - * 12-Mar-01 anne-sophie.harnois@nextream.fr - * - Variables are compatible with those already defined in - * include/net.h - * - Receive buffer descriptor ring is used to send buffers - * to the user - * - Info print about send/received/handled packet number if - * INFO_405_ENET is set - * 17-Apr-01 stefan.roese@esd-electronics.com - * - MAL reset in "eth_halt" included - * - Enet speed and duplex output now in one line - * 08-May-01 stefan.roese@esd-electronics.com - * - MAL error handling added (eth_init called again) - * 13-Nov-01 stefan.roese@esd-electronics.com - * - Set IST bit in EMAC0_MR1 reg upon 100MBit or full duplex - * 04-Jan-02 stefan.roese@esd-electronics.com - * - Wait for PHY auto negotiation to complete added - * 06-Feb-02 stefan.roese@esd-electronics.com - * - Bug fixed in waiting for auto negotiation to complete - * 26-Feb-02 stefan.roese@esd-electronics.com - * - rx and tx buffer descriptors now allocated (no fixed address - * used anymore) - * 17-Jun-02 stefan.roese@esd-electronics.com - * - MAL error debug printf 'M' removed (rx de interrupt may - * occur upon many incoming packets with only 4 rx buffers). - *-----------------------------------------------------------------------------* - * 17-Nov-03 travis.sawyer@sandburst.com - * - ported from 405gp_enet.c to utilized upto 4 EMAC ports - * in the 440GX. This port should work with the 440GP - * (2 EMACs) also - * 15-Aug-05 sr@denx.de - * - merged 405gp_enet.c and 440gx_enet.c to generic 4xx_enet.c - now handling all 4xx cpu's. - *-----------------------------------------------------------------------------*/ - -#include <config.h> -#include <common.h> -#include <net.h> -#include <asm/processor.h> -#include <asm/io.h> -#include <asm/cache.h> -#include <asm/mmu.h> -#include <commproc.h> -#include <asm/ppc4xx.h> -#include <asm/ppc4xx-emac.h> -#include <asm/ppc4xx-mal.h> -#include <miiphy.h> -#include <malloc.h> -#include <linux/compiler.h> - -#if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) -#error "CONFIG_MII has to be defined!" -#endif - -#define EMAC_RESET_TIMEOUT 1000 /* 1000 ms reset timeout */ -#define PHY_AUTONEGOTIATE_TIMEOUT 5000 /* 5000 ms autonegotiate timeout */ - -/* Ethernet Transmit and Receive Buffers */ -/* AS.HARNOIS - * In the same way ENET_MAX_MTU and ENET_MAX_MTU_ALIGNED are set from - * PKTSIZE and PKTSIZE_ALIGN (include/net.h) - */ -#define ENET_MAX_MTU PKTSIZE -#define ENET_MAX_MTU_ALIGNED PKTSIZE_ALIGN - -/*-----------------------------------------------------------------------------+ - * Defines for MAL/EMAC interrupt conditions as reported in the UIC (Universal - * Interrupt Controller). - *-----------------------------------------------------------------------------*/ -#define ETH_IRQ_NUM(dev) (VECNUM_ETH0 + ((dev) * VECNUM_ETH1_OFFS)) - -#if defined(CONFIG_HAS_ETH3) -#if !defined(CONFIG_440GX) -#define UIC_ETHx (UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1)) || \ - UIC_MASK(ETH_IRQ_NUM(2)) || UIC_MASK(ETH_IRQ_NUM(3))) -#else -/* Unfortunately 440GX spreads EMAC interrupts on multiple UIC's */ -#define UIC_ETHx (UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1))) -#define UIC_ETHxB (UIC_MASK(ETH_IRQ_NUM(2)) || UIC_MASK(ETH_IRQ_NUM(3))) -#endif /* !defined(CONFIG_440GX) */ -#elif defined(CONFIG_HAS_ETH2) -#define UIC_ETHx (UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1)) || \ - UIC_MASK(ETH_IRQ_NUM(2))) -#elif defined(CONFIG_HAS_ETH1) -#define UIC_ETHx (UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1))) -#else -#define UIC_ETHx UIC_MASK(ETH_IRQ_NUM(0)) -#endif - -/* - * Define a default version for UIC_ETHxB for non 440GX so that we can - * use common code for all 4xx variants - */ -#if !defined(UIC_ETHxB) -#define UIC_ETHxB 0 -#endif - -#define UIC_MAL_SERR UIC_MASK(VECNUM_MAL_SERR) -#define UIC_MAL_TXDE UIC_MASK(VECNUM_MAL_TXDE) -#define UIC_MAL_RXDE UIC_MASK(VECNUM_MAL_RXDE) -#define UIC_MAL_TXEOB UIC_MASK(VECNUM_MAL_TXEOB) -#define UIC_MAL_RXEOB UIC_MASK(VECNUM_MAL_RXEOB) - -#define MAL_UIC_ERR (UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE) -#define MAL_UIC_DEF (UIC_MAL_RXEOB | MAL_UIC_ERR) - -/* - * We have 3 different interrupt types: - * - MAL interrupts indicating successful transfer - * - MAL error interrupts indicating MAL related errors - * - EMAC interrupts indicating EMAC related errors - * - * All those interrupts can be on different UIC's, but since - * now at least all interrupts from one type are on the same - * UIC. Only exception is 440GX where the EMAC interrupts are - * spread over two UIC's! - */ -#if defined(CONFIG_440GX) -#define UIC_BASE_MAL UIC1_DCR_BASE -#define UIC_BASE_MAL_ERR UIC2_DCR_BASE -#define UIC_BASE_EMAC UIC2_DCR_BASE -#define UIC_BASE_EMAC_B UIC3_DCR_BASE -#else -#define UIC_BASE_MAL (UIC0_DCR_BASE + (UIC_NR(VECNUM_MAL_TXEOB) * 0x10)) -#define UIC_BASE_MAL_ERR (UIC0_DCR_BASE + (UIC_NR(VECNUM_MAL_SERR) * 0x10)) -#define UIC_BASE_EMAC (UIC0_DCR_BASE + (UIC_NR(ETH_IRQ_NUM(0)) * 0x10)) -#define UIC_BASE_EMAC_B (UIC0_DCR_BASE + (UIC_NR(ETH_IRQ_NUM(0)) * 0x10)) -#endif - -#undef INFO_4XX_ENET - -#define BI_PHYMODE_NONE 0 -#define BI_PHYMODE_ZMII 1 -#define BI_PHYMODE_RGMII 2 -#define BI_PHYMODE_GMII 3 -#define BI_PHYMODE_RTBI 4 -#define BI_PHYMODE_TBI 5 -#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ - defined(CONFIG_405EX) -#define BI_PHYMODE_SMII 6 -#define BI_PHYMODE_MII 7 -#if defined(CONFIG_460EX) || defined(CONFIG_460GT) -#define BI_PHYMODE_RMII 8 -#endif -#endif -#define BI_PHYMODE_SGMII 9 - -#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ - defined(CONFIG_405EX) -#define SDR0_MFR_ETH_CLK_SEL_V(n) ((0x01<<27) / (n+1)) -#endif - -#if defined(CONFIG_460EX) || defined(CONFIG_460GT) -#define SDR0_ETH_CFG_CLK_SEL_V(n) (0x01 << (8 + n)) -#endif - -#if defined(CONFIG_460EX) || defined(CONFIG_460GT) -#define MAL_RX_CHAN_MUL 8 /* 460EX/GT uses MAL channel 8 for EMAC1 */ -#else -#define MAL_RX_CHAN_MUL 1 -#endif - -/*--------------------------------------------------------------------+ - * Fixed PHY (PHY-less) support for Ethernet Ports. - *--------------------------------------------------------------------*/ - -/* - * Some boards do not have a PHY for each ethernet port. These ports - * are known as Fixed PHY (or PHY-less) ports. For such ports, set - * the appropriate CONFIG_PHY_ADDR equal to CONFIG_FIXED_PHY and - * then define CONFIG_SYS_FIXED_PHY_PORTS to define what the speed and - * duplex should be for these ports in the board configuration - * file. - * - * For Example: - * #define CONFIG_FIXED_PHY 0xFFFFFFFF - * - * #define CONFIG_PHY_ADDR CONFIG_FIXED_PHY - * #define CONFIG_PHY1_ADDR 1 - * #define CONFIG_PHY2_ADDR CONFIG_FIXED_PHY - * #define CONFIG_PHY3_ADDR 3 - * - * #define CONFIG_SYS_FIXED_PHY_PORT(devnum,speed,duplex) \ - * {devnum, speed, duplex}, - * - * #define CONFIG_SYS_FIXED_PHY_PORTS \ - * CONFIG_SYS_FIXED_PHY_PORT(0,1000,FULL) \ - * CONFIG_SYS_FIXED_PHY_PORT(2,100,HALF) - */ - -#ifndef CONFIG_FIXED_PHY -#define CONFIG_FIXED_PHY 0xFFFFFFFF /* Fixed PHY (PHY-less) */ -#endif - -#ifndef CONFIG_SYS_FIXED_PHY_PORTS -#define CONFIG_SYS_FIXED_PHY_PORTS /* default is an empty array */ -#endif - -struct fixed_phy_port { - unsigned int devnum; /* ethernet port */ - unsigned int speed; /* specified speed 10,100 or 1000 */ - unsigned int duplex; /* specified duplex FULL or HALF */ -}; - -static const struct fixed_phy_port fixed_phy_port[] = { - CONFIG_SYS_FIXED_PHY_PORTS /* defined in board configuration file */ -}; - -/*-----------------------------------------------------------------------------+ - * Global variables. TX and RX descriptors and buffers. - *-----------------------------------------------------------------------------*/ - -/* - * Get count of EMAC devices (doesn't have to be the max. possible number - * supported by the cpu) - * - * CONFIG_BOARD_EMAC_COUNT added so now a "dynamic" way to configure the - * EMAC count is possible. As it is needed for the Kilauea/Haleakala - * 405EX/405EXr eval board, using the same binary. - */ -#if defined(CONFIG_BOARD_EMAC_COUNT) -#define LAST_EMAC_NUM board_emac_count() -#else /* CONFIG_BOARD_EMAC_COUNT */ -#if defined(CONFIG_HAS_ETH3) -#define LAST_EMAC_NUM 4 -#elif defined(CONFIG_HAS_ETH2) -#define LAST_EMAC_NUM 3 -#elif defined(CONFIG_HAS_ETH1) -#define LAST_EMAC_NUM 2 -#else -#define LAST_EMAC_NUM 1 -#endif -#endif /* CONFIG_BOARD_EMAC_COUNT */ - -/* normal boards start with EMAC0 */ -#if !defined(CONFIG_EMAC_NR_START) -#define CONFIG_EMAC_NR_START 0 -#endif - -#define MAL_RX_DESC_SIZE 2048 -#define MAL_TX_DESC_SIZE 2048 -#define MAL_ALLOC_SIZE (MAL_TX_DESC_SIZE + MAL_RX_DESC_SIZE) - -/*-----------------------------------------------------------------------------+ - * Prototypes and externals. - *-----------------------------------------------------------------------------*/ -static void enet_rcv (struct eth_device *dev, unsigned long malisr); - -int enetInt (struct eth_device *dev); -static void mal_err (struct eth_device *dev, unsigned long isr, - unsigned long uic, unsigned long maldef, - unsigned long mal_errr); -static void emac_err (struct eth_device *dev, unsigned long isr); - -extern int phy_setup_aneg (char *devname, unsigned char addr); -extern int emac4xx_miiphy_read (const char *devname, unsigned char addr, - unsigned char reg, unsigned short *value); -extern int emac4xx_miiphy_write (const char *devname, unsigned char addr, - unsigned char reg, unsigned short value); - -int board_emac_count(void); - -static void emac_loopback_enable(EMAC_4XX_HW_PST hw_p) -{ -#if defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_405EX) - u32 val; - - mfsdr(SDR0_MFR, val); - val |= SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum); - mtsdr(SDR0_MFR, val); -#elif defined(CONFIG_460EX) || defined(CONFIG_460GT) - u32 val; - - mfsdr(SDR0_ETH_CFG, val); - val |= SDR0_ETH_CFG_CLK_SEL_V(hw_p->devnum); - mtsdr(SDR0_ETH_CFG, val); -#endif -} - -static void emac_loopback_disable(EMAC_4XX_HW_PST hw_p) -{ -#if defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_405EX) - u32 val; - - mfsdr(SDR0_MFR, val); - val &= ~SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum); - mtsdr(SDR0_MFR, val); -#elif defined(CONFIG_460EX) || defined(CONFIG_460GT) - u32 val; - - mfsdr(SDR0_ETH_CFG, val); - val &= ~SDR0_ETH_CFG_CLK_SEL_V(hw_p->devnum); - mtsdr(SDR0_ETH_CFG, val); -#endif -} - -/*-----------------------------------------------------------------------------+ -| ppc_4xx_eth_halt -| Disable MAL channel, and EMACn -+-----------------------------------------------------------------------------*/ -static void ppc_4xx_eth_halt (struct eth_device *dev) -{ - EMAC_4XX_HW_PST hw_p = dev->priv; - u32 val = 10000; - - out_be32((void *)EMAC0_IER + hw_p->hw_addr, 0x00000000); /* disable emac interrupts */ - - /* 1st reset MAL channel */ - /* Note: writing a 0 to a channel has no effect */ -#if defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR) - mtdcr (MAL0_TXCARR, (MAL_CR_MMSR >> (hw_p->devnum * 2))); -#else - mtdcr (MAL0_TXCARR, (MAL_CR_MMSR >> hw_p->devnum)); -#endif - mtdcr (MAL0_RXCARR, (MAL_CR_MMSR >> hw_p->devnum)); - - /* wait for reset */ - while (mfdcr (MAL0_RXCASR) & (MAL_CR_MMSR >> hw_p->devnum)) { - udelay (1000); /* Delay 1 MS so as not to hammer the register */ - val--; - if (val == 0) - break; - } - - /* provide clocks for EMAC internal loopback */ - emac_loopback_enable(hw_p); - - /* EMAC RESET */ - out_be32((void *)EMAC0_MR0 + hw_p->hw_addr, EMAC_MR0_SRST); - - /* remove clocks for EMAC internal loopback */ - emac_loopback_disable(hw_p); - -#ifndef CONFIG_NETCONSOLE - hw_p->print_speed = 1; /* print speed message again next time */ -#endif - -#if defined(CONFIG_460EX) || defined(CONFIG_460GT) - /* don't bypass the TAHOE0/TAHOE1 cores for Linux */ - mfsdr(SDR0_ETH_CFG, val); - val &= ~(SDR0_ETH_CFG_TAHOE0_BYPASS | SDR0_ETH_CFG_TAHOE1_BYPASS); - mtsdr(SDR0_ETH_CFG, val); -#endif - - return; -} - -#if defined (CONFIG_440GX) -int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis) -{ - unsigned long pfc1; - unsigned long zmiifer; - unsigned long rmiifer; - - mfsdr(SDR0_PFC1, pfc1); - pfc1 = SDR0_PFC1_EPS_DECODE(pfc1); - - zmiifer = 0; - rmiifer = 0; - - switch (pfc1) { - case 1: - zmiifer |= ZMII_FER_RMII << ZMII_FER_V(0); - zmiifer |= ZMII_FER_RMII << ZMII_FER_V(1); - zmiifer |= ZMII_FER_RMII << ZMII_FER_V(2); - zmiifer |= ZMII_FER_RMII << ZMII_FER_V(3); - bis->bi_phymode[0] = BI_PHYMODE_ZMII; - bis->bi_phymode[1] = BI_PHYMODE_ZMII; - bis->bi_phymode[2] = BI_PHYMODE_ZMII; - bis->bi_phymode[3] = BI_PHYMODE_ZMII; - break; - case 2: - zmiifer |= ZMII_FER_SMII << ZMII_FER_V(0); - zmiifer |= ZMII_FER_SMII << ZMII_FER_V(1); - zmiifer |= ZMII_FER_SMII << ZMII_FER_V(2); - zmiifer |= ZMII_FER_SMII << ZMII_FER_V(3); - bis->bi_phymode[0] = BI_PHYMODE_ZMII; - bis->bi_phymode[1] = BI_PHYMODE_ZMII; - bis->bi_phymode[2] = BI_PHYMODE_ZMII; - bis->bi_phymode[3] = BI_PHYMODE_ZMII; - break; - case 3: - zmiifer |= ZMII_FER_RMII << ZMII_FER_V(0); - rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(2); - bis->bi_phymode[0] = BI_PHYMODE_ZMII; - bis->bi_phymode[1] = BI_PHYMODE_NONE; - bis->bi_phymode[2] = BI_PHYMODE_RGMII; - bis->bi_phymode[3] = BI_PHYMODE_NONE; - break; - case 4: - zmiifer |= ZMII_FER_SMII << ZMII_FER_V(0); - zmiifer |= ZMII_FER_SMII << ZMII_FER_V(1); - rmiifer |= RGMII_FER_RGMII << RGMII_FER_V (2); - rmiifer |= RGMII_FER_RGMII << RGMII_FER_V (3); - bis->bi_phymode[0] = BI_PHYMODE_ZMII; - bis->bi_phymode[1] = BI_PHYMODE_ZMII; - bis->bi_phymode[2] = BI_PHYMODE_RGMII; - bis->bi_phymode[3] = BI_PHYMODE_RGMII; - break; - case 5: - zmiifer |= ZMII_FER_SMII << ZMII_FER_V (0); - zmiifer |= ZMII_FER_SMII << ZMII_FER_V (1); - zmiifer |= ZMII_FER_SMII << ZMII_FER_V (2); - rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(3); - bis->bi_phymode[0] = BI_PHYMODE_ZMII; - bis->bi_phymode[1] = BI_PHYMODE_ZMII; - bis->bi_phymode[2] = BI_PHYMODE_ZMII; - bis->bi_phymode[3] = BI_PHYMODE_RGMII; - break; - case 6: - zmiifer |= ZMII_FER_SMII << ZMII_FER_V (0); - zmiifer |= ZMII_FER_SMII << ZMII_FER_V (1); - rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(2); - bis->bi_phymode[0] = BI_PHYMODE_ZMII; - bis->bi_phymode[1] = BI_PHYMODE_ZMII; - bis->bi_phymode[2] = BI_PHYMODE_RGMII; - break; - case 0: - default: - zmiifer = ZMII_FER_MII << ZMII_FER_V(devnum); - rmiifer = 0x0; - bis->bi_phymode[0] = BI_PHYMODE_ZMII; - bis->bi_phymode[1] = BI_PHYMODE_ZMII; - bis->bi_phymode[2] = BI_PHYMODE_ZMII; - bis->bi_phymode[3] = BI_PHYMODE_ZMII; - break; - } - - /* Ensure we setup mdio for this devnum and ONLY this devnum */ - zmiifer |= (ZMII_FER_MDI) << ZMII_FER_V(devnum); - - out_be32((void *)ZMII0_FER, zmiifer); - out_be32((void *)RGMII_FER, rmiifer); - - return ((int)pfc1); -} -#endif /* CONFIG_440_GX */ - -#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) -int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis) -{ - unsigned long zmiifer=0x0; - unsigned long pfc1; - - mfsdr(SDR0_PFC1, pfc1); - pfc1 &= SDR0_PFC1_SELECT_MASK; - - switch (pfc1) { - case SDR0_PFC1_SELECT_CONFIG_2: - /* 1 x GMII port */ - out_be32((void *)ZMII0_FER, 0x00); - out_be32((void *)RGMII_FER, 0x00000037); - bis->bi_phymode[0] = BI_PHYMODE_GMII; - bis->bi_phymode[1] = BI_PHYMODE_NONE; - break; - case SDR0_PFC1_SELECT_CONFIG_4: - /* 2 x RGMII ports */ - out_be32((void *)ZMII0_FER, 0x00); - out_be32((void *)RGMII_FER, 0x00000055); - bis->bi_phymode[0] = BI_PHYMODE_RGMII; - bis->bi_phymode[1] = BI_PHYMODE_RGMII; - break; - case SDR0_PFC1_SELECT_CONFIG_6: - /* 2 x SMII ports */ - out_be32((void *)ZMII0_FER, - ((ZMII_FER_SMII) << ZMII_FER_V(0)) | - ((ZMII_FER_SMII) << ZMII_FER_V(1))); - out_be32((void *)RGMII_FER, 0x00000000); - bis->bi_phymode[0] = BI_PHYMODE_SMII; - bis->bi_phymode[1] = BI_PHYMODE_SMII; - break; - case SDR0_PFC1_SELECT_CONFIG_1_2: - /* only 1 x MII supported */ - out_be32((void *)ZMII0_FER, (ZMII_FER_MII) << ZMII_FER_V(0)); - out_be32((void *)RGMII_FER, 0x00000000); - bis->bi_phymode[0] = BI_PHYMODE_MII; - bis->bi_phymode[1] = BI_PHYMODE_NONE; - break; - default: - break; - } - - /* Ensure we setup mdio for this devnum and ONLY this devnum */ - zmiifer = in_be32((void *)ZMII0_FER); - zmiifer |= (ZMII_FER_MDI) << ZMII_FER_V(devnum); - out_be32((void *)ZMII0_FER, zmiifer); - - return ((int)0x0); -} -#endif /* CONFIG_440EPX */ - -#if defined(CONFIG_405EX) -int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis) -{ - u32 rgmiifer = 0; - - /* - * The 405EX(r)'s RGMII bridge can operate in one of several - * modes, only one of which (2 x RGMII) allows the - * simultaneous use of both EMACs on the 405EX. - */ - - switch (CONFIG_EMAC_PHY_MODE) { - - case EMAC_PHY_MODE_NONE: - /* No ports */ - rgmiifer |= RGMII_FER_DIS << 0; - rgmiifer |= RGMII_FER_DIS << 4; - out_be32((void *)RGMII_FER, rgmiifer); - bis->bi_phymode[0] = BI_PHYMODE_NONE; - bis->bi_phymode[1] = BI_PHYMODE_NONE; - break; - case EMAC_PHY_MODE_NONE_RGMII: - /* 1 x RGMII port on channel 0 */ - rgmiifer |= RGMII_FER_RGMII << 0; - rgmiifer |= RGMII_FER_DIS << 4; - out_be32((void *)RGMII_FER, rgmiifer); - bis->bi_phymode[0] = BI_PHYMODE_RGMII; - bis->bi_phymode[1] = BI_PHYMODE_NONE; - break; - case EMAC_PHY_MODE_RGMII_NONE: - /* 1 x RGMII port on channel 1 */ - rgmiifer |= RGMII_FER_DIS << 0; - rgmiifer |= RGMII_FER_RGMII << 4; - out_be32((void *)RGMII_FER, rgmiifer); - bis->bi_phymode[0] = BI_PHYMODE_NONE; - bis->bi_phymode[1] = BI_PHYMODE_RGMII; - break; - case EMAC_PHY_MODE_RGMII_RGMII: - /* 2 x RGMII ports */ - rgmiifer |= RGMII_FER_RGMII << 0; - rgmiifer |= RGMII_FER_RGMII << 4; - out_be32((void *)RGMII_FER, rgmiifer); - bis->bi_phymode[0] = BI_PHYMODE_RGMII; - bis->bi_phymode[1] = BI_PHYMODE_RGMII; - break; - case EMAC_PHY_MODE_NONE_GMII: - /* 1 x GMII port on channel 0 */ - rgmiifer |= RGMII_FER_GMII << 0; - rgmiifer |= RGMII_FER_DIS << 4; - out_be32((void *)RGMII_FER, rgmiifer); - bis->bi_phymode[0] = BI_PHYMODE_GMII; - bis->bi_phymode[1] = BI_PHYMODE_NONE; - break; - case EMAC_PHY_MODE_NONE_MII: - /* 1 x MII port on channel 0 */ - rgmiifer |= RGMII_FER_MII << 0; - rgmiifer |= RGMII_FER_DIS << 4; - out_be32((void *)RGMII_FER, rgmiifer); - bis->bi_phymode[0] = BI_PHYMODE_MII; - bis->bi_phymode[1] = BI_PHYMODE_NONE; - break; - case EMAC_PHY_MODE_GMII_NONE: - /* 1 x GMII port on channel 1 */ - rgmiifer |= RGMII_FER_DIS << 0; - rgmiifer |= RGMII_FER_GMII << 4; - out_be32((void *)RGMII_FER, rgmiifer); - bis->bi_phymode[0] = BI_PHYMODE_NONE; - bis->bi_phymode[1] = BI_PHYMODE_GMII; - break; - case EMAC_PHY_MODE_MII_NONE: - /* 1 x MII port on channel 1 */ - rgmiifer |= RGMII_FER_DIS << 0; - rgmiifer |= RGMII_FER_MII << 4; - out_be32((void *)RGMII_FER, rgmiifer); - bis->bi_phymode[0] = BI_PHYMODE_NONE; - bis->bi_phymode[1] = BI_PHYMODE_MII; - break; - default: - break; - } - - /* Ensure we setup mdio for this devnum and ONLY this devnum */ - rgmiifer = in_be32((void *)RGMII_FER); - rgmiifer |= (1 << (19-devnum)); - out_be32((void *)RGMII_FER, rgmiifer); - - return ((int)0x0); -} -#endif /* CONFIG_405EX */ - -#if defined(CONFIG_460EX) || defined(CONFIG_460GT) -int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis) -{ - u32 eth_cfg; - u32 zmiifer; /* ZMII0_FER reg. */ - u32 rmiifer; /* RGMII0_FER reg. Bridge 0 */ - u32 rmiifer1; /* RGMII0_FER reg. Bridge 1 */ - int mode; - - zmiifer = 0; - rmiifer = 0; - rmiifer1 = 0; - -#if defined(CONFIG_460EX) - mode = 9; - mfsdr(SDR0_ETH_CFG, eth_cfg); - if (((eth_cfg & SDR0_ETH_CFG_SGMII0_ENABLE) > 0) && - ((eth_cfg & SDR0_ETH_CFG_SGMII1_ENABLE) > 0)) - mode = 11; /* config SGMII */ -#else - mode = 10; - mfsdr(SDR0_ETH_CFG, eth_cfg); - if (((eth_cfg & SDR0_ETH_CFG_SGMII0_ENABLE) > 0) && - ((eth_cfg & SDR0_ETH_CFG_SGMII1_ENABLE) > 0) && - ((eth_cfg & SDR0_ETH_CFG_SGMII2_ENABLE) > 0)) - mode = 12; /* config SGMII */ -#endif - - /* TODO: - * NOTE: 460GT has 2 RGMII bridge cores: - * emac0 ------ RGMII0_BASE - * | - * emac1 -----+ - * - * emac2 ------ RGMII1_BASE - * | - * emac3 -----+ - * - * 460EX has 1 RGMII bridge core: - * and RGMII1_BASE is disabled - * emac0 ------ RGMII0_BASE - * | - * emac1 -----+ - */ - - /* - * Right now only 2*RGMII is supported. Please extend when needed. - * sr - 2008-02-19 - * Add SGMII support. - * vg - 2008-07-28 - */ - switch (mode) { - case 1: - /* 1 MII - 460EX */ - /* GMC0 EMAC4_0, ZMII Bridge */ - zmiifer |= ZMII_FER_MII << ZMII_FER_V(0); - bis->bi_phymode[0] = BI_PHYMODE_MII; - bis->bi_phymode[1] = BI_PHYMODE_NONE; - bis->bi_phymode[2] = BI_PHYMODE_NONE; - bis->bi_phymode[3] = BI_PHYMODE_NONE; - break; - case 2: - /* 2 MII - 460GT */ - /* GMC0 EMAC4_0, GMC1 EMAC4_2, ZMII Bridge */ - zmiifer |= ZMII_FER_MII << ZMII_FER_V(0); - zmiifer |= ZMII_FER_MII << ZMII_FER_V(2); - bis->bi_phymode[0] = BI_PHYMODE_MII; - bis->bi_phymode[1] = BI_PHYMODE_NONE; - bis->bi_phymode[2] = BI_PHYMODE_MII; - bis->bi_phymode[3] = BI_PHYMODE_NONE; - break; - case 3: - /* 2 RMII - 460EX */ - /* GMC0 EMAC4_0, GMC0 EMAC4_1, ZMII Bridge */ - zmiifer |= ZMII_FER_RMII << ZMII_FER_V(0); - zmiifer |= ZMII_FER_RMII << ZMII_FER_V(1); - bis->bi_phymode[0] = BI_PHYMODE_RMII; - bis->bi_phymode[1] = BI_PHYMODE_RMII; - bis->bi_phymode[2] = BI_PHYMODE_NONE; - bis->bi_phymode[3] = BI_PHYMODE_NONE; - break; - case 4: - /* 4 RMII - 460GT */ - /* GMC0 EMAC4_0, GMC0 EMAC4_1, GMC1 EMAC4_2, GMC1, EMAC4_3 */ - /* ZMII Bridge */ - zmiifer |= ZMII_FER_RMII << ZMII_FER_V(0); - zmiifer |= ZMII_FER_RMII << ZMII_FER_V(1); - zmiifer |= ZMII_FER_RMII << ZMII_FER_V(2); - zmiifer |= ZMII_FER_RMII << ZMII_FER_V(3); - bis->bi_phymode[0] = BI_PHYMODE_RMII; - bis->bi_phymode[1] = BI_PHYMODE_RMII; - bis->bi_phymode[2] = BI_PHYMODE_RMII; - bis->bi_phymode[3] = BI_PHYMODE_RMII; - break; - case 5: - /* 2 SMII - 460EX */ - /* GMC0 EMAC4_0, GMC0 EMAC4_1, ZMII Bridge */ - zmiifer |= ZMII_FER_SMII << ZMII_FER_V(0); - zmiifer |= ZMII_FER_SMII << ZMII_FER_V(1); - bis->bi_phymode[0] = BI_PHYMODE_SMII; - bis->bi_phymode[1] = BI_PHYMODE_SMII; - bis->bi_phymode[2] = BI_PHYMODE_NONE; - bis->bi_phymode[3] = BI_PHYMODE_NONE; - break; - case 6: - /* 4 SMII - 460GT */ - /* GMC0 EMAC4_0, GMC0 EMAC4_1, GMC0 EMAC4_3, GMC0 EMAC4_3 */ - /* ZMII Bridge */ - zmiifer |= ZMII_FER_SMII << ZMII_FER_V(0); - zmiifer |= ZMII_FER_SMII << ZMII_FER_V(1); - zmiifer |= ZMII_FER_SMII << ZMII_FER_V(2); - zmiifer |= ZMII_FER_SMII << ZMII_FER_V(3); - bis->bi_phymode[0] = BI_PHYMODE_SMII; - bis->bi_phymode[1] = BI_PHYMODE_SMII; - bis->bi_phymode[2] = BI_PHYMODE_SMII; - bis->bi_phymode[3] = BI_PHYMODE_SMII; - break; - case 7: - /* This is the default mode that we want for board bringup - Maple */ - /* 1 GMII - 460EX */ - /* GMC0 EMAC4_0, RGMII Bridge 0 */ - rmiifer |= RGMII_FER_MDIO(0); - - if (devnum == 0) { - rmiifer |= RGMII_FER_GMII << RGMII_FER_V(2); /* CH0CFG - EMAC0 */ - bis->bi_phymode[0] = BI_PHYMODE_GMII; - bis->bi_phymode[1] = BI_PHYMODE_NONE; - bis->bi_phymode[2] = BI_PHYMODE_NONE; - bis->bi_phymode[3] = BI_PHYMODE_NONE; - } else { - rmiifer |= RGMII_FER_GMII << RGMII_FER_V(3); /* CH1CFG - EMAC1 */ - bis->bi_phymode[0] = BI_PHYMODE_NONE; - bis->bi_phymode[1] = BI_PHYMODE_GMII; - bis->bi_phymode[2] = BI_PHYMODE_NONE; - bis->bi_phymode[3] = BI_PHYMODE_NONE; - } - break; - case 8: - /* 2 GMII - 460GT */ - /* GMC0 EMAC4_0, RGMII Bridge 0 */ - /* GMC1 EMAC4_2, RGMII Bridge 1 */ - rmiifer |= RGMII_FER_GMII << RGMII_FER_V(2); /* CH0CFG - EMAC0 */ - rmiifer1 |= RGMII_FER_GMII << RGMII_FER_V(2); /* CH0CFG - EMAC2 */ - rmiifer |= RGMII_FER_MDIO(0); /* enable MDIO - EMAC0 */ - rmiifer1 |= RGMII_FER_MDIO(0); /* enable MDIO - EMAC2 */ - - bis->bi_phymode[0] = BI_PHYMODE_GMII; - bis->bi_phymode[1] = BI_PHYMODE_NONE; - bis->bi_phymode[2] = BI_PHYMODE_GMII; - bis->bi_phymode[3] = BI_PHYMODE_NONE; - break; - case 9: - /* 2 RGMII - 460EX */ - /* GMC0 EMAC4_0, GMC0 EMAC4_1, RGMII Bridge 0 */ - rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(2); - rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(3); - rmiifer |= RGMII_FER_MDIO(0); /* enable MDIO - EMAC0 */ - - bis->bi_phymode[0] = BI_PHYMODE_RGMII; - bis->bi_phymode[1] = BI_PHYMODE_RGMII; - bis->bi_phymode[2] = BI_PHYMODE_NONE; - bis->bi_phymode[3] = BI_PHYMODE_NONE; - break; - case 10: - /* 4 RGMII - 460GT */ - /* GMC0 EMAC4_0, GMC0 EMAC4_1, RGMII Bridge 0 */ - /* GMC1 EMAC4_2, GMC1 EMAC4_3, RGMII Bridge 1 */ - rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(2); - rmiifer |= RGMII_FER_RGMII << RGMII_FER_V(3); - rmiifer1 |= RGMII_FER_RGMII << RGMII_FER_V(2); - rmiifer1 |= RGMII_FER_RGMII << RGMII_FER_V(3); - bis->bi_phymode[0] = BI_PHYMODE_RGMII; - bis->bi_phymode[1] = BI_PHYMODE_RGMII; - bis->bi_phymode[2] = BI_PHYMODE_RGMII; - bis->bi_phymode[3] = BI_PHYMODE_RGMII; - break; - case 11: - /* 2 SGMII - 460EX */ - bis->bi_phymode[0] = BI_PHYMODE_SGMII; - bis->bi_phymode[1] = BI_PHYMODE_SGMII; - bis->bi_phymode[2] = BI_PHYMODE_NONE; - bis->bi_phymode[3] = BI_PHYMODE_NONE; - break; - case 12: - /* 3 SGMII - 460GT */ - bis->bi_phymode[0] = BI_PHYMODE_SGMII; - bis->bi_phymode[1] = BI_PHYMODE_SGMII; - bis->bi_phymode[2] = BI_PHYMODE_SGMII; - bis->bi_phymode[3] = BI_PHYMODE_NONE; - break; - default: - break; - } - - /* Set EMAC for MDIO */ - mfsdr(SDR0_ETH_CFG, eth_cfg); - eth_cfg |= SDR0_ETH_CFG_MDIO_SEL_EMAC0; - mtsdr(SDR0_ETH_CFG, eth_cfg); - - out_be32((void *)RGMII_FER, rmiifer); -#if defined(CONFIG_460GT) - out_be32((void *)RGMII_FER + RGMII1_BASE_OFFSET, rmiifer1); -#endif - - /* bypass the TAHOE0/TAHOE1 cores for U-Boot */ - mfsdr(SDR0_ETH_CFG, eth_cfg); - eth_cfg |= (SDR0_ETH_CFG_TAHOE0_BYPASS | SDR0_ETH_CFG_TAHOE1_BYPASS); - mtsdr(SDR0_ETH_CFG, eth_cfg); - - return 0; -} -#endif /* CONFIG_460EX || CONFIG_460GT */ - -static inline void *malloc_aligned(u32 size, u32 align) -{ - return (void *)(((u32)malloc(size + align) + align - 1) & - ~(align - 1)); -} - -static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis) -{ - int i; - unsigned long reg = 0; - unsigned long msr; - unsigned long speed; - unsigned long duplex; - unsigned long failsafe; - unsigned mode_reg; - unsigned short devnum; - unsigned short reg_short; -#if defined(CONFIG_440GX) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ - defined(CONFIG_405EX) - u32 opbfreq; - sys_info_t sysinfo; -#if defined(CONFIG_440GX) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ - defined(CONFIG_405EX) - __maybe_unused int ethgroup = -1; -#endif -#endif - u32 bd_cached; - u32 bd_uncached = 0; -#ifdef CONFIG_4xx_DCACHE - static u32 last_used_ea = 0; -#endif -#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ - defined(CONFIG_405EX) - int rgmii_channel; -#endif - - EMAC_4XX_HW_PST hw_p = dev->priv; - - /* before doing anything, figure out if we have a MAC address */ - /* if not, bail */ - if (memcmp (dev->enetaddr, "\0\0\0\0\0\0", 6) == 0) { - printf("ERROR: ethaddr not set!\n"); - return -1; - } - -#if defined(CONFIG_440GX) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ - defined(CONFIG_405EX) - /* Need to get the OPB frequency so we can access the PHY */ - get_sys_info (&sysinfo); -#endif - - msr = mfmsr (); - mtmsr (msr & ~(MSR_EE)); /* disable interrupts */ - - devnum = hw_p->devnum; - -#ifdef INFO_4XX_ENET - /* AS.HARNOIS - * We should have : - * hw_p->stats.pkts_handled <= hw_p->stats.pkts_rx <= hw_p->stats.pkts_handled+PKTBUFSRX - * In the most cases hw_p->stats.pkts_handled = hw_p->stats.pkts_rx, but it - * is possible that new packets (without relationship with - * current transfer) have got the time to arrived before - * netloop calls eth_halt - */ - printf ("About preceeding transfer (eth%d):\n" - "- Sent packet number %d\n" - "- Received packet number %d\n" - "- Handled packet number %d\n", - hw_p->devnum, - hw_p->stats.pkts_tx, - hw_p->stats.pkts_rx, hw_p->stats.pkts_handled); - - hw_p->stats.pkts_tx = 0; - hw_p->stats.pkts_rx = 0; - hw_p->stats.pkts_handled = 0; - hw_p->print_speed = 1; /* print speed message again next time */ -#endif - - hw_p->tx_err_index = 0; /* Transmit Error Index for tx_err_log */ - hw_p->rx_err_index = 0; /* Receive Error Index for rx_err_log */ - - hw_p->rx_slot = 0; /* MAL Receive Slot */ - hw_p->rx_i_index = 0; /* Receive Interrupt Queue Index */ - hw_p->rx_u_index = 0; /* Receive User Queue Index */ - - hw_p->tx_slot = 0; /* MAL Transmit Slot */ - hw_p->tx_i_index = 0; /* Transmit Interrupt Queue Index */ - hw_p->tx_u_index = 0; /* Transmit User Queue Index */ - -#if defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) - /* set RMII mode */ - /* NOTE: 440GX spec states that mode is mutually exclusive */ - /* NOTE: Therefore, disable all other EMACS, since we handle */ - /* NOTE: only one emac at a time */ - reg = 0; - out_be32((void *)ZMII0_FER, 0); - udelay (100); - -#if defined(CONFIG_440GP) || defined(CONFIG_440EP) || defined(CONFIG_440GR) - out_be32((void *)ZMII0_FER, (ZMII_FER_RMII | ZMII_FER_MDI) << ZMII_FER_V (devnum)); -#elif defined(CONFIG_440GX) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) - ethgroup = ppc_4xx_eth_setup_bridge(devnum, bis); -#endif - - out_be32((void *)ZMII0_SSR, ZMII0_SSR_SP << ZMII0_SSR_V(devnum)); -#endif /* defined(CONFIG_440) && !defined(CONFIG_440SP) */ -#if defined(CONFIG_405EX) - ethgroup = ppc_4xx_eth_setup_bridge(devnum, bis); -#endif - - sync(); - - /* provide clocks for EMAC internal loopback */ - emac_loopback_enable(hw_p); - - /* EMAC RESET */ - out_be32((void *)EMAC0_MR0 + hw_p->hw_addr, EMAC_MR0_SRST); - - /* remove clocks for EMAC internal loopback */ - emac_loopback_disable(hw_p); - - failsafe = 1000; - while ((in_be32((void *)EMAC0_MR0 + hw_p->hw_addr) & (EMAC_MR0_SRST)) && failsafe) { - udelay (1000); - failsafe--; - } - if (failsafe <= 0) - printf("\nProblem resetting EMAC!\n"); - -#if defined(CONFIG_440GX) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ - defined(CONFIG_405EX) - /* Whack the M1 register */ - mode_reg = 0x0; - mode_reg &= ~0x00000038; - opbfreq = sysinfo.freqOPB / 1000000; - if (opbfreq <= 50); - else if (opbfreq <= 66) - mode_reg |= EMAC_MR1_OBCI_66; - else if (opbfreq <= 83) - mode_reg |= EMAC_MR1_OBCI_83; - else if (opbfreq <= 100) - mode_reg |= EMAC_MR1_OBCI_100; - else - mode_reg |= EMAC_MR1_OBCI_GT100; - - out_be32((void *)EMAC0_MR1 + hw_p->hw_addr, mode_reg); -#endif /* defined(CONFIG_440GX) || defined(CONFIG_440SP) */ - -#if defined(CONFIG_GPCS_PHY_ADDR) || defined(CONFIG_GPCS_PHY1_ADDR) || \ - defined(CONFIG_GPCS_PHY2_ADDR) || defined(CONFIG_GPCS_PHY3_ADDR) - if (bis->bi_phymode[devnum] == BI_PHYMODE_SGMII) { - /* - * In SGMII mode, GPCS access is needed for - * communication with the internal SGMII SerDes. - */ - switch (devnum) { -#if defined(CONFIG_GPCS_PHY_ADDR) - case 0: - reg = CONFIG_GPCS_PHY_ADDR; - break; -#endif -#if defined(CONFIG_GPCS_PHY1_ADDR) - case 1: - reg = CONFIG_GPCS_PHY1_ADDR; - break; -#endif -#if defined(CONFIG_GPCS_PHY2_ADDR) - case 2: - reg = CONFIG_GPCS_PHY2_ADDR; - break; -#endif -#if defined(CONFIG_GPCS_PHY3_ADDR) - case 3: - reg = CONFIG_GPCS_PHY3_ADDR; - break; -#endif - } - - mode_reg = in_be32((void *)EMAC0_MR1 + hw_p->hw_addr); - mode_reg |= EMAC_MR1_MF_1000GPCS | EMAC_MR1_IPPA_SET(reg); - out_be32((void *)EMAC0_MR1 + hw_p->hw_addr, mode_reg); - - /* Configure GPCS interface to recommended setting for SGMII */ - miiphy_reset(dev->name, reg); - miiphy_write(dev->name, reg, 0x04, 0x8120); /* AsymPause, FDX */ - miiphy_write(dev->name, reg, 0x07, 0x2801); /* msg_pg, toggle */ - miiphy_write(dev->name, reg, 0x00, 0x0140); /* 1Gbps, FDX */ - } -#endif /* defined(CONFIG_GPCS_PHY_ADDR) */ - - /* wait for PHY to complete auto negotiation */ - reg_short = 0; - switch (devnum) { - case 0: - reg = CONFIG_PHY_ADDR; - break; -#if defined (CONFIG_PHY1_ADDR) - case 1: - reg = CONFIG_PHY1_ADDR; - break; -#endif -#if defined (CONFIG_PHY2_ADDR) - case 2: - reg = CONFIG_PHY2_ADDR; - break; -#endif -#if defined (CONFIG_PHY3_ADDR) - case 3: - reg = CONFIG_PHY3_ADDR; - break; -#endif - default: - reg = CONFIG_PHY_ADDR; - break; - } - - bis->bi_phynum[devnum] = reg; - - if (reg == CONFIG_FIXED_PHY) - goto get_speed; - -#if defined(CONFIG_PHY_RESET) - /* - * Reset the phy, only if its the first time through - * otherwise, just check the speeds & feeds - */ - if (hw_p->first_init == 0) { -#if defined(CONFIG_M88E1111_PHY) - miiphy_write (dev->name, reg, 0x14, 0x0ce3); - miiphy_write (dev->name, reg, 0x18, 0x4101); - miiphy_write (dev->name, reg, 0x09, 0x0e00); - miiphy_write (dev->name, reg, 0x04, 0x01e1); -#if defined(CONFIG_M88E1111_DISABLE_FIBER) - miiphy_read(dev->name, reg, 0x1b, ®_short); - reg_short |= 0x8000; - miiphy_write(dev->name, reg, 0x1b, reg_short); -#endif -#endif -#if defined(CONFIG_M88E1112_PHY) - if (bis->bi_phymode[devnum] == BI_PHYMODE_SGMII) { - /* - * Marvell 88E1112 PHY needs to have the SGMII MAC - * interace (page 2) properly configured to - * communicate with the 460EX/GT GPCS interface. - */ - - /* Set access to Page 2 */ - miiphy_write(dev->name, reg, 0x16, 0x0002); - - miiphy_write(dev->name, reg, 0x00, 0x0040); /* 1Gbps */ - miiphy_read(dev->name, reg, 0x1a, ®_short); - reg_short |= 0x8000; /* bypass Auto-Negotiation */ - miiphy_write(dev->name, reg, 0x1a, reg_short); - miiphy_reset(dev->name, reg); /* reset MAC interface */ - - /* Reset access to Page 0 */ - miiphy_write(dev->name, reg, 0x16, 0x0000); - } -#endif /* defined(CONFIG_M88E1112_PHY) */ - miiphy_reset (dev->name, reg); - -#if defined(CONFIG_440GX) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ - defined(CONFIG_405EX) - -#if defined(CONFIG_CIS8201_PHY) - /* - * Cicada 8201 PHY needs to have an extended register whacked - * for RGMII mode. - */ - if (((devnum == 2) || (devnum == 3)) && (4 == ethgroup)) { -#if defined(CONFIG_CIS8201_SHORT_ETCH) - miiphy_write (dev->name, reg, 23, 0x1300); -#else - miiphy_write (dev->name, reg, 23, 0x1000); -#endif - /* - * Vitesse VSC8201/Cicada CIS8201 errata: - * Interoperability problem with Intel 82547EI phys - * This work around (provided by Vitesse) changes - * the default timer convergence from 8ms to 12ms - */ - miiphy_write (dev->name, reg, 0x1f, 0x2a30); - miiphy_write (dev->name, reg, 0x08, 0x0200); - miiphy_write (dev->name, reg, 0x1f, 0x52b5); - miiphy_write (dev->name, reg, 0x02, 0x0004); - miiphy_write (dev->name, reg, 0x01, 0x0671); - miiphy_write (dev->name, reg, 0x00, 0x8fae); - miiphy_write (dev->name, reg, 0x1f, 0x2a30); - miiphy_write (dev->name, reg, 0x08, 0x0000); - miiphy_write (dev->name, reg, 0x1f, 0x0000); - /* end Vitesse/Cicada errata */ - } -#endif /* defined(CONFIG_CIS8201_PHY) */ - -#if defined(CONFIG_ET1011C_PHY) - /* - * Agere ET1011c PHY needs to have an extended register whacked - * for RGMII mode. - */ - if (((devnum == 2) || (devnum ==3)) && (4 == ethgroup)) { - miiphy_read (dev->name, reg, 0x16, ®_short); - reg_short &= ~(0x7); - reg_short |= 0x6; /* RGMII DLL Delay*/ - miiphy_write (dev->name, reg, 0x16, reg_short); - - miiphy_read (dev->name, reg, 0x17, ®_short); - reg_short &= ~(0x40); - miiphy_write (dev->name, reg, 0x17, reg_short); - - miiphy_write(dev->name, reg, 0x1c, 0x74f0); - } -#endif /* defined(CONFIG_ET1011C_PHY) */ - -#endif /* defined(CONFIG_440GX) ... */ - /* Start/Restart autonegotiation */ - phy_setup_aneg (dev->name, reg); - udelay (1000); - } -#endif /* defined(CONFIG_PHY_RESET) */ - - miiphy_read (dev->name, reg, MII_BMSR, ®_short); - - /* - * Wait if PHY is capable of autonegotiation and autonegotiation is not complete - */ - if ((reg_short & BMSR_ANEGCAPABLE) - && !(reg_short & BMSR_ANEGCOMPLETE)) { - puts ("Waiting for PHY auto negotiation to complete"); - i = 0; - while (!(reg_short & BMSR_ANEGCOMPLETE)) { - /* - * Timeout reached ? - */ - if (i > PHY_AUTONEGOTIATE_TIMEOUT) { - puts (" TIMEOUT !\n"); - break; - } - - if ((i++ % 1000) == 0) { - putc ('.'); - } - udelay (1000); /* 1 ms */ - miiphy_read (dev->name, reg, MII_BMSR, ®_short); - } - puts (" done\n"); - udelay (500000); /* another 500 ms (results in faster booting) */ - } - -get_speed: - if (reg == CONFIG_FIXED_PHY) { - for (i = 0; i < ARRAY_SIZE(fixed_phy_port); i++) { - if (devnum == fixed_phy_port[i].devnum) { - speed = fixed_phy_port[i].speed; - duplex = fixed_phy_port[i].duplex; - break; - } - } - - if (i == ARRAY_SIZE(fixed_phy_port)) { - printf("ERROR: PHY (%s) not configured correctly!\n", - dev->name); - return -1; - } - } else { - speed = miiphy_speed(dev->name, reg); - duplex = miiphy_duplex(dev->name, reg); - } - - if (hw_p->print_speed) { - hw_p->print_speed = 0; - printf ("ENET Speed is %d Mbps - %s duplex connection (EMAC%d)\n", - (int) speed, (duplex == HALF) ? "HALF" : "FULL", - hw_p->devnum); - } - -#if defined(CONFIG_440) && \ - !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \ - !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX) && \ - !defined(CONFIG_460EX) && !defined(CONFIG_460GT) -#if defined(CONFIG_440EP) || defined(CONFIG_440GR) - mfsdr(SDR0_MFR, reg); - if (speed == 100) { - reg = (reg & ~SDR0_MFR_ZMII_MODE_MASK) | SDR0_MFR_ZMII_MODE_RMII_100M; - } else { - reg = (reg & ~SDR0_MFR_ZMII_MODE_MASK) | SDR0_MFR_ZMII_MODE_RMII_10M; - } - mtsdr(SDR0_MFR, reg); -#endif - - /* Set ZMII/RGMII speed according to the phy link speed */ - reg = in_be32((void *)ZMII0_SSR); - if ( (speed == 100) || (speed == 1000) ) - out_be32((void *)ZMII0_SSR, reg | (ZMII0_SSR_SP << ZMII0_SSR_V (devnum))); - else - out_be32((void *)ZMII0_SSR, reg & (~(ZMII0_SSR_SP << ZMII0_SSR_V (devnum)))); - - if ((devnum == 2) || (devnum == 3)) { - if (speed == 1000) - reg = (RGMII_SSR_SP_1000MBPS << RGMII_SSR_V (devnum)); - else if (speed == 100) - reg = (RGMII_SSR_SP_100MBPS << RGMII_SSR_V (devnum)); - else if (speed == 10) - reg = (RGMII_SSR_SP_10MBPS << RGMII_SSR_V (devnum)); - else { - printf("Error in RGMII Speed\n"); - return -1; - } - out_be32((void *)RGMII_SSR, reg); - } -#endif /* defined(CONFIG_440) && !defined(CONFIG_440SP) */ - -#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ - defined(CONFIG_405EX) - if (devnum >= 2) - rgmii_channel = devnum - 2; - else - rgmii_channel = devnum; - - if (speed == 1000) - reg = (RGMII_SSR_SP_1000MBPS << RGMII_SSR_V(rgmii_channel)); - else if (speed == 100) - reg = (RGMII_SSR_SP_100MBPS << RGMII_SSR_V(rgmii_channel)); - else if (speed == 10) - reg = (RGMII_SSR_SP_10MBPS << RGMII_SSR_V(rgmii_channel)); - else { - printf("Error in RGMII Speed\n"); - return -1; - } - out_be32((void *)RGMII_SSR, reg); -#if defined(CONFIG_460GT) - if ((devnum == 2) || (devnum == 3)) - out_be32((void *)RGMII_SSR + RGMII1_BASE_OFFSET, reg); -#endif -#endif - - /* set the Mal configuration reg */ -#if defined(CONFIG_440GX) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ - defined(CONFIG_405EX) - mtdcr (MAL0_CFG, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA | - MAL_CR_PLBLT_DEFAULT | MAL_CR_EOPIE | 0x00330000); -#else - mtdcr (MAL0_CFG, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA | MAL_CR_PLBLT_DEFAULT); - /* Errata 1.12: MAL_1 -- Disable MAL bursting */ - if (get_pvr() == PVR_440GP_RB) { - mtdcr (MAL0_CFG, mfdcr(MAL0_CFG) & ~MAL_CR_PLBB); - } -#endif - - /* - * Malloc MAL buffer desciptors, make sure they are - * aligned on cache line boundary size - * (401/403/IOP480 = 16, 405 = 32) - * and doesn't cross cache block boundaries. - */ - if (hw_p->first_init == 0) { - debug("*** Allocating descriptor memory ***\n"); - - bd_cached = (u32)malloc_aligned(MAL_ALLOC_SIZE, 4096); - if (!bd_cached) { - printf("%s: Error allocating MAL descriptor buffers!\n", __func__); - return -1; - } - -#ifdef CONFIG_4xx_DCACHE - flush_dcache_range(bd_cached, bd_cached + MAL_ALLOC_SIZE); - if (!last_used_ea) -#if defined(CONFIG_SYS_MEM_TOP_HIDE) - bd_uncached = bis->bi_memsize + CONFIG_SYS_MEM_TOP_HIDE; -#else - bd_uncached = bis->bi_memsize; -#endif - else - bd_uncached = last_used_ea + MAL_ALLOC_SIZE; - - last_used_ea = bd_uncached; - program_tlb(bd_cached, bd_uncached, MAL_ALLOC_SIZE, - TLB_WORD2_I_ENABLE); -#else - bd_uncached = bd_cached; -#endif - hw_p->tx_phys = bd_cached; - hw_p->rx_phys = bd_cached + MAL_TX_DESC_SIZE; - hw_p->tx = (mal_desc_t *)(bd_uncached); - hw_p->rx = (mal_desc_t *)(bd_uncached + MAL_TX_DESC_SIZE); - debug("hw_p->tx=%p, hw_p->rx=%p\n", hw_p->tx, hw_p->rx); - } - - for (i = 0; i < NUM_TX_BUFF; i++) { - hw_p->tx[i].ctrl = 0; - hw_p->tx[i].data_len = 0; - if (hw_p->first_init == 0) - hw_p->txbuf_ptr = malloc_aligned(MAL_ALLOC_SIZE, - L1_CACHE_BYTES); - hw_p->tx[i].data_ptr = hw_p->txbuf_ptr; - if ((NUM_TX_BUFF - 1) == i) - hw_p->tx[i].ctrl |= MAL_TX_CTRL_WRAP; - hw_p->tx_run[i] = -1; - debug("TX_BUFF %d @ 0x%08x\n", i, (u32)hw_p->tx[i].data_ptr); - } - - for (i = 0; i < NUM_RX_BUFF; i++) { - hw_p->rx[i].ctrl = 0; - hw_p->rx[i].data_len = 0; - hw_p->rx[i].data_ptr = (char *)NetRxPackets[i]; - if ((NUM_RX_BUFF - 1) == i) - hw_p->rx[i].ctrl |= MAL_RX_CTRL_WRAP; - hw_p->rx[i].ctrl |= MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR; - hw_p->rx_ready[i] = -1; - debug("RX_BUFF %d @ 0x%08x\n", i, (u32)hw_p->rx[i].data_ptr); - } - - reg = 0x00000000; - - reg |= dev->enetaddr[0]; /* set high address */ - reg = reg << 8; - reg |= dev->enetaddr[1]; - - out_be32((void *)EMAC0_IAH + hw_p->hw_addr, reg); - - reg = 0x00000000; - reg |= dev->enetaddr[2]; /* set low address */ - reg = reg << 8; - reg |= dev->enetaddr[3]; - reg = reg << 8; - reg |= dev->enetaddr[4]; - reg = reg << 8; - reg |= dev->enetaddr[5]; - - out_be32((void *)EMAC0_IAL + hw_p->hw_addr, reg); - - switch (devnum) { - case 1: - /* setup MAL tx & rx channel pointers */ -#if defined (CONFIG_405EP) || defined (CONFIG_440EP) || defined (CONFIG_440GR) - mtdcr (MAL0_TXCTP2R, hw_p->tx_phys); -#else - mtdcr (MAL0_TXCTP1R, hw_p->tx_phys); -#endif -#if defined(CONFIG_440) - mtdcr (MAL0_TXBADDR, 0x0); - mtdcr (MAL0_RXBADDR, 0x0); -#endif - -#if defined(CONFIG_460EX) || defined(CONFIG_460GT) - mtdcr (MAL0_RXCTP8R, hw_p->rx_phys); - /* set RX buffer size */ - mtdcr (MAL0_RCBS8, ENET_MAX_MTU_ALIGNED / 16); -#else - mtdcr (MAL0_RXCTP1R, hw_p->rx_phys); - /* set RX buffer size */ - mtdcr (MAL0_RCBS1, ENET_MAX_MTU_ALIGNED / 16); -#endif - break; -#if defined (CONFIG_440GX) - case 2: - /* setup MAL tx & rx channel pointers */ - mtdcr (MAL0_TXBADDR, 0x0); - mtdcr (MAL0_RXBADDR, 0x0); - mtdcr (MAL0_TXCTP2R, hw_p->tx_phys); - mtdcr (MAL0_RXCTP2R, hw_p->rx_phys); - /* set RX buffer size */ - mtdcr (MAL0_RCBS2, ENET_MAX_MTU_ALIGNED / 16); - break; - case 3: - /* setup MAL tx & rx channel pointers */ - mtdcr (MAL0_TXBADDR, 0x0); - mtdcr (MAL0_TXCTP3R, hw_p->tx_phys); - mtdcr (MAL0_RXBADDR, 0x0); - mtdcr (MAL0_RXCTP3R, hw_p->rx_phys); - /* set RX buffer size */ - mtdcr (MAL0_RCBS3, ENET_MAX_MTU_ALIGNED / 16); - break; -#endif /* CONFIG_440GX */ -#if defined (CONFIG_460GT) - case 2: - /* setup MAL tx & rx channel pointers */ - mtdcr (MAL0_TXBADDR, 0x0); - mtdcr (MAL0_RXBADDR, 0x0); - mtdcr (MAL0_TXCTP2R, hw_p->tx_phys); - mtdcr (MAL0_RXCTP16R, hw_p->rx_phys); - /* set RX buffer size */ - mtdcr (MAL0_RCBS16, ENET_MAX_MTU_ALIGNED / 16); - break; - case 3: - /* setup MAL tx & rx channel pointers */ - mtdcr (MAL0_TXBADDR, 0x0); - mtdcr (MAL0_RXBADDR, 0x0); - mtdcr (MAL0_TXCTP3R, hw_p->tx_phys); - mtdcr (MAL0_RXCTP24R, hw_p->rx_phys); - /* set RX buffer size */ - mtdcr (MAL0_RCBS24, ENET_MAX_MTU_ALIGNED / 16); - break; -#endif /* CONFIG_460GT */ - case 0: - default: - /* setup MAL tx & rx channel pointers */ -#if defined(CONFIG_440) - mtdcr (MAL0_TXBADDR, 0x0); - mtdcr (MAL0_RXBADDR, 0x0); -#endif - mtdcr (MAL0_TXCTP0R, hw_p->tx_phys); - mtdcr (MAL0_RXCTP0R, hw_p->rx_phys); - /* set RX buffer size */ - mtdcr (MAL0_RCBS0, ENET_MAX_MTU_ALIGNED / 16); - break; - } - - /* Enable MAL transmit and receive channels */ -#if defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR) - mtdcr (MAL0_TXCASR, (MAL_TXRX_CASR >> (hw_p->devnum*2))); -#else - mtdcr (MAL0_TXCASR, (MAL_TXRX_CASR >> hw_p->devnum)); -#endif - mtdcr (MAL0_RXCASR, (MAL_TXRX_CASR >> hw_p->devnum)); - - /* set transmit enable & receive enable */ - out_be32((void *)EMAC0_MR0 + hw_p->hw_addr, EMAC_MR0_TXE | EMAC_MR0_RXE); - - mode_reg = in_be32((void *)EMAC0_MR1 + hw_p->hw_addr); - - /* set rx-/tx-fifo size */ - mode_reg = (mode_reg & ~EMAC_MR1_FIFO_MASK) | EMAC_MR1_FIFO_SIZE; - - /* set speed */ - if (speed == _1000BASET) { -#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) - unsigned long pfc1; - - mfsdr (SDR0_PFC1, pfc1); - pfc1 |= SDR0_PFC1_EM_1000; - mtsdr (SDR0_PFC1, pfc1); -#endif - mode_reg = mode_reg | EMAC_MR1_MF_1000MBPS | EMAC_MR1_IST; - } else if (speed == _100BASET) - mode_reg = mode_reg | EMAC_MR1_MF_100MBPS | EMAC_MR1_IST; - else - mode_reg = mode_reg & ~0x00C00000; /* 10 MBPS */ - if (duplex == FULL) - mode_reg = mode_reg | 0x80000000 | EMAC_MR1_IST; - - out_be32((void *)EMAC0_MR1 + hw_p->hw_addr, mode_reg); - - /* Enable broadcast and indvidual address */ - /* TBS: enabling runts as some misbehaved nics will send runts */ - out_be32((void *)EMAC0_RXM + hw_p->hw_addr, EMAC_RMR_BAE | EMAC_RMR_IAE); - - /* we probably need to set the tx mode1 reg? maybe at tx time */ - - /* set transmit request threshold register */ - out_be32((void *)EMAC0_TRTR + hw_p->hw_addr, 0x18000000); /* 256 byte threshold */ - - /* set receive low/high water mark register */ -#if defined(CONFIG_440) - /* 440s has a 64 byte burst length */ - out_be32((void *)EMAC0_RX_HI_LO_WMARK + hw_p->hw_addr, 0x80009000); -#else - /* 405s have a 16 byte burst length */ - out_be32((void *)EMAC0_RX_HI_LO_WMARK + hw_p->hw_addr, 0x0f002000); -#endif /* defined(CONFIG_440) */ - out_be32((void *)EMAC0_TMR1 + hw_p->hw_addr, 0xf8640000); - - /* Set fifo limit entry in tx mode 0 */ - out_be32((void *)EMAC0_TMR0 + hw_p->hw_addr, 0x00000003); - /* Frame gap set */ - out_be32((void *)EMAC0_I_FRAME_GAP_REG + hw_p->hw_addr, 0x00000008); - - /* Set EMAC IER */ - hw_p->emac_ier = EMAC_ISR_PTLE | EMAC_ISR_BFCS | EMAC_ISR_ORE | EMAC_ISR_IRE; - if (speed == _100BASET) - hw_p->emac_ier = hw_p->emac_ier | EMAC_ISR_SYE; - - out_be32((void *)EMAC0_ISR + hw_p->hw_addr, 0xffffffff); /* clear pending interrupts */ - out_be32((void *)EMAC0_IER + hw_p->hw_addr, hw_p->emac_ier); - - if (hw_p->first_init == 0) { - /* - * Connect interrupt service routines - */ - irq_install_handler(ETH_IRQ_NUM(hw_p->devnum), - (interrupt_handler_t *) enetInt, dev); - } - - mtmsr (msr); /* enable interrupts again */ - - hw_p->bis = bis; - hw_p->first_init = 1; - - return 0; -} - - -static int ppc_4xx_eth_send(struct eth_device *dev, void *ptr, int len) -{ - struct enet_frame *ef_ptr; - ulong time_start, time_now; - unsigned long temp_txm0; - EMAC_4XX_HW_PST hw_p = dev->priv; - - ef_ptr = (struct enet_frame *) ptr; - - /*-----------------------------------------------------------------------+ - * Copy in our address into the frame. - *-----------------------------------------------------------------------*/ - (void) memcpy (ef_ptr->source_addr, dev->enetaddr, ENET_ADDR_LENGTH); - - /*-----------------------------------------------------------------------+ - * If frame is too long or too short, modify length. - *-----------------------------------------------------------------------*/ - /* TBS: where does the fragment go???? */ - if (len > ENET_MAX_MTU) - len = ENET_MAX_MTU; - - /* memcpy ((void *) &tx_buff[tx_slot], (const void *) ptr, len); */ - memcpy ((void *) hw_p->txbuf_ptr, (const void *) ptr, len); - flush_dcache_range((u32)hw_p->txbuf_ptr, (u32)hw_p->txbuf_ptr + len); - - /*-----------------------------------------------------------------------+ - * set TX Buffer busy, and send it - *-----------------------------------------------------------------------*/ - hw_p->tx[hw_p->tx_slot].ctrl = (MAL_TX_CTRL_LAST | - EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP) & - ~(EMAC_TX_CTRL_ISA | EMAC_TX_CTRL_RSA); - if ((NUM_TX_BUFF - 1) == hw_p->tx_slot) - hw_p->tx[hw_p->tx_slot].ctrl |= MAL_TX_CTRL_WRAP; - - hw_p->tx[hw_p->tx_slot].data_len = (short) len; - hw_p->tx[hw_p->tx_slot].ctrl |= MAL_TX_CTRL_READY; - - sync(); - - out_be32((void *)EMAC0_TMR0 + hw_p->hw_addr, - in_be32((void *)EMAC0_TMR0 + hw_p->hw_addr) | EMAC_TMR0_GNP0); -#ifdef INFO_4XX_ENET - hw_p->stats.pkts_tx++; -#endif - - /*-----------------------------------------------------------------------+ - * poll unitl the packet is sent and then make sure it is OK - *-----------------------------------------------------------------------*/ - time_start = get_timer (0); - while (1) { - temp_txm0 = in_be32((void *)EMAC0_TMR0 + hw_p->hw_addr); - /* loop until either TINT turns on or 3 seconds elapse */ - if ((temp_txm0 & EMAC_TMR0_GNP0) != 0) { - /* transmit is done, so now check for errors - * If there is an error, an interrupt should - * happen when we return - */ - time_now = get_timer (0); - if ((time_now - time_start) > 3000) { - return (-1); - } - } else { - return (len); - } - } -} - -int enetInt (struct eth_device *dev) -{ - int serviced; - int rc = -1; /* default to not us */ - u32 mal_isr; - u32 emac_isr = 0; - u32 mal_eob; - u32 uic_mal; - u32 uic_mal_err; - u32 uic_emac; - u32 uic_emac_b; - EMAC_4XX_HW_PST hw_p; - - /* - * Because the mal is generic, we need to get the current - * eth device - */ - dev = eth_get_dev(); - - hw_p = dev->priv; - - /* enter loop that stays in interrupt code until nothing to service */ - do { - serviced = 0; - - uic_mal = mfdcr(UIC_BASE_MAL + UIC_MSR); - uic_mal_err = mfdcr(UIC_BASE_MAL_ERR + UIC_MSR); - uic_emac = mfdcr(UIC_BASE_EMAC + UIC_MSR); - uic_emac_b = mfdcr(UIC_BASE_EMAC_B + UIC_MSR); - - if (!(uic_mal & (UIC_MAL_RXEOB | UIC_MAL_TXEOB)) - && !(uic_mal_err & (UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE)) - && !(uic_emac & UIC_ETHx) && !(uic_emac_b & UIC_ETHxB)) { - /* not for us */ - return (rc); - } - - /* get and clear controller status interrupts */ - /* look at MAL and EMAC error interrupts */ - if (uic_mal_err & (UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE)) { - /* we have a MAL error interrupt */ - mal_isr = mfdcr(MAL0_ESR); - mal_err(dev, mal_isr, uic_mal_err, - MAL_UIC_DEF, MAL_UIC_ERR); - - /* clear MAL error interrupt status bits */ - mtdcr(UIC_BASE_MAL_ERR + UIC_SR, - UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE); - - return -1; - } - - /* look for EMAC errors */ - if ((uic_emac & UIC_ETHx) || (uic_emac_b & UIC_ETHxB)) { - emac_isr = in_be32((void *)EMAC0_ISR + hw_p->hw_addr); - emac_err(dev, emac_isr); - - /* clear EMAC error interrupt status bits */ - mtdcr(UIC_BASE_EMAC + UIC_SR, UIC_ETHx); - mtdcr(UIC_BASE_EMAC_B + UIC_SR, UIC_ETHxB); - - return -1; - } - - /* handle MAX TX EOB interrupt from a tx */ - if (uic_mal & UIC_MAL_TXEOB) { - /* clear MAL interrupt status bits */ - mal_eob = mfdcr(MAL0_TXEOBISR); - mtdcr(MAL0_TXEOBISR, mal_eob); - mtdcr(UIC_BASE_MAL + UIC_SR, UIC_MAL_TXEOB); - - /* indicate that we serviced an interrupt */ - serviced = 1; - rc = 0; - } - - /* handle MAL RX EOB interrupt from a receive */ - /* check for EOB on valid channels */ - if (uic_mal & UIC_MAL_RXEOB) { - mal_eob = mfdcr(MAL0_RXEOBISR); - if (mal_eob & - (0x80000000 >> (hw_p->devnum * MAL_RX_CHAN_MUL))) { - /* push packet to upper layer */ - enet_rcv(dev, emac_isr); - - /* clear MAL interrupt status bits */ - mtdcr(UIC_BASE_MAL + UIC_SR, UIC_MAL_RXEOB); - - /* indicate that we serviced an interrupt */ - serviced = 1; - rc = 0; - } - } -#if defined(CONFIG_405EZ) - /* - * On 405EZ the RX-/TX-interrupts are coalesced into - * one IRQ bit in the UIC. We need to acknowledge the - * RX-/TX-interrupts in the SDR0_ICINTSTAT reg as well. - */ - mtsdr(SDR0_ICINTSTAT, - SDR_ICRX_STAT | SDR_ICTX0_STAT | SDR_ICTX1_STAT); -#endif /* defined(CONFIG_405EZ) */ - } while (serviced); - - return (rc); -} - -/*-----------------------------------------------------------------------------+ - * MAL Error Routine - *-----------------------------------------------------------------------------*/ -static void mal_err (struct eth_device *dev, unsigned long isr, - unsigned long uic, unsigned long maldef, - unsigned long mal_errr) -{ - EMAC_4XX_HW_PST hw_p = dev->priv; - - mtdcr (MAL0_ESR, isr); /* clear interrupt */ - - /* clear DE interrupt */ - mtdcr (MAL0_TXDEIR, 0xC0000000); - mtdcr (MAL0_RXDEIR, 0x80000000); - -#ifdef INFO_4XX_ENET - printf ("\nMAL error occured.... ISR = %lx UIC = = %lx MAL_DEF = %lx MAL_ERR= %lx \n", isr, uic, maldef, mal_errr); -#endif - - eth_init (hw_p->bis); /* start again... */ -} - -/*-----------------------------------------------------------------------------+ - * EMAC Error Routine - *-----------------------------------------------------------------------------*/ -static void emac_err (struct eth_device *dev, unsigned long isr) -{ - EMAC_4XX_HW_PST hw_p = dev->priv; - - printf ("EMAC%d error occured.... ISR = %lx\n", hw_p->devnum, isr); - out_be32((void *)EMAC0_ISR + hw_p->hw_addr, isr); -} - -/*-----------------------------------------------------------------------------+ - * enet_rcv() handles the ethernet receive data - *-----------------------------------------------------------------------------*/ -static void enet_rcv (struct eth_device *dev, unsigned long malisr) -{ - unsigned long data_len; - unsigned long rx_eob_isr; - EMAC_4XX_HW_PST hw_p = dev->priv; - - int handled = 0; - int i; - int loop_count = 0; - - rx_eob_isr = mfdcr (MAL0_RXEOBISR); - if ((0x80000000 >> (hw_p->devnum * MAL_RX_CHAN_MUL)) & rx_eob_isr) { - /* clear EOB */ - mtdcr (MAL0_RXEOBISR, rx_eob_isr); - - /* EMAC RX done */ - while (1) { /* do all */ - i = hw_p->rx_slot; - - if ((MAL_RX_CTRL_EMPTY & hw_p->rx[i].ctrl) - || (loop_count >= NUM_RX_BUFF)) - break; - - loop_count++; - handled++; - data_len = (unsigned long) hw_p->rx[i].data_len & 0x0fff; /* Get len */ - if (data_len) { - if (data_len > ENET_MAX_MTU) /* Check len */ - data_len = 0; - else { - if (EMAC_RX_ERRORS & hw_p->rx[i].ctrl) { /* Check Errors */ - data_len = 0; - hw_p->stats.rx_err_log[hw_p-> - rx_err_index] - = hw_p->rx[i].ctrl; - hw_p->rx_err_index++; - if (hw_p->rx_err_index == - MAX_ERR_LOG) - hw_p->rx_err_index = - 0; - } /* emac_erros */ - } /* data_len < max mtu */ - } /* if data_len */ - if (!data_len) { /* no data */ - hw_p->rx[i].ctrl |= MAL_RX_CTRL_EMPTY; /* Free Recv Buffer */ - - hw_p->stats.data_len_err++; /* Error at Rx */ - } - - /* !data_len */ - /* AS.HARNOIS */ - /* Check if user has already eaten buffer */ - /* if not => ERROR */ - else if (hw_p->rx_ready[hw_p->rx_i_index] != -1) { - if (hw_p->is_receiving) - printf ("ERROR : Receive buffers are full!\n"); - break; - } else { - hw_p->stats.rx_frames++; - hw_p->stats.rx += data_len; -#ifdef INFO_4XX_ENET - hw_p->stats.pkts_rx++; -#endif - /* AS.HARNOIS - * use ring buffer - */ - hw_p->rx_ready[hw_p->rx_i_index] = i; - hw_p->rx_i_index++; - if (NUM_RX_BUFF == hw_p->rx_i_index) - hw_p->rx_i_index = 0; - - hw_p->rx_slot++; - if (NUM_RX_BUFF == hw_p->rx_slot) - hw_p->rx_slot = 0; - - /* AS.HARNOIS - * free receive buffer only when - * buffer has been handled (eth_rx) - rx[i].ctrl |= MAL_RX_CTRL_EMPTY; - */ - } /* if data_len */ - } /* while */ - } /* if EMACK_RXCHL */ -} - - -static int ppc_4xx_eth_rx (struct eth_device *dev) -{ - int length; - int user_index; - unsigned long msr; - EMAC_4XX_HW_PST hw_p = dev->priv; - - hw_p->is_receiving = 1; /* tell driver */ - - for (;;) { - /* AS.HARNOIS - * use ring buffer and - * get index from rx buffer desciptor queue - */ - user_index = hw_p->rx_ready[hw_p->rx_u_index]; - if (user_index == -1) { - length = -1; - break; /* nothing received - leave for() loop */ - } - - msr = mfmsr (); - mtmsr (msr & ~(MSR_EE)); - - length = hw_p->rx[user_index].data_len & 0x0fff; - - /* Pass the packet up to the protocol layers. */ - /* NetReceive(NetRxPackets[rxIdx], length - 4); */ - /* NetReceive(NetRxPackets[i], length); */ - invalidate_dcache_range((u32)hw_p->rx[user_index].data_ptr, - (u32)hw_p->rx[user_index].data_ptr + - length - 4); - NetReceive (NetRxPackets[user_index], length - 4); - /* Free Recv Buffer */ - hw_p->rx[user_index].ctrl |= MAL_RX_CTRL_EMPTY; - /* Free rx buffer descriptor queue */ - hw_p->rx_ready[hw_p->rx_u_index] = -1; - hw_p->rx_u_index++; - if (NUM_RX_BUFF == hw_p->rx_u_index) - hw_p->rx_u_index = 0; - -#ifdef INFO_4XX_ENET - hw_p->stats.pkts_handled++; -#endif - - mtmsr (msr); /* Enable IRQ's */ - } - - hw_p->is_receiving = 0; /* tell driver */ - - return length; -} - -int ppc_4xx_eth_initialize (bd_t * bis) -{ - static int virgin = 0; - struct eth_device *dev; - int eth_num = 0; - EMAC_4XX_HW_PST hw = NULL; - u8 ethaddr[4 + CONFIG_EMAC_NR_START][6]; - u32 hw_addr[4]; - u32 mal_ier; - -#if defined(CONFIG_440GX) - unsigned long pfc1; - - mfsdr (SDR0_PFC1, pfc1); - pfc1 &= ~(0x01e00000); - pfc1 |= 0x01200000; - mtsdr (SDR0_PFC1, pfc1); -#endif - - /* first clear all mac-addresses */ - for (eth_num = 0; eth_num < LAST_EMAC_NUM; eth_num++) - memcpy(ethaddr[eth_num], "\0\0\0\0\0\0", 6); - - for (eth_num = 0; eth_num < LAST_EMAC_NUM; eth_num++) { - int ethaddr_idx = eth_num + CONFIG_EMAC_NR_START; - switch (eth_num) { - default: /* fall through */ - case 0: - eth_getenv_enetaddr("ethaddr", ethaddr[ethaddr_idx]); - hw_addr[eth_num] = 0x0; - break; -#ifdef CONFIG_HAS_ETH1 - case 1: - eth_getenv_enetaddr("eth1addr", ethaddr[ethaddr_idx]); - hw_addr[eth_num] = 0x100; - break; -#endif -#ifdef CONFIG_HAS_ETH2 - case 2: - eth_getenv_enetaddr("eth2addr", ethaddr[ethaddr_idx]); -#if defined(CONFIG_460GT) - hw_addr[eth_num] = 0x300; -#else - hw_addr[eth_num] = 0x400; -#endif - break; -#endif -#ifdef CONFIG_HAS_ETH3 - case 3: - eth_getenv_enetaddr("eth3addr", ethaddr[ethaddr_idx]); -#if defined(CONFIG_460GT) - hw_addr[eth_num] = 0x400; -#else - hw_addr[eth_num] = 0x600; -#endif - break; -#endif - } - } - - /* set phy num and mode */ - bis->bi_phynum[0] = CONFIG_PHY_ADDR; - bis->bi_phymode[0] = 0; - -#if defined(CONFIG_PHY1_ADDR) - bis->bi_phynum[1] = CONFIG_PHY1_ADDR; - bis->bi_phymode[1] = 0; -#endif -#if defined(CONFIG_440GX) - bis->bi_phynum[2] = CONFIG_PHY2_ADDR; - bis->bi_phynum[3] = CONFIG_PHY3_ADDR; - bis->bi_phymode[2] = 2; - bis->bi_phymode[3] = 2; -#endif - -#if defined(CONFIG_440GX) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_405EX) - ppc_4xx_eth_setup_bridge(0, bis); -#endif - - for (eth_num = 0; eth_num < LAST_EMAC_NUM; eth_num++) { - /* - * See if we can actually bring up the interface, - * otherwise, skip it - */ - if (memcmp (ethaddr[eth_num], "\0\0\0\0\0\0", 6) == 0) { - bis->bi_phymode[eth_num] = BI_PHYMODE_NONE; - continue; - } - - /* Allocate device structure */ - dev = (struct eth_device *) malloc (sizeof (*dev)); - if (dev == NULL) { - printf ("ppc_4xx_eth_initialize: " - "Cannot allocate eth_device %d\n", eth_num); - return (-1); - } - memset(dev, 0, sizeof(*dev)); - - /* Allocate our private use data */ - hw = (EMAC_4XX_HW_PST) malloc (sizeof (*hw)); - if (hw == NULL) { - printf ("ppc_4xx_eth_initialize: " - "Cannot allocate private hw data for eth_device %d", - eth_num); - free (dev); - return (-1); - } - memset(hw, 0, sizeof(*hw)); - - hw->hw_addr = hw_addr[eth_num]; - memcpy (dev->enetaddr, ethaddr[eth_num], 6); - hw->devnum = eth_num; - hw->print_speed = 1; - - sprintf (dev->name, "ppc_4xx_eth%d", eth_num - CONFIG_EMAC_NR_START); - dev->priv = (void *) hw; - dev->init = ppc_4xx_eth_init; - dev->halt = ppc_4xx_eth_halt; - dev->send = ppc_4xx_eth_send; - dev->recv = ppc_4xx_eth_rx; - - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - miiphy_register(dev->name, - emac4xx_miiphy_read, emac4xx_miiphy_write); -#endif - - if (0 == virgin) { - /* set the MAL IER ??? names may change with new spec ??? */ -#if defined(CONFIG_440SPE) || \ - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ - defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ - defined(CONFIG_405EX) - mal_ier = - MAL_IER_PT | MAL_IER_PRE | MAL_IER_PWE | - MAL_IER_DE | MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE ; -#else - mal_ier = - MAL_IER_DE | MAL_IER_NE | MAL_IER_TE | - MAL_IER_OPBE | MAL_IER_PLBE; -#endif - mtdcr (MAL0_ESR, 0xffffffff); /* clear pending interrupts */ - mtdcr (MAL0_TXDEIR, 0xffffffff); /* clear pending interrupts */ - mtdcr (MAL0_RXDEIR, 0xffffffff); /* clear pending interrupts */ - mtdcr (MAL0_IER, mal_ier); - - /* install MAL interrupt handler */ - irq_install_handler (VECNUM_MAL_SERR, - (interrupt_handler_t *) enetInt, - dev); - irq_install_handler (VECNUM_MAL_TXEOB, - (interrupt_handler_t *) enetInt, - dev); - irq_install_handler (VECNUM_MAL_RXEOB, - (interrupt_handler_t *) enetInt, - dev); - irq_install_handler (VECNUM_MAL_TXDE, - (interrupt_handler_t *) enetInt, - dev); - irq_install_handler (VECNUM_MAL_RXDE, - (interrupt_handler_t *) enetInt, - dev); - virgin = 1; - } - } /* end for each supported device */ - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/8390.h b/qemu/roms/u-boot/drivers/net/8390.h deleted file mode 100644 index f087217ed..000000000 --- a/qemu/roms/u-boot/drivers/net/8390.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - -Ported to U-Boot by Christian Pellegrin <chri@ascensit.com> - -Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and -eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world -are GPL, so this is, of course, GPL. - -*/ - -/* Generic NS8390 register definitions. */ -/* This file is part of Donald Becker's 8390 drivers, and is distributed - under the same license. Auto-loading of 8390.o only in v2.2 - Paul G. - Some of these names and comments originated from the Crynwr - packet drivers, which are distributed under the GPL. */ - -#ifndef _8390_h -#define _8390_h - -/* Some generic ethernet register configurations. */ -#define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */ -#define E8390_RX_IRQ_MASK 0x5 -#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */ -#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */ -#define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */ -#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */ - -/* Register accessed at EN_CMD, the 8390 base addr. */ -#define E8390_STOP 0x01 /* Stop and reset the chip */ -#define E8390_START 0x02 /* Start the chip, clear reset */ -#define E8390_TRANS 0x04 /* Transmit a frame */ -#define E8390_RREAD 0x08 /* Remote read */ -#define E8390_RWRITE 0x10 /* Remote write */ -#define E8390_NODMA 0x20 /* Remote DMA */ -#define E8390_PAGE0 0x00 /* Select page chip registers */ -#define E8390_PAGE1 0x40 /* using the two high-order bits */ -#define E8390_PAGE2 0x80 /* Page 3 is invalid. */ - -/* - * Only generate indirect loads given a machine that needs them. - * - removed AMIGA_PCMCIA from this list, handled as ISA io now - */ - -#define n2k_inb(port) (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE))) -#define n2k_outb(val,port) (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE)) = val) - -#define EI_SHIFT(x) (x) - -#define E8390_CMD EI_SHIFT(0x00) /* The command register (for all pages) */ -/* Page 0 register offsets. */ -#define EN0_CLDALO EI_SHIFT(0x01) /* Low byte of current local dma addr RD */ -#define EN0_STARTPG EI_SHIFT(0x01) /* Starting page of ring bfr WR */ -#define EN0_CLDAHI EI_SHIFT(0x02) /* High byte of current local dma addr RD */ -#define EN0_STOPPG EI_SHIFT(0x02) /* Ending page +1 of ring bfr WR */ -#define EN0_BOUNDARY EI_SHIFT(0x03) /* Boundary page of ring bfr RD WR */ -#define EN0_TSR EI_SHIFT(0x04) /* Transmit status reg RD */ -#define EN0_TPSR EI_SHIFT(0x04) /* Transmit starting page WR */ -#define EN0_NCR EI_SHIFT(0x05) /* Number of collision reg RD */ -#define EN0_TCNTLO EI_SHIFT(0x05) /* Low byte of tx byte count WR */ -#define EN0_FIFO EI_SHIFT(0x06) /* FIFO RD */ -#define EN0_TCNTHI EI_SHIFT(0x06) /* High byte of tx byte count WR */ -#define EN0_ISR EI_SHIFT(0x07) /* Interrupt status reg RD WR */ -#define EN0_CRDALO EI_SHIFT(0x08) /* low byte of current remote dma address RD */ -#define EN0_RSARLO EI_SHIFT(0x08) /* Remote start address reg 0 */ -#define EN0_CRDAHI EI_SHIFT(0x09) /* high byte, current remote dma address RD */ -#define EN0_RSARHI EI_SHIFT(0x09) /* Remote start address reg 1 */ -#define EN0_RCNTLO EI_SHIFT(0x0a) /* Remote byte count reg WR */ -#define EN0_RCNTHI EI_SHIFT(0x0b) /* Remote byte count reg WR */ -#define EN0_RSR EI_SHIFT(0x0c) /* rx status reg RD */ -#define EN0_RXCR EI_SHIFT(0x0c) /* RX configuration reg WR */ -#define EN0_TXCR EI_SHIFT(0x0d) /* TX configuration reg WR */ -#define EN0_COUNTER0 EI_SHIFT(0x0d) /* Rcv alignment error counter RD */ -#define EN0_DCFG EI_SHIFT(0x0e) /* Data configuration reg WR */ -#define EN0_COUNTER1 EI_SHIFT(0x0e) /* Rcv CRC error counter RD */ -#define EN0_IMR EI_SHIFT(0x0f) /* Interrupt mask reg WR */ -#define EN0_COUNTER2 EI_SHIFT(0x0f) /* Rcv missed frame error counter RD */ - -/* Bits in EN0_ISR - Interrupt status register */ -#define ENISR_RX 0x01 /* Receiver, no error */ -#define ENISR_TX 0x02 /* Transmitter, no error */ -#define ENISR_RX_ERR 0x04 /* Receiver, with error */ -#define ENISR_TX_ERR 0x08 /* Transmitter, with error */ -#define ENISR_OVER 0x10 /* Receiver overwrote the ring */ -#define ENISR_COUNTERS 0x20 /* Counters need emptying */ -#define ENISR_RDC 0x40 /* remote dma complete */ -#define ENISR_RESET 0x80 /* Reset completed */ -#define ENISR_ALL 0x3f /* Interrupts we will enable */ - -/* Bits in EN0_DCFG - Data config register */ -#define ENDCFG_WTS 0x01 /* word transfer mode selection */ -#define ENDCFG_BOS 0x02 /* byte order selection */ -#define ENDCFG_AUTO_INIT 0x10 /* Auto-init to remove packets from ring */ -#define ENDCFG_FIFO 0x40 /* 8 bytes */ - -/* Page 1 register offsets. */ -#define EN1_PHYS EI_SHIFT(0x01) /* This board's physical enet addr RD WR */ -#define EN1_PHYS_SHIFT(i) EI_SHIFT(i+1) /* Get and set mac address */ -#define EN1_CURPAG EI_SHIFT(0x07) /* Current memory page RD WR */ -#define EN1_MULT EI_SHIFT(0x08) /* Multicast filter mask array (8 bytes) RD WR */ -#define EN1_MULT_SHIFT(i) EI_SHIFT(8+i) /* Get and set multicast filter */ - -/* Bits in received packet status byte and EN0_RSR*/ -#define ENRSR_RXOK 0x01 /* Received a good packet */ -#define ENRSR_CRC 0x02 /* CRC error */ -#define ENRSR_FAE 0x04 /* frame alignment error */ -#define ENRSR_FO 0x08 /* FIFO overrun */ -#define ENRSR_MPA 0x10 /* missed pkt */ -#define ENRSR_PHY 0x20 /* physical/multicast address */ -#define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */ -#define ENRSR_DEF 0x80 /* deferring */ - -/* Transmitted packet status, EN0_TSR. */ -#define ENTSR_PTX 0x01 /* Packet transmitted without error */ -#define ENTSR_ND 0x02 /* The transmit wasn't deferred. */ -#define ENTSR_COL 0x04 /* The transmit collided at least once. */ -#define ENTSR_ABT 0x08 /* The transmit collided 16 times, and was deferred. */ -#define ENTSR_CRS 0x10 /* The carrier sense was lost. */ -#define ENTSR_FU 0x20 /* A "FIFO underrun" occurred during transmit. */ -#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */ -#define ENTSR_OWC 0x80 /* There was an out-of-window collision. */ - -#define NIC_RECEIVE_MONITOR_MODE 0x20 - -#endif /* _8390_h */ diff --git a/qemu/roms/u-boot/drivers/net/Makefile b/qemu/roms/u-boot/drivers/net/Makefile deleted file mode 100644 index 6005f7e41..000000000 --- a/qemu/roms/u-boot/drivers/net/Makefile +++ /dev/null @@ -1,66 +0,0 @@ -# -# (C) Copyright 2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o -obj-$(CONFIG_ALTERA_TSE) += altera_tse.o -obj-$(CONFIG_ARMADA100_FEC) += armada100_fec.o -obj-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o -obj-$(CONFIG_DRIVER_AX88180) += ax88180.o -obj-$(CONFIG_BFIN_MAC) += bfin_mac.o -obj-$(CONFIG_CALXEDA_XGMAC) += calxedaxgmac.o -obj-$(CONFIG_CS8900) += cs8900.o -obj-$(CONFIG_TULIP) += dc2114x.o -obj-$(CONFIG_DESIGNWARE_ETH) += designware.o -obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o -obj-$(CONFIG_DNET) += dnet.o -obj-$(CONFIG_E1000) += e1000.o -obj-$(CONFIG_E1000_SPI) += e1000_spi.o -obj-$(CONFIG_EEPRO100) += eepro100.o -obj-$(CONFIG_ENC28J60) += enc28j60.o -obj-$(CONFIG_EP93XX) += ep93xx_eth.o -obj-$(CONFIG_ETHOC) += ethoc.o -obj-$(CONFIG_FEC_MXC) += fec_mxc.o -obj-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o -obj-$(CONFIG_FTGMAC100) += ftgmac100.o -obj-$(CONFIG_FTMAC110) += ftmac110.o -obj-$(CONFIG_FTMAC100) += ftmac100.o -obj-$(CONFIG_GRETH) += greth.o -obj-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o -obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_net.o -obj-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o -obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o -obj-$(CONFIG_LAN91C96) += lan91c96.o -obj-$(CONFIG_MACB) += macb.o -obj-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o -obj-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o -obj-$(CONFIG_MPC512x_FEC) += mpc512x_fec.o -obj-$(CONFIG_MVGBE) += mvgbe.o -obj-$(CONFIG_NATSEMI) += natsemi.o -obj-$(CONFIG_DRIVER_NE2000) += ne2000.o ne2000_base.o -obj-$(CONFIG_DRIVER_AX88796L) += ax88796.o ne2000_base.o -obj-$(CONFIG_NETCONSOLE) += netconsole.o -obj-$(CONFIG_NS8382X) += ns8382x.o -obj-$(CONFIG_PCNET) += pcnet.o -obj-$(CONFIG_PLB2800_ETHER) += plb2800_eth.o -obj-$(CONFIG_RTL8139) += rtl8139.o -obj-$(CONFIG_RTL8169) += rtl8169.o -obj-$(CONFIG_SH_ETHER) += sh_eth.o -obj-$(CONFIG_SMC91111) += smc91111.o -obj-$(CONFIG_SMC911X) += smc911x.o -obj-$(CONFIG_SUNXI_WEMAC) += sunxi_wemac.o -obj-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o -obj-$(CONFIG_TSEC_ENET) += tsec.o fsl_mdio.o -obj-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o -obj-$(CONFIG_FMAN_ENET) += fsl_mdio.o -obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o -obj-$(CONFIG_ULI526X) += uli526x.o -obj-$(CONFIG_VSC7385_ENET) += vsc7385.o -obj-$(CONFIG_XILINX_AXIEMAC) += xilinx_axi_emac.o -obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o -obj-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \ - xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o -obj-$(CONFIG_ZYNQ_GEM) += zynq_gem.o diff --git a/qemu/roms/u-boot/drivers/net/altera_tse.c b/qemu/roms/u-boot/drivers/net/altera_tse.c deleted file mode 100644 index de517f8da..000000000 --- a/qemu/roms/u-boot/drivers/net/altera_tse.c +++ /dev/null @@ -1,971 +0,0 @@ -/* - * Altera 10/100/1000 triple speed ethernet mac driver - * - * Copyright (C) 2008 Altera Corporation. - * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <config.h> -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <command.h> -#include <asm/cache.h> -#include <asm/dma-mapping.h> -#include <miiphy.h> -#include "altera_tse.h" - -/* sgdma debug - print descriptor */ -static void alt_sgdma_print_desc(volatile struct alt_sgdma_descriptor *desc) -{ - debug("SGDMA DEBUG :\n"); - debug("desc->source : 0x%x \n", (unsigned int)desc->source); - debug("desc->destination : 0x%x \n", (unsigned int)desc->destination); - debug("desc->next : 0x%x \n", (unsigned int)desc->next); - debug("desc->source_pad : 0x%x \n", (unsigned int)desc->source_pad); - debug("desc->destination_pad : 0x%x \n", - (unsigned int)desc->destination_pad); - debug("desc->next_pad : 0x%x \n", (unsigned int)desc->next_pad); - debug("desc->bytes_to_transfer : 0x%x \n", - (unsigned int)desc->bytes_to_transfer); - debug("desc->actual_bytes_transferred : 0x%x \n", - (unsigned int)desc->actual_bytes_transferred); - debug("desc->descriptor_status : 0x%x \n", - (unsigned int)desc->descriptor_status); - debug("desc->descriptor_control : 0x%x \n", - (unsigned int)desc->descriptor_control); -} - -/* This is a generic routine that the SGDMA mode-specific routines - * call to populate a descriptor. - * arg1 :pointer to first SGDMA descriptor. - * arg2 :pointer to next SGDMA descriptor. - * arg3 :Address to where data to be written. - * arg4 :Address from where data to be read. - * arg5 :no of byte to transaction. - * arg6 :variable indicating to generate start of packet or not - * arg7 :read fixed - * arg8 :write fixed - * arg9 :read burst - * arg10 :write burst - * arg11 :atlantic_channel number - */ -static void alt_sgdma_construct_descriptor_burst( - volatile struct alt_sgdma_descriptor *desc, - volatile struct alt_sgdma_descriptor *next, - unsigned int *read_addr, - unsigned int *write_addr, - unsigned short length_or_eop, - int generate_eop, - int read_fixed, - int write_fixed_or_sop, - int read_burst, - int write_burst, - unsigned char atlantic_channel) -{ - /* - * Mark the "next" descriptor as "not" owned by hardware. This prevents - * The SGDMA controller from continuing to process the chain. This is - * done as a single IO write to bypass cache, without flushing - * the entire descriptor, since only the 8-bit descriptor status must - * be flushed. - */ - if (!next) - debug("Next descriptor not defined!!\n"); - - next->descriptor_control = (next->descriptor_control & - ~ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK); - - desc->source = (unsigned int *)((unsigned int)read_addr & 0x1FFFFFFF); - desc->destination = - (unsigned int *)((unsigned int)write_addr & 0x1FFFFFFF); - desc->next = (unsigned int *)((unsigned int)next & 0x1FFFFFFF); - desc->source_pad = 0x0; - desc->destination_pad = 0x0; - desc->next_pad = 0x0; - desc->bytes_to_transfer = length_or_eop; - desc->actual_bytes_transferred = 0; - desc->descriptor_status = 0x0; - - /* SGDMA burst not currently supported */ - desc->read_burst = 0; - desc->write_burst = 0; - - /* - * Set the descriptor control block as follows: - * - Set "owned by hardware" bit - * - Optionally set "generate EOP" bit - * - Optionally set the "read from fixed address" bit - * - Optionally set the "write to fixed address bit (which serves - * serves as a "generate SOP" control bit in memory-to-stream mode). - * - Set the 4-bit atlantic channel, if specified - * - * Note this step is performed after all other descriptor information - * has been filled out so that, if the controller already happens to be - * pointing at this descriptor, it will not run (via the "owned by - * hardware" bit) until all other descriptor has been set up. - */ - - desc->descriptor_control = - ((ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK) | - (generate_eop ? - ALT_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK : 0x0) | - (read_fixed ? - ALT_SGDMA_DESCRIPTOR_CONTROL_READ_FIXED_ADDRESS_MSK : 0x0) | - (write_fixed_or_sop ? - ALT_SGDMA_DESCRIPTOR_CONTROL_WRITE_FIXED_ADDRESS_MSK : 0x0) | - (atlantic_channel ? ((atlantic_channel & 0x0F) << 3) : 0) - ); -} - -static int alt_sgdma_do_sync_transfer(volatile struct alt_sgdma_registers *dev, - volatile struct alt_sgdma_descriptor *desc) -{ - unsigned int status; - int counter = 0; - - /* Wait for any pending transfers to complete */ - alt_sgdma_print_desc(desc); - status = dev->status; - - counter = 0; - while (dev->status & ALT_SGDMA_STATUS_BUSY_MSK) { - if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) - break; - } - - if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) - debug("Timeout waiting sgdma in do sync!\n"); - - /* - * Clear any (previous) status register information - * that might occlude our error checking later. - */ - dev->status = 0xFF; - - /* Point the controller at the descriptor */ - dev->next_descriptor_pointer = (unsigned int)desc & 0x1FFFFFFF; - debug("next desc in sgdma 0x%x\n", - (unsigned int)dev->next_descriptor_pointer); - - /* - * Set up SGDMA controller to: - * - Disable interrupt generation - * - Run once a valid descriptor is written to controller - * - Stop on an error with any particular descriptor - */ - dev->control = (ALT_SGDMA_CONTROL_RUN_MSK | - ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK); - - /* Wait for the descriptor (chain) to complete */ - status = dev->status; - debug("wait for sgdma...."); - while (dev->status & ALT_SGDMA_STATUS_BUSY_MSK) - ; - debug("done\n"); - - /* Clear Run */ - dev->control = (dev->control & (~ALT_SGDMA_CONTROL_RUN_MSK)); - - /* Get & clear status register contents */ - status = dev->status; - dev->status = 0xFF; - - /* we really should check if the transfer completes properly */ - debug("tx sgdma status = 0x%x", status); - return 0; -} - -static int alt_sgdma_do_async_transfer(volatile struct alt_sgdma_registers *dev, - volatile struct alt_sgdma_descriptor *desc) -{ - unsigned int status; - int counter = 0; - - /* Wait for any pending transfers to complete */ - alt_sgdma_print_desc(desc); - status = dev->status; - - counter = 0; - while (dev->status & ALT_SGDMA_STATUS_BUSY_MSK) { - if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) - break; - } - - if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) - debug("Timeout waiting sgdma in do async!\n"); - - /* - * Clear the RUN bit in the control register. This is needed - * to restart the SGDMA engine later on. - */ - dev->control = 0; - - /* - * Clear any (previous) status register information - * that might occlude our error checking later. - */ - dev->status = 0xFF; - - /* Point the controller at the descriptor */ - dev->next_descriptor_pointer = (unsigned int)desc & 0x1FFFFFFF; - - /* - * Set up SGDMA controller to: - * - Disable interrupt generation - * - Run once a valid descriptor is written to controller - * - Stop on an error with any particular descriptor - */ - dev->control = (ALT_SGDMA_CONTROL_RUN_MSK | - ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK); - - /* we really should check if the transfer completes properly */ - return 0; -} - -/* u-boot interface */ -static int tse_adjust_link(struct altera_tse_priv *priv) -{ - unsigned int refvar; - - refvar = priv->mac_dev->command_config.image; - - if (!(priv->duplexity)) - refvar |= ALTERA_TSE_CMD_HD_ENA_MSK; - else - refvar &= ~ALTERA_TSE_CMD_HD_ENA_MSK; - - switch (priv->speed) { - case 1000: - refvar |= ALTERA_TSE_CMD_ETH_SPEED_MSK; - refvar &= ~ALTERA_TSE_CMD_ENA_10_MSK; - break; - case 100: - refvar &= ~ALTERA_TSE_CMD_ETH_SPEED_MSK; - refvar &= ~ALTERA_TSE_CMD_ENA_10_MSK; - break; - case 10: - refvar &= ~ALTERA_TSE_CMD_ETH_SPEED_MSK; - refvar |= ALTERA_TSE_CMD_ENA_10_MSK; - break; - } - priv->mac_dev->command_config.image = refvar; - - return 0; -} - -static int tse_eth_send(struct eth_device *dev, void *packet, int length) -{ - struct altera_tse_priv *priv = dev->priv; - volatile struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx; - volatile struct alt_sgdma_descriptor *tx_desc = - (volatile struct alt_sgdma_descriptor *)priv->tx_desc; - - volatile struct alt_sgdma_descriptor *tx_desc_cur = - (volatile struct alt_sgdma_descriptor *)&tx_desc[0]; - - flush_dcache_range((unsigned long)packet, - (unsigned long)packet + length); - alt_sgdma_construct_descriptor_burst( - (volatile struct alt_sgdma_descriptor *)&tx_desc[0], - (volatile struct alt_sgdma_descriptor *)&tx_desc[1], - (unsigned int *)packet, /* read addr */ - (unsigned int *)0, - length, /* length or EOP ,will change for each tx */ - 0x1, /* gen eop */ - 0x0, /* read fixed */ - 0x1, /* write fixed or sop */ - 0x0, /* read burst */ - 0x0, /* write burst */ - 0x0 /* channel */ - ); - debug("TX Packet @ 0x%x,0x%x bytes", (unsigned int)packet, length); - - /* send the packet */ - debug("sending packet\n"); - alt_sgdma_do_sync_transfer(tx_sgdma, tx_desc_cur); - debug("sent %d bytes\n", tx_desc_cur->actual_bytes_transferred); - return tx_desc_cur->actual_bytes_transferred; -} - -static int tse_eth_rx(struct eth_device *dev) -{ - int packet_length = 0; - struct altera_tse_priv *priv = dev->priv; - volatile struct alt_sgdma_descriptor *rx_desc = - (volatile struct alt_sgdma_descriptor *)priv->rx_desc; - volatile struct alt_sgdma_descriptor *rx_desc_cur = &rx_desc[0]; - - if (rx_desc_cur->descriptor_status & - ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) { - debug("got packet\n"); - packet_length = rx_desc->actual_bytes_transferred; - NetReceive(NetRxPackets[0], packet_length); - - /* start descriptor again */ - flush_dcache_range((unsigned long)(NetRxPackets[0]), - (unsigned long)(NetRxPackets[0]) + PKTSIZE_ALIGN); - alt_sgdma_construct_descriptor_burst( - (volatile struct alt_sgdma_descriptor *)&rx_desc[0], - (volatile struct alt_sgdma_descriptor *)&rx_desc[1], - (unsigned int)0x0, /* read addr */ - (unsigned int *)NetRxPackets[0], - 0x0, /* length or EOP */ - 0x0, /* gen eop */ - 0x0, /* read fixed */ - 0x0, /* write fixed or sop */ - 0x0, /* read burst */ - 0x0, /* write burst */ - 0x0 /* channel */ - ); - - /* setup the sgdma */ - alt_sgdma_do_async_transfer(priv->sgdma_rx, &rx_desc[0]); - - return packet_length; - } - - return -1; -} - -static void tse_eth_halt(struct eth_device *dev) -{ - /* don't do anything! */ - /* this gets called after each uboot */ - /* network command. don't need to reset the thing all of the time */ -} - -static void tse_eth_reset(struct eth_device *dev) -{ - /* stop sgdmas, disable tse receive */ - struct altera_tse_priv *priv = dev->priv; - volatile struct alt_tse_mac *mac_dev = priv->mac_dev; - volatile struct alt_sgdma_registers *rx_sgdma = priv->sgdma_rx; - volatile struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx; - int counter; - volatile struct alt_sgdma_descriptor *rx_desc = - (volatile struct alt_sgdma_descriptor *)&priv->rx_desc[0]; - - /* clear rx desc & wait for sgdma to complete */ - rx_desc->descriptor_control = 0; - rx_sgdma->control = 0; - counter = 0; - while (rx_sgdma->status & ALT_SGDMA_STATUS_BUSY_MSK) { - if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) - break; - } - - if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) { - debug("Timeout waiting for rx sgdma!\n"); - rx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK; - rx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK; - } - - counter = 0; - tx_sgdma->control = 0; - while (tx_sgdma->status & ALT_SGDMA_STATUS_BUSY_MSK) { - if (counter++ > ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) - break; - } - - if (counter >= ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR) { - debug("Timeout waiting for tx sgdma!\n"); - tx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK; - tx_sgdma->control = ALT_SGDMA_CONTROL_SOFTWARERESET_MSK; - } - /* reset the mac */ - mac_dev->command_config.bits.transmit_enable = 1; - mac_dev->command_config.bits.receive_enable = 1; - mac_dev->command_config.bits.software_reset = 1; - - counter = 0; - while (mac_dev->command_config.bits.software_reset) { - if (counter++ > ALT_TSE_SW_RESET_WATCHDOG_CNTR) - break; - } - - if (counter >= ALT_TSE_SW_RESET_WATCHDOG_CNTR) - debug("TSEMAC SW reset bit never cleared!\n"); -} - -static int tse_mdio_read(struct altera_tse_priv *priv, unsigned int regnum) -{ - volatile struct alt_tse_mac *mac_dev; - unsigned int *mdio_regs; - unsigned int data; - u16 value; - - mac_dev = priv->mac_dev; - - /* set mdio address */ - mac_dev->mdio_phy1_addr = priv->phyaddr; - mdio_regs = (unsigned int *)&mac_dev->mdio_phy1; - - /* get the data */ - data = mdio_regs[regnum]; - - value = data & 0xffff; - - return value; -} - -static int tse_mdio_write(struct altera_tse_priv *priv, unsigned int regnum, - unsigned int value) -{ - volatile struct alt_tse_mac *mac_dev; - unsigned int *mdio_regs; - unsigned int data; - - mac_dev = priv->mac_dev; - - /* set mdio address */ - mac_dev->mdio_phy1_addr = priv->phyaddr; - mdio_regs = (unsigned int *)&mac_dev->mdio_phy1; - - /* get the data */ - data = (unsigned int)value; - - mdio_regs[regnum] = data; - - return 0; -} - -/* MDIO access to phy */ -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) && !defined(BITBANGMII) -static int altera_tse_miiphy_write(const char *devname, unsigned char addr, - unsigned char reg, unsigned short value) -{ - struct eth_device *dev; - struct altera_tse_priv *priv; - dev = eth_get_dev_by_name(devname); - priv = dev->priv; - - tse_mdio_write(priv, (uint) reg, (uint) value); - - return 0; -} - -static int altera_tse_miiphy_read(const char *devname, unsigned char addr, - unsigned char reg, unsigned short *value) -{ - struct eth_device *dev; - struct altera_tse_priv *priv; - volatile struct alt_tse_mac *mac_dev; - unsigned int *mdio_regs; - - dev = eth_get_dev_by_name(devname); - priv = dev->priv; - - mac_dev = priv->mac_dev; - mac_dev->mdio_phy1_addr = (int)addr; - mdio_regs = (unsigned int *)&mac_dev->mdio_phy1; - - *value = 0xffff & mdio_regs[reg]; - - return 0; - -} -#endif - -/* - * Also copied from tsec.c - */ -/* Parse the status register for link, and then do - * auto-negotiation - */ -static uint mii_parse_sr(uint mii_reg, struct altera_tse_priv *priv) -{ - /* - * Wait if the link is up, and autonegotiation is in progress - * (ie - we're capable and it's not done) - */ - mii_reg = tse_mdio_read(priv, MIIM_STATUS); - - if (!(mii_reg & MIIM_STATUS_LINK) && (mii_reg & BMSR_ANEGCAPABLE) - && !(mii_reg & BMSR_ANEGCOMPLETE)) { - int i = 0; - - puts("Waiting for PHY auto negotiation to complete"); - while (!(mii_reg & BMSR_ANEGCOMPLETE)) { - /* - * Timeout reached ? - */ - if (i > PHY_AUTONEGOTIATE_TIMEOUT) { - puts(" TIMEOUT !\n"); - priv->link = 0; - return 0; - } - - if ((i++ % 1000) == 0) - putc('.'); - udelay(1000); /* 1 ms */ - mii_reg = tse_mdio_read(priv, MIIM_STATUS); - } - puts(" done\n"); - priv->link = 1; - udelay(500000); /* another 500 ms (results in faster booting) */ - } else { - if (mii_reg & MIIM_STATUS_LINK) { - debug("Link is up\n"); - priv->link = 1; - } else { - debug("Link is down\n"); - priv->link = 0; - } - } - - return 0; -} - -/* Parse the 88E1011's status register for speed and duplex - * information - */ -static uint mii_parse_88E1011_psr(uint mii_reg, struct altera_tse_priv *priv) -{ - uint speed; - - mii_reg = tse_mdio_read(priv, MIIM_88E1011_PHY_STATUS); - - if ((mii_reg & MIIM_88E1011_PHYSTAT_LINK) && - !(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) { - int i = 0; - - puts("Waiting for PHY realtime link"); - while (!(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) { - /* Timeout reached ? */ - if (i > PHY_AUTONEGOTIATE_TIMEOUT) { - puts(" TIMEOUT !\n"); - priv->link = 0; - break; - } - - if ((i++ == 1000) == 0) { - i = 0; - puts("."); - } - udelay(1000); /* 1 ms */ - mii_reg = tse_mdio_read(priv, MIIM_88E1011_PHY_STATUS); - } - puts(" done\n"); - udelay(500000); /* another 500 ms (results in faster booting) */ - } else { - if (mii_reg & MIIM_88E1011_PHYSTAT_LINK) - priv->link = 1; - else - priv->link = 0; - } - - if (mii_reg & MIIM_88E1011_PHYSTAT_DUPLEX) - priv->duplexity = 1; - else - priv->duplexity = 0; - - speed = (mii_reg & MIIM_88E1011_PHYSTAT_SPEED); - - switch (speed) { - case MIIM_88E1011_PHYSTAT_GBIT: - priv->speed = 1000; - debug("PHY Speed is 1000Mbit\n"); - break; - case MIIM_88E1011_PHYSTAT_100: - debug("PHY Speed is 100Mbit\n"); - priv->speed = 100; - break; - default: - debug("PHY Speed is 10Mbit\n"); - priv->speed = 10; - } - - return 0; -} - -static uint mii_m88e1111s_setmode_sr(uint mii_reg, struct altera_tse_priv *priv) -{ - uint mii_data = tse_mdio_read(priv, mii_reg); - mii_data &= 0xfff0; - if ((priv->flags >= 1) && (priv->flags <= 4)) - mii_data |= 0xb; - else if (priv->flags == 5) - mii_data |= 0x4; - - return mii_data; -} - -static uint mii_m88e1111s_setmode_cr(uint mii_reg, struct altera_tse_priv *priv) -{ - uint mii_data = tse_mdio_read(priv, mii_reg); - mii_data &= ~0x82; - if ((priv->flags >= 1) && (priv->flags <= 4)) - mii_data |= 0x82; - - return mii_data; -} - -/* - * Returns which value to write to the control register. - * For 10/100, the value is slightly different - */ -static uint mii_cr_init(uint mii_reg, struct altera_tse_priv *priv) -{ - return MIIM_CONTROL_INIT; -} - -/* - * PHY & MDIO code - * Need to add SGMII stuff - * - */ - -static struct phy_info phy_info_M88E1111S = { - 0x01410cc, - "Marvell 88E1111S", - 4, - (struct phy_cmd[]){ /* config */ - /* Reset and configure the PHY */ - {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, - {MIIM_88E1111_PHY_EXT_SR, 0x848f, - &mii_m88e1111s_setmode_sr}, - /* Delay RGMII TX and RX */ - {MIIM_88E1111_PHY_EXT_CR, 0x0cd2, - &mii_m88e1111s_setmode_cr}, - {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, - {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, - {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, - {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, - {miim_end,} - }, - (struct phy_cmd[]){ /* startup */ - /* Status is read once to clear old link state */ - {MIIM_STATUS, miim_read, NULL}, - /* Auto-negotiate */ - {MIIM_STATUS, miim_read, &mii_parse_sr}, - /* Read the status */ - {MIIM_88E1011_PHY_STATUS, miim_read, - &mii_parse_88E1011_psr}, - {miim_end,} - }, - (struct phy_cmd[]){ /* shutdown */ - {miim_end,} - }, -}; - -/* a generic flavor. */ -static struct phy_info phy_info_generic = { - 0, - "Unknown/Generic PHY", - 32, - (struct phy_cmd[]){ /* config */ - {MII_BMCR, BMCR_RESET, NULL}, - {MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART, NULL}, - {miim_end,} - }, - (struct phy_cmd[]){ /* startup */ - {MII_BMSR, miim_read, NULL}, - {MII_BMSR, miim_read, &mii_parse_sr}, - {miim_end,} - }, - (struct phy_cmd[]){ /* shutdown */ - {miim_end,} - } -}; - -static struct phy_info *phy_info[] = { - &phy_info_M88E1111S, - NULL -}; - - /* Grab the identifier of the device's PHY, and search through - * all of the known PHYs to see if one matches. If so, return - * it, if not, return NULL - */ -static struct phy_info *get_phy_info(struct eth_device *dev) -{ - struct altera_tse_priv *priv = (struct altera_tse_priv *)dev->priv; - uint phy_reg, phy_ID; - int i; - struct phy_info *theInfo = NULL; - - /* Grab the bits from PHYIR1, and put them in the upper half */ - phy_reg = tse_mdio_read(priv, MIIM_PHYIR1); - phy_ID = (phy_reg & 0xffff) << 16; - - /* Grab the bits from PHYIR2, and put them in the lower half */ - phy_reg = tse_mdio_read(priv, MIIM_PHYIR2); - phy_ID |= (phy_reg & 0xffff); - - /* loop through all the known PHY types, and find one that */ - /* matches the ID we read from the PHY. */ - for (i = 0; phy_info[i]; i++) { - if (phy_info[i]->id == (phy_ID >> phy_info[i]->shift)) { - theInfo = phy_info[i]; - break; - } - } - - if (theInfo == NULL) { - theInfo = &phy_info_generic; - debug("%s: No support for PHY id %x; assuming generic\n", - dev->name, phy_ID); - } else - debug("%s: PHY is %s (%x)\n", dev->name, theInfo->name, phy_ID); - - return theInfo; -} - -/* Execute the given series of commands on the given device's - * PHY, running functions as necessary - */ -static void phy_run_commands(struct altera_tse_priv *priv, struct phy_cmd *cmd) -{ - int i; - uint result; - - for (i = 0; cmd->mii_reg != miim_end; i++) { - if (cmd->mii_data == miim_read) { - result = tse_mdio_read(priv, cmd->mii_reg); - - if (cmd->funct != NULL) - (*(cmd->funct)) (result, priv); - - } else { - if (cmd->funct != NULL) - result = (*(cmd->funct)) (cmd->mii_reg, priv); - else - result = cmd->mii_data; - - tse_mdio_write(priv, cmd->mii_reg, result); - - } - cmd++; - } -} - -/* Phy init code */ -static int init_phy(struct eth_device *dev) -{ - struct altera_tse_priv *priv = (struct altera_tse_priv *)dev->priv; - struct phy_info *curphy; - - /* Get the cmd structure corresponding to the attached - * PHY */ - curphy = get_phy_info(dev); - - if (curphy == NULL) { - priv->phyinfo = NULL; - debug("%s: No PHY found\n", dev->name); - - return 0; - } else - debug("%s found\n", curphy->name); - priv->phyinfo = curphy; - - phy_run_commands(priv, priv->phyinfo->config); - - return 1; -} - -static int tse_set_mac_address(struct eth_device *dev) -{ - struct altera_tse_priv *priv = dev->priv; - volatile struct alt_tse_mac *mac_dev = priv->mac_dev; - - debug("Setting MAC address to 0x%02x%02x%02x%02x%02x%02x\n", - dev->enetaddr[5], dev->enetaddr[4], - dev->enetaddr[3], dev->enetaddr[2], - dev->enetaddr[1], dev->enetaddr[0]); - mac_dev->mac_addr_0 = ((dev->enetaddr[3]) << 24 | - (dev->enetaddr[2]) << 16 | - (dev->enetaddr[1]) << 8 | (dev->enetaddr[0])); - - mac_dev->mac_addr_1 = ((dev->enetaddr[5] << 8 | - (dev->enetaddr[4])) & 0xFFFF); - - /* Set the MAC address */ - mac_dev->supp_mac_addr_0_0 = mac_dev->mac_addr_0; - mac_dev->supp_mac_addr_0_1 = mac_dev->mac_addr_1; - - /* Set the MAC address */ - mac_dev->supp_mac_addr_1_0 = mac_dev->mac_addr_0; - mac_dev->supp_mac_addr_1_1 = mac_dev->mac_addr_1; - - /* Set the MAC address */ - mac_dev->supp_mac_addr_2_0 = mac_dev->mac_addr_0; - mac_dev->supp_mac_addr_2_1 = mac_dev->mac_addr_1; - - /* Set the MAC address */ - mac_dev->supp_mac_addr_3_0 = mac_dev->mac_addr_0; - mac_dev->supp_mac_addr_3_1 = mac_dev->mac_addr_1; - return 0; -} - -static int tse_eth_init(struct eth_device *dev, bd_t * bd) -{ - int dat; - struct altera_tse_priv *priv = dev->priv; - volatile struct alt_tse_mac *mac_dev = priv->mac_dev; - volatile struct alt_sgdma_descriptor *tx_desc = priv->tx_desc; - volatile struct alt_sgdma_descriptor *rx_desc = priv->rx_desc; - volatile struct alt_sgdma_descriptor *rx_desc_cur = - (volatile struct alt_sgdma_descriptor *)&rx_desc[0]; - - /* stop controller */ - debug("Reseting TSE & SGDMAs\n"); - tse_eth_reset(dev); - - /* start the phy */ - debug("Configuring PHY\n"); - phy_run_commands(priv, priv->phyinfo->startup); - - /* need to create sgdma */ - debug("Configuring tx desc\n"); - alt_sgdma_construct_descriptor_burst( - (volatile struct alt_sgdma_descriptor *)&tx_desc[0], - (volatile struct alt_sgdma_descriptor *)&tx_desc[1], - (unsigned int *)NULL, /* read addr */ - (unsigned int *)0, - 0, /* length or EOP ,will change for each tx */ - 0x1, /* gen eop */ - 0x0, /* read fixed */ - 0x1, /* write fixed or sop */ - 0x0, /* read burst */ - 0x0, /* write burst */ - 0x0 /* channel */ - ); - debug("Configuring rx desc\n"); - flush_dcache_range((unsigned long)(NetRxPackets[0]), - (unsigned long)(NetRxPackets[0]) + PKTSIZE_ALIGN); - alt_sgdma_construct_descriptor_burst( - (volatile struct alt_sgdma_descriptor *)&rx_desc[0], - (volatile struct alt_sgdma_descriptor *)&rx_desc[1], - (unsigned int)0x0, /* read addr */ - (unsigned int *)NetRxPackets[0], - 0x0, /* length or EOP */ - 0x0, /* gen eop */ - 0x0, /* read fixed */ - 0x0, /* write fixed or sop */ - 0x0, /* read burst */ - 0x0, /* write burst */ - 0x0 /* channel */ - ); - /* start rx async transfer */ - debug("Starting rx sgdma\n"); - alt_sgdma_do_async_transfer(priv->sgdma_rx, rx_desc_cur); - - /* start TSE */ - debug("Configuring TSE Mac\n"); - /* Initialize MAC registers */ - mac_dev->max_frame_length = PKTSIZE_ALIGN; - mac_dev->rx_almost_empty_threshold = 8; - mac_dev->rx_almost_full_threshold = 8; - mac_dev->tx_almost_empty_threshold = 8; - mac_dev->tx_almost_full_threshold = 3; - mac_dev->tx_sel_empty_threshold = - CONFIG_SYS_ALTERA_TSE_TX_FIFO - 16; - mac_dev->tx_sel_full_threshold = 0; - mac_dev->rx_sel_empty_threshold = - CONFIG_SYS_ALTERA_TSE_TX_FIFO - 16; - mac_dev->rx_sel_full_threshold = 0; - - /* NO Shift */ - mac_dev->rx_cmd_stat.bits.rx_shift16 = 0; - mac_dev->tx_cmd_stat.bits.tx_shift16 = 0; - - /* enable MAC */ - dat = 0; - dat = ALTERA_TSE_CMD_TX_ENA_MSK | ALTERA_TSE_CMD_RX_ENA_MSK; - - mac_dev->command_config.image = dat; - - /* configure the TSE core */ - /* -- output clocks, */ - /* -- and later config stuff for SGMII */ - if (priv->link) { - debug("Adjusting TSE to link speed\n"); - tse_adjust_link(priv); - } - - return priv->link ? 0 : -1; -} - -/* TSE init code */ -int altera_tse_initialize(u8 dev_num, int mac_base, - int sgdma_rx_base, int sgdma_tx_base, - u32 sgdma_desc_base, u32 sgdma_desc_size) -{ - struct altera_tse_priv *priv; - struct eth_device *dev; - struct alt_sgdma_descriptor *rx_desc; - struct alt_sgdma_descriptor *tx_desc; - unsigned long dma_handle; - - dev = (struct eth_device *)malloc(sizeof *dev); - - if (NULL == dev) - return 0; - - memset(dev, 0, sizeof *dev); - - priv = malloc(sizeof(*priv)); - - if (!priv) { - free(dev); - return 0; - } - if (sgdma_desc_size) { - if (sgdma_desc_size < (sizeof(*tx_desc) * (3 + PKTBUFSRX))) { - printf("ALTERA_TSE-%hu: " - "descriptor memory is too small\n", dev_num); - free(priv); - free(dev); - return 0; - } - tx_desc = (struct alt_sgdma_descriptor *)sgdma_desc_base; - } else { - tx_desc = dma_alloc_coherent(sizeof(*tx_desc) * (3 + PKTBUFSRX), - &dma_handle); - } - - rx_desc = tx_desc + 2; - debug("tx desc: address = 0x%x\n", (unsigned int)tx_desc); - debug("rx desc: address = 0x%x\n", (unsigned int)rx_desc); - - if (!tx_desc) { - free(priv); - free(dev); - return 0; - } - memset(rx_desc, 0, (sizeof *rx_desc) * (PKTBUFSRX + 1)); - memset(tx_desc, 0, (sizeof *tx_desc) * 2); - - /* initialize tse priv */ - priv->mac_dev = (volatile struct alt_tse_mac *)mac_base; - priv->sgdma_rx = (volatile struct alt_sgdma_registers *)sgdma_rx_base; - priv->sgdma_tx = (volatile struct alt_sgdma_registers *)sgdma_tx_base; - priv->phyaddr = CONFIG_SYS_ALTERA_TSE_PHY_ADDR; - priv->flags = CONFIG_SYS_ALTERA_TSE_FLAGS; - priv->rx_desc = rx_desc; - priv->tx_desc = tx_desc; - - /* init eth structure */ - dev->priv = priv; - dev->init = tse_eth_init; - dev->halt = tse_eth_halt; - dev->send = tse_eth_send; - dev->recv = tse_eth_rx; - dev->write_hwaddr = tse_set_mac_address; - sprintf(dev->name, "%s-%hu", "ALTERA_TSE", dev_num); - - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) && !defined(BITBANGMII) - miiphy_register(dev->name, altera_tse_miiphy_read, - altera_tse_miiphy_write); -#endif - - init_phy(dev); - - return 1; -} diff --git a/qemu/roms/u-boot/drivers/net/altera_tse.h b/qemu/roms/u-boot/drivers/net/altera_tse.h deleted file mode 100644 index 8880bfc0f..000000000 --- a/qemu/roms/u-boot/drivers/net/altera_tse.h +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Altera 10/100/1000 triple speed ethernet mac - * - * Copyright (C) 2008 Altera Corporation. - * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _ALTERA_TSE_H_ -#define _ALTERA_TSE_H_ - -#define __packed_1_ __attribute__ ((packed, aligned(1))) - -/* PHY Stuff */ -#define miim_end -2 -#define miim_read -1 - -#define PHY_AUTONEGOTIATE_TIMEOUT 5000 /* in ms */ - -#ifndef CONFIG_SYS_TBIPA_VALUE -#define CONFIG_SYS_TBIPA_VALUE 0x1f -#endif -#define MIIMCFG_INIT_VALUE 0x00000003 -#define MIIMCFG_RESET 0x80000000 - -#define MIIMIND_BUSY 0x00000001 -#define MIIMIND_NOTVALID 0x00000004 - -#define MIIM_CONTROL 0x00 -#define MIIM_CONTROL_RESET 0x00009140 -#define MIIM_CONTROL_INIT 0x00001140 -#define MIIM_CONTROL_RESTART 0x00001340 -#define MIIM_ANEN 0x00001000 - -#define MIIM_CR 0x00 -#define MIIM_CR_RST 0x00008000 -#define MIIM_CR_INIT 0x00001000 - -#define MIIM_STATUS 0x1 -#define MIIM_STATUS_AN_DONE 0x00000020 -#define MIIM_STATUS_LINK 0x0004 - -#define MIIM_PHYIR1 0x2 -#define MIIM_PHYIR2 0x3 - -#define MIIM_ANAR 0x4 -#define MIIM_ANAR_INIT 0x1e1 - -#define MIIM_TBI_ANLPBPA 0x5 -#define MIIM_TBI_ANLPBPA_HALF 0x00000040 -#define MIIM_TBI_ANLPBPA_FULL 0x00000020 - -#define MIIM_TBI_ANEX 0x6 -#define MIIM_TBI_ANEX_NP 0x00000004 -#define MIIM_TBI_ANEX_PRX 0x00000002 - -#define MIIM_GBIT_CONTROL 0x9 -#define MIIM_GBIT_CONTROL_INIT 0xe00 - -#define MIIM_EXT_PAGE_ACCESS 0x1f - -/* 88E1011 PHY Status Register */ -#define MIIM_88E1011_PHY_STATUS 0x11 -#define MIIM_88E1011_PHYSTAT_SPEED 0xc000 -#define MIIM_88E1011_PHYSTAT_GBIT 0x8000 -#define MIIM_88E1011_PHYSTAT_100 0x4000 -#define MIIM_88E1011_PHYSTAT_DUPLEX 0x2000 -#define MIIM_88E1011_PHYSTAT_SPDDONE 0x0800 -#define MIIM_88E1011_PHYSTAT_LINK 0x0400 - -#define MIIM_88E1011_PHY_SCR 0x10 -#define MIIM_88E1011_PHY_MDI_X_AUTO 0x0060 - -#define MIIM_88E1111_PHY_EXT_CR 0x14 -#define MIIM_88E1111_PHY_EXT_SR 0x1b - -/* 88E1111 PHY LED Control Register */ -#define MIIM_88E1111_PHY_LED_CONTROL 24 -#define MIIM_88E1111_PHY_LED_DIRECT 0x4100 -#define MIIM_88E1111_PHY_LED_COMBINE 0x411C - -#define MIIM_READ_COMMAND 0x00000001 - -/* struct phy_info: a structure which defines attributes for a PHY - * id will contain a number which represents the PHY. During - * startup, the driver will poll the PHY to find out what its - * UID--as defined by registers 2 and 3--is. The 32-bit result - * gotten from the PHY will be shifted right by "shift" bits to - * discard any bits which may change based on revision numbers - * unimportant to functionality - * - * The struct phy_cmd entries represent pointers to an arrays of - * commands which tell the driver what to do to the PHY. - */ -struct phy_info { - uint id; - char *name; - uint shift; - /* Called to configure the PHY, and modify the controller - * based on the results */ - struct phy_cmd *config; - - /* Called when starting up the controller */ - struct phy_cmd *startup; - - /* Called when bringing down the controller */ - struct phy_cmd *shutdown; -}; - -/* SGDMA Stuff */ -#define ALT_SGDMA_STATUS_ERROR_MSK (0x00000001) -#define ALT_SGDMA_STATUS_EOP_ENCOUNTERED_MSK (0x00000002) -#define ALT_SGDMA_STATUS_DESC_COMPLETED_MSK (0x00000004) -#define ALT_SGDMA_STATUS_CHAIN_COMPLETED_MSK (0x00000008) -#define ALT_SGDMA_STATUS_BUSY_MSK (0x00000010) - -#define ALT_SGDMA_CONTROL_IE_ERROR_MSK (0x00000001) -#define ALT_SGDMA_CONTROL_IE_EOP_ENCOUNTERED_MSK (0x00000002) -#define ALT_SGDMA_CONTROL_IE_DESC_COMPLETED_MSK (0x00000004) -#define ALT_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK (0x00000008) -#define ALT_SGDMA_CONTROL_IE_GLOBAL_MSK (0x00000010) -#define ALT_SGDMA_CONTROL_RUN_MSK (0x00000020) -#define ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK (0x00000040) -#define ALT_SGDMA_CONTROL_IE_MAX_DESC_PROCESSED_MSK (0x00000080) -#define ALT_SGDMA_CONTROL_MAX_DESC_PROCESSED_MSK (0x0000FF00) -#define ALT_SGDMA_CONTROL_SOFTWARERESET_MSK (0x00010000) -#define ALT_SGDMA_CONTROL_PARK_MSK (0x00020000) -#define ALT_SGDMA_CONTROL_CLEAR_INTERRUPT_MSK (0x80000000) - -#define ALTERA_TSE_SGDMA_INTR_MASK (ALT_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK \ - | ALT_SGDMA_STATUS_DESC_COMPLETED_MSK \ - | ALT_SGDMA_CONTROL_IE_GLOBAL_MSK) - -/* - * Descriptor control bit masks & offsets - * - * Note: The control byte physically occupies bits [31:24] in memory. - * The following bit-offsets are expressed relative to the LSB of - * the control register bitfield. - */ -#define ALT_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK (0x00000001) -#define ALT_SGDMA_DESCRIPTOR_CONTROL_READ_FIXED_ADDRESS_MSK (0x00000002) -#define ALT_SGDMA_DESCRIPTOR_CONTROL_WRITE_FIXED_ADDRESS_MSK (0x00000004) -#define ALT_SGDMA_DESCRIPTOR_CONTROL_ATLANTIC_CHANNEL_MSK (0x00000008) -#define ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK (0x00000080) - -/* - * Descriptor status bit masks & offsets - * - * Note: The status byte physically occupies bits [23:16] in memory. - * The following bit-offsets are expressed relative to the LSB of - * the status register bitfield. - */ -#define ALT_SGDMA_DESCRIPTOR_STATUS_E_CRC_MSK (0x00000001) -#define ALT_SGDMA_DESCRIPTOR_STATUS_E_PARITY_MSK (0x00000002) -#define ALT_SGDMA_DESCRIPTOR_STATUS_E_OVERFLOW_MSK (0x00000004) -#define ALT_SGDMA_DESCRIPTOR_STATUS_E_SYNC_MSK (0x00000008) -#define ALT_SGDMA_DESCRIPTOR_STATUS_E_UEOP_MSK (0x00000010) -#define ALT_SGDMA_DESCRIPTOR_STATUS_E_MEOP_MSK (0x00000020) -#define ALT_SGDMA_DESCRIPTOR_STATUS_E_MSOP_MSK (0x00000040) -#define ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK (0x00000080) -#define ALT_SGDMA_DESCRIPTOR_STATUS_ERROR_MSK (0x0000007F) - -/* - * The SGDMA controller buffer descriptor allocates - * 64 bits for each address. To support ANSI C, the - * struct implementing a descriptor places 32-bits - * of padding directly above each address; each pad must - * be cleared when initializing a descriptor. - */ - -/* - * Buffer Descriptor data structure - * - */ -struct alt_sgdma_descriptor { - unsigned int *source; /* the address of data to be read. */ - unsigned int source_pad; - - unsigned int *destination; /* the address to write data */ - unsigned int destination_pad; - - unsigned int *next; /* the next descriptor in the list. */ - unsigned int next_pad; - - unsigned short bytes_to_transfer; /* the number of bytes to transfer */ - unsigned char read_burst; - unsigned char write_burst; - - unsigned short actual_bytes_transferred;/* bytes transferred by DMA */ - unsigned char descriptor_status; - unsigned char descriptor_control; - -} __packed_1_; - -/* SG-DMA Control/Status Slave registers map */ - -struct alt_sgdma_registers { - unsigned int status; - unsigned int status_pad[3]; - unsigned int control; - unsigned int control_pad[3]; - unsigned int next_descriptor_pointer; - unsigned int descriptor_pad[3]; -}; - -/* TSE Stuff */ -#define ALTERA_TSE_CMD_TX_ENA_MSK (0x00000001) -#define ALTERA_TSE_CMD_RX_ENA_MSK (0x00000002) -#define ALTERA_TSE_CMD_XON_GEN_MSK (0x00000004) -#define ALTERA_TSE_CMD_ETH_SPEED_MSK (0x00000008) -#define ALTERA_TSE_CMD_PROMIS_EN_MSK (0x00000010) -#define ALTERA_TSE_CMD_PAD_EN_MSK (0x00000020) -#define ALTERA_TSE_CMD_CRC_FWD_MSK (0x00000040) -#define ALTERA_TSE_CMD_PAUSE_FWD_MSK (0x00000080) -#define ALTERA_TSE_CMD_PAUSE_IGNORE_MSK (0x00000100) -#define ALTERA_TSE_CMD_TX_ADDR_INS_MSK (0x00000200) -#define ALTERA_TSE_CMD_HD_ENA_MSK (0x00000400) -#define ALTERA_TSE_CMD_EXCESS_COL_MSK (0x00000800) -#define ALTERA_TSE_CMD_LATE_COL_MSK (0x00001000) -#define ALTERA_TSE_CMD_SW_RESET_MSK (0x00002000) -#define ALTERA_TSE_CMD_MHASH_SEL_MSK (0x00004000) -#define ALTERA_TSE_CMD_LOOPBACK_MSK (0x00008000) -/* Bits (18:16) = address select */ -#define ALTERA_TSE_CMD_TX_ADDR_SEL_MSK (0x00070000) -#define ALTERA_TSE_CMD_MAGIC_ENA_MSK (0x00080000) -#define ALTERA_TSE_CMD_SLEEP_MSK (0x00100000) -#define ALTERA_TSE_CMD_WAKEUP_MSK (0x00200000) -#define ALTERA_TSE_CMD_XOFF_GEN_MSK (0x00400000) -#define ALTERA_TSE_CMD_CNTL_FRM_ENA_MSK (0x00800000) -#define ALTERA_TSE_CMD_NO_LENGTH_CHECK_MSK (0x01000000) -#define ALTERA_TSE_CMD_ENA_10_MSK (0x02000000) -#define ALTERA_TSE_CMD_RX_ERR_DISC_MSK (0x04000000) -/* Bits (30..27) reserved */ -#define ALTERA_TSE_CMD_CNT_RESET_MSK (0x80000000) - -#define ALTERA_TSE_TX_CMD_STAT_TX_SHIFT16 (0x00040000) -#define ALTERA_TSE_TX_CMD_STAT_OMIT_CRC (0x00020000) - -#define ALTERA_TSE_RX_CMD_STAT_RX_SHIFT16 (0x02000000) - -#define ALT_TSE_SW_RESET_WATCHDOG_CNTR 10000 -#define ALT_TSE_SGDMA_BUSY_WATCHDOG_CNTR 90000000 - -/* Command_Config Register Bit Definitions */ - -typedef volatile union __alt_tse_command_config { - unsigned int image; - struct { - unsigned int - transmit_enable:1, /* bit 0 */ - receive_enable:1, /* bit 1 */ - pause_frame_xon_gen:1, /* bit 2 */ - ethernet_speed:1, /* bit 3 */ - promiscuous_enable:1, /* bit 4 */ - pad_enable:1, /* bit 5 */ - crc_forward:1, /* bit 6 */ - pause_frame_forward:1, /* bit 7 */ - pause_frame_ignore:1, /* bit 8 */ - set_mac_address_on_tx:1, /* bit 9 */ - halfduplex_enable:1, /* bit 10 */ - excessive_collision:1, /* bit 11 */ - late_collision:1, /* bit 12 */ - software_reset:1, /* bit 13 */ - multicast_hash_mode_sel:1, /* bit 14 */ - loopback_enable:1, /* bit 15 */ - src_mac_addr_sel_on_tx:3, /* bit 18:16 */ - magic_packet_detect:1, /* bit 19 */ - sleep_mode_enable:1, /* bit 20 */ - wake_up_request:1, /* bit 21 */ - pause_frame_xoff_gen:1, /* bit 22 */ - control_frame_enable:1, /* bit 23 */ - payload_len_chk_disable:1, /* bit 24 */ - enable_10mbps_intf:1, /* bit 25 */ - rx_error_discard_enable:1, /* bit 26 */ - reserved_bits:4, /* bit 30:27 */ - self_clear_counter_reset:1; /* bit 31 */ - } __packed_1_ bits; -} __packed_1_ alt_tse_command_config; - -/* Tx_Cmd_Stat Register Bit Definitions */ - -typedef volatile union __alt_tse_tx_cmd_stat { - unsigned int image; - struct { - unsigned int reserved_lsbs:17, /* bit 16:0 */ - omit_crc:1, /* bit 17 */ - tx_shift16:1, /* bit 18 */ - reserved_msbs:13; /* bit 31:19 */ - - } __packed_1_ bits; -} alt_tse_tx_cmd_stat; - -/* Rx_Cmd_Stat Register Bit Definitions */ - -typedef volatile union __alt_tse_rx_cmd_stat { - unsigned int image; - struct { - unsigned int reserved_lsbs:25, /* bit 24:0 */ - rx_shift16:1, /* bit 25 */ - reserved_msbs:6; /* bit 31:26 */ - - } __packed_1_ bits; -} alt_tse_rx_cmd_stat; - -struct alt_tse_mdio { - unsigned int control; /*PHY device operation control register */ - unsigned int status; /*PHY device operation status register */ - unsigned int phy_id1; /*Bits 31:16 of PHY identifier. */ - unsigned int phy_id2; /*Bits 15:0 of PHY identifier. */ - unsigned int auto_negotiation_advertisement; - unsigned int remote_partner_base_page_ability; - - unsigned int reg6; - unsigned int reg7; - unsigned int reg8; - unsigned int reg9; - unsigned int rega; - unsigned int regb; - unsigned int regc; - unsigned int regd; - unsigned int rege; - unsigned int regf; - unsigned int reg10; - unsigned int reg11; - unsigned int reg12; - unsigned int reg13; - unsigned int reg14; - unsigned int reg15; - unsigned int reg16; - unsigned int reg17; - unsigned int reg18; - unsigned int reg19; - unsigned int reg1a; - unsigned int reg1b; - unsigned int reg1c; - unsigned int reg1d; - unsigned int reg1e; - unsigned int reg1f; -}; - -/* MAC register Space */ - -struct alt_tse_mac { - unsigned int megacore_revision; - unsigned int scratch_pad; - alt_tse_command_config command_config; - unsigned int mac_addr_0; - unsigned int mac_addr_1; - unsigned int max_frame_length; - unsigned int pause_quanta; - unsigned int rx_sel_empty_threshold; - unsigned int rx_sel_full_threshold; - unsigned int tx_sel_empty_threshold; - unsigned int tx_sel_full_threshold; - unsigned int rx_almost_empty_threshold; - unsigned int rx_almost_full_threshold; - unsigned int tx_almost_empty_threshold; - unsigned int tx_almost_full_threshold; - unsigned int mdio_phy0_addr; - unsigned int mdio_phy1_addr; - - /* only if 100/1000 BaseX PCS, reserved otherwise */ - unsigned int reservedx44[5]; - - unsigned int reg_read_access_status; - unsigned int min_tx_ipg_length; - - /* IEEE 802.3 oEntity Managed Object Support */ - unsigned int aMACID_1; /*The MAC addresses */ - unsigned int aMACID_2; - unsigned int aFramesTransmittedOK; - unsigned int aFramesReceivedOK; - unsigned int aFramesCheckSequenceErrors; - unsigned int aAlignmentErrors; - unsigned int aOctetsTransmittedOK; - unsigned int aOctetsReceivedOK; - - /* IEEE 802.3 oPausedEntity Managed Object Support */ - unsigned int aTxPAUSEMACCtrlFrames; - unsigned int aRxPAUSEMACCtrlFrames; - - /* IETF MIB (MIB-II) Object Support */ - unsigned int ifInErrors; - unsigned int ifOutErrors; - unsigned int ifInUcastPkts; - unsigned int ifInMulticastPkts; - unsigned int ifInBroadcastPkts; - unsigned int ifOutDiscards; - unsigned int ifOutUcastPkts; - unsigned int ifOutMulticastPkts; - unsigned int ifOutBroadcastPkts; - - /* IETF RMON MIB Object Support */ - unsigned int etherStatsDropEvent; - unsigned int etherStatsOctets; - unsigned int etherStatsPkts; - unsigned int etherStatsUndersizePkts; - unsigned int etherStatsOversizePkts; - unsigned int etherStatsPkts64Octets; - unsigned int etherStatsPkts65to127Octets; - unsigned int etherStatsPkts128to255Octets; - unsigned int etherStatsPkts256to511Octets; - unsigned int etherStatsPkts512to1023Octets; - unsigned int etherStatsPkts1024to1518Octets; - - unsigned int etherStatsPkts1519toXOctets; - unsigned int etherStatsJabbers; - unsigned int etherStatsFragments; - - unsigned int reservedxE4; - - /*FIFO control register. */ - alt_tse_tx_cmd_stat tx_cmd_stat; - alt_tse_rx_cmd_stat rx_cmd_stat; - - unsigned int ipaccTxConf; - unsigned int ipaccRxConf; - unsigned int ipaccRxStat; - unsigned int ipaccRxStatSum; - - /*Multicast address resolution table */ - unsigned int hash_table[64]; - - /*Registers 0 to 31 within PHY device 0/1 */ - struct alt_tse_mdio mdio_phy0; - struct alt_tse_mdio mdio_phy1; - - /*4 Supplemental MAC Addresses */ - unsigned int supp_mac_addr_0_0; - unsigned int supp_mac_addr_0_1; - unsigned int supp_mac_addr_1_0; - unsigned int supp_mac_addr_1_1; - unsigned int supp_mac_addr_2_0; - unsigned int supp_mac_addr_2_1; - unsigned int supp_mac_addr_3_0; - unsigned int supp_mac_addr_3_1; - - unsigned int reservedx320[56]; -}; - -/* flags: TSE MII modes */ -/* GMII/MII = 0 */ -/* RGMII = 1 */ -/* RGMII_ID = 2 */ -/* RGMII_TXID = 3 */ -/* RGMII_RXID = 4 */ -/* SGMII = 5 */ -struct altera_tse_priv { - char devname[16]; - volatile struct alt_tse_mac *mac_dev; - volatile struct alt_sgdma_registers *sgdma_rx; - volatile struct alt_sgdma_registers *sgdma_tx; - unsigned int rx_sgdma_irq; - unsigned int tx_sgdma_irq; - unsigned int has_descriptor_mem; - unsigned int descriptor_mem_base; - unsigned int descriptor_mem_size; - volatile struct alt_sgdma_descriptor *rx_desc; - volatile struct alt_sgdma_descriptor *tx_desc; - volatile unsigned char *rx_buf; - struct phy_info *phyinfo; - unsigned int phyaddr; - unsigned int flags; - unsigned int link; - unsigned int duplexity; - unsigned int speed; -}; - -/* Phy stuff continued */ -/* - * struct phy_cmd: A command for reading or writing a PHY register - * - * mii_reg: The register to read or write - * - * mii_data: For writes, the value to put in the register. - * A value of -1 indicates this is a read. - * - * funct: A function pointer which is invoked for each command. - * For reads, this function will be passed the value read - * from the PHY, and process it. - * For writes, the result of this function will be written - * to the PHY register - */ -struct phy_cmd { - uint mii_reg; - uint mii_data; - uint(*funct) (uint mii_reg, struct altera_tse_priv *priv); -}; -#endif /* _ALTERA_TSE_H_ */ diff --git a/qemu/roms/u-boot/drivers/net/armada100_fec.c b/qemu/roms/u-boot/drivers/net/armada100_fec.c deleted file mode 100644 index a8da6b17d..000000000 --- a/qemu/roms/u-boot/drivers/net/armada100_fec.c +++ /dev/null @@ -1,726 +0,0 @@ -/* - * (C) Copyright 2011 - * eInfochips Ltd. <www.einfochips.com> - * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com> - * - * (C) Copyright 2010 - * Marvell Semiconductor <www.marvell.com> - * Contributor: Mahavir Jain <mjain@marvell.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <net.h> -#include <malloc.h> -#include <miiphy.h> -#include <netdev.h> -#include <asm/types.h> -#include <asm/byteorder.h> -#include <linux/err.h> -#include <linux/mii.h> -#include <asm/io.h> -#include <asm/arch/armada100.h> -#include "armada100_fec.h" - -#define PHY_ADR_REQ 0xFF /* Magic number to read/write PHY address */ - -#ifdef DEBUG -static int eth_dump_regs(struct eth_device *dev) -{ - struct armdfec_device *darmdfec = to_darmdfec(dev); - struct armdfec_reg *regs = darmdfec->regs; - unsigned int i = 0; - - printf("\noffset: phy_adr, value: 0x%x\n", readl(®s->phyadr)); - printf("offset: smi, value: 0x%x\n", readl(®s->smi)); - for (i = 0x400; i <= 0x4e4; i += 4) - printf("offset: 0x%x, value: 0x%x\n", - i, readl(ARMD1_FEC_BASE + i)); - return 0; -} -#endif - -static int armdfec_phy_timeout(u32 *reg, u32 flag, int cond) -{ - u32 timeout = PHY_WAIT_ITERATIONS; - u32 reg_val; - - while (--timeout) { - reg_val = readl(reg); - if (cond && (reg_val & flag)) - break; - else if (!cond && !(reg_val & flag)) - break; - udelay(PHY_WAIT_MICRO_SECONDS); - } - return !timeout; -} - -static int smi_reg_read(const char *devname, u8 phy_addr, u8 phy_reg, - u16 *value) -{ - struct eth_device *dev = eth_get_dev_by_name(devname); - struct armdfec_device *darmdfec = to_darmdfec(dev); - struct armdfec_reg *regs = darmdfec->regs; - u32 val; - - if (phy_addr == PHY_ADR_REQ && phy_reg == PHY_ADR_REQ) { - val = readl(®s->phyadr); - *value = val & 0x1f; - return 0; - } - - /* check parameters */ - if (phy_addr > PHY_MASK) { - printf("ARMD100 FEC: (%s) Invalid phy address: 0x%X\n", - __func__, phy_addr); - return -EINVAL; - } - if (phy_reg > PHY_MASK) { - printf("ARMD100 FEC: (%s) Invalid register offset: 0x%X\n", - __func__, phy_reg); - return -EINVAL; - } - - /* wait for the SMI register to become available */ - if (armdfec_phy_timeout(®s->smi, SMI_BUSY, false)) { - printf("ARMD100 FEC: (%s) PHY busy timeout\n", __func__); - return -1; - } - - writel((phy_addr << 16) | (phy_reg << 21) | SMI_OP_R, ®s->smi); - - /* now wait for the data to be valid */ - if (armdfec_phy_timeout(®s->smi, SMI_R_VALID, true)) { - val = readl(®s->smi); - printf("ARMD100 FEC: (%s) PHY Read timeout, val=0x%x\n", - __func__, val); - return -1; - } - val = readl(®s->smi); - *value = val & 0xffff; - - return 0; -} - -static int smi_reg_write(const char *devname, - u8 phy_addr, u8 phy_reg, u16 value) -{ - struct eth_device *dev = eth_get_dev_by_name(devname); - struct armdfec_device *darmdfec = to_darmdfec(dev); - struct armdfec_reg *regs = darmdfec->regs; - - if (phy_addr == PHY_ADR_REQ && phy_reg == PHY_ADR_REQ) { - clrsetbits_le32(®s->phyadr, 0x1f, value & 0x1f); - return 0; - } - - /* check parameters */ - if (phy_addr > PHY_MASK) { - printf("ARMD100 FEC: (%s) Invalid phy address\n", __func__); - return -EINVAL; - } - if (phy_reg > PHY_MASK) { - printf("ARMD100 FEC: (%s) Invalid register offset\n", __func__); - return -EINVAL; - } - - /* wait for the SMI register to become available */ - if (armdfec_phy_timeout(®s->smi, SMI_BUSY, false)) { - printf("ARMD100 FEC: (%s) PHY busy timeout\n", __func__); - return -1; - } - - writel((phy_addr << 16) | (phy_reg << 21) | SMI_OP_W | (value & 0xffff), - ®s->smi); - return 0; -} - -/* - * Abort any transmit and receive operations and put DMA - * in idle state. AT and AR bits are cleared upon entering - * in IDLE state. So poll those bits to verify operation. - */ -static void abortdma(struct eth_device *dev) -{ - struct armdfec_device *darmdfec = to_darmdfec(dev); - struct armdfec_reg *regs = darmdfec->regs; - int delay; - int maxretries = 40; - u32 tmp; - - while (--maxretries) { - writel(SDMA_CMD_AR | SDMA_CMD_AT, ®s->sdma_cmd); - udelay(100); - - delay = 10; - while (--delay) { - tmp = readl(®s->sdma_cmd); - if (!(tmp & (SDMA_CMD_AR | SDMA_CMD_AT))) - break; - udelay(10); - } - if (delay) - break; - } - - if (!maxretries) - printf("ARMD100 FEC: (%s) DMA Stuck\n", __func__); -} - -static inline u32 nibble_swapping_32_bit(u32 x) -{ - return ((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4); -} - -static inline u32 nibble_swapping_16_bit(u32 x) -{ - return ((x & 0x0000f0f0) >> 4) | ((x & 0x00000f0f) << 4); -} - -static inline u32 flip_4_bits(u32 x) -{ - return ((x & 0x01) << 3) | ((x & 0x002) << 1) - | ((x & 0x04) >> 1) | ((x & 0x008) >> 3); -} - -/* - * This function will calculate the hash function of the address. - * depends on the hash mode and hash size. - * Inputs - * mach - the 2 most significant bytes of the MAC address. - * macl - the 4 least significant bytes of the MAC address. - * Outputs - * return the calculated entry. - */ -static u32 hash_function(u32 mach, u32 macl) -{ - u32 hashresult; - u32 addrh; - u32 addrl; - u32 addr0; - u32 addr1; - u32 addr2; - u32 addr3; - u32 addrhswapped; - u32 addrlswapped; - - addrh = nibble_swapping_16_bit(mach); - addrl = nibble_swapping_32_bit(macl); - - addrhswapped = flip_4_bits(addrh & 0xf) - + ((flip_4_bits((addrh >> 4) & 0xf)) << 4) - + ((flip_4_bits((addrh >> 8) & 0xf)) << 8) - + ((flip_4_bits((addrh >> 12) & 0xf)) << 12); - - addrlswapped = flip_4_bits(addrl & 0xf) - + ((flip_4_bits((addrl >> 4) & 0xf)) << 4) - + ((flip_4_bits((addrl >> 8) & 0xf)) << 8) - + ((flip_4_bits((addrl >> 12) & 0xf)) << 12) - + ((flip_4_bits((addrl >> 16) & 0xf)) << 16) - + ((flip_4_bits((addrl >> 20) & 0xf)) << 20) - + ((flip_4_bits((addrl >> 24) & 0xf)) << 24) - + ((flip_4_bits((addrl >> 28) & 0xf)) << 28); - - addrh = addrhswapped; - addrl = addrlswapped; - - addr0 = (addrl >> 2) & 0x03f; - addr1 = (addrl & 0x003) | (((addrl >> 8) & 0x7f) << 2); - addr2 = (addrl >> 15) & 0x1ff; - addr3 = ((addrl >> 24) & 0x0ff) | ((addrh & 1) << 8); - - hashresult = (addr0 << 9) | (addr1 ^ addr2 ^ addr3); - hashresult = hashresult & 0x07ff; - return hashresult; -} - -/* - * This function will add an entry to the address table. - * depends on the hash mode and hash size that was initialized. - * Inputs - * mach - the 2 most significant bytes of the MAC address. - * macl - the 4 least significant bytes of the MAC address. - * skip - if 1, skip this address. - * rd - the RD field in the address table. - * Outputs - * address table entry is added. - * 0 if success. - * -ENOSPC if table full - */ -static int add_del_hash_entry(struct armdfec_device *darmdfec, u32 mach, - u32 macl, u32 rd, u32 skip, int del) -{ - struct addr_table_entry_t *entry, *start; - u32 newhi; - u32 newlo; - u32 i; - - newlo = (((mach >> 4) & 0xf) << 15) - | (((mach >> 0) & 0xf) << 11) - | (((mach >> 12) & 0xf) << 7) - | (((mach >> 8) & 0xf) << 3) - | (((macl >> 20) & 0x1) << 31) - | (((macl >> 16) & 0xf) << 27) - | (((macl >> 28) & 0xf) << 23) - | (((macl >> 24) & 0xf) << 19) - | (skip << HTESKIP) | (rd << HTERDBIT) - | HTEVALID; - - newhi = (((macl >> 4) & 0xf) << 15) - | (((macl >> 0) & 0xf) << 11) - | (((macl >> 12) & 0xf) << 7) - | (((macl >> 8) & 0xf) << 3) - | (((macl >> 21) & 0x7) << 0); - - /* - * Pick the appropriate table, start scanning for free/reusable - * entries at the index obtained by hashing the specified MAC address - */ - start = (struct addr_table_entry_t *)(darmdfec->htpr); - entry = start + hash_function(mach, macl); - for (i = 0; i < HOP_NUMBER; i++) { - if (!(entry->lo & HTEVALID)) { - break; - } else { - /* if same address put in same position */ - if (((entry->lo & 0xfffffff8) == (newlo & 0xfffffff8)) - && (entry->hi == newhi)) - break; - } - if (entry == start + 0x7ff) - entry = start; - else - entry++; - } - - if (((entry->lo & 0xfffffff8) != (newlo & 0xfffffff8)) && - (entry->hi != newhi) && del) - return 0; - - if (i == HOP_NUMBER) { - if (!del) { - printf("ARMD100 FEC: (%s) table section is full\n", - __func__); - return -ENOSPC; - } else { - return 0; - } - } - - /* - * Update the selected entry - */ - if (del) { - entry->hi = 0; - entry->lo = 0; - } else { - entry->hi = newhi; - entry->lo = newlo; - } - - return 0; -} - -/* - * Create an addressTable entry from MAC address info - * found in the specifed net_device struct - * - * Input : pointer to ethernet interface network device structure - * Output : N/A - */ -static void update_hash_table_mac_address(struct armdfec_device *darmdfec, - u8 *oaddr, u8 *addr) -{ - u32 mach; - u32 macl; - - /* Delete old entry */ - if (oaddr) { - mach = (oaddr[0] << 8) | oaddr[1]; - macl = (oaddr[2] << 24) | (oaddr[3] << 16) | - (oaddr[4] << 8) | oaddr[5]; - add_del_hash_entry(darmdfec, mach, macl, 1, 0, HASH_DELETE); - } - - /* Add new entry */ - mach = (addr[0] << 8) | addr[1]; - macl = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]; - add_del_hash_entry(darmdfec, mach, macl, 1, 0, HASH_ADD); -} - -/* Address Table Initialization */ -static void init_hashtable(struct eth_device *dev) -{ - struct armdfec_device *darmdfec = to_darmdfec(dev); - struct armdfec_reg *regs = darmdfec->regs; - memset(darmdfec->htpr, 0, HASH_ADDR_TABLE_SIZE); - writel((u32)darmdfec->htpr, ®s->htpr); -} - -/* - * This detects PHY chip from address 0-31 by reading PHY status - * registers. PHY chip can be connected at any of this address. - */ -static int ethernet_phy_detect(struct eth_device *dev) -{ - u32 val; - u16 tmp, mii_status; - u8 addr; - - for (addr = 0; addr < 32; addr++) { - if (miiphy_read(dev->name, addr, MII_BMSR, &mii_status) != 0) - /* try next phy */ - continue; - - /* invalid MII status. More validation required here... */ - if (mii_status == 0 || mii_status == 0xffff) - /* try next phy */ - continue; - - if (miiphy_read(dev->name, addr, MII_PHYSID1, &tmp) != 0) - /* try next phy */ - continue; - - val = tmp << 16; - if (miiphy_read(dev->name, addr, MII_PHYSID2, &tmp) != 0) - /* try next phy */ - continue; - - val |= tmp; - - if ((val & 0xfffffff0) != 0) - return addr; - } - return -1; -} - -static void armdfec_init_rx_desc_ring(struct armdfec_device *darmdfec) -{ - struct rx_desc *p_rx_desc; - int i; - - /* initialize the Rx descriptors ring */ - p_rx_desc = darmdfec->p_rxdesc; - for (i = 0; i < RINGSZ; i++) { - p_rx_desc->cmd_sts = BUF_OWNED_BY_DMA | RX_EN_INT; - p_rx_desc->buf_size = PKTSIZE_ALIGN; - p_rx_desc->byte_cnt = 0; - p_rx_desc->buf_ptr = darmdfec->p_rxbuf + i * PKTSIZE_ALIGN; - if (i == (RINGSZ - 1)) { - p_rx_desc->nxtdesc_p = darmdfec->p_rxdesc; - } else { - p_rx_desc->nxtdesc_p = (struct rx_desc *) - ((u32)p_rx_desc + ARMDFEC_RXQ_DESC_ALIGNED_SIZE); - p_rx_desc = p_rx_desc->nxtdesc_p; - } - } - darmdfec->p_rxdesc_curr = darmdfec->p_rxdesc; -} - -static int armdfec_init(struct eth_device *dev, bd_t *bd) -{ - struct armdfec_device *darmdfec = to_darmdfec(dev); - struct armdfec_reg *regs = darmdfec->regs; - int phy_adr; - u32 temp; - - armdfec_init_rx_desc_ring(darmdfec); - - /* Disable interrupts */ - writel(0, ®s->im); - writel(0, ®s->ic); - /* Write to ICR to clear interrupts. */ - writel(0, ®s->iwc); - - /* - * Abort any transmit and receive operations and put DMA - * in idle state. - */ - abortdma(dev); - - /* Initialize address hash table */ - init_hashtable(dev); - - /* SDMA configuration */ - writel(SDCR_BSZ8 | /* Burst size = 32 bytes */ - SDCR_RIFB | /* Rx interrupt on frame */ - SDCR_BLMT | /* Little endian transmit */ - SDCR_BLMR | /* Little endian receive */ - SDCR_RC_MAX_RETRANS, /* Max retransmit count */ - ®s->sdma_conf); - /* Port Configuration */ - writel(PCR_HS, ®s->pconf); /* Hash size is 1/2kb */ - - /* Set extended port configuration */ - writel(PCXR_2BSM | /* Two byte suffix aligns IP hdr */ - PCXR_DSCP_EN | /* Enable DSCP in IP */ - PCXR_MFL_1536 | /* Set MTU = 1536 */ - PCXR_FLP | /* do not force link pass */ - PCXR_TX_HIGH_PRI, /* Transmit - high priority queue */ - ®s->pconf_ext); - - update_hash_table_mac_address(darmdfec, NULL, dev->enetaddr); - - /* Update TX and RX queue descriptor register */ - temp = (u32)®s->txcdp[TXQ]; - writel((u32)darmdfec->p_txdesc, temp); - temp = (u32)®s->rxfdp[RXQ]; - writel((u32)darmdfec->p_rxdesc, temp); - temp = (u32)®s->rxcdp[RXQ]; - writel((u32)darmdfec->p_rxdesc_curr, temp); - - /* Enable Interrupts */ - writel(ALL_INTS, ®s->im); - - /* Enable Ethernet Port */ - setbits_le32(®s->pconf, PCR_EN); - - /* Enable RX DMA engine */ - setbits_le32(®s->sdma_cmd, SDMA_CMD_ERD); - -#ifdef DEBUG - eth_dump_regs(dev); -#endif - -#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) - -#if defined(CONFIG_PHY_BASE_ADR) - miiphy_write(dev->name, PHY_ADR_REQ, PHY_ADR_REQ, CONFIG_PHY_BASE_ADR); -#else - /* Search phy address from range 0-31 */ - phy_adr = ethernet_phy_detect(dev); - if (phy_adr < 0) { - printf("ARMD100 FEC: PHY not detected at address range 0-31\n"); - return -1; - } else { - debug("ARMD100 FEC: PHY detected at addr %d\n", phy_adr); - miiphy_write(dev->name, PHY_ADR_REQ, PHY_ADR_REQ, phy_adr); - } -#endif - -#if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) - /* Wait up to 5s for the link status */ - for (i = 0; i < 5; i++) { - u16 phy_adr; - - miiphy_read(dev->name, 0xFF, 0xFF, &phy_adr); - /* Return if we get link up */ - if (miiphy_link(dev->name, phy_adr)) - return 0; - udelay(1000000); - } - - printf("ARMD100 FEC: No link on %s\n", dev->name); - return -1; -#endif -#endif - return 0; -} - -static void armdfec_halt(struct eth_device *dev) -{ - struct armdfec_device *darmdfec = to_darmdfec(dev); - struct armdfec_reg *regs = darmdfec->regs; - - /* Stop RX DMA */ - clrbits_le32(®s->sdma_cmd, SDMA_CMD_ERD); - - /* - * Abort any transmit and receive operations and put DMA - * in idle state. - */ - abortdma(dev); - - /* Disable interrupts */ - writel(0, ®s->im); - writel(0, ®s->ic); - writel(0, ®s->iwc); - - /* Disable Port */ - clrbits_le32(®s->pconf, PCR_EN); -} - -static int armdfec_send(struct eth_device *dev, void *dataptr, int datasize) -{ - struct armdfec_device *darmdfec = to_darmdfec(dev); - struct armdfec_reg *regs = darmdfec->regs; - struct tx_desc *p_txdesc = darmdfec->p_txdesc; - void *p = (void *)dataptr; - int retry = PHY_WAIT_ITERATIONS * PHY_WAIT_MICRO_SECONDS; - u32 cmd_sts, temp; - - /* Copy buffer if it's misaligned */ - if ((u32)dataptr & 0x07) { - if (datasize > PKTSIZE_ALIGN) { - printf("ARMD100 FEC: Non-aligned data too large (%d)\n", - datasize); - return -1; - } - memcpy(darmdfec->p_aligned_txbuf, p, datasize); - p = darmdfec->p_aligned_txbuf; - } - - p_txdesc->cmd_sts = TX_ZERO_PADDING | TX_GEN_CRC; - p_txdesc->cmd_sts |= TX_FIRST_DESC | TX_LAST_DESC; - p_txdesc->cmd_sts |= BUF_OWNED_BY_DMA; - p_txdesc->cmd_sts |= TX_EN_INT; - p_txdesc->buf_ptr = p; - p_txdesc->byte_cnt = datasize; - - /* Apply send command using high priority TX queue */ - temp = (u32)®s->txcdp[TXQ]; - writel((u32)p_txdesc, temp); - writel(SDMA_CMD_TXDL | SDMA_CMD_TXDH | SDMA_CMD_ERD, ®s->sdma_cmd); - - /* - * wait for packet xmit completion - */ - cmd_sts = readl(&p_txdesc->cmd_sts); - while (cmd_sts & BUF_OWNED_BY_DMA) { - /* return fail if error is detected */ - if ((cmd_sts & (TX_ERROR | TX_LAST_DESC)) == - (TX_ERROR | TX_LAST_DESC)) { - printf("ARMD100 FEC: (%s) in xmit packet\n", __func__); - return -1; - } - cmd_sts = readl(&p_txdesc->cmd_sts); - if (!(retry--)) { - printf("ARMD100 FEC: (%s) xmit packet timeout!\n", - __func__); - return -1; - } - } - - return 0; -} - -static int armdfec_recv(struct eth_device *dev) -{ - struct armdfec_device *darmdfec = to_darmdfec(dev); - struct rx_desc *p_rxdesc_curr = darmdfec->p_rxdesc_curr; - u32 cmd_sts; - u32 timeout = 0; - u32 temp; - - /* wait untill rx packet available or timeout */ - do { - if (timeout < PHY_WAIT_ITERATIONS * PHY_WAIT_MICRO_SECONDS) { - timeout++; - } else { - debug("ARMD100 FEC: %s time out...\n", __func__); - return -1; - } - } while (readl(&p_rxdesc_curr->cmd_sts) & BUF_OWNED_BY_DMA); - - if (p_rxdesc_curr->byte_cnt != 0) { - debug("ARMD100 FEC: %s: Received %d byte Packet @ 0x%x" - "(cmd_sts= %08x)\n", __func__, - (u32)p_rxdesc_curr->byte_cnt, - (u32)p_rxdesc_curr->buf_ptr, - (u32)p_rxdesc_curr->cmd_sts); - } - - /* - * In case received a packet without first/last bits on - * OR the error summary bit is on, - * the packets needs to be dropeed. - */ - cmd_sts = readl(&p_rxdesc_curr->cmd_sts); - - if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) != - (RX_FIRST_DESC | RX_LAST_DESC)) { - printf("ARMD100 FEC: (%s) Dropping packet spread on" - " multiple descriptors\n", __func__); - } else if (cmd_sts & RX_ERROR) { - printf("ARMD100 FEC: (%s) Dropping packet with errors\n", - __func__); - } else { - /* !!! call higher layer processing */ - debug("ARMD100 FEC: (%s) Sending Received packet to" - " upper layer (NetReceive)\n", __func__); - - /* - * let the upper layer handle the packet, subtract offset - * as two dummy bytes are added in received buffer see - * PORT_CONFIG_EXT register bit TWO_Byte_Stuff_Mode bit. - */ - NetReceive((p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET), - (int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET)); - } - /* - * free these descriptors and point next in the ring - */ - p_rxdesc_curr->cmd_sts = BUF_OWNED_BY_DMA | RX_EN_INT; - p_rxdesc_curr->buf_size = PKTSIZE_ALIGN; - p_rxdesc_curr->byte_cnt = 0; - - temp = (u32)&darmdfec->p_rxdesc_curr; - writel((u32)p_rxdesc_curr->nxtdesc_p, temp); - - return 0; -} - -int armada100_fec_register(unsigned long base_addr) -{ - struct armdfec_device *darmdfec; - struct eth_device *dev; - - darmdfec = malloc(sizeof(struct armdfec_device)); - if (!darmdfec) - goto error; - - memset(darmdfec, 0, sizeof(struct armdfec_device)); - - darmdfec->htpr = memalign(8, HASH_ADDR_TABLE_SIZE); - if (!darmdfec->htpr) - goto error1; - - darmdfec->p_rxdesc = memalign(PKTALIGN, - ARMDFEC_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1); - - if (!darmdfec->p_rxdesc) - goto error1; - - darmdfec->p_rxbuf = memalign(PKTALIGN, RINGSZ * PKTSIZE_ALIGN + 1); - if (!darmdfec->p_rxbuf) - goto error1; - - darmdfec->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN); - if (!darmdfec->p_aligned_txbuf) - goto error1; - - darmdfec->p_txdesc = memalign(PKTALIGN, sizeof(struct tx_desc) + 1); - if (!darmdfec->p_txdesc) - goto error1; - - dev = &darmdfec->dev; - /* Assign ARMADA100 Fast Ethernet Controller Base Address */ - darmdfec->regs = (void *)base_addr; - - /* must be less than sizeof(dev->name) */ - strcpy(dev->name, "armd-fec0"); - - dev->init = armdfec_init; - dev->halt = armdfec_halt; - dev->send = armdfec_send; - dev->recv = armdfec_recv; - - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - miiphy_register(dev->name, smi_reg_read, smi_reg_write); -#endif - return 0; - -error1: - free(darmdfec->p_aligned_txbuf); - free(darmdfec->p_rxbuf); - free(darmdfec->p_rxdesc); - free(darmdfec->htpr); -error: - free(darmdfec); - printf("AMD100 FEC: (%s) Failed to allocate memory\n", __func__); - return -1; -} diff --git a/qemu/roms/u-boot/drivers/net/armada100_fec.h b/qemu/roms/u-boot/drivers/net/armada100_fec.h deleted file mode 100644 index 5a0a3d982..000000000 --- a/qemu/roms/u-boot/drivers/net/armada100_fec.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * (C) Copyright 2011 - * eInfochips Ltd. <www.einfochips.com> - * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com> - * - * (C) Copyright 2010 - * Marvell Semiconductor <www.marvell.com> - * Contributor: Mahavir Jain <mjain@marvell.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ARMADA100_FEC_H__ -#define __ARMADA100_FEC_H__ - -#define PORT_NUM 0x0 - -/* RX & TX descriptor command */ -#define BUF_OWNED_BY_DMA (1<<31) - -/* RX descriptor status */ -#define RX_EN_INT (1<<23) -#define RX_FIRST_DESC (1<<17) -#define RX_LAST_DESC (1<<16) -#define RX_ERROR (1<<15) - -/* TX descriptor command */ -#define TX_EN_INT (1<<23) -#define TX_GEN_CRC (1<<22) -#define TX_ZERO_PADDING (1<<18) -#define TX_FIRST_DESC (1<<17) -#define TX_LAST_DESC (1<<16) -#define TX_ERROR (1<<15) - -/* smi register */ -#define SMI_BUSY (1<<28) /* 0 - Write, 1 - Read */ -#define SMI_R_VALID (1<<27) /* 0 - Write, 1 - Read */ -#define SMI_OP_W (0<<26) /* Write operation */ -#define SMI_OP_R (1<<26) /* Read operation */ - -#define HASH_ADD 0 -#define HASH_DELETE 1 -#define HASH_ADDR_TABLE_SIZE 0x4000 /* 16K (1/2K address - PCR_HS == 1) */ -#define HOP_NUMBER 12 - -#define PHY_WAIT_ITERATIONS 1000 /* 1000 iterations * 10uS = 10mS max */ -#define PHY_WAIT_MICRO_SECONDS 10 - -#define ETH_HW_IP_ALIGN 2 /* hw aligns IP header */ -#define ETH_EXTRA_HEADER (6+6+2+4) - /* dest+src addr+protocol id+crc */ -#define MAX_PKT_SIZE 1536 - - -/* Bit definitions of the SDMA Config Reg */ -#define SDCR_BSZ_OFF 12 -#define SDCR_BSZ8 (3<<SDCR_BSZ_OFF) -#define SDCR_BSZ4 (2<<SDCR_BSZ_OFF) -#define SDCR_BSZ2 (1<<SDCR_BSZ_OFF) -#define SDCR_BSZ1 (0<<SDCR_BSZ_OFF) -#define SDCR_BLMR (1<<6) -#define SDCR_BLMT (1<<7) -#define SDCR_RIFB (1<<9) -#define SDCR_RC_OFF 2 -#define SDCR_RC_MAX_RETRANS (0xf << SDCR_RC_OFF) - -/* SDMA_CMD */ -#define SDMA_CMD_AT (1<<31) -#define SDMA_CMD_TXDL (1<<24) -#define SDMA_CMD_TXDH (1<<23) -#define SDMA_CMD_AR (1<<15) -#define SDMA_CMD_ERD (1<<7) - - -/* Bit definitions of the Port Config Reg */ -#define PCR_HS (1<<12) -#define PCR_EN (1<<7) -#define PCR_PM (1<<0) - -/* Bit definitions of the Port Config Extend Reg */ -#define PCXR_2BSM (1<<28) -#define PCXR_DSCP_EN (1<<21) -#define PCXR_MFL_1518 (0<<14) -#define PCXR_MFL_1536 (1<<14) -#define PCXR_MFL_2048 (2<<14) -#define PCXR_MFL_64K (3<<14) -#define PCXR_FLP (1<<11) -#define PCXR_PRIO_TX_OFF 3 -#define PCXR_TX_HIGH_PRI (7<<PCXR_PRIO_TX_OFF) - -/* - * * Bit definitions of the Interrupt Cause Reg - * * and Interrupt MASK Reg is the same - * */ -#define ICR_RXBUF (1<<0) -#define ICR_TXBUF_H (1<<2) -#define ICR_TXBUF_L (1<<3) -#define ICR_TXEND_H (1<<6) -#define ICR_TXEND_L (1<<7) -#define ICR_RXERR (1<<8) -#define ICR_TXERR_H (1<<10) -#define ICR_TXERR_L (1<<11) -#define ICR_TX_UDR (1<<13) -#define ICR_MII_CH (1<<28) - -#define ALL_INTS (ICR_TXBUF_H | ICR_TXBUF_L | ICR_TX_UDR |\ - ICR_TXERR_H | ICR_TXERR_L |\ - ICR_TXEND_H | ICR_TXEND_L |\ - ICR_RXBUF | ICR_RXERR | ICR_MII_CH) - -#define PHY_MASK 0x0000001f - -#define to_darmdfec(_kd) container_of(_kd, struct armdfec_device, dev) -/* Size of a Tx/Rx descriptor used in chain list data structure */ -#define ARMDFEC_RXQ_DESC_ALIGNED_SIZE \ - (((sizeof(struct rx_desc) / PKTALIGN) + 1) * PKTALIGN) - -#define RX_BUF_OFFSET 0x2 -#define RXQ 0x0 /* RX Queue 0 */ -#define TXQ 0x1 /* TX Queue 1 */ - -struct addr_table_entry_t { - u32 lo; - u32 hi; -}; - -/* Bit fields of a Hash Table Entry */ -enum hash_table_entry { - HTEVALID = 1, - HTESKIP = 2, - HTERD = 4, - HTERDBIT = 2 -}; - -struct tx_desc { - u32 cmd_sts; /* Command/status field */ - u16 reserved; - u16 byte_cnt; /* buffer byte count */ - u8 *buf_ptr; /* pointer to buffer for this descriptor */ - struct tx_desc *nextdesc_p; /* Pointer to next descriptor */ -}; - -struct rx_desc { - u32 cmd_sts; /* Descriptor command status */ - u16 byte_cnt; /* Descriptor buffer byte count */ - u16 buf_size; /* Buffer size */ - u8 *buf_ptr; /* Descriptor buffer pointer */ - struct rx_desc *nxtdesc_p; /* Next descriptor pointer */ -}; - -/* - * Armada100 Fast Ethernet controller Registers - * Refer Datasheet Appendix A.22 - */ -struct armdfec_reg { - u32 phyadr; /* PHY Address */ - u32 pad1[3]; - u32 smi; /* SMI */ - u32 pad2[0xFB]; - u32 pconf; /* Port configuration */ - u32 pad3; - u32 pconf_ext; /* Port configuration extend */ - u32 pad4; - u32 pcmd; /* Port Command */ - u32 pad5; - u32 pstatus; /* Port Status */ - u32 pad6; - u32 spar; /* Serial Parameters */ - u32 pad7; - u32 htpr; /* Hash table pointer */ - u32 pad8; - u32 fcsal; /* Flow control source address low */ - u32 pad9; - u32 fcsah; /* Flow control source address high */ - u32 pad10; - u32 sdma_conf; /* SDMA configuration */ - u32 pad11; - u32 sdma_cmd; /* SDMA command */ - u32 pad12; - u32 ic; /* Interrupt cause */ - u32 iwc; /* Interrupt write to clear */ - u32 im; /* Interrupt mask */ - u32 pad13; - u32 *eth_idscpp[4]; /* Eth0 IP Differentiated Services Code - Point to Priority 0 Low */ - u32 eth_vlan_p; /* Eth0 VLAN Priority Tag to Priority */ - u32 pad14[3]; - struct rx_desc *rxfdp[4]; /* Ethernet First Rx Descriptor - Pointer */ - u32 pad15[4]; - struct rx_desc *rxcdp[4]; /* Ethernet Current Rx Descriptor - Pointer */ - u32 pad16[0x0C]; - struct tx_desc *txcdp[2]; /* Ethernet Current Tx Descriptor - Pointer */ -}; - -struct armdfec_device { - struct eth_device dev; - struct armdfec_reg *regs; - struct tx_desc *p_txdesc; - struct rx_desc *p_rxdesc; - struct rx_desc *p_rxdesc_curr; - u8 *p_rxbuf; - u8 *p_aligned_txbuf; - u8 *htpr; /* hash pointer */ -}; - -#endif /* __ARMADA100_FEC_H__ */ diff --git a/qemu/roms/u-boot/drivers/net/at91_emac.c b/qemu/roms/u-boot/drivers/net/at91_emac.c deleted file mode 100644 index 64d4c56ac..000000000 --- a/qemu/roms/u-boot/drivers/net/at91_emac.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright (C) 2009 BuS Elektronik GmbH & Co. KG - * Jens Scharsig (esw@bus-elektronik.de) - * - * (C) Copyright 2003 - * Author : Hamid Ikdoumi (Atmel) - - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/arch/hardware.h> -#include <asm/arch/at91_emac.h> -#include <asm/arch/at91_pmc.h> -#include <asm/arch/at91_pio.h> -#include <net.h> -#include <netdev.h> -#include <malloc.h> -#include <miiphy.h> -#include <linux/mii.h> - -#undef MII_DEBUG -#undef ET_DEBUG - -#if (CONFIG_SYS_RX_ETH_BUFFER > 1024) -#error AT91 EMAC supports max 1024 RX buffers. \ - Please decrease the CONFIG_SYS_RX_ETH_BUFFER value -#endif - -#ifndef CONFIG_DRIVER_AT91EMAC_PHYADDR -#define CONFIG_DRIVER_AT91EMAC_PHYADDR 0 -#endif - -/* MDIO clock must not exceed 2.5 MHz, so enable MCK divider */ -#if (AT91C_MASTER_CLOCK > 80000000) - #define HCLK_DIV AT91_EMAC_CFG_MCLK_64 -#elif (AT91C_MASTER_CLOCK > 40000000) - #define HCLK_DIV AT91_EMAC_CFG_MCLK_32 -#elif (AT91C_MASTER_CLOCK > 20000000) - #define HCLK_DIV AT91_EMAC_CFG_MCLK_16 -#else - #define HCLK_DIV AT91_EMAC_CFG_MCLK_8 -#endif - -#ifdef ET_DEBUG -#define DEBUG_AT91EMAC 1 -#else -#define DEBUG_AT91EMAC 0 -#endif - -#ifdef MII_DEBUG -#define DEBUG_AT91PHY 1 -#else -#define DEBUG_AT91PHY 0 -#endif - -#ifndef CONFIG_DRIVER_AT91EMAC_QUIET -#define VERBOSEP 1 -#else -#define VERBOSEP 0 -#endif - -#define RBF_ADDR 0xfffffffc -#define RBF_OWNER (1<<0) -#define RBF_WRAP (1<<1) -#define RBF_BROADCAST (1<<31) -#define RBF_MULTICAST (1<<30) -#define RBF_UNICAST (1<<29) -#define RBF_EXTERNAL (1<<28) -#define RBF_UNKNOWN (1<<27) -#define RBF_SIZE 0x07ff -#define RBF_LOCAL4 (1<<26) -#define RBF_LOCAL3 (1<<25) -#define RBF_LOCAL2 (1<<24) -#define RBF_LOCAL1 (1<<23) - -#define RBF_FRAMEMAX CONFIG_SYS_RX_ETH_BUFFER -#define RBF_FRAMELEN 0x600 - -typedef struct { - unsigned long addr, size; -} rbf_t; - -typedef struct { - rbf_t rbfdt[RBF_FRAMEMAX]; - unsigned long rbindex; -} emac_device; - -void at91emac_EnableMDIO(at91_emac_t *at91mac) -{ - /* Mac CTRL reg set for MDIO enable */ - writel(readl(&at91mac->ctl) | AT91_EMAC_CTL_MPE, &at91mac->ctl); -} - -void at91emac_DisableMDIO(at91_emac_t *at91mac) -{ - /* Mac CTRL reg set for MDIO disable */ - writel(readl(&at91mac->ctl) & ~AT91_EMAC_CTL_MPE, &at91mac->ctl); -} - -int at91emac_read(at91_emac_t *at91mac, unsigned char addr, - unsigned char reg, unsigned short *value) -{ - unsigned long netstat; - at91emac_EnableMDIO(at91mac); - - writel(AT91_EMAC_MAN_HIGH | AT91_EMAC_MAN_RW_R | - AT91_EMAC_MAN_REGA(reg) | AT91_EMAC_MAN_CODE_802_3 | - AT91_EMAC_MAN_PHYA(addr), - &at91mac->man); - - do { - netstat = readl(&at91mac->sr); - debug_cond(DEBUG_AT91PHY, "poll SR %08lx\n", netstat); - } while (!(netstat & AT91_EMAC_SR_IDLE)); - - *value = readl(&at91mac->man) & AT91_EMAC_MAN_DATA_MASK; - - at91emac_DisableMDIO(at91mac); - - debug_cond(DEBUG_AT91PHY, - "AT91PHY read %p REG(%d)=%x\n", at91mac, reg, *value); - - return 0; -} - -int at91emac_write(at91_emac_t *at91mac, unsigned char addr, - unsigned char reg, unsigned short value) -{ - unsigned long netstat; - debug_cond(DEBUG_AT91PHY, - "AT91PHY write %p REG(%d)=%p\n", at91mac, reg, &value); - - at91emac_EnableMDIO(at91mac); - - writel(AT91_EMAC_MAN_HIGH | AT91_EMAC_MAN_RW_W | - AT91_EMAC_MAN_REGA(reg) | AT91_EMAC_MAN_CODE_802_3 | - AT91_EMAC_MAN_PHYA(addr) | (value & AT91_EMAC_MAN_DATA_MASK), - &at91mac->man); - - do { - netstat = readl(&at91mac->sr); - debug_cond(DEBUG_AT91PHY, "poll SR %08lx\n", netstat); - } while (!(netstat & AT91_EMAC_SR_IDLE)); - - at91emac_DisableMDIO(at91mac); - - return 0; -} - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - -at91_emac_t *get_emacbase_by_name(const char *devname) -{ - struct eth_device *netdev; - - netdev = eth_get_dev_by_name(devname); - return (at91_emac_t *) netdev->iobase; -} - -int at91emac_mii_read(const char *devname, unsigned char addr, - unsigned char reg, unsigned short *value) -{ - at91_emac_t *emac; - - emac = get_emacbase_by_name(devname); - at91emac_read(emac , addr, reg, value); - return 0; -} - - -int at91emac_mii_write(const char *devname, unsigned char addr, - unsigned char reg, unsigned short value) -{ - at91_emac_t *emac; - - emac = get_emacbase_by_name(devname); - at91emac_write(emac, addr, reg, value); - return 0; -} - -#endif - -static int at91emac_phy_reset(struct eth_device *netdev) -{ - int i; - u16 status, adv; - at91_emac_t *emac; - - emac = (at91_emac_t *) netdev->iobase; - - adv = ADVERTISE_CSMA | ADVERTISE_ALL; - at91emac_write(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, - MII_ADVERTISE, adv); - debug_cond(VERBOSEP, "%s: Starting autonegotiation...\n", netdev->name); - at91emac_write(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_BMCR, - (BMCR_ANENABLE | BMCR_ANRESTART)); - - for (i = 0; i < 30000; i++) { - at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, - MII_BMSR, &status); - if (status & BMSR_ANEGCOMPLETE) - break; - udelay(100); - } - - if (status & BMSR_ANEGCOMPLETE) { - debug_cond(VERBOSEP, - "%s: Autonegotiation complete\n", netdev->name); - } else { - printf("%s: Autonegotiation timed out (status=0x%04x)\n", - netdev->name, status); - return -1; - } - return 0; -} - -static int at91emac_phy_init(struct eth_device *netdev) -{ - u16 phy_id, status, adv, lpa; - int media, speed, duplex; - int i; - at91_emac_t *emac; - - emac = (at91_emac_t *) netdev->iobase; - - /* Check if the PHY is up to snuff... */ - at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, - MII_PHYSID1, &phy_id); - if (phy_id == 0xffff) { - printf("%s: No PHY present\n", netdev->name); - return -1; - } - - at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, - MII_BMSR, &status); - - if (!(status & BMSR_LSTATUS)) { - /* Try to re-negotiate if we don't have link already. */ - if (at91emac_phy_reset(netdev)) - return -2; - - for (i = 0; i < 100000 / 100; i++) { - at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, - MII_BMSR, &status); - if (status & BMSR_LSTATUS) - break; - udelay(100); - } - } - if (!(status & BMSR_LSTATUS)) { - debug_cond(VERBOSEP, "%s: link down\n", netdev->name); - return -3; - } else { - at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, - MII_ADVERTISE, &adv); - at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, - MII_LPA, &lpa); - media = mii_nway_result(lpa & adv); - speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) - ? 1 : 0); - duplex = (media & ADVERTISE_FULL) ? 1 : 0; - debug_cond(VERBOSEP, "%s: link up, %sMbps %s-duplex\n", - netdev->name, - speed ? "100" : "10", - duplex ? "full" : "half"); - } - return 0; -} - -int at91emac_UpdateLinkSpeed(at91_emac_t *emac) -{ - unsigned short stat1; - - at91emac_read(emac, CONFIG_DRIVER_AT91EMAC_PHYADDR, MII_BMSR, &stat1); - - if (!(stat1 & BMSR_LSTATUS)) /* link status up? */ - return -1; - - if (stat1 & BMSR_100FULL) { - /*set Emac for 100BaseTX and Full Duplex */ - writel(readl(&emac->cfg) | - AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD, - &emac->cfg); - return 0; - } - - if (stat1 & BMSR_10FULL) { - /*set MII for 10BaseT and Full Duplex */ - writel((readl(&emac->cfg) & - ~(AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD) - ) | AT91_EMAC_CFG_FD, - &emac->cfg); - return 0; - } - - if (stat1 & BMSR_100HALF) { - /*set MII for 100BaseTX and Half Duplex */ - writel((readl(&emac->cfg) & - ~(AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD) - ) | AT91_EMAC_CFG_SPD, - &emac->cfg); - return 0; - } - - if (stat1 & BMSR_10HALF) { - /*set MII for 10BaseT and Half Duplex */ - writel((readl(&emac->cfg) & - ~(AT91_EMAC_CFG_SPD | AT91_EMAC_CFG_FD)), - &emac->cfg); - return 0; - } - return 0; -} - -static int at91emac_init(struct eth_device *netdev, bd_t *bd) -{ - int i; - u32 value; - emac_device *dev; - at91_emac_t *emac; - at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIO; - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - - emac = (at91_emac_t *) netdev->iobase; - dev = (emac_device *) netdev->priv; - - /* PIO Disable Register */ - value = ATMEL_PMX_AA_EMDIO | ATMEL_PMX_AA_EMDC | - ATMEL_PMX_AA_ERXER | ATMEL_PMX_AA_ERX1 | - ATMEL_PMX_AA_ERX0 | ATMEL_PMX_AA_ECRS | - ATMEL_PMX_AA_ETX1 | ATMEL_PMX_AA_ETX0 | - ATMEL_PMX_AA_ETXEN | ATMEL_PMX_AA_EREFCK; - - writel(value, &pio->pioa.pdr); - writel(value, &pio->pioa.asr); - -#ifdef CONFIG_RMII - value = ATMEL_PMX_BA_ERXCK; -#else - value = ATMEL_PMX_BA_ERXCK | ATMEL_PMX_BA_ECOL | - ATMEL_PMX_BA_ERXDV | ATMEL_PMX_BA_ERX3 | - ATMEL_PMX_BA_ERX2 | ATMEL_PMX_BA_ETXER | - ATMEL_PMX_BA_ETX3 | ATMEL_PMX_BA_ETX2; -#endif - writel(value, &pio->piob.pdr); - writel(value, &pio->piob.bsr); - - writel(1 << ATMEL_ID_EMAC, &pmc->pcer); - writel(readl(&emac->ctl) | AT91_EMAC_CTL_CSR, &emac->ctl); - - /* Init Ethernet buffers */ - for (i = 0; i < RBF_FRAMEMAX; i++) { - dev->rbfdt[i].addr = (unsigned long) NetRxPackets[i]; - dev->rbfdt[i].size = 0; - } - dev->rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP; - dev->rbindex = 0; - writel((u32) &(dev->rbfdt[0]), &emac->rbqp); - - writel(readl(&emac->rsr) & - ~(AT91_EMAC_RSR_OVR | AT91_EMAC_RSR_REC | AT91_EMAC_RSR_BNA), - &emac->rsr); - - value = AT91_EMAC_CFG_CAF | AT91_EMAC_CFG_NBC | - HCLK_DIV; -#ifdef CONFIG_RMII - value |= AT91_EMAC_CFG_RMII; -#endif - writel(value, &emac->cfg); - - writel(readl(&emac->ctl) | AT91_EMAC_CTL_TE | AT91_EMAC_CTL_RE, - &emac->ctl); - - if (!at91emac_phy_init(netdev)) { - at91emac_UpdateLinkSpeed(emac); - return 0; - } - return -1; -} - -static void at91emac_halt(struct eth_device *netdev) -{ - at91_emac_t *emac; - - emac = (at91_emac_t *) netdev->iobase; - writel(readl(&emac->ctl) & ~(AT91_EMAC_CTL_TE | AT91_EMAC_CTL_RE), - &emac->ctl); - debug_cond(DEBUG_AT91EMAC, "halt MAC\n"); -} - -static int at91emac_send(struct eth_device *netdev, void *packet, int length) -{ - at91_emac_t *emac; - - emac = (at91_emac_t *) netdev->iobase; - - while (!(readl(&emac->tsr) & AT91_EMAC_TSR_BNQ)) - ; - writel((u32) packet, &emac->tar); - writel(AT91_EMAC_TCR_LEN(length), &emac->tcr); - while (AT91_EMAC_TCR_LEN(readl(&emac->tcr))) - ; - debug_cond(DEBUG_AT91EMAC, "Send %d\n", length); - writel(readl(&emac->tsr) | AT91_EMAC_TSR_COMP, &emac->tsr); - return 0; -} - -static int at91emac_recv(struct eth_device *netdev) -{ - emac_device *dev; - at91_emac_t *emac; - rbf_t *rbfp; - int size; - - emac = (at91_emac_t *) netdev->iobase; - dev = (emac_device *) netdev->priv; - - rbfp = &dev->rbfdt[dev->rbindex]; - while (rbfp->addr & RBF_OWNER) { - size = rbfp->size & RBF_SIZE; - NetReceive(NetRxPackets[dev->rbindex], size); - - debug_cond(DEBUG_AT91EMAC, "Recv[%ld]: %d bytes @ %lx\n", - dev->rbindex, size, rbfp->addr); - - rbfp->addr &= ~RBF_OWNER; - rbfp->size = 0; - if (dev->rbindex < (RBF_FRAMEMAX-1)) - dev->rbindex++; - else - dev->rbindex = 0; - - rbfp = &(dev->rbfdt[dev->rbindex]); - if (!(rbfp->addr & RBF_OWNER)) - writel(readl(&emac->rsr) | AT91_EMAC_RSR_REC, - &emac->rsr); - } - - if (readl(&emac->isr) & AT91_EMAC_IxR_RBNA) { - /* EMAC silicon bug 41.3.1 workaround 1 */ - writel(readl(&emac->ctl) & ~AT91_EMAC_CTL_RE, &emac->ctl); - writel(readl(&emac->ctl) | AT91_EMAC_CTL_RE, &emac->ctl); - dev->rbindex = 0; - printf("%s: reset receiver (EMAC dead lock bug)\n", - netdev->name); - } - return 0; -} - -static int at91emac_write_hwaddr(struct eth_device *netdev) -{ - at91_emac_t *emac; - at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; - emac = (at91_emac_t *) netdev->iobase; - - writel(1 << ATMEL_ID_EMAC, &pmc->pcer); - debug_cond(DEBUG_AT91EMAC, - "init MAC-ADDR %02x:%02x:%02x:%02x:%02x:%02x\n", - netdev->enetaddr[5], netdev->enetaddr[4], netdev->enetaddr[3], - netdev->enetaddr[2], netdev->enetaddr[1], netdev->enetaddr[0]); - writel( (netdev->enetaddr[0] | netdev->enetaddr[1] << 8 | - netdev->enetaddr[2] << 16 | netdev->enetaddr[3] << 24), - &emac->sa2l); - writel((netdev->enetaddr[4] | netdev->enetaddr[5] << 8), &emac->sa2h); - debug_cond(DEBUG_AT91EMAC, "init MAC-ADDR %x%x\n", - readl(&emac->sa2h), readl(&emac->sa2l)); - return 0; -} - -int at91emac_register(bd_t *bis, unsigned long iobase) -{ - emac_device *emac; - emac_device *emacfix; - struct eth_device *dev; - - if (iobase == 0) - iobase = ATMEL_BASE_EMAC; - emac = malloc(sizeof(*emac)+512); - if (emac == NULL) - return -1; - dev = malloc(sizeof(*dev)); - if (dev == NULL) { - free(emac); - return -1; - } - /* alignment as per Errata (64 bytes) is insufficient! */ - emacfix = (emac_device *) (((unsigned long) emac + 0x1ff) & 0xFFFFFE00); - memset(emacfix, 0, sizeof(emac_device)); - - memset(dev, 0, sizeof(*dev)); - sprintf(dev->name, "emac"); - dev->iobase = iobase; - dev->priv = emacfix; - dev->init = at91emac_init; - dev->halt = at91emac_halt; - dev->send = at91emac_send; - dev->recv = at91emac_recv; - dev->write_hwaddr = at91emac_write_hwaddr; - - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - miiphy_register(dev->name, at91emac_mii_read, at91emac_mii_write); -#endif - return 1; -} diff --git a/qemu/roms/u-boot/drivers/net/ax88180.c b/qemu/roms/u-boot/drivers/net/ax88180.c deleted file mode 100644 index 7f0cfe594..000000000 --- a/qemu/roms/u-boot/drivers/net/ax88180.c +++ /dev/null @@ -1,757 +0,0 @@ -/* - * ax88180: ASIX AX88180 Non-PCI Gigabit Ethernet u-boot driver - * - * This program is free software; you can distribute it and/or modify - * it under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * This program is distributed in the hope 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, - * USA. - */ - -/* - * ======================================================================== - * ASIX AX88180 Non-PCI 16/32-bit Gigabit Ethernet Linux Driver - * - * The AX88180 Ethernet controller is a high performance and highly - * integrated local CPU bus Ethernet controller with embedded 40K bytes - * SRAM and supports both 16-bit and 32-bit SRAM-Like interfaces for any - * embedded systems. - * The AX88180 is a single chip 10/100/1000Mbps Gigabit Ethernet - * controller that supports both MII and RGMII interfaces and is - * compliant to IEEE 802.3, IEEE 802.3u and IEEE 802.3z standards. - * - * Please visit ASIX's web site (http://www.asix.com.tw) for more - * details. - * - * Module Name : ax88180.c - * Date : 2008-07-07 - * History - * 09/06/2006 : New release for AX88180 US2 chip. - * 07/07/2008 : Fix up the coding style and using inline functions - * instead of macros - * ======================================================================== - */ -#include <common.h> -#include <command.h> -#include <net.h> -#include <malloc.h> -#include <linux/mii.h> -#include "ax88180.h" - -/* - * =========================================================================== - * Local SubProgram Declaration - * =========================================================================== - */ -static void ax88180_rx_handler (struct eth_device *dev); -static int ax88180_phy_initial (struct eth_device *dev); -static void ax88180_media_config (struct eth_device *dev); -static unsigned long get_CicadaPHY_media_mode (struct eth_device *dev); -static unsigned long get_MarvellPHY_media_mode (struct eth_device *dev); -static unsigned short ax88180_mdio_read (struct eth_device *dev, - unsigned long regaddr); -static void ax88180_mdio_write (struct eth_device *dev, - unsigned long regaddr, unsigned short regdata); - -/* - * =========================================================================== - * Local SubProgram Bodies - * =========================================================================== - */ -static int ax88180_mdio_check_complete (struct eth_device *dev) -{ - int us_cnt = 10000; - unsigned short tmpval; - - /* MDIO read/write should not take more than 10 ms */ - while (--us_cnt) { - tmpval = INW (dev, MDIOCTRL); - if (((tmpval & READ_PHY) == 0) && ((tmpval & WRITE_PHY) == 0)) - break; - } - - return us_cnt; -} - -static unsigned short -ax88180_mdio_read (struct eth_device *dev, unsigned long regaddr) -{ - struct ax88180_private *priv = (struct ax88180_private *)dev->priv; - unsigned long tmpval = 0; - - OUTW (dev, (READ_PHY | (regaddr << 8) | priv->PhyAddr), MDIOCTRL); - - if (ax88180_mdio_check_complete (dev)) - tmpval = INW (dev, MDIODP); - else - printf ("Failed to read PHY register!\n"); - - return (unsigned short)(tmpval & 0xFFFF); -} - -static void -ax88180_mdio_write (struct eth_device *dev, unsigned long regaddr, - unsigned short regdata) -{ - struct ax88180_private *priv = (struct ax88180_private *)dev->priv; - - OUTW (dev, regdata, MDIODP); - - OUTW (dev, (WRITE_PHY | (regaddr << 8) | priv->PhyAddr), MDIOCTRL); - - if (!ax88180_mdio_check_complete (dev)) - printf ("Failed to write PHY register!\n"); -} - -static int ax88180_phy_reset (struct eth_device *dev) -{ - unsigned short delay_cnt = 500; - - ax88180_mdio_write (dev, MII_BMCR, (BMCR_RESET | BMCR_ANENABLE)); - - /* Wait for the reset to complete, or time out (500 ms) */ - while (ax88180_mdio_read (dev, MII_BMCR) & BMCR_RESET) { - udelay (1000); - if (--delay_cnt == 0) { - printf ("Failed to reset PHY!\n"); - return -1; - } - } - - return 0; -} - -static void ax88180_mac_reset (struct eth_device *dev) -{ - unsigned long tmpval; - unsigned char i; - - struct { - unsigned short offset, value; - } program_seq[] = { - { - MISC, MISC_NORMAL}, { - RXINDICATOR, DEFAULT_RXINDICATOR}, { - TXCMD, DEFAULT_TXCMD}, { - TXBS, DEFAULT_TXBS}, { - TXDES0, DEFAULT_TXDES0}, { - TXDES1, DEFAULT_TXDES1}, { - TXDES2, DEFAULT_TXDES2}, { - TXDES3, DEFAULT_TXDES3}, { - TXCFG, DEFAULT_TXCFG}, { - MACCFG2, DEFAULT_MACCFG2}, { - MACCFG3, DEFAULT_MACCFG3}, { - TXLEN, DEFAULT_TXLEN}, { - RXBTHD0, DEFAULT_RXBTHD0}, { - RXBTHD1, DEFAULT_RXBTHD1}, { - RXFULTHD, DEFAULT_RXFULTHD}, { - DOGTHD0, DEFAULT_DOGTHD0}, { - DOGTHD1, DEFAULT_DOGTHD1},}; - - OUTW (dev, MISC_RESET_MAC, MISC); - tmpval = INW (dev, MISC); - - for (i = 0; i < ARRAY_SIZE(program_seq); i++) - OUTW (dev, program_seq[i].value, program_seq[i].offset); -} - -static int ax88180_poll_tx_complete (struct eth_device *dev) -{ - struct ax88180_private *priv = (struct ax88180_private *)dev->priv; - unsigned long tmpval, txbs_txdp; - int TimeOutCnt = 10000; - - txbs_txdp = 1 << priv->NextTxDesc; - - while (TimeOutCnt--) { - - tmpval = INW (dev, TXBS); - - if ((tmpval & txbs_txdp) == 0) - break; - - udelay (100); - } - - if (TimeOutCnt) - return 0; - else - return -TimeOutCnt; -} - -static void ax88180_rx_handler (struct eth_device *dev) -{ - struct ax88180_private *priv = (struct ax88180_private *)dev->priv; - unsigned long data_size; - unsigned short rxcurt_ptr, rxbound_ptr, next_ptr; - int i; -#if defined (CONFIG_DRIVER_AX88180_16BIT) - unsigned short *rxdata = (unsigned short *)NetRxPackets[0]; -#else - unsigned long *rxdata = (unsigned long *)NetRxPackets[0]; -#endif - unsigned short count; - - rxcurt_ptr = INW (dev, RXCURT); - rxbound_ptr = INW (dev, RXBOUND); - next_ptr = (rxbound_ptr + 1) & RX_PAGE_NUM_MASK; - - debug ("ax88180: RX original RXBOUND=0x%04x," - " RXCURT=0x%04x\n", rxbound_ptr, rxcurt_ptr); - - while (next_ptr != rxcurt_ptr) { - - OUTW (dev, RX_START_READ, RXINDICATOR); - - data_size = READ_RXBUF (dev) & 0xFFFF; - - if ((data_size == 0) || (data_size > MAX_RX_SIZE)) { - - OUTW (dev, RX_STOP_READ, RXINDICATOR); - - ax88180_mac_reset (dev); - printf ("ax88180: Invalid Rx packet length!" - " (len=0x%04lx)\n", data_size); - - debug ("ax88180: RX RXBOUND=0x%04x," - "RXCURT=0x%04x\n", rxbound_ptr, rxcurt_ptr); - return; - } - - rxbound_ptr += (((data_size + 0xF) & 0xFFF0) >> 4) + 1; - rxbound_ptr &= RX_PAGE_NUM_MASK; - - /* Comput access times */ - count = (data_size + priv->PadSize) >> priv->BusWidth; - - for (i = 0; i < count; i++) { - *(rxdata + i) = READ_RXBUF (dev); - } - - OUTW (dev, RX_STOP_READ, RXINDICATOR); - - /* Pass the packet up to the protocol layers. */ - NetReceive (NetRxPackets[0], data_size); - - OUTW (dev, rxbound_ptr, RXBOUND); - - rxcurt_ptr = INW (dev, RXCURT); - rxbound_ptr = INW (dev, RXBOUND); - next_ptr = (rxbound_ptr + 1) & RX_PAGE_NUM_MASK; - - debug ("ax88180: RX updated RXBOUND=0x%04x," - "RXCURT=0x%04x\n", rxbound_ptr, rxcurt_ptr); - } - - return; -} - -static int ax88180_phy_initial (struct eth_device *dev) -{ - struct ax88180_private *priv = (struct ax88180_private *)dev->priv; - unsigned long tmp_regval; - unsigned short phyaddr; - - /* Search for first avaliable PHY chipset */ -#ifdef CONFIG_PHY_ADDR - phyaddr = CONFIG_PHY_ADDR; -#else - for (phyaddr = 0; phyaddr < 32; ++phyaddr) -#endif - { - priv->PhyAddr = phyaddr; - priv->PhyID0 = ax88180_mdio_read(dev, MII_PHYSID1); - priv->PhyID1 = ax88180_mdio_read(dev, MII_PHYSID2); - - switch (priv->PhyID0) { - case MARVELL_ALASKA_PHYSID0: - debug("ax88180: Found Marvell Alaska PHY family." - " (PHY Addr=0x%x)\n", priv->PhyAddr); - - switch (priv->PhyID1) { - case MARVELL_88E1118_PHYSID1: - ax88180_mdio_write(dev, M88E1118_PAGE_SEL, 2); - ax88180_mdio_write(dev, M88E1118_CR, - M88E1118_CR_DEFAULT); - ax88180_mdio_write(dev, M88E1118_PAGE_SEL, 3); - ax88180_mdio_write(dev, M88E1118_LEDCTL, - M88E1118_LEDCTL_DEFAULT); - ax88180_mdio_write(dev, M88E1118_LEDMIX, - M88E1118_LEDMIX_LED050 | M88E1118_LEDMIX_LED150 | 0x15); - ax88180_mdio_write(dev, M88E1118_PAGE_SEL, 0); - default: /* Default to 88E1111 Phy */ - tmp_regval = ax88180_mdio_read(dev, M88E1111_EXT_SSR); - if ((tmp_regval & HWCFG_MODE_MASK) != RGMII_COPPER_MODE) - ax88180_mdio_write(dev, M88E1111_EXT_SCR, - DEFAULT_EXT_SCR); - } - - if (ax88180_phy_reset(dev) < 0) - return 0; - ax88180_mdio_write(dev, M88_IER, LINK_CHANGE_INT); - - return 1; - - case CICADA_CIS8201_PHYSID0: - debug("ax88180: Found CICADA CIS8201 PHY" - " chipset. (PHY Addr=0x%x)\n", priv->PhyAddr); - - ax88180_mdio_write(dev, CIS_IMR, - (CIS_INT_ENABLE | LINK_CHANGE_INT)); - - /* Set CIS_SMI_PRIORITY bit before force the media mode */ - tmp_regval = ax88180_mdio_read(dev, CIS_AUX_CTRL_STATUS); - tmp_regval &= ~CIS_SMI_PRIORITY; - ax88180_mdio_write(dev, CIS_AUX_CTRL_STATUS, tmp_regval); - - return 1; - - case 0xffff: - /* No PHY at this addr */ - break; - - default: - printf("ax88180: Unknown PHY chipset %#x at addr %#x\n", - priv->PhyID0, priv->PhyAddr); - break; - } - } - - printf("ax88180: Unknown PHY chipset!!\n"); - return 0; -} - -static void ax88180_media_config (struct eth_device *dev) -{ - struct ax88180_private *priv = (struct ax88180_private *)dev->priv; - unsigned long bmcr_val, bmsr_val; - unsigned long rxcfg_val, maccfg0_val, maccfg1_val; - unsigned long RealMediaMode; - int i; - - /* Waiting 2 seconds for PHY link stable */ - for (i = 0; i < 20000; i++) { - bmsr_val = ax88180_mdio_read (dev, MII_BMSR); - if (bmsr_val & BMSR_LSTATUS) { - break; - } - udelay (100); - } - - bmsr_val = ax88180_mdio_read (dev, MII_BMSR); - debug ("ax88180: BMSR=0x%04x\n", (unsigned int)bmsr_val); - - if (bmsr_val & BMSR_LSTATUS) { - bmcr_val = ax88180_mdio_read (dev, MII_BMCR); - - if (bmcr_val & BMCR_ANENABLE) { - - /* - * Waiting for Auto-negotiation completion, this may - * take up to 5 seconds. - */ - debug ("ax88180: Auto-negotiation is " - "enabled. Waiting for NWay completion..\n"); - for (i = 0; i < 50000; i++) { - bmsr_val = ax88180_mdio_read (dev, MII_BMSR); - if (bmsr_val & BMSR_ANEGCOMPLETE) { - break; - } - udelay (100); - } - } else - debug ("ax88180: Auto-negotiation is disabled.\n"); - - debug ("ax88180: BMCR=0x%04x, BMSR=0x%04x\n", - (unsigned int)bmcr_val, (unsigned int)bmsr_val); - - /* Get real media mode here */ - switch (priv->PhyID0) { - case MARVELL_ALASKA_PHYSID0: - RealMediaMode = get_MarvellPHY_media_mode(dev); - break; - case CICADA_CIS8201_PHYSID0: - RealMediaMode = get_CicadaPHY_media_mode(dev); - break; - default: - RealMediaMode = MEDIA_1000FULL; - break; - } - - priv->LinkState = INS_LINK_UP; - - switch (RealMediaMode) { - case MEDIA_1000FULL: - debug ("ax88180: 1000Mbps Full-duplex mode.\n"); - rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG; - maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0; - maccfg1_val = GIGA_MODE_EN | RXFLOW_EN | - FULLDUPLEX | DEFAULT_MACCFG1; - break; - - case MEDIA_1000HALF: - debug ("ax88180: 1000Mbps Half-duplex mode.\n"); - rxcfg_val = DEFAULT_RXCFG; - maccfg0_val = DEFAULT_MACCFG0; - maccfg1_val = GIGA_MODE_EN | DEFAULT_MACCFG1; - break; - - case MEDIA_100FULL: - debug ("ax88180: 100Mbps Full-duplex mode.\n"); - rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG; - maccfg0_val = SPEED100 | TXFLOW_ENABLE - | DEFAULT_MACCFG0; - maccfg1_val = RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1; - break; - - case MEDIA_100HALF: - debug ("ax88180: 100Mbps Half-duplex mode.\n"); - rxcfg_val = DEFAULT_RXCFG; - maccfg0_val = SPEED100 | DEFAULT_MACCFG0; - maccfg1_val = DEFAULT_MACCFG1; - break; - - case MEDIA_10FULL: - debug ("ax88180: 10Mbps Full-duplex mode.\n"); - rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG; - maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0; - maccfg1_val = RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1; - break; - - case MEDIA_10HALF: - debug ("ax88180: 10Mbps Half-duplex mode.\n"); - rxcfg_val = DEFAULT_RXCFG; - maccfg0_val = DEFAULT_MACCFG0; - maccfg1_val = DEFAULT_MACCFG1; - break; - default: - debug ("ax88180: Unknow media mode.\n"); - rxcfg_val = DEFAULT_RXCFG; - maccfg0_val = DEFAULT_MACCFG0; - maccfg1_val = DEFAULT_MACCFG1; - - priv->LinkState = INS_LINK_DOWN; - break; - } - - } else { - rxcfg_val = DEFAULT_RXCFG; - maccfg0_val = DEFAULT_MACCFG0; - maccfg1_val = DEFAULT_MACCFG1; - - priv->LinkState = INS_LINK_DOWN; - } - - OUTW (dev, rxcfg_val, RXCFG); - OUTW (dev, maccfg0_val, MACCFG0); - OUTW (dev, maccfg1_val, MACCFG1); - - return; -} - -static unsigned long get_MarvellPHY_media_mode (struct eth_device *dev) -{ - unsigned long m88_ssr; - unsigned long MediaMode; - - m88_ssr = ax88180_mdio_read (dev, M88_SSR); - switch (m88_ssr & SSR_MEDIA_MASK) { - case SSR_1000FULL: - MediaMode = MEDIA_1000FULL; - break; - case SSR_1000HALF: - MediaMode = MEDIA_1000HALF; - break; - case SSR_100FULL: - MediaMode = MEDIA_100FULL; - break; - case SSR_100HALF: - MediaMode = MEDIA_100HALF; - break; - case SSR_10FULL: - MediaMode = MEDIA_10FULL; - break; - case SSR_10HALF: - MediaMode = MEDIA_10HALF; - break; - default: - MediaMode = MEDIA_UNKNOWN; - break; - } - - return MediaMode; -} - -static unsigned long get_CicadaPHY_media_mode (struct eth_device *dev) -{ - unsigned long tmp_regval; - unsigned long MediaMode; - - tmp_regval = ax88180_mdio_read (dev, CIS_AUX_CTRL_STATUS); - switch (tmp_regval & CIS_MEDIA_MASK) { - case CIS_1000FULL: - MediaMode = MEDIA_1000FULL; - break; - case CIS_1000HALF: - MediaMode = MEDIA_1000HALF; - break; - case CIS_100FULL: - MediaMode = MEDIA_100FULL; - break; - case CIS_100HALF: - MediaMode = MEDIA_100HALF; - break; - case CIS_10FULL: - MediaMode = MEDIA_10FULL; - break; - case CIS_10HALF: - MediaMode = MEDIA_10HALF; - break; - default: - MediaMode = MEDIA_UNKNOWN; - break; - } - - return MediaMode; -} - -static void ax88180_halt (struct eth_device *dev) -{ - /* Disable AX88180 TX/RX functions */ - OUTW (dev, WAKEMOD, CMD); -} - -static int ax88180_init (struct eth_device *dev, bd_t * bd) -{ - struct ax88180_private *priv = (struct ax88180_private *)dev->priv; - unsigned short tmp_regval; - - ax88180_mac_reset (dev); - - /* Disable interrupt */ - OUTW (dev, CLEAR_IMR, IMR); - - /* Disable AX88180 TX/RX functions */ - OUTW (dev, WAKEMOD, CMD); - - /* Fill the MAC address */ - tmp_regval = - dev->enetaddr[0] | (((unsigned short)dev->enetaddr[1]) << 8); - OUTW (dev, tmp_regval, MACID0); - - tmp_regval = - dev->enetaddr[2] | (((unsigned short)dev->enetaddr[3]) << 8); - OUTW (dev, tmp_regval, MACID1); - - tmp_regval = - dev->enetaddr[4] | (((unsigned short)dev->enetaddr[5]) << 8); - OUTW (dev, tmp_regval, MACID2); - - ax88180_media_config (dev); - - OUTW (dev, DEFAULT_RXFILTER, RXFILTER); - - /* Initial variables here */ - priv->FirstTxDesc = TXDP0; - priv->NextTxDesc = TXDP0; - - /* Check if there is any invalid interrupt status and clear it. */ - OUTW (dev, INW (dev, ISR), ISR); - - /* Start AX88180 TX/RX functions */ - OUTW (dev, (RXEN | TXEN | WAKEMOD), CMD); - - return 0; -} - -/* Get a data block via Ethernet */ -static int ax88180_recv (struct eth_device *dev) -{ - unsigned short ISR_Status; - unsigned short tmp_regval; - - /* Read and check interrupt status here. */ - ISR_Status = INW (dev, ISR); - - while (ISR_Status) { - /* Clear the interrupt status */ - OUTW (dev, ISR_Status, ISR); - - debug ("\nax88180: The interrupt status = 0x%04x\n", - ISR_Status); - - if (ISR_Status & ISR_PHY) { - /* Read ISR register once to clear PHY interrupt bit */ - tmp_regval = ax88180_mdio_read (dev, M88_ISR); - ax88180_media_config (dev); - } - - if ((ISR_Status & ISR_RX) || (ISR_Status & ISR_RXBUFFOVR)) { - ax88180_rx_handler (dev); - } - - /* Read and check interrupt status again */ - ISR_Status = INW (dev, ISR); - } - - return 0; -} - -/* Send a data block via Ethernet. */ -static int ax88180_send(struct eth_device *dev, void *packet, int length) -{ - struct ax88180_private *priv = (struct ax88180_private *)dev->priv; - unsigned short TXDES_addr; - unsigned short txcmd_txdp, txbs_txdp; - unsigned short tmp_data; - int i; -#if defined (CONFIG_DRIVER_AX88180_16BIT) - volatile unsigned short *txdata = (volatile unsigned short *)packet; -#else - volatile unsigned long *txdata = (volatile unsigned long *)packet; -#endif - unsigned short count; - - if (priv->LinkState != INS_LINK_UP) { - return 0; - } - - priv->FirstTxDesc = priv->NextTxDesc; - txbs_txdp = 1 << priv->FirstTxDesc; - - debug ("ax88180: TXDP%d is available\n", priv->FirstTxDesc); - - txcmd_txdp = priv->FirstTxDesc << 13; - TXDES_addr = TXDES0 + (priv->FirstTxDesc << 2); - - OUTW (dev, (txcmd_txdp | length | TX_START_WRITE), TXCMD); - - /* Comput access times */ - count = (length + priv->PadSize) >> priv->BusWidth; - - for (i = 0; i < count; i++) { - WRITE_TXBUF (dev, *(txdata + i)); - } - - OUTW (dev, txcmd_txdp | length, TXCMD); - OUTW (dev, txbs_txdp, TXBS); - OUTW (dev, (TXDPx_ENABLE | length), TXDES_addr); - - priv->NextTxDesc = (priv->NextTxDesc + 1) & TXDP_MASK; - - /* - * Check the available transmit descriptor, if we had exhausted all - * transmit descriptor ,then we have to wait for at least one free - * descriptor - */ - txbs_txdp = 1 << priv->NextTxDesc; - tmp_data = INW (dev, TXBS); - - if (tmp_data & txbs_txdp) { - if (ax88180_poll_tx_complete (dev) < 0) { - ax88180_mac_reset (dev); - priv->FirstTxDesc = TXDP0; - priv->NextTxDesc = TXDP0; - printf ("ax88180: Transmit time out occurred!\n"); - } - } - - return 0; -} - -static void ax88180_read_mac_addr (struct eth_device *dev) -{ - unsigned short macid0_val, macid1_val, macid2_val; - unsigned short tmp_regval; - unsigned short i; - - /* Reload MAC address from EEPROM */ - OUTW (dev, RELOAD_EEPROM, PROMCTRL); - - /* Waiting for reload eeprom completion */ - for (i = 0; i < 500; i++) { - tmp_regval = INW (dev, PROMCTRL); - if ((tmp_regval & RELOAD_EEPROM) == 0) - break; - udelay (1000); - } - - /* Get MAC addresses */ - macid0_val = INW (dev, MACID0); - macid1_val = INW (dev, MACID1); - macid2_val = INW (dev, MACID2); - - if (((macid0_val | macid1_val | macid2_val) != 0) && - ((macid0_val & 0x01) == 0)) { - dev->enetaddr[0] = (unsigned char)macid0_val; - dev->enetaddr[1] = (unsigned char)(macid0_val >> 8); - dev->enetaddr[2] = (unsigned char)macid1_val; - dev->enetaddr[3] = (unsigned char)(macid1_val >> 8); - dev->enetaddr[4] = (unsigned char)macid2_val; - dev->enetaddr[5] = (unsigned char)(macid2_val >> 8); - } -} - -/* -=========================================================================== -<<<<<< Exported SubProgram Bodies >>>>>> -=========================================================================== -*/ -int ax88180_initialize (bd_t * bis) -{ - struct eth_device *dev; - struct ax88180_private *priv; - - dev = (struct eth_device *)malloc (sizeof *dev); - - if (NULL == dev) - return 0; - - memset (dev, 0, sizeof *dev); - - priv = (struct ax88180_private *)malloc (sizeof (*priv)); - - if (NULL == priv) - return 0; - - memset (priv, 0, sizeof *priv); - - sprintf (dev->name, "ax88180"); - dev->iobase = AX88180_BASE; - dev->priv = priv; - dev->init = ax88180_init; - dev->halt = ax88180_halt; - dev->send = ax88180_send; - dev->recv = ax88180_recv; - - priv->BusWidth = BUS_WIDTH_32; - priv->PadSize = 3; -#if defined (CONFIG_DRIVER_AX88180_16BIT) - OUTW (dev, (START_BASE >> 8), BASE); - OUTW (dev, DECODE_EN, DECODE); - - priv->BusWidth = BUS_WIDTH_16; - priv->PadSize = 1; -#endif - - ax88180_mac_reset (dev); - - /* Disable interrupt */ - OUTW (dev, CLEAR_IMR, IMR); - - /* Disable AX88180 TX/RX functions */ - OUTW (dev, WAKEMOD, CMD); - - ax88180_read_mac_addr (dev); - - eth_register (dev); - - return ax88180_phy_initial (dev); - -} diff --git a/qemu/roms/u-boot/drivers/net/ax88180.h b/qemu/roms/u-boot/drivers/net/ax88180.h deleted file mode 100644 index daf18e015..000000000 --- a/qemu/roms/u-boot/drivers/net/ax88180.h +++ /dev/null @@ -1,396 +0,0 @@ -/* ax88180.h: ASIX AX88180 Non-PCI Gigabit Ethernet u-boot driver */ -/* - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope 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., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - */ - -#ifndef _AX88180_H_ -#define _AX88180_H_ - -#include <asm/io.h> -#include <asm/types.h> -#include <config.h> - -typedef enum _ax88180_link_state { - INS_LINK_DOWN, - INS_LINK_UP, - INS_LINK_UNKNOWN -} ax88180_link_state; - -struct ax88180_private { - unsigned char BusWidth; - unsigned char PadSize; - unsigned short PhyAddr; - unsigned short PhyID0; - unsigned short PhyID1; - unsigned short FirstTxDesc; - unsigned short NextTxDesc; - ax88180_link_state LinkState; -}; - -#define BUS_WIDTH_16 1 -#define BUS_WIDTH_32 2 - -#define ENABLE_JUMBO 1 -#define DISABLE_JUMBO 0 - -#define ENABLE_BURST 1 -#define DISABLE_BURST 0 - -#define NORMAL_RX_MODE 0 -#define RX_LOOPBACK_MODE 1 -#define RX_INIFINIT_LOOP_MODE 2 -#define TX_INIFINIT_LOOP_MODE 3 - -#define DEFAULT_ETH_MTU 1500 - -/* Jumbo packet size 4086 bytes included 4 bytes CRC*/ -#define MAX_JUMBO_MTU 4072 - -/* Max Tx Jumbo size 4086 bytes included 4 bytes CRC */ -#define MAX_TX_JUMBO_SIZE 4086 - -/* Max Rx Jumbo size is 15K Bytes */ -#define MAX_RX_SIZE 0x3C00 - -#define MARVELL_ALASKA_PHYSID0 0x141 -#define MARVELL_88E1118_PHYSID1 0xE40 - -#define CICADA_CIS8201_PHYSID0 0x000F - -#define MEDIA_AUTO 0 -#define MEDIA_1000FULL 1 -#define MEDIA_1000HALF 2 -#define MEDIA_100FULL 3 -#define MEDIA_100HALF 4 -#define MEDIA_10FULL 5 -#define MEDIA_10HALF 6 -#define MEDIA_UNKNOWN 7 - -#define AUTO_MEDIA 0 -#define FORCE_MEDIA 1 - -#define TXDP_MASK 3 -#define TXDP0 0 -#define TXDP1 1 -#define TXDP2 2 -#define TXDP3 3 - -#define CMD_MAP_SIZE 0x100 - -#if defined (CONFIG_DRIVER_AX88180_16BIT) - #define AX88180_MEMORY_SIZE 0x00004000 - #define START_BASE 0x1000 - - #define RX_BUF_SIZE 0x1000 - #define TX_BUF_SIZE 0x0F00 - - #define TX_BASE START_BASE - #define CMD_BASE (TX_BASE + TX_BUF_SIZE) - #define RX_BASE (CMD_BASE + CMD_MAP_SIZE) -#else - #define AX88180_MEMORY_SIZE 0x00010000 - - #define RX_BUF_SIZE 0x8000 - #define TX_BUF_SIZE 0x7C00 - - #define RX_BASE 0x0000 - #define TX_BASE (RX_BASE + RX_BUF_SIZE) - #define CMD_BASE (TX_BASE + TX_BUF_SIZE) -#endif - -/* AX88180 Memory Mapping Definition */ -#define RXBUFFER_START RX_BASE - #define RX_PACKET_LEN_OFFSET 0 - #define RX_PAGE_NUM_MASK 0x7FF /* RX pages 0~7FFh */ -#define TXBUFFER_START TX_BASE - -/* AX88180 MAC Register Definition */ -#define DECODE (0) - #define DECODE_EN 0x00000001 -#define BASE (6) -#define CMD (CMD_BASE + 0x0000) - #define WAKEMOD 0x00000001 - #define TXEN 0x00000100 - #define RXEN 0x00000200 - #define DEFAULT_CMD WAKEMOD -#define IMR (CMD_BASE + 0x0004) - #define IMR_RXBUFFOVR 0x00000001 - #define IMR_WATCHDOG 0x00000002 - #define IMR_TX 0x00000008 - #define IMR_RX 0x00000010 - #define IMR_PHY 0x00000020 - #define CLEAR_IMR 0x00000000 - #define DEFAULT_IMR (IMR_PHY | IMR_RX | IMR_TX |\ - IMR_RXBUFFOVR | IMR_WATCHDOG) -#define ISR (CMD_BASE + 0x0008) - #define ISR_RXBUFFOVR 0x00000001 - #define ISR_WATCHDOG 0x00000002 - #define ISR_TX 0x00000008 - #define ISR_RX 0x00000010 - #define ISR_PHY 0x00000020 -#define TXCFG (CMD_BASE + 0x0010) - #define AUTOPAD_CRC 0x00000050 - #define DEFAULT_TXCFG AUTOPAD_CRC -#define TXCMD (CMD_BASE + 0x0014) - #define TXCMD_TXDP_MASK 0x00006000 - #define TXCMD_TXDP0 0x00000000 - #define TXCMD_TXDP1 0x00002000 - #define TXCMD_TXDP2 0x00004000 - #define TXCMD_TXDP3 0x00006000 - #define TX_START_WRITE 0x00008000 - #define TX_STOP_WRITE 0x00000000 - #define DEFAULT_TXCMD 0x00000000 -#define TXBS (CMD_BASE + 0x0018) - #define TXDP0_USED 0x00000001 - #define TXDP1_USED 0x00000002 - #define TXDP2_USED 0x00000004 - #define TXDP3_USED 0x00000008 - #define DEFAULT_TXBS 0x00000000 -#define TXDES0 (CMD_BASE + 0x0020) - #define TXDPx_ENABLE 0x00008000 - #define TXDPx_LEN_MASK 0x00001FFF - #define DEFAULT_TXDES0 0x00000000 -#define TXDES1 (CMD_BASE + 0x0024) - #define TXDPx_ENABLE 0x00008000 - #define TXDPx_LEN_MASK 0x00001FFF - #define DEFAULT_TXDES1 0x00000000 -#define TXDES2 (CMD_BASE + 0x0028) - #define TXDPx_ENABLE 0x00008000 - #define TXDPx_LEN_MASK 0x00001FFF - #define DEFAULT_TXDES2 0x00000000 -#define TXDES3 (CMD_BASE + 0x002C) - #define TXDPx_ENABLE 0x00008000 - #define TXDPx_LEN_MASK 0x00001FFF - #define DEFAULT_TXDES3 0x00000000 -#define RXCFG (CMD_BASE + 0x0030) - #define RXBUFF_PROTECT 0x00000001 - #define RXTCPCRC_CHECK 0x00000010 - #define RXFLOW_ENABLE 0x00000100 - #define DEFAULT_RXCFG RXBUFF_PROTECT -#define RXCURT (CMD_BASE + 0x0034) - #define DEFAULT_RXCURT 0x00000000 -#define RXBOUND (CMD_BASE + 0x0038) - #define DEFAULT_RXBOUND 0x7FF /* RX pages 0~7FFh */ -#define MACCFG0 (CMD_BASE + 0x0040) - #define MACCFG0_BIT3_0 0x00000007 - #define IPGT_VAL 0x00000150 - #define TXFLOW_ENABLE 0x00001000 - #define SPEED100 0x00008000 - #define DEFAULT_MACCFG0 (IPGT_VAL | MACCFG0_BIT3_0) -#define MACCFG1 (CMD_BASE + 0x0044) - #define RGMII_EN 0x00000002 - #define RXFLOW_EN 0x00000020 - #define FULLDUPLEX 0x00000040 - #define MAX_JUMBO_LEN 0x00000780 - #define RXJUMBO_EN 0x00000800 - #define GIGA_MODE_EN 0x00001000 - #define RXCRC_CHECK 0x00002000 - #define RXPAUSE_DA_CHECK 0x00004000 - - #define JUMBO_LEN_4K 0x00000200 - #define JUMBO_LEN_15K 0x00000780 - #define DEFAULT_MACCFG1 (RXCRC_CHECK | RXPAUSE_DA_CHECK | \ - RGMII_EN) - #define CICADA_DEFAULT_MACCFG1 (RXCRC_CHECK | RXPAUSE_DA_CHECK) -#define MACCFG2 (CMD_BASE + 0x0048) - #define MACCFG2_BIT15_8 0x00000100 - #define JAM_LIMIT_MASK 0x000000FC - #define DEFAULT_JAM_LIMIT 0x00000064 - #define DEFAULT_MACCFG2 MACCFG2_BIT15_8 -#define MACCFG3 (CMD_BASE + 0x004C) - #define IPGR2_VAL 0x0000000E - #define IPGR1_VAL 0x00000600 - #define NOABORT 0x00008000 - #define DEFAULT_MACCFG3 (IPGR1_VAL | IPGR2_VAL) -#define TXPAUT (CMD_BASE + 0x0054) - #define DEFAULT_TXPAUT 0x001FE000 -#define RXBTHD0 (CMD_BASE + 0x0058) - #define DEFAULT_RXBTHD0 0x00000300 -#define RXBTHD1 (CMD_BASE + 0x005C) - #define DEFAULT_RXBTHD1 0x00000600 -#define RXFULTHD (CMD_BASE + 0x0060) - #define DEFAULT_RXFULTHD 0x00000100 -#define MISC (CMD_BASE + 0x0068) - /* Normal operation mode */ - #define MISC_NORMAL 0x00000003 - /* Clear bit 0 to reset MAC */ - #define MISC_RESET_MAC 0x00000002 - /* Clear bit 1 to reset PHY */ - #define MISC_RESET_PHY 0x00000001 - /* Clear bit 0 and 1 to reset MAC and PHY */ - #define MISC_RESET_MAC_PHY 0x00000000 - #define DEFAULT_MISC MISC_NORMAL -#define MACID0 (CMD_BASE + 0x0070) -#define MACID1 (CMD_BASE + 0x0074) -#define MACID2 (CMD_BASE + 0x0078) -#define TXLEN (CMD_BASE + 0x007C) - #define DEFAULT_TXLEN 0x000005FC -#define RXFILTER (CMD_BASE + 0x0080) - #define RX_RXANY 0x00000001 - #define RX_MULTICAST 0x00000002 - #define RX_UNICAST 0x00000004 - #define RX_BROADCAST 0x00000008 - #define RX_MULTI_HASH 0x00000010 - #define DISABLE_RXFILTER 0x00000000 - #define DEFAULT_RXFILTER (RX_BROADCAST + RX_UNICAST) -#define MDIOCTRL (CMD_BASE + 0x0084) - #define PHY_ADDR_MASK 0x0000001F - #define REG_ADDR_MASK 0x00001F00 - #define READ_PHY 0x00004000 - #define WRITE_PHY 0x00008000 -#define MDIODP (CMD_BASE + 0x0088) -#define GPIOCTRL (CMD_BASE + 0x008C) -#define RXINDICATOR (CMD_BASE + 0x0090) - #define RX_START_READ 0x00000001 - #define RX_STOP_READ 0x00000000 - #define DEFAULT_RXINDICATOR RX_STOP_READ -#define TXST (CMD_BASE + 0x0094) -#define MDCCLKPAT (CMD_BASE + 0x00A0) -#define RXIPCRCCNT (CMD_BASE + 0x00A4) -#define RXCRCCNT (CMD_BASE + 0x00A8) -#define TXFAILCNT (CMD_BASE + 0x00AC) -#define PROMDP (CMD_BASE + 0x00B0) -#define PROMCTRL (CMD_BASE + 0x00B4) - #define RELOAD_EEPROM 0x00000200 -#define MAXRXLEN (CMD_BASE + 0x00B8) -#define HASHTAB0 (CMD_BASE + 0x00C0) -#define HASHTAB1 (CMD_BASE + 0x00C4) -#define HASHTAB2 (CMD_BASE + 0x00C8) -#define HASHTAB3 (CMD_BASE + 0x00CC) -#define DOGTHD0 (CMD_BASE + 0x00E0) - #define DEFAULT_DOGTHD0 0x0000FFFF -#define DOGTHD1 (CMD_BASE + 0x00E4) - #define START_WATCHDOG_TIMER 0x00008000 - #define DEFAULT_DOGTHD1 0x00000FFF -#define SOFTRST (CMD_BASE + 0x00EC) - #define SOFTRST_NORMAL 0x00000003 - #define SOFTRST_RESET_MAC 0x00000002 - -/* Marvell 88E1111 Gigabit PHY Register Definition */ -#define M88_SSR 0x0011 - #define SSR_SPEED_MASK 0xC000 - #define SSR_SPEED_1000 0x8000 - #define SSR_SPEED_100 0x4000 - #define SSR_SPEED_10 0x0000 - #define SSR_DUPLEX 0x2000 - #define SSR_MEDIA_RESOLVED_OK 0x0800 - - #define SSR_MEDIA_MASK (SSR_SPEED_MASK | SSR_DUPLEX) - #define SSR_1000FULL (SSR_SPEED_1000 | SSR_DUPLEX) - #define SSR_1000HALF SSR_SPEED_1000 - #define SSR_100FULL (SSR_SPEED_100 | SSR_DUPLEX) - #define SSR_100HALF SSR_SPEED_100 - #define SSR_10FULL (SSR_SPEED_10 | SSR_DUPLEX) - #define SSR_10HALF SSR_SPEED_10 -#define M88_IER 0x0012 - #define LINK_CHANGE_INT 0x0400 -#define M88_ISR 0x0013 - #define LINK_CHANGE_STATUS 0x0400 -#define M88E1111_EXT_SCR 0x0014 - #define RGMII_RXCLK_DELAY 0x0080 - #define RGMII_TXCLK_DELAY 0x0002 - #define DEFAULT_EXT_SCR (RGMII_TXCLK_DELAY | RGMII_RXCLK_DELAY) -#define M88E1111_EXT_SSR 0x001B - #define HWCFG_MODE_MASK 0x000F - #define RGMII_COPPER_MODE 0x000B - -/* Marvell 88E1118 Gigabit PHY Register Definition */ -#define M88E1118_CR 0x14 - #define M88E1118_CR_RGMII_RXCLK_DELAY 0x0020 - #define M88E1118_CR_RGMII_TXCLK_DELAY 0x0010 - #define M88E1118_CR_DEFAULT (M88E1118_CR_RGMII_TXCLK_DELAY | \ - M88E1118_CR_RGMII_RXCLK_DELAY) -#define M88E1118_LEDCTL 0x10 /* Reg 16 on page 3 */ - #define M88E1118_LEDCTL_LED2INT 0x200 - #define M88E1118_LEDCTL_LED2BLNK 0x400 - #define M88E1118_LEDCTL_LED0DUALMODE1 0xc - #define M88E1118_LEDCTL_LED0DUALMODE2 0xd - #define M88E1118_LEDCTL_LED0DUALMODE3 0xe - #define M88E1118_LEDCTL_LED0DUALMODE4 0xf - #define M88E1118_LEDCTL_DEFAULT (M88E1118_LEDCTL_LED2BLNK | \ - M88E1118_LEDCTL_LED0DUALMODE4) - -#define M88E1118_LEDMIX 0x11 /* Reg 17 on page 3 */ - #define M88E1118_LEDMIX_LED050 0x4 - #define M88E1118_LEDMIX_LED150 0x8 - -#define M88E1118_PAGE_SEL 0x16 /* Reg page select */ - -/* CICADA CIS8201 Gigabit PHY Register Definition */ -#define CIS_IMR 0x0019 - #define CIS_INT_ENABLE 0x8000 - #define CIS_LINK_CHANGE_INT 0x2000 -#define CIS_ISR 0x001A - #define CIS_INT_PENDING 0x8000 - #define CIS_LINK_CHANGE_STATUS 0x2000 -#define CIS_AUX_CTRL_STATUS 0x001C - #define CIS_AUTONEG_COMPLETE 0x8000 - #define CIS_SPEED_MASK 0x0018 - #define CIS_SPEED_1000 0x0010 - #define CIS_SPEED_100 0x0008 - #define CIS_SPEED_10 0x0000 - #define CIS_DUPLEX 0x0020 - - #define CIS_MEDIA_MASK (CIS_SPEED_MASK | CIS_DUPLEX) - #define CIS_1000FULL (CIS_SPEED_1000 | CIS_DUPLEX) - #define CIS_1000HALF CIS_SPEED_1000 - #define CIS_100FULL (CIS_SPEED_100 | CIS_DUPLEX) - #define CIS_100HALF CIS_SPEED_100 - #define CIS_10FULL (CIS_SPEED_10 | CIS_DUPLEX) - #define CIS_10HALF CIS_SPEED_10 - #define CIS_SMI_PRIORITY 0x0004 - -static inline unsigned short INW (struct eth_device *dev, unsigned long addr) -{ - return le16_to_cpu(readw(addr + (void *)dev->iobase)); -} - -/* - Access RXBUFFER_START/TXBUFFER_START to read RX buffer/write TX buffer -*/ -#if defined (CONFIG_DRIVER_AX88180_16BIT) -static inline void OUTW (struct eth_device *dev, unsigned short command, unsigned long addr) -{ - writew(cpu_to_le16(command), addr + (void *)dev->iobase); -} - -static inline unsigned short READ_RXBUF (struct eth_device *dev) -{ - return le16_to_cpu(readw(RXBUFFER_START + (void *)dev->iobase)); -} - -static inline void WRITE_TXBUF (struct eth_device *dev, unsigned short data) -{ - writew(cpu_to_le16(data), TXBUFFER_START + (void *)dev->iobase); -} -#else -static inline void OUTW (struct eth_device *dev, unsigned short command, unsigned long addr) -{ - writel(cpu_to_le32(command), addr + (void *)dev->iobase); -} - -static inline unsigned long READ_RXBUF (struct eth_device *dev) -{ - return le32_to_cpu(readl(RXBUFFER_START + (void *)dev->iobase)); -} - -static inline void WRITE_TXBUF (struct eth_device *dev, unsigned long data) -{ - writel(cpu_to_le32(data), TXBUFFER_START + (void *)dev->iobase); -} -#endif - -#endif /* _AX88180_H_ */ diff --git a/qemu/roms/u-boot/drivers/net/ax88796.c b/qemu/roms/u-boot/drivers/net/ax88796.c deleted file mode 100644 index c45f64618..000000000 --- a/qemu/roms/u-boot/drivers/net/ax88796.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * (c) 2007 Nobuhiro Iwamatsu <iwamatsu@nigauri.org> - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> -#include "ax88796.h" - -/* - * Set 1 bit data - */ -static void ax88796_bitset(u32 bit) -{ - /* DATA1 */ - if( bit ) - EEDI_HIGH; - else - EEDI_LOW; - - EECLK_LOW; - udelay(1000); - EECLK_HIGH; - udelay(1000); - EEDI_LOW; -} - -/* - * Get 1 bit data - */ -static u8 ax88796_bitget(void) -{ - u8 bit; - - EECLK_LOW; - udelay(1000); - /* DATA */ - bit = EEDO; - EECLK_HIGH; - udelay(1000); - - return bit; -} - -/* - * Send COMMAND to EEPROM - */ -static void ax88796_eep_cmd(u8 cmd) -{ - ax88796_bitset(BIT_DUMMY); - switch(cmd){ - case MAC_EEP_READ: - ax88796_bitset(1); - ax88796_bitset(1); - ax88796_bitset(0); - break; - - case MAC_EEP_WRITE: - ax88796_bitset(1); - ax88796_bitset(0); - ax88796_bitset(1); - break; - - case MAC_EEP_ERACE: - ax88796_bitset(1); - ax88796_bitset(1); - ax88796_bitset(1); - break; - - case MAC_EEP_EWEN: - ax88796_bitset(1); - ax88796_bitset(0); - ax88796_bitset(0); - break; - - case MAC_EEP_EWDS: - ax88796_bitset(1); - ax88796_bitset(0); - ax88796_bitset(0); - break; - default: - break; - } -} - -static void ax88796_eep_setaddr(u16 addr) -{ - int i ; - - for( i = 7 ; i >= 0 ; i-- ) - ax88796_bitset(addr & (1 << i)); -} - -/* - * Get data from EEPROM - */ -static u16 ax88796_eep_getdata(void) -{ - ushort data = 0; - int i; - - ax88796_bitget(); /* DUMMY */ - for( i = 0 ; i < 16 ; i++ ){ - data <<= 1; - data |= ax88796_bitget(); - } - return data; -} - -static void ax88796_mac_read(u8 *buff) -{ - int i ; - u16 data; - u16 addr = 0; - - for( i = 0 ; i < 3; i++ ) - { - EECS_HIGH; - EEDI_LOW; - udelay(1000); - /* READ COMMAND */ - ax88796_eep_cmd(MAC_EEP_READ); - /* ADDRESS */ - ax88796_eep_setaddr(addr++); - /* GET DATA */ - data = ax88796_eep_getdata(); - *buff++ = (uchar)(data & 0xff); - *buff++ = (uchar)((data >> 8) & 0xff); - EECLK_LOW; - EEDI_LOW; - EECS_LOW; - } -} - -int get_prom(u8* mac_addr, u8* base_addr) -{ - u8 prom[32]; - int i; - - ax88796_mac_read(prom); - for (i = 0; i < 6; i++){ - mac_addr[i] = prom[i]; - } - return 1; -} diff --git a/qemu/roms/u-boot/drivers/net/ax88796.h b/qemu/roms/u-boot/drivers/net/ax88796.h deleted file mode 100644 index 2b4e05af3..000000000 --- a/qemu/roms/u-boot/drivers/net/ax88796.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * AX88796L(NE2000) support - * - * (c) 2007 Nobuhiro Iwamatsu <iwamatsu@nigauri.org> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __DRIVERS_AX88796L_H__ -#define __DRIVERS_AX88796L_H__ - -#define DP_DATA (0x10 << 1) -#define START_PG 0x40 /* First page of TX buffer */ -#define START_PG2 0x48 -#define STOP_PG 0x80 /* Last page +1 of RX ring */ -#define TX_PAGES 12 -#define RX_START (START_PG+TX_PAGES) -#define RX_END STOP_PG - -#define AX88796L_BASE_ADDRESS CONFIG_DRIVER_NE2000_BASE -#define AX88796L_BYTE_ACCESS 0x00001000 -#define AX88796L_OFFSET 0x00000400 -#define AX88796L_ADDRESS_BYTE AX88796L_BASE_ADDRESS + \ - AX88796L_BYTE_ACCESS + AX88796L_OFFSET -#define AX88796L_REG_MEMR AX88796L_ADDRESS_BYTE + (0x14<<1) -#define AX88796L_REG_CR AX88796L_ADDRESS_BYTE + (0x00<<1) - -#define AX88796L_CR (*(vu_short *)(AX88796L_REG_CR)) -#define AX88796L_MEMR (*(vu_short *)(AX88796L_REG_MEMR)) - -#define EECS_HIGH (AX88796L_MEMR |= 0x10) -#define EECS_LOW (AX88796L_MEMR &= 0xef) -#define EECLK_HIGH (AX88796L_MEMR |= 0x80) -#define EECLK_LOW (AX88796L_MEMR &= 0x7f) -#define EEDI_HIGH (AX88796L_MEMR |= 0x20) -#define EEDI_LOW (AX88796L_MEMR &= 0xdf) -#define EEDO ((AX88796L_MEMR & 0x40)>>6) - -#define PAGE0_SET (AX88796L_CR &= 0x3f) -#define PAGE1_SET (AX88796L_CR = (AX88796L_CR & 0x3f) | 0x40) - -#define BIT_DUMMY 0 -#define MAC_EEP_READ 1 -#define MAC_EEP_WRITE 2 -#define MAC_EEP_ERACE 3 -#define MAC_EEP_EWEN 4 -#define MAC_EEP_EWDS 5 - -/* R7780MP Specific code */ -#if defined(CONFIG_R7780MP) -#define ISA_OFFSET 0x1400 -#define DP_IN(_b_, _o_, _d_) (_d_) = \ - *( (vu_short *) ((_b_) + ((_o_) * 2) + ISA_OFFSET)) -#define DP_OUT(_b_, _o_, _d_) \ - *((vu_short *)((_b_) + ((_o_) * 2) + ISA_OFFSET)) = (_d_) -#define DP_IN_DATA(_b_, _d_) (_d_) = *( (vu_short *) ((_b_) + ISA_OFFSET)) -#define DP_OUT_DATA(_b_, _d_) *( (vu_short *) ((_b_)+ISA_OFFSET)) = (_d_) -#else -/* Please change for your target boards */ -#define ISA_OFFSET 0x0000 -#define DP_IN(_b_, _o_, _d_) (_d_) = *( (vu_short *)((_b_)+(_o_ )+ISA_OFFSET)) -#define DP_OUT(_b_, _o_, _d_) *((vu_short *)((_b_)+(_o_)+ISA_OFFSET)) = (_d_) -#define DP_IN_DATA(_b_, _d_) (_d_) = *( (vu_short *) ((_b_)+ISA_OFFSET)) -#define DP_OUT_DATA(_b_, _d_) *( (vu_short *) ((_b_)+ISA_OFFSET)) = (_d_) -#endif - -#endif /* __DRIVERS_AX88796L_H__ */ diff --git a/qemu/roms/u-boot/drivers/net/bfin_mac.c b/qemu/roms/u-boot/drivers/net/bfin_mac.c deleted file mode 100644 index 0c2d2ef1a..000000000 --- a/qemu/roms/u-boot/drivers/net/bfin_mac.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Driver for Blackfin On-Chip MAC device - * - * Copyright (c) 2005-2008 Analog Device, Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include <common.h> -#include <config.h> -#include <net.h> -#include <netdev.h> -#include <command.h> -#include <malloc.h> -#include <miiphy.h> -#include <linux/mii.h> - -#include <asm/blackfin.h> -#include <asm/clock.h> -#include <asm/portmux.h> -#include <asm/mach-common/bits/dma.h> -#include <asm/mach-common/bits/emac.h> -#include <asm/mach-common/bits/pll.h> - -#include "bfin_mac.h" - -#ifndef CONFIG_PHY_ADDR -# define CONFIG_PHY_ADDR 1 -#endif -#ifndef CONFIG_PHY_CLOCK_FREQ -# define CONFIG_PHY_CLOCK_FREQ 2500000 -#endif - -#ifdef CONFIG_POST -#include <post.h> -#endif - -#define RXBUF_BASE_ADDR 0xFF900000 -#define TXBUF_BASE_ADDR 0xFF800000 -#define TX_BUF_CNT 1 - -#define TOUT_LOOP 1000000 - -static ADI_ETHER_BUFFER *txbuf[TX_BUF_CNT]; -static ADI_ETHER_BUFFER *rxbuf[PKTBUFSRX]; -static u16 txIdx; /* index of the current RX buffer */ -static u16 rxIdx; /* index of the current TX buffer */ - -/* DMAx_CONFIG values at DMA Restart */ -static const union { - u16 data; - ADI_DMA_CONFIG_REG reg; -} txdmacfg = { - .reg = { - .b_DMA_EN = 1, /* enabled */ - .b_WNR = 0, /* read from memory */ - .b_WDSIZE = 2, /* wordsize is 32 bits */ - .b_DMA2D = 0, - .b_RESTART = 0, - .b_DI_SEL = 0, - .b_DI_EN = 0, /* no interrupt */ - .b_NDSIZE = 5, /* 5 half words is desc size */ - .b_FLOW = 7 /* large desc flow */ - }, -}; - -static int bfin_miiphy_wait(void) -{ - /* poll the STABUSY bit */ - while (bfin_read_EMAC_STAADD() & STABUSY) - continue; - return 0; -} - -static int bfin_miiphy_read(const char *devname, uchar addr, uchar reg, ushort *val) -{ - if (bfin_miiphy_wait()) - return 1; - bfin_write_EMAC_STAADD(SET_PHYAD(addr) | SET_REGAD(reg) | STABUSY); - if (bfin_miiphy_wait()) - return 1; - *val = bfin_read_EMAC_STADAT(); - return 0; -} - -static int bfin_miiphy_write(const char *devname, uchar addr, uchar reg, ushort val) -{ - if (bfin_miiphy_wait()) - return 1; - bfin_write_EMAC_STADAT(val); - bfin_write_EMAC_STAADD(SET_PHYAD(addr) | SET_REGAD(reg) | STAOP | STABUSY); - return 0; -} - -int bfin_EMAC_initialize(bd_t *bis) -{ - struct eth_device *dev; - dev = malloc(sizeof(*dev)); - if (dev == NULL) - hang(); - - memset(dev, 0, sizeof(*dev)); - strcpy(dev->name, "bfin_mac"); - - dev->iobase = 0; - dev->priv = 0; - dev->init = bfin_EMAC_init; - dev->halt = bfin_EMAC_halt; - dev->send = bfin_EMAC_send; - dev->recv = bfin_EMAC_recv; - dev->write_hwaddr = bfin_EMAC_setup_addr; - - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - miiphy_register(dev->name, bfin_miiphy_read, bfin_miiphy_write); -#endif - - return 0; -} - -static int bfin_EMAC_send(struct eth_device *dev, void *packet, int length) -{ - int i; - int result = 0; - - if (length <= 0) { - printf("Ethernet: bad packet size: %d\n", length); - goto out; - } - - if (bfin_read_DMA2_IRQ_STATUS() & DMA_ERR) { - printf("Ethernet: tx DMA error\n"); - goto out; - } - - for (i = 0; (bfin_read_DMA2_IRQ_STATUS() & DMA_RUN); ++i) { - if (i > TOUT_LOOP) { - puts("Ethernet: tx time out\n"); - goto out; - } - } - txbuf[txIdx]->FrmData->NoBytes = length; - memcpy(txbuf[txIdx]->FrmData->Dest, (void *)packet, length); - txbuf[txIdx]->Dma[0].START_ADDR = (u32) txbuf[txIdx]->FrmData; - bfin_write_DMA2_NEXT_DESC_PTR(txbuf[txIdx]->Dma); - bfin_write_DMA2_CONFIG(txdmacfg.data); - bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE); - - for (i = 0; (txbuf[txIdx]->StatusWord & TX_COMP) == 0; i++) { - if (i > TOUT_LOOP) { - puts("Ethernet: tx error\n"); - goto out; - } - } - result = txbuf[txIdx]->StatusWord; - txbuf[txIdx]->StatusWord = 0; - if ((txIdx + 1) >= TX_BUF_CNT) - txIdx = 0; - else - txIdx++; - out: - debug("BFIN EMAC send: length = %d\n", length); - return result; -} - -static int bfin_EMAC_recv(struct eth_device *dev) -{ - int length = 0; - - for (;;) { - if ((rxbuf[rxIdx]->StatusWord & RX_COMP) == 0) { - length = -1; - break; - } - if ((rxbuf[rxIdx]->StatusWord & RX_DMAO) != 0) { - printf("Ethernet: rx dma overrun\n"); - break; - } - if ((rxbuf[rxIdx]->StatusWord & RX_OK) == 0) { - printf("Ethernet: rx error\n"); - break; - } - length = rxbuf[rxIdx]->StatusWord & 0x000007FF; - if (length <= 4) { - printf("Ethernet: bad frame\n"); - break; - } - - debug("%s: len = %d\n", __func__, length - 4); - - NetRxPackets[rxIdx] = rxbuf[rxIdx]->FrmData->Dest; - NetReceive(NetRxPackets[rxIdx], length - 4); - bfin_write_DMA1_IRQ_STATUS(DMA_DONE | DMA_ERR); - rxbuf[rxIdx]->StatusWord = 0x00000000; - if ((rxIdx + 1) >= PKTBUFSRX) - rxIdx = 0; - else - rxIdx++; - } - - return length; -} - -/************************************************************** - * - * Ethernet Initialization Routine - * - *************************************************************/ - -/* MDC = SCLK / MDC_freq / 2 - 1 */ -#define MDC_FREQ_TO_DIV(mdc_freq) (get_sclk() / (mdc_freq) / 2 - 1) - -#ifndef CONFIG_BFIN_MAC_PINS -# ifdef CONFIG_RMII -# define CONFIG_BFIN_MAC_PINS P_RMII0 -# else -# define CONFIG_BFIN_MAC_PINS P_MII0 -# endif -#endif - -static int bfin_miiphy_init(struct eth_device *dev, int *opmode) -{ - const unsigned short pins[] = CONFIG_BFIN_MAC_PINS; - u16 phydat; - size_t count; - - /* Enable PHY output */ - bfin_write_VR_CTL(bfin_read_VR_CTL() | CLKBUFOE); - - /* Set all the pins to peripheral mode */ - peripheral_request_list(pins, "bfin_mac"); - - /* Odd word alignment for Receive Frame DMA word */ - /* Configure checksum support and rcve frame word alignment */ - bfin_write_EMAC_SYSCTL(RXDWA | RXCKS | SET_MDCDIV(MDC_FREQ_TO_DIV(CONFIG_PHY_CLOCK_FREQ))); - - /* turn on auto-negotiation and wait for link to come up */ - bfin_miiphy_write(dev->name, CONFIG_PHY_ADDR, MII_BMCR, BMCR_ANENABLE); - count = 0; - while (1) { - ++count; - if (bfin_miiphy_read(dev->name, CONFIG_PHY_ADDR, MII_BMSR, &phydat)) - return -1; - if (phydat & BMSR_LSTATUS) - break; - if (count > 30000) { - printf("%s: link down, check cable\n", dev->name); - return -1; - } - udelay(100); - } - - /* see what kind of link we have */ - if (bfin_miiphy_read(dev->name, CONFIG_PHY_ADDR, MII_LPA, &phydat)) - return -1; - if (phydat & LPA_DUPLEX) - *opmode = FDMODE; - else - *opmode = 0; - - bfin_write_EMAC_MMC_CTL(RSTC | CROLL); - bfin_write_EMAC_VLAN1(EMAC_VLANX_DEF_VAL); - bfin_write_EMAC_VLAN2(EMAC_VLANX_DEF_VAL); - - /* Initialize the TX DMA channel registers */ - bfin_write_DMA2_X_COUNT(0); - bfin_write_DMA2_X_MODIFY(4); - bfin_write_DMA2_Y_COUNT(0); - bfin_write_DMA2_Y_MODIFY(0); - - /* Initialize the RX DMA channel registers */ - bfin_write_DMA1_X_COUNT(0); - bfin_write_DMA1_X_MODIFY(4); - bfin_write_DMA1_Y_COUNT(0); - bfin_write_DMA1_Y_MODIFY(0); - - return 0; -} - -static int bfin_EMAC_setup_addr(struct eth_device *dev) -{ - bfin_write_EMAC_ADDRLO( - dev->enetaddr[0] | - dev->enetaddr[1] << 8 | - dev->enetaddr[2] << 16 | - dev->enetaddr[3] << 24 - ); - bfin_write_EMAC_ADDRHI( - dev->enetaddr[4] | - dev->enetaddr[5] << 8 - ); - return 0; -} - -static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd) -{ - u32 opmode; - int dat; - int i; - debug("Eth_init: ......\n"); - - txIdx = 0; - rxIdx = 0; - - /* Initialize System Register */ - if (bfin_miiphy_init(dev, &dat) < 0) - return -1; - - /* Initialize EMAC address */ - bfin_EMAC_setup_addr(dev); - - /* Initialize TX and RX buffer */ - for (i = 0; i < PKTBUFSRX; i++) { - rxbuf[i] = SetupRxBuffer(i); - if (i > 0) { - rxbuf[i - 1]->Dma[1].NEXT_DESC_PTR = rxbuf[i]->Dma; - if (i == (PKTBUFSRX - 1)) - rxbuf[i]->Dma[1].NEXT_DESC_PTR = rxbuf[0]->Dma; - } - } - for (i = 0; i < TX_BUF_CNT; i++) { - txbuf[i] = SetupTxBuffer(i); - if (i > 0) { - txbuf[i - 1]->Dma[1].NEXT_DESC_PTR = txbuf[i]->Dma; - if (i == (TX_BUF_CNT - 1)) - txbuf[i]->Dma[1].NEXT_DESC_PTR = txbuf[0]->Dma; - } - } - - /* Set RX DMA */ - bfin_write_DMA1_NEXT_DESC_PTR(rxbuf[0]->Dma); - bfin_write_DMA1_CONFIG(rxbuf[0]->Dma[0].CONFIG_DATA); - - /* Wait MII done */ - bfin_miiphy_wait(); - - /* We enable only RX here */ - /* ASTP : Enable Automatic Pad Stripping - PR : Promiscuous Mode for test - PSF : Receive frames with total length less than 64 bytes. - FDMODE : Full Duplex Mode - LB : Internal Loopback for test - RE : Receiver Enable */ - if (dat == FDMODE) - opmode = ASTP | FDMODE | PSF; - else - opmode = ASTP | PSF; - opmode |= RE; -#ifdef CONFIG_RMII - opmode |= TE | RMII; -#endif - /* Turn on the EMAC */ - bfin_write_EMAC_OPMODE(opmode); - return 0; -} - -static void bfin_EMAC_halt(struct eth_device *dev) -{ - debug("Eth_halt: ......\n"); - /* Turn off the EMAC */ - bfin_write_EMAC_OPMODE(0); - /* Turn off the EMAC RX DMA */ - bfin_write_DMA1_CONFIG(0); - bfin_write_DMA2_CONFIG(0); -} - -ADI_ETHER_BUFFER *SetupRxBuffer(int no) -{ - ADI_ETHER_FRAME_BUFFER *frmbuf; - ADI_ETHER_BUFFER *buf; - int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2; /* ensure a multi. of 4 */ - int total_size = nobytes_buffer + RECV_BUFSIZE; - - buf = (void *) (RXBUF_BASE_ADDR + no * total_size); - frmbuf = (void *) (RXBUF_BASE_ADDR + no * total_size + nobytes_buffer); - - memset(buf, 0x00, nobytes_buffer); - buf->FrmData = frmbuf; - memset(frmbuf, 0xfe, RECV_BUFSIZE); - - /* set up first desc to point to receive frame buffer */ - buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]); - buf->Dma[0].START_ADDR = (u32) buf->FrmData; - buf->Dma[0].CONFIG.b_DMA_EN = 1; /* enabled */ - buf->Dma[0].CONFIG.b_WNR = 1; /* Write to memory */ - buf->Dma[0].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */ - buf->Dma[0].CONFIG.b_NDSIZE = 5; /* 5 half words is desc size. */ - buf->Dma[0].CONFIG.b_FLOW = 7; /* large desc flow */ - - /* set up second desc to point to status word */ - buf->Dma[1].NEXT_DESC_PTR = buf->Dma; - buf->Dma[1].START_ADDR = (u32) & buf->IPHdrChksum; - buf->Dma[1].CONFIG.b_DMA_EN = 1; /* enabled */ - buf->Dma[1].CONFIG.b_WNR = 1; /* Write to memory */ - buf->Dma[1].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */ - buf->Dma[1].CONFIG.b_DI_EN = 1; /* enable interrupt */ - buf->Dma[1].CONFIG.b_NDSIZE = 5; /* must be 0 when FLOW is 0 */ - buf->Dma[1].CONFIG.b_FLOW = 7; /* stop */ - - return buf; -} - -ADI_ETHER_BUFFER *SetupTxBuffer(int no) -{ - ADI_ETHER_FRAME_BUFFER *frmbuf; - ADI_ETHER_BUFFER *buf; - int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2; /* ensure a multi. of 4 */ - int total_size = nobytes_buffer + RECV_BUFSIZE; - - buf = (void *) (TXBUF_BASE_ADDR + no * total_size); - frmbuf = (void *) (TXBUF_BASE_ADDR + no * total_size + nobytes_buffer); - - memset(buf, 0x00, nobytes_buffer); - buf->FrmData = frmbuf; - memset(frmbuf, 0x00, RECV_BUFSIZE); - - /* set up first desc to point to receive frame buffer */ - buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]); - buf->Dma[0].START_ADDR = (u32) buf->FrmData; - buf->Dma[0].CONFIG.b_DMA_EN = 1; /* enabled */ - buf->Dma[0].CONFIG.b_WNR = 0; /* Read to memory */ - buf->Dma[0].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */ - buf->Dma[0].CONFIG.b_NDSIZE = 5; /* 5 half words is desc size. */ - buf->Dma[0].CONFIG.b_FLOW = 7; /* large desc flow */ - - /* set up second desc to point to status word */ - buf->Dma[1].NEXT_DESC_PTR = &(buf->Dma[0]); - buf->Dma[1].START_ADDR = (u32) & buf->StatusWord; - buf->Dma[1].CONFIG.b_DMA_EN = 1; /* enabled */ - buf->Dma[1].CONFIG.b_WNR = 1; /* Write to memory */ - buf->Dma[1].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */ - buf->Dma[1].CONFIG.b_DI_EN = 1; /* enable interrupt */ - buf->Dma[1].CONFIG.b_NDSIZE = 0; /* must be 0 when FLOW is 0 */ - buf->Dma[1].CONFIG.b_FLOW = 0; /* stop */ - - return buf; -} - -#if defined(CONFIG_POST) && defined(CONFIG_SYS_POST_ETHER) -int ether_post_test(int flags) -{ - uchar buf[64]; - int i, value = 0; - int length; - uint addr; - - printf("\n--------"); - bfin_EMAC_init(NULL, NULL); - /* construct the package */ - addr = bfin_read_EMAC_ADDRLO(); - buf[0] = buf[6] = addr; - buf[1] = buf[7] = addr >> 8; - buf[2] = buf[8] = addr >> 16; - buf[3] = buf[9] = addr >> 24; - addr = bfin_read_EMAC_ADDRHI(); - buf[4] = buf[10] = addr; - buf[5] = buf[11] = addr >> 8; - buf[12] = 0x08; /* Type: ARP */ - buf[13] = 0x06; - buf[14] = 0x00; /* Hardware type: Ethernet */ - buf[15] = 0x01; - buf[16] = 0x08; /* Protocal type: IP */ - buf[17] = 0x00; - buf[18] = 0x06; /* Hardware size */ - buf[19] = 0x04; /* Protocol size */ - buf[20] = 0x00; /* Opcode: request */ - buf[21] = 0x01; - - for (i = 0; i < 42; i++) - buf[i + 22] = i; - printf("--------Send 64 bytes......\n"); - bfin_EMAC_send(NULL, buf, 64); - for (i = 0; i < 100; i++) { - udelay(10000); - if ((rxbuf[rxIdx]->StatusWord & RX_COMP) != 0) { - value = 1; - break; - } - } - if (value == 0) { - printf("--------EMAC can't receive any data\n"); - eth_halt(); - return -1; - } - length = rxbuf[rxIdx]->StatusWord & 0x000007FF - 4; - for (i = 0; i < length; i++) { - if (rxbuf[rxIdx]->FrmData->Dest[i] != buf[i]) { - printf("--------EMAC receive error data!\n"); - eth_halt(); - return -1; - } - } - printf("--------receive %d bytes, matched\n", length); - bfin_EMAC_halt(NULL); - return 0; -} -#endif diff --git a/qemu/roms/u-boot/drivers/net/bfin_mac.h b/qemu/roms/u-boot/drivers/net/bfin_mac.h deleted file mode 100644 index 54ffb3830..000000000 --- a/qemu/roms/u-boot/drivers/net/bfin_mac.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * bfin_mac.h - some defines/structures for the Blackfin on-chip MAC. - * - * Copyright (c) 2005-2008 Analog Device, Inc. - * - * Licensed under the GPL-2 or later. - */ - -#ifndef __BFIN_MAC_H__ -#define __BFIN_MAC_H__ - -#define RECV_BUFSIZE (0x614) - -typedef struct ADI_DMA_CONFIG_REG { - u16 b_DMA_EN:1; /* 0 Enabled */ - u16 b_WNR:1; /* 1 Direction */ - u16 b_WDSIZE:2; /* 2:3 Transfer word size */ - u16 b_DMA2D:1; /* 4 DMA mode */ - u16 b_RESTART:1; /* 5 Retain FIFO */ - u16 b_DI_SEL:1; /* 6 Data interrupt timing select */ - u16 b_DI_EN:1; /* 7 Data interrupt enabled */ - u16 b_NDSIZE:4; /* 8:11 Flex descriptor size */ - u16 b_FLOW:3; /* 12:14Flow */ -} ADI_DMA_CONFIG_REG; - -typedef struct adi_ether_frame_buffer { - u16 NoBytes; /* the no. of following bytes */ - u8 Dest[6]; /* destination MAC address */ - u8 Srce[6]; /* source MAC address */ - u16 LTfield; /* length/type field */ - u8 Data[0]; /* payload bytes */ -} ADI_ETHER_FRAME_BUFFER; -/* 16 bytes/struct */ - -typedef struct dma_descriptor { - struct dma_descriptor *NEXT_DESC_PTR; - u32 START_ADDR; - union { - u16 CONFIG_DATA; - ADI_DMA_CONFIG_REG CONFIG; - }; -} DMA_DESCRIPTOR; -/* 10 bytes/struct in 12 bytes */ - -typedef struct adi_ether_buffer { - DMA_DESCRIPTOR Dma[2]; /* first for the frame, second for the status */ - ADI_ETHER_FRAME_BUFFER *FrmData;/* pointer to data */ - struct adi_ether_buffer *pNext; /* next buffer */ - struct adi_ether_buffer *pPrev; /* prev buffer */ - u16 IPHdrChksum; /* the IP header checksum */ - u16 IPPayloadChksum; /* the IP header and payload checksum */ - volatile u32 StatusWord; /* the frame status word */ -} ADI_ETHER_BUFFER; -/* 40 bytes/struct in 44 bytes */ - -static ADI_ETHER_BUFFER *SetupRxBuffer(int no); -static ADI_ETHER_BUFFER *SetupTxBuffer(int no); - -static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd); -static void bfin_EMAC_halt(struct eth_device *dev); -static int bfin_EMAC_send(struct eth_device *dev, void *packet, int length); -static int bfin_EMAC_recv(struct eth_device *dev); -static int bfin_EMAC_setup_addr(struct eth_device *dev); - -#endif diff --git a/qemu/roms/u-boot/drivers/net/calxedaxgmac.c b/qemu/roms/u-boot/drivers/net/calxedaxgmac.c deleted file mode 100644 index ff94865c5..000000000 --- a/qemu/roms/u-boot/drivers/net/calxedaxgmac.c +++ /dev/null @@ -1,544 +0,0 @@ -/* - * Copyright 2010-2011 Calxeda, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <linux/compiler.h> -#include <linux/err.h> -#include <asm/io.h> - -#define TX_NUM_DESC 1 -#define RX_NUM_DESC 32 - -#define MAC_TIMEOUT (5*CONFIG_SYS_HZ) - -#define ETH_BUF_SZ 2048 -#define TX_BUF_SZ (ETH_BUF_SZ * TX_NUM_DESC) -#define RX_BUF_SZ (ETH_BUF_SZ * RX_NUM_DESC) - -#define RXSTART 0x00000002 -#define TXSTART 0x00002000 - -#define RXENABLE 0x00000004 -#define TXENABLE 0x00000008 - -#define XGMAC_CONTROL_SPD 0x40000000 -#define XGMAC_CONTROL_SPD_MASK 0x60000000 -#define XGMAC_CONTROL_SARC 0x10000000 -#define XGMAC_CONTROL_SARK_MASK 0x18000000 -#define XGMAC_CONTROL_CAR 0x04000000 -#define XGMAC_CONTROL_CAR_MASK 0x06000000 -#define XGMAC_CONTROL_CAR_SHIFT 25 -#define XGMAC_CONTROL_DP 0x01000000 -#define XGMAC_CONTROL_WD 0x00800000 -#define XGMAC_CONTROL_JD 0x00400000 -#define XGMAC_CONTROL_JE 0x00100000 -#define XGMAC_CONTROL_LM 0x00001000 -#define XGMAC_CONTROL_IPC 0x00000400 -#define XGMAC_CONTROL_ACS 0x00000080 -#define XGMAC_CONTROL_DDIC 0x00000010 -#define XGMAC_CONTROL_TE 0x00000008 -#define XGMAC_CONTROL_RE 0x00000004 - -#define XGMAC_DMA_BUSMODE_RESET 0x00000001 -#define XGMAC_DMA_BUSMODE_DSL 0x00000004 -#define XGMAC_DMA_BUSMODE_DSL_MASK 0x0000007c -#define XGMAC_DMA_BUSMODE_DSL_SHIFT 2 -#define XGMAC_DMA_BUSMODE_ATDS 0x00000080 -#define XGMAC_DMA_BUSMODE_PBL_MASK 0x00003f00 -#define XGMAC_DMA_BUSMODE_PBL_SHIFT 8 -#define XGMAC_DMA_BUSMODE_FB 0x00010000 -#define XGMAC_DMA_BUSMODE_USP 0x00800000 -#define XGMAC_DMA_BUSMODE_8PBL 0x01000000 -#define XGMAC_DMA_BUSMODE_AAL 0x02000000 - -#define XGMAC_DMA_AXIMODE_ENLPI 0x80000000 -#define XGMAC_DMA_AXIMODE_MGK 0x40000000 -#define XGMAC_DMA_AXIMODE_WROSR 0x00100000 -#define XGMAC_DMA_AXIMODE_WROSR_MASK 0x00F00000 -#define XGMAC_DMA_AXIMODE_WROSR_SHIFT 20 -#define XGMAC_DMA_AXIMODE_RDOSR 0x00010000 -#define XGMAC_DMA_AXIMODE_RDOSR_MASK 0x000F0000 -#define XGMAC_DMA_AXIMODE_RDOSR_SHIFT 16 -#define XGMAC_DMA_AXIMODE_AAL 0x00001000 -#define XGMAC_DMA_AXIMODE_BLEN256 0x00000080 -#define XGMAC_DMA_AXIMODE_BLEN128 0x00000040 -#define XGMAC_DMA_AXIMODE_BLEN64 0x00000020 -#define XGMAC_DMA_AXIMODE_BLEN32 0x00000010 -#define XGMAC_DMA_AXIMODE_BLEN16 0x00000008 -#define XGMAC_DMA_AXIMODE_BLEN8 0x00000004 -#define XGMAC_DMA_AXIMODE_BLEN4 0x00000002 -#define XGMAC_DMA_AXIMODE_UNDEF 0x00000001 - -#define XGMAC_CORE_OMR_RTC_SHIFT 3 -#define XGMAC_CORE_OMR_RTC_MASK 0x00000018 -#define XGMAC_CORE_OMR_RTC 0x00000010 -#define XGMAC_CORE_OMR_RSF 0x00000020 -#define XGMAC_CORE_OMR_DT 0x00000040 -#define XGMAC_CORE_OMR_FEF 0x00000080 -#define XGMAC_CORE_OMR_EFC 0x00000100 -#define XGMAC_CORE_OMR_RFA_SHIFT 9 -#define XGMAC_CORE_OMR_RFA_MASK 0x00000E00 -#define XGMAC_CORE_OMR_RFD_SHIFT 12 -#define XGMAC_CORE_OMR_RFD_MASK 0x00007000 -#define XGMAC_CORE_OMR_TTC_SHIFT 16 -#define XGMAC_CORE_OMR_TTC_MASK 0x00030000 -#define XGMAC_CORE_OMR_TTC 0x00020000 -#define XGMAC_CORE_OMR_FTF 0x00100000 -#define XGMAC_CORE_OMR_TSF 0x00200000 - -#define FIFO_MINUS_1K 0x0 -#define FIFO_MINUS_2K 0x1 -#define FIFO_MINUS_3K 0x2 -#define FIFO_MINUS_4K 0x3 -#define FIFO_MINUS_6K 0x4 -#define FIFO_MINUS_8K 0x5 -#define FIFO_MINUS_12K 0x6 -#define FIFO_MINUS_16K 0x7 - -#define XGMAC_CORE_FLOW_PT_SHIFT 16 -#define XGMAC_CORE_FLOW_PT_MASK 0xFFFF0000 -#define XGMAC_CORE_FLOW_PT 0x00010000 -#define XGMAC_CORE_FLOW_DZQP 0x00000080 -#define XGMAC_CORE_FLOW_PLT_SHIFT 4 -#define XGMAC_CORE_FLOW_PLT_MASK 0x00000030 -#define XGMAC_CORE_FLOW_PLT 0x00000010 -#define XGMAC_CORE_FLOW_UP 0x00000008 -#define XGMAC_CORE_FLOW_RFE 0x00000004 -#define XGMAC_CORE_FLOW_TFE 0x00000002 -#define XGMAC_CORE_FLOW_FCB 0x00000001 - -/* XGMAC Descriptor Defines */ -#define MAX_DESC_BUF_SZ (0x2000 - 8) - -#define RXDESC_EXT_STATUS 0x00000001 -#define RXDESC_CRC_ERR 0x00000002 -#define RXDESC_RX_ERR 0x00000008 -#define RXDESC_RX_WDOG 0x00000010 -#define RXDESC_FRAME_TYPE 0x00000020 -#define RXDESC_GIANT_FRAME 0x00000080 -#define RXDESC_LAST_SEG 0x00000100 -#define RXDESC_FIRST_SEG 0x00000200 -#define RXDESC_VLAN_FRAME 0x00000400 -#define RXDESC_OVERFLOW_ERR 0x00000800 -#define RXDESC_LENGTH_ERR 0x00001000 -#define RXDESC_SA_FILTER_FAIL 0x00002000 -#define RXDESC_DESCRIPTOR_ERR 0x00004000 -#define RXDESC_ERROR_SUMMARY 0x00008000 -#define RXDESC_FRAME_LEN_OFFSET 16 -#define RXDESC_FRAME_LEN_MASK 0x3fff0000 -#define RXDESC_DA_FILTER_FAIL 0x40000000 - -#define RXDESC1_END_RING 0x00008000 - -#define RXDESC_IP_PAYLOAD_MASK 0x00000003 -#define RXDESC_IP_PAYLOAD_UDP 0x00000001 -#define RXDESC_IP_PAYLOAD_TCP 0x00000002 -#define RXDESC_IP_PAYLOAD_ICMP 0x00000003 -#define RXDESC_IP_HEADER_ERR 0x00000008 -#define RXDESC_IP_PAYLOAD_ERR 0x00000010 -#define RXDESC_IPV4_PACKET 0x00000040 -#define RXDESC_IPV6_PACKET 0x00000080 -#define TXDESC_UNDERFLOW_ERR 0x00000001 -#define TXDESC_JABBER_TIMEOUT 0x00000002 -#define TXDESC_LOCAL_FAULT 0x00000004 -#define TXDESC_REMOTE_FAULT 0x00000008 -#define TXDESC_VLAN_FRAME 0x00000010 -#define TXDESC_FRAME_FLUSHED 0x00000020 -#define TXDESC_IP_HEADER_ERR 0x00000040 -#define TXDESC_PAYLOAD_CSUM_ERR 0x00000080 -#define TXDESC_ERROR_SUMMARY 0x00008000 -#define TXDESC_SA_CTRL_INSERT 0x00040000 -#define TXDESC_SA_CTRL_REPLACE 0x00080000 -#define TXDESC_2ND_ADDR_CHAINED 0x00100000 -#define TXDESC_END_RING 0x00200000 -#define TXDESC_CSUM_IP 0x00400000 -#define TXDESC_CSUM_IP_PAYLD 0x00800000 -#define TXDESC_CSUM_ALL 0x00C00000 -#define TXDESC_CRC_EN_REPLACE 0x01000000 -#define TXDESC_CRC_EN_APPEND 0x02000000 -#define TXDESC_DISABLE_PAD 0x04000000 -#define TXDESC_FIRST_SEG 0x10000000 -#define TXDESC_LAST_SEG 0x20000000 -#define TXDESC_INTERRUPT 0x40000000 - -#define DESC_OWN 0x80000000 -#define DESC_BUFFER1_SZ_MASK 0x00001fff -#define DESC_BUFFER2_SZ_MASK 0x1fff0000 -#define DESC_BUFFER2_SZ_OFFSET 16 - -struct xgmac_regs { - u32 config; - u32 framefilter; - u32 resv_1[4]; - u32 flow_control; - u32 vlantag; - u32 version; - u32 vlaninclude; - u32 resv_2[2]; - u32 pacestretch; - u32 vlanhash; - u32 resv_3; - u32 intreg; - struct { - u32 hi; /* 0x40 */ - u32 lo; /* 0x44 */ - } macaddr[16]; - u32 resv_4[0xd0]; - u32 core_opmode; /* 0x400 */ - u32 resv_5[0x2bf]; - u32 busmode; /* 0xf00 */ - u32 txpoll; - u32 rxpoll; - u32 rxdesclist; - u32 txdesclist; - u32 dma_status; - u32 dma_opmode; - u32 intenable; - u32 resv_6[2]; - u32 axi_mode; /* 0xf28 */ -}; - -struct xgmac_dma_desc { - __le32 flags; - __le32 buf_size; - __le32 buf1_addr; /* Buffer 1 Address Pointer */ - __le32 buf2_addr; /* Buffer 2 Address Pointer */ - __le32 ext_status; - __le32 res[3]; -}; - -/* XGMAC Descriptor Access Helpers */ -static inline void desc_set_buf_len(struct xgmac_dma_desc *p, u32 buf_sz) -{ - if (buf_sz > MAX_DESC_BUF_SZ) - p->buf_size = cpu_to_le32(MAX_DESC_BUF_SZ | - (buf_sz - MAX_DESC_BUF_SZ) << DESC_BUFFER2_SZ_OFFSET); - else - p->buf_size = cpu_to_le32(buf_sz); -} - -static inline int desc_get_buf_len(struct xgmac_dma_desc *p) -{ - u32 len = le32_to_cpu(p->buf_size); - return (len & DESC_BUFFER1_SZ_MASK) + - ((len & DESC_BUFFER2_SZ_MASK) >> DESC_BUFFER2_SZ_OFFSET); -} - -static inline void desc_init_rx_desc(struct xgmac_dma_desc *p, int ring_size, - int buf_sz) -{ - struct xgmac_dma_desc *end = p + ring_size - 1; - - memset(p, 0, sizeof(*p) * ring_size); - - for (; p <= end; p++) - desc_set_buf_len(p, buf_sz); - - end->buf_size |= cpu_to_le32(RXDESC1_END_RING); -} - -static inline void desc_init_tx_desc(struct xgmac_dma_desc *p, u32 ring_size) -{ - memset(p, 0, sizeof(*p) * ring_size); - p[ring_size - 1].flags = cpu_to_le32(TXDESC_END_RING); -} - -static inline int desc_get_owner(struct xgmac_dma_desc *p) -{ - return le32_to_cpu(p->flags) & DESC_OWN; -} - -static inline void desc_set_rx_owner(struct xgmac_dma_desc *p) -{ - /* Clear all fields and set the owner */ - p->flags = cpu_to_le32(DESC_OWN); -} - -static inline void desc_set_tx_owner(struct xgmac_dma_desc *p, u32 flags) -{ - u32 tmpflags = le32_to_cpu(p->flags); - tmpflags &= TXDESC_END_RING; - tmpflags |= flags | DESC_OWN; - p->flags = cpu_to_le32(tmpflags); -} - -static inline void *desc_get_buf_addr(struct xgmac_dma_desc *p) -{ - return (void *)le32_to_cpu(p->buf1_addr); -} - -static inline void desc_set_buf_addr(struct xgmac_dma_desc *p, - void *paddr, int len) -{ - p->buf1_addr = cpu_to_le32(paddr); - if (len > MAX_DESC_BUF_SZ) - p->buf2_addr = cpu_to_le32(paddr + MAX_DESC_BUF_SZ); -} - -static inline void desc_set_buf_addr_and_size(struct xgmac_dma_desc *p, - void *paddr, int len) -{ - desc_set_buf_len(p, len); - desc_set_buf_addr(p, paddr, len); -} - -static inline int desc_get_rx_frame_len(struct xgmac_dma_desc *p) -{ - u32 data = le32_to_cpu(p->flags); - u32 len = (data & RXDESC_FRAME_LEN_MASK) >> RXDESC_FRAME_LEN_OFFSET; - if (data & RXDESC_FRAME_TYPE) - len -= 4; - - return len; -} - -struct calxeda_eth_dev { - struct xgmac_dma_desc rx_chain[RX_NUM_DESC]; - struct xgmac_dma_desc tx_chain[TX_NUM_DESC]; - char rxbuffer[RX_BUF_SZ]; - - u32 tx_currdesc; - u32 rx_currdesc; - - struct eth_device *dev; -} __aligned(32); - -/* - * Initialize a descriptor ring. Calxeda XGMAC is configured to use - * advanced descriptors. - */ - -static void init_rx_desc(struct calxeda_eth_dev *priv) -{ - struct xgmac_dma_desc *rxdesc = priv->rx_chain; - struct xgmac_regs *regs = (struct xgmac_regs *)priv->dev->iobase; - void *rxbuffer = priv->rxbuffer; - int i; - - desc_init_rx_desc(rxdesc, RX_NUM_DESC, ETH_BUF_SZ); - writel((ulong)rxdesc, ®s->rxdesclist); - - for (i = 0; i < RX_NUM_DESC; i++) { - desc_set_buf_addr(rxdesc + i, rxbuffer + (i * ETH_BUF_SZ), - ETH_BUF_SZ); - desc_set_rx_owner(rxdesc + i); - } -} - -static void init_tx_desc(struct calxeda_eth_dev *priv) -{ - struct xgmac_regs *regs = (struct xgmac_regs *)priv->dev->iobase; - - desc_init_tx_desc(priv->tx_chain, TX_NUM_DESC); - writel((ulong)priv->tx_chain, ®s->txdesclist); -} - -static int xgmac_reset(struct eth_device *dev) -{ - struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase; - int timeout = MAC_TIMEOUT; - u32 value; - - value = readl(®s->config) & XGMAC_CONTROL_SPD_MASK; - - writel(XGMAC_DMA_BUSMODE_RESET, ®s->busmode); - while ((timeout-- >= 0) && - (readl(®s->busmode) & XGMAC_DMA_BUSMODE_RESET)) - udelay(1); - - writel(value, ®s->config); - - return timeout; -} - -static void xgmac_hwmacaddr(struct eth_device *dev) -{ - struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase; - u32 macaddr[2]; - - memcpy(macaddr, dev->enetaddr, 6); - writel(macaddr[1], ®s->macaddr[0].hi); - writel(macaddr[0], ®s->macaddr[0].lo); -} - -static int xgmac_init(struct eth_device *dev, bd_t * bis) -{ - struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase; - struct calxeda_eth_dev *priv = dev->priv; - int value; - - if (xgmac_reset(dev) < 0) - return -1; - - /* set the hardware MAC address */ - xgmac_hwmacaddr(dev); - - /* set the AXI bus modes */ - value = XGMAC_DMA_BUSMODE_ATDS | - (16 << XGMAC_DMA_BUSMODE_PBL_SHIFT) | - XGMAC_DMA_BUSMODE_FB | XGMAC_DMA_BUSMODE_AAL; - writel(value, ®s->busmode); - - value = XGMAC_DMA_AXIMODE_AAL | XGMAC_DMA_AXIMODE_BLEN16 | - XGMAC_DMA_AXIMODE_BLEN8 | XGMAC_DMA_AXIMODE_BLEN4; - writel(value, ®s->axi_mode); - - /* set flow control parameters and store and forward mode */ - value = (FIFO_MINUS_12K << XGMAC_CORE_OMR_RFD_SHIFT) | - (FIFO_MINUS_4K << XGMAC_CORE_OMR_RFA_SHIFT) | - XGMAC_CORE_OMR_EFC | XGMAC_CORE_OMR_TSF; - writel(value, ®s->core_opmode); - - /* enable pause frames */ - value = (1024 << XGMAC_CORE_FLOW_PT_SHIFT) | - (1 << XGMAC_CORE_FLOW_PLT_SHIFT) | - XGMAC_CORE_FLOW_UP | XGMAC_CORE_FLOW_RFE | XGMAC_CORE_FLOW_TFE; - writel(value, ®s->flow_control); - - /* Initialize the descriptor chains */ - init_rx_desc(priv); - init_tx_desc(priv); - - /* must set to 0, or when started up will cause issues */ - priv->tx_currdesc = 0; - priv->rx_currdesc = 0; - - /* set default core values */ - value = readl(®s->config); - value &= XGMAC_CONTROL_SPD_MASK; - value |= XGMAC_CONTROL_DDIC | XGMAC_CONTROL_ACS | - XGMAC_CONTROL_IPC | XGMAC_CONTROL_CAR; - - /* Everything is ready enable both mac and DMA */ - value |= RXENABLE | TXENABLE; - writel(value, ®s->config); - - value = readl(®s->dma_opmode); - value |= RXSTART | TXSTART; - writel(value, ®s->dma_opmode); - - return 0; -} - -static int xgmac_tx(struct eth_device *dev, void *packet, int length) -{ - struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase; - struct calxeda_eth_dev *priv = dev->priv; - u32 currdesc = priv->tx_currdesc; - struct xgmac_dma_desc *txdesc = &priv->tx_chain[currdesc]; - int timeout; - - desc_set_buf_addr_and_size(txdesc, packet, length); - desc_set_tx_owner(txdesc, TXDESC_FIRST_SEG | - TXDESC_LAST_SEG | TXDESC_CRC_EN_APPEND); - - /* write poll demand */ - writel(1, ®s->txpoll); - - timeout = 1000000; - while (desc_get_owner(txdesc)) { - if (timeout-- < 0) { - printf("xgmac: TX timeout\n"); - return -ETIMEDOUT; - } - udelay(1); - } - - priv->tx_currdesc = (currdesc + 1) & (TX_NUM_DESC - 1); - return 0; -} - -static int xgmac_rx(struct eth_device *dev) -{ - struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase; - struct calxeda_eth_dev *priv = dev->priv; - u32 currdesc = priv->rx_currdesc; - struct xgmac_dma_desc *rxdesc = &priv->rx_chain[currdesc]; - int length = 0; - - /* check if the host has the desc */ - if (desc_get_owner(rxdesc)) - return -1; /* something bad happened */ - - length = desc_get_rx_frame_len(rxdesc); - - NetReceive(desc_get_buf_addr(rxdesc), length); - - /* set descriptor back to owned by XGMAC */ - desc_set_rx_owner(rxdesc); - writel(1, ®s->rxpoll); - - priv->rx_currdesc = (currdesc + 1) & (RX_NUM_DESC - 1); - - return length; -} - -static void xgmac_halt(struct eth_device *dev) -{ - struct xgmac_regs *regs = (struct xgmac_regs *)dev->iobase; - struct calxeda_eth_dev *priv = dev->priv; - int value; - - /* Disable TX/RX */ - value = readl(®s->config); - value &= ~(RXENABLE | TXENABLE); - writel(value, ®s->config); - - /* Disable DMA */ - value = readl(®s->dma_opmode); - value &= ~(RXSTART | TXSTART); - writel(value, ®s->dma_opmode); - - /* must set to 0, or when started up will cause issues */ - priv->tx_currdesc = 0; - priv->rx_currdesc = 0; -} - -int calxedaxgmac_initialize(u32 id, ulong base_addr) -{ - struct eth_device *dev; - struct calxeda_eth_dev *priv; - struct xgmac_regs *regs; - u32 macaddr[2]; - - regs = (struct xgmac_regs *)base_addr; - - /* check hardware version */ - if (readl(®s->version) != 0x1012) - return -1; - - dev = malloc(sizeof(*dev)); - if (!dev) - return 0; - memset(dev, 0, sizeof(*dev)); - - /* Structure must be aligned, because it contains the descriptors */ - priv = memalign(32, sizeof(*priv)); - if (!priv) { - free(dev); - return 0; - } - - dev->iobase = (int)base_addr; - dev->priv = priv; - priv->dev = dev; - sprintf(dev->name, "xgmac%d", id); - - /* The MAC address is already configured, so read it from registers. */ - macaddr[1] = readl(®s->macaddr[0].hi); - macaddr[0] = readl(®s->macaddr[0].lo); - memcpy(dev->enetaddr, macaddr, 6); - - dev->init = xgmac_init; - dev->send = xgmac_tx; - dev->recv = xgmac_rx; - dev->halt = xgmac_halt; - - eth_register(dev); - - return 1; -} diff --git a/qemu/roms/u-boot/drivers/net/cpsw.c b/qemu/roms/u-boot/drivers/net/cpsw.c deleted file mode 100644 index bd5fba21c..000000000 --- a/qemu/roms/u-boot/drivers/net/cpsw.c +++ /dev/null @@ -1,1020 +0,0 @@ -/* - * CPSW Ethernet Switch Driver - * - * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ - * - * 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 version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <common.h> -#include <command.h> -#include <net.h> -#include <miiphy.h> -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <cpsw.h> -#include <asm/errno.h> -#include <asm/io.h> -#include <phy.h> -#include <asm/arch/cpu.h> - -#define BITMASK(bits) (BIT(bits) - 1) -#define PHY_REG_MASK 0x1f -#define PHY_ID_MASK 0x1f -#define NUM_DESCS (PKTBUFSRX * 2) -#define PKT_MIN 60 -#define PKT_MAX (1500 + 14 + 4 + 4) -#define CLEAR_BIT 1 -#define GIGABITEN BIT(7) -#define FULLDUPLEXEN BIT(0) -#define MIIEN BIT(15) - -/* DMA Registers */ -#define CPDMA_TXCONTROL 0x004 -#define CPDMA_RXCONTROL 0x014 -#define CPDMA_SOFTRESET 0x01c -#define CPDMA_RXFREE 0x0e0 -#define CPDMA_TXHDP_VER1 0x100 -#define CPDMA_TXHDP_VER2 0x200 -#define CPDMA_RXHDP_VER1 0x120 -#define CPDMA_RXHDP_VER2 0x220 -#define CPDMA_TXCP_VER1 0x140 -#define CPDMA_TXCP_VER2 0x240 -#define CPDMA_RXCP_VER1 0x160 -#define CPDMA_RXCP_VER2 0x260 - -/* Descriptor mode bits */ -#define CPDMA_DESC_SOP BIT(31) -#define CPDMA_DESC_EOP BIT(30) -#define CPDMA_DESC_OWNER BIT(29) -#define CPDMA_DESC_EOQ BIT(28) - -/* - * This timeout definition is a worst-case ultra defensive measure against - * unexpected controller lock ups. Ideally, we should never ever hit this - * scenario in practice. - */ -#define MDIO_TIMEOUT 100 /* msecs */ -#define CPDMA_TIMEOUT 100 /* msecs */ - -struct cpsw_mdio_regs { - u32 version; - u32 control; -#define CONTROL_IDLE BIT(31) -#define CONTROL_ENABLE BIT(30) - - u32 alive; - u32 link; - u32 linkintraw; - u32 linkintmasked; - u32 __reserved_0[2]; - u32 userintraw; - u32 userintmasked; - u32 userintmaskset; - u32 userintmaskclr; - u32 __reserved_1[20]; - - struct { - u32 access; - u32 physel; -#define USERACCESS_GO BIT(31) -#define USERACCESS_WRITE BIT(30) -#define USERACCESS_ACK BIT(29) -#define USERACCESS_READ (0) -#define USERACCESS_DATA (0xffff) - } user[0]; -}; - -struct cpsw_regs { - u32 id_ver; - u32 control; - u32 soft_reset; - u32 stat_port_en; - u32 ptype; -}; - -struct cpsw_slave_regs { - u32 max_blks; - u32 blk_cnt; - u32 flow_thresh; - u32 port_vlan; - u32 tx_pri_map; -#ifdef CONFIG_AM33XX - u32 gap_thresh; -#elif defined(CONFIG_TI814X) - u32 ts_ctl; - u32 ts_seq_ltype; - u32 ts_vlan; -#endif - u32 sa_lo; - u32 sa_hi; -}; - -struct cpsw_host_regs { - u32 max_blks; - u32 blk_cnt; - u32 flow_thresh; - u32 port_vlan; - u32 tx_pri_map; - u32 cpdma_tx_pri_map; - u32 cpdma_rx_chan_map; -}; - -struct cpsw_sliver_regs { - u32 id_ver; - u32 mac_control; - u32 mac_status; - u32 soft_reset; - u32 rx_maxlen; - u32 __reserved_0; - u32 rx_pause; - u32 tx_pause; - u32 __reserved_1; - u32 rx_pri_map; -}; - -#define ALE_ENTRY_BITS 68 -#define ALE_ENTRY_WORDS DIV_ROUND_UP(ALE_ENTRY_BITS, 32) - -/* ALE Registers */ -#define ALE_CONTROL 0x08 -#define ALE_UNKNOWNVLAN 0x18 -#define ALE_TABLE_CONTROL 0x20 -#define ALE_TABLE 0x34 -#define ALE_PORTCTL 0x40 - -#define ALE_TABLE_WRITE BIT(31) - -#define ALE_TYPE_FREE 0 -#define ALE_TYPE_ADDR 1 -#define ALE_TYPE_VLAN 2 -#define ALE_TYPE_VLAN_ADDR 3 - -#define ALE_UCAST_PERSISTANT 0 -#define ALE_UCAST_UNTOUCHED 1 -#define ALE_UCAST_OUI 2 -#define ALE_UCAST_TOUCHED 3 - -#define ALE_MCAST_FWD 0 -#define ALE_MCAST_BLOCK_LEARN_FWD 1 -#define ALE_MCAST_FWD_LEARN 2 -#define ALE_MCAST_FWD_2 3 - -enum cpsw_ale_port_state { - ALE_PORT_STATE_DISABLE = 0x00, - ALE_PORT_STATE_BLOCK = 0x01, - ALE_PORT_STATE_LEARN = 0x02, - ALE_PORT_STATE_FORWARD = 0x03, -}; - -/* ALE unicast entry flags - passed into cpsw_ale_add_ucast() */ -#define ALE_SECURE 1 -#define ALE_BLOCKED 2 - -struct cpsw_slave { - struct cpsw_slave_regs *regs; - struct cpsw_sliver_regs *sliver; - int slave_num; - u32 mac_control; - struct cpsw_slave_data *data; -}; - -struct cpdma_desc { - /* hardware fields */ - u32 hw_next; - u32 hw_buffer; - u32 hw_len; - u32 hw_mode; - /* software fields */ - u32 sw_buffer; - u32 sw_len; -}; - -struct cpdma_chan { - struct cpdma_desc *head, *tail; - void *hdp, *cp, *rxfree; -}; - -#define desc_write(desc, fld, val) __raw_writel((u32)(val), &(desc)->fld) -#define desc_read(desc, fld) __raw_readl(&(desc)->fld) -#define desc_read_ptr(desc, fld) ((void *)__raw_readl(&(desc)->fld)) - -#define chan_write(chan, fld, val) __raw_writel((u32)(val), (chan)->fld) -#define chan_read(chan, fld) __raw_readl((chan)->fld) -#define chan_read_ptr(chan, fld) ((void *)__raw_readl((chan)->fld)) - -#define for_each_slave(slave, priv) \ - for (slave = (priv)->slaves; slave != (priv)->slaves + \ - (priv)->data.slaves; slave++) - -struct cpsw_priv { - struct eth_device *dev; - struct cpsw_platform_data data; - int host_port; - - struct cpsw_regs *regs; - void *dma_regs; - struct cpsw_host_regs *host_port_regs; - void *ale_regs; - - struct cpdma_desc *descs; - struct cpdma_desc *desc_free; - struct cpdma_chan rx_chan, tx_chan; - - struct cpsw_slave *slaves; - struct phy_device *phydev; - struct mii_dev *bus; - - u32 mdio_link; - u32 phy_mask; -}; - -static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) -{ - int idx; - - idx = start / 32; - start -= idx * 32; - idx = 2 - idx; /* flip */ - return (ale_entry[idx] >> start) & BITMASK(bits); -} - -static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits, - u32 value) -{ - int idx; - - value &= BITMASK(bits); - idx = start / 32; - start -= idx * 32; - idx = 2 - idx; /* flip */ - ale_entry[idx] &= ~(BITMASK(bits) << start); - ale_entry[idx] |= (value << start); -} - -#define DEFINE_ALE_FIELD(name, start, bits) \ -static inline int cpsw_ale_get_##name(u32 *ale_entry) \ -{ \ - return cpsw_ale_get_field(ale_entry, start, bits); \ -} \ -static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value) \ -{ \ - cpsw_ale_set_field(ale_entry, start, bits, value); \ -} - -DEFINE_ALE_FIELD(entry_type, 60, 2) -DEFINE_ALE_FIELD(mcast_state, 62, 2) -DEFINE_ALE_FIELD(port_mask, 66, 3) -DEFINE_ALE_FIELD(ucast_type, 62, 2) -DEFINE_ALE_FIELD(port_num, 66, 2) -DEFINE_ALE_FIELD(blocked, 65, 1) -DEFINE_ALE_FIELD(secure, 64, 1) -DEFINE_ALE_FIELD(mcast, 40, 1) - -/* The MAC address field in the ALE entry cannot be macroized as above */ -static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr) -{ - int i; - - for (i = 0; i < 6; i++) - addr[i] = cpsw_ale_get_field(ale_entry, 40 - 8*i, 8); -} - -static inline void cpsw_ale_set_addr(u32 *ale_entry, u8 *addr) -{ - int i; - - for (i = 0; i < 6; i++) - cpsw_ale_set_field(ale_entry, 40 - 8*i, 8, addr[i]); -} - -static int cpsw_ale_read(struct cpsw_priv *priv, int idx, u32 *ale_entry) -{ - int i; - - __raw_writel(idx, priv->ale_regs + ALE_TABLE_CONTROL); - - for (i = 0; i < ALE_ENTRY_WORDS; i++) - ale_entry[i] = __raw_readl(priv->ale_regs + ALE_TABLE + 4 * i); - - return idx; -} - -static int cpsw_ale_write(struct cpsw_priv *priv, int idx, u32 *ale_entry) -{ - int i; - - for (i = 0; i < ALE_ENTRY_WORDS; i++) - __raw_writel(ale_entry[i], priv->ale_regs + ALE_TABLE + 4 * i); - - __raw_writel(idx | ALE_TABLE_WRITE, priv->ale_regs + ALE_TABLE_CONTROL); - - return idx; -} - -static int cpsw_ale_match_addr(struct cpsw_priv *priv, u8* addr) -{ - u32 ale_entry[ALE_ENTRY_WORDS]; - int type, idx; - - for (idx = 0; idx < priv->data.ale_entries; idx++) { - u8 entry_addr[6]; - - cpsw_ale_read(priv, idx, ale_entry); - type = cpsw_ale_get_entry_type(ale_entry); - if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR) - continue; - cpsw_ale_get_addr(ale_entry, entry_addr); - if (memcmp(entry_addr, addr, 6) == 0) - return idx; - } - return -ENOENT; -} - -static int cpsw_ale_match_free(struct cpsw_priv *priv) -{ - u32 ale_entry[ALE_ENTRY_WORDS]; - int type, idx; - - for (idx = 0; idx < priv->data.ale_entries; idx++) { - cpsw_ale_read(priv, idx, ale_entry); - type = cpsw_ale_get_entry_type(ale_entry); - if (type == ALE_TYPE_FREE) - return idx; - } - return -ENOENT; -} - -static int cpsw_ale_find_ageable(struct cpsw_priv *priv) -{ - u32 ale_entry[ALE_ENTRY_WORDS]; - int type, idx; - - for (idx = 0; idx < priv->data.ale_entries; idx++) { - cpsw_ale_read(priv, idx, ale_entry); - type = cpsw_ale_get_entry_type(ale_entry); - if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR) - continue; - if (cpsw_ale_get_mcast(ale_entry)) - continue; - type = cpsw_ale_get_ucast_type(ale_entry); - if (type != ALE_UCAST_PERSISTANT && - type != ALE_UCAST_OUI) - return idx; - } - return -ENOENT; -} - -static int cpsw_ale_add_ucast(struct cpsw_priv *priv, u8 *addr, - int port, int flags) -{ - u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; - int idx; - - cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR); - cpsw_ale_set_addr(ale_entry, addr); - cpsw_ale_set_ucast_type(ale_entry, ALE_UCAST_PERSISTANT); - cpsw_ale_set_secure(ale_entry, (flags & ALE_SECURE) ? 1 : 0); - cpsw_ale_set_blocked(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0); - cpsw_ale_set_port_num(ale_entry, port); - - idx = cpsw_ale_match_addr(priv, addr); - if (idx < 0) - idx = cpsw_ale_match_free(priv); - if (idx < 0) - idx = cpsw_ale_find_ageable(priv); - if (idx < 0) - return -ENOMEM; - - cpsw_ale_write(priv, idx, ale_entry); - return 0; -} - -static int cpsw_ale_add_mcast(struct cpsw_priv *priv, u8 *addr, int port_mask) -{ - u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; - int idx, mask; - - idx = cpsw_ale_match_addr(priv, addr); - if (idx >= 0) - cpsw_ale_read(priv, idx, ale_entry); - - cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR); - cpsw_ale_set_addr(ale_entry, addr); - cpsw_ale_set_mcast_state(ale_entry, ALE_MCAST_FWD_2); - - mask = cpsw_ale_get_port_mask(ale_entry); - port_mask |= mask; - cpsw_ale_set_port_mask(ale_entry, port_mask); - - if (idx < 0) - idx = cpsw_ale_match_free(priv); - if (idx < 0) - idx = cpsw_ale_find_ageable(priv); - if (idx < 0) - return -ENOMEM; - - cpsw_ale_write(priv, idx, ale_entry); - return 0; -} - -static inline void cpsw_ale_control(struct cpsw_priv *priv, int bit, int val) -{ - u32 tmp, mask = BIT(bit); - - tmp = __raw_readl(priv->ale_regs + ALE_CONTROL); - tmp &= ~mask; - tmp |= val ? mask : 0; - __raw_writel(tmp, priv->ale_regs + ALE_CONTROL); -} - -#define cpsw_ale_enable(priv, val) cpsw_ale_control(priv, 31, val) -#define cpsw_ale_clear(priv, val) cpsw_ale_control(priv, 30, val) -#define cpsw_ale_vlan_aware(priv, val) cpsw_ale_control(priv, 2, val) - -static inline void cpsw_ale_port_state(struct cpsw_priv *priv, int port, - int val) -{ - int offset = ALE_PORTCTL + 4 * port; - u32 tmp, mask = 0x3; - - tmp = __raw_readl(priv->ale_regs + offset); - tmp &= ~mask; - tmp |= val & mask; - __raw_writel(tmp, priv->ale_regs + offset); -} - -static struct cpsw_mdio_regs *mdio_regs; - -/* wait until hardware is ready for another user access */ -static inline u32 wait_for_user_access(void) -{ - u32 reg = 0; - int timeout = MDIO_TIMEOUT; - - while (timeout-- && - ((reg = __raw_readl(&mdio_regs->user[0].access)) & USERACCESS_GO)) - udelay(10); - - if (timeout == -1) { - printf("wait_for_user_access Timeout\n"); - return -ETIMEDOUT; - } - return reg; -} - -/* wait until hardware state machine is idle */ -static inline void wait_for_idle(void) -{ - int timeout = MDIO_TIMEOUT; - - while (timeout-- && - ((__raw_readl(&mdio_regs->control) & CONTROL_IDLE) == 0)) - udelay(10); - - if (timeout == -1) - printf("wait_for_idle Timeout\n"); -} - -static int cpsw_mdio_read(struct mii_dev *bus, int phy_id, - int dev_addr, int phy_reg) -{ - int data; - u32 reg; - - if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK) - return -EINVAL; - - wait_for_user_access(); - reg = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) | - (phy_id << 16)); - __raw_writel(reg, &mdio_regs->user[0].access); - reg = wait_for_user_access(); - - data = (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -1; - return data; -} - -static int cpsw_mdio_write(struct mii_dev *bus, int phy_id, int dev_addr, - int phy_reg, u16 data) -{ - u32 reg; - - if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK) - return -EINVAL; - - wait_for_user_access(); - reg = (USERACCESS_GO | USERACCESS_WRITE | (phy_reg << 21) | - (phy_id << 16) | (data & USERACCESS_DATA)); - __raw_writel(reg, &mdio_regs->user[0].access); - wait_for_user_access(); - - return 0; -} - -static void cpsw_mdio_init(char *name, u32 mdio_base, u32 div) -{ - struct mii_dev *bus = mdio_alloc(); - - mdio_regs = (struct cpsw_mdio_regs *)mdio_base; - - /* set enable and clock divider */ - __raw_writel(div | CONTROL_ENABLE, &mdio_regs->control); - - /* - * wait for scan logic to settle: - * the scan time consists of (a) a large fixed component, and (b) a - * small component that varies with the mii bus frequency. These - * were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x - * silicon. Since the effect of (b) was found to be largely - * negligible, we keep things simple here. - */ - udelay(1000); - - bus->read = cpsw_mdio_read; - bus->write = cpsw_mdio_write; - sprintf(bus->name, name); - - mdio_register(bus); -} - -/* Set a self-clearing bit in a register, and wait for it to clear */ -static inline void setbit_and_wait_for_clear32(void *addr) -{ - __raw_writel(CLEAR_BIT, addr); - while (__raw_readl(addr) & CLEAR_BIT) - ; -} - -#define mac_hi(mac) (((mac)[0] << 0) | ((mac)[1] << 8) | \ - ((mac)[2] << 16) | ((mac)[3] << 24)) -#define mac_lo(mac) (((mac)[4] << 0) | ((mac)[5] << 8)) - -static void cpsw_set_slave_mac(struct cpsw_slave *slave, - struct cpsw_priv *priv) -{ - __raw_writel(mac_hi(priv->dev->enetaddr), &slave->regs->sa_hi); - __raw_writel(mac_lo(priv->dev->enetaddr), &slave->regs->sa_lo); -} - -static void cpsw_slave_update_link(struct cpsw_slave *slave, - struct cpsw_priv *priv, int *link) -{ - struct phy_device *phy; - u32 mac_control = 0; - - phy = priv->phydev; - - if (!phy) - return; - - phy_startup(phy); - *link = phy->link; - - if (*link) { /* link up */ - mac_control = priv->data.mac_control; - if (phy->speed == 1000) - mac_control |= GIGABITEN; - if (phy->duplex == DUPLEX_FULL) - mac_control |= FULLDUPLEXEN; - if (phy->speed == 100) - mac_control |= MIIEN; - } - - if (mac_control == slave->mac_control) - return; - - if (mac_control) { - printf("link up on port %d, speed %d, %s duplex\n", - slave->slave_num, phy->speed, - (phy->duplex == DUPLEX_FULL) ? "full" : "half"); - } else { - printf("link down on port %d\n", slave->slave_num); - } - - __raw_writel(mac_control, &slave->sliver->mac_control); - slave->mac_control = mac_control; -} - -static int cpsw_update_link(struct cpsw_priv *priv) -{ - int link = 0; - struct cpsw_slave *slave; - - for_each_slave(slave, priv) - cpsw_slave_update_link(slave, priv, &link); - priv->mdio_link = readl(&mdio_regs->link); - return link; -} - -static int cpsw_check_link(struct cpsw_priv *priv) -{ - u32 link = 0; - - link = __raw_readl(&mdio_regs->link) & priv->phy_mask; - if ((link) && (link == priv->mdio_link)) - return 1; - - return cpsw_update_link(priv); -} - -static inline u32 cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num) -{ - if (priv->host_port == 0) - return slave_num + 1; - else - return slave_num; -} - -static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv) -{ - u32 slave_port; - - setbit_and_wait_for_clear32(&slave->sliver->soft_reset); - - /* setup priority mapping */ - __raw_writel(0x76543210, &slave->sliver->rx_pri_map); - __raw_writel(0x33221100, &slave->regs->tx_pri_map); - - /* setup max packet size, and mac address */ - __raw_writel(PKT_MAX, &slave->sliver->rx_maxlen); - cpsw_set_slave_mac(slave, priv); - - slave->mac_control = 0; /* no link yet */ - - /* enable forwarding */ - slave_port = cpsw_get_slave_port(priv, slave->slave_num); - cpsw_ale_port_state(priv, slave_port, ALE_PORT_STATE_FORWARD); - - cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << slave_port); - - priv->phy_mask |= 1 << slave->data->phy_addr; -} - -static struct cpdma_desc *cpdma_desc_alloc(struct cpsw_priv *priv) -{ - struct cpdma_desc *desc = priv->desc_free; - - if (desc) - priv->desc_free = desc_read_ptr(desc, hw_next); - return desc; -} - -static void cpdma_desc_free(struct cpsw_priv *priv, struct cpdma_desc *desc) -{ - if (desc) { - desc_write(desc, hw_next, priv->desc_free); - priv->desc_free = desc; - } -} - -static int cpdma_submit(struct cpsw_priv *priv, struct cpdma_chan *chan, - void *buffer, int len) -{ - struct cpdma_desc *desc, *prev; - u32 mode; - - desc = cpdma_desc_alloc(priv); - if (!desc) - return -ENOMEM; - - if (len < PKT_MIN) - len = PKT_MIN; - - mode = CPDMA_DESC_OWNER | CPDMA_DESC_SOP | CPDMA_DESC_EOP; - - desc_write(desc, hw_next, 0); - desc_write(desc, hw_buffer, buffer); - desc_write(desc, hw_len, len); - desc_write(desc, hw_mode, mode | len); - desc_write(desc, sw_buffer, buffer); - desc_write(desc, sw_len, len); - - if (!chan->head) { - /* simple case - first packet enqueued */ - chan->head = desc; - chan->tail = desc; - chan_write(chan, hdp, desc); - goto done; - } - - /* not the first packet - enqueue at the tail */ - prev = chan->tail; - desc_write(prev, hw_next, desc); - chan->tail = desc; - - /* next check if EOQ has been triggered already */ - if (desc_read(prev, hw_mode) & CPDMA_DESC_EOQ) - chan_write(chan, hdp, desc); - -done: - if (chan->rxfree) - chan_write(chan, rxfree, 1); - return 0; -} - -static int cpdma_process(struct cpsw_priv *priv, struct cpdma_chan *chan, - void **buffer, int *len) -{ - struct cpdma_desc *desc = chan->head; - u32 status; - - if (!desc) - return -ENOENT; - - status = desc_read(desc, hw_mode); - - if (len) - *len = status & 0x7ff; - - if (buffer) - *buffer = desc_read_ptr(desc, sw_buffer); - - if (status & CPDMA_DESC_OWNER) { - if (chan_read(chan, hdp) == 0) { - if (desc_read(desc, hw_mode) & CPDMA_DESC_OWNER) - chan_write(chan, hdp, desc); - } - - return -EBUSY; - } - - chan->head = desc_read_ptr(desc, hw_next); - chan_write(chan, cp, desc); - - cpdma_desc_free(priv, desc); - return 0; -} - -static int cpsw_init(struct eth_device *dev, bd_t *bis) -{ - struct cpsw_priv *priv = dev->priv; - struct cpsw_slave *slave; - int i, ret; - - /* soft reset the controller and initialize priv */ - setbit_and_wait_for_clear32(&priv->regs->soft_reset); - - /* initialize and reset the address lookup engine */ - cpsw_ale_enable(priv, 1); - cpsw_ale_clear(priv, 1); - cpsw_ale_vlan_aware(priv, 0); /* vlan unaware mode */ - - /* setup host port priority mapping */ - __raw_writel(0x76543210, &priv->host_port_regs->cpdma_tx_pri_map); - __raw_writel(0, &priv->host_port_regs->cpdma_rx_chan_map); - - /* disable priority elevation and enable statistics on all ports */ - __raw_writel(0, &priv->regs->ptype); - - /* enable statistics collection only on the host port */ - __raw_writel(BIT(priv->host_port), &priv->regs->stat_port_en); - __raw_writel(0x7, &priv->regs->stat_port_en); - - cpsw_ale_port_state(priv, priv->host_port, ALE_PORT_STATE_FORWARD); - - cpsw_ale_add_ucast(priv, priv->dev->enetaddr, priv->host_port, - ALE_SECURE); - cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << priv->host_port); - - for_each_slave(slave, priv) - cpsw_slave_init(slave, priv); - - cpsw_update_link(priv); - - /* init descriptor pool */ - for (i = 0; i < NUM_DESCS; i++) { - desc_write(&priv->descs[i], hw_next, - (i == (NUM_DESCS - 1)) ? 0 : &priv->descs[i+1]); - } - priv->desc_free = &priv->descs[0]; - - /* initialize channels */ - if (priv->data.version == CPSW_CTRL_VERSION_2) { - memset(&priv->rx_chan, 0, sizeof(struct cpdma_chan)); - priv->rx_chan.hdp = priv->dma_regs + CPDMA_RXHDP_VER2; - priv->rx_chan.cp = priv->dma_regs + CPDMA_RXCP_VER2; - priv->rx_chan.rxfree = priv->dma_regs + CPDMA_RXFREE; - - memset(&priv->tx_chan, 0, sizeof(struct cpdma_chan)); - priv->tx_chan.hdp = priv->dma_regs + CPDMA_TXHDP_VER2; - priv->tx_chan.cp = priv->dma_regs + CPDMA_TXCP_VER2; - } else { - memset(&priv->rx_chan, 0, sizeof(struct cpdma_chan)); - priv->rx_chan.hdp = priv->dma_regs + CPDMA_RXHDP_VER1; - priv->rx_chan.cp = priv->dma_regs + CPDMA_RXCP_VER1; - priv->rx_chan.rxfree = priv->dma_regs + CPDMA_RXFREE; - - memset(&priv->tx_chan, 0, sizeof(struct cpdma_chan)); - priv->tx_chan.hdp = priv->dma_regs + CPDMA_TXHDP_VER1; - priv->tx_chan.cp = priv->dma_regs + CPDMA_TXCP_VER1; - } - - /* clear dma state */ - setbit_and_wait_for_clear32(priv->dma_regs + CPDMA_SOFTRESET); - - if (priv->data.version == CPSW_CTRL_VERSION_2) { - for (i = 0; i < priv->data.channels; i++) { - __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER2 + 4 - * i); - __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4 - * i); - __raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER2 + 4 - * i); - __raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER2 + 4 - * i); - __raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER2 + 4 - * i); - } - } else { - for (i = 0; i < priv->data.channels; i++) { - __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER1 + 4 - * i); - __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4 - * i); - __raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER1 + 4 - * i); - __raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER1 + 4 - * i); - __raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER1 + 4 - * i); - - } - } - - __raw_writel(1, priv->dma_regs + CPDMA_TXCONTROL); - __raw_writel(1, priv->dma_regs + CPDMA_RXCONTROL); - - /* submit rx descs */ - for (i = 0; i < PKTBUFSRX; i++) { - ret = cpdma_submit(priv, &priv->rx_chan, NetRxPackets[i], - PKTSIZE); - if (ret < 0) { - printf("error %d submitting rx desc\n", ret); - break; - } - } - - return 0; -} - -static void cpsw_halt(struct eth_device *dev) -{ - struct cpsw_priv *priv = dev->priv; - - writel(0, priv->dma_regs + CPDMA_TXCONTROL); - writel(0, priv->dma_regs + CPDMA_RXCONTROL); - - /* soft reset the controller and initialize priv */ - setbit_and_wait_for_clear32(&priv->regs->soft_reset); - - /* clear dma state */ - setbit_and_wait_for_clear32(priv->dma_regs + CPDMA_SOFTRESET); - - priv->data.control(0); -} - -static int cpsw_send(struct eth_device *dev, void *packet, int length) -{ - struct cpsw_priv *priv = dev->priv; - void *buffer; - int len; - int timeout = CPDMA_TIMEOUT; - - if (!cpsw_check_link(priv)) - return -EIO; - - flush_dcache_range((unsigned long)packet, - (unsigned long)packet + length); - - /* first reap completed packets */ - while (timeout-- && - (cpdma_process(priv, &priv->tx_chan, &buffer, &len) >= 0)) - ; - - if (timeout == -1) { - printf("cpdma_process timeout\n"); - return -ETIMEDOUT; - } - - return cpdma_submit(priv, &priv->tx_chan, packet, length); -} - -static int cpsw_recv(struct eth_device *dev) -{ - struct cpsw_priv *priv = dev->priv; - void *buffer; - int len; - - cpsw_check_link(priv); - - while (cpdma_process(priv, &priv->rx_chan, &buffer, &len) >= 0) { - invalidate_dcache_range((unsigned long)buffer, - (unsigned long)buffer + PKTSIZE_ALIGN); - NetReceive(buffer, len); - cpdma_submit(priv, &priv->rx_chan, buffer, PKTSIZE); - } - - return 0; -} - -static void cpsw_slave_setup(struct cpsw_slave *slave, int slave_num, - struct cpsw_priv *priv) -{ - void *regs = priv->regs; - struct cpsw_slave_data *data = priv->data.slave_data + slave_num; - slave->slave_num = slave_num; - slave->data = data; - slave->regs = regs + data->slave_reg_ofs; - slave->sliver = regs + data->sliver_reg_ofs; -} - -static int cpsw_phy_init(struct eth_device *dev, struct cpsw_slave *slave) -{ - struct cpsw_priv *priv = (struct cpsw_priv *)dev->priv; - struct phy_device *phydev; - u32 supported = PHY_GBIT_FEATURES; - - phydev = phy_connect(priv->bus, - slave->data->phy_addr, - dev, - slave->data->phy_if); - - if (!phydev) - return -1; - - phydev->supported &= supported; - phydev->advertising = phydev->supported; - - priv->phydev = phydev; - phy_config(phydev); - - return 1; -} - -int cpsw_register(struct cpsw_platform_data *data) -{ - struct cpsw_priv *priv; - struct cpsw_slave *slave; - void *regs = (void *)data->cpsw_base; - struct eth_device *dev; - - dev = calloc(sizeof(*dev), 1); - if (!dev) - return -ENOMEM; - - priv = calloc(sizeof(*priv), 1); - if (!priv) { - free(dev); - return -ENOMEM; - } - - priv->data = *data; - priv->dev = dev; - - priv->slaves = malloc(sizeof(struct cpsw_slave) * data->slaves); - if (!priv->slaves) { - free(dev); - free(priv); - return -ENOMEM; - } - - priv->host_port = data->host_port_num; - priv->regs = regs; - priv->host_port_regs = regs + data->host_port_reg_ofs; - priv->dma_regs = regs + data->cpdma_reg_ofs; - priv->ale_regs = regs + data->ale_reg_ofs; - priv->descs = (void *)regs + data->bd_ram_ofs; - - int idx = 0; - - for_each_slave(slave, priv) { - cpsw_slave_setup(slave, idx, priv); - idx = idx + 1; - } - - strcpy(dev->name, "cpsw"); - dev->iobase = 0; - dev->init = cpsw_init; - dev->halt = cpsw_halt; - dev->send = cpsw_send; - dev->recv = cpsw_recv; - dev->priv = priv; - - eth_register(dev); - - cpsw_mdio_init(dev->name, data->mdio_base, data->mdio_div); - priv->bus = miiphy_get_dev_by_name(dev->name); - for_each_slave(slave, priv) - cpsw_phy_init(dev, slave); - - return 1; -} diff --git a/qemu/roms/u-boot/drivers/net/cs8900.c b/qemu/roms/u-boot/drivers/net/cs8900.c deleted file mode 100644 index 84963c1f2..000000000 --- a/qemu/roms/u-boot/drivers/net/cs8900.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Cirrus Logic CS8900A Ethernet - * - * (C) 2009 Ben Warren , biggerbadderben@gmail.com - * Converted to use CONFIG_NET_MULTI API - * - * (C) 2003 Wolfgang Denk, wd@denx.de - * Extension to synchronize ethaddr environment variable - * against value in EEPROM - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Marius Groeger <mgroeger@sysgo.de> - * - * Copyright (C) 1999 Ben Williamson <benw@pobox.com> - * - * This program is loaded into SRAM in bootstrap mode, where it waits - * for commands on UART1 to read and write memory, jump to code etc. - * A design goal for this program is to be entirely independent of the - * target board. Anything with a CL-PS7111 or EP7211 should be able to run - * this code in bootstrap mode. All the board specifics can be handled on - * the host. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <command.h> -#include <asm/io.h> -#include <net.h> -#include <malloc.h> -#include "cs8900.h" - -#undef DEBUG - -/* packet page register access functions */ - -#ifdef CONFIG_CS8900_BUS32 - -#define REG_WRITE(v, a) writel((v),(a)) -#define REG_READ(a) readl((a)) - -/* we don't need 16 bit initialisation on 32 bit bus */ -#define get_reg_init_bus(r,d) get_reg((r),(d)) - -#else - -#define REG_WRITE(v, a) writew((v),(a)) -#define REG_READ(a) readw((a)) - -static u16 get_reg_init_bus(struct eth_device *dev, int regno) -{ - /* force 16 bit busmode */ - struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv); - uint8_t volatile * const iob = (uint8_t volatile * const)dev->iobase; - - readb(iob); - readb(iob + 1); - readb(iob); - readb(iob + 1); - readb(iob); - - REG_WRITE(regno, &priv->regs->pptr); - return REG_READ(&priv->regs->pdata); -} -#endif - -static u16 get_reg(struct eth_device *dev, int regno) -{ - struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv); - REG_WRITE(regno, &priv->regs->pptr); - return REG_READ(&priv->regs->pdata); -} - - -static void put_reg(struct eth_device *dev, int regno, u16 val) -{ - struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv); - REG_WRITE(regno, &priv->regs->pptr); - REG_WRITE(val, &priv->regs->pdata); -} - -static void cs8900_reset(struct eth_device *dev) -{ - int tmo; - u16 us; - - /* reset NIC */ - put_reg(dev, PP_SelfCTL, get_reg(dev, PP_SelfCTL) | PP_SelfCTL_Reset); - - /* wait for 200ms */ - udelay(200000); - /* Wait until the chip is reset */ - - tmo = get_timer(0) + 1 * CONFIG_SYS_HZ; - while ((((us = get_reg_init_bus(dev, PP_SelfSTAT)) & - PP_SelfSTAT_InitD) == 0) && tmo < get_timer(0)) - /*NOP*/; -} - -static void cs8900_reginit(struct eth_device *dev) -{ - /* receive only error free packets addressed to this card */ - put_reg(dev, PP_RxCTL, - PP_RxCTL_IA | PP_RxCTL_Broadcast | PP_RxCTL_RxOK); - /* do not generate any interrupts on receive operations */ - put_reg(dev, PP_RxCFG, 0); - /* do not generate any interrupts on transmit operations */ - put_reg(dev, PP_TxCFG, 0); - /* do not generate any interrupts on buffer operations */ - put_reg(dev, PP_BufCFG, 0); - /* enable transmitter/receiver mode */ - put_reg(dev, PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx); -} - -void cs8900_get_enetaddr(struct eth_device *dev) -{ - int i; - - /* verify chip id */ - if (get_reg_init_bus(dev, PP_ChipID) != 0x630e) - return; - cs8900_reset(dev); - if ((get_reg(dev, PP_SelfSTAT) & - (PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) == - (PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) { - - /* Load the MAC from EEPROM */ - for (i = 0; i < 3; i++) { - u32 Addr; - - Addr = get_reg(dev, PP_IA + i * 2); - dev->enetaddr[i * 2] = Addr & 0xFF; - dev->enetaddr[i * 2 + 1] = Addr >> 8; - } - } -} - -void cs8900_halt(struct eth_device *dev) -{ - /* disable transmitter/receiver mode */ - put_reg(dev, PP_LineCTL, 0); - - /* "shutdown" to show ChipID or kernel wouldn't find he cs8900 ... */ - get_reg_init_bus(dev, PP_ChipID); -} - -static int cs8900_init(struct eth_device *dev, bd_t * bd) -{ - uchar *enetaddr = dev->enetaddr; - u16 id; - - /* verify chip id */ - id = get_reg_init_bus(dev, PP_ChipID); - if (id != 0x630e) { - printf ("CS8900 Ethernet chip not found: " - "ID=0x%04x instead 0x%04x\n", id, 0x630e); - return 1; - } - - cs8900_reset (dev); - /* set the ethernet address */ - put_reg(dev, PP_IA + 0, enetaddr[0] | (enetaddr[1] << 8)); - put_reg(dev, PP_IA + 2, enetaddr[2] | (enetaddr[3] << 8)); - put_reg(dev, PP_IA + 4, enetaddr[4] | (enetaddr[5] << 8)); - - cs8900_reginit(dev); - return 0; -} - -/* Get a data block via Ethernet */ -static int cs8900_recv(struct eth_device *dev) -{ - int i; - u16 rxlen; - u16 *addr; - u16 status; - - struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv); - - status = get_reg(dev, PP_RER); - - if ((status & PP_RER_RxOK) == 0) - return 0; - - status = REG_READ(&priv->regs->rtdata); - rxlen = REG_READ(&priv->regs->rtdata); - - if (rxlen > PKTSIZE_ALIGN + PKTALIGN) - debug("packet too big!\n"); - for (addr = (u16 *) NetRxPackets[0], i = rxlen >> 1; i > 0; - i--) - *addr++ = REG_READ(&priv->regs->rtdata); - if (rxlen & 1) - *addr++ = REG_READ(&priv->regs->rtdata); - - /* Pass the packet up to the protocol layers. */ - NetReceive (NetRxPackets[0], rxlen); - return rxlen; -} - -/* Send a data block via Ethernet. */ -static int cs8900_send(struct eth_device *dev, void *packet, int length) -{ - volatile u16 *addr; - int tmo; - u16 s; - struct cs8900_priv *priv = (struct cs8900_priv *)(dev->priv); - -retry: - /* initiate a transmit sequence */ - REG_WRITE(PP_TxCmd_TxStart_Full, &priv->regs->txcmd); - REG_WRITE(length, &priv->regs->txlen); - - /* Test to see if the chip has allocated memory for the packet */ - if ((get_reg(dev, PP_BusSTAT) & PP_BusSTAT_TxRDY) == 0) { - /* Oops... this should not happen! */ - debug("cs: unable to send packet; retrying...\n"); - for (tmo = get_timer(0) + 5 * CONFIG_SYS_HZ; - get_timer(0) < tmo;) - /*NOP*/; - cs8900_reset(dev); - cs8900_reginit(dev); - goto retry; - } - - /* Write the contents of the packet */ - /* assume even number of bytes */ - for (addr = packet; length > 0; length -= 2) - REG_WRITE(*addr++, &priv->regs->rtdata); - - /* wait for transfer to succeed */ - tmo = get_timer(0) + 5 * CONFIG_SYS_HZ; - while ((s = get_reg(dev, PP_TER) & ~0x1F) == 0) { - if (get_timer(0) >= tmo) - break; - } - - /* nothing */ ; - if((s & (PP_TER_CRS | PP_TER_TxOK)) != PP_TER_TxOK) { - debug("\ntransmission error %#x\n", s); - } - - return 0; -} - -static void cs8900_e2prom_ready(struct eth_device *dev) -{ - while (get_reg(dev, PP_SelfSTAT) & SI_BUSY) - ; -} - -/***********************************************************/ -/* read a 16-bit word out of the EEPROM */ -/***********************************************************/ - -int cs8900_e2prom_read(struct eth_device *dev, - u8 addr, u16 *value) -{ - cs8900_e2prom_ready(dev); - put_reg(dev, PP_EECMD, EEPROM_READ_CMD | addr); - cs8900_e2prom_ready(dev); - *value = get_reg(dev, PP_EEData); - - return 0; -} - - -/***********************************************************/ -/* write a 16-bit word into the EEPROM */ -/***********************************************************/ - -int cs8900_e2prom_write(struct eth_device *dev, u8 addr, u16 value) -{ - cs8900_e2prom_ready(dev); - put_reg(dev, PP_EECMD, EEPROM_WRITE_EN); - cs8900_e2prom_ready(dev); - put_reg(dev, PP_EEData, value); - put_reg(dev, PP_EECMD, EEPROM_WRITE_CMD | addr); - cs8900_e2prom_ready(dev); - put_reg(dev, PP_EECMD, EEPROM_WRITE_DIS); - cs8900_e2prom_ready(dev); - - return 0; -} - -int cs8900_initialize(u8 dev_num, int base_addr) -{ - struct eth_device *dev; - struct cs8900_priv *priv; - - dev = malloc(sizeof(*dev)); - if (!dev) { - return 0; - } - memset(dev, 0, sizeof(*dev)); - - priv = malloc(sizeof(*priv)); - if (!priv) { - free(dev); - return 0; - } - memset(priv, 0, sizeof(*priv)); - priv->regs = (struct cs8900_regs *)base_addr; - - dev->iobase = base_addr; - dev->priv = priv; - dev->init = cs8900_init; - dev->halt = cs8900_halt; - dev->send = cs8900_send; - dev->recv = cs8900_recv; - - /* Load MAC address from EEPROM */ - cs8900_get_enetaddr(dev); - - sprintf(dev->name, "%s-%hu", CS8900_DRIVERNAME, dev_num); - - eth_register(dev); - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/cs8900.h b/qemu/roms/u-boot/drivers/net/cs8900.h deleted file mode 100644 index 79877dd57..000000000 --- a/qemu/roms/u-boot/drivers/net/cs8900.h +++ /dev/null @@ -1,249 +0,0 @@ -#ifndef CS8900_H -#define CS8900_H -/* - * Cirrus Logic CS8900A Ethernet - * - * (C) 2009 Ben Warren , biggerbadderben@gmail.com - * Converted to use CONFIG_NET_MULTI API - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Marius Groeger <mgroeger@sysgo.de> - * - * Copyright (C) 1999 Ben Williamson <benw@pobox.com> - * - * This program is loaded into SRAM in bootstrap mode, where it waits - * for commands on UART1 to read and write memory, jump to code etc. - * A design goal for this program is to be entirely independent of the - * target board. Anything with a CL-PS7111 or EP7211 should be able to run - * this code in bootstrap mode. All the board specifics can be handled on - * the host. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <asm/types.h> -#include <config.h> - -#define CS8900_DRIVERNAME "CS8900" -/* although the registers are 16 bit, they are 32-bit aligned on the - EDB7111. so we have to read them as 32-bit registers and ignore the - upper 16-bits. i'm not sure if this holds for the EDB7211. */ - -#ifdef CONFIG_CS8900_BUS16 - /* 16 bit aligned registers, 16 bit wide */ - #define CS8900_REG u16 -#elif defined(CONFIG_CS8900_BUS32) - /* 32 bit aligned registers, 16 bit wide (we ignore upper 16 bits) */ - #define CS8900_REG u32 -#else - #error unknown bussize ... -#endif - -struct cs8900_regs { - CS8900_REG rtdata; - CS8900_REG pad0; - CS8900_REG txcmd; - CS8900_REG txlen; - CS8900_REG isq; - CS8900_REG pptr; - CS8900_REG pdata; -}; - -struct cs8900_priv { - struct cs8900_regs *regs; -}; - -#define ISQ_RxEvent 0x04 -#define ISQ_TxEvent 0x08 -#define ISQ_BufEvent 0x0C -#define ISQ_RxMissEvent 0x10 -#define ISQ_TxColEvent 0x12 -#define ISQ_EventMask 0x3F - -/* packet page register offsets */ - -/* bus interface registers */ -#define PP_ChipID 0x0000 /* Chip identifier - must be 0x630E */ -#define PP_ChipRev 0x0002 /* Chip revision, model codes */ - -#define PP_IntReg 0x0022 /* Interrupt configuration */ -#define PP_IntReg_IRQ0 0x0000 /* Use INTR0 pin */ -#define PP_IntReg_IRQ1 0x0001 /* Use INTR1 pin */ -#define PP_IntReg_IRQ2 0x0002 /* Use INTR2 pin */ -#define PP_IntReg_IRQ3 0x0003 /* Use INTR3 pin */ - -/* status and control registers */ - -#define PP_RxCFG 0x0102 /* Receiver configuration */ -#define PP_RxCFG_Skip1 0x0040 /* Skip (i.e. discard) current frame */ -#define PP_RxCFG_Stream 0x0080 /* Enable streaming mode */ -#define PP_RxCFG_RxOK 0x0100 /* RxOK interrupt enable */ -#define PP_RxCFG_RxDMAonly 0x0200 /* Use RxDMA for all frames */ -#define PP_RxCFG_AutoRxDMA 0x0400 /* Select RxDMA automatically */ -#define PP_RxCFG_BufferCRC 0x0800 /* Include CRC characters in frame */ -#define PP_RxCFG_CRC 0x1000 /* Enable interrupt on CRC error */ -#define PP_RxCFG_RUNT 0x2000 /* Enable interrupt on RUNT frames */ -#define PP_RxCFG_EXTRA 0x4000 /* Enable interrupt on frames with extra data */ - -#define PP_RxCTL 0x0104 /* Receiver control */ -#define PP_RxCTL_IAHash 0x0040 /* Accept frames that match hash */ -#define PP_RxCTL_Promiscuous 0x0080 /* Accept any frame */ -#define PP_RxCTL_RxOK 0x0100 /* Accept well formed frames */ -#define PP_RxCTL_Multicast 0x0200 /* Accept multicast frames */ -#define PP_RxCTL_IA 0x0400 /* Accept frame that matches IA */ -#define PP_RxCTL_Broadcast 0x0800 /* Accept broadcast frames */ -#define PP_RxCTL_CRC 0x1000 /* Accept frames with bad CRC */ -#define PP_RxCTL_RUNT 0x2000 /* Accept runt frames */ -#define PP_RxCTL_EXTRA 0x4000 /* Accept frames that are too long */ - -#define PP_TxCFG 0x0106 /* Transmit configuration */ -#define PP_TxCFG_CRS 0x0040 /* Enable interrupt on loss of carrier */ -#define PP_TxCFG_SQE 0x0080 /* Enable interrupt on Signal Quality Error */ -#define PP_TxCFG_TxOK 0x0100 /* Enable interrupt on successful xmits */ -#define PP_TxCFG_Late 0x0200 /* Enable interrupt on "out of window" */ -#define PP_TxCFG_Jabber 0x0400 /* Enable interrupt on jabber detect */ -#define PP_TxCFG_Collision 0x0800 /* Enable interrupt if collision */ -#define PP_TxCFG_16Collisions 0x8000 /* Enable interrupt if > 16 collisions */ - -#define PP_TxCmd 0x0108 /* Transmit command status */ -#define PP_TxCmd_TxStart_5 0x0000 /* Start after 5 bytes in buffer */ -#define PP_TxCmd_TxStart_381 0x0040 /* Start after 381 bytes in buffer */ -#define PP_TxCmd_TxStart_1021 0x0080 /* Start after 1021 bytes in buffer */ -#define PP_TxCmd_TxStart_Full 0x00C0 /* Start after all bytes loaded */ -#define PP_TxCmd_Force 0x0100 /* Discard any pending packets */ -#define PP_TxCmd_OneCollision 0x0200 /* Abort after a single collision */ -#define PP_TxCmd_NoCRC 0x1000 /* Do not add CRC */ -#define PP_TxCmd_NoPad 0x2000 /* Do not pad short packets */ - -#define PP_BufCFG 0x010A /* Buffer configuration */ -#define PP_BufCFG_SWI 0x0040 /* Force interrupt via software */ -#define PP_BufCFG_RxDMA 0x0080 /* Enable interrupt on Rx DMA */ -#define PP_BufCFG_TxRDY 0x0100 /* Enable interrupt when ready for Tx */ -#define PP_BufCFG_TxUE 0x0200 /* Enable interrupt in Tx underrun */ -#define PP_BufCFG_RxMiss 0x0400 /* Enable interrupt on missed Rx packets */ -#define PP_BufCFG_Rx128 0x0800 /* Enable Rx interrupt after 128 bytes */ -#define PP_BufCFG_TxCol 0x1000 /* Enable int on Tx collision ctr overflow */ -#define PP_BufCFG_Miss 0x2000 /* Enable int on Rx miss ctr overflow */ -#define PP_BufCFG_RxDest 0x8000 /* Enable int on Rx dest addr match */ - -#define PP_LineCTL 0x0112 /* Line control */ -#define PP_LineCTL_Rx 0x0040 /* Enable receiver */ -#define PP_LineCTL_Tx 0x0080 /* Enable transmitter */ -#define PP_LineCTL_AUIonly 0x0100 /* AUI interface only */ -#define PP_LineCTL_AutoAUI10BT 0x0200 /* Autodetect AUI or 10BaseT interface */ -#define PP_LineCTL_ModBackoffE 0x0800 /* Enable modified backoff algorithm */ -#define PP_LineCTL_PolarityDis 0x1000 /* Disable Rx polarity autodetect */ -#define PP_LineCTL_2partDefDis 0x2000 /* Disable two-part defferal */ -#define PP_LineCTL_LoRxSquelch 0x4000 /* Reduce receiver squelch threshold */ - -#define PP_SelfCTL 0x0114 /* Chip self control */ -#define PP_SelfCTL_Reset 0x0040 /* Self-clearing reset */ -#define PP_SelfCTL_SWSuspend 0x0100 /* Initiate suspend mode */ -#define PP_SelfCTL_HWSleepE 0x0200 /* Enable SLEEP input */ -#define PP_SelfCTL_HWStandbyE 0x0400 /* Enable standby mode */ -#define PP_SelfCTL_HC0E 0x1000 /* use HCB0 for LINK LED */ -#define PP_SelfCTL_HC1E 0x2000 /* use HCB1 for BSTATUS LED */ -#define PP_SelfCTL_HCB0 0x4000 /* control LINK LED if HC0E set */ -#define PP_SelfCTL_HCB1 0x8000 /* control BSTATUS LED if HC1E set */ - -#define PP_BusCTL 0x0116 /* Bus control */ -#define PP_BusCTL_ResetRxDMA 0x0040 /* Reset RxDMA pointer */ -#define PP_BusCTL_DMAextend 0x0100 /* Extend DMA cycle */ -#define PP_BusCTL_UseSA 0x0200 /* Assert MEMCS16 on address decode */ -#define PP_BusCTL_MemoryE 0x0400 /* Enable memory mode */ -#define PP_BusCTL_DMAburst 0x0800 /* Limit DMA access burst */ -#define PP_BusCTL_IOCHRDYE 0x1000 /* Set IOCHRDY high impedence */ -#define PP_BusCTL_RxDMAsize 0x2000 /* Set DMA buffer size 64KB */ -#define PP_BusCTL_EnableIRQ 0x8000 /* Generate interrupt on interrupt event */ - -#define PP_TestCTL 0x0118 /* Test control */ -#define PP_TestCTL_DisableLT 0x0080 /* Disable link status */ -#define PP_TestCTL_ENDECloop 0x0200 /* Internal loopback */ -#define PP_TestCTL_AUIloop 0x0400 /* AUI loopback */ -#define PP_TestCTL_DisBackoff 0x0800 /* Disable backoff algorithm */ -#define PP_TestCTL_FDX 0x4000 /* Enable full duplex mode */ - -#define PP_ISQ 0x0120 /* Interrupt Status Queue */ - -#define PP_RER 0x0124 /* Receive event */ -#define PP_RER_IAHash 0x0040 /* Frame hash match */ -#define PP_RER_Dribble 0x0080 /* Frame had 1-7 extra bits after last byte */ -#define PP_RER_RxOK 0x0100 /* Frame received with no errors */ -#define PP_RER_Hashed 0x0200 /* Frame address hashed OK */ -#define PP_RER_IA 0x0400 /* Frame address matched IA */ -#define PP_RER_Broadcast 0x0800 /* Broadcast frame */ -#define PP_RER_CRC 0x1000 /* Frame had CRC error */ -#define PP_RER_RUNT 0x2000 /* Runt frame */ -#define PP_RER_EXTRA 0x4000 /* Frame was too long */ - -#define PP_TER 0x0128 /* Transmit event */ -#define PP_TER_CRS 0x0040 /* Carrier lost */ -#define PP_TER_SQE 0x0080 /* Signal Quality Error */ -#define PP_TER_TxOK 0x0100 /* Packet sent without error */ -#define PP_TER_Late 0x0200 /* Out of window */ -#define PP_TER_Jabber 0x0400 /* Stuck transmit? */ -#define PP_TER_NumCollisions 0x7800 /* Number of collisions */ -#define PP_TER_16Collisions 0x8000 /* > 16 collisions */ - -#define PP_BER 0x012C /* Buffer event */ -#define PP_BER_SWint 0x0040 /* Software interrupt */ -#define PP_BER_RxDMAFrame 0x0080 /* Received framed DMAed */ -#define PP_BER_Rdy4Tx 0x0100 /* Ready for transmission */ -#define PP_BER_TxUnderrun 0x0200 /* Transmit underrun */ -#define PP_BER_RxMiss 0x0400 /* Received frame missed */ -#define PP_BER_Rx128 0x0800 /* 128 bytes received */ -#define PP_BER_RxDest 0x8000 /* Received framed passed address filter */ - -#define PP_RxMiss 0x0130 /* Receiver miss counter */ - -#define PP_TxCol 0x0132 /* Transmit collision counter */ - -#define PP_LineSTAT 0x0134 /* Line status */ -#define PP_LineSTAT_LinkOK 0x0080 /* Line is connected and working */ -#define PP_LineSTAT_AUI 0x0100 /* Connected via AUI */ -#define PP_LineSTAT_10BT 0x0200 /* Connected via twisted pair */ -#define PP_LineSTAT_Polarity 0x1000 /* Line polarity OK (10BT only) */ -#define PP_LineSTAT_CRS 0x4000 /* Frame being received */ - -#define PP_SelfSTAT 0x0136 /* Chip self status */ -#define PP_SelfSTAT_33VActive 0x0040 /* supply voltage is 3.3V */ -#define PP_SelfSTAT_InitD 0x0080 /* Chip initialization complete */ -#define PP_SelfSTAT_SIBSY 0x0100 /* EEPROM is busy */ -#define PP_SelfSTAT_EEPROM 0x0200 /* EEPROM present */ -#define PP_SelfSTAT_EEPROM_OK 0x0400 /* EEPROM checks out */ -#define PP_SelfSTAT_ELPresent 0x0800 /* External address latch logic available */ -#define PP_SelfSTAT_EEsize 0x1000 /* Size of EEPROM */ - -#define PP_BusSTAT 0x0138 /* Bus status */ -#define PP_BusSTAT_TxBid 0x0080 /* Tx error */ -#define PP_BusSTAT_TxRDY 0x0100 /* Ready for Tx data */ - -#define PP_TDR 0x013C /* AUI Time Domain Reflectometer */ - -/* initiate transmit registers */ - -#define PP_TxCommand 0x0144 /* Tx Command */ -#define PP_TxLength 0x0146 /* Tx Length */ - - -/* address filter registers */ - -#define PP_LAF 0x0150 /* Logical address filter (6 bytes) */ -#define PP_IA 0x0158 /* Individual address (MAC) */ - -/* EEPROM Kram */ -#define SI_BUSY 0x0100 -#define PP_EECMD 0x0040 /* NVR Interface Command register */ -#define PP_EEData 0x0042 /* NVR Interface Data Register */ -#define EEPROM_WRITE_EN 0x00F0 -#define EEPROM_WRITE_DIS 0x0000 -#define EEPROM_WRITE_CMD 0x0100 -#define EEPROM_READ_CMD 0x0200 -#define EEPROM_ERASE_CMD 0x0300 - -/* Exported functions */ -int cs8900_e2prom_read(struct eth_device *dev, uchar, ushort *); -int cs8900_e2prom_write(struct eth_device *dev, uchar, ushort); - -#endif /* CS8900_H */ diff --git a/qemu/roms/u-boot/drivers/net/davinci_emac.c b/qemu/roms/u-boot/drivers/net/davinci_emac.c deleted file mode 100644 index 439f8ae99..000000000 --- a/qemu/roms/u-boot/drivers/net/davinci_emac.c +++ /dev/null @@ -1,894 +0,0 @@ -/* - * Ethernet driver for TI TMS320DM644x (DaVinci) chips. - * - * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> - * - * Parts shamelessly stolen from TI's dm644x_emac.c. Original copyright - * follows: - * - * ---------------------------------------------------------------------------- - * - * dm644x_emac.c - * - * TI DaVinci (DM644X) EMAC peripheral driver source for DV-EVM - * - * Copyright (C) 2005 Texas Instruments. - * - * ---------------------------------------------------------------------------- - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Modifications: - * ver. 1.0: Sep 2005, Anant Gole - Created EMAC version for uBoot. - * ver 1.1: Nov 2005, Anant Gole - Extended the RX logic for multiple descriptors - */ -#include <common.h> -#include <command.h> -#include <net.h> -#include <miiphy.h> -#include <malloc.h> -#include <linux/compiler.h> -#include <asm/arch/emac_defs.h> -#include <asm/io.h> -#include "davinci_emac.h" - -unsigned int emac_dbg = 0; -#define debug_emac(fmt,args...) if (emac_dbg) printf(fmt,##args) - -#ifdef EMAC_HW_RAM_ADDR -static inline unsigned long BD_TO_HW(unsigned long x) -{ - if (x == 0) - return 0; - - return x - EMAC_WRAPPER_RAM_ADDR + EMAC_HW_RAM_ADDR; -} - -static inline unsigned long HW_TO_BD(unsigned long x) -{ - if (x == 0) - return 0; - - return x - EMAC_HW_RAM_ADDR + EMAC_WRAPPER_RAM_ADDR; -} -#else -#define BD_TO_HW(x) (x) -#define HW_TO_BD(x) (x) -#endif - -#ifdef DAVINCI_EMAC_GIG_ENABLE -#define emac_gigabit_enable(phy_addr) davinci_eth_gigabit_enable(phy_addr) -#else -#define emac_gigabit_enable(phy_addr) /* no gigabit to enable */ -#endif - -#if !defined(CONFIG_SYS_EMAC_TI_CLKDIV) -#define CONFIG_SYS_EMAC_TI_CLKDIV ((EMAC_MDIO_BUS_FREQ / \ - EMAC_MDIO_CLOCK_FREQ) - 1) -#endif - -static void davinci_eth_mdio_enable(void); - -static int gen_init_phy(int phy_addr); -static int gen_is_phy_connected(int phy_addr); -static int gen_get_link_speed(int phy_addr); -static int gen_auto_negotiate(int phy_addr); - -void eth_mdio_enable(void) -{ - davinci_eth_mdio_enable(); -} - -/* EMAC Addresses */ -static volatile emac_regs *adap_emac = (emac_regs *)EMAC_BASE_ADDR; -static volatile ewrap_regs *adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR; -static volatile mdio_regs *adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR; - -/* EMAC descriptors */ -static volatile emac_desc *emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE); -static volatile emac_desc *emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE); -static volatile emac_desc *emac_rx_active_head = 0; -static volatile emac_desc *emac_rx_active_tail = 0; -static int emac_rx_queue_active = 0; - -/* Receive packet buffers */ -static unsigned char emac_rx_buffers[EMAC_MAX_RX_BUFFERS * EMAC_RXBUF_SIZE] - __aligned(ARCH_DMA_MINALIGN); - -#ifndef CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT -#define CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT 3 -#endif - -/* PHY address for a discovered PHY (0xff - not found) */ -static u_int8_t active_phy_addr[CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT]; - -/* number of PHY found active */ -static u_int8_t num_phy; - -phy_t phy[CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT]; - -static inline void davinci_flush_rx_descs(void) -{ - /* flush the whole RX descs area */ - flush_dcache_range(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE, - EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE); -} - -static inline void davinci_invalidate_rx_descs(void) -{ - /* invalidate the whole RX descs area */ - invalidate_dcache_range(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE, - EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE); -} - -static inline void davinci_flush_desc(emac_desc *desc) -{ - flush_dcache_range((unsigned long)desc, - (unsigned long)desc + sizeof(*desc)); -} - -static int davinci_eth_set_mac_addr(struct eth_device *dev) -{ - unsigned long mac_hi; - unsigned long mac_lo; - - /* - * Set MAC Addresses & Init multicast Hash to 0 (disable any multicast - * receive) - * Using channel 0 only - other channels are disabled - * */ - writel(0, &adap_emac->MACINDEX); - mac_hi = (dev->enetaddr[3] << 24) | - (dev->enetaddr[2] << 16) | - (dev->enetaddr[1] << 8) | - (dev->enetaddr[0]); - mac_lo = (dev->enetaddr[5] << 8) | - (dev->enetaddr[4]); - - writel(mac_hi, &adap_emac->MACADDRHI); -#if defined(DAVINCI_EMAC_VERSION2) - writel(mac_lo | EMAC_MAC_ADDR_IS_VALID | EMAC_MAC_ADDR_MATCH, - &adap_emac->MACADDRLO); -#else - writel(mac_lo, &adap_emac->MACADDRLO); -#endif - - writel(0, &adap_emac->MACHASH1); - writel(0, &adap_emac->MACHASH2); - - /* Set source MAC address - REQUIRED */ - writel(mac_hi, &adap_emac->MACSRCADDRHI); - writel(mac_lo, &adap_emac->MACSRCADDRLO); - - - return 0; -} - -static void davinci_eth_mdio_enable(void) -{ - u_int32_t clkdiv; - - clkdiv = CONFIG_SYS_EMAC_TI_CLKDIV; - - writel((clkdiv & 0xff) | - MDIO_CONTROL_ENABLE | - MDIO_CONTROL_FAULT | - MDIO_CONTROL_FAULT_ENABLE, - &adap_mdio->CONTROL); - - while (readl(&adap_mdio->CONTROL) & MDIO_CONTROL_IDLE) - ; -} - -/* - * Tries to find an active connected PHY. Returns 1 if address if found. - * If no active PHY (or more than one PHY) found returns 0. - * Sets active_phy_addr variable. - */ -static int davinci_eth_phy_detect(void) -{ - u_int32_t phy_act_state; - int i; - int j; - unsigned int count = 0; - - for (i = 0; i < CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT; i++) - active_phy_addr[i] = 0xff; - - udelay(1000); - phy_act_state = readl(&adap_mdio->ALIVE); - - if (phy_act_state == 0) - return 0; /* No active PHYs */ - - debug_emac("davinci_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state); - - for (i = 0, j = 0; i < 32; i++) - if (phy_act_state & (1 << i)) { - count++; - if (count <= CONFIG_SYS_DAVINCI_EMAC_PHY_COUNT) { - active_phy_addr[j++] = i; - } else { - printf("%s: to many PHYs detected.\n", - __func__); - count = 0; - break; - } - } - - num_phy = count; - - return count; -} - - -/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */ -int davinci_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data) -{ - int tmp; - - while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) - ; - - writel(MDIO_USERACCESS0_GO | - MDIO_USERACCESS0_WRITE_READ | - ((reg_num & 0x1f) << 21) | - ((phy_addr & 0x1f) << 16), - &adap_mdio->USERACCESS0); - - /* Wait for command to complete */ - while ((tmp = readl(&adap_mdio->USERACCESS0)) & MDIO_USERACCESS0_GO) - ; - - if (tmp & MDIO_USERACCESS0_ACK) { - *data = tmp & 0xffff; - return(1); - } - - *data = -1; - return(0); -} - -/* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */ -int davinci_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data) -{ - - while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) - ; - - writel(MDIO_USERACCESS0_GO | - MDIO_USERACCESS0_WRITE_WRITE | - ((reg_num & 0x1f) << 21) | - ((phy_addr & 0x1f) << 16) | - (data & 0xffff), - &adap_mdio->USERACCESS0); - - /* Wait for command to complete */ - while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) - ; - - return(1); -} - -/* PHY functions for a generic PHY */ -static int gen_init_phy(int phy_addr) -{ - int ret = 1; - - if (gen_get_link_speed(phy_addr)) { - /* Try another time */ - ret = gen_get_link_speed(phy_addr); - } - - return(ret); -} - -static int gen_is_phy_connected(int phy_addr) -{ - u_int16_t dummy; - - return davinci_eth_phy_read(phy_addr, MII_PHYSID1, &dummy); -} - -static int get_active_phy(void) -{ - int i; - - for (i = 0; i < num_phy; i++) - if (phy[i].get_link_speed(active_phy_addr[i])) - return i; - - return -1; /* Return error if no link */ -} - -static int gen_get_link_speed(int phy_addr) -{ - u_int16_t tmp; - - if (davinci_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) && - (tmp & 0x04)) { -#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \ - defined(CONFIG_MACH_DAVINCI_DA850_EVM) - davinci_eth_phy_read(phy_addr, MII_LPA, &tmp); - - /* Speed doesn't matter, there is no setting for it in EMAC. */ - if (tmp & (LPA_100FULL | LPA_10FULL)) { - /* set EMAC for Full Duplex */ - writel(EMAC_MACCONTROL_MIIEN_ENABLE | - EMAC_MACCONTROL_FULLDUPLEX_ENABLE, - &adap_emac->MACCONTROL); - } else { - /*set EMAC for Half Duplex */ - writel(EMAC_MACCONTROL_MIIEN_ENABLE, - &adap_emac->MACCONTROL); - } - - if (tmp & (LPA_100FULL | LPA_100HALF)) - writel(readl(&adap_emac->MACCONTROL) | - EMAC_MACCONTROL_RMIISPEED_100, - &adap_emac->MACCONTROL); - else - writel(readl(&adap_emac->MACCONTROL) & - ~EMAC_MACCONTROL_RMIISPEED_100, - &adap_emac->MACCONTROL); -#endif - return(1); - } - - return(0); -} - -static int gen_auto_negotiate(int phy_addr) -{ - u_int16_t tmp; - u_int16_t val; - unsigned long cntr = 0; - - if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp)) - return 0; - - val = tmp | BMCR_FULLDPLX | BMCR_ANENABLE | - BMCR_SPEED100; - davinci_eth_phy_write(phy_addr, MII_BMCR, val); - - if (!davinci_eth_phy_read(phy_addr, MII_ADVERTISE, &val)) - return 0; - - val |= (ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10FULL | - ADVERTISE_10HALF); - davinci_eth_phy_write(phy_addr, MII_ADVERTISE, val); - - if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp)) - return(0); - - /* Restart Auto_negotiation */ - tmp |= BMCR_ANRESTART; - davinci_eth_phy_write(phy_addr, MII_BMCR, tmp); - - /*check AutoNegotiate complete */ - do { - udelay(40000); - if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp)) - return 0; - - if (tmp & BMSR_ANEGCOMPLETE) - break; - - cntr++; - } while (cntr < 200); - - if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp)) - return(0); - - if (!(tmp & BMSR_ANEGCOMPLETE)) - return(0); - - return(gen_get_link_speed(phy_addr)); -} -/* End of generic PHY functions */ - - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) -static int davinci_mii_phy_read(const char *devname, unsigned char addr, unsigned char reg, unsigned short *value) -{ - return(davinci_eth_phy_read(addr, reg, value) ? 0 : 1); -} - -static int davinci_mii_phy_write(const char *devname, unsigned char addr, unsigned char reg, unsigned short value) -{ - return(davinci_eth_phy_write(addr, reg, value) ? 0 : 1); -} -#endif - -static void __attribute__((unused)) davinci_eth_gigabit_enable(int phy_addr) -{ - u_int16_t data; - - if (davinci_eth_phy_read(phy_addr, 0, &data)) { - if (data & (1 << 6)) { /* speed selection MSB */ - /* - * Check if link detected is giga-bit - * If Gigabit mode detected, enable gigbit in MAC - */ - writel(readl(&adap_emac->MACCONTROL) | - EMAC_MACCONTROL_GIGFORCE | - EMAC_MACCONTROL_GIGABIT_ENABLE, - &adap_emac->MACCONTROL); - } - } -} - -/* Eth device open */ -static int davinci_eth_open(struct eth_device *dev, bd_t *bis) -{ - dv_reg_p addr; - u_int32_t clkdiv, cnt; - volatile emac_desc *rx_desc; - int index; - - debug_emac("+ emac_open\n"); - - /* Reset EMAC module and disable interrupts in wrapper */ - writel(1, &adap_emac->SOFTRESET); - while (readl(&adap_emac->SOFTRESET) != 0) - ; -#if defined(DAVINCI_EMAC_VERSION2) - writel(1, &adap_ewrap->softrst); - while (readl(&adap_ewrap->softrst) != 0) - ; -#else - writel(0, &adap_ewrap->EWCTL); - for (cnt = 0; cnt < 5; cnt++) { - clkdiv = readl(&adap_ewrap->EWCTL); - } -#endif - -#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \ - defined(CONFIG_MACH_DAVINCI_DA850_EVM) - adap_ewrap->c0rxen = adap_ewrap->c1rxen = adap_ewrap->c2rxen = 0; - adap_ewrap->c0txen = adap_ewrap->c1txen = adap_ewrap->c2txen = 0; - adap_ewrap->c0miscen = adap_ewrap->c1miscen = adap_ewrap->c2miscen = 0; -#endif - rx_desc = emac_rx_desc; - - writel(1, &adap_emac->TXCONTROL); - writel(1, &adap_emac->RXCONTROL); - - davinci_eth_set_mac_addr(dev); - - /* Set DMA 8 TX / 8 RX Head pointers to 0 */ - addr = &adap_emac->TX0HDP; - for(cnt = 0; cnt < 16; cnt++) - writel(0, addr++); - - addr = &adap_emac->RX0HDP; - for(cnt = 0; cnt < 16; cnt++) - writel(0, addr++); - - /* Clear Statistics (do this before setting MacControl register) */ - addr = &adap_emac->RXGOODFRAMES; - for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++) - writel(0, addr++); - - /* No multicast addressing */ - writel(0, &adap_emac->MACHASH1); - writel(0, &adap_emac->MACHASH2); - - /* Create RX queue and set receive process in place */ - emac_rx_active_head = emac_rx_desc; - for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) { - rx_desc->next = BD_TO_HW((u_int32_t)(rx_desc + 1)); - rx_desc->buffer = &emac_rx_buffers[cnt * EMAC_RXBUF_SIZE]; - rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE; - rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT; - rx_desc++; - } - - /* Finalize the rx desc list */ - rx_desc--; - rx_desc->next = 0; - emac_rx_active_tail = rx_desc; - emac_rx_queue_active = 1; - - davinci_flush_rx_descs(); - - /* Enable TX/RX */ - writel(EMAC_MAX_ETHERNET_PKT_SIZE, &adap_emac->RXMAXLEN); - writel(0, &adap_emac->RXBUFFEROFFSET); - - /* - * No fancy configs - Use this for promiscous debug - * - EMAC_RXMBPENABLE_RXCAFEN_ENABLE - */ - writel(EMAC_RXMBPENABLE_RXBROADEN, &adap_emac->RXMBPENABLE); - - /* Enable ch 0 only */ - writel(1, &adap_emac->RXUNICASTSET); - - /* Enable MII interface and Full duplex mode */ -#if defined(CONFIG_SOC_DA8XX) || \ - (defined(CONFIG_OMAP34XX) && defined(CONFIG_DRIVER_TI_EMAC_USE_RMII)) - writel((EMAC_MACCONTROL_MIIEN_ENABLE | - EMAC_MACCONTROL_FULLDUPLEX_ENABLE | - EMAC_MACCONTROL_RMIISPEED_100), - &adap_emac->MACCONTROL); -#else - writel((EMAC_MACCONTROL_MIIEN_ENABLE | - EMAC_MACCONTROL_FULLDUPLEX_ENABLE), - &adap_emac->MACCONTROL); -#endif - - /* Init MDIO & get link state */ - clkdiv = CONFIG_SYS_EMAC_TI_CLKDIV; - writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT, - &adap_mdio->CONTROL); - - /* We need to wait for MDIO to start */ - udelay(1000); - - index = get_active_phy(); - if (index == -1) - return(0); - - emac_gigabit_enable(active_phy_addr[index]); - - /* Start receive process */ - writel(BD_TO_HW((u_int32_t)emac_rx_desc), &adap_emac->RX0HDP); - - debug_emac("- emac_open\n"); - - return(1); -} - -/* EMAC Channel Teardown */ -static void davinci_eth_ch_teardown(int ch) -{ - dv_reg dly = 0xff; - dv_reg cnt; - - debug_emac("+ emac_ch_teardown\n"); - - if (ch == EMAC_CH_TX) { - /* Init TX channel teardown */ - writel(0, &adap_emac->TXTEARDOWN); - do { - /* - * Wait here for Tx teardown completion interrupt to - * occur. Note: A task delay can be called here to pend - * rather than occupying CPU cycles - anyway it has - * been found that teardown takes very few cpu cycles - * and does not affect functionality - */ - dly--; - udelay(1); - if (dly == 0) - break; - cnt = readl(&adap_emac->TX0CP); - } while (cnt != 0xfffffffc); - writel(cnt, &adap_emac->TX0CP); - writel(0, &adap_emac->TX0HDP); - } else { - /* Init RX channel teardown */ - writel(0, &adap_emac->RXTEARDOWN); - do { - /* - * Wait here for Rx teardown completion interrupt to - * occur. Note: A task delay can be called here to pend - * rather than occupying CPU cycles - anyway it has - * been found that teardown takes very few cpu cycles - * and does not affect functionality - */ - dly--; - udelay(1); - if (dly == 0) - break; - cnt = readl(&adap_emac->RX0CP); - } while (cnt != 0xfffffffc); - writel(cnt, &adap_emac->RX0CP); - writel(0, &adap_emac->RX0HDP); - } - - debug_emac("- emac_ch_teardown\n"); -} - -/* Eth device close */ -static void davinci_eth_close(struct eth_device *dev) -{ - debug_emac("+ emac_close\n"); - - davinci_eth_ch_teardown(EMAC_CH_TX); /* TX Channel teardown */ - davinci_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */ - - /* Reset EMAC module and disable interrupts in wrapper */ - writel(1, &adap_emac->SOFTRESET); -#if defined(DAVINCI_EMAC_VERSION2) - writel(1, &adap_ewrap->softrst); -#else - writel(0, &adap_ewrap->EWCTL); -#endif - -#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \ - defined(CONFIG_MACH_DAVINCI_DA850_EVM) - adap_ewrap->c0rxen = adap_ewrap->c1rxen = adap_ewrap->c2rxen = 0; - adap_ewrap->c0txen = adap_ewrap->c1txen = adap_ewrap->c2txen = 0; - adap_ewrap->c0miscen = adap_ewrap->c1miscen = adap_ewrap->c2miscen = 0; -#endif - debug_emac("- emac_close\n"); -} - -static int tx_send_loop = 0; - -/* - * This function sends a single packet on the network and returns - * positive number (number of bytes transmitted) or negative for error - */ -static int davinci_eth_send_packet (struct eth_device *dev, - void *packet, int length) -{ - int ret_status = -1; - int index; - tx_send_loop = 0; - - index = get_active_phy(); - if (index == -1) { - printf(" WARN: emac_send_packet: No link\n"); - return (ret_status); - } - - emac_gigabit_enable(active_phy_addr[index]); - - /* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */ - if (length < EMAC_MIN_ETHERNET_PKT_SIZE) { - length = EMAC_MIN_ETHERNET_PKT_SIZE; - } - - /* Populate the TX descriptor */ - emac_tx_desc->next = 0; - emac_tx_desc->buffer = (u_int8_t *) packet; - emac_tx_desc->buff_off_len = (length & 0xffff); - emac_tx_desc->pkt_flag_len = ((length & 0xffff) | - EMAC_CPPI_SOP_BIT | - EMAC_CPPI_OWNERSHIP_BIT | - EMAC_CPPI_EOP_BIT); - - flush_dcache_range((unsigned long)packet, - (unsigned long)packet + length); - davinci_flush_desc(emac_tx_desc); - - /* Send the packet */ - writel(BD_TO_HW((unsigned long)emac_tx_desc), &adap_emac->TX0HDP); - - /* Wait for packet to complete or link down */ - while (1) { - if (!phy[index].get_link_speed(active_phy_addr[index])) { - davinci_eth_ch_teardown (EMAC_CH_TX); - return (ret_status); - } - - emac_gigabit_enable(active_phy_addr[index]); - - if (readl(&adap_emac->TXINTSTATRAW) & 0x01) { - ret_status = length; - break; - } - tx_send_loop++; - } - - return (ret_status); -} - -/* - * This function handles receipt of a packet from the network - */ -static int davinci_eth_rcv_packet (struct eth_device *dev) -{ - volatile emac_desc *rx_curr_desc; - volatile emac_desc *curr_desc; - volatile emac_desc *tail_desc; - int status, ret = -1; - - davinci_invalidate_rx_descs(); - - rx_curr_desc = emac_rx_active_head; - status = rx_curr_desc->pkt_flag_len; - if ((rx_curr_desc) && ((status & EMAC_CPPI_OWNERSHIP_BIT) == 0)) { - if (status & EMAC_CPPI_RX_ERROR_FRAME) { - /* Error in packet - discard it and requeue desc */ - printf ("WARN: emac_rcv_pkt: Error in packet\n"); - } else { - unsigned long tmp = (unsigned long)rx_curr_desc->buffer; - - invalidate_dcache_range(tmp, tmp + EMAC_RXBUF_SIZE); - NetReceive (rx_curr_desc->buffer, - (rx_curr_desc->buff_off_len & 0xffff)); - ret = rx_curr_desc->buff_off_len & 0xffff; - } - - /* Ack received packet descriptor */ - writel(BD_TO_HW((ulong)rx_curr_desc), &adap_emac->RX0CP); - curr_desc = rx_curr_desc; - emac_rx_active_head = - (volatile emac_desc *) (HW_TO_BD(rx_curr_desc->next)); - - if (status & EMAC_CPPI_EOQ_BIT) { - if (emac_rx_active_head) { - writel(BD_TO_HW((ulong)emac_rx_active_head), - &adap_emac->RX0HDP); - } else { - emac_rx_queue_active = 0; - printf ("INFO:emac_rcv_packet: RX Queue not active\n"); - } - } - - /* Recycle RX descriptor */ - rx_curr_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE; - rx_curr_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT; - rx_curr_desc->next = 0; - davinci_flush_desc(rx_curr_desc); - - if (emac_rx_active_head == 0) { - printf ("INFO: emac_rcv_pkt: active queue head = 0\n"); - emac_rx_active_head = curr_desc; - emac_rx_active_tail = curr_desc; - if (emac_rx_queue_active != 0) { - writel(BD_TO_HW((ulong)emac_rx_active_head), - &adap_emac->RX0HDP); - printf ("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n"); - emac_rx_queue_active = 1; - } - } else { - tail_desc = emac_rx_active_tail; - emac_rx_active_tail = curr_desc; - tail_desc->next = BD_TO_HW((ulong) curr_desc); - status = tail_desc->pkt_flag_len; - if (status & EMAC_CPPI_EOQ_BIT) { - davinci_flush_desc(tail_desc); - writel(BD_TO_HW((ulong)curr_desc), - &adap_emac->RX0HDP); - status &= ~EMAC_CPPI_EOQ_BIT; - tail_desc->pkt_flag_len = status; - } - davinci_flush_desc(tail_desc); - } - return (ret); - } - return (0); -} - -/* - * This function initializes the emac hardware. It does NOT initialize - * EMAC modules power or pin multiplexors, that is done by board_init() - * much earlier in bootup process. Returns 1 on success, 0 otherwise. - */ -int davinci_emac_initialize(void) -{ - u_int32_t phy_id; - u_int16_t tmp; - int i; - int ret; - struct eth_device *dev; - - dev = malloc(sizeof *dev); - - if (dev == NULL) - return -1; - - memset(dev, 0, sizeof *dev); - sprintf(dev->name, "DaVinci-EMAC"); - - dev->iobase = 0; - dev->init = davinci_eth_open; - dev->halt = davinci_eth_close; - dev->send = davinci_eth_send_packet; - dev->recv = davinci_eth_rcv_packet; - dev->write_hwaddr = davinci_eth_set_mac_addr; - - eth_register(dev); - - davinci_eth_mdio_enable(); - - /* let the EMAC detect the PHYs */ - udelay(5000); - - for (i = 0; i < 256; i++) { - if (readl(&adap_mdio->ALIVE)) - break; - udelay(1000); - } - - if (i >= 256) { - printf("No ETH PHY detected!!!\n"); - return(0); - } - - /* Find if PHY(s) is/are connected */ - ret = davinci_eth_phy_detect(); - if (!ret) - return(0); - else - debug_emac(" %d ETH PHY detected\n", ret); - - /* Get PHY ID and initialize phy_ops for a detected PHY */ - for (i = 0; i < num_phy; i++) { - if (!davinci_eth_phy_read(active_phy_addr[i], MII_PHYSID1, - &tmp)) { - active_phy_addr[i] = 0xff; - continue; - } - - phy_id = (tmp << 16) & 0xffff0000; - - if (!davinci_eth_phy_read(active_phy_addr[i], MII_PHYSID2, - &tmp)) { - active_phy_addr[i] = 0xff; - continue; - } - - phy_id |= tmp & 0x0000ffff; - - switch (phy_id) { -#ifdef PHY_KSZ8873 - case PHY_KSZ8873: - sprintf(phy[i].name, "KSZ8873 @ 0x%02x", - active_phy_addr[i]); - phy[i].init = ksz8873_init_phy; - phy[i].is_phy_connected = ksz8873_is_phy_connected; - phy[i].get_link_speed = ksz8873_get_link_speed; - phy[i].auto_negotiate = ksz8873_auto_negotiate; - break; -#endif -#ifdef PHY_LXT972 - case PHY_LXT972: - sprintf(phy[i].name, "LXT972 @ 0x%02x", - active_phy_addr[i]); - phy[i].init = lxt972_init_phy; - phy[i].is_phy_connected = lxt972_is_phy_connected; - phy[i].get_link_speed = lxt972_get_link_speed; - phy[i].auto_negotiate = lxt972_auto_negotiate; - break; -#endif -#ifdef PHY_DP83848 - case PHY_DP83848: - sprintf(phy[i].name, "DP83848 @ 0x%02x", - active_phy_addr[i]); - phy[i].init = dp83848_init_phy; - phy[i].is_phy_connected = dp83848_is_phy_connected; - phy[i].get_link_speed = dp83848_get_link_speed; - phy[i].auto_negotiate = dp83848_auto_negotiate; - break; -#endif -#ifdef PHY_ET1011C - case PHY_ET1011C: - sprintf(phy[i].name, "ET1011C @ 0x%02x", - active_phy_addr[i]); - phy[i].init = gen_init_phy; - phy[i].is_phy_connected = gen_is_phy_connected; - phy[i].get_link_speed = et1011c_get_link_speed; - phy[i].auto_negotiate = gen_auto_negotiate; - break; -#endif - default: - sprintf(phy[i].name, "GENERIC @ 0x%02x", - active_phy_addr[i]); - phy[i].init = gen_init_phy; - phy[i].is_phy_connected = gen_is_phy_connected; - phy[i].get_link_speed = gen_get_link_speed; - phy[i].auto_negotiate = gen_auto_negotiate; - } - - debug("Ethernet PHY: %s\n", phy[i].name); - - miiphy_register(phy[i].name, davinci_mii_phy_read, - davinci_mii_phy_write); - } - -#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \ - defined(CONFIG_MACH_DAVINCI_DA850_EVM) && \ - !defined(CONFIG_DRIVER_TI_EMAC_RMII_NO_NEGOTIATE) - for (i = 0; i < num_phy; i++) { - if (phy[i].is_phy_connected(i)) - phy[i].auto_negotiate(i); - } -#endif - return(1); -} diff --git a/qemu/roms/u-boot/drivers/net/davinci_emac.h b/qemu/roms/u-boot/drivers/net/davinci_emac.h deleted file mode 100644 index 13cd68f04..000000000 --- a/qemu/roms/u-boot/drivers/net/davinci_emac.h +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (C) 2011 Ilya Yanok, Emcraft Systems - * - * Based on: mach-davinci/emac_defs.h - * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _DAVINCI_EMAC_H_ -#define _DAVINCI_EMAC_H_ -/* Ethernet Min/Max packet size */ -#define EMAC_MIN_ETHERNET_PKT_SIZE 60 -#define EMAC_MAX_ETHERNET_PKT_SIZE 1518 -/* Buffer size (should be aligned on 32 byte and cache line) */ -#define EMAC_RXBUF_SIZE ALIGN(ALIGN(EMAC_MAX_ETHERNET_PKT_SIZE, 32),\ - ARCH_DMA_MINALIGN) - -/* Number of RX packet buffers - * NOTE: Only 1 buffer supported as of now - */ -#define EMAC_MAX_RX_BUFFERS 10 - - -/*********************************************** - ******** Internally used macros *************** - ***********************************************/ - -#define EMAC_CH_TX 1 -#define EMAC_CH_RX 0 - -/* Each descriptor occupies 4 words, lets start RX desc's at 0 and - * reserve space for 64 descriptors max - */ -#define EMAC_RX_DESC_BASE 0x0 -#define EMAC_TX_DESC_BASE 0x1000 - -/* EMAC Teardown value */ -#define EMAC_TEARDOWN_VALUE 0xfffffffc - -/* MII Status Register */ -#define MII_STATUS_REG 1 - -/* Number of statistics registers */ -#define EMAC_NUM_STATS 36 - - -/* EMAC Descriptor */ -typedef volatile struct _emac_desc -{ - u_int32_t next; /* Pointer to next descriptor - in chain */ - u_int8_t *buffer; /* Pointer to data buffer */ - u_int32_t buff_off_len; /* Buffer Offset(MSW) and Length(LSW) */ - u_int32_t pkt_flag_len; /* Packet Flags(MSW) and Length(LSW) */ -} emac_desc; - -/* CPPI bit positions */ -#define EMAC_CPPI_SOP_BIT (0x80000000) -#define EMAC_CPPI_EOP_BIT (0x40000000) -#define EMAC_CPPI_OWNERSHIP_BIT (0x20000000) -#define EMAC_CPPI_EOQ_BIT (0x10000000) -#define EMAC_CPPI_TEARDOWN_COMPLETE_BIT (0x08000000) -#define EMAC_CPPI_PASS_CRC_BIT (0x04000000) - -#define EMAC_CPPI_RX_ERROR_FRAME (0x03fc0000) - -#define EMAC_MACCONTROL_MIIEN_ENABLE (0x20) -#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE (0x1) -#define EMAC_MACCONTROL_GIGABIT_ENABLE (1 << 7) -#define EMAC_MACCONTROL_GIGFORCE (1 << 17) -#define EMAC_MACCONTROL_RMIISPEED_100 (1 << 15) - -#define EMAC_MAC_ADDR_MATCH (1 << 19) -#define EMAC_MAC_ADDR_IS_VALID (1 << 20) - -#define EMAC_RXMBPENABLE_RXCAFEN_ENABLE (0x200000) -#define EMAC_RXMBPENABLE_RXBROADEN (0x2000) - - -#define MDIO_CONTROL_IDLE (0x80000000) -#define MDIO_CONTROL_ENABLE (0x40000000) -#define MDIO_CONTROL_FAULT_ENABLE (0x40000) -#define MDIO_CONTROL_FAULT (0x80000) -#define MDIO_USERACCESS0_GO (0x80000000) -#define MDIO_USERACCESS0_WRITE_READ (0x0) -#define MDIO_USERACCESS0_WRITE_WRITE (0x40000000) -#define MDIO_USERACCESS0_ACK (0x20000000) - -/* Ethernet MAC Registers Structure */ -typedef struct { - dv_reg TXIDVER; - dv_reg TXCONTROL; - dv_reg TXTEARDOWN; - u_int8_t RSVD0[4]; - dv_reg RXIDVER; - dv_reg RXCONTROL; - dv_reg RXTEARDOWN; - u_int8_t RSVD1[100]; - dv_reg TXINTSTATRAW; - dv_reg TXINTSTATMASKED; - dv_reg TXINTMASKSET; - dv_reg TXINTMASKCLEAR; - dv_reg MACINVECTOR; - u_int8_t RSVD2[12]; - dv_reg RXINTSTATRAW; - dv_reg RXINTSTATMASKED; - dv_reg RXINTMASKSET; - dv_reg RXINTMASKCLEAR; - dv_reg MACINTSTATRAW; - dv_reg MACINTSTATMASKED; - dv_reg MACINTMASKSET; - dv_reg MACINTMASKCLEAR; - u_int8_t RSVD3[64]; - dv_reg RXMBPENABLE; - dv_reg RXUNICASTSET; - dv_reg RXUNICASTCLEAR; - dv_reg RXMAXLEN; - dv_reg RXBUFFEROFFSET; - dv_reg RXFILTERLOWTHRESH; - u_int8_t RSVD4[8]; - dv_reg RX0FLOWTHRESH; - dv_reg RX1FLOWTHRESH; - dv_reg RX2FLOWTHRESH; - dv_reg RX3FLOWTHRESH; - dv_reg RX4FLOWTHRESH; - dv_reg RX5FLOWTHRESH; - dv_reg RX6FLOWTHRESH; - dv_reg RX7FLOWTHRESH; - dv_reg RX0FREEBUFFER; - dv_reg RX1FREEBUFFER; - dv_reg RX2FREEBUFFER; - dv_reg RX3FREEBUFFER; - dv_reg RX4FREEBUFFER; - dv_reg RX5FREEBUFFER; - dv_reg RX6FREEBUFFER; - dv_reg RX7FREEBUFFER; - dv_reg MACCONTROL; - dv_reg MACSTATUS; - dv_reg EMCONTROL; - dv_reg FIFOCONTROL; - dv_reg MACCONFIG; - dv_reg SOFTRESET; - u_int8_t RSVD5[88]; - dv_reg MACSRCADDRLO; - dv_reg MACSRCADDRHI; - dv_reg MACHASH1; - dv_reg MACHASH2; - dv_reg BOFFTEST; - dv_reg TPACETEST; - dv_reg RXPAUSE; - dv_reg TXPAUSE; - u_int8_t RSVD6[16]; - dv_reg RXGOODFRAMES; - dv_reg RXBCASTFRAMES; - dv_reg RXMCASTFRAMES; - dv_reg RXPAUSEFRAMES; - dv_reg RXCRCERRORS; - dv_reg RXALIGNCODEERRORS; - dv_reg RXOVERSIZED; - dv_reg RXJABBER; - dv_reg RXUNDERSIZED; - dv_reg RXFRAGMENTS; - dv_reg RXFILTERED; - dv_reg RXQOSFILTERED; - dv_reg RXOCTETS; - dv_reg TXGOODFRAMES; - dv_reg TXBCASTFRAMES; - dv_reg TXMCASTFRAMES; - dv_reg TXPAUSEFRAMES; - dv_reg TXDEFERRED; - dv_reg TXCOLLISION; - dv_reg TXSINGLECOLL; - dv_reg TXMULTICOLL; - dv_reg TXEXCESSIVECOLL; - dv_reg TXLATECOLL; - dv_reg TXUNDERRUN; - dv_reg TXCARRIERSENSE; - dv_reg TXOCTETS; - dv_reg FRAME64; - dv_reg FRAME65T127; - dv_reg FRAME128T255; - dv_reg FRAME256T511; - dv_reg FRAME512T1023; - dv_reg FRAME1024TUP; - dv_reg NETOCTETS; - dv_reg RXSOFOVERRUNS; - dv_reg RXMOFOVERRUNS; - dv_reg RXDMAOVERRUNS; - u_int8_t RSVD7[624]; - dv_reg MACADDRLO; - dv_reg MACADDRHI; - dv_reg MACINDEX; - u_int8_t RSVD8[244]; - dv_reg TX0HDP; - dv_reg TX1HDP; - dv_reg TX2HDP; - dv_reg TX3HDP; - dv_reg TX4HDP; - dv_reg TX5HDP; - dv_reg TX6HDP; - dv_reg TX7HDP; - dv_reg RX0HDP; - dv_reg RX1HDP; - dv_reg RX2HDP; - dv_reg RX3HDP; - dv_reg RX4HDP; - dv_reg RX5HDP; - dv_reg RX6HDP; - dv_reg RX7HDP; - dv_reg TX0CP; - dv_reg TX1CP; - dv_reg TX2CP; - dv_reg TX3CP; - dv_reg TX4CP; - dv_reg TX5CP; - dv_reg TX6CP; - dv_reg TX7CP; - dv_reg RX0CP; - dv_reg RX1CP; - dv_reg RX2CP; - dv_reg RX3CP; - dv_reg RX4CP; - dv_reg RX5CP; - dv_reg RX6CP; - dv_reg RX7CP; -} emac_regs; - -/* EMAC Wrapper Registers Structure */ -typedef struct { -#ifdef DAVINCI_EMAC_VERSION2 - dv_reg idver; - dv_reg softrst; - dv_reg emctrl; - dv_reg c0rxthreshen; - dv_reg c0rxen; - dv_reg c0txen; - dv_reg c0miscen; - dv_reg c1rxthreshen; - dv_reg c1rxen; - dv_reg c1txen; - dv_reg c1miscen; - dv_reg c2rxthreshen; - dv_reg c2rxen; - dv_reg c2txen; - dv_reg c2miscen; - dv_reg c0rxthreshstat; - dv_reg c0rxstat; - dv_reg c0txstat; - dv_reg c0miscstat; - dv_reg c1rxthreshstat; - dv_reg c1rxstat; - dv_reg c1txstat; - dv_reg c1miscstat; - dv_reg c2rxthreshstat; - dv_reg c2rxstat; - dv_reg c2txstat; - dv_reg c2miscstat; - dv_reg c0rximax; - dv_reg c0tximax; - dv_reg c1rximax; - dv_reg c1tximax; - dv_reg c2rximax; - dv_reg c2tximax; -#else - u_int8_t RSVD0[4100]; - dv_reg EWCTL; - dv_reg EWINTTCNT; -#endif -} ewrap_regs; - -/* EMAC MDIO Registers Structure */ -typedef struct { - dv_reg VERSION; - dv_reg CONTROL; - dv_reg ALIVE; - dv_reg LINK; - dv_reg LINKINTRAW; - dv_reg LINKINTMASKED; - u_int8_t RSVD0[8]; - dv_reg USERINTRAW; - dv_reg USERINTMASKED; - dv_reg USERINTMASKSET; - dv_reg USERINTMASKCLEAR; - u_int8_t RSVD1[80]; - dv_reg USERACCESS0; - dv_reg USERPHYSEL0; - dv_reg USERACCESS1; - dv_reg USERPHYSEL1; -} mdio_regs; - -int davinci_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data); -int davinci_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data); - -typedef struct { - char name[64]; - int (*init)(int phy_addr); - int (*is_phy_connected)(int phy_addr); - int (*get_link_speed)(int phy_addr); - int (*auto_negotiate)(int phy_addr); -} phy_t; - -#endif /* _DAVINCI_EMAC_H_ */ diff --git a/qemu/roms/u-boot/drivers/net/dc2114x.c b/qemu/roms/u-boot/drivers/net/dc2114x.c deleted file mode 100644 index 799839c4f..000000000 --- a/qemu/roms/u-boot/drivers/net/dc2114x.c +++ /dev/null @@ -1,760 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <pci.h> - -#undef DEBUG_SROM -#undef DEBUG_SROM2 - -#undef UPDATE_SROM - -/* PCI Registers. - */ -#define PCI_CFDA_PSM 0x43 - -#define CFRV_RN 0x000000f0 /* Revision Number */ - -#define WAKEUP 0x00 /* Power Saving Wakeup */ -#define SLEEP 0x80 /* Power Saving Sleep Mode */ - -#define DC2114x_BRK 0x0020 /* CFRV break between DC21142 & DC21143 */ - -/* Ethernet chip registers. - */ -#define DE4X5_BMR 0x000 /* Bus Mode Register */ -#define DE4X5_TPD 0x008 /* Transmit Poll Demand Reg */ -#define DE4X5_RRBA 0x018 /* RX Ring Base Address Reg */ -#define DE4X5_TRBA 0x020 /* TX Ring Base Address Reg */ -#define DE4X5_STS 0x028 /* Status Register */ -#define DE4X5_OMR 0x030 /* Operation Mode Register */ -#define DE4X5_SICR 0x068 /* SIA Connectivity Register */ -#define DE4X5_APROM 0x048 /* Ethernet Address PROM */ - -/* Register bits. - */ -#define BMR_SWR 0x00000001 /* Software Reset */ -#define STS_TS 0x00700000 /* Transmit Process State */ -#define STS_RS 0x000e0000 /* Receive Process State */ -#define OMR_ST 0x00002000 /* Start/Stop Transmission Command */ -#define OMR_SR 0x00000002 /* Start/Stop Receive */ -#define OMR_PS 0x00040000 /* Port Select */ -#define OMR_SDP 0x02000000 /* SD Polarity - MUST BE ASSERTED */ -#define OMR_PM 0x00000080 /* Pass All Multicast */ - -/* Descriptor bits. - */ -#define R_OWN 0x80000000 /* Own Bit */ -#define RD_RER 0x02000000 /* Receive End Of Ring */ -#define RD_LS 0x00000100 /* Last Descriptor */ -#define RD_ES 0x00008000 /* Error Summary */ -#define TD_TER 0x02000000 /* Transmit End Of Ring */ -#define T_OWN 0x80000000 /* Own Bit */ -#define TD_LS 0x40000000 /* Last Segment */ -#define TD_FS 0x20000000 /* First Segment */ -#define TD_ES 0x00008000 /* Error Summary */ -#define TD_SET 0x08000000 /* Setup Packet */ - -/* The EEPROM commands include the alway-set leading bit. */ -#define SROM_WRITE_CMD 5 -#define SROM_READ_CMD 6 -#define SROM_ERASE_CMD 7 - -#define SROM_HWADD 0x0014 /* Hardware Address offset in SROM */ -#define SROM_RD 0x00004000 /* Read from Boot ROM */ -#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */ -#define EE_WRITE_0 0x4801 -#define EE_WRITE_1 0x4805 -#define EE_DATA_READ 0x08 /* EEPROM chip data out. */ -#define SROM_SR 0x00000800 /* Select Serial ROM when set */ - -#define DT_IN 0x00000004 /* Serial Data In */ -#define DT_CLK 0x00000002 /* Serial ROM Clock */ -#define DT_CS 0x00000001 /* Serial ROM Chip Select */ - -#define POLL_DEMAND 1 - -#ifdef CONFIG_TULIP_FIX_DAVICOM -#define RESET_DM9102(dev) {\ - unsigned long i;\ - i=INL(dev, 0x0);\ - udelay(1000);\ - OUTL(dev, i | BMR_SWR, DE4X5_BMR);\ - udelay(1000);\ -} -#else -#define RESET_DE4X5(dev) {\ - int i;\ - i=INL(dev, DE4X5_BMR);\ - udelay(1000);\ - OUTL(dev, i | BMR_SWR, DE4X5_BMR);\ - udelay(1000);\ - OUTL(dev, i, DE4X5_BMR);\ - udelay(1000);\ - for (i=0;i<5;i++) {INL(dev, DE4X5_BMR); udelay(10000);}\ - udelay(1000);\ -} -#endif - -#define START_DE4X5(dev) {\ - s32 omr; \ - omr = INL(dev, DE4X5_OMR);\ - omr |= OMR_ST | OMR_SR;\ - OUTL(dev, omr, DE4X5_OMR); /* Enable the TX and/or RX */\ -} - -#define STOP_DE4X5(dev) {\ - s32 omr; \ - omr = INL(dev, DE4X5_OMR);\ - omr &= ~(OMR_ST|OMR_SR);\ - OUTL(dev, omr, DE4X5_OMR); /* Disable the TX and/or RX */ \ -} - -#define NUM_RX_DESC PKTBUFSRX -#ifndef CONFIG_TULIP_FIX_DAVICOM - #define NUM_TX_DESC 1 /* Number of TX descriptors */ -#else - #define NUM_TX_DESC 4 -#endif -#define RX_BUFF_SZ PKTSIZE_ALIGN - -#define TOUT_LOOP 1000000 - -#define SETUP_FRAME_LEN 192 -#define ETH_ALEN 6 - -struct de4x5_desc { - volatile s32 status; - u32 des1; - u32 buf; - u32 next; -}; - -static struct de4x5_desc rx_ring[NUM_RX_DESC] __attribute__ ((aligned(32))); /* RX descriptor ring */ -static struct de4x5_desc tx_ring[NUM_TX_DESC] __attribute__ ((aligned(32))); /* TX descriptor ring */ -static int rx_new; /* RX descriptor ring pointer */ -static int tx_new; /* TX descriptor ring pointer */ - -static char rxRingSize; -static char txRingSize; - -#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM) -static void sendto_srom(struct eth_device* dev, u_int command, u_long addr); -static int getfrom_srom(struct eth_device* dev, u_long addr); -static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr,int cmd,int cmd_len); -static int do_read_eeprom(struct eth_device *dev,u_long ioaddr,int location,int addr_len); -#endif /* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */ -#ifdef UPDATE_SROM -static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value); -static void update_srom(struct eth_device *dev, bd_t *bis); -#endif -#ifndef CONFIG_TULIP_FIX_DAVICOM -static int read_srom(struct eth_device *dev, u_long ioaddr, int index); -static void read_hw_addr(struct eth_device* dev, bd_t * bis); -#endif /* CONFIG_TULIP_FIX_DAVICOM */ -static void send_setup_frame(struct eth_device* dev, bd_t * bis); - -static int dc21x4x_init(struct eth_device* dev, bd_t* bis); -static int dc21x4x_send(struct eth_device *dev, void *packet, int length); -static int dc21x4x_recv(struct eth_device* dev); -static void dc21x4x_halt(struct eth_device* dev); -#ifdef CONFIG_TULIP_SELECT_MEDIA -extern void dc21x4x_select_media(struct eth_device* dev); -#endif - -#if defined(CONFIG_E500) -#define phys_to_bus(a) (a) -#else -#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) -#endif - -static int INL(struct eth_device* dev, u_long addr) -{ - return le32_to_cpu(*(volatile u_long *)(addr + dev->iobase)); -} - -static void OUTL(struct eth_device* dev, int command, u_long addr) -{ - *(volatile u_long *)(addr + dev->iobase) = cpu_to_le32(command); -} - -static struct pci_device_id supported[] = { - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST }, - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142 }, -#ifdef CONFIG_TULIP_FIX_DAVICOM - { PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DAVICOM_DM9102A }, -#endif - { } -}; - -int dc21x4x_initialize(bd_t *bis) -{ - int idx=0; - int card_number = 0; - unsigned int cfrv; - unsigned char timer; - pci_dev_t devbusfn; - unsigned int iobase; - unsigned short status; - struct eth_device* dev; - - while(1) { - devbusfn = pci_find_devices(supported, idx++); - if (devbusfn == -1) { - break; - } - - /* Get the chip configuration revision register. */ - pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv); - -#ifndef CONFIG_TULIP_FIX_DAVICOM - if ((cfrv & CFRV_RN) < DC2114x_BRK ) { - printf("Error: The chip is not DC21143.\n"); - continue; - } -#endif - - pci_read_config_word(devbusfn, PCI_COMMAND, &status); - status |= -#ifdef CONFIG_TULIP_USE_IO - PCI_COMMAND_IO | -#else - PCI_COMMAND_MEMORY | -#endif - PCI_COMMAND_MASTER; - pci_write_config_word(devbusfn, PCI_COMMAND, status); - - pci_read_config_word(devbusfn, PCI_COMMAND, &status); -#ifdef CONFIG_TULIP_USE_IO - if (!(status & PCI_COMMAND_IO)) { - printf("Error: Can not enable I/O access.\n"); - continue; - } -#else - if (!(status & PCI_COMMAND_MEMORY)) { - printf("Error: Can not enable MEMORY access.\n"); - continue; - } -#endif - - if (!(status & PCI_COMMAND_MASTER)) { - printf("Error: Can not enable Bus Mastering.\n"); - continue; - } - - /* Check the latency timer for values >= 0x60. */ - pci_read_config_byte(devbusfn, PCI_LATENCY_TIMER, &timer); - - if (timer < 0x60) { - pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x60); - } - -#ifdef CONFIG_TULIP_USE_IO - /* read BAR for memory space access */ - pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase); - iobase &= PCI_BASE_ADDRESS_IO_MASK; -#else - /* read BAR for memory space access */ - pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &iobase); - iobase &= PCI_BASE_ADDRESS_MEM_MASK; -#endif - debug ("dc21x4x: DEC 21142 PCI Device @0x%x\n", iobase); - - dev = (struct eth_device*) malloc(sizeof *dev); - - if (!dev) { - printf("Can not allocalte memory of dc21x4x\n"); - break; - } - memset(dev, 0, sizeof(*dev)); - -#ifdef CONFIG_TULIP_FIX_DAVICOM - sprintf(dev->name, "Davicom#%d", card_number); -#else - sprintf(dev->name, "dc21x4x#%d", card_number); -#endif - -#ifdef CONFIG_TULIP_USE_IO - dev->iobase = pci_io_to_phys(devbusfn, iobase); -#else - dev->iobase = pci_mem_to_phys(devbusfn, iobase); -#endif - dev->priv = (void*) devbusfn; - dev->init = dc21x4x_init; - dev->halt = dc21x4x_halt; - dev->send = dc21x4x_send; - dev->recv = dc21x4x_recv; - - /* Ensure we're not sleeping. */ - pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP); - - udelay(10 * 1000); - -#ifndef CONFIG_TULIP_FIX_DAVICOM - read_hw_addr(dev, bis); -#endif - eth_register(dev); - - card_number++; - } - - return card_number; -} - -static int dc21x4x_init(struct eth_device* dev, bd_t* bis) -{ - int i; - int devbusfn = (int) dev->priv; - - /* Ensure we're not sleeping. */ - pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP); - -#ifdef CONFIG_TULIP_FIX_DAVICOM - RESET_DM9102(dev); -#else - RESET_DE4X5(dev); -#endif - - if ((INL(dev, DE4X5_STS) & (STS_TS | STS_RS)) != 0) { - printf("Error: Cannot reset ethernet controller.\n"); - return -1; - } - -#ifdef CONFIG_TULIP_SELECT_MEDIA - dc21x4x_select_media(dev); -#else - OUTL(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR); -#endif - - for (i = 0; i < NUM_RX_DESC; i++) { - rx_ring[i].status = cpu_to_le32(R_OWN); - rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ); - rx_ring[i].buf = cpu_to_le32(phys_to_bus((u32) NetRxPackets[i])); -#ifdef CONFIG_TULIP_FIX_DAVICOM - rx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &rx_ring[(i+1) % NUM_RX_DESC])); -#else - rx_ring[i].next = 0; -#endif - } - - for (i=0; i < NUM_TX_DESC; i++) { - tx_ring[i].status = 0; - tx_ring[i].des1 = 0; - tx_ring[i].buf = 0; - -#ifdef CONFIG_TULIP_FIX_DAVICOM - tx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &tx_ring[(i+1) % NUM_TX_DESC])); -#else - tx_ring[i].next = 0; -#endif - } - - rxRingSize = NUM_RX_DESC; - txRingSize = NUM_TX_DESC; - - /* Write the end of list marker to the descriptor lists. */ - rx_ring[rxRingSize - 1].des1 |= cpu_to_le32(RD_RER); - tx_ring[txRingSize - 1].des1 |= cpu_to_le32(TD_TER); - - /* Tell the adapter where the TX/RX rings are located. */ - OUTL(dev, phys_to_bus((u32) &rx_ring), DE4X5_RRBA); - OUTL(dev, phys_to_bus((u32) &tx_ring), DE4X5_TRBA); - - START_DE4X5(dev); - - tx_new = 0; - rx_new = 0; - - send_setup_frame(dev, bis); - - return 0; -} - -static int dc21x4x_send(struct eth_device *dev, void *packet, int length) -{ - int status = -1; - int i; - - if (length <= 0) { - printf("%s: bad packet size: %d\n", dev->name, length); - goto Done; - } - - for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { - if (i >= TOUT_LOOP) { - printf("%s: tx error buffer not ready\n", dev->name); - goto Done; - } - } - - tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32) packet)); - tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_LS | TD_FS | length); - tx_ring[tx_new].status = cpu_to_le32(T_OWN); - - OUTL(dev, POLL_DEMAND, DE4X5_TPD); - - for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { - if (i >= TOUT_LOOP) { - printf(".%s: tx buffer not ready\n", dev->name); - goto Done; - } - } - - if (le32_to_cpu(tx_ring[tx_new].status) & TD_ES) { -#if 0 /* test-only */ - printf("TX error status = 0x%08X\n", - le32_to_cpu(tx_ring[tx_new].status)); -#endif - tx_ring[tx_new].status = 0x0; - goto Done; - } - - status = length; - - Done: - tx_new = (tx_new+1) % NUM_TX_DESC; - return status; -} - -static int dc21x4x_recv(struct eth_device* dev) -{ - s32 status; - int length = 0; - - for ( ; ; ) { - status = (s32)le32_to_cpu(rx_ring[rx_new].status); - - if (status & R_OWN) { - break; - } - - if (status & RD_LS) { - /* Valid frame status. - */ - if (status & RD_ES) { - - /* There was an error. - */ - printf("RX error status = 0x%08X\n", status); - } else { - /* A valid frame received. - */ - length = (le32_to_cpu(rx_ring[rx_new].status) >> 16); - - /* Pass the packet up to the protocol - * layers. - */ - NetReceive(NetRxPackets[rx_new], length - 4); - } - - /* Change buffer ownership for this frame, back - * to the adapter. - */ - rx_ring[rx_new].status = cpu_to_le32(R_OWN); - } - - /* Update entry information. - */ - rx_new = (rx_new + 1) % rxRingSize; - } - - return length; -} - -static void dc21x4x_halt(struct eth_device* dev) -{ - int devbusfn = (int) dev->priv; - - STOP_DE4X5(dev); - OUTL(dev, 0, DE4X5_SICR); - - pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP); -} - -static void send_setup_frame(struct eth_device* dev, bd_t *bis) -{ - int i; - char setup_frame[SETUP_FRAME_LEN]; - char *pa = &setup_frame[0]; - - memset(pa, 0xff, SETUP_FRAME_LEN); - - for (i = 0; i < ETH_ALEN; i++) { - *(pa + (i & 1)) = dev->enetaddr[i]; - if (i & 0x01) { - pa += 4; - } - } - - for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { - if (i >= TOUT_LOOP) { - printf("%s: tx error buffer not ready\n", dev->name); - goto Done; - } - } - - tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32) &setup_frame[0])); - tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET| SETUP_FRAME_LEN); - tx_ring[tx_new].status = cpu_to_le32(T_OWN); - - OUTL(dev, POLL_DEMAND, DE4X5_TPD); - - for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { - if (i >= TOUT_LOOP) { - printf("%s: tx buffer not ready\n", dev->name); - goto Done; - } - } - - if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) { - printf("TX error status2 = 0x%08X\n", le32_to_cpu(tx_ring[tx_new].status)); - } - tx_new = (tx_new+1) % NUM_TX_DESC; - -Done: - return; -} - -#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM) -/* SROM Read and write routines. - */ -static void -sendto_srom(struct eth_device* dev, u_int command, u_long addr) -{ - OUTL(dev, command, addr); - udelay(1); -} - -static int -getfrom_srom(struct eth_device* dev, u_long addr) -{ - s32 tmp; - - tmp = INL(dev, addr); - udelay(1); - - return tmp; -} - -/* Note: this routine returns extra data bits for size detection. */ -static int do_read_eeprom(struct eth_device *dev, u_long ioaddr, int location, int addr_len) -{ - int i; - unsigned retval = 0; - int read_cmd = location | (SROM_READ_CMD << addr_len); - - sendto_srom(dev, SROM_RD | SROM_SR, ioaddr); - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); - -#ifdef DEBUG_SROM - printf(" EEPROM read at %d ", location); -#endif - - /* Shift the read command bits out. */ - for (i = 4 + addr_len; i >= 0; i--) { - short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval, ioaddr); - udelay(10); - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | dataval | DT_CLK, ioaddr); - udelay(10); -#ifdef DEBUG_SROM2 - printf("%X", getfrom_srom(dev, ioaddr) & 15); -#endif - retval = (retval << 1) | ((getfrom_srom(dev, ioaddr) & EE_DATA_READ) ? 1 : 0); - } - - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); - -#ifdef DEBUG_SROM2 - printf(" :%X:", getfrom_srom(dev, ioaddr) & 15); -#endif - - for (i = 16; i > 0; i--) { - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr); - udelay(10); -#ifdef DEBUG_SROM2 - printf("%X", getfrom_srom(dev, ioaddr) & 15); -#endif - retval = (retval << 1) | ((getfrom_srom(dev, ioaddr) & EE_DATA_READ) ? 1 : 0); - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); - udelay(10); - } - - /* Terminate the EEPROM access. */ - sendto_srom(dev, SROM_RD | SROM_SR, ioaddr); - -#ifdef DEBUG_SROM2 - printf(" EEPROM value at %d is %5.5x.\n", location, retval); -#endif - - return retval; -} -#endif /* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */ - -/* This executes a generic EEPROM command, typically a write or write - * enable. It returns the data output from the EEPROM, and thus may - * also be used for reads. - */ -#if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM) -static int do_eeprom_cmd(struct eth_device *dev, u_long ioaddr, int cmd, int cmd_len) -{ - unsigned retval = 0; - -#ifdef DEBUG_SROM - printf(" EEPROM op 0x%x: ", cmd); -#endif - - sendto_srom(dev,SROM_RD | SROM_SR | DT_CS | DT_CLK, ioaddr); - - /* Shift the command bits out. */ - do { - short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0; - sendto_srom(dev,dataval, ioaddr); - udelay(10); - -#ifdef DEBUG_SROM2 - printf("%X", getfrom_srom(dev,ioaddr) & 15); -#endif - - sendto_srom(dev,dataval | DT_CLK, ioaddr); - udelay(10); - retval = (retval << 1) | ((getfrom_srom(dev,ioaddr) & EE_DATA_READ) ? 1 : 0); - } while (--cmd_len >= 0); - sendto_srom(dev,SROM_RD | SROM_SR | DT_CS, ioaddr); - - /* Terminate the EEPROM access. */ - sendto_srom(dev,SROM_RD | SROM_SR, ioaddr); - -#ifdef DEBUG_SROM - printf(" EEPROM result is 0x%5.5x.\n", retval); -#endif - - return retval; -} -#endif /* UPDATE_SROM || !CONFIG_TULIP_FIX_DAVICOM */ - -#ifndef CONFIG_TULIP_FIX_DAVICOM -static int read_srom(struct eth_device *dev, u_long ioaddr, int index) -{ - int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6; - - return do_eeprom_cmd(dev, ioaddr, - (((SROM_READ_CMD << ee_addr_size) | index) << 16) - | 0xffff, 3 + ee_addr_size + 16); -} -#endif /* CONFIG_TULIP_FIX_DAVICOM */ - -#ifdef UPDATE_SROM -static int write_srom(struct eth_device *dev, u_long ioaddr, int index, int new_value) -{ - int ee_addr_size = do_read_eeprom(dev, ioaddr, 0xff, 8) & 0x40000 ? 8 : 6; - int i; - unsigned short newval; - - udelay(10*1000); /* test-only */ - -#ifdef DEBUG_SROM - printf("ee_addr_size=%d.\n", ee_addr_size); - printf("Writing new entry 0x%4.4x to offset %d.\n", new_value, index); -#endif - - /* Enable programming modes. */ - do_eeprom_cmd(dev, ioaddr, (0x4f << (ee_addr_size-4)), 3+ee_addr_size); - - /* Do the actual write. */ - do_eeprom_cmd(dev, ioaddr, - (((SROM_WRITE_CMD<<ee_addr_size)|index) << 16) | new_value, - 3 + ee_addr_size + 16); - - /* Poll for write finished. */ - sendto_srom(dev, SROM_RD | SROM_SR | DT_CS, ioaddr); - for (i = 0; i < 10000; i++) /* Typical 2000 ticks */ - if (getfrom_srom(dev, ioaddr) & EE_DATA_READ) - break; - -#ifdef DEBUG_SROM - printf(" Write finished after %d ticks.\n", i); -#endif - - /* Disable programming. */ - do_eeprom_cmd(dev, ioaddr, (0x40 << (ee_addr_size-4)), 3 + ee_addr_size); - - /* And read the result. */ - newval = do_eeprom_cmd(dev, ioaddr, - (((SROM_READ_CMD<<ee_addr_size)|index) << 16) - | 0xffff, 3 + ee_addr_size + 16); -#ifdef DEBUG_SROM - printf(" New value at offset %d is %4.4x.\n", index, newval); -#endif - return 1; -} -#endif - -#ifndef CONFIG_TULIP_FIX_DAVICOM -static void read_hw_addr(struct eth_device *dev, bd_t *bis) -{ - u_short tmp, *p = (u_short *)(&dev->enetaddr[0]); - int i, j = 0; - - for (i = 0; i < (ETH_ALEN >> 1); i++) { - tmp = read_srom(dev, DE4X5_APROM, ((SROM_HWADD >> 1) + i)); - *p = le16_to_cpu(tmp); - j += *p++; - } - - if ((j == 0) || (j == 0x2fffd)) { - memset (dev->enetaddr, 0, ETH_ALEN); - debug ("Warning: can't read HW address from SROM.\n"); - goto Done; - } - - return; - -Done: -#ifdef UPDATE_SROM - update_srom(dev, bis); -#endif - return; -} -#endif /* CONFIG_TULIP_FIX_DAVICOM */ - -#ifdef UPDATE_SROM -static void update_srom(struct eth_device *dev, bd_t *bis) -{ - int i; - static unsigned short eeprom[0x40] = { - 0x140b, 0x6610, 0x0000, 0x0000, /* 00 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 04 */ - 0x00a3, 0x0103, 0x0000, 0x0000, /* 08 */ - 0x0000, 0x1f00, 0x0000, 0x0000, /* 0c */ - 0x0108, 0x038d, 0x0000, 0x0000, /* 10 */ - 0xe078, 0x0001, 0x0040, 0x0018, /* 14 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 18 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 1c */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 20 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 2c */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 30 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 34 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 38 */ - 0x0000, 0x0000, 0x0000, 0x4e07, /* 3c */ - }; - uchar enetaddr[6]; - - /* Ethernet Addr... */ - if (!eth_getenv_enetaddr("ethaddr", enetaddr)) - return; - eeprom[0x0a] = (enetaddr[1] << 8) | enetaddr[0]; - eeprom[0x0b] = (enetaddr[3] << 8) | enetaddr[2]; - eeprom[0x0c] = (enetaddr[5] << 8) | enetaddr[4]; - - for (i=0; i<0x40; i++) { - write_srom(dev, DE4X5_APROM, i, eeprom[i]); - } -} -#endif /* UPDATE_SROM */ diff --git a/qemu/roms/u-boot/drivers/net/designware.c b/qemu/roms/u-boot/drivers/net/designware.c deleted file mode 100644 index 78751b260..000000000 --- a/qemu/roms/u-boot/drivers/net/designware.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * (C) Copyright 2010 - * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * Designware ethernet IP driver for u-boot - */ - -#include <common.h> -#include <miiphy.h> -#include <malloc.h> -#include <linux/compiler.h> -#include <linux/err.h> -#include <asm/io.h> -#include "designware.h" - -#if !defined(CONFIG_PHYLIB) -# error "DesignWare Ether MAC requires PHYLIB - missing CONFIG_PHYLIB" -#endif - -static int dw_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) -{ - struct eth_mac_regs *mac_p = bus->priv; - ulong start; - u16 miiaddr; - int timeout = CONFIG_MDIO_TIMEOUT; - - miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | - ((reg << MIIREGSHIFT) & MII_REGMSK); - - writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr); - - start = get_timer(0); - while (get_timer(start) < timeout) { - if (!(readl(&mac_p->miiaddr) & MII_BUSY)) - return readl(&mac_p->miidata); - udelay(10); - }; - - return -1; -} - -static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, - u16 val) -{ - struct eth_mac_regs *mac_p = bus->priv; - ulong start; - u16 miiaddr; - int ret = -1, timeout = CONFIG_MDIO_TIMEOUT; - - writel(val, &mac_p->miidata); - miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | - ((reg << MIIREGSHIFT) & MII_REGMSK) | MII_WRITE; - - writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr); - - start = get_timer(0); - while (get_timer(start) < timeout) { - if (!(readl(&mac_p->miiaddr) & MII_BUSY)) { - ret = 0; - break; - } - udelay(10); - }; - - return ret; -} - -static int dw_mdio_init(char *name, struct eth_mac_regs *mac_regs_p) -{ - struct mii_dev *bus = mdio_alloc(); - - if (!bus) { - printf("Failed to allocate MDIO bus\n"); - return -1; - } - - bus->read = dw_mdio_read; - bus->write = dw_mdio_write; - sprintf(bus->name, name); - - bus->priv = (void *)mac_regs_p; - - return mdio_register(bus); -} - -static void tx_descs_init(struct eth_device *dev) -{ - struct dw_eth_dev *priv = dev->priv; - struct eth_dma_regs *dma_p = priv->dma_regs_p; - struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0]; - char *txbuffs = &priv->txbuffs[0]; - struct dmamacdescr *desc_p; - u32 idx; - - for (idx = 0; idx < CONFIG_TX_DESCR_NUM; idx++) { - desc_p = &desc_table_p[idx]; - desc_p->dmamac_addr = &txbuffs[idx * CONFIG_ETH_BUFSIZE]; - desc_p->dmamac_next = &desc_table_p[idx + 1]; - -#if defined(CONFIG_DW_ALTDESCRIPTOR) - desc_p->txrx_status &= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST | - DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \ - DESC_TXSTS_TXCHECKINSCTRL | \ - DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS); - - desc_p->txrx_status |= DESC_TXSTS_TXCHAIN; - desc_p->dmamac_cntl = 0; - desc_p->txrx_status &= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA); -#else - desc_p->dmamac_cntl = DESC_TXCTRL_TXCHAIN; - desc_p->txrx_status = 0; -#endif - } - - /* Correcting the last pointer of the chain */ - desc_p->dmamac_next = &desc_table_p[0]; - - /* Flush all Tx buffer descriptors at once */ - flush_dcache_range((unsigned int)priv->tx_mac_descrtable, - (unsigned int)priv->tx_mac_descrtable + - sizeof(priv->tx_mac_descrtable)); - - writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr); - priv->tx_currdescnum = 0; -} - -static void rx_descs_init(struct eth_device *dev) -{ - struct dw_eth_dev *priv = dev->priv; - struct eth_dma_regs *dma_p = priv->dma_regs_p; - struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0]; - char *rxbuffs = &priv->rxbuffs[0]; - struct dmamacdescr *desc_p; - u32 idx; - - /* Before passing buffers to GMAC we need to make sure zeros - * written there right after "priv" structure allocation were - * flushed into RAM. - * Otherwise there's a chance to get some of them flushed in RAM when - * GMAC is already pushing data to RAM via DMA. This way incoming from - * GMAC data will be corrupted. */ - flush_dcache_range((unsigned int)rxbuffs, (unsigned int)rxbuffs + - RX_TOTAL_BUFSIZE); - - for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) { - desc_p = &desc_table_p[idx]; - desc_p->dmamac_addr = &rxbuffs[idx * CONFIG_ETH_BUFSIZE]; - desc_p->dmamac_next = &desc_table_p[idx + 1]; - - desc_p->dmamac_cntl = - (MAC_MAX_FRAME_SZ & DESC_RXCTRL_SIZE1MASK) | \ - DESC_RXCTRL_RXCHAIN; - - desc_p->txrx_status = DESC_RXSTS_OWNBYDMA; - } - - /* Correcting the last pointer of the chain */ - desc_p->dmamac_next = &desc_table_p[0]; - - /* Flush all Rx buffer descriptors at once */ - flush_dcache_range((unsigned int)priv->rx_mac_descrtable, - (unsigned int)priv->rx_mac_descrtable + - sizeof(priv->rx_mac_descrtable)); - - writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr); - priv->rx_currdescnum = 0; -} - -static int dw_write_hwaddr(struct eth_device *dev) -{ - struct dw_eth_dev *priv = dev->priv; - struct eth_mac_regs *mac_p = priv->mac_regs_p; - u32 macid_lo, macid_hi; - u8 *mac_id = &dev->enetaddr[0]; - - macid_lo = mac_id[0] + (mac_id[1] << 8) + (mac_id[2] << 16) + - (mac_id[3] << 24); - macid_hi = mac_id[4] + (mac_id[5] << 8); - - writel(macid_hi, &mac_p->macaddr0hi); - writel(macid_lo, &mac_p->macaddr0lo); - - return 0; -} - -static void dw_adjust_link(struct eth_mac_regs *mac_p, - struct phy_device *phydev) -{ - u32 conf = readl(&mac_p->conf) | FRAMEBURSTENABLE | DISABLERXOWN; - - if (!phydev->link) { - printf("%s: No link.\n", phydev->dev->name); - return; - } - - if (phydev->speed != 1000) - conf |= MII_PORTSELECT; - - if (phydev->speed == 100) - conf |= FES_100; - - if (phydev->duplex) - conf |= FULLDPLXMODE; - - writel(conf, &mac_p->conf); - - printf("Speed: %d, %s duplex%s\n", phydev->speed, - (phydev->duplex) ? "full" : "half", - (phydev->port == PORT_FIBRE) ? ", fiber mode" : ""); -} - -static void dw_eth_halt(struct eth_device *dev) -{ - struct dw_eth_dev *priv = dev->priv; - struct eth_mac_regs *mac_p = priv->mac_regs_p; - struct eth_dma_regs *dma_p = priv->dma_regs_p; - - writel(readl(&mac_p->conf) & ~(RXENABLE | TXENABLE), &mac_p->conf); - writel(readl(&dma_p->opmode) & ~(RXSTART | TXSTART), &dma_p->opmode); - - phy_shutdown(priv->phydev); -} - -static int dw_eth_init(struct eth_device *dev, bd_t *bis) -{ - struct dw_eth_dev *priv = dev->priv; - struct eth_mac_regs *mac_p = priv->mac_regs_p; - struct eth_dma_regs *dma_p = priv->dma_regs_p; - unsigned int start; - - writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode); - - start = get_timer(0); - while (readl(&dma_p->busmode) & DMAMAC_SRST) { - if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT) - return -1; - - mdelay(100); - }; - - /* Soft reset above clears HW address registers. - * So we have to set it here once again */ - dw_write_hwaddr(dev); - - rx_descs_init(dev); - tx_descs_init(dev); - - writel(FIXEDBURST | PRIORXTX_41 | BURST_16, &dma_p->busmode); - - writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD, - &dma_p->opmode); - - writel(readl(&dma_p->opmode) | RXSTART | TXSTART, &dma_p->opmode); - - /* Start up the PHY */ - if (phy_startup(priv->phydev)) { - printf("Could not initialize PHY %s\n", - priv->phydev->dev->name); - return -1; - } - - dw_adjust_link(mac_p, priv->phydev); - - if (!priv->phydev->link) - return -1; - - writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf); - - return 0; -} - -static int dw_eth_send(struct eth_device *dev, void *packet, int length) -{ - struct dw_eth_dev *priv = dev->priv; - struct eth_dma_regs *dma_p = priv->dma_regs_p; - u32 desc_num = priv->tx_currdescnum; - struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num]; - - /* Invalidate only "status" field for the following check */ - invalidate_dcache_range((unsigned long)&desc_p->txrx_status, - (unsigned long)&desc_p->txrx_status + - sizeof(desc_p->txrx_status)); - - /* Check if the descriptor is owned by CPU */ - if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) { - printf("CPU not owner of tx frame\n"); - return -1; - } - - memcpy((void *)desc_p->dmamac_addr, packet, length); - - /* Flush data to be sent */ - flush_dcache_range((unsigned long)desc_p->dmamac_addr, - (unsigned long)desc_p->dmamac_addr + length); - -#if defined(CONFIG_DW_ALTDESCRIPTOR) - desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST; - desc_p->dmamac_cntl |= (length << DESC_TXCTRL_SIZE1SHFT) & \ - DESC_TXCTRL_SIZE1MASK; - - desc_p->txrx_status &= ~(DESC_TXSTS_MSK); - desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA; -#else - desc_p->dmamac_cntl |= ((length << DESC_TXCTRL_SIZE1SHFT) & \ - DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | \ - DESC_TXCTRL_TXFIRST; - - desc_p->txrx_status = DESC_TXSTS_OWNBYDMA; -#endif - - /* Flush modified buffer descriptor */ - flush_dcache_range((unsigned long)desc_p, - (unsigned long)desc_p + sizeof(struct dmamacdescr)); - - /* Test the wrap-around condition. */ - if (++desc_num >= CONFIG_TX_DESCR_NUM) - desc_num = 0; - - priv->tx_currdescnum = desc_num; - - /* Start the transmission */ - writel(POLL_DATA, &dma_p->txpolldemand); - - return 0; -} - -static int dw_eth_recv(struct eth_device *dev) -{ - struct dw_eth_dev *priv = dev->priv; - u32 status, desc_num = priv->rx_currdescnum; - struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num]; - int length = 0; - - /* Invalidate entire buffer descriptor */ - invalidate_dcache_range((unsigned long)desc_p, - (unsigned long)desc_p + - sizeof(struct dmamacdescr)); - - status = desc_p->txrx_status; - - /* Check if the owner is the CPU */ - if (!(status & DESC_RXSTS_OWNBYDMA)) { - - length = (status & DESC_RXSTS_FRMLENMSK) >> \ - DESC_RXSTS_FRMLENSHFT; - - /* Invalidate received data */ - invalidate_dcache_range((unsigned long)desc_p->dmamac_addr, - (unsigned long)desc_p->dmamac_addr + - length); - - NetReceive(desc_p->dmamac_addr, length); - - /* - * Make the current descriptor valid again and go to - * the next one - */ - desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA; - - /* Flush only status field - others weren't changed */ - flush_dcache_range((unsigned long)&desc_p->txrx_status, - (unsigned long)&desc_p->txrx_status + - sizeof(desc_p->txrx_status)); - - /* Test the wrap-around condition. */ - if (++desc_num >= CONFIG_RX_DESCR_NUM) - desc_num = 0; - } - - priv->rx_currdescnum = desc_num; - - return length; -} - -static int dw_phy_init(struct eth_device *dev) -{ - struct dw_eth_dev *priv = dev->priv; - struct phy_device *phydev; - int mask = 0xffffffff; - -#ifdef CONFIG_PHY_ADDR - mask = 1 << CONFIG_PHY_ADDR; -#endif - - phydev = phy_find_by_mask(priv->bus, mask, priv->interface); - if (!phydev) - return -1; - - phy_connect_dev(phydev, dev); - - phydev->supported &= PHY_GBIT_FEATURES; - phydev->advertising = phydev->supported; - - priv->phydev = phydev; - phy_config(phydev); - - return 1; -} - -int designware_initialize(ulong base_addr, u32 interface) -{ - struct eth_device *dev; - struct dw_eth_dev *priv; - - dev = (struct eth_device *) malloc(sizeof(struct eth_device)); - if (!dev) - return -ENOMEM; - - /* - * Since the priv structure contains the descriptors which need a strict - * buswidth alignment, memalign is used to allocate memory - */ - priv = (struct dw_eth_dev *) memalign(16, sizeof(struct dw_eth_dev)); - if (!priv) { - free(dev); - return -ENOMEM; - } - - memset(dev, 0, sizeof(struct eth_device)); - memset(priv, 0, sizeof(struct dw_eth_dev)); - - sprintf(dev->name, "dwmac.%lx", base_addr); - dev->iobase = (int)base_addr; - dev->priv = priv; - - priv->dev = dev; - priv->mac_regs_p = (struct eth_mac_regs *)base_addr; - priv->dma_regs_p = (struct eth_dma_regs *)(base_addr + - DW_DMA_BASE_OFFSET); - - dev->init = dw_eth_init; - dev->send = dw_eth_send; - dev->recv = dw_eth_recv; - dev->halt = dw_eth_halt; - dev->write_hwaddr = dw_write_hwaddr; - - eth_register(dev); - - priv->interface = interface; - - dw_mdio_init(dev->name, priv->mac_regs_p); - priv->bus = miiphy_get_dev_by_name(dev->name); - - return dw_phy_init(dev); -} diff --git a/qemu/roms/u-boot/drivers/net/designware.h b/qemu/roms/u-boot/drivers/net/designware.h deleted file mode 100644 index 382b0c7f0..000000000 --- a/qemu/roms/u-boot/drivers/net/designware.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * (C) Copyright 2010 - * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _DW_ETH_H -#define _DW_ETH_H - -#define CONFIG_TX_DESCR_NUM 16 -#define CONFIG_RX_DESCR_NUM 16 -#define CONFIG_ETH_BUFSIZE 2048 -#define TX_TOTAL_BUFSIZE (CONFIG_ETH_BUFSIZE * CONFIG_TX_DESCR_NUM) -#define RX_TOTAL_BUFSIZE (CONFIG_ETH_BUFSIZE * CONFIG_RX_DESCR_NUM) - -#define CONFIG_MACRESET_TIMEOUT (3 * CONFIG_SYS_HZ) -#define CONFIG_MDIO_TIMEOUT (3 * CONFIG_SYS_HZ) - -struct eth_mac_regs { - u32 conf; /* 0x00 */ - u32 framefilt; /* 0x04 */ - u32 hashtablehigh; /* 0x08 */ - u32 hashtablelow; /* 0x0c */ - u32 miiaddr; /* 0x10 */ - u32 miidata; /* 0x14 */ - u32 flowcontrol; /* 0x18 */ - u32 vlantag; /* 0x1c */ - u32 version; /* 0x20 */ - u8 reserved_1[20]; - u32 intreg; /* 0x38 */ - u32 intmask; /* 0x3c */ - u32 macaddr0hi; /* 0x40 */ - u32 macaddr0lo; /* 0x44 */ -}; - -/* MAC configuration register definitions */ -#define FRAMEBURSTENABLE (1 << 21) -#define MII_PORTSELECT (1 << 15) -#define FES_100 (1 << 14) -#define DISABLERXOWN (1 << 13) -#define FULLDPLXMODE (1 << 11) -#define RXENABLE (1 << 2) -#define TXENABLE (1 << 3) - -/* MII address register definitions */ -#define MII_BUSY (1 << 0) -#define MII_WRITE (1 << 1) -#define MII_CLKRANGE_60_100M (0) -#define MII_CLKRANGE_100_150M (0x4) -#define MII_CLKRANGE_20_35M (0x8) -#define MII_CLKRANGE_35_60M (0xC) -#define MII_CLKRANGE_150_250M (0x10) -#define MII_CLKRANGE_250_300M (0x14) - -#define MIIADDRSHIFT (11) -#define MIIREGSHIFT (6) -#define MII_REGMSK (0x1F << 6) -#define MII_ADDRMSK (0x1F << 11) - - -struct eth_dma_regs { - u32 busmode; /* 0x00 */ - u32 txpolldemand; /* 0x04 */ - u32 rxpolldemand; /* 0x08 */ - u32 rxdesclistaddr; /* 0x0c */ - u32 txdesclistaddr; /* 0x10 */ - u32 status; /* 0x14 */ - u32 opmode; /* 0x18 */ - u32 intenable; /* 0x1c */ - u8 reserved[40]; - u32 currhosttxdesc; /* 0x48 */ - u32 currhostrxdesc; /* 0x4c */ - u32 currhosttxbuffaddr; /* 0x50 */ - u32 currhostrxbuffaddr; /* 0x54 */ -}; - -#define DW_DMA_BASE_OFFSET (0x1000) - -/* Bus mode register definitions */ -#define FIXEDBURST (1 << 16) -#define PRIORXTX_41 (3 << 14) -#define PRIORXTX_31 (2 << 14) -#define PRIORXTX_21 (1 << 14) -#define PRIORXTX_11 (0 << 14) -#define BURST_1 (1 << 8) -#define BURST_2 (2 << 8) -#define BURST_4 (4 << 8) -#define BURST_8 (8 << 8) -#define BURST_16 (16 << 8) -#define BURST_32 (32 << 8) -#define RXHIGHPRIO (1 << 1) -#define DMAMAC_SRST (1 << 0) - -/* Poll demand definitions */ -#define POLL_DATA (0xFFFFFFFF) - -/* Operation mode definitions */ -#define STOREFORWARD (1 << 21) -#define FLUSHTXFIFO (1 << 20) -#define TXSTART (1 << 13) -#define TXSECONDFRAME (1 << 2) -#define RXSTART (1 << 1) - -/* Descriptior related definitions */ -#define MAC_MAX_FRAME_SZ (1600) - -struct dmamacdescr { - u32 txrx_status; - u32 dmamac_cntl; - void *dmamac_addr; - struct dmamacdescr *dmamac_next; -} __aligned(ARCH_DMA_MINALIGN); - -/* - * txrx_status definitions - */ - -/* tx status bits definitions */ -#if defined(CONFIG_DW_ALTDESCRIPTOR) - -#define DESC_TXSTS_OWNBYDMA (1 << 31) -#define DESC_TXSTS_TXINT (1 << 30) -#define DESC_TXSTS_TXLAST (1 << 29) -#define DESC_TXSTS_TXFIRST (1 << 28) -#define DESC_TXSTS_TXCRCDIS (1 << 27) - -#define DESC_TXSTS_TXPADDIS (1 << 26) -#define DESC_TXSTS_TXCHECKINSCTRL (3 << 22) -#define DESC_TXSTS_TXRINGEND (1 << 21) -#define DESC_TXSTS_TXCHAIN (1 << 20) -#define DESC_TXSTS_MSK (0x1FFFF << 0) - -#else - -#define DESC_TXSTS_OWNBYDMA (1 << 31) -#define DESC_TXSTS_MSK (0x1FFFF << 0) - -#endif - -/* rx status bits definitions */ -#define DESC_RXSTS_OWNBYDMA (1 << 31) -#define DESC_RXSTS_DAFILTERFAIL (1 << 30) -#define DESC_RXSTS_FRMLENMSK (0x3FFF << 16) -#define DESC_RXSTS_FRMLENSHFT (16) - -#define DESC_RXSTS_ERROR (1 << 15) -#define DESC_RXSTS_RXTRUNCATED (1 << 14) -#define DESC_RXSTS_SAFILTERFAIL (1 << 13) -#define DESC_RXSTS_RXIPC_GIANTFRAME (1 << 12) -#define DESC_RXSTS_RXDAMAGED (1 << 11) -#define DESC_RXSTS_RXVLANTAG (1 << 10) -#define DESC_RXSTS_RXFIRST (1 << 9) -#define DESC_RXSTS_RXLAST (1 << 8) -#define DESC_RXSTS_RXIPC_GIANT (1 << 7) -#define DESC_RXSTS_RXCOLLISION (1 << 6) -#define DESC_RXSTS_RXFRAMEETHER (1 << 5) -#define DESC_RXSTS_RXWATCHDOG (1 << 4) -#define DESC_RXSTS_RXMIIERROR (1 << 3) -#define DESC_RXSTS_RXDRIBBLING (1 << 2) -#define DESC_RXSTS_RXCRC (1 << 1) - -/* - * dmamac_cntl definitions - */ - -/* tx control bits definitions */ -#if defined(CONFIG_DW_ALTDESCRIPTOR) - -#define DESC_TXCTRL_SIZE1MASK (0x1FFF << 0) -#define DESC_TXCTRL_SIZE1SHFT (0) -#define DESC_TXCTRL_SIZE2MASK (0x1FFF << 16) -#define DESC_TXCTRL_SIZE2SHFT (16) - -#else - -#define DESC_TXCTRL_TXINT (1 << 31) -#define DESC_TXCTRL_TXLAST (1 << 30) -#define DESC_TXCTRL_TXFIRST (1 << 29) -#define DESC_TXCTRL_TXCHECKINSCTRL (3 << 27) -#define DESC_TXCTRL_TXCRCDIS (1 << 26) -#define DESC_TXCTRL_TXRINGEND (1 << 25) -#define DESC_TXCTRL_TXCHAIN (1 << 24) - -#define DESC_TXCTRL_SIZE1MASK (0x7FF << 0) -#define DESC_TXCTRL_SIZE1SHFT (0) -#define DESC_TXCTRL_SIZE2MASK (0x7FF << 11) -#define DESC_TXCTRL_SIZE2SHFT (11) - -#endif - -/* rx control bits definitions */ -#if defined(CONFIG_DW_ALTDESCRIPTOR) - -#define DESC_RXCTRL_RXINTDIS (1 << 31) -#define DESC_RXCTRL_RXRINGEND (1 << 15) -#define DESC_RXCTRL_RXCHAIN (1 << 14) - -#define DESC_RXCTRL_SIZE1MASK (0x1FFF << 0) -#define DESC_RXCTRL_SIZE1SHFT (0) -#define DESC_RXCTRL_SIZE2MASK (0x1FFF << 16) -#define DESC_RXCTRL_SIZE2SHFT (16) - -#else - -#define DESC_RXCTRL_RXINTDIS (1 << 31) -#define DESC_RXCTRL_RXRINGEND (1 << 25) -#define DESC_RXCTRL_RXCHAIN (1 << 24) - -#define DESC_RXCTRL_SIZE1MASK (0x7FF << 0) -#define DESC_RXCTRL_SIZE1SHFT (0) -#define DESC_RXCTRL_SIZE2MASK (0x7FF << 11) -#define DESC_RXCTRL_SIZE2SHFT (11) - -#endif - -struct dw_eth_dev { - u32 interface; - u32 tx_currdescnum; - u32 rx_currdescnum; - - struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM]; - struct dmamacdescr rx_mac_descrtable[CONFIG_RX_DESCR_NUM]; - - char txbuffs[TX_TOTAL_BUFSIZE]; - char rxbuffs[RX_TOTAL_BUFSIZE]; - - struct eth_mac_regs *mac_regs_p; - struct eth_dma_regs *dma_regs_p; - - struct eth_device *dev; - struct phy_device *phydev; - struct mii_dev *bus; -}; - -#endif diff --git a/qemu/roms/u-boot/drivers/net/dm9000x.c b/qemu/roms/u-boot/drivers/net/dm9000x.c deleted file mode 100644 index 4de9d4164..000000000 --- a/qemu/roms/u-boot/drivers/net/dm9000x.c +++ /dev/null @@ -1,643 +0,0 @@ -/* - dm9000.c: Version 1.2 12/15/2003 - - A Davicom DM9000 ISA NIC fast Ethernet driver for Linux. - Copyright (C) 1997 Sten Wang - - * SPDX-License-Identifier: GPL-2.0+ - - (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved. - -V0.11 06/20/2001 REG_0A bit3=1, default enable BP with DA match - 06/22/2001 Support DM9801 progrmming - E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000 - E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200 - R17 = (R17 & 0xfff0) | NF + 3 - E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200 - R17 = (R17 & 0xfff0) | NF - -v1.00 modify by simon 2001.9.5 - change for kernel 2.4.x - -v1.1 11/09/2001 fix force mode bug - -v1.2 03/18/2003 Weilun Huang <weilun_huang@davicom.com.tw>: - Fixed phy reset. - Added tx/rx 32 bit mode. - Cleaned up for kernel merge. - --------------------------------------- - - 12/15/2003 Initial port to u-boot by - Sascha Hauer <saschahauer@web.de> - - 06/03/2008 Remy Bohmer <linux@bohmer.net> - - Fixed the driver to work with DM9000A. - (check on ISR receive status bit before reading the - FIFO as described in DM9000 programming guide and - application notes) - - Added autodetect of databus width. - - Made debug code compile again. - - Adapt eth_send such that it matches the DM9000* - application notes. Needed to make it work properly - for DM9000A. - - Adapted reset procedure to match DM9000 application - notes (i.e. double reset) - - some minor code cleanups - These changes are tested with DM9000{A,EP,E} together - with a 200MHz Atmel AT91SAM9261 core - -TODO: external MII is not functional, only internal at the moment. -*/ - -#include <common.h> -#include <command.h> -#include <net.h> -#include <asm/io.h> -#include <dm9000.h> - -#include "dm9000x.h" - -/* Board/System/Debug information/definition ---------------- */ - -/* #define CONFIG_DM9000_DEBUG */ - -#ifdef CONFIG_DM9000_DEBUG -#define DM9000_DBG(fmt,args...) printf(fmt, ##args) -#define DM9000_DMP_PACKET(func,packet,length) \ - do { \ - int i; \ - printf("%s: length: %d\n", func, length); \ - for (i = 0; i < length; i++) { \ - if (i % 8 == 0) \ - printf("\n%s: %02x: ", func, i); \ - printf("%02x ", ((unsigned char *) packet)[i]); \ - } printf("\n"); \ - } while(0) -#else -#define DM9000_DBG(fmt,args...) -#define DM9000_DMP_PACKET(func,packet,length) -#endif - -/* Structure/enum declaration ------------------------------- */ -typedef struct board_info { - u32 runt_length_counter; /* counter: RX length < 64byte */ - u32 long_length_counter; /* counter: RX length > 1514byte */ - u32 reset_counter; /* counter: RESET */ - u32 reset_tx_timeout; /* RESET caused by TX Timeout */ - u32 reset_rx_status; /* RESET caused by RX Statsus wrong */ - u16 tx_pkt_cnt; - u16 queue_start_addr; - u16 dbug_cnt; - u8 phy_addr; - u8 device_wait_reset; /* device state */ - unsigned char srom[128]; - void (*outblk)(volatile void *data_ptr, int count); - void (*inblk)(void *data_ptr, int count); - void (*rx_status)(u16 *RxStatus, u16 *RxLen); - struct eth_device netdev; -} board_info_t; -static board_info_t dm9000_info; - - -/* function declaration ------------------------------------- */ -static int dm9000_probe(void); -static u16 dm9000_phy_read(int); -static void dm9000_phy_write(int, u16); -static u8 DM9000_ior(int); -static void DM9000_iow(int reg, u8 value); - -/* DM9000 network board routine ---------------------------- */ -#ifndef CONFIG_DM9000_BYTE_SWAPPED -#define DM9000_outb(d,r) writeb(d, (volatile u8 *)(r)) -#define DM9000_outw(d,r) writew(d, (volatile u16 *)(r)) -#define DM9000_outl(d,r) writel(d, (volatile u32 *)(r)) -#define DM9000_inb(r) readb((volatile u8 *)(r)) -#define DM9000_inw(r) readw((volatile u16 *)(r)) -#define DM9000_inl(r) readl((volatile u32 *)(r)) -#else -#define DM9000_outb(d, r) __raw_writeb(d, r) -#define DM9000_outw(d, r) __raw_writew(d, r) -#define DM9000_outl(d, r) __raw_writel(d, r) -#define DM9000_inb(r) __raw_readb(r) -#define DM9000_inw(r) __raw_readw(r) -#define DM9000_inl(r) __raw_readl(r) -#endif - -#ifdef CONFIG_DM9000_DEBUG -static void -dump_regs(void) -{ - DM9000_DBG("\n"); - DM9000_DBG("NCR (0x00): %02x\n", DM9000_ior(0)); - DM9000_DBG("NSR (0x01): %02x\n", DM9000_ior(1)); - DM9000_DBG("TCR (0x02): %02x\n", DM9000_ior(2)); - DM9000_DBG("TSRI (0x03): %02x\n", DM9000_ior(3)); - DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4)); - DM9000_DBG("RCR (0x05): %02x\n", DM9000_ior(5)); - DM9000_DBG("RSR (0x06): %02x\n", DM9000_ior(6)); - DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(DM9000_ISR)); - DM9000_DBG("\n"); -} -#endif - -static void dm9000_outblk_8bit(volatile void *data_ptr, int count) -{ - int i; - for (i = 0; i < count; i++) - DM9000_outb((((u8 *) data_ptr)[i] & 0xff), DM9000_DATA); -} - -static void dm9000_outblk_16bit(volatile void *data_ptr, int count) -{ - int i; - u32 tmplen = (count + 1) / 2; - - for (i = 0; i < tmplen; i++) - DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA); -} -static void dm9000_outblk_32bit(volatile void *data_ptr, int count) -{ - int i; - u32 tmplen = (count + 3) / 4; - - for (i = 0; i < tmplen; i++) - DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA); -} - -static void dm9000_inblk_8bit(void *data_ptr, int count) -{ - int i; - for (i = 0; i < count; i++) - ((u8 *) data_ptr)[i] = DM9000_inb(DM9000_DATA); -} - -static void dm9000_inblk_16bit(void *data_ptr, int count) -{ - int i; - u32 tmplen = (count + 1) / 2; - - for (i = 0; i < tmplen; i++) - ((u16 *) data_ptr)[i] = DM9000_inw(DM9000_DATA); -} -static void dm9000_inblk_32bit(void *data_ptr, int count) -{ - int i; - u32 tmplen = (count + 3) / 4; - - for (i = 0; i < tmplen; i++) - ((u32 *) data_ptr)[i] = DM9000_inl(DM9000_DATA); -} - -static void dm9000_rx_status_32bit(u16 *RxStatus, u16 *RxLen) -{ - u32 tmpdata; - - DM9000_outb(DM9000_MRCMD, DM9000_IO); - - tmpdata = DM9000_inl(DM9000_DATA); - *RxStatus = __le16_to_cpu(tmpdata); - *RxLen = __le16_to_cpu(tmpdata >> 16); -} - -static void dm9000_rx_status_16bit(u16 *RxStatus, u16 *RxLen) -{ - DM9000_outb(DM9000_MRCMD, DM9000_IO); - - *RxStatus = __le16_to_cpu(DM9000_inw(DM9000_DATA)); - *RxLen = __le16_to_cpu(DM9000_inw(DM9000_DATA)); -} - -static void dm9000_rx_status_8bit(u16 *RxStatus, u16 *RxLen) -{ - DM9000_outb(DM9000_MRCMD, DM9000_IO); - - *RxStatus = - __le16_to_cpu(DM9000_inb(DM9000_DATA) + - (DM9000_inb(DM9000_DATA) << 8)); - *RxLen = - __le16_to_cpu(DM9000_inb(DM9000_DATA) + - (DM9000_inb(DM9000_DATA) << 8)); -} - -/* - Search DM9000 board, allocate space and register it -*/ -int -dm9000_probe(void) -{ - u32 id_val; - id_val = DM9000_ior(DM9000_VIDL); - id_val |= DM9000_ior(DM9000_VIDH) << 8; - id_val |= DM9000_ior(DM9000_PIDL) << 16; - id_val |= DM9000_ior(DM9000_PIDH) << 24; - if (id_val == DM9000_ID) { - printf("dm9000 i/o: 0x%x, id: 0x%x \n", CONFIG_DM9000_BASE, - id_val); - return 0; - } else { - printf("dm9000 not found at 0x%08x id: 0x%08x\n", - CONFIG_DM9000_BASE, id_val); - return -1; - } -} - -/* General Purpose dm9000 reset routine */ -static void -dm9000_reset(void) -{ - DM9000_DBG("resetting DM9000\n"); - - /* Reset DM9000, - see DM9000 Application Notes V1.22 Jun 11, 2004 page 29 */ - - /* DEBUG: Make all GPIO0 outputs, all others inputs */ - DM9000_iow(DM9000_GPCR, GPCR_GPIO0_OUT); - /* Step 1: Power internal PHY by writing 0 to GPIO0 pin */ - DM9000_iow(DM9000_GPR, 0); - /* Step 2: Software reset */ - DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); - - do { - DM9000_DBG("resetting the DM9000, 1st reset\n"); - udelay(25); /* Wait at least 20 us */ - } while (DM9000_ior(DM9000_NCR) & 1); - - DM9000_iow(DM9000_NCR, 0); - DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); /* Issue a second reset */ - - do { - DM9000_DBG("resetting the DM9000, 2nd reset\n"); - udelay(25); /* Wait at least 20 us */ - } while (DM9000_ior(DM9000_NCR) & 1); - - /* Check whether the ethernet controller is present */ - if ((DM9000_ior(DM9000_PIDL) != 0x0) || - (DM9000_ior(DM9000_PIDH) != 0x90)) - printf("ERROR: resetting DM9000 -> not responding\n"); -} - -/* Initialize dm9000 board -*/ -static int dm9000_init(struct eth_device *dev, bd_t *bd) -{ - int i, oft, lnk; - u8 io_mode; - struct board_info *db = &dm9000_info; - - DM9000_DBG("%s\n", __func__); - - /* RESET device */ - dm9000_reset(); - - if (dm9000_probe() < 0) - return -1; - - /* Auto-detect 8/16/32 bit mode, ISR Bit 6+7 indicate bus width */ - io_mode = DM9000_ior(DM9000_ISR) >> 6; - - switch (io_mode) { - case 0x0: /* 16-bit mode */ - printf("DM9000: running in 16 bit mode\n"); - db->outblk = dm9000_outblk_16bit; - db->inblk = dm9000_inblk_16bit; - db->rx_status = dm9000_rx_status_16bit; - break; - case 0x01: /* 32-bit mode */ - printf("DM9000: running in 32 bit mode\n"); - db->outblk = dm9000_outblk_32bit; - db->inblk = dm9000_inblk_32bit; - db->rx_status = dm9000_rx_status_32bit; - break; - case 0x02: /* 8 bit mode */ - printf("DM9000: running in 8 bit mode\n"); - db->outblk = dm9000_outblk_8bit; - db->inblk = dm9000_inblk_8bit; - db->rx_status = dm9000_rx_status_8bit; - break; - default: - /* Assume 8 bit mode, will probably not work anyway */ - printf("DM9000: Undefined IO-mode:0x%x\n", io_mode); - db->outblk = dm9000_outblk_8bit; - db->inblk = dm9000_inblk_8bit; - db->rx_status = dm9000_rx_status_8bit; - break; - } - - /* Program operating register, only internal phy supported */ - DM9000_iow(DM9000_NCR, 0x0); - /* TX Polling clear */ - DM9000_iow(DM9000_TCR, 0); - /* Less 3Kb, 200us */ - DM9000_iow(DM9000_BPTR, BPTR_BPHW(3) | BPTR_JPT_600US); - /* Flow Control : High/Low Water */ - DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8)); - /* SH FIXME: This looks strange! Flow Control */ - DM9000_iow(DM9000_FCR, 0x0); - /* Special Mode */ - DM9000_iow(DM9000_SMCR, 0); - /* clear TX status */ - DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); - /* Clear interrupt status */ - DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS); - - printf("MAC: %pM\n", dev->enetaddr); - if (!is_valid_ether_addr(dev->enetaddr)) { -#ifdef CONFIG_RANDOM_MACADDR - printf("Bad MAC address (uninitialized EEPROM?), randomizing\n"); - eth_random_addr(dev->enetaddr); - printf("MAC: %pM\n", dev->enetaddr); -#else - printf("WARNING: Bad MAC address (uninitialized EEPROM?)\n"); -#endif - } - - /* fill device MAC address registers */ - for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++) - DM9000_iow(oft, dev->enetaddr[i]); - for (i = 0, oft = 0x16; i < 8; i++, oft++) - DM9000_iow(oft, 0xff); - - /* read back mac, just to be sure */ - for (i = 0, oft = 0x10; i < 6; i++, oft++) - DM9000_DBG("%02x:", DM9000_ior(oft)); - DM9000_DBG("\n"); - - /* Activate DM9000 */ - /* RX enable */ - DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); - /* Enable TX/RX interrupt mask */ - DM9000_iow(DM9000_IMR, IMR_PAR); - - i = 0; - while (!(dm9000_phy_read(1) & 0x20)) { /* autonegation complete bit */ - udelay(1000); - i++; - if (i == 10000) { - printf("could not establish link\n"); - return 0; - } - } - - /* see what we've got */ - lnk = dm9000_phy_read(17) >> 12; - printf("operating at "); - switch (lnk) { - case 1: - printf("10M half duplex "); - break; - case 2: - printf("10M full duplex "); - break; - case 4: - printf("100M half duplex "); - break; - case 8: - printf("100M full duplex "); - break; - default: - printf("unknown: %d ", lnk); - break; - } - printf("mode\n"); - return 0; -} - -/* - Hardware start transmission. - Send a packet to media from the upper layer. -*/ -static int dm9000_send(struct eth_device *netdev, void *packet, int length) -{ - int tmo; - struct board_info *db = &dm9000_info; - - DM9000_DMP_PACKET(__func__ , packet, length); - - DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */ - - /* Move data to DM9000 TX RAM */ - DM9000_outb(DM9000_MWCMD, DM9000_IO); /* Prepare for TX-data */ - - /* push the data to the TX-fifo */ - (db->outblk)(packet, length); - - /* Set TX length to DM9000 */ - DM9000_iow(DM9000_TXPLL, length & 0xff); - DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff); - - /* Issue TX polling command */ - DM9000_iow(DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */ - - /* wait for end of transmission */ - tmo = get_timer(0) + 5 * CONFIG_SYS_HZ; - while ( !(DM9000_ior(DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) || - !(DM9000_ior(DM9000_ISR) & IMR_PTM) ) { - if (get_timer(0) >= tmo) { - printf("transmission timeout\n"); - break; - } - } - DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */ - - DM9000_DBG("transmit done\n\n"); - return 0; -} - -/* - Stop the interface. - The interface is stopped when it is brought. -*/ -static void dm9000_halt(struct eth_device *netdev) -{ - DM9000_DBG("%s\n", __func__); - - /* RESET devie */ - dm9000_phy_write(0, 0x8000); /* PHY RESET */ - DM9000_iow(DM9000_GPR, 0x01); /* Power-Down PHY */ - DM9000_iow(DM9000_IMR, 0x80); /* Disable all interrupt */ - DM9000_iow(DM9000_RCR, 0x00); /* Disable RX */ -} - -/* - Received a packet and pass to upper layer -*/ -static int dm9000_rx(struct eth_device *netdev) -{ - u8 rxbyte, *rdptr = (u8 *) NetRxPackets[0]; - u16 RxStatus, RxLen = 0; - struct board_info *db = &dm9000_info; - - /* Check packet ready or not, we must check - the ISR status first for DM9000A */ - if (!(DM9000_ior(DM9000_ISR) & 0x01)) /* Rx-ISR bit must be set. */ - return 0; - - DM9000_iow(DM9000_ISR, 0x01); /* clear PR status latched in bit 0 */ - - /* There is _at least_ 1 package in the fifo, read them all */ - for (;;) { - DM9000_ior(DM9000_MRCMDX); /* Dummy read */ - - /* Get most updated data, - only look at bits 0:1, See application notes DM9000 */ - rxbyte = DM9000_inb(DM9000_DATA) & 0x03; - - /* Status check: this byte must be 0 or 1 */ - if (rxbyte > DM9000_PKT_RDY) { - DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */ - DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */ - printf("DM9000 error: status check fail: 0x%x\n", - rxbyte); - return 0; - } - - if (rxbyte != DM9000_PKT_RDY) - return 0; /* No packet received, ignore */ - - DM9000_DBG("receiving packet\n"); - - /* A packet ready now & Get status/length */ - (db->rx_status)(&RxStatus, &RxLen); - - DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen); - - /* Move data from DM9000 */ - /* Read received packet from RX SRAM */ - (db->inblk)(rdptr, RxLen); - - if ((RxStatus & 0xbf00) || (RxLen < 0x40) - || (RxLen > DM9000_PKT_MAX)) { - if (RxStatus & 0x100) { - printf("rx fifo error\n"); - } - if (RxStatus & 0x200) { - printf("rx crc error\n"); - } - if (RxStatus & 0x8000) { - printf("rx length error\n"); - } - if (RxLen > DM9000_PKT_MAX) { - printf("rx length too big\n"); - dm9000_reset(); - } - } else { - DM9000_DMP_PACKET(__func__ , rdptr, RxLen); - - DM9000_DBG("passing packet to upper layer\n"); - NetReceive(NetRxPackets[0], RxLen); - } - } - return 0; -} - -/* - Read a word data from SROM -*/ -#if !defined(CONFIG_DM9000_NO_SROM) -void dm9000_read_srom_word(int offset, u8 *to) -{ - DM9000_iow(DM9000_EPAR, offset); - DM9000_iow(DM9000_EPCR, 0x4); - udelay(8000); - DM9000_iow(DM9000_EPCR, 0x0); - to[0] = DM9000_ior(DM9000_EPDRL); - to[1] = DM9000_ior(DM9000_EPDRH); -} - -void dm9000_write_srom_word(int offset, u16 val) -{ - DM9000_iow(DM9000_EPAR, offset); - DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff)); - DM9000_iow(DM9000_EPDRL, (val & 0xff)); - DM9000_iow(DM9000_EPCR, 0x12); - udelay(8000); - DM9000_iow(DM9000_EPCR, 0); -} -#endif - -static void dm9000_get_enetaddr(struct eth_device *dev) -{ -#if !defined(CONFIG_DM9000_NO_SROM) - int i; - for (i = 0; i < 3; i++) - dm9000_read_srom_word(i, dev->enetaddr + (2 * i)); -#endif -} - -/* - Read a byte from I/O port -*/ -static u8 -DM9000_ior(int reg) -{ - DM9000_outb(reg, DM9000_IO); - return DM9000_inb(DM9000_DATA); -} - -/* - Write a byte to I/O port -*/ -static void -DM9000_iow(int reg, u8 value) -{ - DM9000_outb(reg, DM9000_IO); - DM9000_outb(value, DM9000_DATA); -} - -/* - Read a word from phyxcer -*/ -static u16 -dm9000_phy_read(int reg) -{ - u16 val; - - /* Fill the phyxcer register into REG_0C */ - DM9000_iow(DM9000_EPAR, DM9000_PHY | reg); - DM9000_iow(DM9000_EPCR, 0xc); /* Issue phyxcer read command */ - udelay(100); /* Wait read complete */ - DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer read command */ - val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL); - - /* The read data keeps on REG_0D & REG_0E */ - DM9000_DBG("dm9000_phy_read(0x%x): 0x%x\n", reg, val); - return val; -} - -/* - Write a word to phyxcer -*/ -static void -dm9000_phy_write(int reg, u16 value) -{ - - /* Fill the phyxcer register into REG_0C */ - DM9000_iow(DM9000_EPAR, DM9000_PHY | reg); - - /* Fill the written data into REG_0D & REG_0E */ - DM9000_iow(DM9000_EPDRL, (value & 0xff)); - DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff)); - DM9000_iow(DM9000_EPCR, 0xa); /* Issue phyxcer write command */ - udelay(500); /* Wait write complete */ - DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer write command */ - DM9000_DBG("dm9000_phy_write(reg:0x%x, value:0x%x)\n", reg, value); -} - -int dm9000_initialize(bd_t *bis) -{ - struct eth_device *dev = &(dm9000_info.netdev); - - /* Load MAC address from EEPROM */ - dm9000_get_enetaddr(dev); - - dev->init = dm9000_init; - dev->halt = dm9000_halt; - dev->send = dm9000_send; - dev->recv = dm9000_rx; - sprintf(dev->name, "dm9000"); - - eth_register(dev); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/dm9000x.h b/qemu/roms/u-boot/drivers/net/dm9000x.h deleted file mode 100644 index 0d123e2e1..000000000 --- a/qemu/roms/u-boot/drivers/net/dm9000x.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * dm9000 Ethernet - */ - -#ifdef CONFIG_DRIVER_DM9000 - -#define DM9000_ID 0x90000A46 -#define DM9000_PKT_MAX 1536 /* Received packet max size */ -#define DM9000_PKT_RDY 0x01 /* Packet ready to receive */ - -/* although the registers are 16 bit, they are 32-bit aligned. - */ - -#define DM9000_NCR 0x00 -#define DM9000_NSR 0x01 -#define DM9000_TCR 0x02 -#define DM9000_TSR1 0x03 -#define DM9000_TSR2 0x04 -#define DM9000_RCR 0x05 -#define DM9000_RSR 0x06 -#define DM9000_ROCR 0x07 -#define DM9000_BPTR 0x08 -#define DM9000_FCTR 0x09 -#define DM9000_FCR 0x0A -#define DM9000_EPCR 0x0B -#define DM9000_EPAR 0x0C -#define DM9000_EPDRL 0x0D -#define DM9000_EPDRH 0x0E -#define DM9000_WCR 0x0F - -#define DM9000_PAR 0x10 -#define DM9000_MAR 0x16 - -#define DM9000_GPCR 0x1e -#define DM9000_GPR 0x1f -#define DM9000_TRPAL 0x22 -#define DM9000_TRPAH 0x23 -#define DM9000_RWPAL 0x24 -#define DM9000_RWPAH 0x25 - -#define DM9000_VIDL 0x28 -#define DM9000_VIDH 0x29 -#define DM9000_PIDL 0x2A -#define DM9000_PIDH 0x2B - -#define DM9000_CHIPR 0x2C -#define DM9000_SMCR 0x2F - -#define DM9000_PHY 0x40 /* PHY address 0x01 */ - -#define DM9000_MRCMDX 0xF0 -#define DM9000_MRCMD 0xF2 -#define DM9000_MRRL 0xF4 -#define DM9000_MRRH 0xF5 -#define DM9000_MWCMDX 0xF6 -#define DM9000_MWCMD 0xF8 -#define DM9000_MWRL 0xFA -#define DM9000_MWRH 0xFB -#define DM9000_TXPLL 0xFC -#define DM9000_TXPLH 0xFD -#define DM9000_ISR 0xFE -#define DM9000_IMR 0xFF - -#define NCR_EXT_PHY (1<<7) -#define NCR_WAKEEN (1<<6) -#define NCR_FCOL (1<<4) -#define NCR_FDX (1<<3) -#define NCR_LBK (3<<1) -#define NCR_LBK_INT_MAC (1<<1) -#define NCR_LBK_INT_PHY (2<<1) -#define NCR_RST (1<<0) - -#define NSR_SPEED (1<<7) -#define NSR_LINKST (1<<6) -#define NSR_WAKEST (1<<5) -#define NSR_TX2END (1<<3) -#define NSR_TX1END (1<<2) -#define NSR_RXOV (1<<1) - -#define TCR_TJDIS (1<<6) -#define TCR_EXCECM (1<<5) -#define TCR_PAD_DIS2 (1<<4) -#define TCR_CRC_DIS2 (1<<3) -#define TCR_PAD_DIS1 (1<<2) -#define TCR_CRC_DIS1 (1<<1) -#define TCR_TXREQ (1<<0) - -#define TSR_TJTO (1<<7) -#define TSR_LC (1<<6) -#define TSR_NC (1<<5) -#define TSR_LCOL (1<<4) -#define TSR_COL (1<<3) -#define TSR_EC (1<<2) - -#define RCR_WTDIS (1<<6) -#define RCR_DIS_LONG (1<<5) -#define RCR_DIS_CRC (1<<4) -#define RCR_ALL (1<<3) -#define RCR_RUNT (1<<2) -#define RCR_PRMSC (1<<1) -#define RCR_RXEN (1<<0) - -#define RSR_RF (1<<7) -#define RSR_MF (1<<6) -#define RSR_LCS (1<<5) -#define RSR_RWTO (1<<4) -#define RSR_PLE (1<<3) -#define RSR_AE (1<<2) -#define RSR_CE (1<<1) -#define RSR_FOE (1<<0) - -#define EPCR_EPOS_PHY (1<<3) -#define EPCR_EPOS_EE (0<<3) -#define EPCR_ERPRR (1<<2) -#define EPCR_ERPRW (1<<1) -#define EPCR_ERRE (1<<0) - -#define FCTR_HWOT(ot) (( ot & 0xf ) << 4 ) -#define FCTR_LWOT(ot) ( ot & 0xf ) - -#define BPTR_BPHW(x) ((x) << 4) -#define BPTR_JPT_200US (0x07) -#define BPTR_JPT_600US (0x0f) - -#define IMR_PAR (1<<7) -#define IMR_ROOM (1<<3) -#define IMR_ROM (1<<2) -#define IMR_PTM (1<<1) -#define IMR_PRM (1<<0) - -#define ISR_ROOS (1<<3) -#define ISR_ROS (1<<2) -#define ISR_PTS (1<<1) -#define ISR_PRS (1<<0) - -#define GPCR_GPIO0_OUT (1<<0) - -#define GPR_PHY_PWROFF (1<<0) - -#endif diff --git a/qemu/roms/u-boot/drivers/net/dnet.c b/qemu/roms/u-boot/drivers/net/dnet.c deleted file mode 100644 index 944a0c046..000000000 --- a/qemu/roms/u-boot/drivers/net/dnet.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Dave Ethernet Controller driver - * - * Copyright (C) 2008 Dave S.r.l. <www.dave.eu> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <common.h> - -#ifndef CONFIG_DNET_AUTONEG_TIMEOUT -#define CONFIG_DNET_AUTONEG_TIMEOUT 5000000 /* default value */ -#endif - -#include <net.h> -#include <malloc.h> -#include <linux/mii.h> - -#include <miiphy.h> -#include <asm/io.h> -#include <asm/unaligned.h> - -#include "dnet.h" - -struct dnet_device { - struct dnet_registers *regs; - const struct device *dev; - struct eth_device netdev; - unsigned short phy_addr; -}; - -/* get struct dnet_device from given struct netdev */ -#define to_dnet(_nd) container_of(_nd, struct dnet_device, netdev) - -/* function for reading internal MAC register */ -u16 dnet_readw_mac(struct dnet_device *dnet, u16 reg) -{ - u16 data_read; - - /* issue a read */ - writel(reg, &dnet->regs->MACREG_ADDR); - - /* since a read/write op to the MAC is very slow, - * we must wait before reading the data */ - udelay(1); - - /* read data read from the MAC register */ - data_read = readl(&dnet->regs->MACREG_DATA); - - /* all done */ - return data_read; -} - -/* function for writing internal MAC register */ -void dnet_writew_mac(struct dnet_device *dnet, u16 reg, u16 val) -{ - /* load data to write */ - writel(val, &dnet->regs->MACREG_DATA); - - /* issue a write */ - writel(reg | DNET_INTERNAL_WRITE, &dnet->regs->MACREG_ADDR); - - /* since a read/write op to the MAC is very slow, - * we must wait before exiting */ - udelay(1); -} - -static void dnet_mdio_write(struct dnet_device *dnet, u8 reg, u16 value) -{ - u16 tmp; - - debug(DRIVERNAME "dnet_mdio_write %02x:%02x <- %04x\n", - dnet->phy_addr, reg, value); - - while (!(dnet_readw_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG) & - DNET_INTERNAL_GMII_MNG_CMD_FIN)) - ; - - /* prepare for a write operation */ - tmp = (1 << 13); - - /* only 5 bits allowed for register offset */ - reg &= 0x1f; - - /* prepare reg_value for a write */ - tmp |= (dnet->phy_addr << 8); - tmp |= reg; - - /* write data to write first */ - dnet_writew_mac(dnet, DNET_INTERNAL_GMII_MNG_DAT_REG, value); - - /* write control word */ - dnet_writew_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG, tmp); - - while (!(dnet_readw_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG) & - DNET_INTERNAL_GMII_MNG_CMD_FIN)) - ; -} - -static u16 dnet_mdio_read(struct dnet_device *dnet, u8 reg) -{ - u16 value; - - while (!(dnet_readw_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG) & - DNET_INTERNAL_GMII_MNG_CMD_FIN)) - ; - - /* only 5 bits allowed for register offset*/ - reg &= 0x1f; - - /* prepare reg_value for a read */ - value = (dnet->phy_addr << 8); - value |= reg; - - /* write control word */ - dnet_writew_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG, value); - - /* wait for end of transfer */ - while (!(dnet_readw_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG) & - DNET_INTERNAL_GMII_MNG_CMD_FIN)) - ; - - value = dnet_readw_mac(dnet, DNET_INTERNAL_GMII_MNG_DAT_REG); - - debug(DRIVERNAME "dnet_mdio_read %02x:%02x <- %04x\n", - dnet->phy_addr, reg, value); - - return value; -} - -static int dnet_send(struct eth_device *netdev, void *packet, int length) -{ - struct dnet_device *dnet = to_dnet(netdev); - int i, wrsz; - unsigned int *bufp; - unsigned int tx_cmd; - - debug(DRIVERNAME "[%s] Sending %u bytes\n", __func__, length); - - bufp = (unsigned int *) (((u32)packet) & 0xFFFFFFFC); - wrsz = (u32)length + 3; - wrsz += ((u32)packet) & 0x3; - wrsz >>= 2; - tx_cmd = ((((unsigned int)(packet)) & 0x03) << 16) | (u32)length; - - /* check if there is enough room for the current frame */ - if (wrsz < (DNET_FIFO_SIZE - readl(&dnet->regs->TX_FIFO_WCNT))) { - for (i = 0; i < wrsz; i++) - writel(*bufp++, &dnet->regs->TX_DATA_FIFO); - /* - * inform MAC that a packet's written and ready - * to be shipped out - */ - writel(tx_cmd, &dnet->regs->TX_LEN_FIFO); - } else { - printf(DRIVERNAME "No free space (actual %d, required %d " - "(words))\n", DNET_FIFO_SIZE - - readl(&dnet->regs->TX_FIFO_WCNT), wrsz); - } - - /* No one cares anyway */ - return 0; -} - - -static int dnet_recv(struct eth_device *netdev) -{ - struct dnet_device *dnet = to_dnet(netdev); - unsigned int *data_ptr; - int pkt_len, poll, i; - u32 cmd_word; - - debug("Waiting for pkt (polling)\n"); - poll = 50; - while ((readl(&dnet->regs->RX_FIFO_WCNT) >> 16) == 0) { - udelay(10); /* wait 10 usec */ - if (--poll == 0) - return 0; /* no pkt available */ - } - - cmd_word = readl(&dnet->regs->RX_LEN_FIFO); - pkt_len = cmd_word & 0xFFFF; - - debug("Got pkt with size %d bytes\n", pkt_len); - - if (cmd_word & 0xDF180000) - printf("%s packet receive error %x\n", __func__, cmd_word); - - data_ptr = (unsigned int *) NetRxPackets[0]; - - for (i = 0; i < (pkt_len + 3) >> 2; i++) - *data_ptr++ = readl(&dnet->regs->RX_DATA_FIFO); - - NetReceive(NetRxPackets[0], pkt_len + 5); /* ok + 5 ?? */ - - return 0; -} - -static void dnet_set_hwaddr(struct eth_device *netdev) -{ - struct dnet_device *dnet = to_dnet(netdev); - u16 tmp; - - tmp = get_unaligned_be16(netdev->enetaddr); - dnet_writew_mac(dnet, DNET_INTERNAL_MAC_ADDR_0_REG, tmp); - tmp = get_unaligned_be16(&netdev->enetaddr[2]); - dnet_writew_mac(dnet, DNET_INTERNAL_MAC_ADDR_1_REG, tmp); - tmp = get_unaligned_be16(&netdev->enetaddr[4]); - dnet_writew_mac(dnet, DNET_INTERNAL_MAC_ADDR_2_REG, tmp); -} - -static void dnet_phy_reset(struct dnet_device *dnet) -{ - struct eth_device *netdev = &dnet->netdev; - int i; - u16 status, adv; - - adv = ADVERTISE_CSMA | ADVERTISE_ALL; - dnet_mdio_write(dnet, MII_ADVERTISE, adv); - printf("%s: Starting autonegotiation...\n", netdev->name); - dnet_mdio_write(dnet, MII_BMCR, (BMCR_ANENABLE - | BMCR_ANRESTART)); - - for (i = 0; i < CONFIG_DNET_AUTONEG_TIMEOUT / 100; i++) { - status = dnet_mdio_read(dnet, MII_BMSR); - if (status & BMSR_ANEGCOMPLETE) - break; - udelay(100); - } - - if (status & BMSR_ANEGCOMPLETE) - printf("%s: Autonegotiation complete\n", netdev->name); - else - printf("%s: Autonegotiation timed out (status=0x%04x)\n", - netdev->name, status); -} - -static int dnet_phy_init(struct dnet_device *dnet) -{ - struct eth_device *netdev = &dnet->netdev; - u16 phy_id, status, adv, lpa; - int media, speed, duplex; - int i; - u32 ctl_reg; - - /* Find a PHY */ - for (i = 0; i < 32; i++) { - dnet->phy_addr = i; - phy_id = dnet_mdio_read(dnet, MII_PHYSID1); - if (phy_id != 0xffff) { - /* ok we found it */ - printf("Found PHY at address %d PHYID (%04x:%04x)\n", - i, phy_id, - dnet_mdio_read(dnet, MII_PHYSID2)); - break; - } - } - - /* Check if the PHY is up to snuff... */ - phy_id = dnet_mdio_read(dnet, MII_PHYSID1); - if (phy_id == 0xffff) { - printf("%s: No PHY present\n", netdev->name); - return -1; - } - - status = dnet_mdio_read(dnet, MII_BMSR); - if (!(status & BMSR_LSTATUS)) { - /* Try to re-negotiate if we don't have link already. */ - dnet_phy_reset(dnet); - - for (i = 0; i < CONFIG_DNET_AUTONEG_TIMEOUT / 100; i++) { - status = dnet_mdio_read(dnet, MII_BMSR); - if (status & BMSR_LSTATUS) - break; - udelay(100); - } - } - - if (!(status & BMSR_LSTATUS)) { - printf("%s: link down (status: 0x%04x)\n", - netdev->name, status); - return -1; - } else { - adv = dnet_mdio_read(dnet, MII_ADVERTISE); - lpa = dnet_mdio_read(dnet, MII_LPA); - media = mii_nway_result(lpa & adv); - speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) - ? 1 : 0); - duplex = (media & ADVERTISE_FULL) ? 1 : 0; - /* 1000BaseT ethernet is not supported */ - printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n", - netdev->name, - speed ? "100" : "10", - duplex ? "full" : "half", - lpa); - - ctl_reg = dnet_readw_mac(dnet, DNET_INTERNAL_RXTX_CONTROL_REG); - - if (duplex) - ctl_reg &= ~(DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP); - else - ctl_reg |= DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP; - - dnet_writew_mac(dnet, DNET_INTERNAL_RXTX_CONTROL_REG, ctl_reg); - - return 0; - } -} - -static int dnet_init(struct eth_device *netdev, bd_t *bd) -{ - struct dnet_device *dnet = to_dnet(netdev); - u32 config; - - /* - * dnet_halt should have been called at some point before now, - * so we'll assume the controller is idle. - */ - - /* set hardware address */ - dnet_set_hwaddr(netdev); - - if (dnet_phy_init(dnet) < 0) - return -1; - - /* flush rx/tx fifos */ - writel(DNET_SYS_CTL_RXFIFOFLUSH | DNET_SYS_CTL_TXFIFOFLUSH, - &dnet->regs->SYS_CTL); - udelay(1000); - writel(0, &dnet->regs->SYS_CTL); - - config = dnet_readw_mac(dnet, DNET_INTERNAL_RXTX_CONTROL_REG); - - config |= DNET_INTERNAL_RXTX_CONTROL_RXPAUSE | - DNET_INTERNAL_RXTX_CONTROL_RXBROADCAST | - DNET_INTERNAL_RXTX_CONTROL_DROPCONTROL | - DNET_INTERNAL_RXTX_CONTROL_DISCFXFCS; - - dnet_writew_mac(dnet, DNET_INTERNAL_RXTX_CONTROL_REG, config); - - /* Enable TX and RX */ - dnet_writew_mac(dnet, DNET_INTERNAL_MODE_REG, - DNET_INTERNAL_MODE_RXEN | DNET_INTERNAL_MODE_TXEN); - - return 0; -} - -static void dnet_halt(struct eth_device *netdev) -{ - struct dnet_device *dnet = to_dnet(netdev); - - /* Disable TX and RX */ - dnet_writew_mac(dnet, DNET_INTERNAL_MODE_REG, 0); -} - -int dnet_eth_initialize(int id, void *regs, unsigned int phy_addr) -{ - struct dnet_device *dnet; - struct eth_device *netdev; - unsigned int dev_capa; - - dnet = malloc(sizeof(struct dnet_device)); - if (!dnet) { - printf("Error: Failed to allocate memory for DNET%d\n", id); - return -1; - } - memset(dnet, 0, sizeof(struct dnet_device)); - - netdev = &dnet->netdev; - - dnet->regs = (struct dnet_registers *)regs; - dnet->phy_addr = phy_addr; - - sprintf(netdev->name, "dnet%d", id); - netdev->init = dnet_init; - netdev->halt = dnet_halt; - netdev->send = dnet_send; - netdev->recv = dnet_recv; - - dev_capa = readl(&dnet->regs->VERCAPS) & 0xFFFF; - debug("%s: has %smdio, %sirq, %sgigabit, %sdma \n", netdev->name, - (dev_capa & DNET_HAS_MDIO) ? "" : "no ", - (dev_capa & DNET_HAS_IRQ) ? "" : "no ", - (dev_capa & DNET_HAS_GIGABIT) ? "" : "no ", - (dev_capa & DNET_HAS_DMA) ? "" : "no "); - - eth_register(netdev); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/dnet.h b/qemu/roms/u-boot/drivers/net/dnet.h deleted file mode 100644 index fdb4fd2d3..000000000 --- a/qemu/roms/u-boot/drivers/net/dnet.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Dave Ethernet Controller driver - * - * Copyright (C) 2008 Dave S.r.l. <www.dave.eu> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __DRIVERS_DNET_H__ -#define __DRIVERS_DNET_H__ - -#define DRIVERNAME "dnet" - -struct dnet_registers { - /* ALL DNET FIFO REGISTERS */ - u32 RX_LEN_FIFO; - u32 RX_DATA_FIFO; - u32 TX_LEN_FIFO; - u32 TX_DATA_FIFO; - u32 pad1[0x3c]; - /* ALL DNET CONTROL/STATUS REGISTERS */ - u32 VERCAPS; - u32 INTR_SRC; - u32 INTR_ENB; - u32 RX_STATUS; - u32 TX_STATUS; - u32 RX_FRAMES_CNT; - u32 TX_FRAMES_CNT; - u32 RX_FIFO_TH; - u32 TX_FIFO_TH; - u32 SYS_CTL; - u32 PAUSE_TMR; - u32 RX_FIFO_WCNT; - u32 TX_FIFO_WCNT; - u32 pad2[0x33]; - /* ALL DNET MAC REGISTERS */ - u32 MACREG_DATA; /* Mac-Reg Data */ - u32 MACREG_ADDR; /* Mac-Reg Addr */ - u32 pad3[0x3e]; - /* ALL DNET RX STATISTICS COUNTERS */ - u32 RX_PKT_IGNR_CNT; - u32 RX_LEN_CHK_ERR_CNT; - u32 RX_LNG_FRM_CNT; - u32 RX_SHRT_FRM_CNT; - u32 RX_IPG_VIOL_CNT; - u32 RX_CRC_ERR_CNT; - u32 RX_OK_PKT_CNT; - u32 RX_CTL_FRM_CNT; - u32 RX_PAUSE_FRM_CNT; - u32 RX_MULTICAST_CNT; - u32 RX_BROADCAST_CNT; - u32 RX_VLAN_TAG_CNT; - u32 RX_PRE_SHRINK_CNT; - u32 RX_DRIB_NIB_CNT; - u32 RX_UNSUP_OPCD_CNT; - u32 RX_BYTE_CNT; - u32 pad4[0x30]; - /* DNET TX STATISTICS COUNTERS */ - u32 TX_UNICAST_CNT; - u32 TX_PAUSE_FRM_CNT; - u32 TX_MULTICAST_CNT; - u32 TX_BRDCAST_CNT; - u32 TX_VLAN_TAG_CNT; - u32 TX_BAD_FCS_CNT; - u32 TX_JUMBO_CNT; - u32 TX_BYTE_CNT; -}; - -/* SOME INTERNAL MAC-CORE REGISTER */ -#define DNET_INTERNAL_MODE_REG 0x0 -#define DNET_INTERNAL_RXTX_CONTROL_REG 0x2 -#define DNET_INTERNAL_MAX_PKT_SIZE_REG 0x4 -#define DNET_INTERNAL_IGP_REG 0x8 -#define DNET_INTERNAL_MAC_ADDR_0_REG 0xa -#define DNET_INTERNAL_MAC_ADDR_1_REG 0xc -#define DNET_INTERNAL_MAC_ADDR_2_REG 0xe -#define DNET_INTERNAL_TX_RX_STS_REG 0x12 -#define DNET_INTERNAL_GMII_MNG_CTL_REG 0x14 -#define DNET_INTERNAL_GMII_MNG_DAT_REG 0x16 - -#define DNET_INTERNAL_GMII_MNG_CMD_FIN (1 << 14) - -#define DNET_INTERNAL_WRITE (1 << 31) - -/* MAC-CORE REGISTER FIELDS */ - -/* MAC-CORE MODE REGISTER FIELDS */ -#define DNET_INTERNAL_MODE_GBITEN (1 << 0) -#define DNET_INTERNAL_MODE_FCEN (1 << 1) -#define DNET_INTERNAL_MODE_RXEN (1 << 2) -#define DNET_INTERNAL_MODE_TXEN (1 << 3) - -/* MAC-CORE RXTX CONTROL REGISTER FIELDS */ -#define DNET_INTERNAL_RXTX_CONTROL_RXSHORTFRAME (1 << 8) -#define DNET_INTERNAL_RXTX_CONTROL_RXBROADCAST (1 << 7) -#define DNET_INTERNAL_RXTX_CONTROL_RXMULTICAST (1 << 4) -#define DNET_INTERNAL_RXTX_CONTROL_RXPAUSE (1 << 3) -#define DNET_INTERNAL_RXTX_CONTROL_DISTXFCS (1 << 2) -#define DNET_INTERNAL_RXTX_CONTROL_DISCFXFCS (1 << 1) -#define DNET_INTERNAL_RXTX_CONTROL_ENPROMISC (1 << 0) -#define DNET_INTERNAL_RXTX_CONTROL_DROPCONTROL (1 << 6) -#define DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP (1 << 5) - -/* SYSTEM CONTROL REGISTER FIELDS */ -#define DNET_SYS_CTL_IGNORENEXTPKT (1 << 0) -#define DNET_SYS_CTL_SENDPAUSE (1 << 2) -#define DNET_SYS_CTL_RXFIFOFLUSH (1 << 3) -#define DNET_SYS_CTL_TXFIFOFLUSH (1 << 4) - -/* TX STATUS REGISTER FIELDS */ -#define DNET_TX_STATUS_FIFO_ALMOST_EMPTY (1 << 2) -#define DNET_TX_STATUS_FIFO_ALMOST_FULL (1 << 1) - -/* INTERRUPT SOURCE REGISTER FIELDS */ -#define DNET_INTR_SRC_TX_PKTSENT (1 << 0) -#define DNET_INTR_SRC_TX_FIFOAF (1 << 1) -#define DNET_INTR_SRC_TX_FIFOAE (1 << 2) -#define DNET_INTR_SRC_TX_DISCFRM (1 << 3) -#define DNET_INTR_SRC_TX_FIFOFULL (1 << 4) -#define DNET_INTR_SRC_RX_CMDFIFOAF (1 << 8) -#define DNET_INTR_SRC_RX_CMDFIFOFF (1 << 9) -#define DNET_INTR_SRC_RX_DATAFIFOFF (1 << 10) -#define DNET_INTR_SRC_TX_SUMMARY (1 << 16) -#define DNET_INTR_SRC_RX_SUMMARY (1 << 17) -#define DNET_INTR_SRC_PHY (1 << 19) - -/* INTERRUPT ENABLE REGISTER FIELDS */ -#define DNET_INTR_ENB_TX_PKTSENT (1 << 0) -#define DNET_INTR_ENB_TX_FIFOAF (1 << 1) -#define DNET_INTR_ENB_TX_FIFOAE (1 << 2) -#define DNET_INTR_ENB_TX_DISCFRM (1 << 3) -#define DNET_INTR_ENB_TX_FIFOFULL (1 << 4) -#define DNET_INTR_ENB_RX_PKTRDY (1 << 8) -#define DNET_INTR_ENB_RX_FIFOAF (1 << 9) -#define DNET_INTR_ENB_RX_FIFOERR (1 << 10) -#define DNET_INTR_ENB_RX_ERROR (1 << 11) -#define DNET_INTR_ENB_RX_FIFOFULL (1 << 12) -#define DNET_INTR_ENB_RX_FIFOAE (1 << 13) -#define DNET_INTR_ENB_TX_SUMMARY (1 << 16) -#define DNET_INTR_ENB_RX_SUMMARY (1 << 17) -#define DNET_INTR_ENB_GLOBAL_ENABLE (1 << 18) - -/* - * Capabilities. Used by the driver to know the capabilities that - * the ethernet controller inside the FPGA have. - */ - -#define DNET_HAS_MDIO (1 << 0) -#define DNET_HAS_IRQ (1 << 1) -#define DNET_HAS_GIGABIT (1 << 2) -#define DNET_HAS_DMA (1 << 3) - -#define DNET_HAS_MII (1 << 4) /* or GMII */ -#define DNET_HAS_RMII (1 << 5) /* or RGMII */ - -#define DNET_CAPS_MASK 0xFFFF - -#define DNET_FIFO_SIZE 2048 /* 2K x 32 bit */ -#define DNET_FIFO_TX_DATA_AF_TH (DNET_FIFO_SIZE - 384) /* 384 = 1536 / 4 */ -#define DNET_FIFO_TX_DATA_AE_TH (384) - -#define DNET_FIFO_RX_CMD_AF_TH (1 << 16) /* just one frame inside the FIFO */ - -#endif diff --git a/qemu/roms/u-boot/drivers/net/e1000.c b/qemu/roms/u-boot/drivers/net/e1000.c deleted file mode 100644 index 9d9b259d6..000000000 --- a/qemu/roms/u-boot/drivers/net/e1000.c +++ /dev/null @@ -1,5307 +0,0 @@ -/************************************************************************** -Intel Pro 1000 for ppcboot/das-u-boot -Drivers are port from Intel's Linux driver e1000-4.3.15 -and from Etherboot pro 1000 driver by mrakes at vivato dot net -tested on both gig copper and gig fiber boards -***************************************************************************/ -/******************************************************************************* - - - Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved. - - * SPDX-License-Identifier: GPL-2.0+ - - Contact Information: - Linux NICS <linux.nics@intel.com> - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ -/* - * Copyright (C) Archway Digital Solutions. - * - * written by Chrsitopher Li <cli at arcyway dot com> or <chrisl at gnuchina dot org> - * 2/9/2002 - * - * Copyright (C) Linux Networx. - * Massive upgrade to work with the new intel gigabit NICs. - * <ebiederman at lnxi dot com> - * - * Copyright 2011 Freescale Semiconductor, Inc. - */ - -#include "e1000.h" - -#define TOUT_LOOP 100000 - -#define virt_to_bus(devno, v) pci_virt_to_mem(devno, (void *) (v)) -#define bus_to_phys(devno, a) pci_mem_to_phys(devno, a) - -#define E1000_DEFAULT_PCI_PBA 0x00000030 -#define E1000_DEFAULT_PCIE_PBA 0x000a0026 - -/* NIC specific static variables go here */ - -static char tx_pool[128 + 16]; -static char rx_pool[128 + 16]; -static char packet[2096]; - -static struct e1000_tx_desc *tx_base; -static struct e1000_rx_desc *rx_base; - -static int tx_tail; -static int rx_tail, rx_last; - -static struct pci_device_id e1000_supported[] = { - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82542}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_FIBER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82543GC_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544EI_FIBER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_LOM}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545GM_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_FIBER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541ER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541GI_LF}, - /* E1000 PCIe card */ - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_FIBER }, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES }, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571PT_QUAD_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_FIBER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER_LOWPROFILE}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_DUAL}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_QUAD}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_COPPER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_FIBER}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_SERDES}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E_IAMT}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573L}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82574L}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_QUAD_COPPER_KSP3}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_DPT}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_DPT}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_SPT}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_SPT}, - {} -}; - -/* Function forward declarations */ -static int e1000_setup_link(struct eth_device *nic); -static int e1000_setup_fiber_link(struct eth_device *nic); -static int e1000_setup_copper_link(struct eth_device *nic); -static int e1000_phy_setup_autoneg(struct e1000_hw *hw); -static void e1000_config_collision_dist(struct e1000_hw *hw); -static int e1000_config_mac_to_phy(struct e1000_hw *hw); -static int e1000_config_fc_after_link_up(struct e1000_hw *hw); -static int e1000_check_for_link(struct eth_device *nic); -static int e1000_wait_autoneg(struct e1000_hw *hw); -static int e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, - uint16_t * duplex); -static int e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, - uint16_t * phy_data); -static int e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, - uint16_t phy_data); -static int32_t e1000_phy_hw_reset(struct e1000_hw *hw); -static int e1000_phy_reset(struct e1000_hw *hw); -static int e1000_detect_gig_phy(struct e1000_hw *hw); -static void e1000_set_media_type(struct e1000_hw *hw); - -static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask); -static int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); - -#ifndef CONFIG_E1000_NO_NVM -static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw); -static int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, - uint16_t words, - uint16_t *data); -/****************************************************************************** - * Raises the EEPROM's clock input. - * - * hw - Struct containing variables accessed by shared code - * eecd - EECD's current value - *****************************************************************************/ -void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t * eecd) -{ - /* Raise the clock input to the EEPROM (by setting the SK bit), and then - * wait 50 microseconds. - */ - *eecd = *eecd | E1000_EECD_SK; - E1000_WRITE_REG(hw, EECD, *eecd); - E1000_WRITE_FLUSH(hw); - udelay(50); -} - -/****************************************************************************** - * Lowers the EEPROM's clock input. - * - * hw - Struct containing variables accessed by shared code - * eecd - EECD's current value - *****************************************************************************/ -void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t * eecd) -{ - /* Lower the clock input to the EEPROM (by clearing the SK bit), and then - * wait 50 microseconds. - */ - *eecd = *eecd & ~E1000_EECD_SK; - E1000_WRITE_REG(hw, EECD, *eecd); - E1000_WRITE_FLUSH(hw); - udelay(50); -} - -/****************************************************************************** - * Shift data bits out to the EEPROM. - * - * hw - Struct containing variables accessed by shared code - * data - data to send to the EEPROM - * count - number of bits to shift out - *****************************************************************************/ -static void -e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count) -{ - uint32_t eecd; - uint32_t mask; - - /* We need to shift "count" bits out to the EEPROM. So, value in the - * "data" parameter will be shifted out to the EEPROM one bit at a time. - * In order to do this, "data" must be broken down into bits. - */ - mask = 0x01 << (count - 1); - eecd = E1000_READ_REG(hw, EECD); - eecd &= ~(E1000_EECD_DO | E1000_EECD_DI); - do { - /* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1", - * and then raising and then lowering the clock (the SK bit controls - * the clock input to the EEPROM). A "0" is shifted out to the EEPROM - * by setting "DI" to "0" and then raising and then lowering the clock. - */ - eecd &= ~E1000_EECD_DI; - - if (data & mask) - eecd |= E1000_EECD_DI; - - E1000_WRITE_REG(hw, EECD, eecd); - E1000_WRITE_FLUSH(hw); - - udelay(50); - - e1000_raise_ee_clk(hw, &eecd); - e1000_lower_ee_clk(hw, &eecd); - - mask = mask >> 1; - - } while (mask); - - /* We leave the "DI" bit set to "0" when we leave this routine. */ - eecd &= ~E1000_EECD_DI; - E1000_WRITE_REG(hw, EECD, eecd); -} - -/****************************************************************************** - * Shift data bits in from the EEPROM - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -static uint16_t -e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count) -{ - uint32_t eecd; - uint32_t i; - uint16_t data; - - /* In order to read a register from the EEPROM, we need to shift 'count' - * bits in from the EEPROM. Bits are "shifted in" by raising the clock - * input to the EEPROM (setting the SK bit), and then reading the - * value of the "DO" bit. During this "shifting in" process the - * "DI" bit should always be clear. - */ - - eecd = E1000_READ_REG(hw, EECD); - - eecd &= ~(E1000_EECD_DO | E1000_EECD_DI); - data = 0; - - for (i = 0; i < count; i++) { - data = data << 1; - e1000_raise_ee_clk(hw, &eecd); - - eecd = E1000_READ_REG(hw, EECD); - - eecd &= ~(E1000_EECD_DI); - if (eecd & E1000_EECD_DO) - data |= 1; - - e1000_lower_ee_clk(hw, &eecd); - } - - return data; -} - -/****************************************************************************** - * Returns EEPROM to a "standby" state - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -void e1000_standby_eeprom(struct e1000_hw *hw) -{ - struct e1000_eeprom_info *eeprom = &hw->eeprom; - uint32_t eecd; - - eecd = E1000_READ_REG(hw, EECD); - - if (eeprom->type == e1000_eeprom_microwire) { - eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); - E1000_WRITE_REG(hw, EECD, eecd); - E1000_WRITE_FLUSH(hw); - udelay(eeprom->delay_usec); - - /* Clock high */ - eecd |= E1000_EECD_SK; - E1000_WRITE_REG(hw, EECD, eecd); - E1000_WRITE_FLUSH(hw); - udelay(eeprom->delay_usec); - - /* Select EEPROM */ - eecd |= E1000_EECD_CS; - E1000_WRITE_REG(hw, EECD, eecd); - E1000_WRITE_FLUSH(hw); - udelay(eeprom->delay_usec); - - /* Clock low */ - eecd &= ~E1000_EECD_SK; - E1000_WRITE_REG(hw, EECD, eecd); - E1000_WRITE_FLUSH(hw); - udelay(eeprom->delay_usec); - } else if (eeprom->type == e1000_eeprom_spi) { - /* Toggle CS to flush commands */ - eecd |= E1000_EECD_CS; - E1000_WRITE_REG(hw, EECD, eecd); - E1000_WRITE_FLUSH(hw); - udelay(eeprom->delay_usec); - eecd &= ~E1000_EECD_CS; - E1000_WRITE_REG(hw, EECD, eecd); - E1000_WRITE_FLUSH(hw); - udelay(eeprom->delay_usec); - } -} - -/*************************************************************************** -* Description: Determines if the onboard NVM is FLASH or EEPROM. -* -* hw - Struct containing variables accessed by shared code -****************************************************************************/ -static bool e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw) -{ - uint32_t eecd = 0; - - DEBUGFUNC(); - - if (hw->mac_type == e1000_ich8lan) - return false; - - if (hw->mac_type == e1000_82573 || hw->mac_type == e1000_82574) { - eecd = E1000_READ_REG(hw, EECD); - - /* Isolate bits 15 & 16 */ - eecd = ((eecd >> 15) & 0x03); - - /* If both bits are set, device is Flash type */ - if (eecd == 0x03) - return false; - } - return true; -} - -/****************************************************************************** - * Prepares EEPROM for access - * - * hw - Struct containing variables accessed by shared code - * - * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This - * function should be called before issuing a command to the EEPROM. - *****************************************************************************/ -int32_t e1000_acquire_eeprom(struct e1000_hw *hw) -{ - struct e1000_eeprom_info *eeprom = &hw->eeprom; - uint32_t eecd, i = 0; - - DEBUGFUNC(); - - if (e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM)) - return -E1000_ERR_SWFW_SYNC; - eecd = E1000_READ_REG(hw, EECD); - - if (hw->mac_type != e1000_82573 || hw->mac_type != e1000_82574) { - /* Request EEPROM Access */ - if (hw->mac_type > e1000_82544) { - eecd |= E1000_EECD_REQ; - E1000_WRITE_REG(hw, EECD, eecd); - eecd = E1000_READ_REG(hw, EECD); - while ((!(eecd & E1000_EECD_GNT)) && - (i < E1000_EEPROM_GRANT_ATTEMPTS)) { - i++; - udelay(5); - eecd = E1000_READ_REG(hw, EECD); - } - if (!(eecd & E1000_EECD_GNT)) { - eecd &= ~E1000_EECD_REQ; - E1000_WRITE_REG(hw, EECD, eecd); - DEBUGOUT("Could not acquire EEPROM grant\n"); - return -E1000_ERR_EEPROM; - } - } - } - - /* Setup EEPROM for Read/Write */ - - if (eeprom->type == e1000_eeprom_microwire) { - /* Clear SK and DI */ - eecd &= ~(E1000_EECD_DI | E1000_EECD_SK); - E1000_WRITE_REG(hw, EECD, eecd); - - /* Set CS */ - eecd |= E1000_EECD_CS; - E1000_WRITE_REG(hw, EECD, eecd); - } else if (eeprom->type == e1000_eeprom_spi) { - /* Clear SK and CS */ - eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); - E1000_WRITE_REG(hw, EECD, eecd); - udelay(1); - } - - return E1000_SUCCESS; -} - -/****************************************************************************** - * Sets up eeprom variables in the hw struct. Must be called after mac_type - * is configured. Additionally, if this is ICH8, the flash controller GbE - * registers must be mapped, or this will crash. - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -static int32_t e1000_init_eeprom_params(struct e1000_hw *hw) -{ - struct e1000_eeprom_info *eeprom = &hw->eeprom; - uint32_t eecd = E1000_READ_REG(hw, EECD); - int32_t ret_val = E1000_SUCCESS; - uint16_t eeprom_size; - - DEBUGFUNC(); - - switch (hw->mac_type) { - case e1000_82542_rev2_0: - case e1000_82542_rev2_1: - case e1000_82543: - case e1000_82544: - eeprom->type = e1000_eeprom_microwire; - eeprom->word_size = 64; - eeprom->opcode_bits = 3; - eeprom->address_bits = 6; - eeprom->delay_usec = 50; - eeprom->use_eerd = false; - eeprom->use_eewr = false; - break; - case e1000_82540: - case e1000_82545: - case e1000_82545_rev_3: - case e1000_82546: - case e1000_82546_rev_3: - eeprom->type = e1000_eeprom_microwire; - eeprom->opcode_bits = 3; - eeprom->delay_usec = 50; - if (eecd & E1000_EECD_SIZE) { - eeprom->word_size = 256; - eeprom->address_bits = 8; - } else { - eeprom->word_size = 64; - eeprom->address_bits = 6; - } - eeprom->use_eerd = false; - eeprom->use_eewr = false; - break; - case e1000_82541: - case e1000_82541_rev_2: - case e1000_82547: - case e1000_82547_rev_2: - if (eecd & E1000_EECD_TYPE) { - eeprom->type = e1000_eeprom_spi; - eeprom->opcode_bits = 8; - eeprom->delay_usec = 1; - if (eecd & E1000_EECD_ADDR_BITS) { - eeprom->page_size = 32; - eeprom->address_bits = 16; - } else { - eeprom->page_size = 8; - eeprom->address_bits = 8; - } - } else { - eeprom->type = e1000_eeprom_microwire; - eeprom->opcode_bits = 3; - eeprom->delay_usec = 50; - if (eecd & E1000_EECD_ADDR_BITS) { - eeprom->word_size = 256; - eeprom->address_bits = 8; - } else { - eeprom->word_size = 64; - eeprom->address_bits = 6; - } - } - eeprom->use_eerd = false; - eeprom->use_eewr = false; - break; - case e1000_82571: - case e1000_82572: - eeprom->type = e1000_eeprom_spi; - eeprom->opcode_bits = 8; - eeprom->delay_usec = 1; - if (eecd & E1000_EECD_ADDR_BITS) { - eeprom->page_size = 32; - eeprom->address_bits = 16; - } else { - eeprom->page_size = 8; - eeprom->address_bits = 8; - } - eeprom->use_eerd = false; - eeprom->use_eewr = false; - break; - case e1000_82573: - case e1000_82574: - eeprom->type = e1000_eeprom_spi; - eeprom->opcode_bits = 8; - eeprom->delay_usec = 1; - if (eecd & E1000_EECD_ADDR_BITS) { - eeprom->page_size = 32; - eeprom->address_bits = 16; - } else { - eeprom->page_size = 8; - eeprom->address_bits = 8; - } - eeprom->use_eerd = true; - eeprom->use_eewr = true; - if (e1000_is_onboard_nvm_eeprom(hw) == false) { - eeprom->type = e1000_eeprom_flash; - eeprom->word_size = 2048; - - /* Ensure that the Autonomous FLASH update bit is cleared due to - * Flash update issue on parts which use a FLASH for NVM. */ - eecd &= ~E1000_EECD_AUPDEN; - E1000_WRITE_REG(hw, EECD, eecd); - } - break; - case e1000_80003es2lan: - eeprom->type = e1000_eeprom_spi; - eeprom->opcode_bits = 8; - eeprom->delay_usec = 1; - if (eecd & E1000_EECD_ADDR_BITS) { - eeprom->page_size = 32; - eeprom->address_bits = 16; - } else { - eeprom->page_size = 8; - eeprom->address_bits = 8; - } - eeprom->use_eerd = true; - eeprom->use_eewr = false; - break; - - /* ich8lan does not support currently. if needed, please - * add corresponding code and functions. - */ -#if 0 - case e1000_ich8lan: - { - int32_t i = 0; - - eeprom->type = e1000_eeprom_ich8; - eeprom->use_eerd = false; - eeprom->use_eewr = false; - eeprom->word_size = E1000_SHADOW_RAM_WORDS; - uint32_t flash_size = E1000_READ_ICH_FLASH_REG(hw, - ICH_FLASH_GFPREG); - /* Zero the shadow RAM structure. But don't load it from NVM - * so as to save time for driver init */ - if (hw->eeprom_shadow_ram != NULL) { - for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) { - hw->eeprom_shadow_ram[i].modified = false; - hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF; - } - } - - hw->flash_base_addr = (flash_size & ICH_GFPREG_BASE_MASK) * - ICH_FLASH_SECTOR_SIZE; - - hw->flash_bank_size = ((flash_size >> 16) - & ICH_GFPREG_BASE_MASK) + 1; - hw->flash_bank_size -= (flash_size & ICH_GFPREG_BASE_MASK); - - hw->flash_bank_size *= ICH_FLASH_SECTOR_SIZE; - - hw->flash_bank_size /= 2 * sizeof(uint16_t); - break; - } -#endif - default: - break; - } - - if (eeprom->type == e1000_eeprom_spi) { - /* eeprom_size will be an enum [0..8] that maps - * to eeprom sizes 128B to - * 32KB (incremented by powers of 2). - */ - if (hw->mac_type <= e1000_82547_rev_2) { - /* Set to default value for initial eeprom read. */ - eeprom->word_size = 64; - ret_val = e1000_read_eeprom(hw, EEPROM_CFG, 1, - &eeprom_size); - if (ret_val) - return ret_val; - eeprom_size = (eeprom_size & EEPROM_SIZE_MASK) - >> EEPROM_SIZE_SHIFT; - /* 256B eeprom size was not supported in earlier - * hardware, so we bump eeprom_size up one to - * ensure that "1" (which maps to 256B) is never - * the result used in the shifting logic below. */ - if (eeprom_size) - eeprom_size++; - } else { - eeprom_size = (uint16_t)((eecd & - E1000_EECD_SIZE_EX_MASK) >> - E1000_EECD_SIZE_EX_SHIFT); - } - - eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT); - } - return ret_val; -} - -/****************************************************************************** - * Polls the status bit (bit 1) of the EERD to determine when the read is done. - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -static int32_t -e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd) -{ - uint32_t attempts = 100000; - uint32_t i, reg = 0; - int32_t done = E1000_ERR_EEPROM; - - for (i = 0; i < attempts; i++) { - if (eerd == E1000_EEPROM_POLL_READ) - reg = E1000_READ_REG(hw, EERD); - else - reg = E1000_READ_REG(hw, EEWR); - - if (reg & E1000_EEPROM_RW_REG_DONE) { - done = E1000_SUCCESS; - break; - } - udelay(5); - } - - return done; -} - -/****************************************************************************** - * Reads a 16 bit word from the EEPROM using the EERD register. - * - * hw - Struct containing variables accessed by shared code - * offset - offset of word in the EEPROM to read - * data - word read from the EEPROM - * words - number of words to read - *****************************************************************************/ -static int32_t -e1000_read_eeprom_eerd(struct e1000_hw *hw, - uint16_t offset, - uint16_t words, - uint16_t *data) -{ - uint32_t i, eerd = 0; - int32_t error = 0; - - for (i = 0; i < words; i++) { - eerd = ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) + - E1000_EEPROM_RW_REG_START; - - E1000_WRITE_REG(hw, EERD, eerd); - error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ); - - if (error) - break; - data[i] = (E1000_READ_REG(hw, EERD) >> - E1000_EEPROM_RW_REG_DATA); - - } - - return error; -} - -void e1000_release_eeprom(struct e1000_hw *hw) -{ - uint32_t eecd; - - DEBUGFUNC(); - - eecd = E1000_READ_REG(hw, EECD); - - if (hw->eeprom.type == e1000_eeprom_spi) { - eecd |= E1000_EECD_CS; /* Pull CS high */ - eecd &= ~E1000_EECD_SK; /* Lower SCK */ - - E1000_WRITE_REG(hw, EECD, eecd); - - udelay(hw->eeprom.delay_usec); - } else if (hw->eeprom.type == e1000_eeprom_microwire) { - /* cleanup eeprom */ - - /* CS on Microwire is active-high */ - eecd &= ~(E1000_EECD_CS | E1000_EECD_DI); - - E1000_WRITE_REG(hw, EECD, eecd); - - /* Rising edge of clock */ - eecd |= E1000_EECD_SK; - E1000_WRITE_REG(hw, EECD, eecd); - E1000_WRITE_FLUSH(hw); - udelay(hw->eeprom.delay_usec); - - /* Falling edge of clock */ - eecd &= ~E1000_EECD_SK; - E1000_WRITE_REG(hw, EECD, eecd); - E1000_WRITE_FLUSH(hw); - udelay(hw->eeprom.delay_usec); - } - - /* Stop requesting EEPROM access */ - if (hw->mac_type > e1000_82544) { - eecd &= ~E1000_EECD_REQ; - E1000_WRITE_REG(hw, EECD, eecd); - } -} -/****************************************************************************** - * Reads a 16 bit word from the EEPROM. - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -static int32_t -e1000_spi_eeprom_ready(struct e1000_hw *hw) -{ - uint16_t retry_count = 0; - uint8_t spi_stat_reg; - - DEBUGFUNC(); - - /* Read "Status Register" repeatedly until the LSB is cleared. The - * EEPROM will signal that the command has been completed by clearing - * bit 0 of the internal status register. If it's not cleared within - * 5 milliseconds, then error out. - */ - retry_count = 0; - do { - e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI, - hw->eeprom.opcode_bits); - spi_stat_reg = (uint8_t)e1000_shift_in_ee_bits(hw, 8); - if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI)) - break; - - udelay(5); - retry_count += 5; - - e1000_standby_eeprom(hw); - } while (retry_count < EEPROM_MAX_RETRY_SPI); - - /* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and - * only 0-5mSec on 5V devices) - */ - if (retry_count >= EEPROM_MAX_RETRY_SPI) { - DEBUGOUT("SPI EEPROM Status error\n"); - return -E1000_ERR_EEPROM; - } - - return E1000_SUCCESS; -} - -/****************************************************************************** - * Reads a 16 bit word from the EEPROM. - * - * hw - Struct containing variables accessed by shared code - * offset - offset of word in the EEPROM to read - * data - word read from the EEPROM - *****************************************************************************/ -static int32_t -e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, - uint16_t words, uint16_t *data) -{ - struct e1000_eeprom_info *eeprom = &hw->eeprom; - uint32_t i = 0; - - DEBUGFUNC(); - - /* If eeprom is not yet detected, do so now */ - if (eeprom->word_size == 0) - e1000_init_eeprom_params(hw); - - /* A check for invalid values: offset too large, too many words, - * and not enough words. - */ - if ((offset >= eeprom->word_size) || - (words > eeprom->word_size - offset) || - (words == 0)) { - DEBUGOUT("\"words\" parameter out of bounds." - "Words = %d, size = %d\n", offset, eeprom->word_size); - return -E1000_ERR_EEPROM; - } - - /* EEPROM's that don't use EERD to read require us to bit-bang the SPI - * directly. In this case, we need to acquire the EEPROM so that - * FW or other port software does not interrupt. - */ - if (e1000_is_onboard_nvm_eeprom(hw) == true && - hw->eeprom.use_eerd == false) { - - /* Prepare the EEPROM for bit-bang reading */ - if (e1000_acquire_eeprom(hw) != E1000_SUCCESS) - return -E1000_ERR_EEPROM; - } - - /* Eerd register EEPROM access requires no eeprom aquire/release */ - if (eeprom->use_eerd == true) - return e1000_read_eeprom_eerd(hw, offset, words, data); - - /* ich8lan does not support currently. if needed, please - * add corresponding code and functions. - */ -#if 0 - /* ICH EEPROM access is done via the ICH flash controller */ - if (eeprom->type == e1000_eeprom_ich8) - return e1000_read_eeprom_ich8(hw, offset, words, data); -#endif - /* Set up the SPI or Microwire EEPROM for bit-bang reading. We have - * acquired the EEPROM at this point, so any returns should relase it */ - if (eeprom->type == e1000_eeprom_spi) { - uint16_t word_in; - uint8_t read_opcode = EEPROM_READ_OPCODE_SPI; - - if (e1000_spi_eeprom_ready(hw)) { - e1000_release_eeprom(hw); - return -E1000_ERR_EEPROM; - } - - e1000_standby_eeprom(hw); - - /* Some SPI eeproms use the 8th address bit embedded in - * the opcode */ - if ((eeprom->address_bits == 8) && (offset >= 128)) - read_opcode |= EEPROM_A8_OPCODE_SPI; - - /* Send the READ command (opcode + addr) */ - e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits); - e1000_shift_out_ee_bits(hw, (uint16_t)(offset*2), - eeprom->address_bits); - - /* Read the data. The address of the eeprom internally - * increments with each byte (spi) being read, saving on the - * overhead of eeprom setup and tear-down. The address - * counter will roll over if reading beyond the size of - * the eeprom, thus allowing the entire memory to be read - * starting from any offset. */ - for (i = 0; i < words; i++) { - word_in = e1000_shift_in_ee_bits(hw, 16); - data[i] = (word_in >> 8) | (word_in << 8); - } - } else if (eeprom->type == e1000_eeprom_microwire) { - for (i = 0; i < words; i++) { - /* Send the READ command (opcode + addr) */ - e1000_shift_out_ee_bits(hw, - EEPROM_READ_OPCODE_MICROWIRE, - eeprom->opcode_bits); - e1000_shift_out_ee_bits(hw, (uint16_t)(offset + i), - eeprom->address_bits); - - /* Read the data. For microwire, each word requires - * the overhead of eeprom setup and tear-down. */ - data[i] = e1000_shift_in_ee_bits(hw, 16); - e1000_standby_eeprom(hw); - } - } - - /* End this read operation */ - e1000_release_eeprom(hw); - - return E1000_SUCCESS; -} - -/****************************************************************************** - * Verifies that the EEPROM has a valid checksum - * - * hw - Struct containing variables accessed by shared code - * - * Reads the first 64 16 bit words of the EEPROM and sums the values read. - * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is - * valid. - *****************************************************************************/ -static int e1000_validate_eeprom_checksum(struct e1000_hw *hw) -{ - uint16_t i, checksum, checksum_reg, *buf; - - DEBUGFUNC(); - - /* Allocate a temporary buffer */ - buf = malloc(sizeof(buf[0]) * (EEPROM_CHECKSUM_REG + 1)); - if (!buf) { - E1000_ERR(hw->nic, "Unable to allocate EEPROM buffer!\n"); - return -E1000_ERR_EEPROM; - } - - /* Read the EEPROM */ - if (e1000_read_eeprom(hw, 0, EEPROM_CHECKSUM_REG + 1, buf) < 0) { - E1000_ERR(hw->nic, "Unable to read EEPROM!\n"); - return -E1000_ERR_EEPROM; - } - - /* Compute the checksum */ - checksum = 0; - for (i = 0; i < EEPROM_CHECKSUM_REG; i++) - checksum += buf[i]; - checksum = ((uint16_t)EEPROM_SUM) - checksum; - checksum_reg = buf[i]; - - /* Verify it! */ - if (checksum == checksum_reg) - return 0; - - /* Hrm, verification failed, print an error */ - E1000_ERR(hw->nic, "EEPROM checksum is incorrect!\n"); - E1000_ERR(hw->nic, " ...register was 0x%04hx, calculated 0x%04hx\n", - checksum_reg, checksum); - - return -E1000_ERR_EEPROM; -} -#endif /* CONFIG_E1000_NO_NVM */ - -/***************************************************************************** - * Set PHY to class A mode - * Assumes the following operations will follow to enable the new class mode. - * 1. Do a PHY soft reset - * 2. Restart auto-negotiation or force link. - * - * hw - Struct containing variables accessed by shared code - ****************************************************************************/ -static int32_t -e1000_set_phy_mode(struct e1000_hw *hw) -{ -#ifndef CONFIG_E1000_NO_NVM - int32_t ret_val; - uint16_t eeprom_data; - - DEBUGFUNC(); - - if ((hw->mac_type == e1000_82545_rev_3) && - (hw->media_type == e1000_media_type_copper)) { - ret_val = e1000_read_eeprom(hw, EEPROM_PHY_CLASS_WORD, - 1, &eeprom_data); - if (ret_val) - return ret_val; - - if ((eeprom_data != EEPROM_RESERVED_WORD) && - (eeprom_data & EEPROM_PHY_CLASS_A)) { - ret_val = e1000_write_phy_reg(hw, - M88E1000_PHY_PAGE_SELECT, 0x000B); - if (ret_val) - return ret_val; - ret_val = e1000_write_phy_reg(hw, - M88E1000_PHY_GEN_CONTROL, 0x8104); - if (ret_val) - return ret_val; - - hw->phy_reset_disable = false; - } - } -#endif - return E1000_SUCCESS; -} - -#ifndef CONFIG_E1000_NO_NVM -/*************************************************************************** - * - * Obtaining software semaphore bit (SMBI) before resetting PHY. - * - * hw: Struct containing variables accessed by shared code - * - * returns: - E1000_ERR_RESET if fail to obtain semaphore. - * E1000_SUCCESS at any other case. - * - ***************************************************************************/ -static int32_t -e1000_get_software_semaphore(struct e1000_hw *hw) -{ - int32_t timeout = hw->eeprom.word_size + 1; - uint32_t swsm; - - DEBUGFUNC(); - - if (hw->mac_type != e1000_80003es2lan) - return E1000_SUCCESS; - - while (timeout) { - swsm = E1000_READ_REG(hw, SWSM); - /* If SMBI bit cleared, it is now set and we hold - * the semaphore */ - if (!(swsm & E1000_SWSM_SMBI)) - break; - mdelay(1); - timeout--; - } - - if (!timeout) { - DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); - return -E1000_ERR_RESET; - } - - return E1000_SUCCESS; -} -#endif - -/*************************************************************************** - * This function clears HW semaphore bits. - * - * hw: Struct containing variables accessed by shared code - * - * returns: - None. - * - ***************************************************************************/ -static void -e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw) -{ -#ifndef CONFIG_E1000_NO_NVM - uint32_t swsm; - - DEBUGFUNC(); - - if (!hw->eeprom_semaphore_present) - return; - - swsm = E1000_READ_REG(hw, SWSM); - if (hw->mac_type == e1000_80003es2lan) { - /* Release both semaphores. */ - swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); - } else - swsm &= ~(E1000_SWSM_SWESMBI); - E1000_WRITE_REG(hw, SWSM, swsm); -#endif -} - -/*************************************************************************** - * - * Using the combination of SMBI and SWESMBI semaphore bits when resetting - * adapter or Eeprom access. - * - * hw: Struct containing variables accessed by shared code - * - * returns: - E1000_ERR_EEPROM if fail to access EEPROM. - * E1000_SUCCESS at any other case. - * - ***************************************************************************/ -static int32_t -e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw) -{ -#ifndef CONFIG_E1000_NO_NVM - int32_t timeout; - uint32_t swsm; - - DEBUGFUNC(); - - if (!hw->eeprom_semaphore_present) - return E1000_SUCCESS; - - if (hw->mac_type == e1000_80003es2lan) { - /* Get the SW semaphore. */ - if (e1000_get_software_semaphore(hw) != E1000_SUCCESS) - return -E1000_ERR_EEPROM; - } - - /* Get the FW semaphore. */ - timeout = hw->eeprom.word_size + 1; - while (timeout) { - swsm = E1000_READ_REG(hw, SWSM); - swsm |= E1000_SWSM_SWESMBI; - E1000_WRITE_REG(hw, SWSM, swsm); - /* if we managed to set the bit we got the semaphore. */ - swsm = E1000_READ_REG(hw, SWSM); - if (swsm & E1000_SWSM_SWESMBI) - break; - - udelay(50); - timeout--; - } - - if (!timeout) { - /* Release semaphores */ - e1000_put_hw_eeprom_semaphore(hw); - DEBUGOUT("Driver can't access the Eeprom - " - "SWESMBI bit is set.\n"); - return -E1000_ERR_EEPROM; - } -#endif - return E1000_SUCCESS; -} - -static int32_t -e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask) -{ - uint32_t swfw_sync = 0; - uint32_t swmask = mask; - uint32_t fwmask = mask << 16; - int32_t timeout = 200; - - DEBUGFUNC(); - while (timeout) { - if (e1000_get_hw_eeprom_semaphore(hw)) - return -E1000_ERR_SWFW_SYNC; - - swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC); - if (!(swfw_sync & (fwmask | swmask))) - break; - - /* firmware currently using resource (fwmask) */ - /* or other software thread currently using resource (swmask) */ - e1000_put_hw_eeprom_semaphore(hw); - mdelay(5); - timeout--; - } - - if (!timeout) { - DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); - return -E1000_ERR_SWFW_SYNC; - } - - swfw_sync |= swmask; - E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync); - - e1000_put_hw_eeprom_semaphore(hw); - return E1000_SUCCESS; -} - -static bool e1000_is_second_port(struct e1000_hw *hw) -{ - switch (hw->mac_type) { - case e1000_80003es2lan: - case e1000_82546: - case e1000_82571: - if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) - return true; - /* Fallthrough */ - default: - return false; - } -} - -#ifndef CONFIG_E1000_NO_NVM -/****************************************************************************** - * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the - * second function of dual function devices - * - * nic - Struct containing variables accessed by shared code - *****************************************************************************/ -static int -e1000_read_mac_addr(struct eth_device *nic) -{ - struct e1000_hw *hw = nic->priv; - uint16_t offset; - uint16_t eeprom_data; - int i; - - DEBUGFUNC(); - - for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) { - offset = i >> 1; - if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) { - DEBUGOUT("EEPROM Read Error\n"); - return -E1000_ERR_EEPROM; - } - nic->enetaddr[i] = eeprom_data & 0xff; - nic->enetaddr[i + 1] = (eeprom_data >> 8) & 0xff; - } - - /* Invert the last bit if this is the second device */ - if (e1000_is_second_port(hw)) - nic->enetaddr[5] ^= 1; - -#ifdef CONFIG_E1000_FALLBACK_MAC - if (!is_valid_ether_addr(nic->enetaddr)) { - unsigned char fb_mac[NODE_ADDRESS_SIZE] = CONFIG_E1000_FALLBACK_MAC; - - memcpy (nic->enetaddr, fb_mac, NODE_ADDRESS_SIZE); - } -#endif - return 0; -} -#endif - -/****************************************************************************** - * Initializes receive address filters. - * - * hw - Struct containing variables accessed by shared code - * - * Places the MAC address in receive address register 0 and clears the rest - * of the receive addresss registers. Clears the multicast table. Assumes - * the receiver is in reset when the routine is called. - *****************************************************************************/ -static void -e1000_init_rx_addrs(struct eth_device *nic) -{ - struct e1000_hw *hw = nic->priv; - uint32_t i; - uint32_t addr_low; - uint32_t addr_high; - - DEBUGFUNC(); - - /* Setup the receive address. */ - DEBUGOUT("Programming MAC Address into RAR[0]\n"); - addr_low = (nic->enetaddr[0] | - (nic->enetaddr[1] << 8) | - (nic->enetaddr[2] << 16) | (nic->enetaddr[3] << 24)); - - addr_high = (nic->enetaddr[4] | (nic->enetaddr[5] << 8) | E1000_RAH_AV); - - E1000_WRITE_REG_ARRAY(hw, RA, 0, addr_low); - E1000_WRITE_REG_ARRAY(hw, RA, 1, addr_high); - - /* Zero out the other 15 receive addresses. */ - DEBUGOUT("Clearing RAR[1-15]\n"); - for (i = 1; i < E1000_RAR_ENTRIES; i++) { - E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); - E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); - } -} - -/****************************************************************************** - * Clears the VLAN filer table - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -static void -e1000_clear_vfta(struct e1000_hw *hw) -{ - uint32_t offset; - - for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) - E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0); -} - -/****************************************************************************** - * Set the mac type member in the hw struct. - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -int32_t -e1000_set_mac_type(struct e1000_hw *hw) -{ - DEBUGFUNC(); - - switch (hw->device_id) { - case E1000_DEV_ID_82542: - switch (hw->revision_id) { - case E1000_82542_2_0_REV_ID: - hw->mac_type = e1000_82542_rev2_0; - break; - case E1000_82542_2_1_REV_ID: - hw->mac_type = e1000_82542_rev2_1; - break; - default: - /* Invalid 82542 revision ID */ - return -E1000_ERR_MAC_TYPE; - } - break; - case E1000_DEV_ID_82543GC_FIBER: - case E1000_DEV_ID_82543GC_COPPER: - hw->mac_type = e1000_82543; - break; - case E1000_DEV_ID_82544EI_COPPER: - case E1000_DEV_ID_82544EI_FIBER: - case E1000_DEV_ID_82544GC_COPPER: - case E1000_DEV_ID_82544GC_LOM: - hw->mac_type = e1000_82544; - break; - case E1000_DEV_ID_82540EM: - case E1000_DEV_ID_82540EM_LOM: - case E1000_DEV_ID_82540EP: - case E1000_DEV_ID_82540EP_LOM: - case E1000_DEV_ID_82540EP_LP: - hw->mac_type = e1000_82540; - break; - case E1000_DEV_ID_82545EM_COPPER: - case E1000_DEV_ID_82545EM_FIBER: - hw->mac_type = e1000_82545; - break; - case E1000_DEV_ID_82545GM_COPPER: - case E1000_DEV_ID_82545GM_FIBER: - case E1000_DEV_ID_82545GM_SERDES: - hw->mac_type = e1000_82545_rev_3; - break; - case E1000_DEV_ID_82546EB_COPPER: - case E1000_DEV_ID_82546EB_FIBER: - case E1000_DEV_ID_82546EB_QUAD_COPPER: - hw->mac_type = e1000_82546; - break; - case E1000_DEV_ID_82546GB_COPPER: - case E1000_DEV_ID_82546GB_FIBER: - case E1000_DEV_ID_82546GB_SERDES: - case E1000_DEV_ID_82546GB_PCIE: - case E1000_DEV_ID_82546GB_QUAD_COPPER: - case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: - hw->mac_type = e1000_82546_rev_3; - break; - case E1000_DEV_ID_82541EI: - case E1000_DEV_ID_82541EI_MOBILE: - case E1000_DEV_ID_82541ER_LOM: - hw->mac_type = e1000_82541; - break; - case E1000_DEV_ID_82541ER: - case E1000_DEV_ID_82541GI: - case E1000_DEV_ID_82541GI_LF: - case E1000_DEV_ID_82541GI_MOBILE: - hw->mac_type = e1000_82541_rev_2; - break; - case E1000_DEV_ID_82547EI: - case E1000_DEV_ID_82547EI_MOBILE: - hw->mac_type = e1000_82547; - break; - case E1000_DEV_ID_82547GI: - hw->mac_type = e1000_82547_rev_2; - break; - case E1000_DEV_ID_82571EB_COPPER: - case E1000_DEV_ID_82571EB_FIBER: - case E1000_DEV_ID_82571EB_SERDES: - case E1000_DEV_ID_82571EB_SERDES_DUAL: - case E1000_DEV_ID_82571EB_SERDES_QUAD: - case E1000_DEV_ID_82571EB_QUAD_COPPER: - case E1000_DEV_ID_82571PT_QUAD_COPPER: - case E1000_DEV_ID_82571EB_QUAD_FIBER: - case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE: - hw->mac_type = e1000_82571; - break; - case E1000_DEV_ID_82572EI_COPPER: - case E1000_DEV_ID_82572EI_FIBER: - case E1000_DEV_ID_82572EI_SERDES: - case E1000_DEV_ID_82572EI: - hw->mac_type = e1000_82572; - break; - case E1000_DEV_ID_82573E: - case E1000_DEV_ID_82573E_IAMT: - case E1000_DEV_ID_82573L: - hw->mac_type = e1000_82573; - break; - case E1000_DEV_ID_82574L: - hw->mac_type = e1000_82574; - break; - case E1000_DEV_ID_80003ES2LAN_COPPER_SPT: - case E1000_DEV_ID_80003ES2LAN_SERDES_SPT: - case E1000_DEV_ID_80003ES2LAN_COPPER_DPT: - case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: - hw->mac_type = e1000_80003es2lan; - break; - case E1000_DEV_ID_ICH8_IGP_M_AMT: - case E1000_DEV_ID_ICH8_IGP_AMT: - case E1000_DEV_ID_ICH8_IGP_C: - case E1000_DEV_ID_ICH8_IFE: - case E1000_DEV_ID_ICH8_IFE_GT: - case E1000_DEV_ID_ICH8_IFE_G: - case E1000_DEV_ID_ICH8_IGP_M: - hw->mac_type = e1000_ich8lan; - break; - default: - /* Should never have loaded on this device */ - return -E1000_ERR_MAC_TYPE; - } - return E1000_SUCCESS; -} - -/****************************************************************************** - * Reset the transmit and receive units; mask and clear all interrupts. - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -void -e1000_reset_hw(struct e1000_hw *hw) -{ - uint32_t ctrl; - uint32_t ctrl_ext; - uint32_t manc; - uint32_t pba = 0; - - DEBUGFUNC(); - - /* get the correct pba value for both PCI and PCIe*/ - if (hw->mac_type < e1000_82571) - pba = E1000_DEFAULT_PCI_PBA; - else - pba = E1000_DEFAULT_PCIE_PBA; - - /* For 82542 (rev 2.0), disable MWI before issuing a device reset */ - if (hw->mac_type == e1000_82542_rev2_0) { - DEBUGOUT("Disabling MWI on 82542 rev 2.0\n"); - pci_write_config_word(hw->pdev, PCI_COMMAND, - hw->pci_cmd_word & ~PCI_COMMAND_INVALIDATE); - } - - /* Clear interrupt mask to stop board from generating interrupts */ - DEBUGOUT("Masking off all interrupts\n"); - E1000_WRITE_REG(hw, IMC, 0xffffffff); - - /* Disable the Transmit and Receive units. Then delay to allow - * any pending transactions to complete before we hit the MAC with - * the global reset. - */ - E1000_WRITE_REG(hw, RCTL, 0); - E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP); - E1000_WRITE_FLUSH(hw); - - /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */ - hw->tbi_compatibility_on = false; - - /* Delay to allow any outstanding PCI transactions to complete before - * resetting the device - */ - mdelay(10); - - /* Issue a global reset to the MAC. This will reset the chip's - * transmit, receive, DMA, and link units. It will not effect - * the current PCI configuration. The global reset bit is self- - * clearing, and should clear within a microsecond. - */ - DEBUGOUT("Issuing a global reset to MAC\n"); - ctrl = E1000_READ_REG(hw, CTRL); - - E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST)); - - /* Force a reload from the EEPROM if necessary */ - if (hw->mac_type < e1000_82540) { - /* Wait for reset to complete */ - udelay(10); - ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); - ctrl_ext |= E1000_CTRL_EXT_EE_RST; - E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); - E1000_WRITE_FLUSH(hw); - /* Wait for EEPROM reload */ - mdelay(2); - } else { - /* Wait for EEPROM reload (it happens automatically) */ - mdelay(4); - /* Dissable HW ARPs on ASF enabled adapters */ - manc = E1000_READ_REG(hw, MANC); - manc &= ~(E1000_MANC_ARP_EN); - E1000_WRITE_REG(hw, MANC, manc); - } - - /* Clear interrupt mask to stop board from generating interrupts */ - DEBUGOUT("Masking off all interrupts\n"); - E1000_WRITE_REG(hw, IMC, 0xffffffff); - - /* Clear any pending interrupt events. */ - E1000_READ_REG(hw, ICR); - - /* If MWI was previously enabled, reenable it. */ - if (hw->mac_type == e1000_82542_rev2_0) { - pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word); - } - E1000_WRITE_REG(hw, PBA, pba); -} - -/****************************************************************************** - * - * Initialize a number of hardware-dependent bits - * - * hw: Struct containing variables accessed by shared code - * - * This function contains hardware limitation workarounds for PCI-E adapters - * - *****************************************************************************/ -static void -e1000_initialize_hardware_bits(struct e1000_hw *hw) -{ - if ((hw->mac_type >= e1000_82571) && - (!hw->initialize_hw_bits_disable)) { - /* Settings common to all PCI-express silicon */ - uint32_t reg_ctrl, reg_ctrl_ext; - uint32_t reg_tarc0, reg_tarc1; - uint32_t reg_tctl; - uint32_t reg_txdctl, reg_txdctl1; - - /* link autonegotiation/sync workarounds */ - reg_tarc0 = E1000_READ_REG(hw, TARC0); - reg_tarc0 &= ~((1 << 30)|(1 << 29)|(1 << 28)|(1 << 27)); - - /* Enable not-done TX descriptor counting */ - reg_txdctl = E1000_READ_REG(hw, TXDCTL); - reg_txdctl |= E1000_TXDCTL_COUNT_DESC; - E1000_WRITE_REG(hw, TXDCTL, reg_txdctl); - - reg_txdctl1 = E1000_READ_REG(hw, TXDCTL1); - reg_txdctl1 |= E1000_TXDCTL_COUNT_DESC; - E1000_WRITE_REG(hw, TXDCTL1, reg_txdctl1); - - switch (hw->mac_type) { - case e1000_82571: - case e1000_82572: - /* Clear PHY TX compatible mode bits */ - reg_tarc1 = E1000_READ_REG(hw, TARC1); - reg_tarc1 &= ~((1 << 30)|(1 << 29)); - - /* link autonegotiation/sync workarounds */ - reg_tarc0 |= ((1 << 26)|(1 << 25)|(1 << 24)|(1 << 23)); - - /* TX ring control fixes */ - reg_tarc1 |= ((1 << 26)|(1 << 25)|(1 << 24)); - - /* Multiple read bit is reversed polarity */ - reg_tctl = E1000_READ_REG(hw, TCTL); - if (reg_tctl & E1000_TCTL_MULR) - reg_tarc1 &= ~(1 << 28); - else - reg_tarc1 |= (1 << 28); - - E1000_WRITE_REG(hw, TARC1, reg_tarc1); - break; - case e1000_82573: - case e1000_82574: - reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); - reg_ctrl_ext &= ~(1 << 23); - reg_ctrl_ext |= (1 << 22); - - /* TX byte count fix */ - reg_ctrl = E1000_READ_REG(hw, CTRL); - reg_ctrl &= ~(1 << 29); - - E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext); - E1000_WRITE_REG(hw, CTRL, reg_ctrl); - break; - case e1000_80003es2lan: - /* improve small packet performace for fiber/serdes */ - if ((hw->media_type == e1000_media_type_fiber) - || (hw->media_type == - e1000_media_type_internal_serdes)) { - reg_tarc0 &= ~(1 << 20); - } - - /* Multiple read bit is reversed polarity */ - reg_tctl = E1000_READ_REG(hw, TCTL); - reg_tarc1 = E1000_READ_REG(hw, TARC1); - if (reg_tctl & E1000_TCTL_MULR) - reg_tarc1 &= ~(1 << 28); - else - reg_tarc1 |= (1 << 28); - - E1000_WRITE_REG(hw, TARC1, reg_tarc1); - break; - case e1000_ich8lan: - /* Reduce concurrent DMA requests to 3 from 4 */ - if ((hw->revision_id < 3) || - ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) && - (hw->device_id != E1000_DEV_ID_ICH8_IGP_M))) - reg_tarc0 |= ((1 << 29)|(1 << 28)); - - reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); - reg_ctrl_ext |= (1 << 22); - E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext); - - /* workaround TX hang with TSO=on */ - reg_tarc0 |= ((1 << 27)|(1 << 26)|(1 << 24)|(1 << 23)); - - /* Multiple read bit is reversed polarity */ - reg_tctl = E1000_READ_REG(hw, TCTL); - reg_tarc1 = E1000_READ_REG(hw, TARC1); - if (reg_tctl & E1000_TCTL_MULR) - reg_tarc1 &= ~(1 << 28); - else - reg_tarc1 |= (1 << 28); - - /* workaround TX hang with TSO=on */ - reg_tarc1 |= ((1 << 30)|(1 << 26)|(1 << 24)); - - E1000_WRITE_REG(hw, TARC1, reg_tarc1); - break; - default: - break; - } - - E1000_WRITE_REG(hw, TARC0, reg_tarc0); - } -} - -/****************************************************************************** - * Performs basic configuration of the adapter. - * - * hw - Struct containing variables accessed by shared code - * - * Assumes that the controller has previously been reset and is in a - * post-reset uninitialized state. Initializes the receive address registers, - * multicast table, and VLAN filter table. Calls routines to setup link - * configuration and flow control settings. Clears all on-chip counters. Leaves - * the transmit and receive units disabled and uninitialized. - *****************************************************************************/ -static int -e1000_init_hw(struct eth_device *nic) -{ - struct e1000_hw *hw = nic->priv; - uint32_t ctrl; - uint32_t i; - int32_t ret_val; - uint16_t pcix_cmd_word; - uint16_t pcix_stat_hi_word; - uint16_t cmd_mmrbc; - uint16_t stat_mmrbc; - uint32_t mta_size; - uint32_t reg_data; - uint32_t ctrl_ext; - DEBUGFUNC(); - /* force full DMA clock frequency for 10/100 on ICH8 A0-B0 */ - if ((hw->mac_type == e1000_ich8lan) && - ((hw->revision_id < 3) || - ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) && - (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))) { - reg_data = E1000_READ_REG(hw, STATUS); - reg_data &= ~0x80000000; - E1000_WRITE_REG(hw, STATUS, reg_data); - } - /* Do not need initialize Identification LED */ - - /* Set the media type and TBI compatibility */ - e1000_set_media_type(hw); - - /* Must be called after e1000_set_media_type - * because media_type is used */ - e1000_initialize_hardware_bits(hw); - - /* Disabling VLAN filtering. */ - DEBUGOUT("Initializing the IEEE VLAN\n"); - /* VET hardcoded to standard value and VFTA removed in ICH8 LAN */ - if (hw->mac_type != e1000_ich8lan) { - if (hw->mac_type < e1000_82545_rev_3) - E1000_WRITE_REG(hw, VET, 0); - e1000_clear_vfta(hw); - } - - /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */ - if (hw->mac_type == e1000_82542_rev2_0) { - DEBUGOUT("Disabling MWI on 82542 rev 2.0\n"); - pci_write_config_word(hw->pdev, PCI_COMMAND, - hw-> - pci_cmd_word & ~PCI_COMMAND_INVALIDATE); - E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST); - E1000_WRITE_FLUSH(hw); - mdelay(5); - } - - /* Setup the receive address. This involves initializing all of the Receive - * Address Registers (RARs 0 - 15). - */ - e1000_init_rx_addrs(nic); - - /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */ - if (hw->mac_type == e1000_82542_rev2_0) { - E1000_WRITE_REG(hw, RCTL, 0); - E1000_WRITE_FLUSH(hw); - mdelay(1); - pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word); - } - - /* Zero out the Multicast HASH table */ - DEBUGOUT("Zeroing the MTA\n"); - mta_size = E1000_MC_TBL_SIZE; - if (hw->mac_type == e1000_ich8lan) - mta_size = E1000_MC_TBL_SIZE_ICH8LAN; - for (i = 0; i < mta_size; i++) { - E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); - /* use write flush to prevent Memory Write Block (MWB) from - * occuring when accessing our register space */ - E1000_WRITE_FLUSH(hw); - } -#if 0 - /* Set the PCI priority bit correctly in the CTRL register. This - * determines if the adapter gives priority to receives, or if it - * gives equal priority to transmits and receives. Valid only on - * 82542 and 82543 silicon. - */ - if (hw->dma_fairness && hw->mac_type <= e1000_82543) { - ctrl = E1000_READ_REG(hw, CTRL); - E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR); - } -#endif - switch (hw->mac_type) { - case e1000_82545_rev_3: - case e1000_82546_rev_3: - break; - default: - /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */ - if (hw->bus_type == e1000_bus_type_pcix) { - pci_read_config_word(hw->pdev, PCIX_COMMAND_REGISTER, - &pcix_cmd_word); - pci_read_config_word(hw->pdev, PCIX_STATUS_REGISTER_HI, - &pcix_stat_hi_word); - cmd_mmrbc = - (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >> - PCIX_COMMAND_MMRBC_SHIFT; - stat_mmrbc = - (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >> - PCIX_STATUS_HI_MMRBC_SHIFT; - if (stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K) - stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K; - if (cmd_mmrbc > stat_mmrbc) { - pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK; - pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT; - pci_write_config_word(hw->pdev, PCIX_COMMAND_REGISTER, - pcix_cmd_word); - } - } - break; - } - - /* More time needed for PHY to initialize */ - if (hw->mac_type == e1000_ich8lan) - mdelay(15); - - /* Call a subroutine to configure the link and setup flow control. */ - ret_val = e1000_setup_link(nic); - - /* Set the transmit descriptor write-back policy */ - if (hw->mac_type > e1000_82544) { - ctrl = E1000_READ_REG(hw, TXDCTL); - ctrl = - (ctrl & ~E1000_TXDCTL_WTHRESH) | - E1000_TXDCTL_FULL_TX_DESC_WB; - E1000_WRITE_REG(hw, TXDCTL, ctrl); - } - - /* Set the receive descriptor write back policy */ - - if (hw->mac_type >= e1000_82571) { - ctrl = E1000_READ_REG(hw, RXDCTL); - ctrl = - (ctrl & ~E1000_RXDCTL_WTHRESH) | - E1000_RXDCTL_FULL_RX_DESC_WB; - E1000_WRITE_REG(hw, RXDCTL, ctrl); - } - - switch (hw->mac_type) { - default: - break; - case e1000_80003es2lan: - /* Enable retransmit on late collisions */ - reg_data = E1000_READ_REG(hw, TCTL); - reg_data |= E1000_TCTL_RTLC; - E1000_WRITE_REG(hw, TCTL, reg_data); - - /* Configure Gigabit Carry Extend Padding */ - reg_data = E1000_READ_REG(hw, TCTL_EXT); - reg_data &= ~E1000_TCTL_EXT_GCEX_MASK; - reg_data |= DEFAULT_80003ES2LAN_TCTL_EXT_GCEX; - E1000_WRITE_REG(hw, TCTL_EXT, reg_data); - - /* Configure Transmit Inter-Packet Gap */ - reg_data = E1000_READ_REG(hw, TIPG); - reg_data &= ~E1000_TIPG_IPGT_MASK; - reg_data |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000; - E1000_WRITE_REG(hw, TIPG, reg_data); - - reg_data = E1000_READ_REG_ARRAY(hw, FFLT, 0x0001); - reg_data &= ~0x00100000; - E1000_WRITE_REG_ARRAY(hw, FFLT, 0x0001, reg_data); - /* Fall through */ - case e1000_82571: - case e1000_82572: - case e1000_ich8lan: - ctrl = E1000_READ_REG(hw, TXDCTL1); - ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) - | E1000_TXDCTL_FULL_TX_DESC_WB; - E1000_WRITE_REG(hw, TXDCTL1, ctrl); - break; - case e1000_82573: - case e1000_82574: - reg_data = E1000_READ_REG(hw, GCR); - reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX; - E1000_WRITE_REG(hw, GCR, reg_data); - } - -#if 0 - /* Clear all of the statistics registers (clear on read). It is - * important that we do this after we have tried to establish link - * because the symbol error count will increment wildly if there - * is no link. - */ - e1000_clear_hw_cntrs(hw); - - /* ICH8 No-snoop bits are opposite polarity. - * Set to snoop by default after reset. */ - if (hw->mac_type == e1000_ich8lan) - e1000_set_pci_ex_no_snoop(hw, PCI_EX_82566_SNOOP_ALL); -#endif - - if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER || - hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) { - ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); - /* Relaxed ordering must be disabled to avoid a parity - * error crash in a PCI slot. */ - ctrl_ext |= E1000_CTRL_EXT_RO_DIS; - E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); - } - - return ret_val; -} - -/****************************************************************************** - * Configures flow control and link settings. - * - * hw - Struct containing variables accessed by shared code - * - * Determines which flow control settings to use. Calls the apropriate media- - * specific link configuration function. Configures the flow control settings. - * Assuming the adapter has a valid link partner, a valid link should be - * established. Assumes the hardware has previously been reset and the - * transmitter and receiver are not enabled. - *****************************************************************************/ -static int -e1000_setup_link(struct eth_device *nic) -{ - struct e1000_hw *hw = nic->priv; - int32_t ret_val; -#ifndef CONFIG_E1000_NO_NVM - uint32_t ctrl_ext; - uint16_t eeprom_data; -#endif - - DEBUGFUNC(); - - /* In the case of the phy reset being blocked, we already have a link. - * We do not have to set it up again. */ - if (e1000_check_phy_reset_block(hw)) - return E1000_SUCCESS; - -#ifndef CONFIG_E1000_NO_NVM - /* Read and store word 0x0F of the EEPROM. This word contains bits - * that determine the hardware's default PAUSE (flow control) mode, - * a bit that determines whether the HW defaults to enabling or - * disabling auto-negotiation, and the direction of the - * SW defined pins. If there is no SW over-ride of the flow - * control setting, then the variable hw->fc will - * be initialized based on a value in the EEPROM. - */ - if (e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, - &eeprom_data) < 0) { - DEBUGOUT("EEPROM Read Error\n"); - return -E1000_ERR_EEPROM; - } -#endif - if (hw->fc == e1000_fc_default) { - switch (hw->mac_type) { - case e1000_ich8lan: - case e1000_82573: - case e1000_82574: - hw->fc = e1000_fc_full; - break; - default: -#ifndef CONFIG_E1000_NO_NVM - ret_val = e1000_read_eeprom(hw, - EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data); - if (ret_val) { - DEBUGOUT("EEPROM Read Error\n"); - return -E1000_ERR_EEPROM; - } - if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0) - hw->fc = e1000_fc_none; - else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == - EEPROM_WORD0F_ASM_DIR) - hw->fc = e1000_fc_tx_pause; - else -#endif - hw->fc = e1000_fc_full; - break; - } - } - - /* We want to save off the original Flow Control configuration just - * in case we get disconnected and then reconnected into a different - * hub or switch with different Flow Control capabilities. - */ - if (hw->mac_type == e1000_82542_rev2_0) - hw->fc &= (~e1000_fc_tx_pause); - - if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1)) - hw->fc &= (~e1000_fc_rx_pause); - - hw->original_fc = hw->fc; - - DEBUGOUT("After fix-ups FlowControl is now = %x\n", hw->fc); - -#ifndef CONFIG_E1000_NO_NVM - /* Take the 4 bits from EEPROM word 0x0F that determine the initial - * polarity value for the SW controlled pins, and setup the - * Extended Device Control reg with that info. - * This is needed because one of the SW controlled pins is used for - * signal detection. So this should be done before e1000_setup_pcs_link() - * or e1000_phy_setup() is called. - */ - if (hw->mac_type == e1000_82543) { - ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) << - SWDPIO__EXT_SHIFT); - E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); - } -#endif - - /* Call the necessary subroutine to configure the link. */ - ret_val = (hw->media_type == e1000_media_type_fiber) ? - e1000_setup_fiber_link(nic) : e1000_setup_copper_link(nic); - if (ret_val < 0) { - return ret_val; - } - - /* Initialize the flow control address, type, and PAUSE timer - * registers to their default values. This is done even if flow - * control is disabled, because it does not hurt anything to - * initialize these registers. - */ - DEBUGOUT("Initializing the Flow Control address, type" - "and timer regs\n"); - - /* FCAL/H and FCT are hardcoded to standard values in e1000_ich8lan. */ - if (hw->mac_type != e1000_ich8lan) { - E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE); - E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH); - E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW); - } - - E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time); - - /* Set the flow control receive threshold registers. Normally, - * these registers will be set to a default threshold that may be - * adjusted later by the driver's runtime code. However, if the - * ability to transmit pause frames in not enabled, then these - * registers will be set to 0. - */ - if (!(hw->fc & e1000_fc_tx_pause)) { - E1000_WRITE_REG(hw, FCRTL, 0); - E1000_WRITE_REG(hw, FCRTH, 0); - } else { - /* We need to set up the Receive Threshold high and low water marks - * as well as (optionally) enabling the transmission of XON frames. - */ - if (hw->fc_send_xon) { - E1000_WRITE_REG(hw, FCRTL, - (hw->fc_low_water | E1000_FCRTL_XONE)); - E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water); - } else { - E1000_WRITE_REG(hw, FCRTL, hw->fc_low_water); - E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water); - } - } - return ret_val; -} - -/****************************************************************************** - * Sets up link for a fiber based adapter - * - * hw - Struct containing variables accessed by shared code - * - * Manipulates Physical Coding Sublayer functions in order to configure - * link. Assumes the hardware has been previously reset and the transmitter - * and receiver are not enabled. - *****************************************************************************/ -static int -e1000_setup_fiber_link(struct eth_device *nic) -{ - struct e1000_hw *hw = nic->priv; - uint32_t ctrl; - uint32_t status; - uint32_t txcw = 0; - uint32_t i; - uint32_t signal; - int32_t ret_val; - - DEBUGFUNC(); - /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be - * set when the optics detect a signal. On older adapters, it will be - * cleared when there is a signal - */ - ctrl = E1000_READ_REG(hw, CTRL); - if ((hw->mac_type > e1000_82544) && !(ctrl & E1000_CTRL_ILOS)) - signal = E1000_CTRL_SWDPIN1; - else - signal = 0; - - printf("signal for %s is %x (ctrl %08x)!!!!\n", nic->name, signal, - ctrl); - /* Take the link out of reset */ - ctrl &= ~(E1000_CTRL_LRST); - - e1000_config_collision_dist(hw); - - /* Check for a software override of the flow control settings, and setup - * the device accordingly. If auto-negotiation is enabled, then software - * will have to set the "PAUSE" bits to the correct value in the Tranmsit - * Config Word Register (TXCW) and re-start auto-negotiation. However, if - * auto-negotiation is disabled, then software will have to manually - * configure the two flow control enable bits in the CTRL register. - * - * The possible values of the "fc" parameter are: - * 0: Flow control is completely disabled - * 1: Rx flow control is enabled (we can receive pause frames, but - * not send pause frames). - * 2: Tx flow control is enabled (we can send pause frames but we do - * not support receiving pause frames). - * 3: Both Rx and TX flow control (symmetric) are enabled. - */ - switch (hw->fc) { - case e1000_fc_none: - /* Flow control is completely disabled by a software over-ride. */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD); - break; - case e1000_fc_rx_pause: - /* RX Flow control is enabled and TX Flow control is disabled by a - * software over-ride. Since there really isn't a way to advertise - * that we are capable of RX Pause ONLY, we will advertise that we - * support both symmetric and asymmetric RX PAUSE. Later, we will - * disable the adapter's ability to send PAUSE frames. - */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); - break; - case e1000_fc_tx_pause: - /* TX Flow control is enabled, and RX Flow control is disabled, by a - * software over-ride. - */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR); - break; - case e1000_fc_full: - /* Flow control (both RX and TX) is enabled by a software over-ride. */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); - break; - default: - DEBUGOUT("Flow control param set incorrectly\n"); - return -E1000_ERR_CONFIG; - break; - } - - /* Since auto-negotiation is enabled, take the link out of reset (the link - * will be in reset, because we previously reset the chip). This will - * restart auto-negotiation. If auto-neogtiation is successful then the - * link-up status bit will be set and the flow control enable bits (RFCE - * and TFCE) will be set according to their negotiated value. - */ - DEBUGOUT("Auto-negotiation enabled (%#x)\n", txcw); - - E1000_WRITE_REG(hw, TXCW, txcw); - E1000_WRITE_REG(hw, CTRL, ctrl); - E1000_WRITE_FLUSH(hw); - - hw->txcw = txcw; - mdelay(1); - - /* If we have a signal (the cable is plugged in) then poll for a "Link-Up" - * indication in the Device Status Register. Time-out if a link isn't - * seen in 500 milliseconds seconds (Auto-negotiation should complete in - * less than 500 milliseconds even if the other end is doing it in SW). - */ - if ((E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) { - DEBUGOUT("Looking for Link\n"); - for (i = 0; i < (LINK_UP_TIMEOUT / 10); i++) { - mdelay(10); - status = E1000_READ_REG(hw, STATUS); - if (status & E1000_STATUS_LU) - break; - } - if (i == (LINK_UP_TIMEOUT / 10)) { - /* AutoNeg failed to achieve a link, so we'll call - * e1000_check_for_link. This routine will force the link up if we - * detect a signal. This will allow us to communicate with - * non-autonegotiating link partners. - */ - DEBUGOUT("Never got a valid link from auto-neg!!!\n"); - hw->autoneg_failed = 1; - ret_val = e1000_check_for_link(nic); - if (ret_val < 0) { - DEBUGOUT("Error while checking for link\n"); - return ret_val; - } - hw->autoneg_failed = 0; - } else { - hw->autoneg_failed = 0; - DEBUGOUT("Valid Link Found\n"); - } - } else { - DEBUGOUT("No Signal Detected\n"); - return -E1000_ERR_NOLINK; - } - return 0; -} - -/****************************************************************************** -* Make sure we have a valid PHY and change PHY mode before link setup. -* -* hw - Struct containing variables accessed by shared code -******************************************************************************/ -static int32_t -e1000_copper_link_preconfig(struct e1000_hw *hw) -{ - uint32_t ctrl; - int32_t ret_val; - uint16_t phy_data; - - DEBUGFUNC(); - - ctrl = E1000_READ_REG(hw, CTRL); - /* With 82543, we need to force speed and duplex on the MAC equal to what - * the PHY speed and duplex configuration is. In addition, we need to - * perform a hardware reset on the PHY to take it out of reset. - */ - if (hw->mac_type > e1000_82543) { - ctrl |= E1000_CTRL_SLU; - ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); - E1000_WRITE_REG(hw, CTRL, ctrl); - } else { - ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX - | E1000_CTRL_SLU); - E1000_WRITE_REG(hw, CTRL, ctrl); - ret_val = e1000_phy_hw_reset(hw); - if (ret_val) - return ret_val; - } - - /* Make sure we have a valid PHY */ - ret_val = e1000_detect_gig_phy(hw); - if (ret_val) { - DEBUGOUT("Error, did not detect valid phy.\n"); - return ret_val; - } - DEBUGOUT("Phy ID = %x \n", hw->phy_id); - - /* Set PHY to class A mode (if necessary) */ - ret_val = e1000_set_phy_mode(hw); - if (ret_val) - return ret_val; - if ((hw->mac_type == e1000_82545_rev_3) || - (hw->mac_type == e1000_82546_rev_3)) { - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, - &phy_data); - phy_data |= 0x00000008; - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, - phy_data); - } - - if (hw->mac_type <= e1000_82543 || - hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 || - hw->mac_type == e1000_82541_rev_2 - || hw->mac_type == e1000_82547_rev_2) - hw->phy_reset_disable = false; - - return E1000_SUCCESS; -} - -/***************************************************************************** - * - * This function sets the lplu state according to the active flag. When - * activating lplu this function also disables smart speed and vise versa. - * lplu will not be activated unless the device autonegotiation advertisment - * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes. - * hw: Struct containing variables accessed by shared code - * active - true to enable lplu false to disable lplu. - * - * returns: - E1000_ERR_PHY if fail to read/write the PHY - * E1000_SUCCESS at any other case. - * - ****************************************************************************/ - -static int32_t -e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active) -{ - uint32_t phy_ctrl = 0; - int32_t ret_val; - uint16_t phy_data; - DEBUGFUNC(); - - if (hw->phy_type != e1000_phy_igp && hw->phy_type != e1000_phy_igp_2 - && hw->phy_type != e1000_phy_igp_3) - return E1000_SUCCESS; - - /* During driver activity LPLU should not be used or it will attain link - * from the lowest speeds starting from 10Mbps. The capability is used - * for Dx transitions and states */ - if (hw->mac_type == e1000_82541_rev_2 - || hw->mac_type == e1000_82547_rev_2) { - ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, - &phy_data); - if (ret_val) - return ret_val; - } else if (hw->mac_type == e1000_ich8lan) { - /* MAC writes into PHY register based on the state transition - * and start auto-negotiation. SW driver can overwrite the - * settings in CSR PHY power control E1000_PHY_CTRL register. */ - phy_ctrl = E1000_READ_REG(hw, PHY_CTRL); - } else { - ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, - &phy_data); - if (ret_val) - return ret_val; - } - - if (!active) { - if (hw->mac_type == e1000_82541_rev_2 || - hw->mac_type == e1000_82547_rev_2) { - phy_data &= ~IGP01E1000_GMII_FLEX_SPD; - ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, - phy_data); - if (ret_val) - return ret_val; - } else { - if (hw->mac_type == e1000_ich8lan) { - phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU; - E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); - } else { - phy_data &= ~IGP02E1000_PM_D3_LPLU; - ret_val = e1000_write_phy_reg(hw, - IGP02E1000_PHY_POWER_MGMT, phy_data); - if (ret_val) - return ret_val; - } - } - - /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during - * Dx states where the power conservation is most important. During - * driver activity we should enable SmartSpeed, so performance is - * maintained. */ - if (hw->smart_speed == e1000_smart_speed_on) { - ret_val = e1000_read_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, &phy_data); - if (ret_val) - return ret_val; - - phy_data |= IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, phy_data); - if (ret_val) - return ret_val; - } else if (hw->smart_speed == e1000_smart_speed_off) { - ret_val = e1000_read_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, &phy_data); - if (ret_val) - return ret_val; - - phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, phy_data); - if (ret_val) - return ret_val; - } - - } else if ((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) - || (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL) || - (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) { - - if (hw->mac_type == e1000_82541_rev_2 || - hw->mac_type == e1000_82547_rev_2) { - phy_data |= IGP01E1000_GMII_FLEX_SPD; - ret_val = e1000_write_phy_reg(hw, - IGP01E1000_GMII_FIFO, phy_data); - if (ret_val) - return ret_val; - } else { - if (hw->mac_type == e1000_ich8lan) { - phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU; - E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); - } else { - phy_data |= IGP02E1000_PM_D3_LPLU; - ret_val = e1000_write_phy_reg(hw, - IGP02E1000_PHY_POWER_MGMT, phy_data); - if (ret_val) - return ret_val; - } - } - - /* When LPLU is enabled we should disable SmartSpeed */ - ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, - &phy_data); - if (ret_val) - return ret_val; - - phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, - phy_data); - if (ret_val) - return ret_val; - } - return E1000_SUCCESS; -} - -/***************************************************************************** - * - * This function sets the lplu d0 state according to the active flag. When - * activating lplu this function also disables smart speed and vise versa. - * lplu will not be activated unless the device autonegotiation advertisment - * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes. - * hw: Struct containing variables accessed by shared code - * active - true to enable lplu false to disable lplu. - * - * returns: - E1000_ERR_PHY if fail to read/write the PHY - * E1000_SUCCESS at any other case. - * - ****************************************************************************/ - -static int32_t -e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) -{ - uint32_t phy_ctrl = 0; - int32_t ret_val; - uint16_t phy_data; - DEBUGFUNC(); - - if (hw->mac_type <= e1000_82547_rev_2) - return E1000_SUCCESS; - - if (hw->mac_type == e1000_ich8lan) { - phy_ctrl = E1000_READ_REG(hw, PHY_CTRL); - } else { - ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, - &phy_data); - if (ret_val) - return ret_val; - } - - if (!active) { - if (hw->mac_type == e1000_ich8lan) { - phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU; - E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); - } else { - phy_data &= ~IGP02E1000_PM_D0_LPLU; - ret_val = e1000_write_phy_reg(hw, - IGP02E1000_PHY_POWER_MGMT, phy_data); - if (ret_val) - return ret_val; - } - - /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during - * Dx states where the power conservation is most important. During - * driver activity we should enable SmartSpeed, so performance is - * maintained. */ - if (hw->smart_speed == e1000_smart_speed_on) { - ret_val = e1000_read_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, &phy_data); - if (ret_val) - return ret_val; - - phy_data |= IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, phy_data); - if (ret_val) - return ret_val; - } else if (hw->smart_speed == e1000_smart_speed_off) { - ret_val = e1000_read_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, &phy_data); - if (ret_val) - return ret_val; - - phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, phy_data); - if (ret_val) - return ret_val; - } - - - } else { - - if (hw->mac_type == e1000_ich8lan) { - phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU; - E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); - } else { - phy_data |= IGP02E1000_PM_D0_LPLU; - ret_val = e1000_write_phy_reg(hw, - IGP02E1000_PHY_POWER_MGMT, phy_data); - if (ret_val) - return ret_val; - } - - /* When LPLU is enabled we should disable SmartSpeed */ - ret_val = e1000_read_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, &phy_data); - if (ret_val) - return ret_val; - - phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, phy_data); - if (ret_val) - return ret_val; - - } - return E1000_SUCCESS; -} - -/******************************************************************** -* Copper link setup for e1000_phy_igp series. -* -* hw - Struct containing variables accessed by shared code -*********************************************************************/ -static int32_t -e1000_copper_link_igp_setup(struct e1000_hw *hw) -{ - uint32_t led_ctrl; - int32_t ret_val; - uint16_t phy_data; - - DEBUGFUNC(); - - if (hw->phy_reset_disable) - return E1000_SUCCESS; - - ret_val = e1000_phy_reset(hw); - if (ret_val) { - DEBUGOUT("Error Resetting the PHY\n"); - return ret_val; - } - - /* Wait 15ms for MAC to configure PHY from eeprom settings */ - mdelay(15); - if (hw->mac_type != e1000_ich8lan) { - /* Configure activity LED after PHY reset */ - led_ctrl = E1000_READ_REG(hw, LEDCTL); - led_ctrl &= IGP_ACTIVITY_LED_MASK; - led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); - E1000_WRITE_REG(hw, LEDCTL, led_ctrl); - } - - /* The NVM settings will configure LPLU in D3 for IGP2 and IGP3 PHYs */ - if (hw->phy_type == e1000_phy_igp) { - /* disable lplu d3 during driver init */ - ret_val = e1000_set_d3_lplu_state(hw, false); - if (ret_val) { - DEBUGOUT("Error Disabling LPLU D3\n"); - return ret_val; - } - } - - /* disable lplu d0 during driver init */ - ret_val = e1000_set_d0_lplu_state(hw, false); - if (ret_val) { - DEBUGOUT("Error Disabling LPLU D0\n"); - return ret_val; - } - /* Configure mdi-mdix settings */ - ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data); - if (ret_val) - return ret_val; - - if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { - hw->dsp_config_state = e1000_dsp_config_disabled; - /* Force MDI for earlier revs of the IGP PHY */ - phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX - | IGP01E1000_PSCR_FORCE_MDI_MDIX); - hw->mdix = 1; - - } else { - hw->dsp_config_state = e1000_dsp_config_enabled; - phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX; - - switch (hw->mdix) { - case 1: - phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; - break; - case 2: - phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX; - break; - case 0: - default: - phy_data |= IGP01E1000_PSCR_AUTO_MDIX; - break; - } - } - ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data); - if (ret_val) - return ret_val; - - /* set auto-master slave resolution settings */ - if (hw->autoneg) { - e1000_ms_type phy_ms_setting = hw->master_slave; - - if (hw->ffe_config_state == e1000_ffe_config_active) - hw->ffe_config_state = e1000_ffe_config_enabled; - - if (hw->dsp_config_state == e1000_dsp_config_activated) - hw->dsp_config_state = e1000_dsp_config_enabled; - - /* when autonegotiation advertisment is only 1000Mbps then we - * should disable SmartSpeed and enable Auto MasterSlave - * resolution as hardware default. */ - if (hw->autoneg_advertised == ADVERTISE_1000_FULL) { - /* Disable SmartSpeed */ - ret_val = e1000_read_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, &phy_data); - if (ret_val) - return ret_val; - phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, phy_data); - if (ret_val) - return ret_val; - /* Set auto Master/Slave resolution process */ - ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, - &phy_data); - if (ret_val) - return ret_val; - phy_data &= ~CR_1000T_MS_ENABLE; - ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, - phy_data); - if (ret_val) - return ret_val; - } - - ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data); - if (ret_val) - return ret_val; - - /* load defaults for future use */ - hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ? - ((phy_data & CR_1000T_MS_VALUE) ? - e1000_ms_force_master : - e1000_ms_force_slave) : - e1000_ms_auto; - - switch (phy_ms_setting) { - case e1000_ms_force_master: - phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE); - break; - case e1000_ms_force_slave: - phy_data |= CR_1000T_MS_ENABLE; - phy_data &= ~(CR_1000T_MS_VALUE); - break; - case e1000_ms_auto: - phy_data &= ~CR_1000T_MS_ENABLE; - default: - break; - } - ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data); - if (ret_val) - return ret_val; - } - - return E1000_SUCCESS; -} - -/***************************************************************************** - * This function checks the mode of the firmware. - * - * returns - true when the mode is IAMT or false. - ****************************************************************************/ -bool -e1000_check_mng_mode(struct e1000_hw *hw) -{ - uint32_t fwsm; - DEBUGFUNC(); - - fwsm = E1000_READ_REG(hw, FWSM); - - if (hw->mac_type == e1000_ich8lan) { - if ((fwsm & E1000_FWSM_MODE_MASK) == - (E1000_MNG_ICH_IAMT_MODE << E1000_FWSM_MODE_SHIFT)) - return true; - } else if ((fwsm & E1000_FWSM_MODE_MASK) == - (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT)) - return true; - - return false; -} - -static int32_t -e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data) -{ - uint16_t swfw = E1000_SWFW_PHY0_SM; - uint32_t reg_val; - DEBUGFUNC(); - - if (e1000_is_second_port(hw)) - swfw = E1000_SWFW_PHY1_SM; - - if (e1000_swfw_sync_acquire(hw, swfw)) - return -E1000_ERR_SWFW_SYNC; - - reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) - & E1000_KUMCTRLSTA_OFFSET) | data; - E1000_WRITE_REG(hw, KUMCTRLSTA, reg_val); - udelay(2); - - return E1000_SUCCESS; -} - -static int32_t -e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *data) -{ - uint16_t swfw = E1000_SWFW_PHY0_SM; - uint32_t reg_val; - DEBUGFUNC(); - - if (e1000_is_second_port(hw)) - swfw = E1000_SWFW_PHY1_SM; - - if (e1000_swfw_sync_acquire(hw, swfw)) - return -E1000_ERR_SWFW_SYNC; - - /* Write register address */ - reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) & - E1000_KUMCTRLSTA_OFFSET) | E1000_KUMCTRLSTA_REN; - E1000_WRITE_REG(hw, KUMCTRLSTA, reg_val); - udelay(2); - - /* Read the data returned */ - reg_val = E1000_READ_REG(hw, KUMCTRLSTA); - *data = (uint16_t)reg_val; - - return E1000_SUCCESS; -} - -/******************************************************************** -* Copper link setup for e1000_phy_gg82563 series. -* -* hw - Struct containing variables accessed by shared code -*********************************************************************/ -static int32_t -e1000_copper_link_ggp_setup(struct e1000_hw *hw) -{ - int32_t ret_val; - uint16_t phy_data; - uint32_t reg_data; - - DEBUGFUNC(); - - if (!hw->phy_reset_disable) { - /* Enable CRS on TX for half-duplex operation. */ - ret_val = e1000_read_phy_reg(hw, - GG82563_PHY_MAC_SPEC_CTRL, &phy_data); - if (ret_val) - return ret_val; - - phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX; - /* Use 25MHz for both link down and 1000BASE-T for Tx clock */ - phy_data |= GG82563_MSCR_TX_CLK_1000MBPS_25MHZ; - - ret_val = e1000_write_phy_reg(hw, - GG82563_PHY_MAC_SPEC_CTRL, phy_data); - if (ret_val) - return ret_val; - - /* Options: - * MDI/MDI-X = 0 (default) - * 0 - Auto for all speeds - * 1 - MDI mode - * 2 - MDI-X mode - * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) - */ - ret_val = e1000_read_phy_reg(hw, - GG82563_PHY_SPEC_CTRL, &phy_data); - if (ret_val) - return ret_val; - - phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK; - - switch (hw->mdix) { - case 1: - phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDI; - break; - case 2: - phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDIX; - break; - case 0: - default: - phy_data |= GG82563_PSCR_CROSSOVER_MODE_AUTO; - break; - } - - /* Options: - * disable_polarity_correction = 0 (default) - * Automatic Correction for Reversed Cable Polarity - * 0 - Disabled - * 1 - Enabled - */ - phy_data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE; - ret_val = e1000_write_phy_reg(hw, - GG82563_PHY_SPEC_CTRL, phy_data); - - if (ret_val) - return ret_val; - - /* SW Reset the PHY so all changes take effect */ - ret_val = e1000_phy_reset(hw); - if (ret_val) { - DEBUGOUT("Error Resetting the PHY\n"); - return ret_val; - } - } /* phy_reset_disable */ - - if (hw->mac_type == e1000_80003es2lan) { - /* Bypass RX and TX FIFO's */ - ret_val = e1000_write_kmrn_reg(hw, - E1000_KUMCTRLSTA_OFFSET_FIFO_CTRL, - E1000_KUMCTRLSTA_FIFO_CTRL_RX_BYPASS - | E1000_KUMCTRLSTA_FIFO_CTRL_TX_BYPASS); - if (ret_val) - return ret_val; - - ret_val = e1000_read_phy_reg(hw, - GG82563_PHY_SPEC_CTRL_2, &phy_data); - if (ret_val) - return ret_val; - - phy_data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG; - ret_val = e1000_write_phy_reg(hw, - GG82563_PHY_SPEC_CTRL_2, phy_data); - - if (ret_val) - return ret_val; - - reg_data = E1000_READ_REG(hw, CTRL_EXT); - reg_data &= ~(E1000_CTRL_EXT_LINK_MODE_MASK); - E1000_WRITE_REG(hw, CTRL_EXT, reg_data); - - ret_val = e1000_read_phy_reg(hw, - GG82563_PHY_PWR_MGMT_CTRL, &phy_data); - if (ret_val) - return ret_val; - - /* Do not init these registers when the HW is in IAMT mode, since the - * firmware will have already initialized them. We only initialize - * them if the HW is not in IAMT mode. - */ - if (e1000_check_mng_mode(hw) == false) { - /* Enable Electrical Idle on the PHY */ - phy_data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE; - ret_val = e1000_write_phy_reg(hw, - GG82563_PHY_PWR_MGMT_CTRL, phy_data); - if (ret_val) - return ret_val; - - ret_val = e1000_read_phy_reg(hw, - GG82563_PHY_KMRN_MODE_CTRL, &phy_data); - if (ret_val) - return ret_val; - - phy_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; - ret_val = e1000_write_phy_reg(hw, - GG82563_PHY_KMRN_MODE_CTRL, phy_data); - - if (ret_val) - return ret_val; - } - - /* Workaround: Disable padding in Kumeran interface in the MAC - * and in the PHY to avoid CRC errors. - */ - ret_val = e1000_read_phy_reg(hw, - GG82563_PHY_INBAND_CTRL, &phy_data); - if (ret_val) - return ret_val; - phy_data |= GG82563_ICR_DIS_PADDING; - ret_val = e1000_write_phy_reg(hw, - GG82563_PHY_INBAND_CTRL, phy_data); - if (ret_val) - return ret_val; - } - return E1000_SUCCESS; -} - -/******************************************************************** -* Copper link setup for e1000_phy_m88 series. -* -* hw - Struct containing variables accessed by shared code -*********************************************************************/ -static int32_t -e1000_copper_link_mgp_setup(struct e1000_hw *hw) -{ - int32_t ret_val; - uint16_t phy_data; - - DEBUGFUNC(); - - if (hw->phy_reset_disable) - return E1000_SUCCESS; - - /* Enable CRS on TX. This must be set for half-duplex operation. */ - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); - if (ret_val) - return ret_val; - - phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; - - /* Options: - * MDI/MDI-X = 0 (default) - * 0 - Auto for all speeds - * 1 - MDI mode - * 2 - MDI-X mode - * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) - */ - phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; - - switch (hw->mdix) { - case 1: - phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE; - break; - case 2: - phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE; - break; - case 3: - phy_data |= M88E1000_PSCR_AUTO_X_1000T; - break; - case 0: - default: - phy_data |= M88E1000_PSCR_AUTO_X_MODE; - break; - } - - /* Options: - * disable_polarity_correction = 0 (default) - * Automatic Correction for Reversed Cable Polarity - * 0 - Disabled - * 1 - Enabled - */ - phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); - if (ret_val) - return ret_val; - - if (hw->phy_revision < M88E1011_I_REV_4) { - /* Force TX_CLK in the Extended PHY Specific Control Register - * to 25MHz clock. - */ - ret_val = e1000_read_phy_reg(hw, - M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); - if (ret_val) - return ret_val; - - phy_data |= M88E1000_EPSCR_TX_CLK_25; - - if ((hw->phy_revision == E1000_REVISION_2) && - (hw->phy_id == M88E1111_I_PHY_ID)) { - /* Vidalia Phy, set the downshift counter to 5x */ - phy_data &= ~(M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK); - phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X; - ret_val = e1000_write_phy_reg(hw, - M88E1000_EXT_PHY_SPEC_CTRL, phy_data); - if (ret_val) - return ret_val; - } else { - /* Configure Master and Slave downshift values */ - phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK - | M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK); - phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X - | M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X); - ret_val = e1000_write_phy_reg(hw, - M88E1000_EXT_PHY_SPEC_CTRL, phy_data); - if (ret_val) - return ret_val; - } - } - - /* SW Reset the PHY so all changes take effect */ - ret_val = e1000_phy_reset(hw); - if (ret_val) { - DEBUGOUT("Error Resetting the PHY\n"); - return ret_val; - } - - return E1000_SUCCESS; -} - -/******************************************************************** -* Setup auto-negotiation and flow control advertisements, -* and then perform auto-negotiation. -* -* hw - Struct containing variables accessed by shared code -*********************************************************************/ -static int32_t -e1000_copper_link_autoneg(struct e1000_hw *hw) -{ - int32_t ret_val; - uint16_t phy_data; - - DEBUGFUNC(); - - /* Perform some bounds checking on the hw->autoneg_advertised - * parameter. If this variable is zero, then set it to the default. - */ - hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT; - - /* If autoneg_advertised is zero, we assume it was not defaulted - * by the calling code so we set to advertise full capability. - */ - if (hw->autoneg_advertised == 0) - hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT; - - /* IFE phy only supports 10/100 */ - if (hw->phy_type == e1000_phy_ife) - hw->autoneg_advertised &= AUTONEG_ADVERTISE_10_100_ALL; - - DEBUGOUT("Reconfiguring auto-neg advertisement params\n"); - ret_val = e1000_phy_setup_autoneg(hw); - if (ret_val) { - DEBUGOUT("Error Setting up Auto-Negotiation\n"); - return ret_val; - } - DEBUGOUT("Restarting Auto-Neg\n"); - - /* Restart auto-negotiation by setting the Auto Neg Enable bit and - * the Auto Neg Restart bit in the PHY control register. - */ - ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data); - if (ret_val) - return ret_val; - - phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); - ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data); - if (ret_val) - return ret_val; - - /* Does the user want to wait for Auto-Neg to complete here, or - * check at a later time (for example, callback routine). - */ - /* If we do not wait for autonegtation to complete I - * do not see a valid link status. - * wait_autoneg_complete = 1 . - */ - if (hw->wait_autoneg_complete) { - ret_val = e1000_wait_autoneg(hw); - if (ret_val) { - DEBUGOUT("Error while waiting for autoneg" - "to complete\n"); - return ret_val; - } - } - - hw->get_link_status = true; - - return E1000_SUCCESS; -} - -/****************************************************************************** -* Config the MAC and the PHY after link is up. -* 1) Set up the MAC to the current PHY speed/duplex -* if we are on 82543. If we -* are on newer silicon, we only need to configure -* collision distance in the Transmit Control Register. -* 2) Set up flow control on the MAC to that established with -* the link partner. -* 3) Config DSP to improve Gigabit link quality for some PHY revisions. -* -* hw - Struct containing variables accessed by shared code -******************************************************************************/ -static int32_t -e1000_copper_link_postconfig(struct e1000_hw *hw) -{ - int32_t ret_val; - DEBUGFUNC(); - - if (hw->mac_type >= e1000_82544) { - e1000_config_collision_dist(hw); - } else { - ret_val = e1000_config_mac_to_phy(hw); - if (ret_val) { - DEBUGOUT("Error configuring MAC to PHY settings\n"); - return ret_val; - } - } - ret_val = e1000_config_fc_after_link_up(hw); - if (ret_val) { - DEBUGOUT("Error Configuring Flow Control\n"); - return ret_val; - } - return E1000_SUCCESS; -} - -/****************************************************************************** -* Detects which PHY is present and setup the speed and duplex -* -* hw - Struct containing variables accessed by shared code -******************************************************************************/ -static int -e1000_setup_copper_link(struct eth_device *nic) -{ - struct e1000_hw *hw = nic->priv; - int32_t ret_val; - uint16_t i; - uint16_t phy_data; - uint16_t reg_data; - - DEBUGFUNC(); - - switch (hw->mac_type) { - case e1000_80003es2lan: - case e1000_ich8lan: - /* Set the mac to wait the maximum time between each - * iteration and increase the max iterations when - * polling the phy; this fixes erroneous timeouts at 10Mbps. */ - ret_val = e1000_write_kmrn_reg(hw, - GG82563_REG(0x34, 4), 0xFFFF); - if (ret_val) - return ret_val; - ret_val = e1000_read_kmrn_reg(hw, - GG82563_REG(0x34, 9), ®_data); - if (ret_val) - return ret_val; - reg_data |= 0x3F; - ret_val = e1000_write_kmrn_reg(hw, - GG82563_REG(0x34, 9), reg_data); - if (ret_val) - return ret_val; - default: - break; - } - - /* Check if it is a valid PHY and set PHY mode if necessary. */ - ret_val = e1000_copper_link_preconfig(hw); - if (ret_val) - return ret_val; - switch (hw->mac_type) { - case e1000_80003es2lan: - /* Kumeran registers are written-only */ - reg_data = - E1000_KUMCTRLSTA_INB_CTRL_LINK_STATUS_TX_TIMEOUT_DEFAULT; - reg_data |= E1000_KUMCTRLSTA_INB_CTRL_DIS_PADDING; - ret_val = e1000_write_kmrn_reg(hw, - E1000_KUMCTRLSTA_OFFSET_INB_CTRL, reg_data); - if (ret_val) - return ret_val; - break; - default: - break; - } - - if (hw->phy_type == e1000_phy_igp || - hw->phy_type == e1000_phy_igp_3 || - hw->phy_type == e1000_phy_igp_2) { - ret_val = e1000_copper_link_igp_setup(hw); - if (ret_val) - return ret_val; - } else if (hw->phy_type == e1000_phy_m88) { - ret_val = e1000_copper_link_mgp_setup(hw); - if (ret_val) - return ret_val; - } else if (hw->phy_type == e1000_phy_gg82563) { - ret_val = e1000_copper_link_ggp_setup(hw); - if (ret_val) - return ret_val; - } - - /* always auto */ - /* Setup autoneg and flow control advertisement - * and perform autonegotiation */ - ret_val = e1000_copper_link_autoneg(hw); - if (ret_val) - return ret_val; - - /* Check link status. Wait up to 100 microseconds for link to become - * valid. - */ - for (i = 0; i < 10; i++) { - ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); - if (ret_val) - return ret_val; - ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); - if (ret_val) - return ret_val; - - if (phy_data & MII_SR_LINK_STATUS) { - /* Config the MAC and PHY after link is up */ - ret_val = e1000_copper_link_postconfig(hw); - if (ret_val) - return ret_val; - - DEBUGOUT("Valid link established!!!\n"); - return E1000_SUCCESS; - } - udelay(10); - } - - DEBUGOUT("Unable to establish link!!!\n"); - return E1000_SUCCESS; -} - -/****************************************************************************** -* Configures PHY autoneg and flow control advertisement settings -* -* hw - Struct containing variables accessed by shared code -******************************************************************************/ -int32_t -e1000_phy_setup_autoneg(struct e1000_hw *hw) -{ - int32_t ret_val; - uint16_t mii_autoneg_adv_reg; - uint16_t mii_1000t_ctrl_reg; - - DEBUGFUNC(); - - /* Read the MII Auto-Neg Advertisement Register (Address 4). */ - ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg); - if (ret_val) - return ret_val; - - if (hw->phy_type != e1000_phy_ife) { - /* Read the MII 1000Base-T Control Register (Address 9). */ - ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, - &mii_1000t_ctrl_reg); - if (ret_val) - return ret_val; - } else - mii_1000t_ctrl_reg = 0; - - /* Need to parse both autoneg_advertised and fc and set up - * the appropriate PHY registers. First we will parse for - * autoneg_advertised software override. Since we can advertise - * a plethora of combinations, we need to check each bit - * individually. - */ - - /* First we clear all the 10/100 mb speed bits in the Auto-Neg - * Advertisement Register (Address 4) and the 1000 mb speed bits in - * the 1000Base-T Control Register (Address 9). - */ - mii_autoneg_adv_reg &= ~REG4_SPEED_MASK; - mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK; - - DEBUGOUT("autoneg_advertised %x\n", hw->autoneg_advertised); - - /* Do we want to advertise 10 Mb Half Duplex? */ - if (hw->autoneg_advertised & ADVERTISE_10_HALF) { - DEBUGOUT("Advertise 10mb Half duplex\n"); - mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS; - } - - /* Do we want to advertise 10 Mb Full Duplex? */ - if (hw->autoneg_advertised & ADVERTISE_10_FULL) { - DEBUGOUT("Advertise 10mb Full duplex\n"); - mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS; - } - - /* Do we want to advertise 100 Mb Half Duplex? */ - if (hw->autoneg_advertised & ADVERTISE_100_HALF) { - DEBUGOUT("Advertise 100mb Half duplex\n"); - mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS; - } - - /* Do we want to advertise 100 Mb Full Duplex? */ - if (hw->autoneg_advertised & ADVERTISE_100_FULL) { - DEBUGOUT("Advertise 100mb Full duplex\n"); - mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS; - } - - /* We do not allow the Phy to advertise 1000 Mb Half Duplex */ - if (hw->autoneg_advertised & ADVERTISE_1000_HALF) { - DEBUGOUT - ("Advertise 1000mb Half duplex requested, request denied!\n"); - } - - /* Do we want to advertise 1000 Mb Full Duplex? */ - if (hw->autoneg_advertised & ADVERTISE_1000_FULL) { - DEBUGOUT("Advertise 1000mb Full duplex\n"); - mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS; - } - - /* Check for a software override of the flow control settings, and - * setup the PHY advertisement registers accordingly. If - * auto-negotiation is enabled, then software will have to set the - * "PAUSE" bits to the correct value in the Auto-Negotiation - * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-negotiation. - * - * The possible values of the "fc" parameter are: - * 0: Flow control is completely disabled - * 1: Rx flow control is enabled (we can receive pause frames - * but not send pause frames). - * 2: Tx flow control is enabled (we can send pause frames - * but we do not support receiving pause frames). - * 3: Both Rx and TX flow control (symmetric) are enabled. - * other: No software override. The flow control configuration - * in the EEPROM is used. - */ - switch (hw->fc) { - case e1000_fc_none: /* 0 */ - /* Flow control (RX & TX) is completely disabled by a - * software over-ride. - */ - mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); - break; - case e1000_fc_rx_pause: /* 1 */ - /* RX Flow control is enabled, and TX Flow control is - * disabled, by a software over-ride. - */ - /* Since there really isn't a way to advertise that we are - * capable of RX Pause ONLY, we will advertise that we - * support both symmetric and asymmetric RX PAUSE. Later - * (in e1000_config_fc_after_link_up) we will disable the - *hw's ability to send PAUSE frames. - */ - mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); - break; - case e1000_fc_tx_pause: /* 2 */ - /* TX Flow control is enabled, and RX Flow control is - * disabled, by a software over-ride. - */ - mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR; - mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE; - break; - case e1000_fc_full: /* 3 */ - /* Flow control (both RX and TX) is enabled by a software - * over-ride. - */ - mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); - break; - default: - DEBUGOUT("Flow control param set incorrectly\n"); - return -E1000_ERR_CONFIG; - } - - ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg); - if (ret_val) - return ret_val; - - DEBUGOUT("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); - - if (hw->phy_type != e1000_phy_ife) { - ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, - mii_1000t_ctrl_reg); - if (ret_val) - return ret_val; - } - - return E1000_SUCCESS; -} - -/****************************************************************************** -* Sets the collision distance in the Transmit Control register -* -* hw - Struct containing variables accessed by shared code -* -* Link should have been established previously. Reads the speed and duplex -* information from the Device Status register. -******************************************************************************/ -static void -e1000_config_collision_dist(struct e1000_hw *hw) -{ - uint32_t tctl, coll_dist; - - DEBUGFUNC(); - - if (hw->mac_type < e1000_82543) - coll_dist = E1000_COLLISION_DISTANCE_82542; - else - coll_dist = E1000_COLLISION_DISTANCE; - - tctl = E1000_READ_REG(hw, TCTL); - - tctl &= ~E1000_TCTL_COLD; - tctl |= coll_dist << E1000_COLD_SHIFT; - - E1000_WRITE_REG(hw, TCTL, tctl); - E1000_WRITE_FLUSH(hw); -} - -/****************************************************************************** -* Sets MAC speed and duplex settings to reflect the those in the PHY -* -* hw - Struct containing variables accessed by shared code -* mii_reg - data to write to the MII control register -* -* The contents of the PHY register containing the needed information need to -* be passed in. -******************************************************************************/ -static int -e1000_config_mac_to_phy(struct e1000_hw *hw) -{ - uint32_t ctrl; - uint16_t phy_data; - - DEBUGFUNC(); - - /* Read the Device Control Register and set the bits to Force Speed - * and Duplex. - */ - ctrl = E1000_READ_REG(hw, CTRL); - ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); - ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS); - - /* Set up duplex in the Device Control and Transmit Control - * registers depending on negotiated values. - */ - if (e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - if (phy_data & M88E1000_PSSR_DPLX) - ctrl |= E1000_CTRL_FD; - else - ctrl &= ~E1000_CTRL_FD; - - e1000_config_collision_dist(hw); - - /* Set up speed in the Device Control register depending on - * negotiated values. - */ - if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) - ctrl |= E1000_CTRL_SPD_1000; - else if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS) - ctrl |= E1000_CTRL_SPD_100; - /* Write the configured values back to the Device Control Reg. */ - E1000_WRITE_REG(hw, CTRL, ctrl); - return 0; -} - -/****************************************************************************** - * Forces the MAC's flow control settings. - * - * hw - Struct containing variables accessed by shared code - * - * Sets the TFCE and RFCE bits in the device control register to reflect - * the adapter settings. TFCE and RFCE need to be explicitly set by - * software when a Copper PHY is used because autonegotiation is managed - * by the PHY rather than the MAC. Software must also configure these - * bits when link is forced on a fiber connection. - *****************************************************************************/ -static int -e1000_force_mac_fc(struct e1000_hw *hw) -{ - uint32_t ctrl; - - DEBUGFUNC(); - - /* Get the current configuration of the Device Control Register */ - ctrl = E1000_READ_REG(hw, CTRL); - - /* Because we didn't get link via the internal auto-negotiation - * mechanism (we either forced link or we got link via PHY - * auto-neg), we have to manually enable/disable transmit an - * receive flow control. - * - * The "Case" statement below enables/disable flow control - * according to the "hw->fc" parameter. - * - * The possible values of the "fc" parameter are: - * 0: Flow control is completely disabled - * 1: Rx flow control is enabled (we can receive pause - * frames but not send pause frames). - * 2: Tx flow control is enabled (we can send pause frames - * frames but we do not receive pause frames). - * 3: Both Rx and TX flow control (symmetric) is enabled. - * other: No other values should be possible at this point. - */ - - switch (hw->fc) { - case e1000_fc_none: - ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE)); - break; - case e1000_fc_rx_pause: - ctrl &= (~E1000_CTRL_TFCE); - ctrl |= E1000_CTRL_RFCE; - break; - case e1000_fc_tx_pause: - ctrl &= (~E1000_CTRL_RFCE); - ctrl |= E1000_CTRL_TFCE; - break; - case e1000_fc_full: - ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE); - break; - default: - DEBUGOUT("Flow control param set incorrectly\n"); - return -E1000_ERR_CONFIG; - } - - /* Disable TX Flow Control for 82542 (rev 2.0) */ - if (hw->mac_type == e1000_82542_rev2_0) - ctrl &= (~E1000_CTRL_TFCE); - - E1000_WRITE_REG(hw, CTRL, ctrl); - return 0; -} - -/****************************************************************************** - * Configures flow control settings after link is established - * - * hw - Struct containing variables accessed by shared code - * - * Should be called immediately after a valid link has been established. - * Forces MAC flow control settings if link was forced. When in MII/GMII mode - * and autonegotiation is enabled, the MAC flow control settings will be set - * based on the flow control negotiated by the PHY. In TBI mode, the TFCE - * and RFCE bits will be automaticaly set to the negotiated flow control mode. - *****************************************************************************/ -static int32_t -e1000_config_fc_after_link_up(struct e1000_hw *hw) -{ - int32_t ret_val; - uint16_t mii_status_reg; - uint16_t mii_nway_adv_reg; - uint16_t mii_nway_lp_ability_reg; - uint16_t speed; - uint16_t duplex; - - DEBUGFUNC(); - - /* Check for the case where we have fiber media and auto-neg failed - * so we had to force link. In this case, we need to force the - * configuration of the MAC to match the "fc" parameter. - */ - if (((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) - || ((hw->media_type == e1000_media_type_internal_serdes) - && (hw->autoneg_failed)) - || ((hw->media_type == e1000_media_type_copper) - && (!hw->autoneg))) { - ret_val = e1000_force_mac_fc(hw); - if (ret_val < 0) { - DEBUGOUT("Error forcing flow control settings\n"); - return ret_val; - } - } - - /* Check for the case where we have copper media and auto-neg is - * enabled. In this case, we need to check and see if Auto-Neg - * has completed, and if so, how the PHY and link partner has - * flow control configured. - */ - if (hw->media_type == e1000_media_type_copper) { - /* Read the MII Status Register and check to see if AutoNeg - * has completed. We read this twice because this reg has - * some "sticky" (latched) bits. - */ - if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) { - DEBUGOUT("PHY Read Error \n"); - return -E1000_ERR_PHY; - } - if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) { - DEBUGOUT("PHY Read Error \n"); - return -E1000_ERR_PHY; - } - - if (mii_status_reg & MII_SR_AUTONEG_COMPLETE) { - /* The AutoNeg process has completed, so we now need to - * read both the Auto Negotiation Advertisement Register - * (Address 4) and the Auto_Negotiation Base Page Ability - * Register (Address 5) to determine how flow control was - * negotiated. - */ - if (e1000_read_phy_reg - (hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - if (e1000_read_phy_reg - (hw, PHY_LP_ABILITY, - &mii_nway_lp_ability_reg) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - - /* Two bits in the Auto Negotiation Advertisement Register - * (Address 4) and two bits in the Auto Negotiation Base - * Page Ability Register (Address 5) determine flow control - * for both the PHY and the link partner. The following - * table, taken out of the IEEE 802.3ab/D6.0 dated March 25, - * 1999, describes these PAUSE resolution bits and how flow - * control is determined based upon these settings. - * NOTE: DC = Don't Care - * - * LOCAL DEVICE | LINK PARTNER - * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution - *-------|---------|-------|---------|-------------------- - * 0 | 0 | DC | DC | e1000_fc_none - * 0 | 1 | 0 | DC | e1000_fc_none - * 0 | 1 | 1 | 0 | e1000_fc_none - * 0 | 1 | 1 | 1 | e1000_fc_tx_pause - * 1 | 0 | 0 | DC | e1000_fc_none - * 1 | DC | 1 | DC | e1000_fc_full - * 1 | 1 | 0 | 0 | e1000_fc_none - * 1 | 1 | 0 | 1 | e1000_fc_rx_pause - * - */ - /* Are both PAUSE bits set to 1? If so, this implies - * Symmetric Flow Control is enabled at both ends. The - * ASM_DIR bits are irrelevant per the spec. - * - * For Symmetric Flow Control: - * - * LOCAL DEVICE | LINK PARTNER - * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result - *-------|---------|-------|---------|-------------------- - * 1 | DC | 1 | DC | e1000_fc_full - * - */ - if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && - (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) { - /* Now we need to check if the user selected RX ONLY - * of pause frames. In this case, we had to advertise - * FULL flow control because we could not advertise RX - * ONLY. Hence, we must now check to see if we need to - * turn OFF the TRANSMISSION of PAUSE frames. - */ - if (hw->original_fc == e1000_fc_full) { - hw->fc = e1000_fc_full; - DEBUGOUT("Flow Control = FULL.\r\n"); - } else { - hw->fc = e1000_fc_rx_pause; - DEBUGOUT - ("Flow Control = RX PAUSE frames only.\r\n"); - } - } - /* For receiving PAUSE frames ONLY. - * - * LOCAL DEVICE | LINK PARTNER - * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result - *-------|---------|-------|---------|-------------------- - * 0 | 1 | 1 | 1 | e1000_fc_tx_pause - * - */ - else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) && - (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && - (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && - (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) - { - hw->fc = e1000_fc_tx_pause; - DEBUGOUT - ("Flow Control = TX PAUSE frames only.\r\n"); - } - /* For transmitting PAUSE frames ONLY. - * - * LOCAL DEVICE | LINK PARTNER - * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result - *-------|---------|-------|---------|-------------------- - * 1 | 1 | 0 | 1 | e1000_fc_rx_pause - * - */ - else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && - (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && - !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && - (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) - { - hw->fc = e1000_fc_rx_pause; - DEBUGOUT - ("Flow Control = RX PAUSE frames only.\r\n"); - } - /* Per the IEEE spec, at this point flow control should be - * disabled. However, we want to consider that we could - * be connected to a legacy switch that doesn't advertise - * desired flow control, but can be forced on the link - * partner. So if we advertised no flow control, that is - * what we will resolve to. If we advertised some kind of - * receive capability (Rx Pause Only or Full Flow Control) - * and the link partner advertised none, we will configure - * ourselves to enable Rx Flow Control only. We can do - * this safely for two reasons: If the link partner really - * didn't want flow control enabled, and we enable Rx, no - * harm done since we won't be receiving any PAUSE frames - * anyway. If the intent on the link partner was to have - * flow control enabled, then by us enabling RX only, we - * can at least receive pause frames and process them. - * This is a good idea because in most cases, since we are - * predominantly a server NIC, more times than not we will - * be asked to delay transmission of packets than asking - * our link partner to pause transmission of frames. - */ - else if (hw->original_fc == e1000_fc_none || - hw->original_fc == e1000_fc_tx_pause) { - hw->fc = e1000_fc_none; - DEBUGOUT("Flow Control = NONE.\r\n"); - } else { - hw->fc = e1000_fc_rx_pause; - DEBUGOUT - ("Flow Control = RX PAUSE frames only.\r\n"); - } - - /* Now we need to do one last check... If we auto- - * negotiated to HALF DUPLEX, flow control should not be - * enabled per IEEE 802.3 spec. - */ - e1000_get_speed_and_duplex(hw, &speed, &duplex); - - if (duplex == HALF_DUPLEX) - hw->fc = e1000_fc_none; - - /* Now we call a subroutine to actually force the MAC - * controller to use the correct flow control settings. - */ - ret_val = e1000_force_mac_fc(hw); - if (ret_val < 0) { - DEBUGOUT - ("Error forcing flow control settings\n"); - return ret_val; - } - } else { - DEBUGOUT - ("Copper PHY and Auto Neg has not completed.\r\n"); - } - } - return E1000_SUCCESS; -} - -/****************************************************************************** - * Checks to see if the link status of the hardware has changed. - * - * hw - Struct containing variables accessed by shared code - * - * Called by any function that needs to check the link status of the adapter. - *****************************************************************************/ -static int -e1000_check_for_link(struct eth_device *nic) -{ - struct e1000_hw *hw = nic->priv; - uint32_t rxcw; - uint32_t ctrl; - uint32_t status; - uint32_t rctl; - uint32_t signal; - int32_t ret_val; - uint16_t phy_data; - uint16_t lp_capability; - - DEBUGFUNC(); - - /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be - * set when the optics detect a signal. On older adapters, it will be - * cleared when there is a signal - */ - ctrl = E1000_READ_REG(hw, CTRL); - if ((hw->mac_type > e1000_82544) && !(ctrl & E1000_CTRL_ILOS)) - signal = E1000_CTRL_SWDPIN1; - else - signal = 0; - - status = E1000_READ_REG(hw, STATUS); - rxcw = E1000_READ_REG(hw, RXCW); - DEBUGOUT("ctrl: %#08x status %#08x rxcw %#08x\n", ctrl, status, rxcw); - - /* If we have a copper PHY then we only want to go out to the PHY - * registers to see if Auto-Neg has completed and/or if our link - * status has changed. The get_link_status flag will be set if we - * receive a Link Status Change interrupt or we have Rx Sequence - * Errors. - */ - if ((hw->media_type == e1000_media_type_copper) && hw->get_link_status) { - /* First we want to see if the MII Status Register reports - * link. If so, then we want to get the current speed/duplex - * of the PHY. - * Read the register twice since the link bit is sticky. - */ - if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - - if (phy_data & MII_SR_LINK_STATUS) { - hw->get_link_status = false; - } else { - /* No link detected */ - return -E1000_ERR_NOLINK; - } - - /* We have a M88E1000 PHY and Auto-Neg is enabled. If we - * have Si on board that is 82544 or newer, Auto - * Speed Detection takes care of MAC speed/duplex - * configuration. So we only need to configure Collision - * Distance in the MAC. Otherwise, we need to force - * speed/duplex on the MAC to the current PHY speed/duplex - * settings. - */ - if (hw->mac_type >= e1000_82544) - e1000_config_collision_dist(hw); - else { - ret_val = e1000_config_mac_to_phy(hw); - if (ret_val < 0) { - DEBUGOUT - ("Error configuring MAC to PHY settings\n"); - return ret_val; - } - } - - /* Configure Flow Control now that Auto-Neg has completed. First, we - * need to restore the desired flow control settings because we may - * have had to re-autoneg with a different link partner. - */ - ret_val = e1000_config_fc_after_link_up(hw); - if (ret_val < 0) { - DEBUGOUT("Error configuring flow control\n"); - return ret_val; - } - - /* At this point we know that we are on copper and we have - * auto-negotiated link. These are conditions for checking the link - * parter capability register. We use the link partner capability to - * determine if TBI Compatibility needs to be turned on or off. If - * the link partner advertises any speed in addition to Gigabit, then - * we assume that they are GMII-based, and TBI compatibility is not - * needed. If no other speeds are advertised, we assume the link - * partner is TBI-based, and we turn on TBI Compatibility. - */ - if (hw->tbi_compatibility_en) { - if (e1000_read_phy_reg - (hw, PHY_LP_ABILITY, &lp_capability) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - if (lp_capability & (NWAY_LPAR_10T_HD_CAPS | - NWAY_LPAR_10T_FD_CAPS | - NWAY_LPAR_100TX_HD_CAPS | - NWAY_LPAR_100TX_FD_CAPS | - NWAY_LPAR_100T4_CAPS)) { - /* If our link partner advertises anything in addition to - * gigabit, we do not need to enable TBI compatibility. - */ - if (hw->tbi_compatibility_on) { - /* If we previously were in the mode, turn it off. */ - rctl = E1000_READ_REG(hw, RCTL); - rctl &= ~E1000_RCTL_SBP; - E1000_WRITE_REG(hw, RCTL, rctl); - hw->tbi_compatibility_on = false; - } - } else { - /* If TBI compatibility is was previously off, turn it on. For - * compatibility with a TBI link partner, we will store bad - * packets. Some frames have an additional byte on the end and - * will look like CRC errors to to the hardware. - */ - if (!hw->tbi_compatibility_on) { - hw->tbi_compatibility_on = true; - rctl = E1000_READ_REG(hw, RCTL); - rctl |= E1000_RCTL_SBP; - E1000_WRITE_REG(hw, RCTL, rctl); - } - } - } - } - /* If we don't have link (auto-negotiation failed or link partner cannot - * auto-negotiate), the cable is plugged in (we have signal), and our - * link partner is not trying to auto-negotiate with us (we are receiving - * idles or data), we need to force link up. We also need to give - * auto-negotiation time to complete, in case the cable was just plugged - * in. The autoneg_failed flag does this. - */ - else if ((hw->media_type == e1000_media_type_fiber) && - (!(status & E1000_STATUS_LU)) && - ((ctrl & E1000_CTRL_SWDPIN1) == signal) && - (!(rxcw & E1000_RXCW_C))) { - if (hw->autoneg_failed == 0) { - hw->autoneg_failed = 1; - return 0; - } - DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\r\n"); - - /* Disable auto-negotiation in the TXCW register */ - E1000_WRITE_REG(hw, TXCW, (hw->txcw & ~E1000_TXCW_ANE)); - - /* Force link-up and also force full-duplex. */ - ctrl = E1000_READ_REG(hw, CTRL); - ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); - E1000_WRITE_REG(hw, CTRL, ctrl); - - /* Configure Flow Control after forcing link up. */ - ret_val = e1000_config_fc_after_link_up(hw); - if (ret_val < 0) { - DEBUGOUT("Error configuring flow control\n"); - return ret_val; - } - } - /* If we are forcing link and we are receiving /C/ ordered sets, re-enable - * auto-negotiation in the TXCW register and disable forced link in the - * Device Control register in an attempt to auto-negotiate with our link - * partner. - */ - else if ((hw->media_type == e1000_media_type_fiber) && - (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { - DEBUGOUT - ("RXing /C/, enable AutoNeg and stop forcing link.\r\n"); - E1000_WRITE_REG(hw, TXCW, hw->txcw); - E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU)); - } - return 0; -} - -/****************************************************************************** -* Configure the MAC-to-PHY interface for 10/100Mbps -* -* hw - Struct containing variables accessed by shared code -******************************************************************************/ -static int32_t -e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, uint16_t duplex) -{ - int32_t ret_val = E1000_SUCCESS; - uint32_t tipg; - uint16_t reg_data; - - DEBUGFUNC(); - - reg_data = E1000_KUMCTRLSTA_HD_CTRL_10_100_DEFAULT; - ret_val = e1000_write_kmrn_reg(hw, - E1000_KUMCTRLSTA_OFFSET_HD_CTRL, reg_data); - if (ret_val) - return ret_val; - - /* Configure Transmit Inter-Packet Gap */ - tipg = E1000_READ_REG(hw, TIPG); - tipg &= ~E1000_TIPG_IPGT_MASK; - tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_10_100; - E1000_WRITE_REG(hw, TIPG, tipg); - - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); - - if (ret_val) - return ret_val; - - if (duplex == HALF_DUPLEX) - reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER; - else - reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; - - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); - - return ret_val; -} - -static int32_t -e1000_configure_kmrn_for_1000(struct e1000_hw *hw) -{ - int32_t ret_val = E1000_SUCCESS; - uint16_t reg_data; - uint32_t tipg; - - DEBUGFUNC(); - - reg_data = E1000_KUMCTRLSTA_HD_CTRL_1000_DEFAULT; - ret_val = e1000_write_kmrn_reg(hw, - E1000_KUMCTRLSTA_OFFSET_HD_CTRL, reg_data); - if (ret_val) - return ret_val; - - /* Configure Transmit Inter-Packet Gap */ - tipg = E1000_READ_REG(hw, TIPG); - tipg &= ~E1000_TIPG_IPGT_MASK; - tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000; - E1000_WRITE_REG(hw, TIPG, tipg); - - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); - - if (ret_val) - return ret_val; - - reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); - - return ret_val; -} - -/****************************************************************************** - * Detects the current speed and duplex settings of the hardware. - * - * hw - Struct containing variables accessed by shared code - * speed - Speed of the connection - * duplex - Duplex setting of the connection - *****************************************************************************/ -static int -e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t *speed, - uint16_t *duplex) -{ - uint32_t status; - int32_t ret_val; - uint16_t phy_data; - - DEBUGFUNC(); - - if (hw->mac_type >= e1000_82543) { - status = E1000_READ_REG(hw, STATUS); - if (status & E1000_STATUS_SPEED_1000) { - *speed = SPEED_1000; - DEBUGOUT("1000 Mbs, "); - } else if (status & E1000_STATUS_SPEED_100) { - *speed = SPEED_100; - DEBUGOUT("100 Mbs, "); - } else { - *speed = SPEED_10; - DEBUGOUT("10 Mbs, "); - } - - if (status & E1000_STATUS_FD) { - *duplex = FULL_DUPLEX; - DEBUGOUT("Full Duplex\r\n"); - } else { - *duplex = HALF_DUPLEX; - DEBUGOUT(" Half Duplex\r\n"); - } - } else { - DEBUGOUT("1000 Mbs, Full Duplex\r\n"); - *speed = SPEED_1000; - *duplex = FULL_DUPLEX; - } - - /* IGP01 PHY may advertise full duplex operation after speed downgrade - * even if it is operating at half duplex. Here we set the duplex - * settings to match the duplex in the link partner's capabilities. - */ - if (hw->phy_type == e1000_phy_igp && hw->speed_downgraded) { - ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data); - if (ret_val) - return ret_val; - - if (!(phy_data & NWAY_ER_LP_NWAY_CAPS)) - *duplex = HALF_DUPLEX; - else { - ret_val = e1000_read_phy_reg(hw, - PHY_LP_ABILITY, &phy_data); - if (ret_val) - return ret_val; - if ((*speed == SPEED_100 && - !(phy_data & NWAY_LPAR_100TX_FD_CAPS)) - || (*speed == SPEED_10 - && !(phy_data & NWAY_LPAR_10T_FD_CAPS))) - *duplex = HALF_DUPLEX; - } - } - - if ((hw->mac_type == e1000_80003es2lan) && - (hw->media_type == e1000_media_type_copper)) { - if (*speed == SPEED_1000) - ret_val = e1000_configure_kmrn_for_1000(hw); - else - ret_val = e1000_configure_kmrn_for_10_100(hw, *duplex); - if (ret_val) - return ret_val; - } - return E1000_SUCCESS; -} - -/****************************************************************************** -* Blocks until autoneg completes or times out (~4.5 seconds) -* -* hw - Struct containing variables accessed by shared code -******************************************************************************/ -static int -e1000_wait_autoneg(struct e1000_hw *hw) -{ - uint16_t i; - uint16_t phy_data; - - DEBUGFUNC(); - DEBUGOUT("Waiting for Auto-Neg to complete.\n"); - - /* We will wait for autoneg to complete or 4.5 seconds to expire. */ - for (i = PHY_AUTO_NEG_TIME; i > 0; i--) { - /* Read the MII Status Register and wait for Auto-Neg - * Complete bit to be set. - */ - if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { - DEBUGOUT("PHY Read Error\n"); - return -E1000_ERR_PHY; - } - if (phy_data & MII_SR_AUTONEG_COMPLETE) { - DEBUGOUT("Auto-Neg complete.\n"); - return 0; - } - mdelay(100); - } - DEBUGOUT("Auto-Neg timedout.\n"); - return -E1000_ERR_TIMEOUT; -} - -/****************************************************************************** -* Raises the Management Data Clock -* -* hw - Struct containing variables accessed by shared code -* ctrl - Device control register's current value -******************************************************************************/ -static void -e1000_raise_mdi_clk(struct e1000_hw *hw, uint32_t * ctrl) -{ - /* Raise the clock input to the Management Data Clock (by setting the MDC - * bit), and then delay 2 microseconds. - */ - E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC)); - E1000_WRITE_FLUSH(hw); - udelay(2); -} - -/****************************************************************************** -* Lowers the Management Data Clock -* -* hw - Struct containing variables accessed by shared code -* ctrl - Device control register's current value -******************************************************************************/ -static void -e1000_lower_mdi_clk(struct e1000_hw *hw, uint32_t * ctrl) -{ - /* Lower the clock input to the Management Data Clock (by clearing the MDC - * bit), and then delay 2 microseconds. - */ - E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC)); - E1000_WRITE_FLUSH(hw); - udelay(2); -} - -/****************************************************************************** -* Shifts data bits out to the PHY -* -* hw - Struct containing variables accessed by shared code -* data - Data to send out to the PHY -* count - Number of bits to shift out -* -* Bits are shifted out in MSB to LSB order. -******************************************************************************/ -static void -e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data, uint16_t count) -{ - uint32_t ctrl; - uint32_t mask; - - /* We need to shift "count" number of bits out to the PHY. So, the value - * in the "data" parameter will be shifted out to the PHY one bit at a - * time. In order to do this, "data" must be broken down into bits. - */ - mask = 0x01; - mask <<= (count - 1); - - ctrl = E1000_READ_REG(hw, CTRL); - - /* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */ - ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR); - - while (mask) { - /* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and - * then raising and lowering the Management Data Clock. A "0" is - * shifted out to the PHY by setting the MDIO bit to "0" and then - * raising and lowering the clock. - */ - if (data & mask) - ctrl |= E1000_CTRL_MDIO; - else - ctrl &= ~E1000_CTRL_MDIO; - - E1000_WRITE_REG(hw, CTRL, ctrl); - E1000_WRITE_FLUSH(hw); - - udelay(2); - - e1000_raise_mdi_clk(hw, &ctrl); - e1000_lower_mdi_clk(hw, &ctrl); - - mask = mask >> 1; - } -} - -/****************************************************************************** -* Shifts data bits in from the PHY -* -* hw - Struct containing variables accessed by shared code -* -* Bits are shifted in in MSB to LSB order. -******************************************************************************/ -static uint16_t -e1000_shift_in_mdi_bits(struct e1000_hw *hw) -{ - uint32_t ctrl; - uint16_t data = 0; - uint8_t i; - - /* In order to read a register from the PHY, we need to shift in a total - * of 18 bits from the PHY. The first two bit (turnaround) times are used - * to avoid contention on the MDIO pin when a read operation is performed. - * These two bits are ignored by us and thrown away. Bits are "shifted in" - * by raising the input to the Management Data Clock (setting the MDC bit), - * and then reading the value of the MDIO bit. - */ - ctrl = E1000_READ_REG(hw, CTRL); - - /* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */ - ctrl &= ~E1000_CTRL_MDIO_DIR; - ctrl &= ~E1000_CTRL_MDIO; - - E1000_WRITE_REG(hw, CTRL, ctrl); - E1000_WRITE_FLUSH(hw); - - /* Raise and Lower the clock before reading in the data. This accounts for - * the turnaround bits. The first clock occurred when we clocked out the - * last bit of the Register Address. - */ - e1000_raise_mdi_clk(hw, &ctrl); - e1000_lower_mdi_clk(hw, &ctrl); - - for (data = 0, i = 0; i < 16; i++) { - data = data << 1; - e1000_raise_mdi_clk(hw, &ctrl); - ctrl = E1000_READ_REG(hw, CTRL); - /* Check to see if we shifted in a "1". */ - if (ctrl & E1000_CTRL_MDIO) - data |= 1; - e1000_lower_mdi_clk(hw, &ctrl); - } - - e1000_raise_mdi_clk(hw, &ctrl); - e1000_lower_mdi_clk(hw, &ctrl); - - return data; -} - -/***************************************************************************** -* Reads the value from a PHY register -* -* hw - Struct containing variables accessed by shared code -* reg_addr - address of the PHY register to read -******************************************************************************/ -static int -e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t * phy_data) -{ - uint32_t i; - uint32_t mdic = 0; - const uint32_t phy_addr = 1; - - if (reg_addr > MAX_PHY_REG_ADDRESS) { - DEBUGOUT("PHY Address %d is out of range\n", reg_addr); - return -E1000_ERR_PARAM; - } - - if (hw->mac_type > e1000_82543) { - /* Set up Op-code, Phy Address, and register address in the MDI - * Control register. The MAC will take care of interfacing with the - * PHY to retrieve the desired data. - */ - mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) | - (phy_addr << E1000_MDIC_PHY_SHIFT) | - (E1000_MDIC_OP_READ)); - - E1000_WRITE_REG(hw, MDIC, mdic); - - /* Poll the ready bit to see if the MDI read completed */ - for (i = 0; i < 64; i++) { - udelay(10); - mdic = E1000_READ_REG(hw, MDIC); - if (mdic & E1000_MDIC_READY) - break; - } - if (!(mdic & E1000_MDIC_READY)) { - DEBUGOUT("MDI Read did not complete\n"); - return -E1000_ERR_PHY; - } - if (mdic & E1000_MDIC_ERROR) { - DEBUGOUT("MDI Error\n"); - return -E1000_ERR_PHY; - } - *phy_data = (uint16_t) mdic; - } else { - /* We must first send a preamble through the MDIO pin to signal the - * beginning of an MII instruction. This is done by sending 32 - * consecutive "1" bits. - */ - e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE); - - /* Now combine the next few fields that are required for a read - * operation. We use this method instead of calling the - * e1000_shift_out_mdi_bits routine five different times. The format of - * a MII read instruction consists of a shift out of 14 bits and is - * defined as follows: - * <Preamble><SOF><Op Code><Phy Addr><Reg Addr> - * followed by a shift in of 18 bits. This first two bits shifted in - * are TurnAround bits used to avoid contention on the MDIO pin when a - * READ operation is performed. These two bits are thrown away - * followed by a shift in of 16 bits which contains the desired data. - */ - mdic = ((reg_addr) | (phy_addr << 5) | - (PHY_OP_READ << 10) | (PHY_SOF << 12)); - - e1000_shift_out_mdi_bits(hw, mdic, 14); - - /* Now that we've shifted out the read command to the MII, we need to - * "shift in" the 16-bit value (18 total bits) of the requested PHY - * register address. - */ - *phy_data = e1000_shift_in_mdi_bits(hw); - } - return 0; -} - -/****************************************************************************** -* Writes a value to a PHY register -* -* hw - Struct containing variables accessed by shared code -* reg_addr - address of the PHY register to write -* data - data to write to the PHY -******************************************************************************/ -static int -e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t phy_data) -{ - uint32_t i; - uint32_t mdic = 0; - const uint32_t phy_addr = 1; - - if (reg_addr > MAX_PHY_REG_ADDRESS) { - DEBUGOUT("PHY Address %d is out of range\n", reg_addr); - return -E1000_ERR_PARAM; - } - - if (hw->mac_type > e1000_82543) { - /* Set up Op-code, Phy Address, register address, and data intended - * for the PHY register in the MDI Control register. The MAC will take - * care of interfacing with the PHY to send the desired data. - */ - mdic = (((uint32_t) phy_data) | - (reg_addr << E1000_MDIC_REG_SHIFT) | - (phy_addr << E1000_MDIC_PHY_SHIFT) | - (E1000_MDIC_OP_WRITE)); - - E1000_WRITE_REG(hw, MDIC, mdic); - - /* Poll the ready bit to see if the MDI read completed */ - for (i = 0; i < 64; i++) { - udelay(10); - mdic = E1000_READ_REG(hw, MDIC); - if (mdic & E1000_MDIC_READY) - break; - } - if (!(mdic & E1000_MDIC_READY)) { - DEBUGOUT("MDI Write did not complete\n"); - return -E1000_ERR_PHY; - } - } else { - /* We'll need to use the SW defined pins to shift the write command - * out to the PHY. We first send a preamble to the PHY to signal the - * beginning of the MII instruction. This is done by sending 32 - * consecutive "1" bits. - */ - e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE); - - /* Now combine the remaining required fields that will indicate a - * write operation. We use this method instead of calling the - * e1000_shift_out_mdi_bits routine for each field in the command. The - * format of a MII write instruction is as follows: - * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>. - */ - mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) | - (PHY_OP_WRITE << 12) | (PHY_SOF << 14)); - mdic <<= 16; - mdic |= (uint32_t) phy_data; - - e1000_shift_out_mdi_bits(hw, mdic, 32); - } - return 0; -} - -/****************************************************************************** - * Checks if PHY reset is blocked due to SOL/IDER session, for example. - * Returning E1000_BLK_PHY_RESET isn't necessarily an error. But it's up to - * the caller to figure out how to deal with it. - * - * hw - Struct containing variables accessed by shared code - * - * returns: - E1000_BLK_PHY_RESET - * E1000_SUCCESS - * - *****************************************************************************/ -int32_t -e1000_check_phy_reset_block(struct e1000_hw *hw) -{ - uint32_t manc = 0; - uint32_t fwsm = 0; - - if (hw->mac_type == e1000_ich8lan) { - fwsm = E1000_READ_REG(hw, FWSM); - return (fwsm & E1000_FWSM_RSPCIPHY) ? E1000_SUCCESS - : E1000_BLK_PHY_RESET; - } - - if (hw->mac_type > e1000_82547_rev_2) - manc = E1000_READ_REG(hw, MANC); - return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ? - E1000_BLK_PHY_RESET : E1000_SUCCESS; -} - -/*************************************************************************** - * Checks if the PHY configuration is done - * - * hw: Struct containing variables accessed by shared code - * - * returns: - E1000_ERR_RESET if fail to reset MAC - * E1000_SUCCESS at any other case. - * - ***************************************************************************/ -static int32_t -e1000_get_phy_cfg_done(struct e1000_hw *hw) -{ - int32_t timeout = PHY_CFG_TIMEOUT; - uint32_t cfg_mask = E1000_EEPROM_CFG_DONE; - - DEBUGFUNC(); - - switch (hw->mac_type) { - default: - mdelay(10); - break; - - case e1000_80003es2lan: - /* Separate *_CFG_DONE_* bit for each port */ - if (e1000_is_second_port(hw)) - cfg_mask = E1000_EEPROM_CFG_DONE_PORT_1; - /* Fall Through */ - - case e1000_82571: - case e1000_82572: - while (timeout) { - if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask) - break; - else - mdelay(1); - timeout--; - } - if (!timeout) { - DEBUGOUT("MNG configuration cycle has not " - "completed.\n"); - return -E1000_ERR_RESET; - } - break; - } - - return E1000_SUCCESS; -} - -/****************************************************************************** -* Returns the PHY to the power-on reset state -* -* hw - Struct containing variables accessed by shared code -******************************************************************************/ -int32_t -e1000_phy_hw_reset(struct e1000_hw *hw) -{ - uint16_t swfw = E1000_SWFW_PHY0_SM; - uint32_t ctrl, ctrl_ext; - uint32_t led_ctrl; - int32_t ret_val; - - DEBUGFUNC(); - - /* In the case of the phy reset being blocked, it's not an error, we - * simply return success without performing the reset. */ - ret_val = e1000_check_phy_reset_block(hw); - if (ret_val) - return E1000_SUCCESS; - - DEBUGOUT("Resetting Phy...\n"); - - if (hw->mac_type > e1000_82543) { - if (e1000_is_second_port(hw)) - swfw = E1000_SWFW_PHY1_SM; - - if (e1000_swfw_sync_acquire(hw, swfw)) { - DEBUGOUT("Unable to acquire swfw sync\n"); - return -E1000_ERR_SWFW_SYNC; - } - - /* Read the device control register and assert the E1000_CTRL_PHY_RST - * bit. Then, take it out of reset. - */ - ctrl = E1000_READ_REG(hw, CTRL); - E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST); - E1000_WRITE_FLUSH(hw); - - if (hw->mac_type < e1000_82571) - udelay(10); - else - udelay(100); - - E1000_WRITE_REG(hw, CTRL, ctrl); - E1000_WRITE_FLUSH(hw); - - if (hw->mac_type >= e1000_82571) - mdelay(10); - - } else { - /* Read the Extended Device Control Register, assert the PHY_RESET_DIR - * bit to put the PHY into reset. Then, take it out of reset. - */ - ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); - ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR; - ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA; - E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); - E1000_WRITE_FLUSH(hw); - mdelay(10); - ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA; - E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); - E1000_WRITE_FLUSH(hw); - } - udelay(150); - - if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { - /* Configure activity LED after PHY reset */ - led_ctrl = E1000_READ_REG(hw, LEDCTL); - led_ctrl &= IGP_ACTIVITY_LED_MASK; - led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); - E1000_WRITE_REG(hw, LEDCTL, led_ctrl); - } - - /* Wait for FW to finish PHY configuration. */ - ret_val = e1000_get_phy_cfg_done(hw); - if (ret_val != E1000_SUCCESS) - return ret_val; - - return ret_val; -} - -/****************************************************************************** - * IGP phy init script - initializes the GbE PHY - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -static void -e1000_phy_init_script(struct e1000_hw *hw) -{ - uint32_t ret_val; - uint16_t phy_saved_data; - DEBUGFUNC(); - - if (hw->phy_init_script) { - mdelay(20); - - /* Save off the current value of register 0x2F5B to be - * restored at the end of this routine. */ - ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data); - - /* Disabled the PHY transmitter */ - e1000_write_phy_reg(hw, 0x2F5B, 0x0003); - - mdelay(20); - - e1000_write_phy_reg(hw, 0x0000, 0x0140); - - mdelay(5); - - switch (hw->mac_type) { - case e1000_82541: - case e1000_82547: - e1000_write_phy_reg(hw, 0x1F95, 0x0001); - - e1000_write_phy_reg(hw, 0x1F71, 0xBD21); - - e1000_write_phy_reg(hw, 0x1F79, 0x0018); - - e1000_write_phy_reg(hw, 0x1F30, 0x1600); - - e1000_write_phy_reg(hw, 0x1F31, 0x0014); - - e1000_write_phy_reg(hw, 0x1F32, 0x161C); - - e1000_write_phy_reg(hw, 0x1F94, 0x0003); - - e1000_write_phy_reg(hw, 0x1F96, 0x003F); - - e1000_write_phy_reg(hw, 0x2010, 0x0008); - break; - - case e1000_82541_rev_2: - case e1000_82547_rev_2: - e1000_write_phy_reg(hw, 0x1F73, 0x0099); - break; - default: - break; - } - - e1000_write_phy_reg(hw, 0x0000, 0x3300); - - mdelay(20); - - /* Now enable the transmitter */ - if (!ret_val) - e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data); - - if (hw->mac_type == e1000_82547) { - uint16_t fused, fine, coarse; - - /* Move to analog registers page */ - e1000_read_phy_reg(hw, - IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused); - - if (!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) { - e1000_read_phy_reg(hw, - IGP01E1000_ANALOG_FUSE_STATUS, &fused); - - fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK; - coarse = fused - & IGP01E1000_ANALOG_FUSE_COARSE_MASK; - - if (coarse > - IGP01E1000_ANALOG_FUSE_COARSE_THRESH) { - coarse -= - IGP01E1000_ANALOG_FUSE_COARSE_10; - fine -= IGP01E1000_ANALOG_FUSE_FINE_1; - } else if (coarse - == IGP01E1000_ANALOG_FUSE_COARSE_THRESH) - fine -= IGP01E1000_ANALOG_FUSE_FINE_10; - - fused = (fused - & IGP01E1000_ANALOG_FUSE_POLY_MASK) | - (fine - & IGP01E1000_ANALOG_FUSE_FINE_MASK) | - (coarse - & IGP01E1000_ANALOG_FUSE_COARSE_MASK); - - e1000_write_phy_reg(hw, - IGP01E1000_ANALOG_FUSE_CONTROL, fused); - e1000_write_phy_reg(hw, - IGP01E1000_ANALOG_FUSE_BYPASS, - IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL); - } - } - } -} - -/****************************************************************************** -* Resets the PHY -* -* hw - Struct containing variables accessed by shared code -* -* Sets bit 15 of the MII Control register -******************************************************************************/ -int32_t -e1000_phy_reset(struct e1000_hw *hw) -{ - int32_t ret_val; - uint16_t phy_data; - - DEBUGFUNC(); - - /* In the case of the phy reset being blocked, it's not an error, we - * simply return success without performing the reset. */ - ret_val = e1000_check_phy_reset_block(hw); - if (ret_val) - return E1000_SUCCESS; - - switch (hw->phy_type) { - case e1000_phy_igp: - case e1000_phy_igp_2: - case e1000_phy_igp_3: - case e1000_phy_ife: - ret_val = e1000_phy_hw_reset(hw); - if (ret_val) - return ret_val; - break; - default: - ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data); - if (ret_val) - return ret_val; - - phy_data |= MII_CR_RESET; - ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data); - if (ret_val) - return ret_val; - - udelay(1); - break; - } - - if (hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2) - e1000_phy_init_script(hw); - - return E1000_SUCCESS; -} - -static int e1000_set_phy_type (struct e1000_hw *hw) -{ - DEBUGFUNC (); - - if (hw->mac_type == e1000_undefined) - return -E1000_ERR_PHY_TYPE; - - switch (hw->phy_id) { - case M88E1000_E_PHY_ID: - case M88E1000_I_PHY_ID: - case M88E1011_I_PHY_ID: - case M88E1111_I_PHY_ID: - hw->phy_type = e1000_phy_m88; - break; - case IGP01E1000_I_PHY_ID: - if (hw->mac_type == e1000_82541 || - hw->mac_type == e1000_82541_rev_2 || - hw->mac_type == e1000_82547 || - hw->mac_type == e1000_82547_rev_2) { - hw->phy_type = e1000_phy_igp; - break; - } - case IGP03E1000_E_PHY_ID: - hw->phy_type = e1000_phy_igp_3; - break; - case IFE_E_PHY_ID: - case IFE_PLUS_E_PHY_ID: - case IFE_C_E_PHY_ID: - hw->phy_type = e1000_phy_ife; - break; - case GG82563_E_PHY_ID: - if (hw->mac_type == e1000_80003es2lan) { - hw->phy_type = e1000_phy_gg82563; - break; - } - case BME1000_E_PHY_ID: - hw->phy_type = e1000_phy_bm; - break; - /* Fall Through */ - default: - /* Should never have loaded on this device */ - hw->phy_type = e1000_phy_undefined; - return -E1000_ERR_PHY_TYPE; - } - - return E1000_SUCCESS; -} - -/****************************************************************************** -* Probes the expected PHY address for known PHY IDs -* -* hw - Struct containing variables accessed by shared code -******************************************************************************/ -static int32_t -e1000_detect_gig_phy(struct e1000_hw *hw) -{ - int32_t phy_init_status, ret_val; - uint16_t phy_id_high, phy_id_low; - bool match = false; - - DEBUGFUNC(); - - /* The 82571 firmware may still be configuring the PHY. In this - * case, we cannot access the PHY until the configuration is done. So - * we explicitly set the PHY values. */ - if (hw->mac_type == e1000_82571 || - hw->mac_type == e1000_82572) { - hw->phy_id = IGP01E1000_I_PHY_ID; - hw->phy_type = e1000_phy_igp_2; - return E1000_SUCCESS; - } - - /* ESB-2 PHY reads require e1000_phy_gg82563 to be set because of a - * work- around that forces PHY page 0 to be set or the reads fail. - * The rest of the code in this routine uses e1000_read_phy_reg to - * read the PHY ID. So for ESB-2 we need to have this set so our - * reads won't fail. If the attached PHY is not a e1000_phy_gg82563, - * the routines below will figure this out as well. */ - if (hw->mac_type == e1000_80003es2lan) - hw->phy_type = e1000_phy_gg82563; - - /* Read the PHY ID Registers to identify which PHY is onboard. */ - ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high); - if (ret_val) - return ret_val; - - hw->phy_id = (uint32_t) (phy_id_high << 16); - udelay(20); - ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low); - if (ret_val) - return ret_val; - - hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK); - hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK; - - switch (hw->mac_type) { - case e1000_82543: - if (hw->phy_id == M88E1000_E_PHY_ID) - match = true; - break; - case e1000_82544: - if (hw->phy_id == M88E1000_I_PHY_ID) - match = true; - break; - case e1000_82540: - case e1000_82545: - case e1000_82545_rev_3: - case e1000_82546: - case e1000_82546_rev_3: - if (hw->phy_id == M88E1011_I_PHY_ID) - match = true; - break; - case e1000_82541: - case e1000_82541_rev_2: - case e1000_82547: - case e1000_82547_rev_2: - if(hw->phy_id == IGP01E1000_I_PHY_ID) - match = true; - - break; - case e1000_82573: - if (hw->phy_id == M88E1111_I_PHY_ID) - match = true; - break; - case e1000_82574: - if (hw->phy_id == BME1000_E_PHY_ID) - match = true; - break; - case e1000_80003es2lan: - if (hw->phy_id == GG82563_E_PHY_ID) - match = true; - break; - case e1000_ich8lan: - if (hw->phy_id == IGP03E1000_E_PHY_ID) - match = true; - if (hw->phy_id == IFE_E_PHY_ID) - match = true; - if (hw->phy_id == IFE_PLUS_E_PHY_ID) - match = true; - if (hw->phy_id == IFE_C_E_PHY_ID) - match = true; - break; - default: - DEBUGOUT("Invalid MAC type %d\n", hw->mac_type); - return -E1000_ERR_CONFIG; - } - - phy_init_status = e1000_set_phy_type(hw); - - if ((match) && (phy_init_status == E1000_SUCCESS)) { - DEBUGOUT("PHY ID 0x%X detected\n", hw->phy_id); - return 0; - } - DEBUGOUT("Invalid PHY ID 0x%X\n", hw->phy_id); - return -E1000_ERR_PHY; -} - -/***************************************************************************** - * Set media type and TBI compatibility. - * - * hw - Struct containing variables accessed by shared code - * **************************************************************************/ -void -e1000_set_media_type(struct e1000_hw *hw) -{ - uint32_t status; - - DEBUGFUNC(); - - if (hw->mac_type != e1000_82543) { - /* tbi_compatibility is only valid on 82543 */ - hw->tbi_compatibility_en = false; - } - - switch (hw->device_id) { - case E1000_DEV_ID_82545GM_SERDES: - case E1000_DEV_ID_82546GB_SERDES: - case E1000_DEV_ID_82571EB_SERDES: - case E1000_DEV_ID_82571EB_SERDES_DUAL: - case E1000_DEV_ID_82571EB_SERDES_QUAD: - case E1000_DEV_ID_82572EI_SERDES: - case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: - hw->media_type = e1000_media_type_internal_serdes; - break; - default: - switch (hw->mac_type) { - case e1000_82542_rev2_0: - case e1000_82542_rev2_1: - hw->media_type = e1000_media_type_fiber; - break; - case e1000_ich8lan: - case e1000_82573: - case e1000_82574: - /* The STATUS_TBIMODE bit is reserved or reused - * for the this device. - */ - hw->media_type = e1000_media_type_copper; - break; - default: - status = E1000_READ_REG(hw, STATUS); - if (status & E1000_STATUS_TBIMODE) { - hw->media_type = e1000_media_type_fiber; - /* tbi_compatibility not valid on fiber */ - hw->tbi_compatibility_en = false; - } else { - hw->media_type = e1000_media_type_copper; - } - break; - } - } -} - -/** - * e1000_sw_init - Initialize general software structures (struct e1000_adapter) - * - * e1000_sw_init initializes the Adapter private data structure. - * Fields are initialized based on PCI device information and - * OS network device settings (MTU size). - **/ - -static int -e1000_sw_init(struct eth_device *nic) -{ - struct e1000_hw *hw = (typeof(hw)) nic->priv; - int result; - - /* PCI config space info */ - pci_read_config_word(hw->pdev, PCI_VENDOR_ID, &hw->vendor_id); - pci_read_config_word(hw->pdev, PCI_DEVICE_ID, &hw->device_id); - pci_read_config_word(hw->pdev, PCI_SUBSYSTEM_VENDOR_ID, - &hw->subsystem_vendor_id); - pci_read_config_word(hw->pdev, PCI_SUBSYSTEM_ID, &hw->subsystem_id); - - pci_read_config_byte(hw->pdev, PCI_REVISION_ID, &hw->revision_id); - pci_read_config_word(hw->pdev, PCI_COMMAND, &hw->pci_cmd_word); - - /* identify the MAC */ - result = e1000_set_mac_type(hw); - if (result) { - E1000_ERR(hw->nic, "Unknown MAC Type\n"); - return result; - } - - switch (hw->mac_type) { - default: - break; - case e1000_82541: - case e1000_82547: - case e1000_82541_rev_2: - case e1000_82547_rev_2: - hw->phy_init_script = 1; - break; - } - - /* flow control settings */ - hw->fc_high_water = E1000_FC_HIGH_THRESH; - hw->fc_low_water = E1000_FC_LOW_THRESH; - hw->fc_pause_time = E1000_FC_PAUSE_TIME; - hw->fc_send_xon = 1; - - /* Media type - copper or fiber */ - e1000_set_media_type(hw); - - if (hw->mac_type >= e1000_82543) { - uint32_t status = E1000_READ_REG(hw, STATUS); - - if (status & E1000_STATUS_TBIMODE) { - DEBUGOUT("fiber interface\n"); - hw->media_type = e1000_media_type_fiber; - } else { - DEBUGOUT("copper interface\n"); - hw->media_type = e1000_media_type_copper; - } - } else { - hw->media_type = e1000_media_type_fiber; - } - - hw->tbi_compatibility_en = true; - hw->wait_autoneg_complete = true; - if (hw->mac_type < e1000_82543) - hw->report_tx_early = 0; - else - hw->report_tx_early = 1; - - return E1000_SUCCESS; -} - -void -fill_rx(struct e1000_hw *hw) -{ - struct e1000_rx_desc *rd; - - rx_last = rx_tail; - rd = rx_base + rx_tail; - rx_tail = (rx_tail + 1) % 8; - memset(rd, 0, 16); - rd->buffer_addr = cpu_to_le64((u32) & packet); - E1000_WRITE_REG(hw, RDT, rx_tail); -} - -/** - * e1000_configure_tx - Configure 8254x Transmit Unit after Reset - * @adapter: board private structure - * - * Configure the Tx unit of the MAC after a reset. - **/ - -static void -e1000_configure_tx(struct e1000_hw *hw) -{ - unsigned long ptr; - unsigned long tctl; - unsigned long tipg, tarc; - uint32_t ipgr1, ipgr2; - - ptr = (u32) tx_pool; - if (ptr & 0xf) - ptr = (ptr + 0x10) & (~0xf); - - tx_base = (typeof(tx_base)) ptr; - - E1000_WRITE_REG(hw, TDBAL, (u32) tx_base); - E1000_WRITE_REG(hw, TDBAH, 0); - - E1000_WRITE_REG(hw, TDLEN, 128); - - /* Setup the HW Tx Head and Tail descriptor pointers */ - E1000_WRITE_REG(hw, TDH, 0); - E1000_WRITE_REG(hw, TDT, 0); - tx_tail = 0; - - /* Set the default values for the Tx Inter Packet Gap timer */ - if (hw->mac_type <= e1000_82547_rev_2 && - (hw->media_type == e1000_media_type_fiber || - hw->media_type == e1000_media_type_internal_serdes)) - tipg = DEFAULT_82543_TIPG_IPGT_FIBER; - else - tipg = DEFAULT_82543_TIPG_IPGT_COPPER; - - /* Set the default values for the Tx Inter Packet Gap timer */ - switch (hw->mac_type) { - case e1000_82542_rev2_0: - case e1000_82542_rev2_1: - tipg = DEFAULT_82542_TIPG_IPGT; - ipgr1 = DEFAULT_82542_TIPG_IPGR1; - ipgr2 = DEFAULT_82542_TIPG_IPGR2; - break; - case e1000_80003es2lan: - ipgr1 = DEFAULT_82543_TIPG_IPGR1; - ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; - break; - default: - ipgr1 = DEFAULT_82543_TIPG_IPGR1; - ipgr2 = DEFAULT_82543_TIPG_IPGR2; - break; - } - tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT; - tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT; - E1000_WRITE_REG(hw, TIPG, tipg); - /* Program the Transmit Control Register */ - tctl = E1000_READ_REG(hw, TCTL); - tctl &= ~E1000_TCTL_CT; - tctl |= E1000_TCTL_EN | E1000_TCTL_PSP | - (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT); - - if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) { - tarc = E1000_READ_REG(hw, TARC0); - /* set the speed mode bit, we'll clear it if we're not at - * gigabit link later */ - /* git bit can be set to 1*/ - } else if (hw->mac_type == e1000_80003es2lan) { - tarc = E1000_READ_REG(hw, TARC0); - tarc |= 1; - E1000_WRITE_REG(hw, TARC0, tarc); - tarc = E1000_READ_REG(hw, TARC1); - tarc |= 1; - E1000_WRITE_REG(hw, TARC1, tarc); - } - - - e1000_config_collision_dist(hw); - /* Setup Transmit Descriptor Settings for eop descriptor */ - hw->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS; - - /* Need to set up RS bit */ - if (hw->mac_type < e1000_82543) - hw->txd_cmd |= E1000_TXD_CMD_RPS; - else - hw->txd_cmd |= E1000_TXD_CMD_RS; - E1000_WRITE_REG(hw, TCTL, tctl); -} - -/** - * e1000_setup_rctl - configure the receive control register - * @adapter: Board private structure - **/ -static void -e1000_setup_rctl(struct e1000_hw *hw) -{ - uint32_t rctl; - - rctl = E1000_READ_REG(hw, RCTL); - - rctl &= ~(3 << E1000_RCTL_MO_SHIFT); - - rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO - | E1000_RCTL_RDMTS_HALF; /* | - (hw.mc_filter_type << E1000_RCTL_MO_SHIFT); */ - - if (hw->tbi_compatibility_on == 1) - rctl |= E1000_RCTL_SBP; - else - rctl &= ~E1000_RCTL_SBP; - - rctl &= ~(E1000_RCTL_SZ_4096); - rctl |= E1000_RCTL_SZ_2048; - rctl &= ~(E1000_RCTL_BSEX | E1000_RCTL_LPE); - E1000_WRITE_REG(hw, RCTL, rctl); -} - -/** - * e1000_configure_rx - Configure 8254x Receive Unit after Reset - * @adapter: board private structure - * - * Configure the Rx unit of the MAC after a reset. - **/ -static void -e1000_configure_rx(struct e1000_hw *hw) -{ - unsigned long ptr; - unsigned long rctl, ctrl_ext; - rx_tail = 0; - /* make sure receives are disabled while setting up the descriptors */ - rctl = E1000_READ_REG(hw, RCTL); - E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); - if (hw->mac_type >= e1000_82540) { - /* Set the interrupt throttling rate. Value is calculated - * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) */ -#define MAX_INTS_PER_SEC 8000 -#define DEFAULT_ITR 1000000000/(MAX_INTS_PER_SEC * 256) - E1000_WRITE_REG(hw, ITR, DEFAULT_ITR); - } - - if (hw->mac_type >= e1000_82571) { - ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); - /* Reset delay timers after every interrupt */ - ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR; - E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); - E1000_WRITE_FLUSH(hw); - } - /* Setup the Base and Length of the Rx Descriptor Ring */ - ptr = (u32) rx_pool; - if (ptr & 0xf) - ptr = (ptr + 0x10) & (~0xf); - rx_base = (typeof(rx_base)) ptr; - E1000_WRITE_REG(hw, RDBAL, (u32) rx_base); - E1000_WRITE_REG(hw, RDBAH, 0); - - E1000_WRITE_REG(hw, RDLEN, 128); - - /* Setup the HW Rx Head and Tail Descriptor Pointers */ - E1000_WRITE_REG(hw, RDH, 0); - E1000_WRITE_REG(hw, RDT, 0); - /* Enable Receives */ - - E1000_WRITE_REG(hw, RCTL, rctl); - fill_rx(hw); -} - -/************************************************************************** -POLL - Wait for a frame -***************************************************************************/ -static int -e1000_poll(struct eth_device *nic) -{ - struct e1000_hw *hw = nic->priv; - struct e1000_rx_desc *rd; - /* return true if there's an ethernet packet ready to read */ - rd = rx_base + rx_last; - if (!(le32_to_cpu(rd->status)) & E1000_RXD_STAT_DD) - return 0; - /*DEBUGOUT("recv: packet len=%d \n", rd->length); */ - NetReceive((uchar *)packet, le32_to_cpu(rd->length)); - fill_rx(hw); - return 1; -} - -/************************************************************************** -TRANSMIT - Transmit a frame -***************************************************************************/ -static int e1000_transmit(struct eth_device *nic, void *packet, int length) -{ - void *nv_packet = (void *)packet; - struct e1000_hw *hw = nic->priv; - struct e1000_tx_desc *txp; - int i = 0; - - txp = tx_base + tx_tail; - tx_tail = (tx_tail + 1) % 8; - - txp->buffer_addr = cpu_to_le64(virt_to_bus(hw->pdev, nv_packet)); - txp->lower.data = cpu_to_le32(hw->txd_cmd | length); - txp->upper.data = 0; - E1000_WRITE_REG(hw, TDT, tx_tail); - - E1000_WRITE_FLUSH(hw); - while (!(le32_to_cpu(txp->upper.data) & E1000_TXD_STAT_DD)) { - if (i++ > TOUT_LOOP) { - DEBUGOUT("e1000: tx timeout\n"); - return 0; - } - udelay(10); /* give the nic a chance to write to the register */ - } - return 1; -} - -/*reset function*/ -static inline int -e1000_reset(struct eth_device *nic) -{ - struct e1000_hw *hw = nic->priv; - - e1000_reset_hw(hw); - if (hw->mac_type >= e1000_82544) { - E1000_WRITE_REG(hw, WUC, 0); - } - return e1000_init_hw(nic); -} - -/************************************************************************** -DISABLE - Turn off ethernet interface -***************************************************************************/ -static void -e1000_disable(struct eth_device *nic) -{ - struct e1000_hw *hw = nic->priv; - - /* Turn off the ethernet interface */ - E1000_WRITE_REG(hw, RCTL, 0); - E1000_WRITE_REG(hw, TCTL, 0); - - /* Clear the transmit ring */ - E1000_WRITE_REG(hw, TDH, 0); - E1000_WRITE_REG(hw, TDT, 0); - - /* Clear the receive ring */ - E1000_WRITE_REG(hw, RDH, 0); - E1000_WRITE_REG(hw, RDT, 0); - - /* put the card in its initial state */ -#if 0 - E1000_WRITE_REG(hw, CTRL, E1000_CTRL_RST); -#endif - mdelay(10); - -} - -/************************************************************************** -INIT - set up ethernet interface(s) -***************************************************************************/ -static int -e1000_init(struct eth_device *nic, bd_t * bis) -{ - struct e1000_hw *hw = nic->priv; - int ret_val = 0; - - ret_val = e1000_reset(nic); - if (ret_val < 0) { - if ((ret_val == -E1000_ERR_NOLINK) || - (ret_val == -E1000_ERR_TIMEOUT)) { - E1000_ERR(hw->nic, "Valid Link not detected\n"); - } else { - E1000_ERR(hw->nic, "Hardware Initialization Failed\n"); - } - return 0; - } - e1000_configure_tx(hw); - e1000_setup_rctl(hw); - e1000_configure_rx(hw); - return 1; -} - -/****************************************************************************** - * Gets the current PCI bus type of hardware - * - * hw - Struct containing variables accessed by shared code - *****************************************************************************/ -void e1000_get_bus_type(struct e1000_hw *hw) -{ - uint32_t status; - - switch (hw->mac_type) { - case e1000_82542_rev2_0: - case e1000_82542_rev2_1: - hw->bus_type = e1000_bus_type_pci; - break; - case e1000_82571: - case e1000_82572: - case e1000_82573: - case e1000_82574: - case e1000_80003es2lan: - hw->bus_type = e1000_bus_type_pci_express; - break; - case e1000_ich8lan: - hw->bus_type = e1000_bus_type_pci_express; - break; - default: - status = E1000_READ_REG(hw, STATUS); - hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ? - e1000_bus_type_pcix : e1000_bus_type_pci; - break; - } -} - -/* A list of all registered e1000 devices */ -static LIST_HEAD(e1000_hw_list); - -/************************************************************************** -PROBE - Look for an adapter, this routine's visible to the outside -You should omit the last argument struct pci_device * for a non-PCI NIC -***************************************************************************/ -int -e1000_initialize(bd_t * bis) -{ - unsigned int i; - pci_dev_t devno; - - DEBUGFUNC(); - - /* Find and probe all the matching PCI devices */ - for (i = 0; (devno = pci_find_devices(e1000_supported, i)) >= 0; i++) { - u32 val; - - /* - * These will never get freed due to errors, this allows us to - * perform SPI EEPROM programming from U-boot, for example. - */ - struct eth_device *nic = malloc(sizeof(*nic)); - struct e1000_hw *hw = malloc(sizeof(*hw)); - if (!nic || !hw) { - printf("e1000#%u: Out of Memory!\n", i); - free(nic); - free(hw); - continue; - } - - /* Make sure all of the fields are initially zeroed */ - memset(nic, 0, sizeof(*nic)); - memset(hw, 0, sizeof(*hw)); - - /* Assign the passed-in values */ - hw->cardnum = i; - hw->pdev = devno; - hw->nic = nic; - nic->priv = hw; - - /* Generate a card name */ - sprintf(nic->name, "e1000#%u", hw->cardnum); - - /* Print a debug message with the IO base address */ - pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &val); - E1000_DBG(nic, "iobase 0x%08x\n", val & 0xfffffff0); - - /* Try to enable I/O accesses and bus-mastering */ - val = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - pci_write_config_dword(devno, PCI_COMMAND, val); - - /* Make sure it worked */ - pci_read_config_dword(devno, PCI_COMMAND, &val); - if (!(val & PCI_COMMAND_MEMORY)) { - E1000_ERR(nic, "Can't enable I/O memory\n"); - continue; - } - if (!(val & PCI_COMMAND_MASTER)) { - E1000_ERR(nic, "Can't enable bus-mastering\n"); - continue; - } - - /* Are these variables needed? */ - hw->fc = e1000_fc_default; - hw->original_fc = e1000_fc_default; - hw->autoneg_failed = 0; - hw->autoneg = 1; - hw->get_link_status = true; - hw->hw_addr = pci_map_bar(devno, PCI_BASE_ADDRESS_0, - PCI_REGION_MEM); - hw->mac_type = e1000_undefined; - - /* MAC and Phy settings */ - if (e1000_sw_init(nic) < 0) { - E1000_ERR(nic, "Software init failed\n"); - continue; - } - if (e1000_check_phy_reset_block(hw)) - E1000_ERR(nic, "PHY Reset is blocked!\n"); - - /* Basic init was OK, reset the hardware and allow SPI access */ - e1000_reset_hw(hw); - list_add_tail(&hw->list_node, &e1000_hw_list); - -#ifndef CONFIG_E1000_NO_NVM - /* Validate the EEPROM and get chipset information */ -#if !defined(CONFIG_MVBC_1G) - if (e1000_init_eeprom_params(hw)) { - E1000_ERR(nic, "EEPROM is invalid!\n"); - continue; - } - if (e1000_validate_eeprom_checksum(hw)) - continue; -#endif - e1000_read_mac_addr(nic); -#endif - e1000_get_bus_type(hw); - -#ifndef CONFIG_E1000_NO_NVM - printf("e1000: %02x:%02x:%02x:%02x:%02x:%02x\n ", - nic->enetaddr[0], nic->enetaddr[1], nic->enetaddr[2], - nic->enetaddr[3], nic->enetaddr[4], nic->enetaddr[5]); -#else - memset(nic->enetaddr, 0, 6); - printf("e1000: no NVM\n"); -#endif - - /* Set up the function pointers and register the device */ - nic->init = e1000_init; - nic->recv = e1000_poll; - nic->send = e1000_transmit; - nic->halt = e1000_disable; - eth_register(nic); - } - - return i; -} - -struct e1000_hw *e1000_find_card(unsigned int cardnum) -{ - struct e1000_hw *hw; - - list_for_each_entry(hw, &e1000_hw_list, list_node) - if (hw->cardnum == cardnum) - return hw; - - return NULL; -} - -#ifdef CONFIG_CMD_E1000 -static int do_e1000(cmd_tbl_t *cmdtp, int flag, - int argc, char * const argv[]) -{ - struct e1000_hw *hw; - - if (argc < 3) { - cmd_usage(cmdtp); - return 1; - } - - /* Make sure we can find the requested e1000 card */ - hw = e1000_find_card(simple_strtoul(argv[1], NULL, 10)); - if (!hw) { - printf("e1000: ERROR: No such device: e1000#%s\n", argv[1]); - return 1; - } - - if (!strcmp(argv[2], "print-mac-address")) { - unsigned char *mac = hw->nic->enetaddr; - printf("%02x:%02x:%02x:%02x:%02x:%02x\n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - return 0; - } - -#ifdef CONFIG_E1000_SPI - /* Handle the "SPI" subcommand */ - if (!strcmp(argv[2], "spi")) - return do_e1000_spi(cmdtp, hw, argc - 3, argv + 3); -#endif - - cmd_usage(cmdtp); - return 1; -} - -U_BOOT_CMD( - e1000, 7, 0, do_e1000, - "Intel e1000 controller management", - /* */"<card#> print-mac-address\n" -#ifdef CONFIG_E1000_SPI - "e1000 <card#> spi show [<offset> [<length>]]\n" - "e1000 <card#> spi dump <addr> <offset> <length>\n" - "e1000 <card#> spi program <addr> <offset> <length>\n" - "e1000 <card#> spi checksum [update]\n" -#endif - " - Manage the Intel E1000 PCI device" -); -#endif /* not CONFIG_CMD_E1000 */ diff --git a/qemu/roms/u-boot/drivers/net/e1000.h b/qemu/roms/u-boot/drivers/net/e1000.h deleted file mode 100644 index ff87af2ef..000000000 --- a/qemu/roms/u-boot/drivers/net/e1000.h +++ /dev/null @@ -1,2601 +0,0 @@ -/******************************************************************************* - - - Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved. - Copyright 2011 Freescale Semiconductor, Inc. - - * SPDX-License-Identifier: GPL-2.0+ - - Contact Information: - Linux NICS <linux.nics@intel.com> - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ - -/* e1000_hw.h - * Structures, enums, and macros for the MAC - */ - -#ifndef _E1000_HW_H_ -#define _E1000_HW_H_ - -#include <common.h> -#include <linux/list.h> -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <asm/io.h> -#include <pci.h> - -#ifdef CONFIG_E1000_SPI -#include <spi.h> -#endif - -#define E1000_ERR(NIC, fmt, args...) \ - printf("e1000: %s: ERROR: " fmt, (NIC)->name ,##args) - -#ifdef E1000_DEBUG -#define E1000_DBG(NIC, fmt, args...) \ - printf("e1000: %s: DEBUG: " fmt, (NIC)->name ,##args) -#define DEBUGOUT(fmt, args...) printf(fmt ,##args) -#define DEBUGFUNC() printf("%s\n", __func__); -#else -#define E1000_DBG(HW, args...) do { } while (0) -#define DEBUGFUNC() do { } while (0) -#define DEBUGOUT(fmt, args...) do { } while (0) -#endif - -/* I/O wrapper functions */ -#define E1000_WRITE_REG(a, reg, value) \ - writel((value), ((a)->hw_addr + E1000_##reg)) -#define E1000_READ_REG(a, reg) \ - readl((a)->hw_addr + E1000_##reg) -#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) \ - writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2))) -#define E1000_READ_REG_ARRAY(a, reg, offset) \ - readl((a)->hw_addr + E1000_##reg + ((offset) << 2)) -#define E1000_WRITE_FLUSH(a) \ - do { E1000_READ_REG(a, STATUS); } while (0) - -/* Forward declarations of structures used by the shared code */ -struct e1000_hw; -struct e1000_hw_stats; - -/* Internal E1000 helper functions */ -struct e1000_hw *e1000_find_card(unsigned int cardnum); - -#ifndef CONFIG_E1000_NO_NVM -int32_t e1000_acquire_eeprom(struct e1000_hw *hw); -void e1000_standby_eeprom(struct e1000_hw *hw); -void e1000_release_eeprom(struct e1000_hw *hw); -void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t *eecd); -void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t *eecd); -#endif - -#ifdef CONFIG_E1000_SPI -int do_e1000_spi(cmd_tbl_t *cmdtp, struct e1000_hw *hw, - int argc, char * const argv[]); -#endif - -/* Enumerated types specific to the e1000 hardware */ -/* Media Access Controlers */ -typedef enum { - e1000_undefined = 0, - e1000_82542_rev2_0, - e1000_82542_rev2_1, - e1000_82543, - e1000_82544, - e1000_82540, - e1000_82545, - e1000_82545_rev_3, - e1000_82546, - e1000_82546_rev_3, - e1000_82541, - e1000_82541_rev_2, - e1000_82547, - e1000_82547_rev_2, - e1000_82571, - e1000_82572, - e1000_82573, - e1000_82574, - e1000_80003es2lan, - e1000_ich8lan, - e1000_num_macs -} e1000_mac_type; - -/* Media Types */ -typedef enum { - e1000_media_type_copper = 0, - e1000_media_type_fiber = 1, - e1000_media_type_internal_serdes = 2, - e1000_num_media_types -} e1000_media_type; - -typedef enum { - e1000_eeprom_uninitialized = 0, - e1000_eeprom_spi, - e1000_eeprom_microwire, - e1000_eeprom_flash, - e1000_eeprom_ich8, - e1000_eeprom_none, /* No NVM support */ - e1000_num_eeprom_types -} e1000_eeprom_type; - -typedef enum { - e1000_10_half = 0, - e1000_10_full = 1, - e1000_100_half = 2, - e1000_100_full = 3 -} e1000_speed_duplex_type; - -/* Flow Control Settings */ -typedef enum { - e1000_fc_none = 0, - e1000_fc_rx_pause = 1, - e1000_fc_tx_pause = 2, - e1000_fc_full = 3, - e1000_fc_default = 0xFF -} e1000_fc_type; - -/* PCI bus types */ -typedef enum { - e1000_bus_type_unknown = 0, - e1000_bus_type_pci, - e1000_bus_type_pcix, - e1000_bus_type_pci_express, - e1000_bus_type_reserved -} e1000_bus_type; - -/* PCI bus speeds */ -typedef enum { - e1000_bus_speed_unknown = 0, - e1000_bus_speed_33, - e1000_bus_speed_66, - e1000_bus_speed_100, - e1000_bus_speed_133, - e1000_bus_speed_reserved -} e1000_bus_speed; - -/* PCI bus widths */ -typedef enum { - e1000_bus_width_unknown = 0, - e1000_bus_width_32, - e1000_bus_width_64 -} e1000_bus_width; - -/* PHY status info structure and supporting enums */ -typedef enum { - e1000_cable_length_50 = 0, - e1000_cable_length_50_80, - e1000_cable_length_80_110, - e1000_cable_length_110_140, - e1000_cable_length_140, - e1000_cable_length_undefined = 0xFF -} e1000_cable_length; - -typedef enum { - e1000_10bt_ext_dist_enable_normal = 0, - e1000_10bt_ext_dist_enable_lower, - e1000_10bt_ext_dist_enable_undefined = 0xFF -} e1000_10bt_ext_dist_enable; - -typedef enum { - e1000_rev_polarity_normal = 0, - e1000_rev_polarity_reversed, - e1000_rev_polarity_undefined = 0xFF -} e1000_rev_polarity; - -typedef enum { - e1000_polarity_reversal_enabled = 0, - e1000_polarity_reversal_disabled, - e1000_polarity_reversal_undefined = 0xFF -} e1000_polarity_reversal; - -typedef enum { - e1000_auto_x_mode_manual_mdi = 0, - e1000_auto_x_mode_manual_mdix, - e1000_auto_x_mode_auto1, - e1000_auto_x_mode_auto2, - e1000_auto_x_mode_undefined = 0xFF -} e1000_auto_x_mode; - -typedef enum { - e1000_1000t_rx_status_not_ok = 0, - e1000_1000t_rx_status_ok, - e1000_1000t_rx_status_undefined = 0xFF -} e1000_1000t_rx_status; - -typedef enum { - e1000_phy_m88 = 0, - e1000_phy_igp, - e1000_phy_igp_2, - e1000_phy_gg82563, - e1000_phy_igp_3, - e1000_phy_ife, - e1000_phy_bm, - e1000_phy_undefined = 0xFF -} e1000_phy_type; - -struct e1000_phy_info { - e1000_cable_length cable_length; - e1000_10bt_ext_dist_enable extended_10bt_distance; - e1000_rev_polarity cable_polarity; - e1000_polarity_reversal polarity_correction; - e1000_auto_x_mode mdix_mode; - e1000_1000t_rx_status local_rx; - e1000_1000t_rx_status remote_rx; -}; - -struct e1000_phy_stats { - uint32_t idle_errors; - uint32_t receive_errors; -}; - -/* Error Codes */ -#define E1000_SUCCESS 0 -#define E1000_ERR_EEPROM 1 -#define E1000_ERR_PHY 2 -#define E1000_ERR_CONFIG 3 -#define E1000_ERR_PARAM 4 -#define E1000_ERR_MAC_TYPE 5 -#define E1000_ERR_PHY_TYPE 6 -#define E1000_ERR_NOLINK 7 -#define E1000_ERR_TIMEOUT 8 -#define E1000_ERR_RESET 9 -#define E1000_ERR_MASTER_REQUESTS_PENDING 10 -#define E1000_ERR_HOST_INTERFACE_COMMAND 11 -#define E1000_BLK_PHY_RESET 12 -#define E1000_ERR_SWFW_SYNC 13 - -/* PCI Device IDs */ -#define E1000_DEV_ID_82542 0x1000 -#define E1000_DEV_ID_82543GC_FIBER 0x1001 -#define E1000_DEV_ID_82543GC_COPPER 0x1004 -#define E1000_DEV_ID_82544EI_COPPER 0x1008 -#define E1000_DEV_ID_82544EI_FIBER 0x1009 -#define E1000_DEV_ID_82544GC_COPPER 0x100C -#define E1000_DEV_ID_82544GC_LOM 0x100D -#define E1000_DEV_ID_82540EM 0x100E -#define E1000_DEV_ID_82540EM_LOM 0x1015 -#define E1000_DEV_ID_82540EP_LOM 0x1016 -#define E1000_DEV_ID_82540EP 0x1017 -#define E1000_DEV_ID_82540EP_LP 0x101E -#define E1000_DEV_ID_82545EM_COPPER 0x100F -#define E1000_DEV_ID_82545EM_FIBER 0x1011 -#define E1000_DEV_ID_82545GM_COPPER 0x1026 -#define E1000_DEV_ID_82545GM_FIBER 0x1027 -#define E1000_DEV_ID_82545GM_SERDES 0x1028 -#define E1000_DEV_ID_82546EB_COPPER 0x1010 -#define E1000_DEV_ID_82546EB_FIBER 0x1012 -#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D -#define E1000_DEV_ID_82541EI 0x1013 -#define E1000_DEV_ID_82541EI_MOBILE 0x1018 -#define E1000_DEV_ID_82541ER_LOM 0x1014 -#define E1000_DEV_ID_82541ER 0x1078 -#define E1000_DEV_ID_82547GI 0x1075 -#define E1000_DEV_ID_82541GI 0x1076 -#define E1000_DEV_ID_82541GI_MOBILE 0x1077 -#define E1000_DEV_ID_82541GI_LF 0x107C -#define E1000_DEV_ID_82546GB_COPPER 0x1079 -#define E1000_DEV_ID_82546GB_FIBER 0x107A -#define E1000_DEV_ID_82546GB_SERDES 0x107B -#define E1000_DEV_ID_82546GB_PCIE 0x108A -#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099 -#define E1000_DEV_ID_82547EI 0x1019 -#define E1000_DEV_ID_82547EI_MOBILE 0x101A -#define E1000_DEV_ID_82571EB_COPPER 0x105E -#define E1000_DEV_ID_82571EB_FIBER 0x105F -#define E1000_DEV_ID_82571EB_SERDES 0x1060 -#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4 -#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5 -#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5 -#define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE 0x10BC -#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9 -#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA -#define E1000_DEV_ID_82572EI_COPPER 0x107D -#define E1000_DEV_ID_82572EI_FIBER 0x107E -#define E1000_DEV_ID_82572EI_SERDES 0x107F -#define E1000_DEV_ID_82572EI 0x10B9 -#define E1000_DEV_ID_82573E 0x108B -#define E1000_DEV_ID_82573E_IAMT 0x108C -#define E1000_DEV_ID_82573L 0x109A -#define E1000_DEV_ID_82574L 0x10D3 -#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5 -#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096 -#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098 -#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA -#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB - -#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049 -#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A -#define E1000_DEV_ID_ICH8_IGP_C 0x104B -#define E1000_DEV_ID_ICH8_IFE 0x104C -#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4 -#define E1000_DEV_ID_ICH8_IFE_G 0x10C5 -#define E1000_DEV_ID_ICH8_IGP_M 0x104D - -#define IGP03E1000_E_PHY_ID 0x02A80390 -#define IFE_E_PHY_ID 0x02A80330 /* 10/100 PHY */ -#define IFE_PLUS_E_PHY_ID 0x02A80320 -#define IFE_C_E_PHY_ID 0x02A80310 - -#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10 /* 100BaseTx Extended Status, - Control and Address */ -#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY special - control register */ -#define IFE_PHY_RCV_FALSE_CARRIER 0x13 /* 100BaseTx Receive false - Carrier Counter */ -#define IFE_PHY_RCV_DISCONNECT 0x14 /* 100BaseTx Receive Disconnet - Counter */ -#define IFE_PHY_RCV_ERROT_FRAME 0x15 /* 100BaseTx Receive Error - Frame Counter */ -#define IFE_PHY_RCV_SYMBOL_ERR 0x16 /* Receive Symbol Error - Counter */ -#define IFE_PHY_PREM_EOF_ERR 0x17 /* 100BaseTx Receive - Premature End Of Frame - Error Counter */ -#define IFE_PHY_RCV_EOF_ERR 0x18 /* 10BaseT Receive End Of - Frame Error Counter */ -#define IFE_PHY_TX_JABBER_DETECT 0x19 /* 10BaseT Transmit Jabber - Detect Counter */ -#define IFE_PHY_EQUALIZER 0x1A /* PHY Equalizer Control and - Status */ -#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY special control and - LED configuration */ -#define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control register */ -#define IFE_PHY_HWI_CONTROL 0x1D /* Hardware Integrity Control - (HWI) */ - -#define IFE_PESC_REDUCED_POWER_DOWN_DISABLE 0x2000 /* Defaut 1 = Disable auto - reduced power down */ -#define IFE_PESC_100BTX_POWER_DOWN 0x0400 /* Indicates the power - state of 100BASE-TX */ -#define IFE_PESC_10BTX_POWER_DOWN 0x0200 /* Indicates the power - state of 10BASE-T */ -#define IFE_PESC_POLARITY_REVERSED 0x0100 /* Indicates 10BASE-T - polarity */ -#define IFE_PESC_PHY_ADDR_MASK 0x007C /* Bit 6:2 for sampled PHY - address */ -#define IFE_PESC_SPEED 0x0002 /* Auto-negotiation speed - result 1=100Mbs, 0=10Mbs */ -#define IFE_PESC_DUPLEX 0x0001 /* Auto-negotiation - duplex result 1=Full, 0=Half */ -#define IFE_PESC_POLARITY_REVERSED_SHIFT 8 - -#define IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN 0x0100 /* 1 = Dyanmic Power Down - disabled */ -#define IFE_PSC_FORCE_POLARITY 0x0020 /* 1=Reversed Polarity, - 0=Normal */ -#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010 /* 1=Auto Polarity - Disabled, 0=Enabled */ -#define IFE_PSC_JABBER_FUNC_DISABLE 0x0001 /* 1=Jabber Disabled, - 0=Normal Jabber Operation */ -#define IFE_PSC_FORCE_POLARITY_SHIFT 5 -#define IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT 4 - -#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable MDI/MDI-X - feature, default 0=disabled */ -#define IFE_PMC_FORCE_MDIX 0x0040 /* 1=force MDIX-X, - 0=force MDI */ -#define IFE_PMC_MDIX_STATUS 0x0020 /* 1=MDI-X, 0=MDI */ -#define IFE_PMC_AUTO_MDIX_COMPLETE 0x0010 /* Resolution algorithm - is completed */ -#define IFE_PMC_MDIX_MODE_SHIFT 6 -#define IFE_PHC_MDIX_RESET_ALL_MASK 0x0000 /* Disable auto MDI-X */ - -#define IFE_PHC_HWI_ENABLE 0x8000 /* Enable the HWI - feature */ -#define IFE_PHC_ABILITY_CHECK 0x4000 /* 1= Test Passed, - 0=failed */ -#define IFE_PHC_TEST_EXEC 0x2000 /* PHY launch test pulses - on the wire */ -#define IFE_PHC_HIGHZ 0x0200 /* 1 = Open Circuit */ -#define IFE_PHC_LOWZ 0x0400 /* 1 = Short Circuit */ -#define IFE_PHC_LOW_HIGH_Z_MASK 0x0600 /* Mask for indication - type of problem on the line */ -#define IFE_PHC_DISTANCE_MASK 0x01FF /* Mask for distance to - the cable problem, in 80cm granularity */ -#define IFE_PHC_RESET_ALL_MASK 0x0000 /* Disable HWI */ -#define IFE_PSCL_PROBE_MODE 0x0020 /* LED Probe mode */ -#define IFE_PSCL_PROBE_LEDS_OFF 0x0006 /* Force LEDs 0 and 2 - off */ -#define IFE_PSCL_PROBE_LEDS_ON 0x0007 /* Force LEDs 0 and 2 on */ - - -#define NUM_DEV_IDS 16 - -#define NODE_ADDRESS_SIZE 6 -#define ETH_LENGTH_OF_ADDRESS 6 - -/* MAC decode size is 128K - This is the size of BAR0 */ -#define MAC_DECODE_SIZE (128 * 1024) - -#define E1000_82542_2_0_REV_ID 2 -#define E1000_82542_2_1_REV_ID 3 -#define E1000_REVISION_0 0 -#define E1000_REVISION_1 1 -#define E1000_REVISION_2 2 -#define E1000_REVISION_3 3 - -#define SPEED_10 10 -#define SPEED_100 100 -#define SPEED_1000 1000 -#define HALF_DUPLEX 1 -#define FULL_DUPLEX 2 - -/* The sizes (in bytes) of a ethernet packet */ -#define ENET_HEADER_SIZE 14 -#define MAXIMUM_ETHERNET_FRAME_SIZE 1518 /* With FCS */ -#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */ -#define ETHERNET_FCS_SIZE 4 -#define MAXIMUM_ETHERNET_PACKET_SIZE \ - (MAXIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE) -#define MINIMUM_ETHERNET_PACKET_SIZE \ - (MINIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE) -#define CRC_LENGTH ETHERNET_FCS_SIZE -#define MAX_JUMBO_FRAME_SIZE 0x3F00 - -/* 802.1q VLAN Packet Sizes */ -#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMAed) */ - -/* Ethertype field values */ -#define ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.3ac packet */ -#define ETHERNET_IP_TYPE 0x0800 /* IP packets */ -#define ETHERNET_ARP_TYPE 0x0806 /* Address Resolution Protocol (ARP) */ - -/* Packet Header defines */ -#define IP_PROTOCOL_TCP 6 -#define IP_PROTOCOL_UDP 0x11 - -/* This defines the bits that are set in the Interrupt Mask - * Set/Read Register. Each bit is documented below: - * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0) - * o RXSEQ = Receive Sequence Error - */ -#define POLL_IMS_ENABLE_MASK ( \ - E1000_IMS_RXDMT0 | \ - E1000_IMS_RXSEQ) - -/* This defines the bits that are set in the Interrupt Mask - * Set/Read Register. Each bit is documented below: - * o RXT0 = Receiver Timer Interrupt (ring 0) - * o TXDW = Transmit Descriptor Written Back - * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0) - * o RXSEQ = Receive Sequence Error - * o LSC = Link Status Change - */ -#define IMS_ENABLE_MASK ( \ - E1000_IMS_RXT0 | \ - E1000_IMS_TXDW | \ - E1000_IMS_RXDMT0 | \ - E1000_IMS_RXSEQ | \ - E1000_IMS_LSC) - -/* The number of high/low register pairs in the RAR. The RAR (Receive Address - * Registers) holds the directed and multicast addresses that we monitor. We - * reserve one of these spots for our directed address, allowing us room for - * E1000_RAR_ENTRIES - 1 multicast addresses. - */ -#define E1000_RAR_ENTRIES 16 - -#define MIN_NUMBER_OF_DESCRIPTORS 8 -#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8 - -/* Receive Descriptor */ -struct e1000_rx_desc { - uint64_t buffer_addr; /* Address of the descriptor's data buffer */ - uint16_t length; /* Length of data DMAed into data buffer */ - uint16_t csum; /* Packet checksum */ - uint8_t status; /* Descriptor status */ - uint8_t errors; /* Descriptor Errors */ - uint16_t special; -}; - -/* Receive Decriptor bit definitions */ -#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */ -#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */ -#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */ -#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */ -#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */ -#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */ -#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */ -#define E1000_RXD_ERR_CE 0x01 /* CRC Error */ -#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */ -#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */ -#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */ -#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */ -#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */ -#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ -#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ -#define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */ -#define E1000_RXD_SPC_PRI_SHIFT 0x000D /* Priority is in upper 3 of 16 */ -#define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */ -#define E1000_RXD_SPC_CFI_SHIFT 0x000C /* CFI is bit 12 */ - -/* mask to determine if packets should be dropped due to frame errors */ -#define E1000_RXD_ERR_FRAME_ERR_MASK ( \ - E1000_RXD_ERR_CE | \ - E1000_RXD_ERR_SE | \ - E1000_RXD_ERR_SEQ | \ - E1000_RXD_ERR_CXE | \ - E1000_RXD_ERR_RXE) - -/* Transmit Descriptor */ -struct e1000_tx_desc { - uint64_t buffer_addr; /* Address of the descriptor's data buffer */ - union { - uint32_t data; - struct { - uint16_t length; /* Data buffer length */ - uint8_t cso; /* Checksum offset */ - uint8_t cmd; /* Descriptor control */ - } flags; - } lower; - union { - uint32_t data; - struct { - uint8_t status; /* Descriptor status */ - uint8_t css; /* Checksum start */ - uint16_t special; - } fields; - } upper; -}; - -/* Transmit Descriptor bit definitions */ -#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */ -#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */ -#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */ -#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */ -#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */ -#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ -#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */ -#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */ -#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */ -#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */ -#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */ -#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */ -#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */ -#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */ -#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */ -#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */ -#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */ -#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */ -#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */ -#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */ - -/* Offload Context Descriptor */ -struct e1000_context_desc { - union { - uint32_t ip_config; - struct { - uint8_t ipcss; /* IP checksum start */ - uint8_t ipcso; /* IP checksum offset */ - uint16_t ipcse; /* IP checksum end */ - } ip_fields; - } lower_setup; - union { - uint32_t tcp_config; - struct { - uint8_t tucss; /* TCP checksum start */ - uint8_t tucso; /* TCP checksum offset */ - uint16_t tucse; /* TCP checksum end */ - } tcp_fields; - } upper_setup; - uint32_t cmd_and_length; /* */ - union { - uint32_t data; - struct { - uint8_t status; /* Descriptor status */ - uint8_t hdr_len; /* Header length */ - uint16_t mss; /* Maximum segment size */ - } fields; - } tcp_seg_setup; -}; - -/* Offload data descriptor */ -struct e1000_data_desc { - uint64_t buffer_addr; /* Address of the descriptor's buffer address */ - union { - uint32_t data; - struct { - uint16_t length; /* Data buffer length */ - uint8_t typ_len_ext; /* */ - uint8_t cmd; /* */ - } flags; - } lower; - union { - uint32_t data; - struct { - uint8_t status; /* Descriptor status */ - uint8_t popts; /* Packet Options */ - uint16_t special; /* */ - } fields; - } upper; -}; - -/* Filters */ -#define E1000_NUM_UNICAST 16 /* Unicast filter entries */ -#define E1000_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bits) */ -#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */ - -/* Receive Address Register */ -struct e1000_rar { - volatile uint32_t low; /* receive address low */ - volatile uint32_t high; /* receive address high */ -}; - -/* The number of entries in the Multicast Table Array (MTA). */ -#define E1000_NUM_MTA_REGISTERS 128 - -/* IPv4 Address Table Entry */ -struct e1000_ipv4_at_entry { - volatile uint32_t ipv4_addr; /* IP Address (RW) */ - volatile uint32_t reserved; -}; - -/* Four wakeup IP addresses are supported */ -#define E1000_WAKEUP_IP_ADDRESS_COUNT_MAX 4 -#define E1000_IP4AT_SIZE E1000_WAKEUP_IP_ADDRESS_COUNT_MAX -#define E1000_IP6AT_SIZE 1 - -/* IPv6 Address Table Entry */ -struct e1000_ipv6_at_entry { - volatile uint8_t ipv6_addr[16]; -}; - -/* Flexible Filter Length Table Entry */ -struct e1000_fflt_entry { - volatile uint32_t length; /* Flexible Filter Length (RW) */ - volatile uint32_t reserved; -}; - -/* Flexible Filter Mask Table Entry */ -struct e1000_ffmt_entry { - volatile uint32_t mask; /* Flexible Filter Mask (RW) */ - volatile uint32_t reserved; -}; - -/* Flexible Filter Value Table Entry */ -struct e1000_ffvt_entry { - volatile uint32_t value; /* Flexible Filter Value (RW) */ - volatile uint32_t reserved; -}; - -/* Four Flexible Filters are supported */ -#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4 - -/* Each Flexible Filter is at most 128 (0x80) bytes in length */ -#define E1000_FLEXIBLE_FILTER_SIZE_MAX 128 - -#define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX -#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX -#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX - -/* Register Set. (82543, 82544) - * - * Registers are defined to be 32 bits and should be accessed as 32 bit values. - * These registers are physically located on the NIC, but are mapped into the - * host memory address space. - * - * RW - register is both readable and writable - * RO - register is read only - * WO - register is write only - * R/clr - register is read only and is cleared when read - * A - register array - */ -#define E1000_CTRL 0x00000 /* Device Control - RW */ -#define E1000_STATUS 0x00008 /* Device Status - RO */ -#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */ -#define E1000_EERD 0x00014 /* EEPROM Read - RW */ -#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */ -#define E1000_MDIC 0x00020 /* MDI Control - RW */ -#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */ -#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */ -#define E1000_FCT 0x00030 /* Flow Control Type - RW */ -#define E1000_VET 0x00038 /* VLAN Ether Type - RW */ -#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */ -#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */ -#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */ -#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */ -#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */ -#define E1000_RCTL 0x00100 /* RX Control - RW */ -#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */ -#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */ -#define E1000_RXCW 0x00180 /* RX Configuration Word - RO */ -#define E1000_TCTL 0x00400 /* TX Control - RW */ -#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */ -#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */ -#define E1000_TBT 0x00448 /* TX Burst Timer - RW */ -#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */ -#define E1000_LEDCTL 0x00E00 /* LED Control - RW */ -#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */ -#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */ -#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */ -#define FEXTNVM_SW_CONFIG 0x0001 -#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */ -#define E1000_PBS 0x01008 /* Packet Buffer Size */ -#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */ -#define E1000_FLASH_UPDATES 1000 -#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */ -#define E1000_FLASHT 0x01028 /* FLASH Timer Register */ -#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */ -#define E1000_FLSWCTL 0x01030 /* FLASH control register */ -#define E1000_FLSWDATA 0x01034 /* FLASH data register */ -#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */ -#define E1000_FLOP 0x0103C /* FLASH Opcode Register */ -#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */ -#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */ -#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */ -#define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */ -#define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */ -#define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */ -#define E1000_RDH 0x02810 /* RX Descriptor Head - RW */ -#define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */ -#define E1000_RDTR 0x02820 /* RX Delay Timer - RW */ -#define E1000_RXDCTL 0x02828 /* RX Descriptor Control - RW */ -#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */ -#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */ -#define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */ -#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */ -#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */ -#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */ -#define E1000_TDFTS 0x03428 /* TX Data FIFO Tail Saved - RW */ -#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */ -#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */ -#define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */ -#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */ -#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */ -#define E1000_TDT 0x03818 /* TX Descripotr Tail - RW */ -#define E1000_TIDV 0x03820 /* TX Interrupt Delay Value - RW */ -#define E1000_TXDCTL 0x03828 /* TX Descriptor Control - RW */ -#define E1000_TADV 0x0382C /* TX Interrupt Absolute Delay Val - RW */ -#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */ -#define E1000_TARC0 0x03840 /* TX Arbitration Count (0) */ -#define E1000_TDBAL1 0x03900 /* TX Desc Base Address Low (1) - RW */ -#define E1000_TDBAH1 0x03904 /* TX Desc Base Address High (1) - RW */ -#define E1000_TDLEN1 0x03908 /* TX Desc Length (1) - RW */ -#define E1000_TDH1 0x03910 /* TX Desc Head (1) - RW */ -#define E1000_TDT1 0x03918 /* TX Desc Tail (1) - RW */ -#define E1000_TXDCTL1 0x03928 /* TX Descriptor Control (1) - RW */ -#define E1000_TARC1 0x03940 /* TX Arbitration Count (1) */ -#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */ -#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */ -#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */ -#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */ -#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */ -#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */ -#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */ -#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */ -#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */ -#define E1000_COLC 0x04028 /* Collision Count - R/clr */ -#define E1000_DC 0x04030 /* Defer Count - R/clr */ -#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */ -#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */ -#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */ -#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */ -#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */ -#define E1000_XONTXC 0x0404C /* XON TX Count - R/clr */ -#define E1000_XOFFRXC 0x04050 /* XOFF RX Count - R/clr */ -#define E1000_XOFFTXC 0x04054 /* XOFF TX Count - R/clr */ -#define E1000_FCRUC 0x04058 /* Flow Control RX Unsupported Count- R/clr */ -#define E1000_PRC64 0x0405C /* Packets RX (64 bytes) - R/clr */ -#define E1000_PRC127 0x04060 /* Packets RX (65-127 bytes) - R/clr */ -#define E1000_PRC255 0x04064 /* Packets RX (128-255 bytes) - R/clr */ -#define E1000_PRC511 0x04068 /* Packets RX (255-511 bytes) - R/clr */ -#define E1000_PRC1023 0x0406C /* Packets RX (512-1023 bytes) - R/clr */ -#define E1000_PRC1522 0x04070 /* Packets RX (1024-1522 bytes) - R/clr */ -#define E1000_GPRC 0x04074 /* Good Packets RX Count - R/clr */ -#define E1000_BPRC 0x04078 /* Broadcast Packets RX Count - R/clr */ -#define E1000_MPRC 0x0407C /* Multicast Packets RX Count - R/clr */ -#define E1000_GPTC 0x04080 /* Good Packets TX Count - R/clr */ -#define E1000_GORCL 0x04088 /* Good Octets RX Count Low - R/clr */ -#define E1000_GORCH 0x0408C /* Good Octets RX Count High - R/clr */ -#define E1000_GOTCL 0x04090 /* Good Octets TX Count Low - R/clr */ -#define E1000_GOTCH 0x04094 /* Good Octets TX Count High - R/clr */ -#define E1000_RNBC 0x040A0 /* RX No Buffers Count - R/clr */ -#define E1000_RUC 0x040A4 /* RX Undersize Count - R/clr */ -#define E1000_RFC 0x040A8 /* RX Fragment Count - R/clr */ -#define E1000_ROC 0x040AC /* RX Oversize Count - R/clr */ -#define E1000_RJC 0x040B0 /* RX Jabber Count - R/clr */ -#define E1000_MGTPRC 0x040B4 /* Management Packets RX Count - R/clr */ -#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */ -#define E1000_MGTPTC 0x040BC /* Management Packets TX Count - R/clr */ -#define E1000_TORL 0x040C0 /* Total Octets RX Low - R/clr */ -#define E1000_TORH 0x040C4 /* Total Octets RX High - R/clr */ -#define E1000_TOTL 0x040C8 /* Total Octets TX Low - R/clr */ -#define E1000_TOTH 0x040CC /* Total Octets TX High - R/clr */ -#define E1000_TPR 0x040D0 /* Total Packets RX - R/clr */ -#define E1000_TPT 0x040D4 /* Total Packets TX - R/clr */ -#define E1000_PTC64 0x040D8 /* Packets TX (64 bytes) - R/clr */ -#define E1000_PTC127 0x040DC /* Packets TX (65-127 bytes) - R/clr */ -#define E1000_PTC255 0x040E0 /* Packets TX (128-255 bytes) - R/clr */ -#define E1000_PTC511 0x040E4 /* Packets TX (256-511 bytes) - R/clr */ -#define E1000_PTC1023 0x040E8 /* Packets TX (512-1023 bytes) - R/clr */ -#define E1000_PTC1522 0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */ -#define E1000_MPTC 0x040F0 /* Multicast Packets TX Count - R/clr */ -#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */ -#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */ -#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */ -#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */ -#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */ -#define E1000_RA 0x05400 /* Receive Address - RW Array */ -#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */ -#define E1000_WUC 0x05800 /* Wakeup Control - RW */ -#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */ -#define E1000_WUS 0x05810 /* Wakeup Status - RO */ -#define E1000_MANC 0x05820 /* Management Control - RW */ -#define E1000_IPAV 0x05838 /* IP Address Valid - RW */ -#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */ -#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */ -#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */ -#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */ -#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */ -#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */ -#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */ - -/* Register Set (82542) - * - * Some of the 82542 registers are located at different offsets than they are - * in more current versions of the 8254x. Despite the difference in location, - * the registers function in the same manner. - */ -#define E1000_82542_CTRL E1000_CTRL -#define E1000_82542_STATUS E1000_STATUS -#define E1000_82542_EECD E1000_EECD -#define E1000_82542_EERD E1000_EERD -#define E1000_82542_CTRL_EXT E1000_CTRL_EXT -#define E1000_82542_MDIC E1000_MDIC -#define E1000_82542_FCAL E1000_FCAL -#define E1000_82542_FCAH E1000_FCAH -#define E1000_82542_FCT E1000_FCT -#define E1000_82542_VET E1000_VET -#define E1000_82542_RA 0x00040 -#define E1000_82542_ICR E1000_ICR -#define E1000_82542_ITR E1000_ITR -#define E1000_82542_ICS E1000_ICS -#define E1000_82542_IMS E1000_IMS -#define E1000_82542_IMC E1000_IMC -#define E1000_82542_RCTL E1000_RCTL -#define E1000_82542_RDTR 0x00108 -#define E1000_82542_RDBAL 0x00110 -#define E1000_82542_RDBAH 0x00114 -#define E1000_82542_RDLEN 0x00118 -#define E1000_82542_RDH 0x00120 -#define E1000_82542_RDT 0x00128 -#define E1000_82542_FCRTH 0x00160 -#define E1000_82542_FCRTL 0x00168 -#define E1000_82542_FCTTV E1000_FCTTV -#define E1000_82542_TXCW E1000_TXCW -#define E1000_82542_RXCW E1000_RXCW -#define E1000_82542_MTA 0x00200 -#define E1000_82542_TCTL E1000_TCTL -#define E1000_82542_TIPG E1000_TIPG -#define E1000_82542_TDBAL 0x00420 -#define E1000_82542_TDBAH 0x00424 -#define E1000_82542_TDLEN 0x00428 -#define E1000_82542_TDH 0x00430 -#define E1000_82542_TDT 0x00438 -#define E1000_82542_TIDV 0x00440 -#define E1000_82542_TBT E1000_TBT -#define E1000_82542_AIT E1000_AIT -#define E1000_82542_VFTA 0x00600 -#define E1000_82542_LEDCTL E1000_LEDCTL -#define E1000_82542_PBA E1000_PBA -#define E1000_82542_RXDCTL E1000_RXDCTL -#define E1000_82542_RADV E1000_RADV -#define E1000_82542_RSRPD E1000_RSRPD -#define E1000_82542_TXDMAC E1000_TXDMAC -#define E1000_82542_TXDCTL E1000_TXDCTL -#define E1000_82542_TADV E1000_TADV -#define E1000_82542_TSPMT E1000_TSPMT -#define E1000_82542_CRCERRS E1000_CRCERRS -#define E1000_82542_ALGNERRC E1000_ALGNERRC -#define E1000_82542_SYMERRS E1000_SYMERRS -#define E1000_82542_RXERRC E1000_RXERRC -#define E1000_82542_MPC E1000_MPC -#define E1000_82542_SCC E1000_SCC -#define E1000_82542_ECOL E1000_ECOL -#define E1000_82542_MCC E1000_MCC -#define E1000_82542_LATECOL E1000_LATECOL -#define E1000_82542_COLC E1000_COLC -#define E1000_82542_DC E1000_DC -#define E1000_82542_TNCRS E1000_TNCRS -#define E1000_82542_SEC E1000_SEC -#define E1000_82542_CEXTERR E1000_CEXTERR -#define E1000_82542_RLEC E1000_RLEC -#define E1000_82542_XONRXC E1000_XONRXC -#define E1000_82542_XONTXC E1000_XONTXC -#define E1000_82542_XOFFRXC E1000_XOFFRXC -#define E1000_82542_XOFFTXC E1000_XOFFTXC -#define E1000_82542_FCRUC E1000_FCRUC -#define E1000_82542_PRC64 E1000_PRC64 -#define E1000_82542_PRC127 E1000_PRC127 -#define E1000_82542_PRC255 E1000_PRC255 -#define E1000_82542_PRC511 E1000_PRC511 -#define E1000_82542_PRC1023 E1000_PRC1023 -#define E1000_82542_PRC1522 E1000_PRC1522 -#define E1000_82542_GPRC E1000_GPRC -#define E1000_82542_BPRC E1000_BPRC -#define E1000_82542_MPRC E1000_MPRC -#define E1000_82542_GPTC E1000_GPTC -#define E1000_82542_GORCL E1000_GORCL -#define E1000_82542_GORCH E1000_GORCH -#define E1000_82542_GOTCL E1000_GOTCL -#define E1000_82542_GOTCH E1000_GOTCH -#define E1000_82542_RNBC E1000_RNBC -#define E1000_82542_RUC E1000_RUC -#define E1000_82542_RFC E1000_RFC -#define E1000_82542_ROC E1000_ROC -#define E1000_82542_RJC E1000_RJC -#define E1000_82542_MGTPRC E1000_MGTPRC -#define E1000_82542_MGTPDC E1000_MGTPDC -#define E1000_82542_MGTPTC E1000_MGTPTC -#define E1000_82542_TORL E1000_TORL -#define E1000_82542_TORH E1000_TORH -#define E1000_82542_TOTL E1000_TOTL -#define E1000_82542_TOTH E1000_TOTH -#define E1000_82542_TPR E1000_TPR -#define E1000_82542_TPT E1000_TPT -#define E1000_82542_PTC64 E1000_PTC64 -#define E1000_82542_PTC127 E1000_PTC127 -#define E1000_82542_PTC255 E1000_PTC255 -#define E1000_82542_PTC511 E1000_PTC511 -#define E1000_82542_PTC1023 E1000_PTC1023 -#define E1000_82542_PTC1522 E1000_PTC1522 -#define E1000_82542_MPTC E1000_MPTC -#define E1000_82542_BPTC E1000_BPTC -#define E1000_82542_TSCTC E1000_TSCTC -#define E1000_82542_TSCTFC E1000_TSCTFC -#define E1000_82542_RXCSUM E1000_RXCSUM -#define E1000_82542_WUC E1000_WUC -#define E1000_82542_WUFC E1000_WUFC -#define E1000_82542_WUS E1000_WUS -#define E1000_82542_MANC E1000_MANC -#define E1000_82542_IPAV E1000_IPAV -#define E1000_82542_IP4AT E1000_IP4AT -#define E1000_82542_IP6AT E1000_IP6AT -#define E1000_82542_WUPL E1000_WUPL -#define E1000_82542_WUPM E1000_WUPM -#define E1000_82542_FFLT E1000_FFLT -#define E1000_82542_FFMT E1000_FFMT -#define E1000_82542_FFVT E1000_FFVT - -/* Statistics counters collected by the MAC */ -struct e1000_hw_stats { - uint64_t crcerrs; - uint64_t algnerrc; - uint64_t symerrs; - uint64_t rxerrc; - uint64_t mpc; - uint64_t scc; - uint64_t ecol; - uint64_t mcc; - uint64_t latecol; - uint64_t colc; - uint64_t dc; - uint64_t tncrs; - uint64_t sec; - uint64_t cexterr; - uint64_t rlec; - uint64_t xonrxc; - uint64_t xontxc; - uint64_t xoffrxc; - uint64_t xofftxc; - uint64_t fcruc; - uint64_t prc64; - uint64_t prc127; - uint64_t prc255; - uint64_t prc511; - uint64_t prc1023; - uint64_t prc1522; - uint64_t gprc; - uint64_t bprc; - uint64_t mprc; - uint64_t gptc; - uint64_t gorcl; - uint64_t gorch; - uint64_t gotcl; - uint64_t gotch; - uint64_t rnbc; - uint64_t ruc; - uint64_t rfc; - uint64_t roc; - uint64_t rjc; - uint64_t mgprc; - uint64_t mgpdc; - uint64_t mgptc; - uint64_t torl; - uint64_t torh; - uint64_t totl; - uint64_t toth; - uint64_t tpr; - uint64_t tpt; - uint64_t ptc64; - uint64_t ptc127; - uint64_t ptc255; - uint64_t ptc511; - uint64_t ptc1023; - uint64_t ptc1522; - uint64_t mptc; - uint64_t bptc; - uint64_t tsctc; - uint64_t tsctfc; -}; - -#ifndef CONFIG_E1000_NO_NVM -struct e1000_eeprom_info { -e1000_eeprom_type type; - uint16_t word_size; - uint16_t opcode_bits; - uint16_t address_bits; - uint16_t delay_usec; - uint16_t page_size; - bool use_eerd; - bool use_eewr; -}; -#endif - -typedef enum { - e1000_smart_speed_default = 0, - e1000_smart_speed_on, - e1000_smart_speed_off -} e1000_smart_speed; - -typedef enum { - e1000_dsp_config_disabled = 0, - e1000_dsp_config_enabled, - e1000_dsp_config_activated, - e1000_dsp_config_undefined = 0xFF -} e1000_dsp_config; - -typedef enum { - e1000_ms_hw_default = 0, - e1000_ms_force_master, - e1000_ms_force_slave, - e1000_ms_auto -} e1000_ms_type; - -typedef enum { - e1000_ffe_config_enabled = 0, - e1000_ffe_config_active, - e1000_ffe_config_blocked -} e1000_ffe_config; - - -/* Structure containing variables used by the shared code (e1000_hw.c) */ -struct e1000_hw { - struct list_head list_node; - struct eth_device *nic; -#ifdef CONFIG_E1000_SPI - struct spi_slave spi; -#endif - unsigned int cardnum; - - pci_dev_t pdev; - uint8_t *hw_addr; - e1000_mac_type mac_type; - e1000_phy_type phy_type; - uint32_t phy_init_script; - uint32_t txd_cmd; - e1000_media_type media_type; - e1000_fc_type fc; - e1000_bus_type bus_type; -#if 0 - e1000_bus_speed bus_speed; - e1000_bus_width bus_width; - uint32_t io_base; -#endif - uint32_t asf_firmware_present; -#ifndef CONFIG_E1000_NO_NVM - uint32_t eeprom_semaphore_present; -#endif - uint32_t swfw_sync_present; - uint32_t swfwhw_semaphore_present; -#ifndef CONFIG_E1000_NO_NVM - struct e1000_eeprom_info eeprom; -#endif - e1000_ms_type master_slave; - e1000_ms_type original_master_slave; - e1000_ffe_config ffe_config_state; - uint32_t phy_id; - uint32_t phy_revision; - uint32_t phy_addr; - uint32_t original_fc; - uint32_t txcw; - uint32_t autoneg_failed; -#if 0 - uint32_t max_frame_size; - uint32_t min_frame_size; - uint32_t mc_filter_type; - uint32_t num_mc_addrs; - uint32_t collision_delta; - uint32_t tx_packet_delta; - uint32_t ledctl_default; - uint32_t ledctl_mode1; - uint32_t ledctl_mode2; -#endif - uint16_t autoneg_advertised; - uint16_t pci_cmd_word; - uint16_t fc_high_water; - uint16_t fc_low_water; - uint16_t fc_pause_time; -#if 0 - uint16_t current_ifs_val; - uint16_t ifs_min_val; - uint16_t ifs_max_val; - uint16_t ifs_step_size; - uint16_t ifs_ratio; -#endif - uint16_t device_id; - uint16_t vendor_id; - uint16_t subsystem_id; - uint16_t subsystem_vendor_id; - uint8_t revision_id; - uint8_t autoneg; - uint8_t mdix; - uint8_t forced_speed_duplex; - uint8_t wait_autoneg_complete; - uint8_t dma_fairness; -#if 0 - uint8_t perm_mac_addr[NODE_ADDRESS_SIZE]; -#endif - bool disable_polarity_correction; - bool speed_downgraded; - bool get_link_status; - bool tbi_compatibility_en; - bool tbi_compatibility_on; - bool fc_strict_ieee; - bool fc_send_xon; - bool report_tx_early; - bool phy_reset_disable; - bool initialize_hw_bits_disable; -#if 0 - bool adaptive_ifs; - bool ifs_params_forced; - bool in_ifs_mode; -#endif - e1000_smart_speed smart_speed; - e1000_dsp_config dsp_config_state; -}; - -#define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */ -#define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */ -#define E1000_EEPROM_RW_REG_DATA 16 /* Offset to data in EEPROM - read/write registers */ -#define E1000_EEPROM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */ -#define E1000_EEPROM_RW_REG_START 1 /* First bit for telling part to start - operation */ -#define E1000_EEPROM_RW_ADDR_SHIFT 2 /* Shift to the address bits */ -#define E1000_EEPROM_POLL_WRITE 1 /* Flag for polling for write - complete */ -#define E1000_EEPROM_POLL_READ 0 /* Flag for polling for read complete */ -#define EEPROM_RESERVED_WORD 0xFFFF - -/* Register Bit Masks */ -/* Device Control */ -#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */ -#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */ -#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */ -#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */ -#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */ -#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */ -#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */ -#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */ -#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */ -#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */ -#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */ -#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */ -#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */ -#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */ -#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */ -#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ -#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ -#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ -#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */ -#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */ -#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */ -#define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */ -#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */ -#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */ -#define E1000_CTRL_RST 0x04000000 /* Global reset */ -#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */ -#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */ -#define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */ -#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */ -#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */ - -/* Device Status */ -#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */ -#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */ -#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */ -#define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */ -#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */ -#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */ -#define E1000_STATUS_TBIMODE 0x00000020 /* TBI mode */ -#define E1000_STATUS_SPEED_MASK 0x000000C0 -#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */ -#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */ -#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */ -#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */ -#define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */ -#define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */ -#define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */ -#define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */ -#define E1000_STATUS_PCIX_SPEED 0x0000C000 /* PCI-X bus speed */ - -/* Constants used to intrepret the masked PCI-X bus speed. */ -#define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus speed 50-66 MHz */ -#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus speed 66-100 MHz */ -#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /* PCI-X bus speed 100-133 MHz */ - -/* EEPROM/Flash Control */ -#define E1000_EECD_SK 0x00000001 /* EEPROM Clock */ -#define E1000_EECD_CS 0x00000002 /* EEPROM Chip Select */ -#define E1000_EECD_DI 0x00000004 /* EEPROM Data In */ -#define E1000_EECD_DO 0x00000008 /* EEPROM Data Out */ -#define E1000_EECD_FWE_MASK 0x00000030 -#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */ -#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */ -#define E1000_EECD_FWE_SHIFT 4 -#define E1000_EECD_SIZE 0x00000200 /* EEPROM Size (0=64 word 1=256 word) */ -#define E1000_EECD_REQ 0x00000040 /* EEPROM Access Request */ -#define E1000_EECD_GNT 0x00000080 /* EEPROM Access Grant */ -#define E1000_EECD_PRES 0x00000100 /* EEPROM Present */ -#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type - * (0-small, 1-large) */ - -#define E1000_EECD_TYPE 0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */ -#ifndef E1000_EEPROM_GRANT_ATTEMPTS -#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */ -#endif -#define E1000_EECD_AUTO_RD 0x00000200 /* EEPROM Auto Read done */ -#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* EEprom Size */ -#define E1000_EECD_SIZE_EX_SHIFT 11 -#define E1000_EECD_NVADDS 0x00018000 /* NVM Address Size */ -#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */ -#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */ -#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */ -#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */ -#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */ -#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */ -#define E1000_EECD_SECVAL_SHIFT 22 -#define E1000_STM_OPCODE 0xDB00 -#define E1000_HICR_FW_RESET 0xC0 - -#define E1000_SHADOW_RAM_WORDS 2048 -#define E1000_ICH_NVM_SIG_WORD 0x13 -#define E1000_ICH_NVM_SIG_MASK 0xC0 - -/* EEPROM Read */ -#define E1000_EERD_START 0x00000001 /* Start Read */ -#define E1000_EERD_DONE 0x00000010 /* Read Done */ -#define E1000_EERD_ADDR_SHIFT 8 -#define E1000_EERD_ADDR_MASK 0x0000FF00 /* Read Address */ -#define E1000_EERD_DATA_SHIFT 16 -#define E1000_EERD_DATA_MASK 0xFFFF0000 /* Read Data */ - -/* EEPROM Commands - Microwire */ -#define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */ -#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */ -#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7 /* EEPROM erase opcode */ -#define EEPROM_EWEN_OPCODE_MICROWIRE 0x13 /* EEPROM erase/write enable */ -#define EEPROM_EWDS_OPCODE_MICROWIRE 0x10 /* EEPROM erast/write disable */ - -/* EEPROM Commands - SPI */ -#define EEPROM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */ -#define EEPROM_READ_OPCODE_SPI 0x03 /* EEPROM read opcode */ -#define EEPROM_WRITE_OPCODE_SPI 0x02 /* EEPROM write opcode */ -#define EEPROM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */ -#define EEPROM_WREN_OPCODE_SPI 0x06 /* EEPROM set Write Enable latch */ -#define EEPROM_WRDI_OPCODE_SPI 0x04 /* EEPROM reset Write Enable latch */ -#define EEPROM_RDSR_OPCODE_SPI 0x05 /* EEPROM read Status register */ -#define EEPROM_WRSR_OPCODE_SPI 0x01 /* EEPROM write Status register */ -#define EEPROM_ERASE4K_OPCODE_SPI 0x20 /* EEPROM ERASE 4KB */ -#define EEPROM_ERASE64K_OPCODE_SPI 0xD8 /* EEPROM ERASE 64KB */ -#define EEPROM_ERASE256_OPCODE_SPI 0xDB /* EEPROM ERASE 256B */ - -/* EEPROM Size definitions */ -#define EEPROM_WORD_SIZE_SHIFT 6 -#define EEPROM_SIZE_SHIFT 10 -#define EEPROM_SIZE_MASK 0x1C00 - -/* EEPROM Word Offsets */ -#define EEPROM_COMPAT 0x0003 -#define EEPROM_ID_LED_SETTINGS 0x0004 -#define EEPROM_VERSION 0x0005 -#define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude - adjustment. */ -#define EEPROM_PHY_CLASS_WORD 0x0007 -#define EEPROM_INIT_CONTROL1_REG 0x000A -#define EEPROM_INIT_CONTROL2_REG 0x000F -#define EEPROM_SWDEF_PINS_CTRL_PORT_1 0x0010 -#define EEPROM_INIT_CONTROL3_PORT_B 0x0014 -#define EEPROM_INIT_3GIO_3 0x001A -#define EEPROM_SWDEF_PINS_CTRL_PORT_0 0x0020 -#define EEPROM_INIT_CONTROL3_PORT_A 0x0024 -#define EEPROM_CFG 0x0012 -#define EEPROM_FLASH_VERSION 0x0032 -#define EEPROM_CHECKSUM_REG 0x003F - -#define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle done */ -#define E1000_EEPROM_CFG_DONE_PORT_1 0x00080000 /* ...for second port */ - -/* Extended Device Control */ -#define E1000_CTRL_EXT_GPI0_EN 0x00000001 /* Maps SDP4 to GPI0 */ -#define E1000_CTRL_EXT_GPI1_EN 0x00000002 /* Maps SDP5 to GPI1 */ -#define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN -#define E1000_CTRL_EXT_GPI2_EN 0x00000004 /* Maps SDP6 to GPI2 */ -#define E1000_CTRL_EXT_GPI3_EN 0x00000008 /* Maps SDP7 to GPI3 */ -#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Defineable - Pin 4 */ -#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Defineable - Pin 5 */ -#define E1000_CTRL_EXT_PHY_INT E1000_CTRL_EXT_SDP5_DATA -#define E1000_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW Defineable Pin 6 */ -#define E1000_CTRL_EXT_SWDPIN6 0x00000040 /* SWDPIN 6 value */ -#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */ -#define E1000_CTRL_EXT_SWDPIN7 0x00000080 /* SWDPIN 7 value */ -#define E1000_CTRL_EXT_SDP4_DIR 0x00000100 /* Direction of SDP4 0=in 1=out */ -#define E1000_CTRL_EXT_SDP5_DIR 0x00000200 /* Direction of SDP5 0=in 1=out */ -#define E1000_CTRL_EXT_SDP6_DIR 0x00000400 /* Direction of SDP6 0=in 1=out */ -#define E1000_CTRL_EXT_SWDPIO6 0x00000400 /* SWDPIN 6 Input or output */ -#define E1000_CTRL_EXT_SDP7_DIR 0x00000800 /* Direction of SDP7 0=in 1=out */ -#define E1000_CTRL_EXT_SWDPIO7 0x00000800 /* SWDPIN 7 Input or output */ -#define E1000_CTRL_EXT_ASDCHK 0x00001000 /* Initiate an ASD sequence */ -#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ -#define E1000_CTRL_EXT_IPS 0x00004000 /* Invert Power State */ -#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */ -#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */ -#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000 -#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000 -#define E1000_CTRL_EXT_LINK_MODE_TBI 0x00C00000 -#define E1000_CTRL_EXT_WR_WMARK_MASK 0x03000000 -#define E1000_CTRL_EXT_WR_WMARK_256 0x00000000 -#define E1000_CTRL_EXT_WR_WMARK_320 0x01000000 -#define E1000_CTRL_EXT_WR_WMARK_384 0x02000000 -#define E1000_CTRL_EXT_WR_WMARK_448 0x03000000 - -/* MDI Control */ -#define E1000_MDIC_DATA_MASK 0x0000FFFF -#define E1000_MDIC_REG_MASK 0x001F0000 -#define E1000_MDIC_REG_SHIFT 16 -#define E1000_MDIC_PHY_MASK 0x03E00000 -#define E1000_MDIC_PHY_SHIFT 21 -#define E1000_MDIC_OP_WRITE 0x04000000 -#define E1000_MDIC_OP_READ 0x08000000 -#define E1000_MDIC_READY 0x10000000 -#define E1000_MDIC_INT_EN 0x20000000 -#define E1000_MDIC_ERROR 0x40000000 - -#define E1000_PHY_CTRL_SPD_EN 0x00000001 -#define E1000_PHY_CTRL_D0A_LPLU 0x00000002 -#define E1000_PHY_CTRL_NOND0A_LPLU 0x00000004 -#define E1000_PHY_CTRL_NOND0A_GBE_DISABLE 0x00000008 -#define E1000_PHY_CTRL_GBE_DISABLE 0x00000040 -#define E1000_PHY_CTRL_B2B_EN 0x00000080 -/* LED Control */ -#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F -#define E1000_LEDCTL_LED0_MODE_SHIFT 0 -#define E1000_LEDCTL_LED0_IVRT 0x00000040 -#define E1000_LEDCTL_LED0_BLINK 0x00000080 -#define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00 -#define E1000_LEDCTL_LED1_MODE_SHIFT 8 -#define E1000_LEDCTL_LED1_IVRT 0x00004000 -#define E1000_LEDCTL_LED1_BLINK 0x00008000 -#define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000 -#define E1000_LEDCTL_LED2_MODE_SHIFT 16 -#define E1000_LEDCTL_LED2_IVRT 0x00400000 -#define E1000_LEDCTL_LED2_BLINK 0x00800000 -#define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000 -#define E1000_LEDCTL_LED3_MODE_SHIFT 24 -#define E1000_LEDCTL_LED3_IVRT 0x40000000 -#define E1000_LEDCTL_LED3_BLINK 0x80000000 - -#define E1000_LEDCTL_MODE_LINK_10_1000 0x0 -#define E1000_LEDCTL_MODE_LINK_100_1000 0x1 -#define E1000_LEDCTL_MODE_LINK_UP 0x2 -#define E1000_LEDCTL_MODE_ACTIVITY 0x3 -#define E1000_LEDCTL_MODE_LINK_ACTIVITY 0x4 -#define E1000_LEDCTL_MODE_LINK_10 0x5 -#define E1000_LEDCTL_MODE_LINK_100 0x6 -#define E1000_LEDCTL_MODE_LINK_1000 0x7 -#define E1000_LEDCTL_MODE_PCIX_MODE 0x8 -#define E1000_LEDCTL_MODE_FULL_DUPLEX 0x9 -#define E1000_LEDCTL_MODE_COLLISION 0xA -#define E1000_LEDCTL_MODE_BUS_SPEED 0xB -#define E1000_LEDCTL_MODE_BUS_SIZE 0xC -#define E1000_LEDCTL_MODE_PAUSED 0xD -#define E1000_LEDCTL_MODE_LED_ON 0xE -#define E1000_LEDCTL_MODE_LED_OFF 0xF - -/* Receive Address */ -#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */ - -/* Interrupt Cause Read */ -#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ -#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */ -#define E1000_ICR_LSC 0x00000004 /* Link Status Change */ -#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */ -#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */ -#define E1000_ICR_RXO 0x00000040 /* rx overrun */ -#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */ -#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */ -#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */ -#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */ -#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */ -#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */ -#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */ -#define E1000_ICR_TXD_LOW 0x00008000 -#define E1000_ICR_SRPD 0x00010000 - -/* Interrupt Cause Set */ -#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ -#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ -#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */ -#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ -#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ -#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */ -#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ -#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */ -#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ -#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ -#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ -#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ -#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ -#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW -#define E1000_ICS_SRPD E1000_ICR_SRPD - -/* Interrupt Mask Set */ -#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ -#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ -#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */ -#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ -#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ -#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */ -#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ -#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */ -#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ -#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ -#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ -#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ -#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ -#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW -#define E1000_IMS_SRPD E1000_ICR_SRPD - -/* Interrupt Mask Clear */ -#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */ -#define E1000_IMC_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ -#define E1000_IMC_LSC E1000_ICR_LSC /* Link Status Change */ -#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ -#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ -#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */ -#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */ -#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */ -#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ -#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ -#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ -#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ -#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ -#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW -#define E1000_IMC_SRPD E1000_ICR_SRPD - -/* Receive Control */ -#define E1000_RCTL_RST 0x00000001 /* Software reset */ -#define E1000_RCTL_EN 0x00000002 /* enable */ -#define E1000_RCTL_SBP 0x00000004 /* store bad packet */ -#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */ -#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */ -#define E1000_RCTL_LPE 0x00000020 /* long packet enable */ -#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */ -#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */ -#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */ -#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */ -#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */ -#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */ -#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */ -#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */ -#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */ -#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */ -#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */ -#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */ -#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */ -#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */ -/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */ -#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */ -#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */ -#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */ -#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */ -/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */ -#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */ -#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */ -#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */ -#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */ -#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */ -#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */ -#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */ -#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */ -#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */ - -/* SW_W_SYNC definitions */ -#define E1000_SWFW_EEP_SM 0x0001 -#define E1000_SWFW_PHY0_SM 0x0002 -#define E1000_SWFW_PHY1_SM 0x0004 -#define E1000_SWFW_MAC_CSR_SM 0x0008 - -/* Receive Descriptor */ -#define E1000_RDT_DELAY 0x0000ffff /* Delay timer (1=1024us) */ -#define E1000_RDT_FPDB 0x80000000 /* Flush descriptor block */ -#define E1000_RDLEN_LEN 0x0007ff80 /* descriptor length */ -#define E1000_RDH_RDH 0x0000ffff /* receive descriptor head */ -#define E1000_RDT_RDT 0x0000ffff /* receive descriptor tail */ - -/* Flow Control */ -#define E1000_FCRTH_RTH 0x0000FFF8 /* Mask Bits[15:3] for RTH */ -#define E1000_FCRTH_XFCE 0x80000000 /* External Flow Control Enable */ -#define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */ -#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */ - -/* Receive Descriptor Control */ -#define E1000_RXDCTL_PTHRESH 0x0000003F /* RXDCTL Prefetch Threshold */ -#define E1000_RXDCTL_HTHRESH 0x00003F00 /* RXDCTL Host Threshold */ -#define E1000_RXDCTL_WTHRESH 0x003F0000 /* RXDCTL Writeback Threshold */ -#define E1000_RXDCTL_GRAN 0x01000000 /* RXDCTL Granularity */ -#define E1000_RXDCTL_FULL_RX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ - -/* Transmit Descriptor Control */ -#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */ -#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */ -#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */ -#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */ -#define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */ -#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ -#define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Enable the counting of desc. - still to be processed. */ - -/* Transmit Configuration Word */ -#define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */ -#define E1000_TXCW_HD 0x00000040 /* TXCW half duplex */ -#define E1000_TXCW_PAUSE 0x00000080 /* TXCW sym pause request */ -#define E1000_TXCW_ASM_DIR 0x00000100 /* TXCW astm pause direction */ -#define E1000_TXCW_PAUSE_MASK 0x00000180 /* TXCW pause request mask */ -#define E1000_TXCW_RF 0x00003000 /* TXCW remote fault */ -#define E1000_TXCW_NP 0x00008000 /* TXCW next page */ -#define E1000_TXCW_CW 0x0000ffff /* TxConfigWord mask */ -#define E1000_TXCW_TXC 0x40000000 /* Transmit Config control */ -#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */ - -/* Receive Configuration Word */ -#define E1000_RXCW_CW 0x0000ffff /* RxConfigWord mask */ -#define E1000_RXCW_NC 0x04000000 /* Receive config no carrier */ -#define E1000_RXCW_IV 0x08000000 /* Receive config invalid */ -#define E1000_RXCW_CC 0x10000000 /* Receive config change */ -#define E1000_RXCW_C 0x20000000 /* Receive config */ -#define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */ -#define E1000_RXCW_ANC 0x80000000 /* Auto-neg complete */ - -/* Transmit Control */ -#define E1000_TCTL_RST 0x00000001 /* software reset */ -#define E1000_TCTL_EN 0x00000002 /* enable tx */ -#define E1000_TCTL_BCE 0x00000004 /* busy check enable */ -#define E1000_TCTL_PSP 0x00000008 /* pad short packets */ -#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */ -#define E1000_TCTL_COLD 0x003ff000 /* collision distance */ -#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */ -#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */ -#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ -#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */ -#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */ - -/* Receive Checksum Control */ -#define E1000_RXCSUM_PCSS_MASK 0x000000FF /* Packet Checksum Start */ -#define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */ -#define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */ -#define E1000_RXCSUM_IPV6OFL 0x00000400 /* IPv6 checksum offload */ - -/* Definitions for power management and wakeup registers */ -/* Wake Up Control */ -#define E1000_WUC_APME 0x00000001 /* APM Enable */ -#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */ -#define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */ -#define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */ - -/* Wake Up Filter Control */ -#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ -#define E1000_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */ -#define E1000_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */ -#define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */ -#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ -#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */ -#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */ -#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */ -#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */ -#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */ -#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */ -#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */ -#define E1000_WUFC_ALL_FILTERS 0x000F00FF /* Mask for all wakeup filters */ -#define E1000_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */ -#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */ - -/* Wake Up Status */ -#define E1000_WUS_LNKC 0x00000001 /* Link Status Changed */ -#define E1000_WUS_MAG 0x00000002 /* Magic Packet Received */ -#define E1000_WUS_EX 0x00000004 /* Directed Exact Received */ -#define E1000_WUS_MC 0x00000008 /* Directed Multicast Received */ -#define E1000_WUS_BC 0x00000010 /* Broadcast Received */ -#define E1000_WUS_ARP 0x00000020 /* ARP Request Packet Received */ -#define E1000_WUS_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Received */ -#define E1000_WUS_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Received */ -#define E1000_WUS_FLX0 0x00010000 /* Flexible Filter 0 Match */ -#define E1000_WUS_FLX1 0x00020000 /* Flexible Filter 1 Match */ -#define E1000_WUS_FLX2 0x00040000 /* Flexible Filter 2 Match */ -#define E1000_WUS_FLX3 0x00080000 /* Flexible Filter 3 Match */ -#define E1000_WUS_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */ - -/* Management Control */ -#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */ -#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */ -#define E1000_MANC_R_ON_FORCE 0x00000004 /* Reset on Force TCO - RO */ -#define E1000_MANC_RMCP_EN 0x00000100 /* Enable RCMP 026Fh Filtering */ -#define E1000_MANC_0298_EN 0x00000200 /* Enable RCMP 0298h Filtering */ -#define E1000_MANC_IPV4_EN 0x00000400 /* Enable IPv4 */ -#define E1000_MANC_IPV6_EN 0x00000800 /* Enable IPv6 */ -#define E1000_MANC_SNAP_EN 0x00001000 /* Accept LLC/SNAP */ -#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */ -#define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery - * Filtering */ -#define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */ -#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */ -#define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */ -#define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */ -#define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */ -#define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */ -#define E1000_MANC_SMB_DATA_IN 0x08000000 /* SMBus Data In */ -#define E1000_MANC_SMB_DATA_OUT 0x10000000 /* SMBus Data Out */ -#define E1000_MANC_SMB_CLK_OUT 0x20000000 /* SMBus Clock Out */ - -#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */ -#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */ - -/* Wake Up Packet Length */ -#define E1000_WUPL_LENGTH_MASK 0x0FFF /* Only the lower 12 bits are valid */ - -#define E1000_MDALIGN 4096 - -/* EEPROM Commands */ -#define EEPROM_READ_OPCODE 0x6 /* EERPOM read opcode */ -#define EEPROM_WRITE_OPCODE 0x5 /* EERPOM write opcode */ -#define EEPROM_ERASE_OPCODE 0x7 /* EERPOM erase opcode */ -#define EEPROM_EWEN_OPCODE 0x13 /* EERPOM erase/write enable */ -#define EEPROM_EWDS_OPCODE 0x10 /* EERPOM erast/write disable */ - -/* Word definitions for ID LED Settings */ -#define ID_LED_RESERVED_0000 0x0000 -#define ID_LED_RESERVED_FFFF 0xFFFF -#define ID_LED_DEFAULT ((ID_LED_OFF1_ON2 << 12) | \ - (ID_LED_OFF1_OFF2 << 8) | \ - (ID_LED_DEF1_DEF2 << 4) | \ - (ID_LED_DEF1_DEF2)) -#define ID_LED_DEF1_DEF2 0x1 -#define ID_LED_DEF1_ON2 0x2 -#define ID_LED_DEF1_OFF2 0x3 -#define ID_LED_ON1_DEF2 0x4 -#define ID_LED_ON1_ON2 0x5 -#define ID_LED_ON1_OFF2 0x6 -#define ID_LED_OFF1_DEF2 0x7 -#define ID_LED_OFF1_ON2 0x8 -#define ID_LED_OFF1_OFF2 0x9 - -/* Mask bits for fields in Word 0x03 of the EEPROM */ -#define EEPROM_COMPAT_SERVER 0x0400 -#define EEPROM_COMPAT_CLIENT 0x0200 - -/* Mask bits for fields in Word 0x0a of the EEPROM */ -#define EEPROM_WORD0A_ILOS 0x0010 -#define EEPROM_WORD0A_SWDPIO 0x01E0 -#define EEPROM_WORD0A_LRST 0x0200 -#define EEPROM_WORD0A_FD 0x0400 -#define EEPROM_WORD0A_66MHZ 0x0800 - -/* Mask bits for fields in Word 0x0f of the EEPROM */ -#define EEPROM_WORD0F_PAUSE_MASK 0x3000 -#define EEPROM_WORD0F_PAUSE 0x1000 -#define EEPROM_WORD0F_ASM_DIR 0x2000 -#define EEPROM_WORD0F_ANE 0x0800 -#define EEPROM_WORD0F_SWPDIO_EXT 0x00F0 - -/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */ -#define EEPROM_SUM 0xBABA - -/* EEPROM Map defines (WORD OFFSETS)*/ -#define EEPROM_NODE_ADDRESS_BYTE_0 0 -#define EEPROM_PBA_BYTE_1 8 - -/* EEPROM Map Sizes (Byte Counts) */ -#define PBA_SIZE 4 - -/* Collision related configuration parameters */ -#define E1000_COLLISION_THRESHOLD 0xF -#define E1000_CT_SHIFT 4 -#define E1000_COLLISION_DISTANCE 63 -#define E1000_COLLISION_DISTANCE_82542 64 -#define E1000_FDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE -#define E1000_HDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE -#define E1000_GB_HDX_COLLISION_DISTANCE 512 -#define E1000_COLD_SHIFT 12 - -/* The number of Transmit and Receive Descriptors must be a multiple of 8 */ -#define REQ_TX_DESCRIPTOR_MULTIPLE 8 -#define REQ_RX_DESCRIPTOR_MULTIPLE 8 - -/* Default values for the transmit IPG register */ -#define DEFAULT_82542_TIPG_IPGT 10 -#define DEFAULT_82543_TIPG_IPGT_FIBER 9 -#define DEFAULT_82543_TIPG_IPGT_COPPER 8 - -#define E1000_TIPG_IPGT_MASK 0x000003FF -#define E1000_TIPG_IPGR1_MASK 0x000FFC00 -#define E1000_TIPG_IPGR2_MASK 0x3FF00000 - -#define DEFAULT_82542_TIPG_IPGR1 2 -#define DEFAULT_82543_TIPG_IPGR1 8 -#define E1000_TIPG_IPGR1_SHIFT 10 - -#define DEFAULT_82542_TIPG_IPGR2 10 -#define DEFAULT_82543_TIPG_IPGR2 6 -#define DEFAULT_80003ES2LAN_TIPG_IPGR2 7 -#define E1000_TIPG_IPGR2_SHIFT 20 - -#define E1000_TXDMAC_DPP 0x00000001 - -/* Adaptive IFS defines */ -#define TX_THRESHOLD_START 8 -#define TX_THRESHOLD_INCREMENT 10 -#define TX_THRESHOLD_DECREMENT 1 -#define TX_THRESHOLD_STOP 190 -#define TX_THRESHOLD_DISABLE 0 -#define TX_THRESHOLD_TIMER_MS 10000 -#define MIN_NUM_XMITS 1000 -#define IFS_MAX 80 -#define IFS_STEP 10 -#define IFS_MIN 40 -#define IFS_RATIO 4 - -/* PBA constants */ -#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */ -#define E1000_PBA_24K 0x0018 -#define E1000_PBA_38K 0x0026 -#define E1000_PBA_40K 0x0028 -#define E1000_PBA_48K 0x0030 /* 48KB, default RX allocation */ - -/* Flow Control Constants */ -#define FLOW_CONTROL_ADDRESS_LOW 0x00C28001 -#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100 -#define FLOW_CONTROL_TYPE 0x8808 - -/* The historical defaults for the flow control values are given below. */ -#define FC_DEFAULT_HI_THRESH (0x8000) /* 32KB */ -#define FC_DEFAULT_LO_THRESH (0x4000) /* 16KB */ -#define FC_DEFAULT_TX_TIMER (0x100) /* ~130 us */ - -/* Flow Control High-Watermark: 43464 bytes */ -#define E1000_FC_HIGH_THRESH 0xA9C8 -/* Flow Control Low-Watermark: 43456 bytes */ -#define E1000_FC_LOW_THRESH 0xA9C0 -/* Flow Control Pause Time: 858 usec */ -#define E1000_FC_PAUSE_TIME 0x0680 - -/* PCIX Config space */ -#define PCIX_COMMAND_REGISTER 0xE6 -#define PCIX_STATUS_REGISTER_LO 0xE8 -#define PCIX_STATUS_REGISTER_HI 0xEA - -#define PCIX_COMMAND_MMRBC_MASK 0x000C -#define PCIX_COMMAND_MMRBC_SHIFT 0x2 -#define PCIX_STATUS_HI_MMRBC_MASK 0x0060 -#define PCIX_STATUS_HI_MMRBC_SHIFT 0x5 -#define PCIX_STATUS_HI_MMRBC_4K 0x3 -#define PCIX_STATUS_HI_MMRBC_2K 0x2 - -/* The number of bits that we need to shift right to move the "pause" - * bits from the EEPROM (bits 13:12) to the "pause" (bits 8:7) field - * in the TXCW register - */ -#define PAUSE_SHIFT 5 - -/* The number of bits that we need to shift left to move the "SWDPIO" - * bits from the EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field - * in the CTRL register - */ -#define SWDPIO_SHIFT 17 - -/* The number of bits that we need to shift left to move the "SWDPIO_EXT" - * bits from the EEPROM word F (bits 7:4) to the bits 11:8 of The - * Extended CTRL register. - * in the CTRL register - */ -#define SWDPIO__EXT_SHIFT 4 - -/* The number of bits that we need to shift left to move the "ILOS" - * bit from the EEPROM (bit 4) to the "ILOS" (bit 7) field - * in the CTRL register - */ -#define ILOS_SHIFT 3 - -#define RECEIVE_BUFFER_ALIGN_SIZE (256) - -/* The number of milliseconds we wait for auto-negotiation to complete */ -#define LINK_UP_TIMEOUT 500 - -#define E1000_TX_BUFFER_SIZE ((uint32_t)1514) - -/* The carrier extension symbol, as received by the NIC. */ -#define CARRIER_EXTENSION 0x0F - -/* TBI_ACCEPT macro definition: - * - * This macro requires: - * adapter = a pointer to struct e1000_hw - * status = the 8 bit status field of the RX descriptor with EOP set - * error = the 8 bit error field of the RX descriptor with EOP set - * length = the sum of all the length fields of the RX descriptors that - * make up the current frame - * last_byte = the last byte of the frame DMAed by the hardware - * max_frame_length = the maximum frame length we want to accept. - * min_frame_length = the minimum frame length we want to accept. - * - * This macro is a conditional that should be used in the interrupt - * handler's Rx processing routine when RxErrors have been detected. - * - * Typical use: - * ... - * if (TBI_ACCEPT) { - * accept_frame = true; - * e1000_tbi_adjust_stats(adapter, MacAddress); - * frame_length--; - * } else { - * accept_frame = false; - * } - * ... - */ - -#define TBI_ACCEPT(adapter, status, errors, length, last_byte) \ - ((adapter)->tbi_compatibility_on && \ - (((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \ - ((last_byte) == CARRIER_EXTENSION) && \ - (((status) & E1000_RXD_STAT_VP) ? \ - (((length) > ((adapter)->min_frame_size - VLAN_TAG_SIZE)) && \ - ((length) <= ((adapter)->max_frame_size + 1))) : \ - (((length) > (adapter)->min_frame_size) && \ - ((length) <= ((adapter)->max_frame_size + VLAN_TAG_SIZE + 1))))) - -/* Structures, enums, and macros for the PHY */ - -/* Bit definitions for the Management Data IO (MDIO) and Management Data - * Clock (MDC) pins in the Device Control Register. - */ -#define E1000_CTRL_PHY_RESET_DIR E1000_CTRL_SWDPIO0 -#define E1000_CTRL_PHY_RESET E1000_CTRL_SWDPIN0 -#define E1000_CTRL_MDIO_DIR E1000_CTRL_SWDPIO2 -#define E1000_CTRL_MDIO E1000_CTRL_SWDPIN2 -#define E1000_CTRL_MDC_DIR E1000_CTRL_SWDPIO3 -#define E1000_CTRL_MDC E1000_CTRL_SWDPIN3 -#define E1000_CTRL_PHY_RESET_DIR4 E1000_CTRL_EXT_SDP4_DIR -#define E1000_CTRL_PHY_RESET4 E1000_CTRL_EXT_SDP4_DATA - -/* PHY 1000 MII Register/Bit Definitions */ -/* PHY Registers defined by IEEE */ -#define PHY_CTRL 0x00 /* Control Register */ -#define PHY_STATUS 0x01 /* Status Regiser */ -#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */ -#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */ -#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */ -#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */ -#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Reg */ -#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */ -#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */ -#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */ -#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */ -#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */ - -/* M88E1000 Specific Registers */ -#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ -#define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */ -#define M88E1000_INT_ENABLE 0x12 /* Interrupt Enable Register */ -#define M88E1000_INT_STATUS 0x13 /* Interrupt Status Register */ -#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */ -#define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */ - -#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for page number setting */ -#define M88E1000_PHY_GEN_CONTROL 0x1E /* Its meaning depends on reg 29 */ - -#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ - -/* M88EC018 Rev 2 specific DownShift settings */ -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_1X 0x0000 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_2X 0x0200 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_3X 0x0400 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_4X 0x0600 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_6X 0x0A00 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_7X 0x0C00 -#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_8X 0x0E00 - -/* IGP01E1000 specifics */ -#define IGP01E1000_IEEE_REGS_PAGE 0x0000 -#define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300 -#define IGP01E1000_IEEE_FORCE_GIGA 0x0140 - -/* IGP01E1000 Specific Registers */ -#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* PHY Specific Port Config Register */ -#define IGP01E1000_PHY_PORT_STATUS 0x11 /* PHY Specific Status Register */ -#define IGP01E1000_PHY_PORT_CTRL 0x12 /* PHY Specific Control Register */ -#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health Register */ -#define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO Register */ -#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality Register */ -#define IGP02E1000_PHY_POWER_MGMT 0x19 -#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* PHY Page Select Core Register */ - -/* IGP01E1000 AGC Registers - stores the cable length values*/ -#define IGP01E1000_PHY_AGC_A 0x1172 -#define IGP01E1000_PHY_AGC_B 0x1272 -#define IGP01E1000_PHY_AGC_C 0x1472 -#define IGP01E1000_PHY_AGC_D 0x1872 - -/* IGP01E1000 Specific Port Config Register - R/W */ -#define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT 0x0010 -#define IGP01E1000_PSCFR_PRE_EN 0x0020 -#define IGP01E1000_PSCFR_SMART_SPEED 0x0080 -#define IGP01E1000_PSCFR_DISABLE_TPLOOPBACK 0x0100 -#define IGP01E1000_PSCFR_DISABLE_JABBER 0x0400 -#define IGP01E1000_PSCFR_DISABLE_TRANSMIT 0x2000 -/* IGP02E1000 AGC Registers for cable length values */ -#define IGP02E1000_PHY_AGC_A 0x11B1 -#define IGP02E1000_PHY_AGC_B 0x12B1 -#define IGP02E1000_PHY_AGC_C 0x14B1 -#define IGP02E1000_PHY_AGC_D 0x18B1 - -#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */ -#define IGP02E1000_PM_D3_LPLU 0x0004 /* Enable LPLU in - non-D0a modes */ -#define IGP02E1000_PM_D0_LPLU 0x0002 /* Enable LPLU in - D0a mode */ - -/* IGP01E1000 DSP Reset Register */ -#define IGP01E1000_PHY_DSP_RESET 0x1F33 -#define IGP01E1000_PHY_DSP_SET 0x1F71 -#define IGP01E1000_PHY_DSP_FFE 0x1F35 - -#define IGP01E1000_PHY_CHANNEL_NUM 4 -#define IGP02E1000_PHY_CHANNEL_NUM 4 - -#define IGP01E1000_PHY_AGC_PARAM_A 0x1171 -#define IGP01E1000_PHY_AGC_PARAM_B 0x1271 -#define IGP01E1000_PHY_AGC_PARAM_C 0x1471 -#define IGP01E1000_PHY_AGC_PARAM_D 0x1871 - -#define IGP01E1000_PHY_EDAC_MU_INDEX 0xC000 -#define IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS 0x8000 - -#define IGP01E1000_PHY_ANALOG_TX_STATE 0x2890 -#define IGP01E1000_PHY_ANALOG_CLASS_A 0x2000 -#define IGP01E1000_PHY_FORCE_ANALOG_ENABLE 0x0004 -#define IGP01E1000_PHY_DSP_FFE_CM_CP 0x0069 - -#define IGP01E1000_PHY_DSP_FFE_DEFAULT 0x002A -/* IGP01E1000 PCS Initialization register - stores the polarity status when - * speed = 1000 Mbps. */ -#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 -#define IGP01E1000_PHY_PCS_CTRL_REG 0x00B5 - -#define IGP01E1000_ANALOG_REGS_PAGE 0x20C0 - -/* IGP01E1000 GMII FIFO Register */ -#define IGP01E1000_GMII_FLEX_SPD 0x10 /* Enable flexible speed - * on Link-Up */ -#define IGP01E1000_GMII_SPD 0x20 /* Enable SPD */ - -/* IGP01E1000 Analog Register */ -#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS 0x20D1 -#define IGP01E1000_ANALOG_FUSE_STATUS 0x20D0 -#define IGP01E1000_ANALOG_FUSE_CONTROL 0x20DC -#define IGP01E1000_ANALOG_FUSE_BYPASS 0x20DE - -#define IGP01E1000_ANALOG_FUSE_POLY_MASK 0xF000 -#define IGP01E1000_ANALOG_FUSE_FINE_MASK 0x0F80 -#define IGP01E1000_ANALOG_FUSE_COARSE_MASK 0x0070 -#define IGP01E1000_ANALOG_SPARE_FUSE_ENABLED 0x0100 -#define IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL 0x0002 - -#define IGP01E1000_ANALOG_FUSE_COARSE_THRESH 0x0040 -#define IGP01E1000_ANALOG_FUSE_COARSE_10 0x0010 -#define IGP01E1000_ANALOG_FUSE_FINE_1 0x0080 -#define IGP01E1000_ANALOG_FUSE_FINE_10 0x0500 - -/* IGP01E1000 Specific Port Control Register - R/W */ -#define IGP01E1000_PSCR_TP_LOOPBACK 0x0010 -#define IGP01E1000_PSCR_CORRECT_NC_SCMBLR 0x0200 -#define IGP01E1000_PSCR_TEN_CRS_SELECT 0x0400 -#define IGP01E1000_PSCR_FLIP_CHIP 0x0800 -#define IGP01E1000_PSCR_AUTO_MDIX 0x1000 -#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0-MDI, 1-MDIX */ -/* GG82563 PHY Specific Status Register (Page 0, Register 16 */ -#define GG82563_PSCR_DISABLE_JABBER 0x0001 /* 1=Disable Jabber */ -#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Polarity Reversal - Disabled */ -#define GG82563_PSCR_POWER_DOWN 0x0004 /* 1=Power Down */ -#define GG82563_PSCR_COPPER_TRANSMITER_DISABLE 0x0008 /* 1=Transmitter - Disabled */ -#define GG82563_PSCR_CROSSOVER_MODE_MASK 0x0060 -#define GG82563_PSCR_CROSSOVER_MODE_MDI 0x0000 /* 00=Manual MDI - configuration */ -#define GG82563_PSCR_CROSSOVER_MODE_MDIX 0x0020 /* 01=Manual MDIX - configuration */ -#define GG82563_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Automatic - crossover */ -#define GG82563_PSCR_ENALBE_EXTENDED_DISTANCE 0x0080 /* 1=Enable Extended - Distance */ -#define GG82563_PSCR_ENERGY_DETECT_MASK 0x0300 -#define GG82563_PSCR_ENERGY_DETECT_OFF 0x0000 /* 00,01=Off */ -#define GG82563_PSCR_ENERGY_DETECT_RX 0x0200 /* 10=Sense on Rx only - (Energy Detect) */ -#define GG82563_PSCR_ENERGY_DETECT_RX_TM 0x0300 /* 11=Sense and Tx NLP */ -#define GG82563_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force Link Good */ -#define GG82563_PSCR_DOWNSHIFT_ENABLE 0x0800 /* 1=Enable Downshift */ -#define GG82563_PSCR_DOWNSHIFT_COUNTER_MASK 0x7000 -#define GG82563_PSCR_DOWNSHIFT_COUNTER_SHIFT 12 - -/* PHY Specific Status Register (Page 0, Register 17) */ -#define GG82563_PSSR_JABBER 0x0001 /* 1=Jabber */ -#define GG82563_PSSR_POLARITY 0x0002 /* 1=Polarity Reversed */ -#define GG82563_PSSR_LINK 0x0008 /* 1=Link is Up */ -#define GG82563_PSSR_ENERGY_DETECT 0x0010 /* 1=Sleep, 0=Active */ -#define GG82563_PSSR_DOWNSHIFT 0x0020 /* 1=Downshift */ -#define GG82563_PSSR_CROSSOVER_STATUS 0x0040 /* 1=MDIX, 0=MDI */ -#define GG82563_PSSR_RX_PAUSE_ENABLED 0x0100 /* 1=Receive Pause Enabled */ -#define GG82563_PSSR_TX_PAUSE_ENABLED 0x0200 /* 1=Transmit Pause Enabled */ -#define GG82563_PSSR_LINK_UP 0x0400 /* 1=Link Up */ -#define GG82563_PSSR_SPEED_DUPLEX_RESOLVED 0x0800 /* 1=Resolved */ -#define GG82563_PSSR_PAGE_RECEIVED 0x1000 /* 1=Page Received */ -#define GG82563_PSSR_DUPLEX 0x2000 /* 1-Full-Duplex */ -#define GG82563_PSSR_SPEED_MASK 0xC000 -#define GG82563_PSSR_SPEED_10MBPS 0x0000 /* 00=10Mbps */ -#define GG82563_PSSR_SPEED_100MBPS 0x4000 /* 01=100Mbps */ -#define GG82563_PSSR_SPEED_1000MBPS 0x8000 /* 10=1000Mbps */ - -/* PHY Specific Status Register 2 (Page 0, Register 19) */ -#define GG82563_PSSR2_JABBER 0x0001 /* 1=Jabber */ -#define GG82563_PSSR2_POLARITY_CHANGED 0x0002 /* 1=Polarity Changed */ -#define GG82563_PSSR2_ENERGY_DETECT_CHANGED 0x0010 /* 1=Energy Detect Changed */ -#define GG82563_PSSR2_DOWNSHIFT_INTERRUPT 0x0020 /* 1=Downshift Detected */ -#define GG82563_PSSR2_MDI_CROSSOVER_CHANGE 0x0040 /* 1=Crossover Changed */ -#define GG82563_PSSR2_FALSE_CARRIER 0x0100 /* 1=false Carrier */ -#define GG82563_PSSR2_SYMBOL_ERROR 0x0200 /* 1=Symbol Error */ -#define GG82563_PSSR2_LINK_STATUS_CHANGED 0x0400 /* 1=Link Status Changed */ -#define GG82563_PSSR2_AUTO_NEG_COMPLETED 0x0800 /* 1=Auto-Neg Completed */ -#define GG82563_PSSR2_PAGE_RECEIVED 0x1000 /* 1=Page Received */ -#define GG82563_PSSR2_DUPLEX_CHANGED 0x2000 /* 1=Duplex Changed */ -#define GG82563_PSSR2_SPEED_CHANGED 0x4000 /* 1=Speed Changed */ -#define GG82563_PSSR2_AUTO_NEG_ERROR 0x8000 /* 1=Auto-Neg Error */ - -/* PHY Specific Control Register 2 (Page 0, Register 26) */ -#define GG82563_PSCR2_10BT_POLARITY_FORCE 0x0002 /* 1=Force Negative - Polarity */ -#define GG82563_PSCR2_1000MB_TEST_SELECT_MASK 0x000C -#define GG82563_PSCR2_1000MB_TEST_SELECT_NORMAL 0x0000 /* 00,01=Normal - Operation */ -#define GG82563_PSCR2_1000MB_TEST_SELECT_112NS 0x0008 /* 10=Select 112ns - Sequence */ -#define GG82563_PSCR2_1000MB_TEST_SELECT_16NS 0x000C /* 11=Select 16ns - Sequence */ -#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000 /* 1=Reverse - Auto-Negotiation */ -#define GG82563_PSCR2_1000BT_DISABLE 0x4000 /* 1=Disable - 1000BASE-T */ -#define GG82563_PSCR2_TRANSMITER_TYPE_MASK 0x8000 -#define GG82563_PSCR2_TRANSMITTER_TYPE_CLASS_B 0x0000 /* 0=Class B */ -#define GG82563_PSCR2_TRANSMITTER_TYPE_CLASS_A 0x8000 /* 1=Class A */ - -/* MAC Specific Control Register (Page 2, Register 21) */ -/* Tx clock speed for Link Down and 1000BASE-T for the following speeds */ -#define GG82563_MSCR_TX_CLK_MASK 0x0007 -#define GG82563_MSCR_TX_CLK_10MBPS_2_5MHZ 0x0004 -#define GG82563_MSCR_TX_CLK_100MBPS_25MHZ 0x0005 -#define GG82563_MSCR_TX_CLK_1000MBPS_2_5MHZ 0x0006 -#define GG82563_MSCR_TX_CLK_1000MBPS_25MHZ 0x0007 - -#define GG82563_MSCR_ASSERT_CRS_ON_TX 0x0010 /* 1=Assert */ - -/* DSP Distance Register (Page 5, Register 26) */ -#define GG82563_DSPD_CABLE_LENGTH 0x0007 /* 0 = <50M; - 1 = 50-80M; - 2 = 80-110M; - 3 = 110-140M; - 4 = >140M */ - -/* Kumeran Mode Control Register (Page 193, Register 16) */ -#define GG82563_KMCR_PHY_LEDS_EN 0x0020 /* 1=PHY LEDs, - 0=Kumeran Inband LEDs */ -#define GG82563_KMCR_FORCE_LINK_UP 0x0040 /* 1=Force Link Up */ -#define GG82563_KMCR_SUPPRESS_SGMII_EPD_EXT 0x0080 -#define GG82563_KMCR_MDIO_BUS_SPEED_SELECT_MASK 0x0400 -#define GG82563_KMCR_MDIO_BUS_SPEED_SELECT 0x0400 /* 1=6.25MHz, - 0=0.8MHz */ -#define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800 - -/* Power Management Control Register (Page 193, Register 20) */ -#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001 /* 1=Enalbe SERDES - Electrical Idle */ -#define GG82563_PMCR_DISABLE_PORT 0x0002 /* 1=Disable Port */ -#define GG82563_PMCR_DISABLE_SERDES 0x0004 /* 1=Disable SERDES */ -#define GG82563_PMCR_REVERSE_AUTO_NEG 0x0008 /* 1=Enable Reverse - Auto-Negotiation */ -#define GG82563_PMCR_DISABLE_1000_NON_D0 0x0010 /* 1=Disable 1000Mbps - Auto-Neg in non D0 */ -#define GG82563_PMCR_DISABLE_1000 0x0020 /* 1=Disable 1000Mbps - Auto-Neg Always */ -#define GG82563_PMCR_REVERSE_AUTO_NEG_D0A 0x0040 /* 1=Enable D0a - Reverse Auto-Negotiation */ -#define GG82563_PMCR_FORCE_POWER_STATE 0x0080 /* 1=Force Power State */ -#define GG82563_PMCR_PROGRAMMED_POWER_STATE_MASK 0x0300 -#define GG82563_PMCR_PROGRAMMED_POWER_STATE_DR 0x0000 /* 00=Dr */ -#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D0U 0x0100 /* 01=D0u */ -#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D0A 0x0200 /* 10=D0a */ -#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D3 0x0300 /* 11=D3 */ - -/* In-Band Control Register (Page 194, Register 18) */ -#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding Use */ - - -/* Bits... - * 15-5: page - * 4-0: register offset - */ -#define GG82563_PAGE_SHIFT 5 -#define GG82563_REG(page, reg) \ - (((page) << GG82563_PAGE_SHIFT) | ((reg) & MAX_PHY_REG_ADDRESS)) -#define GG82563_MIN_ALT_REG 30 - -/* GG82563 Specific Registers */ -#define GG82563_PHY_SPEC_CTRL \ - GG82563_REG(0, 16) /* PHY Specific Control */ -#define GG82563_PHY_SPEC_STATUS \ - GG82563_REG(0, 17) /* PHY Specific Status */ -#define GG82563_PHY_INT_ENABLE \ - GG82563_REG(0, 18) /* Interrupt Enable */ -#define GG82563_PHY_SPEC_STATUS_2 \ - GG82563_REG(0, 19) /* PHY Specific Status 2 */ -#define GG82563_PHY_RX_ERR_CNTR \ - GG82563_REG(0, 21) /* Receive Error Counter */ -#define GG82563_PHY_PAGE_SELECT \ - GG82563_REG(0, 22) /* Page Select */ -#define GG82563_PHY_SPEC_CTRL_2 \ - GG82563_REG(0, 26) /* PHY Specific Control 2 */ -#define GG82563_PHY_PAGE_SELECT_ALT \ - GG82563_REG(0, 29) /* Alternate Page Select */ -#define GG82563_PHY_TEST_CLK_CTRL \ - GG82563_REG(0, 30) /* Test Clock Control (use reg. 29 to select) */ - -#define GG82563_PHY_MAC_SPEC_CTRL \ - GG82563_REG(2, 21) /* MAC Specific Control Register */ -#define GG82563_PHY_MAC_SPEC_CTRL_2 \ - GG82563_REG(2, 26) /* MAC Specific Control 2 */ - -#define GG82563_PHY_DSP_DISTANCE \ - GG82563_REG(5, 26) /* DSP Distance */ - -/* Page 193 - Port Control Registers */ -#define GG82563_PHY_KMRN_MODE_CTRL \ - GG82563_REG(193, 16) /* Kumeran Mode Control */ -#define GG82563_PHY_PORT_RESET \ - GG82563_REG(193, 17) /* Port Reset */ -#define GG82563_PHY_REVISION_ID \ - GG82563_REG(193, 18) /* Revision ID */ -#define GG82563_PHY_DEVICE_ID \ - GG82563_REG(193, 19) /* Device ID */ -#define GG82563_PHY_PWR_MGMT_CTRL \ - GG82563_REG(193, 20) /* Power Management Control */ -#define GG82563_PHY_RATE_ADAPT_CTRL \ - GG82563_REG(193, 25) /* Rate Adaptation Control */ - -/* Page 194 - KMRN Registers */ -#define GG82563_PHY_KMRN_FIFO_CTRL_STAT \ - GG82563_REG(194, 16) /* FIFO's Control/Status */ -#define GG82563_PHY_KMRN_CTRL \ - GG82563_REG(194, 17) /* Control */ -#define GG82563_PHY_INBAND_CTRL \ - GG82563_REG(194, 18) /* Inband Control */ -#define GG82563_PHY_KMRN_DIAGNOSTIC \ - GG82563_REG(194, 19) /* Diagnostic */ -#define GG82563_PHY_ACK_TIMEOUTS \ - GG82563_REG(194, 20) /* Acknowledge Timeouts */ -#define GG82563_PHY_ADV_ABILITY \ - GG82563_REG(194, 21) /* Advertised Ability */ -#define GG82563_PHY_LINK_PARTNER_ADV_ABILITY \ - GG82563_REG(194, 23) /* Link Partner Advertised Ability */ -#define GG82563_PHY_ADV_NEXT_PAGE \ - GG82563_REG(194, 24) /* Advertised Next Page */ -#define GG82563_PHY_LINK_PARTNER_ADV_NEXT_PAGE \ - GG82563_REG(194, 25) /* Link Partner Advertised Next page */ -#define GG82563_PHY_KMRN_MISC \ - GG82563_REG(194, 26) /* Misc. */ - -/* PHY Control Register */ -#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ -#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ -#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ -#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ -#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */ -#define MII_CR_POWER_DOWN 0x0800 /* Power down */ -#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ -#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ -#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ -#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ - -/* PHY Status Register */ -#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ -#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ -#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ -#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ -#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ -#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ -#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ -#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ -#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ -#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ -#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ -#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ -#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ -#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ -#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ - -/* Autoneg Advertisement Register */ -#define NWAY_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */ -#define NWAY_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */ -#define NWAY_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */ -#define NWAY_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */ -#define NWAY_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */ -#define NWAY_AR_100T4_CAPS 0x0200 /* 100T4 Capable */ -#define NWAY_AR_PAUSE 0x0400 /* Pause operation desired */ -#define NWAY_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */ -#define NWAY_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */ -#define NWAY_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */ - -/* Link Partner Ability Register (Base Page) */ -#define NWAY_LPAR_SELECTOR_FIELD 0x0000 /* LP protocol selector field */ -#define NWAY_LPAR_10T_HD_CAPS 0x0020 /* LP is 10T Half Duplex Capable */ -#define NWAY_LPAR_10T_FD_CAPS 0x0040 /* LP is 10T Full Duplex Capable */ -#define NWAY_LPAR_100TX_HD_CAPS 0x0080 /* LP is 100TX Half Duplex Capable */ -#define NWAY_LPAR_100TX_FD_CAPS 0x0100 /* LP is 100TX Full Duplex Capable */ -#define NWAY_LPAR_100T4_CAPS 0x0200 /* LP is 100T4 Capable */ -#define NWAY_LPAR_PAUSE 0x0400 /* LP Pause operation desired */ -#define NWAY_LPAR_ASM_DIR 0x0800 /* LP Asymmetric Pause Direction bit */ -#define NWAY_LPAR_REMOTE_FAULT 0x2000 /* LP has detected Remote Fault */ -#define NWAY_LPAR_ACKNOWLEDGE 0x4000 /* LP has rx'd link code word */ -#define NWAY_LPAR_NEXT_PAGE 0x8000 /* Next Page ability supported */ - -/* Autoneg Expansion Register */ -#define NWAY_ER_LP_NWAY_CAPS 0x0001 /* LP has Auto Neg Capability */ -#define NWAY_ER_PAGE_RXD 0x0002 /* LP is 10T Half Duplex Capable */ -#define NWAY_ER_NEXT_PAGE_CAPS 0x0004 /* LP is 10T Full Duplex Capable */ -#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008 /* LP is 100TX Half Duplex Capable */ -#define NWAY_ER_PAR_DETECT_FAULT 0x0100 /* LP is 100TX Full Duplex Capable */ - -/* Next Page TX Register */ -#define NPTX_MSG_CODE_FIELD 0x0001 /* NP msg code or unformatted data */ -#define NPTX_TOGGLE 0x0800 /* Toggles between exchanges - * of different NP - */ -#define NPTX_ACKNOWLDGE2 0x1000 /* 1 = will comply with msg - * 0 = cannot comply with msg - */ -#define NPTX_MSG_PAGE 0x2000 /* formatted(1)/unformatted(0) pg */ -#define NPTX_NEXT_PAGE 0x8000 /* 1 = addition NP will follow - * 0 = sending last NP - */ - -/* Link Partner Next Page Register */ -#define LP_RNPR_MSG_CODE_FIELD 0x0001 /* NP msg code or unformatted data */ -#define LP_RNPR_TOGGLE 0x0800 /* Toggles between exchanges - * of different NP - */ -#define LP_RNPR_ACKNOWLDGE2 0x1000 /* 1 = will comply with msg - * 0 = cannot comply with msg - */ -#define LP_RNPR_MSG_PAGE 0x2000 /* formatted(1)/unformatted(0) pg */ -#define LP_RNPR_ACKNOWLDGE 0x4000 /* 1 = ACK / 0 = NO ACK */ -#define LP_RNPR_NEXT_PAGE 0x8000 /* 1 = addition NP will follow - * 0 = sending last NP - */ - -/* 1000BASE-T Control Register */ -#define CR_1000T_ASYM_PAUSE 0x0080 /* Advertise asymmetric pause bit */ -#define CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */ -#define CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */ -#define CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port */ - /* 0=DTE device */ -#define CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master */ - /* 0=Configure PHY as Slave */ -#define CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */ - /* 0=Automatic Master/Slave config */ -#define CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */ -#define CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */ -#define CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */ -#define CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */ -#define CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */ - -/* 1000BASE-T Status Register */ -#define SR_1000T_IDLE_ERROR_CNT 0x00FF /* Num idle errors since last read */ -#define SR_1000T_ASYM_PAUSE_DIR 0x0100 /* LP asymmetric pause direction bit */ -#define SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */ -#define SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */ -#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */ -#define SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */ -#define SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */ -#define SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */ -#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12 -#define SR_1000T_LOCAL_RX_STATUS_SHIFT 13 - -/* Extended Status Register */ -#define IEEE_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */ -#define IEEE_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */ -#define IEEE_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */ -#define IEEE_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */ - -#define PHY_TX_POLARITY_MASK 0x0100 /* register 10h bit 8 (polarity bit) */ -#define PHY_TX_NORMAL_POLARITY 0 /* register 10h bit 8 (normal polarity) */ - -#define AUTO_POLARITY_DISABLE 0x0010 /* register 11h bit 4 */ - /* (0=enable, 1=disable) */ - -/* M88E1000 PHY Specific Control Register */ -#define M88E1000_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */ -#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */ -#define M88E1000_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */ -#define M88E1000_PSCR_CLK125_DISABLE 0x0010 /* 1=CLK125 low, - * 0=CLK125 toggling - */ -#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */ - /* Manual MDI configuration */ -#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */ -#define M88E1000_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover, - * 100BASE-TX/10BASE-T: - * MDI Mode - */ -#define M88E1000_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled - * all speeds. - */ -#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE 0x0080 - /* 1=Enable Extended 10BASE-T distance - * (Lower 10BASE-T RX Threshold) - * 0=Normal 10BASE-T RX Threshold */ -#define M88E1000_PSCR_MII_5BIT_ENABLE 0x0100 - /* 1=5-Bit interface in 100BASE-TX - * 0=MII interface in 100BASE-TX */ -#define M88E1000_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */ -#define M88E1000_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */ -#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */ - -#define M88E1000_PSCR_POLARITY_REVERSAL_SHIFT 1 -#define M88E1000_PSCR_AUTO_X_MODE_SHIFT 5 -#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7 - -/* M88E1000 PHY Specific Status Register */ -#define M88E1000_PSSR_JABBER 0x0001 /* 1=Jabber */ -#define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */ -#define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */ -#define M88E1000_PSSR_CABLE_LENGTH 0x0380 /* 0=<50M;1=50-80M;2=80-110M; - * 3=110-140M;4=>140M */ -#define M88E1000_PSSR_LINK 0x0400 /* 1=Link up, 0=Link down */ -#define M88E1000_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */ -#define M88E1000_PSSR_PAGE_RCVD 0x1000 /* 1=Page received */ -#define M88E1000_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */ -#define M88E1000_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */ -#define M88E1000_PSSR_10MBS 0x0000 /* 00=10Mbs */ -#define M88E1000_PSSR_100MBS 0x4000 /* 01=100Mbs */ -#define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ - -#define M88E1000_PSSR_REV_POLARITY_SHIFT 1 -#define M88E1000_PSSR_MDIX_SHIFT 6 -#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7 - -/* M88E1000 Extended PHY Specific Control Register */ -#define M88E1000_EPSCR_FIBER_LOOPBACK 0x4000 /* 1=Fiber loopback */ -#define M88E1000_EPSCR_DOWN_NO_IDLE 0x8000 /* 1=Lost lock detect enabled. - * Will assert lost lock and bring - * link down if idle not seen - * within 1ms in 1000BASE-T - */ -/* Number of times we will attempt to autonegotiate before downshifting if we - * are the master */ -#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00 -#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X 0x0000 -#define M88E1000_EPSCR_MASTER_DOWNSHIFT_2X 0x0400 -#define M88E1000_EPSCR_MASTER_DOWNSHIFT_3X 0x0800 -#define M88E1000_EPSCR_MASTER_DOWNSHIFT_4X 0x0C00 -/* Number of times we will attempt to autonegotiate before downshifting if we - * are the slave */ -#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK 0x0300 -#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_DIS 0x0000 -#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100 -#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_2X 0x0200 -#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_3X 0x0300 -#define M88E1000_EPSCR_TX_CLK_2_5 0x0060 /* 2.5 MHz TX_CLK */ -#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */ -#define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */ - -/* Bit definitions for valid PHY IDs. */ -#define M88E1000_E_PHY_ID 0x01410C50 -#define M88E1000_I_PHY_ID 0x01410C30 -#define M88E1011_I_PHY_ID 0x01410C20 -#define M88E1000_12_PHY_ID M88E1000_E_PHY_ID -#define M88E1000_14_PHY_ID M88E1000_E_PHY_ID -#define IGP01E1000_I_PHY_ID 0x02A80380 -#define M88E1011_I_REV_4 0x04 -#define M88E1111_I_PHY_ID 0x01410CC0 -#define L1LXT971A_PHY_ID 0x001378E0 -#define GG82563_E_PHY_ID 0x01410CA0 - -#define BME1000_E_PHY_ID 0x01410CB0 - -/* Miscellaneous PHY bit definitions. */ -#define PHY_PREAMBLE 0xFFFFFFFF -#define PHY_SOF 0x01 -#define PHY_OP_READ 0x02 -#define PHY_OP_WRITE 0x01 -#define PHY_TURNAROUND 0x02 -#define PHY_PREAMBLE_SIZE 32 -#define MII_CR_SPEED_1000 0x0040 -#define MII_CR_SPEED_100 0x2000 -#define MII_CR_SPEED_10 0x0000 -#define E1000_PHY_ADDRESS 0x01 -#define PHY_AUTO_NEG_TIME 45 /* 4.5 Seconds */ -#define PHY_FORCE_TIME 20 /* 2.0 Seconds */ -#define PHY_REVISION_MASK 0xFFFFFFF0 -#define DEVICE_SPEED_MASK 0x00000300 /* Device Ctrl Reg Speed Mask */ -#define REG4_SPEED_MASK 0x01E0 -#define REG9_SPEED_MASK 0x0300 -#define ADVERTISE_10_HALF 0x0001 -#define ADVERTISE_10_FULL 0x0002 -#define ADVERTISE_100_HALF 0x0004 -#define ADVERTISE_100_FULL 0x0008 -#define ADVERTISE_1000_HALF 0x0010 -#define ADVERTISE_1000_FULL 0x0020 - -#define ICH_FLASH_GFPREG 0x0000 -#define ICH_FLASH_HSFSTS 0x0004 -#define ICH_FLASH_HSFCTL 0x0006 -#define ICH_FLASH_FADDR 0x0008 -#define ICH_FLASH_FDATA0 0x0010 -#define ICH_FLASH_FRACC 0x0050 -#define ICH_FLASH_FREG0 0x0054 -#define ICH_FLASH_FREG1 0x0058 -#define ICH_FLASH_FREG2 0x005C -#define ICH_FLASH_FREG3 0x0060 -#define ICH_FLASH_FPR0 0x0074 -#define ICH_FLASH_FPR1 0x0078 -#define ICH_FLASH_SSFSTS 0x0090 -#define ICH_FLASH_SSFCTL 0x0092 -#define ICH_FLASH_PREOP 0x0094 -#define ICH_FLASH_OPTYPE 0x0096 -#define ICH_FLASH_OPMENU 0x0098 - -#define ICH_FLASH_REG_MAPSIZE 0x00A0 -#define ICH_FLASH_SECTOR_SIZE 4096 -#define ICH_GFPREG_BASE_MASK 0x1FFF -#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF - -#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */ - -/* SPI EEPROM Status Register */ -#define EEPROM_STATUS_RDY_SPI 0x01 -#define EEPROM_STATUS_WEN_SPI 0x02 -#define EEPROM_STATUS_BP0_SPI 0x04 -#define EEPROM_STATUS_BP1_SPI 0x08 -#define EEPROM_STATUS_WPEN_SPI 0x80 - -/* SW Semaphore Register */ -#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */ -#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ -#define E1000_SWSM_WMNG 0x00000004 /* Wake MNG Clock */ -#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */ - -/* FW Semaphore Register */ -#define E1000_FWSM_MODE_MASK 0x0000000E /* FW mode */ -#define E1000_FWSM_MODE_SHIFT 1 -#define E1000_FWSM_FW_VALID 0x00008000 /* FW established a valid mode */ - -#define E1000_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI reset */ -#define E1000_FWSM_DISSW 0x10000000 /* FW disable SW Write Access */ -#define E1000_FWSM_SKUSEL_MASK 0x60000000 /* LAN SKU select */ -#define E1000_FWSM_SKUEL_SHIFT 29 -#define E1000_FWSM_SKUSEL_EMB 0x0 /* Embedded SKU */ -#define E1000_FWSM_SKUSEL_CONS 0x1 /* Consumer SKU */ -#define E1000_FWSM_SKUSEL_PERF_100 0x2 /* Perf & Corp 10/100 SKU */ -#define E1000_FWSM_SKUSEL_PERF_GBE 0x3 /* Perf & Copr GbE SKU */ - -#define E1000_GCR 0x05B00 /* PCI-Ex Control */ -#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */ -#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */ -#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */ -#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */ -#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */ -#define E1000_SWSM 0x05B50 /* SW Semaphore */ -#define E1000_FWSM 0x05B54 /* FW Semaphore */ -#define E1000_FFLT_DBG 0x05F04 /* Debug Register */ -#define E1000_HICR 0x08F00 /* Host Inteface Control */ - -#define IGP_ACTIVITY_LED_MASK 0xFFFFF0FF -#define IGP_ACTIVITY_LED_ENABLE 0x0300 -#define IGP_LED3_MODE 0x07000000 - -/* Mask bit for PHY class in Word 7 of the EEPROM */ -#define EEPROM_PHY_CLASS_A 0x8000 -#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F /* Everything but 1000-Half */ -#define AUTONEG_ADVERTISE_10_100_ALL 0x000F /* All 10/100 speeds*/ -#define AUTONEG_ADVERTISE_10_ALL 0x0003 /* 10Mbps Full & Half speeds*/ - -#define E1000_KUMCTRLSTA_MASK 0x0000FFFF -#define E1000_KUMCTRLSTA_OFFSET 0x001F0000 -#define E1000_KUMCTRLSTA_OFFSET_SHIFT 16 -#define E1000_KUMCTRLSTA_REN 0x00200000 - -#define E1000_KUMCTRLSTA_OFFSET_FIFO_CTRL 0x00000000 -#define E1000_KUMCTRLSTA_OFFSET_CTRL 0x00000001 -#define E1000_KUMCTRLSTA_OFFSET_INB_CTRL 0x00000002 -#define E1000_KUMCTRLSTA_OFFSET_DIAG 0x00000003 -#define E1000_KUMCTRLSTA_OFFSET_TIMEOUTS 0x00000004 -#define E1000_KUMCTRLSTA_OFFSET_INB_PARAM 0x00000009 -#define E1000_KUMCTRLSTA_OFFSET_HD_CTRL 0x00000010 -#define E1000_KUMCTRLSTA_OFFSET_M2P_SERDES 0x0000001E -#define E1000_KUMCTRLSTA_OFFSET_M2P_MODES 0x0000001F - -/* FIFO Control */ -#define E1000_KUMCTRLSTA_FIFO_CTRL_RX_BYPASS 0x00000008 -#define E1000_KUMCTRLSTA_FIFO_CTRL_TX_BYPASS 0x00000800 - -/* In-Band Control */ -#define E1000_KUMCTRLSTA_INB_CTRL_LINK_STATUS_TX_TIMEOUT_DEFAULT 0x00000500 -#define E1000_KUMCTRLSTA_INB_CTRL_DIS_PADDING 0x00000010 - -/* Half-Duplex Control */ -#define E1000_KUMCTRLSTA_HD_CTRL_10_100_DEFAULT 0x00000004 -#define E1000_KUMCTRLSTA_HD_CTRL_1000_DEFAULT 0x00000000 - -#define E1000_KUMCTRLSTA_OFFSET_K0S_CTRL 0x0000001E - -#define E1000_KUMCTRLSTA_DIAG_FELPBK 0x2000 -#define E1000_KUMCTRLSTA_DIAG_NELPBK 0x1000 - -#define E1000_KUMCTRLSTA_K0S_100_EN 0x2000 -#define E1000_KUMCTRLSTA_K0S_GBE_EN 0x1000 -#define E1000_KUMCTRLSTA_K0S_ENTRY_LATENCY_MASK 0x0003 - -#define E1000_MNG_ICH_IAMT_MODE 0x2 -#define E1000_MNG_IAMT_MODE 0x3 -#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */ -#define E1000_KUMCTRLSTA 0x00034 /* MAC-PHY interface - RW */ -/* Number of milliseconds we wait for PHY configuration done after MAC reset */ -#define PHY_CFG_TIMEOUT 100 -#define DEFAULT_80003ES2LAN_TIPG_IPGT_10_100 0x00000009 -#define DEFAULT_80003ES2LAN_TIPG_IPGT_1000 0x00000008 -#define AUTO_ALL_MODES 0 - -#ifndef E1000_MASTER_SLAVE -/* Switch to override PHY master/slave setting */ -#define E1000_MASTER_SLAVE e1000_ms_hw_default -#endif -/* Extended Transmit Control */ -#define E1000_TCTL_EXT_BST_MASK 0x000003FF /* Backoff Slot Time */ -#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */ - -#define DEFAULT_80003ES2LAN_TCTL_EXT_GCEX 0x00010000 - -#define PCI_EX_82566_SNOOP_ALL PCI_EX_NO_SNOOP_ALL - -#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 -#define E1000_MC_TBL_SIZE_ICH8LAN 32 - -#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers - after IMS clear */ -#endif /* _E1000_HW_H_ */ diff --git a/qemu/roms/u-boot/drivers/net/e1000_spi.c b/qemu/roms/u-boot/drivers/net/e1000_spi.c deleted file mode 100644 index 93043a1ad..000000000 --- a/qemu/roms/u-boot/drivers/net/e1000_spi.c +++ /dev/null @@ -1,577 +0,0 @@ -#include "e1000.h" -#include <linux/compiler.h> - -/*----------------------------------------------------------------------- - * SPI transfer - * - * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks - * "bitlen" bits in the SPI MISO port. That's just the way SPI works. - * - * The source of the outgoing bits is the "dout" parameter and the - * destination of the input bits is the "din" parameter. Note that "dout" - * and "din" can point to the same memory location, in which case the - * input data overwrites the output data (since both are buffered by - * temporary variables, this is OK). - * - * This may be interrupted with Ctrl-C if "intr" is true, otherwise it will - * never return an error. - */ -static int e1000_spi_xfer(struct e1000_hw *hw, unsigned int bitlen, - const void *dout_mem, void *din_mem, bool intr) -{ - const uint8_t *dout = dout_mem; - uint8_t *din = din_mem; - - uint8_t mask = 0; - uint32_t eecd; - unsigned long i; - - /* Pre-read the control register */ - eecd = E1000_READ_REG(hw, EECD); - - /* Iterate over each bit */ - for (i = 0, mask = 0x80; i < bitlen; i++, mask = (mask >> 1)?:0x80) { - /* Check for interrupt */ - if (intr && ctrlc()) - return -1; - - /* Determine the output bit */ - if (dout && dout[i >> 3] & mask) - eecd |= E1000_EECD_DI; - else - eecd &= ~E1000_EECD_DI; - - /* Write the output bit and wait 50us */ - E1000_WRITE_REG(hw, EECD, eecd); - E1000_WRITE_FLUSH(hw); - udelay(50); - - /* Poke the clock (waits 50us) */ - e1000_raise_ee_clk(hw, &eecd); - - /* Now read the input bit */ - eecd = E1000_READ_REG(hw, EECD); - if (din) { - if (eecd & E1000_EECD_DO) - din[i >> 3] |= mask; - else - din[i >> 3] &= ~mask; - } - - /* Poke the clock again (waits 50us) */ - e1000_lower_ee_clk(hw, &eecd); - } - - /* Now clear any remaining bits of the input */ - if (din && (i & 7)) - din[i >> 3] &= ~((mask << 1) - 1); - - return 0; -} - -#ifdef CONFIG_E1000_SPI_GENERIC -static inline struct e1000_hw *e1000_hw_from_spi(struct spi_slave *spi) -{ - return container_of(spi, struct e1000_hw, spi); -} - -/* Not sure why all of these are necessary */ -void spi_init_r(void) { /* Nothing to do */ } -void spi_init_f(void) { /* Nothing to do */ } -void spi_init(void) { /* Nothing to do */ } - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - /* Find the right PCI device */ - struct e1000_hw *hw = e1000_find_card(bus); - if (!hw) { - printf("ERROR: No such e1000 device: e1000#%u\n", bus); - return NULL; - } - - /* Make sure it has an SPI chip */ - if (hw->eeprom.type != e1000_eeprom_spi) { - E1000_ERR(hw->nic, "No attached SPI EEPROM found!\n"); - return NULL; - } - - /* Argument sanity checks */ - if (cs != 0) { - E1000_ERR(hw->nic, "No such SPI chip: %u\n", cs); - return NULL; - } - if (mode != SPI_MODE_0) { - E1000_ERR(hw->nic, "Only SPI MODE-0 is supported!\n"); - return NULL; - } - - /* TODO: Use max_hz somehow */ - E1000_DBG(hw->nic, "EEPROM SPI access requested\n"); - return &hw->spi; -} - -void spi_free_slave(struct spi_slave *spi) -{ - __maybe_unused struct e1000_hw *hw = e1000_hw_from_spi(spi); - E1000_DBG(hw->nic, "EEPROM SPI access released\n"); -} - -int spi_claim_bus(struct spi_slave *spi) -{ - struct e1000_hw *hw = e1000_hw_from_spi(spi); - - if (e1000_acquire_eeprom(hw)) { - E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n"); - return -1; - } - - return 0; -} - -void spi_release_bus(struct spi_slave *spi) -{ - struct e1000_hw *hw = e1000_hw_from_spi(spi); - e1000_release_eeprom(hw); -} - -/* Skinny wrapper around e1000_spi_xfer */ -int spi_xfer(struct spi_slave *spi, unsigned int bitlen, - const void *dout_mem, void *din_mem, unsigned long flags) -{ - struct e1000_hw *hw = e1000_hw_from_spi(spi); - int ret; - - if (flags & SPI_XFER_BEGIN) - e1000_standby_eeprom(hw); - - ret = e1000_spi_xfer(hw, bitlen, dout_mem, din_mem, true); - - if (flags & SPI_XFER_END) - e1000_standby_eeprom(hw); - - return ret; -} - -#endif /* not CONFIG_E1000_SPI_GENERIC */ - -#ifdef CONFIG_CMD_E1000 - -/* The EEPROM opcodes */ -#define SPI_EEPROM_ENABLE_WR 0x06 -#define SPI_EEPROM_DISABLE_WR 0x04 -#define SPI_EEPROM_WRITE_STATUS 0x01 -#define SPI_EEPROM_READ_STATUS 0x05 -#define SPI_EEPROM_WRITE_PAGE 0x02 -#define SPI_EEPROM_READ_PAGE 0x03 - -/* The EEPROM status bits */ -#define SPI_EEPROM_STATUS_BUSY 0x01 -#define SPI_EEPROM_STATUS_WREN 0x02 - -static int e1000_spi_eeprom_enable_wr(struct e1000_hw *hw, bool intr) -{ - u8 op[] = { SPI_EEPROM_ENABLE_WR }; - e1000_standby_eeprom(hw); - return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr); -} - -/* - * These have been tested to perform correctly, but they are not used by any - * of the EEPROM commands at this time. - */ -#if 0 -static int e1000_spi_eeprom_disable_wr(struct e1000_hw *hw, bool intr) -{ - u8 op[] = { SPI_EEPROM_DISABLE_WR }; - e1000_standby_eeprom(hw); - return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr); -} - -static int e1000_spi_eeprom_write_status(struct e1000_hw *hw, - u8 status, bool intr) -{ - u8 op[] = { SPI_EEPROM_WRITE_STATUS, status }; - e1000_standby_eeprom(hw); - return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr); -} -#endif - -static int e1000_spi_eeprom_read_status(struct e1000_hw *hw, bool intr) -{ - u8 op[] = { SPI_EEPROM_READ_STATUS, 0 }; - e1000_standby_eeprom(hw); - if (e1000_spi_xfer(hw, 8*sizeof(op), op, op, intr)) - return -1; - return op[1]; -} - -static int e1000_spi_eeprom_write_page(struct e1000_hw *hw, - const void *data, u16 off, u16 len, bool intr) -{ - u8 op[] = { - SPI_EEPROM_WRITE_PAGE, - (off >> (hw->eeprom.address_bits - 8)) & 0xff, off & 0xff - }; - - e1000_standby_eeprom(hw); - - if (e1000_spi_xfer(hw, 8 + hw->eeprom.address_bits, op, NULL, intr)) - return -1; - if (e1000_spi_xfer(hw, len << 3, data, NULL, intr)) - return -1; - - return 0; -} - -static int e1000_spi_eeprom_read_page(struct e1000_hw *hw, - void *data, u16 off, u16 len, bool intr) -{ - u8 op[] = { - SPI_EEPROM_READ_PAGE, - (off >> (hw->eeprom.address_bits - 8)) & 0xff, off & 0xff - }; - - e1000_standby_eeprom(hw); - - if (e1000_spi_xfer(hw, 8 + hw->eeprom.address_bits, op, NULL, intr)) - return -1; - if (e1000_spi_xfer(hw, len << 3, NULL, data, intr)) - return -1; - - return 0; -} - -static int e1000_spi_eeprom_poll_ready(struct e1000_hw *hw, bool intr) -{ - int status; - while ((status = e1000_spi_eeprom_read_status(hw, intr)) >= 0) { - if (!(status & SPI_EEPROM_STATUS_BUSY)) - return 0; - } - return -1; -} - -static int e1000_spi_eeprom_dump(struct e1000_hw *hw, - void *data, u16 off, unsigned int len, bool intr) -{ - /* Interruptibly wait for the EEPROM to be ready */ - if (e1000_spi_eeprom_poll_ready(hw, intr)) - return -1; - - /* Dump each page in sequence */ - while (len) { - /* Calculate the data bytes on this page */ - u16 pg_off = off & (hw->eeprom.page_size - 1); - u16 pg_len = hw->eeprom.page_size - pg_off; - if (pg_len > len) - pg_len = len; - - /* Now dump the page */ - if (e1000_spi_eeprom_read_page(hw, data, off, pg_len, intr)) - return -1; - - /* Otherwise go on to the next page */ - len -= pg_len; - off += pg_len; - data += pg_len; - } - - /* We're done! */ - return 0; -} - -static int e1000_spi_eeprom_program(struct e1000_hw *hw, - const void *data, u16 off, u16 len, bool intr) -{ - /* Program each page in sequence */ - while (len) { - /* Calculate the data bytes on this page */ - u16 pg_off = off & (hw->eeprom.page_size - 1); - u16 pg_len = hw->eeprom.page_size - pg_off; - if (pg_len > len) - pg_len = len; - - /* Interruptibly wait for the EEPROM to be ready */ - if (e1000_spi_eeprom_poll_ready(hw, intr)) - return -1; - - /* Enable write access */ - if (e1000_spi_eeprom_enable_wr(hw, intr)) - return -1; - - /* Now program the page */ - if (e1000_spi_eeprom_write_page(hw, data, off, pg_len, intr)) - return -1; - - /* Otherwise go on to the next page */ - len -= pg_len; - off += pg_len; - data += pg_len; - } - - /* Wait for the last write to complete */ - if (e1000_spi_eeprom_poll_ready(hw, intr)) - return -1; - - /* We're done! */ - return 0; -} - -static int do_e1000_spi_show(cmd_tbl_t *cmdtp, struct e1000_hw *hw, - int argc, char * const argv[]) -{ - unsigned int length = 0; - u16 i, offset = 0; - u8 *buffer; - int err; - - if (argc > 2) { - cmd_usage(cmdtp); - return 1; - } - - /* Parse the offset and length */ - if (argc >= 1) - offset = simple_strtoul(argv[0], NULL, 0); - if (argc == 2) - length = simple_strtoul(argv[1], NULL, 0); - else if (offset < (hw->eeprom.word_size << 1)) - length = (hw->eeprom.word_size << 1) - offset; - - /* Extra sanity checks */ - if (!length) { - E1000_ERR(hw->nic, "Requested zero-sized dump!\n"); - return 1; - } - if ((0x10000 < length) || (0x10000 - length < offset)) { - E1000_ERR(hw->nic, "Can't dump past 0xFFFF!\n"); - return 1; - } - - /* Allocate a buffer to hold stuff */ - buffer = malloc(length); - if (!buffer) { - E1000_ERR(hw->nic, "Out of Memory!\n"); - return 1; - } - - /* Acquire the EEPROM and perform the dump */ - if (e1000_acquire_eeprom(hw)) { - E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n"); - free(buffer); - return 1; - } - err = e1000_spi_eeprom_dump(hw, buffer, offset, length, true); - e1000_release_eeprom(hw); - if (err) { - E1000_ERR(hw->nic, "Interrupted!\n"); - free(buffer); - return 1; - } - - /* Now hexdump the result */ - printf("%s: ===== Intel e1000 EEPROM (0x%04hX - 0x%04hX) =====", - hw->nic->name, offset, offset + length - 1); - for (i = 0; i < length; i++) { - if ((i & 0xF) == 0) - printf("\n%s: %04hX: ", hw->nic->name, offset + i); - else if ((i & 0xF) == 0x8) - printf(" "); - printf(" %02hx", buffer[i]); - } - printf("\n"); - - /* Success! */ - free(buffer); - return 0; -} - -static int do_e1000_spi_dump(cmd_tbl_t *cmdtp, struct e1000_hw *hw, - int argc, char * const argv[]) -{ - unsigned int length; - u16 offset; - void *dest; - - if (argc != 3) { - cmd_usage(cmdtp); - return 1; - } - - /* Parse the arguments */ - dest = (void *)simple_strtoul(argv[0], NULL, 16); - offset = simple_strtoul(argv[1], NULL, 0); - length = simple_strtoul(argv[2], NULL, 0); - - /* Extra sanity checks */ - if (!length) { - E1000_ERR(hw->nic, "Requested zero-sized dump!\n"); - return 1; - } - if ((0x10000 < length) || (0x10000 - length < offset)) { - E1000_ERR(hw->nic, "Can't dump past 0xFFFF!\n"); - return 1; - } - - /* Acquire the EEPROM */ - if (e1000_acquire_eeprom(hw)) { - E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n"); - return 1; - } - - /* Perform the programming operation */ - if (e1000_spi_eeprom_dump(hw, dest, offset, length, true) < 0) { - E1000_ERR(hw->nic, "Interrupted!\n"); - e1000_release_eeprom(hw); - return 1; - } - - e1000_release_eeprom(hw); - printf("%s: ===== EEPROM DUMP COMPLETE =====\n", hw->nic->name); - return 0; -} - -static int do_e1000_spi_program(cmd_tbl_t *cmdtp, struct e1000_hw *hw, - int argc, char * const argv[]) -{ - unsigned int length; - const void *source; - u16 offset; - - if (argc != 3) { - cmd_usage(cmdtp); - return 1; - } - - /* Parse the arguments */ - source = (const void *)simple_strtoul(argv[0], NULL, 16); - offset = simple_strtoul(argv[1], NULL, 0); - length = simple_strtoul(argv[2], NULL, 0); - - /* Acquire the EEPROM */ - if (e1000_acquire_eeprom(hw)) { - E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n"); - return 1; - } - - /* Perform the programming operation */ - if (e1000_spi_eeprom_program(hw, source, offset, length, true) < 0) { - E1000_ERR(hw->nic, "Interrupted!\n"); - e1000_release_eeprom(hw); - return 1; - } - - e1000_release_eeprom(hw); - printf("%s: ===== EEPROM PROGRAMMED =====\n", hw->nic->name); - return 0; -} - -static int do_e1000_spi_checksum(cmd_tbl_t *cmdtp, struct e1000_hw *hw, - int argc, char * const argv[]) -{ - uint16_t i, length, checksum = 0, checksum_reg; - uint16_t *buffer; - bool upd; - - if (argc == 0) - upd = 0; - else if ((argc == 1) && !strcmp(argv[0], "update")) - upd = 1; - else { - cmd_usage(cmdtp); - return 1; - } - - /* Allocate a temporary buffer */ - length = sizeof(uint16_t) * (EEPROM_CHECKSUM_REG + 1); - buffer = malloc(length); - if (!buffer) { - E1000_ERR(hw->nic, "Unable to allocate EEPROM buffer!\n"); - return 1; - } - - /* Acquire the EEPROM */ - if (e1000_acquire_eeprom(hw)) { - E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n"); - return 1; - } - - /* Read the EEPROM */ - if (e1000_spi_eeprom_dump(hw, buffer, 0, length, true) < 0) { - E1000_ERR(hw->nic, "Interrupted!\n"); - e1000_release_eeprom(hw); - return 1; - } - - /* Compute the checksum and read the expected value */ - for (i = 0; i < EEPROM_CHECKSUM_REG; i++) - checksum += le16_to_cpu(buffer[i]); - checksum = ((uint16_t)EEPROM_SUM) - checksum; - checksum_reg = le16_to_cpu(buffer[i]); - - /* Verify it! */ - if (checksum_reg == checksum) { - printf("%s: INFO: EEPROM checksum is correct! (0x%04hx)\n", - hw->nic->name, checksum); - e1000_release_eeprom(hw); - return 0; - } - - /* Hrm, verification failed, print an error */ - E1000_ERR(hw->nic, "EEPROM checksum is incorrect!\n"); - E1000_ERR(hw->nic, " ...register was 0x%04hx, calculated 0x%04hx\n", - checksum_reg, checksum); - - /* If they didn't ask us to update it, just return an error */ - if (!upd) { - e1000_release_eeprom(hw); - return 1; - } - - /* Ok, correct it! */ - printf("%s: Reprogramming the EEPROM checksum...\n", hw->nic->name); - buffer[i] = cpu_to_le16(checksum); - if (e1000_spi_eeprom_program(hw, &buffer[i], i * sizeof(uint16_t), - sizeof(uint16_t), true)) { - E1000_ERR(hw->nic, "Interrupted!\n"); - e1000_release_eeprom(hw); - return 1; - } - - e1000_release_eeprom(hw); - return 0; -} - -int do_e1000_spi(cmd_tbl_t *cmdtp, struct e1000_hw *hw, - int argc, char * const argv[]) -{ - if (argc < 1) { - cmd_usage(cmdtp); - return 1; - } - - /* Make sure it has an SPI chip */ - if (hw->eeprom.type != e1000_eeprom_spi) { - E1000_ERR(hw->nic, "No attached SPI EEPROM found!\n"); - return 1; - } - - /* Check the eeprom sub-sub-command arguments */ - if (!strcmp(argv[0], "show")) - return do_e1000_spi_show(cmdtp, hw, argc - 1, argv + 1); - - if (!strcmp(argv[0], "dump")) - return do_e1000_spi_dump(cmdtp, hw, argc - 1, argv + 1); - - if (!strcmp(argv[0], "program")) - return do_e1000_spi_program(cmdtp, hw, argc - 1, argv + 1); - - if (!strcmp(argv[0], "checksum")) - return do_e1000_spi_checksum(cmdtp, hw, argc - 1, argv + 1); - - cmd_usage(cmdtp); - return 1; -} - -#endif /* not CONFIG_CMD_E1000 */ diff --git a/qemu/roms/u-boot/drivers/net/eepro100.c b/qemu/roms/u-boot/drivers/net/eepro100.c deleted file mode 100644 index 1e4ea0c89..000000000 --- a/qemu/roms/u-boot/drivers/net/eepro100.c +++ /dev/null @@ -1,931 +0,0 @@ -/* - * (C) Copyright 2002 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <asm/io.h> -#include <pci.h> -#include <miiphy.h> - -#undef DEBUG - - /* Ethernet chip registers. - */ -#define SCBStatus 0 /* Rx/Command Unit Status *Word* */ -#define SCBIntAckByte 1 /* Rx/Command Unit STAT/ACK byte */ -#define SCBCmd 2 /* Rx/Command Unit Command *Word* */ -#define SCBIntrCtlByte 3 /* Rx/Command Unit Intr.Control Byte */ -#define SCBPointer 4 /* General purpose pointer. */ -#define SCBPort 8 /* Misc. commands and operands. */ -#define SCBflash 12 /* Flash memory control. */ -#define SCBeeprom 14 /* EEPROM memory control. */ -#define SCBCtrlMDI 16 /* MDI interface control. */ -#define SCBEarlyRx 20 /* Early receive byte count. */ -#define SCBGenControl 28 /* 82559 General Control Register */ -#define SCBGenStatus 29 /* 82559 General Status register */ - - /* 82559 SCB status word defnitions - */ -#define SCB_STATUS_CX 0x8000 /* CU finished command (transmit) */ -#define SCB_STATUS_FR 0x4000 /* frame received */ -#define SCB_STATUS_CNA 0x2000 /* CU left active state */ -#define SCB_STATUS_RNR 0x1000 /* receiver left ready state */ -#define SCB_STATUS_MDI 0x0800 /* MDI read/write cycle done */ -#define SCB_STATUS_SWI 0x0400 /* software generated interrupt */ -#define SCB_STATUS_FCP 0x0100 /* flow control pause interrupt */ - -#define SCB_INTACK_MASK 0xFD00 /* all the above */ - -#define SCB_INTACK_TX (SCB_STATUS_CX | SCB_STATUS_CNA) -#define SCB_INTACK_RX (SCB_STATUS_FR | SCB_STATUS_RNR) - - /* System control block commands - */ -/* CU Commands */ -#define CU_NOP 0x0000 -#define CU_START 0x0010 -#define CU_RESUME 0x0020 -#define CU_STATSADDR 0x0040 /* Load Dump Statistics ctrs addr */ -#define CU_SHOWSTATS 0x0050 /* Dump statistics counters. */ -#define CU_ADDR_LOAD 0x0060 /* Base address to add to CU commands */ -#define CU_DUMPSTATS 0x0070 /* Dump then reset stats counters. */ - -/* RUC Commands */ -#define RUC_NOP 0x0000 -#define RUC_START 0x0001 -#define RUC_RESUME 0x0002 -#define RUC_ABORT 0x0004 -#define RUC_ADDR_LOAD 0x0006 /* (seems not to clear on acceptance) */ -#define RUC_RESUMENR 0x0007 - -#define CU_CMD_MASK 0x00f0 -#define RU_CMD_MASK 0x0007 - -#define SCB_M 0x0100 /* 0 = enable interrupt, 1 = disable */ -#define SCB_SWI 0x0200 /* 1 - cause device to interrupt */ - -#define CU_STATUS_MASK 0x00C0 -#define RU_STATUS_MASK 0x003C - -#define RU_STATUS_IDLE (0<<2) -#define RU_STATUS_SUS (1<<2) -#define RU_STATUS_NORES (2<<2) -#define RU_STATUS_READY (4<<2) -#define RU_STATUS_NO_RBDS_SUS ((1<<2)|(8<<2)) -#define RU_STATUS_NO_RBDS_NORES ((2<<2)|(8<<2)) -#define RU_STATUS_NO_RBDS_READY ((4<<2)|(8<<2)) - - /* 82559 Port interface commands. - */ -#define I82559_RESET 0x00000000 /* Software reset */ -#define I82559_SELFTEST 0x00000001 /* 82559 Selftest command */ -#define I82559_SELECTIVE_RESET 0x00000002 -#define I82559_DUMP 0x00000003 -#define I82559_DUMP_WAKEUP 0x00000007 - - /* 82559 Eeprom interface. - */ -#define EE_SHIFT_CLK 0x01 /* EEPROM shift clock. */ -#define EE_CS 0x02 /* EEPROM chip select. */ -#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */ -#define EE_WRITE_0 0x01 -#define EE_WRITE_1 0x05 -#define EE_DATA_READ 0x08 /* EEPROM chip data out. */ -#define EE_ENB (0x4800 | EE_CS) -#define EE_CMD_BITS 3 -#define EE_DATA_BITS 16 - - /* The EEPROM commands include the alway-set leading bit. - */ -#define EE_EWENB_CMD (4 << addr_len) -#define EE_WRITE_CMD (5 << addr_len) -#define EE_READ_CMD (6 << addr_len) -#define EE_ERASE_CMD (7 << addr_len) - - /* Receive frame descriptors. - */ -struct RxFD { - volatile u16 status; - volatile u16 control; - volatile u32 link; /* struct RxFD * */ - volatile u32 rx_buf_addr; /* void * */ - volatile u32 count; - - volatile u8 data[PKTSIZE_ALIGN]; -}; - -#define RFD_STATUS_C 0x8000 /* completion of received frame */ -#define RFD_STATUS_OK 0x2000 /* frame received with no errors */ - -#define RFD_CONTROL_EL 0x8000 /* 1=last RFD in RFA */ -#define RFD_CONTROL_S 0x4000 /* 1=suspend RU after receiving frame */ -#define RFD_CONTROL_H 0x0010 /* 1=RFD is a header RFD */ -#define RFD_CONTROL_SF 0x0008 /* 0=simplified, 1=flexible mode */ - -#define RFD_COUNT_MASK 0x3fff -#define RFD_COUNT_F 0x4000 -#define RFD_COUNT_EOF 0x8000 - -#define RFD_RX_CRC 0x0800 /* crc error */ -#define RFD_RX_ALIGNMENT 0x0400 /* alignment error */ -#define RFD_RX_RESOURCE 0x0200 /* out of space, no resources */ -#define RFD_RX_DMA_OVER 0x0100 /* DMA overrun */ -#define RFD_RX_SHORT 0x0080 /* short frame error */ -#define RFD_RX_LENGTH 0x0020 -#define RFD_RX_ERROR 0x0010 /* receive error */ -#define RFD_RX_NO_ADR_MATCH 0x0004 /* no address match */ -#define RFD_RX_IA_MATCH 0x0002 /* individual address does not match */ -#define RFD_RX_TCO 0x0001 /* TCO indication */ - - /* Transmit frame descriptors - */ -struct TxFD { /* Transmit frame descriptor set. */ - volatile u16 status; - volatile u16 command; - volatile u32 link; /* void * */ - volatile u32 tx_desc_addr; /* Always points to the tx_buf_addr element. */ - volatile s32 count; - - volatile u32 tx_buf_addr0; /* void *, frame to be transmitted. */ - volatile s32 tx_buf_size0; /* Length of Tx frame. */ - volatile u32 tx_buf_addr1; /* void *, frame to be transmitted. */ - volatile s32 tx_buf_size1; /* Length of Tx frame. */ -}; - -#define TxCB_CMD_TRANSMIT 0x0004 /* transmit command */ -#define TxCB_CMD_SF 0x0008 /* 0=simplified, 1=flexible mode */ -#define TxCB_CMD_NC 0x0010 /* 0=CRC insert by controller */ -#define TxCB_CMD_I 0x2000 /* generate interrupt on completion */ -#define TxCB_CMD_S 0x4000 /* suspend on completion */ -#define TxCB_CMD_EL 0x8000 /* last command block in CBL */ - -#define TxCB_COUNT_MASK 0x3fff -#define TxCB_COUNT_EOF 0x8000 - - /* The Speedo3 Rx and Tx frame/buffer descriptors. - */ -struct descriptor { /* A generic descriptor. */ - volatile u16 status; - volatile u16 command; - volatile u32 link; /* struct descriptor * */ - - unsigned char params[0]; -}; - -#define CONFIG_SYS_CMD_EL 0x8000 -#define CONFIG_SYS_CMD_SUSPEND 0x4000 -#define CONFIG_SYS_CMD_INT 0x2000 -#define CONFIG_SYS_CMD_IAS 0x0001 /* individual address setup */ -#define CONFIG_SYS_CMD_CONFIGURE 0x0002 /* configure */ - -#define CONFIG_SYS_STATUS_C 0x8000 -#define CONFIG_SYS_STATUS_OK 0x2000 - - /* Misc. - */ -#define NUM_RX_DESC PKTBUFSRX -#define NUM_TX_DESC 1 /* Number of TX descriptors */ - -#define TOUT_LOOP 1000000 - -#define ETH_ALEN 6 - -static struct RxFD rx_ring[NUM_RX_DESC]; /* RX descriptor ring */ -static struct TxFD tx_ring[NUM_TX_DESC]; /* TX descriptor ring */ -static int rx_next; /* RX descriptor ring pointer */ -static int tx_next; /* TX descriptor ring pointer */ -static int tx_threshold; - -/* - * The parameters for a CmdConfigure operation. - * There are so many options that it would be difficult to document - * each bit. We mostly use the default or recommended settings. - */ -static const char i82557_config_cmd[] = { - 22, 0x08, 0, 0, 0, 0, 0x32, 0x03, 1, /* 1=Use MII 0=Use AUI */ - 0, 0x2E, 0, 0x60, 0, - 0xf2, 0x48, 0, 0x40, 0xf2, 0x80, /* 0x40=Force full-duplex */ - 0x3f, 0x05, -}; -static const char i82558_config_cmd[] = { - 22, 0x08, 0, 1, 0, 0, 0x22, 0x03, 1, /* 1=Use MII 0=Use AUI */ - 0, 0x2E, 0, 0x60, 0x08, 0x88, - 0x68, 0, 0x40, 0xf2, 0x84, /* Disable FC */ - 0x31, 0x05, -}; - -static void init_rx_ring (struct eth_device *dev); -static void purge_tx_ring (struct eth_device *dev); - -static void read_hw_addr (struct eth_device *dev, bd_t * bis); - -static int eepro100_init (struct eth_device *dev, bd_t * bis); -static int eepro100_send(struct eth_device *dev, void *packet, int length); -static int eepro100_recv (struct eth_device *dev); -static void eepro100_halt (struct eth_device *dev); - -#if defined(CONFIG_E500) || defined(CONFIG_DB64360) || defined(CONFIG_DB64460) -#define bus_to_phys(a) (a) -#define phys_to_bus(a) (a) -#else -#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a) -#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) -#endif - -static inline int INW (struct eth_device *dev, u_long addr) -{ - return le16_to_cpu (*(volatile u16 *) (addr + dev->iobase)); -} - -static inline void OUTW (struct eth_device *dev, int command, u_long addr) -{ - *(volatile u16 *) ((addr + dev->iobase)) = cpu_to_le16 (command); -} - -static inline void OUTL (struct eth_device *dev, int command, u_long addr) -{ - *(volatile u32 *) ((addr + dev->iobase)) = cpu_to_le32 (command); -} - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) -static inline int INL (struct eth_device *dev, u_long addr) -{ - return le32_to_cpu (*(volatile u32 *) (addr + dev->iobase)); -} - -static int get_phyreg (struct eth_device *dev, unsigned char addr, - unsigned char reg, unsigned short *value) -{ - int cmd; - int timeout = 50; - - /* read requested data */ - cmd = (2 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16); - OUTL (dev, cmd, SCBCtrlMDI); - - do { - udelay(1000); - cmd = INL (dev, SCBCtrlMDI); - } while (!(cmd & (1 << 28)) && (--timeout)); - - if (timeout == 0) - return -1; - - *value = (unsigned short) (cmd & 0xffff); - - return 0; -} - -static int set_phyreg (struct eth_device *dev, unsigned char addr, - unsigned char reg, unsigned short value) -{ - int cmd; - int timeout = 50; - - /* write requested data */ - cmd = (1 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16); - OUTL (dev, cmd | value, SCBCtrlMDI); - - while (!(INL (dev, SCBCtrlMDI) & (1 << 28)) && (--timeout)) - udelay(1000); - - if (timeout == 0) - return -1; - - return 0; -} - -/* Check if given phyaddr is valid, i.e. there is a PHY connected. - * Do this by checking model value field from ID2 register. - */ -static struct eth_device* verify_phyaddr (const char *devname, - unsigned char addr) -{ - struct eth_device *dev; - unsigned short value; - unsigned char model; - - dev = eth_get_dev_by_name(devname); - if (dev == NULL) { - printf("%s: no such device\n", devname); - return NULL; - } - - /* read id2 register */ - if (get_phyreg(dev, addr, MII_PHYSID2, &value) != 0) { - printf("%s: mii read timeout!\n", devname); - return NULL; - } - - /* get model */ - model = (unsigned char)((value >> 4) & 0x003f); - - if (model == 0) { - printf("%s: no PHY at address %d\n", devname, addr); - return NULL; - } - - return dev; -} - -static int eepro100_miiphy_read(const char *devname, unsigned char addr, - unsigned char reg, unsigned short *value) -{ - struct eth_device *dev; - - dev = verify_phyaddr(devname, addr); - if (dev == NULL) - return -1; - - if (get_phyreg(dev, addr, reg, value) != 0) { - printf("%s: mii read timeout!\n", devname); - return -1; - } - - return 0; -} - -static int eepro100_miiphy_write(const char *devname, unsigned char addr, - unsigned char reg, unsigned short value) -{ - struct eth_device *dev; - - dev = verify_phyaddr(devname, addr); - if (dev == NULL) - return -1; - - if (set_phyreg(dev, addr, reg, value) != 0) { - printf("%s: mii write timeout!\n", devname); - return -1; - } - - return 0; -} - -#endif - -/* Wait for the chip get the command. -*/ -static int wait_for_eepro100 (struct eth_device *dev) -{ - int i; - - for (i = 0; INW (dev, SCBCmd) & (CU_CMD_MASK | RU_CMD_MASK); i++) { - if (i >= TOUT_LOOP) { - return 0; - } - } - - return 1; -} - -static struct pci_device_id supported[] = { - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER}, - {} -}; - -int eepro100_initialize (bd_t * bis) -{ - pci_dev_t devno; - int card_number = 0; - struct eth_device *dev; - u32 iobase, status; - int idx = 0; - - while (1) { - /* Find PCI device - */ - if ((devno = pci_find_devices (supported, idx++)) < 0) { - break; - } - - pci_read_config_dword (devno, PCI_BASE_ADDRESS_0, &iobase); - iobase &= ~0xf; - -#ifdef DEBUG - printf ("eepro100: Intel i82559 PCI EtherExpressPro @0x%x\n", - iobase); -#endif - - pci_write_config_dword (devno, - PCI_COMMAND, - PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - - /* Check if I/O accesses and Bus Mastering are enabled. - */ - pci_read_config_dword (devno, PCI_COMMAND, &status); - if (!(status & PCI_COMMAND_MEMORY)) { - printf ("Error: Can not enable MEM access.\n"); - continue; - } - - if (!(status & PCI_COMMAND_MASTER)) { - printf ("Error: Can not enable Bus Mastering.\n"); - continue; - } - - dev = (struct eth_device *) malloc (sizeof *dev); - if (!dev) { - printf("eepro100: Can not allocate memory\n"); - break; - } - memset(dev, 0, sizeof(*dev)); - - sprintf (dev->name, "i82559#%d", card_number); - dev->priv = (void *) devno; /* this have to come before bus_to_phys() */ - dev->iobase = bus_to_phys (iobase); - dev->init = eepro100_init; - dev->halt = eepro100_halt; - dev->send = eepro100_send; - dev->recv = eepro100_recv; - - eth_register (dev); - -#if defined (CONFIG_MII) || defined(CONFIG_CMD_MII) - /* register mii command access routines */ - miiphy_register(dev->name, - eepro100_miiphy_read, eepro100_miiphy_write); -#endif - - card_number++; - - /* Set the latency timer for value. - */ - pci_write_config_byte (devno, PCI_LATENCY_TIMER, 0x20); - - udelay (10 * 1000); - - read_hw_addr (dev, bis); - } - - return card_number; -} - - -static int eepro100_init (struct eth_device *dev, bd_t * bis) -{ - int i, status = -1; - int tx_cur; - struct descriptor *ias_cmd, *cfg_cmd; - - /* Reset the ethernet controller - */ - OUTL (dev, I82559_SELECTIVE_RESET, SCBPort); - udelay (20); - - OUTL (dev, I82559_RESET, SCBPort); - udelay (20); - - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); - goto Done; - } - OUTL (dev, 0, SCBPointer); - OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd); - - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); - goto Done; - } - OUTL (dev, 0, SCBPointer); - OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd); - - /* Initialize Rx and Tx rings. - */ - init_rx_ring (dev); - purge_tx_ring (dev); - - /* Tell the adapter where the RX ring is located. - */ - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); - goto Done; - } - - OUTL (dev, phys_to_bus ((u32) & rx_ring[rx_next]), SCBPointer); - OUTW (dev, SCB_M | RUC_START, SCBCmd); - - /* Send the Configure frame */ - tx_cur = tx_next; - tx_next = ((tx_next + 1) % NUM_TX_DESC); - - cfg_cmd = (struct descriptor *) &tx_ring[tx_cur]; - cfg_cmd->command = cpu_to_le16 ((CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_CONFIGURE)); - cfg_cmd->status = 0; - cfg_cmd->link = cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next])); - - memcpy (cfg_cmd->params, i82558_config_cmd, - sizeof (i82558_config_cmd)); - - if (!wait_for_eepro100 (dev)) { - printf ("Error---CONFIG_SYS_CMD_CONFIGURE: Can not reset ethernet controller.\n"); - goto Done; - } - - OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer); - OUTW (dev, SCB_M | CU_START, SCBCmd); - - for (i = 0; - !(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); - i++) { - if (i >= TOUT_LOOP) { - printf ("%s: Tx error buffer not ready\n", dev->name); - goto Done; - } - } - - if (!(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { - printf ("TX error status = 0x%08X\n", - le16_to_cpu (tx_ring[tx_cur].status)); - goto Done; - } - - /* Send the Individual Address Setup frame - */ - tx_cur = tx_next; - tx_next = ((tx_next + 1) % NUM_TX_DESC); - - ias_cmd = (struct descriptor *) &tx_ring[tx_cur]; - ias_cmd->command = cpu_to_le16 ((CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_IAS)); - ias_cmd->status = 0; - ias_cmd->link = cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next])); - - memcpy (ias_cmd->params, dev->enetaddr, 6); - - /* Tell the adapter where the TX ring is located. - */ - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); - goto Done; - } - - OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer); - OUTW (dev, SCB_M | CU_START, SCBCmd); - - for (i = 0; !(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); - i++) { - if (i >= TOUT_LOOP) { - printf ("%s: Tx error buffer not ready\n", - dev->name); - goto Done; - } - } - - if (!(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { - printf ("TX error status = 0x%08X\n", - le16_to_cpu (tx_ring[tx_cur].status)); - goto Done; - } - - status = 0; - - Done: - return status; -} - -static int eepro100_send(struct eth_device *dev, void *packet, int length) -{ - int i, status = -1; - int tx_cur; - - if (length <= 0) { - printf ("%s: bad packet size: %d\n", dev->name, length); - goto Done; - } - - tx_cur = tx_next; - tx_next = (tx_next + 1) % NUM_TX_DESC; - - tx_ring[tx_cur].command = cpu_to_le16 ( TxCB_CMD_TRANSMIT | - TxCB_CMD_SF | - TxCB_CMD_S | - TxCB_CMD_EL ); - tx_ring[tx_cur].status = 0; - tx_ring[tx_cur].count = cpu_to_le32 (tx_threshold); - tx_ring[tx_cur].link = - cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next])); - tx_ring[tx_cur].tx_desc_addr = - cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_cur].tx_buf_addr0)); - tx_ring[tx_cur].tx_buf_addr0 = - cpu_to_le32 (phys_to_bus ((u_long) packet)); - tx_ring[tx_cur].tx_buf_size0 = cpu_to_le32 (length); - - if (!wait_for_eepro100 (dev)) { - printf ("%s: Tx error ethernet controller not ready.\n", - dev->name); - goto Done; - } - - /* Send the packet. - */ - OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer); - OUTW (dev, SCB_M | CU_START, SCBCmd); - - for (i = 0; !(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); - i++) { - if (i >= TOUT_LOOP) { - printf ("%s: Tx error buffer not ready\n", dev->name); - goto Done; - } - } - - if (!(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { - printf ("TX error status = 0x%08X\n", - le16_to_cpu (tx_ring[tx_cur].status)); - goto Done; - } - - status = length; - - Done: - return status; -} - -static int eepro100_recv (struct eth_device *dev) -{ - u16 status, stat; - int rx_prev, length = 0; - - stat = INW (dev, SCBStatus); - OUTW (dev, stat & SCB_STATUS_RNR, SCBStatus); - - for (;;) { - status = le16_to_cpu (rx_ring[rx_next].status); - - if (!(status & RFD_STATUS_C)) { - break; - } - - /* Valid frame status. - */ - if ((status & RFD_STATUS_OK)) { - /* A valid frame received. - */ - length = le32_to_cpu (rx_ring[rx_next].count) & 0x3fff; - - /* Pass the packet up to the protocol - * layers. - */ - NetReceive((u8 *)rx_ring[rx_next].data, length); - } else { - /* There was an error. - */ - printf ("RX error status = 0x%08X\n", status); - } - - rx_ring[rx_next].control = cpu_to_le16 (RFD_CONTROL_S); - rx_ring[rx_next].status = 0; - rx_ring[rx_next].count = cpu_to_le32 (PKTSIZE_ALIGN << 16); - - rx_prev = (rx_next + NUM_RX_DESC - 1) % NUM_RX_DESC; - rx_ring[rx_prev].control = 0; - - /* Update entry information. - */ - rx_next = (rx_next + 1) % NUM_RX_DESC; - } - - if (stat & SCB_STATUS_RNR) { - - printf ("%s: Receiver is not ready, restart it !\n", dev->name); - - /* Reinitialize Rx ring. - */ - init_rx_ring (dev); - - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not restart ethernet controller.\n"); - goto Done; - } - - OUTL (dev, phys_to_bus ((u32) & rx_ring[rx_next]), SCBPointer); - OUTW (dev, SCB_M | RUC_START, SCBCmd); - } - - Done: - return length; -} - -static void eepro100_halt (struct eth_device *dev) -{ - /* Reset the ethernet controller - */ - OUTL (dev, I82559_SELECTIVE_RESET, SCBPort); - udelay (20); - - OUTL (dev, I82559_RESET, SCBPort); - udelay (20); - - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); - goto Done; - } - OUTL (dev, 0, SCBPointer); - OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd); - - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); - goto Done; - } - OUTL (dev, 0, SCBPointer); - OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd); - - Done: - return; -} - - /* SROM Read. - */ -static int read_eeprom (struct eth_device *dev, int location, int addr_len) -{ - unsigned short retval = 0; - int read_cmd = location | EE_READ_CMD; - int i; - - OUTW (dev, EE_ENB & ~EE_CS, SCBeeprom); - OUTW (dev, EE_ENB, SCBeeprom); - - /* Shift the read command bits out. */ - for (i = 12; i >= 0; i--) { - short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - - OUTW (dev, EE_ENB | dataval, SCBeeprom); - udelay (1); - OUTW (dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom); - udelay (1); - } - OUTW (dev, EE_ENB, SCBeeprom); - - for (i = 15; i >= 0; i--) { - OUTW (dev, EE_ENB | EE_SHIFT_CLK, SCBeeprom); - udelay (1); - retval = (retval << 1) | - ((INW (dev, SCBeeprom) & EE_DATA_READ) ? 1 : 0); - OUTW (dev, EE_ENB, SCBeeprom); - udelay (1); - } - - /* Terminate the EEPROM access. */ - OUTW (dev, EE_ENB & ~EE_CS, SCBeeprom); - return retval; -} - -#ifdef CONFIG_EEPRO100_SROM_WRITE -int eepro100_write_eeprom (struct eth_device* dev, int location, int addr_len, unsigned short data) -{ - unsigned short dataval; - int enable_cmd = 0x3f | EE_EWENB_CMD; - int write_cmd = location | EE_WRITE_CMD; - int i; - unsigned long datalong, tmplong; - - OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB, SCBeeprom); - - /* Shift the enable command bits out. */ - for (i = (addr_len+EE_CMD_BITS-1); i >= 0; i--) - { - dataval = (enable_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - OUTW(dev, EE_ENB | dataval, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom); - udelay(1); - } - - OUTW(dev, EE_ENB, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB, SCBeeprom); - - - /* Shift the write command bits out. */ - for (i = (addr_len+EE_CMD_BITS-1); i >= 0; i--) - { - dataval = (write_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - OUTW(dev, EE_ENB | dataval, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom); - udelay(1); - } - - /* Write the data */ - datalong= (unsigned long) ((((data) & 0x00ff) << 8) | ( (data) >> 8)); - - for (i = 0; i< EE_DATA_BITS; i++) - { - /* Extract and move data bit to bit DI */ - dataval = ((datalong & 0x8000)>>13) ? EE_DATA_WRITE : 0; - - OUTW(dev, EE_ENB | dataval, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB | dataval, SCBeeprom); - udelay(1); - - datalong = datalong << 1; /* Adjust significant data bit*/ - } - - /* Finish up command (toggle CS) */ - OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); - udelay(1); /* delay for more than 250 ns */ - OUTW(dev, EE_ENB, SCBeeprom); - - /* Wait for programming ready (D0 = 1) */ - tmplong = 10; - do - { - dataval = INW(dev, SCBeeprom); - if (dataval & EE_DATA_READ) - break; - udelay(10000); - } - while (-- tmplong); - - if (tmplong == 0) - { - printf ("Write i82559 eeprom timed out (100 ms waiting for data ready.\n"); - return -1; - } - - /* Terminate the EEPROM access. */ - OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); - - return 0; -} -#endif - -static void init_rx_ring (struct eth_device *dev) -{ - int i; - - for (i = 0; i < NUM_RX_DESC; i++) { - rx_ring[i].status = 0; - rx_ring[i].control = - (i == NUM_RX_DESC - 1) ? cpu_to_le16 (RFD_CONTROL_S) : 0; - rx_ring[i].link = - cpu_to_le32 (phys_to_bus - ((u32) & rx_ring[(i + 1) % NUM_RX_DESC])); - rx_ring[i].rx_buf_addr = 0xffffffff; - rx_ring[i].count = cpu_to_le32 (PKTSIZE_ALIGN << 16); - } - - rx_next = 0; -} - -static void purge_tx_ring (struct eth_device *dev) -{ - int i; - - tx_next = 0; - tx_threshold = 0x01208000; - - for (i = 0; i < NUM_TX_DESC; i++) { - tx_ring[i].status = 0; - tx_ring[i].command = 0; - tx_ring[i].link = 0; - tx_ring[i].tx_desc_addr = 0; - tx_ring[i].count = 0; - - tx_ring[i].tx_buf_addr0 = 0; - tx_ring[i].tx_buf_size0 = 0; - tx_ring[i].tx_buf_addr1 = 0; - tx_ring[i].tx_buf_size1 = 0; - } -} - -static void read_hw_addr (struct eth_device *dev, bd_t * bis) -{ - u16 sum = 0; - int i, j; - int addr_len = read_eeprom (dev, 0, 6) == 0xffff ? 8 : 6; - - for (j = 0, i = 0; i < 0x40; i++) { - u16 value = read_eeprom (dev, i, addr_len); - - sum += value; - if (i < 3) { - dev->enetaddr[j++] = value; - dev->enetaddr[j++] = value >> 8; - } - } - - if (sum != 0xBABA) { - memset (dev->enetaddr, 0, ETH_ALEN); -#ifdef DEBUG - printf ("%s: Invalid EEPROM checksum %#4.4x, " - "check settings before activating this device!\n", - dev->name, sum); -#endif - } -} diff --git a/qemu/roms/u-boot/drivers/net/enc28j60.c b/qemu/roms/u-boot/drivers/net/enc28j60.c deleted file mode 100644 index ec33764f5..000000000 --- a/qemu/roms/u-boot/drivers/net/enc28j60.c +++ /dev/null @@ -1,963 +0,0 @@ -/* - * (C) Copyright 2010 - * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de - * Martin Krause, Martin.Krause@tqs.de - * reworked original enc28j60.c - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <net.h> -#include <spi.h> -#include <malloc.h> -#include <netdev.h> -#include <miiphy.h> -#include "enc28j60.h" - -/* - * IMPORTANT: spi_claim_bus() and spi_release_bus() - * are called at begin and end of each of the following functions: - * enc_miiphy_read(), enc_miiphy_write(), enc_write_hwaddr(), - * enc_init(), enc_recv(), enc_send(), enc_halt() - * ALL other functions assume that the bus has already been claimed! - * Since NetReceive() might call enc_send() in return, the bus must be - * released, NetReceive() called and claimed again. - */ - -/* - * Controller memory layout. - * We only allow 1 frame for transmission and reserve the rest - * for reception to handle as many broadcast packets as possible. - * Also use the memory from 0x0000 for receiver buffer. See errata pt. 5 - * 0x0000 - 0x19ff 6656 bytes receive buffer - * 0x1a00 - 0x1fff 1536 bytes transmit buffer = - * control(1)+frame(1518)+status(7)+reserve(10). - */ -#define ENC_RX_BUF_START 0x0000 -#define ENC_RX_BUF_END 0x19ff -#define ENC_TX_BUF_START 0x1a00 -#define ENC_TX_BUF_END 0x1fff -#define ENC_MAX_FRM_LEN 1518 -#define RX_RESET_COUNTER 1000 - -/* - * For non data transfer functions, like phy read/write, set hwaddr, init - * we do not need a full, time consuming init including link ready wait. - * This enum helps to bring the chip through the minimum necessary inits. - */ -enum enc_initstate {none=0, setupdone, linkready}; -typedef struct enc_device { - struct eth_device *dev; /* back pointer */ - struct spi_slave *slave; - int rx_reset_counter; - u16 next_pointer; - u8 bank; /* current bank in enc28j60 */ - enum enc_initstate initstate; -} enc_dev_t; - -/* - * enc_bset: set bits in a common register - * enc_bclr: clear bits in a common register - * - * making the reg parameter u8 will give a compile time warning if the - * functions are called with a register not accessible in all Banks - */ -static void enc_bset(enc_dev_t *enc, const u8 reg, const u8 data) -{ - u8 dout[2]; - - dout[0] = CMD_BFS(reg); - dout[1] = data; - spi_xfer(enc->slave, 2 * 8, dout, NULL, - SPI_XFER_BEGIN | SPI_XFER_END); -} - -static void enc_bclr(enc_dev_t *enc, const u8 reg, const u8 data) -{ - u8 dout[2]; - - dout[0] = CMD_BFC(reg); - dout[1] = data; - spi_xfer(enc->slave, 2 * 8, dout, NULL, - SPI_XFER_BEGIN | SPI_XFER_END); -} - -/* - * high byte of the register contains bank number: - * 0: no bank switch necessary - * 1: switch to bank 0 - * 2: switch to bank 1 - * 3: switch to bank 2 - * 4: switch to bank 3 - */ -static void enc_set_bank(enc_dev_t *enc, const u16 reg) -{ - u8 newbank = reg >> 8; - - if (newbank == 0 || newbank == enc->bank) - return; - switch (newbank) { - case 1: - enc_bclr(enc, CTL_REG_ECON1, - ENC_ECON1_BSEL0 | ENC_ECON1_BSEL1); - break; - case 2: - enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_BSEL0); - enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_BSEL1); - break; - case 3: - enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_BSEL0); - enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_BSEL1); - break; - case 4: - enc_bset(enc, CTL_REG_ECON1, - ENC_ECON1_BSEL0 | ENC_ECON1_BSEL1); - break; - } - enc->bank = newbank; -} - -/* - * local functions to access SPI - * - * reg: register inside ENC28J60 - * data: 8/16 bits to write - * c: number of retries - * - * enc_r8: read 8 bits - * enc_r16: read 16 bits - * enc_w8: write 8 bits - * enc_w16: write 16 bits - * enc_w8_retry: write 8 bits, verify and retry - * enc_rbuf: read from ENC28J60 into buffer - * enc_wbuf: write from buffer into ENC28J60 - */ - -/* - * MAC and MII registers need a 3 byte SPI transfer to read, - * all other registers need a 2 byte SPI transfer. - */ -static int enc_reg2nbytes(const u16 reg) -{ - /* check if MAC or MII register */ - return ((reg >= CTL_REG_MACON1 && reg <= CTL_REG_MIRDH) || - (reg >= CTL_REG_MAADR1 && reg <= CTL_REG_MAADR4) || - (reg == CTL_REG_MISTAT)) ? 3 : 2; -} - -/* - * Read a byte register - */ -static u8 enc_r8(enc_dev_t *enc, const u16 reg) -{ - u8 dout[3]; - u8 din[3]; - int nbytes = enc_reg2nbytes(reg); - - enc_set_bank(enc, reg); - dout[0] = CMD_RCR(reg); - spi_xfer(enc->slave, nbytes * 8, dout, din, - SPI_XFER_BEGIN | SPI_XFER_END); - return din[nbytes-1]; -} - -/* - * Read a L/H register pair and return a word. - * Must be called with the L register's address. - */ -static u16 enc_r16(enc_dev_t *enc, const u16 reg) -{ - u8 dout[3]; - u8 din[3]; - u16 result; - int nbytes = enc_reg2nbytes(reg); - - enc_set_bank(enc, reg); - dout[0] = CMD_RCR(reg); - spi_xfer(enc->slave, nbytes * 8, dout, din, - SPI_XFER_BEGIN | SPI_XFER_END); - result = din[nbytes-1]; - dout[0]++; /* next register */ - spi_xfer(enc->slave, nbytes * 8, dout, din, - SPI_XFER_BEGIN | SPI_XFER_END); - result |= din[nbytes-1] << 8; - return result; -} - -/* - * Write a byte register - */ -static void enc_w8(enc_dev_t *enc, const u16 reg, const u8 data) -{ - u8 dout[2]; - - enc_set_bank(enc, reg); - dout[0] = CMD_WCR(reg); - dout[1] = data; - spi_xfer(enc->slave, 2 * 8, dout, NULL, - SPI_XFER_BEGIN | SPI_XFER_END); -} - -/* - * Write a L/H register pair. - * Must be called with the L register's address. - */ -static void enc_w16(enc_dev_t *enc, const u16 reg, const u16 data) -{ - u8 dout[2]; - - enc_set_bank(enc, reg); - dout[0] = CMD_WCR(reg); - dout[1] = data; - spi_xfer(enc->slave, 2 * 8, dout, NULL, - SPI_XFER_BEGIN | SPI_XFER_END); - dout[0]++; /* next register */ - dout[1] = data >> 8; - spi_xfer(enc->slave, 2 * 8, dout, NULL, - SPI_XFER_BEGIN | SPI_XFER_END); -} - -/* - * Write a byte register, verify and retry - */ -static void enc_w8_retry(enc_dev_t *enc, const u16 reg, const u8 data, const int c) -{ - u8 dout[2]; - u8 readback; - int i; - - enc_set_bank(enc, reg); - for (i = 0; i < c; i++) { - dout[0] = CMD_WCR(reg); - dout[1] = data; - spi_xfer(enc->slave, 2 * 8, dout, NULL, - SPI_XFER_BEGIN | SPI_XFER_END); - readback = enc_r8(enc, reg); - if (readback == data) - break; - /* wait 1ms */ - udelay(1000); - } - if (i == c) { - printf("%s: write reg 0x%03x failed\n", enc->dev->name, reg); - } -} - -/* - * Read ENC RAM into buffer - */ -static void enc_rbuf(enc_dev_t *enc, const u16 length, u8 *buf) -{ - u8 dout[1]; - - dout[0] = CMD_RBM; - spi_xfer(enc->slave, 8, dout, NULL, SPI_XFER_BEGIN); - spi_xfer(enc->slave, length * 8, NULL, buf, SPI_XFER_END); -#ifdef DEBUG - puts("Rx:\n"); - print_buffer(0, buf, 1, length, 0); -#endif -} - -/* - * Write buffer into ENC RAM - */ -static void enc_wbuf(enc_dev_t *enc, const u16 length, const u8 *buf, const u8 control) -{ - u8 dout[2]; - dout[0] = CMD_WBM; - dout[1] = control; - spi_xfer(enc->slave, 2 * 8, dout, NULL, SPI_XFER_BEGIN); - spi_xfer(enc->slave, length * 8, buf, NULL, SPI_XFER_END); -#ifdef DEBUG - puts("Tx:\n"); - print_buffer(0, buf, 1, length, 0); -#endif -} - -/* - * Try to claim the SPI bus. - * Print error message on failure. - */ -static int enc_claim_bus(enc_dev_t *enc) -{ - int rc = spi_claim_bus(enc->slave); - if (rc) - printf("%s: failed to claim SPI bus\n", enc->dev->name); - return rc; -} - -/* - * Release previously claimed SPI bus. - * This function is mainly for symmetry to enc_claim_bus(). - * Let the toolchain decide to inline it... - */ -static void enc_release_bus(enc_dev_t *enc) -{ - spi_release_bus(enc->slave); -} - -/* - * Read PHY register - */ -static u16 enc_phy_read(enc_dev_t *enc, const u8 addr) -{ - uint64_t etime; - u8 status; - - enc_w8(enc, CTL_REG_MIREGADR, addr); - enc_w8(enc, CTL_REG_MICMD, ENC_MICMD_MIIRD); - /* 1 second timeout - only happens on hardware problem */ - etime = get_ticks() + get_tbclk(); - /* poll MISTAT.BUSY bit until operation is complete */ - do - { - status = enc_r8(enc, CTL_REG_MISTAT); - } while (get_ticks() <= etime && (status & ENC_MISTAT_BUSY)); - if (status & ENC_MISTAT_BUSY) { - printf("%s: timeout reading phy\n", enc->dev->name); - return 0; - } - enc_w8(enc, CTL_REG_MICMD, 0); - return enc_r16(enc, CTL_REG_MIRDL); -} - -/* - * Write PHY register - */ -static void enc_phy_write(enc_dev_t *enc, const u8 addr, const u16 data) -{ - uint64_t etime; - u8 status; - - enc_w8(enc, CTL_REG_MIREGADR, addr); - enc_w16(enc, CTL_REG_MIWRL, data); - /* 1 second timeout - only happens on hardware problem */ - etime = get_ticks() + get_tbclk(); - /* poll MISTAT.BUSY bit until operation is complete */ - do - { - status = enc_r8(enc, CTL_REG_MISTAT); - } while (get_ticks() <= etime && (status & ENC_MISTAT_BUSY)); - if (status & ENC_MISTAT_BUSY) { - printf("%s: timeout writing phy\n", enc->dev->name); - return; - } -} - -/* - * Verify link status, wait if necessary - * - * Note: with a 10 MBit/s only PHY there is no autonegotiation possible, - * half/full duplex is a pure setup matter. For the time being, this driver - * will setup in half duplex mode only. - */ -static int enc_phy_link_wait(enc_dev_t *enc) -{ - u16 status; - int duplex; - uint64_t etime; - -#ifdef CONFIG_ENC_SILENTLINK - /* check if we have a link, then just return */ - status = enc_phy_read(enc, PHY_REG_PHSTAT1); - if (status & ENC_PHSTAT1_LLSTAT) - return 0; -#endif - - /* wait for link with 1 second timeout */ - etime = get_ticks() + get_tbclk(); - while (get_ticks() <= etime) { - status = enc_phy_read(enc, PHY_REG_PHSTAT1); - if (status & ENC_PHSTAT1_LLSTAT) { - /* now we have a link */ - status = enc_phy_read(enc, PHY_REG_PHSTAT2); - duplex = (status & ENC_PHSTAT2_DPXSTAT) ? 1 : 0; - printf("%s: link up, 10Mbps %s-duplex\n", - enc->dev->name, duplex ? "full" : "half"); - return 0; - } - udelay(1000); - } - - /* timeout occured */ - printf("%s: link down\n", enc->dev->name); - return 1; -} - -/* - * This function resets the receiver only. - */ -static void enc_reset_rx(enc_dev_t *enc) -{ - u8 econ1; - - econ1 = enc_r8(enc, CTL_REG_ECON1); - if ((econ1 & ENC_ECON1_RXRST) == 0) { - enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_RXRST); - enc->rx_reset_counter = RX_RESET_COUNTER; - } -} - -/* - * Reset receiver and reenable it. - */ -static void enc_reset_rx_call(enc_dev_t *enc) -{ - enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_RXRST); - enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_RXEN); -} - -/* - * Copy a packet from the receive ring and forward it to - * the protocol stack. - */ -static void enc_receive(enc_dev_t *enc) -{ - u8 *packet = (u8 *)NetRxPackets[0]; - u16 pkt_len; - u16 copy_len; - u16 status; - u8 pkt_cnt = 0; - u16 rxbuf_rdpt; - u8 hbuf[6]; - - enc_w16(enc, CTL_REG_ERDPTL, enc->next_pointer); - do { - enc_rbuf(enc, 6, hbuf); - enc->next_pointer = hbuf[0] | (hbuf[1] << 8); - pkt_len = hbuf[2] | (hbuf[3] << 8); - status = hbuf[4] | (hbuf[5] << 8); - debug("next_pointer=$%04x pkt_len=%u status=$%04x\n", - enc->next_pointer, pkt_len, status); - if (pkt_len <= ENC_MAX_FRM_LEN) - copy_len = pkt_len; - else - copy_len = 0; - if ((status & (1L << 7)) == 0) /* check Received Ok bit */ - copy_len = 0; - /* check if next pointer is resonable */ - if (enc->next_pointer >= ENC_TX_BUF_START) - copy_len = 0; - if (copy_len > 0) { - enc_rbuf(enc, copy_len, packet); - } - /* advance read pointer to next pointer */ - enc_w16(enc, CTL_REG_ERDPTL, enc->next_pointer); - /* decrease packet counter */ - enc_bset(enc, CTL_REG_ECON2, ENC_ECON2_PKTDEC); - /* - * Only odd values should be written to ERXRDPTL, - * see errata B4 pt.13 - */ - rxbuf_rdpt = enc->next_pointer - 1; - if ((rxbuf_rdpt < enc_r16(enc, CTL_REG_ERXSTL)) || - (rxbuf_rdpt > enc_r16(enc, CTL_REG_ERXNDL))) { - enc_w16(enc, CTL_REG_ERXRDPTL, - enc_r16(enc, CTL_REG_ERXNDL)); - } else { - enc_w16(enc, CTL_REG_ERXRDPTL, rxbuf_rdpt); - } - /* read pktcnt */ - pkt_cnt = enc_r8(enc, CTL_REG_EPKTCNT); - if (copy_len == 0) { - (void)enc_r8(enc, CTL_REG_EIR); - enc_reset_rx(enc); - printf("%s: receive copy_len=0\n", enc->dev->name); - continue; - } - /* - * Because NetReceive() might call enc_send(), we need to - * release the SPI bus, call NetReceive(), reclaim the bus - */ - enc_release_bus(enc); - NetReceive(packet, pkt_len); - if (enc_claim_bus(enc)) - return; - (void)enc_r8(enc, CTL_REG_EIR); - } while (pkt_cnt); - /* Use EPKTCNT not EIR.PKTIF flag, see errata pt. 6 */ -} - -/* - * Poll for completely received packets. - */ -static void enc_poll(enc_dev_t *enc) -{ - u8 eir_reg; - u8 pkt_cnt; - -#ifdef CONFIG_USE_IRQ - /* clear global interrupt enable bit in enc28j60 */ - enc_bclr(enc, CTL_REG_EIE, ENC_EIE_INTIE); -#endif - (void)enc_r8(enc, CTL_REG_ESTAT); - eir_reg = enc_r8(enc, CTL_REG_EIR); - if (eir_reg & ENC_EIR_TXIF) { - /* clear TXIF bit in EIR */ - enc_bclr(enc, CTL_REG_EIR, ENC_EIR_TXIF); - } - /* We have to use pktcnt and not pktif bit, see errata pt. 6 */ - pkt_cnt = enc_r8(enc, CTL_REG_EPKTCNT); - if (pkt_cnt > 0) { - if ((eir_reg & ENC_EIR_PKTIF) == 0) { - debug("enc_poll: pkt cnt > 0, but pktif not set\n"); - } - enc_receive(enc); - /* - * clear PKTIF bit in EIR, this should not need to be done - * but it seems like we get problems if we do not - */ - enc_bclr(enc, CTL_REG_EIR, ENC_EIR_PKTIF); - } - if (eir_reg & ENC_EIR_RXERIF) { - printf("%s: rx error\n", enc->dev->name); - enc_bclr(enc, CTL_REG_EIR, ENC_EIR_RXERIF); - } - if (eir_reg & ENC_EIR_TXERIF) { - printf("%s: tx error\n", enc->dev->name); - enc_bclr(enc, CTL_REG_EIR, ENC_EIR_TXERIF); - } -#ifdef CONFIG_USE_IRQ - /* set global interrupt enable bit in enc28j60 */ - enc_bset(enc, CTL_REG_EIE, ENC_EIE_INTIE); -#endif -} - -/* - * Completely Reset the ENC - */ -static void enc_reset(enc_dev_t *enc) -{ - u8 dout[1]; - - dout[0] = CMD_SRC; - spi_xfer(enc->slave, 8, dout, NULL, - SPI_XFER_BEGIN | SPI_XFER_END); - /* sleep 1 ms. See errata pt. 2 */ - udelay(1000); -} - -/* - * Initialisation data for most of the ENC registers - */ -static const u16 enc_initdata[] = { - /* - * Setup the buffer space. The reset values are valid for the - * other pointers. - * - * We shall not write to ERXST, see errata pt. 5. Instead we - * have to make sure that ENC_RX_BUS_START is 0. - */ - CTL_REG_ERXSTL, ENC_RX_BUF_START, - CTL_REG_ERXSTH, ENC_RX_BUF_START >> 8, - CTL_REG_ERXNDL, ENC_RX_BUF_END, - CTL_REG_ERXNDH, ENC_RX_BUF_END >> 8, - CTL_REG_ERDPTL, ENC_RX_BUF_START, - CTL_REG_ERDPTH, ENC_RX_BUF_START >> 8, - /* - * Set the filter to receive only good-CRC, unicast and broadcast - * frames. - * Note: some DHCP servers return their answers as broadcasts! - * So its unwise to remove broadcast from this. This driver - * might incur receiver overruns with packet loss on a broadcast - * flooded network. - */ - CTL_REG_ERXFCON, ENC_RFR_BCEN | ENC_RFR_UCEN | ENC_RFR_CRCEN, - - /* enable MAC to receive frames */ - CTL_REG_MACON1, - ENC_MACON1_MARXEN | ENC_MACON1_TXPAUS | ENC_MACON1_RXPAUS, - - /* configure pad, tx-crc and duplex */ - CTL_REG_MACON3, - ENC_MACON3_PADCFG0 | ENC_MACON3_TXCRCEN | - ENC_MACON3_FRMLNEN, - - /* Allow infinite deferals if the medium is continously busy */ - CTL_REG_MACON4, ENC_MACON4_DEFER, - - /* Late collisions occur beyond 63 bytes */ - CTL_REG_MACLCON2, 63, - - /* - * Set (low byte) Non-Back-to_Back Inter-Packet Gap. - * Recommended 0x12 - */ - CTL_REG_MAIPGL, 0x12, - - /* - * Set (high byte) Non-Back-to_Back Inter-Packet Gap. - * Recommended 0x0c for half-duplex. Nothing for full-duplex - */ - CTL_REG_MAIPGH, 0x0C, - - /* set maximum frame length */ - CTL_REG_MAMXFLL, ENC_MAX_FRM_LEN, - CTL_REG_MAMXFLH, ENC_MAX_FRM_LEN >> 8, - - /* - * Set MAC back-to-back inter-packet gap. - * Recommended 0x12 for half duplex - * and 0x15 for full duplex. - */ - CTL_REG_MABBIPG, 0x12, - - /* end of table */ - 0xffff -}; - -/* - * Wait for the XTAL oscillator to become ready - */ -static int enc_clock_wait(enc_dev_t *enc) -{ - uint64_t etime; - - /* one second timeout */ - etime = get_ticks() + get_tbclk(); - - /* - * Wait for CLKRDY to become set (i.e., check that we can - * communicate with the ENC) - */ - do - { - if (enc_r8(enc, CTL_REG_ESTAT) & ENC_ESTAT_CLKRDY) - return 0; - } while (get_ticks() <= etime); - - printf("%s: timeout waiting for CLKRDY\n", enc->dev->name); - return -1; -} - -/* - * Write the MAC address into the ENC - */ -static int enc_write_macaddr(enc_dev_t *enc) -{ - unsigned char *p = enc->dev->enetaddr; - - enc_w8_retry(enc, CTL_REG_MAADR5, *p++, 5); - enc_w8_retry(enc, CTL_REG_MAADR4, *p++, 5); - enc_w8_retry(enc, CTL_REG_MAADR3, *p++, 5); - enc_w8_retry(enc, CTL_REG_MAADR2, *p++, 5); - enc_w8_retry(enc, CTL_REG_MAADR1, *p++, 5); - enc_w8_retry(enc, CTL_REG_MAADR0, *p, 5); - return 0; -} - -/* - * Setup most of the ENC registers - */ -static int enc_setup(enc_dev_t *enc) -{ - u16 phid1 = 0; - u16 phid2 = 0; - const u16 *tp; - - /* reset enc struct values */ - enc->next_pointer = ENC_RX_BUF_START; - enc->rx_reset_counter = RX_RESET_COUNTER; - enc->bank = 0xff; /* invalidate current bank in enc28j60 */ - - /* verify PHY identification */ - phid1 = enc_phy_read(enc, PHY_REG_PHID1); - phid2 = enc_phy_read(enc, PHY_REG_PHID2) & ENC_PHID2_MASK; - if (phid1 != ENC_PHID1_VALUE || phid2 != ENC_PHID2_VALUE) { - printf("%s: failed to identify PHY. Found %04x:%04x\n", - enc->dev->name, phid1, phid2); - return -1; - } - - /* now program registers */ - for (tp = enc_initdata; *tp != 0xffff; tp += 2) - enc_w8_retry(enc, tp[0], tp[1], 10); - - /* - * Prevent automatic loopback of data beeing transmitted by setting - * ENC_PHCON2_HDLDIS - */ - enc_phy_write(enc, PHY_REG_PHCON2, (1<<8)); - - /* - * LEDs configuration - * LEDA: LACFG = 0100 -> display link status - * LEDB: LBCFG = 0111 -> display TX & RX activity - * STRCH = 1 -> LED pulses - */ - enc_phy_write(enc, PHY_REG_PHLCON, 0x0472); - - /* Reset PDPXMD-bit => half duplex */ - enc_phy_write(enc, PHY_REG_PHCON1, 0); - -#ifdef CONFIG_USE_IRQ - /* enable interrupts */ - enc_bset(enc, CTL_REG_EIE, ENC_EIE_PKTIE); - enc_bset(enc, CTL_REG_EIE, ENC_EIE_TXIE); - enc_bset(enc, CTL_REG_EIE, ENC_EIE_RXERIE); - enc_bset(enc, CTL_REG_EIE, ENC_EIE_TXERIE); - enc_bset(enc, CTL_REG_EIE, ENC_EIE_INTIE); -#endif - - return 0; -} - -/* - * Check if ENC has been initialized. - * If not, try to initialize it. - * Remember initialized state in struct. - */ -static int enc_initcheck(enc_dev_t *enc, const enum enc_initstate requiredstate) -{ - if (enc->initstate >= requiredstate) - return 0; - - if (enc->initstate < setupdone) { - /* Initialize the ENC only */ - enc_reset(enc); - /* if any of functions fails, skip the rest and return an error */ - if (enc_clock_wait(enc) || enc_setup(enc) || enc_write_macaddr(enc)) { - return -1; - } - enc->initstate = setupdone; - } - /* if that's all we need, return here */ - if (enc->initstate >= requiredstate) - return 0; - - /* now wait for link ready condition */ - if (enc_phy_link_wait(enc)) { - return -1; - } - enc->initstate = linkready; - return 0; -} - -#if defined(CONFIG_CMD_MII) -/* - * Read a PHY register. - * - * This function is registered with miiphy_register(). - */ -int enc_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value) -{ - struct eth_device *dev = eth_get_dev_by_name(devname); - enc_dev_t *enc; - - if (!dev || phy_adr != 0) - return -1; - - enc = dev->priv; - if (enc_claim_bus(enc)) - return -1; - if (enc_initcheck(enc, setupdone)) { - enc_release_bus(enc); - return -1; - } - *value = enc_phy_read(enc, reg); - enc_release_bus(enc); - return 0; -} - -/* - * Write a PHY register. - * - * This function is registered with miiphy_register(). - */ -int enc_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value) -{ - struct eth_device *dev = eth_get_dev_by_name(devname); - enc_dev_t *enc; - - if (!dev || phy_adr != 0) - return -1; - - enc = dev->priv; - if (enc_claim_bus(enc)) - return -1; - if (enc_initcheck(enc, setupdone)) { - enc_release_bus(enc); - return -1; - } - enc_phy_write(enc, reg, value); - enc_release_bus(enc); - return 0; -} -#endif - -/* - * Write hardware (MAC) address. - * - * This function entered into eth_device structure. - */ -static int enc_write_hwaddr(struct eth_device *dev) -{ - enc_dev_t *enc = dev->priv; - - if (enc_claim_bus(enc)) - return -1; - if (enc_initcheck(enc, setupdone)) { - enc_release_bus(enc); - return -1; - } - enc_release_bus(enc); - return 0; -} - -/* - * Initialize ENC28J60 for use. - * - * This function entered into eth_device structure. - */ -static int enc_init(struct eth_device *dev, bd_t *bis) -{ - enc_dev_t *enc = dev->priv; - - if (enc_claim_bus(enc)) - return -1; - if (enc_initcheck(enc, linkready)) { - enc_release_bus(enc); - return -1; - } - /* enable receive */ - enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_RXEN); - enc_release_bus(enc); - return 0; -} - -/* - * Check for received packets. - * - * This function entered into eth_device structure. - */ -static int enc_recv(struct eth_device *dev) -{ - enc_dev_t *enc = dev->priv; - - if (enc_claim_bus(enc)) - return -1; - if (enc_initcheck(enc, linkready)) { - enc_release_bus(enc); - return -1; - } - /* Check for dead receiver */ - if (enc->rx_reset_counter > 0) - enc->rx_reset_counter--; - else - enc_reset_rx_call(enc); - enc_poll(enc); - enc_release_bus(enc); - return 0; -} - -/* - * Send a packet. - * - * This function entered into eth_device structure. - * - * Should we wait here until we have a Link? Or shall we leave that to - * protocol retries? - */ -static int enc_send( - struct eth_device *dev, - void *packet, - int length) -{ - enc_dev_t *enc = dev->priv; - - if (enc_claim_bus(enc)) - return -1; - if (enc_initcheck(enc, linkready)) { - enc_release_bus(enc); - return -1; - } - /* setup transmit pointers */ - enc_w16(enc, CTL_REG_EWRPTL, ENC_TX_BUF_START); - enc_w16(enc, CTL_REG_ETXNDL, length + ENC_TX_BUF_START); - enc_w16(enc, CTL_REG_ETXSTL, ENC_TX_BUF_START); - /* write packet to ENC */ - enc_wbuf(enc, length, (u8 *) packet, 0x00); - /* - * Check that the internal transmit logic has not been altered - * by excessive collisions. Reset transmitter if so. - * See Errata B4 12 and 14. - */ - if (enc_r8(enc, CTL_REG_EIR) & ENC_EIR_TXERIF) { - enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_TXRST); - enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_TXRST); - } - enc_bclr(enc, CTL_REG_EIR, (ENC_EIR_TXERIF | ENC_EIR_TXIF)); - /* start transmitting */ - enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_TXRTS); - enc_release_bus(enc); - return 0; -} - -/* - * Finish use of ENC. - * - * This function entered into eth_device structure. - */ -static void enc_halt(struct eth_device *dev) -{ - enc_dev_t *enc = dev->priv; - - if (enc_claim_bus(enc)) - return; - /* Just disable receiver */ - enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_RXEN); - enc_release_bus(enc); -} - -/* - * This is the only exported function. - * - * It may be called several times with different bus:cs combinations. - */ -int enc28j60_initialize(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct eth_device *dev; - enc_dev_t *enc; - - /* try to allocate, check and clear eth_device object */ - dev = malloc(sizeof(*dev)); - if (!dev) { - return -1; - } - memset(dev, 0, sizeof(*dev)); - - /* try to allocate, check and clear enc_dev_t object */ - enc = malloc(sizeof(*enc)); - if (!enc) { - free(dev); - return -1; - } - memset(enc, 0, sizeof(*enc)); - - /* try to setup the SPI slave */ - enc->slave = spi_setup_slave(bus, cs, max_hz, mode); - if (!enc->slave) { - printf("enc28j60: invalid SPI device %i:%i\n", bus, cs); - free(enc); - free(dev); - return -1; - } - - enc->dev = dev; - /* now fill the eth_device object */ - dev->priv = enc; - dev->init = enc_init; - dev->halt = enc_halt; - dev->send = enc_send; - dev->recv = enc_recv; - dev->write_hwaddr = enc_write_hwaddr; - sprintf(dev->name, "enc%i.%i", bus, cs); - eth_register(dev); -#if defined(CONFIG_CMD_MII) - miiphy_register(dev->name, enc_miiphy_read, enc_miiphy_write); -#endif - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/enc28j60.h b/qemu/roms/u-boot/drivers/net/enc28j60.h deleted file mode 100644 index 289e41288..000000000 --- a/qemu/roms/u-boot/drivers/net/enc28j60.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * (X) extracted from enc28j60.c - * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _enc28j60_h -#define _enc28j60_h - -/* - * SPI Commands - * - * Bits 7-5: Command - * Bits 4-0: Register - */ -#define CMD_RCR(x) (0x00+((x)&0x1f)) /* Read Control Register */ -#define CMD_RBM 0x3a /* Read Buffer Memory */ -#define CMD_WCR(x) (0x40+((x)&0x1f)) /* Write Control Register */ -#define CMD_WBM 0x7a /* Write Buffer Memory */ -#define CMD_BFS(x) (0x80+((x)&0x1f)) /* Bit Field Set */ -#define CMD_BFC(x) (0xa0+((x)&0x1f)) /* Bit Field Clear */ -#define CMD_SRC 0xff /* System Reset Command */ - -/* NEW: encode (bank number+1) in upper byte */ - -/* Common Control Registers accessible in all Banks */ -#define CTL_REG_EIE 0x01B -#define CTL_REG_EIR 0x01C -#define CTL_REG_ESTAT 0x01D -#define CTL_REG_ECON2 0x01E -#define CTL_REG_ECON1 0x01F - -/* Control Registers accessible in Bank 0 */ -#define CTL_REG_ERDPTL 0x100 -#define CTL_REG_ERDPTH 0x101 -#define CTL_REG_EWRPTL 0x102 -#define CTL_REG_EWRPTH 0x103 -#define CTL_REG_ETXSTL 0x104 -#define CTL_REG_ETXSTH 0x105 -#define CTL_REG_ETXNDL 0x106 -#define CTL_REG_ETXNDH 0x107 -#define CTL_REG_ERXSTL 0x108 -#define CTL_REG_ERXSTH 0x109 -#define CTL_REG_ERXNDL 0x10A -#define CTL_REG_ERXNDH 0x10B -#define CTL_REG_ERXRDPTL 0x10C -#define CTL_REG_ERXRDPTH 0x10D -#define CTL_REG_ERXWRPTL 0x10E -#define CTL_REG_ERXWRPTH 0x10F -#define CTL_REG_EDMASTL 0x110 -#define CTL_REG_EDMASTH 0x111 -#define CTL_REG_EDMANDL 0x112 -#define CTL_REG_EDMANDH 0x113 -#define CTL_REG_EDMADSTL 0x114 -#define CTL_REG_EDMADSTH 0x115 -#define CTL_REG_EDMACSL 0x116 -#define CTL_REG_EDMACSH 0x117 - -/* Control Registers accessible in Bank 1 */ -#define CTL_REG_EHT0 0x200 -#define CTL_REG_EHT1 0x201 -#define CTL_REG_EHT2 0x202 -#define CTL_REG_EHT3 0x203 -#define CTL_REG_EHT4 0x204 -#define CTL_REG_EHT5 0x205 -#define CTL_REG_EHT6 0x206 -#define CTL_REG_EHT7 0x207 -#define CTL_REG_EPMM0 0x208 -#define CTL_REG_EPMM1 0x209 -#define CTL_REG_EPMM2 0x20A -#define CTL_REG_EPMM3 0x20B -#define CTL_REG_EPMM4 0x20C -#define CTL_REG_EPMM5 0x20D -#define CTL_REG_EPMM6 0x20E -#define CTL_REG_EPMM7 0x20F -#define CTL_REG_EPMCSL 0x210 -#define CTL_REG_EPMCSH 0x211 -#define CTL_REG_EPMOL 0x214 -#define CTL_REG_EPMOH 0x215 -#define CTL_REG_EWOLIE 0x216 -#define CTL_REG_EWOLIR 0x217 -#define CTL_REG_ERXFCON 0x218 -#define CTL_REG_EPKTCNT 0x219 - -/* Control Registers accessible in Bank 2 */ -#define CTL_REG_MACON1 0x300 -#define CTL_REG_MACON2 0x301 -#define CTL_REG_MACON3 0x302 -#define CTL_REG_MACON4 0x303 -#define CTL_REG_MABBIPG 0x304 -#define CTL_REG_MAIPGL 0x306 -#define CTL_REG_MAIPGH 0x307 -#define CTL_REG_MACLCON1 0x308 -#define CTL_REG_MACLCON2 0x309 -#define CTL_REG_MAMXFLL 0x30A -#define CTL_REG_MAMXFLH 0x30B -#define CTL_REG_MAPHSUP 0x30D -#define CTL_REG_MICON 0x311 -#define CTL_REG_MICMD 0x312 -#define CTL_REG_MIREGADR 0x314 -#define CTL_REG_MIWRL 0x316 -#define CTL_REG_MIWRH 0x317 -#define CTL_REG_MIRDL 0x318 -#define CTL_REG_MIRDH 0x319 - -/* Control Registers accessible in Bank 3 */ -#define CTL_REG_MAADR1 0x400 -#define CTL_REG_MAADR0 0x401 -#define CTL_REG_MAADR3 0x402 -#define CTL_REG_MAADR2 0x403 -#define CTL_REG_MAADR5 0x404 -#define CTL_REG_MAADR4 0x405 -#define CTL_REG_EBSTSD 0x406 -#define CTL_REG_EBSTCON 0x407 -#define CTL_REG_EBSTCSL 0x408 -#define CTL_REG_EBSTCSH 0x409 -#define CTL_REG_MISTAT 0x40A -#define CTL_REG_EREVID 0x412 -#define CTL_REG_ECOCON 0x415 -#define CTL_REG_EFLOCON 0x417 -#define CTL_REG_EPAUSL 0x418 -#define CTL_REG_EPAUSH 0x419 - -/* PHY Register */ -#define PHY_REG_PHCON1 0x00 -#define PHY_REG_PHSTAT1 0x01 -#define PHY_REG_PHID1 0x02 -#define PHY_REG_PHID2 0x03 -#define PHY_REG_PHCON2 0x10 -#define PHY_REG_PHSTAT2 0x11 -#define PHY_REG_PHLCON 0x14 - -/* Receive Filter Register (ERXFCON) bits */ -#define ENC_RFR_UCEN 0x80 -#define ENC_RFR_ANDOR 0x40 -#define ENC_RFR_CRCEN 0x20 -#define ENC_RFR_PMEN 0x10 -#define ENC_RFR_MPEN 0x08 -#define ENC_RFR_HTEN 0x04 -#define ENC_RFR_MCEN 0x02 -#define ENC_RFR_BCEN 0x01 - -/* ECON1 Register Bits */ -#define ENC_ECON1_TXRST 0x80 -#define ENC_ECON1_RXRST 0x40 -#define ENC_ECON1_DMAST 0x20 -#define ENC_ECON1_CSUMEN 0x10 -#define ENC_ECON1_TXRTS 0x08 -#define ENC_ECON1_RXEN 0x04 -#define ENC_ECON1_BSEL1 0x02 -#define ENC_ECON1_BSEL0 0x01 - -/* ECON2 Register Bits */ -#define ENC_ECON2_AUTOINC 0x80 -#define ENC_ECON2_PKTDEC 0x40 -#define ENC_ECON2_PWRSV 0x20 -#define ENC_ECON2_VRPS 0x08 - -/* EIR Register Bits */ -#define ENC_EIR_PKTIF 0x40 -#define ENC_EIR_DMAIF 0x20 -#define ENC_EIR_LINKIF 0x10 -#define ENC_EIR_TXIF 0x08 -#define ENC_EIR_WOLIF 0x04 -#define ENC_EIR_TXERIF 0x02 -#define ENC_EIR_RXERIF 0x01 - -/* ESTAT Register Bits */ -#define ENC_ESTAT_INT 0x80 -#define ENC_ESTAT_LATECOL 0x10 -#define ENC_ESTAT_RXBUSY 0x04 -#define ENC_ESTAT_TXABRT 0x02 -#define ENC_ESTAT_CLKRDY 0x01 - -/* EIE Register Bits */ -#define ENC_EIE_INTIE 0x80 -#define ENC_EIE_PKTIE 0x40 -#define ENC_EIE_DMAIE 0x20 -#define ENC_EIE_LINKIE 0x10 -#define ENC_EIE_TXIE 0x08 -#define ENC_EIE_WOLIE 0x04 -#define ENC_EIE_TXERIE 0x02 -#define ENC_EIE_RXERIE 0x01 - -/* MACON1 Register Bits */ -#define ENC_MACON1_LOOPBK 0x10 -#define ENC_MACON1_TXPAUS 0x08 -#define ENC_MACON1_RXPAUS 0x04 -#define ENC_MACON1_PASSALL 0x02 -#define ENC_MACON1_MARXEN 0x01 - -/* MACON2 Register Bits */ -#define ENC_MACON2_MARST 0x80 -#define ENC_MACON2_RNDRST 0x40 -#define ENC_MACON2_MARXRST 0x08 -#define ENC_MACON2_RFUNRST 0x04 -#define ENC_MACON2_MATXRST 0x02 -#define ENC_MACON2_TFUNRST 0x01 - -/* MACON3 Register Bits */ -#define ENC_MACON3_PADCFG2 0x80 -#define ENC_MACON3_PADCFG1 0x40 -#define ENC_MACON3_PADCFG0 0x20 -#define ENC_MACON3_TXCRCEN 0x10 -#define ENC_MACON3_PHDRLEN 0x08 -#define ENC_MACON3_HFRMEN 0x04 -#define ENC_MACON3_FRMLNEN 0x02 -#define ENC_MACON3_FULDPX 0x01 - -/* MACON4 Register Bits */ -#define ENC_MACON4_DEFER 0x40 - -/* MICMD Register Bits */ -#define ENC_MICMD_MIISCAN 0x02 -#define ENC_MICMD_MIIRD 0x01 - -/* MISTAT Register Bits */ -#define ENC_MISTAT_NVALID 0x04 -#define ENC_MISTAT_SCAN 0x02 -#define ENC_MISTAT_BUSY 0x01 - -/* PHID1 and PHID2 values */ -#define ENC_PHID1_VALUE 0x0083 -#define ENC_PHID2_VALUE 0x1400 -#define ENC_PHID2_MASK 0xFC00 - -/* PHCON1 values */ -#define ENC_PHCON1_PDPXMD 0x0100 - -/* PHSTAT1 values */ -#define ENC_PHSTAT1_LLSTAT 0x0004 - -/* PHSTAT2 values */ -#define ENC_PHSTAT2_LSTAT 0x0400 -#define ENC_PHSTAT2_DPXSTAT 0x0200 - -#endif diff --git a/qemu/roms/u-boot/drivers/net/ep93xx_eth.c b/qemu/roms/u-boot/drivers/net/ep93xx_eth.c deleted file mode 100644 index 1c09f1004..000000000 --- a/qemu/roms/u-boot/drivers/net/ep93xx_eth.c +++ /dev/null @@ -1,639 +0,0 @@ -/* - * Cirrus Logic EP93xx ethernet MAC / MII driver. - * - * Copyright (C) 2010, 2009 - * Matthias Kaehlcke <matthias@kaehlcke.net> - * - * Copyright (C) 2004, 2005 - * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com> - * - * Based on the original eth.[ch] Cirrus Logic EP93xx Rev D. Ethernet Driver, - * which is - * - * (C) Copyright 2002 2003 - * Adam Bezanson, Network Audio Technologies, Inc. - * <bezanson@netaudiotech.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <command.h> -#include <common.h> -#include <asm/arch/ep93xx.h> -#include <asm/io.h> -#include <malloc.h> -#include <miiphy.h> -#include <linux/types.h> -#include "ep93xx_eth.h" - -#define GET_PRIV(eth_dev) ((struct ep93xx_priv *)(eth_dev)->priv) -#define GET_REGS(eth_dev) (GET_PRIV(eth_dev)->regs) - -/* ep93xx_miiphy ops forward declarations */ -static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr, - unsigned char const reg, unsigned short * const value); -static int ep93xx_miiphy_write(const char * const dev, unsigned char const addr, - unsigned char const reg, unsigned short const value); - -#if defined(EP93XX_MAC_DEBUG) -/** - * Dump ep93xx_mac values to the terminal. - */ -static void dump_dev(struct eth_device *dev) -{ - struct ep93xx_priv *priv = GET_PRIV(dev); - int i; - - printf("\ndump_dev()\n"); - printf(" rx_dq.base %p\n", priv->rx_dq.base); - printf(" rx_dq.current %p\n", priv->rx_dq.current); - printf(" rx_dq.end %p\n", priv->rx_dq.end); - printf(" rx_sq.base %p\n", priv->rx_sq.base); - printf(" rx_sq.current %p\n", priv->rx_sq.current); - printf(" rx_sq.end %p\n", priv->rx_sq.end); - - for (i = 0; i < NUMRXDESC; i++) - printf(" rx_buffer[%2.d] %p\n", i, NetRxPackets[i]); - - printf(" tx_dq.base %p\n", priv->tx_dq.base); - printf(" tx_dq.current %p\n", priv->tx_dq.current); - printf(" tx_dq.end %p\n", priv->tx_dq.end); - printf(" tx_sq.base %p\n", priv->tx_sq.base); - printf(" tx_sq.current %p\n", priv->tx_sq.current); - printf(" tx_sq.end %p\n", priv->tx_sq.end); -} - -/** - * Dump all RX status queue entries to the terminal. - */ -static void dump_rx_status_queue(struct eth_device *dev) -{ - struct ep93xx_priv *priv = GET_PRIV(dev); - int i; - - printf("\ndump_rx_status_queue()\n"); - printf(" descriptor address word1 word2\n"); - for (i = 0; i < NUMRXDESC; i++) { - printf(" [ %p ] %08X %08X\n", - priv->rx_sq.base + i, - (priv->rx_sq.base + i)->word1, - (priv->rx_sq.base + i)->word2); - } -} - -/** - * Dump all RX descriptor queue entries to the terminal. - */ -static void dump_rx_descriptor_queue(struct eth_device *dev) -{ - struct ep93xx_priv *priv = GET_PRIV(dev); - int i; - - printf("\ndump_rx_descriptor_queue()\n"); - printf(" descriptor address word1 word2\n"); - for (i = 0; i < NUMRXDESC; i++) { - printf(" [ %p ] %08X %08X\n", - priv->rx_dq.base + i, - (priv->rx_dq.base + i)->word1, - (priv->rx_dq.base + i)->word2); - } -} - -/** - * Dump all TX descriptor queue entries to the terminal. - */ -static void dump_tx_descriptor_queue(struct eth_device *dev) -{ - struct ep93xx_priv *priv = GET_PRIV(dev); - int i; - - printf("\ndump_tx_descriptor_queue()\n"); - printf(" descriptor address word1 word2\n"); - for (i = 0; i < NUMTXDESC; i++) { - printf(" [ %p ] %08X %08X\n", - priv->tx_dq.base + i, - (priv->tx_dq.base + i)->word1, - (priv->tx_dq.base + i)->word2); - } -} - -/** - * Dump all TX status queue entries to the terminal. - */ -static void dump_tx_status_queue(struct eth_device *dev) -{ - struct ep93xx_priv *priv = GET_PRIV(dev); - int i; - - printf("\ndump_tx_status_queue()\n"); - printf(" descriptor address word1\n"); - for (i = 0; i < NUMTXDESC; i++) { - printf(" [ %p ] %08X\n", - priv->rx_sq.base + i, - (priv->rx_sq.base + i)->word1); - } -} -#else -#define dump_dev(x) -#define dump_rx_descriptor_queue(x) -#define dump_rx_status_queue(x) -#define dump_tx_descriptor_queue(x) -#define dump_tx_status_queue(x) -#endif /* defined(EP93XX_MAC_DEBUG) */ - -/** - * Reset the EP93xx MAC by twiddling the soft reset bit and spinning until - * it's cleared. - */ -static void ep93xx_mac_reset(struct eth_device *dev) -{ - struct mac_regs *mac = GET_REGS(dev); - uint32_t value; - - debug("+ep93xx_mac_reset"); - - value = readl(&mac->selfctl); - value |= SELFCTL_RESET; - writel(value, &mac->selfctl); - - while (readl(&mac->selfctl) & SELFCTL_RESET) - ; /* noop */ - - debug("-ep93xx_mac_reset"); -} - -/* Eth device open */ -static int ep93xx_eth_open(struct eth_device *dev, bd_t *bd) -{ - struct ep93xx_priv *priv = GET_PRIV(dev); - struct mac_regs *mac = GET_REGS(dev); - uchar *mac_addr = dev->enetaddr; - int i; - - debug("+ep93xx_eth_open"); - - /* Reset the MAC */ - ep93xx_mac_reset(dev); - - /* Reset the descriptor queues' current and end address values */ - priv->tx_dq.current = priv->tx_dq.base; - priv->tx_dq.end = (priv->tx_dq.base + NUMTXDESC); - - priv->tx_sq.current = priv->tx_sq.base; - priv->tx_sq.end = (priv->tx_sq.base + NUMTXDESC); - - priv->rx_dq.current = priv->rx_dq.base; - priv->rx_dq.end = (priv->rx_dq.base + NUMRXDESC); - - priv->rx_sq.current = priv->rx_sq.base; - priv->rx_sq.end = (priv->rx_sq.base + NUMRXDESC); - - /* - * Set the transmit descriptor and status queues' base address, - * current address, and length registers. Set the maximum frame - * length and threshold. Enable the transmit descriptor processor. - */ - writel((uint32_t)priv->tx_dq.base, &mac->txdq.badd); - writel((uint32_t)priv->tx_dq.base, &mac->txdq.curadd); - writel(sizeof(struct tx_descriptor) * NUMTXDESC, &mac->txdq.blen); - - writel((uint32_t)priv->tx_sq.base, &mac->txstsq.badd); - writel((uint32_t)priv->tx_sq.base, &mac->txstsq.curadd); - writel(sizeof(struct tx_status) * NUMTXDESC, &mac->txstsq.blen); - - writel(0x00040000, &mac->txdthrshld); - writel(0x00040000, &mac->txststhrshld); - - writel((TXSTARTMAX << 0) | (PKTSIZE_ALIGN << 16), &mac->maxfrmlen); - writel(BMCTL_TXEN, &mac->bmctl); - - /* - * Set the receive descriptor and status queues' base address, - * current address, and length registers. Enable the receive - * descriptor processor. - */ - writel((uint32_t)priv->rx_dq.base, &mac->rxdq.badd); - writel((uint32_t)priv->rx_dq.base, &mac->rxdq.curadd); - writel(sizeof(struct rx_descriptor) * NUMRXDESC, &mac->rxdq.blen); - - writel((uint32_t)priv->rx_sq.base, &mac->rxstsq.badd); - writel((uint32_t)priv->rx_sq.base, &mac->rxstsq.curadd); - writel(sizeof(struct rx_status) * NUMRXDESC, &mac->rxstsq.blen); - - writel(0x00040000, &mac->rxdthrshld); - - writel(BMCTL_RXEN, &mac->bmctl); - - writel(0x00040000, &mac->rxststhrshld); - - /* Wait until the receive descriptor processor is active */ - while (!(readl(&mac->bmsts) & BMSTS_RXACT)) - ; /* noop */ - - /* - * Initialize the RX descriptor queue. Clear the TX descriptor queue. - * Clear the RX and TX status queues. Enqueue the RX descriptor and - * status entries to the MAC. - */ - for (i = 0; i < NUMRXDESC; i++) { - /* set buffer address */ - (priv->rx_dq.base + i)->word1 = (uint32_t)NetRxPackets[i]; - - /* set buffer length, clear buffer index and NSOF */ - (priv->rx_dq.base + i)->word2 = PKTSIZE_ALIGN; - } - - memset(priv->tx_dq.base, 0, - (sizeof(struct tx_descriptor) * NUMTXDESC)); - memset(priv->rx_sq.base, 0, - (sizeof(struct rx_status) * NUMRXDESC)); - memset(priv->tx_sq.base, 0, - (sizeof(struct tx_status) * NUMTXDESC)); - - writel(NUMRXDESC, &mac->rxdqenq); - writel(NUMRXDESC, &mac->rxstsqenq); - - /* Set the primary MAC address */ - writel(AFP_IAPRIMARY, &mac->afp); - writel(mac_addr[0] | (mac_addr[1] << 8) | - (mac_addr[2] << 16) | (mac_addr[3] << 24), - &mac->indad); - writel(mac_addr[4] | (mac_addr[5] << 8), &mac->indad_upper); - - /* Turn on RX and TX */ - writel(RXCTL_IA0 | RXCTL_BA | RXCTL_SRXON | - RXCTL_RCRCA | RXCTL_MA, &mac->rxctl); - writel(TXCTL_STXON, &mac->txctl); - - /* Dump data structures if we're debugging */ - dump_dev(dev); - dump_rx_descriptor_queue(dev); - dump_rx_status_queue(dev); - dump_tx_descriptor_queue(dev); - dump_tx_status_queue(dev); - - debug("-ep93xx_eth_open"); - - return 1; -} - -/** - * Halt EP93xx MAC transmit and receive by clearing the TxCTL and RxCTL - * registers. - */ -static void ep93xx_eth_close(struct eth_device *dev) -{ - struct mac_regs *mac = GET_REGS(dev); - - debug("+ep93xx_eth_close"); - - writel(0x00000000, &mac->rxctl); - writel(0x00000000, &mac->txctl); - - debug("-ep93xx_eth_close"); -} - -/** - * Copy a frame of data from the MAC into the protocol layer for further - * processing. - */ -static int ep93xx_eth_rcv_packet(struct eth_device *dev) -{ - struct mac_regs *mac = GET_REGS(dev); - struct ep93xx_priv *priv = GET_PRIV(dev); - int len = -1; - - debug("+ep93xx_eth_rcv_packet"); - - if (RX_STATUS_RFP(priv->rx_sq.current)) { - if (RX_STATUS_RWE(priv->rx_sq.current)) { - /* - * We have a good frame. Extract the frame's length - * from the current rx_status_queue entry, and copy - * the frame's data into NetRxPackets[] of the - * protocol stack. We track the total number of - * bytes in the frame (nbytes_frame) which will be - * used when we pass the data off to the protocol - * layer via NetReceive(). - */ - len = RX_STATUS_FRAME_LEN(priv->rx_sq.current); - - NetReceive((uchar *)priv->rx_dq.current->word1, len); - - debug("reporting %d bytes...\n", len); - } else { - /* Do we have an erroneous packet? */ - error("packet rx error, status %08X %08X", - priv->rx_sq.current->word1, - priv->rx_sq.current->word2); - dump_rx_descriptor_queue(dev); - dump_rx_status_queue(dev); - } - - /* - * Clear the associated status queue entry, and - * increment our current pointers to the next RX - * descriptor and status queue entries (making sure - * we wrap properly). - */ - memset((void *)priv->rx_sq.current, 0, - sizeof(struct rx_status)); - - priv->rx_sq.current++; - if (priv->rx_sq.current >= priv->rx_sq.end) - priv->rx_sq.current = priv->rx_sq.base; - - priv->rx_dq.current++; - if (priv->rx_dq.current >= priv->rx_dq.end) - priv->rx_dq.current = priv->rx_dq.base; - - /* - * Finally, return the RX descriptor and status entries - * back to the MAC engine, and loop again, checking for - * more descriptors to process. - */ - writel(1, &mac->rxdqenq); - writel(1, &mac->rxstsqenq); - } else { - len = 0; - } - - debug("-ep93xx_eth_rcv_packet %d", len); - return len; -} - -/** - * Send a block of data via ethernet. - */ -static int ep93xx_eth_send_packet(struct eth_device *dev, - void * const packet, int const length) -{ - struct mac_regs *mac = GET_REGS(dev); - struct ep93xx_priv *priv = GET_PRIV(dev); - int ret = -1; - - debug("+ep93xx_eth_send_packet"); - - /* Parameter check */ - BUG_ON(packet == NULL); - - /* - * Initialize the TX descriptor queue with the new packet's info. - * Clear the associated status queue entry. Enqueue the packet - * to the MAC for transmission. - */ - - /* set buffer address */ - priv->tx_dq.current->word1 = (uint32_t)packet; - - /* set buffer length and EOF bit */ - priv->tx_dq.current->word2 = length | TX_DESC_EOF; - - /* clear tx status */ - priv->tx_sq.current->word1 = 0; - - /* enqueue the TX descriptor */ - writel(1, &mac->txdqenq); - - /* wait for the frame to become processed */ - while (!TX_STATUS_TXFP(priv->tx_sq.current)) - ; /* noop */ - - if (!TX_STATUS_TXWE(priv->tx_sq.current)) { - error("packet tx error, status %08X", - priv->tx_sq.current->word1); - dump_tx_descriptor_queue(dev); - dump_tx_status_queue(dev); - - /* TODO: Add better error handling? */ - goto eth_send_out; - } - - ret = 0; - /* Fall through */ - -eth_send_out: - debug("-ep93xx_eth_send_packet %d", ret); - return ret; -} - -#if defined(CONFIG_MII) -int ep93xx_miiphy_initialize(bd_t * const bd) -{ - miiphy_register("ep93xx_eth0", ep93xx_miiphy_read, ep93xx_miiphy_write); - return 0; -} -#endif - -/** - * Initialize the EP93xx MAC. The MAC hardware is reset. Buffers are - * allocated, if necessary, for the TX and RX descriptor and status queues, - * as well as for received packets. The EP93XX MAC hardware is initialized. - * Transmit and receive operations are enabled. - */ -int ep93xx_eth_initialize(u8 dev_num, int base_addr) -{ - int ret = -1; - struct eth_device *dev; - struct ep93xx_priv *priv; - - debug("+ep93xx_eth_initialize"); - - priv = malloc(sizeof(*priv)); - if (!priv) { - error("malloc() failed"); - goto eth_init_failed_0; - } - memset(priv, 0, sizeof(*priv)); - - priv->regs = (struct mac_regs *)base_addr; - - priv->tx_dq.base = calloc(NUMTXDESC, - sizeof(struct tx_descriptor)); - if (priv->tx_dq.base == NULL) { - error("calloc() failed"); - goto eth_init_failed_1; - } - - priv->tx_sq.base = calloc(NUMTXDESC, - sizeof(struct tx_status)); - if (priv->tx_sq.base == NULL) { - error("calloc() failed"); - goto eth_init_failed_2; - } - - priv->rx_dq.base = calloc(NUMRXDESC, - sizeof(struct rx_descriptor)); - if (priv->rx_dq.base == NULL) { - error("calloc() failed"); - goto eth_init_failed_3; - } - - priv->rx_sq.base = calloc(NUMRXDESC, - sizeof(struct rx_status)); - if (priv->rx_sq.base == NULL) { - error("calloc() failed"); - goto eth_init_failed_4; - } - - dev = malloc(sizeof *dev); - if (dev == NULL) { - error("malloc() failed"); - goto eth_init_failed_5; - } - memset(dev, 0, sizeof *dev); - - dev->iobase = base_addr; - dev->priv = priv; - dev->init = ep93xx_eth_open; - dev->halt = ep93xx_eth_close; - dev->send = ep93xx_eth_send_packet; - dev->recv = ep93xx_eth_rcv_packet; - - sprintf(dev->name, "ep93xx_eth-%hu", dev_num); - - eth_register(dev); - - /* Done! */ - ret = 1; - goto eth_init_done; - -eth_init_failed_5: - free(priv->rx_sq.base); - /* Fall through */ - -eth_init_failed_4: - free(priv->rx_dq.base); - /* Fall through */ - -eth_init_failed_3: - free(priv->tx_sq.base); - /* Fall through */ - -eth_init_failed_2: - free(priv->tx_dq.base); - /* Fall through */ - -eth_init_failed_1: - free(priv); - /* Fall through */ - -eth_init_failed_0: - /* Fall through */ - -eth_init_done: - debug("-ep93xx_eth_initialize %d", ret); - return ret; -} - -#if defined(CONFIG_MII) - -/** - * Maximum MII address we support - */ -#define MII_ADDRESS_MAX 31 - -/** - * Maximum MII register address we support - */ -#define MII_REGISTER_MAX 31 - -/** - * Read a 16-bit value from an MII register. - */ -static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr, - unsigned char const reg, unsigned short * const value) -{ - struct mac_regs *mac = (struct mac_regs *)MAC_BASE; - int ret = -1; - uint32_t self_ctl; - - debug("+ep93xx_miiphy_read"); - - /* Parameter checks */ - BUG_ON(dev == NULL); - BUG_ON(addr > MII_ADDRESS_MAX); - BUG_ON(reg > MII_REGISTER_MAX); - BUG_ON(value == NULL); - - /* - * Save the current SelfCTL register value. Set MAC to suppress - * preamble bits. Wait for any previous MII command to complete - * before issuing the new command. - */ - self_ctl = readl(&mac->selfctl); -#if defined(CONFIG_MII_SUPPRESS_PREAMBLE) - writel(self_ctl & ~(1 << 8), &mac->selfctl); -#endif /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */ - - while (readl(&mac->miists) & MIISTS_BUSY) - ; /* noop */ - - /* - * Issue the MII 'read' command. Wait for the command to complete. - * Read the MII data value. - */ - writel(MIICMD_OPCODE_READ | ((uint32_t)addr << 5) | (uint32_t)reg, - &mac->miicmd); - while (readl(&mac->miists) & MIISTS_BUSY) - ; /* noop */ - - *value = (unsigned short)readl(&mac->miidata); - - /* Restore the saved SelfCTL value and return. */ - writel(self_ctl, &mac->selfctl); - - ret = 0; - /* Fall through */ - - debug("-ep93xx_miiphy_read"); - return ret; -} - -/** - * Write a 16-bit value to an MII register. - */ -static int ep93xx_miiphy_write(const char * const dev, unsigned char const addr, - unsigned char const reg, unsigned short const value) -{ - struct mac_regs *mac = (struct mac_regs *)MAC_BASE; - int ret = -1; - uint32_t self_ctl; - - debug("+ep93xx_miiphy_write"); - - /* Parameter checks */ - BUG_ON(dev == NULL); - BUG_ON(addr > MII_ADDRESS_MAX); - BUG_ON(reg > MII_REGISTER_MAX); - - /* - * Save the current SelfCTL register value. Set MAC to suppress - * preamble bits. Wait for any previous MII command to complete - * before issuing the new command. - */ - self_ctl = readl(&mac->selfctl); -#if defined(CONFIG_MII_SUPPRESS_PREAMBLE) - writel(self_ctl & ~(1 << 8), &mac->selfctl); -#endif /* defined(CONFIG_MII_SUPPRESS_PREAMBLE) */ - - while (readl(&mac->miists) & MIISTS_BUSY) - ; /* noop */ - - /* Issue the MII 'write' command. Wait for the command to complete. */ - writel((uint32_t)value, &mac->miidata); - writel(MIICMD_OPCODE_WRITE | ((uint32_t)addr << 5) | (uint32_t)reg, - &mac->miicmd); - while (readl(&mac->miists) & MIISTS_BUSY) - ; /* noop */ - - /* Restore the saved SelfCTL value and return. */ - writel(self_ctl, &mac->selfctl); - - ret = 0; - /* Fall through */ - - debug("-ep93xx_miiphy_write"); - return ret; -} -#endif /* defined(CONFIG_MII) */ diff --git a/qemu/roms/u-boot/drivers/net/ep93xx_eth.h b/qemu/roms/u-boot/drivers/net/ep93xx_eth.h deleted file mode 100644 index e6c949ffc..000000000 --- a/qemu/roms/u-boot/drivers/net/ep93xx_eth.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net> - * - * Copyright (C) 2004, 2005 - * Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _EP93XX_ETH_H -#define _EP93XX_ETH_H - -#include <net.h> - -/** - * #define this to dump device status and queue info during initialization and - * following errors. - */ -#undef EP93XX_MAC_DEBUG - -/** - * Number of descriptor and status entries in our RX queues. - * It must be power of 2 ! - */ -#define NUMRXDESC PKTBUFSRX - -/** - * Number of descriptor and status entries in our TX queues. - */ -#define NUMTXDESC 1 - -/** - * 944 = (1024 - 64) - 16, Fifo size - Minframesize - 16 (Chip FACT) - */ -#define TXSTARTMAX 944 - -/** - * Receive descriptor queue entry - */ -struct rx_descriptor { - uint32_t word1; - uint32_t word2; -}; - -/** - * Receive status queue entry - */ -struct rx_status { - uint32_t word1; - uint32_t word2; -}; - -#define RX_STATUS_RWE(rx_status) ((rx_status->word1 >> 30) & 0x01) -#define RX_STATUS_RFP(rx_status) ((rx_status->word1 >> 31) & 0x01) -#define RX_STATUS_FRAME_LEN(rx_status) (rx_status->word2 & 0xFFFF) - -/** - * Transmit descriptor queue entry - */ -struct tx_descriptor { - uint32_t word1; - uint32_t word2; -}; - -#define TX_DESC_EOF (1 << 31) - -/** - * Transmit status queue entry - */ -struct tx_status { - uint32_t word1; -}; - -#define TX_STATUS_TXWE(tx_status) (((tx_status)->word1 >> 30) & 0x01) -#define TX_STATUS_TXFP(tx_status) (((tx_status)->word1 >> 31) & 0x01) - -/** - * Transmit descriptor queue - */ -struct tx_descriptor_queue { - struct tx_descriptor *base; - struct tx_descriptor *current; - struct tx_descriptor *end; -}; - -/** - * Transmit status queue - */ -struct tx_status_queue { - struct tx_status *base; - volatile struct tx_status *current; - struct tx_status *end; -}; - -/** - * Receive descriptor queue - */ -struct rx_descriptor_queue { - struct rx_descriptor *base; - struct rx_descriptor *current; - struct rx_descriptor *end; -}; - -/** - * Receive status queue - */ -struct rx_status_queue { - struct rx_status *base; - volatile struct rx_status *current; - struct rx_status *end; -}; - -/** - * EP93xx MAC private data structure - */ -struct ep93xx_priv { - struct rx_descriptor_queue rx_dq; - struct rx_status_queue rx_sq; - void *rx_buffer[NUMRXDESC]; - - struct tx_descriptor_queue tx_dq; - struct tx_status_queue tx_sq; - - struct mac_regs *regs; -}; - -#endif diff --git a/qemu/roms/u-boot/drivers/net/ethoc.c b/qemu/roms/u-boot/drivers/net/ethoc.c deleted file mode 100644 index af06d4fb8..000000000 --- a/qemu/roms/u-boot/drivers/net/ethoc.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Opencore 10/100 ethernet mac driver - * - * Copyright (C) 2007-2008 Avionic Design Development GmbH - * Copyright (C) 2008-2009 Avionic Design GmbH - * Thierry Reding <thierry.reding@avionic-design.de> - * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <common.h> -#include <command.h> -#include <malloc.h> -#include <net.h> -#include <miiphy.h> -#include <asm/io.h> -#include <asm/cache.h> - -/* register offsets */ -#define MODER 0x00 -#define INT_SOURCE 0x04 -#define INT_MASK 0x08 -#define IPGT 0x0c -#define IPGR1 0x10 -#define IPGR2 0x14 -#define PACKETLEN 0x18 -#define COLLCONF 0x1c -#define TX_BD_NUM 0x20 -#define CTRLMODER 0x24 -#define MIIMODER 0x28 -#define MIICOMMAND 0x2c -#define MIIADDRESS 0x30 -#define MIITX_DATA 0x34 -#define MIIRX_DATA 0x38 -#define MIISTATUS 0x3c -#define MAC_ADDR0 0x40 -#define MAC_ADDR1 0x44 -#define ETH_HASH0 0x48 -#define ETH_HASH1 0x4c -#define ETH_TXCTRL 0x50 - -/* mode register */ -#define MODER_RXEN (1 << 0) /* receive enable */ -#define MODER_TXEN (1 << 1) /* transmit enable */ -#define MODER_NOPRE (1 << 2) /* no preamble */ -#define MODER_BRO (1 << 3) /* broadcast address */ -#define MODER_IAM (1 << 4) /* individual address mode */ -#define MODER_PRO (1 << 5) /* promiscuous mode */ -#define MODER_IFG (1 << 6) /* interframe gap for incoming frames */ -#define MODER_LOOP (1 << 7) /* loopback */ -#define MODER_NBO (1 << 8) /* no back-off */ -#define MODER_EDE (1 << 9) /* excess defer enable */ -#define MODER_FULLD (1 << 10) /* full duplex */ -#define MODER_RESET (1 << 11) /* FIXME: reset (undocumented) */ -#define MODER_DCRC (1 << 12) /* delayed CRC enable */ -#define MODER_CRC (1 << 13) /* CRC enable */ -#define MODER_HUGE (1 << 14) /* huge packets enable */ -#define MODER_PAD (1 << 15) /* padding enabled */ -#define MODER_RSM (1 << 16) /* receive small packets */ - -/* interrupt source and mask registers */ -#define INT_MASK_TXF (1 << 0) /* transmit frame */ -#define INT_MASK_TXE (1 << 1) /* transmit error */ -#define INT_MASK_RXF (1 << 2) /* receive frame */ -#define INT_MASK_RXE (1 << 3) /* receive error */ -#define INT_MASK_BUSY (1 << 4) -#define INT_MASK_TXC (1 << 5) /* transmit control frame */ -#define INT_MASK_RXC (1 << 6) /* receive control frame */ - -#define INT_MASK_TX (INT_MASK_TXF | INT_MASK_TXE) -#define INT_MASK_RX (INT_MASK_RXF | INT_MASK_RXE) - -#define INT_MASK_ALL ( \ - INT_MASK_TXF | INT_MASK_TXE | \ - INT_MASK_RXF | INT_MASK_RXE | \ - INT_MASK_TXC | INT_MASK_RXC | \ - INT_MASK_BUSY \ - ) - -/* packet length register */ -#define PACKETLEN_MIN(min) (((min) & 0xffff) << 16) -#define PACKETLEN_MAX(max) (((max) & 0xffff) << 0) -#define PACKETLEN_MIN_MAX(min, max) (PACKETLEN_MIN(min) | \ - PACKETLEN_MAX(max)) - -/* transmit buffer number register */ -#define TX_BD_NUM_VAL(x) (((x) <= 0x80) ? (x) : 0x80) - -/* control module mode register */ -#define CTRLMODER_PASSALL (1 << 0) /* pass all receive frames */ -#define CTRLMODER_RXFLOW (1 << 1) /* receive control flow */ -#define CTRLMODER_TXFLOW (1 << 2) /* transmit control flow */ - -/* MII mode register */ -#define MIIMODER_CLKDIV(x) ((x) & 0xfe) /* needs to be an even number */ -#define MIIMODER_NOPRE (1 << 8) /* no preamble */ - -/* MII command register */ -#define MIICOMMAND_SCAN (1 << 0) /* scan status */ -#define MIICOMMAND_READ (1 << 1) /* read status */ -#define MIICOMMAND_WRITE (1 << 2) /* write control data */ - -/* MII address register */ -#define MIIADDRESS_FIAD(x) (((x) & 0x1f) << 0) -#define MIIADDRESS_RGAD(x) (((x) & 0x1f) << 8) -#define MIIADDRESS_ADDR(phy, reg) (MIIADDRESS_FIAD(phy) | \ - MIIADDRESS_RGAD(reg)) - -/* MII transmit data register */ -#define MIITX_DATA_VAL(x) ((x) & 0xffff) - -/* MII receive data register */ -#define MIIRX_DATA_VAL(x) ((x) & 0xffff) - -/* MII status register */ -#define MIISTATUS_LINKFAIL (1 << 0) -#define MIISTATUS_BUSY (1 << 1) -#define MIISTATUS_INVALID (1 << 2) - -/* TX buffer descriptor */ -#define TX_BD_CS (1 << 0) /* carrier sense lost */ -#define TX_BD_DF (1 << 1) /* defer indication */ -#define TX_BD_LC (1 << 2) /* late collision */ -#define TX_BD_RL (1 << 3) /* retransmission limit */ -#define TX_BD_RETRY_MASK (0x00f0) -#define TX_BD_RETRY(x) (((x) & 0x00f0) >> 4) -#define TX_BD_UR (1 << 8) /* transmitter underrun */ -#define TX_BD_CRC (1 << 11) /* TX CRC enable */ -#define TX_BD_PAD (1 << 12) /* pad enable */ -#define TX_BD_WRAP (1 << 13) -#define TX_BD_IRQ (1 << 14) /* interrupt request enable */ -#define TX_BD_READY (1 << 15) /* TX buffer ready */ -#define TX_BD_LEN(x) (((x) & 0xffff) << 16) -#define TX_BD_LEN_MASK (0xffff << 16) - -#define TX_BD_STATS (TX_BD_CS | TX_BD_DF | TX_BD_LC | \ - TX_BD_RL | TX_BD_RETRY_MASK | TX_BD_UR) - -/* RX buffer descriptor */ -#define RX_BD_LC (1 << 0) /* late collision */ -#define RX_BD_CRC (1 << 1) /* RX CRC error */ -#define RX_BD_SF (1 << 2) /* short frame */ -#define RX_BD_TL (1 << 3) /* too long */ -#define RX_BD_DN (1 << 4) /* dribble nibble */ -#define RX_BD_IS (1 << 5) /* invalid symbol */ -#define RX_BD_OR (1 << 6) /* receiver overrun */ -#define RX_BD_MISS (1 << 7) -#define RX_BD_CF (1 << 8) /* control frame */ -#define RX_BD_WRAP (1 << 13) -#define RX_BD_IRQ (1 << 14) /* interrupt request enable */ -#define RX_BD_EMPTY (1 << 15) -#define RX_BD_LEN(x) (((x) & 0xffff) << 16) - -#define RX_BD_STATS (RX_BD_LC | RX_BD_CRC | RX_BD_SF | RX_BD_TL | \ - RX_BD_DN | RX_BD_IS | RX_BD_OR | RX_BD_MISS) - -#define ETHOC_BUFSIZ 1536 -#define ETHOC_ZLEN 64 -#define ETHOC_BD_BASE 0x400 -#define ETHOC_TIMEOUT (HZ / 2) -#define ETHOC_MII_TIMEOUT (1 + (HZ / 5)) - -/** - * struct ethoc - driver-private device structure - * @num_tx: number of send buffers - * @cur_tx: last send buffer written - * @dty_tx: last buffer actually sent - * @num_rx: number of receive buffers - * @cur_rx: current receive buffer - */ -struct ethoc { - u32 num_tx; - u32 cur_tx; - u32 dty_tx; - u32 num_rx; - u32 cur_rx; -}; - -/** - * struct ethoc_bd - buffer descriptor - * @stat: buffer statistics - * @addr: physical memory address - */ -struct ethoc_bd { - u32 stat; - u32 addr; -}; - -static inline u32 ethoc_read(struct eth_device *dev, loff_t offset) -{ - return readl(dev->iobase + offset); -} - -static inline void ethoc_write(struct eth_device *dev, loff_t offset, u32 data) -{ - writel(data, dev->iobase + offset); -} - -static inline void ethoc_read_bd(struct eth_device *dev, int index, - struct ethoc_bd *bd) -{ - loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd)); - bd->stat = ethoc_read(dev, offset + 0); - bd->addr = ethoc_read(dev, offset + 4); -} - -static inline void ethoc_write_bd(struct eth_device *dev, int index, - const struct ethoc_bd *bd) -{ - loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd)); - ethoc_write(dev, offset + 0, bd->stat); - ethoc_write(dev, offset + 4, bd->addr); -} - -static int ethoc_set_mac_address(struct eth_device *dev) -{ - u8 *mac = dev->enetaddr; - - ethoc_write(dev, MAC_ADDR0, (mac[2] << 24) | (mac[3] << 16) | - (mac[4] << 8) | (mac[5] << 0)); - ethoc_write(dev, MAC_ADDR1, (mac[0] << 8) | (mac[1] << 0)); - return 0; -} - -static inline void ethoc_ack_irq(struct eth_device *dev, u32 mask) -{ - ethoc_write(dev, INT_SOURCE, mask); -} - -static inline void ethoc_enable_rx_and_tx(struct eth_device *dev) -{ - u32 mode = ethoc_read(dev, MODER); - mode |= MODER_RXEN | MODER_TXEN; - ethoc_write(dev, MODER, mode); -} - -static inline void ethoc_disable_rx_and_tx(struct eth_device *dev) -{ - u32 mode = ethoc_read(dev, MODER); - mode &= ~(MODER_RXEN | MODER_TXEN); - ethoc_write(dev, MODER, mode); -} - -static int ethoc_init_ring(struct eth_device *dev) -{ - struct ethoc *priv = (struct ethoc *)dev->priv; - struct ethoc_bd bd; - int i; - - priv->cur_tx = 0; - priv->dty_tx = 0; - priv->cur_rx = 0; - - /* setup transmission buffers */ - bd.stat = TX_BD_IRQ | TX_BD_CRC; - - for (i = 0; i < priv->num_tx; i++) { - if (i == priv->num_tx - 1) - bd.stat |= TX_BD_WRAP; - - ethoc_write_bd(dev, i, &bd); - } - - bd.stat = RX_BD_EMPTY | RX_BD_IRQ; - - for (i = 0; i < priv->num_rx; i++) { - bd.addr = (u32)NetRxPackets[i]; - if (i == priv->num_rx - 1) - bd.stat |= RX_BD_WRAP; - - flush_dcache_range(bd.addr, bd.addr + PKTSIZE_ALIGN); - ethoc_write_bd(dev, priv->num_tx + i, &bd); - } - - return 0; -} - -static int ethoc_reset(struct eth_device *dev) -{ - u32 mode; - - /* TODO: reset controller? */ - - ethoc_disable_rx_and_tx(dev); - - /* TODO: setup registers */ - - /* enable FCS generation and automatic padding */ - mode = ethoc_read(dev, MODER); - mode |= MODER_CRC | MODER_PAD; - ethoc_write(dev, MODER, mode); - - /* set full-duplex mode */ - mode = ethoc_read(dev, MODER); - mode |= MODER_FULLD; - ethoc_write(dev, MODER, mode); - ethoc_write(dev, IPGT, 0x15); - - ethoc_ack_irq(dev, INT_MASK_ALL); - ethoc_enable_rx_and_tx(dev); - return 0; -} - -static int ethoc_init(struct eth_device *dev, bd_t * bd) -{ - struct ethoc *priv = (struct ethoc *)dev->priv; - printf("ethoc\n"); - - priv->num_tx = 1; - priv->num_rx = PKTBUFSRX; - ethoc_write(dev, TX_BD_NUM, priv->num_tx); - ethoc_init_ring(dev); - ethoc_reset(dev); - - return 0; -} - -static int ethoc_update_rx_stats(struct ethoc_bd *bd) -{ - int ret = 0; - - if (bd->stat & RX_BD_TL) { - debug("ETHOC: " "RX: frame too long\n"); - ret++; - } - - if (bd->stat & RX_BD_SF) { - debug("ETHOC: " "RX: frame too short\n"); - ret++; - } - - if (bd->stat & RX_BD_DN) - debug("ETHOC: " "RX: dribble nibble\n"); - - if (bd->stat & RX_BD_CRC) { - debug("ETHOC: " "RX: wrong CRC\n"); - ret++; - } - - if (bd->stat & RX_BD_OR) { - debug("ETHOC: " "RX: overrun\n"); - ret++; - } - - if (bd->stat & RX_BD_LC) { - debug("ETHOC: " "RX: late collision\n"); - ret++; - } - - return ret; -} - -static int ethoc_rx(struct eth_device *dev, int limit) -{ - struct ethoc *priv = (struct ethoc *)dev->priv; - int count; - - for (count = 0; count < limit; ++count) { - u32 entry; - struct ethoc_bd bd; - - entry = priv->num_tx + (priv->cur_rx % priv->num_rx); - ethoc_read_bd(dev, entry, &bd); - if (bd.stat & RX_BD_EMPTY) - break; - - debug("%s(): RX buffer %d, %x received\n", - __func__, priv->cur_rx, bd.stat); - if (ethoc_update_rx_stats(&bd) == 0) { - int size = bd.stat >> 16; - size -= 4; /* strip the CRC */ - NetReceive((void *)bd.addr, size); - } - - /* clear the buffer descriptor so it can be reused */ - flush_dcache_range(bd.addr, bd.addr + PKTSIZE_ALIGN); - bd.stat &= ~RX_BD_STATS; - bd.stat |= RX_BD_EMPTY; - ethoc_write_bd(dev, entry, &bd); - priv->cur_rx++; - } - - return count; -} - -static int ethoc_update_tx_stats(struct ethoc_bd *bd) -{ - if (bd->stat & TX_BD_LC) - debug("ETHOC: " "TX: late collision\n"); - - if (bd->stat & TX_BD_RL) - debug("ETHOC: " "TX: retransmit limit\n"); - - if (bd->stat & TX_BD_UR) - debug("ETHOC: " "TX: underrun\n"); - - if (bd->stat & TX_BD_CS) - debug("ETHOC: " "TX: carrier sense lost\n"); - - return 0; -} - -static void ethoc_tx(struct eth_device *dev) -{ - struct ethoc *priv = (struct ethoc *)dev->priv; - u32 entry = priv->dty_tx % priv->num_tx; - struct ethoc_bd bd; - - ethoc_read_bd(dev, entry, &bd); - if ((bd.stat & TX_BD_READY) == 0) - (void)ethoc_update_tx_stats(&bd); -} - -static int ethoc_send(struct eth_device *dev, void *packet, int length) -{ - struct ethoc *priv = (struct ethoc *)dev->priv; - struct ethoc_bd bd; - u32 entry; - u32 pending; - int tmo; - - entry = priv->cur_tx % priv->num_tx; - ethoc_read_bd(dev, entry, &bd); - if (unlikely(length < ETHOC_ZLEN)) - bd.stat |= TX_BD_PAD; - else - bd.stat &= ~TX_BD_PAD; - bd.addr = (u32)packet; - - flush_dcache_range(bd.addr, bd.addr + length); - bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK); - bd.stat |= TX_BD_LEN(length); - ethoc_write_bd(dev, entry, &bd); - - /* start transmit */ - bd.stat |= TX_BD_READY; - ethoc_write_bd(dev, entry, &bd); - - /* wait for transfer to succeed */ - tmo = get_timer(0) + 5 * CONFIG_SYS_HZ; - while (1) { - pending = ethoc_read(dev, INT_SOURCE); - ethoc_ack_irq(dev, pending & ~INT_MASK_RX); - if (pending & INT_MASK_BUSY) - debug("%s(): packet dropped\n", __func__); - - if (pending & INT_MASK_TX) { - ethoc_tx(dev); - break; - } - if (get_timer(0) >= tmo) { - debug("%s(): timed out\n", __func__); - return -1; - } - } - - debug("%s(): packet sent\n", __func__); - return 0; -} - -static void ethoc_halt(struct eth_device *dev) -{ - ethoc_disable_rx_and_tx(dev); -} - -static int ethoc_recv(struct eth_device *dev) -{ - u32 pending; - - pending = ethoc_read(dev, INT_SOURCE); - ethoc_ack_irq(dev, pending); - if (pending & INT_MASK_BUSY) - debug("%s(): packet dropped\n", __func__); - if (pending & INT_MASK_RX) { - debug("%s(): rx irq\n", __func__); - ethoc_rx(dev, PKTBUFSRX); - } - - return 0; -} - -int ethoc_initialize(u8 dev_num, int base_addr) -{ - struct ethoc *priv; - struct eth_device *dev; - - priv = malloc(sizeof(*priv)); - if (!priv) - return 0; - dev = malloc(sizeof(*dev)); - if (!dev) { - free(priv); - return 0; - } - - memset(dev, 0, sizeof(*dev)); - dev->priv = priv; - dev->iobase = base_addr; - dev->init = ethoc_init; - dev->halt = ethoc_halt; - dev->send = ethoc_send; - dev->recv = ethoc_recv; - dev->write_hwaddr = ethoc_set_mac_address; - sprintf(dev->name, "%s-%hu", "ETHOC", dev_num); - - eth_register(dev); - return 1; -} diff --git a/qemu/roms/u-boot/drivers/net/fec_mxc.c b/qemu/roms/u-boot/drivers/net/fec_mxc.c deleted file mode 100644 index 4cefda48e..000000000 --- a/qemu/roms/u-boot/drivers/net/fec_mxc.c +++ /dev/null @@ -1,1102 +0,0 @@ -/* - * (C) Copyright 2009 Ilya Yanok, Emcraft Systems Ltd <yanok@emcraft.com> - * (C) Copyright 2008,2009 Eric Jarrige <eric.jarrige@armadeus.org> - * (C) Copyright 2008 Armadeus Systems nc - * (C) Copyright 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> - * (C) Copyright 2007 Pengutronix, Juergen Beisert <j.beisert@pengutronix.de> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <miiphy.h> -#include "fec_mxc.h" - -#include <asm/arch/clock.h> -#include <asm/arch/imx-regs.h> -#include <asm/io.h> -#include <asm/errno.h> -#include <linux/compiler.h> - -DECLARE_GLOBAL_DATA_PTR; - -/* - * Timeout the transfer after 5 mS. This is usually a bit more, since - * the code in the tightloops this timeout is used in adds some overhead. - */ -#define FEC_XFER_TIMEOUT 5000 - -#ifndef CONFIG_MII -#error "CONFIG_MII has to be defined!" -#endif - -#ifndef CONFIG_FEC_XCV_TYPE -#define CONFIG_FEC_XCV_TYPE MII100 -#endif - -/* - * The i.MX28 operates with packets in big endian. We need to swap them before - * sending and after receiving. - */ -#ifdef CONFIG_MX28 -#define CONFIG_FEC_MXC_SWAP_PACKET -#endif - -#define RXDESC_PER_CACHELINE (ARCH_DMA_MINALIGN/sizeof(struct fec_bd)) - -/* Check various alignment issues at compile time */ -#if ((ARCH_DMA_MINALIGN < 16) || (ARCH_DMA_MINALIGN % 16 != 0)) -#error "ARCH_DMA_MINALIGN must be multiple of 16!" -#endif - -#if ((PKTALIGN < ARCH_DMA_MINALIGN) || \ - (PKTALIGN % ARCH_DMA_MINALIGN != 0)) -#error "PKTALIGN must be multiple of ARCH_DMA_MINALIGN!" -#endif - -#undef DEBUG - -struct nbuf { - uint8_t data[1500]; /**< actual data */ - int length; /**< actual length */ - int used; /**< buffer in use or not */ - uint8_t head[16]; /**< MAC header(6 + 6 + 2) + 2(aligned) */ -}; - -#ifdef CONFIG_FEC_MXC_SWAP_PACKET -static void swap_packet(uint32_t *packet, int length) -{ - int i; - - for (i = 0; i < DIV_ROUND_UP(length, 4); i++) - packet[i] = __swab32(packet[i]); -} -#endif - -/* - * MII-interface related functions - */ -static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr, - uint8_t regAddr) -{ - uint32_t reg; /* convenient holder for the PHY register */ - uint32_t phy; /* convenient holder for the PHY */ - uint32_t start; - int val; - - /* - * reading from any PHY's register is done by properly - * programming the FEC's MII data register. - */ - writel(FEC_IEVENT_MII, ð->ievent); - reg = regAddr << FEC_MII_DATA_RA_SHIFT; - phy = phyAddr << FEC_MII_DATA_PA_SHIFT; - - writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA | - phy | reg, ð->mii_data); - - /* - * wait for the related interrupt - */ - start = get_timer(0); - while (!(readl(ð->ievent) & FEC_IEVENT_MII)) { - if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) { - printf("Read MDIO failed...\n"); - return -1; - } - } - - /* - * clear mii interrupt bit - */ - writel(FEC_IEVENT_MII, ð->ievent); - - /* - * it's now safe to read the PHY's register - */ - val = (unsigned short)readl(ð->mii_data); - debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyAddr, - regAddr, val); - return val; -} - -static void fec_mii_setspeed(struct ethernet_regs *eth) -{ - /* - * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock - * and do not drop the Preamble. - */ - register u32 speed = DIV_ROUND_UP(imx_get_fecclk(), 5000000); -#ifdef FEC_QUIRK_ENET_MAC - speed--; -#endif - speed <<= 1; - writel(speed, ð->mii_speed); - debug("%s: mii_speed %08x\n", __func__, readl(ð->mii_speed)); -} - -static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr, - uint8_t regAddr, uint16_t data) -{ - uint32_t reg; /* convenient holder for the PHY register */ - uint32_t phy; /* convenient holder for the PHY */ - uint32_t start; - - reg = regAddr << FEC_MII_DATA_RA_SHIFT; - phy = phyAddr << FEC_MII_DATA_PA_SHIFT; - - writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR | - FEC_MII_DATA_TA | phy | reg | data, ð->mii_data); - - /* - * wait for the MII interrupt - */ - start = get_timer(0); - while (!(readl(ð->ievent) & FEC_IEVENT_MII)) { - if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) { - printf("Write MDIO failed...\n"); - return -1; - } - } - - /* - * clear MII interrupt bit - */ - writel(FEC_IEVENT_MII, ð->ievent); - debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyAddr, - regAddr, data); - - return 0; -} - -int fec_phy_read(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr) -{ - return fec_mdio_read(bus->priv, phyAddr, regAddr); -} - -int fec_phy_write(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr, - u16 data) -{ - return fec_mdio_write(bus->priv, phyAddr, regAddr, data); -} - -#ifndef CONFIG_PHYLIB -static int miiphy_restart_aneg(struct eth_device *dev) -{ - int ret = 0; -#if !defined(CONFIG_FEC_MXC_NO_ANEG) - struct fec_priv *fec = (struct fec_priv *)dev->priv; - struct ethernet_regs *eth = fec->bus->priv; - - /* - * Wake up from sleep if necessary - * Reset PHY, then delay 300ns - */ -#ifdef CONFIG_MX27 - fec_mdio_write(eth, fec->phy_id, MII_DCOUNTER, 0x00FF); -#endif - fec_mdio_write(eth, fec->phy_id, MII_BMCR, BMCR_RESET); - udelay(1000); - - /* - * Set the auto-negotiation advertisement register bits - */ - fec_mdio_write(eth, fec->phy_id, MII_ADVERTISE, - LPA_100FULL | LPA_100HALF | LPA_10FULL | - LPA_10HALF | PHY_ANLPAR_PSB_802_3); - fec_mdio_write(eth, fec->phy_id, MII_BMCR, - BMCR_ANENABLE | BMCR_ANRESTART); - - if (fec->mii_postcall) - ret = fec->mii_postcall(fec->phy_id); - -#endif - return ret; -} - -static int miiphy_wait_aneg(struct eth_device *dev) -{ - uint32_t start; - int status; - struct fec_priv *fec = (struct fec_priv *)dev->priv; - struct ethernet_regs *eth = fec->bus->priv; - - /* - * Wait for AN completion - */ - start = get_timer(0); - do { - if (get_timer(start) > (CONFIG_SYS_HZ * 5)) { - printf("%s: Autonegotiation timeout\n", dev->name); - return -1; - } - - status = fec_mdio_read(eth, fec->phy_id, MII_BMSR); - if (status < 0) { - printf("%s: Autonegotiation failed. status: %d\n", - dev->name, status); - return -1; - } - } while (!(status & BMSR_LSTATUS)); - - return 0; -} -#endif - -static int fec_rx_task_enable(struct fec_priv *fec) -{ - writel(FEC_R_DES_ACTIVE_RDAR, &fec->eth->r_des_active); - return 0; -} - -static int fec_rx_task_disable(struct fec_priv *fec) -{ - return 0; -} - -static int fec_tx_task_enable(struct fec_priv *fec) -{ - writel(FEC_X_DES_ACTIVE_TDAR, &fec->eth->x_des_active); - return 0; -} - -static int fec_tx_task_disable(struct fec_priv *fec) -{ - return 0; -} - -/** - * Initialize receive task's buffer descriptors - * @param[in] fec all we know about the device yet - * @param[in] count receive buffer count to be allocated - * @param[in] dsize desired size of each receive buffer - * @return 0 on success - * - * Init all RX descriptors to default values. - */ -static void fec_rbd_init(struct fec_priv *fec, int count, int dsize) -{ - uint32_t size; - uint8_t *data; - int i; - - /* - * Reload the RX descriptors with default values and wipe - * the RX buffers. - */ - size = roundup(dsize, ARCH_DMA_MINALIGN); - for (i = 0; i < count; i++) { - data = (uint8_t *)fec->rbd_base[i].data_pointer; - memset(data, 0, dsize); - flush_dcache_range((uint32_t)data, (uint32_t)data + size); - - fec->rbd_base[i].status = FEC_RBD_EMPTY; - fec->rbd_base[i].data_length = 0; - } - - /* Mark the last RBD to close the ring. */ - fec->rbd_base[i - 1].status = FEC_RBD_WRAP | FEC_RBD_EMPTY; - fec->rbd_index = 0; - - flush_dcache_range((unsigned)fec->rbd_base, - (unsigned)fec->rbd_base + size); -} - -/** - * Initialize transmit task's buffer descriptors - * @param[in] fec all we know about the device yet - * - * Transmit buffers are created externally. We only have to init the BDs here.\n - * Note: There is a race condition in the hardware. When only one BD is in - * use it must be marked with the WRAP bit to use it for every transmitt. - * This bit in combination with the READY bit results into double transmit - * of each data buffer. It seems the state machine checks READY earlier then - * resetting it after the first transfer. - * Using two BDs solves this issue. - */ -static void fec_tbd_init(struct fec_priv *fec) -{ - unsigned addr = (unsigned)fec->tbd_base; - unsigned size = roundup(2 * sizeof(struct fec_bd), - ARCH_DMA_MINALIGN); - - memset(fec->tbd_base, 0, size); - fec->tbd_base[0].status = 0; - fec->tbd_base[1].status = FEC_TBD_WRAP; - fec->tbd_index = 0; - flush_dcache_range(addr, addr + size); -} - -/** - * Mark the given read buffer descriptor as free - * @param[in] last 1 if this is the last buffer descriptor in the chain, else 0 - * @param[in] pRbd buffer descriptor to mark free again - */ -static void fec_rbd_clean(int last, struct fec_bd *pRbd) -{ - unsigned short flags = FEC_RBD_EMPTY; - if (last) - flags |= FEC_RBD_WRAP; - writew(flags, &pRbd->status); - writew(0, &pRbd->data_length); -} - -static int fec_get_hwaddr(struct eth_device *dev, int dev_id, - unsigned char *mac) -{ - imx_get_mac_from_fuse(dev_id, mac); - return !is_valid_ether_addr(mac); -} - -static int fec_set_hwaddr(struct eth_device *dev) -{ - uchar *mac = dev->enetaddr; - struct fec_priv *fec = (struct fec_priv *)dev->priv; - - writel(0, &fec->eth->iaddr1); - writel(0, &fec->eth->iaddr2); - writel(0, &fec->eth->gaddr1); - writel(0, &fec->eth->gaddr2); - - /* - * Set physical address - */ - writel((mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3], - &fec->eth->paddr1); - writel((mac[4] << 24) + (mac[5] << 16) + 0x8808, &fec->eth->paddr2); - - return 0; -} - -/* - * Do initial configuration of the FEC registers - */ -static void fec_reg_setup(struct fec_priv *fec) -{ - uint32_t rcntrl; - - /* - * Set interrupt mask register - */ - writel(0x00000000, &fec->eth->imask); - - /* - * Clear FEC-Lite interrupt event register(IEVENT) - */ - writel(0xffffffff, &fec->eth->ievent); - - - /* - * Set FEC-Lite receive control register(R_CNTRL): - */ - - /* Start with frame length = 1518, common for all modes. */ - rcntrl = PKTSIZE << FEC_RCNTRL_MAX_FL_SHIFT; - if (fec->xcv_type != SEVENWIRE) /* xMII modes */ - rcntrl |= FEC_RCNTRL_FCE | FEC_RCNTRL_MII_MODE; - if (fec->xcv_type == RGMII) - rcntrl |= FEC_RCNTRL_RGMII; - else if (fec->xcv_type == RMII) - rcntrl |= FEC_RCNTRL_RMII; - - writel(rcntrl, &fec->eth->r_cntrl); -} - -/** - * Start the FEC engine - * @param[in] dev Our device to handle - */ -static int fec_open(struct eth_device *edev) -{ - struct fec_priv *fec = (struct fec_priv *)edev->priv; - int speed; - uint32_t addr, size; - int i; - - debug("fec_open: fec_open(dev)\n"); - /* full-duplex, heartbeat disabled */ - writel(1 << 2, &fec->eth->x_cntrl); - fec->rbd_index = 0; - - /* Invalidate all descriptors */ - for (i = 0; i < FEC_RBD_NUM - 1; i++) - fec_rbd_clean(0, &fec->rbd_base[i]); - fec_rbd_clean(1, &fec->rbd_base[i]); - - /* Flush the descriptors into RAM */ - size = roundup(FEC_RBD_NUM * sizeof(struct fec_bd), - ARCH_DMA_MINALIGN); - addr = (uint32_t)fec->rbd_base; - flush_dcache_range(addr, addr + size); - -#ifdef FEC_QUIRK_ENET_MAC - /* Enable ENET HW endian SWAP */ - writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_DBSWAP, - &fec->eth->ecntrl); - /* Enable ENET store and forward mode */ - writel(readl(&fec->eth->x_wmrk) | FEC_X_WMRK_STRFWD, - &fec->eth->x_wmrk); -#endif - /* - * Enable FEC-Lite controller - */ - writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_ETHER_EN, - &fec->eth->ecntrl); -#if defined(CONFIG_MX25) || defined(CONFIG_MX53) || defined(CONFIG_MX6SL) - udelay(100); - /* - * setup the MII gasket for RMII mode - */ - - /* disable the gasket */ - writew(0, &fec->eth->miigsk_enr); - - /* wait for the gasket to be disabled */ - while (readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) - udelay(2); - - /* configure gasket for RMII, 50 MHz, no loopback, and no echo */ - writew(MIIGSK_CFGR_IF_MODE_RMII, &fec->eth->miigsk_cfgr); - - /* re-enable the gasket */ - writew(MIIGSK_ENR_EN, &fec->eth->miigsk_enr); - - /* wait until MII gasket is ready */ - int max_loops = 10; - while ((readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) == 0) { - if (--max_loops <= 0) { - printf("WAIT for MII Gasket ready timed out\n"); - break; - } - } -#endif - -#ifdef CONFIG_PHYLIB - { - /* Start up the PHY */ - int ret = phy_startup(fec->phydev); - - if (ret) { - printf("Could not initialize PHY %s\n", - fec->phydev->dev->name); - return ret; - } - speed = fec->phydev->speed; - } -#else - miiphy_wait_aneg(edev); - speed = miiphy_speed(edev->name, fec->phy_id); - miiphy_duplex(edev->name, fec->phy_id); -#endif - -#ifdef FEC_QUIRK_ENET_MAC - { - u32 ecr = readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_SPEED; - u32 rcr = readl(&fec->eth->r_cntrl) & ~FEC_RCNTRL_RMII_10T; - if (speed == _1000BASET) - ecr |= FEC_ECNTRL_SPEED; - else if (speed != _100BASET) - rcr |= FEC_RCNTRL_RMII_10T; - writel(ecr, &fec->eth->ecntrl); - writel(rcr, &fec->eth->r_cntrl); - } -#endif - debug("%s:Speed=%i\n", __func__, speed); - - /* - * Enable SmartDMA receive task - */ - fec_rx_task_enable(fec); - - udelay(100000); - return 0; -} - -static int fec_init(struct eth_device *dev, bd_t* bd) -{ - struct fec_priv *fec = (struct fec_priv *)dev->priv; - uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop; - int i; - - /* Initialize MAC address */ - fec_set_hwaddr(dev); - - /* - * Setup transmit descriptors, there are two in total. - */ - fec_tbd_init(fec); - - /* Setup receive descriptors. */ - fec_rbd_init(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE); - - fec_reg_setup(fec); - - if (fec->xcv_type != SEVENWIRE) - fec_mii_setspeed(fec->bus->priv); - - /* - * Set Opcode/Pause Duration Register - */ - writel(0x00010020, &fec->eth->op_pause); /* FIXME 0xffff0020; */ - writel(0x2, &fec->eth->x_wmrk); - /* - * Set multicast address filter - */ - writel(0x00000000, &fec->eth->gaddr1); - writel(0x00000000, &fec->eth->gaddr2); - - - /* clear MIB RAM */ - for (i = mib_ptr; i <= mib_ptr + 0xfc; i += 4) - writel(0, i); - - /* FIFO receive start register */ - writel(0x520, &fec->eth->r_fstart); - - /* size and address of each buffer */ - writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr); - writel((uint32_t)fec->tbd_base, &fec->eth->etdsr); - writel((uint32_t)fec->rbd_base, &fec->eth->erdsr); - -#ifndef CONFIG_PHYLIB - if (fec->xcv_type != SEVENWIRE) - miiphy_restart_aneg(dev); -#endif - fec_open(dev); - return 0; -} - -/** - * Halt the FEC engine - * @param[in] dev Our device to handle - */ -static void fec_halt(struct eth_device *dev) -{ - struct fec_priv *fec = (struct fec_priv *)dev->priv; - int counter = 0xffff; - - /* - * issue graceful stop command to the FEC transmitter if necessary - */ - writel(FEC_TCNTRL_GTS | readl(&fec->eth->x_cntrl), - &fec->eth->x_cntrl); - - debug("eth_halt: wait for stop regs\n"); - /* - * wait for graceful stop to register - */ - while ((counter--) && (!(readl(&fec->eth->ievent) & FEC_IEVENT_GRA))) - udelay(1); - - /* - * Disable SmartDMA tasks - */ - fec_tx_task_disable(fec); - fec_rx_task_disable(fec); - - /* - * Disable the Ethernet Controller - * Note: this will also reset the BD index counter! - */ - writel(readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_ETHER_EN, - &fec->eth->ecntrl); - fec->rbd_index = 0; - fec->tbd_index = 0; - debug("eth_halt: done\n"); -} - -/** - * Transmit one frame - * @param[in] dev Our ethernet device to handle - * @param[in] packet Pointer to the data to be transmitted - * @param[in] length Data count in bytes - * @return 0 on success - */ -static int fec_send(struct eth_device *dev, void *packet, int length) -{ - unsigned int status; - uint32_t size, end; - uint32_t addr; - int timeout = FEC_XFER_TIMEOUT; - int ret = 0; - - /* - * This routine transmits one frame. This routine only accepts - * 6-byte Ethernet addresses. - */ - struct fec_priv *fec = (struct fec_priv *)dev->priv; - - /* - * Check for valid length of data. - */ - if ((length > 1500) || (length <= 0)) { - printf("Payload (%d) too large\n", length); - return -1; - } - - /* - * Setup the transmit buffer. We are always using the first buffer for - * transmission, the second will be empty and only used to stop the DMA - * engine. We also flush the packet to RAM here to avoid cache trouble. - */ -#ifdef CONFIG_FEC_MXC_SWAP_PACKET - swap_packet((uint32_t *)packet, length); -#endif - - addr = (uint32_t)packet; - end = roundup(addr + length, ARCH_DMA_MINALIGN); - addr &= ~(ARCH_DMA_MINALIGN - 1); - flush_dcache_range(addr, end); - - writew(length, &fec->tbd_base[fec->tbd_index].data_length); - writel(addr, &fec->tbd_base[fec->tbd_index].data_pointer); - - /* - * update BD's status now - * This block: - * - is always the last in a chain (means no chain) - * - should transmitt the CRC - * - might be the last BD in the list, so the address counter should - * wrap (-> keep the WRAP flag) - */ - status = readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_WRAP; - status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY; - writew(status, &fec->tbd_base[fec->tbd_index].status); - - /* - * Flush data cache. This code flushes both TX descriptors to RAM. - * After this code, the descriptors will be safely in RAM and we - * can start DMA. - */ - size = roundup(2 * sizeof(struct fec_bd), ARCH_DMA_MINALIGN); - addr = (uint32_t)fec->tbd_base; - flush_dcache_range(addr, addr + size); - - /* - * Below we read the DMA descriptor's last four bytes back from the - * DRAM. This is important in order to make sure that all WRITE - * operations on the bus that were triggered by previous cache FLUSH - * have completed. - * - * Otherwise, on MX28, it is possible to observe a corruption of the - * DMA descriptors. Please refer to schematic "Figure 1-2" in MX28RM - * for the bus structure of MX28. The scenario is as follows: - * - * 1) ARM core triggers a series of WRITEs on the AHB_ARB2 bus going - * to DRAM due to flush_dcache_range() - * 2) ARM core writes the FEC registers via AHB_ARB2 - * 3) FEC DMA starts reading/writing from/to DRAM via AHB_ARB3 - * - * Note that 2) does sometimes finish before 1) due to reordering of - * WRITE accesses on the AHB bus, therefore triggering 3) before the - * DMA descriptor is fully written into DRAM. This results in occasional - * corruption of the DMA descriptor. - */ - readl(addr + size - 4); - - /* - * Enable SmartDMA transmit task - */ - fec_tx_task_enable(fec); - - /* - * Wait until frame is sent. On each turn of the wait cycle, we must - * invalidate data cache to see what's really in RAM. Also, we need - * barrier here. - */ - while (--timeout) { - if (!(readl(&fec->eth->x_des_active) & FEC_X_DES_ACTIVE_TDAR)) - break; - } - - if (!timeout) - ret = -EINVAL; - - invalidate_dcache_range(addr, addr + size); - if (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) - ret = -EINVAL; - - debug("fec_send: status 0x%x index %d ret %i\n", - readw(&fec->tbd_base[fec->tbd_index].status), - fec->tbd_index, ret); - /* for next transmission use the other buffer */ - if (fec->tbd_index) - fec->tbd_index = 0; - else - fec->tbd_index = 1; - - return ret; -} - -/** - * Pull one frame from the card - * @param[in] dev Our ethernet device to handle - * @return Length of packet read - */ -static int fec_recv(struct eth_device *dev) -{ - struct fec_priv *fec = (struct fec_priv *)dev->priv; - struct fec_bd *rbd = &fec->rbd_base[fec->rbd_index]; - unsigned long ievent; - int frame_length, len = 0; - struct nbuf *frame; - uint16_t bd_status; - uint32_t addr, size, end; - int i; - ALLOC_CACHE_ALIGN_BUFFER(uchar, buff, FEC_MAX_PKT_SIZE); - - /* - * Check if any critical events have happened - */ - ievent = readl(&fec->eth->ievent); - writel(ievent, &fec->eth->ievent); - debug("fec_recv: ievent 0x%lx\n", ievent); - if (ievent & FEC_IEVENT_BABR) { - fec_halt(dev); - fec_init(dev, fec->bd); - printf("some error: 0x%08lx\n", ievent); - return 0; - } - if (ievent & FEC_IEVENT_HBERR) { - /* Heartbeat error */ - writel(0x00000001 | readl(&fec->eth->x_cntrl), - &fec->eth->x_cntrl); - } - if (ievent & FEC_IEVENT_GRA) { - /* Graceful stop complete */ - if (readl(&fec->eth->x_cntrl) & 0x00000001) { - fec_halt(dev); - writel(~0x00000001 & readl(&fec->eth->x_cntrl), - &fec->eth->x_cntrl); - fec_init(dev, fec->bd); - } - } - - /* - * Read the buffer status. Before the status can be read, the data cache - * must be invalidated, because the data in RAM might have been changed - * by DMA. The descriptors are properly aligned to cachelines so there's - * no need to worry they'd overlap. - * - * WARNING: By invalidating the descriptor here, we also invalidate - * the descriptors surrounding this one. Therefore we can NOT change the - * contents of this descriptor nor the surrounding ones. The problem is - * that in order to mark the descriptor as processed, we need to change - * the descriptor. The solution is to mark the whole cache line when all - * descriptors in the cache line are processed. - */ - addr = (uint32_t)rbd; - addr &= ~(ARCH_DMA_MINALIGN - 1); - size = roundup(sizeof(struct fec_bd), ARCH_DMA_MINALIGN); - invalidate_dcache_range(addr, addr + size); - - bd_status = readw(&rbd->status); - debug("fec_recv: status 0x%x\n", bd_status); - - if (!(bd_status & FEC_RBD_EMPTY)) { - if ((bd_status & FEC_RBD_LAST) && !(bd_status & FEC_RBD_ERR) && - ((readw(&rbd->data_length) - 4) > 14)) { - /* - * Get buffer address and size - */ - frame = (struct nbuf *)readl(&rbd->data_pointer); - frame_length = readw(&rbd->data_length) - 4; - /* - * Invalidate data cache over the buffer - */ - addr = (uint32_t)frame; - end = roundup(addr + frame_length, ARCH_DMA_MINALIGN); - addr &= ~(ARCH_DMA_MINALIGN - 1); - invalidate_dcache_range(addr, end); - - /* - * Fill the buffer and pass it to upper layers - */ -#ifdef CONFIG_FEC_MXC_SWAP_PACKET - swap_packet((uint32_t *)frame->data, frame_length); -#endif - memcpy(buff, frame->data, frame_length); - NetReceive(buff, frame_length); - len = frame_length; - } else { - if (bd_status & FEC_RBD_ERR) - printf("error frame: 0x%08lx 0x%08x\n", - (ulong)rbd->data_pointer, - bd_status); - } - - /* - * Free the current buffer, restart the engine and move forward - * to the next buffer. Here we check if the whole cacheline of - * descriptors was already processed and if so, we mark it free - * as whole. - */ - size = RXDESC_PER_CACHELINE - 1; - if ((fec->rbd_index & size) == size) { - i = fec->rbd_index - size; - addr = (uint32_t)&fec->rbd_base[i]; - for (; i <= fec->rbd_index ; i++) { - fec_rbd_clean(i == (FEC_RBD_NUM - 1), - &fec->rbd_base[i]); - } - flush_dcache_range(addr, - addr + ARCH_DMA_MINALIGN); - } - - fec_rx_task_enable(fec); - fec->rbd_index = (fec->rbd_index + 1) % FEC_RBD_NUM; - } - debug("fec_recv: stop\n"); - - return len; -} - -static void fec_set_dev_name(char *dest, int dev_id) -{ - sprintf(dest, (dev_id == -1) ? "FEC" : "FEC%i", dev_id); -} - -static int fec_alloc_descs(struct fec_priv *fec) -{ - unsigned int size; - int i; - uint8_t *data; - - /* Allocate TX descriptors. */ - size = roundup(2 * sizeof(struct fec_bd), ARCH_DMA_MINALIGN); - fec->tbd_base = memalign(ARCH_DMA_MINALIGN, size); - if (!fec->tbd_base) - goto err_tx; - - /* Allocate RX descriptors. */ - size = roundup(FEC_RBD_NUM * sizeof(struct fec_bd), ARCH_DMA_MINALIGN); - fec->rbd_base = memalign(ARCH_DMA_MINALIGN, size); - if (!fec->rbd_base) - goto err_rx; - - memset(fec->rbd_base, 0, size); - - /* Allocate RX buffers. */ - - /* Maximum RX buffer size. */ - size = roundup(FEC_MAX_PKT_SIZE, ARCH_DMA_MINALIGN); - for (i = 0; i < FEC_RBD_NUM; i++) { - data = memalign(ARCH_DMA_MINALIGN, size); - if (!data) { - printf("%s: error allocating rxbuf %d\n", __func__, i); - goto err_ring; - } - - memset(data, 0, size); - - fec->rbd_base[i].data_pointer = (uint32_t)data; - fec->rbd_base[i].status = FEC_RBD_EMPTY; - fec->rbd_base[i].data_length = 0; - /* Flush the buffer to memory. */ - flush_dcache_range((uint32_t)data, (uint32_t)data + size); - } - - /* Mark the last RBD to close the ring. */ - fec->rbd_base[i - 1].status = FEC_RBD_WRAP | FEC_RBD_EMPTY; - - fec->rbd_index = 0; - fec->tbd_index = 0; - - return 0; - -err_ring: - for (; i >= 0; i--) - free((void *)fec->rbd_base[i].data_pointer); - free(fec->rbd_base); -err_rx: - free(fec->tbd_base); -err_tx: - return -ENOMEM; -} - -static void fec_free_descs(struct fec_priv *fec) -{ - int i; - - for (i = 0; i < FEC_RBD_NUM; i++) - free((void *)fec->rbd_base[i].data_pointer); - free(fec->rbd_base); - free(fec->tbd_base); -} - -#ifdef CONFIG_PHYLIB -int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr, - struct mii_dev *bus, struct phy_device *phydev) -#else -static int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr, - struct mii_dev *bus, int phy_id) -#endif -{ - struct eth_device *edev; - struct fec_priv *fec; - unsigned char ethaddr[6]; - uint32_t start; - int ret = 0; - - /* create and fill edev struct */ - edev = (struct eth_device *)malloc(sizeof(struct eth_device)); - if (!edev) { - puts("fec_mxc: not enough malloc memory for eth_device\n"); - ret = -ENOMEM; - goto err1; - } - - fec = (struct fec_priv *)malloc(sizeof(struct fec_priv)); - if (!fec) { - puts("fec_mxc: not enough malloc memory for fec_priv\n"); - ret = -ENOMEM; - goto err2; - } - - memset(edev, 0, sizeof(*edev)); - memset(fec, 0, sizeof(*fec)); - - ret = fec_alloc_descs(fec); - if (ret) - goto err3; - - edev->priv = fec; - edev->init = fec_init; - edev->send = fec_send; - edev->recv = fec_recv; - edev->halt = fec_halt; - edev->write_hwaddr = fec_set_hwaddr; - - fec->eth = (struct ethernet_regs *)base_addr; - fec->bd = bd; - - fec->xcv_type = CONFIG_FEC_XCV_TYPE; - - /* Reset chip. */ - writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_RESET, &fec->eth->ecntrl); - start = get_timer(0); - while (readl(&fec->eth->ecntrl) & FEC_ECNTRL_RESET) { - if (get_timer(start) > (CONFIG_SYS_HZ * 5)) { - printf("FEC MXC: Timeout reseting chip\n"); - goto err4; - } - udelay(10); - } - - fec_reg_setup(fec); - fec_set_dev_name(edev->name, dev_id); - fec->dev_id = (dev_id == -1) ? 0 : dev_id; - fec->bus = bus; - fec_mii_setspeed(bus->priv); -#ifdef CONFIG_PHYLIB - fec->phydev = phydev; - phy_connect_dev(phydev, edev); - /* Configure phy */ - phy_config(phydev); -#else - fec->phy_id = phy_id; -#endif - eth_register(edev); - - if (fec_get_hwaddr(edev, dev_id, ethaddr) == 0) { - debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr); - memcpy(edev->enetaddr, ethaddr, 6); - if (!getenv("ethaddr")) - eth_setenv_enetaddr("ethaddr", ethaddr); - } - return ret; -err4: - fec_free_descs(fec); -err3: - free(fec); -err2: - free(edev); -err1: - return ret; -} - -struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id) -{ - struct ethernet_regs *eth = (struct ethernet_regs *)base_addr; - struct mii_dev *bus; - int ret; - - bus = mdio_alloc(); - if (!bus) { - printf("mdio_alloc failed\n"); - return NULL; - } - bus->read = fec_phy_read; - bus->write = fec_phy_write; - bus->priv = eth; - fec_set_dev_name(bus->name, dev_id); - - ret = mdio_register(bus); - if (ret) { - printf("mdio_register failed\n"); - free(bus); - return NULL; - } - fec_mii_setspeed(eth); - return bus; -} - -int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr) -{ - uint32_t base_mii; - struct mii_dev *bus = NULL; -#ifdef CONFIG_PHYLIB - struct phy_device *phydev = NULL; -#endif - int ret; - -#ifdef CONFIG_MX28 - /* - * The i.MX28 has two ethernet interfaces, but they are not equal. - * Only the first one can access the MDIO bus. - */ - base_mii = MXS_ENET0_BASE; -#else - base_mii = addr; -#endif - debug("eth_init: fec_probe(bd, %i, %i) @ %08x\n", dev_id, phy_id, addr); - bus = fec_get_miibus(base_mii, dev_id); - if (!bus) - return -ENOMEM; -#ifdef CONFIG_PHYLIB - phydev = phy_find_by_mask(bus, 1 << phy_id, PHY_INTERFACE_MODE_RGMII); - if (!phydev) { - free(bus); - return -ENOMEM; - } - ret = fec_probe(bd, dev_id, addr, bus, phydev); -#else - ret = fec_probe(bd, dev_id, addr, bus, phy_id); -#endif - if (ret) { -#ifdef CONFIG_PHYLIB - free(phydev); -#endif - free(bus); - } - return ret; -} - -#ifdef CONFIG_FEC_MXC_PHYADDR -int fecmxc_initialize(bd_t *bd) -{ - return fecmxc_initialize_multi(bd, -1, CONFIG_FEC_MXC_PHYADDR, - IMX_FEC_BASE); -} -#endif - -#ifndef CONFIG_PHYLIB -int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int)) -{ - struct fec_priv *fec = (struct fec_priv *)dev->priv; - fec->mii_postcall = cb; - return 0; -} -#endif diff --git a/qemu/roms/u-boot/drivers/net/fec_mxc.h b/qemu/roms/u-boot/drivers/net/fec_mxc.h deleted file mode 100644 index 0717cc6c3..000000000 --- a/qemu/roms/u-boot/drivers/net/fec_mxc.h +++ /dev/null @@ -1,323 +0,0 @@ -/* - * (C) Copyright 2009 Ilya Yanok, Emcraft Systems Ltd <yanok@emcraft.com> - * (C) Copyright 2008 Armadeus Systems, nc - * (C) Copyright 2008 Eric Jarrige <eric.jarrige@armadeus.org> - * (C) Copyright 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> - * (C) Copyright 2007 Pengutronix, Juergen Beisert <j.beisert@pengutronix.de> - * - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * This file is based on mpc4200fec.h - * (C) Copyright Motorola, Inc., 2000 - * - * SPDX-License-Identifier: GPL-2.0+ - */ - - -#ifndef __FEC_MXC_H -#define __FEC_MXC_H - -void imx_get_mac_from_fuse(int dev_id, unsigned char *mac); - -/** - * Layout description of the FEC - */ -struct ethernet_regs { - -/* [10:2]addr = 00 */ - -/* Control and status Registers (offset 000-1FF) */ - - uint32_t res0[1]; /* MBAR_ETH + 0x000 */ - uint32_t ievent; /* MBAR_ETH + 0x004 */ - uint32_t imask; /* MBAR_ETH + 0x008 */ - - uint32_t res1[1]; /* MBAR_ETH + 0x00C */ - uint32_t r_des_active; /* MBAR_ETH + 0x010 */ - uint32_t x_des_active; /* MBAR_ETH + 0x014 */ - uint32_t res2[3]; /* MBAR_ETH + 0x018-20 */ - uint32_t ecntrl; /* MBAR_ETH + 0x024 */ - - uint32_t res3[6]; /* MBAR_ETH + 0x028-03C */ - uint32_t mii_data; /* MBAR_ETH + 0x040 */ - uint32_t mii_speed; /* MBAR_ETH + 0x044 */ - uint32_t res4[7]; /* MBAR_ETH + 0x048-60 */ - uint32_t mib_control; /* MBAR_ETH + 0x064 */ - - uint32_t res5[7]; /* MBAR_ETH + 0x068-80 */ - uint32_t r_cntrl; /* MBAR_ETH + 0x084 */ - uint32_t res6[15]; /* MBAR_ETH + 0x088-C0 */ - uint32_t x_cntrl; /* MBAR_ETH + 0x0C4 */ - uint32_t res7[7]; /* MBAR_ETH + 0x0C8-E0 */ - uint32_t paddr1; /* MBAR_ETH + 0x0E4 */ - uint32_t paddr2; /* MBAR_ETH + 0x0E8 */ - uint32_t op_pause; /* MBAR_ETH + 0x0EC */ - - uint32_t res8[10]; /* MBAR_ETH + 0x0F0-114 */ - uint32_t iaddr1; /* MBAR_ETH + 0x118 */ - uint32_t iaddr2; /* MBAR_ETH + 0x11C */ - uint32_t gaddr1; /* MBAR_ETH + 0x120 */ - uint32_t gaddr2; /* MBAR_ETH + 0x124 */ - uint32_t res9[7]; /* MBAR_ETH + 0x128-140 */ - - uint32_t x_wmrk; /* MBAR_ETH + 0x144 */ - uint32_t res10[1]; /* MBAR_ETH + 0x148 */ - uint32_t r_bound; /* MBAR_ETH + 0x14C */ - uint32_t r_fstart; /* MBAR_ETH + 0x150 */ - uint32_t res11[11]; /* MBAR_ETH + 0x154-17C */ - uint32_t erdsr; /* MBAR_ETH + 0x180 */ - uint32_t etdsr; /* MBAR_ETH + 0x184 */ - uint32_t emrbr; /* MBAR_ETH + 0x188 */ - uint32_t res12[29]; /* MBAR_ETH + 0x18C-1FC */ - -/* MIB COUNTERS (Offset 200-2FF) */ - - uint32_t rmon_t_drop; /* MBAR_ETH + 0x200 */ - uint32_t rmon_t_packets; /* MBAR_ETH + 0x204 */ - uint32_t rmon_t_bc_pkt; /* MBAR_ETH + 0x208 */ - uint32_t rmon_t_mc_pkt; /* MBAR_ETH + 0x20C */ - uint32_t rmon_t_crc_align; /* MBAR_ETH + 0x210 */ - uint32_t rmon_t_undersize; /* MBAR_ETH + 0x214 */ - uint32_t rmon_t_oversize; /* MBAR_ETH + 0x218 */ - uint32_t rmon_t_frag; /* MBAR_ETH + 0x21C */ - uint32_t rmon_t_jab; /* MBAR_ETH + 0x220 */ - uint32_t rmon_t_col; /* MBAR_ETH + 0x224 */ - uint32_t rmon_t_p64; /* MBAR_ETH + 0x228 */ - uint32_t rmon_t_p65to127; /* MBAR_ETH + 0x22C */ - uint32_t rmon_t_p128to255; /* MBAR_ETH + 0x230 */ - uint32_t rmon_t_p256to511; /* MBAR_ETH + 0x234 */ - uint32_t rmon_t_p512to1023; /* MBAR_ETH + 0x238 */ - uint32_t rmon_t_p1024to2047; /* MBAR_ETH + 0x23C */ - uint32_t rmon_t_p_gte2048; /* MBAR_ETH + 0x240 */ - uint32_t rmon_t_octets; /* MBAR_ETH + 0x244 */ - uint32_t ieee_t_drop; /* MBAR_ETH + 0x248 */ - uint32_t ieee_t_frame_ok; /* MBAR_ETH + 0x24C */ - uint32_t ieee_t_1col; /* MBAR_ETH + 0x250 */ - uint32_t ieee_t_mcol; /* MBAR_ETH + 0x254 */ - uint32_t ieee_t_def; /* MBAR_ETH + 0x258 */ - uint32_t ieee_t_lcol; /* MBAR_ETH + 0x25C */ - uint32_t ieee_t_excol; /* MBAR_ETH + 0x260 */ - uint32_t ieee_t_macerr; /* MBAR_ETH + 0x264 */ - uint32_t ieee_t_cserr; /* MBAR_ETH + 0x268 */ - uint32_t ieee_t_sqe; /* MBAR_ETH + 0x26C */ - uint32_t t_fdxfc; /* MBAR_ETH + 0x270 */ - uint32_t ieee_t_octets_ok; /* MBAR_ETH + 0x274 */ - - uint32_t res13[2]; /* MBAR_ETH + 0x278-27C */ - uint32_t rmon_r_drop; /* MBAR_ETH + 0x280 */ - uint32_t rmon_r_packets; /* MBAR_ETH + 0x284 */ - uint32_t rmon_r_bc_pkt; /* MBAR_ETH + 0x288 */ - uint32_t rmon_r_mc_pkt; /* MBAR_ETH + 0x28C */ - uint32_t rmon_r_crc_align; /* MBAR_ETH + 0x290 */ - uint32_t rmon_r_undersize; /* MBAR_ETH + 0x294 */ - uint32_t rmon_r_oversize; /* MBAR_ETH + 0x298 */ - uint32_t rmon_r_frag; /* MBAR_ETH + 0x29C */ - uint32_t rmon_r_jab; /* MBAR_ETH + 0x2A0 */ - - uint32_t rmon_r_resvd_0; /* MBAR_ETH + 0x2A4 */ - - uint32_t rmon_r_p64; /* MBAR_ETH + 0x2A8 */ - uint32_t rmon_r_p65to127; /* MBAR_ETH + 0x2AC */ - uint32_t rmon_r_p128to255; /* MBAR_ETH + 0x2B0 */ - uint32_t rmon_r_p256to511; /* MBAR_ETH + 0x2B4 */ - uint32_t rmon_r_p512to1023; /* MBAR_ETH + 0x2B8 */ - uint32_t rmon_r_p1024to2047; /* MBAR_ETH + 0x2BC */ - uint32_t rmon_r_p_gte2048; /* MBAR_ETH + 0x2C0 */ - uint32_t rmon_r_octets; /* MBAR_ETH + 0x2C4 */ - uint32_t ieee_r_drop; /* MBAR_ETH + 0x2C8 */ - uint32_t ieee_r_frame_ok; /* MBAR_ETH + 0x2CC */ - uint32_t ieee_r_crc; /* MBAR_ETH + 0x2D0 */ - uint32_t ieee_r_align; /* MBAR_ETH + 0x2D4 */ - uint32_t r_macerr; /* MBAR_ETH + 0x2D8 */ - uint32_t r_fdxfc; /* MBAR_ETH + 0x2DC */ - uint32_t ieee_r_octets_ok; /* MBAR_ETH + 0x2E0 */ - - uint32_t res14[7]; /* MBAR_ETH + 0x2E4-2FC */ - -#if defined(CONFIG_MX25) || defined(CONFIG_MX53) || defined(CONFIG_MX6SL) - uint16_t miigsk_cfgr; /* MBAR_ETH + 0x300 */ - uint16_t res15[3]; /* MBAR_ETH + 0x302-306 */ - uint16_t miigsk_enr; /* MBAR_ETH + 0x308 */ - uint16_t res16[3]; /* MBAR_ETH + 0x30a-30e */ - uint32_t res17[60]; /* MBAR_ETH + 0x300-3FF */ -#else - uint32_t res15[64]; /* MBAR_ETH + 0x300-3FF */ -#endif -}; - -#define FEC_IEVENT_HBERR 0x80000000 -#define FEC_IEVENT_BABR 0x40000000 -#define FEC_IEVENT_BABT 0x20000000 -#define FEC_IEVENT_GRA 0x10000000 -#define FEC_IEVENT_TXF 0x08000000 -#define FEC_IEVENT_TXB 0x04000000 -#define FEC_IEVENT_RXF 0x02000000 -#define FEC_IEVENT_RXB 0x01000000 -#define FEC_IEVENT_MII 0x00800000 -#define FEC_IEVENT_EBERR 0x00400000 -#define FEC_IEVENT_LC 0x00200000 -#define FEC_IEVENT_RL 0x00100000 -#define FEC_IEVENT_UN 0x00080000 - -#define FEC_IMASK_HBERR 0x80000000 -#define FEC_IMASK_BABR 0x40000000 -#define FEC_IMASKT_BABT 0x20000000 -#define FEC_IMASK_GRA 0x10000000 -#define FEC_IMASKT_TXF 0x08000000 -#define FEC_IMASK_TXB 0x04000000 -#define FEC_IMASKT_RXF 0x02000000 -#define FEC_IMASK_RXB 0x01000000 -#define FEC_IMASK_MII 0x00800000 -#define FEC_IMASK_EBERR 0x00400000 -#define FEC_IMASK_LC 0x00200000 -#define FEC_IMASKT_RL 0x00100000 -#define FEC_IMASK_UN 0x00080000 - - -#define FEC_RCNTRL_MAX_FL_SHIFT 16 -#define FEC_RCNTRL_LOOP 0x00000001 -#define FEC_RCNTRL_DRT 0x00000002 -#define FEC_RCNTRL_MII_MODE 0x00000004 -#define FEC_RCNTRL_PROM 0x00000008 -#define FEC_RCNTRL_BC_REJ 0x00000010 -#define FEC_RCNTRL_FCE 0x00000020 -#define FEC_RCNTRL_RGMII 0x00000040 -#define FEC_RCNTRL_RMII 0x00000100 -#define FEC_RCNTRL_RMII_10T 0x00000200 - -#define FEC_TCNTRL_GTS 0x00000001 -#define FEC_TCNTRL_HBC 0x00000002 -#define FEC_TCNTRL_FDEN 0x00000004 -#define FEC_TCNTRL_TFC_PAUSE 0x00000008 -#define FEC_TCNTRL_RFC_PAUSE 0x00000010 - -#define FEC_ECNTRL_RESET 0x00000001 /* reset the FEC */ -#define FEC_ECNTRL_ETHER_EN 0x00000002 /* enable the FEC */ -#define FEC_ECNTRL_SPEED 0x00000020 -#define FEC_ECNTRL_DBSWAP 0x00000100 - -#define FEC_X_WMRK_STRFWD 0x00000100 - -#define FEC_X_DES_ACTIVE_TDAR 0x01000000 -#define FEC_R_DES_ACTIVE_RDAR 0x01000000 - -#if defined(CONFIG_MX25) || defined(CONFIG_MX53) || defined(CONFIG_MX6SL) -/* defines for MIIGSK */ -/* RMII frequency control: 0=50MHz, 1=5MHz */ -#define MIIGSK_CFGR_FRCONT (1 << 6) -/* loopback mode */ -#define MIIGSK_CFGR_LBMODE (1 << 4) -/* echo mode */ -#define MIIGSK_CFGR_EMODE (1 << 3) -/* MII gasket mode field */ -#define MIIGSK_CFGR_IF_MODE_MASK (3 << 0) -/* MMI/7-Wire mode */ -#define MIIGSK_CFGR_IF_MODE_MII (0 << 0) -/* RMII mode */ -#define MIIGSK_CFGR_IF_MODE_RMII (1 << 0) -/* reflects MIIGSK Enable bit (RO) */ -#define MIIGSK_ENR_READY (1 << 2) -/* enable MIGSK (set by default) */ -#define MIIGSK_ENR_EN (1 << 1) -#endif - -/** - * @brief Receive & Transmit Buffer Descriptor definitions - * - * Note: The first BD must be aligned (see DB_ALIGNMENT) - */ -struct fec_bd { - uint16_t data_length; /* payload's length in bytes */ - uint16_t status; /* BD's staus (see datasheet) */ - uint32_t data_pointer; /* payload's buffer address */ -}; - -/** - * Supported phy types on this platform - */ -enum xceiver_type { - SEVENWIRE, /* 7-wire */ - MII10, /* MII 10Mbps */ - MII100, /* MII 100Mbps */ - RMII, /* RMII */ - RGMII, /* RGMII */ -}; - -/** - * @brief i.MX27-FEC private structure - */ -struct fec_priv { - struct ethernet_regs *eth; /* pointer to register'S base */ - enum xceiver_type xcv_type; /* transceiver type */ - struct fec_bd *rbd_base; /* RBD ring */ - int rbd_index; /* next receive BD to read */ - struct fec_bd *tbd_base; /* TBD ring */ - int tbd_index; /* next transmit BD to write */ - bd_t *bd; - uint8_t *tdb_ptr; - int dev_id; - struct mii_dev *bus; -#ifdef CONFIG_PHYLIB - struct phy_device *phydev; -#else - int phy_id; - int (*mii_postcall)(int); -#endif -}; - -/** - * @brief Numbers of buffer descriptors for receiving - * - * The number defines the stocked memory buffers for the receiving task. - * Larger values makes no sense in this limited environment. - */ -#define FEC_RBD_NUM 64 - -/** - * @brief Define the ethernet packet size limit in memory - * - * Note: Do not shrink this number. This will force the FEC to spread larger - * frames in more than one BD. This is nothing to worry about, but the current - * driver can't handle it. - */ -#define FEC_MAX_PKT_SIZE 1536 - -/* Receive BD status bits */ -#define FEC_RBD_EMPTY 0x8000 /* Receive BD status: Buffer is empty */ -#define FEC_RBD_WRAP 0x2000 /* Receive BD status: Last BD in ring */ -/* Receive BD status: Buffer is last in frame (useless here!) */ -#define FEC_RBD_LAST 0x0800 -#define FEC_RBD_MISS 0x0100 /* Receive BD status: Miss bit for prom mode */ -/* Receive BD status: The received frame is broadcast frame */ -#define FEC_RBD_BC 0x0080 -/* Receive BD status: The received frame is multicast frame */ -#define FEC_RBD_MC 0x0040 -#define FEC_RBD_LG 0x0020 /* Receive BD status: Frame length violation */ -#define FEC_RBD_NO 0x0010 /* Receive BD status: Nonoctet align frame */ -#define FEC_RBD_CR 0x0004 /* Receive BD status: CRC error */ -#define FEC_RBD_OV 0x0002 /* Receive BD status: Receive FIFO overrun */ -#define FEC_RBD_TR 0x0001 /* Receive BD status: Frame is truncated */ -#define FEC_RBD_ERR (FEC_RBD_LG | FEC_RBD_NO | FEC_RBD_CR | \ - FEC_RBD_OV | FEC_RBD_TR) - -/* Transmit BD status bits */ -#define FEC_TBD_READY 0x8000 /* Tansmit BD status: Buffer is ready */ -#define FEC_TBD_WRAP 0x2000 /* Tansmit BD status: Mark as last BD in ring */ -#define FEC_TBD_LAST 0x0800 /* Tansmit BD status: Buffer is last in frame */ -#define FEC_TBD_TC 0x0400 /* Tansmit BD status: Transmit the CRC */ -#define FEC_TBD_ABC 0x0200 /* Tansmit BD status: Append bad CRC */ - -/* MII-related definitios */ -#define FEC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */ -#define FEC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */ -#define FEC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */ -#define FEC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */ -#define FEC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */ -#define FEC_MII_DATA_TA 0x00020000 /* Turnaround */ -#define FEC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */ - -#define FEC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */ -#define FEC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */ - -#endif /* __FEC_MXC_H */ diff --git a/qemu/roms/u-boot/drivers/net/fm/Makefile b/qemu/roms/u-boot/drivers/net/fm/Makefile deleted file mode 100644 index 5ae3b167a..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright 2009-2011 Freescale Semiconductor, Inc. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y += dtsec.o -obj-y += eth.o -obj-y += fm.o -obj-y += init.o -obj-y += tgec.o -obj-y += tgec_phy.o - -# Soc have FMAN v3 with mEMAC -obj-$(CONFIG_SYS_FMAN_V3) += memac_phy.o -obj-$(CONFIG_SYS_FMAN_V3) += memac.o - -# SoC specific SERDES support -obj-$(CONFIG_P1017) += p1023.o -obj-$(CONFIG_P1023) += p1023.o -# The P204x, P304x, and P5020 are the same -obj-$(CONFIG_PPC_P2041) += p5020.o -obj-$(CONFIG_PPC_P3041) += p5020.o -obj-$(CONFIG_PPC_P4080) += p4080.o -obj-$(CONFIG_PPC_P5020) += p5020.o -obj-$(CONFIG_PPC_P5040) += p5040.o -obj-$(CONFIG_PPC_T1040) += t1040.o -obj-$(CONFIG_PPC_T1042) += t1040.o -obj-$(CONFIG_PPC_T1020) += t1040.o -obj-$(CONFIG_PPC_T1022) += t1040.o -obj-$(CONFIG_PPC_T2080) += t2080.o -obj-$(CONFIG_PPC_T2081) += t2080.o -obj-$(CONFIG_PPC_T4240) += t4240.o -obj-$(CONFIG_PPC_T4160) += t4240.o -obj-$(CONFIG_PPC_T4080) += t4240.o -obj-$(CONFIG_PPC_B4420) += b4860.o -obj-$(CONFIG_PPC_B4860) += b4860.o diff --git a/qemu/roms/u-boot/drivers/net/fm/b4860.c b/qemu/roms/u-boot/drivers/net/fm/b4860.c deleted file mode 100644 index 373cc4f42..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/b4860.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * Roy Zang <tie-fei.zang@freescale.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> -#include <phy.h> -#include <fm_eth.h> -#include <asm/io.h> -#include <asm/immap_85xx.h> -#include <asm/fsl_serdes.h> - -u32 port_to_devdisr[] = { - [FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1, - [FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2, - [FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3, - [FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4, - [FM1_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC1_5, - [FM1_DTSEC6] = FSL_CORENET_DEVDISR2_DTSEC1_6, - [FM1_10GEC1] = FSL_CORENET_DEVDISR2_10GEC1_1, - [FM1_10GEC2] = FSL_CORENET_DEVDISR2_10GEC1_2, -}; - -static int is_device_disabled(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 devdisr2 = in_be32(&gur->devdisr2); - - return port_to_devdisr[port] & devdisr2; -} - -void fman_disable_port(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - setbits_be32(&gur->devdisr2, port_to_devdisr[port]); -} - -void fman_enable_port(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - clrbits_be32(&gur->devdisr2, port_to_devdisr[port]); -} - -phy_interface_t fman_port_enet_if(enum fm_port port) -{ - if (is_device_disabled(port)) - return PHY_INTERFACE_MODE_NONE; - - /*B4860 has two 10Gig Mac*/ - if ((port == FM1_10GEC1 || port == FM1_10GEC2) && - ((is_serdes_configured(XAUI_FM1_MAC9)) || - (is_serdes_configured(XAUI_FM1_MAC10)))) - return PHY_INTERFACE_MODE_XGMII; - - /* Fix me need to handle RGMII here first */ - - switch (port) { - case FM1_DTSEC1: - case FM1_DTSEC2: - case FM1_DTSEC3: - case FM1_DTSEC4: - case FM1_DTSEC5: - case FM1_DTSEC6: - if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1)) - return PHY_INTERFACE_MODE_SGMII; - break; - default: - return PHY_INTERFACE_MODE_NONE; - } - - return PHY_INTERFACE_MODE_NONE; -} diff --git a/qemu/roms/u-boot/drivers/net/fm/dtsec.c b/qemu/roms/u-boot/drivers/net/fm/dtsec.c deleted file mode 100644 index 78bbd439f..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/dtsec.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2009-2011 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/types.h> -#include <asm/io.h> -#include <asm/fsl_enet.h> -#include <asm/fsl_dtsec.h> -#include <fsl_mdio.h> -#include <phy.h> - -#include "fm.h" - -#define RCTRL_INIT (RCTRL_GRS | RCTRL_UPROM) -#define TCTRL_INIT TCTRL_GTS -#define MACCFG1_INIT MACCFG1_SOFT_RST - -#define MACCFG2_INIT (MACCFG2_PRE_LEN(0x7) | MACCFG2_LEN_CHECK | \ - MACCFG2_PAD_CRC | MACCFG2_FULL_DUPLEX | \ - MACCFG2_IF_MODE_NIBBLE) - -/* MAXFRM - maximum frame length register */ -#define MAXFRM_MASK 0x00003fff - -static void dtsec_init_mac(struct fsl_enet_mac *mac) -{ - struct dtsec *regs = mac->base; - - /* soft reset */ - out_be32(®s->maccfg1, MACCFG1_SOFT_RST); - udelay(1000); - - /* clear soft reset, Rx/Tx MAC disable */ - out_be32(®s->maccfg1, 0); - - /* graceful stop rx */ - out_be32(®s->rctrl, RCTRL_INIT); - udelay(1000); - - /* graceful stop tx */ - out_be32(®s->tctrl, TCTRL_INIT); - udelay(1000); - - /* disable all interrupts */ - out_be32(®s->imask, IMASK_MASK_ALL); - - /* clear all events */ - out_be32(®s->ievent, IEVENT_CLEAR_ALL); - - /* set the max Rx length */ - out_be32(®s->maxfrm, mac->max_rx_len & MAXFRM_MASK); - - /* set the ecntrl to reset value */ - out_be32(®s->ecntrl, ECNTRL_DEFAULT); - - /* - * Rx length check, no strip CRC for Rx, pad and append CRC for Tx, - * full duplex - */ - out_be32(®s->maccfg2, MACCFG2_INIT); -} - -static void dtsec_enable_mac(struct fsl_enet_mac *mac) -{ - struct dtsec *regs = mac->base; - - /* enable Rx/Tx MAC */ - setbits_be32(®s->maccfg1, MACCFG1_RXTX_EN); - - /* clear the graceful Rx stop */ - clrbits_be32(®s->rctrl, RCTRL_GRS); - - /* clear the graceful Tx stop */ - clrbits_be32(®s->tctrl, TCTRL_GTS); -} - -static void dtsec_disable_mac(struct fsl_enet_mac *mac) -{ - struct dtsec *regs = mac->base; - - /* graceful Rx stop */ - setbits_be32(®s->rctrl, RCTRL_GRS); - - /* graceful Tx stop */ - setbits_be32(®s->tctrl, TCTRL_GTS); - - /* disable Rx/Tx MAC */ - clrbits_be32(®s->maccfg1, MACCFG1_RXTX_EN); -} - -static void dtsec_set_mac_addr(struct fsl_enet_mac *mac, u8 *mac_addr) -{ - struct dtsec *regs = mac->base; - u32 mac_addr1, mac_addr2; - - /* - * if a station address of 0x12345678ABCD, perform a write to - * MACSTNADDR1 of 0xCDAB7856, MACSTNADDR2 of 0x34120000 - */ - mac_addr1 = (mac_addr[5] << 24) | (mac_addr[4] << 16) | \ - (mac_addr[3] << 8) | (mac_addr[2]); - out_be32(®s->macstnaddr1, mac_addr1); - - mac_addr2 = ((mac_addr[1] << 24) | (mac_addr[0] << 16)) & 0xffff0000; - out_be32(®s->macstnaddr2, mac_addr2); -} - -static void dtsec_set_interface_mode(struct fsl_enet_mac *mac, - phy_interface_t type, int speed) -{ - struct dtsec *regs = mac->base; - u32 ecntrl, maccfg2; - - /* clear all bits relative with interface mode */ - ecntrl = in_be32(®s->ecntrl); - ecntrl &= ~(ECNTRL_TBIM | ECNTRL_GMIIM | ECNTRL_RPM | - ECNTRL_R100M | ECNTRL_SGMIIM); - - maccfg2 = in_be32(®s->maccfg2); - maccfg2 &= ~MACCFG2_IF_MODE_MASK; - - if (speed == SPEED_1000) - maccfg2 |= MACCFG2_IF_MODE_BYTE; - else - maccfg2 |= MACCFG2_IF_MODE_NIBBLE; - - /* set interface mode */ - switch (type) { - case PHY_INTERFACE_MODE_GMII: - ecntrl |= ECNTRL_GMIIM; - break; - case PHY_INTERFACE_MODE_RGMII: - ecntrl |= (ECNTRL_GMIIM | ECNTRL_RPM); - if (speed == SPEED_100) - ecntrl |= ECNTRL_R100M; - break; - case PHY_INTERFACE_MODE_RMII: - if (speed == SPEED_100) - ecntrl |= ECNTRL_R100M; - break; - case PHY_INTERFACE_MODE_SGMII: - ecntrl |= (ECNTRL_SGMIIM | ECNTRL_TBIM); - if (speed == SPEED_100) - ecntrl |= ECNTRL_R100M; - break; - default: - break; - } - - out_be32(®s->ecntrl, ecntrl); - out_be32(®s->maccfg2, maccfg2); -} - -void init_dtsec(struct fsl_enet_mac *mac, void *base, - void *phyregs, int max_rx_len) -{ - mac->base = base; - mac->phyregs = phyregs; - mac->max_rx_len = max_rx_len; - mac->init_mac = dtsec_init_mac; - mac->enable_mac = dtsec_enable_mac; - mac->disable_mac = dtsec_disable_mac; - mac->set_mac_addr = dtsec_set_mac_addr; - mac->set_if_mode = dtsec_set_interface_mode; -} diff --git a/qemu/roms/u-boot/drivers/net/fm/eth.c b/qemu/roms/u-boot/drivers/net/fm/eth.c deleted file mode 100644 index 218a5ed17..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/eth.c +++ /dev/null @@ -1,712 +0,0 @@ -/* - * Copyright 2009-2012 Freescale Semiconductor, Inc. - * Dave Liu <daveliu@freescale.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> -#include <asm/io.h> -#include <malloc.h> -#include <net.h> -#include <hwconfig.h> -#include <fm_eth.h> -#include <fsl_mdio.h> -#include <miiphy.h> -#include <phy.h> -#include <asm/fsl_dtsec.h> -#include <asm/fsl_tgec.h> -#include <asm/fsl_memac.h> - -#include "fm.h" - -static struct eth_device *devlist[NUM_FM_PORTS]; -static int num_controllers; - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) && !defined(BITBANGMII) - -#define TBIANA_SETTINGS (TBIANA_ASYMMETRIC_PAUSE | TBIANA_SYMMETRIC_PAUSE | \ - TBIANA_FULL_DUPLEX) - -#define TBIANA_SGMII_ACK 0x4001 - -#define TBICR_SETTINGS (TBICR_ANEG_ENABLE | TBICR_RESTART_ANEG | \ - TBICR_FULL_DUPLEX | TBICR_SPEED1_SET) - -/* Configure the TBI for SGMII operation */ -static void dtsec_configure_serdes(struct fm_eth *priv) -{ -#ifdef CONFIG_SYS_FMAN_V3 - u32 value; - struct mii_dev bus; - bus.priv = priv->mac->phyregs; - - /* SGMII IF mode + AN enable */ - value = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII; - memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x14, value); - - /* Dev ability according to SGMII specification */ - value = PHY_SGMII_DEV_ABILITY_SGMII; - memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x4, value); - - /* Adjust link timer for SGMII - - 1.6 ms in units of 8 ns = 2 * 10^5 = 0x30d40 */ - memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x13, 0x3); - memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x12, 0xd40); - - /* Restart AN */ - value = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN; - memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0, value); -#else - struct dtsec *regs = priv->mac->base; - struct tsec_mii_mng *phyregs = priv->mac->phyregs; - - /* - * Access TBI PHY registers at given TSEC register offset as - * opposed to the register offset used for external PHY accesses - */ - tsec_local_mdio_write(phyregs, in_be32(®s->tbipa), 0, TBI_TBICON, - TBICON_CLK_SELECT); - tsec_local_mdio_write(phyregs, in_be32(®s->tbipa), 0, TBI_ANA, - TBIANA_SGMII_ACK); - tsec_local_mdio_write(phyregs, in_be32(®s->tbipa), 0, - TBI_CR, TBICR_SETTINGS); -#endif -} - -static void dtsec_init_phy(struct eth_device *dev) -{ - struct fm_eth *fm_eth = dev->priv; -#ifndef CONFIG_SYS_FMAN_V3 - struct dtsec *regs = (struct dtsec *)CONFIG_SYS_FSL_FM1_DTSEC1_ADDR; - - /* Assign a Physical address to the TBI */ - out_be32(®s->tbipa, CONFIG_SYS_TBIPA_VALUE); -#endif - - if (fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII) - dtsec_configure_serdes(fm_eth); -} - -static int tgec_is_fibre(struct eth_device *dev) -{ - struct fm_eth *fm = dev->priv; - char phyopt[20]; - - sprintf(phyopt, "fsl_fm%d_xaui_phy", fm->fm_index + 1); - - return hwconfig_arg_cmp(phyopt, "xfi"); -} -#endif - -static u16 muram_readw(u16 *addr) -{ - u32 base = (u32)addr & ~0x3; - u32 val32 = *(u32 *)base; - int byte_pos; - u16 ret; - - byte_pos = (u32)addr & 0x3; - if (byte_pos) - ret = (u16)(val32 & 0x0000ffff); - else - ret = (u16)((val32 & 0xffff0000) >> 16); - - return ret; -} - -static void muram_writew(u16 *addr, u16 val) -{ - u32 base = (u32)addr & ~0x3; - u32 org32 = *(u32 *)base; - u32 val32; - int byte_pos; - - byte_pos = (u32)addr & 0x3; - if (byte_pos) - val32 = (org32 & 0xffff0000) | val; - else - val32 = (org32 & 0x0000ffff) | ((u32)val << 16); - - *(u32 *)base = val32; -} - -static void bmi_rx_port_disable(struct fm_bmi_rx_port *rx_port) -{ - int timeout = 1000000; - - clrbits_be32(&rx_port->fmbm_rcfg, FMBM_RCFG_EN); - - /* wait until the rx port is not busy */ - while ((in_be32(&rx_port->fmbm_rst) & FMBM_RST_BSY) && timeout--) - ; -} - -static void bmi_rx_port_init(struct fm_bmi_rx_port *rx_port) -{ - /* set BMI to independent mode, Rx port disable */ - out_be32(&rx_port->fmbm_rcfg, FMBM_RCFG_IM); - /* clear FOF in IM case */ - out_be32(&rx_port->fmbm_rim, 0); - /* Rx frame next engine -RISC */ - out_be32(&rx_port->fmbm_rfne, NIA_ENG_RISC | NIA_RISC_AC_IM_RX); - /* Rx command attribute - no order, MR[3] = 1 */ - clrbits_be32(&rx_port->fmbm_rfca, FMBM_RFCA_ORDER | FMBM_RFCA_MR_MASK); - setbits_be32(&rx_port->fmbm_rfca, FMBM_RFCA_MR(4)); - /* enable Rx statistic counters */ - out_be32(&rx_port->fmbm_rstc, FMBM_RSTC_EN); - /* disable Rx performance counters */ - out_be32(&rx_port->fmbm_rpc, 0); -} - -static void bmi_tx_port_disable(struct fm_bmi_tx_port *tx_port) -{ - int timeout = 1000000; - - clrbits_be32(&tx_port->fmbm_tcfg, FMBM_TCFG_EN); - - /* wait until the tx port is not busy */ - while ((in_be32(&tx_port->fmbm_tst) & FMBM_TST_BSY) && timeout--) - ; -} - -static void bmi_tx_port_init(struct fm_bmi_tx_port *tx_port) -{ - /* set BMI to independent mode, Tx port disable */ - out_be32(&tx_port->fmbm_tcfg, FMBM_TCFG_IM); - /* Tx frame next engine -RISC */ - out_be32(&tx_port->fmbm_tfne, NIA_ENG_RISC | NIA_RISC_AC_IM_TX); - out_be32(&tx_port->fmbm_tfene, NIA_ENG_RISC | NIA_RISC_AC_IM_TX); - /* Tx command attribute - no order, MR[3] = 1 */ - clrbits_be32(&tx_port->fmbm_tfca, FMBM_TFCA_ORDER | FMBM_TFCA_MR_MASK); - setbits_be32(&tx_port->fmbm_tfca, FMBM_TFCA_MR(4)); - /* enable Tx statistic counters */ - out_be32(&tx_port->fmbm_tstc, FMBM_TSTC_EN); - /* disable Tx performance counters */ - out_be32(&tx_port->fmbm_tpc, 0); -} - -static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth) -{ - struct fm_port_global_pram *pram; - u32 pram_page_offset; - void *rx_bd_ring_base; - void *rx_buf_pool; - struct fm_port_bd *rxbd; - struct fm_port_qd *rxqd; - struct fm_bmi_rx_port *bmi_rx_port = fm_eth->rx_port; - int i; - - /* alloc global parameter ram at MURAM */ - pram = (struct fm_port_global_pram *)fm_muram_alloc(fm_eth->fm_index, - FM_PRAM_SIZE, FM_PRAM_ALIGN); - fm_eth->rx_pram = pram; - - /* parameter page offset to MURAM */ - pram_page_offset = (u32)pram - fm_muram_base(fm_eth->fm_index); - - /* enable global mode- snooping data buffers and BDs */ - pram->mode = PRAM_MODE_GLOBAL; - - /* init the Rx queue descriptor pionter */ - pram->rxqd_ptr = pram_page_offset + 0x20; - - /* set the max receive buffer length, power of 2 */ - muram_writew(&pram->mrblr, MAX_RXBUF_LOG2); - - /* alloc Rx buffer descriptors from main memory */ - rx_bd_ring_base = malloc(sizeof(struct fm_port_bd) - * RX_BD_RING_SIZE); - if (!rx_bd_ring_base) - return 0; - memset(rx_bd_ring_base, 0, sizeof(struct fm_port_bd) - * RX_BD_RING_SIZE); - - /* alloc Rx buffer from main memory */ - rx_buf_pool = malloc(MAX_RXBUF_LEN * RX_BD_RING_SIZE); - if (!rx_buf_pool) - return 0; - memset(rx_buf_pool, 0, MAX_RXBUF_LEN * RX_BD_RING_SIZE); - - /* save them to fm_eth */ - fm_eth->rx_bd_ring = rx_bd_ring_base; - fm_eth->cur_rxbd = rx_bd_ring_base; - fm_eth->rx_buf = rx_buf_pool; - - /* init Rx BDs ring */ - rxbd = (struct fm_port_bd *)rx_bd_ring_base; - for (i = 0; i < RX_BD_RING_SIZE; i++) { - rxbd->status = RxBD_EMPTY; - rxbd->len = 0; - rxbd->buf_ptr_hi = 0; - rxbd->buf_ptr_lo = (u32)rx_buf_pool + i * MAX_RXBUF_LEN; - rxbd++; - } - - /* set the Rx queue descriptor */ - rxqd = &pram->rxqd; - muram_writew(&rxqd->gen, 0); - muram_writew(&rxqd->bd_ring_base_hi, 0); - rxqd->bd_ring_base_lo = (u32)rx_bd_ring_base; - muram_writew(&rxqd->bd_ring_size, sizeof(struct fm_port_bd) - * RX_BD_RING_SIZE); - muram_writew(&rxqd->offset_in, 0); - muram_writew(&rxqd->offset_out, 0); - - /* set IM parameter ram pointer to Rx Frame Queue ID */ - out_be32(&bmi_rx_port->fmbm_rfqid, pram_page_offset); - - return 1; -} - -static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth) -{ - struct fm_port_global_pram *pram; - u32 pram_page_offset; - void *tx_bd_ring_base; - struct fm_port_bd *txbd; - struct fm_port_qd *txqd; - struct fm_bmi_tx_port *bmi_tx_port = fm_eth->tx_port; - int i; - - /* alloc global parameter ram at MURAM */ - pram = (struct fm_port_global_pram *)fm_muram_alloc(fm_eth->fm_index, - FM_PRAM_SIZE, FM_PRAM_ALIGN); - fm_eth->tx_pram = pram; - - /* parameter page offset to MURAM */ - pram_page_offset = (u32)pram - fm_muram_base(fm_eth->fm_index); - - /* enable global mode- snooping data buffers and BDs */ - pram->mode = PRAM_MODE_GLOBAL; - - /* init the Tx queue descriptor pionter */ - pram->txqd_ptr = pram_page_offset + 0x40; - - /* alloc Tx buffer descriptors from main memory */ - tx_bd_ring_base = malloc(sizeof(struct fm_port_bd) - * TX_BD_RING_SIZE); - if (!tx_bd_ring_base) - return 0; - memset(tx_bd_ring_base, 0, sizeof(struct fm_port_bd) - * TX_BD_RING_SIZE); - /* save it to fm_eth */ - fm_eth->tx_bd_ring = tx_bd_ring_base; - fm_eth->cur_txbd = tx_bd_ring_base; - - /* init Tx BDs ring */ - txbd = (struct fm_port_bd *)tx_bd_ring_base; - for (i = 0; i < TX_BD_RING_SIZE; i++) { - txbd->status = TxBD_LAST; - txbd->len = 0; - txbd->buf_ptr_hi = 0; - txbd->buf_ptr_lo = 0; - } - - /* set the Tx queue decriptor */ - txqd = &pram->txqd; - muram_writew(&txqd->bd_ring_base_hi, 0); - txqd->bd_ring_base_lo = (u32)tx_bd_ring_base; - muram_writew(&txqd->bd_ring_size, sizeof(struct fm_port_bd) - * TX_BD_RING_SIZE); - muram_writew(&txqd->offset_in, 0); - muram_writew(&txqd->offset_out, 0); - - /* set IM parameter ram pointer to Tx Confirmation Frame Queue ID */ - out_be32(&bmi_tx_port->fmbm_tcfqid, pram_page_offset); - - return 1; -} - -static int fm_eth_init(struct fm_eth *fm_eth) -{ - - if (!fm_eth_rx_port_parameter_init(fm_eth)) - return 0; - - if (!fm_eth_tx_port_parameter_init(fm_eth)) - return 0; - - return 1; -} - -static int fm_eth_startup(struct fm_eth *fm_eth) -{ - struct fsl_enet_mac *mac; - mac = fm_eth->mac; - - /* Rx/TxBDs, Rx/TxQDs, Rx buff and parameter ram init */ - if (!fm_eth_init(fm_eth)) - return 0; - /* setup the MAC controller */ - mac->init_mac(mac); - - /* For some reason we need to set SPEED_100 */ - if (((fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII) || - (fm_eth->enet_if == PHY_INTERFACE_MODE_QSGMII)) && - mac->set_if_mode) - mac->set_if_mode(mac, fm_eth->enet_if, SPEED_100); - - /* init bmi rx port, IM mode and disable */ - bmi_rx_port_init(fm_eth->rx_port); - /* init bmi tx port, IM mode and disable */ - bmi_tx_port_init(fm_eth->tx_port); - - return 1; -} - -static void fmc_tx_port_graceful_stop_enable(struct fm_eth *fm_eth) -{ - struct fm_port_global_pram *pram; - - pram = fm_eth->tx_pram; - /* graceful stop transmission of frames */ - pram->mode |= PRAM_MODE_GRACEFUL_STOP; - sync(); -} - -static void fmc_tx_port_graceful_stop_disable(struct fm_eth *fm_eth) -{ - struct fm_port_global_pram *pram; - - pram = fm_eth->tx_pram; - /* re-enable transmission of frames */ - pram->mode &= ~PRAM_MODE_GRACEFUL_STOP; - sync(); -} - -static int fm_eth_open(struct eth_device *dev, bd_t *bd) -{ - struct fm_eth *fm_eth; - struct fsl_enet_mac *mac; -#ifdef CONFIG_PHYLIB - int ret; -#endif - - fm_eth = (struct fm_eth *)dev->priv; - mac = fm_eth->mac; - - /* setup the MAC address */ - if (dev->enetaddr[0] & 0x01) { - printf("%s: MacAddress is multcast address\n", __func__); - return 1; - } - mac->set_mac_addr(mac, dev->enetaddr); - - /* enable bmi Rx port */ - setbits_be32(&fm_eth->rx_port->fmbm_rcfg, FMBM_RCFG_EN); - /* enable MAC rx/tx port */ - mac->enable_mac(mac); - /* enable bmi Tx port */ - setbits_be32(&fm_eth->tx_port->fmbm_tcfg, FMBM_TCFG_EN); - /* re-enable transmission of frame */ - fmc_tx_port_graceful_stop_disable(fm_eth); - -#ifdef CONFIG_PHYLIB - ret = phy_startup(fm_eth->phydev); - if (ret) { - printf("%s: Could not initialize\n", fm_eth->phydev->dev->name); - return ret; - } -#else - fm_eth->phydev->speed = SPEED_1000; - fm_eth->phydev->link = 1; - fm_eth->phydev->duplex = DUPLEX_FULL; -#endif - - /* set the MAC-PHY mode */ - mac->set_if_mode(mac, fm_eth->enet_if, fm_eth->phydev->speed); - - if (!fm_eth->phydev->link) - printf("%s: No link.\n", fm_eth->phydev->dev->name); - - return fm_eth->phydev->link ? 0 : -1; -} - -static void fm_eth_halt(struct eth_device *dev) -{ - struct fm_eth *fm_eth; - struct fsl_enet_mac *mac; - - fm_eth = (struct fm_eth *)dev->priv; - mac = fm_eth->mac; - - /* graceful stop the transmission of frames */ - fmc_tx_port_graceful_stop_enable(fm_eth); - /* disable bmi Tx port */ - bmi_tx_port_disable(fm_eth->tx_port); - /* disable MAC rx/tx port */ - mac->disable_mac(mac); - /* disable bmi Rx port */ - bmi_rx_port_disable(fm_eth->rx_port); - - phy_shutdown(fm_eth->phydev); -} - -static int fm_eth_send(struct eth_device *dev, void *buf, int len) -{ - struct fm_eth *fm_eth; - struct fm_port_global_pram *pram; - struct fm_port_bd *txbd, *txbd_base; - u16 offset_in; - int i; - - fm_eth = (struct fm_eth *)dev->priv; - pram = fm_eth->tx_pram; - txbd = fm_eth->cur_txbd; - - /* find one empty TxBD */ - for (i = 0; txbd->status & TxBD_READY; i++) { - udelay(100); - if (i > 0x1000) { - printf("%s: Tx buffer not ready\n", dev->name); - return 0; - } - } - /* setup TxBD */ - txbd->buf_ptr_hi = 0; - txbd->buf_ptr_lo = (u32)buf; - txbd->len = len; - sync(); - txbd->status = TxBD_READY | TxBD_LAST; - sync(); - - /* update TxQD, let RISC to send the packet */ - offset_in = muram_readw(&pram->txqd.offset_in); - offset_in += sizeof(struct fm_port_bd); - if (offset_in >= muram_readw(&pram->txqd.bd_ring_size)) - offset_in = 0; - muram_writew(&pram->txqd.offset_in, offset_in); - sync(); - - /* wait for buffer to be transmitted */ - for (i = 0; txbd->status & TxBD_READY; i++) { - udelay(100); - if (i > 0x10000) { - printf("%s: Tx error\n", dev->name); - return 0; - } - } - - /* advance the TxBD */ - txbd++; - txbd_base = (struct fm_port_bd *)fm_eth->tx_bd_ring; - if (txbd >= (txbd_base + TX_BD_RING_SIZE)) - txbd = txbd_base; - /* update current txbd */ - fm_eth->cur_txbd = (void *)txbd; - - return 1; -} - -static int fm_eth_recv(struct eth_device *dev) -{ - struct fm_eth *fm_eth; - struct fm_port_global_pram *pram; - struct fm_port_bd *rxbd, *rxbd_base; - u16 status, len; - u8 *data; - u16 offset_out; - - fm_eth = (struct fm_eth *)dev->priv; - pram = fm_eth->rx_pram; - rxbd = fm_eth->cur_rxbd; - status = rxbd->status; - - while (!(status & RxBD_EMPTY)) { - if (!(status & RxBD_ERROR)) { - data = (u8 *)rxbd->buf_ptr_lo; - len = rxbd->len; - NetReceive(data, len); - } else { - printf("%s: Rx error\n", dev->name); - return 0; - } - - /* clear the RxBDs */ - rxbd->status = RxBD_EMPTY; - rxbd->len = 0; - sync(); - - /* advance RxBD */ - rxbd++; - rxbd_base = (struct fm_port_bd *)fm_eth->rx_bd_ring; - if (rxbd >= (rxbd_base + RX_BD_RING_SIZE)) - rxbd = rxbd_base; - /* read next status */ - status = rxbd->status; - - /* update RxQD */ - offset_out = muram_readw(&pram->rxqd.offset_out); - offset_out += sizeof(struct fm_port_bd); - if (offset_out >= muram_readw(&pram->rxqd.bd_ring_size)) - offset_out = 0; - muram_writew(&pram->rxqd.offset_out, offset_out); - sync(); - } - fm_eth->cur_rxbd = (void *)rxbd; - - return 1; -} - -static int fm_eth_init_mac(struct fm_eth *fm_eth, struct ccsr_fman *reg) -{ - struct fsl_enet_mac *mac; - int num; - void *base, *phyregs = NULL; - - num = fm_eth->num; - -#ifdef CONFIG_SYS_FMAN_V3 - if (fm_eth->type == FM_ETH_10G_E) { - /* 10GEC1/10GEC2 use mEMAC9/mEMAC10 - * 10GEC3/10GEC4 use mEMAC1/mEMAC2 - * so it needs to change the num. - */ - if (fm_eth->num >= 2) - num -= 2; - else - num += 8; - } - base = ®->memac[num].fm_memac; - phyregs = ®->memac[num].fm_memac_mdio; -#else - /* Get the mac registers base address */ - if (fm_eth->type == FM_ETH_1G_E) { - base = ®->mac_1g[num].fm_dtesc; - phyregs = ®->mac_1g[num].fm_mdio.miimcfg; - } else { - base = ®->mac_10g[num].fm_10gec; - phyregs = ®->mac_10g[num].fm_10gec_mdio; - } -#endif - - /* alloc mac controller */ - mac = malloc(sizeof(struct fsl_enet_mac)); - if (!mac) - return 0; - memset(mac, 0, sizeof(struct fsl_enet_mac)); - - /* save the mac to fm_eth struct */ - fm_eth->mac = mac; - -#ifdef CONFIG_SYS_FMAN_V3 - init_memac(mac, base, phyregs, MAX_RXBUF_LEN); -#else - if (fm_eth->type == FM_ETH_1G_E) - init_dtsec(mac, base, phyregs, MAX_RXBUF_LEN); - else - init_tgec(mac, base, phyregs, MAX_RXBUF_LEN); -#endif - - return 1; -} - -static int init_phy(struct eth_device *dev) -{ - struct fm_eth *fm_eth = dev->priv; - struct phy_device *phydev = NULL; - u32 supported; - -#ifdef CONFIG_PHYLIB - if (fm_eth->type == FM_ETH_1G_E) - dtsec_init_phy(dev); - - if (fm_eth->bus) { - phydev = phy_connect(fm_eth->bus, fm_eth->phyaddr, dev, - fm_eth->enet_if); - } - - if (!phydev) { - printf("Failed to connect\n"); - return -1; - } - - if (fm_eth->type == FM_ETH_1G_E) { - supported = (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full); - } else { - supported = SUPPORTED_10000baseT_Full; - - if (tgec_is_fibre(dev)) - phydev->port = PORT_FIBRE; - } - - phydev->supported &= supported; - phydev->advertising = phydev->supported; - - fm_eth->phydev = phydev; - - phy_config(phydev); -#endif - - return 0; -} - -int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info) -{ - struct eth_device *dev; - struct fm_eth *fm_eth; - int i, num = info->num; - - /* alloc eth device */ - dev = (struct eth_device *)malloc(sizeof(struct eth_device)); - if (!dev) - return 0; - memset(dev, 0, sizeof(struct eth_device)); - - /* alloc the FMan ethernet private struct */ - fm_eth = (struct fm_eth *)malloc(sizeof(struct fm_eth)); - if (!fm_eth) - return 0; - memset(fm_eth, 0, sizeof(struct fm_eth)); - - /* save off some things we need from the info struct */ - fm_eth->fm_index = info->index - 1; /* keep as 0 based for muram */ - fm_eth->num = num; - fm_eth->type = info->type; - - fm_eth->rx_port = (void *)®->port[info->rx_port_id - 1].fm_bmi; - fm_eth->tx_port = (void *)®->port[info->tx_port_id - 1].fm_bmi; - - /* set the ethernet max receive length */ - fm_eth->max_rx_len = MAX_RXBUF_LEN; - - /* init global mac structure */ - if (!fm_eth_init_mac(fm_eth, reg)) - return 0; - - /* keep same as the manual, we call FMAN1, FMAN2, DTSEC1, DTSEC2, etc */ - if (fm_eth->type == FM_ETH_1G_E) - sprintf(dev->name, "FM%d@DTSEC%d", info->index, num + 1); - else - sprintf(dev->name, "FM%d@TGEC%d", info->index, num + 1); - - devlist[num_controllers++] = dev; - dev->iobase = 0; - dev->priv = (void *)fm_eth; - dev->init = fm_eth_open; - dev->halt = fm_eth_halt; - dev->send = fm_eth_send; - dev->recv = fm_eth_recv; - fm_eth->dev = dev; - fm_eth->bus = info->bus; - fm_eth->phyaddr = info->phy_addr; - fm_eth->enet_if = info->enet_if; - - /* startup the FM im */ - if (!fm_eth_startup(fm_eth)) - return 0; - - if (init_phy(dev)) - return 0; - - /* clear the ethernet address */ - for (i = 0; i < 6; i++) - dev->enetaddr[i] = 0; - eth_register(dev); - - return 1; -} diff --git a/qemu/roms/u-boot/drivers/net/fm/fm.c b/qemu/roms/u-boot/drivers/net/fm/fm.c deleted file mode 100644 index 400e9dd5e..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/fm.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Copyright 2009-2011 Freescale Semiconductor, Inc. - * Dave Liu <daveliu@freescale.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> -#include <malloc.h> -#include <asm/io.h> -#include <asm/errno.h> - -#include "fm.h" -#include "../../qe/qe.h" /* For struct qe_firmware */ - -#ifdef CONFIG_SYS_QE_FMAN_FW_IN_NAND -#include <nand.h> -#elif defined(CONFIG_SYS_QE_FW_IN_SPIFLASH) -#include <spi_flash.h> -#elif defined(CONFIG_SYS_QE_FMAN_FW_IN_MMC) -#include <mmc.h> -#endif - -struct fm_muram muram[CONFIG_SYS_NUM_FMAN]; - -u32 fm_muram_base(int fm_idx) -{ - return muram[fm_idx].base; -} - -u32 fm_muram_alloc(int fm_idx, u32 size, u32 align) -{ - u32 ret; - u32 align_mask, off; - u32 save; - - align_mask = align - 1; - save = muram[fm_idx].alloc; - - off = save & align_mask; - if (off != 0) - muram[fm_idx].alloc += (align - off); - off = size & align_mask; - if (off != 0) - size += (align - off); - if ((muram[fm_idx].alloc + size) >= muram[fm_idx].top) { - muram[fm_idx].alloc = save; - printf("%s: run out of ram.\n", __func__); - } - - ret = muram[fm_idx].alloc; - muram[fm_idx].alloc += size; - memset((void *)ret, 0, size); - - return ret; -} - -static void fm_init_muram(int fm_idx, void *reg) -{ - u32 base = (u32)reg; - - muram[fm_idx].base = base; - muram[fm_idx].size = CONFIG_SYS_FM_MURAM_SIZE; - muram[fm_idx].alloc = base + FM_MURAM_RES_SIZE; - muram[fm_idx].top = base + CONFIG_SYS_FM_MURAM_SIZE; -} - -/* - * fm_upload_ucode - Fman microcode upload worker function - * - * This function does the actual uploading of an Fman microcode - * to an Fman. - */ -static void fm_upload_ucode(int fm_idx, struct fm_imem *imem, - u32 *ucode, unsigned int size) -{ - unsigned int i; - unsigned int timeout = 1000000; - - /* enable address auto increase */ - out_be32(&imem->iadd, IRAM_IADD_AIE); - /* write microcode to IRAM */ - for (i = 0; i < size / 4; i++) - out_be32(&imem->idata, ucode[i]); - - /* verify if the writing is over */ - out_be32(&imem->iadd, 0); - while ((in_be32(&imem->idata) != ucode[0]) && --timeout) - ; - if (!timeout) - printf("Fman%u: microcode upload timeout\n", fm_idx + 1); - - /* enable microcode from IRAM */ - out_be32(&imem->iready, IRAM_READY); -} - -/* - * Upload an Fman firmware - * - * This function is similar to qe_upload_firmware(), exception that it uploads - * a microcode to the Fman instead of the QE. - * - * Because the process for uploading a microcode to the Fman is similar for - * that of the QE, the QE firmware binary format is used for Fman microcode. - * It should be possible to unify these two functions, but for now we keep them - * separate. - */ -static int fman_upload_firmware(int fm_idx, - struct fm_imem *fm_imem, - const struct qe_firmware *firmware) -{ - unsigned int i; - u32 crc; - size_t calc_size = sizeof(struct qe_firmware); - size_t length; - const struct qe_header *hdr; - - if (!firmware) { - printf("Fman%u: Invalid address for firmware\n", fm_idx + 1); - return -EINVAL; - } - - hdr = &firmware->header; - length = be32_to_cpu(hdr->length); - - /* Check the magic */ - if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') || - (hdr->magic[2] != 'F')) { - printf("Fman%u: Data at %p is not a firmware\n", fm_idx + 1, - firmware); - return -EPERM; - } - - /* Check the version */ - if (hdr->version != 1) { - printf("Fman%u: Unsupported firmware version %u\n", fm_idx + 1, - hdr->version); - return -EPERM; - } - - /* Validate some of the fields */ - if ((firmware->count != 1)) { - printf("Fman%u: Invalid data in firmware header\n", fm_idx + 1); - return -EINVAL; - } - - /* Validate the length and check if there's a CRC */ - calc_size += (firmware->count - 1) * sizeof(struct qe_microcode); - - for (i = 0; i < firmware->count; i++) - /* - * For situations where the second RISC uses the same microcode - * as the first, the 'code_offset' and 'count' fields will be - * zero, so it's okay to add those. - */ - calc_size += sizeof(u32) * - be32_to_cpu(firmware->microcode[i].count); - - /* Validate the length */ - if (length != calc_size + sizeof(u32)) { - printf("Fman%u: Invalid length in firmware header\n", - fm_idx + 1); - return -EPERM; - } - - /* - * Validate the CRC. We would normally call crc32_no_comp(), but that - * function isn't available unless you turn on JFFS support. - */ - crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size)); - if (crc != (crc32(-1, (const void *)firmware, calc_size) ^ -1)) { - printf("Fman%u: Firmware CRC is invalid\n", fm_idx + 1); - return -EIO; - } - - /* Loop through each microcode. */ - for (i = 0; i < firmware->count; i++) { - const struct qe_microcode *ucode = &firmware->microcode[i]; - - /* Upload a microcode if it's present */ - if (ucode->code_offset) { - u32 ucode_size; - u32 *code; - printf("Fman%u: Uploading microcode version %u.%u.%u\n", - fm_idx + 1, ucode->major, ucode->minor, - ucode->revision); - code = (void *)firmware + ucode->code_offset; - ucode_size = sizeof(u32) * ucode->count; - fm_upload_ucode(fm_idx, fm_imem, code, ucode_size); - } - } - - return 0; -} - -static u32 fm_assign_risc(int port_id) -{ - u32 risc_sel, val; - risc_sel = (port_id & 0x1) ? FMFPPRC_RISC2 : FMFPPRC_RISC1; - val = (port_id << FMFPPRC_PORTID_SHIFT) & FMFPPRC_PORTID_MASK; - val |= ((risc_sel << FMFPPRC_ORA_SHIFT) | risc_sel); - - return val; -} - -static void fm_init_fpm(struct fm_fpm *fpm) -{ - int i, port_id; - u32 val; - - setbits_be32(&fpm->fmfpee, FMFPEE_EHM | FMFPEE_UEC | - FMFPEE_CER | FMFPEE_DER); - - /* IM mode, each even port ID to RISC#1, each odd port ID to RISC#2 */ - - /* offline/parser port */ - for (i = 0; i < MAX_NUM_OH_PORT; i++) { - port_id = OH_PORT_ID_BASE + i; - val = fm_assign_risc(port_id); - out_be32(&fpm->fpmprc, val); - } - /* Rx 1G port */ - for (i = 0; i < MAX_NUM_RX_PORT_1G; i++) { - port_id = RX_PORT_1G_BASE + i; - val = fm_assign_risc(port_id); - out_be32(&fpm->fpmprc, val); - } - /* Tx 1G port */ - for (i = 0; i < MAX_NUM_TX_PORT_1G; i++) { - port_id = TX_PORT_1G_BASE + i; - val = fm_assign_risc(port_id); - out_be32(&fpm->fpmprc, val); - } - /* Rx 10G port */ - port_id = RX_PORT_10G_BASE; - val = fm_assign_risc(port_id); - out_be32(&fpm->fpmprc, val); - /* Tx 10G port */ - port_id = TX_PORT_10G_BASE; - val = fm_assign_risc(port_id); - out_be32(&fpm->fpmprc, val); - - /* disable the dispatch limit in IM case */ - out_be32(&fpm->fpmflc, FMFP_FLC_DISP_LIM_NONE); - /* clear events */ - out_be32(&fpm->fmfpee, FMFPEE_CLEAR_EVENT); - - /* clear risc events */ - for (i = 0; i < 4; i++) - out_be32(&fpm->fpmcev[i], 0xffffffff); - - /* clear error */ - out_be32(&fpm->fpmrcr, FMFP_RCR_MDEC | FMFP_RCR_IDEC); -} - -static int fm_init_bmi(int fm_idx, struct fm_bmi_common *bmi) -{ - int blk, i, port_id; - u32 val, offset, base; - - /* alloc free buffer pool in MURAM */ - base = fm_muram_alloc(fm_idx, FM_FREE_POOL_SIZE, FM_FREE_POOL_ALIGN); - if (!base) { - printf("%s: no muram for free buffer pool\n", __func__); - return -ENOMEM; - } - offset = base - fm_muram_base(fm_idx); - - /* Need 128KB total free buffer pool size */ - val = offset / 256; - blk = FM_FREE_POOL_SIZE / 256; - /* in IM, we must not begin from offset 0 in MURAM */ - val |= ((blk - 1) << FMBM_CFG1_FBPS_SHIFT); - out_be32(&bmi->fmbm_cfg1, val); - - /* disable all BMI interrupt */ - out_be32(&bmi->fmbm_ier, FMBM_IER_DISABLE_ALL); - - /* clear all events */ - out_be32(&bmi->fmbm_ievr, FMBM_IEVR_CLEAR_ALL); - - /* - * set port parameters - FMBM_PP_x - * max tasks 10G Rx/Tx=12, 1G Rx/Tx 4, others is 1 - * max dma 10G Rx/Tx=3, others is 1 - * set port FIFO size - FMBM_PFS_x - * 4KB for all Rx and Tx ports - */ - /* offline/parser port */ - for (i = 0; i < MAX_NUM_OH_PORT; i++) { - port_id = OH_PORT_ID_BASE + i - 1; - /* max tasks=1, max dma=1, no extra */ - out_be32(&bmi->fmbm_pp[port_id], 0); - /* port FIFO size - 256 bytes, no extra */ - out_be32(&bmi->fmbm_pfs[port_id], 0); - } - /* Rx 1G port */ - for (i = 0; i < MAX_NUM_RX_PORT_1G; i++) { - port_id = RX_PORT_1G_BASE + i - 1; - /* max tasks=4, max dma=1, no extra */ - out_be32(&bmi->fmbm_pp[port_id], FMBM_PP_MXT(4)); - /* FIFO size - 4KB, no extra */ - out_be32(&bmi->fmbm_pfs[port_id], FMBM_PFS_IFSZ(0xf)); - } - /* Tx 1G port FIFO size - 4KB, no extra */ - for (i = 0; i < MAX_NUM_TX_PORT_1G; i++) { - port_id = TX_PORT_1G_BASE + i - 1; - /* max tasks=4, max dma=1, no extra */ - out_be32(&bmi->fmbm_pp[port_id], FMBM_PP_MXT(4)); - /* FIFO size - 4KB, no extra */ - out_be32(&bmi->fmbm_pfs[port_id], FMBM_PFS_IFSZ(0xf)); - } - /* Rx 10G port */ - port_id = RX_PORT_10G_BASE - 1; - /* max tasks=12, max dma=3, no extra */ - out_be32(&bmi->fmbm_pp[port_id], FMBM_PP_MXT(12) | FMBM_PP_MXD(3)); - /* FIFO size - 4KB, no extra */ - out_be32(&bmi->fmbm_pfs[port_id], FMBM_PFS_IFSZ(0xf)); - - /* Tx 10G port */ - port_id = TX_PORT_10G_BASE - 1; - /* max tasks=12, max dma=3, no extra */ - out_be32(&bmi->fmbm_pp[port_id], FMBM_PP_MXT(12) | FMBM_PP_MXD(3)); - /* FIFO size - 4KB, no extra */ - out_be32(&bmi->fmbm_pfs[port_id], FMBM_PFS_IFSZ(0xf)); - - /* initialize internal buffers data base (linked list) */ - out_be32(&bmi->fmbm_init, FMBM_INIT_START); - - return 0; -} - -static void fm_init_qmi(struct fm_qmi_common *qmi) -{ - /* disable enqueue and dequeue of QMI */ - clrbits_be32(&qmi->fmqm_gc, FMQM_GC_ENQ_EN | FMQM_GC_DEQ_EN); - - /* disable all error interrupts */ - out_be32(&qmi->fmqm_eien, FMQM_EIEN_DISABLE_ALL); - /* clear all error events */ - out_be32(&qmi->fmqm_eie, FMQM_EIE_CLEAR_ALL); - - /* disable all interrupts */ - out_be32(&qmi->fmqm_ien, FMQM_IEN_DISABLE_ALL); - /* clear all interrupts */ - out_be32(&qmi->fmqm_ie, FMQM_IE_CLEAR_ALL); -} - -/* Init common part of FM, index is fm num# like fm as above */ -int fm_init_common(int index, struct ccsr_fman *reg) -{ - int rc; -#if defined(CONFIG_SYS_QE_FMAN_FW_IN_NOR) - void *addr = (void *)CONFIG_SYS_FMAN_FW_ADDR; -#elif defined(CONFIG_SYS_QE_FMAN_FW_IN_NAND) - size_t fw_length = CONFIG_SYS_QE_FMAN_FW_LENGTH; - void *addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH); - - rc = nand_read(&nand_info[0], (loff_t)CONFIG_SYS_FMAN_FW_ADDR, - &fw_length, (u_char *)addr); - if (rc == -EUCLEAN) { - printf("NAND read of FMAN firmware at offset 0x%x failed %d\n", - CONFIG_SYS_FMAN_FW_ADDR, rc); - } -#elif defined(CONFIG_SYS_QE_FW_IN_SPIFLASH) - struct spi_flash *ucode_flash; - void *addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH); - int ret = 0; - - ucode_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, - CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE); - if (!ucode_flash) - printf("SF: probe for ucode failed\n"); - else { - ret = spi_flash_read(ucode_flash, CONFIG_SYS_FMAN_FW_ADDR, - CONFIG_SYS_QE_FMAN_FW_LENGTH, addr); - if (ret) - printf("SF: read for ucode failed\n"); - spi_flash_free(ucode_flash); - } -#elif defined(CONFIG_SYS_QE_FMAN_FW_IN_MMC) - int dev = CONFIG_SYS_MMC_ENV_DEV; - void *addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH); - u32 cnt = CONFIG_SYS_QE_FMAN_FW_LENGTH / 512; - u32 blk = CONFIG_SYS_FMAN_FW_ADDR / 512; - struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); - - if (!mmc) - printf("\nMMC cannot find device for ucode\n"); - else { - printf("\nMMC read: dev # %u, block # %u, count %u ...\n", - dev, blk, cnt); - mmc_init(mmc); - (void)mmc->block_dev.block_read(dev, blk, cnt, addr); - /* flush cache after read */ - flush_cache((ulong)addr, cnt * 512); - } -#elif defined(CONFIG_SYS_QE_FMAN_FW_IN_REMOTE) - void *addr = (void *)CONFIG_SYS_FMAN_FW_ADDR; -#else - void *addr = NULL; -#endif - - /* Upload the Fman microcode if it's present */ - rc = fman_upload_firmware(index, ®->fm_imem, addr); - if (rc) - return rc; - setenv_addr("fman_ucode", addr); - - fm_init_muram(index, ®->muram); - fm_init_qmi(®->fm_qmi_common); - fm_init_fpm(®->fm_fpm); - - /* clear DMA status */ - setbits_be32(®->fm_dma.fmdmsr, FMDMSR_CLEAR_ALL); - - /* set DMA mode */ - setbits_be32(®->fm_dma.fmdmmr, FMDMMR_SBER); - - return fm_init_bmi(index, ®->fm_bmi_common); -} diff --git a/qemu/roms/u-boot/drivers/net/fm/fm.h b/qemu/roms/u-boot/drivers/net/fm/fm.h deleted file mode 100644 index 43de114b5..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/fm.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright 2009-2011 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __FM_H__ -#define __FM_H__ - -#include <common.h> -#include <fm_eth.h> -#include <asm/fsl_enet.h> -#include <asm/fsl_fman.h> - -/* Port ID */ -#define OH_PORT_ID_BASE 0x01 -#define MAX_NUM_OH_PORT 7 -#define RX_PORT_1G_BASE 0x08 -#define MAX_NUM_RX_PORT_1G CONFIG_SYS_NUM_FM1_DTSEC -#define RX_PORT_10G_BASE 0x10 -#define RX_PORT_10G_BASE2 0x08 -#define TX_PORT_1G_BASE 0x28 -#define MAX_NUM_TX_PORT_1G CONFIG_SYS_NUM_FM1_DTSEC -#define TX_PORT_10G_BASE 0x30 -#define TX_PORT_10G_BASE2 0x28 -#define MIIM_TIMEOUT 0xFFFF - -struct fm_muram { - u32 base; - u32 top; - u32 size; - u32 alloc; -}; -#define FM_MURAM_RES_SIZE 0x01000 - -/* Rx/Tx buffer descriptor */ -struct fm_port_bd { - u16 status; - u16 len; - u32 res0; - u16 res1; - u16 buf_ptr_hi; - u32 buf_ptr_lo; -}; - -/* Common BD flags */ -#define BD_LAST 0x0800 - -/* Rx BD status flags */ -#define RxBD_EMPTY 0x8000 -#define RxBD_LAST BD_LAST -#define RxBD_FIRST 0x0400 -#define RxBD_PHYS_ERR 0x0008 -#define RxBD_SIZE_ERR 0x0004 -#define RxBD_ERROR (RxBD_PHYS_ERR | RxBD_SIZE_ERR) - -/* Tx BD status flags */ -#define TxBD_READY 0x8000 -#define TxBD_LAST BD_LAST - -/* Rx/Tx queue descriptor */ -struct fm_port_qd { - u16 gen; - u16 bd_ring_base_hi; - u32 bd_ring_base_lo; - u16 bd_ring_size; - u16 offset_in; - u16 offset_out; - u16 res0; - u32 res1[0x4]; -}; - -/* IM global parameter RAM */ -struct fm_port_global_pram { - u32 mode; /* independent mode register */ - u32 rxqd_ptr; /* Rx queue descriptor pointer */ - u32 txqd_ptr; /* Tx queue descriptor pointer */ - u16 mrblr; /* max Rx buffer length */ - u16 rxqd_bsy_cnt; /* RxQD busy counter, should be cleared */ - u32 res0[0x4]; - struct fm_port_qd rxqd; /* Rx queue descriptor */ - struct fm_port_qd txqd; /* Tx queue descriptor */ - u32 res1[0x28]; -}; - -#define FM_PRAM_SIZE sizeof(struct fm_port_global_pram) -#define FM_PRAM_ALIGN 256 -#define PRAM_MODE_GLOBAL 0x20000000 -#define PRAM_MODE_GRACEFUL_STOP 0x00800000 - -#if defined(CONFIG_P1017) || defined(CONFIG_P1023) -#define FM_FREE_POOL_SIZE 0x2000 /* 8K bytes */ -#else -#define FM_FREE_POOL_SIZE 0x20000 /* 128K bytes */ -#endif -#define FM_FREE_POOL_ALIGN 256 - -u32 fm_muram_alloc(int fm_idx, u32 size, u32 align); -u32 fm_muram_base(int fm_idx); -int fm_init_common(int index, struct ccsr_fman *reg); -int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info); -phy_interface_t fman_port_enet_if(enum fm_port port); -void fman_disable_port(enum fm_port port); -void fman_enable_port(enum fm_port port); - -struct fsl_enet_mac { - void *base; /* MAC controller registers base address */ - void *phyregs; - int max_rx_len; - void (*init_mac)(struct fsl_enet_mac *mac); - void (*enable_mac)(struct fsl_enet_mac *mac); - void (*disable_mac)(struct fsl_enet_mac *mac); - void (*set_mac_addr)(struct fsl_enet_mac *mac, u8 *mac_addr); - void (*set_if_mode)(struct fsl_enet_mac *mac, phy_interface_t type, - int speed); -}; - -/* Fman ethernet private struct */ -struct fm_eth { - int fm_index; /* Fman index */ - u32 num; /* 0..n-1 for give type */ - struct fm_bmi_tx_port *tx_port; - struct fm_bmi_rx_port *rx_port; - enum fm_eth_type type; /* 1G or 10G ethernet */ - phy_interface_t enet_if; - struct fsl_enet_mac *mac; /* MAC controller */ - struct mii_dev *bus; - struct phy_device *phydev; - int phyaddr; - struct eth_device *dev; - int max_rx_len; - struct fm_port_global_pram *rx_pram; /* Rx parameter table */ - struct fm_port_global_pram *tx_pram; /* Tx parameter table */ - void *rx_bd_ring; /* Rx BD ring base */ - void *cur_rxbd; /* current Rx BD */ - void *rx_buf; /* Rx buffer base */ - void *tx_bd_ring; /* Tx BD ring base */ - void *cur_txbd; /* current Tx BD */ -}; - -#define RX_BD_RING_SIZE 8 -#define TX_BD_RING_SIZE 8 -#define MAX_RXBUF_LOG2 11 -#define MAX_RXBUF_LEN (1 << MAX_RXBUF_LOG2) - -#define PORT_IS_ENABLED(port) fm_info[fm_port_to_index(port)].enabled - -#endif /* __FM_H__ */ diff --git a/qemu/roms/u-boot/drivers/net/fm/init.c b/qemu/roms/u-boot/drivers/net/fm/init.c deleted file mode 100644 index cd787f4ee..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/init.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> -#include <asm/io.h> -#include <asm/fsl_serdes.h> - -#include "fm.h" - -struct fm_eth_info fm_info[] = { -#if (CONFIG_SYS_NUM_FM1_DTSEC >= 1) - FM_DTSEC_INFO_INITIALIZER(1, 1), -#endif -#if (CONFIG_SYS_NUM_FM1_DTSEC >= 2) - FM_DTSEC_INFO_INITIALIZER(1, 2), -#endif -#if (CONFIG_SYS_NUM_FM1_DTSEC >= 3) - FM_DTSEC_INFO_INITIALIZER(1, 3), -#endif -#if (CONFIG_SYS_NUM_FM1_DTSEC >= 4) - FM_DTSEC_INFO_INITIALIZER(1, 4), -#endif -#if (CONFIG_SYS_NUM_FM1_DTSEC >= 5) - FM_DTSEC_INFO_INITIALIZER(1, 5), -#endif -#if (CONFIG_SYS_NUM_FM1_DTSEC >= 6) - FM_DTSEC_INFO_INITIALIZER(1, 6), -#endif -#if (CONFIG_SYS_NUM_FM1_DTSEC >= 7) - FM_DTSEC_INFO_INITIALIZER(1, 9), -#endif -#if (CONFIG_SYS_NUM_FM1_DTSEC >= 8) - FM_DTSEC_INFO_INITIALIZER(1, 10), -#endif -#if (CONFIG_SYS_NUM_FM2_DTSEC >= 1) - FM_DTSEC_INFO_INITIALIZER(2, 1), -#endif -#if (CONFIG_SYS_NUM_FM2_DTSEC >= 2) - FM_DTSEC_INFO_INITIALIZER(2, 2), -#endif -#if (CONFIG_SYS_NUM_FM2_DTSEC >= 3) - FM_DTSEC_INFO_INITIALIZER(2, 3), -#endif -#if (CONFIG_SYS_NUM_FM2_DTSEC >= 4) - FM_DTSEC_INFO_INITIALIZER(2, 4), -#endif -#if (CONFIG_SYS_NUM_FM2_DTSEC >= 5) - FM_DTSEC_INFO_INITIALIZER(2, 5), -#endif -#if (CONFIG_SYS_NUM_FM2_DTSEC >= 6) - FM_DTSEC_INFO_INITIALIZER(2, 6), -#endif -#if (CONFIG_SYS_NUM_FM2_DTSEC >= 7) - FM_DTSEC_INFO_INITIALIZER(2, 9), -#endif -#if (CONFIG_SYS_NUM_FM2_DTSEC >= 8) - FM_DTSEC_INFO_INITIALIZER(2, 10), -#endif -#if (CONFIG_SYS_NUM_FM1_10GEC >= 1) - FM_TGEC_INFO_INITIALIZER(1, 1), -#endif -#if (CONFIG_SYS_NUM_FM1_10GEC >= 2) - FM_TGEC_INFO_INITIALIZER(1, 2), -#endif -#if (CONFIG_SYS_NUM_FM1_10GEC >= 3) - FM_TGEC_INFO_INITIALIZER2(1, 3), -#endif -#if (CONFIG_SYS_NUM_FM1_10GEC >= 4) - FM_TGEC_INFO_INITIALIZER2(1, 4), -#endif -#if (CONFIG_SYS_NUM_FM2_10GEC >= 1) - FM_TGEC_INFO_INITIALIZER(2, 1), -#endif -#if (CONFIG_SYS_NUM_FM2_10GEC >= 2) - FM_TGEC_INFO_INITIALIZER(2, 2), -#endif -}; - -int fm_standard_init(bd_t *bis) -{ - int i; - struct ccsr_fman *reg; - - reg = (void *)CONFIG_SYS_FSL_FM1_ADDR; - if (fm_init_common(0, reg)) - return 0; - - for (i = 0; i < ARRAY_SIZE(fm_info); i++) { - if ((fm_info[i].enabled) && (fm_info[i].index == 1)) - fm_eth_initialize(reg, &fm_info[i]); - } - -#if (CONFIG_SYS_NUM_FMAN == 2) - reg = (void *)CONFIG_SYS_FSL_FM2_ADDR; - if (fm_init_common(1, reg)) - return 0; - - for (i = 0; i < ARRAY_SIZE(fm_info); i++) { - if ((fm_info[i].enabled) && (fm_info[i].index == 2)) - fm_eth_initialize(reg, &fm_info[i]); - } -#endif - - return 1; -} - -/* simple linear search to map from port to array index */ -static int fm_port_to_index(enum fm_port port) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(fm_info); i++) { - if (fm_info[i].port == port) - return i; - } - - return -1; -} - -/* - * Determine if an interface is actually active based on HW config - * we expect fman_port_enet_if() to report PHY_INTERFACE_MODE_NONE if - * the interface is not active based on HW cfg of the SoC - */ -void fman_enet_init(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(fm_info); i++) { - phy_interface_t enet_if; - - enet_if = fman_port_enet_if(fm_info[i].port); - if (enet_if != PHY_INTERFACE_MODE_NONE) { - fm_info[i].enabled = 1; - fm_info[i].enet_if = enet_if; - } else { - fm_info[i].enabled = 0; - } - } - - return ; -} - -void fm_disable_port(enum fm_port port) -{ - int i = fm_port_to_index(port); - - fm_info[i].enabled = 0; - fman_disable_port(port); -} - -void fm_enable_port(enum fm_port port) -{ - int i = fm_port_to_index(port); - - fm_info[i].enabled = 1; - fman_enable_port(port); -} - -void fm_info_set_mdio(enum fm_port port, struct mii_dev *bus) -{ - int i = fm_port_to_index(port); - - if (i == -1) - return; - - fm_info[i].bus = bus; -} - -void fm_info_set_phy_address(enum fm_port port, int address) -{ - int i = fm_port_to_index(port); - - if (i == -1) - return; - - fm_info[i].phy_addr = address; -} - -/* - * Returns the PHY address for a given Fman port - * - * The port must be set via a prior call to fm_info_set_phy_address(). - * A negative error code is returned if the port is invalid. - */ -int fm_info_get_phy_address(enum fm_port port) -{ - int i = fm_port_to_index(port); - - if (i == -1) - return -1; - - return fm_info[i].phy_addr; -} - -/* - * Returns the type of the data interface between the given MAC and its PHY. - * This is typically determined by the RCW. - */ -phy_interface_t fm_info_get_enet_if(enum fm_port port) -{ - int i = fm_port_to_index(port); - - if (i == -1) - return PHY_INTERFACE_MODE_NONE; - - if (fm_info[i].enabled) - return fm_info[i].enet_if; - - return PHY_INTERFACE_MODE_NONE; -} - -static void -__def_board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa, - enum fm_port port, int offset) -{ - return ; -} - -void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa, - enum fm_port port, int offset) - __attribute__((weak, alias("__def_board_ft_fman_fixup_port"))); - -static void ft_fixup_port(void *blob, struct fm_eth_info *info, char *prop) -{ - int off; - uint32_t ph; - phys_addr_t paddr = CONFIG_SYS_CCSRBAR_PHYS + info->compat_offset; - u64 dtsec1_addr = (u64)CONFIG_SYS_CCSRBAR_PHYS + - CONFIG_SYS_FSL_FM1_DTSEC1_OFFSET; - - off = fdt_node_offset_by_compat_reg(blob, prop, paddr); - - if (info->enabled) { - fdt_fixup_phy_connection(blob, off, info->enet_if); - board_ft_fman_fixup_port(blob, prop, paddr, info->port, off); - return ; - } - -#ifdef CONFIG_SYS_FMAN_V3 - /* - * Physically FM1_DTSEC9 and FM1_10GEC1 use the same dual-role MAC, when - * FM1_10GEC1 is enabled and FM1_DTSEC9 is disabled, ensure that the - * dual-role MAC is not disabled, ditto for other dual-role MACs. - */ - if (((info->port == FM1_DTSEC9) && (PORT_IS_ENABLED(FM1_10GEC1))) || - ((info->port == FM1_DTSEC10) && (PORT_IS_ENABLED(FM1_10GEC2))) || - ((info->port == FM1_DTSEC1) && (PORT_IS_ENABLED(FM1_10GEC3))) || - ((info->port == FM1_DTSEC2) && (PORT_IS_ENABLED(FM1_10GEC4))) || - ((info->port == FM1_10GEC1) && (PORT_IS_ENABLED(FM1_DTSEC9))) || - ((info->port == FM1_10GEC2) && (PORT_IS_ENABLED(FM1_DTSEC10))) || - ((info->port == FM1_10GEC3) && (PORT_IS_ENABLED(FM1_DTSEC1))) || - ((info->port == FM1_10GEC4) && (PORT_IS_ENABLED(FM1_DTSEC2))) -#if (CONFIG_SYS_NUM_FMAN == 2) - || - ((info->port == FM2_DTSEC9) && (PORT_IS_ENABLED(FM2_10GEC1))) || - ((info->port == FM2_DTSEC10) && (PORT_IS_ENABLED(FM2_10GEC2))) || - ((info->port == FM2_10GEC1) && (PORT_IS_ENABLED(FM2_DTSEC9))) || - ((info->port == FM2_10GEC2) && (PORT_IS_ENABLED(FM2_DTSEC10))) -#endif - ) - return; -#endif - /* board code might have caused offset to change */ - off = fdt_node_offset_by_compat_reg(blob, prop, paddr); - - /* Don't disable FM1-DTSEC1 MAC as its used for MDIO */ - if (paddr != dtsec1_addr) - fdt_status_disabled(blob, off); /* disable the MAC node */ - - /* disable the fsl,dpa-ethernet node that points to the MAC */ - ph = fdt_get_phandle(blob, off); - do_fixup_by_prop(blob, "fsl,fman-mac", &ph, sizeof(ph), - "status", "disabled", strlen("disabled") + 1, 1); -} - -void fdt_fixup_fman_ethernet(void *blob) -{ - int i; - -#ifdef CONFIG_SYS_FMAN_V3 - for (i = 0; i < ARRAY_SIZE(fm_info); i++) - ft_fixup_port(blob, &fm_info[i], "fsl,fman-memac"); -#else - for (i = 0; i < ARRAY_SIZE(fm_info); i++) { - if (fm_info[i].type == FM_ETH_1G_E) - ft_fixup_port(blob, &fm_info[i], "fsl,fman-1g-mac"); - else - ft_fixup_port(blob, &fm_info[i], "fsl,fman-10g-mac"); - } -#endif -} - -/*QSGMII Riser Card can work in SGMII mode, but the PHY address is different. - *This function scans which Riser Card being used(QSGMII or SGMII Riser Card), - *then set the correct PHY address - */ -void set_sgmii_phy(struct mii_dev *bus, enum fm_port base_port, - unsigned int port_num, int phy_base_addr) -{ - unsigned int regnum = 0; - int qsgmii; - int i; - int phy_real_addr; - - qsgmii = is_qsgmii_riser_card(bus, phy_base_addr, port_num, regnum); - - if (!qsgmii) - return; - - for (i = base_port; i < base_port + port_num; i++) { - if (fm_info_get_enet_if(i) == PHY_INTERFACE_MODE_SGMII) { - phy_real_addr = phy_base_addr + i - base_port; - fm_info_set_phy_address(i, phy_real_addr); - } - } -} - -/*to check whether qsgmii riser card is used*/ -int is_qsgmii_riser_card(struct mii_dev *bus, int phy_base_addr, - unsigned int port_num, unsigned regnum) -{ - int i; - int val; - - if (!bus) - return 0; - - for (i = phy_base_addr; i < phy_base_addr + port_num; i++) { - val = bus->read(bus, i, MDIO_DEVAD_NONE, regnum); - if (val != MIIM_TIMEOUT) - return 1; - } - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/fm/memac.c b/qemu/roms/u-boot/drivers/net/fm/memac.c deleted file mode 100644 index 592a67f2a..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/memac.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * Roy Zang <tie-fei.zang@freescale.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* MAXFRM - maximum frame length */ -#define MAXFRM_MASK 0x0000ffff - -#include <common.h> -#include <phy.h> -#include <asm/types.h> -#include <asm/io.h> -#include <asm/fsl_enet.h> -#include <asm/fsl_memac.h> - -#include "fm.h" - -static void memac_init_mac(struct fsl_enet_mac *mac) -{ - struct memac *regs = mac->base; - - /* mask all interrupt */ - out_be32(®s->imask, IMASK_MASK_ALL); - - /* clear all events */ - out_be32(®s->ievent, IEVENT_CLEAR_ALL); - - /* set the max receive length */ - out_be32(®s->maxfrm, mac->max_rx_len & MAXFRM_MASK); - - /* multicast frame reception for the hash entry disable */ - out_be32(®s->hashtable_ctrl, 0); -} - -static void memac_enable_mac(struct fsl_enet_mac *mac) -{ - struct memac *regs = mac->base; - - setbits_be32(®s->command_config, MEMAC_CMD_CFG_RXTX_EN); -} - -static void memac_disable_mac(struct fsl_enet_mac *mac) -{ - struct memac *regs = mac->base; - - clrbits_be32(®s->command_config, MEMAC_CMD_CFG_RXTX_EN); -} - -static void memac_set_mac_addr(struct fsl_enet_mac *mac, u8 *mac_addr) -{ - struct memac *regs = mac->base; - u32 mac_addr0, mac_addr1; - - /* - * if a station address of 0x12345678ABCD, perform a write to - * MAC_ADDR0 of 0x78563412, MAC_ADDR1 of 0x0000CDAB - */ - mac_addr0 = (mac_addr[3] << 24) | (mac_addr[2] << 16) | \ - (mac_addr[1] << 8) | (mac_addr[0]); - out_be32(®s->mac_addr_0, mac_addr0); - - mac_addr1 = ((mac_addr[5] << 8) | mac_addr[4]) & 0x0000ffff; - out_be32(®s->mac_addr_1, mac_addr1); -} - -static void memac_set_interface_mode(struct fsl_enet_mac *mac, - phy_interface_t type, int speed) -{ - /* Roy need more work here */ - - struct memac *regs = mac->base; - u32 if_mode, if_status; - - /* clear all bits relative with interface mode */ - if_mode = in_be32(®s->if_mode); - if_status = in_be32(®s->if_status); - - /* set interface mode */ - switch (type) { - case PHY_INTERFACE_MODE_GMII: - if_mode &= ~IF_MODE_MASK; - if_mode |= IF_MODE_GMII; - break; - case PHY_INTERFACE_MODE_RGMII: - if_mode |= (IF_MODE_GMII | IF_MODE_RG); - break; - case PHY_INTERFACE_MODE_RMII: - if_mode |= (IF_MODE_GMII | IF_MODE_RM); - break; - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_QSGMII: - if_mode &= ~IF_MODE_MASK; - if_mode |= (IF_MODE_GMII); - break; - default: - break; - } - /* Enable automatic speed selection */ - if_mode |= IF_MODE_EN_AUTO; - - if (type == PHY_INTERFACE_MODE_RGMII) { - if_mode &= ~IF_MODE_EN_AUTO; - if_mode &= ~IF_MODE_SETSP_MASK; - switch (speed) { - case SPEED_1000: - if_mode |= IF_MODE_SETSP_1000M; - break; - case SPEED_100: - if_mode |= IF_MODE_SETSP_100M; - break; - case SPEED_10: - if_mode |= IF_MODE_SETSP_10M; - default: - break; - } - } - - debug(" %s, if_mode = %x\n", __func__, if_mode); - debug(" %s, if_status = %x\n", __func__, if_status); - out_be32(®s->if_mode, if_mode); - return; -} - -void init_memac(struct fsl_enet_mac *mac, void *base, - void *phyregs, int max_rx_len) -{ - mac->base = base; - mac->phyregs = phyregs; - mac->max_rx_len = max_rx_len; - mac->init_mac = memac_init_mac; - mac->enable_mac = memac_enable_mac; - mac->disable_mac = memac_disable_mac; - mac->set_mac_addr = memac_set_mac_addr; - mac->set_if_mode = memac_set_interface_mode; -} diff --git a/qemu/roms/u-boot/drivers/net/fm/memac_phy.c b/qemu/roms/u-boot/drivers/net/fm/memac_phy.c deleted file mode 100644 index de9c0e9cd..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/memac_phy.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * Andy Fleming <afleming@freescale.com> - * Roy Zang <tie-fei.zang@freescale.com> - * - * SPDX-License-Identifier: GPL-2.0+ - * Some part is taken from tsec.c - */ -#include <common.h> -#include <miiphy.h> -#include <phy.h> -#include <asm/io.h> -#include <asm/fsl_memac.h> -#include <fm_eth.h> - -/* - * Write value to the PHY for this device to the register at regnum, waiting - * until the write is done before it returns. All PHY configuration has to be - * done through the TSEC1 MIIM regs - */ -int memac_mdio_write(struct mii_dev *bus, int port_addr, int dev_addr, - int regnum, u16 value) -{ - u32 mdio_ctl; - struct memac_mdio_controller *regs = bus->priv; - u32 c45 = 1; /* Default to 10G interface */ - - if (dev_addr == MDIO_DEVAD_NONE) { - c45 = 0; /* clause 22 */ - dev_addr = regnum & 0x1f; - clrbits_be32(®s->mdio_stat, MDIO_STAT_ENC); - } else - setbits_be32(®s->mdio_stat, MDIO_STAT_ENC); - - /* Wait till the bus is free */ - while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) - ; - - /* Set the port and dev addr */ - mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr); - out_be32(®s->mdio_ctl, mdio_ctl); - - /* Set the register address */ - if (c45) - out_be32(®s->mdio_addr, regnum & 0xffff); - - /* Wait till the bus is free */ - while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) - ; - - /* Write the value to the register */ - out_be32(®s->mdio_data, MDIO_DATA(value)); - - /* Wait till the MDIO write is complete */ - while ((in_be32(®s->mdio_data)) & MDIO_DATA_BSY) - ; - - return 0; -} - -/* - * Reads from register regnum in the PHY for device dev, returning the value. - * Clears miimcom first. All PHY configuration has to be done through the - * TSEC1 MIIM regs - */ -int memac_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr, - int regnum) -{ - u32 mdio_ctl; - struct memac_mdio_controller *regs = bus->priv; - u32 c45 = 1; - - if (dev_addr == MDIO_DEVAD_NONE) { - c45 = 0; /* clause 22 */ - dev_addr = regnum & 0x1f; - clrbits_be32(®s->mdio_stat, MDIO_STAT_ENC); - } else - setbits_be32(®s->mdio_stat, MDIO_STAT_ENC); - - /* Wait till the bus is free */ - while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) - ; - - /* Set the Port and Device Addrs */ - mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr); - out_be32(®s->mdio_ctl, mdio_ctl); - - /* Set the register address */ - if (c45) - out_be32(®s->mdio_addr, regnum & 0xffff); - - /* Wait till the bus is free */ - while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) - ; - - /* Initiate the read */ - mdio_ctl |= MDIO_CTL_READ; - out_be32(®s->mdio_ctl, mdio_ctl); - - /* Wait till the MDIO write is complete */ - while ((in_be32(®s->mdio_data)) & MDIO_DATA_BSY) - ; - - /* Return all Fs if nothing was there */ - if (in_be32(®s->mdio_stat) & MDIO_STAT_RD_ER) - return 0xffff; - - return in_be32(®s->mdio_data) & 0xffff; -} - -int memac_mdio_reset(struct mii_dev *bus) -{ - return 0; -} - -int fm_memac_mdio_init(bd_t *bis, struct memac_mdio_info *info) -{ - struct mii_dev *bus = mdio_alloc(); - - if (!bus) { - printf("Failed to allocate FM TGEC MDIO bus\n"); - return -1; - } - - bus->read = memac_mdio_read; - bus->write = memac_mdio_write; - bus->reset = memac_mdio_reset; - sprintf(bus->name, info->name); - - bus->priv = info->regs; - - /* - * On some platforms like B4860, default value of MDIO_CLK_DIV bits - * in mdio_stat(mdio_cfg) register generates MDIO clock too high - * (much higher than 2.5MHz), violating the IEEE specs. - * On other platforms like T1040, default value of MDIO_CLK_DIV bits - * is zero, so MDIO clock is disabled. - * So, for proper functioning of MDIO, MDIO_CLK_DIV bits needs to - * be properly initialized. - */ - setbits_be32(&((struct memac_mdio_controller *)info->regs)->mdio_stat, - MDIO_STAT_CLKDIV(258)); - - return mdio_register(bus); -} diff --git a/qemu/roms/u-boot/drivers/net/fm/p1023.c b/qemu/roms/u-boot/drivers/net/fm/p1023.c deleted file mode 100644 index b25d10ae0..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/p1023.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> -#include <phy.h> -#include <fm_eth.h> -#include <asm/io.h> -#include <asm/immap_85xx.h> -#include <asm/fsl_serdes.h> - -static u32 port_to_devdisr[] = { - [FM1_DTSEC1] = MPC85xx_DEVDISR_TSEC1, - [FM1_DTSEC2] = MPC85xx_DEVDISR_TSEC2, -}; - -static int is_device_disabled(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 devdisr = in_be32(&gur->devdisr); - - return port_to_devdisr[port] & devdisr; -} - -void fman_disable_port(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - /* don't allow disabling of DTSEC1 as its needed for MDIO */ - if (port == FM1_DTSEC1) - return; - - setbits_be32(&gur->devdisr, port_to_devdisr[port]); -} - -void fman_enable_port(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - clrbits_be32(&gur->devdisr, port_to_devdisr[port]); -} - -phy_interface_t fman_port_enet_if(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 pordevsr = in_be32(&gur->pordevsr); - - if (is_device_disabled(port)) - return PHY_INTERFACE_MODE_NONE; - - /* DTSEC1 can be SGMII, RGMII or RMII */ - if (port == FM1_DTSEC1) { - if (is_serdes_configured(SGMII_FM1_DTSEC1)) - return PHY_INTERFACE_MODE_SGMII; - if (pordevsr & MPC85xx_PORDEVSR_SGMII1_DIS) { - if (pordevsr & MPC85xx_PORDEVSR_TSEC1_PRTC) - return PHY_INTERFACE_MODE_RGMII; - else - return PHY_INTERFACE_MODE_RMII; - } - } - - /* DTSEC2 only supports SGMII or RGMII */ - if (port == FM1_DTSEC2) { - if (is_serdes_configured(SGMII_FM1_DTSEC2)) - return PHY_INTERFACE_MODE_SGMII; - if (pordevsr & MPC85xx_PORDEVSR_SGMII2_DIS) - return PHY_INTERFACE_MODE_RGMII; - } - - return PHY_INTERFACE_MODE_NONE; -} diff --git a/qemu/roms/u-boot/drivers/net/fm/p4080.c b/qemu/roms/u-boot/drivers/net/fm/p4080.c deleted file mode 100644 index de7191135..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/p4080.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> -#include <phy.h> -#include <fm_eth.h> -#include <asm/io.h> -#include <asm/immap_85xx.h> -#include <asm/fsl_serdes.h> - -static u32 port_to_devdisr[] = { - [FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1, - [FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2, - [FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3, - [FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4, - [FM1_10GEC1] = FSL_CORENET_DEVDISR2_10GEC1, - [FM2_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC2_1, - [FM2_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC2_2, - [FM2_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC2_3, - [FM2_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC2_4, - [FM2_10GEC1] = FSL_CORENET_DEVDISR2_10GEC2, -}; - -static int is_device_disabled(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 devdisr2 = in_be32(&gur->devdisr2); - - return port_to_devdisr[port] & devdisr2; -} - -void fman_disable_port(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - /* don't allow disabling of DTSEC1 as its needed for MDIO */ - if (port == FM1_DTSEC1) - return; - - setbits_be32(&gur->devdisr2, port_to_devdisr[port]); -} - -void fman_enable_port(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - clrbits_be32(&gur->devdisr2, port_to_devdisr[port]); -} - -phy_interface_t fman_port_enet_if(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 rcwsr11 = in_be32(&gur->rcwsr[11]); - - if (is_device_disabled(port)) - return PHY_INTERFACE_MODE_NONE; - - if ((port == FM1_10GEC1) && (is_serdes_configured(XAUI_FM1))) - return PHY_INTERFACE_MODE_XGMII; - - if ((port == FM2_10GEC1) && (is_serdes_configured(XAUI_FM2))) - return PHY_INTERFACE_MODE_XGMII; - - /* handle RGMII first */ - if ((port == FM1_DTSEC1) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC1) == - FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1)) - return PHY_INTERFACE_MODE_RGMII; - - if ((port == FM1_DTSEC2) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2)) - return PHY_INTERFACE_MODE_RGMII; - - if ((port == FM2_DTSEC1) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1)) - return PHY_INTERFACE_MODE_RGMII; - - switch (port) { - case FM1_DTSEC1: - case FM1_DTSEC2: - case FM1_DTSEC3: - case FM1_DTSEC4: - if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1)) - return PHY_INTERFACE_MODE_SGMII; - break; - case FM2_DTSEC1: - case FM2_DTSEC2: - case FM2_DTSEC3: - case FM2_DTSEC4: - if (is_serdes_configured(SGMII_FM2_DTSEC1 + port - FM2_DTSEC1)) - return PHY_INTERFACE_MODE_SGMII; - break; - default: - return PHY_INTERFACE_MODE_NONE; - } - - return PHY_INTERFACE_MODE_NONE; -} diff --git a/qemu/roms/u-boot/drivers/net/fm/p5020.c b/qemu/roms/u-boot/drivers/net/fm/p5020.c deleted file mode 100644 index 5c158cd5d..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/p5020.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> -#include <phy.h> -#include <fm_eth.h> -#include <asm/io.h> -#include <asm/immap_85xx.h> -#include <asm/fsl_serdes.h> - -static u32 port_to_devdisr[] = { - [FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1, - [FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2, - [FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3, - [FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4, - [FM1_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC1_5, - [FM1_10GEC1] = FSL_CORENET_DEVDISR2_10GEC1, -}; - -static int is_device_disabled(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 devdisr2 = in_be32(&gur->devdisr2); - - return port_to_devdisr[port] & devdisr2; -} - -void fman_disable_port(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - /* don't allow disabling of DTSEC1 as its needed for MDIO */ - if (port == FM1_DTSEC1) - return; - - setbits_be32(&gur->devdisr2, port_to_devdisr[port]); -} - -void fman_enable_port(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - clrbits_be32(&gur->devdisr2, port_to_devdisr[port]); -} - -phy_interface_t fman_port_enet_if(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 rcwsr11 = in_be32(&gur->rcwsr[11]); - - if (is_device_disabled(port)) - return PHY_INTERFACE_MODE_NONE; - - if ((port == FM1_10GEC1) && (is_serdes_configured(XAUI_FM1))) - return PHY_INTERFACE_MODE_XGMII; - - /* handle RGMII first */ - if ((port == FM1_DTSEC4) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC1) == - FSL_CORENET_RCWSR11_EC1_FM1_DTSEC4_RGMII)) - return PHY_INTERFACE_MODE_RGMII; - - if ((port == FM1_DTSEC4) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC1) == - FSL_CORENET_RCWSR11_EC1_FM1_DTSEC4_MII)) - return PHY_INTERFACE_MODE_MII; - - if ((port == FM1_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM1_DTSEC5_RGMII)) - return PHY_INTERFACE_MODE_RGMII; - - if ((port == FM1_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM1_DTSEC5_MII)) - return PHY_INTERFACE_MODE_MII; - - switch (port) { - case FM1_DTSEC1: - case FM1_DTSEC2: - case FM1_DTSEC3: - case FM1_DTSEC4: - case FM1_DTSEC5: - if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1)) - return PHY_INTERFACE_MODE_SGMII; - break; - default: - return PHY_INTERFACE_MODE_NONE; - } - - return PHY_INTERFACE_MODE_NONE; -} diff --git a/qemu/roms/u-boot/drivers/net/fm/p5040.c b/qemu/roms/u-boot/drivers/net/fm/p5040.c deleted file mode 100644 index 403d7d794..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/p5040.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> -#include <phy.h> -#include <fm_eth.h> -#include <asm/io.h> -#include <asm/immap_85xx.h> -#include <asm/fsl_serdes.h> - -u32 port_to_devdisr[] = { - [FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1, - [FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2, - [FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3, - [FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4, - [FM1_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC1_5, - [FM1_10GEC1] = FSL_CORENET_DEVDISR2_10GEC1, - [FM2_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC2_1, - [FM2_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC2_2, - [FM2_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC2_3, - [FM2_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC2_4, - [FM2_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC2_5, - [FM2_10GEC1] = FSL_CORENET_DEVDISR2_10GEC2, -}; - -static int is_device_disabled(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 devdisr2 = in_be32(&gur->devdisr2); - - return port_to_devdisr[port] & devdisr2; -} - -void fman_disable_port(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - /* don't allow disabling of DTSEC1 as its needed for MDIO */ - if (port == FM1_DTSEC1) - return; - - setbits_be32(&gur->devdisr2, port_to_devdisr[port]); -} - -void fman_enable_port(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - clrbits_be32(&gur->devdisr2, port_to_devdisr[port]); -} - -phy_interface_t fman_port_enet_if(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 rcwsr11 = in_be32(&gur->rcwsr[11]); - - if (is_device_disabled(port)) - return PHY_INTERFACE_MODE_NONE; - - if ((port == FM1_10GEC1) && (is_serdes_configured(XAUI_FM1))) - return PHY_INTERFACE_MODE_XGMII; - - if ((port == FM2_10GEC1) && (is_serdes_configured(XAUI_FM2))) - return PHY_INTERFACE_MODE_XGMII; - - /* handle RGMII first */ - if ((port == FM1_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC1) == - FSL_CORENET_RCWSR11_EC1_FM1_DTSEC5_RGMII)) - return PHY_INTERFACE_MODE_RGMII; - - if ((port == FM1_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC1) == - FSL_CORENET_RCWSR11_EC1_FM1_DTSEC5_MII)) - return PHY_INTERFACE_MODE_MII; - - if ((port == FM2_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM2_DTSEC5_RGMII)) - return PHY_INTERFACE_MODE_RGMII; - - if ((port == FM2_DTSEC5) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM2_DTSEC5_MII)) - return PHY_INTERFACE_MODE_MII; - - switch (port) { - case FM1_DTSEC1: - case FM1_DTSEC2: - case FM1_DTSEC3: - case FM1_DTSEC4: - case FM1_DTSEC5: - if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1)) - return PHY_INTERFACE_MODE_SGMII; - break; - case FM2_DTSEC1: - case FM2_DTSEC2: - case FM2_DTSEC3: - case FM2_DTSEC4: - case FM2_DTSEC5: - if (is_serdes_configured(SGMII_FM2_DTSEC1 + port - FM2_DTSEC1)) - return PHY_INTERFACE_MODE_SGMII; - break; - default: - return PHY_INTERFACE_MODE_NONE; - } - - return PHY_INTERFACE_MODE_NONE; -} diff --git a/qemu/roms/u-boot/drivers/net/fm/t1040.c b/qemu/roms/u-boot/drivers/net/fm/t1040.c deleted file mode 100644 index bcc871d84..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/t1040.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> -#include <phy.h> -#include <fm_eth.h> -#include <asm/io.h> -#include <asm/immap_85xx.h> -#include <asm/fsl_serdes.h> - -phy_interface_t fman_port_enet_if(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 rcwsr13 = in_be32(&gur->rcwsr[13]); - - /* handle RGMII first */ - if ((port == FM1_DTSEC2) && - ((rcwsr13 & FSL_CORENET_RCWSR13_MAC2_GMII_SEL) == - FSL_CORENET_RCWSR13_MAC2_GMII_SEL_ENET_PORT)) { - if ((rcwsr13 & FSL_CORENET_RCWSR13_EC1) == - FSL_CORENET_RCWSR13_EC1_FM1_DTSEC4_RGMII) - return PHY_INTERFACE_MODE_RGMII; - else if ((rcwsr13 & FSL_CORENET_RCWSR13_EC1) == - FSL_CORENET_RCWSR13_EC1_FM1_DTSEC4_MII) - return PHY_INTERFACE_MODE_MII; - else - return PHY_INTERFACE_MODE_NONE; - } - - if ((port == FM1_DTSEC4) && - ((rcwsr13 & FSL_CORENET_RCWSR13_MAC2_GMII_SEL) == - FSL_CORENET_RCWSR13_MAC2_GMII_SEL_L2_SWITCH)) { - if ((rcwsr13 & FSL_CORENET_RCWSR13_EC1) == - FSL_CORENET_RCWSR13_EC1_FM1_DTSEC4_RGMII) - return PHY_INTERFACE_MODE_RGMII; - else if ((rcwsr13 & FSL_CORENET_RCWSR13_EC1) == - FSL_CORENET_RCWSR13_EC1_FM1_DTSEC4_MII) - return PHY_INTERFACE_MODE_MII; - else - return PHY_INTERFACE_MODE_NONE; - } - - if (port == FM1_DTSEC5) { - if ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) == - FSL_CORENET_RCWSR13_EC2_FM1_DTSEC5_RGMII) - return PHY_INTERFACE_MODE_RGMII; - else if ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) == - FSL_CORENET_RCWSR13_EC2_FM1_DTSEC5_MII) - return PHY_INTERFACE_MODE_MII; - else - return PHY_INTERFACE_MODE_NONE; - } - - switch (port) { - case FM1_DTSEC1: - case FM1_DTSEC2: - if (is_serdes_configured(QSGMII_SW1_A + port - FM1_DTSEC1)) - return PHY_INTERFACE_MODE_QSGMII; - case FM1_DTSEC3: - case FM1_DTSEC4: - case FM1_DTSEC5: - if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1)) - return PHY_INTERFACE_MODE_SGMII; - break; - default: - return PHY_INTERFACE_MODE_NONE; - } - - return PHY_INTERFACE_MODE_NONE; -} diff --git a/qemu/roms/u-boot/drivers/net/fm/t2080.c b/qemu/roms/u-boot/drivers/net/fm/t2080.c deleted file mode 100644 index 3b6212f85..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/t2080.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * - * Shengzhou Liu <Shengzhou.Liu@freescale.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <phy.h> -#include <fm_eth.h> -#include <asm/immap_85xx.h> -#include <asm/fsl_serdes.h> - -u32 port_to_devdisr[] = { - [FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1, - [FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2, - [FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3, - [FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4, - [FM1_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC1_5, - [FM1_DTSEC6] = FSL_CORENET_DEVDISR2_DTSEC1_6, - [FM1_DTSEC9] = FSL_CORENET_DEVDISR2_DTSEC1_9, - [FM1_DTSEC10] = FSL_CORENET_DEVDISR2_DTSEC1_10, - [FM1_10GEC1] = FSL_CORENET_DEVDISR2_10GEC1_1, - [FM1_10GEC2] = FSL_CORENET_DEVDISR2_10GEC1_2, - [FM1_10GEC3] = FSL_CORENET_DEVDISR2_10GEC1_3, - [FM1_10GEC4] = FSL_CORENET_DEVDISR2_10GEC1_4, -}; - -static int is_device_disabled(enum fm_port port) -{ - ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 devdisr2 = in_be32(&gur->devdisr2); - - return port_to_devdisr[port] & devdisr2; -} - -void fman_disable_port(enum fm_port port) -{ - ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - setbits_be32(&gur->devdisr2, port_to_devdisr[port]); -} - -phy_interface_t fman_port_enet_if(enum fm_port port) -{ - ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 rcwsr13 = in_be32(&gur->rcwsr[13]); - - if (is_device_disabled(port)) - return PHY_INTERFACE_MODE_NONE; - - if ((port == FM1_10GEC1 || port == FM1_10GEC2) && - ((is_serdes_configured(XAUI_FM1_MAC9)) || - (is_serdes_configured(XFI_FM1_MAC9)) || - (is_serdes_configured(XFI_FM1_MAC10)))) - return PHY_INTERFACE_MODE_XGMII; - - if ((port == FM1_10GEC3 || port == FM1_10GEC4) && - ((is_serdes_configured(XFI_FM1_MAC1)) || - (is_serdes_configured(XFI_FM1_MAC2)))) - return PHY_INTERFACE_MODE_XGMII; - - if ((port == FM1_DTSEC3) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC1) == - FSL_CORENET_RCWSR13_EC1_DTSEC3_RGMII)) - return PHY_INTERFACE_MODE_RGMII; - - if ((port == FM1_DTSEC4) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) == - FSL_CORENET_RCWSR13_EC2_DTSEC4_RGMII)) - return PHY_INTERFACE_MODE_RGMII; - - if ((port == FM1_DTSEC10) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) == - FSL_CORENET_RCWSR13_EC2_DTSEC10_RGMII)) - return PHY_INTERFACE_MODE_RGMII; - - switch (port) { - case FM1_DTSEC1: - case FM1_DTSEC2: - case FM1_DTSEC3: - case FM1_DTSEC4: - case FM1_DTSEC5: - case FM1_DTSEC6: - case FM1_DTSEC9: - case FM1_DTSEC10: - if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1)) - return PHY_INTERFACE_MODE_SGMII; - break; - default: - return PHY_INTERFACE_MODE_NONE; - } - - return PHY_INTERFACE_MODE_NONE; -} diff --git a/qemu/roms/u-boot/drivers/net/fm/t4240.c b/qemu/roms/u-boot/drivers/net/fm/t4240.c deleted file mode 100644 index 1eacb2284..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/t4240.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * Roy Zang <tie-fei.zang@freescale.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> -#include <phy.h> -#include <fm_eth.h> -#include <asm/io.h> -#include <asm/immap_85xx.h> -#include <asm/fsl_serdes.h> - -u32 port_to_devdisr[] = { - [FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1, - [FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2, - [FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3, - [FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4, - [FM1_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC1_5, - [FM1_DTSEC6] = FSL_CORENET_DEVDISR2_DTSEC1_6, - [FM1_DTSEC9] = FSL_CORENET_DEVDISR2_DTSEC1_9, - [FM1_DTSEC10] = FSL_CORENET_DEVDISR2_DTSEC1_10, - [FM1_10GEC1] = FSL_CORENET_DEVDISR2_10GEC1_1, - [FM1_10GEC2] = FSL_CORENET_DEVDISR2_10GEC1_2, - [FM2_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC2_1, - [FM2_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC2_2, - [FM2_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC2_3, - [FM2_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC2_4, - [FM2_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC2_5, - [FM2_DTSEC6] = FSL_CORENET_DEVDISR2_DTSEC2_6, - [FM2_DTSEC9] = FSL_CORENET_DEVDISR2_DTSEC2_9, - [FM2_DTSEC10] = FSL_CORENET_DEVDISR2_DTSEC2_10, - [FM2_10GEC1] = FSL_CORENET_DEVDISR2_10GEC2_1, - [FM2_10GEC2] = FSL_CORENET_DEVDISR2_10GEC2_2, -}; - -static int is_device_disabled(enum fm_port port) -{ - ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 devdisr2 = in_be32(&gur->devdisr2); - - return port_to_devdisr[port] & devdisr2; -} - -void fman_disable_port(enum fm_port port) -{ - ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - setbits_be32(&gur->devdisr2, port_to_devdisr[port]); -} - -void fman_enable_port(enum fm_port port) -{ - ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - clrbits_be32(&gur->devdisr2, port_to_devdisr[port]); -} - -phy_interface_t fman_port_enet_if(enum fm_port port) -{ - ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 rcwsr13 = in_be32(&gur->rcwsr[13]); - - if (is_device_disabled(port)) - return PHY_INTERFACE_MODE_NONE; - - if ((port == FM1_10GEC1 || port == FM1_10GEC2) && - ((is_serdes_configured(XAUI_FM1_MAC9)) || - (is_serdes_configured(XAUI_FM1_MAC10)) || - (is_serdes_configured(XFI_FM1_MAC9)) || - (is_serdes_configured(XFI_FM1_MAC10)))) - return PHY_INTERFACE_MODE_XGMII; - - if ((port == FM2_10GEC1 || port == FM2_10GEC2) && - ((is_serdes_configured(XAUI_FM2_MAC9)) || - (is_serdes_configured(XAUI_FM2_MAC10)) || - (is_serdes_configured(XFI_FM2_MAC9)) || - (is_serdes_configured(XFI_FM2_MAC10)))) - return PHY_INTERFACE_MODE_XGMII; - -#define FSL_CORENET_RCWSR13_EC1 0x60000000 /* bits 417..418 */ -#define FSL_CORENET_RCWSR13_EC1_FM2_DTSEC5_RGMII 0x00000000 -#define FSL_CORENET_RCWSR13_EC1_FM2_GPIO 0x40000000 -#define FSL_CORENET_RCWSR13_EC2 0x18000000 /* bits 419..420 */ -#define FSL_CORENET_RCWSR13_EC2_FM1_DTSEC5_RGMII 0x00000000 -#define FSL_CORENET_RCWSR13_EC2_FM2_DTSEC6_RGMII 0x08000000 -#define FSL_CORENET_RCWSR13_EC2_FM1_GPIO 0x10000000 - /* handle RGMII first */ - if ((port == FM2_DTSEC5) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC1) == - FSL_CORENET_RCWSR13_EC1_FM2_DTSEC5_RGMII)) - return PHY_INTERFACE_MODE_RGMII; - - if ((port == FM1_DTSEC5) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) == - FSL_CORENET_RCWSR13_EC2_FM1_DTSEC5_RGMII)) - return PHY_INTERFACE_MODE_RGMII; - - if ((port == FM2_DTSEC6) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) == - FSL_CORENET_RCWSR13_EC2_FM2_DTSEC6_RGMII)) - return PHY_INTERFACE_MODE_RGMII; - switch (port) { - case FM1_DTSEC1: - case FM1_DTSEC2: - case FM1_DTSEC3: - case FM1_DTSEC4: - case FM1_DTSEC5: - case FM1_DTSEC6: - case FM1_DTSEC9: - case FM1_DTSEC10: - if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1)) - return PHY_INTERFACE_MODE_SGMII; - break; - case FM2_DTSEC1: - case FM2_DTSEC2: - case FM2_DTSEC3: - case FM2_DTSEC4: - case FM2_DTSEC5: - case FM2_DTSEC6: - case FM2_DTSEC9: - case FM2_DTSEC10: - if (is_serdes_configured(SGMII_FM2_DTSEC1 + port - FM2_DTSEC1)) - return PHY_INTERFACE_MODE_SGMII; - break; - default: - break; - } - - /* handle QSGMII */ - switch (port) { - case FM1_DTSEC1: - case FM1_DTSEC2: - case FM1_DTSEC3: - case FM1_DTSEC4: - /* check lane G on SerDes1 */ - if (is_serdes_configured(QSGMII_FM1_A)) - return PHY_INTERFACE_MODE_QSGMII; - break; - case FM1_DTSEC5: - case FM1_DTSEC6: - case FM1_DTSEC9: - case FM1_DTSEC10: - /* check lane C on SerDes1 */ - if (is_serdes_configured(QSGMII_FM1_B)) - return PHY_INTERFACE_MODE_QSGMII; - break; - case FM2_DTSEC1: - case FM2_DTSEC2: - case FM2_DTSEC3: - case FM2_DTSEC4: - /* check lane G on SerDes2 */ - if (is_serdes_configured(QSGMII_FM2_A)) - return PHY_INTERFACE_MODE_QSGMII; - break; - case FM2_DTSEC5: - case FM2_DTSEC6: - case FM2_DTSEC9: - case FM2_DTSEC10: - /* check lane C on SerDes2 */ - if (is_serdes_configured(QSGMII_FM2_B)) - return PHY_INTERFACE_MODE_QSGMII; - break; - default: - break; - } - - return PHY_INTERFACE_MODE_NONE; -} diff --git a/qemu/roms/u-boot/drivers/net/fm/tgec.c b/qemu/roms/u-boot/drivers/net/fm/tgec.c deleted file mode 100644 index f450f800e..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/tgec.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2009-2011 Freescale Semiconductor, Inc. - * Dave Liu <daveliu@freescale.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* MAXFRM - maximum frame length */ -#define MAXFRM_MASK 0x0000ffff - -#include <common.h> -#include <phy.h> -#include <asm/types.h> -#include <asm/io.h> -#include <asm/fsl_enet.h> -#include <asm/fsl_tgec.h> - -#include "fm.h" - -#define TGEC_CMD_CFG_INIT (TGEC_CMD_CFG_NO_LEN_CHK | \ - TGEC_CMD_CFG_RX_ER_DISC | \ - TGEC_CMD_CFG_STAT_CLR | \ - TGEC_CMD_CFG_PAUSE_IGNORE | \ - TGEC_CMD_CFG_CRC_FWD) -#define TGEC_CMD_CFG_FINAL (TGEC_CMD_CFG_NO_LEN_CHK | \ - TGEC_CMD_CFG_RX_ER_DISC | \ - TGEC_CMD_CFG_PAUSE_IGNORE | \ - TGEC_CMD_CFG_CRC_FWD) - -static void tgec_init_mac(struct fsl_enet_mac *mac) -{ - struct tgec *regs = mac->base; - - /* mask all interrupt */ - out_be32(®s->imask, IMASK_MASK_ALL); - - /* clear all events */ - out_be32(®s->ievent, IEVENT_CLEAR_ALL); - - /* set the max receive length */ - out_be32(®s->maxfrm, mac->max_rx_len & MAXFRM_MASK); - - /* - * 1588 disable, insert second mac disable payload length check - * disable, normal operation, any rx error frame is discarded, clear - * counters, pause frame ignore, no promiscuous, LAN mode Rx CRC no - * strip, Tx CRC append, Rx disable and Tx disable - */ - out_be32(®s->command_config, TGEC_CMD_CFG_INIT); - udelay(1000); - out_be32(®s->command_config, TGEC_CMD_CFG_FINAL); - - /* multicast frame reception for the hash entry disable */ - out_be32(®s->hashtable_ctrl, 0); -} - -static void tgec_enable_mac(struct fsl_enet_mac *mac) -{ - struct tgec *regs = mac->base; - - setbits_be32(®s->command_config, TGEC_CMD_CFG_RXTX_EN); -} - -static void tgec_disable_mac(struct fsl_enet_mac *mac) -{ - struct tgec *regs = mac->base; - - clrbits_be32(®s->command_config, TGEC_CMD_CFG_RXTX_EN); -} - -static void tgec_set_mac_addr(struct fsl_enet_mac *mac, u8 *mac_addr) -{ - struct tgec *regs = mac->base; - u32 mac_addr0, mac_addr1; - - /* - * if a station address of 0x12345678ABCD, perform a write to - * MAC_ADDR0 of 0x78563412, MAC_ADDR1 of 0x0000CDAB - */ - mac_addr0 = (mac_addr[3] << 24) | (mac_addr[2] << 16) | \ - (mac_addr[1] << 8) | (mac_addr[0]); - out_be32(®s->mac_addr_0, mac_addr0); - - mac_addr1 = ((mac_addr[5] << 8) | mac_addr[4]) & 0x0000ffff; - out_be32(®s->mac_addr_1, mac_addr1); -} - -static void tgec_set_interface_mode(struct fsl_enet_mac *mac, - phy_interface_t type, int speed) -{ - /* nothing right now */ - return; -} - -void init_tgec(struct fsl_enet_mac *mac, void *base, - void *phyregs, int max_rx_len) -{ - mac->base = base; - mac->phyregs = phyregs; - mac->max_rx_len = max_rx_len; - mac->init_mac = tgec_init_mac; - mac->enable_mac = tgec_enable_mac; - mac->disable_mac = tgec_disable_mac; - mac->set_mac_addr = tgec_set_mac_addr; - mac->set_if_mode = tgec_set_interface_mode; -} diff --git a/qemu/roms/u-boot/drivers/net/fm/tgec_phy.c b/qemu/roms/u-boot/drivers/net/fm/tgec_phy.c deleted file mode 100644 index faec317a0..000000000 --- a/qemu/roms/u-boot/drivers/net/fm/tgec_phy.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2009-2011 Freescale Semiconductor, Inc. - * Andy Fleming <afleming@freescale.com> - * - * SPDX-License-Identifier: GPL-2.0+ - * Some part is taken from tsec.c - */ -#include <common.h> -#include <miiphy.h> -#include <phy.h> -#include <asm/io.h> -#include <asm/fsl_tgec.h> -#include <fm_eth.h> - -/* - * Write value to the PHY for this device to the register at regnum, waiting - * until the write is done before it returns. All PHY configuration has to be - * done through the TSEC1 MIIM regs - */ -static int tgec_mdio_write(struct mii_dev *bus, int port_addr, int dev_addr, - int regnum, u16 value) -{ - u32 mdio_ctl; - u32 stat_val; - struct tgec_mdio_controller *regs = bus->priv; - - if (dev_addr == MDIO_DEVAD_NONE) - return 0; - - /* Wait till the bus is free */ - stat_val = MDIO_STAT_CLKDIV(100); - out_be32(®s->mdio_stat, stat_val); - while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) - ; - - /* Set the port and dev addr */ - mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr); - out_be32(®s->mdio_ctl, mdio_ctl); - - /* Set the register address */ - out_be32(®s->mdio_addr, regnum & 0xffff); - - /* Wait till the bus is free */ - while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) - ; - - /* Write the value to the register */ - out_be32(®s->mdio_data, MDIO_DATA(value)); - - /* Wait till the MDIO write is complete */ - while ((in_be32(®s->mdio_data)) & MDIO_DATA_BSY) - ; - - return 0; -} - -/* - * Reads from register regnum in the PHY for device dev, returning the value. - * Clears miimcom first. All PHY configuration has to be done through the - * TSEC1 MIIM regs - */ -static int tgec_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr, - int regnum) -{ - u32 mdio_ctl; - u32 stat_val; - struct tgec_mdio_controller *regs = bus->priv; - - if (dev_addr == MDIO_DEVAD_NONE) - return 0xffff; - - stat_val = MDIO_STAT_CLKDIV(100); - out_be32(®s->mdio_stat, stat_val); - /* Wait till the bus is free */ - while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) - ; - - /* Set the Port and Device Addrs */ - mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr); - out_be32(®s->mdio_ctl, mdio_ctl); - - /* Set the register address */ - out_be32(®s->mdio_addr, regnum & 0xffff); - - /* Wait till the bus is free */ - while ((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY) - ; - - /* Initiate the read */ - mdio_ctl |= MDIO_CTL_READ; - out_be32(®s->mdio_ctl, mdio_ctl); - - /* Wait till the MDIO write is complete */ - while ((in_be32(®s->mdio_data)) & MDIO_DATA_BSY) - ; - - /* Return all Fs if nothing was there */ - if (in_be32(®s->mdio_stat) & MDIO_STAT_RD_ER) - return 0xffff; - - return in_be32(®s->mdio_data) & 0xffff; -} - -static int tgec_mdio_reset(struct mii_dev *bus) -{ - return 0; -} - -int fm_tgec_mdio_init(bd_t *bis, struct tgec_mdio_info *info) -{ - struct mii_dev *bus = mdio_alloc(); - - if (!bus) { - printf("Failed to allocate FM TGEC MDIO bus\n"); - return -1; - } - - bus->read = tgec_mdio_read; - bus->write = tgec_mdio_write; - bus->reset = tgec_mdio_reset; - sprintf(bus->name, info->name); - - bus->priv = info->regs; - - return mdio_register(bus); -} diff --git a/qemu/roms/u-boot/drivers/net/fsl_mcdmafec.c b/qemu/roms/u-boot/drivers/net/fsl_mcdmafec.c deleted file mode 100644 index 6391f9b32..000000000 --- a/qemu/roms/u-boot/drivers/net/fsl_mcdmafec.c +++ /dev/null @@ -1,571 +0,0 @@ -/* - * (C) Copyright 2000-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2007 Freescale Semiconductor, Inc. - * TsiChung Liew (Tsi-Chung.Liew@freescale.com) - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <command.h> -#include <config.h> -#include <net.h> -#include <miiphy.h> - -#undef ET_DEBUG -#undef MII_DEBUG - -/* Ethernet Transmit and Receive Buffers */ -#define DBUF_LENGTH 1520 -#define PKT_MAXBUF_SIZE 1518 -#define PKT_MINBUF_SIZE 64 -#define PKT_MAXBLR_SIZE 1536 -#define LAST_PKTBUFSRX PKTBUFSRX - 1 -#define BD_ENET_RX_W_E (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY) -#define BD_ENET_TX_RDY_LST (BD_ENET_TX_READY | BD_ENET_TX_LAST) -#define FIFO_ERRSTAT (FIFO_STAT_RXW | FIFO_STAT_UF | FIFO_STAT_OF) - -/* RxBD bits definitions */ -#define BD_ENET_RX_ERR (BD_ENET_RX_LG | BD_ENET_RX_NO | BD_ENET_RX_CR | \ - BD_ENET_RX_OV | BD_ENET_RX_TR) - -#include <asm/immap.h> -#include <asm/fsl_mcdmafec.h> - -#include "MCD_dma.h" - -DECLARE_GLOBAL_DATA_PTR; - -struct fec_info_dma fec_info[] = { -#ifdef CONFIG_SYS_FEC0_IOBASE - { - 0, /* index */ - CONFIG_SYS_FEC0_IOBASE, /* io base */ - CONFIG_SYS_FEC0_PINMUX, /* gpio pin muxing */ - CONFIG_SYS_FEC0_MIIBASE, /* mii base */ - -1, /* phy_addr */ - 0, /* duplex and speed */ - 0, /* phy name */ - 0, /* phyname init */ - 0, /* RX BD */ - 0, /* TX BD */ - 0, /* rx Index */ - 0, /* tx Index */ - 0, /* tx buffer */ - 0, /* initialized flag */ - (struct fec_info_dma *)-1, /* next */ - FEC0_RX_TASK, /* rxTask */ - FEC0_TX_TASK, /* txTask */ - FEC0_RX_PRIORITY, /* rxPri */ - FEC0_TX_PRIORITY, /* txPri */ - FEC0_RX_INIT, /* rxInit */ - FEC0_TX_INIT, /* txInit */ - 0, /* usedTbdIndex */ - 0, /* cleanTbdNum */ - }, -#endif -#ifdef CONFIG_SYS_FEC1_IOBASE - { - 1, /* index */ - CONFIG_SYS_FEC1_IOBASE, /* io base */ - CONFIG_SYS_FEC1_PINMUX, /* gpio pin muxing */ - CONFIG_SYS_FEC1_MIIBASE, /* mii base */ - -1, /* phy_addr */ - 0, /* duplex and speed */ - 0, /* phy name */ - 0, /* phy name init */ -#ifdef CONFIG_SYS_DMA_USE_INTSRAM - (cbd_t *)DBUF_LENGTH, /* RX BD */ -#else - 0, /* RX BD */ -#endif - 0, /* TX BD */ - 0, /* rx Index */ - 0, /* tx Index */ - 0, /* tx buffer */ - 0, /* initialized flag */ - (struct fec_info_dma *)-1, /* next */ - FEC1_RX_TASK, /* rxTask */ - FEC1_TX_TASK, /* txTask */ - FEC1_RX_PRIORITY, /* rxPri */ - FEC1_TX_PRIORITY, /* txPri */ - FEC1_RX_INIT, /* rxInit */ - FEC1_TX_INIT, /* txInit */ - 0, /* usedTbdIndex */ - 0, /* cleanTbdNum */ - } -#endif -}; - -static int fec_send(struct eth_device *dev, void *packet, int length); -static int fec_recv(struct eth_device *dev); -static int fec_init(struct eth_device *dev, bd_t * bd); -static void fec_halt(struct eth_device *dev); - -#ifdef ET_DEBUG -static void dbg_fec_regs(struct eth_device *dev) -{ - struct fec_info_dma *info = dev->priv; - volatile fecdma_t *fecp = (fecdma_t *) (info->iobase); - - printf("=====\n"); - printf("ievent %x - %x\n", (int)&fecp->eir, fecp->eir); - printf("imask %x - %x\n", (int)&fecp->eimr, fecp->eimr); - printf("ecntrl %x - %x\n", (int)&fecp->ecr, fecp->ecr); - printf("mii_mframe %x - %x\n", (int)&fecp->mmfr, fecp->mmfr); - printf("mii_speed %x - %x\n", (int)&fecp->mscr, fecp->mscr); - printf("mii_ctrlstat %x - %x\n", (int)&fecp->mibc, fecp->mibc); - printf("r_cntrl %x - %x\n", (int)&fecp->rcr, fecp->rcr); - printf("r hash %x - %x\n", (int)&fecp->rhr, fecp->rhr); - printf("x_cntrl %x - %x\n", (int)&fecp->tcr, fecp->tcr); - printf("padr_l %x - %x\n", (int)&fecp->palr, fecp->palr); - printf("padr_u %x - %x\n", (int)&fecp->paur, fecp->paur); - printf("op_pause %x - %x\n", (int)&fecp->opd, fecp->opd); - printf("iadr_u %x - %x\n", (int)&fecp->iaur, fecp->iaur); - printf("iadr_l %x - %x\n", (int)&fecp->ialr, fecp->ialr); - printf("gadr_u %x - %x\n", (int)&fecp->gaur, fecp->gaur); - printf("gadr_l %x - %x\n", (int)&fecp->galr, fecp->galr); - printf("x_wmrk %x - %x\n", (int)&fecp->tfwr, fecp->tfwr); - printf("r_fdata %x - %x\n", (int)&fecp->rfdr, fecp->rfdr); - printf("r_fstat %x - %x\n", (int)&fecp->rfsr, fecp->rfsr); - printf("r_fctrl %x - %x\n", (int)&fecp->rfcr, fecp->rfcr); - printf("r_flrfp %x - %x\n", (int)&fecp->rlrfp, fecp->rlrfp); - printf("r_flwfp %x - %x\n", (int)&fecp->rlwfp, fecp->rlwfp); - printf("r_frfar %x - %x\n", (int)&fecp->rfar, fecp->rfar); - printf("r_frfrp %x - %x\n", (int)&fecp->rfrp, fecp->rfrp); - printf("r_frfwp %x - %x\n", (int)&fecp->rfwp, fecp->rfwp); - printf("t_fdata %x - %x\n", (int)&fecp->tfdr, fecp->tfdr); - printf("t_fstat %x - %x\n", (int)&fecp->tfsr, fecp->tfsr); - printf("t_fctrl %x - %x\n", (int)&fecp->tfcr, fecp->tfcr); - printf("t_flrfp %x - %x\n", (int)&fecp->tlrfp, fecp->tlrfp); - printf("t_flwfp %x - %x\n", (int)&fecp->tlwfp, fecp->tlwfp); - printf("t_ftfar %x - %x\n", (int)&fecp->tfar, fecp->tfar); - printf("t_ftfrp %x - %x\n", (int)&fecp->tfrp, fecp->tfrp); - printf("t_ftfwp %x - %x\n", (int)&fecp->tfwp, fecp->tfwp); - printf("frst %x - %x\n", (int)&fecp->frst, fecp->frst); - printf("ctcwr %x - %x\n", (int)&fecp->ctcwr, fecp->ctcwr); -} -#endif - -static void set_fec_duplex_speed(volatile fecdma_t * fecp, bd_t * bd, - int dup_spd) -{ - if ((dup_spd >> 16) == FULL) { - /* Set maximum frame length */ - fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | FEC_RCR_MII_MODE | - FEC_RCR_PROM | 0x100; - fecp->tcr = FEC_TCR_FDEN; - } else { - /* Half duplex mode */ - fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | - FEC_RCR_MII_MODE | FEC_RCR_DRT; - fecp->tcr &= ~FEC_TCR_FDEN; - } - - if ((dup_spd & 0xFFFF) == _100BASET) { -#ifdef MII_DEBUG - printf("100Mbps\n"); -#endif - bd->bi_ethspeed = 100; - } else { -#ifdef MII_DEBUG - printf("10Mbps\n"); -#endif - bd->bi_ethspeed = 10; - } -} - -static int fec_send(struct eth_device *dev, void *packet, int length) -{ - struct fec_info_dma *info = dev->priv; - cbd_t *pTbd, *pUsedTbd; - u16 phyStatus; - - miiphy_read(dev->name, info->phy_addr, MII_BMSR, &phyStatus); - - /* process all the consumed TBDs */ - while (info->cleanTbdNum < CONFIG_SYS_TX_ETH_BUFFER) { - pUsedTbd = &info->txbd[info->usedTbdIdx]; - if (pUsedTbd->cbd_sc & BD_ENET_TX_READY) { -#ifdef ET_DEBUG - printf("Cannot clean TBD %d, in use\n", - info->cleanTbdNum); -#endif - return 0; - } - - /* clean this buffer descriptor */ - if (info->usedTbdIdx == (CONFIG_SYS_TX_ETH_BUFFER - 1)) - pUsedTbd->cbd_sc = BD_ENET_TX_WRAP; - else - pUsedTbd->cbd_sc = 0; - - /* update some indeces for a correct handling of the TBD ring */ - info->cleanTbdNum++; - info->usedTbdIdx = (info->usedTbdIdx + 1) % CONFIG_SYS_TX_ETH_BUFFER; - } - - /* Check for valid length of data. */ - if ((length > 1500) || (length <= 0)) { - return -1; - } - - /* Check the number of vacant TxBDs. */ - if (info->cleanTbdNum < 1) { - printf("No available TxBDs ...\n"); - return -1; - } - - /* Get the first TxBD to send the mac header */ - pTbd = &info->txbd[info->txIdx]; - pTbd->cbd_datlen = length; - pTbd->cbd_bufaddr = (u32) packet; - pTbd->cbd_sc |= BD_ENET_TX_LAST | BD_ENET_TX_TC | BD_ENET_TX_READY; - info->txIdx = (info->txIdx + 1) % CONFIG_SYS_TX_ETH_BUFFER; - - /* Enable DMA transmit task */ - MCD_continDma(info->txTask); - - info->cleanTbdNum -= 1; - - /* wait until frame is sent . */ - while (pTbd->cbd_sc & BD_ENET_TX_READY) { - udelay(10); - } - - return (int)(info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_STATS); -} - -static int fec_recv(struct eth_device *dev) -{ - struct fec_info_dma *info = dev->priv; - volatile fecdma_t *fecp = (fecdma_t *) (info->iobase); - - cbd_t *pRbd = &info->rxbd[info->rxIdx]; - u32 ievent; - int frame_length, len = 0; - - /* Check if any critical events have happened */ - ievent = fecp->eir; - if (ievent != 0) { - fecp->eir = ievent; - - if (ievent & (FEC_EIR_BABT | FEC_EIR_TXERR | FEC_EIR_RXERR)) { - printf("fec_recv: error\n"); - fec_halt(dev); - fec_init(dev, NULL); - return 0; - } - - if (ievent & FEC_EIR_HBERR) { - /* Heartbeat error */ - fecp->tcr |= FEC_TCR_GTS; - } - - if (ievent & FEC_EIR_GRA) { - /* Graceful stop complete */ - if (fecp->tcr & FEC_TCR_GTS) { - printf("fec_recv: tcr_gts\n"); - fec_halt(dev); - fecp->tcr &= ~FEC_TCR_GTS; - fec_init(dev, NULL); - } - } - } - - if (!(pRbd->cbd_sc & BD_ENET_RX_EMPTY)) { - if ((pRbd->cbd_sc & BD_ENET_RX_LAST) - && !(pRbd->cbd_sc & BD_ENET_RX_ERR) - && ((pRbd->cbd_datlen - 4) > 14)) { - - /* Get buffer address and size */ - frame_length = pRbd->cbd_datlen - 4; - - /* Fill the buffer and pass it to upper layers */ - NetReceive((uchar *)pRbd->cbd_bufaddr, frame_length); - len = frame_length; - } - - /* Reset buffer descriptor as empty */ - if ((info->rxIdx) == (PKTBUFSRX - 1)) - pRbd->cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY); - else - pRbd->cbd_sc = BD_ENET_RX_EMPTY; - - pRbd->cbd_datlen = PKTSIZE_ALIGN; - - /* Now, we have an empty RxBD, restart the DMA receive task */ - MCD_continDma(info->rxTask); - - /* Increment BD count */ - info->rxIdx = (info->rxIdx + 1) % PKTBUFSRX; - } - - return len; -} - -static void fec_set_hwaddr(volatile fecdma_t * fecp, u8 * mac) -{ - u8 currByte; /* byte for which to compute the CRC */ - int byte; /* loop - counter */ - int bit; /* loop - counter */ - u32 crc = 0xffffffff; /* initial value */ - - for (byte = 0; byte < 6; byte++) { - currByte = mac[byte]; - for (bit = 0; bit < 8; bit++) { - if ((currByte & 0x01) ^ (crc & 0x01)) { - crc >>= 1; - crc = crc ^ 0xedb88320; - } else { - crc >>= 1; - } - currByte >>= 1; - } - } - - crc = crc >> 26; - - /* Set individual hash table register */ - if (crc >= 32) { - fecp->ialr = (1 << (crc - 32)); - fecp->iaur = 0; - } else { - fecp->ialr = 0; - fecp->iaur = (1 << crc); - } - - /* Set physical address */ - fecp->palr = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3]; - fecp->paur = (mac[4] << 24) + (mac[5] << 16) + 0x8808; - - /* Clear multicast address hash table */ - fecp->gaur = 0; - fecp->galr = 0; -} - -static int fec_init(struct eth_device *dev, bd_t * bd) -{ - struct fec_info_dma *info = dev->priv; - volatile fecdma_t *fecp = (fecdma_t *) (info->iobase); - int i; - uchar enetaddr[6]; - -#ifdef ET_DEBUG - printf("fec_init: iobase 0x%08x ...\n", info->iobase); -#endif - - fecpin_setclear(dev, 1); - - fec_halt(dev); - -#if defined(CONFIG_CMD_MII) || defined (CONFIG_MII) || \ - defined (CONFIG_SYS_DISCOVER_PHY) - - mii_init(); - - set_fec_duplex_speed(fecp, bd, info->dup_spd); -#else -#ifndef CONFIG_SYS_DISCOVER_PHY - set_fec_duplex_speed(fecp, bd, (FECDUPLEX << 16) | FECSPEED); -#endif /* ifndef CONFIG_SYS_DISCOVER_PHY */ -#endif /* CONFIG_CMD_MII || CONFIG_MII */ - - /* We use strictly polling mode only */ - fecp->eimr = 0; - - /* Clear any pending interrupt */ - fecp->eir = 0xffffffff; - - /* Set station address */ - if ((u32) fecp == CONFIG_SYS_FEC0_IOBASE) - eth_getenv_enetaddr("ethaddr", enetaddr); - else - eth_getenv_enetaddr("eth1addr", enetaddr); - fec_set_hwaddr(fecp, enetaddr); - - /* Set Opcode/Pause Duration Register */ - fecp->opd = 0x00010020; - - /* Setup Buffers and Buffer Desriptors */ - info->rxIdx = 0; - info->txIdx = 0; - - /* Setup Receiver Buffer Descriptors (13.14.24.18) - * Settings: Empty, Wrap */ - for (i = 0; i < PKTBUFSRX; i++) { - info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; - info->rxbd[i].cbd_datlen = PKTSIZE_ALIGN; - info->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i]; - } - info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; - - /* Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19) - * Settings: Last, Tx CRC */ - for (i = 0; i < CONFIG_SYS_TX_ETH_BUFFER; i++) { - info->txbd[i].cbd_sc = 0; - info->txbd[i].cbd_datlen = 0; - info->txbd[i].cbd_bufaddr = (uint) (&info->txbuf[0]); - } - info->txbd[CONFIG_SYS_TX_ETH_BUFFER - 1].cbd_sc |= BD_ENET_TX_WRAP; - - info->usedTbdIdx = 0; - info->cleanTbdNum = CONFIG_SYS_TX_ETH_BUFFER; - - /* Set Rx FIFO alarm and granularity value */ - fecp->rfcr = 0x0c000000; - fecp->rfar = 0x0000030c; - - /* Set Tx FIFO granularity value */ - fecp->tfcr = FIFO_CTRL_FRAME | FIFO_CTRL_GR(6) | 0x00040000; - fecp->tfar = 0x00000080; - - fecp->tfwr = 0x2; - fecp->ctcwr = 0x03000000; - - /* Enable DMA receive task */ - MCD_startDma(info->rxTask, /* Dma channel */ - (s8 *) info->rxbd, /*Source Address */ - 0, /* Source increment */ - (s8 *) (&fecp->rfdr), /* dest */ - 4, /* dest increment */ - 0, /* DMA size */ - 4, /* xfer size */ - info->rxInit, /* initiator */ - info->rxPri, /* priority */ - (MCD_FECRX_DMA | MCD_TT_FLAGS_DEF), /* Flags */ - (MCD_NO_CSUM | MCD_NO_BYTE_SWAP) /* Function description */ - ); - - /* Enable DMA tx task with no ready buffer descriptors */ - MCD_startDma(info->txTask, /* Dma channel */ - (s8 *) info->txbd, /*Source Address */ - 0, /* Source increment */ - (s8 *) (&fecp->tfdr), /* dest */ - 4, /* dest incr */ - 0, /* DMA size */ - 4, /* xfer size */ - info->txInit, /* initiator */ - info->txPri, /* priority */ - (MCD_FECTX_DMA | MCD_TT_FLAGS_DEF), /* Flags */ - (MCD_NO_CSUM | MCD_NO_BYTE_SWAP) /* Function description */ - ); - - /* Now enable the transmit and receive processing */ - fecp->ecr |= FEC_ECR_ETHER_EN; - - return 1; -} - -static void fec_halt(struct eth_device *dev) -{ - struct fec_info_dma *info = dev->priv; - volatile fecdma_t *fecp = (fecdma_t *) (info->iobase); - int counter = 0xffff; - - /* issue graceful stop command to the FEC transmitter if necessary */ - fecp->tcr |= FEC_TCR_GTS; - - /* wait for graceful stop to register */ - while ((counter--) && (!(fecp->eir & FEC_EIR_GRA))) ; - - /* Disable DMA tasks */ - MCD_killDma(info->txTask); - MCD_killDma(info->rxTask);; - - /* Disable the Ethernet Controller */ - fecp->ecr &= ~FEC_ECR_ETHER_EN; - - /* Clear FIFO status registers */ - fecp->rfsr &= FIFO_ERRSTAT; - fecp->tfsr &= FIFO_ERRSTAT; - - fecp->frst = 0x01000000; - - /* Issue a reset command to the FEC chip */ - fecp->ecr |= FEC_ECR_RESET; - - /* wait at least 20 clock cycles */ - udelay(10000); - -#ifdef ET_DEBUG - printf("Ethernet task stopped\n"); -#endif -} - -int mcdmafec_initialize(bd_t * bis) -{ - struct eth_device *dev; - int i; -#ifdef CONFIG_SYS_DMA_USE_INTSRAM - u32 tmp = CONFIG_SYS_INTSRAM + 0x2000; -#endif - - for (i = 0; i < ARRAY_SIZE(fec_info); i++) { - - dev = - (struct eth_device *)memalign(CONFIG_SYS_CACHELINE_SIZE, - sizeof *dev); - if (dev == NULL) - hang(); - - memset(dev, 0, sizeof(*dev)); - - sprintf(dev->name, "FEC%d", fec_info[i].index); - - dev->priv = &fec_info[i]; - dev->init = fec_init; - dev->halt = fec_halt; - dev->send = fec_send; - dev->recv = fec_recv; - - /* setup Receive and Transmit buffer descriptor */ -#ifdef CONFIG_SYS_DMA_USE_INTSRAM - fec_info[i].rxbd = (cbd_t *)((u32)fec_info[i].rxbd + tmp); - tmp = (u32)fec_info[i].rxbd; - fec_info[i].txbd = - (cbd_t *)((u32)fec_info[i].txbd + tmp + - (PKTBUFSRX * sizeof(cbd_t))); - tmp = (u32)fec_info[i].txbd; - fec_info[i].txbuf = - (char *)((u32)fec_info[i].txbuf + tmp + - (CONFIG_SYS_TX_ETH_BUFFER * sizeof(cbd_t))); - tmp = (u32)fec_info[i].txbuf; -#else - fec_info[i].rxbd = - (cbd_t *) memalign(CONFIG_SYS_CACHELINE_SIZE, - (PKTBUFSRX * sizeof(cbd_t))); - fec_info[i].txbd = - (cbd_t *) memalign(CONFIG_SYS_CACHELINE_SIZE, - (CONFIG_SYS_TX_ETH_BUFFER * sizeof(cbd_t))); - fec_info[i].txbuf = - (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, DBUF_LENGTH); -#endif - -#ifdef ET_DEBUG - printf("rxbd %x txbd %x\n", - (int)fec_info[i].rxbd, (int)fec_info[i].txbd); -#endif - - fec_info[i].phy_name = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, 32); - - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - miiphy_register(dev->name, - mcffec_miiphy_read, mcffec_miiphy_write); -#endif - - if (i > 0) - fec_info[i - 1].next = &fec_info[i]; - } - fec_info[i - 1].next = &fec_info[0]; - - /* default speed */ - bis->bi_ethspeed = 10; - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/fsl_mdio.c b/qemu/roms/u-boot/drivers/net/fsl_mdio.c deleted file mode 100644 index 1d88e6504..000000000 --- a/qemu/roms/u-boot/drivers/net/fsl_mdio.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2009-2010, 2013 Freescale Semiconductor, Inc. - * Jun-jie Zhang <b18070@freescale.com> - * Mingkai Hu <Mingkai.hu@freescale.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> -#include <miiphy.h> -#include <phy.h> -#include <fsl_mdio.h> -#include <asm/io.h> -#include <asm/errno.h> -#include <asm/fsl_enet.h> - -void tsec_local_mdio_write(struct tsec_mii_mng __iomem *phyregs, int port_addr, - int dev_addr, int regnum, int value) -{ - int timeout = 1000000; - - out_be32(&phyregs->miimadd, (port_addr << 8) | (regnum & 0x1f)); - out_be32(&phyregs->miimcon, value); - asm("sync"); - - while ((in_be32(&phyregs->miimind) & MIIMIND_BUSY) && timeout--) - ; -} - -int tsec_local_mdio_read(struct tsec_mii_mng __iomem *phyregs, int port_addr, - int dev_addr, int regnum) -{ - int value; - int timeout = 1000000; - - /* Put the address of the phy, and the register - * number into MIIMADD */ - out_be32(&phyregs->miimadd, (port_addr << 8) | (regnum & 0x1f)); - - /* Clear the command register, and wait */ - out_be32(&phyregs->miimcom, 0); - asm("sync"); - - /* Initiate a read command, and wait */ - out_be32(&phyregs->miimcom, MIIMCOM_READ_CYCLE); - asm("sync"); - - /* Wait for the the indication that the read is done */ - while ((in_be32(&phyregs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY)) - && timeout--) - ; - - /* Grab the value read from the PHY */ - value = in_be32(&phyregs->miimstat); - - return value; -} - -static int fsl_pq_mdio_reset(struct mii_dev *bus) -{ - struct tsec_mii_mng __iomem *regs = - (struct tsec_mii_mng __iomem *)bus->priv; - - /* Reset MII (due to new addresses) */ - out_be32(®s->miimcfg, MIIMCFG_RESET_MGMT); - - out_be32(®s->miimcfg, MIIMCFG_INIT_VALUE); - - while (in_be32(®s->miimind) & MIIMIND_BUSY) - ; - - return 0; -} - -int tsec_phy_read(struct mii_dev *bus, int addr, int dev_addr, int regnum) -{ - struct tsec_mii_mng __iomem *phyregs = - (struct tsec_mii_mng __iomem *)bus->priv; - - return tsec_local_mdio_read(phyregs, addr, dev_addr, regnum); -} - -int tsec_phy_write(struct mii_dev *bus, int addr, int dev_addr, int regnum, - u16 value) -{ - struct tsec_mii_mng __iomem *phyregs = - (struct tsec_mii_mng __iomem *)bus->priv; - - tsec_local_mdio_write(phyregs, addr, dev_addr, regnum, value); - - return 0; -} - -int fsl_pq_mdio_init(bd_t *bis, struct fsl_pq_mdio_info *info) -{ - struct mii_dev *bus = mdio_alloc(); - - if (!bus) { - printf("Failed to allocate FSL MDIO bus\n"); - return -1; - } - - bus->read = tsec_phy_read; - bus->write = tsec_phy_write; - bus->reset = fsl_pq_mdio_reset; - sprintf(bus->name, info->name); - - bus->priv = (void *)info->regs; - - return mdio_register(bus); -} diff --git a/qemu/roms/u-boot/drivers/net/ftgmac100.c b/qemu/roms/u-boot/drivers/net/ftgmac100.c deleted file mode 100644 index 85193140a..000000000 --- a/qemu/roms/u-boot/drivers/net/ftgmac100.c +++ /dev/null @@ -1,583 +0,0 @@ -/* - * Faraday FTGMAC100 Ethernet - * - * (C) Copyright 2009 Faraday Technology - * Po-Yu Chuang <ratbert@faraday-tech.com> - * - * (C) Copyright 2010 Andes Technology - * Macpaul Lin <macpaul@andestech.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <config.h> -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <asm/io.h> -#include <asm/dma-mapping.h> -#include <linux/mii.h> - -#include "ftgmac100.h" - -#define ETH_ZLEN 60 -#define CFG_XBUF_SIZE 1536 - -/* RBSR - hw default init value is also 0x640 */ -#define RBSR_DEFAULT_VALUE 0x640 - -/* PKTBUFSTX/PKTBUFSRX must both be power of 2 */ -#define PKTBUFSTX 4 /* must be power of 2 */ - -struct ftgmac100_data { - ulong txdes_dma; - struct ftgmac100_txdes *txdes; - ulong rxdes_dma; - struct ftgmac100_rxdes *rxdes; - int tx_index; - int rx_index; - int phy_addr; -}; - -/* - * struct mii_bus functions - */ -static int ftgmac100_mdiobus_read(struct eth_device *dev, int phy_addr, - int regnum) -{ - struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; - int phycr; - int i; - - phycr = readl(&ftgmac100->phycr); - - /* preserve MDC cycle threshold */ - phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK; - - phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr) - | FTGMAC100_PHYCR_REGAD(regnum) - | FTGMAC100_PHYCR_MIIRD; - - writel(phycr, &ftgmac100->phycr); - - for (i = 0; i < 10; i++) { - phycr = readl(&ftgmac100->phycr); - - if ((phycr & FTGMAC100_PHYCR_MIIRD) == 0) { - int data; - - data = readl(&ftgmac100->phydata); - return FTGMAC100_PHYDATA_MIIRDATA(data); - } - - mdelay(10); - } - - debug("mdio read timed out\n"); - return -1; -} - -static int ftgmac100_mdiobus_write(struct eth_device *dev, int phy_addr, - int regnum, u16 value) -{ - struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; - int phycr; - int data; - int i; - - phycr = readl(&ftgmac100->phycr); - - /* preserve MDC cycle threshold */ - phycr &= FTGMAC100_PHYCR_MDC_CYCTHR_MASK; - - phycr |= FTGMAC100_PHYCR_PHYAD(phy_addr) - | FTGMAC100_PHYCR_REGAD(regnum) - | FTGMAC100_PHYCR_MIIWR; - - data = FTGMAC100_PHYDATA_MIIWDATA(value); - - writel(data, &ftgmac100->phydata); - writel(phycr, &ftgmac100->phycr); - - for (i = 0; i < 10; i++) { - phycr = readl(&ftgmac100->phycr); - - if ((phycr & FTGMAC100_PHYCR_MIIWR) == 0) { - debug("(phycr & FTGMAC100_PHYCR_MIIWR) == 0: " \ - "phy_addr: %x\n", phy_addr); - return 0; - } - - mdelay(1); - } - - debug("mdio write timed out\n"); - return -1; -} - -int ftgmac100_phy_read(struct eth_device *dev, int addr, int reg, u16 *value) -{ - *value = ftgmac100_mdiobus_read(dev , addr, reg); - - if (*value == -1) - return -1; - - return 0; -} - -int ftgmac100_phy_write(struct eth_device *dev, int addr, int reg, u16 value) -{ - if (ftgmac100_mdiobus_write(dev, addr, reg, value) == -1) - return -1; - - return 0; -} - -static int ftgmac100_phy_reset(struct eth_device *dev) -{ - struct ftgmac100_data *priv = dev->priv; - int i; - u16 status, adv; - - adv = ADVERTISE_CSMA | ADVERTISE_ALL; - - ftgmac100_phy_write(dev, priv->phy_addr, MII_ADVERTISE, adv); - - printf("%s: Starting autonegotiation...\n", dev->name); - - ftgmac100_phy_write(dev, priv->phy_addr, - MII_BMCR, (BMCR_ANENABLE | BMCR_ANRESTART)); - - for (i = 0; i < 100000 / 100; i++) { - ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &status); - - if (status & BMSR_ANEGCOMPLETE) - break; - mdelay(1); - } - - if (status & BMSR_ANEGCOMPLETE) { - printf("%s: Autonegotiation complete\n", dev->name); - } else { - printf("%s: Autonegotiation timed out (status=0x%04x)\n", - dev->name, status); - return 0; - } - - return 1; -} - -static int ftgmac100_phy_init(struct eth_device *dev) -{ - struct ftgmac100_data *priv = dev->priv; - - int phy_addr; - u16 phy_id, status, adv, lpa, stat_ge; - int media, speed, duplex; - int i; - - /* Check if the PHY is up to snuff... */ - for (phy_addr = 0; phy_addr < CONFIG_PHY_MAX_ADDR; phy_addr++) { - - ftgmac100_phy_read(dev, phy_addr, MII_PHYSID1, &phy_id); - - /* - * When it is unable to found PHY, - * the interface usually return 0xffff or 0x0000 - */ - if (phy_id != 0xffff && phy_id != 0x0) { - printf("%s: found PHY at 0x%02x\n", - dev->name, phy_addr); - priv->phy_addr = phy_addr; - break; - } - } - - if (phy_id == 0xffff || phy_id == 0x0) { - printf("%s: no PHY present\n", dev->name); - return 0; - } - - ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &status); - - if (!(status & BMSR_LSTATUS)) { - /* Try to re-negotiate if we don't have link already. */ - ftgmac100_phy_reset(dev); - - for (i = 0; i < 100000 / 100; i++) { - ftgmac100_phy_read(dev, priv->phy_addr, - MII_BMSR, &status); - if (status & BMSR_LSTATUS) - break; - udelay(100); - } - } - - if (!(status & BMSR_LSTATUS)) { - printf("%s: link down\n", dev->name); - return 0; - } - -#ifdef CONFIG_FTGMAC100_EGIGA - /* 1000 Base-T Status Register */ - ftgmac100_phy_read(dev, priv->phy_addr, - MII_STAT1000, &stat_ge); - - speed = (stat_ge & (LPA_1000FULL | LPA_1000HALF) - ? 1 : 0); - - duplex = ((stat_ge & LPA_1000FULL) - ? 1 : 0); - - if (speed) { /* Speed is 1000 */ - printf("%s: link up, 1000bps %s-duplex\n", - dev->name, duplex ? "full" : "half"); - return 0; - } -#endif - - ftgmac100_phy_read(dev, priv->phy_addr, MII_ADVERTISE, &adv); - ftgmac100_phy_read(dev, priv->phy_addr, MII_LPA, &lpa); - - media = mii_nway_result(lpa & adv); - speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? 1 : 0); - duplex = (media & ADVERTISE_FULL) ? 1 : 0; - - printf("%s: link up, %sMbps %s-duplex\n", - dev->name, speed ? "100" : "10", duplex ? "full" : "half"); - - return 1; -} - -static int ftgmac100_update_link_speed(struct eth_device *dev) -{ - struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; - struct ftgmac100_data *priv = dev->priv; - - unsigned short stat_fe; - unsigned short stat_ge; - unsigned int maccr; - -#ifdef CONFIG_FTGMAC100_EGIGA - /* 1000 Base-T Status Register */ - ftgmac100_phy_read(dev, priv->phy_addr, MII_STAT1000, &stat_ge); -#endif - - ftgmac100_phy_read(dev, priv->phy_addr, MII_BMSR, &stat_fe); - - if (!(stat_fe & BMSR_LSTATUS)) /* link status up? */ - return 0; - - /* read MAC control register and clear related bits */ - maccr = readl(&ftgmac100->maccr) & - ~(FTGMAC100_MACCR_GIGA_MODE | - FTGMAC100_MACCR_FAST_MODE | - FTGMAC100_MACCR_FULLDUP); - -#ifdef CONFIG_FTGMAC100_EGIGA - if (stat_ge & LPA_1000FULL) { - /* set gmac for 1000BaseTX and Full Duplex */ - maccr |= FTGMAC100_MACCR_GIGA_MODE | FTGMAC100_MACCR_FULLDUP; - } - - if (stat_ge & LPA_1000HALF) { - /* set gmac for 1000BaseTX and Half Duplex */ - maccr |= FTGMAC100_MACCR_GIGA_MODE; - } -#endif - - if (stat_fe & BMSR_100FULL) { - /* set MII for 100BaseTX and Full Duplex */ - maccr |= FTGMAC100_MACCR_FAST_MODE | FTGMAC100_MACCR_FULLDUP; - } - - if (stat_fe & BMSR_10FULL) { - /* set MII for 10BaseT and Full Duplex */ - maccr |= FTGMAC100_MACCR_FULLDUP; - } - - if (stat_fe & BMSR_100HALF) { - /* set MII for 100BaseTX and Half Duplex */ - maccr |= FTGMAC100_MACCR_FAST_MODE; - } - - if (stat_fe & BMSR_10HALF) { - /* set MII for 10BaseT and Half Duplex */ - /* we have already clear these bits, do nothing */ - ; - } - - /* update MII config into maccr */ - writel(maccr, &ftgmac100->maccr); - - return 1; -} - -/* - * Reset MAC - */ -static void ftgmac100_reset(struct eth_device *dev) -{ - struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; - - debug("%s()\n", __func__); - - writel(FTGMAC100_MACCR_SW_RST, &ftgmac100->maccr); - - while (readl(&ftgmac100->maccr) & FTGMAC100_MACCR_SW_RST) - ; -} - -/* - * Set MAC address - */ -static void ftgmac100_set_mac(struct eth_device *dev, - const unsigned char *mac) -{ - struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; - unsigned int maddr = mac[0] << 8 | mac[1]; - unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; - - debug("%s(%x %x)\n", __func__, maddr, laddr); - - writel(maddr, &ftgmac100->mac_madr); - writel(laddr, &ftgmac100->mac_ladr); -} - -static void ftgmac100_set_mac_from_env(struct eth_device *dev) -{ - eth_getenv_enetaddr("ethaddr", dev->enetaddr); - - ftgmac100_set_mac(dev, dev->enetaddr); -} - -/* - * disable transmitter, receiver - */ -static void ftgmac100_halt(struct eth_device *dev) -{ - struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; - - debug("%s()\n", __func__); - - writel(0, &ftgmac100->maccr); -} - -static int ftgmac100_init(struct eth_device *dev, bd_t *bd) -{ - struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; - struct ftgmac100_data *priv = dev->priv; - struct ftgmac100_txdes *txdes; - struct ftgmac100_rxdes *rxdes; - unsigned int maccr; - void *buf; - int i; - - debug("%s()\n", __func__); - - if (!priv->txdes) { - txdes = dma_alloc_coherent( - sizeof(*txdes) * PKTBUFSTX, &priv->txdes_dma); - if (!txdes) - panic("ftgmac100: out of memory\n"); - memset(txdes, 0, sizeof(*txdes) * PKTBUFSTX); - priv->txdes = txdes; - } - txdes = priv->txdes; - - if (!priv->rxdes) { - rxdes = dma_alloc_coherent( - sizeof(*rxdes) * PKTBUFSRX, &priv->rxdes_dma); - if (!rxdes) - panic("ftgmac100: out of memory\n"); - memset(rxdes, 0, sizeof(*rxdes) * PKTBUFSRX); - priv->rxdes = rxdes; - } - rxdes = priv->rxdes; - - /* set the ethernet address */ - ftgmac100_set_mac_from_env(dev); - - /* disable all interrupts */ - writel(0, &ftgmac100->ier); - - /* initialize descriptors */ - priv->tx_index = 0; - priv->rx_index = 0; - - txdes[PKTBUFSTX - 1].txdes0 = FTGMAC100_TXDES0_EDOTR; - rxdes[PKTBUFSRX - 1].rxdes0 = FTGMAC100_RXDES0_EDORR; - - for (i = 0; i < PKTBUFSTX; i++) { - /* TXBUF_BADR */ - if (!txdes[i].txdes2) { - buf = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE); - if (!buf) - panic("ftgmac100: out of memory\n"); - txdes[i].txdes3 = virt_to_phys(buf); - txdes[i].txdes2 = (uint)buf; - } - txdes[i].txdes1 = 0; - } - - for (i = 0; i < PKTBUFSRX; i++) { - /* RXBUF_BADR */ - if (!rxdes[i].rxdes2) { - buf = NetRxPackets[i]; - rxdes[i].rxdes3 = virt_to_phys(buf); - rxdes[i].rxdes2 = (uint)buf; - } - rxdes[i].rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY; - } - - /* transmit ring */ - writel(priv->txdes_dma, &ftgmac100->txr_badr); - - /* receive ring */ - writel(priv->rxdes_dma, &ftgmac100->rxr_badr); - - /* poll receive descriptor automatically */ - writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc); - - /* config receive buffer size register */ - writel(FTGMAC100_RBSR_SIZE(RBSR_DEFAULT_VALUE), &ftgmac100->rbsr); - - /* enable transmitter, receiver */ - maccr = FTGMAC100_MACCR_TXMAC_EN | - FTGMAC100_MACCR_RXMAC_EN | - FTGMAC100_MACCR_TXDMA_EN | - FTGMAC100_MACCR_RXDMA_EN | - FTGMAC100_MACCR_CRC_APD | - FTGMAC100_MACCR_FULLDUP | - FTGMAC100_MACCR_RX_RUNT | - FTGMAC100_MACCR_RX_BROADPKT; - - writel(maccr, &ftgmac100->maccr); - - if (!ftgmac100_phy_init(dev)) { - if (!ftgmac100_update_link_speed(dev)) - return -1; - } - - return 0; -} - -/* - * Get a data block via Ethernet - */ -static int ftgmac100_recv(struct eth_device *dev) -{ - struct ftgmac100_data *priv = dev->priv; - struct ftgmac100_rxdes *curr_des; - unsigned short rxlen; - - curr_des = &priv->rxdes[priv->rx_index]; - - if (!(curr_des->rxdes0 & FTGMAC100_RXDES0_RXPKT_RDY)) - return -1; - - if (curr_des->rxdes0 & (FTGMAC100_RXDES0_RX_ERR | - FTGMAC100_RXDES0_CRC_ERR | - FTGMAC100_RXDES0_FTL | - FTGMAC100_RXDES0_RUNT | - FTGMAC100_RXDES0_RX_ODD_NB)) { - return -1; - } - - rxlen = FTGMAC100_RXDES0_VDBC(curr_des->rxdes0); - - debug("%s(): RX buffer %d, %x received\n", - __func__, priv->rx_index, rxlen); - - /* invalidate d-cache */ - dma_map_single((void *)curr_des->rxdes2, rxlen, DMA_FROM_DEVICE); - - /* pass the packet up to the protocol layers. */ - NetReceive((void *)curr_des->rxdes2, rxlen); - - /* release buffer to DMA */ - curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY; - - priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX; - - return 0; -} - -/* - * Send a data block via Ethernet - */ -static int ftgmac100_send(struct eth_device *dev, void *packet, int length) -{ - struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; - struct ftgmac100_data *priv = dev->priv; - struct ftgmac100_txdes *curr_des = &priv->txdes[priv->tx_index]; - - if (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) { - debug("%s(): no TX descriptor available\n", __func__); - return -1; - } - - debug("%s(%x, %x)\n", __func__, (int)packet, length); - - length = (length < ETH_ZLEN) ? ETH_ZLEN : length; - - memcpy((void *)curr_des->txdes2, (void *)packet, length); - dma_map_single((void *)curr_des->txdes2, length, DMA_TO_DEVICE); - - /* only one descriptor on TXBUF */ - curr_des->txdes0 &= FTGMAC100_TXDES0_EDOTR; - curr_des->txdes0 |= FTGMAC100_TXDES0_FTS | - FTGMAC100_TXDES0_LTS | - FTGMAC100_TXDES0_TXBUF_SIZE(length) | - FTGMAC100_TXDES0_TXDMA_OWN ; - - /* start transmit */ - writel(1, &ftgmac100->txpd); - - debug("%s(): packet sent\n", __func__); - - priv->tx_index = (priv->tx_index + 1) % PKTBUFSTX; - - return 0; -} - -int ftgmac100_initialize(bd_t *bd) -{ - struct eth_device *dev; - struct ftgmac100_data *priv; - - dev = malloc(sizeof *dev); - if (!dev) { - printf("%s(): failed to allocate dev\n", __func__); - goto out; - } - - /* Transmit and receive descriptors should align to 16 bytes */ - priv = memalign(16, sizeof(struct ftgmac100_data)); - if (!priv) { - printf("%s(): failed to allocate priv\n", __func__); - goto free_dev; - } - - memset(dev, 0, sizeof(*dev)); - memset(priv, 0, sizeof(*priv)); - - sprintf(dev->name, "FTGMAC100"); - dev->iobase = CONFIG_FTGMAC100_BASE; - dev->init = ftgmac100_init; - dev->halt = ftgmac100_halt; - dev->send = ftgmac100_send; - dev->recv = ftgmac100_recv; - dev->priv = priv; - - eth_register(dev); - - ftgmac100_reset(dev); - - return 1; - -free_dev: - free(dev); -out: - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/ftgmac100.h b/qemu/roms/u-boot/drivers/net/ftgmac100.h deleted file mode 100644 index 71121ba9d..000000000 --- a/qemu/roms/u-boot/drivers/net/ftgmac100.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Faraday FTGMAC100 Ethernet - * - * (C) Copyright 2010 Faraday Technology - * Po-Yu Chuang <ratbert@faraday-tech.com> - * - * (C) Copyright 2010 Andes Technology - * Macpaul Lin <macpaul@andestech.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __FTGMAC100_H -#define __FTGMAC100_H - -/* The registers offset table of ftgmac100 */ -struct ftgmac100 { - unsigned int isr; /* 0x00 */ - unsigned int ier; /* 0x04 */ - unsigned int mac_madr; /* 0x08 */ - unsigned int mac_ladr; /* 0x0c */ - unsigned int maht0; /* 0x10 */ - unsigned int maht1; /* 0x14 */ - unsigned int txpd; /* 0x18 */ - unsigned int rxpd; /* 0x1c */ - unsigned int txr_badr; /* 0x20 */ - unsigned int rxr_badr; /* 0x24 */ - unsigned int hptxpd; /* 0x28 */ - unsigned int hptxpd_badr; /* 0x2c */ - unsigned int itc; /* 0x30 */ - unsigned int aptc; /* 0x34 */ - unsigned int dblac; /* 0x38 */ - unsigned int dmafifos; /* 0x3c */ - unsigned int revr; /* 0x40 */ - unsigned int fear; /* 0x44 */ - unsigned int tpafcr; /* 0x48 */ - unsigned int rbsr; /* 0x4c */ - unsigned int maccr; /* 0x50 */ - unsigned int macsr; /* 0x54 */ - unsigned int tm; /* 0x58 */ - unsigned int resv1; /* 0x5c */ /* not defined in spec */ - unsigned int phycr; /* 0x60 */ - unsigned int phydata; /* 0x64 */ - unsigned int fcr; /* 0x68 */ - unsigned int bpr; /* 0x6c */ - unsigned int wolcr; /* 0x70 */ - unsigned int wolsr; /* 0x74 */ - unsigned int wfcrc; /* 0x78 */ - unsigned int resv2; /* 0x7c */ /* not defined in spec */ - unsigned int wfbm1; /* 0x80 */ - unsigned int wfbm2; /* 0x84 */ - unsigned int wfbm3; /* 0x88 */ - unsigned int wfbm4; /* 0x8c */ - unsigned int nptxr_ptr; /* 0x90 */ - unsigned int hptxr_ptr; /* 0x94 */ - unsigned int rxr_ptr; /* 0x98 */ - unsigned int resv3; /* 0x9c */ /* not defined in spec */ - unsigned int tx; /* 0xa0 */ - unsigned int tx_mcol_scol; /* 0xa4 */ - unsigned int tx_ecol_fail; /* 0xa8 */ - unsigned int tx_lcol_und; /* 0xac */ - unsigned int rx; /* 0xb0 */ - unsigned int rx_bc; /* 0xb4 */ - unsigned int rx_mc; /* 0xb8 */ - unsigned int rx_pf_aep; /* 0xbc */ - unsigned int rx_runt; /* 0xc0 */ - unsigned int rx_crcer_ftl; /* 0xc4 */ - unsigned int rx_col_lost; /* 0xc8 */ -}; - -/* - * Interrupt status register & interrupt enable register - */ -#define FTGMAC100_INT_RPKT_BUF (1 << 0) -#define FTGMAC100_INT_RPKT_FIFO (1 << 1) -#define FTGMAC100_INT_NO_RXBUF (1 << 2) -#define FTGMAC100_INT_RPKT_LOST (1 << 3) -#define FTGMAC100_INT_XPKT_ETH (1 << 4) -#define FTGMAC100_INT_XPKT_FIFO (1 << 5) -#define FTGMAC100_INT_NO_NPTXBUF (1 << 6) -#define FTGMAC100_INT_XPKT_LOST (1 << 7) -#define FTGMAC100_INT_AHB_ERR (1 << 8) -#define FTGMAC100_INT_PHYSTS_CHG (1 << 9) -#define FTGMAC100_INT_NO_HPTXBUF (1 << 10) - -/* - * Interrupt timer control register - */ -#define FTGMAC100_ITC_RXINT_CNT(x) (((x) & 0xf) << 0) -#define FTGMAC100_ITC_RXINT_THR(x) (((x) & 0x7) << 4) -#define FTGMAC100_ITC_RXINT_TIME_SEL (1 << 7) -#define FTGMAC100_ITC_TXINT_CNT(x) (((x) & 0xf) << 8) -#define FTGMAC100_ITC_TXINT_THR(x) (((x) & 0x7) << 12) -#define FTGMAC100_ITC_TXINT_TIME_SEL (1 << 15) - -/* - * Automatic polling timer control register - */ -#define FTGMAC100_APTC_RXPOLL_CNT(x) (((x) & 0xf) << 0) -#define FTGMAC100_APTC_RXPOLL_TIME_SEL (1 << 4) -#define FTGMAC100_APTC_TXPOLL_CNT(x) (((x) & 0xf) << 8) -#define FTGMAC100_APTC_TXPOLL_TIME_SEL (1 << 12) - -/* - * DMA burst length and arbitration control register - */ -#define FTGMAC100_DBLAC_RXFIFO_LTHR(x) (((x) & 0x7) << 0) -#define FTGMAC100_DBLAC_RXFIFO_HTHR(x) (((x) & 0x7) << 3) -#define FTGMAC100_DBLAC_RX_THR_EN (1 << 6) -#define FTGMAC100_DBLAC_RXBURST_SIZE(x) (((x) & 0x3) << 8) -#define FTGMAC100_DBLAC_TXBURST_SIZE(x) (((x) & 0x3) << 10) -#define FTGMAC100_DBLAC_RXDES_SIZE(x) (((x) & 0xf) << 12) -#define FTGMAC100_DBLAC_TXDES_SIZE(x) (((x) & 0xf) << 16) -#define FTGMAC100_DBLAC_IFG_CNT(x) (((x) & 0x7) << 20) -#define FTGMAC100_DBLAC_IFG_INC (1 << 23) - -/* - * DMA FIFO status register - */ -#define FTGMAC100_DMAFIFOS_RXDMA1_SM(dmafifos) ((dmafifos) & 0xf) -#define FTGMAC100_DMAFIFOS_RXDMA2_SM(dmafifos) (((dmafifos) >> 4) & 0xf) -#define FTGMAC100_DMAFIFOS_RXDMA3_SM(dmafifos) (((dmafifos) >> 8) & 0x7) -#define FTGMAC100_DMAFIFOS_TXDMA1_SM(dmafifos) (((dmafifos) >> 12) & 0xf) -#define FTGMAC100_DMAFIFOS_TXDMA2_SM(dmafifos) (((dmafifos) >> 16) & 0x3) -#define FTGMAC100_DMAFIFOS_TXDMA3_SM(dmafifos) (((dmafifos) >> 18) & 0xf) -#define FTGMAC100_DMAFIFOS_RXFIFO_EMPTY (1 << 26) -#define FTGMAC100_DMAFIFOS_TXFIFO_EMPTY (1 << 27) -#define FTGMAC100_DMAFIFOS_RXDMA_GRANT (1 << 28) -#define FTGMAC100_DMAFIFOS_TXDMA_GRANT (1 << 29) -#define FTGMAC100_DMAFIFOS_RXDMA_REQ (1 << 30) -#define FTGMAC100_DMAFIFOS_TXDMA_REQ (1 << 31) - -/* - * Receive buffer size register - */ -#define FTGMAC100_RBSR_SIZE(x) ((x) & 0x3fff) - -/* - * MAC control register - */ -#define FTGMAC100_MACCR_TXDMA_EN (1 << 0) -#define FTGMAC100_MACCR_RXDMA_EN (1 << 1) -#define FTGMAC100_MACCR_TXMAC_EN (1 << 2) -#define FTGMAC100_MACCR_RXMAC_EN (1 << 3) -#define FTGMAC100_MACCR_RM_VLAN (1 << 4) -#define FTGMAC100_MACCR_HPTXR_EN (1 << 5) -#define FTGMAC100_MACCR_LOOP_EN (1 << 6) -#define FTGMAC100_MACCR_ENRX_IN_HALFTX (1 << 7) -#define FTGMAC100_MACCR_FULLDUP (1 << 8) -#define FTGMAC100_MACCR_GIGA_MODE (1 << 9) -#define FTGMAC100_MACCR_CRC_APD (1 << 10) -#define FTGMAC100_MACCR_RX_RUNT (1 << 12) -#define FTGMAC100_MACCR_JUMBO_LF (1 << 13) -#define FTGMAC100_MACCR_RX_ALL (1 << 14) -#define FTGMAC100_MACCR_HT_MULTI_EN (1 << 15) -#define FTGMAC100_MACCR_RX_MULTIPKT (1 << 16) -#define FTGMAC100_MACCR_RX_BROADPKT (1 << 17) -#define FTGMAC100_MACCR_DISCARD_CRCERR (1 << 18) -#define FTGMAC100_MACCR_FAST_MODE (1 << 19) -#define FTGMAC100_MACCR_SW_RST (1 << 31) - -/* - * PHY control register - */ -#define FTGMAC100_PHYCR_MDC_CYCTHR_MASK 0x3f -#define FTGMAC100_PHYCR_MDC_CYCTHR(x) ((x) & 0x3f) -#define FTGMAC100_PHYCR_PHYAD(x) (((x) & 0x1f) << 16) -#define FTGMAC100_PHYCR_REGAD(x) (((x) & 0x1f) << 21) -#define FTGMAC100_PHYCR_MIIRD (1 << 26) -#define FTGMAC100_PHYCR_MIIWR (1 << 27) - -/* - * PHY data register - */ -#define FTGMAC100_PHYDATA_MIIWDATA(x) ((x) & 0xffff) -#define FTGMAC100_PHYDATA_MIIRDATA(phydata) (((phydata) >> 16) & 0xffff) - -/* - * Transmit descriptor, aligned to 16 bytes - */ -struct ftgmac100_txdes { - unsigned int txdes0; - unsigned int txdes1; - unsigned int txdes2; /* not used by HW */ - unsigned int txdes3; /* TXBUF_BADR */ -} __attribute__ ((aligned(16))); - -#define FTGMAC100_TXDES0_TXBUF_SIZE(x) ((x) & 0x3fff) -#define FTGMAC100_TXDES0_EDOTR (1 << 15) -#define FTGMAC100_TXDES0_CRC_ERR (1 << 19) -#define FTGMAC100_TXDES0_LTS (1 << 28) -#define FTGMAC100_TXDES0_FTS (1 << 29) -#define FTGMAC100_TXDES0_TXDMA_OWN (1 << 31) - -#define FTGMAC100_TXDES1_VLANTAG_CI(x) ((x) & 0xffff) -#define FTGMAC100_TXDES1_INS_VLANTAG (1 << 16) -#define FTGMAC100_TXDES1_TCP_CHKSUM (1 << 17) -#define FTGMAC100_TXDES1_UDP_CHKSUM (1 << 18) -#define FTGMAC100_TXDES1_IP_CHKSUM (1 << 19) -#define FTGMAC100_TXDES1_LLC (1 << 22) -#define FTGMAC100_TXDES1_TX2FIC (1 << 30) -#define FTGMAC100_TXDES1_TXIC (1 << 31) - -/* - * Receive descriptor, aligned to 16 bytes - */ -struct ftgmac100_rxdes { - unsigned int rxdes0; - unsigned int rxdes1; - unsigned int rxdes2; /* not used by HW */ - unsigned int rxdes3; /* RXBUF_BADR */ -} __attribute__ ((aligned(16))); - -#define FTGMAC100_RXDES0_VDBC(x) ((x) & 0x3fff) -#define FTGMAC100_RXDES0_EDORR (1 << 15) -#define FTGMAC100_RXDES0_MULTICAST (1 << 16) -#define FTGMAC100_RXDES0_BROADCAST (1 << 17) -#define FTGMAC100_RXDES0_RX_ERR (1 << 18) -#define FTGMAC100_RXDES0_CRC_ERR (1 << 19) -#define FTGMAC100_RXDES0_FTL (1 << 20) -#define FTGMAC100_RXDES0_RUNT (1 << 21) -#define FTGMAC100_RXDES0_RX_ODD_NB (1 << 22) -#define FTGMAC100_RXDES0_FIFO_FULL (1 << 23) -#define FTGMAC100_RXDES0_PAUSE_OPCODE (1 << 24) -#define FTGMAC100_RXDES0_PAUSE_FRAME (1 << 25) -#define FTGMAC100_RXDES0_LRS (1 << 28) -#define FTGMAC100_RXDES0_FRS (1 << 29) -#define FTGMAC100_RXDES0_RXPKT_RDY (1 << 31) - -#define FTGMAC100_RXDES1_VLANTAG_CI 0xffff -#define FTGMAC100_RXDES1_PROT_MASK (0x3 << 20) -#define FTGMAC100_RXDES1_PROT_NONIP (0x0 << 20) -#define FTGMAC100_RXDES1_PROT_IP (0x1 << 20) -#define FTGMAC100_RXDES1_PROT_TCPIP (0x2 << 20) -#define FTGMAC100_RXDES1_PROT_UDPIP (0x3 << 20) -#define FTGMAC100_RXDES1_LLC (1 << 22) -#define FTGMAC100_RXDES1_DF (1 << 23) -#define FTGMAC100_RXDES1_VLANTAG_AVAIL (1 << 24) -#define FTGMAC100_RXDES1_TCP_CHKSUM_ERR (1 << 25) -#define FTGMAC100_RXDES1_UDP_CHKSUM_ERR (1 << 26) -#define FTGMAC100_RXDES1_IP_CHKSUM_ERR (1 << 27) - -#endif /* __FTGMAC100_H */ diff --git a/qemu/roms/u-boot/drivers/net/ftmac100.c b/qemu/roms/u-boot/drivers/net/ftmac100.c deleted file mode 100644 index 3e148db5c..000000000 --- a/qemu/roms/u-boot/drivers/net/ftmac100.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Faraday FTMAC100 Ethernet - * - * (C) Copyright 2009 Faraday Technology - * Po-Yu Chuang <ratbert@faraday-tech.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <config.h> -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <asm/io.h> - -#include "ftmac100.h" - -#define ETH_ZLEN 60 - -struct ftmac100_data { - struct ftmac100_txdes txdes[1]; - struct ftmac100_rxdes rxdes[PKTBUFSRX]; - int rx_index; -}; - -/* - * Reset MAC - */ -static void ftmac100_reset (struct eth_device *dev) -{ - struct ftmac100 *ftmac100 = (struct ftmac100 *)dev->iobase; - - debug ("%s()\n", __func__); - - writel (FTMAC100_MACCR_SW_RST, &ftmac100->maccr); - - while (readl (&ftmac100->maccr) & FTMAC100_MACCR_SW_RST) - ; -} - -/* - * Set MAC address - */ -static void ftmac100_set_mac (struct eth_device *dev, const unsigned char *mac) -{ - struct ftmac100 *ftmac100 = (struct ftmac100 *)dev->iobase; - unsigned int maddr = mac[0] << 8 | mac[1]; - unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; - - debug ("%s(%x %x)\n", __func__, maddr, laddr); - - writel (maddr, &ftmac100->mac_madr); - writel (laddr, &ftmac100->mac_ladr); -} - -static void ftmac100_set_mac_from_env (struct eth_device *dev) -{ - eth_getenv_enetaddr ("ethaddr", dev->enetaddr); - - ftmac100_set_mac (dev, dev->enetaddr); -} - -/* - * disable transmitter, receiver - */ -static void ftmac100_halt (struct eth_device *dev) -{ - struct ftmac100 *ftmac100 = (struct ftmac100 *)dev->iobase; - - debug ("%s()\n", __func__); - - writel (0, &ftmac100->maccr); -} - -static int ftmac100_init (struct eth_device *dev, bd_t *bd) -{ - struct ftmac100 *ftmac100 = (struct ftmac100 *)dev->iobase; - struct ftmac100_data *priv = dev->priv; - struct ftmac100_txdes *txdes = priv->txdes; - struct ftmac100_rxdes *rxdes = priv->rxdes; - unsigned int maccr; - int i; - - debug ("%s()\n", __func__); - - ftmac100_reset (dev); - - /* set the ethernet address */ - - ftmac100_set_mac_from_env (dev); - - /* disable all interrupts */ - - writel (0, &ftmac100->imr); - - /* initialize descriptors */ - - priv->rx_index = 0; - - txdes[0].txdes1 = FTMAC100_TXDES1_EDOTR; - rxdes[PKTBUFSRX - 1].rxdes1 = FTMAC100_RXDES1_EDORR; - - for (i = 0; i < PKTBUFSRX; i++) { - /* RXBUF_BADR */ - rxdes[i].rxdes2 = (unsigned int)NetRxPackets[i]; - rxdes[i].rxdes1 |= FTMAC100_RXDES1_RXBUF_SIZE (PKTSIZE_ALIGN); - rxdes[i].rxdes0 = FTMAC100_RXDES0_RXDMA_OWN; - } - - /* transmit ring */ - - writel ((unsigned int)txdes, &ftmac100->txr_badr); - - /* receive ring */ - - writel ((unsigned int)rxdes, &ftmac100->rxr_badr); - - /* poll receive descriptor automatically */ - - writel (FTMAC100_APTC_RXPOLL_CNT (1), &ftmac100->aptc); - - /* enable transmitter, receiver */ - - maccr = FTMAC100_MACCR_XMT_EN | - FTMAC100_MACCR_RCV_EN | - FTMAC100_MACCR_XDMA_EN | - FTMAC100_MACCR_RDMA_EN | - FTMAC100_MACCR_CRC_APD | - FTMAC100_MACCR_ENRX_IN_HALFTX | - FTMAC100_MACCR_RX_RUNT | - FTMAC100_MACCR_RX_BROADPKT; - - writel (maccr, &ftmac100->maccr); - - return 0; -} - -/* - * Get a data block via Ethernet - */ -static int ftmac100_recv (struct eth_device *dev) -{ - struct ftmac100_data *priv = dev->priv; - struct ftmac100_rxdes *curr_des; - unsigned short rxlen; - - curr_des = &priv->rxdes[priv->rx_index]; - - if (curr_des->rxdes0 & FTMAC100_RXDES0_RXDMA_OWN) - return -1; - - if (curr_des->rxdes0 & (FTMAC100_RXDES0_RX_ERR | - FTMAC100_RXDES0_CRC_ERR | - FTMAC100_RXDES0_FTL | - FTMAC100_RXDES0_RUNT | - FTMAC100_RXDES0_RX_ODD_NB)) { - return -1; - } - - rxlen = FTMAC100_RXDES0_RFL (curr_des->rxdes0); - - debug ("%s(): RX buffer %d, %x received\n", - __func__, priv->rx_index, rxlen); - - /* pass the packet up to the protocol layers. */ - - NetReceive ((void *)curr_des->rxdes2, rxlen); - - /* release buffer to DMA */ - - curr_des->rxdes0 |= FTMAC100_RXDES0_RXDMA_OWN; - - priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX; - - return 0; -} - -/* - * Send a data block via Ethernet - */ -static int ftmac100_send(struct eth_device *dev, void *packet, int length) -{ - struct ftmac100 *ftmac100 = (struct ftmac100 *)dev->iobase; - struct ftmac100_data *priv = dev->priv; - struct ftmac100_txdes *curr_des = priv->txdes; - ulong start; - - if (curr_des->txdes0 & FTMAC100_TXDES0_TXDMA_OWN) { - debug ("%s(): no TX descriptor available\n", __func__); - return -1; - } - - debug ("%s(%x, %x)\n", __func__, (int)packet, length); - - length = (length < ETH_ZLEN) ? ETH_ZLEN : length; - - /* initiate a transmit sequence */ - - curr_des->txdes2 = (unsigned int)packet; /* TXBUF_BADR */ - - curr_des->txdes1 &= FTMAC100_TXDES1_EDOTR; - curr_des->txdes1 |= FTMAC100_TXDES1_FTS | - FTMAC100_TXDES1_LTS | - FTMAC100_TXDES1_TXBUF_SIZE (length); - - curr_des->txdes0 = FTMAC100_TXDES0_TXDMA_OWN; - - /* start transmit */ - - writel (1, &ftmac100->txpd); - - /* wait for transfer to succeed */ - - start = get_timer(0); - while (curr_des->txdes0 & FTMAC100_TXDES0_TXDMA_OWN) { - if (get_timer(start) >= 5) { - debug ("%s(): timed out\n", __func__); - return -1; - } - } - - debug ("%s(): packet sent\n", __func__); - - return 0; -} - -int ftmac100_initialize (bd_t *bd) -{ - struct eth_device *dev; - struct ftmac100_data *priv; - - dev = malloc (sizeof *dev); - if (!dev) { - printf ("%s(): failed to allocate dev\n", __func__); - goto out; - } - - /* Transmit and receive descriptors should align to 16 bytes */ - - priv = memalign (16, sizeof (struct ftmac100_data)); - if (!priv) { - printf ("%s(): failed to allocate priv\n", __func__); - goto free_dev; - } - - memset (dev, 0, sizeof (*dev)); - memset (priv, 0, sizeof (*priv)); - - sprintf (dev->name, "FTMAC100"); - dev->iobase = CONFIG_FTMAC100_BASE; - dev->init = ftmac100_init; - dev->halt = ftmac100_halt; - dev->send = ftmac100_send; - dev->recv = ftmac100_recv; - dev->priv = priv; - - eth_register (dev); - - return 1; - -free_dev: - free (dev); -out: - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/ftmac100.h b/qemu/roms/u-boot/drivers/net/ftmac100.h deleted file mode 100644 index b674d0291..000000000 --- a/qemu/roms/u-boot/drivers/net/ftmac100.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Faraday FTMAC100 Ethernet - * - * (C) Copyright 2009 Faraday Technology - * Po-Yu Chuang <ratbert@faraday-tech.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __FTMAC100_H -#define __FTMAC100_H - -struct ftmac100 { - unsigned int isr; /* 0x00 */ - unsigned int imr; /* 0x04 */ - unsigned int mac_madr; /* 0x08 */ - unsigned int mac_ladr; /* 0x0c */ - unsigned int maht0; /* 0x10 */ - unsigned int maht1; /* 0x14 */ - unsigned int txpd; /* 0x18 */ - unsigned int rxpd; /* 0x1c */ - unsigned int txr_badr; /* 0x20 */ - unsigned int rxr_badr; /* 0x24 */ - unsigned int itc; /* 0x28 */ - unsigned int aptc; /* 0x2c */ - unsigned int dblac; /* 0x30 */ - unsigned int pad1[3]; /* 0x34 - 0x3c */ - unsigned int pad2[16]; /* 0x40 - 0x7c */ - unsigned int pad3[2]; /* 0x80 - 0x84 */ - unsigned int maccr; /* 0x88 */ - unsigned int macsr; /* 0x8c */ - unsigned int phycr; /* 0x90 */ - unsigned int phywdata; /* 0x94 */ - unsigned int fcr; /* 0x98 */ - unsigned int bpr; /* 0x9c */ - unsigned int pad4[8]; /* 0xa0 - 0xbc */ - unsigned int pad5; /* 0xc0 */ - unsigned int ts; /* 0xc4 */ - unsigned int dmafifos; /* 0xc8 */ - unsigned int tm; /* 0xcc */ - unsigned int pad6; /* 0xd0 */ - unsigned int tx_mcol_scol; /* 0xd4 */ - unsigned int rpf_aep; /* 0xd8 */ - unsigned int xm_pg; /* 0xdc */ - unsigned int runt_tlcc; /* 0xe0 */ - unsigned int crcer_ftl; /* 0xe4 */ - unsigned int rlc_rcc; /* 0xe8 */ - unsigned int broc; /* 0xec */ - unsigned int mulca; /* 0xf0 */ - unsigned int rp; /* 0xf4 */ - unsigned int xp; /* 0xf8 */ -}; - -/* - * Interrupt status register & interrupt mask register - */ -#define FTMAC100_INT_RPKT_FINISH (1 << 0) -#define FTMAC100_INT_NORXBUF (1 << 1) -#define FTMAC100_INT_XPKT_FINISH (1 << 2) -#define FTMAC100_INT_NOTXBUF (1 << 3) -#define FTMAC100_INT_XPKT_OK (1 << 4) -#define FTMAC100_INT_XPKT_LOST (1 << 5) -#define FTMAC100_INT_RPKT_SAV (1 << 6) -#define FTMAC100_INT_RPKT_LOST (1 << 7) -#define FTMAC100_INT_AHB_ERR (1 << 8) -#define FTMAC100_INT_PHYSTS_CHG (1 << 9) - -/* - * Automatic polling timer control register - */ -#define FTMAC100_APTC_RXPOLL_CNT(x) (((x) & 0xf) << 0) -#define FTMAC100_APTC_RXPOLL_TIME_SEL (1 << 4) -#define FTMAC100_APTC_TXPOLL_CNT(x) (((x) & 0xf) << 8) -#define FTMAC100_APTC_TXPOLL_TIME_SEL (1 << 12) - -/* - * MAC control register - */ -#define FTMAC100_MACCR_XDMA_EN (1 << 0) -#define FTMAC100_MACCR_RDMA_EN (1 << 1) -#define FTMAC100_MACCR_SW_RST (1 << 2) -#define FTMAC100_MACCR_LOOP_EN (1 << 3) -#define FTMAC100_MACCR_CRC_DIS (1 << 4) -#define FTMAC100_MACCR_XMT_EN (1 << 5) -#define FTMAC100_MACCR_ENRX_IN_HALFTX (1 << 6) -#define FTMAC100_MACCR_RCV_EN (1 << 8) -#define FTMAC100_MACCR_HT_MULTI_EN (1 << 9) -#define FTMAC100_MACCR_RX_RUNT (1 << 10) -#define FTMAC100_MACCR_RX_FTL (1 << 11) -#define FTMAC100_MACCR_RCV_ALL (1 << 12) -#define FTMAC100_MACCR_CRC_APD (1 << 14) -#define FTMAC100_MACCR_FULLDUP (1 << 15) -#define FTMAC100_MACCR_RX_MULTIPKT (1 << 16) -#define FTMAC100_MACCR_RX_BROADPKT (1 << 17) - -/* - * Transmit descriptor, aligned to 16 bytes - */ -struct ftmac100_txdes { - unsigned int txdes0; - unsigned int txdes1; - unsigned int txdes2; /* TXBUF_BADR */ - unsigned int txdes3; /* not used by HW */ -} __attribute__ ((aligned(16))); - -#define FTMAC100_TXDES0_TXPKT_LATECOL (1 << 0) -#define FTMAC100_TXDES0_TXPKT_EXSCOL (1 << 1) -#define FTMAC100_TXDES0_TXDMA_OWN (1 << 31) - -#define FTMAC100_TXDES1_TXBUF_SIZE(x) ((x) & 0x7ff) -#define FTMAC100_TXDES1_LTS (1 << 27) -#define FTMAC100_TXDES1_FTS (1 << 28) -#define FTMAC100_TXDES1_TX2FIC (1 << 29) -#define FTMAC100_TXDES1_TXIC (1 << 30) -#define FTMAC100_TXDES1_EDOTR (1 << 31) - -/* - * Receive descriptor, aligned to 16 bytes - */ -struct ftmac100_rxdes { - unsigned int rxdes0; - unsigned int rxdes1; - unsigned int rxdes2; /* RXBUF_BADR */ - unsigned int rxdes3; /* not used by HW */ -} __attribute__ ((aligned(16))); - -#define FTMAC100_RXDES0_RFL(des) ((des) & 0x7ff) -#define FTMAC100_RXDES0_MULTICAST (1 << 16) -#define FTMAC100_RXDES0_BROADCAST (1 << 17) -#define FTMAC100_RXDES0_RX_ERR (1 << 18) -#define FTMAC100_RXDES0_CRC_ERR (1 << 19) -#define FTMAC100_RXDES0_FTL (1 << 20) -#define FTMAC100_RXDES0_RUNT (1 << 21) -#define FTMAC100_RXDES0_RX_ODD_NB (1 << 22) -#define FTMAC100_RXDES0_LRS (1 << 28) -#define FTMAC100_RXDES0_FRS (1 << 29) -#define FTMAC100_RXDES0_RXDMA_OWN (1 << 31) - -#define FTMAC100_RXDES1_RXBUF_SIZE(x) ((x) & 0x7ff) -#define FTMAC100_RXDES1_EDORR (1 << 31) - -#endif /* __FTMAC100_H */ diff --git a/qemu/roms/u-boot/drivers/net/ftmac110.c b/qemu/roms/u-boot/drivers/net/ftmac110.c deleted file mode 100644 index 98c4f0962..000000000 --- a/qemu/roms/u-boot/drivers/net/ftmac110.c +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Faraday 10/100Mbps Ethernet Controller - * - * (C) Copyright 2013 Faraday Technology - * Dante Su <dantesu@faraday-tech.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <command.h> -#include <malloc.h> -#include <net.h> -#include <asm/errno.h> -#include <asm/io.h> -#include <asm/dma-mapping.h> - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) -#include <miiphy.h> -#endif - -#include "ftmac110.h" - -#define CFG_RXDES_NUM 8 -#define CFG_TXDES_NUM 2 -#define CFG_XBUF_SIZE 1536 - -#define CFG_MDIORD_TIMEOUT (CONFIG_SYS_HZ >> 1) /* 500 ms */ -#define CFG_MDIOWR_TIMEOUT (CONFIG_SYS_HZ >> 1) /* 500 ms */ -#define CFG_LINKUP_TIMEOUT (CONFIG_SYS_HZ << 2) /* 4 sec */ - -/* - * FTMAC110 DMA design issue - * - * Its DMA engine has a weird restriction that its Rx DMA engine - * accepts only 16-bits aligned address, 32-bits aligned is not - * acceptable. However this restriction does not apply to Tx DMA. - * - * Conclusion: - * (1) Tx DMA Buffer Address: - * 1 bytes aligned: Invalid - * 2 bytes aligned: O.K - * 4 bytes aligned: O.K (-> u-boot ZeroCopy is possible) - * (2) Rx DMA Buffer Address: - * 1 bytes aligned: Invalid - * 2 bytes aligned: O.K - * 4 bytes aligned: Invalid - */ - -struct ftmac110_chip { - void __iomem *regs; - uint32_t imr; - uint32_t maccr; - uint32_t lnkup; - uint32_t phy_addr; - - struct ftmac110_desc *rxd; - ulong rxd_dma; - uint32_t rxd_idx; - - struct ftmac110_desc *txd; - ulong txd_dma; - uint32_t txd_idx; -}; - -static int ftmac110_reset(struct eth_device *dev); - -static uint16_t mdio_read(struct eth_device *dev, - uint8_t phyaddr, uint8_t phyreg) -{ - struct ftmac110_chip *chip = dev->priv; - struct ftmac110_regs *regs = chip->regs; - uint32_t tmp, ts; - uint16_t ret = 0xffff; - - tmp = PHYCR_READ - | (phyaddr << PHYCR_ADDR_SHIFT) - | (phyreg << PHYCR_REG_SHIFT); - - writel(tmp, ®s->phycr); - - for (ts = get_timer(0); get_timer(ts) < CFG_MDIORD_TIMEOUT; ) { - tmp = readl(®s->phycr); - if (tmp & PHYCR_READ) - continue; - break; - } - - if (tmp & PHYCR_READ) - printf("ftmac110: mdio read timeout\n"); - else - ret = (uint16_t)(tmp & 0xffff); - - return ret; -} - -static void mdio_write(struct eth_device *dev, - uint8_t phyaddr, uint8_t phyreg, uint16_t phydata) -{ - struct ftmac110_chip *chip = dev->priv; - struct ftmac110_regs *regs = chip->regs; - uint32_t tmp, ts; - - tmp = PHYCR_WRITE - | (phyaddr << PHYCR_ADDR_SHIFT) - | (phyreg << PHYCR_REG_SHIFT); - - writel(phydata, ®s->phydr); - writel(tmp, ®s->phycr); - - for (ts = get_timer(0); get_timer(ts) < CFG_MDIOWR_TIMEOUT; ) { - if (readl(®s->phycr) & PHYCR_WRITE) - continue; - break; - } - - if (readl(®s->phycr) & PHYCR_WRITE) - printf("ftmac110: mdio write timeout\n"); -} - -static uint32_t ftmac110_phyqry(struct eth_device *dev) -{ - ulong ts; - uint32_t maccr; - uint16_t pa, tmp, bmsr, bmcr; - struct ftmac110_chip *chip = dev->priv; - - /* Default = 100Mbps Full */ - maccr = MACCR_100M | MACCR_FD; - - /* 1. find the phy device */ - for (pa = 0; pa < 32; ++pa) { - tmp = mdio_read(dev, pa, MII_PHYSID1); - if (tmp == 0xFFFF || tmp == 0x0000) - continue; - chip->phy_addr = pa; - break; - } - if (pa >= 32) { - puts("ftmac110: phy device not found!\n"); - goto exit; - } - - /* 2. wait until link-up & auto-negotiation complete */ - chip->lnkup = 0; - bmcr = mdio_read(dev, chip->phy_addr, MII_BMCR); - ts = get_timer(0); - do { - bmsr = mdio_read(dev, chip->phy_addr, MII_BMSR); - chip->lnkup = (bmsr & BMSR_LSTATUS) ? 1 : 0; - if (!chip->lnkup) - continue; - if (!(bmcr & BMCR_ANENABLE) || (bmsr & BMSR_ANEGCOMPLETE)) - break; - } while (get_timer(ts) < CFG_LINKUP_TIMEOUT); - if (!chip->lnkup) { - puts("ftmac110: link down\n"); - goto exit; - } - if (!(bmcr & BMCR_ANENABLE)) - puts("ftmac110: auto negotiation disabled\n"); - else if (!(bmsr & BMSR_ANEGCOMPLETE)) - puts("ftmac110: auto negotiation timeout\n"); - - /* 3. derive MACCR */ - if ((bmcr & BMCR_ANENABLE) && (bmsr & BMSR_ANEGCOMPLETE)) { - tmp = mdio_read(dev, chip->phy_addr, MII_ADVERTISE); - tmp &= mdio_read(dev, chip->phy_addr, MII_LPA); - if (tmp & LPA_100FULL) /* 100Mbps full-duplex */ - maccr = MACCR_100M | MACCR_FD; - else if (tmp & LPA_100HALF) /* 100Mbps half-duplex */ - maccr = MACCR_100M; - else if (tmp & LPA_10FULL) /* 10Mbps full-duplex */ - maccr = MACCR_FD; - else if (tmp & LPA_10HALF) /* 10Mbps half-duplex */ - maccr = 0; - } else { - if (bmcr & BMCR_SPEED100) - maccr = MACCR_100M; - else - maccr = 0; - if (bmcr & BMCR_FULLDPLX) - maccr |= MACCR_FD; - } - -exit: - printf("ftmac110: %d Mbps, %s\n", - (maccr & MACCR_100M) ? 100 : 10, - (maccr & MACCR_FD) ? "Full" : "half"); - return maccr; -} - -static int ftmac110_reset(struct eth_device *dev) -{ - uint8_t *a; - uint32_t i, maccr; - struct ftmac110_chip *chip = dev->priv; - struct ftmac110_regs *regs = chip->regs; - - /* 1. MAC reset */ - writel(MACCR_RESET, ®s->maccr); - for (i = get_timer(0); get_timer(i) < 1000; ) { - if (readl(®s->maccr) & MACCR_RESET) - continue; - break; - } - if (readl(®s->maccr) & MACCR_RESET) { - printf("ftmac110: reset failed\n"); - return -ENXIO; - } - - /* 1-1. Init tx ring */ - for (i = 0; i < CFG_TXDES_NUM; ++i) { - /* owned by SW */ - chip->txd[i].ctrl &= cpu_to_le64(FTMAC110_TXD_CLRMASK); - } - chip->txd_idx = 0; - - /* 1-2. Init rx ring */ - for (i = 0; i < CFG_RXDES_NUM; ++i) { - /* owned by HW */ - chip->rxd[i].ctrl &= cpu_to_le64(FTMAC110_RXD_CLRMASK); - chip->rxd[i].ctrl |= cpu_to_le64(FTMAC110_RXD_OWNER); - } - chip->rxd_idx = 0; - - /* 2. PHY status query */ - maccr = ftmac110_phyqry(dev); - - /* 3. Fix up the MACCR value */ - chip->maccr = maccr | MACCR_CRCAPD | MACCR_RXALL | MACCR_RXRUNT - | MACCR_RXEN | MACCR_TXEN | MACCR_RXDMAEN | MACCR_TXDMAEN; - - /* 4. MAC address setup */ - a = dev->enetaddr; - writel(a[1] | (a[0] << 8), ®s->mac[0]); - writel(a[5] | (a[4] << 8) | (a[3] << 16) - | (a[2] << 24), ®s->mac[1]); - - /* 5. MAC registers setup */ - writel(chip->rxd_dma, ®s->rxba); - writel(chip->txd_dma, ®s->txba); - /* interrupt at each tx/rx */ - writel(ITC_DEFAULT, ®s->itc); - /* no tx pool, rx poll = 1 normal cycle */ - writel(APTC_DEFAULT, ®s->aptc); - /* rx threshold = [6/8 fifo, 2/8 fifo] */ - writel(DBLAC_DEFAULT, ®s->dblac); - /* disable & clear all interrupt status */ - chip->imr = 0; - writel(ISR_ALL, ®s->isr); - writel(chip->imr, ®s->imr); - /* enable mac */ - writel(chip->maccr, ®s->maccr); - - return 0; -} - -static int ftmac110_probe(struct eth_device *dev, bd_t *bis) -{ - debug("ftmac110: probe\n"); - - if (ftmac110_reset(dev)) - return -1; - - return 0; -} - -static void ftmac110_halt(struct eth_device *dev) -{ - struct ftmac110_chip *chip = dev->priv; - struct ftmac110_regs *regs = chip->regs; - - writel(0, ®s->imr); - writel(0, ®s->maccr); - - debug("ftmac110: halt\n"); -} - -static int ftmac110_send(struct eth_device *dev, void *pkt, int len) -{ - struct ftmac110_chip *chip = dev->priv; - struct ftmac110_regs *regs = chip->regs; - struct ftmac110_desc *txd; - uint64_t ctrl; - - if (!chip->lnkup) - return 0; - - if (len <= 0 || len > CFG_XBUF_SIZE) { - printf("ftmac110: bad tx pkt len(%d)\n", len); - return 0; - } - - len = max(60, len); - - txd = &chip->txd[chip->txd_idx]; - ctrl = le64_to_cpu(txd->ctrl); - if (ctrl & FTMAC110_TXD_OWNER) { - /* kick-off Tx DMA */ - writel(0xffffffff, ®s->txpd); - printf("ftmac110: out of txd\n"); - return 0; - } - - memcpy(txd->vbuf, (void *)pkt, len); - dma_map_single(txd->vbuf, len, DMA_TO_DEVICE); - - /* clear control bits */ - ctrl &= FTMAC110_TXD_CLRMASK; - /* set len, fts and lts */ - ctrl |= FTMAC110_TXD_LEN(len) | FTMAC110_TXD_FTS | FTMAC110_TXD_LTS; - /* set owner bit */ - ctrl |= FTMAC110_TXD_OWNER; - /* write back to descriptor */ - txd->ctrl = cpu_to_le64(ctrl); - - /* kick-off Tx DMA */ - writel(0xffffffff, ®s->txpd); - - chip->txd_idx = (chip->txd_idx + 1) % CFG_TXDES_NUM; - - return len; -} - -static int ftmac110_recv(struct eth_device *dev) -{ - struct ftmac110_chip *chip = dev->priv; - struct ftmac110_desc *rxd; - uint32_t len, rlen = 0; - uint64_t ctrl; - uint8_t *buf; - - if (!chip->lnkup) - return 0; - - do { - rxd = &chip->rxd[chip->rxd_idx]; - ctrl = le64_to_cpu(rxd->ctrl); - if (ctrl & FTMAC110_RXD_OWNER) - break; - - len = (uint32_t)FTMAC110_RXD_LEN(ctrl); - buf = rxd->vbuf; - - if (ctrl & FTMAC110_RXD_ERRMASK) { - printf("ftmac110: rx error\n"); - } else { - dma_map_single(buf, len, DMA_FROM_DEVICE); - NetReceive(buf, len); - rlen += len; - } - - /* owned by hardware */ - ctrl &= FTMAC110_RXD_CLRMASK; - ctrl |= FTMAC110_RXD_OWNER; - rxd->ctrl |= cpu_to_le64(ctrl); - - chip->rxd_idx = (chip->rxd_idx + 1) % CFG_RXDES_NUM; - } while (0); - - return rlen; -} - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - -static int ftmac110_mdio_read( - const char *devname, uint8_t addr, uint8_t reg, uint16_t *value) -{ - int ret = 0; - struct eth_device *dev; - - dev = eth_get_dev_by_name(devname); - if (dev == NULL) { - printf("%s: no such device\n", devname); - ret = -1; - } else { - *value = mdio_read(dev, addr, reg); - } - - return ret; -} - -static int ftmac110_mdio_write( - const char *devname, uint8_t addr, uint8_t reg, uint16_t value) -{ - int ret = 0; - struct eth_device *dev; - - dev = eth_get_dev_by_name(devname); - if (dev == NULL) { - printf("%s: no such device\n", devname); - ret = -1; - } else { - mdio_write(dev, addr, reg, value); - } - - return ret; -} - -#endif /* #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) */ - -int ftmac110_initialize(bd_t *bis) -{ - int i, card_nr = 0; - struct eth_device *dev; - struct ftmac110_chip *chip; - - dev = malloc(sizeof(*dev) + sizeof(*chip)); - if (dev == NULL) { - panic("ftmac110: out of memory 1\n"); - return -1; - } - chip = (struct ftmac110_chip *)(dev + 1); - memset(dev, 0, sizeof(*dev) + sizeof(*chip)); - - sprintf(dev->name, "FTMAC110#%d", card_nr); - - dev->iobase = CONFIG_FTMAC110_BASE; - chip->regs = (void __iomem *)dev->iobase; - dev->priv = chip; - dev->init = ftmac110_probe; - dev->halt = ftmac110_halt; - dev->send = ftmac110_send; - dev->recv = ftmac110_recv; - - if (!eth_getenv_enetaddr_by_index("eth", card_nr, dev->enetaddr)) - eth_random_addr(dev->enetaddr); - - /* allocate tx descriptors (it must be 16 bytes aligned) */ - chip->txd = dma_alloc_coherent( - sizeof(struct ftmac110_desc) * CFG_TXDES_NUM, &chip->txd_dma); - if (!chip->txd) - panic("ftmac110: out of memory 3\n"); - memset(chip->txd, 0, - sizeof(struct ftmac110_desc) * CFG_TXDES_NUM); - for (i = 0; i < CFG_TXDES_NUM; ++i) { - void *va = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE); - - if (!va) - panic("ftmac110: out of memory 4\n"); - chip->txd[i].vbuf = va; - chip->txd[i].pbuf = cpu_to_le32(virt_to_phys(va)); - chip->txd[i].ctrl = 0; /* owned by SW */ - } - chip->txd[i - 1].ctrl |= cpu_to_le64(FTMAC110_TXD_END); - chip->txd_idx = 0; - - /* allocate rx descriptors (it must be 16 bytes aligned) */ - chip->rxd = dma_alloc_coherent( - sizeof(struct ftmac110_desc) * CFG_RXDES_NUM, &chip->rxd_dma); - if (!chip->rxd) - panic("ftmac110: out of memory 4\n"); - memset((void *)chip->rxd, 0, - sizeof(struct ftmac110_desc) * CFG_RXDES_NUM); - for (i = 0; i < CFG_RXDES_NUM; ++i) { - void *va = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE + 2); - - if (!va) - panic("ftmac110: out of memory 5\n"); - /* it needs to be exactly 2 bytes aligned */ - va = ((uint8_t *)va + 2); - chip->rxd[i].vbuf = va; - chip->rxd[i].pbuf = cpu_to_le32(virt_to_phys(va)); - chip->rxd[i].ctrl = cpu_to_le64(FTMAC110_RXD_OWNER - | FTMAC110_RXD_BUFSZ(CFG_XBUF_SIZE)); - } - chip->rxd[i - 1].ctrl |= cpu_to_le64(FTMAC110_RXD_END); - chip->rxd_idx = 0; - - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - miiphy_register(dev->name, ftmac110_mdio_read, ftmac110_mdio_write); -#endif - - card_nr++; - - return card_nr; -} diff --git a/qemu/roms/u-boot/drivers/net/ftmac110.h b/qemu/roms/u-boot/drivers/net/ftmac110.h deleted file mode 100644 index 2772ae7b7..000000000 --- a/qemu/roms/u-boot/drivers/net/ftmac110.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Faraday 10/100Mbps Ethernet Controller - * - * (C) Copyright 2013 Faraday Technology - * Dante Su <dantesu@faraday-tech.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _FTMAC110_H -#define _FTMAC110_H - -struct ftmac110_regs { - uint32_t isr; /* 0x00: Interrups Status Register */ - uint32_t imr; /* 0x04: Interrupt Mask Register */ - uint32_t mac[2]; /* 0x08: MAC Address */ - uint32_t mht[2]; /* 0x10: Multicast Hash Table Register */ - uint32_t txpd; /* 0x18: Tx Poll Demand Register */ - uint32_t rxpd; /* 0x1c: Rx Poll Demand Register */ - uint32_t txba; /* 0x20: Tx Ring Base Address Register */ - uint32_t rxba; /* 0x24: Rx Ring Base Address Register */ - uint32_t itc; /* 0x28: Interrupt Timer Control Register */ - uint32_t aptc; /* 0x2C: Automatic Polling Timer Control Register */ - uint32_t dblac; /* 0x30: DMA Burst Length&Arbitration Control */ - uint32_t revr; /* 0x34: Revision Register */ - uint32_t fear; /* 0x38: Feature Register */ - uint32_t rsvd[19]; - uint32_t maccr; /* 0x88: MAC Control Register */ - uint32_t macsr; /* 0x8C: MAC Status Register */ - uint32_t phycr; /* 0x90: PHY Control Register */ - uint32_t phydr; /* 0x94: PHY Data Register */ - uint32_t fcr; /* 0x98: Flow Control Register */ - uint32_t bpr; /* 0x9C: Back Pressure Register */ -}; - -/* - * Interrupt status/mask register(ISR/IMR) bits - */ -#define ISR_ALL 0x3ff -#define ISR_PHYSTCHG (1 << 9) /* phy status change */ -#define ISR_AHBERR (1 << 8) /* bus error */ -#define ISR_RXLOST (1 << 7) /* rx lost */ -#define ISR_RXFIFO (1 << 6) /* rx to fifo */ -#define ISR_TXLOST (1 << 5) /* tx lost */ -#define ISR_TXOK (1 << 4) /* tx to ethernet */ -#define ISR_NOTXBUF (1 << 3) /* out of tx buffer */ -#define ISR_TXFIFO (1 << 2) /* tx to fifo */ -#define ISR_NORXBUF (1 << 1) /* out of rx buffer */ -#define ISR_RXOK (1 << 0) /* rx to buffer */ - -/* - * MACCR control bits - */ -#define MACCR_100M (1 << 18) /* 100Mbps mode */ -#define MACCR_RXBCST (1 << 17) /* rx broadcast packet */ -#define MACCR_RXMCST (1 << 16) /* rx multicast packet */ -#define MACCR_FD (1 << 15) /* full duplex */ -#define MACCR_CRCAPD (1 << 14) /* tx crc append */ -#define MACCR_RXALL (1 << 12) /* rx all packets */ -#define MACCR_RXFTL (1 << 11) /* rx packet even it's > 1518 byte */ -#define MACCR_RXRUNT (1 << 10) /* rx packet even it's < 64 byte */ -#define MACCR_RXMCSTHT (1 << 9) /* rx multicast hash table */ -#define MACCR_RXEN (1 << 8) /* rx enable */ -#define MACCR_RXINHDTX (1 << 6) /* rx in half duplex tx */ -#define MACCR_TXEN (1 << 5) /* tx enable */ -#define MACCR_CRCDIS (1 << 4) /* tx packet even it's crc error */ -#define MACCR_LOOPBACK (1 << 3) /* loop-back */ -#define MACCR_RESET (1 << 2) /* reset */ -#define MACCR_RXDMAEN (1 << 1) /* rx dma enable */ -#define MACCR_TXDMAEN (1 << 0) /* tx dma enable */ - -/* - * PHYCR control bits - */ -#define PHYCR_READ (1 << 26) -#define PHYCR_WRITE (1 << 27) -#define PHYCR_REG_SHIFT 21 -#define PHYCR_ADDR_SHIFT 16 - -/* - * ITC control bits - */ - -/* Tx Cycle Length */ -#define ITC_TX_CYCLONG (1 << 15) /* 100Mbps=81.92us; 10Mbps=819.2us */ -#define ITC_TX_CYCNORM (0 << 15) /* 100Mbps=5.12us; 10Mbps=51.2us */ -/* Tx Threshold: Aggregate n interrupts as 1 interrupt */ -#define ITC_TX_THR(n) (((n) & 0x7) << 12) -/* Tx Interrupt Timeout = n * Tx Cycle */ -#define ITC_TX_ITMO(n) (((n) & 0xf) << 8) -/* Rx Cycle Length */ -#define ITC_RX_CYCLONG (1 << 7) /* 100Mbps=81.92us; 10Mbps=819.2us */ -#define ITC_RX_CYCNORM (0 << 7) /* 100Mbps=5.12us; 10Mbps=51.2us */ -/* Rx Threshold: Aggregate n interrupts as 1 interrupt */ -#define ITC_RX_THR(n) (((n) & 0x7) << 4) -/* Rx Interrupt Timeout = n * Rx Cycle */ -#define ITC_RX_ITMO(n) (((n) & 0xf) << 0) - -#define ITC_DEFAULT \ - (ITC_TX_THR(1) | ITC_TX_ITMO(0) | ITC_RX_THR(1) | ITC_RX_ITMO(0)) - -/* - * APTC contrl bits - */ - -/* Tx Cycle Length */ -#define APTC_TX_CYCLONG (1 << 12) /* 100Mbps=81.92us; 10Mbps=819.2us */ -#define APTC_TX_CYCNORM (0 << 12) /* 100Mbps=5.12us; 10Mbps=51.2us */ -/* Tx Poll Timeout = n * Tx Cycle, 0=No auto polling */ -#define APTC_TX_PTMO(n) (((n) & 0xf) << 8) -/* Rx Cycle Length */ -#define APTC_RX_CYCLONG (1 << 4) /* 100Mbps=81.92us; 10Mbps=819.2us */ -#define APTC_RX_CYCNORM (0 << 4) /* 100Mbps=5.12us; 10Mbps=51.2us */ -/* Rx Poll Timeout = n * Rx Cycle, 0=No auto polling */ -#define APTC_RX_PTMO(n) (((n) & 0xf) << 0) - -#define APTC_DEFAULT (APTC_TX_PTMO(0) | APTC_RX_PTMO(1)) - -/* - * DBLAC contrl bits - */ -#define DBLAC_BURST_MAX_ANY (0 << 14) /* un-limited */ -#define DBLAC_BURST_MAX_32X4 (2 << 14) /* max = 32 x 4 bytes */ -#define DBLAC_BURST_MAX_64X4 (3 << 14) /* max = 64 x 4 bytes */ -#define DBLAC_RXTHR_EN (1 << 9) /* enable rx threshold arbitration */ -#define DBLAC_RXTHR_HIGH(n) (((n) & 0x7) << 6) /* upper bound = n/8 fifo */ -#define DBLAC_RXTHR_LOW(n) (((n) & 0x7) << 3) /* lower bound = n/8 fifo */ -#define DBLAC_BURST_CAP16 (1 << 2) /* support burst 16 */ -#define DBLAC_BURST_CAP8 (1 << 1) /* support burst 8 */ -#define DBLAC_BURST_CAP4 (1 << 0) /* support burst 4 */ - -#define DBLAC_DEFAULT \ - (DBLAC_RXTHR_EN | DBLAC_RXTHR_HIGH(6) | DBLAC_RXTHR_LOW(2)) - -/* - * descriptor structure - */ -struct ftmac110_desc { - uint64_t ctrl; - uint32_t pbuf; - void *vbuf; -}; - -#define FTMAC110_RXD_END ((uint64_t)1 << 63) -#define FTMAC110_RXD_BUFSZ(x) (((uint64_t)(x) & 0x7ff) << 32) - -#define FTMAC110_RXD_OWNER ((uint64_t)1 << 31) /* owner: 1=HW, 0=SW */ -#define FTMAC110_RXD_FRS ((uint64_t)1 << 29) /* first pkt desc */ -#define FTMAC110_RXD_LRS ((uint64_t)1 << 28) /* last pkt desc */ -#define FTMAC110_RXD_ODDNB ((uint64_t)1 << 22) /* odd nibble */ -#define FTMAC110_RXD_RUNT ((uint64_t)1 << 21) /* runt pkt */ -#define FTMAC110_RXD_FTL ((uint64_t)1 << 20) /* frame too long */ -#define FTMAC110_RXD_CRC ((uint64_t)1 << 19) /* pkt crc error */ -#define FTMAC110_RXD_ERR ((uint64_t)1 << 18) /* bus error */ -#define FTMAC110_RXD_ERRMASK ((uint64_t)0x1f << 18) -#define FTMAC110_RXD_BCST ((uint64_t)1 << 17) /* Bcst pkt */ -#define FTMAC110_RXD_MCST ((uint64_t)1 << 16) /* Mcst pkt */ -#define FTMAC110_RXD_LEN(x) ((uint64_t)((x) & 0x7ff)) - -#define FTMAC110_RXD_CLRMASK \ - (FTMAC110_RXD_END | FTMAC110_RXD_BUFSZ(0x7ff)) - -#define FTMAC110_TXD_END ((uint64_t)1 << 63) /* end of ring */ -#define FTMAC110_TXD_TXIC ((uint64_t)1 << 62) /* tx done interrupt */ -#define FTMAC110_TXD_TX2FIC ((uint64_t)1 << 61) /* tx fifo interrupt */ -#define FTMAC110_TXD_FTS ((uint64_t)1 << 60) /* first pkt desc */ -#define FTMAC110_TXD_LTS ((uint64_t)1 << 59) /* last pkt desc */ -#define FTMAC110_TXD_LEN(x) ((uint64_t)((x) & 0x7ff) << 32) - -#define FTMAC110_TXD_OWNER ((uint64_t)1 << 31) /* owner: 1=HW, 0=SW */ -#define FTMAC110_TXD_COL ((uint64_t)3) /* collision */ - -#define FTMAC110_TXD_CLRMASK \ - (FTMAC110_TXD_END) - -#endif /* FTMAC110_H */ diff --git a/qemu/roms/u-boot/drivers/net/greth.c b/qemu/roms/u-boot/drivers/net/greth.c deleted file mode 100644 index c817af4da..000000000 --- a/qemu/roms/u-boot/drivers/net/greth.c +++ /dev/null @@ -1,670 +0,0 @@ -/* Gaisler.com GRETH 10/100/1000 Ethernet MAC driver - * - * Driver use polling mode (no Interrupt) - * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* #define DEBUG */ - -#include <common.h> -#include <command.h> -#include <net.h> -#include <netdev.h> -#include <malloc.h> -#include <asm/processor.h> -#include <ambapp.h> -#include <asm/leon.h> - -#include "greth.h" - -/* Default to 3s timeout on autonegotiation */ -#ifndef GRETH_PHY_TIMEOUT_MS -#define GRETH_PHY_TIMEOUT_MS 3000 -#endif - -/* Default to PHY adrress 0 not not specified */ -#ifdef CONFIG_SYS_GRLIB_GRETH_PHYADDR -#define GRETH_PHY_ADR_DEFAULT CONFIG_SYS_GRLIB_GRETH_PHYADDR -#else -#define GRETH_PHY_ADR_DEFAULT 0 -#endif - -/* ByPass Cache when reading regs */ -#define GRETH_REGLOAD(addr) SPARC_NOCACHE_READ(addr) -/* Write-through cache ==> no bypassing needed on writes */ -#define GRETH_REGSAVE(addr,data) (*(volatile unsigned int *)(addr) = (data)) -#define GRETH_REGORIN(addr,data) GRETH_REGSAVE(addr,GRETH_REGLOAD(addr)|data) -#define GRETH_REGANDIN(addr,data) GRETH_REGSAVE(addr,GRETH_REGLOAD(addr)&data) - -#define GRETH_RXBD_CNT 4 -#define GRETH_TXBD_CNT 1 - -#define GRETH_RXBUF_SIZE 1540 -#define GRETH_BUF_ALIGN 4 -#define GRETH_RXBUF_EFF_SIZE \ - ( (GRETH_RXBUF_SIZE&~(GRETH_BUF_ALIGN-1))+GRETH_BUF_ALIGN ) - -typedef struct { - greth_regs *regs; - int irq; - struct eth_device *dev; - - /* Hardware info */ - unsigned char phyaddr; - int gbit_mac; - - /* Current operating Mode */ - int gb; /* GigaBit */ - int fd; /* Full Duplex */ - int sp; /* 10/100Mbps speed (1=100,0=10) */ - int auto_neg; /* Auto negotiate done */ - - unsigned char hwaddr[6]; /* MAC Address */ - - /* Descriptors */ - greth_bd *rxbd_base, *rxbd_max; - greth_bd *txbd_base, *txbd_max; - - greth_bd *rxbd_curr; - - /* rx buffers in rx descriptors */ - void *rxbuf_base; /* (GRETH_RXBUF_SIZE+ALIGNBYTES) * GRETH_RXBD_CNT */ - - /* unused for gbit_mac, temp buffer for sending packets with unligned - * start. - * Pointer to packet allocated with malloc. - */ - void *txbuf; - - struct { - /* rx status */ - unsigned int rx_packets, - rx_crc_errors, rx_frame_errors, rx_length_errors, rx_errors; - - /* tx stats */ - unsigned int tx_packets, - tx_latecol_errors, - tx_underrun_errors, tx_limit_errors, tx_errors; - } stats; -} greth_priv; - -/* Read MII register 'addr' from core 'regs' */ -static int read_mii(int phyaddr, int regaddr, volatile greth_regs * regs) -{ - while (GRETH_REGLOAD(®s->mdio) & GRETH_MII_BUSY) { - } - - GRETH_REGSAVE(®s->mdio, ((phyaddr & 0x1F) << 11) | ((regaddr & 0x1F) << 6) | 2); - - while (GRETH_REGLOAD(®s->mdio) & GRETH_MII_BUSY) { - } - - if (!(GRETH_REGLOAD(®s->mdio) & GRETH_MII_NVALID)) { - return (GRETH_REGLOAD(®s->mdio) >> 16) & 0xFFFF; - } else { - return -1; - } -} - -static void write_mii(int phyaddr, int regaddr, int data, volatile greth_regs * regs) -{ - while (GRETH_REGLOAD(®s->mdio) & GRETH_MII_BUSY) { - } - - GRETH_REGSAVE(®s->mdio, - ((data & 0xFFFF) << 16) | ((phyaddr & 0x1F) << 11) | - ((regaddr & 0x1F) << 6) | 1); - - while (GRETH_REGLOAD(®s->mdio) & GRETH_MII_BUSY) { - } - -} - -/* init/start hardware and allocate descriptor buffers for rx side - * - */ -int greth_init(struct eth_device *dev, bd_t * bis) -{ - int i; - - greth_priv *greth = dev->priv; - greth_regs *regs = greth->regs; - - debug("greth_init\n"); - - /* Reset core */ - GRETH_REGSAVE(®s->control, (GRETH_RESET | (greth->gb << 8) | - (greth->sp << 7) | (greth->fd << 4))); - - /* Wait for Reset to complete */ - while ( GRETH_REGLOAD(®s->control) & GRETH_RESET) ; - - GRETH_REGSAVE(®s->control, - ((greth->gb << 8) | (greth->sp << 7) | (greth->fd << 4))); - - if (!greth->rxbd_base) { - - /* allocate descriptors */ - greth->rxbd_base = (greth_bd *) - memalign(0x1000, GRETH_RXBD_CNT * sizeof(greth_bd)); - greth->txbd_base = (greth_bd *) - memalign(0x1000, GRETH_TXBD_CNT * sizeof(greth_bd)); - - /* allocate buffers to all descriptors */ - greth->rxbuf_base = - malloc(GRETH_RXBUF_EFF_SIZE * GRETH_RXBD_CNT); - } - - /* initate rx decriptors */ - for (i = 0; i < GRETH_RXBD_CNT; i++) { - greth->rxbd_base[i].addr = (unsigned int) - greth->rxbuf_base + (GRETH_RXBUF_EFF_SIZE * i); - /* enable desciptor & set wrap bit if last descriptor */ - if (i >= (GRETH_RXBD_CNT - 1)) { - greth->rxbd_base[i].stat = GRETH_BD_EN | GRETH_BD_WR; - } else { - greth->rxbd_base[i].stat = GRETH_BD_EN; - } - } - - /* initiate indexes */ - greth->rxbd_curr = greth->rxbd_base; - greth->rxbd_max = greth->rxbd_base + (GRETH_RXBD_CNT - 1); - greth->txbd_max = greth->txbd_base + (GRETH_TXBD_CNT - 1); - /* - * greth->txbd_base->addr = 0; - * greth->txbd_base->stat = GRETH_BD_WR; - */ - - /* initate tx decriptors */ - for (i = 0; i < GRETH_TXBD_CNT; i++) { - greth->txbd_base[i].addr = 0; - /* enable desciptor & set wrap bit if last descriptor */ - if (i >= (GRETH_TXBD_CNT - 1)) { - greth->txbd_base[i].stat = GRETH_BD_WR; - } else { - greth->txbd_base[i].stat = 0; - } - } - - /**** SET HARDWARE REGS ****/ - - /* Set pointer to tx/rx descriptor areas */ - GRETH_REGSAVE(®s->rx_desc_p, (unsigned int)&greth->rxbd_base[0]); - GRETH_REGSAVE(®s->tx_desc_p, (unsigned int)&greth->txbd_base[0]); - - /* Enable Transmitter, GRETH will now scan descriptors for packets - * to transmitt */ - debug("greth_init: enabling receiver\n"); - GRETH_REGORIN(®s->control, GRETH_RXEN); - - return 0; -} - -/* Initiate PHY to a relevant speed - * return: - * - 0 = success - * - 1 = timeout/fail - */ -int greth_init_phy(greth_priv * dev, bd_t * bis) -{ - greth_regs *regs = dev->regs; - int tmp, tmp1, tmp2, i; - unsigned int start, timeout; - int phyaddr = GRETH_PHY_ADR_DEFAULT; - -#ifndef CONFIG_SYS_GRLIB_GRETH_PHYADDR - /* If BSP doesn't provide a hardcoded PHY address the driver will - * try to autodetect PHY address by stopping the search on the first - * PHY address which has REG0 implemented. - */ - for (i=0; i<32; i++) { - tmp = read_mii(i, 0, regs); - if ( (tmp != 0) && (tmp != 0xffff) ) { - phyaddr = i; - break; - } - } -#endif - - /* Save PHY Address */ - dev->phyaddr = phyaddr; - - debug("GRETH PHY ADDRESS: %d\n", phyaddr); - - /* X msecs to ticks */ - timeout = usec2ticks(GRETH_PHY_TIMEOUT_MS * 1000); - - /* Get system timer0 current value - * Total timeout is 5s - */ - start = get_timer(0); - - /* get phy control register default values */ - - while ((tmp = read_mii(phyaddr, 0, regs)) & 0x8000) { - if (get_timer(start) > timeout) { - debug("greth_init_phy: PHY read 1 failed\n"); - return 1; /* Fail */ - } - } - - /* reset PHY and wait for completion */ - write_mii(phyaddr, 0, 0x8000 | tmp, regs); - - while (((tmp = read_mii(phyaddr, 0, regs))) & 0x8000) { - if (get_timer(start) > timeout) { - debug("greth_init_phy: PHY read 2 failed\n"); - return 1; /* Fail */ - } - } - - /* Check if PHY is autoneg capable and then determine operating - * mode, otherwise force it to 10 Mbit halfduplex - */ - dev->gb = 0; - dev->fd = 0; - dev->sp = 0; - dev->auto_neg = 0; - if (!((tmp >> 12) & 1)) { - write_mii(phyaddr, 0, 0, regs); - } else { - /* wait for auto negotiation to complete and then check operating mode */ - dev->auto_neg = 1; - i = 0; - while (!(((tmp = read_mii(phyaddr, 1, regs)) >> 5) & 1)) { - if (get_timer(start) > timeout) { - printf("Auto negotiation timed out. " - "Selecting default config\n"); - tmp = read_mii(phyaddr, 0, regs); - dev->gb = ((tmp >> 6) & 1) - && !((tmp >> 13) & 1); - dev->sp = !((tmp >> 6) & 1) - && ((tmp >> 13) & 1); - dev->fd = (tmp >> 8) & 1; - goto auto_neg_done; - } - } - if ((tmp >> 8) & 1) { - tmp1 = read_mii(phyaddr, 9, regs); - tmp2 = read_mii(phyaddr, 10, regs); - if ((tmp1 & GRETH_MII_EXTADV_1000FD) && - (tmp2 & GRETH_MII_EXTPRT_1000FD)) { - dev->gb = 1; - dev->fd = 1; - } - if ((tmp1 & GRETH_MII_EXTADV_1000HD) && - (tmp2 & GRETH_MII_EXTPRT_1000HD)) { - dev->gb = 1; - dev->fd = 0; - } - } - if ((dev->gb == 0) || ((dev->gb == 1) && (dev->gbit_mac == 0))) { - tmp1 = read_mii(phyaddr, 4, regs); - tmp2 = read_mii(phyaddr, 5, regs); - if ((tmp1 & GRETH_MII_100TXFD) && - (tmp2 & GRETH_MII_100TXFD)) { - dev->sp = 1; - dev->fd = 1; - } - if ((tmp1 & GRETH_MII_100TXHD) && - (tmp2 & GRETH_MII_100TXHD)) { - dev->sp = 1; - dev->fd = 0; - } - if ((tmp1 & GRETH_MII_10FD) && (tmp2 & GRETH_MII_10FD)) { - dev->fd = 1; - } - if ((dev->gb == 1) && (dev->gbit_mac == 0)) { - dev->gb = 0; - dev->fd = 0; - write_mii(phyaddr, 0, dev->sp << 13, regs); - } - } - - } - auto_neg_done: - debug("%s GRETH Ethermac at [0x%x] irq %d. Running \ - %d Mbps %s duplex\n", dev->gbit_mac ? "10/100/1000" : "10/100", (unsigned int)(regs), (unsigned int)(dev->irq), dev->gb ? 1000 : (dev->sp ? 100 : 10), dev->fd ? "full" : "half"); - /* Read out PHY info if extended registers are available */ - if (tmp & 1) { - tmp1 = read_mii(phyaddr, 2, regs); - tmp2 = read_mii(phyaddr, 3, regs); - tmp1 = (tmp1 << 6) | ((tmp2 >> 10) & 0x3F); - tmp = tmp2 & 0xF; - - tmp2 = (tmp2 >> 4) & 0x3F; - debug("PHY: Vendor %x Device %x Revision %d\n", tmp1, - tmp2, tmp); - } else { - printf("PHY info not available\n"); - } - - /* set speed and duplex bits in control register */ - GRETH_REGORIN(®s->control, - (dev->gb << 8) | (dev->sp << 7) | (dev->fd << 4)); - - return 0; -} - -void greth_halt(struct eth_device *dev) -{ - greth_priv *greth; - greth_regs *regs; - int i; - - debug("greth_halt\n"); - - if (!dev || !dev->priv) - return; - - greth = dev->priv; - regs = greth->regs; - - if (!regs) - return; - - /* disable receiver/transmitter by clearing the enable bits */ - GRETH_REGANDIN(®s->control, ~(GRETH_RXEN | GRETH_TXEN)); - - /* reset rx/tx descriptors */ - if (greth->rxbd_base) { - for (i = 0; i < GRETH_RXBD_CNT; i++) { - greth->rxbd_base[i].stat = - (i >= (GRETH_RXBD_CNT - 1)) ? GRETH_BD_WR : 0; - } - } - - if (greth->txbd_base) { - for (i = 0; i < GRETH_TXBD_CNT; i++) { - greth->txbd_base[i].stat = - (i >= (GRETH_TXBD_CNT - 1)) ? GRETH_BD_WR : 0; - } - } -} - -int greth_send(struct eth_device *dev, void *eth_data, int data_length) -{ - greth_priv *greth = dev->priv; - greth_regs *regs = greth->regs; - greth_bd *txbd; - void *txbuf; - unsigned int status; - - debug("greth_send\n"); - - /* send data, wait for data to be sent, then return */ - if (((unsigned int)eth_data & (GRETH_BUF_ALIGN - 1)) - && !greth->gbit_mac) { - /* data not aligned as needed by GRETH 10/100, solve this by allocating 4 byte aligned buffer - * and copy data to before giving it to GRETH. - */ - if (!greth->txbuf) { - greth->txbuf = malloc(GRETH_RXBUF_SIZE); - } - - txbuf = greth->txbuf; - - /* copy data info buffer */ - memcpy((char *)txbuf, (char *)eth_data, data_length); - - /* keep buffer to next time */ - } else { - txbuf = (void *)eth_data; - } - /* get descriptor to use, only 1 supported... hehe easy */ - txbd = greth->txbd_base; - - /* setup descriptor to wrap around to it self */ - txbd->addr = (unsigned int)txbuf; - txbd->stat = GRETH_BD_EN | GRETH_BD_WR | data_length; - - /* Remind Core which descriptor to use when sending */ - GRETH_REGSAVE(®s->tx_desc_p, (unsigned int)txbd); - - /* initate send by enabling transmitter */ - GRETH_REGORIN(®s->control, GRETH_TXEN); - - /* Wait for data to be sent */ - while ((status = GRETH_REGLOAD(&txbd->stat)) & GRETH_BD_EN) { - ; - } - - /* was the packet transmitted succesfully? */ - if (status & GRETH_TXBD_ERR_AL) { - greth->stats.tx_limit_errors++; - } - - if (status & GRETH_TXBD_ERR_UE) { - greth->stats.tx_underrun_errors++; - } - - if (status & GRETH_TXBD_ERR_LC) { - greth->stats.tx_latecol_errors++; - } - - if (status & - (GRETH_TXBD_ERR_LC | GRETH_TXBD_ERR_UE | GRETH_TXBD_ERR_AL)) { - /* any error */ - greth->stats.tx_errors++; - return -1; - } - - /* bump tx packet counter */ - greth->stats.tx_packets++; - - /* return succefully */ - return 0; -} - -int greth_recv(struct eth_device *dev) -{ - greth_priv *greth = dev->priv; - greth_regs *regs = greth->regs; - greth_bd *rxbd; - unsigned int status, len = 0, bad; - char *d; - int enable = 0; - int i; - - /* Receive One packet only, but clear as many error packets as there are - * available. - */ - { - /* current receive descriptor */ - rxbd = greth->rxbd_curr; - - /* get status of next received packet */ - status = GRETH_REGLOAD(&rxbd->stat); - - bad = 0; - - /* stop if no more packets received */ - if (status & GRETH_BD_EN) { - goto done; - } - - debug("greth_recv: packet 0x%x, 0x%x, len: %d\n", - (unsigned int)rxbd, status, status & GRETH_BD_LEN); - - /* Check status for errors. - */ - if (status & GRETH_RXBD_ERR_FT) { - greth->stats.rx_length_errors++; - bad = 1; - } - if (status & (GRETH_RXBD_ERR_AE | GRETH_RXBD_ERR_OE)) { - greth->stats.rx_frame_errors++; - bad = 1; - } - if (status & GRETH_RXBD_ERR_CRC) { - greth->stats.rx_crc_errors++; - bad = 1; - } - if (bad) { - greth->stats.rx_errors++; - printf - ("greth_recv: Bad packet (%d, %d, %d, 0x%08x, %d)\n", - greth->stats.rx_length_errors, - greth->stats.rx_frame_errors, - greth->stats.rx_crc_errors, status, - greth->stats.rx_packets); - /* print all rx descriptors */ - for (i = 0; i < GRETH_RXBD_CNT; i++) { - printf("[%d]: Stat=0x%lx, Addr=0x%lx\n", i, - GRETH_REGLOAD(&greth->rxbd_base[i].stat), - GRETH_REGLOAD(&greth->rxbd_base[i].addr)); - } - } else { - /* Process the incoming packet. */ - len = status & GRETH_BD_LEN; - d = (char *)rxbd->addr; - - debug - ("greth_recv: new packet, length: %d. data: %x %x %x %x %x %x %x %x\n", - len, d[0], d[1], d[2], d[3], d[4], d[5], d[6], - d[7]); - - /* flush all data cache to make sure we're not reading old packet data */ - sparc_dcache_flush_all(); - - /* pass packet on to network subsystem */ - NetReceive((void *)d, len); - - /* bump stats counters */ - greth->stats.rx_packets++; - - /* bad is now 0 ==> will stop loop */ - } - - /* reenable descriptor to receive more packet with this descriptor, wrap around if needed */ - rxbd->stat = - GRETH_BD_EN | - (((unsigned int)greth->rxbd_curr >= - (unsigned int)greth->rxbd_max) ? GRETH_BD_WR : 0); - enable = 1; - - /* increase index */ - greth->rxbd_curr = - ((unsigned int)greth->rxbd_curr >= - (unsigned int)greth->rxbd_max) ? greth-> - rxbd_base : (greth->rxbd_curr + 1); - - } - - if (enable) { - GRETH_REGORIN(®s->control, GRETH_RXEN); - } - done: - /* return positive length of packet or 0 if non received */ - return len; -} - -void greth_set_hwaddr(greth_priv * greth, unsigned char *mac) -{ - /* save new MAC address */ - greth->dev->enetaddr[0] = greth->hwaddr[0] = mac[0]; - greth->dev->enetaddr[1] = greth->hwaddr[1] = mac[1]; - greth->dev->enetaddr[2] = greth->hwaddr[2] = mac[2]; - greth->dev->enetaddr[3] = greth->hwaddr[3] = mac[3]; - greth->dev->enetaddr[4] = greth->hwaddr[4] = mac[4]; - greth->dev->enetaddr[5] = greth->hwaddr[5] = mac[5]; - greth->regs->esa_msb = (mac[0] << 8) | mac[1]; - greth->regs->esa_lsb = - (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5]; - - debug("GRETH: New MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); -} - -int greth_initialize(bd_t * bis) -{ - greth_priv *greth; - ambapp_apbdev apbdev; - struct eth_device *dev; - int i; - char *addr_str, *end; - unsigned char addr[6]; - - debug("Scanning for GRETH\n"); - - /* Find Device & IRQ via AMBA Plug&Play information */ - if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_ETHMAC, &apbdev) != 1) { - return -1; /* GRETH not found */ - } - - greth = (greth_priv *) malloc(sizeof(greth_priv)); - dev = (struct eth_device *)malloc(sizeof(struct eth_device)); - memset(dev, 0, sizeof(struct eth_device)); - memset(greth, 0, sizeof(greth_priv)); - - greth->regs = (greth_regs *) apbdev.address; - greth->irq = apbdev.irq; - debug("Found GRETH at %p, irq %d\n", greth->regs, greth->irq); - dev->priv = (void *)greth; - dev->iobase = (unsigned int)greth->regs; - dev->init = greth_init; - dev->halt = greth_halt; - dev->send = greth_send; - dev->recv = greth_recv; - greth->dev = dev; - - /* Reset Core */ - GRETH_REGSAVE(&greth->regs->control, GRETH_RESET); - - /* Wait for core to finish reset cycle */ - while (GRETH_REGLOAD(&greth->regs->control) & GRETH_RESET) ; - - /* Get the phy address which assumed to have been set - correctly with the reset value in hardware */ - greth->phyaddr = (GRETH_REGLOAD(&greth->regs->mdio) >> 11) & 0x1F; - - /* Check if mac is gigabit capable */ - greth->gbit_mac = (GRETH_REGLOAD(&greth->regs->control) >> 27) & 1; - - /* Make descriptor string */ - if (greth->gbit_mac) { - sprintf(dev->name, "GRETH_10/100/GB"); - } else { - sprintf(dev->name, "GRETH_10/100"); - } - - /* initiate PHY, select speed/duplex depending on connected PHY */ - if (greth_init_phy(greth, bis)) { - /* Failed to init PHY (timedout) */ - debug("GRETH[%p]: Failed to init PHY\n", greth->regs); - return -1; - } - - /* Register Device to EtherNet subsystem */ - eth_register(dev); - - /* Get MAC address */ - if ((addr_str = getenv("ethaddr")) != NULL) { - for (i = 0; i < 6; i++) { - addr[i] = - addr_str ? simple_strtoul(addr_str, &end, 16) : 0; - if (addr_str) { - addr_str = (*end) ? end + 1 : end; - } - } - } else { - /* HW Address not found in environment, Set default HW address */ - addr[0] = GRETH_HWADDR_0; /* MSB */ - addr[1] = GRETH_HWADDR_1; - addr[2] = GRETH_HWADDR_2; - addr[3] = GRETH_HWADDR_3; - addr[4] = GRETH_HWADDR_4; - addr[5] = GRETH_HWADDR_5; /* LSB */ - } - - /* set and remember MAC address */ - greth_set_hwaddr(greth, addr); - - debug("GRETH[%p]: Initialized successfully\n", greth->regs); - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/greth.h b/qemu/roms/u-boot/drivers/net/greth.h deleted file mode 100644 index 5299b2861..000000000 --- a/qemu/roms/u-boot/drivers/net/greth.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Gaisler.com GRETH 10/100/1000 Ethernet MAC driver - * - * (C) Copyright 2007 - * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#define GRETH_FD 0x10 -#define GRETH_RESET 0x40 -#define GRETH_MII_BUSY 0x8 -#define GRETH_MII_NVALID 0x10 - -/* MII registers */ -#define GRETH_MII_EXTADV_1000FD 0x00000200 -#define GRETH_MII_EXTADV_1000HD 0x00000100 -#define GRETH_MII_EXTPRT_1000FD 0x00000800 -#define GRETH_MII_EXTPRT_1000HD 0x00000400 - -#define GRETH_MII_100T4 0x00000200 -#define GRETH_MII_100TXFD 0x00000100 -#define GRETH_MII_100TXHD 0x00000080 -#define GRETH_MII_10FD 0x00000040 -#define GRETH_MII_10HD 0x00000020 - -#define GRETH_BD_EN 0x800 -#define GRETH_BD_WR 0x1000 -#define GRETH_BD_IE 0x2000 -#define GRETH_BD_LEN 0x7FF - -#define GRETH_TXEN 0x1 -#define GRETH_INT_TX 0x8 -#define GRETH_TXI 0x4 -#define GRETH_TXBD_STATUS 0x0001C000 -#define GRETH_TXBD_MORE 0x20000 -#define GRETH_TXBD_IPCS 0x40000 -#define GRETH_TXBD_TCPCS 0x80000 -#define GRETH_TXBD_UDPCS 0x100000 -#define GRETH_TXBD_ERR_LC 0x10000 -#define GRETH_TXBD_ERR_UE 0x4000 -#define GRETH_TXBD_ERR_AL 0x8000 -#define GRETH_TXBD_NUM 128 -#define GRETH_TXBD_NUM_MASK (GRETH_TXBD_NUM-1) -#define GRETH_TX_BUF_SIZE 2048 - -#define GRETH_INT_RX 0x4 -#define GRETH_RXEN 0x2 -#define GRETH_RXI 0x8 -#define GRETH_RXBD_STATUS 0xFFFFC000 -#define GRETH_RXBD_ERR_AE 0x4000 -#define GRETH_RXBD_ERR_FT 0x8000 -#define GRETH_RXBD_ERR_CRC 0x10000 -#define GRETH_RXBD_ERR_OE 0x20000 -#define GRETH_RXBD_ERR_LE 0x40000 -#define GRETH_RXBD_IP_DEC 0x80000 -#define GRETH_RXBD_IP_CSERR 0x100000 -#define GRETH_RXBD_UDP_DEC 0x200000 -#define GRETH_RXBD_UDP_CSERR 0x400000 -#define GRETH_RXBD_TCP_DEC 0x800000 -#define GRETH_RXBD_TCP_CSERR 0x1000000 - -#define GRETH_RXBD_NUM 128 -#define GRETH_RXBD_NUM_MASK (GRETH_RXBD_NUM-1) -#define GRETH_RX_BUF_SIZE 2048 - -/* Ethernet configuration registers */ -typedef struct _greth_regs { - volatile unsigned int control; - volatile unsigned int status; - volatile unsigned int esa_msb; - volatile unsigned int esa_lsb; - volatile unsigned int mdio; - volatile unsigned int tx_desc_p; - volatile unsigned int rx_desc_p; -} greth_regs; - -/* Ethernet buffer descriptor */ -typedef struct _greth_bd { - volatile unsigned int stat; - unsigned int addr; /* Buffer address not changed by HW */ -} greth_bd; diff --git a/qemu/roms/u-boot/drivers/net/keystone_net.c b/qemu/roms/u-boot/drivers/net/keystone_net.c deleted file mode 100644 index f95c92807..000000000 --- a/qemu/roms/u-boot/drivers/net/keystone_net.c +++ /dev/null @@ -1,716 +0,0 @@ -/* - * Ethernet driver for TI K2HK EVM. - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, <www.ti.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> -#include <command.h> - -#include <net.h> -#include <miiphy.h> -#include <malloc.h> -#include <asm/arch/emac_defs.h> -#include <asm/arch/psc_defs.h> -#include <asm/arch/keystone_nav.h> - -unsigned int emac_dbg; - -unsigned int emac_open; -static unsigned int sys_has_mdio = 1; - -#ifdef KEYSTONE2_EMAC_GIG_ENABLE -#define emac_gigabit_enable(x) keystone2_eth_gigabit_enable(x) -#else -#define emac_gigabit_enable(x) /* no gigabit to enable */ -#endif - -#define RX_BUFF_NUMS 24 -#define RX_BUFF_LEN 1520 -#define MAX_SIZE_STREAM_BUFFER RX_BUFF_LEN - -static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16); - -struct rx_buff_desc net_rx_buffs = { - .buff_ptr = rx_buffs, - .num_buffs = RX_BUFF_NUMS, - .buff_len = RX_BUFF_LEN, - .rx_flow = 22, -}; - -static void keystone2_eth_mdio_enable(void); - -static int gen_get_link_speed(int phy_addr); - -/* EMAC Addresses */ -static volatile struct emac_regs *adap_emac = - (struct emac_regs *)EMAC_EMACSL_BASE_ADDR; -static volatile struct mdio_regs *adap_mdio = - (struct mdio_regs *)EMAC_MDIO_BASE_ADDR; - -int keystone2_eth_read_mac_addr(struct eth_device *dev) -{ - struct eth_priv_t *eth_priv; - u32 maca = 0; - u32 macb = 0; - - eth_priv = (struct eth_priv_t *)dev->priv; - - /* Read the e-fuse mac address */ - if (eth_priv->slave_port == 1) { - maca = __raw_readl(MAC_ID_BASE_ADDR); - macb = __raw_readl(MAC_ID_BASE_ADDR + 4); - } - - dev->enetaddr[0] = (macb >> 8) & 0xff; - dev->enetaddr[1] = (macb >> 0) & 0xff; - dev->enetaddr[2] = (maca >> 24) & 0xff; - dev->enetaddr[3] = (maca >> 16) & 0xff; - dev->enetaddr[4] = (maca >> 8) & 0xff; - dev->enetaddr[5] = (maca >> 0) & 0xff; - - return 0; -} - -static void keystone2_eth_mdio_enable(void) -{ - u_int32_t clkdiv; - - clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1; - - writel((clkdiv & 0xffff) | - MDIO_CONTROL_ENABLE | - MDIO_CONTROL_FAULT | - MDIO_CONTROL_FAULT_ENABLE, - &adap_mdio->control); - - while (readl(&adap_mdio->control) & MDIO_CONTROL_IDLE) - ; -} - -/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */ -int keystone2_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data) -{ - int tmp; - - while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO) - ; - - writel(MDIO_USERACCESS0_GO | - MDIO_USERACCESS0_WRITE_READ | - ((reg_num & 0x1f) << 21) | - ((phy_addr & 0x1f) << 16), - &adap_mdio->useraccess0); - - /* Wait for command to complete */ - while ((tmp = readl(&adap_mdio->useraccess0)) & MDIO_USERACCESS0_GO) - ; - - if (tmp & MDIO_USERACCESS0_ACK) { - *data = tmp & 0xffff; - return 0; - } - - *data = -1; - return -1; -} - -/* - * Write to a PHY register via MDIO inteface. - * Blocks until operation is complete. - */ -int keystone2_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data) -{ - while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO) - ; - - writel(MDIO_USERACCESS0_GO | - MDIO_USERACCESS0_WRITE_WRITE | - ((reg_num & 0x1f) << 21) | - ((phy_addr & 0x1f) << 16) | - (data & 0xffff), - &adap_mdio->useraccess0); - - /* Wait for command to complete */ - while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO) - ; - - return 0; -} - -/* PHY functions for a generic PHY */ -static int gen_get_link_speed(int phy_addr) -{ - u_int16_t tmp; - - if ((!keystone2_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp)) && - (tmp & 0x04)) { - return 0; - } - - return -1; -} - -static void __attribute__((unused)) - keystone2_eth_gigabit_enable(struct eth_device *dev) -{ - u_int16_t data; - struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; - - if (sys_has_mdio) { - if (keystone2_eth_phy_read(eth_priv->phy_addr, 0, &data) || - !(data & (1 << 6))) /* speed selection MSB */ - return; - } - - /* - * Check if link detected is giga-bit - * If Gigabit mode detected, enable gigbit in MAC - */ - writel(readl(&(adap_emac[eth_priv->slave_port - 1].maccontrol)) | - EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE, - &(adap_emac[eth_priv->slave_port - 1].maccontrol)) - ; -} - -int keystone_sgmii_link_status(int port) -{ - u32 status = 0; - - status = __raw_readl(SGMII_STATUS_REG(port)); - - return status & SGMII_REG_STATUS_LINK; -} - - -int keystone_get_link_status(struct eth_device *dev) -{ - struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; - int sgmii_link; - int link_state = 0; -#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1 - int j; - - for (j = 0; (j < CONFIG_GET_LINK_STATUS_ATTEMPTS) && (link_state == 0); - j++) { -#endif - sgmii_link = - keystone_sgmii_link_status(eth_priv->slave_port - 1); - - if (sgmii_link) { - link_state = 1; - - if (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) - if (gen_get_link_speed(eth_priv->phy_addr)) - link_state = 0; - } -#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1 - } -#endif - return link_state; -} - -int keystone_sgmii_config(int port, int interface) -{ - unsigned int i, status, mask; - unsigned int mr_adv_ability, control; - - switch (interface) { - case SGMII_LINK_MAC_MAC_AUTONEG: - mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | - SGMII_REG_MR_ADV_LINK | - SGMII_REG_MR_ADV_FULL_DUPLEX | - SGMII_REG_MR_ADV_GIG_MODE); - control = (SGMII_REG_CONTROL_MASTER | - SGMII_REG_CONTROL_AUTONEG); - - break; - case SGMII_LINK_MAC_PHY: - case SGMII_LINK_MAC_PHY_FORCED: - mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; - control = SGMII_REG_CONTROL_AUTONEG; - - break; - case SGMII_LINK_MAC_MAC_FORCED: - mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | - SGMII_REG_MR_ADV_LINK | - SGMII_REG_MR_ADV_FULL_DUPLEX | - SGMII_REG_MR_ADV_GIG_MODE); - control = SGMII_REG_CONTROL_MASTER; - - break; - case SGMII_LINK_MAC_FIBER: - mr_adv_ability = 0x20; - control = SGMII_REG_CONTROL_AUTONEG; - - break; - default: - mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; - control = SGMII_REG_CONTROL_AUTONEG; - } - - __raw_writel(0, SGMII_CTL_REG(port)); - - /* - * Wait for the SerDes pll to lock, - * but don't trap if lock is never read - */ - for (i = 0; i < 1000; i++) { - udelay(2000); - status = __raw_readl(SGMII_STATUS_REG(port)); - if ((status & SGMII_REG_STATUS_LOCK) != 0) - break; - } - - __raw_writel(mr_adv_ability, SGMII_MRADV_REG(port)); - __raw_writel(control, SGMII_CTL_REG(port)); - - - mask = SGMII_REG_STATUS_LINK; - - if (control & SGMII_REG_CONTROL_AUTONEG) - mask |= SGMII_REG_STATUS_AUTONEG; - - for (i = 0; i < 1000; i++) { - status = __raw_readl(SGMII_STATUS_REG(port)); - if ((status & mask) == mask) - break; - } - - return 0; -} - -int mac_sl_reset(u32 port) -{ - u32 i, v; - - if (port >= DEVICE_N_GMACSL_PORTS) - return GMACSL_RET_INVALID_PORT; - - /* Set the soft reset bit */ - DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + - CPGMACSL_REG_RESET, CPGMAC_REG_RESET_VAL_RESET); - - /* Wait for the bit to clear */ - for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { - v = DEVICE_REG32_R(DEVICE_EMACSL_BASE(port) + - CPGMACSL_REG_RESET); - if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) != - CPGMAC_REG_RESET_VAL_RESET) - return GMACSL_RET_OK; - } - - /* Timeout on the reset */ - return GMACSL_RET_WARN_RESET_INCOMPLETE; -} - -int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg) -{ - u32 v, i; - int ret = GMACSL_RET_OK; - - if (port >= DEVICE_N_GMACSL_PORTS) - return GMACSL_RET_INVALID_PORT; - - if (cfg->max_rx_len > CPGMAC_REG_MAXLEN_LEN) { - cfg->max_rx_len = CPGMAC_REG_MAXLEN_LEN; - ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG; - } - - /* Must wait if the device is undergoing reset */ - for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { - v = DEVICE_REG32_R(DEVICE_EMACSL_BASE(port) + - CPGMACSL_REG_RESET); - if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) != - CPGMAC_REG_RESET_VAL_RESET) - break; - } - - if (i == DEVICE_EMACSL_RESET_POLL_COUNT) - return GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE; - - DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN, - cfg->max_rx_len); - - DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL, - cfg->ctl); - - return ret; -} - -int ethss_config(u32 ctl, u32 max_pkt_size) -{ - u32 i; - - /* Max length register */ - DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_MAXLEN, max_pkt_size); - - /* Control register */ - DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_CTL, ctl); - - /* All statistics enabled by default */ - DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_STAT_PORT_EN, - CPSW_REG_VAL_STAT_ENABLE_ALL); - - /* Reset and enable the ALE */ - DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_ALE_CONTROL, - CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE | - CPSW_REG_VAL_ALE_CTL_BYPASS); - - /* All ports put into forward mode */ - for (i = 0; i < DEVICE_CPSW_NUM_PORTS; i++) - DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_ALE_PORTCTL(i), - CPSW_REG_VAL_PORTCTL_FORWARD_MODE); - - return 0; -} - -int ethss_start(void) -{ - int i; - struct mac_sl_cfg cfg; - - cfg.max_rx_len = MAX_SIZE_STREAM_BUFFER; - cfg.ctl = GMACSL_ENABLE | GMACSL_RX_ENABLE_EXT_CTL; - - for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) { - mac_sl_reset(i); - mac_sl_config(i, &cfg); - } - - return 0; -} - -int ethss_stop(void) -{ - int i; - - for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) - mac_sl_reset(i); - - return 0; -} - -int32_t cpmac_drv_send(u32 *buffer, int num_bytes, int slave_port_num) -{ - if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE) - num_bytes = EMAC_MIN_ETHERNET_PKT_SIZE; - - return netcp_send(buffer, num_bytes, (slave_port_num) << 16); -} - -/* Eth device open */ -static int keystone2_eth_open(struct eth_device *dev, bd_t *bis) -{ - u_int32_t clkdiv; - int link; - struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; - - debug("+ emac_open\n"); - - net_rx_buffs.rx_flow = eth_priv->rx_flow; - - sys_has_mdio = - (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0; - - psc_enable_module(KS2_LPSC_PA); - psc_enable_module(KS2_LPSC_CPGMAC); - - sgmii_serdes_setup_156p25mhz(); - - if (sys_has_mdio) - keystone2_eth_mdio_enable(); - - keystone_sgmii_config(eth_priv->slave_port - 1, - eth_priv->sgmii_link_type); - - udelay(10000); - - /* On chip switch configuration */ - ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE); - - /* TODO: add error handling code */ - if (qm_init()) { - printf("ERROR: qm_init()\n"); - return -1; - } - if (netcp_init(&net_rx_buffs)) { - qm_close(); - printf("ERROR: netcp_init()\n"); - return -1; - } - - /* - * Streaming switch configuration. If not present this - * statement is defined to void in target.h. - * If present this is usually defined to a series of register writes - */ - hw_config_streaming_switch(); - - if (sys_has_mdio) { - /* Init MDIO & get link state */ - clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1; - writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | - MDIO_CONTROL_FAULT, &adap_mdio->control) - ; - - /* We need to wait for MDIO to start */ - udelay(1000); - - link = keystone_get_link_status(dev); - if (link == 0) { - netcp_close(); - qm_close(); - return -1; - } - } - - emac_gigabit_enable(dev); - - ethss_start(); - - debug("- emac_open\n"); - - emac_open = 1; - - return 0; -} - -/* Eth device close */ -void keystone2_eth_close(struct eth_device *dev) -{ - debug("+ emac_close\n"); - - if (!emac_open) - return; - - ethss_stop(); - - netcp_close(); - qm_close(); - - emac_open = 0; - - debug("- emac_close\n"); -} - -static int tx_send_loop; - -/* - * This function sends a single packet on the network and returns - * positive number (number of bytes transmitted) or negative for error - */ -static int keystone2_eth_send_packet(struct eth_device *dev, - void *packet, int length) -{ - int ret_status = -1; - struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; - - tx_send_loop = 0; - - if (keystone_get_link_status(dev) == 0) - return -1; - - emac_gigabit_enable(dev); - - if (cpmac_drv_send((u32 *)packet, length, eth_priv->slave_port) != 0) - return ret_status; - - if (keystone_get_link_status(dev) == 0) - return -1; - - emac_gigabit_enable(dev); - - return length; -} - -/* - * This function handles receipt of a packet from the network - */ -static int keystone2_eth_rcv_packet(struct eth_device *dev) -{ - void *hd; - int pkt_size; - u32 *pkt; - - hd = netcp_recv(&pkt, &pkt_size); - if (hd == NULL) - return 0; - - NetReceive((uchar *)pkt, pkt_size); - - netcp_release_rxhd(hd); - - return pkt_size; -} - -/* - * This function initializes the EMAC hardware. - */ -int keystone2_emac_initialize(struct eth_priv_t *eth_priv) -{ - struct eth_device *dev; - - dev = malloc(sizeof(struct eth_device)); - if (dev == NULL) - return -1; - - memset(dev, 0, sizeof(struct eth_device)); - - strcpy(dev->name, eth_priv->int_name); - dev->priv = eth_priv; - - keystone2_eth_read_mac_addr(dev); - - dev->iobase = 0; - dev->init = keystone2_eth_open; - dev->halt = keystone2_eth_close; - dev->send = keystone2_eth_send_packet; - dev->recv = keystone2_eth_rcv_packet; - - eth_register(dev); - - return 0; -} - -void sgmii_serdes_setup_156p25mhz(void) -{ - unsigned int cnt; - - /* - * configure Serializer/Deserializer (SerDes) hardware. SerDes IP - * hardware vendor published only register addresses and their values - * to be used for configuring SerDes. So had to use hardcoded values - * below. - */ - clrsetbits_le32(0x0232a000, 0xffff0000, 0x00800000); - clrsetbits_le32(0x0232a014, 0x0000ffff, 0x00008282); - clrsetbits_le32(0x0232a060, 0x00ffffff, 0x00142438); - clrsetbits_le32(0x0232a064, 0x00ffff00, 0x00c3c700); - clrsetbits_le32(0x0232a078, 0x0000ff00, 0x0000c000); - - clrsetbits_le32(0x0232a204, 0xff0000ff, 0x38000080); - clrsetbits_le32(0x0232a208, 0x000000ff, 0x00000000); - clrsetbits_le32(0x0232a20c, 0xff000000, 0x02000000); - clrsetbits_le32(0x0232a210, 0xff000000, 0x1b000000); - clrsetbits_le32(0x0232a214, 0x0000ffff, 0x00006fb8); - clrsetbits_le32(0x0232a218, 0xffff00ff, 0x758000e4); - clrsetbits_le32(0x0232a2ac, 0x0000ff00, 0x00004400); - clrsetbits_le32(0x0232a22c, 0x00ffff00, 0x00200800); - clrsetbits_le32(0x0232a280, 0x00ff00ff, 0x00820082); - clrsetbits_le32(0x0232a284, 0xffffffff, 0x1d0f0385); - - clrsetbits_le32(0x0232a404, 0xff0000ff, 0x38000080); - clrsetbits_le32(0x0232a408, 0x000000ff, 0x00000000); - clrsetbits_le32(0x0232a40c, 0xff000000, 0x02000000); - clrsetbits_le32(0x0232a410, 0xff000000, 0x1b000000); - clrsetbits_le32(0x0232a414, 0x0000ffff, 0x00006fb8); - clrsetbits_le32(0x0232a418, 0xffff00ff, 0x758000e4); - clrsetbits_le32(0x0232a4ac, 0x0000ff00, 0x00004400); - clrsetbits_le32(0x0232a42c, 0x00ffff00, 0x00200800); - clrsetbits_le32(0x0232a480, 0x00ff00ff, 0x00820082); - clrsetbits_le32(0x0232a484, 0xffffffff, 0x1d0f0385); - - clrsetbits_le32(0x0232a604, 0xff0000ff, 0x38000080); - clrsetbits_le32(0x0232a608, 0x000000ff, 0x00000000); - clrsetbits_le32(0x0232a60c, 0xff000000, 0x02000000); - clrsetbits_le32(0x0232a610, 0xff000000, 0x1b000000); - clrsetbits_le32(0x0232a614, 0x0000ffff, 0x00006fb8); - clrsetbits_le32(0x0232a618, 0xffff00ff, 0x758000e4); - clrsetbits_le32(0x0232a6ac, 0x0000ff00, 0x00004400); - clrsetbits_le32(0x0232a62c, 0x00ffff00, 0x00200800); - clrsetbits_le32(0x0232a680, 0x00ff00ff, 0x00820082); - clrsetbits_le32(0x0232a684, 0xffffffff, 0x1d0f0385); - - clrsetbits_le32(0x0232a804, 0xff0000ff, 0x38000080); - clrsetbits_le32(0x0232a808, 0x000000ff, 0x00000000); - clrsetbits_le32(0x0232a80c, 0xff000000, 0x02000000); - clrsetbits_le32(0x0232a810, 0xff000000, 0x1b000000); - clrsetbits_le32(0x0232a814, 0x0000ffff, 0x00006fb8); - clrsetbits_le32(0x0232a818, 0xffff00ff, 0x758000e4); - clrsetbits_le32(0x0232a8ac, 0x0000ff00, 0x00004400); - clrsetbits_le32(0x0232a82c, 0x00ffff00, 0x00200800); - clrsetbits_le32(0x0232a880, 0x00ff00ff, 0x00820082); - clrsetbits_le32(0x0232a884, 0xffffffff, 0x1d0f0385); - - clrsetbits_le32(0x0232aa00, 0x0000ff00, 0x00000800); - clrsetbits_le32(0x0232aa08, 0xffff0000, 0x38a20000); - clrsetbits_le32(0x0232aa30, 0x00ffff00, 0x008a8a00); - clrsetbits_le32(0x0232aa84, 0x0000ff00, 0x00000600); - clrsetbits_le32(0x0232aa94, 0xff000000, 0x10000000); - clrsetbits_le32(0x0232aaa0, 0xff000000, 0x81000000); - clrsetbits_le32(0x0232aabc, 0xff000000, 0xff000000); - clrsetbits_le32(0x0232aac0, 0x000000ff, 0x0000008b); - clrsetbits_le32(0x0232ab08, 0xffff0000, 0x583f0000); - clrsetbits_le32(0x0232ab0c, 0x000000ff, 0x0000004e); - clrsetbits_le32(0x0232a000, 0x000000ff, 0x00000003); - clrsetbits_le32(0x0232aa00, 0x000000ff, 0x0000005f); - - clrsetbits_le32(0x0232aa48, 0x00ffff00, 0x00fd8c00); - clrsetbits_le32(0x0232aa54, 0x00ffffff, 0x002fec72); - clrsetbits_le32(0x0232aa58, 0xffffff00, 0x00f92100); - clrsetbits_le32(0x0232aa5c, 0xffffffff, 0x00040060); - clrsetbits_le32(0x0232aa60, 0xffffffff, 0x00008000); - clrsetbits_le32(0x0232aa64, 0xffffffff, 0x0c581220); - clrsetbits_le32(0x0232aa68, 0xffffffff, 0xe13b0602); - clrsetbits_le32(0x0232aa6c, 0xffffffff, 0xb8074cc1); - clrsetbits_le32(0x0232aa70, 0xffffffff, 0x3f02e989); - clrsetbits_le32(0x0232aa74, 0x000000ff, 0x00000001); - clrsetbits_le32(0x0232ab20, 0x00ff0000, 0x00370000); - clrsetbits_le32(0x0232ab1c, 0xff000000, 0x37000000); - clrsetbits_le32(0x0232ab20, 0x000000ff, 0x0000005d); - - /*Bring SerDes out of Reset if SerDes is Shutdown & is in Reset Mode*/ - clrbits_le32(0x0232a010, 1 << 28); - - /* Enable TX and RX via the LANExCTL_STS 0x0000 + x*4 */ - clrbits_le32(0x0232a228, 1 << 29); - writel(0xF800F8C0, 0x0232bfe0); - clrbits_le32(0x0232a428, 1 << 29); - writel(0xF800F8C0, 0x0232bfe4); - clrbits_le32(0x0232a628, 1 << 29); - writel(0xF800F8C0, 0x0232bfe8); - clrbits_le32(0x0232a828, 1 << 29); - writel(0xF800F8C0, 0x0232bfec); - - /*Enable pll via the pll_ctrl 0x0014*/ - writel(0xe0000000, 0x0232bff4) - ; - - /*Waiting for SGMII Serdes PLL lock.*/ - for (cnt = 10000; cnt > 0 && ((readl(0x02090114) & 0x10) == 0); cnt--) - ; - - for (cnt = 10000; cnt > 0 && ((readl(0x02090214) & 0x10) == 0); cnt--) - ; - - for (cnt = 10000; cnt > 0 && ((readl(0x02090414) & 0x10) == 0); cnt--) - ; - - for (cnt = 10000; cnt > 0 && ((readl(0x02090514) & 0x10) == 0); cnt--) - ; - - udelay(45000); -} - -void sgmii_serdes_shutdown(void) -{ - /* - * shutdown SerDes hardware. SerDes hardware vendor published only - * register addresses and their values. So had to use hardcoded - * values below. - */ - clrbits_le32(0x0232bfe0, 3 << 29 | 3 << 13); - setbits_le32(0x02320228, 1 << 29); - clrbits_le32(0x0232bfe4, 3 << 29 | 3 << 13); - setbits_le32(0x02320428, 1 << 29); - clrbits_le32(0x0232bfe8, 3 << 29 | 3 << 13); - setbits_le32(0x02320628, 1 << 29); - clrbits_le32(0x0232bfec, 3 << 29 | 3 << 13); - setbits_le32(0x02320828, 1 << 29); - - clrbits_le32(0x02320034, 3 << 29); - setbits_le32(0x02320010, 1 << 28); -} diff --git a/qemu/roms/u-boot/drivers/net/ks8695eth.c b/qemu/roms/u-boot/drivers/net/ks8695eth.c deleted file mode 100644 index b4822e950..000000000 --- a/qemu/roms/u-boot/drivers/net/ks8695eth.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * ks8695eth.c -- KS8695 ethernet driver - * - * (C) Copyright 2004-2005, Greg Ungerer <greg.ungerer@opengear.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/****************************************************************************/ - -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <asm/io.h> -#include <asm/arch/platform.h> - -/****************************************************************************/ - -/* - * Hardware register access to the KS8695 LAN ethernet port - * (well, it is the 4 port switch really). - */ -#define ks8695_read(a) *((volatile unsigned long *) (KS8695_IO_BASE + (a))) -#define ks8695_write(a,v) *((volatile unsigned long *) (KS8695_IO_BASE + (a))) = (v) - -/****************************************************************************/ - -/* - * Define the descriptor in-memory data structures. - */ -struct ks8695_txdesc { - uint32_t owner; - uint32_t ctrl; - uint32_t addr; - uint32_t next; -}; - -struct ks8695_rxdesc { - uint32_t status; - uint32_t ctrl; - uint32_t addr; - uint32_t next; -}; - -/****************************************************************************/ - -/* - * Allocate local data structures to use for receiving and sending - * packets. Just to keep it all nice and simple. - */ - -#define TXDESCS 4 -#define RXDESCS 4 -#define BUFSIZE 2048 - -volatile struct ks8695_txdesc ks8695_tx[TXDESCS] __attribute__((aligned(256))); -volatile struct ks8695_rxdesc ks8695_rx[RXDESCS] __attribute__((aligned(256))); -volatile uint8_t ks8695_bufs[BUFSIZE*(TXDESCS+RXDESCS)] __attribute__((aligned(2048)));; - -/****************************************************************************/ - -/* - * Ideally we want to use the MAC address stored in flash. - * But we do some sanity checks in case they are not present - * first. - */ -unsigned char eth_mac[] = { - 0x00, 0x13, 0xc6, 0x00, 0x00, 0x00 -}; - -void ks8695_getmac(void) -{ - unsigned char *fp; - int i; - - /* Check if flash MAC is valid */ - fp = (unsigned char *) 0x0201c000; - for (i = 0; (i < 6); i++) { - if ((fp[i] != 0) && (fp[i] != 0xff)) - break; - } - - /* If we found a valid looking MAC address then use it */ - if (i < 6) - memcpy(ð_mac[0], fp, 6); -} - -/****************************************************************************/ - -static int ks8695_eth_init(struct eth_device *dev, bd_t *bd) -{ - int i; - - debug ("%s(%d): eth_reset()\n", __FILE__, __LINE__); - - /* Reset the ethernet engines first */ - ks8695_write(KS8695_LAN_DMA_TX, 0x80000000); - ks8695_write(KS8695_LAN_DMA_RX, 0x80000000); - - ks8695_getmac(); - - /* Set MAC address */ - ks8695_write(KS8695_LAN_MAC_LOW, (eth_mac[5] | (eth_mac[4] << 8) | - (eth_mac[3] << 16) | (eth_mac[2] << 24))); - ks8695_write(KS8695_LAN_MAC_HIGH, (eth_mac[1] | (eth_mac[0] << 8))); - - /* Turn the 4 port switch on */ - i = ks8695_read(KS8695_SWITCH_CTRL0); - ks8695_write(KS8695_SWITCH_CTRL0, (i | 0x1)); - /* ks8695_write(KS8695_WAN_CONTROL, 0x3f000066); */ - - /* Initialize descriptor rings */ - for (i = 0; (i < TXDESCS); i++) { - ks8695_tx[i].owner = 0; - ks8695_tx[i].ctrl = 0; - ks8695_tx[i].addr = (uint32_t) &ks8695_bufs[i*BUFSIZE]; - ks8695_tx[i].next = (uint32_t) &ks8695_tx[i+1]; - } - ks8695_tx[TXDESCS-1].ctrl = 0x02000000; - ks8695_tx[TXDESCS-1].next = (uint32_t) &ks8695_tx[0]; - - for (i = 0; (i < RXDESCS); i++) { - ks8695_rx[i].status = 0x80000000; - ks8695_rx[i].ctrl = BUFSIZE - 4; - ks8695_rx[i].addr = (uint32_t) &ks8695_bufs[(i+TXDESCS)*BUFSIZE]; - ks8695_rx[i].next = (uint32_t) &ks8695_rx[i+1]; - } - ks8695_rx[RXDESCS-1].ctrl |= 0x00080000; - ks8695_rx[RXDESCS-1].next = (uint32_t) &ks8695_rx[0]; - - /* The KS8695 is pretty slow reseting the ethernets... */ - udelay(2000000); - - /* Enable the ethernet engine */ - ks8695_write(KS8695_LAN_TX_LIST, (uint32_t) &ks8695_tx[0]); - ks8695_write(KS8695_LAN_RX_LIST, (uint32_t) &ks8695_rx[0]); - ks8695_write(KS8695_LAN_DMA_TX, 0x3); - ks8695_write(KS8695_LAN_DMA_RX, 0x71); - ks8695_write(KS8695_LAN_DMA_RX_START, 0x1); - - printf("KS8695 ETHERNET: %pM\n", eth_mac); - return 0; -} - -/****************************************************************************/ - -static void ks8695_eth_halt(struct eth_device *dev) -{ - debug ("%s(%d): eth_halt()\n", __FILE__, __LINE__); - - /* Reset the ethernet engines */ - ks8695_write(KS8695_LAN_DMA_TX, 0x80000000); - ks8695_write(KS8695_LAN_DMA_RX, 0x80000000); -} - -/****************************************************************************/ - -static int ks8695_eth_recv(struct eth_device *dev) -{ - volatile struct ks8695_rxdesc *dp; - int i, len = 0; - - debug ("%s(%d): eth_rx()\n", __FILE__, __LINE__); - - for (i = 0; (i < RXDESCS); i++) { - dp= &ks8695_rx[i]; - if ((dp->status & 0x80000000) == 0) { - len = (dp->status & 0x7ff) - 4; - NetReceive((void *) dp->addr, len); - dp->status = 0x80000000; - ks8695_write(KS8695_LAN_DMA_RX_START, 0x1); - break; - } - } - - return len; -} - -/****************************************************************************/ - -static int ks8695_eth_send(struct eth_device *dev, void *packet, int len) -{ - volatile struct ks8695_txdesc *dp; - static int next = 0; - - debug ("%s(%d): eth_send(packet=%p,len=%d)\n", __FILE__, __LINE__, - packet, len); - - dp = &ks8695_tx[next]; - memcpy((void *) dp->addr, (void *) packet, len); - - if (len < 64) { - memset((void *) (dp->addr + len), 0, 64-len); - len = 64; - } - - dp->ctrl = len | 0xe0000000; - dp->owner = 0x80000000; - - ks8695_write(KS8695_LAN_DMA_TX, 0x3); - ks8695_write(KS8695_LAN_DMA_TX_START, 0x1); - - if (++next >= TXDESCS) - next = 0; - - return 0; -} - -/****************************************************************************/ - -int ks8695_eth_initialize(void) -{ - struct eth_device *dev; - - dev = malloc(sizeof(*dev)); - if (dev == NULL) - return -1; - memset(dev, 0, sizeof(*dev)); - - dev->iobase = KS8695_IO_BASE + KS8695_LAN_DMA_TX; - dev->init = ks8695_eth_init; - dev->halt = ks8695_eth_halt; - dev->send = ks8695_eth_send; - dev->recv = ks8695_eth_recv; - strcpy(dev->name, "ks8695eth"); - - eth_register(dev); - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/ks8851_mll.c b/qemu/roms/u-boot/drivers/net/ks8851_mll.c deleted file mode 100644 index 05e5b14d2..000000000 --- a/qemu/roms/u-boot/drivers/net/ks8851_mll.c +++ /dev/null @@ -1,633 +0,0 @@ -/* - * Micrel KS8851_MLL 16bit Network driver - * Copyright (c) 2011 Roberto Cerati <roberto.cerati@bticino.it> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <asm/io.h> -#include <common.h> -#include <command.h> -#include <malloc.h> -#include <net.h> -#include <miiphy.h> - -#include "ks8851_mll.h" - -#define DRIVERNAME "ks8851_mll" - -#define MAX_RECV_FRAMES 32 -#define MAX_BUF_SIZE 2048 -#define TX_BUF_SIZE 2000 -#define RX_BUF_SIZE 2000 - -static const struct chip_id chip_ids[] = { - {CIDER_ID, "KSZ8851"}, - {0, NULL}, -}; - -/* - * union ks_tx_hdr - tx header data - * @txb: The header as bytes - * @txw: The header as 16bit, little-endian words - * - * A dual representation of the tx header data to allow - * access to individual bytes, and to allow 16bit accesses - * with 16bit alignment. - */ -union ks_tx_hdr { - u8 txb[4]; - __le16 txw[2]; -}; - -/* - * struct ks_net - KS8851 driver private data - * @net_device : The network device we're bound to - * @txh : temporaly buffer to save status/length. - * @frame_head_info : frame header information for multi-pkt rx. - * @statelock : Lock on this structure for tx list. - * @msg_enable : The message flags controlling driver output (see ethtool). - * @frame_cnt : number of frames received. - * @bus_width : i/o bus width. - * @irq : irq number assigned to this device. - * @rc_rxqcr : Cached copy of KS_RXQCR. - * @rc_txcr : Cached copy of KS_TXCR. - * @rc_ier : Cached copy of KS_IER. - * @sharedbus : Multipex(addr and data bus) mode indicator. - * @cmd_reg_cache : command register cached. - * @cmd_reg_cache_int : command register cached. Used in the irq handler. - * @promiscuous : promiscuous mode indicator. - * @all_mcast : mutlicast indicator. - * @mcast_lst_size : size of multicast list. - * @mcast_lst : multicast list. - * @mcast_bits : multicast enabed. - * @mac_addr : MAC address assigned to this device. - * @fid : frame id. - * @extra_byte : number of extra byte prepended rx pkt. - * @enabled : indicator this device works. - */ - -/* Receive multiplex framer header info */ -struct type_frame_head { - u16 sts; /* Frame status */ - u16 len; /* Byte count */ -} fr_h_i[MAX_RECV_FRAMES]; - -struct ks_net { - struct net_device *netdev; - union ks_tx_hdr txh; - struct type_frame_head *frame_head_info; - u32 msg_enable; - u32 frame_cnt; - int bus_width; - int irq; - u16 rc_rxqcr; - u16 rc_txcr; - u16 rc_ier; - u16 sharedbus; - u16 cmd_reg_cache; - u16 cmd_reg_cache_int; - u16 promiscuous; - u16 all_mcast; - u16 mcast_lst_size; - u8 mcast_lst[MAX_MCAST_LST][MAC_ADDR_LEN]; - u8 mcast_bits[HW_MCAST_SIZE]; - u8 mac_addr[6]; - u8 fid; - u8 extra_byte; - u8 enabled; -} ks_str, *ks; - -#define BE3 0x8000 /* Byte Enable 3 */ -#define BE2 0x4000 /* Byte Enable 2 */ -#define BE1 0x2000 /* Byte Enable 1 */ -#define BE0 0x1000 /* Byte Enable 0 */ - -static u8 ks_rdreg8(struct eth_device *dev, u16 offset) -{ - u8 shift_bit = offset & 0x03; - u8 shift_data = (offset & 1) << 3; - - writew(offset | (BE0 << shift_bit), dev->iobase + 2); - - return (u8)(readw(dev->iobase) >> shift_data); -} - -static u16 ks_rdreg16(struct eth_device *dev, u16 offset) -{ - writew(offset | ((BE1 | BE0) << (offset & 0x02)), dev->iobase + 2); - - return readw(dev->iobase); -} - -static void ks_wrreg8(struct eth_device *dev, u16 offset, u8 val) -{ - u8 shift_bit = (offset & 0x03); - u16 value_write = (u16)(val << ((offset & 1) << 3)); - - writew(offset | (BE0 << shift_bit), dev->iobase + 2); - writew(value_write, dev->iobase); -} - -static void ks_wrreg16(struct eth_device *dev, u16 offset, u16 val) -{ - writew(offset | ((BE1 | BE0) << (offset & 0x02)), dev->iobase + 2); - writew(val, dev->iobase); -} - -/* - * ks_inblk - read a block of data from QMU. This is called after sudo DMA mode - * enabled. - * @ks: The chip state - * @wptr: buffer address to save data - * @len: length in byte to read - */ -static inline void ks_inblk(struct eth_device *dev, u16 *wptr, u32 len) -{ - len >>= 1; - - while (len--) - *wptr++ = readw(dev->iobase); -} - -/* - * ks_outblk - write data to QMU. This is called after sudo DMA mode enabled. - * @ks: The chip information - * @wptr: buffer address - * @len: length in byte to write - */ -static inline void ks_outblk(struct eth_device *dev, u16 *wptr, u32 len) -{ - len >>= 1; - - while (len--) - writew(*wptr++, dev->iobase); -} - -static void ks_enable_int(struct eth_device *dev) -{ - ks_wrreg16(dev, KS_IER, ks->rc_ier); -} - -static void ks_set_powermode(struct eth_device *dev, unsigned pwrmode) -{ - unsigned pmecr; - - ks_rdreg16(dev, KS_GRR); - pmecr = ks_rdreg16(dev, KS_PMECR); - pmecr &= ~PMECR_PM_MASK; - pmecr |= pwrmode; - - ks_wrreg16(dev, KS_PMECR, pmecr); -} - -/* - * ks_read_config - read chip configuration of bus width. - * @ks: The chip information - */ -static void ks_read_config(struct eth_device *dev) -{ - u16 reg_data = 0; - - /* Regardless of bus width, 8 bit read should always work. */ - reg_data = ks_rdreg8(dev, KS_CCR) & 0x00FF; - reg_data |= ks_rdreg8(dev, KS_CCR + 1) << 8; - - /* addr/data bus are multiplexed */ - ks->sharedbus = (reg_data & CCR_SHARED) == CCR_SHARED; - - /* - * There are garbage data when reading data from QMU, - * depending on bus-width. - */ - if (reg_data & CCR_8BIT) { - ks->bus_width = ENUM_BUS_8BIT; - ks->extra_byte = 1; - } else if (reg_data & CCR_16BIT) { - ks->bus_width = ENUM_BUS_16BIT; - ks->extra_byte = 2; - } else { - ks->bus_width = ENUM_BUS_32BIT; - ks->extra_byte = 4; - } -} - -/* - * ks_soft_reset - issue one of the soft reset to the device - * @ks: The device state. - * @op: The bit(s) to set in the GRR - * - * Issue the relevant soft-reset command to the device's GRR register - * specified by @op. - * - * Note, the delays are in there as a caution to ensure that the reset - * has time to take effect and then complete. Since the datasheet does - * not currently specify the exact sequence, we have chosen something - * that seems to work with our device. - */ -static void ks_soft_reset(struct eth_device *dev, unsigned op) -{ - /* Disable interrupt first */ - ks_wrreg16(dev, KS_IER, 0x0000); - ks_wrreg16(dev, KS_GRR, op); - mdelay(10); /* wait a short time to effect reset */ - ks_wrreg16(dev, KS_GRR, 0); - mdelay(1); /* wait for condition to clear */ -} - -void ks_enable_qmu(struct eth_device *dev) -{ - u16 w; - - w = ks_rdreg16(dev, KS_TXCR); - - /* Enables QMU Transmit (TXCR). */ - ks_wrreg16(dev, KS_TXCR, w | TXCR_TXE); - - /* Enable RX Frame Count Threshold and Auto-Dequeue RXQ Frame */ - w = ks_rdreg16(dev, KS_RXQCR); - ks_wrreg16(dev, KS_RXQCR, w | RXQCR_RXFCTE); - - /* Enables QMU Receive (RXCR1). */ - w = ks_rdreg16(dev, KS_RXCR1); - ks_wrreg16(dev, KS_RXCR1, w | RXCR1_RXE); -} - -static void ks_disable_qmu(struct eth_device *dev) -{ - u16 w; - - w = ks_rdreg16(dev, KS_TXCR); - - /* Disables QMU Transmit (TXCR). */ - w &= ~TXCR_TXE; - ks_wrreg16(dev, KS_TXCR, w); - - /* Disables QMU Receive (RXCR1). */ - w = ks_rdreg16(dev, KS_RXCR1); - w &= ~RXCR1_RXE; - ks_wrreg16(dev, KS_RXCR1, w); -} - -static inline void ks_read_qmu(struct eth_device *dev, u16 *buf, u32 len) -{ - u32 r = ks->extra_byte & 0x1; - u32 w = ks->extra_byte - r; - - /* 1. set sudo DMA mode */ - ks_wrreg16(dev, KS_RXFDPR, RXFDPR_RXFPAI); - ks_wrreg8(dev, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff); - - /* - * 2. read prepend data - * - * read 4 + extra bytes and discard them. - * extra bytes for dummy, 2 for status, 2 for len - */ - - if (r) - ks_rdreg8(dev, 0); - - ks_inblk(dev, buf, w + 2 + 2); - - /* 3. read pkt data */ - ks_inblk(dev, buf, ALIGN(len, 4)); - - /* 4. reset sudo DMA Mode */ - ks_wrreg8(dev, KS_RXQCR, (ks->rc_rxqcr & ~RXQCR_SDA) & 0xff); -} - -static void ks_rcv(struct eth_device *dev, uchar **pv_data) -{ - struct type_frame_head *frame_hdr = ks->frame_head_info; - int i; - - ks->frame_cnt = ks_rdreg16(dev, KS_RXFCTR) >> 8; - - /* read all header information */ - for (i = 0; i < ks->frame_cnt; i++) { - /* Checking Received packet status */ - frame_hdr->sts = ks_rdreg16(dev, KS_RXFHSR); - /* Get packet len from hardware */ - frame_hdr->len = ks_rdreg16(dev, KS_RXFHBCR); - frame_hdr++; - } - - frame_hdr = ks->frame_head_info; - while (ks->frame_cnt--) { - if ((frame_hdr->sts & RXFSHR_RXFV) && - (frame_hdr->len < RX_BUF_SIZE) && - frame_hdr->len) { - /* read data block including CRC 4 bytes */ - ks_read_qmu(dev, (u16 *)(*pv_data), frame_hdr->len); - - /* NetRxPackets buffer size is ok (*pv_data pointer) */ - NetReceive(*pv_data, frame_hdr->len); - pv_data++; - } else { - ks_wrreg16(dev, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF)); - printf(DRIVERNAME ": bad packet\n"); - } - frame_hdr++; - } -} - -/* - * ks_read_selftest - read the selftest memory info. - * @ks: The device state - * - * Read and check the TX/RX memory selftest information. - */ -static int ks_read_selftest(struct eth_device *dev) -{ - u16 both_done = MBIR_TXMBF | MBIR_RXMBF; - u16 mbir; - int ret = 0; - - mbir = ks_rdreg16(dev, KS_MBIR); - - if ((mbir & both_done) != both_done) { - printf(DRIVERNAME ": Memory selftest not finished\n"); - return 0; - } - - if (mbir & MBIR_TXMBFA) { - printf(DRIVERNAME ": TX memory selftest fails\n"); - ret |= 1; - } - - if (mbir & MBIR_RXMBFA) { - printf(DRIVERNAME ": RX memory selftest fails\n"); - ret |= 2; - } - - debug(DRIVERNAME ": the selftest passes\n"); - - return ret; -} - -static void ks_setup(struct eth_device *dev) -{ - u16 w; - - /* Setup Transmit Frame Data Pointer Auto-Increment (TXFDPR) */ - ks_wrreg16(dev, KS_TXFDPR, TXFDPR_TXFPAI); - - /* Setup Receive Frame Data Pointer Auto-Increment */ - ks_wrreg16(dev, KS_RXFDPR, RXFDPR_RXFPAI); - - /* Setup Receive Frame Threshold - 1 frame (RXFCTFC) */ - ks_wrreg16(dev, KS_RXFCTR, 1 & RXFCTR_THRESHOLD_MASK); - - /* Setup RxQ Command Control (RXQCR) */ - ks->rc_rxqcr = RXQCR_CMD_CNTL; - ks_wrreg16(dev, KS_RXQCR, ks->rc_rxqcr); - - /* - * set the force mode to half duplex, default is full duplex - * because if the auto-negotiation fails, most switch uses - * half-duplex. - */ - w = ks_rdreg16(dev, KS_P1MBCR); - w &= ~P1MBCR_FORCE_FDX; - ks_wrreg16(dev, KS_P1MBCR, w); - - w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP; - ks_wrreg16(dev, KS_TXCR, w); - - w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME | RXCR1_RXIPFCC; - - /* Normal mode */ - w |= RXCR1_RXPAFMA; - - ks_wrreg16(dev, KS_RXCR1, w); -} - -static void ks_setup_int(struct eth_device *dev) -{ - ks->rc_ier = 0x00; - - /* Clear the interrupts status of the hardware. */ - ks_wrreg16(dev, KS_ISR, 0xffff); - - /* Enables the interrupts of the hardware. */ - ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI); -} - -static int ks8851_mll_detect_chip(struct eth_device *dev) -{ - unsigned short val, i; - - ks_read_config(dev); - - val = ks_rdreg16(dev, KS_CIDER); - - if (val == 0xffff) { - /* Special case -- no chip present */ - printf(DRIVERNAME ": is chip mounted ?\n"); - return -1; - } else if ((val & 0xfff0) != CIDER_ID) { - printf(DRIVERNAME ": Invalid chip id 0x%04x\n", val); - return -1; - } - - debug("Read back KS8851 id 0x%x\n", val); - - /* only one entry in the table */ - val &= 0xfff0; - for (i = 0; chip_ids[i].id != 0; i++) { - if (chip_ids[i].id == val) - break; - } - if (!chip_ids[i].id) { - printf(DRIVERNAME ": Unknown chip ID %04x\n", val); - return -1; - } - - dev->priv = (void *)&chip_ids[i]; - - return 0; -} - -static void ks8851_mll_reset(struct eth_device *dev) -{ - /* wake up powermode to normal mode */ - ks_set_powermode(dev, PMECR_PM_NORMAL); - mdelay(1); /* wait for normal mode to take effect */ - - /* Disable interrupt and reset */ - ks_soft_reset(dev, GRR_GSR); - - /* turn off the IRQs and ack any outstanding */ - ks_wrreg16(dev, KS_IER, 0x0000); - ks_wrreg16(dev, KS_ISR, 0xffff); - - /* shutdown RX/TX QMU */ - ks_disable_qmu(dev); -} - -static void ks8851_mll_phy_configure(struct eth_device *dev) -{ - u16 data; - - ks_setup(dev); - ks_setup_int(dev); - - /* Probing the phy */ - data = ks_rdreg16(dev, KS_OBCR); - ks_wrreg16(dev, KS_OBCR, data | OBCR_ODS_16MA); - - debug(DRIVERNAME ": phy initialized\n"); -} - -static void ks8851_mll_enable(struct eth_device *dev) -{ - ks_wrreg16(dev, KS_ISR, 0xffff); - ks_enable_int(dev); - ks_enable_qmu(dev); -} - -static int ks8851_mll_init(struct eth_device *dev, bd_t *bd) -{ - struct chip_id *id = dev->priv; - - debug(DRIVERNAME ": detected %s controller\n", id->name); - - if (ks_read_selftest(dev)) { - printf(DRIVERNAME ": Selftest failed\n"); - return -1; - } - - ks8851_mll_reset(dev); - - /* Configure the PHY, initialize the link state */ - ks8851_mll_phy_configure(dev); - - /* static allocation of private informations */ - ks->frame_head_info = fr_h_i; - - /* Turn on Tx + Rx */ - ks8851_mll_enable(dev); - - return 0; -} - -static void ks_write_qmu(struct eth_device *dev, u8 *pdata, u16 len) -{ - /* start header at txb[0] to align txw entries */ - ks->txh.txw[0] = 0; - ks->txh.txw[1] = cpu_to_le16(len); - - /* 1. set sudo-DMA mode */ - ks_wrreg16(dev, KS_TXFDPR, TXFDPR_TXFPAI); - ks_wrreg8(dev, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff); - /* 2. write status/lenth info */ - ks_outblk(dev, ks->txh.txw, 4); - /* 3. write pkt data */ - ks_outblk(dev, (u16 *)pdata, ALIGN(len, 4)); - /* 4. reset sudo-DMA mode */ - ks_wrreg8(dev, KS_RXQCR, (ks->rc_rxqcr & ~RXQCR_SDA) & 0xff); - /* 5. Enqueue Tx(move the pkt from TX buffer into TXQ) */ - ks_wrreg16(dev, KS_TXQCR, TXQCR_METFE); - /* 6. wait until TXQCR_METFE is auto-cleared */ - do { } while (ks_rdreg16(dev, KS_TXQCR) & TXQCR_METFE); -} - -static int ks8851_mll_send(struct eth_device *dev, void *packet, int length) -{ - u8 *data = (u8 *)packet; - u16 tmplen = (u16)length; - u16 retv; - - /* - * Extra space are required: - * 4 byte for alignment, 4 for status/length, 4 for CRC - */ - retv = ks_rdreg16(dev, KS_TXMIR) & 0x1fff; - if (retv >= tmplen + 12) { - ks_write_qmu(dev, data, tmplen); - return 0; - } else { - printf(DRIVERNAME ": failed to send packet: No buffer\n"); - return -1; - } -} - -static void ks8851_mll_halt(struct eth_device *dev) -{ - ks8851_mll_reset(dev); -} - -/* - * Maximum receive ring size; that is, the number of packets - * we can buffer before overflow happens. Basically, this just - * needs to be enough to prevent a packet being discarded while - * we are processing the previous one. - */ -static int ks8851_mll_recv(struct eth_device *dev) -{ - u16 status; - - status = ks_rdreg16(dev, KS_ISR); - - ks_wrreg16(dev, KS_ISR, status); - - if ((status & IRQ_RXI)) - ks_rcv(dev, (uchar **)NetRxPackets); - - if ((status & IRQ_LDI)) { - u16 pmecr = ks_rdreg16(dev, KS_PMECR); - pmecr &= ~PMECR_WKEVT_MASK; - ks_wrreg16(dev, KS_PMECR, pmecr | PMECR_WKEVT_LINK); - } - - return 0; -} - -static int ks8851_mll_write_hwaddr(struct eth_device *dev) -{ - u16 addrl, addrm, addrh; - - addrh = (dev->enetaddr[0] << 8) | dev->enetaddr[1]; - addrm = (dev->enetaddr[2] << 8) | dev->enetaddr[3]; - addrl = (dev->enetaddr[4] << 8) | dev->enetaddr[5]; - - ks_wrreg16(dev, KS_MARH, addrh); - ks_wrreg16(dev, KS_MARM, addrm); - ks_wrreg16(dev, KS_MARL, addrl); - - return 0; -} - -int ks8851_mll_initialize(u8 dev_num, int base_addr) -{ - struct eth_device *dev; - - dev = malloc(sizeof(*dev)); - if (!dev) { - printf("Error: Failed to allocate memory\n"); - return -1; - } - memset(dev, 0, sizeof(*dev)); - - dev->iobase = base_addr; - - ks = &ks_str; - - /* Try to detect chip. Will fail if not present. */ - if (ks8851_mll_detect_chip(dev)) { - free(dev); - return -1; - } - - dev->init = ks8851_mll_init; - dev->halt = ks8851_mll_halt; - dev->send = ks8851_mll_send; - dev->recv = ks8851_mll_recv; - dev->write_hwaddr = ks8851_mll_write_hwaddr; - sprintf(dev->name, "%s-%hu", DRIVERNAME, dev_num); - - eth_register(dev); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/ks8851_mll.h b/qemu/roms/u-boot/drivers/net/ks8851_mll.h deleted file mode 100644 index 7f90ae4e5..000000000 --- a/qemu/roms/u-boot/drivers/net/ks8851_mll.h +++ /dev/null @@ -1,357 +0,0 @@ -/* - * drivers/net/ks8851_mll.c - * - * Supports: - * KS8851 16bit MLL chip from Micrel Inc. - * - * Copyright (c) 2009 Micrel Inc. - * - * modified by - * (c) 2011 Bticino s.p.a, Roberto Cerati <roberto.cerati@bticino.it> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#ifndef _KS8851_MLL_H_ -#define _KS8851_MLL_H_ - -#include <linux/types.h> - -#define KS_CCR 0x08 -#define CCR_EEPROM (1 << 9) -#define CCR_SPI (1 << 8) -#define CCR_8BIT (1 << 7) -#define CCR_16BIT (1 << 6) -#define CCR_32BIT (1 << 5) -#define CCR_SHARED (1 << 4) -#define CCR_32PIN (1 << 0) - -/* MAC address registers */ -#define KS_MARL 0x10 -#define KS_MARM 0x12 -#define KS_MARH 0x14 - -#define KS_OBCR 0x20 -#define OBCR_ODS_16MA (1 << 6) - -#define KS_EEPCR 0x22 -#define EEPCR_EESA (1 << 4) -#define EEPCR_EESB (1 << 3) -#define EEPCR_EEDO (1 << 2) -#define EEPCR_EESCK (1 << 1) -#define EEPCR_EECS (1 << 0) - -#define KS_MBIR 0x24 -#define MBIR_TXMBF (1 << 12) -#define MBIR_TXMBFA (1 << 11) -#define MBIR_RXMBF (1 << 4) -#define MBIR_RXMBFA (1 << 3) - -#define KS_GRR 0x26 -#define GRR_QMU (1 << 1) -#define GRR_GSR (1 << 0) - -#define KS_WFCR 0x2A -#define WFCR_MPRXE (1 << 7) -#define WFCR_WF3E (1 << 3) -#define WFCR_WF2E (1 << 2) -#define WFCR_WF1E (1 << 1) -#define WFCR_WF0E (1 << 0) - -#define KS_WF0CRC0 0x30 -#define KS_WF0CRC1 0x32 -#define KS_WF0BM0 0x34 -#define KS_WF0BM1 0x36 -#define KS_WF0BM2 0x38 -#define KS_WF0BM3 0x3A - -#define KS_WF1CRC0 0x40 -#define KS_WF1CRC1 0x42 -#define KS_WF1BM0 0x44 -#define KS_WF1BM1 0x46 -#define KS_WF1BM2 0x48 -#define KS_WF1BM3 0x4A - -#define KS_WF2CRC0 0x50 -#define KS_WF2CRC1 0x52 -#define KS_WF2BM0 0x54 -#define KS_WF2BM1 0x56 -#define KS_WF2BM2 0x58 -#define KS_WF2BM3 0x5A - -#define KS_WF3CRC0 0x60 -#define KS_WF3CRC1 0x62 -#define KS_WF3BM0 0x64 -#define KS_WF3BM1 0x66 -#define KS_WF3BM2 0x68 -#define KS_WF3BM3 0x6A - -#define KS_TXCR 0x70 -#define TXCR_TCGICMP (1 << 8) -#define TXCR_TCGUDP (1 << 7) -#define TXCR_TCGTCP (1 << 6) -#define TXCR_TCGIP (1 << 5) -#define TXCR_FTXQ (1 << 4) -#define TXCR_TXFCE (1 << 3) -#define TXCR_TXPE (1 << 2) -#define TXCR_TXCRC (1 << 1) -#define TXCR_TXE (1 << 0) - -#define KS_TXSR 0x72 -#define TXSR_TXLC (1 << 13) -#define TXSR_TXMC (1 << 12) -#define TXSR_TXFID_MASK (0x3f << 0) -#define TXSR_TXFID_SHIFT (0) -#define TXSR_TXFID_GET(_v) (((_v) >> 0) & 0x3f) - - -#define KS_RXCR1 0x74 -#define RXCR1_FRXQ (1 << 15) -#define RXCR1_RXUDPFCC (1 << 14) -#define RXCR1_RXTCPFCC (1 << 13) -#define RXCR1_RXIPFCC (1 << 12) -#define RXCR1_RXPAFMA (1 << 11) -#define RXCR1_RXFCE (1 << 10) -#define RXCR1_RXEFE (1 << 9) -#define RXCR1_RXMAFMA (1 << 8) -#define RXCR1_RXBE (1 << 7) -#define RXCR1_RXME (1 << 6) -#define RXCR1_RXUE (1 << 5) -#define RXCR1_RXAE (1 << 4) -#define RXCR1_RXINVF (1 << 1) -#define RXCR1_RXE (1 << 0) -#define RXCR1_FILTER_MASK (RXCR1_RXINVF | RXCR1_RXAE | \ - RXCR1_RXMAFMA | RXCR1_RXPAFMA) - -#define KS_RXCR2 0x76 -#define RXCR2_SRDBL_MASK (0x7 << 5) -#define RXCR2_SRDBL_SHIFT (5) -#define RXCR2_SRDBL_4B (0x0 << 5) -#define RXCR2_SRDBL_8B (0x1 << 5) -#define RXCR2_SRDBL_16B (0x2 << 5) -#define RXCR2_SRDBL_32B (0x3 << 5) -/* #define RXCR2_SRDBL_FRAME (0x4 << 5) */ -#define RXCR2_IUFFP (1 << 4) -#define RXCR2_RXIUFCEZ (1 << 3) -#define RXCR2_UDPLFE (1 << 2) -#define RXCR2_RXICMPFCC (1 << 1) -#define RXCR2_RXSAF (1 << 0) - -#define KS_TXMIR 0x78 - -#define KS_RXFHSR 0x7C -#define RXFSHR_RXFV (1 << 15) -#define RXFSHR_RXICMPFCS (1 << 13) -#define RXFSHR_RXIPFCS (1 << 12) -#define RXFSHR_RXTCPFCS (1 << 11) -#define RXFSHR_RXUDPFCS (1 << 10) -#define RXFSHR_RXBF (1 << 7) -#define RXFSHR_RXMF (1 << 6) -#define RXFSHR_RXUF (1 << 5) -#define RXFSHR_RXMR (1 << 4) -#define RXFSHR_RXFT (1 << 3) -#define RXFSHR_RXFTL (1 << 2) -#define RXFSHR_RXRF (1 << 1) -#define RXFSHR_RXCE (1 << 0) -#define RXFSHR_ERR (RXFSHR_RXCE | RXFSHR_RXRF |\ - RXFSHR_RXFTL | RXFSHR_RXMR |\ - RXFSHR_RXICMPFCS | RXFSHR_RXIPFCS |\ - RXFSHR_RXTCPFCS) -#define KS_RXFHBCR 0x7E -#define RXFHBCR_CNT_MASK 0x0FFF - -#define KS_TXQCR 0x80 -#define TXQCR_AETFE (1 << 2) -#define TXQCR_TXQMAM (1 << 1) -#define TXQCR_METFE (1 << 0) - -#define KS_RXQCR 0x82 -#define RXQCR_RXDTTS (1 << 12) -#define RXQCR_RXDBCTS (1 << 11) -#define RXQCR_RXFCTS (1 << 10) -#define RXQCR_RXIPHTOE (1 << 9) -#define RXQCR_RXDTTE (1 << 7) -#define RXQCR_RXDBCTE (1 << 6) -#define RXQCR_RXFCTE (1 << 5) -#define RXQCR_ADRFE (1 << 4) -#define RXQCR_SDA (1 << 3) -#define RXQCR_RRXEF (1 << 0) -#define RXQCR_CMD_CNTL (RXQCR_RXFCTE|RXQCR_ADRFE) - -#define KS_TXFDPR 0x84 -#define TXFDPR_TXFPAI (1 << 14) -#define TXFDPR_TXFP_MASK (0x7ff << 0) -#define TXFDPR_TXFP_SHIFT (0) - -#define KS_RXFDPR 0x86 -#define RXFDPR_RXFPAI (1 << 14) - -#define KS_RXDTTR 0x8C -#define KS_RXDBCTR 0x8E - -#define KS_IER 0x90 -#define KS_ISR 0x92 -#define IRQ_LCI (1 << 15) -#define IRQ_TXI (1 << 14) -#define IRQ_RXI (1 << 13) -#define IRQ_RXOI (1 << 11) -#define IRQ_TXPSI (1 << 9) -#define IRQ_RXPSI (1 << 8) -#define IRQ_TXSAI (1 << 6) -#define IRQ_RXWFDI (1 << 5) -#define IRQ_RXMPDI (1 << 4) -#define IRQ_LDI (1 << 3) -#define IRQ_EDI (1 << 2) -#define IRQ_SPIBEI (1 << 1) -#define IRQ_DEDI (1 << 0) - -#define KS_RXFCTR 0x9C -#define RXFCTR_THRESHOLD_MASK 0x00FF - -#define KS_RXFC 0x9D -#define RXFCTR_RXFC_MASK (0xff << 8) -#define RXFCTR_RXFC_SHIFT (8) -#define RXFCTR_RXFC_GET(_v) (((_v) >> 8) & 0xff) -#define RXFCTR_RXFCT_MASK (0xff << 0) -#define RXFCTR_RXFCT_SHIFT (0) - -#define KS_TXNTFSR 0x9E - -#define KS_MAHTR0 0xA0 -#define KS_MAHTR1 0xA2 -#define KS_MAHTR2 0xA4 -#define KS_MAHTR3 0xA6 - -#define KS_FCLWR 0xB0 -#define KS_FCHWR 0xB2 -#define KS_FCOWR 0xB4 - -#define KS_CIDER 0xC0 -#define CIDER_ID 0x8870 -#define CIDER_REV_MASK (0x7 << 1) -#define CIDER_REV_SHIFT (1) -#define CIDER_REV_GET(_v) (((_v) >> 1) & 0x7) - -#define KS_CGCR 0xC6 -#define KS_IACR 0xC8 -#define IACR_RDEN (1 << 12) -#define IACR_TSEL_MASK (0x3 << 10) -#define IACR_TSEL_SHIFT (10) -#define IACR_TSEL_MIB (0x3 << 10) -#define IACR_ADDR_MASK (0x1f << 0) -#define IACR_ADDR_SHIFT (0) - -#define KS_IADLR 0xD0 -#define KS_IAHDR 0xD2 - -#define KS_PMECR 0xD4 -#define PMECR_PME_DELAY (1 << 14) -#define PMECR_PME_POL (1 << 12) -#define PMECR_WOL_WAKEUP (1 << 11) -#define PMECR_WOL_MAGICPKT (1 << 10) -#define PMECR_WOL_LINKUP (1 << 9) -#define PMECR_WOL_ENERGY (1 << 8) -#define PMECR_AUTO_WAKE_EN (1 << 7) -#define PMECR_WAKEUP_NORMAL (1 << 6) -#define PMECR_WKEVT_MASK (0xf << 2) -#define PMECR_WKEVT_SHIFT (2) -#define PMECR_WKEVT_GET(_v) (((_v) >> 2) & 0xf) -#define PMECR_WKEVT_ENERGY (0x1 << 2) -#define PMECR_WKEVT_LINK (0x2 << 2) -#define PMECR_WKEVT_MAGICPKT (0x4 << 2) -#define PMECR_WKEVT_FRAME (0x8 << 2) -#define PMECR_PM_MASK (0x3 << 0) -#define PMECR_PM_SHIFT (0) -#define PMECR_PM_NORMAL (0x0 << 0) -#define PMECR_PM_ENERGY (0x1 << 0) -#define PMECR_PM_SOFTDOWN (0x2 << 0) -#define PMECR_PM_POWERSAVE (0x3 << 0) - -/* Standard MII PHY data */ -#define KS_P1MBCR 0xE4 -#define P1MBCR_FORCE_FDX (1 << 8) - -#define KS_P1MBSR 0xE6 -#define P1MBSR_AN_COMPLETE (1 << 5) -#define P1MBSR_AN_CAPABLE (1 << 3) -#define P1MBSR_LINK_UP (1 << 2) - -#define KS_PHY1ILR 0xE8 -#define KS_PHY1IHR 0xEA -#define KS_P1ANAR 0xEC -#define KS_P1ANLPR 0xEE - -#define KS_P1SCLMD 0xF4 -#define P1SCLMD_LEDOFF (1 << 15) -#define P1SCLMD_TXIDS (1 << 14) -#define P1SCLMD_RESTARTAN (1 << 13) -#define P1SCLMD_DISAUTOMDIX (1 << 10) -#define P1SCLMD_FORCEMDIX (1 << 9) -#define P1SCLMD_AUTONEGEN (1 << 7) -#define P1SCLMD_FORCE100 (1 << 6) -#define P1SCLMD_FORCEFDX (1 << 5) -#define P1SCLMD_ADV_FLOW (1 << 4) -#define P1SCLMD_ADV_100BT_FDX (1 << 3) -#define P1SCLMD_ADV_100BT_HDX (1 << 2) -#define P1SCLMD_ADV_10BT_FDX (1 << 1) -#define P1SCLMD_ADV_10BT_HDX (1 << 0) - -#define KS_P1CR 0xF6 -#define P1CR_HP_MDIX (1 << 15) -#define P1CR_REV_POL (1 << 13) -#define P1CR_OP_100M (1 << 10) -#define P1CR_OP_FDX (1 << 9) -#define P1CR_OP_MDI (1 << 7) -#define P1CR_AN_DONE (1 << 6) -#define P1CR_LINK_GOOD (1 << 5) -#define P1CR_PNTR_FLOW (1 << 4) -#define P1CR_PNTR_100BT_FDX (1 << 3) -#define P1CR_PNTR_100BT_HDX (1 << 2) -#define P1CR_PNTR_10BT_FDX (1 << 1) -#define P1CR_PNTR_10BT_HDX (1 << 0) - -/* TX Frame control */ -#define TXFR_TXIC (1 << 15) -#define TXFR_TXFID_MASK (0x3f << 0) -#define TXFR_TXFID_SHIFT (0) - -#define KS_P1SR 0xF8 -#define P1SR_HP_MDIX (1 << 15) -#define P1SR_REV_POL (1 << 13) -#define P1SR_OP_100M (1 << 10) -#define P1SR_OP_FDX (1 << 9) -#define P1SR_OP_MDI (1 << 7) -#define P1SR_AN_DONE (1 << 6) -#define P1SR_LINK_GOOD (1 << 5) -#define P1SR_PNTR_FLOW (1 << 4) -#define P1SR_PNTR_100BT_FDX (1 << 3) -#define P1SR_PNTR_100BT_HDX (1 << 2) -#define P1SR_PNTR_10BT_FDX (1 << 1) -#define P1SR_PNTR_10BT_HDX (1 << 0) - -#define ENUM_BUS_NONE 0 -#define ENUM_BUS_8BIT 1 -#define ENUM_BUS_16BIT 2 -#define ENUM_BUS_32BIT 3 - -#define MAX_MCAST_LST 32 -#define HW_MCAST_SIZE 8 -#define MAC_ADDR_LEN 6 - -/* Chip ID values */ -struct chip_id { - u16 id; - char *name; -}; - -#endif diff --git a/qemu/roms/u-boot/drivers/net/lan91c96.c b/qemu/roms/u-boot/drivers/net/lan91c96.c deleted file mode 100644 index 229658abc..000000000 --- a/qemu/roms/u-boot/drivers/net/lan91c96.c +++ /dev/null @@ -1,804 +0,0 @@ -/*------------------------------------------------------------------------ - * lan91c96.c - * This is a driver for SMSC's LAN91C96 single-chip Ethernet device, based - * on the SMC91111 driver from U-boot. - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Rolf Offermanns <rof@sysgo.de> - * - * Copyright (C) 2001 Standard Microsystems Corporation (SMSC) - * Developed by Simple Network Magic Corporation (SNMC) - * Copyright (C) 1996 by Erik Stahlman (ES) - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Information contained in this file was obtained from the LAN91C96 - * manual from SMC. To get a copy, if you really want one, you can find - * information under www.smsc.com. - * - * "Features" of the SMC chip: - * 6144 byte packet memory. ( for the 91C96 ) - * EEPROM for configuration - * AUI/TP selection ( mine has 10Base2/10BaseT select ) - * - * Arguments: - * io = for the base address - * irq = for the IRQ - * - * author: - * Erik Stahlman ( erik@vt.edu ) - * Daris A Nevil ( dnevil@snmc.com ) - * - * - * Hardware multicast code from Peter Cammaert ( pc@denkart.be ) - * - * Sources: - * o SMSC LAN91C96 databook (www.smsc.com) - * o smc91111.c (u-boot driver) - * o smc9194.c (linux kernel driver) - * o lan91c96.c (Intel Diagnostic Manager driver) - * - * History: - * 04/30/03 Mathijs Haarman Modified smc91111.c (u-boot version) - * for lan91c96 - *--------------------------------------------------------------------------- - */ - -#include <common.h> -#include <command.h> -#include <malloc.h> -#include "lan91c96.h" -#include <net.h> -#include <linux/compiler.h> - -/*------------------------------------------------------------------------ - * - * Configuration options, for the experienced user to change. - * - -------------------------------------------------------------------------*/ - -/* Use power-down feature of the chip */ -#define POWER_DOWN 0 - -/* - * Wait time for memory to be free. This probably shouldn't be - * tuned that much, as waiting for this means nothing else happens - * in the system -*/ -#define MEMORY_WAIT_TIME 16 - -#define SMC_DEBUG 0 - -#if (SMC_DEBUG > 2 ) -#define PRINTK3(args...) printf(args) -#else -#define PRINTK3(args...) -#endif - -#if SMC_DEBUG > 1 -#define PRINTK2(args...) printf(args) -#else -#define PRINTK2(args...) -#endif - -#ifdef SMC_DEBUG -#define PRINTK(args...) printf(args) -#else -#define PRINTK(args...) -#endif - - -/*------------------------------------------------------------------------ - * - * The internal workings of the driver. If you are changing anything - * here with the SMC stuff, you should have the datasheet and know - * what you are doing. - * - *------------------------------------------------------------------------ - */ -#define DRIVER_NAME "LAN91C96" -#define SMC_ALLOC_MAX_TRY 5 -#define SMC_TX_TIMEOUT 30 - -#define ETH_ZLEN 60 - -#ifdef CONFIG_LAN91C96_USE_32_BIT -#define USE_32_BIT 1 -#else -#undef USE_32_BIT -#endif - -/* See if a MAC address is defined in the current environment. If so use it. If not - . print a warning and set the environment and other globals with the default. - . If an EEPROM is present it really should be consulted. -*/ -static int smc_get_ethaddr(bd_t *bd, struct eth_device *dev); -static int get_rom_mac(struct eth_device *dev, unsigned char *v_rom_mac); - -/* ------------------------------------------------------------ - * Internal routines - * ------------------------------------------------------------ - */ - -static unsigned char smc_mac_addr[] = { 0xc0, 0x00, 0x00, 0x1b, 0x62, 0x9c }; - -/* - * This function must be called before smc_open() if you want to override - * the default mac address. - */ - -static void smc_set_mac_addr(const unsigned char *addr) -{ - int i; - - for (i = 0; i < sizeof (smc_mac_addr); i++) { - smc_mac_addr[i] = addr[i]; - } -} - -/*********************************************** - * Show available memory * - ***********************************************/ -void dump_memory_info(struct eth_device *dev) -{ - __maybe_unused word mem_info; - word old_bank; - - old_bank = SMC_inw(dev, LAN91C96_BANK_SELECT) & 0xF; - - SMC_SELECT_BANK(dev, 0); - mem_info = SMC_inw(dev, LAN91C96_MIR); - PRINTK2 ("Memory: %4d available\n", (mem_info >> 8) * 2048); - - SMC_SELECT_BANK(dev, old_bank); -} - -/* - * A rather simple routine to print out a packet for debugging purposes. - */ -#if SMC_DEBUG > 2 -static void print_packet (byte *, int); -#endif - -static int poll4int (struct eth_device *dev, byte mask, int timeout) -{ - int tmo = get_timer (0) + timeout * CONFIG_SYS_HZ; - int is_timeout = 0; - word old_bank = SMC_inw(dev, LAN91C96_BANK_SELECT); - - PRINTK2 ("Polling...\n"); - SMC_SELECT_BANK(dev, 2); - while ((SMC_inw(dev, LAN91C96_INT_STATS) & mask) == 0) { - if (get_timer (0) >= tmo) { - is_timeout = 1; - break; - } - } - - /* restore old bank selection */ - SMC_SELECT_BANK(dev, old_bank); - - if (is_timeout) - return 1; - else - return 0; -} - -/* - * Function: smc_reset - * Purpose: - * This sets the SMC91111 chip to its normal state, hopefully from whatever - * mess that any other DOS driver has put it in. - * - * Maybe I should reset more registers to defaults in here? SOFTRST should - * do that for me. - * - * Method: - * 1. send a SOFT RESET - * 2. wait for it to finish - * 3. enable autorelease mode - * 4. reset the memory management unit - * 5. clear all interrupts - * -*/ -static void smc_reset(struct eth_device *dev) -{ - PRINTK2("%s:smc_reset\n", dev->name); - - /* This resets the registers mostly to defaults, but doesn't - affect EEPROM. That seems unnecessary */ - SMC_SELECT_BANK(dev, 0); - SMC_outw(dev, LAN91C96_RCR_SOFT_RST, LAN91C96_RCR); - - udelay (10); - - /* Disable transmit and receive functionality */ - SMC_outw(dev, 0, LAN91C96_RCR); - SMC_outw(dev, 0, LAN91C96_TCR); - - /* set the control register */ - SMC_SELECT_BANK(dev, 1); - SMC_outw(dev, SMC_inw(dev, LAN91C96_CONTROL) | LAN91C96_CTR_BIT_8, - LAN91C96_CONTROL); - - /* Disable all interrupts */ - SMC_outb(dev, 0, LAN91C96_INT_MASK); -} - -/* - * Function: smc_enable - * Purpose: let the chip talk to the outside work - * Method: - * 1. Initialize the Memory Configuration Register - * 2. Enable the transmitter - * 3. Enable the receiver -*/ -static void smc_enable(struct eth_device *dev) -{ - PRINTK2("%s:smc_enable\n", dev->name); - SMC_SELECT_BANK(dev, 0); - - /* Initialize the Memory Configuration Register. See page - 49 of the LAN91C96 data sheet for details. */ - SMC_outw(dev, LAN91C96_MCR_TRANSMIT_PAGES, LAN91C96_MCR); - - /* Initialize the Transmit Control Register */ - SMC_outw(dev, LAN91C96_TCR_TXENA, LAN91C96_TCR); - /* Initialize the Receive Control Register - * FIXME: - * The promiscuous bit set because I could not receive ARP reply - * packets from the server when I send a ARP request. It only works - * when I set the promiscuous bit - */ - SMC_outw(dev, LAN91C96_RCR_RXEN | LAN91C96_RCR_PRMS, LAN91C96_RCR); -} - -/* - * Function: smc_shutdown - * Purpose: closes down the SMC91xxx chip. - * Method: - * 1. zero the interrupt mask - * 2. clear the enable receive flag - * 3. clear the enable xmit flags - * - * TODO: - * (1) maybe utilize power down mode. - * Why not yet? Because while the chip will go into power down mode, - * the manual says that it will wake up in response to any I/O requests - * in the register space. Empirical results do not show this working. - */ -static void smc_shutdown(struct eth_device *dev) -{ - PRINTK2("%s:smc_shutdown\n", dev->name); - - /* no more interrupts for me */ - SMC_SELECT_BANK(dev, 2); - SMC_outb(dev, 0, LAN91C96_INT_MASK); - - /* and tell the card to stay away from that nasty outside world */ - SMC_SELECT_BANK(dev, 0); - SMC_outb(dev, 0, LAN91C96_RCR); - SMC_outb(dev, 0, LAN91C96_TCR); -} - - -/* - * Function: smc_hardware_send_packet(struct net_device * ) - * Purpose: - * This sends the actual packet to the SMC9xxx chip. - * - * Algorithm: - * First, see if a saved_skb is available. - * ( this should NOT be called if there is no 'saved_skb' - * Now, find the packet number that the chip allocated - * Point the data pointers at it in memory - * Set the length word in the chip's memory - * Dump the packet to chip memory - * Check if a last byte is needed ( odd length packet ) - * if so, set the control flag right - * Tell the card to send it - * Enable the transmit interrupt, so I know if it failed - * Free the kernel data if I actually sent it. - */ -static int smc_send_packet(struct eth_device *dev, void *packet, - int packet_length) -{ - byte packet_no; - byte *buf; - int length; - int numPages; - int try = 0; - int time_out; - byte status; - - - PRINTK3("%s:smc_hardware_send_packet\n", dev->name); - - length = ETH_ZLEN < packet_length ? packet_length : ETH_ZLEN; - - /* allocate memory - ** The MMU wants the number of pages to be the number of 256 bytes - ** 'pages', minus 1 ( since a packet can't ever have 0 pages :) ) - ** - ** The 91C111 ignores the size bits, but the code is left intact - ** for backwards and future compatibility. - ** - ** Pkt size for allocating is data length +6 (for additional status - ** words, length and ctl!) - ** - ** If odd size then last byte is included in this header. - */ - numPages = ((length & 0xfffe) + 6); - numPages >>= 8; /* Divide by 256 */ - - if (numPages > 7) { - printf("%s: Far too big packet error. \n", dev->name); - return 0; - } - - /* now, try to allocate the memory */ - - SMC_SELECT_BANK(dev, 2); - SMC_outw(dev, LAN91C96_MMUCR_ALLOC_TX | numPages, LAN91C96_MMU); - - again: - try++; - time_out = MEMORY_WAIT_TIME; - do { - status = SMC_inb(dev, LAN91C96_INT_STATS); - if (status & LAN91C96_IST_ALLOC_INT) { - - SMC_outb(dev, LAN91C96_IST_ALLOC_INT, - LAN91C96_INT_STATS); - break; - } - } while (--time_out); - - if (!time_out) { - PRINTK2 ("%s: memory allocation, try %d failed ...\n", - dev->name, try); - if (try < SMC_ALLOC_MAX_TRY) - goto again; - else - return 0; - } - - PRINTK2 ("%s: memory allocation, try %d succeeded ...\n", - dev->name, try); - - /* I can send the packet now.. */ - buf = (byte *) packet; - - /* If I get here, I _know_ there is a packet slot waiting for me */ - packet_no = SMC_inb(dev, LAN91C96_ARR); - if (packet_no & LAN91C96_ARR_FAILED) { - /* or isn't there? BAD CHIP! */ - printf("%s: Memory allocation failed. \n", dev->name); - return 0; - } - - /* we have a packet address, so tell the card to use it */ - SMC_outb(dev, packet_no, LAN91C96_PNR); - - /* point to the beginning of the packet */ - SMC_outw(dev, LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER); - - PRINTK3("%s: Trying to xmit packet of length %x\n", - dev->name, length); - -#if SMC_DEBUG > 2 - printf ("Transmitting Packet\n"); - print_packet (buf, length); -#endif - - /* send the packet length ( +6 for status, length and ctl byte ) - and the status word ( set to zeros ) */ -#ifdef USE_32_BIT - SMC_outl(dev, (length + 6) << 16, LAN91C96_DATA_HIGH); -#else - SMC_outw(dev, 0, LAN91C96_DATA_HIGH); - /* send the packet length ( +6 for status words, length, and ctl */ - SMC_outw(dev, (length + 6), LAN91C96_DATA_HIGH); -#endif /* USE_32_BIT */ - - /* send the actual data - * I _think_ it's faster to send the longs first, and then - * mop up by sending the last word. It depends heavily - * on alignment, at least on the 486. Maybe it would be - * a good idea to check which is optimal? But that could take - * almost as much time as is saved? - */ -#ifdef USE_32_BIT - SMC_outsl(dev, LAN91C96_DATA_HIGH, buf, length >> 2); - if (length & 0x2) - SMC_outw(dev, *((word *) (buf + (length & 0xFFFFFFFC))), - LAN91C96_DATA_HIGH); -#else - SMC_outsw(dev, LAN91C96_DATA_HIGH, buf, (length) >> 1); -#endif /* USE_32_BIT */ - - /* Send the last byte, if there is one. */ - if ((length & 1) == 0) { - SMC_outw(dev, 0, LAN91C96_DATA_HIGH); - } else { - SMC_outw(dev, buf[length - 1] | 0x2000, LAN91C96_DATA_HIGH); - } - - /* and let the chipset deal with it */ - SMC_outw(dev, LAN91C96_MMUCR_ENQUEUE, LAN91C96_MMU); - - /* poll for TX INT */ - if (poll4int (dev, LAN91C96_MSK_TX_INT, SMC_TX_TIMEOUT)) { - /* sending failed */ - PRINTK2("%s: TX timeout, sending failed...\n", dev->name); - - /* release packet */ - SMC_outw(dev, LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU); - - /* wait for MMU getting ready (low) */ - while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY) - udelay (10); - - PRINTK2("MMU ready\n"); - - - return 0; - } else { - /* ack. int */ - SMC_outw(dev, LAN91C96_IST_TX_INT, LAN91C96_INT_STATS); - - PRINTK2("%s: Sent packet of length %d \n", dev->name, length); - - /* release packet */ - SMC_outw(dev, LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU); - - /* wait for MMU getting ready (low) */ - while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY) - udelay (10); - - PRINTK2 ("MMU ready\n"); - } - - return length; -} - - -/* - * Open and Initialize the board - * - * Set up everything, reset the card, etc .. - * - */ -static int smc_open(bd_t *bd, struct eth_device *dev) -{ - int i, err; /* used to set hw ethernet address */ - - PRINTK2("%s:smc_open\n", dev->name); - - /* reset the hardware */ - - smc_reset(dev); - smc_enable(dev); - - SMC_SELECT_BANK(dev, 1); - /* set smc_mac_addr, and sync it with u-boot globals */ - err = smc_get_ethaddr(bd, dev); - if (err < 0) - return -1; -#ifdef USE_32_BIT - for (i = 0; i < 6; i += 2) { - word address; - - address = smc_mac_addr[i + 1] << 8; - address |= smc_mac_addr[i]; - SMC_outw(dev, address, LAN91C96_IA0 + i); - } -#else - for (i = 0; i < 6; i++) - SMC_outb(dev, smc_mac_addr[i], LAN91C96_IA0 + i); -#endif - return 0; -} - -/*------------------------------------------------------------- - * - * smc_rcv - receive a packet from the card - * - * There is ( at least ) a packet waiting to be read from - * chip-memory. - * - * o Read the status - * o If an error, record it - * o otherwise, read in the packet - *------------------------------------------------------------- - */ -static int smc_rcv(struct eth_device *dev) -{ - int packet_number; - word status; - word packet_length; - int is_error = 0; - -#ifdef USE_32_BIT - dword stat_len; -#endif - - - SMC_SELECT_BANK(dev, 2); - packet_number = SMC_inw(dev, LAN91C96_FIFO); - - if (packet_number & LAN91C96_FIFO_RXEMPTY) { - return 0; - } - - PRINTK3("%s:smc_rcv\n", dev->name); - /* start reading from the start of the packet */ - SMC_outw(dev, LAN91C96_PTR_READ | LAN91C96_PTR_RCV | - LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER); - - /* First two words are status and packet_length */ -#ifdef USE_32_BIT - stat_len = SMC_inl(dev, LAN91C96_DATA_HIGH); - status = stat_len & 0xffff; - packet_length = stat_len >> 16; -#else - status = SMC_inw(dev, LAN91C96_DATA_HIGH); - packet_length = SMC_inw(dev, LAN91C96_DATA_HIGH); -#endif - - packet_length &= 0x07ff; /* mask off top bits */ - - PRINTK2 ("RCV: STATUS %4x LENGTH %4x\n", status, packet_length); - - if (!(status & FRAME_FILTER)) { - /* Adjust for having already read the first two words */ - packet_length -= 4; /*4; */ - - - /* set odd length for bug in LAN91C111, */ - /* which never sets RS_ODDFRAME */ - /* TODO ? */ - - -#ifdef USE_32_BIT - PRINTK3 (" Reading %d dwords (and %d bytes) \n", - packet_length >> 2, packet_length & 3); - /* QUESTION: Like in the TX routine, do I want - to send the DWORDs or the bytes first, or some - mixture. A mixture might improve already slow PIO - performance */ - SMC_insl(dev, LAN91C96_DATA_HIGH, NetRxPackets[0], - packet_length >> 2); - /* read the left over bytes */ - if (packet_length & 3) { - int i; - - byte *tail = (byte *) (NetRxPackets[0] + (packet_length & ~3)); - dword leftover = SMC_inl(dev, LAN91C96_DATA_HIGH); - - for (i = 0; i < (packet_length & 3); i++) - *tail++ = (byte) (leftover >> (8 * i)) & 0xff; - } -#else - PRINTK3 (" Reading %d words and %d byte(s) \n", - (packet_length >> 1), packet_length & 1); - SMC_insw(dev, LAN91C96_DATA_HIGH, NetRxPackets[0], - packet_length >> 1); - -#endif /* USE_32_BIT */ - -#if SMC_DEBUG > 2 - printf ("Receiving Packet\n"); - print_packet((byte *)NetRxPackets[0], packet_length); -#endif - } else { - /* error ... */ - /* TODO ? */ - is_error = 1; - } - - while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY) - udelay (1); /* Wait until not busy */ - - /* error or good, tell the card to get rid of this packet */ - SMC_outw(dev, LAN91C96_MMUCR_RELEASE_RX, LAN91C96_MMU); - - while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY) - udelay (1); /* Wait until not busy */ - - if (!is_error) { - /* Pass the packet up to the protocol layers. */ - NetReceive (NetRxPackets[0], packet_length); - return packet_length; - } else { - return 0; - } - -} - -/*---------------------------------------------------- - * smc_close - * - * this makes the board clean up everything that it can - * and not talk to the outside world. Caused by - * an 'ifconfig ethX down' - * - -----------------------------------------------------*/ -static int smc_close(struct eth_device *dev) -{ - PRINTK2("%s:smc_close\n", dev->name); - - /* clear everything */ - smc_shutdown(dev); - - return 0; -} - -#if SMC_DEBUG > 2 -static void print_packet(byte *buf, int length) -{ -#if 0 - int i; - int remainder; - int lines; - - printf ("Packet of length %d \n", length); - - lines = length / 16; - remainder = length % 16; - - for (i = 0; i < lines; i++) { - int cur; - - for (cur = 0; cur < 8; cur++) { - byte a, b; - - a = *(buf++); - b = *(buf++); - printf ("%02x%02x ", a, b); - } - printf ("\n"); - } - for (i = 0; i < remainder / 2; i++) { - byte a, b; - - a = *(buf++); - b = *(buf++); - printf ("%02x%02x ", a, b); - } - printf ("\n"); -#endif /* 0 */ -} -#endif /* SMC_DEBUG > 2 */ - -static int lan91c96_init(struct eth_device *dev, bd_t *bd) -{ - return smc_open(bd, dev); -} - -static void lan91c96_halt(struct eth_device *dev) -{ - smc_close(dev); -} - -static int lan91c96_recv(struct eth_device *dev) -{ - return smc_rcv(dev); -} - -static int lan91c96_send(struct eth_device *dev, void *packet, - int length) -{ - return smc_send_packet(dev, packet, length); -} - -/* smc_get_ethaddr - * - * This checks both the environment and the ROM for an ethernet address. If - * found, the environment takes precedence. - */ - -static int smc_get_ethaddr(bd_t *bd, struct eth_device *dev) -{ - uchar v_mac[6]; - - if (!eth_getenv_enetaddr("ethaddr", v_mac)) { - /* get ROM mac value if any */ - if (!get_rom_mac(dev, v_mac)) { - printf("\n*** ERROR: ethaddr is NOT set !!\n"); - return -1; - } - eth_setenv_enetaddr("ethaddr", v_mac); - } - - smc_set_mac_addr(v_mac); /* use old function to update smc default */ - PRINTK("Using MAC Address %pM\n", v_mac); - return 0; -} - -/* - * get_rom_mac() - * Note, this has omly been tested for the OMAP730 P2. - */ - -static int get_rom_mac(struct eth_device *dev, unsigned char *v_rom_mac) -{ -#ifdef HARDCODE_MAC /* used for testing or to supress run time warnings */ - char hw_mac_addr[] = { 0x02, 0x80, 0xad, 0x20, 0x31, 0xb8 }; - - memcpy (v_rom_mac, hw_mac_addr, 6); - return (1); -#else - int i; - SMC_SELECT_BANK(dev, 1); - for (i=0; i<6; i++) - { - v_rom_mac[i] = SMC_inb(dev, LAN91C96_IA0 + i); - } - return (1); -#endif -} - -/* Structure to detect the device IDs */ -struct id_type { - u8 id; - char *name; -}; -static struct id_type supported_chips[] = { - {0, ""}, /* Dummy entry to prevent id check failure */ - {9, "LAN91C110"}, - {8, "LAN91C100FD"}, - {7, "LAN91C100"}, - {5, "LAN91C95"}, - {4, "LAN91C94/96"}, - {3, "LAN91C90/92"}, -}; -/* lan91c96_detect_chip - * See: - * http://www.embeddedsys.com/subpages/resources/images/documents/LAN91C96_datasheet.pdf - * page 71 - that is the closest we get to detect this device - */ -static int lan91c96_detect_chip(struct eth_device *dev) -{ - u8 chip_id; - int r; - SMC_SELECT_BANK(dev, 3); - chip_id = (SMC_inw(dev, 0xA) & LAN91C96_REV_CHIPID) >> 4; - SMC_SELECT_BANK(dev, 0); - for (r = 0; r < ARRAY_SIZE(supported_chips); r++) - if (chip_id == supported_chips[r].id) - return r; - return 0; -} - -int lan91c96_initialize(u8 dev_num, int base_addr) -{ - struct eth_device *dev; - int r = 0; - - dev = malloc(sizeof(*dev)); - if (!dev) { - return 0; - } - memset(dev, 0, sizeof(*dev)); - - dev->iobase = base_addr; - - /* Try to detect chip. Will fail if not present. */ - r = lan91c96_detect_chip(dev); - if (!r) { - free(dev); - return 0; - } - get_rom_mac(dev, dev->enetaddr); - - dev->init = lan91c96_init; - dev->halt = lan91c96_halt; - dev->send = lan91c96_send; - dev->recv = lan91c96_recv; - sprintf(dev->name, "%s-%hu", supported_chips[r].name, dev_num); - - eth_register(dev); - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/lan91c96.h b/qemu/roms/u-boot/drivers/net/lan91c96.h deleted file mode 100644 index 3e914ce5a..000000000 --- a/qemu/roms/u-boot/drivers/net/lan91c96.h +++ /dev/null @@ -1,617 +0,0 @@ -/*------------------------------------------------------------------------ - * lan91c96.h - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Rolf Offermanns <rof@sysgo.de> - * Copyright (C) 2001 Standard Microsystems Corporation (SMSC) - * Developed by Simple Network Magic Corporation (SNMC) - * Copyright (C) 1996 by Erik Stahlman (ES) - * - * SPDX-License-Identifier: GPL-2.0+ - * - * This file contains register information and access macros for - * the LAN91C96 single chip ethernet controller. It is a modified - * version of the smc9111.h file. - * - * Information contained in this file was obtained from the LAN91C96 - * manual from SMC. To get a copy, if you really want one, you can find - * information under www.smsc.com. - * - * Authors - * Erik Stahlman ( erik@vt.edu ) - * Daris A Nevil ( dnevil@snmc.com ) - * - * History - * 04/30/03 Mathijs Haarman Modified smc91111.h (u-boot version) - * for lan91c96 - *------------------------------------------------------------------------- - */ -#ifndef _LAN91C96_H_ -#define _LAN91C96_H_ - -#include <asm/types.h> -#include <asm/io.h> -#include <config.h> - -/* I want some simple types */ - -typedef unsigned char byte; -typedef unsigned short word; -typedef unsigned long int dword; - -/* - * DEBUGGING LEVELS - * - * 0 for normal operation - * 1 for slightly more details - * >2 for various levels of increasingly useless information - * 2 for interrupt tracking, status flags - * 3 for packet info - * 4 for complete packet dumps - */ -/*#define SMC_DEBUG 0 */ - -/* Because of bank switching, the LAN91xxx uses only 16 I/O ports */ - -#define SMC_IO_EXTENT 16 - -#ifdef CONFIG_CPU_PXA25X - -#define SMC_IO_SHIFT 0 - -#define SMCREG(edev, r) ((edev)->iobase+((r)<<SMC_IO_SHIFT)) - -#define SMC_inl(edev, r) (*((volatile dword *)SMCREG(edev, r))) -#define SMC_inw(edev, r) (*((volatile word *)SMCREG(edev, r))) -#define SMC_inb(edev, p) ({ \ - unsigned int __p = p; \ - unsigned int __v = SMC_inw(edev, __p & ~1); \ - if (__p & 1) __v >>= 8; \ - else __v &= 0xff; \ - __v; }) - -#define SMC_outl(edev, d, r) (*((volatile dword *)SMCREG(edev, r)) = d) -#define SMC_outw(edev, d, r) (*((volatile word *)SMCREG(edev, r)) = d) -#define SMC_outb(edev, d, r) ({ word __d = (byte)(d); \ - word __w = SMC_inw(edev, (r)&~1); \ - __w &= ((r)&1) ? 0x00FF : 0xFF00; \ - __w |= ((r)&1) ? __d<<8 : __d; \ - SMC_outw(edev, __w, (r)&~1); \ - }) - -#define SMC_outsl(edev, r, b, l) ({ int __i; \ - dword *__b2; \ - __b2 = (dword *) b; \ - for (__i = 0; __i < l; __i++) { \ - SMC_outl(edev, *(__b2 + __i),\ - r); \ - } \ - }) - -#define SMC_outsw(edev, r, b, l) ({ int __i; \ - word *__b2; \ - __b2 = (word *) b; \ - for (__i = 0; __i < l; __i++) { \ - SMC_outw(edev, *(__b2 + __i),\ - r); \ - } \ - }) - -#define SMC_insl(edev, r, b, l) ({ int __i ; \ - dword *__b2; \ - __b2 = (dword *) b; \ - for (__i = 0; __i < l; __i++) { \ - *(__b2 + __i) = SMC_inl(edev,\ - r); \ - SMC_inl(edev, 0); \ - }; \ - }) - -#define SMC_insw(edev, r, b, l) ({ int __i ; \ - word *__b2; \ - __b2 = (word *) b; \ - for (__i = 0; __i < l; __i++) { \ - *(__b2 + __i) = SMC_inw(edev,\ - r); \ - SMC_inw(edev, 0); \ - }; \ - }) - -#define SMC_insb(edev, r, b, l) ({ int __i ; \ - byte *__b2; \ - __b2 = (byte *) b; \ - for (__i = 0; __i < l; __i++) { \ - *(__b2 + __i) = SMC_inb(edev,\ - r); \ - SMC_inb(edev, 0); \ - }; \ - }) - -#else /* if not CONFIG_CPU_PXA25X */ - -/* - * We have only 16 Bit PCMCIA access on Socket 0 - */ - -#define SMC_inw(edev, r) (*((volatile word *)((edev)->iobase+(r)))) -#define SMC_inb(edev, r) (((r)&1) ? SMC_inw(edev, (r)&~1)>>8 :\ - SMC_inw(edev, r)&0xFF) - -#define SMC_outw(edev, d, r) (*((volatile word *)((edev)->iobase+(r))) = d) -#define SMC_outb(edev, d, r) ({ word __d = (byte)(d); \ - word __w = SMC_inw(edev, (r)&~1); \ - __w &= ((r)&1) ? 0x00FF : 0xFF00; \ - __w |= ((r)&1) ? __d<<8 : __d; \ - SMC_outw(edev, __w, (r)&~1); \ - }) -#define SMC_outsw(edev, r, b, l) ({ int __i; \ - word *__b2; \ - __b2 = (word *) b; \ - for (__i = 0; __i < l; __i++) { \ - SMC_outw(edev, *(__b2 + __i),\ - r); \ - } \ - }) - -#define SMC_insw(edev, r, b, l) ({ int __i ; \ - word *__b2; \ - __b2 = (word *) b; \ - for (__i = 0; __i < l; __i++) { \ - *(__b2 + __i) = SMC_inw(edev,\ - r); \ - SMC_inw(edev, 0); \ - }; \ - }) - -#endif - -/* - **************************************************************************** - * Bank Select Field - **************************************************************************** - */ -#define LAN91C96_BANK_SELECT 14 /* Bank Select Register */ -#define LAN91C96_BANKSELECT (0x3UC << 0) -#define BANK0 0x00 -#define BANK1 0x01 -#define BANK2 0x02 -#define BANK3 0x03 -#define BANK4 0x04 - -/* - **************************************************************************** - * EEPROM Addresses. - **************************************************************************** - */ -#define EEPROM_MAC_OFFSET_1 0x6020 -#define EEPROM_MAC_OFFSET_2 0x6021 -#define EEPROM_MAC_OFFSET_3 0x6022 - -/* - **************************************************************************** - * Bank 0 Register Map in I/O Space - **************************************************************************** - */ -#define LAN91C96_TCR 0 /* Transmit Control Register */ -#define LAN91C96_EPH_STATUS 2 /* EPH Status Register */ -#define LAN91C96_RCR 4 /* Receive Control Register */ -#define LAN91C96_COUNTER 6 /* Counter Register */ -#define LAN91C96_MIR 8 /* Memory Information Register */ -#define LAN91C96_MCR 10 /* Memory Configuration Register */ - -/* - **************************************************************************** - * Transmit Control Register - Bank 0 - Offset 0 - **************************************************************************** - */ -#define LAN91C96_TCR_TXENA (0x1U << 0) -#define LAN91C96_TCR_LOOP (0x1U << 1) -#define LAN91C96_TCR_FORCOL (0x1U << 2) -#define LAN91C96_TCR_TXP_EN (0x1U << 3) -#define LAN91C96_TCR_PAD_EN (0x1U << 7) -#define LAN91C96_TCR_NOCRC (0x1U << 8) -#define LAN91C96_TCR_MON_CSN (0x1U << 10) -#define LAN91C96_TCR_FDUPLX (0x1U << 11) -#define LAN91C96_TCR_STP_SQET (0x1U << 12) -#define LAN91C96_TCR_EPH_LOOP (0x1U << 13) -#define LAN91C96_TCR_ETEN_TYPE (0x1U << 14) -#define LAN91C96_TCR_FDSE (0x1U << 15) - -/* - **************************************************************************** - * EPH Status Register - Bank 0 - Offset 2 - **************************************************************************** - */ -#define LAN91C96_EPHSR_TX_SUC (0x1U << 0) -#define LAN91C96_EPHSR_SNGL_COL (0x1U << 1) -#define LAN91C96_EPHSR_MUL_COL (0x1U << 2) -#define LAN91C96_EPHSR_LTX_MULT (0x1U << 3) -#define LAN91C96_EPHSR_16COL (0x1U << 4) -#define LAN91C96_EPHSR_SQET (0x1U << 5) -#define LAN91C96_EPHSR_LTX_BRD (0x1U << 6) -#define LAN91C96_EPHSR_TX_DEFR (0x1U << 7) -#define LAN91C96_EPHSR_WAKEUP (0x1U << 8) -#define LAN91C96_EPHSR_LATCOL (0x1U << 9) -#define LAN91C96_EPHSR_LOST_CARR (0x1U << 10) -#define LAN91C96_EPHSR_EXC_DEF (0x1U << 11) -#define LAN91C96_EPHSR_CTR_ROL (0x1U << 12) - -#define LAN91C96_EPHSR_LINK_OK (0x1U << 14) -#define LAN91C96_EPHSR_TX_UNRN (0x1U << 15) - -#define LAN91C96_EPHSR_ERRORS (LAN91C96_EPHSR_SNGL_COL | \ - LAN91C96_EPHSR_MUL_COL | \ - LAN91C96_EPHSR_16COL | \ - LAN91C96_EPHSR_SQET | \ - LAN91C96_EPHSR_TX_DEFR | \ - LAN91C96_EPHSR_LATCOL | \ - LAN91C96_EPHSR_LOST_CARR | \ - LAN91C96_EPHSR_EXC_DEF | \ - LAN91C96_EPHSR_LINK_OK | \ - LAN91C96_EPHSR_TX_UNRN) - -/* - **************************************************************************** - * Receive Control Register - Bank 0 - Offset 4 - **************************************************************************** - */ -#define LAN91C96_RCR_RX_ABORT (0x1U << 0) -#define LAN91C96_RCR_PRMS (0x1U << 1) -#define LAN91C96_RCR_ALMUL (0x1U << 2) -#define LAN91C96_RCR_RXEN (0x1U << 8) -#define LAN91C96_RCR_STRIP_CRC (0x1U << 9) -#define LAN91C96_RCR_FILT_CAR (0x1U << 14) -#define LAN91C96_RCR_SOFT_RST (0x1U << 15) - -/* - **************************************************************************** - * Counter Register - Bank 0 - Offset 6 - **************************************************************************** - */ -#define LAN91C96_ECR_SNGL_COL (0xFU << 0) -#define LAN91C96_ECR_MULT_COL (0xFU << 5) -#define LAN91C96_ECR_DEF_TX (0xFU << 8) -#define LAN91C96_ECR_EXC_DEF_TX (0xFU << 12) - -/* - **************************************************************************** - * Memory Information Register - Bank 0 - OFfset 8 - **************************************************************************** - */ -#define LAN91C96_MIR_SIZE (0x18 << 0) /* 6144 bytes */ - -/* - **************************************************************************** - * Memory Configuration Register - Bank 0 - Offset 10 - **************************************************************************** - */ -#define LAN91C96_MCR_MEM_RES (0xFFU << 0) -#define LAN91C96_MCR_MEM_MULT (0x3U << 9) -#define LAN91C96_MCR_HIGH_ID (0x3U << 12) - -#define LAN91C96_MCR_TRANSMIT_PAGES 0x6 - -/* - **************************************************************************** - * Bank 1 Register Map in I/O Space - **************************************************************************** - */ -#define LAN91C96_CONFIG 0 /* Configuration Register */ -#define LAN91C96_BASE 2 /* Base Address Register */ -#define LAN91C96_IA0 4 /* Individual Address Register - 0 */ -#define LAN91C96_IA1 5 /* Individual Address Register - 1 */ -#define LAN91C96_IA2 6 /* Individual Address Register - 2 */ -#define LAN91C96_IA3 7 /* Individual Address Register - 3 */ -#define LAN91C96_IA4 8 /* Individual Address Register - 4 */ -#define LAN91C96_IA5 9 /* Individual Address Register - 5 */ -#define LAN91C96_GEN_PURPOSE 10 /* General Address Registers */ -#define LAN91C96_CONTROL 12 /* Control Register */ - -/* - **************************************************************************** - * Configuration Register - Bank 1 - Offset 0 - **************************************************************************** - */ -#define LAN91C96_CR_INT_SEL0 (0x1U << 1) -#define LAN91C96_CR_INT_SEL1 (0x1U << 2) -#define LAN91C96_CR_RES (0x3U << 3) -#define LAN91C96_CR_DIS_LINK (0x1U << 6) -#define LAN91C96_CR_16BIT (0x1U << 7) -#define LAN91C96_CR_AUI_SELECT (0x1U << 8) -#define LAN91C96_CR_SET_SQLCH (0x1U << 9) -#define LAN91C96_CR_FULL_STEP (0x1U << 10) -#define LAN91C96_CR_NO_WAIT (0x1U << 12) - -/* - **************************************************************************** - * Base Address Register - Bank 1 - Offset 2 - **************************************************************************** - */ -#define LAN91C96_BAR_RA_BITS (0x27U << 0) -#define LAN91C96_BAR_ROM_SIZE (0x1U << 6) -#define LAN91C96_BAR_A_BITS (0xFFU << 8) - -/* - **************************************************************************** - * Control Register - Bank 1 - Offset 12 - **************************************************************************** - */ -#define LAN91C96_CTR_STORE (0x1U << 0) -#define LAN91C96_CTR_RELOAD (0x1U << 1) -#define LAN91C96_CTR_EEPROM (0x1U << 2) -#define LAN91C96_CTR_TE_ENABLE (0x1U << 5) -#define LAN91C96_CTR_CR_ENABLE (0x1U << 6) -#define LAN91C96_CTR_LE_ENABLE (0x1U << 7) -#define LAN91C96_CTR_BIT_8 (0x1U << 8) -#define LAN91C96_CTR_AUTO_RELEASE (0x1U << 11) -#define LAN91C96_CTR_WAKEUP_EN (0x1U << 12) -#define LAN91C96_CTR_PWRDN (0x1U << 13) -#define LAN91C96_CTR_RCV_BAD (0x1U << 14) - -/* - **************************************************************************** - * Bank 2 Register Map in I/O Space - **************************************************************************** - */ -#define LAN91C96_MMU 0 /* MMU Command Register */ -#define LAN91C96_AUTO_TX_START 1 /* Auto Tx Start Register */ -#define LAN91C96_PNR 2 /* Packet Number Register */ -#define LAN91C96_ARR 3 /* Allocation Result Register */ -#define LAN91C96_FIFO 4 /* FIFO Ports Register */ -#define LAN91C96_POINTER 6 /* Pointer Register */ -#define LAN91C96_DATA_HIGH 8 /* Data High Register */ -#define LAN91C96_DATA_LOW 10 /* Data Low Register */ -#define LAN91C96_INT_STATS 12 /* Interrupt Status Register - RO */ -#define LAN91C96_INT_ACK 12 /* Interrupt Acknowledge Register -WO */ -#define LAN91C96_INT_MASK 13 /* Interrupt Mask Register */ - -/* - **************************************************************************** - * MMU Command Register - Bank 2 - Offset 0 - **************************************************************************** - */ -#define LAN91C96_MMUCR_NO_BUSY (0x1U << 0) -#define LAN91C96_MMUCR_N1 (0x1U << 1) -#define LAN91C96_MMUCR_N2 (0x1U << 2) -#define LAN91C96_MMUCR_COMMAND (0xFU << 4) -#define LAN91C96_MMUCR_ALLOC_TX (0x2U << 4) /* WXYZ = 0010 */ -#define LAN91C96_MMUCR_RESET_MMU (0x4U << 4) /* WXYZ = 0100 */ -#define LAN91C96_MMUCR_REMOVE_RX (0x6U << 4) /* WXYZ = 0110 */ -#define LAN91C96_MMUCR_REMOVE_TX (0x7U << 4) /* WXYZ = 0111 */ -#define LAN91C96_MMUCR_RELEASE_RX (0x8U << 4) /* WXYZ = 1000 */ -#define LAN91C96_MMUCR_RELEASE_TX (0xAU << 4) /* WXYZ = 1010 */ -#define LAN91C96_MMUCR_ENQUEUE (0xCU << 4) /* WXYZ = 1100 */ -#define LAN91C96_MMUCR_RESET_TX (0xEU << 4) /* WXYZ = 1110 */ - -/* - **************************************************************************** - * Auto Tx Start Register - Bank 2 - Offset 1 - **************************************************************************** - */ -#define LAN91C96_AUTOTX (0xFFU << 0) - -/* - **************************************************************************** - * Packet Number Register - Bank 2 - Offset 2 - **************************************************************************** - */ -#define LAN91C96_PNR_TX (0x1FU << 0) - -/* - **************************************************************************** - * Allocation Result Register - Bank 2 - Offset 3 - **************************************************************************** - */ -#define LAN91C96_ARR_ALLOC_PN (0x7FU << 0) -#define LAN91C96_ARR_FAILED (0x1U << 7) - -/* - **************************************************************************** - * FIFO Ports Register - Bank 2 - Offset 4 - **************************************************************************** - */ -#define LAN91C96_FIFO_TX_DONE_PN (0x1FU << 0) -#define LAN91C96_FIFO_TEMPTY (0x1U << 7) -#define LAN91C96_FIFO_RX_DONE_PN (0x1FU << 8) -#define LAN91C96_FIFO_RXEMPTY (0x1U << 15) - -/* - **************************************************************************** - * Pointer Register - Bank 2 - Offset 6 - **************************************************************************** - */ -#define LAN91C96_PTR_LOW (0xFFU << 0) -#define LAN91C96_PTR_HIGH (0x7U << 8) -#define LAN91C96_PTR_AUTO_TX (0x1U << 11) -#define LAN91C96_PTR_ETEN (0x1U << 12) -#define LAN91C96_PTR_READ (0x1U << 13) -#define LAN91C96_PTR_AUTO_INCR (0x1U << 14) -#define LAN91C96_PTR_RCV (0x1U << 15) - -#define LAN91C96_PTR_RX_FRAME (LAN91C96_PTR_RCV | \ - LAN91C96_PTR_AUTO_INCR | \ - LAN91C96_PTR_READ) - -/* - **************************************************************************** - * Data Register - Bank 2 - Offset 8 - **************************************************************************** - */ -#define LAN91C96_CONTROL_CRC (0x1U << 4) /* CRC bit */ -#define LAN91C96_CONTROL_ODD (0x1U << 5) /* ODD bit */ - -/* - **************************************************************************** - * Interrupt Status Register - Bank 2 - Offset 12 - **************************************************************************** - */ -#define LAN91C96_IST_RCV_INT (0x1U << 0) -#define LAN91C96_IST_TX_INT (0x1U << 1) -#define LAN91C96_IST_TX_EMPTY_INT (0x1U << 2) -#define LAN91C96_IST_ALLOC_INT (0x1U << 3) -#define LAN91C96_IST_RX_OVRN_INT (0x1U << 4) -#define LAN91C96_IST_EPH_INT (0x1U << 5) -#define LAN91C96_IST_ERCV_INT (0x1U << 6) -#define LAN91C96_IST_RX_IDLE_INT (0x1U << 7) - -/* - **************************************************************************** - * Interrupt Acknowledge Register - Bank 2 - Offset 12 - **************************************************************************** - */ -#define LAN91C96_ACK_TX_INT (0x1U << 1) -#define LAN91C96_ACK_TX_EMPTY_INT (0x1U << 2) -#define LAN91C96_ACK_RX_OVRN_INT (0x1U << 4) -#define LAN91C96_ACK_ERCV_INT (0x1U << 6) - -/* - **************************************************************************** - * Interrupt Mask Register - Bank 2 - Offset 13 - **************************************************************************** - */ -#define LAN91C96_MSK_RCV_INT (0x1U << 0) -#define LAN91C96_MSK_TX_INT (0x1U << 1) -#define LAN91C96_MSK_TX_EMPTY_INT (0x1U << 2) -#define LAN91C96_MSK_ALLOC_INT (0x1U << 3) -#define LAN91C96_MSK_RX_OVRN_INT (0x1U << 4) -#define LAN91C96_MSK_EPH_INT (0x1U << 5) -#define LAN91C96_MSK_ERCV_INT (0x1U << 6) -#define LAN91C96_MSK_TX_IDLE_INT (0x1U << 7) - -/* - **************************************************************************** - * Bank 3 Register Map in I/O Space - ************************************************************************** - */ -#define LAN91C96_MGMT_MDO (0x1U << 0) -#define LAN91C96_MGMT_MDI (0x1U << 1) -#define LAN91C96_MGMT_MCLK (0x1U << 2) -#define LAN91C96_MGMT_MDOE (0x1U << 3) -#define LAN91C96_MGMT_LOW_ID (0x3U << 4) -#define LAN91C96_MGMT_IOS0 (0x1U << 8) -#define LAN91C96_MGMT_IOS1 (0x1U << 9) -#define LAN91C96_MGMT_IOS2 (0x1U << 10) -#define LAN91C96_MGMT_nXNDEC (0x1U << 11) -#define LAN91C96_MGMT_HIGH_ID (0x3U << 12) - -/* - **************************************************************************** - * Revision Register - Bank 3 - Offset 10 - **************************************************************************** - */ -#define LAN91C96_REV_REVID (0xFU << 0) -#define LAN91C96_REV_CHIPID (0xFU << 4) - -/* - **************************************************************************** - * Early RCV Register - Bank 3 - Offset 12 - **************************************************************************** - */ -#define LAN91C96_ERCV_THRESHOLD (0x1FU << 0) -#define LAN91C96_ERCV_RCV_DISCRD (0x1U << 7) - -/* - **************************************************************************** - * PCMCIA Configuration Registers - **************************************************************************** - */ -#define LAN91C96_ECOR 0x8000 /* Ethernet Configuration Register */ -#define LAN91C96_ECSR 0x8002 /* Ethernet Configuration and Status */ - -/* - **************************************************************************** - * PCMCIA Ethernet Configuration Option Register (ECOR) - **************************************************************************** - */ -#define LAN91C96_ECOR_ENABLE (0x1U << 0) -#define LAN91C96_ECOR_WR_ATTRIB (0x1U << 2) -#define LAN91C96_ECOR_LEVEL_REQ (0x1U << 6) -#define LAN91C96_ECOR_SRESET (0x1U << 7) - -/* - **************************************************************************** - * PCMCIA Ethernet Configuration and Status Register (ECSR) - **************************************************************************** - */ -#define LAN91C96_ECSR_INTR (0x1U << 1) -#define LAN91C96_ECSR_PWRDWN (0x1U << 2) -#define LAN91C96_ECSR_IOIS8 (0x1U << 5) - -/* - **************************************************************************** - * Receive Frame Status Word - See page 38 of the LAN91C96 specification. - **************************************************************************** - */ -#define LAN91C96_TOO_SHORT (0x1U << 10) -#define LAN91C96_TOO_LONG (0x1U << 11) -#define LAN91C96_ODD_FRM (0x1U << 12) -#define LAN91C96_BAD_CRC (0x1U << 13) -#define LAN91C96_BROD_CAST (0x1U << 14) -#define LAN91C96_ALGN_ERR (0x1U << 15) - -#define FRAME_FILTER (LAN91C96_TOO_SHORT | LAN91C96_TOO_LONG | LAN91C96_BAD_CRC | LAN91C96_ALGN_ERR) - -/* - **************************************************************************** - * Default MAC Address - **************************************************************************** - */ -#define MAC_DEF_HI 0x0800 -#define MAC_DEF_MED 0x3333 -#define MAC_DEF_LO 0x0100 - -/* - **************************************************************************** - * Default I/O Signature - 0x33 - **************************************************************************** - */ -#define LAN91C96_LOW_SIGNATURE (0x33U << 0) -#define LAN91C96_HIGH_SIGNATURE (0x33U << 8) -#define LAN91C96_SIGNATURE (LAN91C96_HIGH_SIGNATURE | LAN91C96_LOW_SIGNATURE) - -#define LAN91C96_MAX_PAGES 6 /* Maximum number of 256 pages. */ -#define ETHERNET_MAX_LENGTH 1514 - - -/*------------------------------------------------------------------------- - * I define some macros to make it easier to do somewhat common - * or slightly complicated, repeated tasks. - *------------------------------------------------------------------------- - */ - -/* select a register bank, 0 to 3 */ - -#define SMC_SELECT_BANK(edev, x) { SMC_outw(edev, x, LAN91C96_BANK_SELECT); } - -/* this enables an interrupt in the interrupt mask register */ -#define SMC_ENABLE_INT(edev, x) {\ - unsigned char mask;\ - SMC_SELECT_BANK(edev, 2);\ - mask = SMC_inb(edev, LAN91C96_INT_MASK);\ - mask |= (x);\ - SMC_outb(edev, mask, LAN91C96_INT_MASK); \ -} - -/* this disables an interrupt from the interrupt mask register */ - -#define SMC_DISABLE_INT(edev, x) {\ - unsigned char mask;\ - SMC_SELECT_BANK(edev, 2);\ - mask = SMC_inb(edev, LAN91C96_INT_MASK);\ - mask &= ~(x);\ - SMC_outb(edev, mask, LAN91C96_INT_MASK); \ -} - -/*---------------------------------------------------------------------- - * Define the interrupts that I want to receive from the card - * - * I want: - * LAN91C96_IST_EPH_INT, for nasty errors - * LAN91C96_IST_RCV_INT, for happy received packets - * LAN91C96_IST_RX_OVRN_INT, because I have to kick the receiver - *------------------------------------------------------------------------- - */ -#define SMC_INTERRUPT_MASK (LAN91C96_IST_EPH_INT | LAN91C96_IST_RX_OVRN_INT | LAN91C96_IST_RCV_INT) - -#endif /* _LAN91C96_H_ */ diff --git a/qemu/roms/u-boot/drivers/net/macb.c b/qemu/roms/u-boot/drivers/net/macb.c deleted file mode 100644 index 781a272cf..000000000 --- a/qemu/roms/u-boot/drivers/net/macb.c +++ /dev/null @@ -1,702 +0,0 @@ -/* - * Copyright (C) 2005-2006 Atmel Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> - -/* - * The u-boot networking stack is a little weird. It seems like the - * networking core allocates receive buffers up front without any - * regard to the hardware that's supposed to actually receive those - * packets. - * - * The MACB receives packets into 128-byte receive buffers, so the - * buffers allocated by the core isn't very practical to use. We'll - * allocate our own, but we need one such buffer in case a packet - * wraps around the DMA ring so that we have to copy it. - * - * Therefore, define CONFIG_SYS_RX_ETH_BUFFER to 1 in the board-specific - * configuration header. This way, the core allocates one RX buffer - * and one TX buffer, each of which can hold a ethernet packet of - * maximum size. - * - * For some reason, the networking core unconditionally specifies a - * 32-byte packet "alignment" (which really should be called - * "padding"). MACB shouldn't need that, but we'll refrain from any - * core modifications here... - */ - -#include <net.h> -#include <netdev.h> -#include <malloc.h> -#include <miiphy.h> - -#include <linux/mii.h> -#include <asm/io.h> -#include <asm/dma-mapping.h> -#include <asm/arch/clk.h> -#include <asm-generic/errno.h> - -#include "macb.h" - -#define CONFIG_SYS_MACB_RX_BUFFER_SIZE 4096 -#define CONFIG_SYS_MACB_RX_RING_SIZE (CONFIG_SYS_MACB_RX_BUFFER_SIZE / 128) -#define CONFIG_SYS_MACB_TX_RING_SIZE 16 -#define CONFIG_SYS_MACB_TX_TIMEOUT 1000 -#define CONFIG_SYS_MACB_AUTONEG_TIMEOUT 5000000 - -struct macb_dma_desc { - u32 addr; - u32 ctrl; -}; - -#define RXADDR_USED 0x00000001 -#define RXADDR_WRAP 0x00000002 - -#define RXBUF_FRMLEN_MASK 0x00000fff -#define RXBUF_FRAME_START 0x00004000 -#define RXBUF_FRAME_END 0x00008000 -#define RXBUF_TYPEID_MATCH 0x00400000 -#define RXBUF_ADDR4_MATCH 0x00800000 -#define RXBUF_ADDR3_MATCH 0x01000000 -#define RXBUF_ADDR2_MATCH 0x02000000 -#define RXBUF_ADDR1_MATCH 0x04000000 -#define RXBUF_BROADCAST 0x80000000 - -#define TXBUF_FRMLEN_MASK 0x000007ff -#define TXBUF_FRAME_END 0x00008000 -#define TXBUF_NOCRC 0x00010000 -#define TXBUF_EXHAUSTED 0x08000000 -#define TXBUF_UNDERRUN 0x10000000 -#define TXBUF_MAXRETRY 0x20000000 -#define TXBUF_WRAP 0x40000000 -#define TXBUF_USED 0x80000000 - -struct macb_device { - void *regs; - - unsigned int rx_tail; - unsigned int tx_head; - unsigned int tx_tail; - - void *rx_buffer; - void *tx_buffer; - struct macb_dma_desc *rx_ring; - struct macb_dma_desc *tx_ring; - - unsigned long rx_buffer_dma; - unsigned long rx_ring_dma; - unsigned long tx_ring_dma; - - const struct device *dev; - struct eth_device netdev; - unsigned short phy_addr; - struct mii_dev *bus; -}; -#define to_macb(_nd) container_of(_nd, struct macb_device, netdev) - -static int macb_is_gem(struct macb_device *macb) -{ - return MACB_BFEXT(IDNUM, macb_readl(macb, MID)) == 0x2; -} - -static void macb_mdio_write(struct macb_device *macb, u8 reg, u16 value) -{ - unsigned long netctl; - unsigned long netstat; - unsigned long frame; - - netctl = macb_readl(macb, NCR); - netctl |= MACB_BIT(MPE); - macb_writel(macb, NCR, netctl); - - frame = (MACB_BF(SOF, 1) - | MACB_BF(RW, 1) - | MACB_BF(PHYA, macb->phy_addr) - | MACB_BF(REGA, reg) - | MACB_BF(CODE, 2) - | MACB_BF(DATA, value)); - macb_writel(macb, MAN, frame); - - do { - netstat = macb_readl(macb, NSR); - } while (!(netstat & MACB_BIT(IDLE))); - - netctl = macb_readl(macb, NCR); - netctl &= ~MACB_BIT(MPE); - macb_writel(macb, NCR, netctl); -} - -static u16 macb_mdio_read(struct macb_device *macb, u8 reg) -{ - unsigned long netctl; - unsigned long netstat; - unsigned long frame; - - netctl = macb_readl(macb, NCR); - netctl |= MACB_BIT(MPE); - macb_writel(macb, NCR, netctl); - - frame = (MACB_BF(SOF, 1) - | MACB_BF(RW, 2) - | MACB_BF(PHYA, macb->phy_addr) - | MACB_BF(REGA, reg) - | MACB_BF(CODE, 2)); - macb_writel(macb, MAN, frame); - - do { - netstat = macb_readl(macb, NSR); - } while (!(netstat & MACB_BIT(IDLE))); - - frame = macb_readl(macb, MAN); - - netctl = macb_readl(macb, NCR); - netctl &= ~MACB_BIT(MPE); - macb_writel(macb, NCR, netctl); - - return MACB_BFEXT(DATA, frame); -} - -void __weak arch_get_mdio_control(const char *name) -{ - return; -} - -#if defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) - -int macb_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value) -{ - struct eth_device *dev = eth_get_dev_by_name(devname); - struct macb_device *macb = to_macb(dev); - - if ( macb->phy_addr != phy_adr ) - return -1; - - arch_get_mdio_control(devname); - *value = macb_mdio_read(macb, reg); - - return 0; -} - -int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value) -{ - struct eth_device *dev = eth_get_dev_by_name(devname); - struct macb_device *macb = to_macb(dev); - - if ( macb->phy_addr != phy_adr ) - return -1; - - arch_get_mdio_control(devname); - macb_mdio_write(macb, reg, value); - - return 0; -} -#endif - - -#if defined(CONFIG_CMD_NET) - -static int macb_send(struct eth_device *netdev, void *packet, int length) -{ - struct macb_device *macb = to_macb(netdev); - unsigned long paddr, ctrl; - unsigned int tx_head = macb->tx_head; - int i; - - paddr = dma_map_single(packet, length, DMA_TO_DEVICE); - - ctrl = length & TXBUF_FRMLEN_MASK; - ctrl |= TXBUF_FRAME_END; - if (tx_head == (CONFIG_SYS_MACB_TX_RING_SIZE - 1)) { - ctrl |= TXBUF_WRAP; - macb->tx_head = 0; - } else - macb->tx_head++; - - macb->tx_ring[tx_head].ctrl = ctrl; - macb->tx_ring[tx_head].addr = paddr; - barrier(); - macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART)); - - /* - * I guess this is necessary because the networking core may - * re-use the transmit buffer as soon as we return... - */ - for (i = 0; i <= CONFIG_SYS_MACB_TX_TIMEOUT; i++) { - barrier(); - ctrl = macb->tx_ring[tx_head].ctrl; - if (ctrl & TXBUF_USED) - break; - udelay(1); - } - - dma_unmap_single(packet, length, paddr); - - if (i <= CONFIG_SYS_MACB_TX_TIMEOUT) { - if (ctrl & TXBUF_UNDERRUN) - printf("%s: TX underrun\n", netdev->name); - if (ctrl & TXBUF_EXHAUSTED) - printf("%s: TX buffers exhausted in mid frame\n", - netdev->name); - } else { - printf("%s: TX timeout\n", netdev->name); - } - - /* No one cares anyway */ - return 0; -} - -static void reclaim_rx_buffers(struct macb_device *macb, - unsigned int new_tail) -{ - unsigned int i; - - i = macb->rx_tail; - while (i > new_tail) { - macb->rx_ring[i].addr &= ~RXADDR_USED; - i++; - if (i > CONFIG_SYS_MACB_RX_RING_SIZE) - i = 0; - } - - while (i < new_tail) { - macb->rx_ring[i].addr &= ~RXADDR_USED; - i++; - } - - barrier(); - macb->rx_tail = new_tail; -} - -static int macb_recv(struct eth_device *netdev) -{ - struct macb_device *macb = to_macb(netdev); - unsigned int rx_tail = macb->rx_tail; - void *buffer; - int length; - int wrapped = 0; - u32 status; - - for (;;) { - if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED)) - return -1; - - status = macb->rx_ring[rx_tail].ctrl; - if (status & RXBUF_FRAME_START) { - if (rx_tail != macb->rx_tail) - reclaim_rx_buffers(macb, rx_tail); - wrapped = 0; - } - - if (status & RXBUF_FRAME_END) { - buffer = macb->rx_buffer + 128 * macb->rx_tail; - length = status & RXBUF_FRMLEN_MASK; - if (wrapped) { - unsigned int headlen, taillen; - - headlen = 128 * (CONFIG_SYS_MACB_RX_RING_SIZE - - macb->rx_tail); - taillen = length - headlen; - memcpy((void *)NetRxPackets[0], - buffer, headlen); - memcpy((void *)NetRxPackets[0] + headlen, - macb->rx_buffer, taillen); - buffer = (void *)NetRxPackets[0]; - } - - NetReceive(buffer, length); - if (++rx_tail >= CONFIG_SYS_MACB_RX_RING_SIZE) - rx_tail = 0; - reclaim_rx_buffers(macb, rx_tail); - } else { - if (++rx_tail >= CONFIG_SYS_MACB_RX_RING_SIZE) { - wrapped = 1; - rx_tail = 0; - } - } - barrier(); - } - - return 0; -} - -static void macb_phy_reset(struct macb_device *macb) -{ - struct eth_device *netdev = &macb->netdev; - int i; - u16 status, adv; - - adv = ADVERTISE_CSMA | ADVERTISE_ALL; - macb_mdio_write(macb, MII_ADVERTISE, adv); - printf("%s: Starting autonegotiation...\n", netdev->name); - macb_mdio_write(macb, MII_BMCR, (BMCR_ANENABLE - | BMCR_ANRESTART)); - - for (i = 0; i < CONFIG_SYS_MACB_AUTONEG_TIMEOUT / 100; i++) { - status = macb_mdio_read(macb, MII_BMSR); - if (status & BMSR_ANEGCOMPLETE) - break; - udelay(100); - } - - if (status & BMSR_ANEGCOMPLETE) - printf("%s: Autonegotiation complete\n", netdev->name); - else - printf("%s: Autonegotiation timed out (status=0x%04x)\n", - netdev->name, status); -} - -#ifdef CONFIG_MACB_SEARCH_PHY -static int macb_phy_find(struct macb_device *macb) -{ - int i; - u16 phy_id; - - /* Search for PHY... */ - for (i = 0; i < 32; i++) { - macb->phy_addr = i; - phy_id = macb_mdio_read(macb, MII_PHYSID1); - if (phy_id != 0xffff) { - printf("%s: PHY present at %d\n", macb->netdev.name, i); - return 1; - } - } - - /* PHY isn't up to snuff */ - printf("%s: PHY not found\n", macb->netdev.name); - - return 0; -} -#endif /* CONFIG_MACB_SEARCH_PHY */ - - -static int macb_phy_init(struct macb_device *macb) -{ - struct eth_device *netdev = &macb->netdev; -#ifdef CONFIG_PHYLIB - struct phy_device *phydev; -#endif - u32 ncfgr; - u16 phy_id, status, adv, lpa; - int media, speed, duplex; - int i; - - arch_get_mdio_control(netdev->name); -#ifdef CONFIG_MACB_SEARCH_PHY - /* Auto-detect phy_addr */ - if (!macb_phy_find(macb)) { - return 0; - } -#endif /* CONFIG_MACB_SEARCH_PHY */ - - /* Check if the PHY is up to snuff... */ - phy_id = macb_mdio_read(macb, MII_PHYSID1); - if (phy_id == 0xffff) { - printf("%s: No PHY present\n", netdev->name); - return 0; - } - -#ifdef CONFIG_PHYLIB - /* need to consider other phy interface mode */ - phydev = phy_connect(macb->bus, macb->phy_addr, netdev, - PHY_INTERFACE_MODE_RGMII); - if (!phydev) { - printf("phy_connect failed\n"); - return -ENODEV; - } - - phy_config(phydev); -#endif - - status = macb_mdio_read(macb, MII_BMSR); - if (!(status & BMSR_LSTATUS)) { - /* Try to re-negotiate if we don't have link already. */ - macb_phy_reset(macb); - - for (i = 0; i < CONFIG_SYS_MACB_AUTONEG_TIMEOUT / 100; i++) { - status = macb_mdio_read(macb, MII_BMSR); - if (status & BMSR_LSTATUS) - break; - udelay(100); - } - } - - if (!(status & BMSR_LSTATUS)) { - printf("%s: link down (status: 0x%04x)\n", - netdev->name, status); - return 0; - } - - /* First check for GMAC */ - if (macb_is_gem(macb)) { - lpa = macb_mdio_read(macb, MII_STAT1000); - if (lpa & (1 << 11)) { - speed = 1000; - duplex = 1; - } else { - if (lpa & (1 << 10)) { - speed = 1000; - duplex = 1; - } else { - speed = 0; - } - } - - if (speed == 1000) { - printf("%s: link up, %dMbps %s-duplex (lpa: 0x%04x)\n", - netdev->name, - speed, - duplex ? "full" : "half", - lpa); - - ncfgr = macb_readl(macb, NCFGR); - ncfgr &= ~(GEM_BIT(GBE) | MACB_BIT(SPD) | MACB_BIT(FD)); - if (speed) - ncfgr |= GEM_BIT(GBE); - if (duplex) - ncfgr |= MACB_BIT(FD); - macb_writel(macb, NCFGR, ncfgr); - - return 1; - } - } - - /* fall back for EMAC checking */ - adv = macb_mdio_read(macb, MII_ADVERTISE); - lpa = macb_mdio_read(macb, MII_LPA); - media = mii_nway_result(lpa & adv); - speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF) - ? 1 : 0); - duplex = (media & ADVERTISE_FULL) ? 1 : 0; - printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n", - netdev->name, - speed ? "100" : "10", - duplex ? "full" : "half", - lpa); - - ncfgr = macb_readl(macb, NCFGR); - ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD)); - if (speed) - ncfgr |= MACB_BIT(SPD); - if (duplex) - ncfgr |= MACB_BIT(FD); - macb_writel(macb, NCFGR, ncfgr); - - return 1; -} - -static int macb_init(struct eth_device *netdev, bd_t *bd) -{ - struct macb_device *macb = to_macb(netdev); - unsigned long paddr; - int i; - - /* - * macb_halt should have been called at some point before now, - * so we'll assume the controller is idle. - */ - - /* initialize DMA descriptors */ - paddr = macb->rx_buffer_dma; - for (i = 0; i < CONFIG_SYS_MACB_RX_RING_SIZE; i++) { - if (i == (CONFIG_SYS_MACB_RX_RING_SIZE - 1)) - paddr |= RXADDR_WRAP; - macb->rx_ring[i].addr = paddr; - macb->rx_ring[i].ctrl = 0; - paddr += 128; - } - for (i = 0; i < CONFIG_SYS_MACB_TX_RING_SIZE; i++) { - macb->tx_ring[i].addr = 0; - if (i == (CONFIG_SYS_MACB_TX_RING_SIZE - 1)) - macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP; - else - macb->tx_ring[i].ctrl = TXBUF_USED; - } - macb->rx_tail = macb->tx_head = macb->tx_tail = 0; - - macb_writel(macb, RBQP, macb->rx_ring_dma); - macb_writel(macb, TBQP, macb->tx_ring_dma); - - if (macb_is_gem(macb)) { -#ifdef CONFIG_RGMII - gem_writel(macb, UR, GEM_BIT(RGMII)); -#else - gem_writel(macb, UR, 0); -#endif - } else { - /* choose RMII or MII mode. This depends on the board */ -#ifdef CONFIG_RMII -#ifdef CONFIG_AT91FAMILY - macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN)); -#else - macb_writel(macb, USRIO, 0); -#endif -#else -#ifdef CONFIG_AT91FAMILY - macb_writel(macb, USRIO, MACB_BIT(CLKEN)); -#else - macb_writel(macb, USRIO, MACB_BIT(MII)); -#endif -#endif /* CONFIG_RMII */ - } - - if (!macb_phy_init(macb)) - return -1; - - /* Enable TX and RX */ - macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE)); - - return 0; -} - -static void macb_halt(struct eth_device *netdev) -{ - struct macb_device *macb = to_macb(netdev); - u32 ncr, tsr; - - /* Halt the controller and wait for any ongoing transmission to end. */ - ncr = macb_readl(macb, NCR); - ncr |= MACB_BIT(THALT); - macb_writel(macb, NCR, ncr); - - do { - tsr = macb_readl(macb, TSR); - } while (tsr & MACB_BIT(TGO)); - - /* Disable TX and RX, and clear statistics */ - macb_writel(macb, NCR, MACB_BIT(CLRSTAT)); -} - -static int macb_write_hwaddr(struct eth_device *dev) -{ - struct macb_device *macb = to_macb(dev); - u32 hwaddr_bottom; - u16 hwaddr_top; - - /* set hardware address */ - hwaddr_bottom = dev->enetaddr[0] | dev->enetaddr[1] << 8 | - dev->enetaddr[2] << 16 | dev->enetaddr[3] << 24; - macb_writel(macb, SA1B, hwaddr_bottom); - hwaddr_top = dev->enetaddr[4] | dev->enetaddr[5] << 8; - macb_writel(macb, SA1T, hwaddr_top); - return 0; -} - -static u32 macb_mdc_clk_div(int id, struct macb_device *macb) -{ - u32 config; - unsigned long macb_hz = get_macb_pclk_rate(id); - - if (macb_hz < 20000000) - config = MACB_BF(CLK, MACB_CLK_DIV8); - else if (macb_hz < 40000000) - config = MACB_BF(CLK, MACB_CLK_DIV16); - else if (macb_hz < 80000000) - config = MACB_BF(CLK, MACB_CLK_DIV32); - else - config = MACB_BF(CLK, MACB_CLK_DIV64); - - return config; -} - -static u32 gem_mdc_clk_div(int id, struct macb_device *macb) -{ - u32 config; - unsigned long macb_hz = get_macb_pclk_rate(id); - - if (macb_hz < 20000000) - config = GEM_BF(CLK, GEM_CLK_DIV8); - else if (macb_hz < 40000000) - config = GEM_BF(CLK, GEM_CLK_DIV16); - else if (macb_hz < 80000000) - config = GEM_BF(CLK, GEM_CLK_DIV32); - else if (macb_hz < 120000000) - config = GEM_BF(CLK, GEM_CLK_DIV48); - else if (macb_hz < 160000000) - config = GEM_BF(CLK, GEM_CLK_DIV64); - else - config = GEM_BF(CLK, GEM_CLK_DIV96); - - return config; -} - -/* - * Get the DMA bus width field of the network configuration register that we - * should program. We find the width from decoding the design configuration - * register to find the maximum supported data bus width. - */ -static u32 macb_dbw(struct macb_device *macb) -{ - switch (GEM_BFEXT(DBWDEF, gem_readl(macb, DCFG1))) { - case 4: - return GEM_BF(DBW, GEM_DBW128); - case 2: - return GEM_BF(DBW, GEM_DBW64); - case 1: - default: - return GEM_BF(DBW, GEM_DBW32); - } -} - -int macb_eth_initialize(int id, void *regs, unsigned int phy_addr) -{ - struct macb_device *macb; - struct eth_device *netdev; - u32 ncfgr; - - macb = malloc(sizeof(struct macb_device)); - if (!macb) { - printf("Error: Failed to allocate memory for MACB%d\n", id); - return -1; - } - memset(macb, 0, sizeof(struct macb_device)); - - netdev = &macb->netdev; - - macb->rx_buffer = dma_alloc_coherent(CONFIG_SYS_MACB_RX_BUFFER_SIZE, - &macb->rx_buffer_dma); - macb->rx_ring = dma_alloc_coherent(CONFIG_SYS_MACB_RX_RING_SIZE - * sizeof(struct macb_dma_desc), - &macb->rx_ring_dma); - macb->tx_ring = dma_alloc_coherent(CONFIG_SYS_MACB_TX_RING_SIZE - * sizeof(struct macb_dma_desc), - &macb->tx_ring_dma); - - macb->regs = regs; - macb->phy_addr = phy_addr; - - if (macb_is_gem(macb)) - sprintf(netdev->name, "gmac%d", id); - else - sprintf(netdev->name, "macb%d", id); - - netdev->init = macb_init; - netdev->halt = macb_halt; - netdev->send = macb_send; - netdev->recv = macb_recv; - netdev->write_hwaddr = macb_write_hwaddr; - - /* - * Do some basic initialization so that we at least can talk - * to the PHY - */ - if (macb_is_gem(macb)) { - ncfgr = gem_mdc_clk_div(id, macb); - ncfgr |= macb_dbw(macb); - } else { - ncfgr = macb_mdc_clk_div(id, macb); - } - - macb_writel(macb, NCFGR, ncfgr); - - eth_register(netdev); - -#if defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) - miiphy_register(netdev->name, macb_miiphy_read, macb_miiphy_write); - macb->bus = miiphy_get_dev_by_name(netdev->name); -#endif - return 0; -} - -#endif diff --git a/qemu/roms/u-boot/drivers/net/macb.h b/qemu/roms/u-boot/drivers/net/macb.h deleted file mode 100644 index 06f7c66df..000000000 --- a/qemu/roms/u-boot/drivers/net/macb.h +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (C) 2005-2006 Atmel Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#ifndef __DRIVERS_MACB_H__ -#define __DRIVERS_MACB_H__ - -/* MACB register offsets */ -#define MACB_NCR 0x0000 -#define MACB_NCFGR 0x0004 -#define MACB_NSR 0x0008 -#define GEM_UR 0x000c -#define MACB_TSR 0x0014 -#define MACB_RBQP 0x0018 -#define MACB_TBQP 0x001c -#define MACB_RSR 0x0020 -#define MACB_ISR 0x0024 -#define MACB_IER 0x0028 -#define MACB_IDR 0x002c -#define MACB_IMR 0x0030 -#define MACB_MAN 0x0034 -#define MACB_PTR 0x0038 -#define MACB_PFR 0x003c -#define MACB_FTO 0x0040 -#define MACB_SCF 0x0044 -#define MACB_MCF 0x0048 -#define MACB_FRO 0x004c -#define MACB_FCSE 0x0050 -#define MACB_ALE 0x0054 -#define MACB_DTF 0x0058 -#define MACB_LCOL 0x005c -#define MACB_EXCOL 0x0060 -#define MACB_TUND 0x0064 -#define MACB_CSE 0x0068 -#define MACB_RRE 0x006c -#define MACB_ROVR 0x0070 -#define MACB_RSE 0x0074 -#define MACB_ELE 0x0078 -#define MACB_RJA 0x007c -#define MACB_USF 0x0080 -#define MACB_STE 0x0084 -#define MACB_RLE 0x0088 -#define MACB_TPF 0x008c -#define MACB_HRB 0x0090 -#define MACB_HRT 0x0094 -#define MACB_SA1B 0x0098 -#define MACB_SA1T 0x009c -#define MACB_SA2B 0x00a0 -#define MACB_SA2T 0x00a4 -#define MACB_SA3B 0x00a8 -#define MACB_SA3T 0x00ac -#define MACB_SA4B 0x00b0 -#define MACB_SA4T 0x00b4 -#define MACB_TID 0x00b8 -#define MACB_TPQ 0x00bc -#define MACB_USRIO 0x00c0 -#define MACB_WOL 0x00c4 -#define MACB_MID 0x00fc - -/* GEM specific register offsets */ -#define GEM_DCFG1 0x0280 - -/* Bitfields in NCR */ -#define MACB_LB_OFFSET 0 -#define MACB_LB_SIZE 1 -#define MACB_LLB_OFFSET 1 -#define MACB_LLB_SIZE 1 -#define MACB_RE_OFFSET 2 -#define MACB_RE_SIZE 1 -#define MACB_TE_OFFSET 3 -#define MACB_TE_SIZE 1 -#define MACB_MPE_OFFSET 4 -#define MACB_MPE_SIZE 1 -#define MACB_CLRSTAT_OFFSET 5 -#define MACB_CLRSTAT_SIZE 1 -#define MACB_INCSTAT_OFFSET 6 -#define MACB_INCSTAT_SIZE 1 -#define MACB_WESTAT_OFFSET 7 -#define MACB_WESTAT_SIZE 1 -#define MACB_BP_OFFSET 8 -#define MACB_BP_SIZE 1 -#define MACB_TSTART_OFFSET 9 -#define MACB_TSTART_SIZE 1 -#define MACB_THALT_OFFSET 10 -#define MACB_THALT_SIZE 1 -#define MACB_NCR_TPF_OFFSET 11 -#define MACB_NCR_TPF_SIZE 1 -#define MACB_TZQ_OFFSET 12 -#define MACB_TZQ_SIZE 1 - -/* Bitfields in NCFGR */ -#define MACB_SPD_OFFSET 0 -#define MACB_SPD_SIZE 1 -#define MACB_FD_OFFSET 1 -#define MACB_FD_SIZE 1 -#define MACB_BIT_RATE_OFFSET 2 -#define MACB_BIT_RATE_SIZE 1 -#define MACB_JFRAME_OFFSET 3 -#define MACB_JFRAME_SIZE 1 -#define MACB_CAF_OFFSET 4 -#define MACB_CAF_SIZE 1 -#define MACB_NBC_OFFSET 5 -#define MACB_NBC_SIZE 1 -#define MACB_NCFGR_MTI_OFFSET 6 -#define MACB_NCFGR_MTI_SIZE 1 -#define MACB_UNI_OFFSET 7 -#define MACB_UNI_SIZE 1 -#define MACB_BIG_OFFSET 8 -#define MACB_BIG_SIZE 1 -#define MACB_EAE_OFFSET 9 -#define MACB_EAE_SIZE 1 -#define MACB_CLK_OFFSET 10 -#define MACB_CLK_SIZE 2 -#define MACB_RTY_OFFSET 12 -#define MACB_RTY_SIZE 1 -#define MACB_PAE_OFFSET 13 -#define MACB_PAE_SIZE 1 -#define MACB_RBOF_OFFSET 14 -#define MACB_RBOF_SIZE 2 -#define MACB_RLCE_OFFSET 16 -#define MACB_RLCE_SIZE 1 -#define MACB_DRFCS_OFFSET 17 -#define MACB_DRFCS_SIZE 1 -#define MACB_EFRHD_OFFSET 18 -#define MACB_EFRHD_SIZE 1 -#define MACB_IRXFCS_OFFSET 19 -#define MACB_IRXFCS_SIZE 1 - -#define GEM_GBE_OFFSET 10 -#define GEM_GBE_SIZE 1 -#define GEM_CLK_OFFSET 18 -#define GEM_CLK_SIZE 3 -#define GEM_DBW_OFFSET 21 -#define GEM_DBW_SIZE 2 - -/* Bitfields in NSR */ -#define MACB_NSR_LINK_OFFSET 0 -#define MACB_NSR_LINK_SIZE 1 -#define MACB_MDIO_OFFSET 1 -#define MACB_MDIO_SIZE 1 -#define MACB_IDLE_OFFSET 2 -#define MACB_IDLE_SIZE 1 - -/* Bitfields in UR */ -#define GEM_RGMII_OFFSET 0 -#define GEM_RGMII_SIZE 1 - -/* Bitfields in TSR */ -#define MACB_UBR_OFFSET 0 -#define MACB_UBR_SIZE 1 -#define MACB_COL_OFFSET 1 -#define MACB_COL_SIZE 1 -#define MACB_TSR_RLE_OFFSET 2 -#define MACB_TSR_RLE_SIZE 1 -#define MACB_TGO_OFFSET 3 -#define MACB_TGO_SIZE 1 -#define MACB_BEX_OFFSET 4 -#define MACB_BEX_SIZE 1 -#define MACB_COMP_OFFSET 5 -#define MACB_COMP_SIZE 1 -#define MACB_UND_OFFSET 6 -#define MACB_UND_SIZE 1 - -/* Bitfields in RSR */ -#define MACB_BNA_OFFSET 0 -#define MACB_BNA_SIZE 1 -#define MACB_REC_OFFSET 1 -#define MACB_REC_SIZE 1 -#define MACB_OVR_OFFSET 2 -#define MACB_OVR_SIZE 1 - -/* Bitfields in ISR/IER/IDR/IMR */ -#define MACB_MFD_OFFSET 0 -#define MACB_MFD_SIZE 1 -#define MACB_RCOMP_OFFSET 1 -#define MACB_RCOMP_SIZE 1 -#define MACB_RXUBR_OFFSET 2 -#define MACB_RXUBR_SIZE 1 -#define MACB_TXUBR_OFFSET 3 -#define MACB_TXUBR_SIZE 1 -#define MACB_ISR_TUND_OFFSET 4 -#define MACB_ISR_TUND_SIZE 1 -#define MACB_ISR_RLE_OFFSET 5 -#define MACB_ISR_RLE_SIZE 1 -#define MACB_TXERR_OFFSET 6 -#define MACB_TXERR_SIZE 1 -#define MACB_TCOMP_OFFSET 7 -#define MACB_TCOMP_SIZE 1 -#define MACB_ISR_LINK_OFFSET 9 -#define MACB_ISR_LINK_SIZE 1 -#define MACB_ISR_ROVR_OFFSET 10 -#define MACB_ISR_ROVR_SIZE 1 -#define MACB_HRESP_OFFSET 11 -#define MACB_HRESP_SIZE 1 -#define MACB_PFR_OFFSET 12 -#define MACB_PFR_SIZE 1 -#define MACB_PTZ_OFFSET 13 -#define MACB_PTZ_SIZE 1 - -/* Bitfields in MAN */ -#define MACB_DATA_OFFSET 0 -#define MACB_DATA_SIZE 16 -#define MACB_CODE_OFFSET 16 -#define MACB_CODE_SIZE 2 -#define MACB_REGA_OFFSET 18 -#define MACB_REGA_SIZE 5 -#define MACB_PHYA_OFFSET 23 -#define MACB_PHYA_SIZE 5 -#define MACB_RW_OFFSET 28 -#define MACB_RW_SIZE 2 -#define MACB_SOF_OFFSET 30 -#define MACB_SOF_SIZE 2 - -/* Bitfields in USRIO */ -#define MACB_MII_OFFSET 0 -#define MACB_MII_SIZE 1 -#define MACB_EAM_OFFSET 1 -#define MACB_EAM_SIZE 1 -#define MACB_TX_PAUSE_OFFSET 2 -#define MACB_TX_PAUSE_SIZE 1 -#define MACB_TX_PAUSE_ZERO_OFFSET 3 -#define MACB_TX_PAUSE_ZERO_SIZE 1 - -/* Bitfields in USRIO (AT91) */ -#define MACB_RMII_OFFSET 0 -#define MACB_RMII_SIZE 1 -#define MACB_CLKEN_OFFSET 1 -#define MACB_CLKEN_SIZE 1 - -/* Bitfields in WOL */ -#define MACB_IP_OFFSET 0 -#define MACB_IP_SIZE 16 -#define MACB_MAG_OFFSET 16 -#define MACB_MAG_SIZE 1 -#define MACB_ARP_OFFSET 17 -#define MACB_ARP_SIZE 1 -#define MACB_SA1_OFFSET 18 -#define MACB_SA1_SIZE 1 -#define MACB_WOL_MTI_OFFSET 19 -#define MACB_WOL_MTI_SIZE 1 - -/* Bitfields in MID */ -#define MACB_IDNUM_OFFSET 16 -#define MACB_IDNUM_SIZE 16 - -/* Bitfields in DCFG1 */ -#define GEM_DBWDEF_OFFSET 25 -#define GEM_DBWDEF_SIZE 3 - -/* constants for data bus width */ -#define GEM_DBW32 0 -#define GEM_DBW64 1 -#define GEM_DBW128 2 - -/* Constants for CLK */ -#define MACB_CLK_DIV8 0 -#define MACB_CLK_DIV16 1 -#define MACB_CLK_DIV32 2 -#define MACB_CLK_DIV64 3 - -/* GEM specific constants for CLK */ -#define GEM_CLK_DIV8 0 -#define GEM_CLK_DIV16 1 -#define GEM_CLK_DIV32 2 -#define GEM_CLK_DIV48 3 -#define GEM_CLK_DIV64 4 -#define GEM_CLK_DIV96 5 - -/* Constants for MAN register */ -#define MACB_MAN_SOF 1 -#define MACB_MAN_WRITE 1 -#define MACB_MAN_READ 2 -#define MACB_MAN_CODE 2 - -/* Bit manipulation macros */ -#define MACB_BIT(name) \ - (1 << MACB_##name##_OFFSET) -#define MACB_BF(name, value) \ - (((value) & ((1 << MACB_##name##_SIZE) - 1)) \ - << MACB_##name##_OFFSET) -#define MACB_BFEXT(name, value)\ - (((value) >> MACB_##name##_OFFSET) \ - & ((1 << MACB_##name##_SIZE) - 1)) -#define MACB_BFINS(name, value, old) \ - (((old) & ~(((1 << MACB_##name##_SIZE) - 1) \ - << MACB_##name##_OFFSET)) \ - | MACB_BF(name, value)) - -#define GEM_BIT(name) \ - (1 << GEM_##name##_OFFSET) -#define GEM_BF(name, value) \ - (((value) & ((1 << GEM_##name##_SIZE) - 1)) \ - << GEM_##name##_OFFSET) -#define GEM_BFEXT(name, value)\ - (((value) >> GEM_##name##_OFFSET) \ - & ((1 << GEM_##name##_SIZE) - 1)) -#define GEM_BFINS(name, value, old) \ - (((old) & ~(((1 << GEM_##name##_SIZE) - 1) \ - << GEM_##name##_OFFSET)) \ - | GEM_BF(name, value)) - -/* Register access macros */ -#define macb_readl(port, reg) \ - readl((port)->regs + MACB_##reg) -#define macb_writel(port, reg, value) \ - writel((value), (port)->regs + MACB_##reg) -#define gem_readl(port, reg) \ - readl((port)->regs + GEM_##reg) -#define gem_writel(port, reg, value) \ - writel((value), (port)->regs + GEM_##reg) - -#endif /* __DRIVERS_MACB_H__ */ diff --git a/qemu/roms/u-boot/drivers/net/mcffec.c b/qemu/roms/u-boot/drivers/net/mcffec.c deleted file mode 100644 index 7c4b210b0..000000000 --- a/qemu/roms/u-boot/drivers/net/mcffec.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - * (C) Copyright 2000-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2007 Freescale Semiconductor, Inc. - * TsiChung Liew (Tsi-Chung.Liew@freescale.com) - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> - -#include <command.h> -#include <net.h> -#include <netdev.h> -#include <miiphy.h> - -#include <asm/fec.h> -#include <asm/immap.h> - -#undef ET_DEBUG -#undef MII_DEBUG - -/* Ethernet Transmit and Receive Buffers */ -#define DBUF_LENGTH 1520 -#define TX_BUF_CNT 2 -#define PKT_MAXBUF_SIZE 1518 -#define PKT_MINBUF_SIZE 64 -#define PKT_MAXBLR_SIZE 1520 -#define LAST_PKTBUFSRX PKTBUFSRX - 1 -#define BD_ENET_RX_W_E (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY) -#define BD_ENET_TX_RDY_LST (BD_ENET_TX_READY | BD_ENET_TX_LAST) - -DECLARE_GLOBAL_DATA_PTR; - -struct fec_info_s fec_info[] = { -#ifdef CONFIG_SYS_FEC0_IOBASE - { - 0, /* index */ - CONFIG_SYS_FEC0_IOBASE, /* io base */ - CONFIG_SYS_FEC0_PINMUX, /* gpio pin muxing */ - CONFIG_SYS_FEC0_MIIBASE, /* mii base */ - -1, /* phy_addr */ - 0, /* duplex and speed */ - 0, /* phy name */ - 0, /* phyname init */ - 0, /* RX BD */ - 0, /* TX BD */ - 0, /* rx Index */ - 0, /* tx Index */ - 0, /* tx buffer */ - 0, /* initialized flag */ - (struct fec_info_s *)-1, - }, -#endif -#ifdef CONFIG_SYS_FEC1_IOBASE - { - 1, /* index */ - CONFIG_SYS_FEC1_IOBASE, /* io base */ - CONFIG_SYS_FEC1_PINMUX, /* gpio pin muxing */ - CONFIG_SYS_FEC1_MIIBASE, /* mii base */ - -1, /* phy_addr */ - 0, /* duplex and speed */ - 0, /* phy name */ - 0, /* phy name init */ -#ifdef CONFIG_SYS_FEC_BUF_USE_SRAM - (cbd_t *)DBUF_LENGTH, /* RX BD */ -#else - 0, /* RX BD */ -#endif - 0, /* TX BD */ - 0, /* rx Index */ - 0, /* tx Index */ - 0, /* tx buffer */ - 0, /* initialized flag */ - (struct fec_info_s *)-1, - } -#endif -}; - -int fec_recv(struct eth_device *dev); -int fec_init(struct eth_device *dev, bd_t * bd); -void fec_halt(struct eth_device *dev); -void fec_reset(struct eth_device *dev); - -void setFecDuplexSpeed(volatile fec_t * fecp, bd_t * bd, int dup_spd) -{ - if ((dup_spd >> 16) == FULL) { - /* Set maximum frame length */ - fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | FEC_RCR_MII_MODE | - FEC_RCR_PROM | 0x100; - fecp->tcr = FEC_TCR_FDEN; - } else { - /* Half duplex mode */ - fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | - FEC_RCR_MII_MODE | FEC_RCR_DRT; - fecp->tcr &= ~FEC_TCR_FDEN; - } - - if ((dup_spd & 0xFFFF) == _100BASET) { -#ifdef CONFIG_MCF5445x - fecp->rcr &= ~0x200; /* disabled 10T base */ -#endif -#ifdef MII_DEBUG - printf("100Mbps\n"); -#endif - bd->bi_ethspeed = 100; - } else { -#ifdef CONFIG_MCF5445x - fecp->rcr |= 0x200; /* enabled 10T base */ -#endif -#ifdef MII_DEBUG - printf("10Mbps\n"); -#endif - bd->bi_ethspeed = 10; - } -} - -static int fec_send(struct eth_device *dev, void *packet, int length) -{ - struct fec_info_s *info = dev->priv; - volatile fec_t *fecp = (fec_t *) (info->iobase); - int j, rc; - u16 phyStatus; - - miiphy_read(dev->name, info->phy_addr, MII_BMSR, &phyStatus); - - /* section 16.9.23.3 - * Wait for ready - */ - j = 0; - while ((info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_READY) && - (j < MCFFEC_TOUT_LOOP)) { - udelay(1); - j++; - } - if (j >= MCFFEC_TOUT_LOOP) { - printf("TX not ready\n"); - } - - info->txbd[info->txIdx].cbd_bufaddr = (uint) packet; - info->txbd[info->txIdx].cbd_datlen = length; - info->txbd[info->txIdx].cbd_sc |= BD_ENET_TX_RDY_LST; - - /* Activate transmit Buffer Descriptor polling */ - fecp->tdar = 0x01000000; /* Descriptor polling active */ - -#ifndef CONFIG_SYS_FEC_BUF_USE_SRAM - /* - * FEC unable to initial transmit data packet. - * A nop will ensure the descriptor polling active completed. - * CF Internal RAM has shorter cycle access than DRAM. If use - * DRAM as Buffer descriptor and data, a nop is a must. - * Affect only V2 and V3. - */ - __asm__ ("nop"); - -#endif - -#ifdef CONFIG_SYS_UNIFY_CACHE - icache_invalid(); -#endif - - j = 0; - while ((info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_READY) && - (j < MCFFEC_TOUT_LOOP)) { - udelay(1); - j++; - } - if (j >= MCFFEC_TOUT_LOOP) { - printf("TX timeout\n"); - } - -#ifdef ET_DEBUG - printf("%s[%d] %s: cycles: %d status: %x retry cnt: %d\n", - __FILE__, __LINE__, __FUNCTION__, j, - info->txbd[info->txIdx].cbd_sc, - (info->txbd[info->txIdx].cbd_sc & 0x003C) >> 2); -#endif - - /* return only status bits */ - rc = (info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_STATS); - info->txIdx = (info->txIdx + 1) % TX_BUF_CNT; - - return rc; -} - -int fec_recv(struct eth_device *dev) -{ - struct fec_info_s *info = dev->priv; - volatile fec_t *fecp = (fec_t *) (info->iobase); - int length; - - for (;;) { -#ifndef CONFIG_SYS_FEC_BUF_USE_SRAM -#endif -#ifdef CONFIG_SYS_UNIFY_CACHE - icache_invalid(); -#endif - /* section 16.9.23.2 */ - if (info->rxbd[info->rxIdx].cbd_sc & BD_ENET_RX_EMPTY) { - length = -1; - break; /* nothing received - leave for() loop */ - } - - length = info->rxbd[info->rxIdx].cbd_datlen; - - if (info->rxbd[info->rxIdx].cbd_sc & 0x003f) { - printf("%s[%d] err: %x\n", - __FUNCTION__, __LINE__, - info->rxbd[info->rxIdx].cbd_sc); -#ifdef ET_DEBUG - printf("%s[%d] err: %x\n", - __FUNCTION__, __LINE__, - info->rxbd[info->rxIdx].cbd_sc); -#endif - } else { - - length -= 4; - /* Pass the packet up to the protocol layers. */ - NetReceive(NetRxPackets[info->rxIdx], length); - - fecp->eir |= FEC_EIR_RXF; - } - - /* Give the buffer back to the FEC. */ - info->rxbd[info->rxIdx].cbd_datlen = 0; - - /* wrap around buffer index when necessary */ - if (info->rxIdx == LAST_PKTBUFSRX) { - info->rxbd[PKTBUFSRX - 1].cbd_sc = BD_ENET_RX_W_E; - info->rxIdx = 0; - } else { - info->rxbd[info->rxIdx].cbd_sc = BD_ENET_RX_EMPTY; - info->rxIdx++; - } - - /* Try to fill Buffer Descriptors */ - fecp->rdar = 0x01000000; /* Descriptor polling active */ - } - - return length; -} - -#ifdef ET_DEBUG -void dbgFecRegs(struct eth_device *dev) -{ - struct fec_info_s *info = dev->priv; - volatile fec_t *fecp = (fec_t *) (info->iobase); - - printf("=====\n"); - printf("ievent %x - %x\n", (int)&fecp->eir, fecp->eir); - printf("imask %x - %x\n", (int)&fecp->eimr, fecp->eimr); - printf("r_des_active %x - %x\n", (int)&fecp->rdar, fecp->rdar); - printf("x_des_active %x - %x\n", (int)&fecp->tdar, fecp->tdar); - printf("ecntrl %x - %x\n", (int)&fecp->ecr, fecp->ecr); - printf("mii_mframe %x - %x\n", (int)&fecp->mmfr, fecp->mmfr); - printf("mii_speed %x - %x\n", (int)&fecp->mscr, fecp->mscr); - printf("mii_ctrlstat %x - %x\n", (int)&fecp->mibc, fecp->mibc); - printf("r_cntrl %x - %x\n", (int)&fecp->rcr, fecp->rcr); - printf("x_cntrl %x - %x\n", (int)&fecp->tcr, fecp->tcr); - printf("padr_l %x - %x\n", (int)&fecp->palr, fecp->palr); - printf("padr_u %x - %x\n", (int)&fecp->paur, fecp->paur); - printf("op_pause %x - %x\n", (int)&fecp->opd, fecp->opd); - printf("iadr_u %x - %x\n", (int)&fecp->iaur, fecp->iaur); - printf("iadr_l %x - %x\n", (int)&fecp->ialr, fecp->ialr); - printf("gadr_u %x - %x\n", (int)&fecp->gaur, fecp->gaur); - printf("gadr_l %x - %x\n", (int)&fecp->galr, fecp->galr); - printf("x_wmrk %x - %x\n", (int)&fecp->tfwr, fecp->tfwr); - printf("r_bound %x - %x\n", (int)&fecp->frbr, fecp->frbr); - printf("r_fstart %x - %x\n", (int)&fecp->frsr, fecp->frsr); - printf("r_drng %x - %x\n", (int)&fecp->erdsr, fecp->erdsr); - printf("x_drng %x - %x\n", (int)&fecp->etdsr, fecp->etdsr); - printf("r_bufsz %x - %x\n", (int)&fecp->emrbr, fecp->emrbr); - - printf("\n"); - printf("rmon_t_drop %x - %x\n", (int)&fecp->rmon_t_drop, - fecp->rmon_t_drop); - printf("rmon_t_packets %x - %x\n", (int)&fecp->rmon_t_packets, - fecp->rmon_t_packets); - printf("rmon_t_bc_pkt %x - %x\n", (int)&fecp->rmon_t_bc_pkt, - fecp->rmon_t_bc_pkt); - printf("rmon_t_mc_pkt %x - %x\n", (int)&fecp->rmon_t_mc_pkt, - fecp->rmon_t_mc_pkt); - printf("rmon_t_crc_align %x - %x\n", (int)&fecp->rmon_t_crc_align, - fecp->rmon_t_crc_align); - printf("rmon_t_undersize %x - %x\n", (int)&fecp->rmon_t_undersize, - fecp->rmon_t_undersize); - printf("rmon_t_oversize %x - %x\n", (int)&fecp->rmon_t_oversize, - fecp->rmon_t_oversize); - printf("rmon_t_frag %x - %x\n", (int)&fecp->rmon_t_frag, - fecp->rmon_t_frag); - printf("rmon_t_jab %x - %x\n", (int)&fecp->rmon_t_jab, - fecp->rmon_t_jab); - printf("rmon_t_col %x - %x\n", (int)&fecp->rmon_t_col, - fecp->rmon_t_col); - printf("rmon_t_p64 %x - %x\n", (int)&fecp->rmon_t_p64, - fecp->rmon_t_p64); - printf("rmon_t_p65to127 %x - %x\n", (int)&fecp->rmon_t_p65to127, - fecp->rmon_t_p65to127); - printf("rmon_t_p128to255 %x - %x\n", (int)&fecp->rmon_t_p128to255, - fecp->rmon_t_p128to255); - printf("rmon_t_p256to511 %x - %x\n", (int)&fecp->rmon_t_p256to511, - fecp->rmon_t_p256to511); - printf("rmon_t_p512to1023 %x - %x\n", (int)&fecp->rmon_t_p512to1023, - fecp->rmon_t_p512to1023); - printf("rmon_t_p1024to2047 %x - %x\n", (int)&fecp->rmon_t_p1024to2047, - fecp->rmon_t_p1024to2047); - printf("rmon_t_p_gte2048 %x - %x\n", (int)&fecp->rmon_t_p_gte2048, - fecp->rmon_t_p_gte2048); - printf("rmon_t_octets %x - %x\n", (int)&fecp->rmon_t_octets, - fecp->rmon_t_octets); - - printf("\n"); - printf("ieee_t_drop %x - %x\n", (int)&fecp->ieee_t_drop, - fecp->ieee_t_drop); - printf("ieee_t_frame_ok %x - %x\n", (int)&fecp->ieee_t_frame_ok, - fecp->ieee_t_frame_ok); - printf("ieee_t_1col %x - %x\n", (int)&fecp->ieee_t_1col, - fecp->ieee_t_1col); - printf("ieee_t_mcol %x - %x\n", (int)&fecp->ieee_t_mcol, - fecp->ieee_t_mcol); - printf("ieee_t_def %x - %x\n", (int)&fecp->ieee_t_def, - fecp->ieee_t_def); - printf("ieee_t_lcol %x - %x\n", (int)&fecp->ieee_t_lcol, - fecp->ieee_t_lcol); - printf("ieee_t_excol %x - %x\n", (int)&fecp->ieee_t_excol, - fecp->ieee_t_excol); - printf("ieee_t_macerr %x - %x\n", (int)&fecp->ieee_t_macerr, - fecp->ieee_t_macerr); - printf("ieee_t_cserr %x - %x\n", (int)&fecp->ieee_t_cserr, - fecp->ieee_t_cserr); - printf("ieee_t_sqe %x - %x\n", (int)&fecp->ieee_t_sqe, - fecp->ieee_t_sqe); - printf("ieee_t_fdxfc %x - %x\n", (int)&fecp->ieee_t_fdxfc, - fecp->ieee_t_fdxfc); - printf("ieee_t_octets_ok %x - %x\n", (int)&fecp->ieee_t_octets_ok, - fecp->ieee_t_octets_ok); - - printf("\n"); - printf("rmon_r_drop %x - %x\n", (int)&fecp->rmon_r_drop, - fecp->rmon_r_drop); - printf("rmon_r_packets %x - %x\n", (int)&fecp->rmon_r_packets, - fecp->rmon_r_packets); - printf("rmon_r_bc_pkt %x - %x\n", (int)&fecp->rmon_r_bc_pkt, - fecp->rmon_r_bc_pkt); - printf("rmon_r_mc_pkt %x - %x\n", (int)&fecp->rmon_r_mc_pkt, - fecp->rmon_r_mc_pkt); - printf("rmon_r_crc_align %x - %x\n", (int)&fecp->rmon_r_crc_align, - fecp->rmon_r_crc_align); - printf("rmon_r_undersize %x - %x\n", (int)&fecp->rmon_r_undersize, - fecp->rmon_r_undersize); - printf("rmon_r_oversize %x - %x\n", (int)&fecp->rmon_r_oversize, - fecp->rmon_r_oversize); - printf("rmon_r_frag %x - %x\n", (int)&fecp->rmon_r_frag, - fecp->rmon_r_frag); - printf("rmon_r_jab %x - %x\n", (int)&fecp->rmon_r_jab, - fecp->rmon_r_jab); - printf("rmon_r_p64 %x - %x\n", (int)&fecp->rmon_r_p64, - fecp->rmon_r_p64); - printf("rmon_r_p65to127 %x - %x\n", (int)&fecp->rmon_r_p65to127, - fecp->rmon_r_p65to127); - printf("rmon_r_p128to255 %x - %x\n", (int)&fecp->rmon_r_p128to255, - fecp->rmon_r_p128to255); - printf("rmon_r_p256to511 %x - %x\n", (int)&fecp->rmon_r_p256to511, - fecp->rmon_r_p256to511); - printf("rmon_r_p512to1023 %x - %x\n", (int)&fecp->rmon_r_p512to1023, - fecp->rmon_r_p512to1023); - printf("rmon_r_p1024to2047 %x - %x\n", (int)&fecp->rmon_r_p1024to2047, - fecp->rmon_r_p1024to2047); - printf("rmon_r_p_gte2048 %x - %x\n", (int)&fecp->rmon_r_p_gte2048, - fecp->rmon_r_p_gte2048); - printf("rmon_r_octets %x - %x\n", (int)&fecp->rmon_r_octets, - fecp->rmon_r_octets); - - printf("\n"); - printf("ieee_r_drop %x - %x\n", (int)&fecp->ieee_r_drop, - fecp->ieee_r_drop); - printf("ieee_r_frame_ok %x - %x\n", (int)&fecp->ieee_r_frame_ok, - fecp->ieee_r_frame_ok); - printf("ieee_r_crc %x - %x\n", (int)&fecp->ieee_r_crc, - fecp->ieee_r_crc); - printf("ieee_r_align %x - %x\n", (int)&fecp->ieee_r_align, - fecp->ieee_r_align); - printf("ieee_r_macerr %x - %x\n", (int)&fecp->ieee_r_macerr, - fecp->ieee_r_macerr); - printf("ieee_r_fdxfc %x - %x\n", (int)&fecp->ieee_r_fdxfc, - fecp->ieee_r_fdxfc); - printf("ieee_r_octets_ok %x - %x\n", (int)&fecp->ieee_r_octets_ok, - fecp->ieee_r_octets_ok); - - printf("\n\n\n"); -} -#endif - -int fec_init(struct eth_device *dev, bd_t * bd) -{ - struct fec_info_s *info = dev->priv; - volatile fec_t *fecp = (fec_t *) (info->iobase); - int i; - uchar ea[6]; - - fecpin_setclear(dev, 1); - - fec_reset(dev); - -#if defined(CONFIG_CMD_MII) || defined (CONFIG_MII) || \ - defined (CONFIG_SYS_DISCOVER_PHY) - - mii_init(); - - setFecDuplexSpeed(fecp, bd, info->dup_spd); -#else -#ifndef CONFIG_SYS_DISCOVER_PHY - setFecDuplexSpeed(fecp, bd, (FECDUPLEX << 16) | FECSPEED); -#endif /* ifndef CONFIG_SYS_DISCOVER_PHY */ -#endif /* CONFIG_CMD_MII || CONFIG_MII */ - - /* We use strictly polling mode only */ - fecp->eimr = 0; - - /* Clear any pending interrupt */ - fecp->eir = 0xffffffff; - - /* Set station address */ - if ((u32) fecp == CONFIG_SYS_FEC0_IOBASE) { -#ifdef CONFIG_SYS_FEC1_IOBASE - volatile fec_t *fecp1 = (fec_t *) (CONFIG_SYS_FEC1_IOBASE); - eth_getenv_enetaddr("eth1addr", ea); - fecp1->palr = - (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]); - fecp1->paur = (ea[4] << 24) | (ea[5] << 16); -#endif - eth_getenv_enetaddr("ethaddr", ea); - fecp->palr = - (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]); - fecp->paur = (ea[4] << 24) | (ea[5] << 16); - } else { -#ifdef CONFIG_SYS_FEC0_IOBASE - volatile fec_t *fecp0 = (fec_t *) (CONFIG_SYS_FEC0_IOBASE); - eth_getenv_enetaddr("ethaddr", ea); - fecp0->palr = - (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]); - fecp0->paur = (ea[4] << 24) | (ea[5] << 16); -#endif -#ifdef CONFIG_SYS_FEC1_IOBASE - eth_getenv_enetaddr("eth1addr", ea); - fecp->palr = - (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]); - fecp->paur = (ea[4] << 24) | (ea[5] << 16); -#endif - } - - /* Clear unicast address hash table */ - fecp->iaur = 0; - fecp->ialr = 0; - - /* Clear multicast address hash table */ - fecp->gaur = 0; - fecp->galr = 0; - - /* Set maximum receive buffer size. */ - fecp->emrbr = PKT_MAXBLR_SIZE; - - /* - * Setup Buffers and Buffer Desriptors - */ - info->rxIdx = 0; - info->txIdx = 0; - - /* - * Setup Receiver Buffer Descriptors (13.14.24.18) - * Settings: - * Empty, Wrap - */ - for (i = 0; i < PKTBUFSRX; i++) { - info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; - info->rxbd[i].cbd_datlen = 0; /* Reset */ - info->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i]; - } - info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; - - /* - * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19) - * Settings: - * Last, Tx CRC - */ - for (i = 0; i < TX_BUF_CNT; i++) { - info->txbd[i].cbd_sc = BD_ENET_TX_LAST | BD_ENET_TX_TC; - info->txbd[i].cbd_datlen = 0; /* Reset */ - info->txbd[i].cbd_bufaddr = (uint) (&info->txbuf[0]); - } - info->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP; - - /* Set receive and transmit descriptor base */ - fecp->erdsr = (unsigned int)(&info->rxbd[0]); - fecp->etdsr = (unsigned int)(&info->txbd[0]); - - /* Now enable the transmit and receive processing */ - fecp->ecr |= FEC_ECR_ETHER_EN; - - /* And last, try to fill Rx Buffer Descriptors */ - fecp->rdar = 0x01000000; /* Descriptor polling active */ - - return 1; -} - -void fec_reset(struct eth_device *dev) -{ - struct fec_info_s *info = dev->priv; - volatile fec_t *fecp = (fec_t *) (info->iobase); - int i; - - fecp->ecr = FEC_ECR_RESET; - for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) { - udelay(1); - } - if (i == FEC_RESET_DELAY) { - printf("FEC_RESET_DELAY timeout\n"); - } -} - -void fec_halt(struct eth_device *dev) -{ - struct fec_info_s *info = dev->priv; - - fec_reset(dev); - - fecpin_setclear(dev, 0); - - info->rxIdx = info->txIdx = 0; - memset(info->rxbd, 0, PKTBUFSRX * sizeof(cbd_t)); - memset(info->txbd, 0, TX_BUF_CNT * sizeof(cbd_t)); - memset(info->txbuf, 0, DBUF_LENGTH); -} - -int mcffec_initialize(bd_t * bis) -{ - struct eth_device *dev; - int i; -#ifdef CONFIG_SYS_FEC_BUF_USE_SRAM - u32 tmp = CONFIG_SYS_INIT_RAM_ADDR + 0x1000; -#endif - - for (i = 0; i < ARRAY_SIZE(fec_info); i++) { - - dev = - (struct eth_device *)memalign(CONFIG_SYS_CACHELINE_SIZE, - sizeof *dev); - if (dev == NULL) - hang(); - - memset(dev, 0, sizeof(*dev)); - - sprintf(dev->name, "FEC%d", fec_info[i].index); - - dev->priv = &fec_info[i]; - dev->init = fec_init; - dev->halt = fec_halt; - dev->send = fec_send; - dev->recv = fec_recv; - - /* setup Receive and Transmit buffer descriptor */ -#ifdef CONFIG_SYS_FEC_BUF_USE_SRAM - fec_info[i].rxbd = (cbd_t *)((u32)fec_info[i].rxbd + tmp); - tmp = (u32)fec_info[i].rxbd; - fec_info[i].txbd = - (cbd_t *)((u32)fec_info[i].txbd + tmp + - (PKTBUFSRX * sizeof(cbd_t))); - tmp = (u32)fec_info[i].txbd; - fec_info[i].txbuf = - (char *)((u32)fec_info[i].txbuf + tmp + - (CONFIG_SYS_TX_ETH_BUFFER * sizeof(cbd_t))); - tmp = (u32)fec_info[i].txbuf; -#else - fec_info[i].rxbd = - (cbd_t *) memalign(CONFIG_SYS_CACHELINE_SIZE, - (PKTBUFSRX * sizeof(cbd_t))); - fec_info[i].txbd = - (cbd_t *) memalign(CONFIG_SYS_CACHELINE_SIZE, - (TX_BUF_CNT * sizeof(cbd_t))); - fec_info[i].txbuf = - (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, DBUF_LENGTH); -#endif - -#ifdef ET_DEBUG - printf("rxbd %x txbd %x\n", - (int)fec_info[i].rxbd, (int)fec_info[i].txbd); -#endif - - fec_info[i].phy_name = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, 32); - - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - miiphy_register(dev->name, - mcffec_miiphy_read, mcffec_miiphy_write); -#endif - if (i > 0) - fec_info[i - 1].next = &fec_info[i]; - } - fec_info[i - 1].next = &fec_info[0]; - - /* default speed */ - bis->bi_ethspeed = 10; - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/mcfmii.c b/qemu/roms/u-boot/drivers/net/mcfmii.c deleted file mode 100644 index 17a780c85..000000000 --- a/qemu/roms/u-boot/drivers/net/mcfmii.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (C) 2004-2008 Freescale Semiconductor, Inc. - * TsiChung Liew (Tsi-Chung.Liew@freescale.com) - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <config.h> -#include <net.h> -#include <netdev.h> - -#ifdef CONFIG_MCF547x_8x -#include <asm/fsl_mcdmafec.h> -#else -#include <asm/fec.h> -#endif -#include <asm/immap.h> - -DECLARE_GLOBAL_DATA_PTR; - -#if defined(CONFIG_CMD_NET) -#undef MII_DEBUG -#undef ET_DEBUG - -/*extern int fecpin_setclear(struct eth_device *dev, int setclear);*/ - -#if defined(CONFIG_SYS_DISCOVER_PHY) || defined(CONFIG_CMD_MII) -#include <miiphy.h> - -/* Make MII read/write commands for the FEC. */ -#define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | \ - (REG & 0x1f) << 18)) -#define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | \ - (REG & 0x1f) << 18) | (VAL & 0xffff)) - -#ifndef CONFIG_SYS_UNSPEC_PHYID -# define CONFIG_SYS_UNSPEC_PHYID 0 -#endif -#ifndef CONFIG_SYS_UNSPEC_STRID -# define CONFIG_SYS_UNSPEC_STRID 0 -#endif - -#ifdef CONFIG_MCF547x_8x -typedef struct fec_info_dma FEC_INFO_T; -#define FEC_T fecdma_t -#else -typedef struct fec_info_s FEC_INFO_T; -#define FEC_T fec_t -#endif - -typedef struct phy_info_struct { - u32 phyid; - char *strid; -} phy_info_t; - -phy_info_t phyinfo[] = { - {0x0022561B, "AMD79C784VC"}, /* AMD 79C784VC */ - {0x00406322, "BCM5222"}, /* Broadcom 5222 */ - {0x02a80150, "Intel82555"}, /* Intel 82555 */ - {0x0016f870, "LSI80225"}, /* LSI 80225 */ - {0x0016f880, "LSI80225/B"}, /* LSI 80225/B */ - {0x78100000, "LXT970"}, /* LXT970 */ - {0x001378e0, "LXT971"}, /* LXT971 and 972 */ - {0x00221619, "KS8721BL"}, /* Micrel KS8721BL/SL */ - {0x00221512, "KSZ8041NL"}, /* Micrel KSZ8041NL */ - {0x20005CE1, "N83640"}, /* National 83640 */ - {0x20005C90, "N83848"}, /* National 83848 */ - {0x20005CA2, "N83849"}, /* National 83849 */ - {0x01814400, "QS6612"}, /* QS6612 */ -#if defined(CONFIG_SYS_UNSPEC_PHYID) && defined(CONFIG_SYS_UNSPEC_STRID) - {CONFIG_SYS_UNSPEC_PHYID, CONFIG_SYS_UNSPEC_STRID}, -#endif - {0, 0} -}; - -/* - * mii_init -- Initialize the MII for MII command without ethernet - * This function is a subset of eth_init - */ -void mii_reset(FEC_INFO_T *info) -{ - volatile FEC_T *fecp = (FEC_T *) (info->miibase); - int i; - - fecp->ecr = FEC_ECR_RESET; - - for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) { - udelay(1); - } - if (i == FEC_RESET_DELAY) - printf("FEC_RESET_DELAY timeout\n"); -} - -/* send command to phy using mii, wait for result */ -uint mii_send(uint mii_cmd) -{ - FEC_INFO_T *info; - volatile FEC_T *ep; - struct eth_device *dev; - uint mii_reply; - int j = 0; - - /* retrieve from register structure */ - dev = eth_get_dev(); - info = dev->priv; - - ep = (FEC_T *) info->miibase; - - ep->mmfr = mii_cmd; /* command to phy */ - - /* wait for mii complete */ - while (!(ep->eir & FEC_EIR_MII) && (j < MCFFEC_TOUT_LOOP)) { - udelay(1); - j++; - } - if (j >= MCFFEC_TOUT_LOOP) { - printf("MII not complete\n"); - return -1; - } - - mii_reply = ep->mmfr; /* result from phy */ - ep->eir = FEC_EIR_MII; /* clear MII complete */ -#ifdef ET_DEBUG - printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n", - __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply); -#endif - - return (mii_reply & 0xffff); /* data read from phy */ -} -#endif /* CONFIG_SYS_DISCOVER_PHY || (CONFIG_MII) */ - -#if defined(CONFIG_SYS_DISCOVER_PHY) -int mii_discover_phy(struct eth_device *dev) -{ -#define MAX_PHY_PASSES 11 - FEC_INFO_T *info = dev->priv; - int phyaddr, pass; - uint phyno, phytype; - int i, found = 0; - - if (info->phyname_init) - return info->phy_addr; - - phyaddr = -1; /* didn't find a PHY yet */ - for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) { - if (pass > 1) { - /* PHY may need more time to recover from reset. - * The LXT970 needs 50ms typical, no maximum is - * specified, so wait 10ms before try again. - * With 11 passes this gives it 100ms to wake up. - */ - udelay(10000); /* wait 10ms */ - } - - for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) { - - phytype = mii_send(mk_mii_read(phyno, MII_PHYSID1)); -#ifdef ET_DEBUG - printf("PHY type 0x%x pass %d type\n", phytype, pass); -#endif - if (phytype == 0xffff) - continue; - phyaddr = phyno; - phytype <<= 16; - phytype |= - mii_send(mk_mii_read(phyno, MII_PHYSID2)); - -#ifdef ET_DEBUG - printf("PHY @ 0x%x pass %d\n", phyno, pass); -#endif - - for (i = 0; (i < ARRAY_SIZE(phyinfo)) - && (phyinfo[i].phyid != 0); i++) { - if (phyinfo[i].phyid == phytype) { -#ifdef ET_DEBUG - printf("phyid %x - %s\n", - phyinfo[i].phyid, - phyinfo[i].strid); -#endif - strcpy(info->phy_name, phyinfo[i].strid); - info->phyname_init = 1; - found = 1; - break; - } - } - - if (!found) { -#ifdef ET_DEBUG - printf("0x%08x\n", phytype); -#endif - strcpy(info->phy_name, "unknown"); - info->phyname_init = 1; - break; - } - } - } - - if (phyaddr < 0) - printf("No PHY device found.\n"); - - return phyaddr; -} -#endif /* CONFIG_SYS_DISCOVER_PHY */ - -void mii_init(void) __attribute__((weak,alias("__mii_init"))); - -void __mii_init(void) -{ - FEC_INFO_T *info; - volatile FEC_T *fecp; - struct eth_device *dev; - int miispd = 0, i = 0; - u16 status = 0; - u16 linkgood = 0; - - /* retrieve from register structure */ - dev = eth_get_dev(); - info = dev->priv; - - fecp = (FEC_T *) info->miibase; - - fecpin_setclear(dev, 1); - - mii_reset(info); - - /* We use strictly polling mode only */ - fecp->eimr = 0; - - /* Clear any pending interrupt */ - fecp->eir = 0xffffffff; - - /* Set MII speed */ - miispd = (gd->bus_clk / 1000000) / 5; - fecp->mscr = miispd << 1; - - info->phy_addr = mii_discover_phy(dev); - - while (i < MCFFEC_TOUT_LOOP) { - status = 0; - i++; - /* Read PHY control register */ - miiphy_read(dev->name, info->phy_addr, MII_BMCR, &status); - - /* If phy set to autonegotiate, wait for autonegotiation done, - * if phy is not autonegotiating, just wait for link up. - */ - if ((status & BMCR_ANENABLE) == BMCR_ANENABLE) { - linkgood = (BMSR_ANEGCOMPLETE | BMSR_LSTATUS); - } else { - linkgood = BMSR_LSTATUS; - } - /* Read PHY status register */ - miiphy_read(dev->name, info->phy_addr, MII_BMSR, &status); - if ((status & linkgood) == linkgood) - break; - - udelay(1); - } - if (i >= MCFFEC_TOUT_LOOP) { - printf("Link UP timeout\n"); - } - - /* adapt to the duplex and speed settings of the phy */ - info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16; - info->dup_spd |= miiphy_speed(dev->name, info->phy_addr); -} - -/* - * Read and write a MII PHY register, routines used by MII Utilities - * - * FIXME: These routines are expected to return 0 on success, but mii_send - * does _not_ return an error code. Maybe 0xFFFF means error, i.e. - * no PHY connected... - * For now always return 0. - * FIXME: These routines only work after calling eth_init() at least once! - * Otherwise they hang in mii_send() !!! Sorry! - */ - -int mcffec_miiphy_read(const char *devname, unsigned char addr, unsigned char reg, - unsigned short *value) -{ - short rdreg; /* register working value */ - -#ifdef MII_DEBUG - printf("miiphy_read(0x%x) @ 0x%x = ", reg, addr); -#endif - rdreg = mii_send(mk_mii_read(addr, reg)); - - *value = rdreg; - -#ifdef MII_DEBUG - printf("0x%04x\n", *value); -#endif - - return 0; -} - -int mcffec_miiphy_write(const char *devname, unsigned char addr, unsigned char reg, - unsigned short value) -{ -#ifdef MII_DEBUG - printf("miiphy_write(0x%x) @ 0x%x = ", reg, addr); -#endif - - mii_send(mk_mii_write(addr, reg, value)); - -#ifdef MII_DEBUG - printf("0x%04x\n", value); -#endif - - return 0; -} - -#endif /* CONFIG_CMD_NET */ diff --git a/qemu/roms/u-boot/drivers/net/mpc512x_fec.c b/qemu/roms/u-boot/drivers/net/mpc512x_fec.c deleted file mode 100644 index 427e0b8b4..000000000 --- a/qemu/roms/u-boot/drivers/net/mpc512x_fec.c +++ /dev/null @@ -1,754 +0,0 @@ -/* - * (C) Copyright 2003-2010 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * Derived from the MPC8xx FEC driver. - * Adapted for MPC512x by Grzegorz Bernacki <gjb@semihalf.com> - */ - -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <miiphy.h> -#include <asm/io.h> -#include "mpc512x_fec.h" - -DECLARE_GLOBAL_DATA_PTR; - -#define DEBUG 0 - -#if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) -#error "CONFIG_MII has to be defined!" -#endif - -int fec512x_miiphy_read(const char *devname, u8 phyAddr, u8 regAddr, u16 * retVal); -int fec512x_miiphy_write(const char *devname, u8 phyAddr, u8 regAddr, u16 data); -int mpc512x_fec_init_phy(struct eth_device *dev, bd_t * bis); - -static uchar rx_buff[FEC_BUFFER_SIZE]; -static int rx_buff_idx = 0; - -/********************************************************************/ -#if (DEBUG & 0x2) -static void mpc512x_fec_phydump (char *devname) -{ - u16 phyStatus, i; - u8 phyAddr = CONFIG_PHY_ADDR; - u8 reg_mask[] = { - /* regs to print: 0...8, 21,27,31 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, - }; - - for (i = 0; i < 32; i++) { - if (reg_mask[i]) { - miiphy_read (devname, phyAddr, i, &phyStatus); - printf ("Mii reg %d: 0x%04x\n", i, phyStatus); - } - } -} -#endif - -/********************************************************************/ -static int mpc512x_fec_bd_init (mpc512x_fec_priv *fec) -{ - int ix; - - /* - * Receive BDs init - */ - for (ix = 0; ix < FEC_RBD_NUM; ix++) { - fec->bdBase->rbd[ix].dataPointer = - (u32)&fec->bdBase->recv_frames[ix]; - fec->bdBase->rbd[ix].status = FEC_RBD_EMPTY; - fec->bdBase->rbd[ix].dataLength = 0; - } - - /* - * have the last RBD to close the ring - */ - fec->bdBase->rbd[ix - 1].status |= FEC_RBD_WRAP; - fec->rbdIndex = 0; - - /* - * Trasmit BDs init - */ - for (ix = 0; ix < FEC_TBD_NUM; ix++) { - fec->bdBase->tbd[ix].status = 0; - } - - /* - * Have the last TBD to close the ring - */ - fec->bdBase->tbd[ix - 1].status |= FEC_TBD_WRAP; - - /* - * Initialize some indices - */ - fec->tbdIndex = 0; - fec->usedTbdIndex = 0; - fec->cleanTbdNum = FEC_TBD_NUM; - - return 0; -} - -/********************************************************************/ -static void mpc512x_fec_rbd_clean (mpc512x_fec_priv *fec, volatile FEC_RBD * pRbd) -{ - /* - * Reset buffer descriptor as empty - */ - if ((fec->rbdIndex) == (FEC_RBD_NUM - 1)) - pRbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY); - else - pRbd->status = FEC_RBD_EMPTY; - - pRbd->dataLength = 0; - - /* - * Increment BD count - */ - fec->rbdIndex = (fec->rbdIndex + 1) % FEC_RBD_NUM; - - /* - * Now, we have an empty RxBD, notify FEC - * Set Descriptor polling active - */ - out_be32(&fec->eth->r_des_active, 0x01000000); -} - -/********************************************************************/ -static void mpc512x_fec_tbd_scrub (mpc512x_fec_priv *fec) -{ - volatile FEC_TBD *pUsedTbd; - -#if (DEBUG & 0x1) - printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n", - fec->cleanTbdNum, fec->usedTbdIndex); -#endif - - /* - * process all the consumed TBDs - */ - while (fec->cleanTbdNum < FEC_TBD_NUM) { - pUsedTbd = &fec->bdBase->tbd[fec->usedTbdIndex]; - if (pUsedTbd->status & FEC_TBD_READY) { -#if (DEBUG & 0x20) - printf ("Cannot clean TBD %d, in use\n", fec->usedTbdIndex); -#endif - return; - } - - /* - * clean this buffer descriptor - */ - if (fec->usedTbdIndex == (FEC_TBD_NUM - 1)) - pUsedTbd->status = FEC_TBD_WRAP; - else - pUsedTbd->status = 0; - - /* - * update some indeces for a correct handling of the TBD ring - */ - fec->cleanTbdNum++; - fec->usedTbdIndex = (fec->usedTbdIndex + 1) % FEC_TBD_NUM; - } -} - -/********************************************************************/ -static void mpc512x_fec_set_hwaddr (mpc512x_fec_priv *fec, unsigned char *mac) -{ - u8 currByte; /* byte for which to compute the CRC */ - int byte; /* loop - counter */ - int bit; /* loop - counter */ - u32 crc = 0xffffffff; /* initial value */ - - /* - * The algorithm used is the following: - * we loop on each of the six bytes of the provided address, - * and we compute the CRC by left-shifting the previous - * value by one position, so that each bit in the current - * byte of the address may contribute the calculation. If - * the latter and the MSB in the CRC are different, then - * the CRC value so computed is also ex-ored with the - * "polynomium generator". The current byte of the address - * is also shifted right by one bit at each iteration. - * This is because the CRC generatore in hardware is implemented - * as a shift-register with as many ex-ores as the radixes - * in the polynomium. This suggests that we represent the - * polynomiumm itself as a 32-bit constant. - */ - for (byte = 0; byte < 6; byte++) { - currByte = mac[byte]; - for (bit = 0; bit < 8; bit++) { - if ((currByte & 0x01) ^ (crc & 0x01)) { - crc >>= 1; - crc = crc ^ 0xedb88320; - } else { - crc >>= 1; - } - currByte >>= 1; - } - } - - crc = crc >> 26; - - /* - * Set individual hash table register - */ - if (crc >= 32) { - out_be32(&fec->eth->iaddr1, (1 << (crc - 32))); - out_be32(&fec->eth->iaddr2, 0); - } else { - out_be32(&fec->eth->iaddr1, 0); - out_be32(&fec->eth->iaddr2, (1 << crc)); - } - - /* - * Set physical address - */ - out_be32(&fec->eth->paddr1, (mac[0] << 24) + (mac[1] << 16) + - (mac[2] << 8) + mac[3]); - out_be32(&fec->eth->paddr2, (mac[4] << 24) + (mac[5] << 16) + - 0x8808); -} - -/********************************************************************/ -static int mpc512x_fec_init (struct eth_device *dev, bd_t * bis) -{ - mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; - -#if (DEBUG & 0x1) - printf ("mpc512x_fec_init... Begin\n"); -#endif - - mpc512x_fec_set_hwaddr (fec, dev->enetaddr); - out_be32(&fec->eth->gaddr1, 0x00000000); - out_be32(&fec->eth->gaddr2, 0x00000000); - - mpc512x_fec_init_phy (dev, bis); - - /* Set interrupt mask register */ - out_be32(&fec->eth->imask, 0x00000000); - - /* Clear FEC-Lite interrupt event register(IEVENT) */ - out_be32(&fec->eth->ievent, 0xffffffff); - - /* Set transmit fifo watermark register(X_WMRK), default = 64 */ - out_be32(&fec->eth->x_wmrk, 0x0); - - /* Set Opcode/Pause Duration Register */ - out_be32(&fec->eth->op_pause, 0x00010020); - - /* Frame length=1522; MII mode */ - out_be32(&fec->eth->r_cntrl, (FEC_MAX_FRAME_LEN << 16) | 0x24); - - /* Half-duplex, heartbeat disabled */ - out_be32(&fec->eth->x_cntrl, 0x00000000); - - /* Enable MIB counters */ - out_be32(&fec->eth->mib_control, 0x0); - - /* Setup recv fifo start and buff size */ - out_be32(&fec->eth->r_fstart, 0x500); - out_be32(&fec->eth->r_buff_size, FEC_BUFFER_SIZE); - - /* Setup BD base addresses */ - out_be32(&fec->eth->r_des_start, (u32)fec->bdBase->rbd); - out_be32(&fec->eth->x_des_start, (u32)fec->bdBase->tbd); - - /* DMA Control */ - out_be32(&fec->eth->dma_control, 0xc0000000); - - /* Enable FEC */ - setbits_be32(&fec->eth->ecntrl, 0x00000006); - - /* Initilize addresses and status words of BDs */ - mpc512x_fec_bd_init (fec); - - /* Descriptor polling active */ - out_be32(&fec->eth->r_des_active, 0x01000000); - -#if (DEBUG & 0x1) - printf("mpc512x_fec_init... Done \n"); -#endif - return 1; -} - -/********************************************************************/ -int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis) -{ - mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; - const u8 phyAddr = CONFIG_PHY_ADDR; /* Only one PHY */ - int timeout = 1; - u16 phyStatus; - -#if (DEBUG & 0x1) - printf ("mpc512x_fec_init_phy... Begin\n"); -#endif - - /* - * Clear FEC-Lite interrupt event register(IEVENT) - */ - out_be32(&fec->eth->ievent, 0xffffffff); - - /* - * Set interrupt mask register - */ - out_be32(&fec->eth->imask, 0x00000000); - - if (fec->xcv_type != SEVENWIRE) { - /* - * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock - * and do not drop the Preamble. - */ - out_be32(&fec->eth->mii_speed, - (((gd->arch.ips_clk / 1000000) / 5) + 1) << 1); - - /* - * Reset PHY, then delay 300ns - */ - miiphy_write (dev->name, phyAddr, 0x0, 0x8000); - udelay (1000); - - if (fec->xcv_type == MII10) { - /* - * Force 10Base-T, FDX operation - */ -#if (DEBUG & 0x2) - printf ("Forcing 10 Mbps ethernet link... "); -#endif - miiphy_read (dev->name, phyAddr, 0x1, &phyStatus); - - miiphy_write (dev->name, phyAddr, 0x0, 0x0180); - - timeout = 20; - do { /* wait for link status to go down */ - udelay (10000); - if ((timeout--) == 0) { -#if (DEBUG & 0x2) - printf ("hmmm, should not have waited..."); -#endif - break; - } - miiphy_read (dev->name, phyAddr, 0x1, &phyStatus); -#if (DEBUG & 0x2) - printf ("="); -#endif - } while ((phyStatus & 0x0004)); /* !link up */ - - timeout = 1000; - do { /* wait for link status to come back up */ - udelay (10000); - if ((timeout--) == 0) { - printf ("failed. Link is down.\n"); - break; - } - miiphy_read (dev->name, phyAddr, 0x1, &phyStatus); -#if (DEBUG & 0x2) - printf ("+"); -#endif - } while (!(phyStatus & 0x0004)); /* !link up */ - -#if (DEBUG & 0x2) - printf ("done.\n"); -#endif - } else { /* MII100 */ - /* - * Set the auto-negotiation advertisement register bits - */ - miiphy_write (dev->name, phyAddr, 0x4, 0x01e1); - - /* - * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation - */ - miiphy_write (dev->name, phyAddr, 0x0, 0x1200); - - /* - * Wait for AN completion - */ - timeout = 2500; - do { - udelay (1000); - - if ((timeout--) == 0) { -#if (DEBUG & 0x2) - printf ("PHY auto neg 0 failed...\n"); -#endif - return -1; - } - - if (miiphy_read (dev->name, phyAddr, 0x1, &phyStatus) != 0) { -#if (DEBUG & 0x2) - printf ("PHY auto neg 1 failed 0x%04x...\n", phyStatus); -#endif - return -1; - } - } while (!(phyStatus & 0x0004)); - -#if (DEBUG & 0x2) - printf ("PHY auto neg complete! \n"); -#endif - } - } - -#if (DEBUG & 0x2) - if (fec->xcv_type != SEVENWIRE) - mpc512x_fec_phydump (dev->name); -#endif - -#if (DEBUG & 0x1) - printf ("mpc512x_fec_init_phy... Done \n"); -#endif - return 1; -} - -/********************************************************************/ -static void mpc512x_fec_halt (struct eth_device *dev) -{ - mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; - int counter = 0xffff; - -#if (DEBUG & 0x2) - if (fec->xcv_type != SEVENWIRE) - mpc512x_fec_phydump (dev->name); -#endif - - /* - * mask FEC chip interrupts - */ - out_be32(&fec->eth->imask, 0); - - /* - * issue graceful stop command to the FEC transmitter if necessary - */ - setbits_be32(&fec->eth->x_cntrl, 0x00000001); - - /* - * wait for graceful stop to register - */ - while ((counter--) && (!(in_be32(&fec->eth->ievent) & 0x10000000))) - ; - - /* - * Disable the Ethernet Controller - */ - clrbits_be32(&fec->eth->ecntrl, 0x00000002); - - /* - * Issue a reset command to the FEC chip - */ - setbits_be32(&fec->eth->ecntrl, 0x1); - - /* - * wait at least 16 clock cycles - */ - udelay (10); -#if (DEBUG & 0x3) - printf ("Ethernet task stopped\n"); -#endif -} - -/********************************************************************/ - -static int mpc512x_fec_send(struct eth_device *dev, void *eth_data, - int data_length) -{ - /* - * This routine transmits one frame. This routine only accepts - * 6-byte Ethernet addresses. - */ - mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; - volatile FEC_TBD *pTbd; - -#if (DEBUG & 0x20) - printf("tbd status: 0x%04x\n", fec->tbdBase[fec->tbdIndex].status); -#endif - - /* - * Clear Tx BD ring at first - */ - mpc512x_fec_tbd_scrub (fec); - - /* - * Check for valid length of data. - */ - if ((data_length > 1500) || (data_length <= 0)) { - return -1; - } - - /* - * Check the number of vacant TxBDs. - */ - if (fec->cleanTbdNum < 1) { -#if (DEBUG & 0x20) - printf ("No available TxBDs ...\n"); -#endif - return -1; - } - - /* - * Get the first TxBD to send the mac header - */ - pTbd = &fec->bdBase->tbd[fec->tbdIndex]; - pTbd->dataLength = data_length; - pTbd->dataPointer = (u32)eth_data; - pTbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY; - fec->tbdIndex = (fec->tbdIndex + 1) % FEC_TBD_NUM; - - /* Activate transmit Buffer Descriptor polling */ - out_be32(&fec->eth->x_des_active, 0x01000000); - -#if (DEBUG & 0x8) - printf ( "+" ); -#endif - - fec->cleanTbdNum -= 1; - - /* - * wait until frame is sent . - */ - while (pTbd->status & FEC_TBD_READY) { - udelay (10); -#if (DEBUG & 0x8) - printf ("TDB status = %04x\n", pTbd->status); -#endif - } - - return 0; -} - - -/********************************************************************/ -static int mpc512x_fec_recv (struct eth_device *dev) -{ - /* - * This command pulls one frame from the card - */ - mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; - volatile FEC_RBD *pRbd = &fec->bdBase->rbd[fec->rbdIndex]; - unsigned long ievent; - int frame_length = 0; - -#if (DEBUG & 0x1) - printf ("mpc512x_fec_recv %d Start...\n", fec->rbdIndex); -#endif -#if (DEBUG & 0x8) - printf( "-" ); -#endif - - /* - * Check if any critical events have happened - */ - ievent = in_be32(&fec->eth->ievent); - out_be32(&fec->eth->ievent, ievent); - if (ievent & 0x20060000) { - /* BABT, Rx/Tx FIFO errors */ - mpc512x_fec_halt (dev); - mpc512x_fec_init (dev, NULL); - return 0; - } - if (ievent & 0x80000000) { - /* Heartbeat error */ - setbits_be32(&fec->eth->x_cntrl, 0x00000001); - } - if (ievent & 0x10000000) { - /* Graceful stop complete */ - if (in_be32(&fec->eth->x_cntrl) & 0x00000001) { - mpc512x_fec_halt (dev); - clrbits_be32(&fec->eth->x_cntrl, 0x00000001);; - mpc512x_fec_init (dev, NULL); - } - } - - if (!(pRbd->status & FEC_RBD_EMPTY)) { - if (!(pRbd->status & FEC_RBD_ERR) && - ((pRbd->dataLength - 4) > 14)) { - - /* - * Get buffer size - */ - if (pRbd->status & FEC_RBD_LAST) - frame_length = pRbd->dataLength - 4; - else - frame_length = pRbd->dataLength; -#if (DEBUG & 0x20) - { - int i; - printf ("recv data length 0x%08x data hdr: ", - pRbd->dataLength); - for (i = 0; i < 14; i++) - printf ("%x ", *((u8*)pRbd->dataPointer + i)); - printf("\n"); - } -#endif - /* - * Fill the buffer and pass it to upper layers - */ - memcpy (&rx_buff[rx_buff_idx], (void*)pRbd->dataPointer, - frame_length - rx_buff_idx); - rx_buff_idx = frame_length; - - if (pRbd->status & FEC_RBD_LAST) { - NetReceive ((uchar*)rx_buff, frame_length); - rx_buff_idx = 0; - } - } - - /* - * Reset buffer descriptor as empty - */ - mpc512x_fec_rbd_clean (fec, pRbd); - } - - /* Try to fill Buffer Descriptors */ - out_be32(&fec->eth->r_des_active, 0x01000000); - - return frame_length; -} - -/********************************************************************/ -int mpc512x_fec_initialize (bd_t * bis) -{ - volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; - mpc512x_fec_priv *fec; - struct eth_device *dev; - void * bd; - - fec = (mpc512x_fec_priv *) malloc (sizeof(*fec)); - dev = (struct eth_device *) malloc (sizeof(*dev)); - memset (dev, 0, sizeof *dev); - - fec->eth = &im->fec; - -# ifndef CONFIG_FEC_10MBIT - fec->xcv_type = MII100; -# else - fec->xcv_type = MII10; -# endif - dev->priv = (void *)fec; - dev->iobase = (int)&im->fec; - dev->init = mpc512x_fec_init; - dev->halt = mpc512x_fec_halt; - dev->send = mpc512x_fec_send; - dev->recv = mpc512x_fec_recv; - - sprintf (dev->name, "FEC"); - eth_register (dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - miiphy_register (dev->name, - fec512x_miiphy_read, fec512x_miiphy_write); -#endif - - /* Clean up space FEC's MIB and FIFO RAM ...*/ - memset ((void *)&im->fec.mib, 0x00, sizeof(im->fec.mib)); - memset ((void *)&im->fec.fifo, 0x00, sizeof(im->fec.fifo)); - - /* - * Malloc space for BDs (must be quad word-aligned) - * this pointer is lost, so cannot be freed - */ - bd = malloc (sizeof(mpc512x_buff_descs) + 0x1f); - fec->bdBase = (mpc512x_buff_descs*)((u32)bd & 0xfffffff0); - memset ((void *) bd, 0x00, sizeof(mpc512x_buff_descs) + 0x1f); - - /* - * Set interrupt mask register - */ - out_be32(&fec->eth->imask, 0x00000000); - - /* - * Clear FEC-Lite interrupt event register(IEVENT) - */ - out_be32(&fec->eth->ievent, 0xffffffff); - - return 1; -} - -/* MII-interface related functions */ -/********************************************************************/ -int fec512x_miiphy_read(const char *devname, u8 phyAddr, u8 regAddr, u16 *retVal) -{ - volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; - volatile fec512x_t *eth = &im->fec; - u32 reg; /* convenient holder for the PHY register */ - u32 phy; /* convenient holder for the PHY */ - int timeout = 0xffff; - - /* - * reading from any PHY's register is done by properly - * programming the FEC's MII data register. - */ - reg = regAddr << FEC_MII_DATA_RA_SHIFT; - phy = phyAddr << FEC_MII_DATA_PA_SHIFT; - - out_be32(ð->mii_data, FEC_MII_DATA_ST | - FEC_MII_DATA_OP_RD | - FEC_MII_DATA_TA | - phy | reg); - - /* - * wait for the related interrupt - */ - while ((timeout--) && (!(in_be32(ð->ievent) & 0x00800000))) - ; - - if (timeout == 0) { -#if (DEBUG & 0x2) - printf ("Read MDIO failed...\n"); -#endif - return -1; - } - - /* - * clear mii interrupt bit - */ - out_be32(ð->ievent, 0x00800000); - - /* - * it's now safe to read the PHY's register - */ - *retVal = (u16) in_be32(ð->mii_data); - - return 0; -} - -/********************************************************************/ -int fec512x_miiphy_write(const char *devname, u8 phyAddr, u8 regAddr, u16 data) -{ - volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; - volatile fec512x_t *eth = &im->fec; - u32 reg; /* convenient holder for the PHY register */ - u32 phy; /* convenient holder for the PHY */ - int timeout = 0xffff; - - reg = regAddr << FEC_MII_DATA_RA_SHIFT; - phy = phyAddr << FEC_MII_DATA_PA_SHIFT; - - out_be32(ð->mii_data, FEC_MII_DATA_ST | - FEC_MII_DATA_OP_WR | - FEC_MII_DATA_TA | - phy | reg | data); - - /* - * wait for the MII interrupt - */ - while ((timeout--) && (!(in_be32(ð->ievent) & 0x00800000))) - ; - - if (timeout == 0) { -#if (DEBUG & 0x2) - printf ("Write MDIO failed...\n"); -#endif - return -1; - } - - /* - * clear MII interrupt bit - */ - out_be32(ð->ievent, 0x00800000); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/mpc512x_fec.h b/qemu/roms/u-boot/drivers/net/mpc512x_fec.h deleted file mode 100644 index a083cca2f..000000000 --- a/qemu/roms/u-boot/drivers/net/mpc512x_fec.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * (C) Copyright 2003 - 2009 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * Derived from the MPC8xx driver's header file. - */ - -#ifndef __MPC512X_FEC_H -#define __MPC512X_FEC_H - -#include <common.h> - -/* Receive & Transmit Buffer Descriptor definitions */ -typedef struct BufferDescriptor { - u16 status; - u16 dataLength; - u32 dataPointer; -} FEC_RBD; - -typedef struct { - u16 status; - u16 dataLength; - u32 dataPointer; -} FEC_TBD; - -/* private structure */ -typedef enum { - SEVENWIRE, /* 7-wire */ - MII10, /* MII 10Mbps */ - MII100 /* MII 100Mbps */ -} xceiver_type; - -/* BD Numer definitions */ -#define FEC_TBD_NUM 48 /* The user can adjust this value */ -#define FEC_RBD_NUM 32 /* The user can adjust this value */ - -/* packet size limit */ -#define FEC_MAX_FRAME_LEN 1522 /* recommended default value */ - -/* Buffer size must be evenly divisible by 16 */ -#define FEC_BUFFER_SIZE ((FEC_MAX_FRAME_LEN + 0x10) & (~0xf)) - -typedef struct { - u8 frame[FEC_BUFFER_SIZE]; -} mpc512x_frame; - -typedef struct { - FEC_RBD rbd[FEC_RBD_NUM]; /* RBD ring */ - FEC_TBD tbd[FEC_TBD_NUM]; /* TBD ring */ - mpc512x_frame recv_frames[FEC_RBD_NUM]; /* receive buff */ -} mpc512x_buff_descs; - -typedef struct { - volatile fec512x_t *eth; - xceiver_type xcv_type; /* transceiver type */ - mpc512x_buff_descs *bdBase; /* BD rings and recv buffer */ - u16 rbdIndex; /* next receive BD to read */ - u16 tbdIndex; /* next transmit BD to send */ - u16 usedTbdIndex; /* next transmit BD to clean */ - u16 cleanTbdNum; /* the number of available transmit BDs */ -} mpc512x_fec_priv; - -/* RBD bits definitions */ -#define FEC_RBD_EMPTY 0x8000 /* Buffer is empty */ -#define FEC_RBD_WRAP 0x2000 /* Last BD in ring */ -#define FEC_RBD_LAST 0x0800 /* Buffer is last in frame(useless) */ -#define FEC_RBD_MISS 0x0100 /* Miss bit for prom mode */ -#define FEC_RBD_BC 0x0080 /* The received frame is broadcast frame */ -#define FEC_RBD_MC 0x0040 /* The received frame is multicast frame */ -#define FEC_RBD_LG 0x0020 /* Frame length violation */ -#define FEC_RBD_NO 0x0010 /* Nonoctet align frame */ -#define FEC_RBD_SH 0x0008 /* Short frame */ -#define FEC_RBD_CR 0x0004 /* CRC error */ -#define FEC_RBD_OV 0x0002 /* Receive FIFO overrun */ -#define FEC_RBD_TR 0x0001 /* Frame is truncated */ -#define FEC_RBD_ERR (FEC_RBD_LG | FEC_RBD_NO | FEC_RBD_CR | \ - FEC_RBD_OV | FEC_RBD_TR) - -/* TBD bits definitions */ -#define FEC_TBD_READY 0x8000 /* Buffer is ready */ -#define FEC_TBD_WRAP 0x2000 /* Last BD in ring */ -#define FEC_TBD_LAST 0x0800 /* Buffer is last in frame */ -#define FEC_TBD_TC 0x0400 /* Transmit the CRC */ -#define FEC_TBD_ABC 0x0200 /* Append bad CRC */ - -/* MII-related definitios */ -#define FEC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */ -#define FEC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */ -#define FEC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */ -#define FEC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */ -#define FEC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */ -#define FEC_MII_DATA_TA 0x00020000 /* Turnaround */ -#define FEC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */ - -#define FEC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */ -#define FEC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */ - -#endif /* __MPC512X_FEC_H */ diff --git a/qemu/roms/u-boot/drivers/net/mpc5xxx_fec.c b/qemu/roms/u-boot/drivers/net/mpc5xxx_fec.c deleted file mode 100644 index 1093ba59d..000000000 --- a/qemu/roms/u-boot/drivers/net/mpc5xxx_fec.c +++ /dev/null @@ -1,1027 +0,0 @@ -/* - * (C) Copyright 2003-2010 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * This file is based on mpc4200fec.c, - * (C) Copyright Motorola, Inc., 2000 - */ - -#include <common.h> -#include <mpc5xxx.h> -#include <mpc5xxx_sdma.h> -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <miiphy.h> -#include "mpc5xxx_fec.h" - -DECLARE_GLOBAL_DATA_PTR; - -/* #define DEBUG 0x28 */ - -#if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) -#error "CONFIG_MII has to be defined!" -#endif - -#if (DEBUG & 0x60) -static void tfifo_print(char *devname, mpc5xxx_fec_priv *fec); -static void rfifo_print(char *devname, mpc5xxx_fec_priv *fec); -#endif /* DEBUG */ - -typedef struct { - uint8 data[1500]; /* actual data */ - int length; /* actual length */ - int used; /* buffer in use or not */ - uint8 head[16]; /* MAC header(6 + 6 + 2) + 2(aligned) */ -} NBUF; - -int fec5xxx_miiphy_read(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 *retVal); -int fec5xxx_miiphy_write(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 data); - -static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis); - -/********************************************************************/ -#if (DEBUG & 0x2) -static void mpc5xxx_fec_phydump (char *devname) -{ - uint16 phyStatus, i; - uint8 phyAddr = CONFIG_PHY_ADDR; - uint8 reg_mask[] = { -#if CONFIG_PHY_TYPE == 0x79c874 /* AMD Am79C874 */ - /* regs to print: 0...7, 16...19, 21, 23, 24 */ - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, -#else - /* regs to print: 0...8, 16...20 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -#endif - }; - - for (i = 0; i < 32; i++) { - if (reg_mask[i]) { - miiphy_read(devname, phyAddr, i, &phyStatus); - printf("Mii reg %d: 0x%04x\n", i, phyStatus); - } - } -} -#endif - -/********************************************************************/ -static int mpc5xxx_fec_rbd_init(mpc5xxx_fec_priv *fec) -{ - int ix; - char *data; - static int once = 0; - - for (ix = 0; ix < FEC_RBD_NUM; ix++) { - if (!once) { - data = (char *)malloc(FEC_MAX_PKT_SIZE); - if (data == NULL) { - printf ("RBD INIT FAILED\n"); - return -1; - } - fec->rbdBase[ix].dataPointer = (uint32)data; - } - fec->rbdBase[ix].status = FEC_RBD_EMPTY; - fec->rbdBase[ix].dataLength = 0; - } - once ++; - - /* - * have the last RBD to close the ring - */ - fec->rbdBase[ix - 1].status |= FEC_RBD_WRAP; - fec->rbdIndex = 0; - - return 0; -} - -/********************************************************************/ -static void mpc5xxx_fec_tbd_init(mpc5xxx_fec_priv *fec) -{ - int ix; - - for (ix = 0; ix < FEC_TBD_NUM; ix++) { - fec->tbdBase[ix].status = 0; - } - - /* - * Have the last TBD to close the ring - */ - fec->tbdBase[ix - 1].status |= FEC_TBD_WRAP; - - /* - * Initialize some indices - */ - fec->tbdIndex = 0; - fec->usedTbdIndex = 0; - fec->cleanTbdNum = FEC_TBD_NUM; -} - -/********************************************************************/ -static void mpc5xxx_fec_rbd_clean(mpc5xxx_fec_priv *fec, volatile FEC_RBD * pRbd) -{ - /* - * Reset buffer descriptor as empty - */ - if ((fec->rbdIndex) == (FEC_RBD_NUM - 1)) - pRbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY); - else - pRbd->status = FEC_RBD_EMPTY; - - pRbd->dataLength = 0; - - /* - * Now, we have an empty RxBD, restart the SmartDMA receive task - */ - SDMA_TASK_ENABLE(FEC_RECV_TASK_NO); - - /* - * Increment BD count - */ - fec->rbdIndex = (fec->rbdIndex + 1) % FEC_RBD_NUM; -} - -/********************************************************************/ -static void mpc5xxx_fec_tbd_scrub(mpc5xxx_fec_priv *fec) -{ - volatile FEC_TBD *pUsedTbd; - -#if (DEBUG & 0x1) - printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n", - fec->cleanTbdNum, fec->usedTbdIndex); -#endif - - /* - * process all the consumed TBDs - */ - while (fec->cleanTbdNum < FEC_TBD_NUM) { - pUsedTbd = &fec->tbdBase[fec->usedTbdIndex]; - if (pUsedTbd->status & FEC_TBD_READY) { -#if (DEBUG & 0x20) - printf("Cannot clean TBD %d, in use\n", fec->cleanTbdNum); -#endif - return; - } - - /* - * clean this buffer descriptor - */ - if (fec->usedTbdIndex == (FEC_TBD_NUM - 1)) - pUsedTbd->status = FEC_TBD_WRAP; - else - pUsedTbd->status = 0; - - /* - * update some indeces for a correct handling of the TBD ring - */ - fec->cleanTbdNum++; - fec->usedTbdIndex = (fec->usedTbdIndex + 1) % FEC_TBD_NUM; - } -} - -/********************************************************************/ -static void mpc5xxx_fec_set_hwaddr(mpc5xxx_fec_priv *fec, char *mac) -{ - uint8 currByte; /* byte for which to compute the CRC */ - int byte; /* loop - counter */ - int bit; /* loop - counter */ - uint32 crc = 0xffffffff; /* initial value */ - - /* - * The algorithm used is the following: - * we loop on each of the six bytes of the provided address, - * and we compute the CRC by left-shifting the previous - * value by one position, so that each bit in the current - * byte of the address may contribute the calculation. If - * the latter and the MSB in the CRC are different, then - * the CRC value so computed is also ex-ored with the - * "polynomium generator". The current byte of the address - * is also shifted right by one bit at each iteration. - * This is because the CRC generatore in hardware is implemented - * as a shift-register with as many ex-ores as the radixes - * in the polynomium. This suggests that we represent the - * polynomiumm itself as a 32-bit constant. - */ - for (byte = 0; byte < 6; byte++) { - currByte = mac[byte]; - for (bit = 0; bit < 8; bit++) { - if ((currByte & 0x01) ^ (crc & 0x01)) { - crc >>= 1; - crc = crc ^ 0xedb88320; - } else { - crc >>= 1; - } - currByte >>= 1; - } - } - - crc = crc >> 26; - - /* - * Set individual hash table register - */ - if (crc >= 32) { - fec->eth->iaddr1 = (1 << (crc - 32)); - fec->eth->iaddr2 = 0; - } else { - fec->eth->iaddr1 = 0; - fec->eth->iaddr2 = (1 << crc); - } - - /* - * Set physical address - */ - fec->eth->paddr1 = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3]; - fec->eth->paddr2 = (mac[4] << 24) + (mac[5] << 16) + 0x8808; -} - -/********************************************************************/ -static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis) -{ - mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv; - struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA; - -#if (DEBUG & 0x1) - printf ("mpc5xxx_fec_init... Begin\n"); -#endif - - mpc5xxx_fec_init_phy(dev, bis); - - /* - * Call board-specific PHY fixups (if any) - */ -#ifdef CONFIG_RESET_PHY_R - reset_phy(); -#endif - - /* - * Initialize RxBD/TxBD rings - */ - mpc5xxx_fec_rbd_init(fec); - mpc5xxx_fec_tbd_init(fec); - - /* - * Clear FEC-Lite interrupt event register(IEVENT) - */ - fec->eth->ievent = 0xffffffff; - - /* - * Set interrupt mask register - */ - fec->eth->imask = 0x00000000; - - /* - * Set FEC-Lite receive control register(R_CNTRL): - */ - if (fec->xcv_type == SEVENWIRE) { - /* - * Frame length=1518; 7-wire mode - */ - fec->eth->r_cntrl = 0x05ee0020; /*0x05ee0000;FIXME */ - } else { - /* - * Frame length=1518; MII mode; - */ - fec->eth->r_cntrl = 0x05ee0024; /*0x05ee0004;FIXME */ - } - - fec->eth->x_cntrl = 0x00000000; /* half-duplex, heartbeat disabled */ - - /* - * Set Opcode/Pause Duration Register - */ - fec->eth->op_pause = 0x00010020; /*FIXME 0xffff0020; */ - - /* - * Set Rx FIFO alarm and granularity value - */ - fec->eth->rfifo_cntrl = 0x0c000000 - | (fec->eth->rfifo_cntrl & ~0x0f000000); - fec->eth->rfifo_alarm = 0x0000030c; -#if (DEBUG & 0x22) - if (fec->eth->rfifo_status & 0x00700000 ) { - printf("mpc5xxx_fec_init() RFIFO error\n"); - } -#endif - - /* - * Set Tx FIFO granularity value - */ - fec->eth->tfifo_cntrl = 0x0c000000 - | (fec->eth->tfifo_cntrl & ~0x0f000000); -#if (DEBUG & 0x2) - printf("tfifo_status: 0x%08x\n", fec->eth->tfifo_status); - printf("tfifo_alarm: 0x%08x\n", fec->eth->tfifo_alarm); -#endif - - /* - * Set transmit fifo watermark register(X_WMRK), default = 64 - */ - fec->eth->tfifo_alarm = 0x00000080; - fec->eth->x_wmrk = 0x2; - - /* - * Set individual address filter for unicast address - * and set physical address registers. - */ - mpc5xxx_fec_set_hwaddr(fec, (char *)dev->enetaddr); - - /* - * Set multicast address filter - */ - fec->eth->gaddr1 = 0x00000000; - fec->eth->gaddr2 = 0x00000000; - - /* - * Turn ON cheater FSM: ???? - */ - fec->eth->xmit_fsm = 0x03000000; - - /* - * Turn off COMM bus prefetch in the MPC5200 BestComm. It doesn't - * work w/ the current receive task. - */ - sdma->PtdCntrl |= 0x00000001; - - /* - * Set priority of different initiators - */ - sdma->IPR0 = 7; /* always */ - sdma->IPR3 = 6; /* Eth RX */ - sdma->IPR4 = 5; /* Eth Tx */ - - /* - * Clear SmartDMA task interrupt pending bits - */ - SDMA_CLEAR_IEVENT(FEC_RECV_TASK_NO); - - /* - * Initialize SmartDMA parameters stored in SRAM - */ - *(volatile int *)FEC_TBD_BASE = (int)fec->tbdBase; - *(volatile int *)FEC_RBD_BASE = (int)fec->rbdBase; - *(volatile int *)FEC_TBD_NEXT = (int)fec->tbdBase; - *(volatile int *)FEC_RBD_NEXT = (int)fec->rbdBase; - - /* - * Enable FEC-Lite controller - */ - fec->eth->ecntrl |= 0x00000006; - -#if (DEBUG & 0x2) - if (fec->xcv_type != SEVENWIRE) - mpc5xxx_fec_phydump (dev->name); -#endif - - /* - * Enable SmartDMA receive task - */ - SDMA_TASK_ENABLE(FEC_RECV_TASK_NO); - -#if (DEBUG & 0x1) - printf("mpc5xxx_fec_init... Done \n"); -#endif - - return 1; -} - -/********************************************************************/ -static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis) -{ - mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv; - const uint8 phyAddr = CONFIG_PHY_ADDR; /* Only one PHY */ - static int initialized = 0; - - if(initialized) - return 0; - initialized = 1; - -#if (DEBUG & 0x1) - printf ("mpc5xxx_fec_init_phy... Begin\n"); -#endif - - /* - * Initialize GPIO pins - */ - if (fec->xcv_type == SEVENWIRE) { - /* 10MBit with 7-wire operation */ -#if defined(CONFIG_TOTAL5200) - /* 7-wire and USB2 on Ethernet */ - *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00030000; -#else /* !CONFIG_TOTAL5200 */ - /* 7-wire only */ - *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00020000; -#endif /* CONFIG_TOTAL5200 */ - } else { - /* 100MBit with MD operation */ - *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00050000; - } - - /* - * Clear FEC-Lite interrupt event register(IEVENT) - */ - fec->eth->ievent = 0xffffffff; - - /* - * Set interrupt mask register - */ - fec->eth->imask = 0x00000000; - -/* - * In original Promess-provided code PHY initialization is disabled with the - * following comment: "Phy initialization is DISABLED for now. There was a - * problem with running 100 Mbps on PRO board". Thus we temporarily disable - * PHY initialization for the Motion-PRO board, until a proper fix is found. - */ - - if (fec->xcv_type != SEVENWIRE) { - /* - * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock - * and do not drop the Preamble. - * No MII for 7-wire mode - */ - fec->eth->mii_speed = (((gd->arch.ipb_clk >> 20) / 5) << 1); - } - - if (fec->xcv_type != SEVENWIRE) { - /* - * Initialize PHY(LXT971A): - * - * Generally, on power up, the LXT971A reads its configuration - * pins to check for forced operation, If not cofigured for - * forced operation, it uses auto-negotiation/parallel detection - * to automatically determine line operating conditions. - * If the PHY device on the other side of the link supports - * auto-negotiation, the LXT971A auto-negotiates with it - * using Fast Link Pulse(FLP) Bursts. If the PHY partner does not - * support auto-negotiation, the LXT971A automatically detects - * the presence of either link pulses(10Mbps PHY) or Idle - * symbols(100Mbps) and sets its operating conditions accordingly. - * - * When auto-negotiation is controlled by software, the following - * steps are recommended. - * - * Note: - * The physical address is dependent on hardware configuration. - * - */ - int timeout = 1; - uint16 phyStatus; - - /* - * Reset PHY, then delay 300ns - */ - miiphy_write(dev->name, phyAddr, 0x0, 0x8000); - udelay(1000); - -#if defined(CONFIG_UC101) || defined(CONFIG_MUCMC52) - /* Set the LED configuration Register for the UC101 - and MUCMC52 Board */ - miiphy_write(dev->name, phyAddr, 0x14, 0x4122); -#endif - if (fec->xcv_type == MII10) { - /* - * Force 10Base-T, FDX operation - */ -#if (DEBUG & 0x2) - printf("Forcing 10 Mbps ethernet link... "); -#endif - miiphy_read(dev->name, phyAddr, 0x1, &phyStatus); - /* - miiphy_write(dev->name, fec, phyAddr, 0x0, 0x0100); - */ - miiphy_write(dev->name, phyAddr, 0x0, 0x0180); - - timeout = 20; - do { /* wait for link status to go down */ - udelay(10000); - if ((timeout--) == 0) { -#if (DEBUG & 0x2) - printf("hmmm, should not have waited..."); -#endif - break; - } - miiphy_read(dev->name, phyAddr, 0x1, &phyStatus); -#if (DEBUG & 0x2) - printf("="); -#endif - } while ((phyStatus & 0x0004)); /* !link up */ - - timeout = 1000; - do { /* wait for link status to come back up */ - udelay(10000); - if ((timeout--) == 0) { - printf("failed. Link is down.\n"); - break; - } - miiphy_read(dev->name, phyAddr, 0x1, &phyStatus); -#if (DEBUG & 0x2) - printf("+"); -#endif - } while (!(phyStatus & 0x0004)); /* !link up */ - -#if (DEBUG & 0x2) - printf ("done.\n"); -#endif - } else { /* MII100 */ - /* - * Set the auto-negotiation advertisement register bits - */ - miiphy_write(dev->name, phyAddr, 0x4, 0x01e1); - - /* - * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation - */ - miiphy_write(dev->name, phyAddr, 0x0, 0x1200); - - /* - * Wait for AN completion - */ - timeout = 5000; - do { - udelay(1000); - - if ((timeout--) == 0) { -#if (DEBUG & 0x2) - printf("PHY auto neg 0 failed...\n"); -#endif - return -1; - } - - if (miiphy_read(dev->name, phyAddr, 0x1, &phyStatus) != 0) { -#if (DEBUG & 0x2) - printf("PHY auto neg 1 failed 0x%04x...\n", phyStatus); -#endif - return -1; - } - } while (!(phyStatus & 0x0004)); - -#if (DEBUG & 0x2) - printf("PHY auto neg complete! \n"); -#endif - } - - } - -#if (DEBUG & 0x2) - if (fec->xcv_type != SEVENWIRE) - mpc5xxx_fec_phydump (dev->name); -#endif - - -#if (DEBUG & 0x1) - printf("mpc5xxx_fec_init_phy... Done \n"); -#endif - - return 1; -} - -/********************************************************************/ -static void mpc5xxx_fec_halt(struct eth_device *dev) -{ - struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA; - mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv; - int counter = 0xffff; - -#if (DEBUG & 0x2) - if (fec->xcv_type != SEVENWIRE) - mpc5xxx_fec_phydump (dev->name); -#endif - - /* - * mask FEC chip interrupts - */ - fec->eth->imask = 0; - - /* - * issue graceful stop command to the FEC transmitter if necessary - */ - fec->eth->x_cntrl |= 0x00000001; - - /* - * wait for graceful stop to register - */ - while ((counter--) && (!(fec->eth->ievent & 0x10000000))) ; - - /* - * Disable SmartDMA tasks - */ - SDMA_TASK_DISABLE (FEC_XMIT_TASK_NO); - SDMA_TASK_DISABLE (FEC_RECV_TASK_NO); - - /* - * Turn on COMM bus prefetch in the MPC5200 BestComm after we're - * done. It doesn't work w/ the current receive task. - */ - sdma->PtdCntrl &= ~0x00000001; - - /* - * Disable the Ethernet Controller - */ - fec->eth->ecntrl &= 0xfffffffd; - - /* - * Clear FIFO status registers - */ - fec->eth->rfifo_status &= 0x00700000; - fec->eth->tfifo_status &= 0x00700000; - - fec->eth->reset_cntrl = 0x01000000; - - /* - * Issue a reset command to the FEC chip - */ - fec->eth->ecntrl |= 0x1; - - /* - * wait at least 16 clock cycles - */ - udelay(10); - - /* don't leave the MII speed set to zero */ - if (fec->xcv_type != SEVENWIRE) { - /* - * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock - * and do not drop the Preamble. - * No MII for 7-wire mode - */ - fec->eth->mii_speed = (((gd->arch.ipb_clk >> 20) / 5) << 1); - } - -#if (DEBUG & 0x3) - printf("Ethernet task stopped\n"); -#endif -} - -#if (DEBUG & 0x60) -/********************************************************************/ - -static void tfifo_print(char *devname, mpc5xxx_fec_priv *fec) -{ - uint16 phyAddr = CONFIG_PHY_ADDR; - uint16 phyStatus; - - if ((fec->eth->tfifo_lrf_ptr != fec->eth->tfifo_lwf_ptr) - || (fec->eth->tfifo_rdptr != fec->eth->tfifo_wrptr)) { - - miiphy_read(devname, phyAddr, 0x1, &phyStatus); - printf("\nphyStatus: 0x%04x\n", phyStatus); - printf("ecntrl: 0x%08x\n", fec->eth->ecntrl); - printf("ievent: 0x%08x\n", fec->eth->ievent); - printf("x_status: 0x%08x\n", fec->eth->x_status); - printf("tfifo: status 0x%08x\n", fec->eth->tfifo_status); - - printf(" control 0x%08x\n", fec->eth->tfifo_cntrl); - printf(" lrfp 0x%08x\n", fec->eth->tfifo_lrf_ptr); - printf(" lwfp 0x%08x\n", fec->eth->tfifo_lwf_ptr); - printf(" alarm 0x%08x\n", fec->eth->tfifo_alarm); - printf(" readptr 0x%08x\n", fec->eth->tfifo_rdptr); - printf(" writptr 0x%08x\n", fec->eth->tfifo_wrptr); - } -} - -static void rfifo_print(char *devname, mpc5xxx_fec_priv *fec) -{ - uint16 phyAddr = CONFIG_PHY_ADDR; - uint16 phyStatus; - - if ((fec->eth->rfifo_lrf_ptr != fec->eth->rfifo_lwf_ptr) - || (fec->eth->rfifo_rdptr != fec->eth->rfifo_wrptr)) { - - miiphy_read(devname, phyAddr, 0x1, &phyStatus); - printf("\nphyStatus: 0x%04x\n", phyStatus); - printf("ecntrl: 0x%08x\n", fec->eth->ecntrl); - printf("ievent: 0x%08x\n", fec->eth->ievent); - printf("x_status: 0x%08x\n", fec->eth->x_status); - printf("rfifo: status 0x%08x\n", fec->eth->rfifo_status); - - printf(" control 0x%08x\n", fec->eth->rfifo_cntrl); - printf(" lrfp 0x%08x\n", fec->eth->rfifo_lrf_ptr); - printf(" lwfp 0x%08x\n", fec->eth->rfifo_lwf_ptr); - printf(" alarm 0x%08x\n", fec->eth->rfifo_alarm); - printf(" readptr 0x%08x\n", fec->eth->rfifo_rdptr); - printf(" writptr 0x%08x\n", fec->eth->rfifo_wrptr); - } -} -#endif /* DEBUG */ - -/********************************************************************/ - -static int mpc5xxx_fec_send(struct eth_device *dev, void *eth_data, - int data_length) -{ - /* - * This routine transmits one frame. This routine only accepts - * 6-byte Ethernet addresses. - */ - mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv; - volatile FEC_TBD *pTbd; - -#if (DEBUG & 0x20) - printf("tbd status: 0x%04x\n", fec->tbdBase[0].status); - tfifo_print(dev->name, fec); -#endif - - /* - * Clear Tx BD ring at first - */ - mpc5xxx_fec_tbd_scrub(fec); - - /* - * Check for valid length of data. - */ - if ((data_length > 1500) || (data_length <= 0)) { - return -1; - } - - /* - * Check the number of vacant TxBDs. - */ - if (fec->cleanTbdNum < 1) { -#if (DEBUG & 0x20) - printf("No available TxBDs ...\n"); -#endif - return -1; - } - - /* - * Get the first TxBD to send the mac header - */ - pTbd = &fec->tbdBase[fec->tbdIndex]; - pTbd->dataLength = data_length; - pTbd->dataPointer = (uint32)eth_data; - pTbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY; - fec->tbdIndex = (fec->tbdIndex + 1) % FEC_TBD_NUM; - -#if (DEBUG & 0x100) - printf("SDMA_TASK_ENABLE, fec->tbdIndex = %d \n", fec->tbdIndex); -#endif - - /* - * Kick the MII i/f - */ - if (fec->xcv_type != SEVENWIRE) { - uint16 phyStatus; - miiphy_read(dev->name, 0, 0x1, &phyStatus); - } - - /* - * Enable SmartDMA transmit task - */ - -#if (DEBUG & 0x20) - tfifo_print(dev->name, fec); -#endif - SDMA_TASK_ENABLE (FEC_XMIT_TASK_NO); -#if (DEBUG & 0x20) - tfifo_print(dev->name, fec); -#endif -#if (DEBUG & 0x8) - printf( "+" ); -#endif - - fec->cleanTbdNum -= 1; - -#if (DEBUG & 0x129) && (DEBUG & 0x80000000) - printf ("smartDMA ethernet Tx task enabled\n"); -#endif - /* - * wait until frame is sent . - */ - while (pTbd->status & FEC_TBD_READY) { - udelay(10); -#if (DEBUG & 0x8) - printf ("TDB status = %04x\n", pTbd->status); -#endif - } - - return 0; -} - - -/********************************************************************/ -static int mpc5xxx_fec_recv(struct eth_device *dev) -{ - /* - * This command pulls one frame from the card - */ - mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv; - volatile FEC_RBD *pRbd = &fec->rbdBase[fec->rbdIndex]; - unsigned long ievent; - int frame_length, len = 0; - NBUF *frame; - uchar buff[FEC_MAX_PKT_SIZE]; - -#if (DEBUG & 0x1) - printf ("mpc5xxx_fec_recv %d Start...\n", fec->rbdIndex); -#endif -#if (DEBUG & 0x8) - printf( "-" ); -#endif - - /* - * Check if any critical events have happened - */ - ievent = fec->eth->ievent; - fec->eth->ievent = ievent; - if (ievent & 0x20060000) { - /* BABT, Rx/Tx FIFO errors */ - mpc5xxx_fec_halt(dev); - mpc5xxx_fec_init(dev, NULL); - return 0; - } - if (ievent & 0x80000000) { - /* Heartbeat error */ - fec->eth->x_cntrl |= 0x00000001; - } - if (ievent & 0x10000000) { - /* Graceful stop complete */ - if (fec->eth->x_cntrl & 0x00000001) { - mpc5xxx_fec_halt(dev); - fec->eth->x_cntrl &= ~0x00000001; - mpc5xxx_fec_init(dev, NULL); - } - } - - if (!(pRbd->status & FEC_RBD_EMPTY)) { - if ((pRbd->status & FEC_RBD_LAST) && !(pRbd->status & FEC_RBD_ERR) && - ((pRbd->dataLength - 4) > 14)) { - - /* - * Get buffer address and size - */ - frame = (NBUF *)pRbd->dataPointer; - frame_length = pRbd->dataLength - 4; - -#if (DEBUG & 0x20) - { - int i; - printf("recv data hdr:"); - for (i = 0; i < 14; i++) - printf("%x ", *(frame->head + i)); - printf("\n"); - } -#endif - /* - * Fill the buffer and pass it to upper layers - */ - memcpy(buff, frame->head, 14); - memcpy(buff + 14, frame->data, frame_length); - NetReceive(buff, frame_length); - len = frame_length; - } - /* - * Reset buffer descriptor as empty - */ - mpc5xxx_fec_rbd_clean(fec, pRbd); - } - SDMA_CLEAR_IEVENT (FEC_RECV_TASK_NO); - return len; -} - - -/********************************************************************/ -int mpc5xxx_fec_initialize(bd_t * bis) -{ - mpc5xxx_fec_priv *fec; - struct eth_device *dev; - char *tmp, *end; - char env_enetaddr[6]; - int i; - - fec = (mpc5xxx_fec_priv *)malloc(sizeof(*fec)); - dev = (struct eth_device *)malloc(sizeof(*dev)); - memset(dev, 0, sizeof *dev); - - fec->eth = (ethernet_regs *)MPC5XXX_FEC; - fec->tbdBase = (FEC_TBD *)FEC_BD_BASE; - fec->rbdBase = (FEC_RBD *)(FEC_BD_BASE + FEC_TBD_NUM * sizeof(FEC_TBD)); -#if defined(CONFIG_MPC5xxx_FEC_MII100) - fec->xcv_type = MII100; -#elif defined(CONFIG_MPC5xxx_FEC_MII10) - fec->xcv_type = MII10; -#elif defined(CONFIG_MPC5xxx_FEC_SEVENWIRE) - fec->xcv_type = SEVENWIRE; -#else -#error fec->xcv_type not initialized. -#endif - if (fec->xcv_type != SEVENWIRE) { - /* - * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock - * and do not drop the Preamble. - * No MII for 7-wire mode - */ - fec->eth->mii_speed = (((gd->arch.ipb_clk >> 20) / 5) << 1); - } - - dev->priv = (void *)fec; - dev->iobase = MPC5XXX_FEC; - dev->init = mpc5xxx_fec_init; - dev->halt = mpc5xxx_fec_halt; - dev->send = mpc5xxx_fec_send; - dev->recv = mpc5xxx_fec_recv; - - sprintf(dev->name, "FEC"); - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - miiphy_register (dev->name, - fec5xxx_miiphy_read, fec5xxx_miiphy_write); -#endif - - /* - * Try to set the mac address now. The fec mac address is - * a garbage after reset. When not using fec for booting - * the Linux fec driver will try to work with this garbage. - */ - tmp = getenv("ethaddr"); - if (tmp) { - for (i=0; i<6; i++) { - env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0; - if (tmp) - tmp = (*end) ? end+1 : end; - } - mpc5xxx_fec_set_hwaddr(fec, env_enetaddr); - } - - return 1; -} - -/* MII-interface related functions */ -/********************************************************************/ -int fec5xxx_miiphy_read(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal) -{ - ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC; - uint32 reg; /* convenient holder for the PHY register */ - uint32 phy; /* convenient holder for the PHY */ - int timeout = 0xffff; - - /* - * reading from any PHY's register is done by properly - * programming the FEC's MII data register. - */ - reg = regAddr << FEC_MII_DATA_RA_SHIFT; - phy = phyAddr << FEC_MII_DATA_PA_SHIFT; - - eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA | phy | reg); - - /* - * wait for the related interrupt - */ - while ((timeout--) && (!(eth->ievent & 0x00800000))) ; - - if (timeout == 0) { -#if (DEBUG & 0x2) - printf ("Read MDIO failed...\n"); -#endif - return -1; - } - - /* - * clear mii interrupt bit - */ - eth->ievent = 0x00800000; - - /* - * it's now safe to read the PHY's register - */ - *retVal = (uint16) eth->mii_data; - - return 0; -} - -/********************************************************************/ -int fec5xxx_miiphy_write(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 data) -{ - ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC; - uint32 reg; /* convenient holder for the PHY register */ - uint32 phy; /* convenient holder for the PHY */ - int timeout = 0xffff; - - reg = regAddr << FEC_MII_DATA_RA_SHIFT; - phy = phyAddr << FEC_MII_DATA_PA_SHIFT; - - eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR | - FEC_MII_DATA_TA | phy | reg | data); - - /* - * wait for the MII interrupt - */ - while ((timeout--) && (!(eth->ievent & 0x00800000))) ; - - if (timeout == 0) { -#if (DEBUG & 0x2) - printf ("Write MDIO failed...\n"); -#endif - return -1; - } - - /* - * clear MII interrupt bit - */ - eth->ievent = 0x00800000; - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/mpc5xxx_fec.h b/qemu/roms/u-boot/drivers/net/mpc5xxx_fec.h deleted file mode 100644 index 16c3e8e91..000000000 --- a/qemu/roms/u-boot/drivers/net/mpc5xxx_fec.h +++ /dev/null @@ -1,282 +0,0 @@ -/* - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * This file is based on mpc4200fec.h - * (C) Copyright Motorola, Inc., 2000 - * - * odin ethernet header file - */ - -#ifndef __MPC5XXX_FEC_H -#define __MPC5XXX_FEC_H - -typedef unsigned long uint32; -typedef unsigned short uint16; -typedef unsigned char uint8; - -typedef struct ethernet_register_set { - -/* [10:2]addr = 00 */ - -/* Control and status Registers (offset 000-1FF) */ - - volatile uint32 fec_id; /* MBAR_ETH + 0x000 */ - volatile uint32 ievent; /* MBAR_ETH + 0x004 */ - volatile uint32 imask; /* MBAR_ETH + 0x008 */ - - volatile uint32 RES0[1]; /* MBAR_ETH + 0x00C */ - volatile uint32 r_des_active; /* MBAR_ETH + 0x010 */ - volatile uint32 x_des_active; /* MBAR_ETH + 0x014 */ - volatile uint32 r_des_active_cl; /* MBAR_ETH + 0x018 */ - volatile uint32 x_des_active_cl; /* MBAR_ETH + 0x01C */ - volatile uint32 ivent_set; /* MBAR_ETH + 0x020 */ - volatile uint32 ecntrl; /* MBAR_ETH + 0x024 */ - - volatile uint32 RES1[6]; /* MBAR_ETH + 0x028-03C */ - volatile uint32 mii_data; /* MBAR_ETH + 0x040 */ - volatile uint32 mii_speed; /* MBAR_ETH + 0x044 */ - volatile uint32 mii_status; /* MBAR_ETH + 0x048 */ - - volatile uint32 RES2[5]; /* MBAR_ETH + 0x04C-05C */ - volatile uint32 mib_data; /* MBAR_ETH + 0x060 */ - volatile uint32 mib_control; /* MBAR_ETH + 0x064 */ - - volatile uint32 RES3[6]; /* MBAR_ETH + 0x068-7C */ - volatile uint32 r_activate; /* MBAR_ETH + 0x080 */ - volatile uint32 r_cntrl; /* MBAR_ETH + 0x084 */ - volatile uint32 r_hash; /* MBAR_ETH + 0x088 */ - volatile uint32 r_data; /* MBAR_ETH + 0x08C */ - volatile uint32 ar_done; /* MBAR_ETH + 0x090 */ - volatile uint32 r_test; /* MBAR_ETH + 0x094 */ - volatile uint32 r_mib; /* MBAR_ETH + 0x098 */ - volatile uint32 r_da_low; /* MBAR_ETH + 0x09C */ - volatile uint32 r_da_high; /* MBAR_ETH + 0x0A0 */ - - volatile uint32 RES4[7]; /* MBAR_ETH + 0x0A4-0BC */ - volatile uint32 x_activate; /* MBAR_ETH + 0x0C0 */ - volatile uint32 x_cntrl; /* MBAR_ETH + 0x0C4 */ - volatile uint32 backoff; /* MBAR_ETH + 0x0C8 */ - volatile uint32 x_data; /* MBAR_ETH + 0x0CC */ - volatile uint32 x_status; /* MBAR_ETH + 0x0D0 */ - volatile uint32 x_mib; /* MBAR_ETH + 0x0D4 */ - volatile uint32 x_test; /* MBAR_ETH + 0x0D8 */ - volatile uint32 fdxfc_da1; /* MBAR_ETH + 0x0DC */ - volatile uint32 fdxfc_da2; /* MBAR_ETH + 0x0E0 */ - volatile uint32 paddr1; /* MBAR_ETH + 0x0E4 */ - volatile uint32 paddr2; /* MBAR_ETH + 0x0E8 */ - volatile uint32 op_pause; /* MBAR_ETH + 0x0EC */ - - volatile uint32 RES5[4]; /* MBAR_ETH + 0x0F0-0FC */ - volatile uint32 instr_reg; /* MBAR_ETH + 0x100 */ - volatile uint32 context_reg; /* MBAR_ETH + 0x104 */ - volatile uint32 test_cntrl; /* MBAR_ETH + 0x108 */ - volatile uint32 acc_reg; /* MBAR_ETH + 0x10C */ - volatile uint32 ones; /* MBAR_ETH + 0x110 */ - volatile uint32 zeros; /* MBAR_ETH + 0x114 */ - volatile uint32 iaddr1; /* MBAR_ETH + 0x118 */ - volatile uint32 iaddr2; /* MBAR_ETH + 0x11C */ - volatile uint32 gaddr1; /* MBAR_ETH + 0x120 */ - volatile uint32 gaddr2; /* MBAR_ETH + 0x124 */ - volatile uint32 random; /* MBAR_ETH + 0x128 */ - volatile uint32 rand1; /* MBAR_ETH + 0x12C */ - volatile uint32 tmp; /* MBAR_ETH + 0x130 */ - - volatile uint32 RES6[3]; /* MBAR_ETH + 0x134-13C */ - volatile uint32 fifo_id; /* MBAR_ETH + 0x140 */ - volatile uint32 x_wmrk; /* MBAR_ETH + 0x144 */ - volatile uint32 fcntrl; /* MBAR_ETH + 0x148 */ - volatile uint32 r_bound; /* MBAR_ETH + 0x14C */ - volatile uint32 r_fstart; /* MBAR_ETH + 0x150 */ - volatile uint32 r_count; /* MBAR_ETH + 0x154 */ - volatile uint32 r_lag; /* MBAR_ETH + 0x158 */ - volatile uint32 r_read; /* MBAR_ETH + 0x15C */ - volatile uint32 r_write; /* MBAR_ETH + 0x160 */ - volatile uint32 x_count; /* MBAR_ETH + 0x164 */ - volatile uint32 x_lag; /* MBAR_ETH + 0x168 */ - volatile uint32 x_retry; /* MBAR_ETH + 0x16C */ - volatile uint32 x_write; /* MBAR_ETH + 0x170 */ - volatile uint32 x_read; /* MBAR_ETH + 0x174 */ - - volatile uint32 RES7[2]; /* MBAR_ETH + 0x178-17C */ - volatile uint32 fm_cntrl; /* MBAR_ETH + 0x180 */ - volatile uint32 rfifo_data; /* MBAR_ETH + 0x184 */ - volatile uint32 rfifo_status; /* MBAR_ETH + 0x188 */ - volatile uint32 rfifo_cntrl; /* MBAR_ETH + 0x18C */ - volatile uint32 rfifo_lrf_ptr; /* MBAR_ETH + 0x190 */ - volatile uint32 rfifo_lwf_ptr; /* MBAR_ETH + 0x194 */ - volatile uint32 rfifo_alarm; /* MBAR_ETH + 0x198 */ - volatile uint32 rfifo_rdptr; /* MBAR_ETH + 0x19C */ - volatile uint32 rfifo_wrptr; /* MBAR_ETH + 0x1A0 */ - volatile uint32 tfifo_data; /* MBAR_ETH + 0x1A4 */ - volatile uint32 tfifo_status; /* MBAR_ETH + 0x1A8 */ - volatile uint32 tfifo_cntrl; /* MBAR_ETH + 0x1AC */ - volatile uint32 tfifo_lrf_ptr; /* MBAR_ETH + 0x1B0 */ - volatile uint32 tfifo_lwf_ptr; /* MBAR_ETH + 0x1B4 */ - volatile uint32 tfifo_alarm; /* MBAR_ETH + 0x1B8 */ - volatile uint32 tfifo_rdptr; /* MBAR_ETH + 0x1BC */ - volatile uint32 tfifo_wrptr; /* MBAR_ETH + 0x1C0 */ - - volatile uint32 reset_cntrl; /* MBAR_ETH + 0x1C4 */ - volatile uint32 xmit_fsm; /* MBAR_ETH + 0x1C8 */ - - volatile uint32 RES8[3]; /* MBAR_ETH + 0x1CC-1D4 */ - volatile uint32 rdes_data0; /* MBAR_ETH + 0x1D8 */ - volatile uint32 rdes_data1; /* MBAR_ETH + 0x1DC */ - volatile uint32 r_length; /* MBAR_ETH + 0x1E0 */ - volatile uint32 x_length; /* MBAR_ETH + 0x1E4 */ - volatile uint32 x_addr; /* MBAR_ETH + 0x1E8 */ - volatile uint32 cdes_data; /* MBAR_ETH + 0x1EC */ - volatile uint32 status; /* MBAR_ETH + 0x1F0 */ - volatile uint32 dma_control; /* MBAR_ETH + 0x1F4 */ - volatile uint32 des_cmnd; /* MBAR_ETH + 0x1F8 */ - volatile uint32 data; /* MBAR_ETH + 0x1FC */ - -/* MIB COUNTERS (Offset 200-2FF) */ - - volatile uint32 rmon_t_drop; /* MBAR_ETH + 0x200 */ - volatile uint32 rmon_t_packets; /* MBAR_ETH + 0x204 */ - volatile uint32 rmon_t_bc_pkt; /* MBAR_ETH + 0x208 */ - volatile uint32 rmon_t_mc_pkt; /* MBAR_ETH + 0x20C */ - volatile uint32 rmon_t_crc_align; /* MBAR_ETH + 0x210 */ - volatile uint32 rmon_t_undersize; /* MBAR_ETH + 0x214 */ - volatile uint32 rmon_t_oversize; /* MBAR_ETH + 0x218 */ - volatile uint32 rmon_t_frag; /* MBAR_ETH + 0x21C */ - volatile uint32 rmon_t_jab; /* MBAR_ETH + 0x220 */ - volatile uint32 rmon_t_col; /* MBAR_ETH + 0x224 */ - volatile uint32 rmon_t_p64; /* MBAR_ETH + 0x228 */ - volatile uint32 rmon_t_p65to127; /* MBAR_ETH + 0x22C */ - volatile uint32 rmon_t_p128to255; /* MBAR_ETH + 0x230 */ - volatile uint32 rmon_t_p256to511; /* MBAR_ETH + 0x234 */ - volatile uint32 rmon_t_p512to1023; /* MBAR_ETH + 0x238 */ - volatile uint32 rmon_t_p1024to2047; /* MBAR_ETH + 0x23C */ - volatile uint32 rmon_t_p_gte2048; /* MBAR_ETH + 0x240 */ - volatile uint32 rmon_t_octets; /* MBAR_ETH + 0x244 */ - volatile uint32 ieee_t_drop; /* MBAR_ETH + 0x248 */ - volatile uint32 ieee_t_frame_ok; /* MBAR_ETH + 0x24C */ - volatile uint32 ieee_t_1col; /* MBAR_ETH + 0x250 */ - volatile uint32 ieee_t_mcol; /* MBAR_ETH + 0x254 */ - volatile uint32 ieee_t_def; /* MBAR_ETH + 0x258 */ - volatile uint32 ieee_t_lcol; /* MBAR_ETH + 0x25C */ - volatile uint32 ieee_t_excol; /* MBAR_ETH + 0x260 */ - volatile uint32 ieee_t_macerr; /* MBAR_ETH + 0x264 */ - volatile uint32 ieee_t_cserr; /* MBAR_ETH + 0x268 */ - volatile uint32 ieee_t_sqe; /* MBAR_ETH + 0x26C */ - volatile uint32 t_fdxfc; /* MBAR_ETH + 0x270 */ - volatile uint32 ieee_t_octets_ok; /* MBAR_ETH + 0x274 */ - - volatile uint32 RES9[2]; /* MBAR_ETH + 0x278-27C */ - volatile uint32 rmon_r_drop; /* MBAR_ETH + 0x280 */ - volatile uint32 rmon_r_packets; /* MBAR_ETH + 0x284 */ - volatile uint32 rmon_r_bc_pkt; /* MBAR_ETH + 0x288 */ - volatile uint32 rmon_r_mc_pkt; /* MBAR_ETH + 0x28C */ - volatile uint32 rmon_r_crc_align; /* MBAR_ETH + 0x290 */ - volatile uint32 rmon_r_undersize; /* MBAR_ETH + 0x294 */ - volatile uint32 rmon_r_oversize; /* MBAR_ETH + 0x298 */ - volatile uint32 rmon_r_frag; /* MBAR_ETH + 0x29C */ - volatile uint32 rmon_r_jab; /* MBAR_ETH + 0x2A0 */ - - volatile uint32 rmon_r_resvd_0; /* MBAR_ETH + 0x2A4 */ - - volatile uint32 rmon_r_p64; /* MBAR_ETH + 0x2A8 */ - volatile uint32 rmon_r_p65to127; /* MBAR_ETH + 0x2AC */ - volatile uint32 rmon_r_p128to255; /* MBAR_ETH + 0x2B0 */ - volatile uint32 rmon_r_p256to511; /* MBAR_ETH + 0x2B4 */ - volatile uint32 rmon_r_p512to1023; /* MBAR_ETH + 0x2B8 */ - volatile uint32 rmon_r_p1024to2047; /* MBAR_ETH + 0x2BC */ - volatile uint32 rmon_r_p_gte2048; /* MBAR_ETH + 0x2C0 */ - volatile uint32 rmon_r_octets; /* MBAR_ETH + 0x2C4 */ - volatile uint32 ieee_r_drop; /* MBAR_ETH + 0x2C8 */ - volatile uint32 ieee_r_frame_ok; /* MBAR_ETH + 0x2CC */ - volatile uint32 ieee_r_crc; /* MBAR_ETH + 0x2D0 */ - volatile uint32 ieee_r_align; /* MBAR_ETH + 0x2D4 */ - volatile uint32 r_macerr; /* MBAR_ETH + 0x2D8 */ - volatile uint32 r_fdxfc; /* MBAR_ETH + 0x2DC */ - volatile uint32 ieee_r_octets_ok; /* MBAR_ETH + 0x2E0 */ - - volatile uint32 RES10[6]; /* MBAR_ETH + 0x2E4-2FC */ - - volatile uint32 RES11[64]; /* MBAR_ETH + 0x300-3FF */ -} ethernet_regs; - -/* Receive & Transmit Buffer Descriptor definitions */ -typedef struct BufferDescriptor { - uint16 status; - uint16 dataLength; - uint32 dataPointer; -} FEC_RBD; -typedef struct { - uint16 status; - uint16 dataLength; - uint32 dataPointer; -} FEC_TBD; - -/* private structure */ -typedef enum { - SEVENWIRE, /* 7-wire */ - MII10, /* MII 10Mbps */ - MII100 /* MII 100Mbps */ -} xceiver_type; - -typedef struct { - ethernet_regs *eth; - xceiver_type xcv_type; /* transceiver type */ - FEC_RBD *rbdBase; /* RBD ring */ - FEC_TBD *tbdBase; /* TBD ring */ - uint16 rbdIndex; /* next receive BD to read */ - uint16 tbdIndex; /* next transmit BD to send */ - uint16 usedTbdIndex; /* next transmit BD to clean */ - uint16 cleanTbdNum; /* the number of available transmit BDs */ -} mpc5xxx_fec_priv; - -/* Ethernet parameter area */ -#define FEC_TBD_BASE (FEC_PARAM_BASE + 0x00) -#define FEC_TBD_NEXT (FEC_PARAM_BASE + 0x04) -#define FEC_RBD_BASE (FEC_PARAM_BASE + 0x08) -#define FEC_RBD_NEXT (FEC_PARAM_BASE + 0x0c) - -/* BD Numer definitions */ -#define FEC_TBD_NUM 48 /* The user can adjust this value */ -#define FEC_RBD_NUM 32 /* The user can adjust this value */ - -/* packet size limit */ -#define FEC_MAX_PKT_SIZE 1536 - -/* RBD bits definitions */ -#define FEC_RBD_EMPTY 0x8000 /* Buffer is empty */ -#define FEC_RBD_WRAP 0x2000 /* Last BD in ring */ -#define FEC_RBD_INT 0x1000 /* Interrupt */ -#define FEC_RBD_LAST 0x0800 /* Buffer is last in frame(useless) */ -#define FEC_RBD_MISS 0x0100 /* Miss bit for prom mode */ -#define FEC_RBD_BC 0x0080 /* The received frame is broadcast frame */ -#define FEC_RBD_MC 0x0040 /* The received frame is multicast frame */ -#define FEC_RBD_LG 0x0020 /* Frame length violation */ -#define FEC_RBD_NO 0x0010 /* Nonoctet align frame */ -#define FEC_RBD_SH 0x0008 /* Short frame */ -#define FEC_RBD_CR 0x0004 /* CRC error */ -#define FEC_RBD_OV 0x0002 /* Receive FIFO overrun */ -#define FEC_RBD_TR 0x0001 /* Frame is truncated */ -#define FEC_RBD_ERR (FEC_RBD_LG | FEC_RBD_NO | FEC_RBD_CR | \ - FEC_RBD_OV | FEC_RBD_TR) - -/* TBD bits definitions */ -#define FEC_TBD_READY 0x8000 /* Buffer is ready */ -#define FEC_TBD_WRAP 0x2000 /* Last BD in ring */ -#define FEC_TBD_INT 0x1000 /* Interrupt */ -#define FEC_TBD_LAST 0x0800 /* Buffer is last in frame */ -#define FEC_TBD_TC 0x0400 /* Transmit the CRC */ -#define FEC_TBD_ABC 0x0200 /* Append bad CRC */ - -/* MII-related definitios */ -#define FEC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */ -#define FEC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */ -#define FEC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */ -#define FEC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */ -#define FEC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */ -#define FEC_MII_DATA_TA 0x00020000 /* Turnaround */ -#define FEC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */ - -#define FEC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */ -#define FEC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */ - -#endif /* __MPC5XXX_FEC_H */ diff --git a/qemu/roms/u-boot/drivers/net/mvgbe.c b/qemu/roms/u-boot/drivers/net/mvgbe.c deleted file mode 100644 index 0cd06b6a6..000000000 --- a/qemu/roms/u-boot/drivers/net/mvgbe.c +++ /dev/null @@ -1,788 +0,0 @@ -/* - * (C) Copyright 2009 - * Marvell Semiconductor <www.marvell.com> - * Written-by: Prafulla Wadaskar <prafulla@marvell.com> - * - * (C) Copyright 2003 - * Ingo Assmus <ingo.assmus@keymile.com> - * - * based on - Driver for MV64360X ethernet ports - * Copyright (C) 2002 rabeeh@galileo.co.il - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <net.h> -#include <malloc.h> -#include <miiphy.h> -#include <asm/io.h> -#include <asm/errno.h> -#include <asm/types.h> -#include <asm/system.h> -#include <asm/byteorder.h> -#include <asm/arch/cpu.h> - -#if defined(CONFIG_KIRKWOOD) -#include <asm/arch/kirkwood.h> -#elif defined(CONFIG_ORION5X) -#include <asm/arch/orion5x.h> -#elif defined(CONFIG_DOVE) -#include <asm/arch/dove.h> -#endif - -#include "mvgbe.h" - -DECLARE_GLOBAL_DATA_PTR; - -#define MV_PHY_ADR_REQUEST 0xee -#define MVGBE_SMI_REG (((struct mvgbe_registers *)MVGBE0_BASE)->smi) - -#if defined(CONFIG_PHYLIB) || defined(CONFIG_MII) || defined(CONFIG_CMD_MII) -/* - * smi_reg_read - miiphy_read callback function. - * - * Returns 16bit phy register value, or 0xffff on error - */ -static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 * data) -{ - struct eth_device *dev = eth_get_dev_by_name(devname); - struct mvgbe_device *dmvgbe = to_mvgbe(dev); - struct mvgbe_registers *regs = dmvgbe->regs; - u32 smi_reg; - u32 timeout; - - /* Phyadr read request */ - if (phy_adr == MV_PHY_ADR_REQUEST && - reg_ofs == MV_PHY_ADR_REQUEST) { - /* */ - *data = (u16) (MVGBE_REG_RD(regs->phyadr) & PHYADR_MASK); - return 0; - } - /* check parameters */ - if (phy_adr > PHYADR_MASK) { - printf("Err..(%s) Invalid PHY address %d\n", - __FUNCTION__, phy_adr); - return -EFAULT; - } - if (reg_ofs > PHYREG_MASK) { - printf("Err..(%s) Invalid register offset %d\n", - __FUNCTION__, reg_ofs); - return -EFAULT; - } - - timeout = MVGBE_PHY_SMI_TIMEOUT; - /* wait till the SMI is not busy */ - do { - /* read smi register */ - smi_reg = MVGBE_REG_RD(MVGBE_SMI_REG); - if (timeout-- == 0) { - printf("Err..(%s) SMI busy timeout\n", __FUNCTION__); - return -EFAULT; - } - } while (smi_reg & MVGBE_PHY_SMI_BUSY_MASK); - - /* fill the phy address and regiser offset and read opcode */ - smi_reg = (phy_adr << MVGBE_PHY_SMI_DEV_ADDR_OFFS) - | (reg_ofs << MVGBE_SMI_REG_ADDR_OFFS) - | MVGBE_PHY_SMI_OPCODE_READ; - - /* write the smi register */ - MVGBE_REG_WR(MVGBE_SMI_REG, smi_reg); - - /*wait till read value is ready */ - timeout = MVGBE_PHY_SMI_TIMEOUT; - - do { - /* read smi register */ - smi_reg = MVGBE_REG_RD(MVGBE_SMI_REG); - if (timeout-- == 0) { - printf("Err..(%s) SMI read ready timeout\n", - __FUNCTION__); - return -EFAULT; - } - } while (!(smi_reg & MVGBE_PHY_SMI_READ_VALID_MASK)); - - /* Wait for the data to update in the SMI register */ - for (timeout = 0; timeout < MVGBE_PHY_SMI_TIMEOUT; timeout++) - ; - - *data = (u16) (MVGBE_REG_RD(MVGBE_SMI_REG) & MVGBE_PHY_SMI_DATA_MASK); - - debug("%s:(adr %d, off %d) value= %04x\n", __FUNCTION__, phy_adr, - reg_ofs, *data); - - return 0; -} - -/* - * smi_reg_write - imiiphy_write callback function. - * - * Returns 0 if write succeed, -EINVAL on bad parameters - * -ETIME on timeout - */ -static int smi_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data) -{ - struct eth_device *dev = eth_get_dev_by_name(devname); - struct mvgbe_device *dmvgbe = to_mvgbe(dev); - struct mvgbe_registers *regs = dmvgbe->regs; - u32 smi_reg; - u32 timeout; - - /* Phyadr write request*/ - if (phy_adr == MV_PHY_ADR_REQUEST && - reg_ofs == MV_PHY_ADR_REQUEST) { - MVGBE_REG_WR(regs->phyadr, data); - return 0; - } - - /* check parameters */ - if (phy_adr > PHYADR_MASK) { - printf("Err..(%s) Invalid phy address\n", __FUNCTION__); - return -EINVAL; - } - if (reg_ofs > PHYREG_MASK) { - printf("Err..(%s) Invalid register offset\n", __FUNCTION__); - return -EINVAL; - } - - /* wait till the SMI is not busy */ - timeout = MVGBE_PHY_SMI_TIMEOUT; - do { - /* read smi register */ - smi_reg = MVGBE_REG_RD(MVGBE_SMI_REG); - if (timeout-- == 0) { - printf("Err..(%s) SMI busy timeout\n", __FUNCTION__); - return -ETIME; - } - } while (smi_reg & MVGBE_PHY_SMI_BUSY_MASK); - - /* fill the phy addr and reg offset and write opcode and data */ - smi_reg = (data << MVGBE_PHY_SMI_DATA_OFFS); - smi_reg |= (phy_adr << MVGBE_PHY_SMI_DEV_ADDR_OFFS) - | (reg_ofs << MVGBE_SMI_REG_ADDR_OFFS); - smi_reg &= ~MVGBE_PHY_SMI_OPCODE_READ; - - /* write the smi register */ - MVGBE_REG_WR(MVGBE_SMI_REG, smi_reg); - - return 0; -} -#endif - -#if defined(CONFIG_PHYLIB) -int mvgbe_phy_read(struct mii_dev *bus, int phy_addr, int dev_addr, - int reg_addr) -{ - u16 data; - int ret; - ret = smi_reg_read(bus->name, phy_addr, reg_addr, &data); - if (ret) - return ret; - return data; -} - -int mvgbe_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr, - int reg_addr, u16 data) -{ - return smi_reg_write(bus->name, phy_addr, reg_addr, data); -} -#endif - -/* Stop and checks all queues */ -static void stop_queue(u32 * qreg) -{ - u32 reg_data; - - reg_data = readl(qreg); - - if (reg_data & 0xFF) { - /* Issue stop command for active channels only */ - writel((reg_data << 8), qreg); - - /* Wait for all queue activity to terminate. */ - do { - /* - * Check port cause register that all queues - * are stopped - */ - reg_data = readl(qreg); - } - while (reg_data & 0xFF); - } -} - -/* - * set_access_control - Config address decode parameters for Ethernet unit - * - * This function configures the address decode parameters for the Gigabit - * Ethernet Controller according the given parameters struct. - * - * @regs Register struct pointer. - * @param Address decode parameter struct. - */ -static void set_access_control(struct mvgbe_registers *regs, - struct mvgbe_winparam *param) -{ - u32 access_prot_reg; - - /* Set access control register */ - access_prot_reg = MVGBE_REG_RD(regs->epap); - /* clear window permission */ - access_prot_reg &= (~(3 << (param->win * 2))); - access_prot_reg |= (param->access_ctrl << (param->win * 2)); - MVGBE_REG_WR(regs->epap, access_prot_reg); - - /* Set window Size reg (SR) */ - MVGBE_REG_WR(regs->barsz[param->win].size, - (((param->size / 0x10000) - 1) << 16)); - - /* Set window Base address reg (BA) */ - MVGBE_REG_WR(regs->barsz[param->win].bar, - (param->target | param->attrib | param->base_addr)); - /* High address remap reg (HARR) */ - if (param->win < 4) - MVGBE_REG_WR(regs->ha_remap[param->win], param->high_addr); - - /* Base address enable reg (BARER) */ - if (param->enable == 1) - MVGBE_REG_BITS_RESET(regs->bare, (1 << param->win)); - else - MVGBE_REG_BITS_SET(regs->bare, (1 << param->win)); -} - -static void set_dram_access(struct mvgbe_registers *regs) -{ - struct mvgbe_winparam win_param; - int i; - - for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { - /* Set access parameters for DRAM bank i */ - win_param.win = i; /* Use Ethernet window i */ - /* Window target - DDR */ - win_param.target = MVGBE_TARGET_DRAM; - /* Enable full access */ - win_param.access_ctrl = EWIN_ACCESS_FULL; - win_param.high_addr = 0; - /* Get bank base and size */ - win_param.base_addr = gd->bd->bi_dram[i].start; - win_param.size = gd->bd->bi_dram[i].size; - if (win_param.size == 0) - win_param.enable = 0; - else - win_param.enable = 1; /* Enable the access */ - - /* Enable DRAM bank */ - switch (i) { - case 0: - win_param.attrib = EBAR_DRAM_CS0; - break; - case 1: - win_param.attrib = EBAR_DRAM_CS1; - break; - case 2: - win_param.attrib = EBAR_DRAM_CS2; - break; - case 3: - win_param.attrib = EBAR_DRAM_CS3; - break; - default: - /* invalid bank, disable access */ - win_param.enable = 0; - win_param.attrib = 0; - break; - } - /* Set the access control for address window(EPAPR) RD/WR */ - set_access_control(regs, &win_param); - } -} - -/* - * port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables - * - * Go through all the DA filter tables (Unicast, Special Multicast & Other - * Multicast) and set each entry to 0. - */ -static void port_init_mac_tables(struct mvgbe_registers *regs) -{ - int table_index; - - /* Clear DA filter unicast table (Ex_dFUT) */ - for (table_index = 0; table_index < 4; ++table_index) - MVGBE_REG_WR(regs->dfut[table_index], 0); - - for (table_index = 0; table_index < 64; ++table_index) { - /* Clear DA filter special multicast table (Ex_dFSMT) */ - MVGBE_REG_WR(regs->dfsmt[table_index], 0); - /* Clear DA filter other multicast table (Ex_dFOMT) */ - MVGBE_REG_WR(regs->dfomt[table_index], 0); - } -} - -/* - * port_uc_addr - This function Set the port unicast address table - * - * This function locates the proper entry in the Unicast table for the - * specified MAC nibble and sets its properties according to function - * parameters. - * This function add/removes MAC addresses from the port unicast address - * table. - * - * @uc_nibble Unicast MAC Address last nibble. - * @option 0 = Add, 1 = remove address. - * - * RETURN: 1 if output succeeded. 0 if option parameter is invalid. - */ -static int port_uc_addr(struct mvgbe_registers *regs, u8 uc_nibble, - int option) -{ - u32 unicast_reg; - u32 tbl_offset; - u32 reg_offset; - - /* Locate the Unicast table entry */ - uc_nibble = (0xf & uc_nibble); - /* Register offset from unicast table base */ - tbl_offset = (uc_nibble / 4); - /* Entry offset within the above register */ - reg_offset = uc_nibble % 4; - - switch (option) { - case REJECT_MAC_ADDR: - /* - * Clear accepts frame bit at specified unicast - * DA table entry - */ - unicast_reg = MVGBE_REG_RD(regs->dfut[tbl_offset]); - unicast_reg &= (0xFF << (8 * reg_offset)); - MVGBE_REG_WR(regs->dfut[tbl_offset], unicast_reg); - break; - case ACCEPT_MAC_ADDR: - /* Set accepts frame bit at unicast DA filter table entry */ - unicast_reg = MVGBE_REG_RD(regs->dfut[tbl_offset]); - unicast_reg &= (0xFF << (8 * reg_offset)); - unicast_reg |= ((0x01 | (RXUQ << 1)) << (8 * reg_offset)); - MVGBE_REG_WR(regs->dfut[tbl_offset], unicast_reg); - break; - default: - return 0; - } - return 1; -} - -/* - * port_uc_addr_set - This function Set the port Unicast address. - */ -static void port_uc_addr_set(struct mvgbe_registers *regs, u8 * p_addr) -{ - u32 mac_h; - u32 mac_l; - - mac_l = (p_addr[4] << 8) | (p_addr[5]); - mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) | - (p_addr[3] << 0); - - MVGBE_REG_WR(regs->macal, mac_l); - MVGBE_REG_WR(regs->macah, mac_h); - - /* Accept frames of this address */ - port_uc_addr(regs, p_addr[5], ACCEPT_MAC_ADDR); -} - -/* - * mvgbe_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory. - */ -static void mvgbe_init_rx_desc_ring(struct mvgbe_device *dmvgbe) -{ - struct mvgbe_rxdesc *p_rx_desc; - int i; - - /* initialize the Rx descriptors ring */ - p_rx_desc = dmvgbe->p_rxdesc; - for (i = 0; i < RINGSZ; i++) { - p_rx_desc->cmd_sts = - MVGBE_BUFFER_OWNED_BY_DMA | MVGBE_RX_EN_INTERRUPT; - p_rx_desc->buf_size = PKTSIZE_ALIGN; - p_rx_desc->byte_cnt = 0; - p_rx_desc->buf_ptr = dmvgbe->p_rxbuf + i * PKTSIZE_ALIGN; - if (i == (RINGSZ - 1)) - p_rx_desc->nxtdesc_p = dmvgbe->p_rxdesc; - else { - p_rx_desc->nxtdesc_p = (struct mvgbe_rxdesc *) - ((u32) p_rx_desc + MV_RXQ_DESC_ALIGNED_SIZE); - p_rx_desc = p_rx_desc->nxtdesc_p; - } - } - dmvgbe->p_rxdesc_curr = dmvgbe->p_rxdesc; -} - -static int mvgbe_init(struct eth_device *dev) -{ - struct mvgbe_device *dmvgbe = to_mvgbe(dev); - struct mvgbe_registers *regs = dmvgbe->regs; -#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \ - !defined(CONFIG_PHYLIB) && \ - defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) - int i; -#endif - /* setup RX rings */ - mvgbe_init_rx_desc_ring(dmvgbe); - - /* Clear the ethernet port interrupts */ - MVGBE_REG_WR(regs->ic, 0); - MVGBE_REG_WR(regs->ice, 0); - /* Unmask RX buffer and TX end interrupt */ - MVGBE_REG_WR(regs->pim, INT_CAUSE_UNMASK_ALL); - /* Unmask phy and link status changes interrupts */ - MVGBE_REG_WR(regs->peim, INT_CAUSE_UNMASK_ALL_EXT); - - set_dram_access(regs); - port_init_mac_tables(regs); - port_uc_addr_set(regs, dmvgbe->dev.enetaddr); - - /* Assign port configuration and command. */ - MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL); - MVGBE_REG_WR(regs->pxcx, PORT_CFG_EXTEND_VALUE); - MVGBE_REG_WR(regs->psc0, PORT_SERIAL_CONTROL_VALUE); - - /* Assign port SDMA configuration */ - MVGBE_REG_WR(regs->sdc, PORT_SDMA_CFG_VALUE); - MVGBE_REG_WR(regs->tqx[0].qxttbc, QTKNBKT_DEF_VAL); - MVGBE_REG_WR(regs->tqx[0].tqxtbc, - (QMTBS_DEF_VAL << 16) | QTKNRT_DEF_VAL); - /* Turn off the port/RXUQ bandwidth limitation */ - MVGBE_REG_WR(regs->pmtu, 0); - - /* Set maximum receive buffer to 9700 bytes */ - MVGBE_REG_WR(regs->psc0, MVGBE_MAX_RX_PACKET_9700BYTE - | (MVGBE_REG_RD(regs->psc0) & MRU_MASK)); - - /* Enable port initially */ - MVGBE_REG_BITS_SET(regs->psc0, MVGBE_SERIAL_PORT_EN); - - /* - * Set ethernet MTU for leaky bucket mechanism to 0 - this will - * disable the leaky bucket mechanism . - */ - MVGBE_REG_WR(regs->pmtu, 0); - - /* Assignment of Rx CRDB of given RXUQ */ - MVGBE_REG_WR(regs->rxcdp[RXUQ], (u32) dmvgbe->p_rxdesc_curr); - /* ensure previous write is done before enabling Rx DMA */ - isb(); - /* Enable port Rx. */ - MVGBE_REG_WR(regs->rqc, (1 << RXUQ)); - -#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \ - !defined(CONFIG_PHYLIB) && \ - defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) - /* Wait up to 5s for the link status */ - for (i = 0; i < 5; i++) { - u16 phyadr; - - miiphy_read(dev->name, MV_PHY_ADR_REQUEST, - MV_PHY_ADR_REQUEST, &phyadr); - /* Return if we get link up */ - if (miiphy_link(dev->name, phyadr)) - return 0; - udelay(1000000); - } - - printf("No link on %s\n", dev->name); - return -1; -#endif - return 0; -} - -static int mvgbe_halt(struct eth_device *dev) -{ - struct mvgbe_device *dmvgbe = to_mvgbe(dev); - struct mvgbe_registers *regs = dmvgbe->regs; - - /* Disable all gigE address decoder */ - MVGBE_REG_WR(regs->bare, 0x3f); - - stop_queue(®s->tqc); - stop_queue(®s->rqc); - - /* Disable port */ - MVGBE_REG_BITS_RESET(regs->psc0, MVGBE_SERIAL_PORT_EN); - /* Set port is not reset */ - MVGBE_REG_BITS_RESET(regs->psc1, 1 << 4); -#ifdef CONFIG_SYS_MII_MODE - /* Set MMI interface up */ - MVGBE_REG_BITS_RESET(regs->psc1, 1 << 3); -#endif - /* Disable & mask ethernet port interrupts */ - MVGBE_REG_WR(regs->ic, 0); - MVGBE_REG_WR(regs->ice, 0); - MVGBE_REG_WR(regs->pim, 0); - MVGBE_REG_WR(regs->peim, 0); - - return 0; -} - -static int mvgbe_write_hwaddr(struct eth_device *dev) -{ - struct mvgbe_device *dmvgbe = to_mvgbe(dev); - struct mvgbe_registers *regs = dmvgbe->regs; - - /* Programs net device MAC address after initialization */ - port_uc_addr_set(regs, dmvgbe->dev.enetaddr); - return 0; -} - -static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize) -{ - struct mvgbe_device *dmvgbe = to_mvgbe(dev); - struct mvgbe_registers *regs = dmvgbe->regs; - struct mvgbe_txdesc *p_txdesc = dmvgbe->p_txdesc; - void *p = (void *)dataptr; - u32 cmd_sts; - u32 txuq0_reg_addr; - - /* Copy buffer if it's misaligned */ - if ((u32) dataptr & 0x07) { - if (datasize > PKTSIZE_ALIGN) { - printf("Non-aligned data too large (%d)\n", - datasize); - return -1; - } - - memcpy(dmvgbe->p_aligned_txbuf, p, datasize); - p = dmvgbe->p_aligned_txbuf; - } - - p_txdesc->cmd_sts = MVGBE_ZERO_PADDING | MVGBE_GEN_CRC; - p_txdesc->cmd_sts |= MVGBE_TX_FIRST_DESC | MVGBE_TX_LAST_DESC; - p_txdesc->cmd_sts |= MVGBE_BUFFER_OWNED_BY_DMA; - p_txdesc->cmd_sts |= MVGBE_TX_EN_INTERRUPT; - p_txdesc->buf_ptr = (u8 *) p; - p_txdesc->byte_cnt = datasize; - - /* Set this tc desc as zeroth TXUQ */ - txuq0_reg_addr = (u32)®s->tcqdp[TXUQ]; - writel((u32) p_txdesc, txuq0_reg_addr); - - /* ensure tx desc writes above are performed before we start Tx DMA */ - isb(); - - /* Apply send command using zeroth TXUQ */ - MVGBE_REG_WR(regs->tqc, (1 << TXUQ)); - - /* - * wait for packet xmit completion - */ - cmd_sts = readl(&p_txdesc->cmd_sts); - while (cmd_sts & MVGBE_BUFFER_OWNED_BY_DMA) { - /* return fail if error is detected */ - if ((cmd_sts & (MVGBE_ERROR_SUMMARY | MVGBE_TX_LAST_FRAME)) == - (MVGBE_ERROR_SUMMARY | MVGBE_TX_LAST_FRAME) && - cmd_sts & (MVGBE_UR_ERROR | MVGBE_RL_ERROR)) { - printf("Err..(%s) in xmit packet\n", __FUNCTION__); - return -1; - } - cmd_sts = readl(&p_txdesc->cmd_sts); - }; - return 0; -} - -static int mvgbe_recv(struct eth_device *dev) -{ - struct mvgbe_device *dmvgbe = to_mvgbe(dev); - struct mvgbe_rxdesc *p_rxdesc_curr = dmvgbe->p_rxdesc_curr; - u32 cmd_sts; - u32 timeout = 0; - u32 rxdesc_curr_addr; - - /* wait untill rx packet available or timeout */ - do { - if (timeout < MVGBE_PHY_SMI_TIMEOUT) - timeout++; - else { - debug("%s time out...\n", __FUNCTION__); - return -1; - } - } while (readl(&p_rxdesc_curr->cmd_sts) & MVGBE_BUFFER_OWNED_BY_DMA); - - if (p_rxdesc_curr->byte_cnt != 0) { - debug("%s: Received %d byte Packet @ 0x%x (cmd_sts= %08x)\n", - __FUNCTION__, (u32) p_rxdesc_curr->byte_cnt, - (u32) p_rxdesc_curr->buf_ptr, - (u32) p_rxdesc_curr->cmd_sts); - } - - /* - * In case received a packet without first/last bits on - * OR the error summary bit is on, - * the packets needs to be dropeed. - */ - cmd_sts = readl(&p_rxdesc_curr->cmd_sts); - - if ((cmd_sts & - (MVGBE_RX_FIRST_DESC | MVGBE_RX_LAST_DESC)) - != (MVGBE_RX_FIRST_DESC | MVGBE_RX_LAST_DESC)) { - - printf("Err..(%s) Dropping packet spread on" - " multiple descriptors\n", __FUNCTION__); - - } else if (cmd_sts & MVGBE_ERROR_SUMMARY) { - - printf("Err..(%s) Dropping packet with errors\n", - __FUNCTION__); - - } else { - /* !!! call higher layer processing */ - debug("%s: Sending Received packet to" - " upper layer (NetReceive)\n", __FUNCTION__); - - /* let the upper layer handle the packet */ - NetReceive((p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET), - (int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET)); - } - /* - * free these descriptors and point next in the ring - */ - p_rxdesc_curr->cmd_sts = - MVGBE_BUFFER_OWNED_BY_DMA | MVGBE_RX_EN_INTERRUPT; - p_rxdesc_curr->buf_size = PKTSIZE_ALIGN; - p_rxdesc_curr->byte_cnt = 0; - - rxdesc_curr_addr = (u32)&dmvgbe->p_rxdesc_curr; - writel((unsigned)p_rxdesc_curr->nxtdesc_p, rxdesc_curr_addr); - - return 0; -} - -#if defined(CONFIG_PHYLIB) -int mvgbe_phylib_init(struct eth_device *dev, int phyid) -{ - struct mii_dev *bus; - struct phy_device *phydev; - int ret; - - bus = mdio_alloc(); - if (!bus) { - printf("mdio_alloc failed\n"); - return -ENOMEM; - } - bus->read = mvgbe_phy_read; - bus->write = mvgbe_phy_write; - sprintf(bus->name, dev->name); - - ret = mdio_register(bus); - if (ret) { - printf("mdio_register failed\n"); - free(bus); - return -ENOMEM; - } - - /* Set phy address of the port */ - mvgbe_phy_write(bus, MV_PHY_ADR_REQUEST, 0, MV_PHY_ADR_REQUEST, phyid); - - phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RGMII); - if (!phydev) { - printf("phy_connect failed\n"); - return -ENODEV; - } - - phy_config(phydev); - phy_startup(phydev); - - return 0; -} -#endif - -int mvgbe_initialize(bd_t *bis) -{ - struct mvgbe_device *dmvgbe; - struct eth_device *dev; - int devnum; - u8 used_ports[MAX_MVGBE_DEVS] = CONFIG_MVGBE_PORTS; - - for (devnum = 0; devnum < MAX_MVGBE_DEVS; devnum++) { - /*skip if port is configured not to use */ - if (used_ports[devnum] == 0) - continue; - - dmvgbe = malloc(sizeof(struct mvgbe_device)); - - if (!dmvgbe) - goto error1; - - memset(dmvgbe, 0, sizeof(struct mvgbe_device)); - - dmvgbe->p_rxdesc = - (struct mvgbe_rxdesc *)memalign(PKTALIGN, - MV_RXQ_DESC_ALIGNED_SIZE*RINGSZ + 1); - - if (!dmvgbe->p_rxdesc) - goto error2; - - dmvgbe->p_rxbuf = (u8 *) memalign(PKTALIGN, - RINGSZ*PKTSIZE_ALIGN + 1); - - if (!dmvgbe->p_rxbuf) - goto error3; - - dmvgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN); - - if (!dmvgbe->p_aligned_txbuf) - goto error4; - - dmvgbe->p_txdesc = (struct mvgbe_txdesc *) memalign( - PKTALIGN, sizeof(struct mvgbe_txdesc) + 1); - - if (!dmvgbe->p_txdesc) { - free(dmvgbe->p_aligned_txbuf); -error4: - free(dmvgbe->p_rxbuf); -error3: - free(dmvgbe->p_rxdesc); -error2: - free(dmvgbe); -error1: - printf("Err.. %s Failed to allocate memory\n", - __FUNCTION__); - return -1; - } - - dev = &dmvgbe->dev; - - /* must be less than sizeof(dev->name) */ - sprintf(dev->name, "egiga%d", devnum); - - switch (devnum) { - case 0: - dmvgbe->regs = (void *)MVGBE0_BASE; - break; -#if defined(MVGBE1_BASE) - case 1: - dmvgbe->regs = (void *)MVGBE1_BASE; - break; -#endif - default: /* this should never happen */ - printf("Err..(%s) Invalid device number %d\n", - __FUNCTION__, devnum); - return -1; - } - - dev->init = (void *)mvgbe_init; - dev->halt = (void *)mvgbe_halt; - dev->send = (void *)mvgbe_send; - dev->recv = (void *)mvgbe_recv; - dev->write_hwaddr = (void *)mvgbe_write_hwaddr; - - eth_register(dev); - -#if defined(CONFIG_PHYLIB) - mvgbe_phylib_init(dev, PHY_BASE_ADR + devnum); -#elif defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - miiphy_register(dev->name, smi_reg_read, smi_reg_write); - /* Set phy address of the port */ - miiphy_write(dev->name, MV_PHY_ADR_REQUEST, - MV_PHY_ADR_REQUEST, PHY_BASE_ADR + devnum); -#endif - } - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/mvgbe.h b/qemu/roms/u-boot/drivers/net/mvgbe.h deleted file mode 100644 index 27a3f41e8..000000000 --- a/qemu/roms/u-boot/drivers/net/mvgbe.h +++ /dev/null @@ -1,498 +0,0 @@ -/* - * (C) Copyright 2009 - * Marvell Semiconductor <www.marvell.com> - * Written-by: Prafulla Wadaskar <prafulla@marvell.com> - * - * based on - Driver for MV64360X ethernet ports - * Copyright (C) 2002 rabeeh@galileo.co.il - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __MVGBE_H__ -#define __MVGBE_H__ - -/* PHY_BASE_ADR is board specific and can be configured */ -#if defined (CONFIG_PHY_BASE_ADR) -#define PHY_BASE_ADR CONFIG_PHY_BASE_ADR -#else -#define PHY_BASE_ADR 0x08 /* default phy base addr */ -#endif - -/* Constants */ -#define INT_CAUSE_UNMASK_ALL 0x0007ffff -#define INT_CAUSE_UNMASK_ALL_EXT 0x0011ffff -#define MRU_MASK 0xfff1ffff -#define PHYADR_MASK 0x0000001f -#define PHYREG_MASK 0x0000001f -#define QTKNBKT_DEF_VAL 0x3fffffff -#define QMTBS_DEF_VAL 0x000003ff -#define QTKNRT_DEF_VAL 0x0000fcff -#define RXUQ 0 /* Used Rx queue */ -#define TXUQ 0 /* Used Rx queue */ - -#define to_mvgbe(_d) container_of(_d, struct mvgbe_device, dev) -#define MVGBE_REG_WR(adr, val) writel(val, &adr) -#define MVGBE_REG_RD(adr) readl(&adr) -#define MVGBE_REG_BITS_RESET(adr, val) writel(readl(&adr) & ~(val), &adr) -#define MVGBE_REG_BITS_SET(adr, val) writel(readl(&adr) | val, &adr) - -/* Default port configuration value */ -#define PRT_CFG_VAL ( \ - MVGBE_UCAST_MOD_NRML | \ - MVGBE_DFLT_RXQ(RXUQ) | \ - MVGBE_DFLT_RX_ARPQ(RXUQ) | \ - MVGBE_RX_BC_IF_NOT_IP_OR_ARP | \ - MVGBE_RX_BC_IF_IP | \ - MVGBE_RX_BC_IF_ARP | \ - MVGBE_CPTR_TCP_FRMS_DIS | \ - MVGBE_CPTR_UDP_FRMS_DIS | \ - MVGBE_DFLT_RX_TCPQ(RXUQ) | \ - MVGBE_DFLT_RX_UDPQ(RXUQ) | \ - MVGBE_DFLT_RX_BPDUQ(RXUQ)) - -/* Default port extend configuration value */ -#define PORT_CFG_EXTEND_VALUE \ - MVGBE_SPAN_BPDU_PACKETS_AS_NORMAL | \ - MVGBE_PARTITION_DIS | \ - MVGBE_TX_CRC_GENERATION_EN - -#define GT_MVGBE_IPG_INT_RX(value) ((value & 0x3fff) << 8) - -/* Default sdma control value */ -#define PORT_SDMA_CFG_VALUE ( \ - MVGBE_RX_BURST_SIZE_16_64BIT | \ - MVGBE_BLM_RX_NO_SWAP | \ - MVGBE_BLM_TX_NO_SWAP | \ - GT_MVGBE_IPG_INT_RX(RXUQ) | \ - MVGBE_TX_BURST_SIZE_16_64BIT) - -/* Default port serial control value */ -#ifndef PORT_SERIAL_CONTROL_VALUE -#define PORT_SERIAL_CONTROL_VALUE ( \ - MVGBE_FORCE_LINK_PASS | \ - MVGBE_DIS_AUTO_NEG_FOR_DUPLX | \ - MVGBE_DIS_AUTO_NEG_FOR_FLOW_CTRL | \ - MVGBE_ADV_NO_FLOW_CTRL | \ - MVGBE_FORCE_FC_MODE_NO_PAUSE_DIS_TX | \ - MVGBE_FORCE_BP_MODE_NO_JAM | \ - (1 << 9) /* Reserved bit has to be 1 */ | \ - MVGBE_DO_NOT_FORCE_LINK_FAIL | \ - MVGBE_EN_AUTO_NEG_SPEED_GMII | \ - MVGBE_DTE_ADV_0 | \ - MVGBE_MIIPHY_MAC_MODE | \ - MVGBE_AUTO_NEG_NO_CHANGE | \ - MVGBE_MAX_RX_PACKET_1552BYTE | \ - MVGBE_CLR_EXT_LOOPBACK | \ - MVGBE_SET_FULL_DUPLEX_MODE | \ - MVGBE_DIS_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX) -#endif - -/* Tx WRR confoguration macros */ -#define PORT_MAX_TRAN_UNIT 0x24 /* MTU register (default) 9KByte */ -#define PORT_MAX_TOKEN_BUCKET_SIZE 0x_FFFF /* PMTBS reg (default) */ -#define PORT_TOKEN_RATE 1023 /* PTTBRC reg (default) */ -/* MAC accepet/reject macros */ -#define ACCEPT_MAC_ADDR 0 -#define REJECT_MAC_ADDR 1 -/* Size of a Tx/Rx descriptor used in chain list data structure */ -#define MV_RXQ_DESC_ALIGNED_SIZE \ - (((sizeof(struct mvgbe_rxdesc) / PKTALIGN) + 1) * PKTALIGN) -/* Buffer offset from buffer pointer */ -#define RX_BUF_OFFSET 0x2 - -/* Port serial status reg (PSR) */ -#define MVGBE_INTERFACE_GMII_MII 0 -#define MVGBE_INTERFACE_PCM 1 -#define MVGBE_LINK_IS_DOWN 0 -#define MVGBE_LINK_IS_UP (1 << 1) -#define MVGBE_PORT_AT_HALF_DUPLEX 0 -#define MVGBE_PORT_AT_FULL_DUPLEX (1 << 2) -#define MVGBE_RX_FLOW_CTRL_DISD 0 -#define MVGBE_RX_FLOW_CTRL_ENBALED (1 << 3) -#define MVGBE_GMII_SPEED_100_10 0 -#define MVGBE_GMII_SPEED_1000 (1 << 4) -#define MVGBE_MII_SPEED_10 0 -#define MVGBE_MII_SPEED_100 (1 << 5) -#define MVGBE_NO_TX 0 -#define MVGBE_TX_IN_PROGRESS (1 << 7) -#define MVGBE_BYPASS_NO_ACTIVE 0 -#define MVGBE_BYPASS_ACTIVE (1 << 8) -#define MVGBE_PORT_NOT_AT_PARTN_STT 0 -#define MVGBE_PORT_AT_PARTN_STT (1 << 9) -#define MVGBE_PORT_TX_FIFO_NOT_EMPTY 0 -#define MVGBE_PORT_TX_FIFO_EMPTY (1 << 10) - -/* These macros describes the Port configuration reg (Px_cR) bits */ -#define MVGBE_UCAST_MOD_NRML 0 -#define MVGBE_UNICAST_PROMISCUOUS_MODE 1 -#define MVGBE_DFLT_RXQ(_x) (_x << 1) -#define MVGBE_DFLT_RX_ARPQ(_x) (_x << 4) -#define MVGBE_RX_BC_IF_NOT_IP_OR_ARP 0 -#define MVGBE_REJECT_BC_IF_NOT_IP_OR_ARP (1 << 7) -#define MVGBE_RX_BC_IF_IP 0 -#define MVGBE_REJECT_BC_IF_IP (1 << 8) -#define MVGBE_RX_BC_IF_ARP 0 -#define MVGBE_REJECT_BC_IF_ARP (1 << 9) -#define MVGBE_TX_AM_NO_UPDATE_ERR_SMRY (1 << 12) -#define MVGBE_CPTR_TCP_FRMS_DIS 0 -#define MVGBE_CPTR_TCP_FRMS_EN (1 << 14) -#define MVGBE_CPTR_UDP_FRMS_DIS 0 -#define MVGBE_CPTR_UDP_FRMS_EN (1 << 15) -#define MVGBE_DFLT_RX_TCPQ(_x) (_x << 16) -#define MVGBE_DFLT_RX_UDPQ(_x) (_x << 19) -#define MVGBE_DFLT_RX_BPDUQ(_x) (_x << 22) -#define MVGBE_DFLT_RX_TCP_CHKSUM_MODE (1 << 25) - -/* These macros describes the Port configuration extend reg (Px_cXR) bits*/ -#define MVGBE_CLASSIFY_EN 1 -#define MVGBE_SPAN_BPDU_PACKETS_AS_NORMAL 0 -#define MVGBE_SPAN_BPDU_PACKETS_TO_RX_Q7 (1 << 1) -#define MVGBE_PARTITION_DIS 0 -#define MVGBE_PARTITION_EN (1 << 2) -#define MVGBE_TX_CRC_GENERATION_EN 0 -#define MVGBE_TX_CRC_GENERATION_DIS (1 << 3) - -/* These macros describes the Port Sdma configuration reg (SDCR) bits */ -#define MVGBE_RIFB 1 -#define MVGBE_RX_BURST_SIZE_1_64BIT 0 -#define MVGBE_RX_BURST_SIZE_2_64BIT (1 << 1) -#define MVGBE_RX_BURST_SIZE_4_64BIT (1 << 2) -#define MVGBE_RX_BURST_SIZE_8_64BIT ((1 << 2) | (1 << 1)) -#define MVGBE_RX_BURST_SIZE_16_64BIT (1 << 3) -#define MVGBE_BLM_RX_NO_SWAP (1 << 4) -#define MVGBE_BLM_RX_BYTE_SWAP 0 -#define MVGBE_BLM_TX_NO_SWAP (1 << 5) -#define MVGBE_BLM_TX_BYTE_SWAP 0 -#define MVGBE_DESCRIPTORS_BYTE_SWAP (1 << 6) -#define MVGBE_DESCRIPTORS_NO_SWAP 0 -#define MVGBE_TX_BURST_SIZE_1_64BIT 0 -#define MVGBE_TX_BURST_SIZE_2_64BIT (1 << 22) -#define MVGBE_TX_BURST_SIZE_4_64BIT (1 << 23) -#define MVGBE_TX_BURST_SIZE_8_64BIT ((1 << 23) | (1 << 22)) -#define MVGBE_TX_BURST_SIZE_16_64BIT (1 << 24) - -/* These macros describes the Port serial control reg (PSCR) bits */ -#define MVGBE_SERIAL_PORT_DIS 0 -#define MVGBE_SERIAL_PORT_EN 1 -#define MVGBE_FORCE_LINK_PASS (1 << 1) -#define MVGBE_DO_NOT_FORCE_LINK_PASS 0 -#define MVGBE_EN_AUTO_NEG_FOR_DUPLX 0 -#define MVGBE_DIS_AUTO_NEG_FOR_DUPLX (1 << 2) -#define MVGBE_EN_AUTO_NEG_FOR_FLOW_CTRL 0 -#define MVGBE_DIS_AUTO_NEG_FOR_FLOW_CTRL (1 << 3) -#define MVGBE_ADV_NO_FLOW_CTRL 0 -#define MVGBE_ADV_SYMMETRIC_FLOW_CTRL (1 << 4) -#define MVGBE_FORCE_FC_MODE_NO_PAUSE_DIS_TX 0 -#define MVGBE_FORCE_FC_MODE_TX_PAUSE_DIS (1 << 5) -#define MVGBE_FORCE_BP_MODE_NO_JAM 0 -#define MVGBE_FORCE_BP_MODE_JAM_TX (1 << 7) -#define MVGBE_FORCE_BP_MODE_JAM_TX_ON_RX_ERR (1 << 8) -#define MVGBE_FORCE_LINK_FAIL 0 -#define MVGBE_DO_NOT_FORCE_LINK_FAIL (1 << 10) -#define MVGBE_DIS_AUTO_NEG_SPEED_GMII (1 << 13) -#define MVGBE_EN_AUTO_NEG_SPEED_GMII 0 -#define MVGBE_DTE_ADV_0 0 -#define MVGBE_DTE_ADV_1 (1 << 14) -#define MVGBE_MIIPHY_MAC_MODE 0 -#define MVGBE_MIIPHY_PHY_MODE (1 << 15) -#define MVGBE_AUTO_NEG_NO_CHANGE 0 -#define MVGBE_RESTART_AUTO_NEG (1 << 16) -#define MVGBE_MAX_RX_PACKET_1518BYTE 0 -#define MVGBE_MAX_RX_PACKET_1522BYTE (1 << 17) -#define MVGBE_MAX_RX_PACKET_1552BYTE (1 << 18) -#define MVGBE_MAX_RX_PACKET_9022BYTE ((1 << 18) | (1 << 17)) -#define MVGBE_MAX_RX_PACKET_9192BYTE (1 << 19) -#define MVGBE_MAX_RX_PACKET_9700BYTE ((1 << 19) | (1 << 17)) -#define MVGBE_SET_EXT_LOOPBACK (1 << 20) -#define MVGBE_CLR_EXT_LOOPBACK 0 -#define MVGBE_SET_FULL_DUPLEX_MODE (1 << 21) -#define MVGBE_SET_HALF_DUPLEX_MODE 0 -#define MVGBE_EN_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX (1 << 22) -#define MVGBE_DIS_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX 0 -#define MVGBE_SET_GMII_SPEED_TO_10_100 0 -#define MVGBE_SET_GMII_SPEED_TO_1000 (1 << 23) -#define MVGBE_SET_MII_SPEED_TO_10 0 -#define MVGBE_SET_MII_SPEED_TO_100 (1 << 24) - -/* SMI register fields */ -#define MVGBE_PHY_SMI_TIMEOUT 10000 -#define MVGBE_PHY_SMI_DATA_OFFS 0 /* Data */ -#define MVGBE_PHY_SMI_DATA_MASK (0xffff << MVGBE_PHY_SMI_DATA_OFFS) -#define MVGBE_PHY_SMI_DEV_ADDR_OFFS 16 /* PHY device address */ -#define MVGBE_PHY_SMI_DEV_ADDR_MASK \ - (PHYADR_MASK << MVGBE_PHY_SMI_DEV_ADDR_OFFS) -#define MVGBE_SMI_REG_ADDR_OFFS 21 /* PHY device reg addr */ -#define MVGBE_SMI_REG_ADDR_MASK \ - (PHYADR_MASK << MVGBE_SMI_REG_ADDR_OFFS) -#define MVGBE_PHY_SMI_OPCODE_OFFS 26 /* Write/Read opcode */ -#define MVGBE_PHY_SMI_OPCODE_MASK (3 << MVGBE_PHY_SMI_OPCODE_OFFS) -#define MVGBE_PHY_SMI_OPCODE_WRITE (0 << MVGBE_PHY_SMI_OPCODE_OFFS) -#define MVGBE_PHY_SMI_OPCODE_READ (1 << MVGBE_PHY_SMI_OPCODE_OFFS) -#define MVGBE_PHY_SMI_READ_VALID_MASK (1 << 27) /* Read Valid */ -#define MVGBE_PHY_SMI_BUSY_MASK (1 << 28) /* Busy */ - -/* SDMA command status fields macros */ -/* Tx & Rx descriptors status */ -#define MVGBE_ERROR_SUMMARY 1 -/* Tx & Rx descriptors command */ -#define MVGBE_BUFFER_OWNED_BY_DMA (1 << 31) -/* Tx descriptors status */ -#define MVGBE_LC_ERROR 0 -#define MVGBE_UR_ERROR (1 << 1) -#define MVGBE_RL_ERROR (1 << 2) -#define MVGBE_LLC_SNAP_FORMAT (1 << 9) -#define MVGBE_TX_LAST_FRAME (1 << 20) - -/* Rx descriptors status */ -#define MVGBE_CRC_ERROR 0 -#define MVGBE_OVERRUN_ERROR (1 << 1) -#define MVGBE_MAX_FRAME_LENGTH_ERROR (1 << 2) -#define MVGBE_RESOURCE_ERROR ((1 << 2) | (1 << 1)) -#define MVGBE_VLAN_TAGGED (1 << 19) -#define MVGBE_BPDU_FRAME (1 << 20) -#define MVGBE_TCP_FRAME_OVER_IP_V_4 0 -#define MVGBE_UDP_FRAME_OVER_IP_V_4 (1 << 21) -#define MVGBE_OTHER_FRAME_TYPE (1 << 22) -#define MVGBE_LAYER_2_IS_MVGBE_V_2 (1 << 23) -#define MVGBE_FRAME_TYPE_IP_V_4 (1 << 24) -#define MVGBE_FRAME_HEADER_OK (1 << 25) -#define MVGBE_RX_LAST_DESC (1 << 26) -#define MVGBE_RX_FIRST_DESC (1 << 27) -#define MVGBE_UNKNOWN_DESTINATION_ADDR (1 << 28) -#define MVGBE_RX_EN_INTERRUPT (1 << 29) -#define MVGBE_LAYER_4_CHECKSUM_OK (1 << 30) - -/* Rx descriptors byte count */ -#define MVGBE_FRAME_FRAGMENTED (1 << 2) - -/* Tx descriptors command */ -#define MVGBE_LAYER_4_CHECKSUM_FIRST_DESC (1 << 10) -#define MVGBE_FRAME_SET_TO_VLAN (1 << 15) -#define MVGBE_TCP_FRAME 0 -#define MVGBE_UDP_FRAME (1 << 16) -#define MVGBE_GEN_TCP_UDP_CHECKSUM (1 << 17) -#define MVGBE_GEN_IP_V_4_CHECKSUM (1 << 18) -#define MVGBE_ZERO_PADDING (1 << 19) -#define MVGBE_TX_LAST_DESC (1 << 20) -#define MVGBE_TX_FIRST_DESC (1 << 21) -#define MVGBE_GEN_CRC (1 << 22) -#define MVGBE_TX_EN_INTERRUPT (1 << 23) -#define MVGBE_AUTO_MODE (1 << 30) - -/* Address decode parameters */ -/* Ethernet Base Address Register bits */ -#define EBAR_TARGET_DRAM 0x00000000 -#define EBAR_TARGET_DEVICE 0x00000001 -#define EBAR_TARGET_CBS 0x00000002 -#define EBAR_TARGET_PCI0 0x00000003 -#define EBAR_TARGET_PCI1 0x00000004 -#define EBAR_TARGET_CUNIT 0x00000005 -#define EBAR_TARGET_AUNIT 0x00000006 -#define EBAR_TARGET_GUNIT 0x00000007 - -/* Window attrib */ -#if defined(CONFIG_DOVE) -#define EBAR_DRAM_CS0 0x00000000 -#define EBAR_DRAM_CS1 0x00000000 -#define EBAR_DRAM_CS2 0x00000000 -#define EBAR_DRAM_CS3 0x00000000 -#else -#define EBAR_DRAM_CS0 0x00000E00 -#define EBAR_DRAM_CS1 0x00000D00 -#define EBAR_DRAM_CS2 0x00000B00 -#define EBAR_DRAM_CS3 0x00000700 -#endif - -/* DRAM Target interface */ -#define EBAR_DRAM_NO_CACHE_COHERENCY 0x00000000 -#define EBAR_DRAM_CACHE_COHERENCY_WT 0x00001000 -#define EBAR_DRAM_CACHE_COHERENCY_WB 0x00002000 - -/* Device Bus Target interface */ -#define EBAR_DEVICE_DEVCS0 0x00001E00 -#define EBAR_DEVICE_DEVCS1 0x00001D00 -#define EBAR_DEVICE_DEVCS2 0x00001B00 -#define EBAR_DEVICE_DEVCS3 0x00001700 -#define EBAR_DEVICE_BOOTCS3 0x00000F00 - -/* PCI Target interface */ -#define EBAR_PCI_BYTE_SWAP 0x00000000 -#define EBAR_PCI_NO_SWAP 0x00000100 -#define EBAR_PCI_BYTE_WORD_SWAP 0x00000200 -#define EBAR_PCI_WORD_SWAP 0x00000300 -#define EBAR_PCI_NO_SNOOP_NOT_ASSERT 0x00000000 -#define EBAR_PCI_NO_SNOOP_ASSERT 0x00000400 -#define EBAR_PCI_IO_SPACE 0x00000000 -#define EBAR_PCI_MEMORY_SPACE 0x00000800 -#define EBAR_PCI_REQ64_FORCE 0x00000000 -#define EBAR_PCI_REQ64_SIZE 0x00001000 - -/* Window access control */ -#define EWIN_ACCESS_NOT_ALLOWED 0 -#define EWIN_ACCESS_READ_ONLY 1 -#define EWIN_ACCESS_FULL ((1 << 1) | 1) - -/* structures represents Controller registers */ -struct mvgbe_barsz { - u32 bar; - u32 size; -}; - -struct mvgbe_rxcdp { - struct mvgbe_rxdesc *rxcdp; - u32 rxcdp_pad[3]; -}; - -struct mvgbe_tqx { - u32 qxttbc; - u32 tqxtbc; - u32 tqxac; - u32 tqxpad; -}; - -struct mvgbe_registers { - u32 phyadr; - u32 smi; - u32 euda; - u32 eudid; - u8 pad1[0x080 - 0x00c - 4]; - u32 euic; - u32 euim; - u8 pad2[0x094 - 0x084 - 4]; - u32 euea; - u32 euiae; - u8 pad3[0x0b0 - 0x098 - 4]; - u32 euc; - u8 pad3a[0x200 - 0x0b0 - 4]; - struct mvgbe_barsz barsz[6]; - u8 pad4[0x280 - 0x22c - 4]; - u32 ha_remap[4]; - u32 bare; - u32 epap; - u8 pad5[0x400 - 0x294 - 4]; - u32 pxc; - u32 pxcx; - u32 mii_ser_params; - u8 pad6[0x410 - 0x408 - 4]; - u32 evlane; - u32 macal; - u32 macah; - u32 sdc; - u32 dscp[7]; - u32 psc0; - u32 vpt2p; - u32 ps0; - u32 tqc; - u32 psc1; - u32 ps1; - u32 mrvl_header; - u8 pad7[0x460 - 0x454 - 4]; - u32 ic; - u32 ice; - u32 pim; - u32 peim; - u8 pad8[0x474 - 0x46c - 4]; - u32 pxtfut; - u32 pad9; - u32 pxmfs; - u32 pad10; - u32 pxdfc; - u32 pxofc; - u8 pad11[0x494 - 0x488 - 4]; - u32 peuiae; - u8 pad12[0x4bc - 0x494 - 4]; - u32 eth_type_prio; - u8 pad13[0x4dc - 0x4bc - 4]; - u32 tqfpc; - u32 pttbrc; - u32 tqc1; - u32 pmtu; - u32 pmtbs; - u8 pad14[0x60c - 0x4ec - 4]; - struct mvgbe_rxcdp rxcdp[7]; - struct mvgbe_rxdesc *rxcdp7; - u32 rqc; - struct mvgbe_txdesc *tcsdp; - u8 pad15[0x6c0 - 0x684 - 4]; - struct mvgbe_txdesc *tcqdp[8]; - u8 pad16[0x700 - 0x6dc - 4]; - struct mvgbe_tqx tqx[8]; - u32 pttbc; - u8 pad17[0x7a8 - 0x780 - 4]; - u32 tqxipg0; - u32 pad18[3]; - u32 tqxipg1; - u8 pad19[0x7c0 - 0x7b8 - 4]; - u32 hitkninlopkt; - u32 hitkninasyncpkt; - u32 lotkninasyncpkt; - u32 pad20; - u32 ts; - u8 pad21[0x3000 - 0x27d0 - 4]; - u32 pad20_1[32]; /* mib counter registes */ - u8 pad22[0x3400 - 0x3000 - sizeof(u32) * 32]; - u32 dfsmt[64]; - u32 dfomt[64]; - u32 dfut[4]; - u8 pad23[0xe20c0 - 0x7360c - 4]; - u32 pmbus_top_arbiter; -}; - -/* structures/enums needed by driver */ -enum mvgbe_adrwin { - MVGBE_WIN0, - MVGBE_WIN1, - MVGBE_WIN2, - MVGBE_WIN3, - MVGBE_WIN4, - MVGBE_WIN5 -}; - -enum mvgbe_target { - MVGBE_TARGET_DRAM, - MVGBE_TARGET_DEV, - MVGBE_TARGET_CBS, - MVGBE_TARGET_PCI0, - MVGBE_TARGET_PCI1 -}; - -struct mvgbe_winparam { - enum mvgbe_adrwin win; /* Window number */ - enum mvgbe_target target; /* System targets */ - u16 attrib; /* BAR attrib. See above macros */ - u32 base_addr; /* Window base address in u32 form */ - u32 high_addr; /* Window high address in u32 form */ - u32 size; /* Size in MBytes. Must be % 64Kbyte. */ - int enable; /* Enable/disable access to the window. */ - u16 access_ctrl; /*Access ctrl register. see above macros */ -}; - -struct mvgbe_rxdesc { - u32 cmd_sts; /* Descriptor command status */ - u16 buf_size; /* Buffer size */ - u16 byte_cnt; /* Descriptor buffer byte count */ - u8 *buf_ptr; /* Descriptor buffer pointer */ - struct mvgbe_rxdesc *nxtdesc_p; /* Next descriptor pointer */ -}; - -struct mvgbe_txdesc { - u32 cmd_sts; /* Descriptor command status */ - u16 l4i_chk; /* CPU provided TCP Checksum */ - u16 byte_cnt; /* Descriptor buffer byte count */ - u8 *buf_ptr; /* Descriptor buffer ptr */ - struct mvgbe_txdesc *nxtdesc_p; /* Next descriptor ptr */ -}; - -/* port device data struct */ -struct mvgbe_device { - struct eth_device dev; - struct mvgbe_registers *regs; - struct mvgbe_txdesc *p_txdesc; - struct mvgbe_rxdesc *p_rxdesc; - struct mvgbe_rxdesc *p_rxdesc_curr; - u8 *p_rxbuf; - u8 *p_aligned_txbuf; -}; - -#endif /* __MVGBE_H__ */ diff --git a/qemu/roms/u-boot/drivers/net/natsemi.c b/qemu/roms/u-boot/drivers/net/natsemi.c deleted file mode 100644 index 04743bd2b..000000000 --- a/qemu/roms/u-boot/drivers/net/natsemi.c +++ /dev/null @@ -1,882 +0,0 @@ -/* - natsemi.c: A U-Boot driver for the NatSemi DP8381x series. - Author: Mark A. Rakes (mark_rakes@vivato.net) - - Adapted from an Etherboot driver written by: - - Copyright (C) 2001 Entity Cyber, Inc. - - This development of this Etherboot driver was funded by - - Sicom Systems: http://www.sicompos.com/ - - Author: Marty Connor (mdc@thinguin.org) - Adapted from a Linux driver which was written by Donald Becker - - This software may be used and distributed according to the terms - of the GNU Public License (GPL), incorporated herein by reference. - - Original Copyright Notice: - - Written/copyright 1999-2001 by Donald Becker. - - This software may be used and distributed according to the terms of - the GNU General Public License (GPL), incorporated herein by reference. - Drivers based on or derived from this code fall under the GPL and must - retain the authorship, copyright and license notice. This file is not - a complete program and may only be used when the entire operating - system is licensed under the GPL. License for under other terms may be - available. Contact the original author for details. - - The original author may be reached as becker@scyld.com, or at - Scyld Computing Corporation - 410 Severn Ave., Suite 210 - Annapolis MD 21403 - - Support information and updates available at - http://www.scyld.com/network/netsemi.html - - References: - http://www.scyld.com/expert/100mbps.html - http://www.scyld.com/expert/NWay.html - Datasheet is available from: - http://www.national.com/pf/DP/DP83815.html -*/ - -/* Revision History - * October 2002 mar 1.0 - * Initial U-Boot Release. Tested with Netgear FA311 board - * and dp83815 chipset on custom board -*/ - -/* Includes */ -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <asm/io.h> -#include <pci.h> - -/* defines */ -#define EEPROM_SIZE 0xb /*12 16-bit chunks, or 24 bytes*/ - -#define DSIZE 0x00000FFF -#define ETH_ALEN 6 -#define CRC_SIZE 4 -#define TOUT_LOOP 500000 -#define TX_BUF_SIZE 1536 -#define RX_BUF_SIZE 1536 -#define NUM_RX_DESC 4 /* Number of Rx descriptor registers. */ - -/* Offsets to the device registers. - Unlike software-only systems, device drivers interact with complex hardware. - It's not useful to define symbolic names for every register bit in the - device. */ -enum register_offsets { - ChipCmd = 0x00, - ChipConfig = 0x04, - EECtrl = 0x08, - IntrMask = 0x14, - IntrEnable = 0x18, - TxRingPtr = 0x20, - TxConfig = 0x24, - RxRingPtr = 0x30, - RxConfig = 0x34, - ClkRun = 0x3C, - RxFilterAddr = 0x48, - RxFilterData = 0x4C, - SiliconRev = 0x58, - PCIPM = 0x44, - BasicControl = 0x80, - BasicStatus = 0x84, - /* These are from the spec, around page 78... on a separate table. */ - PGSEL = 0xCC, - PMDCSR = 0xE4, - TSTDAT = 0xFC, - DSPCFG = 0xF4, - SDCFG = 0x8C -}; - -/* Bit in ChipCmd. */ -enum ChipCmdBits { - ChipReset = 0x100, - RxReset = 0x20, - TxReset = 0x10, - RxOff = 0x08, - RxOn = 0x04, - TxOff = 0x02, - TxOn = 0x01 -}; - -enum ChipConfigBits { - LinkSts = 0x80000000, - HundSpeed = 0x40000000, - FullDuplex = 0x20000000, - TenPolarity = 0x10000000, - AnegDone = 0x08000000, - AnegEnBothBoth = 0x0000E000, - AnegDis100Full = 0x0000C000, - AnegEn100Both = 0x0000A000, - AnegDis100Half = 0x00008000, - AnegEnBothHalf = 0x00006000, - AnegDis10Full = 0x00004000, - AnegEn10Both = 0x00002000, - DuplexMask = 0x00008000, - SpeedMask = 0x00004000, - AnegMask = 0x00002000, - AnegDis10Half = 0x00000000, - ExtPhy = 0x00001000, - PhyRst = 0x00000400, - PhyDis = 0x00000200, - BootRomDisable = 0x00000004, - BEMode = 0x00000001, -}; - -enum TxConfig_bits { - TxDrthMask = 0x3f, - TxFlthMask = 0x3f00, - TxMxdmaMask = 0x700000, - TxMxdma_512 = 0x0, - TxMxdma_4 = 0x100000, - TxMxdma_8 = 0x200000, - TxMxdma_16 = 0x300000, - TxMxdma_32 = 0x400000, - TxMxdma_64 = 0x500000, - TxMxdma_128 = 0x600000, - TxMxdma_256 = 0x700000, - TxCollRetry = 0x800000, - TxAutoPad = 0x10000000, - TxMacLoop = 0x20000000, - TxHeartIgn = 0x40000000, - TxCarrierIgn = 0x80000000 -}; - -enum RxConfig_bits { - RxDrthMask = 0x3e, - RxMxdmaMask = 0x700000, - RxMxdma_512 = 0x0, - RxMxdma_4 = 0x100000, - RxMxdma_8 = 0x200000, - RxMxdma_16 = 0x300000, - RxMxdma_32 = 0x400000, - RxMxdma_64 = 0x500000, - RxMxdma_128 = 0x600000, - RxMxdma_256 = 0x700000, - RxAcceptLong = 0x8000000, - RxAcceptTx = 0x10000000, - RxAcceptRunt = 0x40000000, - RxAcceptErr = 0x80000000 -}; - -/* Bits in the RxMode register. */ -enum rx_mode_bits { - AcceptErr = 0x20, - AcceptRunt = 0x10, - AcceptBroadcast = 0xC0000000, - AcceptMulticast = 0x00200000, - AcceptAllMulticast = 0x20000000, - AcceptAllPhys = 0x10000000, - AcceptMyPhys = 0x08000000 -}; - -typedef struct _BufferDesc { - u32 link; - vu_long cmdsts; - u32 bufptr; - u32 software_use; -} BufferDesc; - -/* Bits in network_desc.status */ -enum desc_status_bits { - DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000, - DescNoCRC = 0x10000000, DescPktOK = 0x08000000, - DescSizeMask = 0xfff, - - DescTxAbort = 0x04000000, DescTxFIFO = 0x02000000, - DescTxCarrier = 0x01000000, DescTxDefer = 0x00800000, - DescTxExcDefer = 0x00400000, DescTxOOWCol = 0x00200000, - DescTxExcColl = 0x00100000, DescTxCollCount = 0x000f0000, - - DescRxAbort = 0x04000000, DescRxOver = 0x02000000, - DescRxDest = 0x01800000, DescRxLong = 0x00400000, - DescRxRunt = 0x00200000, DescRxInvalid = 0x00100000, - DescRxCRC = 0x00080000, DescRxAlign = 0x00040000, - DescRxLoop = 0x00020000, DesRxColl = 0x00010000, -}; - -/* Globals */ -#ifdef NATSEMI_DEBUG -static int natsemi_debug = 0; /* 1 verbose debugging, 0 normal */ -#endif -static u32 SavedClkRun; -static unsigned int cur_rx; -static unsigned int advertising; -static unsigned int rx_config; -static unsigned int tx_config; - -/* Note: transmit and receive buffers and descriptors must be - longword aligned */ -static BufferDesc txd __attribute__ ((aligned(4))); -static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(4))); - -static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(4))); -static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE] - __attribute__ ((aligned(4))); - -/* Function Prototypes */ -#if 0 -static void write_eeprom(struct eth_device *dev, long addr, int location, - short value); -#endif -static int read_eeprom(struct eth_device *dev, long addr, int location); -static int mdio_read(struct eth_device *dev, int phy_id, int location); -static int natsemi_init(struct eth_device *dev, bd_t * bis); -static void natsemi_reset(struct eth_device *dev); -static void natsemi_init_rxfilter(struct eth_device *dev); -static void natsemi_init_txd(struct eth_device *dev); -static void natsemi_init_rxd(struct eth_device *dev); -static void natsemi_set_rx_mode(struct eth_device *dev); -static void natsemi_check_duplex(struct eth_device *dev); -static int natsemi_send(struct eth_device *dev, void *packet, int length); -static int natsemi_poll(struct eth_device *dev); -static void natsemi_disable(struct eth_device *dev); - -static struct pci_device_id supported[] = { - {PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815}, - {} -}; - -#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a) -#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) - -static inline int -INW(struct eth_device *dev, u_long addr) -{ - return le16_to_cpu(*(vu_short *) (addr + dev->iobase)); -} - -static int -INL(struct eth_device *dev, u_long addr) -{ - return le32_to_cpu(*(vu_long *) (addr + dev->iobase)); -} - -static inline void -OUTW(struct eth_device *dev, int command, u_long addr) -{ - *(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command); -} - -static inline void -OUTL(struct eth_device *dev, int command, u_long addr) -{ - *(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command); -} - -/* - * Function: natsemi_initialize - * - * Description: Retrieves the MAC address of the card, and sets up some - * globals required by other routines, and initializes the NIC, making it - * ready to send and receive packets. - * - * Side effects: - * leaves the natsemi initialized, and ready to receive packets. - * - * Returns: struct eth_device *: pointer to NIC data structure - */ - -int -natsemi_initialize(bd_t * bis) -{ - pci_dev_t devno; - int card_number = 0; - struct eth_device *dev; - u32 iobase, status, chip_config; - int i, idx = 0; - int prev_eedata; - u32 tmp; - - while (1) { - /* Find PCI device(s) */ - if ((devno = pci_find_devices(supported, idx++)) < 0) { - break; - } - - pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase); - iobase &= ~0x3; /* bit 1: unused and bit 0: I/O Space Indicator */ - - pci_write_config_dword(devno, PCI_COMMAND, - PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - - /* Check if I/O accesses and Bus Mastering are enabled. */ - pci_read_config_dword(devno, PCI_COMMAND, &status); - if (!(status & PCI_COMMAND_MEMORY)) { - printf("Error: Can not enable MEM access.\n"); - continue; - } else if (!(status & PCI_COMMAND_MASTER)) { - printf("Error: Can not enable Bus Mastering.\n"); - continue; - } - - dev = (struct eth_device *) malloc(sizeof *dev); - if (!dev) { - printf("natsemi: Can not allocate memory\n"); - break; - } - memset(dev, 0, sizeof(*dev)); - - sprintf(dev->name, "dp83815#%d", card_number); - dev->iobase = bus_to_phys(iobase); -#ifdef NATSEMI_DEBUG - printf("natsemi: NatSemi ns8381[56] @ %#x\n", dev->iobase); -#endif - dev->priv = (void *) devno; - dev->init = natsemi_init; - dev->halt = natsemi_disable; - dev->send = natsemi_send; - dev->recv = natsemi_poll; - - eth_register(dev); - - card_number++; - - /* Set the latency timer for value. */ - pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20); - - udelay(10 * 1000); - - /* natsemi has a non-standard PM control register - * in PCI config space. Some boards apparently need - * to be brought to D0 in this manner. */ - pci_read_config_dword(devno, PCIPM, &tmp); - if (tmp & (0x03 | 0x100)) { - /* D0 state, disable PME assertion */ - u32 newtmp = tmp & ~(0x03 | 0x100); - pci_write_config_dword(devno, PCIPM, newtmp); - } - - printf("natsemi: EEPROM contents:\n"); - for (i = 0; i <= EEPROM_SIZE; i++) { - short eedata = read_eeprom(dev, EECtrl, i); - printf(" %04hx", eedata); - } - printf("\n"); - - /* get MAC address */ - prev_eedata = read_eeprom(dev, EECtrl, 6); - for (i = 0; i < 3; i++) { - int eedata = read_eeprom(dev, EECtrl, i + 7); - dev->enetaddr[i*2] = (eedata << 1) + (prev_eedata >> 15); - dev->enetaddr[i*2+1] = eedata >> 7; - prev_eedata = eedata; - } - - /* Reset the chip to erase any previous misconfiguration. */ - OUTL(dev, ChipReset, ChipCmd); - - advertising = mdio_read(dev, 1, 4); - chip_config = INL(dev, ChipConfig); -#ifdef NATSEMI_DEBUG - printf("%s: Transceiver status %#08X advertising %#08X\n", - dev->name, (int) INL(dev, BasicStatus), advertising); - printf("%s: Transceiver default autoneg. %s 10%s %s duplex.\n", - dev->name, chip_config & AnegMask ? "enabled, advertise" : - "disabled, force", chip_config & SpeedMask ? "0" : "", - chip_config & DuplexMask ? "full" : "half"); -#endif - chip_config |= AnegEnBothBoth; -#ifdef NATSEMI_DEBUG - printf("%s: changed to autoneg. %s 10%s %s duplex.\n", - dev->name, chip_config & AnegMask ? "enabled, advertise" : - "disabled, force", chip_config & SpeedMask ? "0" : "", - chip_config & DuplexMask ? "full" : "half"); -#endif - /*write new autoneg bits, reset phy*/ - OUTL(dev, (chip_config | PhyRst), ChipConfig); - /*un-reset phy*/ - OUTL(dev, chip_config, ChipConfig); - - /* Disable PME: - * The PME bit is initialized from the EEPROM contents. - * PCI cards probably have PME disabled, but motherboard - * implementations may have PME set to enable WakeOnLan. - * With PME set the chip will scan incoming packets but - * nothing will be written to memory. */ - SavedClkRun = INL(dev, ClkRun); - OUTL(dev, SavedClkRun & ~0x100, ClkRun); - } - return card_number; -} - -/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. - The EEPROM code is for common 93c06/46 EEPROMs w/ 6bit addresses. */ - -/* Delay between EEPROM clock transitions. - No extra delay is needed with 33MHz PCI, but future 66MHz - access may need a delay. */ -#define eeprom_delay(ee_addr) INL(dev, ee_addr) - -enum EEPROM_Ctrl_Bits { - EE_ShiftClk = 0x04, - EE_DataIn = 0x01, - EE_ChipSelect = 0x08, - EE_DataOut = 0x02 -}; - -#define EE_Write0 (EE_ChipSelect) -#define EE_Write1 (EE_ChipSelect | EE_DataIn) -/* The EEPROM commands include the alway-set leading bit. */ -enum EEPROM_Cmds { - EE_WrEnCmd = (4 << 6), EE_WriteCmd = (5 << 6), - EE_ReadCmd = (6 << 6), EE_EraseCmd = (7 << 6), -}; - -#if 0 -static void -write_eeprom(struct eth_device *dev, long addr, int location, short value) -{ - int i; - int ee_addr = (typeof(ee_addr))addr; - short wren_cmd = EE_WrEnCmd | 0x30; /*wren is 100 + 11XXXX*/ - short write_cmd = location | EE_WriteCmd; - -#ifdef NATSEMI_DEBUG - printf("write_eeprom: %08x, %04hx, %04hx\n", - dev->iobase + ee_addr, write_cmd, value); -#endif - /* Shift the write enable command bits out. */ - for (i = 9; i >= 0; i--) { - short cmdval = (wren_cmd & (1 << i)) ? EE_Write1 : EE_Write0; - OUTL(dev, cmdval, ee_addr); - eeprom_delay(ee_addr); - OUTL(dev, cmdval | EE_ShiftClk, ee_addr); - eeprom_delay(ee_addr); - } - - OUTL(dev, 0, ee_addr); /*bring chip select low*/ - OUTL(dev, EE_ShiftClk, ee_addr); - eeprom_delay(ee_addr); - - /* Shift the write command bits out. */ - for (i = 9; i >= 0; i--) { - short cmdval = (write_cmd & (1 << i)) ? EE_Write1 : EE_Write0; - OUTL(dev, cmdval, ee_addr); - eeprom_delay(ee_addr); - OUTL(dev, cmdval | EE_ShiftClk, ee_addr); - eeprom_delay(ee_addr); - } - - for (i = 0; i < 16; i++) { - short cmdval = (value & (1 << i)) ? EE_Write1 : EE_Write0; - OUTL(dev, cmdval, ee_addr); - eeprom_delay(ee_addr); - OUTL(dev, cmdval | EE_ShiftClk, ee_addr); - eeprom_delay(ee_addr); - } - - OUTL(dev, 0, ee_addr); /*bring chip select low*/ - OUTL(dev, EE_ShiftClk, ee_addr); - for (i = 0; i < 200000; i++) { - OUTL(dev, EE_Write0, ee_addr); /*poll for done*/ - if (INL(dev, ee_addr) & EE_DataOut) { - break; /*finished*/ - } - } - eeprom_delay(ee_addr); - - /* Terminate the EEPROM access. */ - OUTL(dev, EE_Write0, ee_addr); - OUTL(dev, 0, ee_addr); - return; -} -#endif - -static int -read_eeprom(struct eth_device *dev, long addr, int location) -{ - int i; - int retval = 0; - int ee_addr = (typeof(ee_addr))addr; - int read_cmd = location | EE_ReadCmd; - - OUTL(dev, EE_Write0, ee_addr); - - /* Shift the read command bits out. */ - for (i = 10; i >= 0; i--) { - short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0; - OUTL(dev, dataval, ee_addr); - eeprom_delay(ee_addr); - OUTL(dev, dataval | EE_ShiftClk, ee_addr); - eeprom_delay(ee_addr); - } - OUTL(dev, EE_ChipSelect, ee_addr); - eeprom_delay(ee_addr); - - for (i = 0; i < 16; i++) { - OUTL(dev, EE_ChipSelect | EE_ShiftClk, ee_addr); - eeprom_delay(ee_addr); - retval |= (INL(dev, ee_addr) & EE_DataOut) ? 1 << i : 0; - OUTL(dev, EE_ChipSelect, ee_addr); - eeprom_delay(ee_addr); - } - - /* Terminate the EEPROM access. */ - OUTL(dev, EE_Write0, ee_addr); - OUTL(dev, 0, ee_addr); -#ifdef NATSEMI_DEBUG - if (natsemi_debug) - printf("read_eeprom: %08x, %08x, retval %08x\n", - dev->iobase + ee_addr, read_cmd, retval); -#endif - return retval; -} - -/* MII transceiver control section. - The 83815 series has an internal transceiver, and we present the - management registers as if they were MII connected. */ - -static int -mdio_read(struct eth_device *dev, int phy_id, int location) -{ - if (phy_id == 1 && location < 32) - return INL(dev, BasicControl+(location<<2))&0xffff; - else - return 0xffff; -} - -/* Function: natsemi_init - * - * Description: resets the ethernet controller chip and configures - * registers and data structures required for sending and receiving packets. - * - * Arguments: struct eth_device *dev: NIC data structure - * - * returns: int. - */ - -static int -natsemi_init(struct eth_device *dev, bd_t * bis) -{ - - natsemi_reset(dev); - - /* Disable PME: - * The PME bit is initialized from the EEPROM contents. - * PCI cards probably have PME disabled, but motherboard - * implementations may have PME set to enable WakeOnLan. - * With PME set the chip will scan incoming packets but - * nothing will be written to memory. */ - OUTL(dev, SavedClkRun & ~0x100, ClkRun); - - natsemi_init_rxfilter(dev); - natsemi_init_txd(dev); - natsemi_init_rxd(dev); - - /* Configure the PCI bus bursts and FIFO thresholds. */ - tx_config = TxAutoPad | TxCollRetry | TxMxdma_256 | (0x1002); - rx_config = RxMxdma_256 | 0x20; - -#ifdef NATSEMI_DEBUG - printf("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config); - printf("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config); -#endif - OUTL(dev, tx_config, TxConfig); - OUTL(dev, rx_config, RxConfig); - - natsemi_check_duplex(dev); - natsemi_set_rx_mode(dev); - - OUTL(dev, (RxOn | TxOn), ChipCmd); - return 1; -} - -/* - * Function: natsemi_reset - * - * Description: soft resets the controller chip - * - * Arguments: struct eth_device *dev: NIC data structure - * - * Returns: void. - */ -static void -natsemi_reset(struct eth_device *dev) -{ - OUTL(dev, ChipReset, ChipCmd); - - /* On page 78 of the spec, they recommend some settings for "optimum - performance" to be done in sequence. These settings optimize some - of the 100Mbit autodetection circuitry. Also, we only want to do - this for rev C of the chip. */ - if (INL(dev, SiliconRev) == 0x302) { - OUTW(dev, 0x0001, PGSEL); - OUTW(dev, 0x189C, PMDCSR); - OUTW(dev, 0x0000, TSTDAT); - OUTW(dev, 0x5040, DSPCFG); - OUTW(dev, 0x008C, SDCFG); - } - /* Disable interrupts using the mask. */ - OUTL(dev, 0, IntrMask); - OUTL(dev, 0, IntrEnable); -} - -/* Function: natsemi_init_rxfilter - * - * Description: sets receive filter address to our MAC address - * - * Arguments: struct eth_device *dev: NIC data structure - * - * returns: void. - */ - -static void -natsemi_init_rxfilter(struct eth_device *dev) -{ - int i; - - for (i = 0; i < ETH_ALEN; i += 2) { - OUTL(dev, i, RxFilterAddr); - OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8), - RxFilterData); - } -} - -/* - * Function: natsemi_init_txd - * - * Description: initializes the Tx descriptor - * - * Arguments: struct eth_device *dev: NIC data structure - * - * returns: void. - */ - -static void -natsemi_init_txd(struct eth_device *dev) -{ - txd.link = (u32) 0; - txd.cmdsts = (u32) 0; - txd.bufptr = (u32) & txb[0]; - - /* load Transmit Descriptor Register */ - OUTL(dev, (u32) & txd, TxRingPtr); -#ifdef NATSEMI_DEBUG - printf("natsemi_init_txd: TX descriptor reg loaded with: %#08X\n", - INL(dev, TxRingPtr)); -#endif -} - -/* Function: natsemi_init_rxd - * - * Description: initializes the Rx descriptor ring - * - * Arguments: struct eth_device *dev: NIC data structure - * - * Returns: void. - */ - -static void -natsemi_init_rxd(struct eth_device *dev) -{ - int i; - - cur_rx = 0; - - /* init RX descriptor */ - for (i = 0; i < NUM_RX_DESC; i++) { - rxd[i].link = - cpu_to_le32((i + 1 < - NUM_RX_DESC) ? (u32) & rxd[i + - 1] : (u32) & - rxd[0]); - rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE); - rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]); -#ifdef NATSEMI_DEBUG - printf - ("natsemi_init_rxd: rxd[%d]=%p link=%X cmdsts=%lX bufptr=%X\n", - i, &rxd[i], le32_to_cpu(rxd[i].link), - rxd[i].cmdsts, rxd[i].bufptr); -#endif - } - - /* load Receive Descriptor Register */ - OUTL(dev, (u32) & rxd[0], RxRingPtr); - -#ifdef NATSEMI_DEBUG - printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n", - INL(dev, RxRingPtr)); -#endif -} - -/* Function: natsemi_set_rx_mode - * - * Description: - * sets the receive mode to accept all broadcast packets and packets - * with our MAC address, and reject all multicast packets. - * - * Arguments: struct eth_device *dev: NIC data structure - * - * Returns: void. - */ - -static void -natsemi_set_rx_mode(struct eth_device *dev) -{ - u32 rx_mode = AcceptBroadcast | AcceptMyPhys; - - OUTL(dev, rx_mode, RxFilterAddr); -} - -static void -natsemi_check_duplex(struct eth_device *dev) -{ - int duplex = INL(dev, ChipConfig) & FullDuplex ? 1 : 0; - -#ifdef NATSEMI_DEBUG - printf("%s: Setting %s-duplex based on negotiated link" - " capability.\n", dev->name, duplex ? "full" : "half"); -#endif - if (duplex) { - rx_config |= RxAcceptTx; - tx_config |= (TxCarrierIgn | TxHeartIgn); - } else { - rx_config &= ~RxAcceptTx; - tx_config &= ~(TxCarrierIgn | TxHeartIgn); - } - OUTL(dev, tx_config, TxConfig); - OUTL(dev, rx_config, RxConfig); -} - -/* Function: natsemi_send - * - * Description: transmits a packet and waits for completion or timeout. - * - * Returns: void. */ -static int natsemi_send(struct eth_device *dev, void *packet, int length) -{ - u32 i, status = 0; - u32 tx_status = 0; - u32 *tx_ptr = &tx_status; - vu_long *res = (vu_long *)tx_ptr; - - /* Stop the transmitter */ - OUTL(dev, TxOff, ChipCmd); - -#ifdef NATSEMI_DEBUG - if (natsemi_debug) - printf("natsemi_send: sending %d bytes\n", (int) length); -#endif - - /* set the transmit buffer descriptor and enable Transmit State Machine */ - txd.link = cpu_to_le32(0); - txd.bufptr = cpu_to_le32(phys_to_bus((u32) packet)); - txd.cmdsts = cpu_to_le32(DescOwn | length); - - /* load Transmit Descriptor Register */ - OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr); -#ifdef NATSEMI_DEBUG - if (natsemi_debug) - printf("natsemi_send: TX descriptor register loaded with: %#08X\n", - INL(dev, TxRingPtr)); -#endif - /* restart the transmitter */ - OUTL(dev, TxOn, ChipCmd); - - for (i = 0; - (*res = le32_to_cpu(txd.cmdsts)) & DescOwn; - i++) { - if (i >= TOUT_LOOP) { - printf - ("%s: tx error buffer not ready: txd.cmdsts == %#X\n", - dev->name, tx_status); - goto Done; - } - } - - if (!(tx_status & DescPktOK)) { - printf("natsemi_send: Transmit error, Tx status %X.\n", - tx_status); - goto Done; - } - - status = 1; - Done: - return status; -} - -/* Function: natsemi_poll - * - * Description: checks for a received packet and returns it if found. - * - * Arguments: struct eth_device *dev: NIC data structure - * - * Returns: 1 if packet was received. - * 0 if no packet was received. - * - * Side effects: - * Returns (copies) the packet to the array dev->packet. - * Returns the length of the packet. - */ - -static int -natsemi_poll(struct eth_device *dev) -{ - int retstat = 0; - int length = 0; - u32 rx_status = le32_to_cpu(rxd[cur_rx].cmdsts); - - if (!(rx_status & (u32) DescOwn)) - return retstat; -#ifdef NATSEMI_DEBUG - if (natsemi_debug) - printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n", - cur_rx, rx_status); -#endif - length = (rx_status & DSIZE) - CRC_SIZE; - - if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) { - printf - ("natsemi_poll: Corrupted packet received, buffer status = %X\n", - rx_status); - retstat = 0; - } else { /* give packet to higher level routine */ - NetReceive((rxb + cur_rx * RX_BUF_SIZE), length); - retstat = 1; - } - - /* return the descriptor and buffer to receive ring */ - rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE); - rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]); - - if (++cur_rx == NUM_RX_DESC) - cur_rx = 0; - - /* re-enable the potentially idle receive state machine */ - OUTL(dev, RxOn, ChipCmd); - - return retstat; -} - -/* Function: natsemi_disable - * - * Description: Turns off interrupts and stops Tx and Rx engines - * - * Arguments: struct eth_device *dev: NIC data structure - * - * Returns: void. - */ - -static void -natsemi_disable(struct eth_device *dev) -{ - /* Disable interrupts using the mask. */ - OUTL(dev, 0, IntrMask); - OUTL(dev, 0, IntrEnable); - - /* Stop the chip's Tx and Rx processes. */ - OUTL(dev, RxOff | TxOff, ChipCmd); - - /* Restore PME enable bit */ - OUTL(dev, SavedClkRun, ClkRun); -} diff --git a/qemu/roms/u-boot/drivers/net/ne2000.c b/qemu/roms/u-boot/drivers/net/ne2000.c deleted file mode 100644 index e6cd3e9ba..000000000 --- a/qemu/roms/u-boot/drivers/net/ne2000.c +++ /dev/null @@ -1,259 +0,0 @@ -/* -Ported to U-Boot by Christian Pellegrin <chri@ascensit.com> - -Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and -eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world -are GPL, so this is, of course, GPL. - -========================================================================== - -dev/if_dp83902a.c - -Ethernet device driver for NS DP83902a ethernet controller - -========================================================================== -####ECOSGPLCOPYRIGHTBEGIN#### -------------------------------------------- -This file is part of eCos, the Embedded Configurable Operating System. -Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, 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., -59 Temple Place, Suite 330, Boston, MA 02111-1307 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. - -This exception does not invalidate any other reasons why a work based on -this file might be covered by the GNU General Public License. - -Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -at http://sources.redhat.com/ecos/ecos-license/ -------------------------------------------- -####ECOSGPLCOPYRIGHTEND#### -####BSDCOPYRIGHTBEGIN#### - -------------------------------------------- - -Portions of this software may have been derived from OpenBSD or other sources, -and are covered by the appropriate copyright disclaimers included herein. - -------------------------------------------- - -####BSDCOPYRIGHTEND#### -========================================================================== -#####DESCRIPTIONBEGIN#### - -Author(s): gthomas -Contributors: gthomas, jskov, rsandifo -Date: 2001-06-13 -Purpose: -Description: - -FIXME: Will fail if pinged with large packets (1520 bytes) -Add promisc config -Add SNMP - -####DESCRIPTIONEND#### - -========================================================================== -*/ - -#include <common.h> -#include <command.h> - -/* NE2000 base header file */ -#include "ne2000_base.h" - -/* find prom (taken from pc_net_cs.c from Linux) */ - -#include "8390.h" -/* -typedef struct hw_info_t { - u_int offset; - u_char a0, a1, a2; - u_int flags; -} hw_info_t; -*/ -#define DELAY_OUTPUT 0x01 -#define HAS_MISC_REG 0x02 -#define USE_BIG_BUF 0x04 -#define HAS_IBM_MISC 0x08 -#define IS_DL10019 0x10 -#define IS_DL10022 0x20 -#define HAS_MII 0x40 -#define USE_SHMEM 0x80 /* autodetected */ - -#define AM79C9XX_HOME_PHY 0x00006B90 /* HomePNA PHY */ -#define AM79C9XX_ETH_PHY 0x00006B70 /* 10baseT PHY */ -#define MII_PHYID_REV_MASK 0xfffffff0 -#define MII_PHYID_REG1 0x02 -#define MII_PHYID_REG2 0x03 - -static hw_info_t hw_info[] = { - { /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT }, - { /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 }, - { /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 }, - { /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94, - DELAY_OUTPUT | HAS_IBM_MISC }, - { /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 }, - { /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 }, - { /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 }, - { /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 }, - { /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 }, - { /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 }, - { /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 }, - { /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 }, - { /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* IBM FME */ 0x0374, 0x00, 0x04, 0xac, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 }, - { /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 }, - { /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 }, - { /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 }, - { /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 }, - { /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 }, - { /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45, - HAS_MISC_REG | HAS_IBM_MISC }, - { /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 }, - { /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 }, - { /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 }, - { /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b, - DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF }, - { /* Socket LP-E CF+ */ 0x01c0, 0x00, 0xc0, 0x1b, 0 }, - { /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 }, - { /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 }, - { /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 }, - { /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 }, - { /* Qemu */ 0x0, 0x52, 0x54, 0x00, 0 }, - { /* RTL8019AS */ 0x0, 0x0, 0x18, 0x5f, 0 } -}; - -#define NR_INFO (sizeof(hw_info)/sizeof(hw_info_t)) - -#define PCNET_CMD 0x00 -#define PCNET_DATAPORT 0x10 /* NatSemi-defined port window offset. */ -#define PCNET_RESET 0x1f /* Issue a read to reset, a write to clear. */ -#define PCNET_MISC 0x18 /* For IBM CCAE and Socket EA cards */ - -static void pcnet_reset_8390(u8* addr) -{ - int i, r; - - n2k_outb(E8390_NODMA + E8390_PAGE0+E8390_STOP, E8390_CMD); - PRINTK("cmd (at %lx) is %x\n", addr + E8390_CMD, n2k_inb(E8390_CMD)); - n2k_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, E8390_CMD); - PRINTK("cmd (at %lx) is %x\n", addr + E8390_CMD, n2k_inb(E8390_CMD)); - n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); - PRINTK("cmd (at %lx) is %x\n", addr + E8390_CMD, n2k_inb(E8390_CMD)); - n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); - - n2k_outb(n2k_inb(PCNET_RESET), PCNET_RESET); - - for (i = 0; i < 100; i++) { - if ((r = (n2k_inb(EN0_ISR) & ENISR_RESET)) != 0) - break; - PRINTK("got %x in reset\n", r); - udelay(100); - } - n2k_outb(ENISR_RESET, EN0_ISR); /* Ack intr. */ - - if (i == 100) - printf("pcnet_reset_8390() did not complete.\n"); -} /* pcnet_reset_8390 */ - -int get_prom(u8* mac_addr, u8* base_addr) -{ - u8 prom[32]; - int i, j; - struct { - u_char value, offset; - } program_seq[] = { - {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ - {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */ - {0x00, EN0_RCNTLO}, /* Clear the count regs. */ - {0x00, EN0_RCNTHI}, - {0x00, EN0_IMR}, /* Mask completion irq. */ - {0xFF, EN0_ISR}, - {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ - {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ - {32, EN0_RCNTLO}, - {0x00, EN0_RCNTHI}, - {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ - {0x00, EN0_RSARHI}, - {E8390_RREAD+E8390_START, E8390_CMD}, - }; - - PRINTK ("trying to get MAC via prom reading\n"); - - pcnet_reset_8390 (base_addr); - - mdelay (10); - - for (i = 0; i < ARRAY_SIZE(program_seq); i++) - n2k_outb (program_seq[i].value, program_seq[i].offset); - - PRINTK ("PROM:"); - for (i = 0; i < 32; i++) { - prom[i] = n2k_inb (PCNET_DATAPORT); - PRINTK (" %02x", prom[i]); - } - PRINTK ("\n"); - for (i = 0; i < NR_INFO; i++) { - if ((prom[0] == hw_info[i].a0) && - (prom[2] == hw_info[i].a1) && - (prom[4] == hw_info[i].a2)) { - PRINTK ("matched board %d\n", i); - break; - } - } - if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) { - PRINTK ("on exit i is %d/%ld\n", i, NR_INFO); - PRINTK ("MAC address is "); - for (j = 0; j < 6; j++) { - mac_addr[j] = prom[j << 1]; - PRINTK ("%02x:", mac_addr[i]); - } - PRINTK ("\n"); - return (i < NR_INFO) ? i : 0; - } - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/ne2000.h b/qemu/roms/u-boot/drivers/net/ne2000.h deleted file mode 100644 index 2cde6be43..000000000 --- a/qemu/roms/u-boot/drivers/net/ne2000.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -Ported to U-Boot by Christian Pellegrin <chri@ascensit.com> - -Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and -eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world -are GPL, so this is, of course, GPL. - -========================================================================== - - dev/dp83902a.h - - National Semiconductor DP83902a ethernet chip - -========================================================================== -####ECOSGPLCOPYRIGHTBEGIN#### - ------------------------------------------- - This file is part of eCos, the Embedded Configurable Operating System. - Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, 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., - 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. - - This exception does not invalidate any other reasons why a work based on - this file might be covered by the GNU General Public License. - - Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. - at http://sources.redhat.com/ecos/ecos-license/ - ------------------------------------------- -####ECOSGPLCOPYRIGHTEND#### -####BSDCOPYRIGHTBEGIN#### - - ------------------------------------------- - - Portions of this software may have been derived from OpenBSD or other sources, - and are covered by the appropriate copyright disclaimers included herein. - - ------------------------------------------- - -####BSDCOPYRIGHTEND#### -========================================================================== -#####DESCRIPTIONBEGIN#### - - Author(s): gthomas - Contributors: gthomas, jskov - Date: 2001-06-13 - Purpose: - Description: - -####DESCRIPTIONEND#### - -========================================================================== -*/ - -/* - * NE2000 support header file. - * Created by Nobuhiro Iwamatsu <iwamatsu@nigauri.org> - */ - -#ifndef __DRIVERS_NE2000_H__ -#define __DRIVERS_NE2000_H__ - -/* Enable NE2000 basic init function */ -#define NE2000_BASIC_INIT - -#define DP_DATA 0x10 -#define START_PG 0x50 /* First page of TX buffer */ -#define START_PG2 0x48 -#define STOP_PG 0x80 /* Last page +1 of RX ring */ - -#define RX_START 0x50 -#define RX_END 0x80 - -#define DP_IN(_b_, _o_, _d_) (_d_) = *( (vu_char *) ((_b_)+(_o_))) -#define DP_OUT(_b_, _o_, _d_) *( (vu_char *) ((_b_)+(_o_))) = (_d_) -#define DP_IN_DATA(_b_, _d_) (_d_) = *( (vu_char *) ((_b_))) -#define DP_OUT_DATA(_b_, _d_) *( (vu_char *) ((_b_))) = (_d_) -#endif /* __DRIVERS_NE2000_H__ */ diff --git a/qemu/roms/u-boot/drivers/net/ne2000_base.c b/qemu/roms/u-boot/drivers/net/ne2000_base.c deleted file mode 100644 index ef3592204..000000000 --- a/qemu/roms/u-boot/drivers/net/ne2000_base.c +++ /dev/null @@ -1,800 +0,0 @@ -/* -Ported to U-Boot by Christian Pellegrin <chri@ascensit.com> - -Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and -eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world -are GPL, so this is, of course, GPL. - -========================================================================== - -dev/if_dp83902a.c - -Ethernet device driver for NS DP83902a ethernet controller - -========================================================================== -####ECOSGPLCOPYRIGHTBEGIN#### -------------------------------------------- -This file is part of eCos, the Embedded Configurable Operating System. -Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, 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., -59 Temple Place, Suite 330, Boston, MA 02111-1307 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. - -This exception does not invalidate any other reasons why a work based on -this file might be covered by the GNU General Public License. - -Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -at http://sources.redhat.com/ecos/ecos-license/ -------------------------------------------- -####ECOSGPLCOPYRIGHTEND#### -####BSDCOPYRIGHTBEGIN#### - -------------------------------------------- - -Portions of this software may have been derived from OpenBSD or other sources, -and are covered by the appropriate copyright disclaimers included herein. - -------------------------------------------- - -####BSDCOPYRIGHTEND#### -========================================================================== -#####DESCRIPTIONBEGIN#### - -Author(s): gthomas -Contributors: gthomas, jskov, rsandifo -Date: 2001-06-13 -Purpose: -Description: - -FIXME: Will fail if pinged with large packets (1520 bytes) -Add promisc config -Add SNMP - -####DESCRIPTIONEND#### - -========================================================================== -*/ - -#include <common.h> -#include <command.h> -#include <net.h> -#include <malloc.h> -#include <linux/compiler.h> - -/* forward definition of function used for the uboot interface */ -void uboot_push_packet_len(int len); -void uboot_push_tx_done(int key, int val); - -/* NE2000 base header file */ -#include "ne2000_base.h" - -#if defined(CONFIG_DRIVER_AX88796L) -/* AX88796L support */ -#include "ax88796.h" -#else -/* Basic NE2000 chip support */ -#include "ne2000.h" -#endif - -static dp83902a_priv_data_t nic; /* just one instance of the card supported */ - -/** - * This function reads the MAC address from the serial EEPROM, - * used if PROM read fails. Does nothing for ax88796 chips (sh boards) - */ -static bool -dp83902a_init(unsigned char *enetaddr) -{ - dp83902a_priv_data_t *dp = &nic; - u8* base; -#if defined(NE2000_BASIC_INIT) - int i; -#endif - - DEBUG_FUNCTION(); - - base = dp->base; - if (!base) - return false; /* No device found */ - - DEBUG_LINE(); - -#if defined(NE2000_BASIC_INIT) - /* AX88796L doesn't need */ - /* Prepare ESA */ - DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); /* Select page 1 */ - /* Use the address from the serial EEPROM */ - for (i = 0; i < 6; i++) - DP_IN(base, DP_P1_PAR0+i, dp->esa[i]); - DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0); /* Select page 0 */ - - printf("NE2000 - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n", - "eeprom", - dp->esa[0], - dp->esa[1], - dp->esa[2], - dp->esa[3], - dp->esa[4], - dp->esa[5] ); - - memcpy(enetaddr, dp->esa, 6); /* Use MAC from serial EEPROM */ -#endif /* NE2000_BASIC_INIT */ - return true; -} - -static void -dp83902a_stop(void) -{ - dp83902a_priv_data_t *dp = &nic; - u8 *base = dp->base; - - DEBUG_FUNCTION(); - - DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */ - DP_OUT(base, DP_ISR, 0xFF); /* Clear any pending interrupts */ - DP_OUT(base, DP_IMR, 0x00); /* Disable all interrupts */ - - dp->running = false; -} - -/* - * This function is called to "start up" the interface. It may be called - * multiple times, even when the hardware is already running. It will be - * called whenever something "hardware oriented" changes and should leave - * the hardware ready to send/receive packets. - */ -static void -dp83902a_start(u8 * enaddr) -{ - dp83902a_priv_data_t *dp = &nic; - u8 *base = dp->base; - int i; - - debug("The MAC is %pM\n", enaddr); - - DEBUG_FUNCTION(); - - DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */ - DP_OUT(base, DP_DCR, DP_DCR_INIT); - DP_OUT(base, DP_RBCH, 0); /* Remote byte count */ - DP_OUT(base, DP_RBCL, 0); - DP_OUT(base, DP_RCR, DP_RCR_MON); /* Accept no packets */ - DP_OUT(base, DP_TCR, DP_TCR_LOCAL); /* Transmitter [virtually] off */ - DP_OUT(base, DP_TPSR, dp->tx_buf1); /* Transmitter start page */ - dp->tx1 = dp->tx2 = 0; - dp->tx_next = dp->tx_buf1; - dp->tx_started = false; - dp->running = true; - DP_OUT(base, DP_PSTART, dp->rx_buf_start); /* Receive ring start page */ - DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); /* Receive ring boundary */ - DP_OUT(base, DP_PSTOP, dp->rx_buf_end); /* Receive ring end page */ - dp->rx_next = dp->rx_buf_start - 1; - dp->running = true; - DP_OUT(base, DP_ISR, 0xFF); /* Clear any pending interrupts */ - DP_OUT(base, DP_IMR, DP_IMR_All); /* Enable all interrupts */ - DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP); /* Select page 1 */ - DP_OUT(base, DP_P1_CURP, dp->rx_buf_start); /* Current page - next free page for Rx */ - dp->running = true; - for (i = 0; i < ETHER_ADDR_LEN; i++) { - /* FIXME */ - /*((vu_short*)( base + ((DP_P1_PAR0 + i) * 2) + - * 0x1400)) = enaddr[i];*/ - DP_OUT(base, DP_P1_PAR0+i, enaddr[i]); - } - /* Enable and start device */ - DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); - DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* Normal transmit operations */ - DP_OUT(base, DP_RCR, DP_RCR_AB); /* Accept broadcast, no errors, no multicast */ - dp->running = true; -} - -/* - * This routine is called to start the transmitter. It is split out from the - * data handling routine so it may be called either when data becomes first - * available or when an Tx interrupt occurs - */ - -static void -dp83902a_start_xmit(int start_page, int len) -{ - dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic; - u8 *base = dp->base; - - DEBUG_FUNCTION(); - -#if DEBUG & 1 - printf("Tx pkt %d len %d\n", start_page, len); - if (dp->tx_started) - printf("TX already started?!?\n"); -#endif - - DP_OUT(base, DP_ISR, (DP_ISR_TxP | DP_ISR_TxE)); - DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); - DP_OUT(base, DP_TBCL, len & 0xFF); - DP_OUT(base, DP_TBCH, len >> 8); - DP_OUT(base, DP_TPSR, start_page); - DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START); - - dp->tx_started = true; -} - -/* - * This routine is called to send data to the hardware. It is known a-priori - * that there is free buffer space (dp->tx_next). - */ -static void -dp83902a_send(u8 *data, int total_len, u32 key) -{ - struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; - u8 *base = dp->base; - int len, start_page, pkt_len, i, isr; -#if DEBUG & 4 - int dx; -#endif - - DEBUG_FUNCTION(); - - len = pkt_len = total_len; - if (pkt_len < IEEE_8023_MIN_FRAME) - pkt_len = IEEE_8023_MIN_FRAME; - - start_page = dp->tx_next; - if (dp->tx_next == dp->tx_buf1) { - dp->tx1 = start_page; - dp->tx1_len = pkt_len; - dp->tx1_key = key; - dp->tx_next = dp->tx_buf2; - } else { - dp->tx2 = start_page; - dp->tx2_len = pkt_len; - dp->tx2_key = key; - dp->tx_next = dp->tx_buf1; - } - -#if DEBUG & 5 - printf("TX prep page %d len %d\n", start_page, pkt_len); -#endif - - DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ - { - /* - * Dummy read. The manual sez something slightly different, - * but the code is extended a bit to do what Hitachi's monitor - * does (i.e., also read data). - */ - - __maybe_unused u16 tmp; - int len = 1; - - DP_OUT(base, DP_RSAL, 0x100 - len); - DP_OUT(base, DP_RSAH, (start_page - 1) & 0xff); - DP_OUT(base, DP_RBCL, len); - DP_OUT(base, DP_RBCH, 0); - DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START); - DP_IN_DATA(dp->data, tmp); - } - -#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA - /* - * Stall for a bit before continuing to work around random data - * corruption problems on some platforms. - */ - CYGACC_CALL_IF_DELAY_US(1); -#endif - - /* Send data to device buffer(s) */ - DP_OUT(base, DP_RSAL, 0); - DP_OUT(base, DP_RSAH, start_page); - DP_OUT(base, DP_RBCL, pkt_len & 0xFF); - DP_OUT(base, DP_RBCH, pkt_len >> 8); - DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START); - - /* Put data into buffer */ -#if DEBUG & 4 - printf(" sg buf %08lx len %08x\n ", (u32)data, len); - dx = 0; -#endif - while (len > 0) { -#if DEBUG & 4 - printf(" %02x", *data); - if (0 == (++dx % 16)) printf("\n "); -#endif - - DP_OUT_DATA(dp->data, *data++); - len--; - } -#if DEBUG & 4 - printf("\n"); -#endif - if (total_len < pkt_len) { -#if DEBUG & 4 - printf(" + %d bytes of padding\n", pkt_len - total_len); -#endif - /* Padding to 802.3 length was required */ - for (i = total_len; i < pkt_len;) { - i++; - DP_OUT_DATA(dp->data, 0); - } - } - -#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA - /* - * After last data write, delay for a bit before accessing the - * device again, or we may get random data corruption in the last - * datum (on some platforms). - */ - CYGACC_CALL_IF_DELAY_US(1); -#endif - - /* Wait for DMA to complete */ - do { - DP_IN(base, DP_ISR, isr); - } while ((isr & DP_ISR_RDC) == 0); - - /* Then disable DMA */ - DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); - - /* Start transmit if not already going */ - if (!dp->tx_started) { - if (start_page == dp->tx1) { - dp->tx_int = 1; /* Expecting interrupt from BUF1 */ - } else { - dp->tx_int = 2; /* Expecting interrupt from BUF2 */ - } - dp83902a_start_xmit(start_page, pkt_len); - } -} - -/* - * This function is called when a packet has been received. It's job is - * to prepare to unload the packet from the hardware. Once the length of - * the packet is known, the upper layer of the driver can be told. When - * the upper layer is ready to unload the packet, the internal function - * 'dp83902a_recv' will be called to actually fetch it from the hardware. - */ -static void -dp83902a_RxEvent(void) -{ - struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; - u8 *base = dp->base; - __maybe_unused u8 rsr; - u8 rcv_hdr[4]; - int i, len, pkt, cur; - - DEBUG_FUNCTION(); - - DP_IN(base, DP_RSR, rsr); - while (true) { - /* Read incoming packet header */ - DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START); - DP_IN(base, DP_P1_CURP, cur); - DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); - DP_IN(base, DP_BNDRY, pkt); - - pkt += 1; - if (pkt == dp->rx_buf_end) - pkt = dp->rx_buf_start; - - if (pkt == cur) { - break; - } - DP_OUT(base, DP_RBCL, sizeof(rcv_hdr)); - DP_OUT(base, DP_RBCH, 0); - DP_OUT(base, DP_RSAL, 0); - DP_OUT(base, DP_RSAH, pkt); - if (dp->rx_next == pkt) { - if (cur == dp->rx_buf_start) - DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); - else - DP_OUT(base, DP_BNDRY, cur - 1); /* Update pointer */ - return; - } - dp->rx_next = pkt; - DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ - DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START); -#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA - CYGACC_CALL_IF_DELAY_US(10); -#endif - - /* read header (get data size)*/ - for (i = 0; i < sizeof(rcv_hdr);) { - DP_IN_DATA(dp->data, rcv_hdr[i++]); - } - -#if DEBUG & 5 - printf("rx hdr %02x %02x %02x %02x\n", - rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]); -#endif - len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr); - - /* data read */ - uboot_push_packet_len(len); - - if (rcv_hdr[1] == dp->rx_buf_start) - DP_OUT(base, DP_BNDRY, dp->rx_buf_end - 1); - else - DP_OUT(base, DP_BNDRY, rcv_hdr[1] - 1); /* Update pointer */ - } -} - -/* - * This function is called as a result of the "eth_drv_recv()" call above. - * It's job is to actually fetch data for a packet from the hardware once - * memory buffers have been allocated for the packet. Note that the buffers - * may come in pieces, using a scatter-gather list. This allows for more - * efficient processing in the upper layers of the stack. - */ -static void -dp83902a_recv(u8 *data, int len) -{ - struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; - u8 *base = dp->base; - int i, mlen; - u8 saved_char = 0; - bool saved; -#if DEBUG & 4 - int dx; -#endif - - DEBUG_FUNCTION(); - -#if DEBUG & 5 - printf("Rx packet %d length %d\n", dp->rx_next, len); -#endif - - /* Read incoming packet data */ - DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); - DP_OUT(base, DP_RBCL, len & 0xFF); - DP_OUT(base, DP_RBCH, len >> 8); - DP_OUT(base, DP_RSAL, 4); /* Past header */ - DP_OUT(base, DP_RSAH, dp->rx_next); - DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ - DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START); -#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA - CYGACC_CALL_IF_DELAY_US(10); -#endif - - saved = false; - for (i = 0; i < 1; i++) { - if (data) { - mlen = len; -#if DEBUG & 4 - printf(" sg buf %08lx len %08x \n", (u32) data, mlen); - dx = 0; -#endif - while (0 < mlen) { - /* Saved byte from previous loop? */ - if (saved) { - *data++ = saved_char; - mlen--; - saved = false; - continue; - } - - { - u8 tmp; - DP_IN_DATA(dp->data, tmp); -#if DEBUG & 4 - printf(" %02x", tmp); - if (0 == (++dx % 16)) printf("\n "); -#endif - *data++ = tmp;; - mlen--; - } - } -#if DEBUG & 4 - printf("\n"); -#endif - } - } -} - -static void -dp83902a_TxEvent(void) -{ - struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; - u8 *base = dp->base; - __maybe_unused u8 tsr; - u32 key; - - DEBUG_FUNCTION(); - - DP_IN(base, DP_TSR, tsr); - if (dp->tx_int == 1) { - key = dp->tx1_key; - dp->tx1 = 0; - } else { - key = dp->tx2_key; - dp->tx2 = 0; - } - /* Start next packet if one is ready */ - dp->tx_started = false; - if (dp->tx1) { - dp83902a_start_xmit(dp->tx1, dp->tx1_len); - dp->tx_int = 1; - } else if (dp->tx2) { - dp83902a_start_xmit(dp->tx2, dp->tx2_len); - dp->tx_int = 2; - } else { - dp->tx_int = 0; - } - /* Tell higher level we sent this packet */ - uboot_push_tx_done(key, 0); -} - -/* - * Read the tally counters to clear them. Called in response to a CNT - * interrupt. - */ -static void -dp83902a_ClearCounters(void) -{ - struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; - u8 *base = dp->base; - __maybe_unused u8 cnt1, cnt2, cnt3; - - DP_IN(base, DP_FER, cnt1); - DP_IN(base, DP_CER, cnt2); - DP_IN(base, DP_MISSED, cnt3); - DP_OUT(base, DP_ISR, DP_ISR_CNT); -} - -/* - * Deal with an overflow condition. This code follows the procedure set - * out in section 7.0 of the datasheet. - */ -static void -dp83902a_Overflow(void) -{ - struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic; - u8 *base = dp->base; - u8 isr; - - /* Issue a stop command and wait 1.6ms for it to complete. */ - DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA); - CYGACC_CALL_IF_DELAY_US(1600); - - /* Clear the remote byte counter registers. */ - DP_OUT(base, DP_RBCL, 0); - DP_OUT(base, DP_RBCH, 0); - - /* Enter loopback mode while we clear the buffer. */ - DP_OUT(base, DP_TCR, DP_TCR_LOCAL); - DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA); - - /* - * Read in as many packets as we can and acknowledge any and receive - * interrupts. Since the buffer has overflowed, a receive event of - * some kind will have occured. - */ - dp83902a_RxEvent(); - DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE); - - /* Clear the overflow condition and leave loopback mode. */ - DP_OUT(base, DP_ISR, DP_ISR_OFLW); - DP_OUT(base, DP_TCR, DP_TCR_NORMAL); - - /* - * If a transmit command was issued, but no transmit event has occured, - * restart it here. - */ - DP_IN(base, DP_ISR, isr); - if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) { - DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START); - } -} - -static void -dp83902a_poll(void) -{ - struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; - u8 *base = dp->base; - u8 isr; - - DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START); - DP_IN(base, DP_ISR, isr); - while (0 != isr) { - /* - * The CNT interrupt triggers when the MSB of one of the error - * counters is set. We don't much care about these counters, but - * we should read their values to reset them. - */ - if (isr & DP_ISR_CNT) { - dp83902a_ClearCounters(); - } - /* - * Check for overflow. It's a special case, since there's a - * particular procedure that must be followed to get back into - * a running state.a - */ - if (isr & DP_ISR_OFLW) { - dp83902a_Overflow(); - } else { - /* - * Other kinds of interrupts can be acknowledged simply by - * clearing the relevant bits of the ISR. Do that now, then - * handle the interrupts we care about. - */ - DP_OUT(base, DP_ISR, isr); /* Clear set bits */ - if (!dp->running) break; /* Is this necessary? */ - /* - * Check for tx_started on TX event since these may happen - * spuriously it seems. - */ - if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) { - dp83902a_TxEvent(); - } - if (isr & (DP_ISR_RxP|DP_ISR_RxE)) { - dp83902a_RxEvent(); - } - } - DP_IN(base, DP_ISR, isr); - } -} - - -/* U-boot specific routines */ -static u8 *pbuf = NULL; - -static int pkey = -1; -static int initialized = 0; - -void uboot_push_packet_len(int len) { - PRINTK("pushed len = %d\n", len); - if (len >= 2000) { - printf("NE2000: packet too big\n"); - return; - } - dp83902a_recv(&pbuf[0], len); - - /*Just pass it to the upper layer*/ - NetReceive(&pbuf[0], len); -} - -void uboot_push_tx_done(int key, int val) { - PRINTK("pushed key = %d\n", key); - pkey = key; -} - -/** - * Setup the driver and init MAC address according to doc/README.enetaddr - * Called by ne2k_register() before registering the driver @eth layer - * - * @param struct ethdevice of this instance of the driver for dev->enetaddr - * @return 0 on success, -1 on error (causing caller to print error msg) - */ -static int ne2k_setup_driver(struct eth_device *dev) -{ - PRINTK("### ne2k_setup_driver\n"); - - if (!pbuf) { - pbuf = malloc(2000); - if (!pbuf) { - printf("Cannot allocate rx buffer\n"); - return -1; - } - } - -#ifdef CONFIG_DRIVER_NE2000_CCR - { - vu_char *p = (vu_char *) CONFIG_DRIVER_NE2000_CCR; - - PRINTK("CCR before is %x\n", *p); - *p = CONFIG_DRIVER_NE2000_VAL; - PRINTK("CCR after is %x\n", *p); - } -#endif - - nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE; - - nic.data = nic.base + DP_DATA; - nic.tx_buf1 = START_PG; - nic.tx_buf2 = START_PG2; - nic.rx_buf_start = RX_START; - nic.rx_buf_end = RX_END; - - /* - * According to doc/README.enetaddr, drivers shall give priority - * to the MAC address value in the environment, so we do not read - * it from the prom or eeprom if it is specified in the environment. - */ - if (!eth_getenv_enetaddr("ethaddr", dev->enetaddr)) { - /* If the MAC address is not in the environment, get it: */ - if (!get_prom(dev->enetaddr, nic.base)) /* get MAC from prom */ - dp83902a_init(dev->enetaddr); /* fallback: seeprom */ - /* And write it into the environment otherwise eth_write_hwaddr - * returns -1 due to eth_getenv_enetaddr_by_index() failing, - * and this causes "Warning: failed to set MAC address", and - * cmd_bdinfo has no ethaddr value which it can show: */ - eth_setenv_enetaddr("ethaddr", dev->enetaddr); - } - return 0; -} - -static int ne2k_init(struct eth_device *dev, bd_t *bd) -{ - dp83902a_start(dev->enetaddr); - initialized = 1; - return 0; -} - -static void ne2k_halt(struct eth_device *dev) -{ - debug("### ne2k_halt\n"); - if(initialized) - dp83902a_stop(); - initialized = 0; -} - -static int ne2k_recv(struct eth_device *dev) -{ - dp83902a_poll(); - return 1; -} - -static int ne2k_send(struct eth_device *dev, void *packet, int length) -{ - int tmo; - - debug("### ne2k_send\n"); - - pkey = -1; - - dp83902a_send((u8 *) packet, length, 666); - tmo = get_timer (0) + TOUT * CONFIG_SYS_HZ; - while(1) { - dp83902a_poll(); - if (pkey != -1) { - PRINTK("Packet sucesfully sent\n"); - return 0; - } - if (get_timer (0) >= tmo) { - printf("transmission error (timoeut)\n"); - return 0; - } - - } - return 0; -} - -/** - * Setup the driver for use and register it with the eth layer - * @return 0 on success, -1 on error (causing caller to print error msg) - */ -int ne2k_register(void) -{ - struct eth_device *dev; - - dev = calloc(sizeof(*dev), 1); - if (dev == NULL) - return -1; - - if (ne2k_setup_driver(dev)) - return -1; - - dev->init = ne2k_init; - dev->halt = ne2k_halt; - dev->send = ne2k_send; - dev->recv = ne2k_recv; - - sprintf(dev->name, "NE2000"); - - return eth_register(dev); -} diff --git a/qemu/roms/u-boot/drivers/net/ne2000_base.h b/qemu/roms/u-boot/drivers/net/ne2000_base.h deleted file mode 100644 index eee0956fd..000000000 --- a/qemu/roms/u-boot/drivers/net/ne2000_base.h +++ /dev/null @@ -1,304 +0,0 @@ -/* -Ported to U-Boot by Christian Pellegrin <chri@ascensit.com> - -Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and -eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world -are GPL, so this is, of course, GPL. - - -========================================================================== - - dev/dp83902a.h - - National Semiconductor DP83902a ethernet chip - -========================================================================== -####ECOSGPLCOPYRIGHTBEGIN#### - ------------------------------------------- - This file is part of eCos, the Embedded Configurable Operating System. - Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, 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., - 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. - - This exception does not invalidate any other reasons why a work based on - this file might be covered by the GNU General Public License. - - Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. - at http://sources.redhat.com/ecos/ecos-license/ - ------------------------------------------- -####ECOSGPLCOPYRIGHTEND#### -####BSDCOPYRIGHTBEGIN#### - - ------------------------------------------- - - Portions of this software may have been derived from OpenBSD or other sources, - and are covered by the appropriate copyright disclaimers included herein. - - ------------------------------------------- - -####BSDCOPYRIGHTEND#### -========================================================================== -#####DESCRIPTIONBEGIN#### - - Author(s): gthomas - Contributors: gthomas, jskov - Date: 2001-06-13 - Purpose: - Description: - -####DESCRIPTIONEND#### - -========================================================================== - -*/ - -/* - ------------------------------------------------------------------------ - Macros for accessing DP registers - These can be overridden by the platform header -*/ - -#ifndef __NE2000_BASE_H__ -#define __NE2000_BASE_H__ - -/* - * Debugging details - * - * Set to perms of: - * 0 disables all debug output - * 1 for process debug output - * 2 for added data IO output: get_reg, put_reg - * 4 for packet allocation/free output - * 8 for only startup status, so we can tell we're installed OK - */ -#if 0 -#define DEBUG 0xf -#else -#define DEBUG 0 -#endif - -#if DEBUG & 1 -#define DEBUG_FUNCTION() do { printf("%s\n", __FUNCTION__); } while (0) -#define DEBUG_LINE() do { printf("%d\n", __LINE__); } while (0) -#define PRINTK(args...) printf(args) -#else -#define DEBUG_FUNCTION() do {} while(0) -#define DEBUG_LINE() do {} while(0) -#define PRINTK(args...) -#endif - -/* timeout for tx/rx in s */ -#define TOUT 5 -/* Ether MAC address size */ -#define ETHER_ADDR_LEN 6 - - -#define CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA 1 -#define CYGACC_CALL_IF_DELAY_US(X) udelay(X) - -/* H/W infomation struct */ -typedef struct hw_info_t { - u32 offset; - u8 a0, a1, a2; - u32 flags; -} hw_info_t; - -typedef struct dp83902a_priv_data { - u8* base; - u8* data; - u8* reset; - int tx_next; /* First free Tx page */ - int tx_int; /* Expecting interrupt from this buffer */ - int rx_next; /* First free Rx page */ - int tx1, tx2; /* Page numbers for Tx buffers */ - u32 tx1_key, tx2_key; /* Used to ack when packet sent */ - int tx1_len, tx2_len; - bool tx_started, running, hardwired_esa; - u8 esa[6]; - void* plf_priv; - - /* Buffer allocation */ - int tx_buf1, tx_buf2; - int rx_buf_start, rx_buf_end; -} dp83902a_priv_data_t; - -/* ------------------------------------------------------------------------ */ -/* Register offsets */ - -#define DP_CR 0x00 -#define DP_CLDA0 0x01 -#define DP_PSTART 0x01 /* write */ -#define DP_CLDA1 0x02 -#define DP_PSTOP 0x02 /* write */ -#define DP_BNDRY 0x03 -#define DP_TSR 0x04 -#define DP_TPSR 0x04 /* write */ -#define DP_NCR 0x05 -#define DP_TBCL 0x05 /* write */ -#define DP_FIFO 0x06 -#define DP_TBCH 0x06 /* write */ -#define DP_ISR 0x07 -#define DP_CRDA0 0x08 -#define DP_RSAL 0x08 /* write */ -#define DP_CRDA1 0x09 -#define DP_RSAH 0x09 /* write */ -#define DP_RBCL 0x0a /* write */ -#define DP_RBCH 0x0b /* write */ -#define DP_RSR 0x0c -#define DP_RCR 0x0c /* write */ -#define DP_FER 0x0d -#define DP_TCR 0x0d /* write */ -#define DP_CER 0x0e -#define DP_DCR 0x0e /* write */ -#define DP_MISSED 0x0f -#define DP_IMR 0x0f /* write */ -#define DP_DATAPORT 0x10 /* "eprom" data port */ - -#define DP_P1_CR 0x00 -#define DP_P1_PAR0 0x01 -#define DP_P1_PAR1 0x02 -#define DP_P1_PAR2 0x03 -#define DP_P1_PAR3 0x04 -#define DP_P1_PAR4 0x05 -#define DP_P1_PAR5 0x06 -#define DP_P1_CURP 0x07 -#define DP_P1_MAR0 0x08 -#define DP_P1_MAR1 0x09 -#define DP_P1_MAR2 0x0a -#define DP_P1_MAR3 0x0b -#define DP_P1_MAR4 0x0c -#define DP_P1_MAR5 0x0d -#define DP_P1_MAR6 0x0e -#define DP_P1_MAR7 0x0f - -#define DP_P2_CR 0x00 -#define DP_P2_PSTART 0x01 -#define DP_P2_CLDA0 0x01 /* write */ -#define DP_P2_PSTOP 0x02 -#define DP_P2_CLDA1 0x02 /* write */ -#define DP_P2_RNPP 0x03 -#define DP_P2_TPSR 0x04 -#define DP_P2_LNPP 0x05 -#define DP_P2_ACH 0x06 -#define DP_P2_ACL 0x07 -#define DP_P2_RCR 0x0c -#define DP_P2_TCR 0x0d -#define DP_P2_DCR 0x0e -#define DP_P2_IMR 0x0f - -/* Command register - common to all pages */ - -#define DP_CR_STOP 0x01 /* Stop: software reset */ -#define DP_CR_START 0x02 /* Start: initialize device */ -#define DP_CR_TXPKT 0x04 /* Transmit packet */ -#define DP_CR_RDMA 0x08 /* Read DMA (recv data from device) */ -#define DP_CR_WDMA 0x10 /* Write DMA (send data to device) */ -#define DP_CR_SEND 0x18 /* Send packet */ -#define DP_CR_NODMA 0x20 /* Remote (or no) DMA */ -#define DP_CR_PAGE0 0x00 /* Page select */ -#define DP_CR_PAGE1 0x40 -#define DP_CR_PAGE2 0x80 -#define DP_CR_PAGEMSK 0x3F /* Used to mask out page bits */ - -/* Data configuration register */ - -#define DP_DCR_WTS 0x01 /* 1=16 bit word transfers */ -#define DP_DCR_BOS 0x02 /* 1=Little Endian */ -#define DP_DCR_LAS 0x04 /* 1=Single 32 bit DMA mode */ -#define DP_DCR_LS 0x08 /* 1=normal mode, 0=loopback */ -#define DP_DCR_ARM 0x10 /* 0=no send command (program I/O) */ -#define DP_DCR_FIFO_1 0x00 /* FIFO threshold */ -#define DP_DCR_FIFO_2 0x20 -#define DP_DCR_FIFO_4 0x40 -#define DP_DCR_FIFO_6 0x60 - -#define DP_DCR_INIT (DP_DCR_LS|DP_DCR_FIFO_4) - -/* Interrupt status register */ - -#define DP_ISR_RxP 0x01 /* Packet received */ -#define DP_ISR_TxP 0x02 /* Packet transmitted */ -#define DP_ISR_RxE 0x04 /* Receive error */ -#define DP_ISR_TxE 0x08 /* Transmit error */ -#define DP_ISR_OFLW 0x10 /* Receive overflow */ -#define DP_ISR_CNT 0x20 /* Tally counters need emptying */ -#define DP_ISR_RDC 0x40 /* Remote DMA complete */ -#define DP_ISR_RESET 0x80 /* Device has reset (shutdown, error) */ - -/* Interrupt mask register */ - -#define DP_IMR_RxP 0x01 /* Packet received */ -#define DP_IMR_TxP 0x02 /* Packet transmitted */ -#define DP_IMR_RxE 0x04 /* Receive error */ -#define DP_IMR_TxE 0x08 /* Transmit error */ -#define DP_IMR_OFLW 0x10 /* Receive overflow */ -#define DP_IMR_CNT 0x20 /* Tall counters need emptying */ -#define DP_IMR_RDC 0x40 /* Remote DMA complete */ - -#define DP_IMR_All 0x3F /* Everything but remote DMA */ - -/* Receiver control register */ - -#define DP_RCR_SEP 0x01 /* Save bad(error) packets */ -#define DP_RCR_AR 0x02 /* Accept runt packets */ -#define DP_RCR_AB 0x04 /* Accept broadcast packets */ -#define DP_RCR_AM 0x08 /* Accept multicast packets */ -#define DP_RCR_PROM 0x10 /* Promiscuous mode */ -#define DP_RCR_MON 0x20 /* Monitor mode - 1=accept no packets */ - -/* Receiver status register */ - -#define DP_RSR_RxP 0x01 /* Packet received */ -#define DP_RSR_CRC 0x02 /* CRC error */ -#define DP_RSR_FRAME 0x04 /* Framing error */ -#define DP_RSR_FO 0x08 /* FIFO overrun */ -#define DP_RSR_MISS 0x10 /* Missed packet */ -#define DP_RSR_PHY 0x20 /* 0=pad match, 1=mad match */ -#define DP_RSR_DIS 0x40 /* Receiver disabled */ -#define DP_RSR_DFR 0x80 /* Receiver processing deferred */ - -/* Transmitter control register */ - -#define DP_TCR_NOCRC 0x01 /* 1=inhibit CRC */ -#define DP_TCR_NORMAL 0x00 /* Normal transmitter operation */ -#define DP_TCR_LOCAL 0x02 /* Internal NIC loopback */ -#define DP_TCR_INLOOP 0x04 /* Full internal loopback */ -#define DP_TCR_OUTLOOP 0x08 /* External loopback */ -#define DP_TCR_ATD 0x10 /* Auto transmit disable */ -#define DP_TCR_OFFSET 0x20 /* Collision offset adjust */ - -/* Transmit status register */ - -#define DP_TSR_TxP 0x01 /* Packet transmitted */ -#define DP_TSR_COL 0x04 /* Collision (at least one) */ -#define DP_TSR_ABT 0x08 /* Aborted because of too many collisions */ -#define DP_TSR_CRS 0x10 /* Lost carrier */ -#define DP_TSR_FU 0x20 /* FIFO underrun */ -#define DP_TSR_CDH 0x40 /* Collision Detect Heartbeat */ -#define DP_TSR_OWC 0x80 /* Collision outside normal window */ - -#define IEEE_8023_MAX_FRAME 1518 /* Largest possible ethernet frame */ -#define IEEE_8023_MIN_FRAME 64 /* Smallest possible ethernet frame */ - -/* Functions */ -int get_prom(u8* mac_addr, u8* base_addr); - -#endif /* __NE2000_BASE_H__ */ diff --git a/qemu/roms/u-boot/drivers/net/netconsole.c b/qemu/roms/u-boot/drivers/net/netconsole.c deleted file mode 100644 index 65c747e14..000000000 --- a/qemu/roms/u-boot/drivers/net/netconsole.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * (C) Copyright 2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <command.h> -#include <stdio_dev.h> -#include <net.h> - -DECLARE_GLOBAL_DATA_PTR; - -#ifndef CONFIG_NETCONSOLE_BUFFER_SIZE -#define CONFIG_NETCONSOLE_BUFFER_SIZE 512 -#endif - -static char input_buffer[CONFIG_NETCONSOLE_BUFFER_SIZE]; -static int input_size; /* char count in input buffer */ -static int input_offset; /* offset to valid chars in input buffer */ -static int input_recursion; -static int output_recursion; -static int net_timeout; -static uchar nc_ether[6]; /* server enet address */ -static IPaddr_t nc_ip; /* server ip */ -static short nc_out_port; /* target output port */ -static short nc_in_port; /* source input port */ -static const char *output_packet; /* used by first send udp */ -static int output_packet_len; -/* - * Start with a default last protocol. - * We are only interested in NETCONS or not. - */ -enum proto_t net_loop_last_protocol = BOOTP; - -static void nc_wait_arp_handler(uchar *pkt, unsigned dest, - IPaddr_t sip, unsigned src, - unsigned len) -{ - net_set_state(NETLOOP_SUCCESS); /* got arp reply - quit net loop */ -} - -static void nc_handler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, - unsigned len) -{ - if (input_size) - net_set_state(NETLOOP_SUCCESS); /* got input - quit net loop */ -} - -static void nc_timeout(void) -{ - net_set_state(NETLOOP_SUCCESS); -} - -static int is_broadcast(IPaddr_t ip) -{ - static IPaddr_t netmask; - static IPaddr_t our_ip; - static int env_changed_id; - int env_id = get_env_id(); - - /* update only when the environment has changed */ - if (env_changed_id != env_id) { - netmask = getenv_IPaddr("netmask"); - our_ip = getenv_IPaddr("ipaddr"); - - env_changed_id = env_id; - } - - return (ip == ~0 || /* 255.255.255.255 */ - ((netmask & our_ip) == (netmask & ip) && /* on the same net */ - (netmask | ip) == ~0)); /* broadcast to our net */ -} - -static int refresh_settings_from_env(void) -{ - const char *p; - static int env_changed_id; - int env_id = get_env_id(); - - /* update only when the environment has changed */ - if (env_changed_id != env_id) { - if (getenv("ncip")) { - nc_ip = getenv_IPaddr("ncip"); - if (!nc_ip) - return -1; /* ncip is 0.0.0.0 */ - p = strchr(getenv("ncip"), ':'); - if (p != NULL) { - nc_out_port = simple_strtoul(p + 1, NULL, 10); - nc_in_port = nc_out_port; - } - } else - nc_ip = ~0; /* ncip is not set, so broadcast */ - - p = getenv("ncoutport"); - if (p != NULL) - nc_out_port = simple_strtoul(p, NULL, 10); - p = getenv("ncinport"); - if (p != NULL) - nc_in_port = simple_strtoul(p, NULL, 10); - - if (is_broadcast(nc_ip)) - /* broadcast MAC address */ - memset(nc_ether, 0xff, sizeof(nc_ether)); - else - /* force arp request */ - memset(nc_ether, 0, sizeof(nc_ether)); - } - return 0; -} - -/** - * Called from NetLoop in net/net.c before each packet - */ -void NcStart(void) -{ - refresh_settings_from_env(); - if (!output_packet_len || memcmp(nc_ether, NetEtherNullAddr, 6)) { - /* going to check for input packet */ - net_set_udp_handler(nc_handler); - NetSetTimeout(net_timeout, nc_timeout); - } else { - /* send arp request */ - uchar *pkt; - net_set_arp_handler(nc_wait_arp_handler); - pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE; - memcpy(pkt, output_packet, output_packet_len); - NetSendUDPPacket(nc_ether, nc_ip, nc_out_port, nc_in_port, - output_packet_len); - } -} - -int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port, - unsigned src_port, unsigned len) -{ - int end, chunk; - - if (dest_port != nc_in_port || !len) - return 0; /* not for us */ - - if (src_ip != nc_ip && !is_broadcast(nc_ip)) - return 0; /* not from our client */ - - debug_cond(DEBUG_DEV_PKT, "input: \"%*.*s\"\n", len, len, pkt); - - if (input_size == sizeof(input_buffer)) - return 1; /* no space */ - if (len > sizeof(input_buffer) - input_size) - len = sizeof(input_buffer) - input_size; - - end = input_offset + input_size; - if (end > sizeof(input_buffer)) - end -= sizeof(input_buffer); - - chunk = len; - if (end + len > sizeof(input_buffer)) { - chunk = sizeof(input_buffer) - end; - memcpy(input_buffer, pkt + chunk, len - chunk); - } - memcpy(input_buffer + end, pkt, chunk); - - input_size += len; - - return 1; -} - -static void nc_send_packet(const char *buf, int len) -{ - struct eth_device *eth; - int inited = 0; - uchar *pkt; - uchar *ether; - IPaddr_t ip; - - debug_cond(DEBUG_DEV_PKT, "output: \"%*.*s\"\n", len, len, buf); - - eth = eth_get_dev(); - if (eth == NULL) - return; - - if (!memcmp(nc_ether, NetEtherNullAddr, 6)) { - if (eth->state == ETH_STATE_ACTIVE) - return; /* inside net loop */ - output_packet = buf; - output_packet_len = len; - input_recursion = 1; - NetLoop(NETCONS); /* wait for arp reply and send packet */ - input_recursion = 0; - output_packet_len = 0; - return; - } - - if (eth->state != ETH_STATE_ACTIVE) { - if (eth_is_on_demand_init()) { - if (eth_init(gd->bd) < 0) - return; - eth_set_last_protocol(NETCONS); - } else - eth_init_state_only(gd->bd); - - inited = 1; - } - pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE; - memcpy(pkt, buf, len); - ether = nc_ether; - ip = nc_ip; - NetSendUDPPacket(ether, ip, nc_out_port, nc_in_port, len); - - if (inited) { - if (eth_is_on_demand_init()) - eth_halt(); - else - eth_halt_state_only(); - } -} - -static int nc_start(void) -{ - int retval; - - nc_out_port = 6666; /* default port */ - nc_in_port = nc_out_port; - - retval = refresh_settings_from_env(); - if (retval != 0) - return retval; - - /* - * Initialize the static IP settings and buffer pointers - * incase we call NetSendUDPPacket before NetLoop - */ - net_init(); - - return 0; -} - -static void nc_putc(char c) -{ - if (output_recursion) - return; - output_recursion = 1; - - nc_send_packet(&c, 1); - - output_recursion = 0; -} - -static void nc_puts(const char *s) -{ - int len; - - if (output_recursion) - return; - output_recursion = 1; - - len = strlen(s); - while (len) { - int send_len = min(len, sizeof(input_buffer)); - nc_send_packet(s, send_len); - len -= send_len; - s += send_len; - } - - output_recursion = 0; -} - -static int nc_getc(void) -{ - uchar c; - - input_recursion = 1; - - net_timeout = 0; /* no timeout */ - while (!input_size) - NetLoop(NETCONS); - - input_recursion = 0; - - c = input_buffer[input_offset++]; - - if (input_offset >= sizeof(input_buffer)) - input_offset -= sizeof(input_buffer); - input_size--; - - return c; -} - -static int nc_tstc(void) -{ - struct eth_device *eth; - - if (input_recursion) - return 0; - - if (input_size) - return 1; - - eth = eth_get_dev(); - if (eth && eth->state == ETH_STATE_ACTIVE) - return 0; /* inside net loop */ - - input_recursion = 1; - - net_timeout = 1; - NetLoop(NETCONS); /* kind of poll */ - - input_recursion = 0; - - return input_size != 0; -} - -int drv_nc_init(void) -{ - struct stdio_dev dev; - int rc; - - memset(&dev, 0, sizeof(dev)); - - strcpy(dev.name, "nc"); - dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; - dev.start = nc_start; - dev.putc = nc_putc; - dev.puts = nc_puts; - dev.getc = nc_getc; - dev.tstc = nc_tstc; - - rc = stdio_register(&dev); - - return (rc == 0) ? 1 : rc; -} diff --git a/qemu/roms/u-boot/drivers/net/ns8382x.c b/qemu/roms/u-boot/drivers/net/ns8382x.c deleted file mode 100644 index cfe1f349d..000000000 --- a/qemu/roms/u-boot/drivers/net/ns8382x.c +++ /dev/null @@ -1,851 +0,0 @@ -/* - ns8382x.c: A U-Boot driver for the NatSemi DP8382[01]. - ported by: Mark A. Rakes (mark_rakes@vivato.net) - - Adapted from: - 1. an Etherboot driver for DP8381[56] written by: - Copyright (C) 2001 Entity Cyber, Inc. - - This development of this Etherboot driver was funded by - Sicom Systems: http://www.sicompos.com/ - - Author: Marty Connor (mdc@thinguin.org) - Adapted from a Linux driver which was written by Donald Becker - - This software may be used and distributed according to the terms - of the GNU Public License (GPL), incorporated herein by reference. - - 2. A Linux driver by Donald Becker, ns820.c: - Written/copyright 1999-2002 by Donald Becker. - - This software may be used and distributed according to the terms of - the GNU General Public License (GPL), incorporated herein by reference. - Drivers based on or derived from this code fall under the GPL and must - retain the authorship, copyright and license notice. This file is not - a complete program and may only be used when the entire operating - system is licensed under the GPL. License for under other terms may be - available. Contact the original author for details. - - The original author may be reached as becker@scyld.com, or at - Scyld Computing Corporation - 410 Severn Ave., Suite 210 - Annapolis MD 21403 - - Support information and updates available at - http://www.scyld.com/network/netsemi.html - - Datasheets available from: - http://www.national.com/pf/DP/DP83820.html - http://www.national.com/pf/DP/DP83821.html -*/ - -/* Revision History - * October 2002 mar 1.0 - * Initial U-Boot Release. - * Tested with Netgear GA622T (83820) - * and SMC9452TX (83821) - * NOTE: custom boards with these chips may (likely) require - * a programmed EEPROM device (if present) in order to work - * correctly. -*/ - -/* Includes */ -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <asm/io.h> -#include <pci.h> - -/* defines */ -#define DSIZE 0x00000FFF -#define ETH_ALEN 6 -#define CRC_SIZE 4 -#define TOUT_LOOP 500000 -#define TX_BUF_SIZE 1536 -#define RX_BUF_SIZE 1536 -#define NUM_RX_DESC 4 /* Number of Rx descriptor registers. */ - -enum register_offsets { - ChipCmd = 0x00, - ChipConfig = 0x04, - EECtrl = 0x08, - IntrMask = 0x14, - IntrEnable = 0x18, - TxRingPtr = 0x20, - TxRingPtrHi = 0x24, - TxConfig = 0x28, - RxRingPtr = 0x30, - RxRingPtrHi = 0x34, - RxConfig = 0x38, - PriQueue = 0x3C, - RxFilterAddr = 0x48, - RxFilterData = 0x4C, - ClkRun = 0xCC, - PCIPM = 0x44, -}; - -enum ChipCmdBits { - ChipReset = 0x100, - RxReset = 0x20, - TxReset = 0x10, - RxOff = 0x08, - RxOn = 0x04, - TxOff = 0x02, - TxOn = 0x01 -}; - -enum ChipConfigBits { - LinkSts = 0x80000000, - GigSpeed = 0x40000000, - HundSpeed = 0x20000000, - FullDuplex = 0x10000000, - TBIEn = 0x01000000, - Mode1000 = 0x00400000, - T64En = 0x00004000, - D64En = 0x00001000, - M64En = 0x00000800, - PhyRst = 0x00000400, - PhyDis = 0x00000200, - ExtStEn = 0x00000100, - BEMode = 0x00000001, -}; -#define SpeedStatus_Polarity ( GigSpeed | HundSpeed | FullDuplex) - -enum TxConfig_bits { - TxDrthMask = 0x000000ff, - TxFlthMask = 0x0000ff00, - TxMxdmaMask = 0x00700000, - TxMxdma_8 = 0x00100000, - TxMxdma_16 = 0x00200000, - TxMxdma_32 = 0x00300000, - TxMxdma_64 = 0x00400000, - TxMxdma_128 = 0x00500000, - TxMxdma_256 = 0x00600000, - TxMxdma_512 = 0x00700000, - TxMxdma_1024 = 0x00000000, - TxCollRetry = 0x00800000, - TxAutoPad = 0x10000000, - TxMacLoop = 0x20000000, - TxHeartIgn = 0x40000000, - TxCarrierIgn = 0x80000000 -}; - -enum RxConfig_bits { - RxDrthMask = 0x0000003e, - RxMxdmaMask = 0x00700000, - RxMxdma_8 = 0x00100000, - RxMxdma_16 = 0x00200000, - RxMxdma_32 = 0x00300000, - RxMxdma_64 = 0x00400000, - RxMxdma_128 = 0x00500000, - RxMxdma_256 = 0x00600000, - RxMxdma_512 = 0x00700000, - RxMxdma_1024 = 0x00000000, - RxAcceptLenErr = 0x04000000, - RxAcceptLong = 0x08000000, - RxAcceptTx = 0x10000000, - RxStripCRC = 0x20000000, - RxAcceptRunt = 0x40000000, - RxAcceptErr = 0x80000000, -}; - -/* Bits in the RxMode register. */ -enum rx_mode_bits { - RxFilterEnable = 0x80000000, - AcceptAllBroadcast = 0x40000000, - AcceptAllMulticast = 0x20000000, - AcceptAllUnicast = 0x10000000, - AcceptPerfectMatch = 0x08000000, -}; - -typedef struct _BufferDesc { - u32 link; - u32 bufptr; - vu_long cmdsts; - u32 extsts; /*not used here */ -} BufferDesc; - -/* Bits in network_desc.status */ -enum desc_status_bits { - DescOwn = 0x80000000, DescMore = 0x40000000, DescIntr = 0x20000000, - DescNoCRC = 0x10000000, DescPktOK = 0x08000000, - DescSizeMask = 0xfff, - - DescTxAbort = 0x04000000, DescTxFIFO = 0x02000000, - DescTxCarrier = 0x01000000, DescTxDefer = 0x00800000, - DescTxExcDefer = 0x00400000, DescTxOOWCol = 0x00200000, - DescTxExcColl = 0x00100000, DescTxCollCount = 0x000f0000, - - DescRxAbort = 0x04000000, DescRxOver = 0x02000000, - DescRxDest = 0x01800000, DescRxLong = 0x00400000, - DescRxRunt = 0x00200000, DescRxInvalid = 0x00100000, - DescRxCRC = 0x00080000, DescRxAlign = 0x00040000, - DescRxLoop = 0x00020000, DesRxColl = 0x00010000, -}; - -/* Bits in MEAR */ -enum mii_reg_bits { - MDIO_ShiftClk = 0x0040, - MDIO_EnbOutput = 0x0020, - MDIO_Data = 0x0010, -}; - -/* PHY Register offsets. */ -enum phy_reg_offsets { - BMCR = 0x00, - BMSR = 0x01, - PHYIDR1 = 0x02, - PHYIDR2 = 0x03, - ANAR = 0x04, - KTCR = 0x09, -}; - -/* basic mode control register bits */ -enum bmcr_bits { - Bmcr_Reset = 0x8000, - Bmcr_Loop = 0x4000, - Bmcr_Speed0 = 0x2000, - Bmcr_AutoNegEn = 0x1000, /*if set ignores Duplex, Speed[01] */ - Bmcr_RstAutoNeg = 0x0200, - Bmcr_Duplex = 0x0100, - Bmcr_Speed1 = 0x0040, - Bmcr_Force10H = 0x0000, - Bmcr_Force10F = 0x0100, - Bmcr_Force100H = 0x2000, - Bmcr_Force100F = 0x2100, - Bmcr_Force1000H = 0x0040, - Bmcr_Force1000F = 0x0140, -}; - -/* auto negotiation advertisement register */ -enum anar_bits { - anar_adv_100F = 0x0100, - anar_adv_100H = 0x0080, - anar_adv_10F = 0x0040, - anar_adv_10H = 0x0020, - anar_ieee_8023 = 0x0001, -}; - -/* 1K-base T control register */ -enum ktcr_bits { - ktcr_adv_1000H = 0x0100, - ktcr_adv_1000F = 0x0200, -}; - -/* Globals */ -static u32 SavedClkRun; -static unsigned int cur_rx; -static unsigned int rx_config; -static unsigned int tx_config; - -/* Note: transmit and receive buffers and descriptors must be - long long word aligned */ -static BufferDesc txd __attribute__ ((aligned(8))); -static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(8))); -static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(8))); -static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE] - __attribute__ ((aligned(8))); - -/* Function Prototypes */ -static int mdio_read(struct eth_device *dev, int phy_id, int addr); -static void mdio_write(struct eth_device *dev, int phy_id, int addr, int value); -static void mdio_sync(struct eth_device *dev, u32 offset); -static int ns8382x_init(struct eth_device *dev, bd_t * bis); -static void ns8382x_reset(struct eth_device *dev); -static void ns8382x_init_rxfilter(struct eth_device *dev); -static void ns8382x_init_txd(struct eth_device *dev); -static void ns8382x_init_rxd(struct eth_device *dev); -static void ns8382x_set_rx_mode(struct eth_device *dev); -static void ns8382x_check_duplex(struct eth_device *dev); -static int ns8382x_send(struct eth_device *dev, void *packet, int length); -static int ns8382x_poll(struct eth_device *dev); -static void ns8382x_disable(struct eth_device *dev); - -static struct pci_device_id supported[] = { - {PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83820}, - {} -}; - -#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a) -#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) - -static inline int -INW(struct eth_device *dev, u_long addr) -{ - return le16_to_cpu(*(vu_short *) (addr + dev->iobase)); -} - -static int -INL(struct eth_device *dev, u_long addr) -{ - return le32_to_cpu(*(vu_long *) (addr + dev->iobase)); -} - -static inline void -OUTW(struct eth_device *dev, int command, u_long addr) -{ - *(vu_short *) ((addr + dev->iobase)) = cpu_to_le16(command); -} - -static inline void -OUTL(struct eth_device *dev, int command, u_long addr) -{ - *(vu_long *) ((addr + dev->iobase)) = cpu_to_le32(command); -} - -/* Function: ns8382x_initialize - * Description: Retrieves the MAC address of the card, and sets up some - * globals required by other routines, and initializes the NIC, making it - * ready to send and receive packets. - * Side effects: initializes ns8382xs, ready to receive packets. - * Returns: int: number of cards found - */ - -int -ns8382x_initialize(bd_t * bis) -{ - pci_dev_t devno; - int card_number = 0; - struct eth_device *dev; - u32 iobase, status; - int i, idx = 0; - u32 phyAddress; - u32 tmp; - u32 chip_config; - - while (1) { /* Find PCI device(s) */ - if ((devno = pci_find_devices(supported, idx++)) < 0) - break; - - pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase); - iobase &= ~0x3; /* 1: unused and 0:I/O Space Indicator */ - - debug("ns8382x: NatSemi dp8382x @ 0x%x\n", iobase); - - pci_write_config_dword(devno, PCI_COMMAND, - PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - - /* Check if I/O accesses and Bus Mastering are enabled. */ - pci_read_config_dword(devno, PCI_COMMAND, &status); - if (!(status & PCI_COMMAND_MEMORY)) { - printf("Error: Can not enable MEM access.\n"); - continue; - } else if (!(status & PCI_COMMAND_MASTER)) { - printf("Error: Can not enable Bus Mastering.\n"); - continue; - } - - dev = (struct eth_device *) malloc(sizeof *dev); - if (!dev) { - printf("ns8382x: Can not allocate memory\n"); - break; - } - memset(dev, 0, sizeof(*dev)); - - sprintf(dev->name, "dp8382x#%d", card_number); - dev->iobase = bus_to_phys(iobase); - dev->priv = (void *) devno; - dev->init = ns8382x_init; - dev->halt = ns8382x_disable; - dev->send = ns8382x_send; - dev->recv = ns8382x_poll; - - /* ns8382x has a non-standard PM control register - * in PCI config space. Some boards apparently need - * to be brought to D0 in this manner. */ - pci_read_config_dword(devno, PCIPM, &tmp); - if (tmp & (0x03 | 0x100)) { /* D0 state, disable PME assertion */ - u32 newtmp = tmp & ~(0x03 | 0x100); - pci_write_config_dword(devno, PCIPM, newtmp); - } - - /* get MAC address */ - for (i = 0; i < 3; i++) { - u32 data; - char *mac = (char *)&dev->enetaddr[i * 2]; - - OUTL(dev, i * 2, RxFilterAddr); - data = INL(dev, RxFilterData); - *mac++ = data; - *mac++ = data >> 8; - } - /* get PHY address, can't be zero */ - for (phyAddress = 1; phyAddress < 32; phyAddress++) { - u32 rev, phy1; - - phy1 = mdio_read(dev, phyAddress, PHYIDR1); - if (phy1 == 0x2000) { /*check for 83861/91 */ - rev = mdio_read(dev, phyAddress, PHYIDR2); - if ((rev & ~(0x000f)) == 0x00005c50 || - (rev & ~(0x000f)) == 0x00005c60) { - debug("phy rev is %x\n", rev); - debug("phy address is %x\n", - phyAddress); - break; - } - } - } - - /* set phy to autonegotiate && advertise everything */ - mdio_write(dev, phyAddress, KTCR, - (ktcr_adv_1000H | ktcr_adv_1000F)); - mdio_write(dev, phyAddress, ANAR, - (anar_adv_100F | anar_adv_100H | anar_adv_10H | - anar_adv_10F | anar_ieee_8023)); - mdio_write(dev, phyAddress, BMCR, 0x0); /*restore */ - mdio_write(dev, phyAddress, BMCR, - (Bmcr_AutoNegEn | Bmcr_RstAutoNeg)); - /* Reset the chip to erase any previous misconfiguration. */ - OUTL(dev, (ChipReset), ChipCmd); - - chip_config = INL(dev, ChipConfig); - /* reset the phy */ - OUTL(dev, (chip_config | PhyRst), ChipConfig); - /* power up and initialize transceiver */ - OUTL(dev, (chip_config & ~(PhyDis)), ChipConfig); - - mdio_sync(dev, EECtrl); - - { - u32 chpcfg = - INL(dev, ChipConfig) ^ SpeedStatus_Polarity; - - debug("%s: Transceiver 10%s %s duplex.\n", dev->name, - (chpcfg & GigSpeed) ? "00" : (chpcfg & HundSpeed) - ? "0" : "", - chpcfg & FullDuplex ? "full" : "half"); - debug("%s: %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, - dev->enetaddr[0], dev->enetaddr[1], - dev->enetaddr[2], dev->enetaddr[3], - dev->enetaddr[4], dev->enetaddr[5]); - } - - /* Disable PME: - * The PME bit is initialized from the EEPROM contents. - * PCI cards probably have PME disabled, but motherboard - * implementations may have PME set to enable WakeOnLan. - * With PME set the chip will scan incoming packets but - * nothing will be written to memory. */ - SavedClkRun = INL(dev, ClkRun); - OUTL(dev, SavedClkRun & ~0x100, ClkRun); - - eth_register(dev); - - card_number++; - - pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x60); - - udelay(10 * 1000); - } - return card_number; -} - -/* MII transceiver control section. - Read and write MII registers using software-generated serial MDIO - protocol. See the MII specifications or DP83840A data sheet for details. - - The maximum data clock rate is 2.5 MHz. To meet minimum timing we - must flush writes to the PCI bus with a PCI read. */ -#define mdio_delay(mdio_addr) INL(dev, mdio_addr) - -#define MDIO_EnbIn (0) -#define MDIO_WRITE0 (MDIO_EnbOutput) -#define MDIO_WRITE1 (MDIO_Data | MDIO_EnbOutput) - -/* Generate the preamble required for initial synchronization and - a few older transceivers. */ -static void -mdio_sync(struct eth_device *dev, u32 offset) -{ - int bits = 32; - - /* Establish sync by sending at least 32 logic ones. */ - while (--bits >= 0) { - OUTL(dev, MDIO_WRITE1, offset); - mdio_delay(offset); - OUTL(dev, MDIO_WRITE1 | MDIO_ShiftClk, offset); - mdio_delay(offset); - } -} - -static int -mdio_read(struct eth_device *dev, int phy_id, int addr) -{ - int mii_cmd = (0xf6 << 10) | (phy_id << 5) | addr; - int i, retval = 0; - - /* Shift the read command bits out. */ - for (i = 15; i >= 0; i--) { - int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0; - - OUTL(dev, dataval, EECtrl); - mdio_delay(EECtrl); - OUTL(dev, dataval | MDIO_ShiftClk, EECtrl); - mdio_delay(EECtrl); - } - /* Read the two transition, 16 data, and wire-idle bits. */ - for (i = 19; i > 0; i--) { - OUTL(dev, MDIO_EnbIn, EECtrl); - mdio_delay(EECtrl); - retval = - (retval << 1) | ((INL(dev, EECtrl) & MDIO_Data) ? 1 : 0); - OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl); - mdio_delay(EECtrl); - } - return (retval >> 1) & 0xffff; -} - -static void -mdio_write(struct eth_device *dev, int phy_id, int addr, int value) -{ - int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (addr << 18) | value; - int i; - - /* Shift the command bits out. */ - for (i = 31; i >= 0; i--) { - int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0; - - OUTL(dev, dataval, EECtrl); - mdio_delay(EECtrl); - OUTL(dev, dataval | MDIO_ShiftClk, EECtrl); - mdio_delay(EECtrl); - } - /* Clear out extra bits. */ - for (i = 2; i > 0; i--) { - OUTL(dev, MDIO_EnbIn, EECtrl); - mdio_delay(EECtrl); - OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl); - mdio_delay(EECtrl); - } - return; -} - -/* Function: ns8382x_init - * Description: resets the ethernet controller chip and configures - * registers and data structures required for sending and receiving packets. - * Arguments: struct eth_device *dev: NIC data structure - * returns: int. - */ - -static int -ns8382x_init(struct eth_device *dev, bd_t * bis) -{ - u32 config; - - ns8382x_reset(dev); - - /* Disable PME: - * The PME bit is initialized from the EEPROM contents. - * PCI cards probably have PME disabled, but motherboard - * implementations may have PME set to enable WakeOnLan. - * With PME set the chip will scan incoming packets but - * nothing will be written to memory. */ - OUTL(dev, SavedClkRun & ~0x100, ClkRun); - - ns8382x_init_rxfilter(dev); - ns8382x_init_txd(dev); - ns8382x_init_rxd(dev); - - /*set up ChipConfig */ - config = INL(dev, ChipConfig); - /*turn off 64 bit ops && Ten-bit interface - * && big-endian mode && extended status */ - config &= ~(TBIEn | Mode1000 | T64En | D64En | M64En | BEMode | PhyDis | ExtStEn); - OUTL(dev, config, ChipConfig); - - /* Configure the PCI bus bursts and FIFO thresholds. */ - tx_config = TxCarrierIgn | TxHeartIgn | TxAutoPad - | TxCollRetry | TxMxdma_1024 | (0x1002); - rx_config = RxMxdma_1024 | 0x20; - - debug("%s: Setting TxConfig Register %#08X\n", dev->name, tx_config); - debug("%s: Setting RxConfig Register %#08X\n", dev->name, rx_config); - - OUTL(dev, tx_config, TxConfig); - OUTL(dev, rx_config, RxConfig); - - /*turn off priority queueing */ - OUTL(dev, 0x0, PriQueue); - - ns8382x_check_duplex(dev); - ns8382x_set_rx_mode(dev); - - OUTL(dev, (RxOn | TxOn), ChipCmd); - return 1; -} - -/* Function: ns8382x_reset - * Description: soft resets the controller chip - * Arguments: struct eth_device *dev: NIC data structure - * Returns: void. - */ -static void -ns8382x_reset(struct eth_device *dev) -{ - OUTL(dev, ChipReset, ChipCmd); - while (INL(dev, ChipCmd)) - /*wait until done */ ; - OUTL(dev, 0, IntrMask); - OUTL(dev, 0, IntrEnable); -} - -/* Function: ns8382x_init_rxfilter - * Description: sets receive filter address to our MAC address - * Arguments: struct eth_device *dev: NIC data structure - * returns: void. - */ - -static void -ns8382x_init_rxfilter(struct eth_device *dev) -{ - int i; - - for (i = 0; i < ETH_ALEN; i += 2) { - OUTL(dev, i, RxFilterAddr); - OUTW(dev, dev->enetaddr[i] + (dev->enetaddr[i + 1] << 8), - RxFilterData); - } -} - -/* Function: ns8382x_init_txd - * Description: initializes the Tx descriptor - * Arguments: struct eth_device *dev: NIC data structure - * returns: void. - */ - -static void -ns8382x_init_txd(struct eth_device *dev) -{ - txd.link = (u32) 0; - txd.bufptr = cpu_to_le32((u32) & txb[0]); - txd.cmdsts = (u32) 0; - txd.extsts = (u32) 0; - - OUTL(dev, 0x0, TxRingPtrHi); - OUTL(dev, phys_to_bus((u32)&txd), TxRingPtr); - - debug("ns8382x_init_txd: TX descriptor register loaded with: %#08X (&txd: %p)\n", - INL(dev, TxRingPtr), &txd); -} - -/* Function: ns8382x_init_rxd - * Description: initializes the Rx descriptor ring - * Arguments: struct eth_device *dev: NIC data structure - * Returns: void. - */ - -static void -ns8382x_init_rxd(struct eth_device *dev) -{ - int i; - - OUTL(dev, 0x0, RxRingPtrHi); - - cur_rx = 0; - for (i = 0; i < NUM_RX_DESC; i++) { - rxd[i].link = - cpu_to_le32((i + 1 < - NUM_RX_DESC) ? (u32) & rxd[i + - 1] : (u32) & - rxd[0]); - rxd[i].extsts = cpu_to_le32((u32) 0x0); - rxd[i].cmdsts = cpu_to_le32((u32) RX_BUF_SIZE); - rxd[i].bufptr = cpu_to_le32((u32) & rxb[i * RX_BUF_SIZE]); - - debug - ("ns8382x_init_rxd: rxd[%d]=%p link=%X cmdsts=%X bufptr=%X\n", - i, &rxd[i], le32_to_cpu(rxd[i].link), - le32_to_cpu(rxd[i].cmdsts), le32_to_cpu(rxd[i].bufptr)); - } - OUTL(dev, phys_to_bus((u32) & rxd), RxRingPtr); - - debug("ns8382x_init_rxd: RX descriptor register loaded with: %X\n", - INL(dev, RxRingPtr)); -} - -/* Function: ns8382x_set_rx_mode - * Description: - * sets the receive mode to accept all broadcast packets and packets - * with our MAC address, and reject all multicast packets. - * Arguments: struct eth_device *dev: NIC data structure - * Returns: void. - */ - -static void -ns8382x_set_rx_mode(struct eth_device *dev) -{ - u32 rx_mode = 0x0; - /*spec says RxFilterEnable has to be 0 for rest of - * this stuff to be properly configured. Linux driver - * seems to support this*/ -/* OUTL(dev, rx_mode, RxFilterAddr);*/ - rx_mode = (RxFilterEnable | AcceptAllBroadcast | AcceptPerfectMatch); - OUTL(dev, rx_mode, RxFilterAddr); - printf("ns8382x_set_rx_mode: set to %X\n", rx_mode); - /*now we turn RxFilterEnable back on */ - /*rx_mode |= RxFilterEnable; - OUTL(dev, rx_mode, RxFilterAddr);*/ -} - -static void -ns8382x_check_duplex(struct eth_device *dev) -{ - int gig = 0; - int hun = 0; - int duplex = 0; - int config = (INL(dev, ChipConfig) ^ SpeedStatus_Polarity); - - duplex = (config & FullDuplex) ? 1 : 0; - gig = (config & GigSpeed) ? 1 : 0; - hun = (config & HundSpeed) ? 1 : 0; - - debug("%s: Setting 10%s %s-duplex based on negotiated link" - " capability.\n", dev->name, (gig) ? "00" : (hun) ? "0" : "", - duplex ? "full" : "half"); - - if (duplex) { - rx_config |= RxAcceptTx; - tx_config |= (TxCarrierIgn | TxHeartIgn); - } else { - rx_config &= ~RxAcceptTx; - tx_config &= ~(TxCarrierIgn | TxHeartIgn); - } - - debug("%s: Resetting TxConfig Register %#08X\n", dev->name, tx_config); - debug("%s: Resetting RxConfig Register %#08X\n", dev->name, rx_config); - - OUTL(dev, tx_config, TxConfig); - OUTL(dev, rx_config, RxConfig); - - /*if speed is 10 or 100, remove MODE1000, - * if it's 1000, then set it */ - config = INL(dev, ChipConfig); - if (gig) - config |= Mode1000; - else - config &= ~Mode1000; - - debug("%s: %setting Mode1000\n", dev->name, (gig) ? "S" : "Uns"); - - OUTL(dev, config, ChipConfig); -} - -/* Function: ns8382x_send - * Description: transmits a packet and waits for completion or timeout. - * Returns: void. */ -static int ns8382x_send(struct eth_device *dev, void *packet, int length) -{ - u32 i, status = 0; - vu_long tx_stat = 0; - - /* Stop the transmitter */ - OUTL(dev, TxOff, ChipCmd); - - debug("ns8382x_send: sending %d bytes\n", (int)length); - - /* set the transmit buffer descriptor and enable Transmit State Machine */ - txd.link = cpu_to_le32(0x0); - txd.bufptr = cpu_to_le32(phys_to_bus((u32)packet)); - txd.extsts = cpu_to_le32(0x0); - txd.cmdsts = cpu_to_le32(DescOwn | length); - - /* load Transmit Descriptor Register */ - OUTL(dev, phys_to_bus((u32) & txd), TxRingPtr); - - debug("ns8382x_send: TX descriptor register loaded with: %#08X\n", - INL(dev, TxRingPtr)); - debug("\ttxd.link:%X\tbufp:%X\texsts:%X\tcmdsts:%X\n", - le32_to_cpu(txd.link), le32_to_cpu(txd.bufptr), - le32_to_cpu(txd.extsts), le32_to_cpu(txd.cmdsts)); - - /* restart the transmitter */ - OUTL(dev, TxOn, ChipCmd); - - for (i = 0; (tx_stat = le32_to_cpu(txd.cmdsts)) & DescOwn; i++) { - if (i >= TOUT_LOOP) { - printf ("%s: tx error buffer not ready: txd.cmdsts %#lX\n", - dev->name, tx_stat); - goto Done; - } - } - - if (!(tx_stat & DescPktOK)) { - printf("ns8382x_send: Transmit error, Tx status %lX.\n", tx_stat); - goto Done; - } - - debug("ns8382x_send: tx_stat: %#08lX\n", tx_stat); - - status = 1; -Done: - return status; -} - -/* Function: ns8382x_poll - * Description: checks for a received packet and returns it if found. - * Arguments: struct eth_device *dev: NIC data structure - * Returns: 1 if packet was received. - * 0 if no packet was received. - * Side effects: - * Returns (copies) the packet to the array dev->packet. - * Returns the length of the packet. - */ - -static int -ns8382x_poll(struct eth_device *dev) -{ - int retstat = 0; - int length = 0; - vu_long rx_status = le32_to_cpu(rxd[cur_rx].cmdsts); - - if (!(rx_status & (u32) DescOwn)) - return retstat; - - debug("ns8382x_poll: got a packet: cur_rx:%u, status:%lx\n", - cur_rx, rx_status); - - length = (rx_status & DSIZE) - CRC_SIZE; - - if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) { - /* corrupted packet received */ - printf("ns8382x_poll: Corrupted packet, status:%lx\n", rx_status); - retstat = 0; - } else { - /* give packet to higher level routine */ - NetReceive((rxb + cur_rx * RX_BUF_SIZE), length); - retstat = 1; - } - - /* return the descriptor and buffer to receive ring */ - rxd[cur_rx].cmdsts = cpu_to_le32(RX_BUF_SIZE); - rxd[cur_rx].bufptr = cpu_to_le32((u32) & rxb[cur_rx * RX_BUF_SIZE]); - - if (++cur_rx == NUM_RX_DESC) - cur_rx = 0; - - /* re-enable the potentially idle receive state machine */ - OUTL(dev, RxOn, ChipCmd); - - return retstat; -} - -/* Function: ns8382x_disable - * Description: Turns off interrupts and stops Tx and Rx engines - * Arguments: struct eth_device *dev: NIC data structure - * Returns: void. - */ - -static void -ns8382x_disable(struct eth_device *dev) -{ - /* Disable interrupts using the mask. */ - OUTL(dev, 0, IntrMask); - OUTL(dev, 0, IntrEnable); - - /* Stop the chip's Tx and Rx processes. */ - OUTL(dev, (RxOff | TxOff), ChipCmd); - - /* Restore PME enable bit */ - OUTL(dev, SavedClkRun, ClkRun); -} diff --git a/qemu/roms/u-boot/drivers/net/pcnet.c b/qemu/roms/u-boot/drivers/net/pcnet.c deleted file mode 100644 index 237fbba51..000000000 --- a/qemu/roms/u-boot/drivers/net/pcnet.c +++ /dev/null @@ -1,542 +0,0 @@ -/* - * (C) Copyright 2002 Wolfgang Grandegger, wg@denx.de. - * - * This driver for AMD PCnet network controllers is derived from the - * Linux driver pcnet32.c written 1996-1999 by Thomas Bogendoerfer. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <asm/io.h> -#include <pci.h> - -#define PCNET_DEBUG_LEVEL 0 /* 0=off, 1=init, 2=rx/tx */ - -#define PCNET_DEBUG1(fmt,args...) \ - debug_cond(PCNET_DEBUG_LEVEL > 0, fmt ,##args) -#define PCNET_DEBUG2(fmt,args...) \ - debug_cond(PCNET_DEBUG_LEVEL > 1, fmt ,##args) - -#if !defined(CONF_PCNET_79C973) && defined(CONF_PCNET_79C975) -#error "Macro for PCnet chip version is not defined!" -#endif - -/* - * Set the number of Tx and Rx buffers, using Log_2(# buffers). - * Reasonable default values are 4 Tx buffers, and 16 Rx buffers. - * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4). - */ -#define PCNET_LOG_TX_BUFFERS 0 -#define PCNET_LOG_RX_BUFFERS 2 - -#define TX_RING_SIZE (1 << (PCNET_LOG_TX_BUFFERS)) -#define TX_RING_LEN_BITS ((PCNET_LOG_TX_BUFFERS) << 12) - -#define RX_RING_SIZE (1 << (PCNET_LOG_RX_BUFFERS)) -#define RX_RING_LEN_BITS ((PCNET_LOG_RX_BUFFERS) << 4) - -#define PKT_BUF_SZ 1544 - -/* The PCNET Rx and Tx ring descriptors. */ -struct pcnet_rx_head { - u32 base; - s16 buf_length; - s16 status; - u32 msg_length; - u32 reserved; -}; - -struct pcnet_tx_head { - u32 base; - s16 length; - s16 status; - u32 misc; - u32 reserved; -}; - -/* The PCNET 32-Bit initialization block, described in databook. */ -struct pcnet_init_block { - u16 mode; - u16 tlen_rlen; - u8 phys_addr[6]; - u16 reserved; - u32 filter[2]; - /* Receive and transmit ring base, along with extra bits. */ - u32 rx_ring; - u32 tx_ring; - u32 reserved2; -}; - -struct pcnet_uncached_priv { - struct pcnet_rx_head rx_ring[RX_RING_SIZE]; - struct pcnet_tx_head tx_ring[TX_RING_SIZE]; - struct pcnet_init_block init_block; -}; - -typedef struct pcnet_priv { - struct pcnet_uncached_priv *uc; - /* Receive Buffer space */ - unsigned char (*rx_buf)[RX_RING_SIZE][PKT_BUF_SZ + 4]; - int cur_rx; - int cur_tx; -} pcnet_priv_t; - -static pcnet_priv_t *lp; - -/* Offsets from base I/O address for WIO mode */ -#define PCNET_RDP 0x10 -#define PCNET_RAP 0x12 -#define PCNET_RESET 0x14 -#define PCNET_BDP 0x16 - -static u16 pcnet_read_csr(struct eth_device *dev, int index) -{ - outw(index, dev->iobase + PCNET_RAP); - return inw(dev->iobase + PCNET_RDP); -} - -static void pcnet_write_csr(struct eth_device *dev, int index, u16 val) -{ - outw(index, dev->iobase + PCNET_RAP); - outw(val, dev->iobase + PCNET_RDP); -} - -static u16 pcnet_read_bcr(struct eth_device *dev, int index) -{ - outw(index, dev->iobase + PCNET_RAP); - return inw(dev->iobase + PCNET_BDP); -} - -static void pcnet_write_bcr(struct eth_device *dev, int index, u16 val) -{ - outw(index, dev->iobase + PCNET_RAP); - outw(val, dev->iobase + PCNET_BDP); -} - -static void pcnet_reset(struct eth_device *dev) -{ - inw(dev->iobase + PCNET_RESET); -} - -static int pcnet_check(struct eth_device *dev) -{ - outw(88, dev->iobase + PCNET_RAP); - return inw(dev->iobase + PCNET_RAP) == 88; -} - -static int pcnet_init (struct eth_device *dev, bd_t * bis); -static int pcnet_send(struct eth_device *dev, void *packet, int length); -static int pcnet_recv (struct eth_device *dev); -static void pcnet_halt (struct eth_device *dev); -static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_num); - -#define PCI_TO_MEM(d, a) pci_virt_to_mem((pci_dev_t)d->priv, (a)) -#define PCI_TO_MEM_LE(d,a) (u32)(cpu_to_le32(PCI_TO_MEM(d,a))) - -static struct pci_device_id supported[] = { - {PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE}, - {} -}; - - -int pcnet_initialize(bd_t *bis) -{ - pci_dev_t devbusfn; - struct eth_device *dev; - u16 command, status; - int dev_nr = 0; - - PCNET_DEBUG1("\npcnet_initialize...\n"); - - for (dev_nr = 0;; dev_nr++) { - - /* - * Find the PCnet PCI device(s). - */ - devbusfn = pci_find_devices(supported, dev_nr); - if (devbusfn < 0) - break; - - /* - * Allocate and pre-fill the device structure. - */ - dev = (struct eth_device *)malloc(sizeof(*dev)); - if (!dev) { - printf("pcnet: Can not allocate memory\n"); - break; - } - memset(dev, 0, sizeof(*dev)); - dev->priv = (void *)devbusfn; - sprintf(dev->name, "pcnet#%d", dev_nr); - - /* - * Setup the PCI device. - */ - pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, - (unsigned int *)&dev->iobase); - dev->iobase = pci_io_to_phys(devbusfn, dev->iobase); - dev->iobase &= ~0xf; - - PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%x: ", - dev->name, devbusfn, dev->iobase); - - command = PCI_COMMAND_IO | PCI_COMMAND_MASTER; - pci_write_config_word(devbusfn, PCI_COMMAND, command); - pci_read_config_word(devbusfn, PCI_COMMAND, &status); - if ((status & command) != command) { - printf("%s: Couldn't enable IO access or Bus Mastering\n", - dev->name); - free(dev); - continue; - } - - pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40); - - /* - * Probe the PCnet chip. - */ - if (pcnet_probe(dev, bis, dev_nr) < 0) { - free(dev); - continue; - } - - /* - * Setup device structure and register the driver. - */ - dev->init = pcnet_init; - dev->halt = pcnet_halt; - dev->send = pcnet_send; - dev->recv = pcnet_recv; - - eth_register(dev); - } - - udelay(10 * 1000); - - return dev_nr; -} - -static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) -{ - int chip_version; - char *chipname; - -#ifdef PCNET_HAS_PROM - int i; -#endif - - /* Reset the PCnet controller */ - pcnet_reset(dev); - - /* Check if register access is working */ - if (pcnet_read_csr(dev, 0) != 4 || !pcnet_check(dev)) { - printf("%s: CSR register access check failed\n", dev->name); - return -1; - } - - /* Identify the chip */ - chip_version = - pcnet_read_csr(dev, 88) | (pcnet_read_csr(dev, 89) << 16); - if ((chip_version & 0xfff) != 0x003) - return -1; - chip_version = (chip_version >> 12) & 0xffff; - switch (chip_version) { - case 0x2621: - chipname = "PCnet/PCI II 79C970A"; /* PCI */ - break; -#ifdef CONFIG_PCNET_79C973 - case 0x2625: - chipname = "PCnet/FAST III 79C973"; /* PCI */ - break; -#endif -#ifdef CONFIG_PCNET_79C975 - case 0x2627: - chipname = "PCnet/FAST III 79C975"; /* PCI */ - break; -#endif - default: - printf("%s: PCnet version %#x not supported\n", - dev->name, chip_version); - return -1; - } - - PCNET_DEBUG1("AMD %s\n", chipname); - -#ifdef PCNET_HAS_PROM - /* - * In most chips, after a chip reset, the ethernet address is read from - * the station address PROM at the base address and programmed into the - * "Physical Address Registers" CSR12-14. - */ - for (i = 0; i < 3; i++) { - unsigned int val; - - val = pcnet_read_csr(dev, i + 12) & 0x0ffff; - /* There may be endianness issues here. */ - dev->enetaddr[2 * i] = val & 0x0ff; - dev->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; - } -#endif /* PCNET_HAS_PROM */ - - return 0; -} - -static int pcnet_init(struct eth_device *dev, bd_t *bis) -{ - struct pcnet_uncached_priv *uc; - int i, val; - u32 addr; - - PCNET_DEBUG1("%s: pcnet_init...\n", dev->name); - - /* Switch pcnet to 32bit mode */ - pcnet_write_bcr(dev, 20, 2); - - /* Set/reset autoselect bit */ - val = pcnet_read_bcr(dev, 2) & ~2; - val |= 2; - pcnet_write_bcr(dev, 2, val); - - /* Enable auto negotiate, setup, disable fd */ - val = pcnet_read_bcr(dev, 32) & ~0x98; - val |= 0x20; - pcnet_write_bcr(dev, 32, val); - - /* - * Enable NOUFLO on supported controllers, with the transmit - * start point set to the full packet. This will cause entire - * packets to be buffered by the ethernet controller before - * transmission, eliminating underflows which are common on - * slower devices. Controllers which do not support NOUFLO will - * simply be left with a larger transmit FIFO threshold. - */ - val = pcnet_read_bcr(dev, 18); - val |= 1 << 11; - pcnet_write_bcr(dev, 18, val); - val = pcnet_read_csr(dev, 80); - val |= 0x3 << 10; - pcnet_write_csr(dev, 80, val); - - /* - * We only maintain one structure because the drivers will never - * be used concurrently. In 32bit mode the RX and TX ring entries - * must be aligned on 16-byte boundaries. - */ - if (lp == NULL) { - addr = (u32)malloc(sizeof(pcnet_priv_t) + 0x10); - addr = (addr + 0xf) & ~0xf; - lp = (pcnet_priv_t *)addr; - - addr = (u32)memalign(ARCH_DMA_MINALIGN, sizeof(*lp->uc)); - flush_dcache_range(addr, addr + sizeof(*lp->uc)); - addr = UNCACHED_SDRAM(addr); - lp->uc = (struct pcnet_uncached_priv *)addr; - - addr = (u32)memalign(ARCH_DMA_MINALIGN, sizeof(*lp->rx_buf)); - flush_dcache_range(addr, addr + sizeof(*lp->rx_buf)); - lp->rx_buf = (void *)addr; - } - - uc = lp->uc; - - uc->init_block.mode = cpu_to_le16(0x0000); - uc->init_block.filter[0] = 0x00000000; - uc->init_block.filter[1] = 0x00000000; - - /* - * Initialize the Rx ring. - */ - lp->cur_rx = 0; - for (i = 0; i < RX_RING_SIZE; i++) { - uc->rx_ring[i].base = PCI_TO_MEM_LE(dev, (*lp->rx_buf)[i]); - uc->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ); - uc->rx_ring[i].status = cpu_to_le16(0x8000); - PCNET_DEBUG1 - ("Rx%d: base=0x%x buf_length=0x%hx status=0x%hx\n", i, - uc->rx_ring[i].base, uc->rx_ring[i].buf_length, - uc->rx_ring[i].status); - } - - /* - * Initialize the Tx ring. The Tx buffer address is filled in as - * needed, but we do need to clear the upper ownership bit. - */ - lp->cur_tx = 0; - for (i = 0; i < TX_RING_SIZE; i++) { - uc->tx_ring[i].base = 0; - uc->tx_ring[i].status = 0; - } - - /* - * Setup Init Block. - */ - PCNET_DEBUG1("Init block at 0x%p: MAC", &lp->uc->init_block); - - for (i = 0; i < 6; i++) { - lp->uc->init_block.phys_addr[i] = dev->enetaddr[i]; - PCNET_DEBUG1(" %02x", lp->uc->init_block.phys_addr[i]); - } - - uc->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS | - RX_RING_LEN_BITS); - uc->init_block.rx_ring = PCI_TO_MEM_LE(dev, uc->rx_ring); - uc->init_block.tx_ring = PCI_TO_MEM_LE(dev, uc->tx_ring); - - PCNET_DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n", - uc->init_block.tlen_rlen, - uc->init_block.rx_ring, uc->init_block.tx_ring); - - /* - * Tell the controller where the Init Block is located. - */ - barrier(); - addr = PCI_TO_MEM(dev, &lp->uc->init_block); - pcnet_write_csr(dev, 1, addr & 0xffff); - pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff); - - pcnet_write_csr(dev, 4, 0x0915); - pcnet_write_csr(dev, 0, 0x0001); /* start */ - - /* Wait for Init Done bit */ - for (i = 10000; i > 0; i--) { - if (pcnet_read_csr(dev, 0) & 0x0100) - break; - udelay(10); - } - if (i <= 0) { - printf("%s: TIMEOUT: controller init failed\n", dev->name); - pcnet_reset(dev); - return -1; - } - - /* - * Finally start network controller operation. - */ - pcnet_write_csr(dev, 0, 0x0002); - - return 0; -} - -static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) -{ - int i, status; - struct pcnet_tx_head *entry = &lp->uc->tx_ring[lp->cur_tx]; - - PCNET_DEBUG2("Tx%d: %d bytes from 0x%p ", lp->cur_tx, pkt_len, - packet); - - flush_dcache_range((unsigned long)packet, - (unsigned long)packet + pkt_len); - - /* Wait for completion by testing the OWN bit */ - for (i = 1000; i > 0; i--) { - status = readw(&entry->status); - if ((status & 0x8000) == 0) - break; - udelay(100); - PCNET_DEBUG2("."); - } - if (i <= 0) { - printf("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n", - dev->name, lp->cur_tx, status); - pkt_len = 0; - goto failure; - } - - /* - * Setup Tx ring. Caution: the write order is important here, - * set the status with the "ownership" bits last. - */ - writew(-pkt_len, &entry->length); - writel(0, &entry->misc); - writel(PCI_TO_MEM(dev, packet), &entry->base); - writew(0x8300, &entry->status); - - /* Trigger an immediate send poll. */ - pcnet_write_csr(dev, 0, 0x0008); - - failure: - if (++lp->cur_tx >= TX_RING_SIZE) - lp->cur_tx = 0; - - PCNET_DEBUG2("done\n"); - return pkt_len; -} - -static int pcnet_recv (struct eth_device *dev) -{ - struct pcnet_rx_head *entry; - unsigned char *buf; - int pkt_len = 0; - u16 status, err_status; - - while (1) { - entry = &lp->uc->rx_ring[lp->cur_rx]; - /* - * If we own the next entry, it's a new packet. Send it up. - */ - status = readw(&entry->status); - if ((status & 0x8000) != 0) - break; - err_status = status >> 8; - - if (err_status != 0x03) { /* There was an error. */ - printf("%s: Rx%d", dev->name, lp->cur_rx); - PCNET_DEBUG1(" (status=0x%x)", err_status); - if (err_status & 0x20) - printf(" Frame"); - if (err_status & 0x10) - printf(" Overflow"); - if (err_status & 0x08) - printf(" CRC"); - if (err_status & 0x04) - printf(" Fifo"); - printf(" Error\n"); - status &= 0x03ff; - - } else { - pkt_len = (readl(&entry->msg_length) & 0xfff) - 4; - if (pkt_len < 60) { - printf("%s: Rx%d: invalid packet length %d\n", - dev->name, lp->cur_rx, pkt_len); - } else { - buf = (*lp->rx_buf)[lp->cur_rx]; - invalidate_dcache_range((unsigned long)buf, - (unsigned long)buf + pkt_len); - NetReceive(buf, pkt_len); - PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n", - lp->cur_rx, pkt_len, buf); - } - } - - status |= 0x8000; - writew(status, &entry->status); - - if (++lp->cur_rx >= RX_RING_SIZE) - lp->cur_rx = 0; - } - return pkt_len; -} - -static void pcnet_halt(struct eth_device *dev) -{ - int i; - - PCNET_DEBUG1("%s: pcnet_halt...\n", dev->name); - - /* Reset the PCnet controller */ - pcnet_reset(dev); - - /* Wait for Stop bit */ - for (i = 1000; i > 0; i--) { - if (pcnet_read_csr(dev, 0) & 0x4) - break; - udelay(10); - } - if (i <= 0) - printf("%s: TIMEOUT: controller reset failed\n", dev->name); -} diff --git a/qemu/roms/u-boot/drivers/net/phy/Makefile b/qemu/roms/u-boot/drivers/net/phy/Makefile deleted file mode 100644 index dbf7bf705..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# -# (C) Copyright 2008 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-$(CONFIG_BITBANGMII) += miiphybb.o -obj-$(CONFIG_MV88E61XX_SWITCH) += mv88e61xx.o -obj-$(CONFIG_MV88E6352_SWITCH) += mv88e6352.o - -obj-$(CONFIG_PHYLIB) += phy.o -obj-$(CONFIG_PHYLIB_10G) += generic_10g.o -obj-$(CONFIG_PHY_ATHEROS) += atheros.o -obj-$(CONFIG_PHY_BROADCOM) += broadcom.o -obj-$(CONFIG_PHY_DAVICOM) += davicom.o -obj-$(CONFIG_PHY_ET1011C) += et1011c.o -obj-$(CONFIG_PHY_ICPLUS) += icplus.o -obj-$(CONFIG_PHY_LXT) += lxt.o -obj-$(CONFIG_PHY_MARVELL) += marvell.o -obj-$(CONFIG_PHY_MICREL) += micrel.o -obj-$(CONFIG_PHY_NATSEMI) += natsemi.o -obj-$(CONFIG_PHY_REALTEK) += realtek.o -obj-$(CONFIG_PHY_SMSC) += smsc.o -obj-$(CONFIG_PHY_TERANETICS) += teranetics.o -obj-$(CONFIG_PHY_VITESSE) += vitesse.o diff --git a/qemu/roms/u-boot/drivers/net/phy/atheros.c b/qemu/roms/u-boot/drivers/net/phy/atheros.c deleted file mode 100644 index d509e30d3..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/atheros.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Atheros PHY drivers - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Copyright 2011, 2013 Freescale Semiconductor, Inc. - * author Andy Fleming - */ -#include <phy.h> - -static int ar8021_config(struct phy_device *phydev) -{ - phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); - phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x3D47); - - phydev->supported = phydev->drv->features; - return 0; -} - -static int ar8035_config(struct phy_device *phydev) -{ - int regval; - - phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x0007); - phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016); - phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007); - regval = phy_read(phydev, MDIO_DEVAD_NONE, 0xe); - phy_write(phydev, MDIO_DEVAD_NONE, 0xe, (regval|0x0018)); - - phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); - regval = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e); - phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, (regval|0x0100)); - - phydev->supported = phydev->drv->features; - - return 0; -} - -static struct phy_driver AR8021_driver = { - .name = "AR8021", - .uid = 0x4dd040, - .mask = 0x4ffff0, - .features = PHY_GBIT_FEATURES, - .config = ar8021_config, - .startup = genphy_startup, - .shutdown = genphy_shutdown, -}; - -static struct phy_driver AR8031_driver = { - .name = "AR8031/AR8033", - .uid = 0x4dd074, - .mask = 0xffffffef, - .features = PHY_GBIT_FEATURES, - .config = ar8021_config, - .startup = genphy_startup, - .shutdown = genphy_shutdown, -}; - -static struct phy_driver AR8035_driver = { - .name = "AR8035", - .uid = 0x4dd072, - .mask = 0xffffffef, - .features = PHY_GBIT_FEATURES, - .config = ar8035_config, - .startup = genphy_startup, - .shutdown = genphy_shutdown, -}; - -int phy_atheros_init(void) -{ - phy_register(&AR8021_driver); - phy_register(&AR8031_driver); - phy_register(&AR8035_driver); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/phy/broadcom.c b/qemu/roms/u-boot/drivers/net/phy/broadcom.c deleted file mode 100644 index 4512763b5..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/broadcom.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Broadcom PHY drivers - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Copyright 2010-2011 Freescale Semiconductor, Inc. - * author Andy Fleming - */ -#include <config.h> -#include <common.h> -#include <phy.h> - -/* Broadcom BCM54xx -- taken from linux sungem_phy */ -#define MIIM_BCM54xx_AUXCNTL 0x18 -#define MIIM_BCM54xx_AUXCNTL_ENCODE(val) (((val & 0x7) << 12)|(val & 0x7)) -#define MIIM_BCM54xx_AUXSTATUS 0x19 -#define MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK 0x0700 -#define MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT 8 - -#define MIIM_BCM54XX_SHD 0x1c -#define MIIM_BCM54XX_SHD_WRITE 0x8000 -#define MIIM_BCM54XX_SHD_VAL(x) ((x & 0x1f) << 10) -#define MIIM_BCM54XX_SHD_DATA(x) ((x & 0x3ff) << 0) -#define MIIM_BCM54XX_SHD_WR_ENCODE(val, data) \ - (MIIM_BCM54XX_SHD_WRITE | MIIM_BCM54XX_SHD_VAL(val) | \ - MIIM_BCM54XX_SHD_DATA(data)) - -#define MIIM_BCM54XX_EXP_DATA 0x15 /* Expansion register data */ -#define MIIM_BCM54XX_EXP_SEL 0x17 /* Expansion register select */ -#define MIIM_BCM54XX_EXP_SEL_SSD 0x0e00 /* Secondary SerDes select */ -#define MIIM_BCM54XX_EXP_SEL_ER 0x0f00 /* Expansion register select */ - -/* Broadcom BCM5461S */ -static int bcm5461_config(struct phy_device *phydev) -{ - genphy_config_aneg(phydev); - - phy_reset(phydev); - - return 0; -} - -static int bcm54xx_parse_status(struct phy_device *phydev) -{ - unsigned int mii_reg; - - mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXSTATUS); - - switch ((mii_reg & MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK) >> - MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT) { - case 1: - phydev->duplex = DUPLEX_HALF; - phydev->speed = SPEED_10; - break; - case 2: - phydev->duplex = DUPLEX_FULL; - phydev->speed = SPEED_10; - break; - case 3: - phydev->duplex = DUPLEX_HALF; - phydev->speed = SPEED_100; - break; - case 5: - phydev->duplex = DUPLEX_FULL; - phydev->speed = SPEED_100; - break; - case 6: - phydev->duplex = DUPLEX_HALF; - phydev->speed = SPEED_1000; - break; - case 7: - phydev->duplex = DUPLEX_FULL; - phydev->speed = SPEED_1000; - break; - default: - printf("Auto-neg error, defaulting to 10BT/HD\n"); - phydev->duplex = DUPLEX_HALF; - phydev->speed = SPEED_10; - break; - } - - return 0; -} - -static int bcm54xx_startup(struct phy_device *phydev) -{ - /* Read the Status (2x to make sure link is right) */ - genphy_update_link(phydev); - bcm54xx_parse_status(phydev); - - return 0; -} - -/* Broadcom BCM5482S */ -/* - * "Ethernet@Wirespeed" needs to be enabled to achieve link in certain - * circumstances. eg a gigabit TSEC connected to a gigabit switch with - * a 4-wire ethernet cable. Both ends advertise gigabit, but can't - * link. "Ethernet@Wirespeed" reduces advertised speed until link - * can be achieved. - */ -static u32 bcm5482_read_wirespeed(struct phy_device *phydev, u32 reg) -{ - return (phy_read(phydev, MDIO_DEVAD_NONE, reg) & 0x8FFF) | 0x8010; -} - -static int bcm5482_config(struct phy_device *phydev) -{ - unsigned int reg; - - /* reset the PHY */ - reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); - reg |= BMCR_RESET; - phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, reg); - - /* Setup read from auxilary control shadow register 7 */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL, - MIIM_BCM54xx_AUXCNTL_ENCODE(7)); - /* Read Misc Control register and or in Ethernet@Wirespeed */ - reg = bcm5482_read_wirespeed(phydev, MIIM_BCM54xx_AUXCNTL); - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL, reg); - - /* Initial config/enable of secondary SerDes interface */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_SHD, - MIIM_BCM54XX_SHD_WR_ENCODE(0x14, 0xf)); - /* Write intial value to secondary SerDes Contol */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_SEL, - MIIM_BCM54XX_EXP_SEL_SSD | 0); - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_DATA, - BMCR_ANRESTART); - /* Enable copper/fiber auto-detect */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_SHD, - MIIM_BCM54XX_SHD_WR_ENCODE(0x1e, 0x201)); - - genphy_config_aneg(phydev); - - return 0; -} - -/* - * Find out if PHY is in copper or serdes mode by looking at Expansion Reg - * 0x42 - "Operating Mode Status Register" - */ -static int bcm5482_is_serdes(struct phy_device *phydev) -{ - u16 val; - int serdes = 0; - - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_SEL, - MIIM_BCM54XX_EXP_SEL_ER | 0x42); - val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_DATA); - - switch (val & 0x1f) { - case 0x0d: /* RGMII-to-100Base-FX */ - case 0x0e: /* RGMII-to-SGMII */ - case 0x0f: /* RGMII-to-SerDes */ - case 0x12: /* SGMII-to-SerDes */ - case 0x13: /* SGMII-to-100Base-FX */ - case 0x16: /* SerDes-to-Serdes */ - serdes = 1; - break; - case 0x6: /* RGMII-to-Copper */ - case 0x14: /* SGMII-to-Copper */ - case 0x17: /* SerDes-to-Copper */ - break; - default: - printf("ERROR, invalid PHY mode (0x%x\n)", val); - break; - } - - return serdes; -} - -/* - * Determine SerDes link speed and duplex from Expansion reg 0x42 "Operating - * Mode Status Register" - */ -static u32 bcm5482_parse_serdes_sr(struct phy_device *phydev) -{ - u16 val; - int i = 0; - - /* Wait 1s for link - Clause 37 autonegotiation happens very fast */ - while (1) { - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_SEL, - MIIM_BCM54XX_EXP_SEL_ER | 0x42); - val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_DATA); - - if (val & 0x8000) - break; - - if (i++ > 1000) { - phydev->link = 0; - return 1; - } - - udelay(1000); /* 1 ms */ - } - - phydev->link = 1; - switch ((val >> 13) & 0x3) { - case (0x00): - phydev->speed = 10; - break; - case (0x01): - phydev->speed = 100; - break; - case (0x02): - phydev->speed = 1000; - break; - } - - phydev->duplex = (val & 0x1000) == 0x1000; - - return 0; -} - -/* - * Figure out if BCM5482 is in serdes or copper mode and determine link - * configuration accordingly - */ -static int bcm5482_startup(struct phy_device *phydev) -{ - if (bcm5482_is_serdes(phydev)) { - bcm5482_parse_serdes_sr(phydev); - phydev->port = PORT_FIBRE; - } else { - /* Wait for auto-negotiation to complete or fail */ - genphy_update_link(phydev); - /* Parse BCM54xx copper aux status register */ - bcm54xx_parse_status(phydev); - } - - return 0; -} - -static struct phy_driver BCM5461S_driver = { - .name = "Broadcom BCM5461S", - .uid = 0x2060c0, - .mask = 0xfffff0, - .features = PHY_GBIT_FEATURES, - .config = &bcm5461_config, - .startup = &bcm54xx_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver BCM5464S_driver = { - .name = "Broadcom BCM5464S", - .uid = 0x2060b0, - .mask = 0xfffff0, - .features = PHY_GBIT_FEATURES, - .config = &bcm5461_config, - .startup = &bcm54xx_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver BCM5482S_driver = { - .name = "Broadcom BCM5482S", - .uid = 0x143bcb0, - .mask = 0xffffff0, - .features = PHY_GBIT_FEATURES, - .config = &bcm5482_config, - .startup = &bcm5482_startup, - .shutdown = &genphy_shutdown, -}; - -int phy_broadcom_init(void) -{ - phy_register(&BCM5482S_driver); - phy_register(&BCM5464S_driver); - phy_register(&BCM5461S_driver); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/phy/davicom.c b/qemu/roms/u-boot/drivers/net/phy/davicom.c deleted file mode 100644 index 0c039fe79..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/davicom.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Davicom PHY drivers - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Copyright 2010-2011 Freescale Semiconductor, Inc. - * author Andy Fleming - */ -#include <phy.h> - -#define MIIM_DM9161_SCR 0x10 -#define MIIM_DM9161_SCR_INIT 0x0610 - -/* DM9161 Specified Configuration and Status Register */ -#define MIIM_DM9161_SCSR 0x11 -#define MIIM_DM9161_SCSR_100F 0x8000 -#define MIIM_DM9161_SCSR_100H 0x4000 -#define MIIM_DM9161_SCSR_10F 0x2000 -#define MIIM_DM9161_SCSR_10H 0x1000 - -/* DM9161 10BT Configuration/Status */ -#define MIIM_DM9161_10BTCSR 0x12 -#define MIIM_DM9161_10BTCSR_INIT 0x7800 - - -/* Davicom DM9161E */ -static int dm9161_config(struct phy_device *phydev) -{ - phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_ISOLATE); - /* Do not bypass the scrambler/descrambler */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_DM9161_SCR, - MIIM_DM9161_SCR_INIT); - /* Clear 10BTCSR to default */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_DM9161_10BTCSR, - MIIM_DM9161_10BTCSR_INIT); - - genphy_config_aneg(phydev); - - return 0; -} - -static int dm9161_parse_status(struct phy_device *phydev) -{ - int mii_reg; - - mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_DM9161_SCSR); - - if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_100H)) - phydev->speed = SPEED_100; - else - phydev->speed = SPEED_10; - - if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_10F)) - phydev->duplex = DUPLEX_FULL; - else - phydev->duplex = DUPLEX_HALF; - - return 0; -} - -static int dm9161_startup(struct phy_device *phydev) -{ - genphy_update_link(phydev); - dm9161_parse_status(phydev); - - return 0; -} - -static struct phy_driver DM9161_driver = { - .name = "Davicom DM9161E", - .uid = 0x181b880, - .mask = 0xffffff0, - .features = PHY_BASIC_FEATURES, - .config = &dm9161_config, - .startup = &dm9161_startup, - .shutdown = &genphy_shutdown, -}; - -int phy_davicom_init(void) -{ - phy_register(&DM9161_driver); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/phy/et1011c.c b/qemu/roms/u-boot/drivers/net/phy/et1011c.c deleted file mode 100644 index 70c15e2f2..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/et1011c.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * ET1011C PHY driver - * - * Derived from Linux kernel driver by Chaithrika U S - * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/ - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <config.h> -#include <phy.h> - -#define ET1011C_CONFIG_REG (0x16) -#define ET1011C_TX_FIFO_MASK (0x3 << 12) -#define ET1011C_TX_FIFO_DEPTH_8 (0x0 << 12) -#define ET1011C_TX_FIFO_DEPTH_16 (0x1 << 12) -#define ET1011C_INTERFACE_MASK (0x7 << 0) -#define ET1011C_GMII_INTERFACE (0x2 << 0) -#define ET1011C_SYS_CLK_EN (0x1 << 4) -#define ET1011C_TX_CLK_EN (0x1 << 5) - -#define ET1011C_STATUS_REG (0x1A) -#define ET1011C_DUPLEX_STATUS (0x1 << 7) -#define ET1011C_SPEED_MASK (0x3 << 8) -#define ET1011C_SPEED_1000 (0x2 << 8) -#define ET1011C_SPEED_100 (0x1 << 8) -#define ET1011C_SPEED_10 (0x0 << 8) - -static int et1011c_config(struct phy_device *phydev) -{ - int ctl = 0; - ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); - if (ctl < 0) - return ctl; - ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | - BMCR_ANENABLE); - /* First clear the PHY */ - phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl | BMCR_RESET); - - return genphy_config_aneg(phydev); -} - -static int et1011c_parse_status(struct phy_device *phydev) -{ - int mii_reg; - int speed; - - mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, ET1011C_STATUS_REG); - - if (mii_reg & ET1011C_DUPLEX_STATUS) - phydev->duplex = DUPLEX_FULL; - else - phydev->duplex = DUPLEX_HALF; - - speed = mii_reg & ET1011C_SPEED_MASK; - switch (speed) { - case ET1011C_SPEED_1000: - phydev->speed = SPEED_1000; - mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, ET1011C_CONFIG_REG); - mii_reg &= ~ET1011C_TX_FIFO_MASK; - phy_write(phydev, MDIO_DEVAD_NONE, ET1011C_CONFIG_REG, - mii_reg | - ET1011C_GMII_INTERFACE | - ET1011C_SYS_CLK_EN | -#ifdef CONFIG_PHY_ET1011C_TX_CLK_FIX - ET1011C_TX_CLK_EN | -#endif - ET1011C_TX_FIFO_DEPTH_16); - break; - case ET1011C_SPEED_100: - phydev->speed = SPEED_100; - break; - case ET1011C_SPEED_10: - phydev->speed = SPEED_10; - break; - } - - return 0; -} - -static int et1011c_startup(struct phy_device *phydev) -{ - genphy_update_link(phydev); - et1011c_parse_status(phydev); - return 0; -} - -static struct phy_driver et1011c_driver = { - .name = "ET1011C", - .uid = 0x0282f014, - .mask = 0xfffffff0, - .features = PHY_GBIT_FEATURES, - .config = &et1011c_config, - .startup = &et1011c_startup, -}; - -int phy_et1011c_init(void) -{ - phy_register(&et1011c_driver); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/phy/generic_10g.c b/qemu/roms/u-boot/drivers/net/phy/generic_10g.c deleted file mode 100644 index ed3dcd91d..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/generic_10g.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Generic PHY Management code - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Copyright 2011 Freescale Semiconductor, Inc. - * author Andy Fleming - * - * Based loosely off of Linux's PHY Lib - */ - -#include <config.h> -#include <common.h> -#include <miiphy.h> -#include <phy.h> - -int gen10g_shutdown(struct phy_device *phydev) -{ - return 0; -} - -int gen10g_startup(struct phy_device *phydev) -{ - int devad, reg; - u32 mmd_mask = phydev->mmds & MDIO_DEVS_LINK; - - phydev->link = 1; - - /* For now just lie and say it's 10G all the time */ - phydev->speed = SPEED_10000; - phydev->duplex = DUPLEX_FULL; - - /* - * Go through all the link-reporting devices, and make sure - * they're all up and happy - */ - for (devad = 0; mmd_mask; devad++, mmd_mask = mmd_mask >> 1) { - if (!(mmd_mask & 1)) - continue; - - /* Read twice because link state is latched and a - * read moves the current state into the register */ - phy_read(phydev, devad, MDIO_STAT1); - reg = phy_read(phydev, devad, MDIO_STAT1); - if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS)) - phydev->link = 0; - } - - return 0; -} - -int gen10g_discover_mmds(struct phy_device *phydev) -{ - int mmd, stat2, devs1, devs2; - - /* Assume PHY must have at least one of PMA/PMD, WIS, PCS, PHY - * XS or DTE XS; give up if none is present. */ - for (mmd = 1; mmd <= 5; mmd++) { - /* Is this MMD present? */ - stat2 = phy_read(phydev, mmd, MDIO_STAT2); - if (stat2 < 0 || - (stat2 & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL) - continue; - - /* It should tell us about all the other MMDs */ - devs1 = phy_read(phydev, mmd, MDIO_DEVS1); - devs2 = phy_read(phydev, mmd, MDIO_DEVS2); - if (devs1 < 0 || devs2 < 0) - continue; - - phydev->mmds = devs1 | (devs2 << 16); - return 0; - } - - return 0; -} - -int gen10g_config(struct phy_device *phydev) -{ - /* For now, assume 10000baseT. Fill in later */ - phydev->supported = phydev->advertising = SUPPORTED_10000baseT_Full; - - return gen10g_discover_mmds(phydev); -} - -struct phy_driver gen10g_driver = { - .uid = 0xffffffff, - .mask = 0xffffffff, - .name = "Generic 10G PHY", - .features = 0, - .config = gen10g_config, - .startup = gen10g_startup, - .shutdown = gen10g_shutdown, -}; diff --git a/qemu/roms/u-boot/drivers/net/phy/icplus.c b/qemu/roms/u-boot/drivers/net/phy/icplus.c deleted file mode 100644 index 597195580..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/icplus.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * ICPlus PHY drivers - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Copyright (c) 2007 Freescale Semiconductor, Inc. - */ -#include <phy.h> - -/* IP101A/G - IP1001 */ -#define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */ -#define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */ -#define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */ -#define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ -#define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ -#define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */ -#define IP101A_G_IRQ_PIN_USED (1<<15) /* INTR pin used */ -#define IP101A_G_IRQ_DEFAULT IP101A_G_IRQ_PIN_USED - -static int ip1001_config(struct phy_device *phydev) -{ - int c; - - /* Enable Auto Power Saving mode */ - c = phy_read(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2); - if (c < 0) - return c; - c |= IP1001_APS_ON; - c = phy_write(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2, c); - if (c < 0) - return c; - - /* INTR pin used: speed/link/duplex will cause an interrupt */ - c = phy_write(phydev, MDIO_DEVAD_NONE, IP101A_G_IRQ_CONF_STATUS, - IP101A_G_IRQ_DEFAULT); - if (c < 0) - return c; - - if (phydev->interface == PHY_INTERFACE_MODE_RGMII) { - /* - * Additional delay (2ns) used to adjust RX clock phase - * at RGMII interface - */ - c = phy_read(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS); - if (c < 0) - return c; - - c |= IP1001_PHASE_SEL_MASK; - c = phy_write(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS, - c); - if (c < 0) - return c; - } - - return 0; -} - -static int ip1001_startup(struct phy_device *phydev) -{ - genphy_update_link(phydev); - genphy_parse_link(phydev); - - return 0; -} -static struct phy_driver IP1001_driver = { - .name = "ICPlus IP1001", - .uid = 0x02430d90, - .mask = 0x0ffffff0, - .features = PHY_GBIT_FEATURES, - .config = &ip1001_config, - .startup = &ip1001_startup, - .shutdown = &genphy_shutdown, -}; - -int phy_icplus_init(void) -{ - phy_register(&IP1001_driver); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/phy/lxt.c b/qemu/roms/u-boot/drivers/net/phy/lxt.c deleted file mode 100644 index 91838ce5e..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/lxt.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * LXT PHY drivers - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Copyright 2010-2011 Freescale Semiconductor, Inc. - * author Andy Fleming - */ -#include <phy.h> - -/* LXT971 Status 2 registers */ -#define MIIM_LXT971_SR2 0x11 /* Status Register 2 */ -#define MIIM_LXT971_SR2_SPEED_MASK 0x4200 -#define MIIM_LXT971_SR2_10HDX 0x0000 /* 10 Mbit half duplex selected */ -#define MIIM_LXT971_SR2_10FDX 0x0200 /* 10 Mbit full duplex selected */ -#define MIIM_LXT971_SR2_100HDX 0x4000 /* 100 Mbit half duplex selected */ -#define MIIM_LXT971_SR2_100FDX 0x4200 /* 100 Mbit full duplex selected */ - - -/* LXT971 */ -static int lxt971_parse_status(struct phy_device *phydev) -{ - int mii_reg; - int speed; - - mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_LXT971_SR2); - speed = mii_reg & MIIM_LXT971_SR2_SPEED_MASK; - - switch (speed) { - case MIIM_LXT971_SR2_10HDX: - phydev->speed = SPEED_10; - phydev->duplex = DUPLEX_HALF; - break; - case MIIM_LXT971_SR2_10FDX: - phydev->speed = SPEED_10; - phydev->duplex = DUPLEX_FULL; - break; - case MIIM_LXT971_SR2_100HDX: - phydev->speed = SPEED_100; - phydev->duplex = DUPLEX_HALF; - break; - default: - phydev->speed = SPEED_100; - phydev->duplex = DUPLEX_FULL; - } - - return 0; -} - -static int lxt971_startup(struct phy_device *phydev) -{ - genphy_update_link(phydev); - lxt971_parse_status(phydev); - - return 0; -} - -static struct phy_driver LXT971_driver = { - .name = "LXT971", - .uid = 0x1378e0, - .mask = 0xfffff0, - .features = PHY_BASIC_FEATURES, - .config = &genphy_config_aneg, - .startup = &lxt971_startup, - .shutdown = &genphy_shutdown, -}; - -int phy_lxt_init(void) -{ - phy_register(&LXT971_driver); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/phy/marvell.c b/qemu/roms/u-boot/drivers/net/phy/marvell.c deleted file mode 100644 index d2ecadc89..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/marvell.c +++ /dev/null @@ -1,524 +0,0 @@ -/* - * Marvell PHY drivers - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Copyright 2010-2011 Freescale Semiconductor, Inc. - * author Andy Fleming - */ -#include <config.h> -#include <common.h> -#include <phy.h> - -#define PHY_AUTONEGOTIATE_TIMEOUT 5000 - -/* 88E1011 PHY Status Register */ -#define MIIM_88E1xxx_PHY_STATUS 0x11 -#define MIIM_88E1xxx_PHYSTAT_SPEED 0xc000 -#define MIIM_88E1xxx_PHYSTAT_GBIT 0x8000 -#define MIIM_88E1xxx_PHYSTAT_100 0x4000 -#define MIIM_88E1xxx_PHYSTAT_DUPLEX 0x2000 -#define MIIM_88E1xxx_PHYSTAT_SPDDONE 0x0800 -#define MIIM_88E1xxx_PHYSTAT_LINK 0x0400 - -#define MIIM_88E1xxx_PHY_SCR 0x10 -#define MIIM_88E1xxx_PHY_MDI_X_AUTO 0x0060 - -/* 88E1111 PHY LED Control Register */ -#define MIIM_88E1111_PHY_LED_CONTROL 24 -#define MIIM_88E1111_PHY_LED_DIRECT 0x4100 -#define MIIM_88E1111_PHY_LED_COMBINE 0x411C - -/* 88E1111 Extended PHY Specific Control Register */ -#define MIIM_88E1111_PHY_EXT_CR 0x14 -#define MIIM_88E1111_RX_DELAY 0x80 -#define MIIM_88E1111_TX_DELAY 0x2 - -/* 88E1111 Extended PHY Specific Status Register */ -#define MIIM_88E1111_PHY_EXT_SR 0x1b -#define MIIM_88E1111_HWCFG_MODE_MASK 0xf -#define MIIM_88E1111_HWCFG_MODE_COPPER_RGMII 0xb -#define MIIM_88E1111_HWCFG_MODE_FIBER_RGMII 0x3 -#define MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK 0x4 -#define MIIM_88E1111_HWCFG_MODE_COPPER_RTBI 0x9 -#define MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO 0x8000 -#define MIIM_88E1111_HWCFG_FIBER_COPPER_RES 0x2000 - -#define MIIM_88E1111_COPPER 0 -#define MIIM_88E1111_FIBER 1 - -/* 88E1118 PHY defines */ -#define MIIM_88E1118_PHY_PAGE 22 -#define MIIM_88E1118_PHY_LED_PAGE 3 - -/* 88E1121 PHY LED Control Register */ -#define MIIM_88E1121_PHY_LED_CTRL 16 -#define MIIM_88E1121_PHY_LED_PAGE 3 -#define MIIM_88E1121_PHY_LED_DEF 0x0030 - -/* 88E1121 PHY IRQ Enable/Status Register */ -#define MIIM_88E1121_PHY_IRQ_EN 18 -#define MIIM_88E1121_PHY_IRQ_STATUS 19 - -#define MIIM_88E1121_PHY_PAGE 22 - -/* 88E1145 Extended PHY Specific Control Register */ -#define MIIM_88E1145_PHY_EXT_CR 20 -#define MIIM_M88E1145_RGMII_RX_DELAY 0x0080 -#define MIIM_M88E1145_RGMII_TX_DELAY 0x0002 - -#define MIIM_88E1145_PHY_LED_CONTROL 24 -#define MIIM_88E1145_PHY_LED_DIRECT 0x4100 - -#define MIIM_88E1145_PHY_PAGE 29 -#define MIIM_88E1145_PHY_CAL_OV 30 - -#define MIIM_88E1149_PHY_PAGE 29 - -/* 88E1310 PHY defines */ -#define MIIM_88E1310_PHY_LED_CTRL 16 -#define MIIM_88E1310_PHY_IRQ_EN 18 -#define MIIM_88E1310_PHY_RGMII_CTRL 21 -#define MIIM_88E1310_PHY_PAGE 22 - -/* Marvell 88E1011S */ -static int m88e1011s_config(struct phy_device *phydev) -{ - /* Reset and configure the PHY */ - phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); - - phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); - phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x200c); - phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5); - phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0); - phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); - - phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); - - genphy_config_aneg(phydev); - - return 0; -} - -/* Parse the 88E1011's status register for speed and duplex - * information - */ -static uint m88e1xxx_parse_status(struct phy_device *phydev) -{ - unsigned int speed; - unsigned int mii_reg; - - mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1xxx_PHY_STATUS); - - if ((mii_reg & MIIM_88E1xxx_PHYSTAT_LINK) && - !(mii_reg & MIIM_88E1xxx_PHYSTAT_SPDDONE)) { - int i = 0; - - puts("Waiting for PHY realtime link"); - while (!(mii_reg & MIIM_88E1xxx_PHYSTAT_SPDDONE)) { - /* Timeout reached ? */ - if (i > PHY_AUTONEGOTIATE_TIMEOUT) { - puts(" TIMEOUT !\n"); - phydev->link = 0; - break; - } - - if ((i++ % 1000) == 0) - putc('.'); - udelay(1000); - mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, - MIIM_88E1xxx_PHY_STATUS); - } - puts(" done\n"); - udelay(500000); /* another 500 ms (results in faster booting) */ - } else { - if (mii_reg & MIIM_88E1xxx_PHYSTAT_LINK) - phydev->link = 1; - else - phydev->link = 0; - } - - if (mii_reg & MIIM_88E1xxx_PHYSTAT_DUPLEX) - phydev->duplex = DUPLEX_FULL; - else - phydev->duplex = DUPLEX_HALF; - - speed = mii_reg & MIIM_88E1xxx_PHYSTAT_SPEED; - - switch (speed) { - case MIIM_88E1xxx_PHYSTAT_GBIT: - phydev->speed = SPEED_1000; - break; - case MIIM_88E1xxx_PHYSTAT_100: - phydev->speed = SPEED_100; - break; - default: - phydev->speed = SPEED_10; - break; - } - - return 0; -} - -static int m88e1011s_startup(struct phy_device *phydev) -{ - genphy_update_link(phydev); - m88e1xxx_parse_status(phydev); - - return 0; -} - -/* Marvell 88E1111S */ -static int m88e1111s_config(struct phy_device *phydev) -{ - int reg; - int timeout; - - if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) { - reg = phy_read(phydev, - MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR); - if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)) { - reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY); - } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { - reg &= ~MIIM_88E1111_TX_DELAY; - reg |= MIIM_88E1111_RX_DELAY; - } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { - reg &= ~MIIM_88E1111_RX_DELAY; - reg |= MIIM_88E1111_TX_DELAY; - } - - phy_write(phydev, - MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg); - - reg = phy_read(phydev, - MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR); - - reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK); - - if (reg & MIIM_88E1111_HWCFG_FIBER_COPPER_RES) - reg |= MIIM_88E1111_HWCFG_MODE_FIBER_RGMII; - else - reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RGMII; - - phy_write(phydev, - MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR, reg); - } - - if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { - reg = phy_read(phydev, - MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR); - - reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK); - reg |= MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK; - reg |= MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO; - - phy_write(phydev, MDIO_DEVAD_NONE, - MIIM_88E1111_PHY_EXT_SR, reg); - } - - if (phydev->interface == PHY_INTERFACE_MODE_RTBI) { - reg = phy_read(phydev, - MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR); - reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY); - phy_write(phydev, - MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg); - - reg = phy_read(phydev, MDIO_DEVAD_NONE, - MIIM_88E1111_PHY_EXT_SR); - reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK | - MIIM_88E1111_HWCFG_FIBER_COPPER_RES); - reg |= 0x7 | MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO; - phy_write(phydev, MDIO_DEVAD_NONE, - MIIM_88E1111_PHY_EXT_SR, reg); - - /* soft reset */ - timeout = 1000; - phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); - udelay(1000); - reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); - while ((reg & BMCR_RESET) && --timeout) { - udelay(1000); - reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); - } - if (!timeout) - printf("%s: phy soft reset timeout\n", __func__); - - reg = phy_read(phydev, MDIO_DEVAD_NONE, - MIIM_88E1111_PHY_EXT_SR); - reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK | - MIIM_88E1111_HWCFG_FIBER_COPPER_RES); - reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RTBI | - MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO; - phy_write(phydev, MDIO_DEVAD_NONE, - MIIM_88E1111_PHY_EXT_SR, reg); - } - - /* soft reset */ - timeout = 1000; - phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); - udelay(1000); - reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); - while ((reg & BMCR_RESET) && --timeout) { - udelay(1000); - reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); - } - if (!timeout) - printf("%s: phy soft reset timeout\n", __func__); - - genphy_config_aneg(phydev); - - phy_reset(phydev); - - return 0; -} - -/* Marvell 88E1118 */ -static int m88e1118_config(struct phy_device *phydev) -{ - /* Change Page Number */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0002); - /* Delay RGMII TX and RX */ - phy_write(phydev, MDIO_DEVAD_NONE, 0x15, 0x1070); - /* Change Page Number */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0003); - /* Adjust LED control */ - phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x021e); - /* Change Page Number */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000); - - genphy_config_aneg(phydev); - - phy_reset(phydev); - - return 0; -} - -static int m88e1118_startup(struct phy_device *phydev) -{ - /* Change Page Number */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000); - - genphy_update_link(phydev); - m88e1xxx_parse_status(phydev); - - return 0; -} - -/* Marvell 88E1121R */ -static int m88e1121_config(struct phy_device *phydev) -{ - int pg; - - /* Configure the PHY */ - genphy_config_aneg(phydev); - - /* Switch the page to access the led register */ - pg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE); - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE, - MIIM_88E1121_PHY_LED_PAGE); - /* Configure leds */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_LED_CTRL, - MIIM_88E1121_PHY_LED_DEF); - /* Restore the page pointer */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE, pg); - - /* Disable IRQs and de-assert interrupt */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_IRQ_EN, 0); - phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_IRQ_STATUS); - - return 0; -} - -/* Marvell 88E1145 */ -static int m88e1145_config(struct phy_device *phydev) -{ - int reg; - - /* Errata E0, E1 */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_PAGE, 0x001b); - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_CAL_OV, 0x418f); - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_PAGE, 0x0016); - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_CAL_OV, 0xa2da); - - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1xxx_PHY_SCR, - MIIM_88E1xxx_PHY_MDI_X_AUTO); - - reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_EXT_CR); - if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) - reg |= MIIM_M88E1145_RGMII_RX_DELAY | - MIIM_M88E1145_RGMII_TX_DELAY; - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_EXT_CR, reg); - - genphy_config_aneg(phydev); - - phy_reset(phydev); - - return 0; -} - -static int m88e1145_startup(struct phy_device *phydev) -{ - genphy_update_link(phydev); - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_LED_CONTROL, - MIIM_88E1145_PHY_LED_DIRECT); - m88e1xxx_parse_status(phydev); - - return 0; -} - -/* Marvell 88E1149S */ -static int m88e1149_config(struct phy_device *phydev) -{ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1149_PHY_PAGE, 0x1f); - phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x200c); - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1149_PHY_PAGE, 0x5); - phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x0); - phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); - - genphy_config_aneg(phydev); - - phy_reset(phydev); - - return 0; -} - -/* Marvell 88E1310 */ -static int m88e1310_config(struct phy_device *phydev) -{ - u16 reg; - - /* LED link and activity */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0003); - reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_LED_CTRL); - reg = (reg & ~0xf) | 0x1; - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_LED_CTRL, reg); - - /* Set LED2/INT to INT mode, low active */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0003); - reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_IRQ_EN); - reg = (reg & 0x77ff) | 0x0880; - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_IRQ_EN, reg); - - /* Set RGMII delay */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0002); - reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_RGMII_CTRL); - reg |= 0x0030; - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_RGMII_CTRL, reg); - - /* Ensure to return to page 0 */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0000); - - genphy_config_aneg(phydev); - phy_reset(phydev); - - return 0; -} - -static struct phy_driver M88E1011S_driver = { - .name = "Marvell 88E1011S", - .uid = 0x1410c60, - .mask = 0xffffff0, - .features = PHY_GBIT_FEATURES, - .config = &m88e1011s_config, - .startup = &m88e1011s_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver M88E1111S_driver = { - .name = "Marvell 88E1111S", - .uid = 0x1410cc0, - .mask = 0xffffff0, - .features = PHY_GBIT_FEATURES, - .config = &m88e1111s_config, - .startup = &m88e1011s_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver M88E1118_driver = { - .name = "Marvell 88E1118", - .uid = 0x1410e10, - .mask = 0xffffff0, - .features = PHY_GBIT_FEATURES, - .config = &m88e1118_config, - .startup = &m88e1118_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver M88E1118R_driver = { - .name = "Marvell 88E1118R", - .uid = 0x1410e40, - .mask = 0xffffff0, - .features = PHY_GBIT_FEATURES, - .config = &m88e1118_config, - .startup = &m88e1118_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver M88E1121R_driver = { - .name = "Marvell 88E1121R", - .uid = 0x1410cb0, - .mask = 0xffffff0, - .features = PHY_GBIT_FEATURES, - .config = &m88e1121_config, - .startup = &genphy_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver M88E1145_driver = { - .name = "Marvell 88E1145", - .uid = 0x1410cd0, - .mask = 0xffffff0, - .features = PHY_GBIT_FEATURES, - .config = &m88e1145_config, - .startup = &m88e1145_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver M88E1149S_driver = { - .name = "Marvell 88E1149S", - .uid = 0x1410ca0, - .mask = 0xffffff0, - .features = PHY_GBIT_FEATURES, - .config = &m88e1149_config, - .startup = &m88e1011s_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver M88E1518_driver = { - .name = "Marvell 88E1518", - .uid = 0x1410dd1, - .mask = 0xffffff0, - .features = PHY_GBIT_FEATURES, - .config = &m88e1111s_config, - .startup = &m88e1011s_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver M88E1310_driver = { - .name = "Marvell 88E1310", - .uid = 0x01410e90, - .mask = 0xffffff0, - .features = PHY_GBIT_FEATURES, - .config = &m88e1310_config, - .startup = &m88e1011s_startup, - .shutdown = &genphy_shutdown, -}; - -int phy_marvell_init(void) -{ - phy_register(&M88E1310_driver); - phy_register(&M88E1149S_driver); - phy_register(&M88E1145_driver); - phy_register(&M88E1121R_driver); - phy_register(&M88E1118_driver); - phy_register(&M88E1118R_driver); - phy_register(&M88E1111S_driver); - phy_register(&M88E1011S_driver); - phy_register(&M88E1518_driver); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/phy/micrel.c b/qemu/roms/u-boot/drivers/net/phy/micrel.c deleted file mode 100644 index 5d7e3be52..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/micrel.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Micrel PHY drivers - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Copyright 2010-2011 Freescale Semiconductor, Inc. - * author Andy Fleming - * (C) 2012 NetModule AG, David Andrey, added KSZ9031 - */ -#include <config.h> -#include <common.h> -#include <micrel.h> -#include <phy.h> - -static struct phy_driver KSZ804_driver = { - .name = "Micrel KSZ804", - .uid = 0x221510, - .mask = 0xfffff0, - .features = PHY_BASIC_FEATURES, - .config = &genphy_config, - .startup = &genphy_startup, - .shutdown = &genphy_shutdown, -}; - -#ifndef CONFIG_PHY_MICREL_KSZ9021 -/* - * I can't believe Micrel used the exact same part number - * for the KSZ9021 - * Shame Micrel, Shame!!!!! - */ -static struct phy_driver KS8721_driver = { - .name = "Micrel KS8721BL", - .uid = 0x221610, - .mask = 0xfffff0, - .features = PHY_BASIC_FEATURES, - .config = &genphy_config, - .startup = &genphy_startup, - .shutdown = &genphy_shutdown, -}; -#endif - - -/** - * KSZ9021 - KSZ9031 common - */ - -#define MII_KSZ90xx_PHY_CTL 0x1f -#define MIIM_KSZ90xx_PHYCTL_1000 (1 << 6) -#define MIIM_KSZ90xx_PHYCTL_100 (1 << 5) -#define MIIM_KSZ90xx_PHYCTL_10 (1 << 4) -#define MIIM_KSZ90xx_PHYCTL_DUPLEX (1 << 3) - -static int ksz90xx_startup(struct phy_device *phydev) -{ - unsigned phy_ctl; - genphy_update_link(phydev); - phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ90xx_PHY_CTL); - - if (phy_ctl & MIIM_KSZ90xx_PHYCTL_DUPLEX) - phydev->duplex = DUPLEX_FULL; - else - phydev->duplex = DUPLEX_HALF; - - if (phy_ctl & MIIM_KSZ90xx_PHYCTL_1000) - phydev->speed = SPEED_1000; - else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_100) - phydev->speed = SPEED_100; - else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_10) - phydev->speed = SPEED_10; - return 0; -} -#ifdef CONFIG_PHY_MICREL_KSZ9021 - -/* - * KSZ9021 - */ - -/* PHY Registers */ -#define MII_KSZ9021_EXTENDED_CTRL 0x0b -#define MII_KSZ9021_EXTENDED_DATAW 0x0c -#define MII_KSZ9021_EXTENDED_DATAR 0x0d - -#define CTRL1000_PREFER_MASTER (1 << 10) -#define CTRL1000_CONFIG_MASTER (1 << 11) -#define CTRL1000_MANUAL_CONFIG (1 << 12) - -int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val) -{ - /* extended registers */ - phy_write(phydev, MDIO_DEVAD_NONE, - MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000); - return phy_write(phydev, MDIO_DEVAD_NONE, - MII_KSZ9021_EXTENDED_DATAW, val); -} - -int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum) -{ - /* extended registers */ - phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum); - return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR); -} - - -static int ksz9021_phy_extread(struct phy_device *phydev, int addr, int devaddr, - int regnum) -{ - return ksz9021_phy_extended_read(phydev, regnum); -} - -static int ksz9021_phy_extwrite(struct phy_device *phydev, int addr, - int devaddr, int regnum, u16 val) -{ - return ksz9021_phy_extended_write(phydev, regnum, val); -} - -/* Micrel ksz9021 */ -static int ksz9021_config(struct phy_device *phydev) -{ - unsigned ctrl1000 = 0; - const unsigned master = CTRL1000_PREFER_MASTER | - CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG; - unsigned features = phydev->drv->features; - - if (getenv("disable_giga")) - features &= ~(SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full); - /* force master mode for 1000BaseT due to chip errata */ - if (features & SUPPORTED_1000baseT_Half) - ctrl1000 |= ADVERTISE_1000HALF | master; - if (features & SUPPORTED_1000baseT_Full) - ctrl1000 |= ADVERTISE_1000FULL | master; - phydev->advertising = phydev->supported = features; - phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000); - genphy_config_aneg(phydev); - genphy_restart_aneg(phydev); - return 0; -} - -static struct phy_driver ksz9021_driver = { - .name = "Micrel ksz9021", - .uid = 0x221610, - .mask = 0xfffff0, - .features = PHY_GBIT_FEATURES, - .config = &ksz9021_config, - .startup = &ksz90xx_startup, - .shutdown = &genphy_shutdown, - .writeext = &ksz9021_phy_extwrite, - .readext = &ksz9021_phy_extread, -}; -#endif - -/** - * KSZ9031 - */ -/* PHY Registers */ -#define MII_KSZ9031_MMD_ACCES_CTRL 0x0d -#define MII_KSZ9031_MMD_REG_DATA 0x0e - -/* Accessors to extended registers*/ -int ksz9031_phy_extended_write(struct phy_device *phydev, - int devaddr, int regnum, u16 mode, u16 val) -{ - /*select register addr for mmd*/ - phy_write(phydev, MDIO_DEVAD_NONE, - MII_KSZ9031_MMD_ACCES_CTRL, devaddr); - /*select register for mmd*/ - phy_write(phydev, MDIO_DEVAD_NONE, - MII_KSZ9031_MMD_REG_DATA, regnum); - /*setup mode*/ - phy_write(phydev, MDIO_DEVAD_NONE, - MII_KSZ9031_MMD_ACCES_CTRL, (mode | devaddr)); - /*write the value*/ - return phy_write(phydev, MDIO_DEVAD_NONE, - MII_KSZ9031_MMD_REG_DATA, val); -} - -int ksz9031_phy_extended_read(struct phy_device *phydev, int devaddr, - int regnum, u16 mode) -{ - phy_write(phydev, MDIO_DEVAD_NONE, - MII_KSZ9031_MMD_ACCES_CTRL, devaddr); - phy_write(phydev, MDIO_DEVAD_NONE, - MII_KSZ9031_MMD_REG_DATA, regnum); - phy_write(phydev, MDIO_DEVAD_NONE, - MII_KSZ9031_MMD_ACCES_CTRL, (devaddr | mode)); - return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9031_MMD_REG_DATA); -} - -static int ksz9031_phy_extread(struct phy_device *phydev, int addr, int devaddr, - int regnum) -{ - return ksz9031_phy_extended_read(phydev, devaddr, regnum, - MII_KSZ9031_MOD_DATA_NO_POST_INC); -}; - -static int ksz9031_phy_extwrite(struct phy_device *phydev, int addr, - int devaddr, int regnum, u16 val) -{ - return ksz9031_phy_extended_write(phydev, devaddr, regnum, - MII_KSZ9031_MOD_DATA_POST_INC_RW, val); -}; - - -static struct phy_driver ksz9031_driver = { - .name = "Micrel ksz9031", - .uid = 0x221620, - .mask = 0xfffff0, - .features = PHY_GBIT_FEATURES, - .config = &genphy_config, - .startup = &ksz90xx_startup, - .shutdown = &genphy_shutdown, - .writeext = &ksz9031_phy_extwrite, - .readext = &ksz9031_phy_extread, -}; - -int phy_micrel_init(void) -{ - phy_register(&KSZ804_driver); -#ifdef CONFIG_PHY_MICREL_KSZ9021 - phy_register(&ksz9021_driver); -#else - phy_register(&KS8721_driver); -#endif - phy_register(&ksz9031_driver); - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/phy/miiphybb.c b/qemu/roms/u-boot/drivers/net/phy/miiphybb.c deleted file mode 100644 index 5cda0b846..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/miiphybb.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * (C) Copyright 2009 Industrie Dial Face S.p.A. - * Luigi 'Comio' Mantellini <luigi.mantellini@idf-hit.com> - * - * (C) Copyright 2001 - * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * This provides a bit-banged interface to the ethernet MII management - * channel. - */ - -#include <common.h> -#include <ioports.h> -#include <ppc_asm.tmpl> -#include <miiphy.h> - -#define BB_MII_RELOCATE(v,off) (v += (v?off:0)) - -DECLARE_GLOBAL_DATA_PTR; - -#ifndef CONFIG_BITBANGMII_MULTI - -/* - * If CONFIG_BITBANGMII_MULTI is not defined we use a - * compatibility layer with the previous miiphybb implementation - * based on macros usage. - * - */ -static int bb_mii_init_wrap(struct bb_miiphy_bus *bus) -{ -#ifdef MII_INIT - MII_INIT; -#endif - return 0; -} - -static int bb_mdio_active_wrap(struct bb_miiphy_bus *bus) -{ -#ifdef MDIO_DECLARE - MDIO_DECLARE; -#endif - MDIO_ACTIVE; - return 0; -} - -static int bb_mdio_tristate_wrap(struct bb_miiphy_bus *bus) -{ -#ifdef MDIO_DECLARE - MDIO_DECLARE; -#endif - MDIO_TRISTATE; - return 0; -} - -static int bb_set_mdio_wrap(struct bb_miiphy_bus *bus, int v) -{ -#ifdef MDIO_DECLARE - MDIO_DECLARE; -#endif - MDIO(v); - return 0; -} - -static int bb_get_mdio_wrap(struct bb_miiphy_bus *bus, int *v) -{ -#ifdef MDIO_DECLARE - MDIO_DECLARE; -#endif - *v = MDIO_READ; - return 0; -} - -static int bb_set_mdc_wrap(struct bb_miiphy_bus *bus, int v) -{ -#ifdef MDC_DECLARE - MDC_DECLARE; -#endif - MDC(v); - return 0; -} - -static int bb_delay_wrap(struct bb_miiphy_bus *bus) -{ - MIIDELAY; - return 0; -} - -struct bb_miiphy_bus bb_miiphy_buses[] = { - { - .name = BB_MII_DEVNAME, - .init = bb_mii_init_wrap, - .mdio_active = bb_mdio_active_wrap, - .mdio_tristate = bb_mdio_tristate_wrap, - .set_mdio = bb_set_mdio_wrap, - .get_mdio = bb_get_mdio_wrap, - .set_mdc = bb_set_mdc_wrap, - .delay = bb_delay_wrap, - } -}; - -int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) / - sizeof(bb_miiphy_buses[0]); -#endif - -void bb_miiphy_init(void) -{ - int i; - - for (i = 0; i < bb_miiphy_buses_num; i++) { -#if defined(CONFIG_NEEDS_MANUAL_RELOC) - /* Relocate the hook pointers*/ - BB_MII_RELOCATE(bb_miiphy_buses[i].init, gd->reloc_off); - BB_MII_RELOCATE(bb_miiphy_buses[i].mdio_active, gd->reloc_off); - BB_MII_RELOCATE(bb_miiphy_buses[i].mdio_tristate, gd->reloc_off); - BB_MII_RELOCATE(bb_miiphy_buses[i].set_mdio, gd->reloc_off); - BB_MII_RELOCATE(bb_miiphy_buses[i].get_mdio, gd->reloc_off); - BB_MII_RELOCATE(bb_miiphy_buses[i].set_mdc, gd->reloc_off); - BB_MII_RELOCATE(bb_miiphy_buses[i].delay, gd->reloc_off); -#endif - if (bb_miiphy_buses[i].init != NULL) { - bb_miiphy_buses[i].init(&bb_miiphy_buses[i]); - } - } -} - -static inline struct bb_miiphy_bus *bb_miiphy_getbus(const char *devname) -{ -#ifdef CONFIG_BITBANGMII_MULTI - int i; - - /* Search the correct bus */ - for (i = 0; i < bb_miiphy_buses_num; i++) { - if (!strcmp(bb_miiphy_buses[i].name, devname)) { - return &bb_miiphy_buses[i]; - } - } - return NULL; -#else - /* We have just one bitbanging bus */ - return &bb_miiphy_buses[0]; -#endif -} - -/***************************************************************************** - * - * Utility to send the preamble, address, and register (common to read - * and write). - */ -static void miiphy_pre(struct bb_miiphy_bus *bus, char read, - unsigned char addr, unsigned char reg) -{ - int j; - - /* - * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure. - * The IEEE spec says this is a PHY optional requirement. The AMD - * 79C874 requires one after power up and one after a MII communications - * error. This means that we are doing more preambles than we need, - * but it is safer and will be much more robust. - */ - - bus->mdio_active(bus); - bus->set_mdio(bus, 1); - for (j = 0; j < 32; j++) { - bus->set_mdc(bus, 0); - bus->delay(bus); - bus->set_mdc(bus, 1); - bus->delay(bus); - } - - /* send the start bit (01) and the read opcode (10) or write (10) */ - bus->set_mdc(bus, 0); - bus->set_mdio(bus, 0); - bus->delay(bus); - bus->set_mdc(bus, 1); - bus->delay(bus); - bus->set_mdc(bus, 0); - bus->set_mdio(bus, 1); - bus->delay(bus); - bus->set_mdc(bus, 1); - bus->delay(bus); - bus->set_mdc(bus, 0); - bus->set_mdio(bus, read); - bus->delay(bus); - bus->set_mdc(bus, 1); - bus->delay(bus); - bus->set_mdc(bus, 0); - bus->set_mdio(bus, !read); - bus->delay(bus); - bus->set_mdc(bus, 1); - bus->delay(bus); - - /* send the PHY address */ - for (j = 0; j < 5; j++) { - bus->set_mdc(bus, 0); - if ((addr & 0x10) == 0) { - bus->set_mdio(bus, 0); - } else { - bus->set_mdio(bus, 1); - } - bus->delay(bus); - bus->set_mdc(bus, 1); - bus->delay(bus); - addr <<= 1; - } - - /* send the register address */ - for (j = 0; j < 5; j++) { - bus->set_mdc(bus, 0); - if ((reg & 0x10) == 0) { - bus->set_mdio(bus, 0); - } else { - bus->set_mdio(bus, 1); - } - bus->delay(bus); - bus->set_mdc(bus, 1); - bus->delay(bus); - reg <<= 1; - } -} - -/***************************************************************************** - * - * Read a MII PHY register. - * - * Returns: - * 0 on success - */ -int bb_miiphy_read(const char *devname, unsigned char addr, - unsigned char reg, unsigned short *value) -{ - short rdreg; /* register working value */ - int v; - int j; /* counter */ - struct bb_miiphy_bus *bus; - - bus = bb_miiphy_getbus(devname); - if (bus == NULL) { - return -1; - } - - if (value == NULL) { - puts("NULL value pointer\n"); - return -1; - } - - miiphy_pre (bus, 1, addr, reg); - - /* tri-state our MDIO I/O pin so we can read */ - bus->set_mdc(bus, 0); - bus->mdio_tristate(bus); - bus->delay(bus); - bus->set_mdc(bus, 1); - bus->delay(bus); - - /* check the turnaround bit: the PHY should be driving it to zero */ - bus->get_mdio(bus, &v); - if (v != 0) { - /* puts ("PHY didn't drive TA low\n"); */ - for (j = 0; j < 32; j++) { - bus->set_mdc(bus, 0); - bus->delay(bus); - bus->set_mdc(bus, 1); - bus->delay(bus); - } - /* There is no PHY, set value to 0xFFFF and return */ - *value = 0xFFFF; - return -1; - } - - bus->set_mdc(bus, 0); - bus->delay(bus); - - /* read 16 bits of register data, MSB first */ - rdreg = 0; - for (j = 0; j < 16; j++) { - bus->set_mdc(bus, 1); - bus->delay(bus); - rdreg <<= 1; - bus->get_mdio(bus, &v); - rdreg |= (v & 0x1); - bus->set_mdc(bus, 0); - bus->delay(bus); - } - - bus->set_mdc(bus, 1); - bus->delay(bus); - bus->set_mdc(bus, 0); - bus->delay(bus); - bus->set_mdc(bus, 1); - bus->delay(bus); - - *value = rdreg; - -#ifdef DEBUG - printf ("miiphy_read(0x%x) @ 0x%x = 0x%04x\n", reg, addr, *value); -#endif - - return 0; -} - - -/***************************************************************************** - * - * Write a MII PHY register. - * - * Returns: - * 0 on success - */ -int bb_miiphy_write (const char *devname, unsigned char addr, - unsigned char reg, unsigned short value) -{ - struct bb_miiphy_bus *bus; - int j; /* counter */ - - bus = bb_miiphy_getbus(devname); - if (bus == NULL) { - /* Bus not found! */ - return -1; - } - - miiphy_pre (bus, 0, addr, reg); - - /* send the turnaround (10) */ - bus->set_mdc(bus, 0); - bus->set_mdio(bus, 1); - bus->delay(bus); - bus->set_mdc(bus, 1); - bus->delay(bus); - bus->set_mdc(bus, 0); - bus->set_mdio(bus, 0); - bus->delay(bus); - bus->set_mdc(bus, 1); - bus->delay(bus); - - /* write 16 bits of register data, MSB first */ - for (j = 0; j < 16; j++) { - bus->set_mdc(bus, 0); - if ((value & 0x00008000) == 0) { - bus->set_mdio(bus, 0); - } else { - bus->set_mdio(bus, 1); - } - bus->delay(bus); - bus->set_mdc(bus, 1); - bus->delay(bus); - value <<= 1; - } - - /* - * Tri-state the MDIO line. - */ - bus->mdio_tristate(bus); - bus->set_mdc(bus, 0); - bus->delay(bus); - bus->set_mdc(bus, 1); - bus->delay(bus); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/phy/mv88e61xx.c b/qemu/roms/u-boot/drivers/net/phy/mv88e61xx.c deleted file mode 100644 index 302abe86c..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/mv88e61xx.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * (C) Copyright 2009 - * Marvell Semiconductor <www.marvell.com> - * Prafulla Wadaskar <prafulla@marvell.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <netdev.h> -#include "mv88e61xx.h" - -/* - * Uncomment either of the following line for local debug control; - * otherwise global debug control will apply. - */ - -/* #undef DEBUG */ -/* #define DEBUG */ - -#ifdef CONFIG_MV88E61XX_MULTICHIP_ADRMODE -/* Chip Address mode - * The Switch support two modes of operation - * 1. single chip mode and - * 2. Multi-chip mode - * Refer section 9.2 &9.3 in chip datasheet-02 for more details - * - * By default single chip mode is configured - * multichip mode operation can be configured in board header - */ -static int mv88e61xx_busychk_multic(char *name, u32 devaddr) -{ - u16 reg = 0; - u32 timeout = MV88E61XX_PHY_TIMEOUT; - - /* Poll till SMIBusy bit is clear */ - do { - miiphy_read(name, devaddr, 0x0, ®); - if (timeout-- == 0) { - printf("SMI busy timeout\n"); - return -1; - } - } while (reg & (1 << 15)); - return 0; -} - -static void mv88e61xx_switch_write(char *name, u32 phy_adr, - u32 reg_ofs, u16 data) -{ - u16 mii_dev_addr; - - /* command to read PHY dev address */ - if (miiphy_read(name, 0xEE, 0xEE, &mii_dev_addr)) { - printf("Error..could not read PHY dev address\n"); - return; - } - mv88e61xx_busychk_multic(name, mii_dev_addr); - /* Write data to Switch indirect data register */ - miiphy_write(name, mii_dev_addr, 0x1, data); - /* Write command to Switch indirect command register (write) */ - miiphy_write(name, mii_dev_addr, 0x0, - reg_ofs | (phy_adr << 5) | (1 << 10) | (1 << 12) | (1 << - 15)); -} - -static void mv88e61xx_switch_read(char *name, u32 phy_adr, - u32 reg_ofs, u16 *data) -{ - u16 mii_dev_addr; - - /* command to read PHY dev address */ - if (miiphy_read(name, 0xEE, 0xEE, &mii_dev_addr)) { - printf("Error..could not read PHY dev address\n"); - return; - } - mv88e61xx_busychk_multic(name, mii_dev_addr); - /* Write command to Switch indirect command register (read) */ - miiphy_write(name, mii_dev_addr, 0x0, - reg_ofs | (phy_adr << 5) | (1 << 11) | (1 << 12) | (1 << - 15)); - mv88e61xx_busychk_multic(name, mii_dev_addr); - /* Read data from Switch indirect data register */ - miiphy_read(name, mii_dev_addr, 0x1, data); -} -#endif /* CONFIG_MV88E61XX_MULTICHIP_ADRMODE */ - -/* - * Convenience macros for switch device/port reads/writes - * These macros output valid 'mv88e61xx' U_BOOT_CMDs - */ - -#ifndef DEBUG -#define WR_SWITCH_REG wr_switch_reg -#define RD_SWITCH_REG rd_switch_reg -#define WR_SWITCH_PORT_REG(n, p, r, d) \ - WR_SWITCH_REG(n, (MV88E61XX_PRT_OFST+p), r, d) -#define RD_SWITCH_PORT_REG(n, p, r, d) \ - RD_SWITCH_REG(n, (MV88E61XX_PRT_OFST+p), r, d) -#else -static void WR_SWITCH_REG(char *name, u32 dev_adr, u32 reg_ofs, u16 data) -{ - printf("mv88e61xx %s dev %02x reg %02x write %04x\n", - name, dev_adr, reg_ofs, data); - wr_switch_reg(name, dev_adr, reg_ofs, data); -} -static void RD_SWITCH_REG(char *name, u32 dev_adr, u32 reg_ofs, u16 *data) -{ - rd_switch_reg(name, dev_adr, reg_ofs, data); - printf("mv88e61xx %s dev %02x reg %02x read %04x\n", - name, dev_adr, reg_ofs, *data); -} -static void WR_SWITCH_PORT_REG(char *name, u32 prt_adr, u32 reg_ofs, - u16 data) -{ - printf("mv88e61xx %s port %02x reg %02x write %04x\n", - name, prt_adr, reg_ofs, data); - wr_switch_reg(name, (MV88E61XX_PRT_OFST+prt_adr), reg_ofs, data); -} -static void RD_SWITCH_PORT_REG(char *name, u32 prt_adr, u32 reg_ofs, - u16 *data) -{ - rd_switch_reg(name, (MV88E61XX_PRT_OFST+prt_adr), reg_ofs, data); - printf("mv88e61xx %s port %02x reg %02x read %04x\n", - name, prt_adr, reg_ofs, *data); -} -#endif - -/* - * Local functions to read/write registers on the switch PHYs. - * NOTE! This goes through switch, not direct miiphy, writes and reads! - */ - -/* - * Make sure SMIBusy bit cleared before another - * SMI operation can take place - */ -static int mv88e61xx_busychk(char *name) -{ - u16 reg = 0; - u32 timeout = MV88E61XX_PHY_TIMEOUT; - do { - rd_switch_reg(name, MV88E61XX_GLB2REG_DEVADR, - MV88E61XX_PHY_CMD, ®); - if (timeout-- == 0) { - printf("SMI busy timeout\n"); - return -1; - } - } while (reg & 1 << 15); /* busy mask */ - return 0; -} - -static inline int mv88e61xx_switch_miiphy_write(char *name, u32 phy, - u32 reg, u16 data) -{ - /* write switch data reg then cmd reg then check completion */ - wr_switch_reg(name, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA, - data); - wr_switch_reg(name, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_CMD, - (MV88E61XX_PHY_WRITE_CMD | (phy << 5) | reg)); - return mv88e61xx_busychk(name); -} - -static inline int mv88e61xx_switch_miiphy_read(char *name, u32 phy, - u32 reg, u16 *data) -{ - /* write switch cmd reg, check for completion */ - wr_switch_reg(name, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_CMD, - (MV88E61XX_PHY_READ_CMD | (phy << 5) | reg)); - if (mv88e61xx_busychk(name)) - return -1; - /* read switch data reg and return success */ - rd_switch_reg(name, MV88E61XX_GLB2REG_DEVADR, MV88E61XX_PHY_DATA, data); - return 0; -} - -/* - * Convenience macros for switch PHY reads/writes - */ - -#ifndef DEBUG -#define WR_SWITCH_PHY_REG mv88e61xx_switch_miiphy_write -#define RD_SWITCH_PHY_REG mv88e61xx_switch_miiphy_read -#else -static inline int WR_SWITCH_PHY_REG(char *name, u32 phy_adr, - u32 reg_ofs, u16 data) -{ - int r = mv88e61xx_switch_miiphy_write(name, phy_adr, reg_ofs, data); - if (r) - printf("** ERROR writing mv88e61xx %s phy %02x reg %02x\n", - name, phy_adr, reg_ofs); - else - printf("mv88e61xx %s phy %02x reg %02x write %04x\n", - name, phy_adr, reg_ofs, data); - return r; -} -static inline int RD_SWITCH_PHY_REG(char *name, u32 phy_adr, - u32 reg_ofs, u16 *data) -{ - int r = mv88e61xx_switch_miiphy_read(name, phy_adr, reg_ofs, data); - if (r) - printf("** ERROR reading mv88e61xx %s phy %02x reg %02x\n", - name, phy_adr, reg_ofs); - else - printf("mv88e61xx %s phy %02x reg %02x read %04x\n", - name, phy_adr, reg_ofs, *data); - return r; -} -#endif - -static void mv88e61xx_port_vlan_config(struct mv88e61xx_config *swconfig) -{ - u32 prt; - u16 reg; - char *name = swconfig->name; - u32 port_mask = swconfig->ports_enabled; - - /* apply internal vlan config */ - for (prt = 0; prt < MV88E61XX_MAX_PORTS_NUM; prt++) { - /* only for enabled ports */ - if ((1 << prt) & port_mask) { - /* take vlan map from swconfig */ - u8 vlanmap = swconfig->vlancfg[prt]; - /* remove disabled ports from vlan map */ - vlanmap &= swconfig->ports_enabled; - /* apply vlan map to port */ - RD_SWITCH_PORT_REG(name, prt, - MV88E61XX_PRT_VMAP_REG, ®); - reg &= ~((1 << MV88E61XX_MAX_PORTS_NUM) - 1); - reg |= vlanmap; - WR_SWITCH_PORT_REG(name, prt, - MV88E61XX_PRT_VMAP_REG, reg); - } - } -} - -/* - * Power up the specified port and reset PHY - */ -static int mv88361xx_powerup(struct mv88e61xx_config *swconfig, u32 phy) -{ - char *name = swconfig->name; - - /* Write Copper Specific control reg1 (0x10) for- - * Enable Phy power up - * Energy Detect on (sense&Xmit NLP Periodically - * reset other settings default - */ - if (WR_SWITCH_PHY_REG(name, phy, 0x10, 0x3360)) - return -1; - - /* Write PHY ctrl reg (0x0) to apply - * Phy reset (set bit 15 low) - * reset other default values - */ - if (WR_SWITCH_PHY_REG(name, phy, 0x00, 0x9140)) - return -1; - - return 0; -} - -/* - * Default Setup for LED[0]_Control (ref: Table 46 Datasheet-3) - * is set to "On-1000Mb/s Link, Off Else" - * This function sets it to "On-Link, Blink-Activity, Off-NoLink" - * - * This is optional settings may be needed on some boards - * to setup PHY LEDs default configuration to detect 10/100/1000Mb/s - * Link status - */ -static int mv88361xx_led_init(struct mv88e61xx_config *swconfig, u32 phy) -{ - char *name = swconfig->name; - - if (swconfig->led_init != MV88E61XX_LED_INIT_EN) - return 0; - - /* set page address to 3 */ - if (WR_SWITCH_PHY_REG(name, phy, 0x16, 0x0003)) - return -1; - - /* - * set LED Func Ctrl reg - * value 0x0001 = LED[0] On-Link, Blink-Activity, Off-NoLink - */ - if (WR_SWITCH_PHY_REG(name, phy, 0x10, 0x0001)) - return -1; - - /* set page address to 0 */ - if (WR_SWITCH_PHY_REG(name, phy, 0x16, 0x0000)) - return -1; - - return 0; -} - -/* - * Reverse Transmit polarity for Media Dependent Interface - * Pins (MDIP) bits in Copper Specific Control Register 3 - * (Page 0, Reg 20 for each phy (except cpu port) - * Reference: Section 1.1 Switch datasheet-3 - * - * This is optional settings may be needed on some boards - * for PHY<->magnetics h/w tuning - */ -static int mv88361xx_reverse_mdipn(struct mv88e61xx_config *swconfig, u32 phy) -{ - char *name = swconfig->name; - - if (swconfig->mdip != MV88E61XX_MDIP_REVERSE) - return 0; - - /*Reverse MDIP/N[3:0] bits */ - if (WR_SWITCH_PHY_REG(name, phy, 0x14, 0x000f)) - return -1; - - return 0; -} - -/* - * Marvell 88E61XX Switch initialization - */ -int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig) -{ - u32 prt; - u16 reg; - char *idstr; - char *name = swconfig->name; - int time; - - if (miiphy_set_current_dev(name)) { - printf("%s failed\n", __FUNCTION__); - return -1; - } - - if (!(swconfig->cpuport & ((1 << 4) | (1 << 5)))) { - swconfig->cpuport = (1 << 5); - printf("Invalid cpu port config, using default port5\n"); - } - - RD_SWITCH_PORT_REG(name, 0, MII_PHYSID2, ®); - switch (reg &= 0xfff0) { - case 0x1610: - idstr = "88E6161"; - break; - case 0x1650: - idstr = "88E6165"; - break; - case 0x1210: - idstr = "88E6123"; - /* ports 2,3,4 not available */ - swconfig->ports_enabled &= 0x023; - break; - default: - /* Could not detect switch id */ - idstr = "88E61??"; - break; - } - - /* be sure all ports are disabled */ - for (prt = 0; prt < MV88E61XX_MAX_PORTS_NUM; prt++) { - RD_SWITCH_PORT_REG(name, prt, MV88E61XX_PRT_CTRL_REG, ®); - reg &= ~0x3; - WR_SWITCH_PORT_REG(name, prt, MV88E61XX_PRT_CTRL_REG, reg); - } - - /* wait 2 ms for queues to drain */ - udelay(2000); - - /* reset switch */ - RD_SWITCH_REG(name, MV88E61XX_GLBREG_DEVADR, MV88E61XX_SGCR, ®); - reg |= 0x8000; - WR_SWITCH_REG(name, MV88E61XX_GLBREG_DEVADR, MV88E61XX_SGCR, reg); - - /* wait up to 1 second for switch reset complete */ - for (time = 1000; time; time--) { - RD_SWITCH_REG(name, MV88E61XX_GLBREG_DEVADR, MV88E61XX_SGSR, - ®); - if ((reg & 0xc800) == 0xc800) - break; - udelay(1000); - } - if (!time) - return -1; - - /* Port based VLANs configuration */ - mv88e61xx_port_vlan_config(swconfig); - - if (swconfig->rgmii_delay == MV88E61XX_RGMII_DELAY_EN) { - /* - * Enable RGMII delay on Tx and Rx for CPU port - * Ref: sec 9.5 of chip datasheet-02 - */ - /*Force port link down */ - WR_SWITCH_PORT_REG(name, 5, MV88E61XX_PCS_CTRL_REG, 0x10); - /* configure port RGMII delay */ - WR_SWITCH_PORT_REG(name, 4, - MV88E61XX_RGMII_TIMECTRL_REG, 0x81e7); - RD_SWITCH_PORT_REG(name, 5, - MV88E61XX_RGMII_TIMECTRL_REG, ®); - WR_SWITCH_PORT_REG(name, 5, - MV88E61XX_RGMII_TIMECTRL_REG, reg | 0x18); - WR_SWITCH_PORT_REG(name, 4, - MV88E61XX_RGMII_TIMECTRL_REG, 0xc1e7); - /* Force port to RGMII FDX 1000Base then up */ - WR_SWITCH_PORT_REG(name, 5, MV88E61XX_PCS_CTRL_REG, 0x1e); - WR_SWITCH_PORT_REG(name, 5, MV88E61XX_PCS_CTRL_REG, 0x3e); - } - - for (prt = 0; prt < MV88E61XX_MAX_PORTS_NUM; prt++) { - - /* configure port's PHY */ - if (!((1 << prt) & swconfig->cpuport)) { - /* port 4 has phy 6, not 4 */ - int phy = (prt == 4) ? 6 : prt; - if (mv88361xx_powerup(swconfig, phy)) - return -1; - if (mv88361xx_reverse_mdipn(swconfig, phy)) - return -1; - if (mv88361xx_led_init(swconfig, phy)) - return -1; - } - - /* set port VID to port+1 except for cpu port */ - if (!((1 << prt) & swconfig->cpuport)) { - RD_SWITCH_PORT_REG(name, prt, - MV88E61XX_PRT_VID_REG, ®); - WR_SWITCH_PORT_REG(name, prt, - MV88E61XX_PRT_VID_REG, - (reg & ~1023) | (prt+1)); - } - - /*Program port state */ - RD_SWITCH_PORT_REG(name, prt, - MV88E61XX_PRT_CTRL_REG, ®); - WR_SWITCH_PORT_REG(name, prt, - MV88E61XX_PRT_CTRL_REG, - reg | (swconfig->portstate & 0x03)); - - } - - printf("%s Initialized on %s\n", idstr, name); - return 0; -} - -#ifdef CONFIG_MV88E61XX_CMD -static int -do_switch(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - char *name, *endp; - int write = 0; - enum { dev, prt, phy } target = dev; - u32 addrlo, addrhi, addr; - u32 reglo, reghi, reg; - u16 data, rdata; - - if (argc < 7) - return -1; - - name = argv[1]; - - if (strcmp(argv[2], "phy") == 0) - target = phy; - else if (strcmp(argv[2], "port") == 0) - target = prt; - else if (strcmp(argv[2], "dev") != 0) - return 1; - - addrlo = simple_strtoul(argv[3], &endp, 16); - - if (!*endp) { - addrhi = addrlo; - } else { - while (*endp < '0' || *endp > '9') - endp++; - addrhi = simple_strtoul(endp, NULL, 16); - } - - reglo = simple_strtoul(argv[5], &endp, 16); - if (!*endp) { - reghi = reglo; - } else { - while (*endp < '0' || *endp > '9') - endp++; - reghi = simple_strtoul(endp, NULL, 16); - } - - if (strcmp(argv[6], "write") == 0) - write = 1; - else if (strcmp(argv[6], "read") != 0) - return 1; - - data = simple_strtoul(argv[7], NULL, 16); - - for (addr = addrlo; addr <= addrhi; addr++) { - for (reg = reglo; reg <= reghi; reg++) { - if (write) { - if (target == phy) - mv88e61xx_switch_miiphy_write( - name, addr, reg, data); - else if (target == prt) - wr_switch_reg(name, - addr+MV88E61XX_PRT_OFST, - reg, data); - else - wr_switch_reg(name, addr, reg, data); - } else { - if (target == phy) - mv88e61xx_switch_miiphy_read( - name, addr, reg, &rdata); - else if (target == prt) - rd_switch_reg(name, - addr+MV88E61XX_PRT_OFST, - reg, &rdata); - else - rd_switch_reg(name, addr, reg, &rdata); - printf("%s %s %s %02x %s %02x %s %04x\n", - argv[0], argv[1], argv[2], addr, - argv[4], reg, argv[6], rdata); - if (write && argc == 7 && rdata != data) - return 1; - } - } - } - return 0; -} - -U_BOOT_CMD(mv88e61xx, 8, 0, do_switch, - "Read or write mv88e61xx switch registers", - "<ethdevice> dev|port|phy <addr> reg <reg> write <data>\n" - "<ethdevice> dev|port|phy <addr> reg <reg> read [<data>]\n" - " - read/write switch device, port or phy at (addr,reg)\n" - " addr=0..0x1C for dev, 0..5 for port or phy.\n" - " reg=0..0x1F.\n" - " data=0..0xFFFF (tested if present against actual read).\n" - " All numeric parameters are assumed to be hex.\n" - " <addr> and <<reg> arguments can be ranges (x..y)" -); -#endif /* CONFIG_MV88E61XX_CMD */ diff --git a/qemu/roms/u-boot/drivers/net/phy/mv88e61xx.h b/qemu/roms/u-boot/drivers/net/phy/mv88e61xx.h deleted file mode 100644 index 9c62e4a77..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/mv88e61xx.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * (C) Copyright 2009 - * Marvell Semiconductor <www.marvell.com> - * Prafulla Wadaskar <prafulla@marvell.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _MV88E61XX_H -#define _MV88E61XX_H - -#include <miiphy.h> - -#define MV88E61XX_CPU_PORT 0x5 - -#define MV88E61XX_PHY_TIMEOUT 100000 - -/* port dev-addr (= port + 0x10) */ -#define MV88E61XX_PRT_OFST 0x10 -/* port registers */ -#define MV88E61XX_PCS_CTRL_REG 0x1 -#define MV88E61XX_PRT_CTRL_REG 0x4 -#define MV88E61XX_PRT_VMAP_REG 0x6 -#define MV88E61XX_PRT_VID_REG 0x7 -#define MV88E61XX_RGMII_TIMECTRL_REG 0x1A - -/* global registers dev-addr */ -#define MV88E61XX_GLBREG_DEVADR 0x1B -/* global registers */ -#define MV88E61XX_SGSR 0x00 -#define MV88E61XX_SGCR 0x04 - -/* global 2 registers dev-addr */ -#define MV88E61XX_GLB2REG_DEVADR 0x1C -/* global 2 registers */ -#define MV88E61XX_PHY_CMD 0x18 -#define MV88E61XX_PHY_DATA 0x19 -/* global 2 phy commands */ -#define MV88E61XX_PHY_WRITE_CMD 0x9400 -#define MV88E61XX_PHY_READ_CMD 0x9800 - -#define MV88E61XX_BUSY_OFST 15 -#define MV88E61XX_MODE_OFST 12 -#define MV88E61XX_OP_OFST 10 -#define MV88E61XX_ADDR_OFST 5 - -#ifdef CONFIG_MV88E61XX_MULTICHIP_ADRMODE -static int mv88e61xx_busychk_multic(char *name, u32 devaddr); -static void mv88e61xx_switch_write(char *name, u32 phy_adr, - u32 reg_ofs, u16 data); -static void mv88e61xx_switch_read(char *name, u32 phy_adr, - u32 reg_ofs, u16 *data); -#define wr_switch_reg mv88e61xx_switch_write -#define rd_switch_reg mv88e61xx_switch_read -#else -/* switch appears a s simple PHY and can thus use miiphy */ -#define wr_switch_reg miiphy_write -#define rd_switch_reg miiphy_read -#endif /* CONFIG_MV88E61XX_MULTICHIP_ADRMODE */ - -#endif /* _MV88E61XX_H */ diff --git a/qemu/roms/u-boot/drivers/net/phy/mv88e6352.c b/qemu/roms/u-boot/drivers/net/phy/mv88e6352.c deleted file mode 100644 index f639a42fa..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/mv88e6352.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * (C) Copyright 2012 - * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <miiphy.h> -#include <asm/errno.h> -#include <mv88e6352.h> - -#define SMI_HDR ((0x8 | 0x1) << 12) -#define SMI_BUSY_MASK (0x8000) -#define SMIRD_OP (0x2 << 10) -#define SMIWR_OP (0x1 << 10) -#define SMI_MASK 0x1f -#define PORT_SHIFT 5 - -#define COMMAND_REG 0 -#define DATA_REG 1 - -/* global registers */ -#define GLOBAL 0x1b - -#define GLOBAL_STATUS 0x00 -#define PPU_STATE 0x8000 - -#define GLOBAL_CTRL 0x04 -#define SW_RESET 0x8000 -#define PPU_ENABLE 0x4000 - -static int sw_wait_rdy(const char *devname, u8 phy_addr) -{ - u16 command; - u32 timeout = 100; - int ret; - - /* wait till the SMI is not busy */ - do { - /* read command register */ - ret = miiphy_read(devname, phy_addr, COMMAND_REG, &command); - if (ret < 0) { - printf("%s: Error reading command register\n", - __func__); - return ret; - } - if (timeout-- == 0) { - printf("Err..(%s) SMI busy timeout\n", __func__); - return -EFAULT; - } - } while (command & SMI_BUSY_MASK); - - return 0; -} - -static int sw_reg_read(const char *devname, u8 phy_addr, u8 port, - u8 reg, u16 *data) -{ - int ret; - u16 command; - - ret = sw_wait_rdy(devname, phy_addr); - if (ret) - return ret; - - command = SMI_HDR | SMIRD_OP | ((port&SMI_MASK) << PORT_SHIFT) | - (reg & SMI_MASK); - debug("%s: write to command: %#x\n", __func__, command); - ret = miiphy_write(devname, phy_addr, COMMAND_REG, command); - if (ret) - return ret; - - ret = sw_wait_rdy(devname, phy_addr); - if (ret) - return ret; - - ret = miiphy_read(devname, phy_addr, DATA_REG, data); - - return ret; -} - -static int sw_reg_write(const char *devname, u8 phy_addr, u8 port, - u8 reg, u16 data) -{ - int ret; - u16 value; - - ret = sw_wait_rdy(devname, phy_addr); - if (ret) - return ret; - - debug("%s: write to data: %#x\n", __func__, data); - ret = miiphy_write(devname, phy_addr, DATA_REG, data); - if (ret) - return ret; - - value = SMI_HDR | SMIWR_OP | ((port & SMI_MASK) << PORT_SHIFT) | - (reg & SMI_MASK); - debug("%s: write to command: %#x\n", __func__, value); - ret = miiphy_write(devname, phy_addr, COMMAND_REG, value); - if (ret) - return ret; - - ret = sw_wait_rdy(devname, phy_addr); - if (ret) - return ret; - - return 0; -} - -static int ppu_enable(const char *devname, u8 phy_addr) -{ - int i, ret = 0; - u16 reg; - - ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, ®); - if (ret) { - printf("%s: Error reading global ctrl reg\n", __func__); - return ret; - } - - reg |= PPU_ENABLE; - - ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg); - if (ret) { - printf("%s: Error writing global ctrl reg\n", __func__); - return ret; - } - - for (i = 0; i < 1000; i++) { - sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS, - ®); - if ((reg & 0xc000) == 0xc000) - return 0; - udelay(1000); - } - - return -ETIMEDOUT; -} - -static int ppu_disable(const char *devname, u8 phy_addr) -{ - int i, ret = 0; - u16 reg; - - ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, ®); - if (ret) { - printf("%s: Error reading global ctrl reg\n", __func__); - return ret; - } - - reg &= ~PPU_ENABLE; - - ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg); - if (ret) { - printf("%s: Error writing global ctrl reg\n", __func__); - return ret; - } - - for (i = 0; i < 1000; i++) { - sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS, - ®); - if ((reg & 0xc000) != 0xc000) - return 0; - udelay(1000); - } - - return -ETIMEDOUT; -} - -int mv88e_sw_program(const char *devname, u8 phy_addr, - struct mv88e_sw_reg *regs, int regs_nb) -{ - int i, ret = 0; - - /* first we need to disable the PPU */ - ret = ppu_disable(devname, phy_addr); - if (ret) { - printf("%s: Error disabling PPU\n", __func__); - return ret; - } - - for (i = 0; i < regs_nb; i++) { - ret = sw_reg_write(devname, phy_addr, regs[i].port, - regs[i].reg, regs[i].value); - if (ret) { - printf("%s: Error configuring switch\n", __func__); - ppu_enable(devname, phy_addr); - return ret; - } - } - - /* re-enable the PPU */ - ret = ppu_enable(devname, phy_addr); - if (ret) { - printf("%s: Error enabling PPU\n", __func__); - return ret; - } - - return 0; -} - -int mv88e_sw_reset(const char *devname, u8 phy_addr) -{ - int i, ret = 0; - u16 reg; - - ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, ®); - if (ret) { - printf("%s: Error reading global ctrl reg\n", __func__); - return ret; - } - - reg = SW_RESET | PPU_ENABLE | 0x0400; - - ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg); - if (ret) { - printf("%s: Error writing global ctrl reg\n", __func__); - return ret; - } - - for (i = 0; i < 1000; i++) { - sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS, - ®); - if ((reg & 0xc800) != 0xc800) - return 0; - udelay(1000); - } - - return -ETIMEDOUT; -} - -int do_mvsw_reg_read(const char *name, int argc, char * const argv[]) -{ - u16 value = 0, phyaddr, reg, port; - int ret; - - phyaddr = simple_strtoul(argv[1], NULL, 10); - port = simple_strtoul(argv[2], NULL, 10); - reg = simple_strtoul(argv[3], NULL, 10); - - ret = sw_reg_read(name, phyaddr, port, reg, &value); - printf("%#x\n", value); - - return ret; -} - -int do_mvsw_reg_write(const char *name, int argc, char * const argv[]) -{ - u16 value = 0, phyaddr, reg, port; - int ret; - - phyaddr = simple_strtoul(argv[1], NULL, 10); - port = simple_strtoul(argv[2], NULL, 10); - reg = simple_strtoul(argv[3], NULL, 10); - value = simple_strtoul(argv[4], NULL, 16); - - ret = sw_reg_write(name, phyaddr, port, reg, value); - - return ret; -} - - -int do_mvsw_reg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - int ret; - const char *cmd, *ethname; - - if (argc < 2) - return cmd_usage(cmdtp); - - cmd = argv[1]; - --argc; - ++argv; - - if (strcmp(cmd, "read") == 0) { - if (argc < 5) - return cmd_usage(cmdtp); - ethname = argv[1]; - --argc; - ++argv; - ret = do_mvsw_reg_read(ethname, argc, argv); - } else if (strcmp(cmd, "write") == 0) { - if (argc < 6) - return cmd_usage(cmdtp); - ethname = argv[1]; - --argc; - ++argv; - ret = do_mvsw_reg_write(ethname, argc, argv); - } else - return cmd_usage(cmdtp); - - return ret; -} - -U_BOOT_CMD( - mvsw_reg, 7, 1, do_mvsw_reg, - "marvell 88e6352 switch register access", - "write ethname phyaddr port reg value\n" - "mvsw_reg read ethname phyaddr port reg\n" - ); diff --git a/qemu/roms/u-boot/drivers/net/phy/natsemi.c b/qemu/roms/u-boot/drivers/net/phy/natsemi.c deleted file mode 100644 index ea9fe833e..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/natsemi.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * National Semiconductor PHY drivers - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Copyright 2010-2011 Freescale Semiconductor, Inc. - * author Andy Fleming - */ -#include <phy.h> - -/* NatSemi DP83630 */ - -#define DP83630_PHY_PAGESEL_REG 0x13 -#define DP83630_PHY_PTP_COC_REG 0x14 -#define DP83630_PHY_PTP_CLKOUT_EN (1<<15) -#define DP83630_PHY_RBR_REG 0x17 - -static int dp83630_config(struct phy_device *phydev) -{ - int ptp_coc_reg; - - phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); - phy_write(phydev, MDIO_DEVAD_NONE, DP83630_PHY_PAGESEL_REG, 0x6); - ptp_coc_reg = phy_read(phydev, MDIO_DEVAD_NONE, - DP83630_PHY_PTP_COC_REG); - ptp_coc_reg &= ~DP83630_PHY_PTP_CLKOUT_EN; - phy_write(phydev, MDIO_DEVAD_NONE, DP83630_PHY_PTP_COC_REG, - ptp_coc_reg); - phy_write(phydev, MDIO_DEVAD_NONE, DP83630_PHY_PAGESEL_REG, 0); - - genphy_config_aneg(phydev); - - return 0; -} - -static struct phy_driver DP83630_driver = { - .name = "NatSemi DP83630", - .uid = 0x20005ce1, - .mask = 0xfffffff0, - .features = PHY_BASIC_FEATURES, - .config = &dp83630_config, - .startup = &genphy_startup, - .shutdown = &genphy_shutdown, -}; - - -/* DP83865 Link and Auto-Neg Status Register */ -#define MIIM_DP83865_LANR 0x11 -#define MIIM_DP83865_SPD_MASK 0x0018 -#define MIIM_DP83865_SPD_1000 0x0010 -#define MIIM_DP83865_SPD_100 0x0008 -#define MIIM_DP83865_DPX_FULL 0x0002 - - -/* NatSemi DP83865 */ -static int dp83865_config(struct phy_device *phydev) -{ - phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); - genphy_config_aneg(phydev); - - return 0; -} - -static int dp83865_parse_status(struct phy_device *phydev) -{ - int mii_reg; - - mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_DP83865_LANR); - - switch (mii_reg & MIIM_DP83865_SPD_MASK) { - - case MIIM_DP83865_SPD_1000: - phydev->speed = SPEED_1000; - break; - - case MIIM_DP83865_SPD_100: - phydev->speed = SPEED_100; - break; - - default: - phydev->speed = SPEED_10; - break; - - } - - if (mii_reg & MIIM_DP83865_DPX_FULL) - phydev->duplex = DUPLEX_FULL; - else - phydev->duplex = DUPLEX_HALF; - - return 0; -} - -static int dp83865_startup(struct phy_device *phydev) -{ - genphy_update_link(phydev); - dp83865_parse_status(phydev); - - return 0; -} - - -static struct phy_driver DP83865_driver = { - .name = "NatSemi DP83865", - .uid = 0x20005c70, - .mask = 0xfffffff0, - .features = PHY_GBIT_FEATURES, - .config = &dp83865_config, - .startup = &dp83865_startup, - .shutdown = &genphy_shutdown, -}; - -int phy_natsemi_init(void) -{ - phy_register(&DP83630_driver); - phy_register(&DP83865_driver); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/phy/phy.c b/qemu/roms/u-boot/drivers/net/phy/phy.c deleted file mode 100644 index 230ed97dd..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/phy.c +++ /dev/null @@ -1,817 +0,0 @@ -/* - * Generic PHY Management code - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Copyright 2011 Freescale Semiconductor, Inc. - * author Andy Fleming - * - * Based loosely off of Linux's PHY Lib - */ - -#include <config.h> -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <command.h> -#include <miiphy.h> -#include <phy.h> -#include <errno.h> -#include <linux/err.h> -#include <linux/compiler.h> - -/* Generic PHY support and helper functions */ - -/** - * genphy_config_advert - sanitize and advertise auto-negotation parameters - * @phydev: target phy_device struct - * - * Description: Writes MII_ADVERTISE with the appropriate values, - * after sanitizing the values to make sure we only advertise - * what is supported. Returns < 0 on error, 0 if the PHY's advertisement - * hasn't changed, and > 0 if it has changed. - */ -static int genphy_config_advert(struct phy_device *phydev) -{ - u32 advertise; - int oldadv, adv; - int err, changed = 0; - - /* Only allow advertising what - * this PHY supports */ - phydev->advertising &= phydev->supported; - advertise = phydev->advertising; - - /* Setup standard advertisement */ - oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE); - - if (adv < 0) - return adv; - - adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | - ADVERTISE_PAUSE_ASYM); - if (advertise & ADVERTISED_10baseT_Half) - adv |= ADVERTISE_10HALF; - if (advertise & ADVERTISED_10baseT_Full) - adv |= ADVERTISE_10FULL; - if (advertise & ADVERTISED_100baseT_Half) - adv |= ADVERTISE_100HALF; - if (advertise & ADVERTISED_100baseT_Full) - adv |= ADVERTISE_100FULL; - if (advertise & ADVERTISED_Pause) - adv |= ADVERTISE_PAUSE_CAP; - if (advertise & ADVERTISED_Asym_Pause) - adv |= ADVERTISE_PAUSE_ASYM; - if (advertise & ADVERTISED_1000baseX_Half) - adv |= ADVERTISE_1000XHALF; - if (advertise & ADVERTISED_1000baseX_Full) - adv |= ADVERTISE_1000XFULL; - - if (adv != oldadv) { - err = phy_write(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE, adv); - - if (err < 0) - return err; - changed = 1; - } - - /* Configure gigabit if it's supported */ - if (phydev->supported & (SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full)) { - oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000); - - if (adv < 0) - return adv; - - adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); - if (advertise & SUPPORTED_1000baseT_Half) - adv |= ADVERTISE_1000HALF; - if (advertise & SUPPORTED_1000baseT_Full) - adv |= ADVERTISE_1000FULL; - - if (adv != oldadv) { - err = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, - adv); - - if (err < 0) - return err; - changed = 1; - } - } - - return changed; -} - - -/** - * genphy_setup_forced - configures/forces speed/duplex from @phydev - * @phydev: target phy_device struct - * - * Description: Configures MII_BMCR to force speed/duplex - * to the values in phydev. Assumes that the values are valid. - */ -static int genphy_setup_forced(struct phy_device *phydev) -{ - int err; - int ctl = 0; - - phydev->pause = phydev->asym_pause = 0; - - if (SPEED_1000 == phydev->speed) - ctl |= BMCR_SPEED1000; - else if (SPEED_100 == phydev->speed) - ctl |= BMCR_SPEED100; - - if (DUPLEX_FULL == phydev->duplex) - ctl |= BMCR_FULLDPLX; - - err = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl); - - return err; -} - - -/** - * genphy_restart_aneg - Enable and Restart Autonegotiation - * @phydev: target phy_device struct - */ -int genphy_restart_aneg(struct phy_device *phydev) -{ - int ctl; - - ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); - - if (ctl < 0) - return ctl; - - ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); - - /* Don't isolate the PHY if we're negotiating */ - ctl &= ~(BMCR_ISOLATE); - - ctl = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl); - - return ctl; -} - - -/** - * genphy_config_aneg - restart auto-negotiation or write BMCR - * @phydev: target phy_device struct - * - * Description: If auto-negotiation is enabled, we configure the - * advertising, and then restart auto-negotiation. If it is not - * enabled, then we write the BMCR. - */ -int genphy_config_aneg(struct phy_device *phydev) -{ - int result; - - if (AUTONEG_ENABLE != phydev->autoneg) - return genphy_setup_forced(phydev); - - result = genphy_config_advert(phydev); - - if (result < 0) /* error */ - return result; - - if (result == 0) { - /* Advertisment hasn't changed, but maybe aneg was never on to - * begin with? Or maybe phy was isolated? */ - int ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); - - if (ctl < 0) - return ctl; - - if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE)) - result = 1; /* do restart aneg */ - } - - /* Only restart aneg if we are advertising something different - * than we were before. */ - if (result > 0) - result = genphy_restart_aneg(phydev); - - return result; -} - -/** - * genphy_update_link - update link status in @phydev - * @phydev: target phy_device struct - * - * Description: Update the value in phydev->link to reflect the - * current link value. In order to do this, we need to read - * the status register twice, keeping the second value. - */ -int genphy_update_link(struct phy_device *phydev) -{ - unsigned int mii_reg; - - /* - * Wait if the link is up, and autonegotiation is in progress - * (ie - we're capable and it's not done) - */ - mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); - - /* - * If we already saw the link up, and it hasn't gone down, then - * we don't need to wait for autoneg again - */ - if (phydev->link && mii_reg & BMSR_LSTATUS) - return 0; - - if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) { - int i = 0; - - printf("%s Waiting for PHY auto negotiation to complete", - phydev->dev->name); - while (!(mii_reg & BMSR_ANEGCOMPLETE)) { - /* - * Timeout reached ? - */ - if (i > PHY_ANEG_TIMEOUT) { - printf(" TIMEOUT !\n"); - phydev->link = 0; - return 0; - } - - if (ctrlc()) { - puts("user interrupt!\n"); - phydev->link = 0; - return -EINTR; - } - - if ((i++ % 500) == 0) - printf("."); - - udelay(1000); /* 1 ms */ - mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); - } - printf(" done\n"); - phydev->link = 1; - } else { - /* Read the link a second time to clear the latched state */ - mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); - - if (mii_reg & BMSR_LSTATUS) - phydev->link = 1; - else - phydev->link = 0; - } - - return 0; -} - -/* - * Generic function which updates the speed and duplex. If - * autonegotiation is enabled, it uses the AND of the link - * partner's advertised capabilities and our advertised - * capabilities. If autonegotiation is disabled, we use the - * appropriate bits in the control register. - * - * Stolen from Linux's mii.c and phy_device.c - */ -int genphy_parse_link(struct phy_device *phydev) -{ - int mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); - - /* We're using autonegotiation */ - if (phydev->supported & SUPPORTED_Autoneg) { - u32 lpa = 0; - int gblpa = 0; - u32 estatus = 0; - - /* Check for gigabit capability */ - if (phydev->supported & (SUPPORTED_1000baseT_Full | - SUPPORTED_1000baseT_Half)) { - /* We want a list of states supported by - * both PHYs in the link - */ - gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000); - if (gblpa < 0) { - debug("Could not read MII_STAT1000. Ignoring gigabit capability\n"); - gblpa = 0; - } - gblpa &= phy_read(phydev, - MDIO_DEVAD_NONE, MII_CTRL1000) << 2; - } - - /* Set the baseline so we only have to set them - * if they're different - */ - phydev->speed = SPEED_10; - phydev->duplex = DUPLEX_HALF; - - /* Check the gigabit fields */ - if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) { - phydev->speed = SPEED_1000; - - if (gblpa & PHY_1000BTSR_1000FD) - phydev->duplex = DUPLEX_FULL; - - /* We're done! */ - return 0; - } - - lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE); - lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA); - - if (lpa & (LPA_100FULL | LPA_100HALF)) { - phydev->speed = SPEED_100; - - if (lpa & LPA_100FULL) - phydev->duplex = DUPLEX_FULL; - - } else if (lpa & LPA_10FULL) - phydev->duplex = DUPLEX_FULL; - - /* - * Extended status may indicate that the PHY supports - * 1000BASE-T/X even though the 1000BASE-T registers - * are missing. In this case we can't tell whether the - * peer also supports it, so we only check extended - * status if the 1000BASE-T registers are actually - * missing. - */ - if ((mii_reg & BMSR_ESTATEN) && !(mii_reg & BMSR_ERCAP)) - estatus = phy_read(phydev, MDIO_DEVAD_NONE, - MII_ESTATUS); - - if (estatus & (ESTATUS_1000_XFULL | ESTATUS_1000_XHALF | - ESTATUS_1000_TFULL | ESTATUS_1000_THALF)) { - phydev->speed = SPEED_1000; - if (estatus & (ESTATUS_1000_XFULL | ESTATUS_1000_TFULL)) - phydev->duplex = DUPLEX_FULL; - } - - } else { - u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); - - phydev->speed = SPEED_10; - phydev->duplex = DUPLEX_HALF; - - if (bmcr & BMCR_FULLDPLX) - phydev->duplex = DUPLEX_FULL; - - if (bmcr & BMCR_SPEED1000) - phydev->speed = SPEED_1000; - else if (bmcr & BMCR_SPEED100) - phydev->speed = SPEED_100; - } - - return 0; -} - -int genphy_config(struct phy_device *phydev) -{ - int val; - u32 features; - - /* For now, I'll claim that the generic driver supports - * all possible port types */ - features = (SUPPORTED_TP | SUPPORTED_MII - | SUPPORTED_AUI | SUPPORTED_FIBRE | - SUPPORTED_BNC); - - /* Do we support autonegotiation? */ - val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); - - if (val < 0) - return val; - - if (val & BMSR_ANEGCAPABLE) - features |= SUPPORTED_Autoneg; - - if (val & BMSR_100FULL) - features |= SUPPORTED_100baseT_Full; - if (val & BMSR_100HALF) - features |= SUPPORTED_100baseT_Half; - if (val & BMSR_10FULL) - features |= SUPPORTED_10baseT_Full; - if (val & BMSR_10HALF) - features |= SUPPORTED_10baseT_Half; - - if (val & BMSR_ESTATEN) { - val = phy_read(phydev, MDIO_DEVAD_NONE, MII_ESTATUS); - - if (val < 0) - return val; - - if (val & ESTATUS_1000_TFULL) - features |= SUPPORTED_1000baseT_Full; - if (val & ESTATUS_1000_THALF) - features |= SUPPORTED_1000baseT_Half; - if (val & ESTATUS_1000_XFULL) - features |= SUPPORTED_1000baseX_Full; - if (val & ESTATUS_1000_XHALF) - features |= SUPPORTED_1000baseX_Half; - } - - phydev->supported = features; - phydev->advertising = features; - - genphy_config_aneg(phydev); - - return 0; -} - -int genphy_startup(struct phy_device *phydev) -{ - genphy_update_link(phydev); - genphy_parse_link(phydev); - - return 0; -} - -int genphy_shutdown(struct phy_device *phydev) -{ - return 0; -} - -static struct phy_driver genphy_driver = { - .uid = 0xffffffff, - .mask = 0xffffffff, - .name = "Generic PHY", - .features = 0, - .config = genphy_config, - .startup = genphy_startup, - .shutdown = genphy_shutdown, -}; - -static LIST_HEAD(phy_drivers); - -int phy_init(void) -{ -#ifdef CONFIG_PHY_ATHEROS - phy_atheros_init(); -#endif -#ifdef CONFIG_PHY_BROADCOM - phy_broadcom_init(); -#endif -#ifdef CONFIG_PHY_DAVICOM - phy_davicom_init(); -#endif -#ifdef CONFIG_PHY_ET1011C - phy_et1011c_init(); -#endif -#ifdef CONFIG_PHY_ICPLUS - phy_icplus_init(); -#endif -#ifdef CONFIG_PHY_LXT - phy_lxt_init(); -#endif -#ifdef CONFIG_PHY_MARVELL - phy_marvell_init(); -#endif -#ifdef CONFIG_PHY_MICREL - phy_micrel_init(); -#endif -#ifdef CONFIG_PHY_NATSEMI - phy_natsemi_init(); -#endif -#ifdef CONFIG_PHY_REALTEK - phy_realtek_init(); -#endif -#ifdef CONFIG_PHY_SMSC - phy_smsc_init(); -#endif -#ifdef CONFIG_PHY_TERANETICS - phy_teranetics_init(); -#endif -#ifdef CONFIG_PHY_VITESSE - phy_vitesse_init(); -#endif - - return 0; -} - -int phy_register(struct phy_driver *drv) -{ - INIT_LIST_HEAD(&drv->list); - list_add_tail(&drv->list, &phy_drivers); - - return 0; -} - -static int phy_probe(struct phy_device *phydev) -{ - int err = 0; - - phydev->advertising = phydev->supported = phydev->drv->features; - phydev->mmds = phydev->drv->mmds; - - if (phydev->drv->probe) - err = phydev->drv->probe(phydev); - - return err; -} - -static struct phy_driver *generic_for_interface(phy_interface_t interface) -{ -#ifdef CONFIG_PHYLIB_10G - if (is_10g_interface(interface)) - return &gen10g_driver; -#endif - - return &genphy_driver; -} - -static struct phy_driver *get_phy_driver(struct phy_device *phydev, - phy_interface_t interface) -{ - struct list_head *entry; - int phy_id = phydev->phy_id; - struct phy_driver *drv = NULL; - - list_for_each(entry, &phy_drivers) { - drv = list_entry(entry, struct phy_driver, list); - if ((drv->uid & drv->mask) == (phy_id & drv->mask)) - return drv; - } - - /* If we made it here, there's no driver for this PHY */ - return generic_for_interface(interface); -} - -static struct phy_device *phy_device_create(struct mii_dev *bus, int addr, - int phy_id, - phy_interface_t interface) -{ - struct phy_device *dev; - - /* We allocate the device, and initialize the - * default values */ - dev = malloc(sizeof(*dev)); - if (!dev) { - printf("Failed to allocate PHY device for %s:%d\n", - bus->name, addr); - return NULL; - } - - memset(dev, 0, sizeof(*dev)); - - dev->duplex = -1; - dev->link = 1; - dev->interface = interface; - - dev->autoneg = AUTONEG_ENABLE; - - dev->addr = addr; - dev->phy_id = phy_id; - dev->bus = bus; - - dev->drv = get_phy_driver(dev, interface); - - phy_probe(dev); - - bus->phymap[addr] = dev; - - return dev; -} - -/** - * get_phy_id - reads the specified addr for its ID. - * @bus: the target MII bus - * @addr: PHY address on the MII bus - * @phy_id: where to store the ID retrieved. - * - * Description: Reads the ID registers of the PHY at @addr on the - * @bus, stores it in @phy_id and returns zero on success. - */ -int __weak get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id) -{ - int phy_reg; - - /* Grab the bits from PHYIR1, and put them - * in the upper half */ - phy_reg = bus->read(bus, addr, devad, MII_PHYSID1); - - if (phy_reg < 0) - return -EIO; - - *phy_id = (phy_reg & 0xffff) << 16; - - /* Grab the bits from PHYIR2, and put them in the lower half */ - phy_reg = bus->read(bus, addr, devad, MII_PHYSID2); - - if (phy_reg < 0) - return -EIO; - - *phy_id |= (phy_reg & 0xffff); - - return 0; -} - -static struct phy_device *create_phy_by_mask(struct mii_dev *bus, - unsigned phy_mask, int devad, phy_interface_t interface) -{ - u32 phy_id = 0xffffffff; - while (phy_mask) { - int addr = ffs(phy_mask) - 1; - int r = get_phy_id(bus, addr, devad, &phy_id); - if (r < 0) - return ERR_PTR(r); - /* If the PHY ID is mostly f's, we didn't find anything */ - if ((phy_id & 0x1fffffff) != 0x1fffffff) - return phy_device_create(bus, addr, phy_id, interface); - phy_mask &= ~(1 << addr); - } - return NULL; -} - -static struct phy_device *search_for_existing_phy(struct mii_dev *bus, - unsigned phy_mask, phy_interface_t interface) -{ - /* If we have one, return the existing device, with new interface */ - while (phy_mask) { - int addr = ffs(phy_mask) - 1; - if (bus->phymap[addr]) { - bus->phymap[addr]->interface = interface; - return bus->phymap[addr]; - } - phy_mask &= ~(1 << addr); - } - return NULL; -} - -static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus, - unsigned phy_mask, phy_interface_t interface) -{ - int i; - struct phy_device *phydev; - - phydev = search_for_existing_phy(bus, phy_mask, interface); - if (phydev) - return phydev; - /* Try Standard (ie Clause 22) access */ - /* Otherwise we have to try Clause 45 */ - for (i = 0; i < 5; i++) { - phydev = create_phy_by_mask(bus, phy_mask, - i ? i : MDIO_DEVAD_NONE, interface); - if (IS_ERR(phydev)) - return NULL; - if (phydev) - return phydev; - } - printf("Phy not found\n"); - return phy_device_create(bus, ffs(phy_mask) - 1, 0xffffffff, interface); -} - -/** - * get_phy_device - reads the specified PHY device and returns its @phy_device struct - * @bus: the target MII bus - * @addr: PHY address on the MII bus - * - * Description: Reads the ID registers of the PHY at @addr on the - * @bus, then allocates and returns the phy_device to represent it. - */ -static struct phy_device *get_phy_device(struct mii_dev *bus, int addr, - phy_interface_t interface) -{ - return get_phy_device_by_mask(bus, 1 << addr, interface); -} - -int phy_reset(struct phy_device *phydev) -{ - int reg; - int timeout = 500; - int devad = MDIO_DEVAD_NONE; - -#ifdef CONFIG_PHYLIB_10G - /* If it's 10G, we need to issue reset through one of the MMDs */ - if (is_10g_interface(phydev->interface)) { - if (!phydev->mmds) - gen10g_discover_mmds(phydev); - - devad = ffs(phydev->mmds) - 1; - } -#endif - - reg = phy_read(phydev, devad, MII_BMCR); - if (reg < 0) { - debug("PHY status read failed\n"); - return -1; - } - - reg |= BMCR_RESET; - - if (phy_write(phydev, devad, MII_BMCR, reg) < 0) { - debug("PHY reset failed\n"); - return -1; - } - -#ifdef CONFIG_PHY_RESET_DELAY - udelay(CONFIG_PHY_RESET_DELAY); /* Intel LXT971A needs this */ -#endif - /* - * Poll the control register for the reset bit to go to 0 (it is - * auto-clearing). This should happen within 0.5 seconds per the - * IEEE spec. - */ - while ((reg & BMCR_RESET) && timeout--) { - reg = phy_read(phydev, devad, MII_BMCR); - - if (reg < 0) { - debug("PHY status read failed\n"); - return -1; - } - udelay(1000); - } - - if (reg & BMCR_RESET) { - puts("PHY reset timed out\n"); - return -1; - } - - return 0; -} - -int miiphy_reset(const char *devname, unsigned char addr) -{ - struct mii_dev *bus = miiphy_get_dev_by_name(devname); - struct phy_device *phydev; - - /* - * miiphy_reset was only used on standard PHYs, so we'll fake it here. - * If later code tries to connect with the right interface, this will - * be corrected by get_phy_device in phy_connect() - */ - phydev = get_phy_device(bus, addr, PHY_INTERFACE_MODE_MII); - - return phy_reset(phydev); -} - -struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask, - phy_interface_t interface) -{ - /* Reset the bus */ - if (bus->reset) - bus->reset(bus); - - /* Wait 15ms to make sure the PHY has come out of hard reset */ - udelay(15000); - return get_phy_device_by_mask(bus, phy_mask, interface); -} - -void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev) -{ - /* Soft Reset the PHY */ - phy_reset(phydev); - if (phydev->dev) { - printf("%s:%d is connected to %s. Reconnecting to %s\n", - phydev->bus->name, phydev->addr, - phydev->dev->name, dev->name); - } - phydev->dev = dev; - debug("%s connected to %s\n", dev->name, phydev->drv->name); -} - -struct phy_device *phy_connect(struct mii_dev *bus, int addr, - struct eth_device *dev, phy_interface_t interface) -{ - struct phy_device *phydev; - - phydev = phy_find_by_mask(bus, 1 << addr, interface); - if (phydev) - phy_connect_dev(phydev, dev); - else - printf("Could not get PHY for %s: addr %d\n", bus->name, addr); - return phydev; -} - -/* - * Start the PHY. Returns 0 on success, or a negative error code. - */ -int phy_startup(struct phy_device *phydev) -{ - if (phydev->drv->startup) - return phydev->drv->startup(phydev); - - return 0; -} - -static int __board_phy_config(struct phy_device *phydev) -{ - if (phydev->drv->config) - return phydev->drv->config(phydev); - return 0; -} - -int board_phy_config(struct phy_device *phydev) - __attribute__((weak, alias("__board_phy_config"))); - -int phy_config(struct phy_device *phydev) -{ - /* Invoke an optional board-specific helper */ - board_phy_config(phydev); - - return 0; -} - -int phy_shutdown(struct phy_device *phydev) -{ - if (phydev->drv->shutdown) - phydev->drv->shutdown(phydev); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/phy/realtek.c b/qemu/roms/u-boot/drivers/net/phy/realtek.c deleted file mode 100644 index a3ace6852..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/realtek.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * RealTek PHY drivers - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Copyright 2010-2011 Freescale Semiconductor, Inc. - * author Andy Fleming - */ -#include <config.h> -#include <common.h> -#include <phy.h> - -#define PHY_AUTONEGOTIATE_TIMEOUT 5000 - -/* RTL8211x PHY Status Register */ -#define MIIM_RTL8211x_PHY_STATUS 0x11 -#define MIIM_RTL8211x_PHYSTAT_SPEED 0xc000 -#define MIIM_RTL8211x_PHYSTAT_GBIT 0x8000 -#define MIIM_RTL8211x_PHYSTAT_100 0x4000 -#define MIIM_RTL8211x_PHYSTAT_DUPLEX 0x2000 -#define MIIM_RTL8211x_PHYSTAT_SPDDONE 0x0800 -#define MIIM_RTL8211x_PHYSTAT_LINK 0x0400 - - -/* RealTek RTL8211x */ -static int rtl8211x_config(struct phy_device *phydev) -{ - phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); - - genphy_config_aneg(phydev); - - return 0; -} - -static int rtl8211x_parse_status(struct phy_device *phydev) -{ - unsigned int speed; - unsigned int mii_reg; - - mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_STATUS); - - if (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) { - int i = 0; - - /* in case of timeout ->link is cleared */ - phydev->link = 1; - puts("Waiting for PHY realtime link"); - while (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) { - /* Timeout reached ? */ - if (i > PHY_AUTONEGOTIATE_TIMEOUT) { - puts(" TIMEOUT !\n"); - phydev->link = 0; - break; - } - - if ((i++ % 1000) == 0) - putc('.'); - udelay(1000); /* 1 ms */ - mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, - MIIM_RTL8211x_PHY_STATUS); - } - puts(" done\n"); - udelay(500000); /* another 500 ms (results in faster booting) */ - } else { - if (mii_reg & MIIM_RTL8211x_PHYSTAT_LINK) - phydev->link = 1; - else - phydev->link = 0; - } - - if (mii_reg & MIIM_RTL8211x_PHYSTAT_DUPLEX) - phydev->duplex = DUPLEX_FULL; - else - phydev->duplex = DUPLEX_HALF; - - speed = (mii_reg & MIIM_RTL8211x_PHYSTAT_SPEED); - - switch (speed) { - case MIIM_RTL8211x_PHYSTAT_GBIT: - phydev->speed = SPEED_1000; - break; - case MIIM_RTL8211x_PHYSTAT_100: - phydev->speed = SPEED_100; - break; - default: - phydev->speed = SPEED_10; - } - - return 0; -} - -static int rtl8211x_startup(struct phy_device *phydev) -{ - /* Read the Status (2x to make sure link is right) */ - genphy_update_link(phydev); - rtl8211x_parse_status(phydev); - - return 0; -} - -/* Support for RTL8211B PHY */ -static struct phy_driver RTL8211B_driver = { - .name = "RealTek RTL8211B", - .uid = 0x1cc910, - .mask = 0xffffff, - .features = PHY_GBIT_FEATURES, - .config = &rtl8211x_config, - .startup = &rtl8211x_startup, - .shutdown = &genphy_shutdown, -}; - -/* Support for RTL8211E-VB-CG, RTL8211E-VL-CG and RTL8211EG-VB-CG PHYs */ -static struct phy_driver RTL8211E_driver = { - .name = "RealTek RTL8211E", - .uid = 0x1cc915, - .mask = 0xffffff, - .features = PHY_GBIT_FEATURES, - .config = &rtl8211x_config, - .startup = &rtl8211x_startup, - .shutdown = &genphy_shutdown, -}; - -/* Support for RTL8211DN PHY */ -static struct phy_driver RTL8211DN_driver = { - .name = "RealTek RTL8211DN", - .uid = 0x1cc914, - .mask = 0xffffff, - .features = PHY_GBIT_FEATURES, - .config = &rtl8211x_config, - .startup = &rtl8211x_startup, - .shutdown = &genphy_shutdown, -}; - -int phy_realtek_init(void) -{ - phy_register(&RTL8211B_driver); - phy_register(&RTL8211E_driver); - phy_register(&RTL8211DN_driver); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/phy/smsc.c b/qemu/roms/u-boot/drivers/net/phy/smsc.c deleted file mode 100644 index bfd9815ab..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/smsc.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * SMSC PHY drivers - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Base code from drivers/net/phy/davicom.c - * Copyright 2010-2011 Freescale Semiconductor, Inc. - * author Andy Fleming - * - * Some code copied from linux kernel - * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org> - */ -#include <miiphy.h> - -/* This code does not check the partner abilities. */ -static int smsc_parse_status(struct phy_device *phydev) -{ - int mii_reg; - - mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); - - if (mii_reg & (BMSR_100FULL | BMSR_100HALF)) - phydev->speed = SPEED_100; - else - phydev->speed = SPEED_10; - - if (mii_reg & (BMSR_10FULL | BMSR_100FULL)) - phydev->duplex = DUPLEX_FULL; - else - phydev->duplex = DUPLEX_HALF; - - return 0; -} - -static int smsc_startup(struct phy_device *phydev) -{ - genphy_update_link(phydev); - smsc_parse_status(phydev); - return 0; -} - -static struct phy_driver lan8700_driver = { - .name = "SMSC LAN8700", - .uid = 0x0007c0c0, - .mask = 0xffff0, - .features = PHY_BASIC_FEATURES, - .config = &genphy_config_aneg, - .startup = &smsc_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver lan911x_driver = { - .name = "SMSC LAN911x Internal PHY", - .uid = 0x0007c0d0, - .mask = 0xffff0, - .features = PHY_BASIC_FEATURES, - .config = &genphy_config_aneg, - .startup = &smsc_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver lan8710_driver = { - .name = "SMSC LAN8710/LAN8720", - .uid = 0x0007c0f0, - .mask = 0xffff0, - .features = PHY_BASIC_FEATURES, - .config = &genphy_config_aneg, - .startup = &genphy_startup, - .shutdown = &genphy_shutdown, -}; - -int phy_smsc_init(void) -{ - phy_register(&lan8710_driver); - phy_register(&lan911x_driver); - phy_register(&lan8700_driver); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/phy/teranetics.c b/qemu/roms/u-boot/drivers/net/phy/teranetics.c deleted file mode 100644 index 93d5ac3d1..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/teranetics.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Teranetics PHY drivers - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Copyright 2010-2011 Freescale Semiconductor, Inc. - * author Andy Fleming - */ -#include <config.h> -#include <common.h> -#include <phy.h> - -#ifndef CONFIG_PHYLIB_10G -#error The Teranetics PHY needs 10G support -#endif - -int tn2020_config(struct phy_device *phydev) -{ - if (phydev->port == PORT_FIBRE) { - unsigned short restart_an = (MDIO_AN_CTRL1_RESTART | - MDIO_AN_CTRL1_ENABLE | - MDIO_AN_CTRL1_XNP); - u8 phy_hwversion; - - /* - * bit 15:12 of register 30.32 indicates PHY hardware - * version. It can be used to distinguish TN80xx from - * TN2020. TN2020 needs write 0x2 to 30.93, but TN80xx - * needs 0x1. - */ - phy_hwversion = (phy_read(phydev, 30, 32) >> 12) & 0xf; - if (phy_hwversion <= 3) { - phy_write(phydev, 30, 93, 2); - phy_write(phydev, MDIO_MMD_AN, MDIO_CTRL1, restart_an); - } else { - phy_write(phydev, 30, 93, 1); - } - } - - return 0; -} - -int tn2020_startup(struct phy_device *phydev) -{ - unsigned int timeout = 5 * 1000; /* 5 second timeout */ - -#define MDIO_PHYXS_LANE_READY (MDIO_PHYXS_LNSTAT_SYNC0 | \ - MDIO_PHYXS_LNSTAT_SYNC1 | \ - MDIO_PHYXS_LNSTAT_SYNC2 | \ - MDIO_PHYXS_LNSTAT_SYNC3 | \ - MDIO_PHYXS_LNSTAT_ALIGN) - - /* - * Wait for the XAUI-SERDES lanes to align first. Under normal - * circumstances, this can take up to three seconds. - */ - while (--timeout) { - int reg = phy_read(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_LNSTAT); - if (reg < 0) { - printf("TN2020: Error reading from PHY at " - "address %u\n", phydev->addr); - break; - } - if ((reg & MDIO_PHYXS_LANE_READY) == MDIO_PHYXS_LANE_READY) - break; - udelay(1000); - } - if (!timeout) { - /* - * A timeout is bad, but it may not be fatal, so don't - * return an error. Display a warning instead. - */ - printf("TN2020: Timeout waiting for PHY at address %u to " - "align.\n", phydev->addr); - } - - if (phydev->port != PORT_FIBRE) - return gen10g_startup(phydev); - - /* - * The TN2020 only pretends to support fiber. - * It works, but it doesn't look like it works, - * so the link status reports no link. - */ - phydev->link = 1; - - /* For now just lie and say it's 10G all the time */ - phydev->speed = SPEED_10000; - phydev->duplex = DUPLEX_FULL; - - return 0; -} - -struct phy_driver tn2020_driver = { - .name = "Teranetics TN2020", - .uid = PHY_UID_TN2020, - .mask = 0xfffffff0, - .features = PHY_10G_FEATURES, - .mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | - MDIO_DEVS_PHYXS | MDIO_DEVS_AN | - MDIO_DEVS_VEND1 | MDIO_DEVS_VEND2), - .config = &tn2020_config, - .startup = &tn2020_startup, - .shutdown = &gen10g_shutdown, -}; - -int phy_teranetics_init(void) -{ - phy_register(&tn2020_driver); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/phy/vitesse.c b/qemu/roms/u-boot/drivers/net/phy/vitesse.c deleted file mode 100644 index 3a55d271a..000000000 --- a/qemu/roms/u-boot/drivers/net/phy/vitesse.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Vitesse PHY drivers - * - * Copyright 2010-2012 Freescale Semiconductor, Inc. - * Author: Andy Fleming - * Add vsc8662 phy support - Priyanka Jain - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <miiphy.h> - -/* Cicada Auxiliary Control/Status Register */ -#define MIIM_CIS82xx_AUX_CONSTAT 0x1c -#define MIIM_CIS82xx_AUXCONSTAT_INIT 0x0004 -#define MIIM_CIS82xx_AUXCONSTAT_DUPLEX 0x0020 -#define MIIM_CIS82xx_AUXCONSTAT_SPEED 0x0018 -#define MIIM_CIS82xx_AUXCONSTAT_GBIT 0x0010 -#define MIIM_CIS82xx_AUXCONSTAT_100 0x0008 - -/* Cicada Extended Control Register 1 */ -#define MIIM_CIS82xx_EXT_CON1 0x17 -#define MIIM_CIS8201_EXTCON1_INIT 0x0000 - -/* Cicada 8204 Extended PHY Control Register 1 */ -#define MIIM_CIS8204_EPHY_CON 0x17 -#define MIIM_CIS8204_EPHYCON_INIT 0x0006 -#define MIIM_CIS8204_EPHYCON_RGMII 0x1100 - -/* Cicada 8204 Serial LED Control Register */ -#define MIIM_CIS8204_SLED_CON 0x1b -#define MIIM_CIS8204_SLEDCON_INIT 0x1115 - -/* Vitesse VSC8601 Extended PHY Control Register 1 */ -#define MIIM_VSC8601_EPHY_CON 0x17 -#define MIIM_VSC8601_EPHY_CON_INIT_SKEW 0x1120 -#define MIIM_VSC8601_SKEW_CTRL 0x1c - -#define PHY_EXT_PAGE_ACCESS 0x1f -#define PHY_EXT_PAGE_ACCESS_GENERAL 0x10 -#define PHY_EXT_PAGE_ACCESS_EXTENDED3 0x3 - -/* Vitesse VSC8574 control register */ -#define MIIM_VSC8574_MAC_SERDES_CON 0x10 -#define MIIM_VSC8574_MAC_SERDES_ANEG 0x80 -#define MIIM_VSC8574_GENERAL18 0x12 -#define MIIM_VSC8574_GENERAL19 0x13 - -/* Vitesse VSC8574 gerenal purpose register 18 */ -#define MIIM_VSC8574_18G_SGMII 0x80f0 -#define MIIM_VSC8574_18G_QSGMII 0x80e0 -#define MIIM_VSC8574_18G_CMDSTAT 0x8000 - -/* Vitesse VSC8514 control register */ -#define MIIM_VSC8514_GENERAL18 0x12 -#define MIIM_VSC8514_GENERAL19 0x13 -#define MIIM_VSC8514_GENERAL23 0x17 - -/* Vitesse VSC8514 gerenal purpose register 18 */ -#define MIIM_VSC8514_18G_QSGMII 0x80e0 -#define MIIM_VSC8514_18G_CMDSTAT 0x8000 - -/* CIS8201 */ -static int vitesse_config(struct phy_device *phydev) -{ - /* Override PHY config settings */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT, - MIIM_CIS82xx_AUXCONSTAT_INIT); - /* Set up the interface mode */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_EXT_CON1, - MIIM_CIS8201_EXTCON1_INIT); - - genphy_config_aneg(phydev); - - return 0; -} - -static int vitesse_parse_status(struct phy_device *phydev) -{ - int speed; - int mii_reg; - - mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT); - - if (mii_reg & MIIM_CIS82xx_AUXCONSTAT_DUPLEX) - phydev->duplex = DUPLEX_FULL; - else - phydev->duplex = DUPLEX_HALF; - - speed = mii_reg & MIIM_CIS82xx_AUXCONSTAT_SPEED; - switch (speed) { - case MIIM_CIS82xx_AUXCONSTAT_GBIT: - phydev->speed = SPEED_1000; - break; - case MIIM_CIS82xx_AUXCONSTAT_100: - phydev->speed = SPEED_100; - break; - default: - phydev->speed = SPEED_10; - break; - } - - return 0; -} - -static int vitesse_startup(struct phy_device *phydev) -{ - genphy_update_link(phydev); - vitesse_parse_status(phydev); - - return 0; -} - -static int cis8204_config(struct phy_device *phydev) -{ - /* Override PHY config settings */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT, - MIIM_CIS82xx_AUXCONSTAT_INIT); - - genphy_config_aneg(phydev); - - if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) || - (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)) - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS8204_EPHY_CON, - MIIM_CIS8204_EPHYCON_INIT | - MIIM_CIS8204_EPHYCON_RGMII); - else - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS8204_EPHY_CON, - MIIM_CIS8204_EPHYCON_INIT); - - return 0; -} - -/* Vitesse VSC8601 */ -static int vsc8601_config(struct phy_device *phydev) -{ - /* Configure some basic stuff */ -#ifdef CONFIG_SYS_VSC8601_SKEWFIX - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8601_EPHY_CON, - MIIM_VSC8601_EPHY_CON_INIT_SKEW); -#if defined(CONFIG_SYS_VSC8601_SKEW_TX) && defined(CONFIG_SYS_VSC8601_SKEW_RX) - phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 1); -#define VSC8101_SKEW \ - ((CONFIG_SYS_VSC8601_SKEW_TX << 14) \ - | (CONFIG_SYS_VSC8601_SKEW_RX << 12)) - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8601_SKEW_CTRL, - VSC8101_SKEW); - phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0); -#endif -#endif - - genphy_config_aneg(phydev); - - return 0; -} - -static int vsc8574_config(struct phy_device *phydev) -{ - u32 val; - /* configure register 19G for MAC */ - phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, - PHY_EXT_PAGE_ACCESS_GENERAL); - - val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL19); - if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) { - /* set bit 15:14 to '01' for QSGMII mode */ - val = (val & 0x3fff) | (1 << 14); - phy_write(phydev, MDIO_DEVAD_NONE, - MIIM_VSC8574_GENERAL19, val); - /* Enable 4 ports MAC QSGMII */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18, - MIIM_VSC8574_18G_QSGMII); - } else { - /* set bit 15:14 to '00' for SGMII mode */ - val = val & 0x3fff; - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL19, val); - /* Enable 4 ports MAC SGMII */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18, - MIIM_VSC8574_18G_SGMII); - } - val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18); - /* When bit 15 is cleared the command has completed */ - while (val & MIIM_VSC8574_18G_CMDSTAT) - val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18); - - /* Enable Serdes Auto-negotiation */ - phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, - PHY_EXT_PAGE_ACCESS_EXTENDED3); - val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_MAC_SERDES_CON); - val = val | MIIM_VSC8574_MAC_SERDES_ANEG; - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_MAC_SERDES_CON, val); - - phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0); - - genphy_config_aneg(phydev); - - return 0; -} - -static int vsc8514_config(struct phy_device *phydev) -{ - u32 val; - int timeout = 1000000; - - /* configure register to access 19G */ - phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, - PHY_EXT_PAGE_ACCESS_GENERAL); - - val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL19); - if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) { - /* set bit 15:14 to '01' for QSGMII mode */ - val = (val & 0x3fff) | (1 << 14); - phy_write(phydev, MDIO_DEVAD_NONE, - MIIM_VSC8514_GENERAL19, val); - /* Enable 4 ports MAC QSGMII */ - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL18, - MIIM_VSC8514_18G_QSGMII); - } else { - /*TODO Add SGMII functionality once spec sheet - * for VSC8514 defines complete functionality - */ - } - - val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL18); - /* When bit 15 is cleared the command has completed */ - while ((val & MIIM_VSC8514_18G_CMDSTAT) && timeout--) - val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL18); - - if (0 == timeout) { - printf("PHY 8514 config failed\n"); - return -1; - } - - phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0); - - /* configure register to access 23 */ - val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL23); - /* set bits 10:8 to '000' */ - val = (val & 0xf8ff); - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL23, val); - - genphy_config_aneg(phydev); - - return 0; -} - -static struct phy_driver VSC8211_driver = { - .name = "Vitesse VSC8211", - .uid = 0xfc4b0, - .mask = 0xffff0, - .features = PHY_GBIT_FEATURES, - .config = &vitesse_config, - .startup = &vitesse_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver VSC8221_driver = { - .name = "Vitesse VSC8221", - .uid = 0xfc550, - .mask = 0xffff0, - .features = PHY_GBIT_FEATURES, - .config = &genphy_config_aneg, - .startup = &vitesse_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver VSC8244_driver = { - .name = "Vitesse VSC8244", - .uid = 0xfc6c0, - .mask = 0xffff0, - .features = PHY_GBIT_FEATURES, - .config = &genphy_config_aneg, - .startup = &vitesse_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver VSC8234_driver = { - .name = "Vitesse VSC8234", - .uid = 0xfc620, - .mask = 0xffff0, - .features = PHY_GBIT_FEATURES, - .config = &genphy_config_aneg, - .startup = &vitesse_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver VSC8574_driver = { - .name = "Vitesse VSC8574", - .uid = 0x704a0, - .mask = 0xffff0, - .features = PHY_GBIT_FEATURES, - .config = &vsc8574_config, - .startup = &vitesse_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver VSC8514_driver = { - .name = "Vitesse VSC8514", - .uid = 0x70670, - .mask = 0xffff0, - .features = PHY_GBIT_FEATURES, - .config = &vsc8514_config, - .startup = &vitesse_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver VSC8601_driver = { - .name = "Vitesse VSC8601", - .uid = 0x70420, - .mask = 0xffff0, - .features = PHY_GBIT_FEATURES, - .config = &vsc8601_config, - .startup = &vitesse_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver VSC8641_driver = { - .name = "Vitesse VSC8641", - .uid = 0x70430, - .mask = 0xffff0, - .features = PHY_GBIT_FEATURES, - .config = &genphy_config_aneg, - .startup = &vitesse_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver VSC8662_driver = { - .name = "Vitesse VSC8662", - .uid = 0x70660, - .mask = 0xffff0, - .features = PHY_GBIT_FEATURES, - .config = &genphy_config_aneg, - .startup = &vitesse_startup, - .shutdown = &genphy_shutdown, -}; - -/* Vitesse bought Cicada, so we'll put these here */ -static struct phy_driver cis8201_driver = { - .name = "CIS8201", - .uid = 0xfc410, - .mask = 0xffff0, - .features = PHY_GBIT_FEATURES, - .config = &vitesse_config, - .startup = &vitesse_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver cis8204_driver = { - .name = "Cicada Cis8204", - .uid = 0xfc440, - .mask = 0xffff0, - .features = PHY_GBIT_FEATURES, - .config = &cis8204_config, - .startup = &vitesse_startup, - .shutdown = &genphy_shutdown, -}; - -int phy_vitesse_init(void) -{ - phy_register(&VSC8641_driver); - phy_register(&VSC8601_driver); - phy_register(&VSC8234_driver); - phy_register(&VSC8244_driver); - phy_register(&VSC8211_driver); - phy_register(&VSC8221_driver); - phy_register(&VSC8574_driver); - phy_register(&VSC8514_driver); - phy_register(&VSC8662_driver); - phy_register(&cis8201_driver); - phy_register(&cis8204_driver); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/plb2800_eth.c b/qemu/roms/u-boot/drivers/net/plb2800_eth.c deleted file mode 100644 index f869514f2..000000000 --- a/qemu/roms/u-boot/drivers/net/plb2800_eth.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * PLB2800 internal switch ethernet driver. - * - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <asm/addrspace.h> - - -#define NUM_RX_DESC PKTBUFSRX -#define TOUT_LOOP 1000000 - -#define LONG_REF(addr) (*((volatile unsigned long*)addr)) - -#define CMAC_CRX_CTRL LONG_REF(0xb800c870) -#define CMAC_CTX_CTRL LONG_REF(0xb800c874) -#define SYS_MAC_ADDR_0 LONG_REF(0xb800c878) -#define SYS_MAC_ADDR_1 LONG_REF(0xb800c87c) -#define MIPS_H_MASK LONG_REF(0xB800C810) - -#define MA_LEARN LONG_REF(0xb8008004) -#define DA_LOOKUP LONG_REF(0xb8008008) - -#define CMAC_CRX_CTRL_PD 0x00000001 -#define CMAC_CRX_CTRL_CG 0x00000002 -#define CMAC_CRX_CTRL_PL_SHIFT 2 -#define CMAC_CRIT 0x0 -#define CMAC_NON_CRIT 0x1 -#define MBOX_STAT_ID_SHF 28 -#define MBOX_STAT_CP 0x80000000 -#define MBOX_STAT_MB 0x00000001 -#define EN_MA_LEARN 0x02000000 -#define EN_DA_LKUP 0x01000000 -#define MA_DEST_SHF 11 -#define DA_DEST_SHF 11 -#define DA_STATE_SHF 19 -#define TSTAMP_MS 0x00000000 -#define SW_H_MBOX4_MASK 0x08000000 -#define SW_H_MBOX3_MASK 0x04000000 -#define SW_H_MBOX2_MASK 0x02000000 -#define SW_H_MBOX1_MASK 0x01000000 - -typedef volatile struct { - unsigned int stat; - unsigned int cmd; - unsigned int cnt; - unsigned int adr; -} mailbox_t; - -#define MBOX_REG(mb) ((mailbox_t*)(0xb800c830+(mb<<4))) - -typedef volatile struct { - unsigned int word0; - unsigned int word1; - unsigned int word2; -} mbhdr_t; - -#define MBOX_MEM(mb) ((void*)(0xb800a000+((3-mb)<<11))) - - -static int plb2800_eth_init(struct eth_device *dev, bd_t * bis); -static int plb2800_eth_send(struct eth_device *dev, void *packet, int length); -static int plb2800_eth_recv(struct eth_device *dev); -static void plb2800_eth_halt(struct eth_device *dev); - -static void plb2800_set_mac_addr(struct eth_device *dev, unsigned char * addr); -static unsigned char * plb2800_get_mac_addr(void); - -static int rx_new; -static int mac_addr_set = 0; - - -int plb2800_eth_initialize(bd_t * bis) -{ - struct eth_device *dev; - ulong temp; - -#ifdef DEBUG - printf("Entered plb2800_eth_initialize()\n"); -#endif - - if (!(dev = (struct eth_device *) malloc (sizeof *dev))) - { - printf("Failed to allocate memory\n"); - return -1; - } - memset(dev, 0, sizeof(*dev)); - - sprintf(dev->name, "PLB2800 Switch"); - dev->init = plb2800_eth_init; - dev->halt = plb2800_eth_halt; - dev->send = plb2800_eth_send; - dev->recv = plb2800_eth_recv; - - eth_register(dev); - - /* bug fix */ - *(ulong *)0xb800e800 = 0x838; - - /* Set MBOX ownership */ - temp = CMAC_CRIT << MBOX_STAT_ID_SHF; - MBOX_REG(0)->stat = temp; - MBOX_REG(1)->stat = temp; - - temp = CMAC_NON_CRIT << MBOX_STAT_ID_SHF; - MBOX_REG(2)->stat = temp; - MBOX_REG(3)->stat = temp; - - plb2800_set_mac_addr(dev, plb2800_get_mac_addr()); - - /* Disable all Mbox interrupt */ - temp = MIPS_H_MASK; - temp &= ~ (SW_H_MBOX1_MASK | SW_H_MBOX2_MASK | SW_H_MBOX3_MASK | SW_H_MBOX4_MASK) ; - MIPS_H_MASK = temp; - -#ifdef DEBUG - printf("Leaving plb2800_eth_initialize()\n"); -#endif - - return 0; -} - -static int plb2800_eth_init(struct eth_device *dev, bd_t * bis) -{ -#ifdef DEBUG - printf("Entering plb2800_eth_init()\n"); -#endif - - plb2800_set_mac_addr(dev, dev->enetaddr); - - rx_new = 0; - -#ifdef DEBUG - printf("Leaving plb2800_eth_init()\n"); -#endif - - return 0; -} - - -static int plb2800_eth_send(struct eth_device *dev, void *packet, int length) -{ - int i; - int res = -1; - u32 temp; - mailbox_t * mb = MBOX_REG(0); - char * mem = MBOX_MEM(0); - -#ifdef DEBUG - printf("Entered plb2800_eth_send()\n"); -#endif - - if (length <= 0) - { - printf ("%s: bad packet size: %d\n", dev->name, length); - goto Done; - } - - if (length < 64) - { - length = 64; - } - - temp = CMAC_CRX_CTRL_CG | ((length + 4) << CMAC_CRX_CTRL_PL_SHIFT); - -#ifdef DEBUG - printf("0 mb->stat = 0x%x\n", mb->stat); -#endif - - for(i = 0; mb->stat & (MBOX_STAT_CP | MBOX_STAT_MB); i++) - { - if (i >= TOUT_LOOP) - { - printf("%s: tx buffer not ready\n", dev->name); - printf("1 mb->stat = 0x%x\n", mb->stat); - goto Done; - } - } - - /* For some strange reason, memcpy doesn't work, here! - */ - do - { - int words = (length >> 2) + 1; - unsigned int* dst = (unsigned int*)(mem); - unsigned int* src = (unsigned int*)(packet); - for (i = 0; i < words; i++) - { - *dst = *src; - dst++; - src++; - }; - } while(0); - - CMAC_CRX_CTRL = temp; - mb->cmd = MBOX_STAT_CP; - -#ifdef DEBUG - printf("2 mb->stat = 0x%x\n", mb->stat); -#endif - - res = length; -Done: - -#ifdef DEBUG - printf("Leaving plb2800_eth_send()\n"); -#endif - - return res; -} - - -static int plb2800_eth_recv(struct eth_device *dev) -{ - int length = 0; - mailbox_t * mbox = MBOX_REG(3); - unsigned char * hdr = MBOX_MEM(3); - unsigned int stat; - -#ifdef DEBUG - printf("Entered plb2800_eth_recv()\n"); -#endif - - for (;;) - { - stat = mbox->stat; - - if (!(stat & MBOX_STAT_CP)) - { - break; - } - - length = ((*(hdr + 6) & 0x3f) << 8) + *(hdr + 7); - memcpy((void *)NetRxPackets[rx_new], hdr + 12, length); - - stat &= ~MBOX_STAT_CP; - mbox->stat = stat; -#ifdef DEBUG - { - int i; - for (i=0;i<length - 4;i++) - { - if (i % 16 == 0) printf("\n%04x: ", i); - printf("%02X ", NetRxPackets[rx_new][i]); - } - printf("\n"); - } -#endif - - if (length) - { -#ifdef DEBUG - printf("Received %d bytes\n", length); -#endif - NetReceive((void*)(NetRxPackets[rx_new]), - length - 4); - } - else - { -#if 1 - printf("Zero length!!!\n"); -#endif - } - - rx_new = (rx_new + 1) % NUM_RX_DESC; - } - -#ifdef DEBUG - printf("Leaving plb2800_eth_recv()\n"); -#endif - - return length; -} - - -static void plb2800_eth_halt(struct eth_device *dev) -{ -#ifdef DEBUG - printf("Entered plb2800_eth_halt()\n"); -#endif - -#ifdef DEBUG - printf("Leaving plb2800_eth_halt()\n"); -#endif -} - -static void plb2800_set_mac_addr(struct eth_device *dev, unsigned char * addr) -{ - char packet[60]; - ulong temp; - int ix; - - if (mac_addr_set || - NULL == addr || memcmp(addr, "\0\0\0\0\0\0", 6) == 0) - { - return; - } - - /* send one packet through CPU port - * in order to learn system MAC address - */ - - /* Set DA_LOOKUP register */ - temp = EN_MA_LEARN | (0 << DA_STATE_SHF) | (63 << DA_DEST_SHF); - DA_LOOKUP = temp; - - /* Set MA_LEARN register */ - temp = 50 << MA_DEST_SHF; /* static entry */ - MA_LEARN = temp; - - /* set destination address */ - for (ix=0;ix<6;ix++) - packet[ix] = 0xff; - - /* set source address = system MAC address */ - for (ix=0;ix<6;ix++) - packet[6+ix] = addr[ix]; - - /* set type field */ - packet[12]=0xaa; - packet[13]=0x55; - - /* set data field */ - for(ix=14;ix<60;ix++) - packet[ix] = 0x00; - -#ifdef DEBUG - for (ix=0;ix<6;ix++) - printf("mac_addr[%d]=%02X\n", ix, (unsigned char)packet[6+ix]); -#endif - - /* set one packet */ - plb2800_eth_send(dev, packet, sizeof(packet)); - - /* delay for a while */ - for(ix=0;ix<65535;ix++) - temp = ~temp; - - /* Set CMAC_CTX_CTRL register */ - temp = TSTAMP_MS; /* no autocast */ - CMAC_CTX_CTRL = temp; - - /* Set DA_LOOKUP register */ - temp = EN_DA_LKUP; - DA_LOOKUP = temp; - - mac_addr_set = 1; -} - -static unsigned char * plb2800_get_mac_addr(void) -{ - static unsigned char addr[6]; - char *tmp, *end; - int i; - - tmp = getenv ("ethaddr"); - if (NULL == tmp) return NULL; - - for (i=0; i<6; i++) { - addr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0; - if (tmp) - tmp = (*end) ? end+1 : end; - } - - return addr; -} diff --git a/qemu/roms/u-boot/drivers/net/rtl8139.c b/qemu/roms/u-boot/drivers/net/rtl8139.c deleted file mode 100644 index 208ce5ccc..000000000 --- a/qemu/roms/u-boot/drivers/net/rtl8139.c +++ /dev/null @@ -1,539 +0,0 @@ -/* - * rtl8139.c : U-Boot driver for the RealTek RTL8139 - * - * Masami Komiya (mkomiya@sonare.it) - * - * Most part is taken from rtl8139.c of etherboot - * - */ - -/* rtl8139.c - etherboot driver for the Realtek 8139 chipset - - ported from the linux driver written by Donald Becker - by Rainer Bawidamann (Rainer.Bawidamann@informatik.uni-ulm.de) 1999 - - This software may be used and distributed according to the terms - of the GNU Public License, incorporated herein by reference. - - changes to the original driver: - - removed support for interrupts, switching to polling mode (yuck!) - - removed support for the 8129 chip (external MII) - -*/ - -/*********************************************************************/ -/* Revision History */ -/*********************************************************************/ - -/* - 28 Dec 2002 ken_yap@users.sourceforge.net (Ken Yap) - Put in virt_to_bus calls to allow Etherboot relocation. - - 06 Apr 2001 ken_yap@users.sourceforge.net (Ken Yap) - Following email from Hyun-Joon Cha, added a disable routine, otherwise - NIC remains live and can crash the kernel later. - - 4 Feb 2000 espenlaub@informatik.uni-ulm.de (Klaus Espenlaub) - Shuffled things around, removed the leftovers from the 8129 support - that was in the Linux driver and added a bit more 8139 definitions. - Moved the 8K receive buffer to a fixed, available address outside the - 0x98000-0x9ffff range. This is a bit of a hack, but currently the only - way to make room for the Etherboot features that need substantial amounts - of code like the ANSI console support. Currently the buffer is just below - 0x10000, so this even conforms to the tagged boot image specification, - which reserves the ranges 0x00000-0x10000 and 0x98000-0xA0000. My - interpretation of this "reserved" is that Etherboot may do whatever it - likes, as long as its environment is kept intact (like the BIOS - variables). Hopefully fixed rtl_poll() once and for all. The symptoms - were that if Etherboot was left at the boot menu for several minutes, the - first eth_poll failed. Seems like I am the only person who does this. - First of all I fixed the debugging code and then set out for a long bug - hunting session. It took me about a week full time work - poking around - various places in the driver, reading Don Becker's and Jeff Garzik's Linux - driver and even the FreeBSD driver (what a piece of crap!) - and - eventually spotted the nasty thing: the transmit routine was acknowledging - each and every interrupt pending, including the RxOverrun and RxFIFIOver - interrupts. This confused the RTL8139 thoroughly. It destroyed the - Rx ring contents by dumping the 2K FIFO contents right where we wanted to - get the next packet. Oh well, what fun. - - 18 Jan 2000 mdc@thinguin.org (Marty Connor) - Drastically simplified error handling. Basically, if any error - in transmission or reception occurs, the card is reset. - Also, pointed all transmit descriptors to the same buffer to - save buffer space. This should decrease driver size and avoid - corruption because of exceeding 32K during runtime. - - 28 Jul 1999 (Matthias Meixner - meixner@rbg.informatik.tu-darmstadt.de) - rtl_poll was quite broken: it used the RxOK interrupt flag instead - of the RxBufferEmpty flag which often resulted in very bad - transmission performace - below 1kBytes/s. - -*/ - -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <asm/io.h> -#include <pci.h> - -#define RTL_TIMEOUT 100000 - -#define ETH_FRAME_LEN 1514 -#define ETH_ALEN 6 -#define ETH_ZLEN 60 - -/* PCI Tuning Parameters - Threshold is bytes transferred to chip before transmission starts. */ -#define TX_FIFO_THRESH 256 /* In bytes, rounded down to 32 byte units. */ -#define RX_FIFO_THRESH 4 /* Rx buffer level before first PCI xfer. */ -#define RX_DMA_BURST 4 /* Maximum PCI burst, '4' is 256 bytes */ -#define TX_DMA_BURST 4 /* Calculate as 16<<val. */ -#define NUM_TX_DESC 4 /* Number of Tx descriptor registers. */ -#define TX_BUF_SIZE ETH_FRAME_LEN /* FCS is added by the chip */ -#define RX_BUF_LEN_IDX 0 /* 0, 1, 2 is allowed - 8,16,32K rx buffer */ -#define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX) - -#define DEBUG_TX 0 /* set to 1 to enable debug code */ -#define DEBUG_RX 0 /* set to 1 to enable debug code */ - -#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a) -#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) - -/* Symbolic offsets to registers. */ -enum RTL8139_registers { - MAC0=0, /* Ethernet hardware address. */ - MAR0=8, /* Multicast filter. */ - TxStatus0=0x10, /* Transmit status (four 32bit registers). */ - TxAddr0=0x20, /* Tx descriptors (also four 32bit). */ - RxBuf=0x30, RxEarlyCnt=0x34, RxEarlyStatus=0x36, - ChipCmd=0x37, RxBufPtr=0x38, RxBufAddr=0x3A, - IntrMask=0x3C, IntrStatus=0x3E, - TxConfig=0x40, RxConfig=0x44, - Timer=0x48, /* general-purpose counter. */ - RxMissed=0x4C, /* 24 bits valid, write clears. */ - Cfg9346=0x50, Config0=0x51, Config1=0x52, - TimerIntrReg=0x54, /* intr if gp counter reaches this value */ - MediaStatus=0x58, - Config3=0x59, - MultiIntr=0x5C, - RevisionID=0x5E, /* revision of the RTL8139 chip */ - TxSummary=0x60, - MII_BMCR=0x62, MII_BMSR=0x64, NWayAdvert=0x66, NWayLPAR=0x68, - NWayExpansion=0x6A, - DisconnectCnt=0x6C, FalseCarrierCnt=0x6E, - NWayTestReg=0x70, - RxCnt=0x72, /* packet received counter */ - CSCR=0x74, /* chip status and configuration register */ - PhyParm1=0x78,TwisterParm=0x7c,PhyParm2=0x80, /* undocumented */ - /* from 0x84 onwards are a number of power management/wakeup frame - * definitions we will probably never need to know about. */ -}; - -enum ChipCmdBits { - CmdReset=0x10, CmdRxEnb=0x08, CmdTxEnb=0x04, RxBufEmpty=0x01, }; - -/* Interrupt register bits, using my own meaningful names. */ -enum IntrStatusBits { - PCIErr=0x8000, PCSTimeout=0x4000, CableLenChange= 0x2000, - RxFIFOOver=0x40, RxUnderrun=0x20, RxOverflow=0x10, - TxErr=0x08, TxOK=0x04, RxErr=0x02, RxOK=0x01, -}; -enum TxStatusBits { - TxHostOwns=0x2000, TxUnderrun=0x4000, TxStatOK=0x8000, - TxOutOfWindow=0x20000000, TxAborted=0x40000000, - TxCarrierLost=0x80000000, -}; -enum RxStatusBits { - RxMulticast=0x8000, RxPhysical=0x4000, RxBroadcast=0x2000, - RxBadSymbol=0x0020, RxRunt=0x0010, RxTooLong=0x0008, RxCRCErr=0x0004, - RxBadAlign=0x0002, RxStatusOK=0x0001, -}; - -enum MediaStatusBits { - MSRTxFlowEnable=0x80, MSRRxFlowEnable=0x40, MSRSpeed10=0x08, - MSRLinkFail=0x04, MSRRxPauseFlag=0x02, MSRTxPauseFlag=0x01, -}; - -enum MIIBMCRBits { - BMCRReset=0x8000, BMCRSpeed100=0x2000, BMCRNWayEnable=0x1000, - BMCRRestartNWay=0x0200, BMCRDuplex=0x0100, -}; - -enum CSCRBits { - CSCR_LinkOKBit=0x0400, CSCR_LinkChangeBit=0x0800, - CSCR_LinkStatusBits=0x0f000, CSCR_LinkDownOffCmd=0x003c0, - CSCR_LinkDownCmd=0x0f3c0, -}; - -/* Bits in RxConfig. */ -enum rx_mode_bits { - RxCfgWrap=0x80, - AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0x08, - AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01, -}; - -static int ioaddr; -static unsigned int cur_rx,cur_tx; - -/* The RTL8139 can only transmit from a contiguous, aligned memory block. */ -static unsigned char tx_buffer[TX_BUF_SIZE] __attribute__((aligned(4))); -static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4))); - -static int rtl8139_probe(struct eth_device *dev, bd_t *bis); -static int read_eeprom(int location, int addr_len); -static void rtl_reset(struct eth_device *dev); -static int rtl_transmit(struct eth_device *dev, void *packet, int length); -static int rtl_poll(struct eth_device *dev); -static void rtl_disable(struct eth_device *dev); -#ifdef CONFIG_MCAST_TFTP/* This driver already accepts all b/mcast */ -static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, u8 set) -{ - return (0); -} -#endif - -static struct pci_device_id supported[] = { - {PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139}, - {PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_8139}, - {} -}; - -int rtl8139_initialize(bd_t *bis) -{ - pci_dev_t devno; - int card_number = 0; - struct eth_device *dev; - u32 iobase; - int idx=0; - - while(1){ - /* Find RTL8139 */ - if ((devno = pci_find_devices(supported, idx++)) < 0) - break; - - pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase); - iobase &= ~0xf; - - debug ("rtl8139: REALTEK RTL8139 @0x%x\n", iobase); - - dev = (struct eth_device *)malloc(sizeof *dev); - if (!dev) { - printf("Can not allocate memory of rtl8139\n"); - break; - } - memset(dev, 0, sizeof(*dev)); - - sprintf (dev->name, "RTL8139#%d", card_number); - - dev->priv = (void *) devno; - dev->iobase = (int)bus_to_phys(iobase); - dev->init = rtl8139_probe; - dev->halt = rtl_disable; - dev->send = rtl_transmit; - dev->recv = rtl_poll; -#ifdef CONFIG_MCAST_TFTP - dev->mcast = rtl_bcast_addr; -#endif - - eth_register (dev); - - card_number++; - - pci_write_config_byte (devno, PCI_LATENCY_TIMER, 0x20); - - udelay (10 * 1000); - } - - return card_number; -} - -static int rtl8139_probe(struct eth_device *dev, bd_t *bis) -{ - int i; - int addr_len; - unsigned short *ap = (unsigned short *)dev->enetaddr; - - ioaddr = dev->iobase; - - /* Bring the chip out of low-power mode. */ - outb(0x00, ioaddr + Config1); - - addr_len = read_eeprom(0,8) == 0x8129 ? 8 : 6; - for (i = 0; i < 3; i++) - *ap++ = le16_to_cpu (read_eeprom(i + 7, addr_len)); - - rtl_reset(dev); - - if (inb(ioaddr + MediaStatus) & MSRLinkFail) { - printf("Cable not connected or other link failure\n"); - return -1 ; - } - - return 0; -} - -/* Serial EEPROM section. */ - -/* EEPROM_Ctrl bits. */ -#define EE_SHIFT_CLK 0x04 /* EEPROM shift clock. */ -#define EE_CS 0x08 /* EEPROM chip select. */ -#define EE_DATA_WRITE 0x02 /* EEPROM chip data in. */ -#define EE_WRITE_0 0x00 -#define EE_WRITE_1 0x02 -#define EE_DATA_READ 0x01 /* EEPROM chip data out. */ -#define EE_ENB (0x80 | EE_CS) - -/* - Delay between EEPROM clock transitions. - No extra delay is needed with 33MHz PCI, but 66MHz may change this. -*/ - -#define eeprom_delay() inl(ee_addr) - -/* The EEPROM commands include the alway-set leading bit. */ -#define EE_WRITE_CMD (5) -#define EE_READ_CMD (6) -#define EE_ERASE_CMD (7) - -static int read_eeprom(int location, int addr_len) -{ - int i; - unsigned int retval = 0; - long ee_addr = ioaddr + Cfg9346; - int read_cmd = location | (EE_READ_CMD << addr_len); - - outb(EE_ENB & ~EE_CS, ee_addr); - outb(EE_ENB, ee_addr); - eeprom_delay(); - - /* Shift the read command bits out. */ - for (i = 4 + addr_len; i >= 0; i--) { - int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - outb(EE_ENB | dataval, ee_addr); - eeprom_delay(); - outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); - eeprom_delay(); - } - outb(EE_ENB, ee_addr); - eeprom_delay(); - - for (i = 16; i > 0; i--) { - outb(EE_ENB | EE_SHIFT_CLK, ee_addr); - eeprom_delay(); - retval = (retval << 1) | ((inb(ee_addr) & EE_DATA_READ) ? 1 : 0); - outb(EE_ENB, ee_addr); - eeprom_delay(); - } - - /* Terminate the EEPROM access. */ - outb(~EE_CS, ee_addr); - eeprom_delay(); - return retval; -} - -static const unsigned int rtl8139_rx_config = - (RX_BUF_LEN_IDX << 11) | - (RX_FIFO_THRESH << 13) | - (RX_DMA_BURST << 8); - -static void set_rx_mode(struct eth_device *dev) { - unsigned int mc_filter[2]; - int rx_mode; - /* !IFF_PROMISC */ - rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; - mc_filter[1] = mc_filter[0] = 0xffffffff; - - outl(rtl8139_rx_config | rx_mode, ioaddr + RxConfig); - - outl(mc_filter[0], ioaddr + MAR0 + 0); - outl(mc_filter[1], ioaddr + MAR0 + 4); -} - -static void rtl_reset(struct eth_device *dev) -{ - int i; - - outb(CmdReset, ioaddr + ChipCmd); - - cur_rx = 0; - cur_tx = 0; - - /* Give the chip 10ms to finish the reset. */ - for (i=0; i<100; ++i){ - if ((inb(ioaddr + ChipCmd) & CmdReset) == 0) break; - udelay (100); /* wait 100us */ - } - - - for (i = 0; i < ETH_ALEN; i++) - outb(dev->enetaddr[i], ioaddr + MAC0 + i); - - /* Must enable Tx/Rx before setting transfer thresholds! */ - outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd); - outl((RX_FIFO_THRESH<<13) | (RX_BUF_LEN_IDX<<11) | (RX_DMA_BURST<<8), - ioaddr + RxConfig); /* accept no frames yet! */ - outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + TxConfig); - - /* The Linux driver changes Config1 here to use a different LED pattern - * for half duplex or full/autodetect duplex (for full/autodetect, the - * outputs are TX/RX, Link10/100, FULL, while for half duplex it uses - * TX/RX, Link100, Link10). This is messy, because it doesn't match - * the inscription on the mounting bracket. It should not be changed - * from the configuration EEPROM default, because the card manufacturer - * should have set that to match the card. */ - - debug_cond(DEBUG_RX, - "rx ring address is %lX\n",(unsigned long)rx_ring); - flush_cache((unsigned long)rx_ring, RX_BUF_LEN); - outl(phys_to_bus((int)rx_ring), ioaddr + RxBuf); - - /* If we add multicast support, the MAR0 register would have to be - * initialized to 0xffffffffffffffff (two 32 bit accesses). Etherboot - * only needs broadcast (for ARP/RARP/BOOTP/DHCP) and unicast. */ - - outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd); - - outl(rtl8139_rx_config, ioaddr + RxConfig); - - /* Start the chip's Tx and Rx process. */ - outl(0, ioaddr + RxMissed); - - /* set_rx_mode */ - set_rx_mode(dev); - - /* Disable all known interrupts by setting the interrupt mask. */ - outw(0, ioaddr + IntrMask); -} - -static int rtl_transmit(struct eth_device *dev, void *packet, int length) -{ - unsigned int status; - unsigned long txstatus; - unsigned int len = length; - int i = 0; - - ioaddr = dev->iobase; - - memcpy((char *)tx_buffer, (char *)packet, (int)length); - - debug_cond(DEBUG_TX, "sending %d bytes\n", len); - - /* Note: RTL8139 doesn't auto-pad, send minimum payload (another 4 - * bytes are sent automatically for the FCS, totalling to 64 bytes). */ - while (len < ETH_ZLEN) { - tx_buffer[len++] = '\0'; - } - - flush_cache((unsigned long)tx_buffer, length); - outl(phys_to_bus((int)tx_buffer), ioaddr + TxAddr0 + cur_tx*4); - outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len, - ioaddr + TxStatus0 + cur_tx*4); - - do { - status = inw(ioaddr + IntrStatus); - /* Only acknlowledge interrupt sources we can properly handle - * here - the RxOverflow/RxFIFOOver MUST be handled in the - * rtl_poll() function. */ - outw(status & (TxOK | TxErr | PCIErr), ioaddr + IntrStatus); - if ((status & (TxOK | TxErr | PCIErr)) != 0) break; - udelay(10); - } while (i++ < RTL_TIMEOUT); - - txstatus = inl(ioaddr + TxStatus0 + cur_tx*4); - - if (status & TxOK) { - cur_tx = (cur_tx + 1) % NUM_TX_DESC; - - debug_cond(DEBUG_TX, - "tx done, status %hX txstatus %lX\n", - status, txstatus); - - return length; - } else { - - debug_cond(DEBUG_TX, - "tx timeout/error (%d usecs), status %hX txstatus %lX\n", - 10*i, status, txstatus); - - rtl_reset(dev); - - return 0; - } -} - -static int rtl_poll(struct eth_device *dev) -{ - unsigned int status; - unsigned int ring_offs; - unsigned int rx_size, rx_status; - int length=0; - - ioaddr = dev->iobase; - - if (inb(ioaddr + ChipCmd) & RxBufEmpty) { - return 0; - } - - status = inw(ioaddr + IntrStatus); - /* See below for the rest of the interrupt acknowledges. */ - outw(status & ~(RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus); - - debug_cond(DEBUG_RX, "rtl_poll: int %hX ", status); - - ring_offs = cur_rx % RX_BUF_LEN; - /* ring_offs is guaranteed being 4-byte aligned */ - rx_status = le32_to_cpu(*(unsigned int *)(rx_ring + ring_offs)); - rx_size = rx_status >> 16; - rx_status &= 0xffff; - - if ((rx_status & (RxBadSymbol|RxRunt|RxTooLong|RxCRCErr|RxBadAlign)) || - (rx_size < ETH_ZLEN) || (rx_size > ETH_FRAME_LEN + 4)) { - printf("rx error %hX\n", rx_status); - rtl_reset(dev); /* this clears all interrupts still pending */ - return 0; - } - - /* Received a good packet */ - length = rx_size - 4; /* no one cares about the FCS */ - if (ring_offs+4+rx_size-4 > RX_BUF_LEN) { - int semi_count = RX_BUF_LEN - ring_offs - 4; - unsigned char rxdata[RX_BUF_LEN]; - - memcpy(rxdata, rx_ring + ring_offs + 4, semi_count); - memcpy(&(rxdata[semi_count]), rx_ring, rx_size-4-semi_count); - - NetReceive(rxdata, length); - debug_cond(DEBUG_RX, "rx packet %d+%d bytes", - semi_count, rx_size-4-semi_count); - } else { - NetReceive(rx_ring + ring_offs + 4, length); - debug_cond(DEBUG_RX, "rx packet %d bytes", rx_size-4); - } - flush_cache((unsigned long)rx_ring, RX_BUF_LEN); - - cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; - outw(cur_rx - 16, ioaddr + RxBufPtr); - /* See RTL8139 Programming Guide V0.1 for the official handling of - * Rx overflow situations. The document itself contains basically no - * usable information, except for a few exception handling rules. */ - outw(status & (RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus); - return length; -} - -static void rtl_disable(struct eth_device *dev) -{ - int i; - - ioaddr = dev->iobase; - - /* reset the chip */ - outb(CmdReset, ioaddr + ChipCmd); - - /* Give the chip 10ms to finish the reset. */ - for (i=0; i<100; ++i){ - if ((inb(ioaddr + ChipCmd) & CmdReset) == 0) break; - udelay (100); /* wait 100us */ - } -} diff --git a/qemu/roms/u-boot/drivers/net/rtl8169.c b/qemu/roms/u-boot/drivers/net/rtl8169.c deleted file mode 100644 index d040ab171..000000000 --- a/qemu/roms/u-boot/drivers/net/rtl8169.c +++ /dev/null @@ -1,967 +0,0 @@ -/* - * rtl8169.c : U-Boot driver for the RealTek RTL8169 - * - * Masami Komiya (mkomiya@sonare.it) - * - * Most part is taken from r8169.c of etherboot - * - */ - -/************************************************************************** -* r8169.c: Etherboot device driver for the RealTek RTL-8169 Gigabit -* Written 2003 by Timothy Legge <tlegge@rogers.com> -* - * SPDX-License-Identifier: GPL-2.0+ -* -* Portions of this code based on: -* r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver -* for Linux kernel 2.4.x. -* -* Written 2002 ShuChen <shuchen@realtek.com.tw> -* See Linux Driver for full information -* -* Linux Driver Version 1.27a, 10.02.2002 -* -* Thanks to: -* Jean Chen of RealTek Semiconductor Corp. for -* providing the evaluation NIC used to develop -* this driver. RealTek's support for Etherboot -* is appreciated. -* -* REVISION HISTORY: -* ================ -* -* v1.0 11-26-2003 timlegge Initial port of Linux driver -* v1.5 01-17-2004 timlegge Initial driver output cleanup -* -* Indent Options: indent -kr -i8 -***************************************************************************/ -/* - * 26 August 2006 Mihai Georgian <u-boot@linuxnotincluded.org.uk> - * Modified to use le32_to_cpu and cpu_to_le32 properly - */ -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <asm/io.h> -#include <pci.h> - -#undef DEBUG_RTL8169 -#undef DEBUG_RTL8169_TX -#undef DEBUG_RTL8169_RX - -#define drv_version "v1.5" -#define drv_date "01-17-2004" - -static u32 ioaddr; - -/* Condensed operations for readability. */ -#define currticks() get_timer(0) - -/* media options */ -#define MAX_UNITS 8 -static int media[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; - -/* MAC address length*/ -#define MAC_ADDR_LEN 6 - -/* max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4).*/ -#define MAX_ETH_FRAME_SIZE 1536 - -#define TX_FIFO_THRESH 256 /* In bytes */ - -#define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ -#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ -#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ -#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ -#define RxPacketMaxSize 0x0800 /* Maximum size supported is 16K-1 */ -#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ - -#define NUM_TX_DESC 1 /* Number of Tx descriptor registers */ -#define NUM_RX_DESC 4 /* Number of Rx descriptor registers */ -#define RX_BUF_SIZE 1536 /* Rx Buffer size */ -#define RX_BUF_LEN 8192 - -#define RTL_MIN_IO_SIZE 0x80 -#define TX_TIMEOUT (6*HZ) - -/* write/read MMIO register. Notice: {read,write}[wl] do the necessary swapping */ -#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) -#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) -#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) -#define RTL_R8(reg) readb (ioaddr + (reg)) -#define RTL_R16(reg) readw (ioaddr + (reg)) -#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) - -#define ETH_FRAME_LEN MAX_ETH_FRAME_SIZE -#define ETH_ALEN MAC_ADDR_LEN -#define ETH_ZLEN 60 - -#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, (pci_addr_t)a) -#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, (phys_addr_t)a) - -enum RTL8169_registers { - MAC0 = 0, /* Ethernet hardware address. */ - MAR0 = 8, /* Multicast filter. */ - TxDescStartAddrLow = 0x20, - TxDescStartAddrHigh = 0x24, - TxHDescStartAddrLow = 0x28, - TxHDescStartAddrHigh = 0x2c, - FLASH = 0x30, - ERSR = 0x36, - ChipCmd = 0x37, - TxPoll = 0x38, - IntrMask = 0x3C, - IntrStatus = 0x3E, - TxConfig = 0x40, - RxConfig = 0x44, - RxMissed = 0x4C, - Cfg9346 = 0x50, - Config0 = 0x51, - Config1 = 0x52, - Config2 = 0x53, - Config3 = 0x54, - Config4 = 0x55, - Config5 = 0x56, - MultiIntr = 0x5C, - PHYAR = 0x60, - TBICSR = 0x64, - TBI_ANAR = 0x68, - TBI_LPAR = 0x6A, - PHYstatus = 0x6C, - RxMaxSize = 0xDA, - CPlusCmd = 0xE0, - RxDescStartAddrLow = 0xE4, - RxDescStartAddrHigh = 0xE8, - EarlyTxThres = 0xEC, - FuncEvent = 0xF0, - FuncEventMask = 0xF4, - FuncPresetState = 0xF8, - FuncForceEvent = 0xFC, -}; - -enum RTL8169_register_content { - /*InterruptStatusBits */ - SYSErr = 0x8000, - PCSTimeout = 0x4000, - SWInt = 0x0100, - TxDescUnavail = 0x80, - RxFIFOOver = 0x40, - RxUnderrun = 0x20, - RxOverflow = 0x10, - TxErr = 0x08, - TxOK = 0x04, - RxErr = 0x02, - RxOK = 0x01, - - /*RxStatusDesc */ - RxRES = 0x00200000, - RxCRC = 0x00080000, - RxRUNT = 0x00100000, - RxRWT = 0x00400000, - - /*ChipCmdBits */ - CmdReset = 0x10, - CmdRxEnb = 0x08, - CmdTxEnb = 0x04, - RxBufEmpty = 0x01, - - /*Cfg9346Bits */ - Cfg9346_Lock = 0x00, - Cfg9346_Unlock = 0xC0, - - /*rx_mode_bits */ - AcceptErr = 0x20, - AcceptRunt = 0x10, - AcceptBroadcast = 0x08, - AcceptMulticast = 0x04, - AcceptMyPhys = 0x02, - AcceptAllPhys = 0x01, - - /*RxConfigBits */ - RxCfgFIFOShift = 13, - RxCfgDMAShift = 8, - - /*TxConfigBits */ - TxInterFrameGapShift = 24, - TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ - - /*rtl8169_PHYstatus */ - TBI_Enable = 0x80, - TxFlowCtrl = 0x40, - RxFlowCtrl = 0x20, - _1000bpsF = 0x10, - _100bps = 0x08, - _10bps = 0x04, - LinkStatus = 0x02, - FullDup = 0x01, - - /*GIGABIT_PHY_registers */ - PHY_CTRL_REG = 0, - PHY_STAT_REG = 1, - PHY_AUTO_NEGO_REG = 4, - PHY_1000_CTRL_REG = 9, - - /*GIGABIT_PHY_REG_BIT */ - PHY_Restart_Auto_Nego = 0x0200, - PHY_Enable_Auto_Nego = 0x1000, - - /* PHY_STAT_REG = 1; */ - PHY_Auto_Nego_Comp = 0x0020, - - /* PHY_AUTO_NEGO_REG = 4; */ - PHY_Cap_10_Half = 0x0020, - PHY_Cap_10_Full = 0x0040, - PHY_Cap_100_Half = 0x0080, - PHY_Cap_100_Full = 0x0100, - - /* PHY_1000_CTRL_REG = 9; */ - PHY_Cap_1000_Full = 0x0200, - - PHY_Cap_Null = 0x0, - - /*_MediaType*/ - _10_Half = 0x01, - _10_Full = 0x02, - _100_Half = 0x04, - _100_Full = 0x08, - _1000_Full = 0x10, - - /*_TBICSRBit*/ - TBILinkOK = 0x02000000, -}; - -static struct { - const char *name; - u8 version; /* depend on RTL8169 docs */ - u32 RxConfigMask; /* should clear the bits supported by this chip */ -} rtl_chip_info[] = { - {"RTL-8169", 0x00, 0xff7e1880,}, - {"RTL-8169", 0x04, 0xff7e1880,}, - {"RTL-8169", 0x00, 0xff7e1880,}, - {"RTL-8169s/8110s", 0x02, 0xff7e1880,}, - {"RTL-8169s/8110s", 0x04, 0xff7e1880,}, - {"RTL-8169sb/8110sb", 0x10, 0xff7e1880,}, - {"RTL-8169sc/8110sc", 0x18, 0xff7e1880,}, - {"RTL-8168b/8111sb", 0x30, 0xff7e1880,}, - {"RTL-8168b/8111sb", 0x38, 0xff7e1880,}, - {"RTL-8168d/8111d", 0x28, 0xff7e1880,}, - {"RTL-8168evl/8111evl", 0x2e, 0xff7e1880,}, - {"RTL-8101e", 0x34, 0xff7e1880,}, - {"RTL-8100e", 0x32, 0xff7e1880,}, -}; - -enum _DescStatusBit { - OWNbit = 0x80000000, - EORbit = 0x40000000, - FSbit = 0x20000000, - LSbit = 0x10000000, -}; - -struct TxDesc { - u32 status; - u32 vlan_tag; - u32 buf_addr; - u32 buf_Haddr; -}; - -struct RxDesc { - u32 status; - u32 vlan_tag; - u32 buf_addr; - u32 buf_Haddr; -}; - -/* Define the TX Descriptor */ -static u8 tx_ring[NUM_TX_DESC * sizeof(struct TxDesc) + 256]; -/* __attribute__ ((aligned(256))); */ - -/* Create a static buffer of size RX_BUF_SZ for each -TX Descriptor. All descriptors point to a -part of this buffer */ -static unsigned char txb[NUM_TX_DESC * RX_BUF_SIZE]; - -/* Define the RX Descriptor */ -static u8 rx_ring[NUM_RX_DESC * sizeof(struct TxDesc) + 256]; - /* __attribute__ ((aligned(256))); */ - -/* Create a static buffer of size RX_BUF_SZ for each -RX Descriptor All descriptors point to a -part of this buffer */ -static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE]; - -struct rtl8169_private { - void *mmio_addr; /* memory map physical address */ - int chipset; - unsigned long cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ - unsigned long cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ - unsigned long dirty_tx; - unsigned char *TxDescArrays; /* Index of Tx Descriptor buffer */ - unsigned char *RxDescArrays; /* Index of Rx Descriptor buffer */ - struct TxDesc *TxDescArray; /* Index of 256-alignment Tx Descriptor buffer */ - struct RxDesc *RxDescArray; /* Index of 256-alignment Rx Descriptor buffer */ - unsigned char *RxBufferRings; /* Index of Rx Buffer */ - unsigned char *RxBufferRing[NUM_RX_DESC]; /* Index of Rx Buffer array */ - unsigned char *Tx_skbuff[NUM_TX_DESC]; -} tpx; - -static struct rtl8169_private *tpc; - -static const u16 rtl8169_intr_mask = - SYSErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr | - TxOK | RxErr | RxOK; -static const unsigned int rtl8169_rx_config = - (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); - -static struct pci_device_id supported[] = { - {PCI_VENDOR_ID_REALTEK, 0x8167}, - {PCI_VENDOR_ID_REALTEK, 0x8168}, - {PCI_VENDOR_ID_REALTEK, 0x8169}, - {} -}; - -void mdio_write(int RegAddr, int value) -{ - int i; - - RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value); - udelay(1000); - - for (i = 2000; i > 0; i--) { - /* Check if the RTL8169 has completed writing to the specified MII register */ - if (!(RTL_R32(PHYAR) & 0x80000000)) { - break; - } else { - udelay(100); - } - } -} - -int mdio_read(int RegAddr) -{ - int i, value = -1; - - RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16); - udelay(1000); - - for (i = 2000; i > 0; i--) { - /* Check if the RTL8169 has completed retrieving data from the specified MII register */ - if (RTL_R32(PHYAR) & 0x80000000) { - value = (int) (RTL_R32(PHYAR) & 0xFFFF); - break; - } else { - udelay(100); - } - } - return value; -} - -static int rtl8169_init_board(struct eth_device *dev) -{ - int i; - u32 tmp; - -#ifdef DEBUG_RTL8169 - printf ("%s\n", __FUNCTION__); -#endif - ioaddr = dev->iobase; - - /* Soft reset the chip. */ - RTL_W8(ChipCmd, CmdReset); - - /* Check that the chip has finished the reset. */ - for (i = 1000; i > 0; i--) - if ((RTL_R8(ChipCmd) & CmdReset) == 0) - break; - else - udelay(10); - - /* identify chip attached to board */ - tmp = RTL_R32(TxConfig); - tmp = ((tmp & 0x7c000000) + ((tmp & 0x00800000) << 2)) >> 24; - - for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--){ - if (tmp == rtl_chip_info[i].version) { - tpc->chipset = i; - goto match; - } - } - - /* if unknown chip, assume array element #0, original RTL-8169 in this case */ - printf("PCI device %s: unknown chip version, assuming RTL-8169\n", dev->name); - printf("PCI device: TxConfig = 0x%lX\n", (unsigned long) RTL_R32(TxConfig)); - tpc->chipset = 0; - -match: - return 0; -} - -/* - * Cache maintenance functions. These are simple wrappers around the more - * general purpose flush_cache() and invalidate_dcache_range() functions. - */ - -static void rtl_inval_rx_desc(struct RxDesc *desc) -{ - unsigned long start = (unsigned long)desc & ~(ARCH_DMA_MINALIGN - 1); - unsigned long end = ALIGN(start + sizeof(*desc), ARCH_DMA_MINALIGN); - - invalidate_dcache_range(start, end); -} - -static void rtl_flush_rx_desc(struct RxDesc *desc) -{ - flush_cache((unsigned long)desc, sizeof(*desc)); -} - -static void rtl_inval_tx_desc(struct TxDesc *desc) -{ - unsigned long start = (unsigned long)desc & ~(ARCH_DMA_MINALIGN - 1); - unsigned long end = ALIGN(start + sizeof(*desc), ARCH_DMA_MINALIGN); - - invalidate_dcache_range(start, end); -} - -static void rtl_flush_tx_desc(struct TxDesc *desc) -{ - flush_cache((unsigned long)desc, sizeof(*desc)); -} - -static void rtl_inval_buffer(void *buf, size_t size) -{ - unsigned long start = (unsigned long)buf & ~(ARCH_DMA_MINALIGN - 1); - unsigned long end = ALIGN(start + size, ARCH_DMA_MINALIGN); - - invalidate_dcache_range(start, end); -} - -static void rtl_flush_buffer(void *buf, size_t size) -{ - flush_cache((unsigned long)buf, size); -} - -/************************************************************************** -RECV - Receive a frame -***************************************************************************/ -static int rtl_recv(struct eth_device *dev) -{ - /* return true if there's an ethernet packet ready to read */ - /* nic->packet should contain data on return */ - /* nic->packetlen should contain length of data */ - int cur_rx; - int length = 0; - -#ifdef DEBUG_RTL8169_RX - printf ("%s\n", __FUNCTION__); -#endif - ioaddr = dev->iobase; - - cur_rx = tpc->cur_rx; - - rtl_inval_rx_desc(&tpc->RxDescArray[cur_rx]); - - if ((le32_to_cpu(tpc->RxDescArray[cur_rx].status) & OWNbit) == 0) { - if (!(le32_to_cpu(tpc->RxDescArray[cur_rx].status) & RxRES)) { - unsigned char rxdata[RX_BUF_LEN]; - length = (int) (le32_to_cpu(tpc->RxDescArray[cur_rx]. - status) & 0x00001FFF) - 4; - - rtl_inval_buffer(tpc->RxBufferRing[cur_rx], length); - memcpy(rxdata, tpc->RxBufferRing[cur_rx], length); - NetReceive(rxdata, length); - - if (cur_rx == NUM_RX_DESC - 1) - tpc->RxDescArray[cur_rx].status = - cpu_to_le32((OWNbit | EORbit) + RX_BUF_SIZE); - else - tpc->RxDescArray[cur_rx].status = - cpu_to_le32(OWNbit + RX_BUF_SIZE); - tpc->RxDescArray[cur_rx].buf_addr = - cpu_to_le32(bus_to_phys(tpc->RxBufferRing[cur_rx])); - rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]); - } else { - puts("Error Rx"); - } - cur_rx = (cur_rx + 1) % NUM_RX_DESC; - tpc->cur_rx = cur_rx; - return 1; - - } else { - ushort sts = RTL_R8(IntrStatus); - RTL_W8(IntrStatus, sts & ~(TxErr | RxErr | SYSErr)); - udelay(100); /* wait */ - } - tpc->cur_rx = cur_rx; - return (0); /* initially as this is called to flush the input */ -} - -#define HZ 1000 -/************************************************************************** -SEND - Transmit a frame -***************************************************************************/ -static int rtl_send(struct eth_device *dev, void *packet, int length) -{ - /* send the packet to destination */ - - u32 to; - u8 *ptxb; - int entry = tpc->cur_tx % NUM_TX_DESC; - u32 len = length; - int ret; - -#ifdef DEBUG_RTL8169_TX - int stime = currticks(); - printf ("%s\n", __FUNCTION__); - printf("sending %d bytes\n", len); -#endif - - ioaddr = dev->iobase; - - /* point to the current txb incase multiple tx_rings are used */ - ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE]; - memcpy(ptxb, (char *)packet, (int)length); - rtl_flush_buffer(ptxb, length); - - while (len < ETH_ZLEN) - ptxb[len++] = '\0'; - - tpc->TxDescArray[entry].buf_Haddr = 0; - tpc->TxDescArray[entry].buf_addr = cpu_to_le32(bus_to_phys(ptxb)); - if (entry != (NUM_TX_DESC - 1)) { - tpc->TxDescArray[entry].status = - cpu_to_le32((OWNbit | FSbit | LSbit) | - ((len > ETH_ZLEN) ? len : ETH_ZLEN)); - } else { - tpc->TxDescArray[entry].status = - cpu_to_le32((OWNbit | EORbit | FSbit | LSbit) | - ((len > ETH_ZLEN) ? len : ETH_ZLEN)); - } - rtl_flush_tx_desc(&tpc->TxDescArray[entry]); - RTL_W8(TxPoll, 0x40); /* set polling bit */ - - tpc->cur_tx++; - to = currticks() + TX_TIMEOUT; - do { - rtl_inval_tx_desc(&tpc->TxDescArray[entry]); - } while ((le32_to_cpu(tpc->TxDescArray[entry].status) & OWNbit) - && (currticks() < to)); /* wait */ - - if (currticks() >= to) { -#ifdef DEBUG_RTL8169_TX - puts("tx timeout/error\n"); - printf("%s elapsed time : %lu\n", __func__, currticks()-stime); -#endif - ret = 0; - } else { -#ifdef DEBUG_RTL8169_TX - puts("tx done\n"); -#endif - ret = length; - } - /* Delay to make net console (nc) work properly */ - udelay(20); - return ret; -} - -static void rtl8169_set_rx_mode(struct eth_device *dev) -{ - u32 mc_filter[2]; /* Multicast hash filter */ - int rx_mode; - u32 tmp = 0; - -#ifdef DEBUG_RTL8169 - printf ("%s\n", __FUNCTION__); -#endif - - /* IFF_ALLMULTI */ - /* Too many to filter perfectly -- accept all multicasts. */ - rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; - mc_filter[1] = mc_filter[0] = 0xffffffff; - - tmp = rtl8169_rx_config | rx_mode | (RTL_R32(RxConfig) & - rtl_chip_info[tpc->chipset].RxConfigMask); - - RTL_W32(RxConfig, tmp); - RTL_W32(MAR0 + 0, mc_filter[0]); - RTL_W32(MAR0 + 4, mc_filter[1]); -} - -static void rtl8169_hw_start(struct eth_device *dev) -{ - u32 i; - -#ifdef DEBUG_RTL8169 - int stime = currticks(); - printf ("%s\n", __FUNCTION__); -#endif - -#if 0 - /* Soft reset the chip. */ - RTL_W8(ChipCmd, CmdReset); - - /* Check that the chip has finished the reset. */ - for (i = 1000; i > 0; i--) { - if ((RTL_R8(ChipCmd) & CmdReset) == 0) - break; - else - udelay(10); - } -#endif - - RTL_W8(Cfg9346, Cfg9346_Unlock); - - /* RTL-8169sb/8110sb or previous version */ - if (tpc->chipset <= 5) - RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); - - RTL_W8(EarlyTxThres, EarlyTxThld); - - /* For gigabit rtl8169 */ - RTL_W16(RxMaxSize, RxPacketMaxSize); - - /* Set Rx Config register */ - i = rtl8169_rx_config | (RTL_R32(RxConfig) & - rtl_chip_info[tpc->chipset].RxConfigMask); - RTL_W32(RxConfig, i); - - /* Set DMA burst size and Interframe Gap Time */ - RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) | - (InterFrameGap << TxInterFrameGapShift)); - - - tpc->cur_rx = 0; - - RTL_W32(TxDescStartAddrLow, bus_to_phys(tpc->TxDescArray)); - RTL_W32(TxDescStartAddrHigh, (unsigned long)0); - RTL_W32(RxDescStartAddrLow, bus_to_phys(tpc->RxDescArray)); - RTL_W32(RxDescStartAddrHigh, (unsigned long)0); - - /* RTL-8169sc/8110sc or later version */ - if (tpc->chipset > 5) - RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); - - RTL_W8(Cfg9346, Cfg9346_Lock); - udelay(10); - - RTL_W32(RxMissed, 0); - - rtl8169_set_rx_mode(dev); - - /* no early-rx interrupts */ - RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); - -#ifdef DEBUG_RTL8169 - printf("%s elapsed time : %lu\n", __func__, currticks()-stime); -#endif -} - -static void rtl8169_init_ring(struct eth_device *dev) -{ - int i; - -#ifdef DEBUG_RTL8169 - int stime = currticks(); - printf ("%s\n", __FUNCTION__); -#endif - - tpc->cur_rx = 0; - tpc->cur_tx = 0; - tpc->dirty_tx = 0; - memset(tpc->TxDescArray, 0x0, NUM_TX_DESC * sizeof(struct TxDesc)); - memset(tpc->RxDescArray, 0x0, NUM_RX_DESC * sizeof(struct RxDesc)); - - for (i = 0; i < NUM_TX_DESC; i++) { - tpc->Tx_skbuff[i] = &txb[i]; - } - - for (i = 0; i < NUM_RX_DESC; i++) { - if (i == (NUM_RX_DESC - 1)) - tpc->RxDescArray[i].status = - cpu_to_le32((OWNbit | EORbit) + RX_BUF_SIZE); - else - tpc->RxDescArray[i].status = - cpu_to_le32(OWNbit + RX_BUF_SIZE); - - tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE]; - tpc->RxDescArray[i].buf_addr = - cpu_to_le32(bus_to_phys(tpc->RxBufferRing[i])); - rtl_flush_rx_desc(&tpc->RxDescArray[i]); - } - -#ifdef DEBUG_RTL8169 - printf("%s elapsed time : %lu\n", __func__, currticks()-stime); -#endif -} - -/************************************************************************** -RESET - Finish setting up the ethernet interface -***************************************************************************/ -static int rtl_reset(struct eth_device *dev, bd_t *bis) -{ - int i; - -#ifdef DEBUG_RTL8169 - int stime = currticks(); - printf ("%s\n", __FUNCTION__); -#endif - - tpc->TxDescArrays = tx_ring; - /* Tx Desscriptor needs 256 bytes alignment; */ - tpc->TxDescArray = (struct TxDesc *) ((unsigned long)(tpc->TxDescArrays + - 255) & ~255); - - tpc->RxDescArrays = rx_ring; - /* Rx Desscriptor needs 256 bytes alignment; */ - tpc->RxDescArray = (struct RxDesc *) ((unsigned long)(tpc->RxDescArrays + - 255) & ~255); - - rtl8169_init_ring(dev); - rtl8169_hw_start(dev); - /* Construct a perfect filter frame with the mac address as first match - * and broadcast for all others */ - for (i = 0; i < 192; i++) - txb[i] = 0xFF; - - txb[0] = dev->enetaddr[0]; - txb[1] = dev->enetaddr[1]; - txb[2] = dev->enetaddr[2]; - txb[3] = dev->enetaddr[3]; - txb[4] = dev->enetaddr[4]; - txb[5] = dev->enetaddr[5]; - -#ifdef DEBUG_RTL8169 - printf("%s elapsed time : %lu\n", __func__, currticks()-stime); -#endif - return 0; -} - -/************************************************************************** -HALT - Turn off ethernet interface -***************************************************************************/ -static void rtl_halt(struct eth_device *dev) -{ - int i; - -#ifdef DEBUG_RTL8169 - printf ("%s\n", __FUNCTION__); -#endif - - ioaddr = dev->iobase; - - /* Stop the chip's Tx and Rx DMA processes. */ - RTL_W8(ChipCmd, 0x00); - - /* Disable interrupts by clearing the interrupt mask. */ - RTL_W16(IntrMask, 0x0000); - - RTL_W32(RxMissed, 0); - - tpc->TxDescArrays = NULL; - tpc->RxDescArrays = NULL; - tpc->TxDescArray = NULL; - tpc->RxDescArray = NULL; - for (i = 0; i < NUM_RX_DESC; i++) { - tpc->RxBufferRing[i] = NULL; - } -} - -/************************************************************************** -INIT - Look for an adapter, this routine's visible to the outside -***************************************************************************/ - -#define board_found 1 -#define valid_link 0 -static int rtl_init(struct eth_device *dev, bd_t *bis) -{ - static int board_idx = -1; - int i, rc; - int option = -1, Cap10_100 = 0, Cap1000 = 0; - -#ifdef DEBUG_RTL8169 - printf ("%s\n", __FUNCTION__); -#endif - - ioaddr = dev->iobase; - - board_idx++; - - /* point to private storage */ - tpc = &tpx; - - rc = rtl8169_init_board(dev); - if (rc) - return rc; - - /* Get MAC address. FIXME: read EEPROM */ - for (i = 0; i < MAC_ADDR_LEN; i++) - dev->enetaddr[i] = RTL_R8(MAC0 + i); - -#ifdef DEBUG_RTL8169 - printf("chipset = %d\n", tpc->chipset); - printf("MAC Address"); - for (i = 0; i < MAC_ADDR_LEN; i++) - printf(":%02x", dev->enetaddr[i]); - putc('\n'); -#endif - -#ifdef DEBUG_RTL8169 - /* Print out some hardware info */ - printf("%s: at ioaddr 0x%x\n", dev->name, ioaddr); -#endif - - /* if TBI is not endbled */ - if (!(RTL_R8(PHYstatus) & TBI_Enable)) { - int val = mdio_read(PHY_AUTO_NEGO_REG); - - option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx]; - /* Force RTL8169 in 10/100/1000 Full/Half mode. */ - if (option > 0) { -#ifdef DEBUG_RTL8169 - printf("%s: Force-mode Enabled.\n", dev->name); -#endif - Cap10_100 = 0, Cap1000 = 0; - switch (option) { - case _10_Half: - Cap10_100 = PHY_Cap_10_Half; - Cap1000 = PHY_Cap_Null; - break; - case _10_Full: - Cap10_100 = PHY_Cap_10_Full; - Cap1000 = PHY_Cap_Null; - break; - case _100_Half: - Cap10_100 = PHY_Cap_100_Half; - Cap1000 = PHY_Cap_Null; - break; - case _100_Full: - Cap10_100 = PHY_Cap_100_Full; - Cap1000 = PHY_Cap_Null; - break; - case _1000_Full: - Cap10_100 = PHY_Cap_Null; - Cap1000 = PHY_Cap_1000_Full; - break; - default: - break; - } - mdio_write(PHY_AUTO_NEGO_REG, Cap10_100 | (val & 0x1F)); /* leave PHY_AUTO_NEGO_REG bit4:0 unchanged */ - mdio_write(PHY_1000_CTRL_REG, Cap1000); - } else { -#ifdef DEBUG_RTL8169 - printf("%s: Auto-negotiation Enabled.\n", - dev->name); -#endif - /* enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged */ - mdio_write(PHY_AUTO_NEGO_REG, - PHY_Cap_10_Half | PHY_Cap_10_Full | - PHY_Cap_100_Half | PHY_Cap_100_Full | - (val & 0x1F)); - - /* enable 1000 Full Mode */ - mdio_write(PHY_1000_CTRL_REG, PHY_Cap_1000_Full); - - } - - /* Enable auto-negotiation and restart auto-nigotiation */ - mdio_write(PHY_CTRL_REG, - PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego); - udelay(100); - - /* wait for auto-negotiation process */ - for (i = 10000; i > 0; i--) { - /* check if auto-negotiation complete */ - if (mdio_read(PHY_STAT_REG) & PHY_Auto_Nego_Comp) { - udelay(100); - option = RTL_R8(PHYstatus); - if (option & _1000bpsF) { -#ifdef DEBUG_RTL8169 - printf("%s: 1000Mbps Full-duplex operation.\n", - dev->name); -#endif - } else { -#ifdef DEBUG_RTL8169 - printf("%s: %sMbps %s-duplex operation.\n", - dev->name, - (option & _100bps) ? "100" : - "10", - (option & FullDup) ? "Full" : - "Half"); -#endif - } - break; - } else { - udelay(100); - } - } /* end for-loop to wait for auto-negotiation process */ - - } else { - udelay(100); -#ifdef DEBUG_RTL8169 - printf - ("%s: 1000Mbps Full-duplex operation, TBI Link %s!\n", - dev->name, - (RTL_R32(TBICSR) & TBILinkOK) ? "OK" : "Failed"); -#endif - } - - return 1; -} - -int rtl8169_initialize(bd_t *bis) -{ - pci_dev_t devno; - int card_number = 0; - struct eth_device *dev; - u32 iobase; - int idx=0; - - while(1){ - unsigned int region; - u16 device; - - /* Find RTL8169 */ - if ((devno = pci_find_devices(supported, idx++)) < 0) - break; - - pci_read_config_word(devno, PCI_DEVICE_ID, &device); - switch (device) { - case 0x8168: - region = 2; - break; - - default: - region = 1; - break; - } - - pci_read_config_dword(devno, PCI_BASE_ADDRESS_0 + (region * 4), &iobase); - iobase &= ~0xf; - - debug ("rtl8169: REALTEK RTL8169 @0x%x\n", iobase); - - dev = (struct eth_device *)malloc(sizeof *dev); - if (!dev) { - printf("Can not allocate memory of rtl8169\n"); - break; - } - - memset(dev, 0, sizeof(*dev)); - sprintf (dev->name, "RTL8169#%d", card_number); - - dev->priv = (void *) devno; - dev->iobase = (int)pci_mem_to_phys(devno, iobase); - - dev->init = rtl_reset; - dev->halt = rtl_halt; - dev->send = rtl_send; - dev->recv = rtl_recv; - - eth_register (dev); - - rtl_init(dev, bis); - - card_number++; - } - return card_number; -} diff --git a/qemu/roms/u-boot/drivers/net/sh_eth.c b/qemu/roms/u-boot/drivers/net/sh_eth.c deleted file mode 100644 index 5e132f2b5..000000000 --- a/qemu/roms/u-boot/drivers/net/sh_eth.c +++ /dev/null @@ -1,655 +0,0 @@ -/* - * sh_eth.c - Driver for Renesas ethernet controler. - * - * Copyright (C) 2008, 2011 Renesas Solutions Corp. - * Copyright (c) 2008, 2011 Nobuhiro Iwamatsu - * Copyright (c) 2007 Carlos Munoz <carlos@kenati.com> - * Copyright (C) 2013 Renesas Electronics Corporation - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <config.h> -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <miiphy.h> -#include <asm/errno.h> -#include <asm/io.h> - -#include "sh_eth.h" - -#ifndef CONFIG_SH_ETHER_USE_PORT -# error "Please define CONFIG_SH_ETHER_USE_PORT" -#endif -#ifndef CONFIG_SH_ETHER_PHY_ADDR -# error "Please define CONFIG_SH_ETHER_PHY_ADDR" -#endif - -#if defined(CONFIG_SH_ETHER_CACHE_WRITEBACK) && !defined(CONFIG_SYS_DCACHE_OFF) -#define flush_cache_wback(addr, len) \ - flush_dcache_range((u32)addr, (u32)(addr + len - 1)) -#else -#define flush_cache_wback(...) -#endif - -#if defined(CONFIG_SH_ETHER_CACHE_INVALIDATE) && defined(CONFIG_ARM) -#define invalidate_cache(addr, len) \ - { \ - u32 line_size = CONFIG_SH_ETHER_ALIGNE_SIZE; \ - u32 start, end; \ - \ - start = (u32)addr; \ - end = start + len; \ - start &= ~(line_size - 1); \ - end = ((end + line_size - 1) & ~(line_size - 1)); \ - \ - invalidate_dcache_range(start, end); \ - } -#else -#define invalidate_cache(...) -#endif - -#define TIMEOUT_CNT 1000 - -int sh_eth_send(struct eth_device *dev, void *packet, int len) -{ - struct sh_eth_dev *eth = dev->priv; - int port = eth->port, ret = 0, timeout; - struct sh_eth_info *port_info = ð->port_info[port]; - - if (!packet || len > 0xffff) { - printf(SHETHER_NAME ": %s: Invalid argument\n", __func__); - ret = -EINVAL; - goto err; - } - - /* packet must be a 4 byte boundary */ - if ((int)packet & 3) { - printf(SHETHER_NAME ": %s: packet not 4 byte alligned\n", __func__); - ret = -EFAULT; - goto err; - } - - /* Update tx descriptor */ - flush_cache_wback(packet, len); - port_info->tx_desc_cur->td2 = ADDR_TO_PHY(packet); - port_info->tx_desc_cur->td1 = len << 16; - /* Must preserve the end of descriptor list indication */ - if (port_info->tx_desc_cur->td0 & TD_TDLE) - port_info->tx_desc_cur->td0 = TD_TACT | TD_TFP | TD_TDLE; - else - port_info->tx_desc_cur->td0 = TD_TACT | TD_TFP; - - /* Restart the transmitter if disabled */ - if (!(sh_eth_read(eth, EDTRR) & EDTRR_TRNS)) - sh_eth_write(eth, EDTRR_TRNS, EDTRR); - - /* Wait until packet is transmitted */ - timeout = TIMEOUT_CNT; - do { - invalidate_cache(port_info->tx_desc_cur, - sizeof(struct tx_desc_s)); - udelay(100); - } while (port_info->tx_desc_cur->td0 & TD_TACT && timeout--); - - if (timeout < 0) { - printf(SHETHER_NAME ": transmit timeout\n"); - ret = -ETIMEDOUT; - goto err; - } - - port_info->tx_desc_cur++; - if (port_info->tx_desc_cur >= port_info->tx_desc_base + NUM_TX_DESC) - port_info->tx_desc_cur = port_info->tx_desc_base; - -err: - return ret; -} - -int sh_eth_recv(struct eth_device *dev) -{ - struct sh_eth_dev *eth = dev->priv; - int port = eth->port, len = 0; - struct sh_eth_info *port_info = ð->port_info[port]; - uchar *packet; - - /* Check if the rx descriptor is ready */ - invalidate_cache(port_info->rx_desc_cur, sizeof(struct rx_desc_s)); - if (!(port_info->rx_desc_cur->rd0 & RD_RACT)) { - /* Check for errors */ - if (!(port_info->rx_desc_cur->rd0 & RD_RFE)) { - len = port_info->rx_desc_cur->rd1 & 0xffff; - packet = (uchar *) - ADDR_TO_P2(port_info->rx_desc_cur->rd2); - invalidate_cache(packet, len); - NetReceive(packet, len); - } - - /* Make current descriptor available again */ - if (port_info->rx_desc_cur->rd0 & RD_RDLE) - port_info->rx_desc_cur->rd0 = RD_RACT | RD_RDLE; - else - port_info->rx_desc_cur->rd0 = RD_RACT; - /* Point to the next descriptor */ - port_info->rx_desc_cur++; - if (port_info->rx_desc_cur >= - port_info->rx_desc_base + NUM_RX_DESC) - port_info->rx_desc_cur = port_info->rx_desc_base; - } - - /* Restart the receiver if disabled */ - if (!(sh_eth_read(eth, EDRRR) & EDRRR_R)) - sh_eth_write(eth, EDRRR_R, EDRRR); - - return len; -} - -static int sh_eth_reset(struct sh_eth_dev *eth) -{ -#if defined(SH_ETH_TYPE_GETHER) - int ret = 0, i; - - /* Start e-dmac transmitter and receiver */ - sh_eth_write(eth, EDSR_ENALL, EDSR); - - /* Perform a software reset and wait for it to complete */ - sh_eth_write(eth, EDMR_SRST, EDMR); - for (i = 0; i < TIMEOUT_CNT ; i++) { - if (!(sh_eth_read(eth, EDMR) & EDMR_SRST)) - break; - udelay(1000); - } - - if (i == TIMEOUT_CNT) { - printf(SHETHER_NAME ": Software reset timeout\n"); - ret = -EIO; - } - - return ret; -#else - sh_eth_write(eth, sh_eth_read(eth, EDMR) | EDMR_SRST, EDMR); - udelay(3000); - sh_eth_write(eth, sh_eth_read(eth, EDMR) & ~EDMR_SRST, EDMR); - - return 0; -#endif -} - -static int sh_eth_tx_desc_init(struct sh_eth_dev *eth) -{ - int port = eth->port, i, ret = 0; - u32 tmp_addr; - struct sh_eth_info *port_info = ð->port_info[port]; - struct tx_desc_s *cur_tx_desc; - - /* - * Allocate tx descriptors. They must be TX_DESC_SIZE bytes aligned - */ - port_info->tx_desc_malloc = malloc(NUM_TX_DESC * - sizeof(struct tx_desc_s) + - TX_DESC_SIZE - 1); - if (!port_info->tx_desc_malloc) { - printf(SHETHER_NAME ": malloc failed\n"); - ret = -ENOMEM; - goto err; - } - - tmp_addr = (u32) (((int)port_info->tx_desc_malloc + TX_DESC_SIZE - 1) & - ~(TX_DESC_SIZE - 1)); - flush_cache_wback(tmp_addr, NUM_TX_DESC * sizeof(struct tx_desc_s)); - /* Make sure we use a P2 address (non-cacheable) */ - port_info->tx_desc_base = (struct tx_desc_s *)ADDR_TO_P2(tmp_addr); - port_info->tx_desc_cur = port_info->tx_desc_base; - - /* Initialize all descriptors */ - for (cur_tx_desc = port_info->tx_desc_base, i = 0; i < NUM_TX_DESC; - cur_tx_desc++, i++) { - cur_tx_desc->td0 = 0x00; - cur_tx_desc->td1 = 0x00; - cur_tx_desc->td2 = 0x00; - } - - /* Mark the end of the descriptors */ - cur_tx_desc--; - cur_tx_desc->td0 |= TD_TDLE; - - /* Point the controller to the tx descriptor list. Must use physical - addresses */ - sh_eth_write(eth, ADDR_TO_PHY(port_info->tx_desc_base), TDLAR); -#if defined(SH_ETH_TYPE_GETHER) - sh_eth_write(eth, ADDR_TO_PHY(port_info->tx_desc_base), TDFAR); - sh_eth_write(eth, ADDR_TO_PHY(cur_tx_desc), TDFXR); - sh_eth_write(eth, 0x01, TDFFR);/* Last discriptor bit */ -#endif - -err: - return ret; -} - -static int sh_eth_rx_desc_init(struct sh_eth_dev *eth) -{ - int port = eth->port, i , ret = 0; - struct sh_eth_info *port_info = ð->port_info[port]; - struct rx_desc_s *cur_rx_desc; - u32 tmp_addr; - u8 *rx_buf; - - /* - * Allocate rx descriptors. They must be RX_DESC_SIZE bytes aligned - */ - port_info->rx_desc_malloc = malloc(NUM_RX_DESC * - sizeof(struct rx_desc_s) + - RX_DESC_SIZE - 1); - if (!port_info->rx_desc_malloc) { - printf(SHETHER_NAME ": malloc failed\n"); - ret = -ENOMEM; - goto err; - } - - tmp_addr = (u32) (((int)port_info->rx_desc_malloc + RX_DESC_SIZE - 1) & - ~(RX_DESC_SIZE - 1)); - flush_cache_wback(tmp_addr, NUM_RX_DESC * sizeof(struct rx_desc_s)); - /* Make sure we use a P2 address (non-cacheable) */ - port_info->rx_desc_base = (struct rx_desc_s *)ADDR_TO_P2(tmp_addr); - - port_info->rx_desc_cur = port_info->rx_desc_base; - - /* - * Allocate rx data buffers. They must be 32 bytes aligned and in - * P2 area - */ - port_info->rx_buf_malloc = malloc( - NUM_RX_DESC * MAX_BUF_SIZE + RX_BUF_ALIGNE_SIZE - 1); - if (!port_info->rx_buf_malloc) { - printf(SHETHER_NAME ": malloc failed\n"); - ret = -ENOMEM; - goto err_buf_malloc; - } - - tmp_addr = (u32)(((int)port_info->rx_buf_malloc - + (RX_BUF_ALIGNE_SIZE - 1)) & - ~(RX_BUF_ALIGNE_SIZE - 1)); - port_info->rx_buf_base = (u8 *)ADDR_TO_P2(tmp_addr); - - /* Initialize all descriptors */ - for (cur_rx_desc = port_info->rx_desc_base, - rx_buf = port_info->rx_buf_base, i = 0; - i < NUM_RX_DESC; cur_rx_desc++, rx_buf += MAX_BUF_SIZE, i++) { - cur_rx_desc->rd0 = RD_RACT; - cur_rx_desc->rd1 = MAX_BUF_SIZE << 16; - cur_rx_desc->rd2 = (u32) ADDR_TO_PHY(rx_buf); - } - - /* Mark the end of the descriptors */ - cur_rx_desc--; - cur_rx_desc->rd0 |= RD_RDLE; - - /* Point the controller to the rx descriptor list */ - sh_eth_write(eth, ADDR_TO_PHY(port_info->rx_desc_base), RDLAR); -#if defined(SH_ETH_TYPE_GETHER) - sh_eth_write(eth, ADDR_TO_PHY(port_info->rx_desc_base), RDFAR); - sh_eth_write(eth, ADDR_TO_PHY(cur_rx_desc), RDFXR); - sh_eth_write(eth, RDFFR_RDLF, RDFFR); -#endif - - return ret; - -err_buf_malloc: - free(port_info->rx_desc_malloc); - port_info->rx_desc_malloc = NULL; - -err: - return ret; -} - -static void sh_eth_tx_desc_free(struct sh_eth_dev *eth) -{ - int port = eth->port; - struct sh_eth_info *port_info = ð->port_info[port]; - - if (port_info->tx_desc_malloc) { - free(port_info->tx_desc_malloc); - port_info->tx_desc_malloc = NULL; - } -} - -static void sh_eth_rx_desc_free(struct sh_eth_dev *eth) -{ - int port = eth->port; - struct sh_eth_info *port_info = ð->port_info[port]; - - if (port_info->rx_desc_malloc) { - free(port_info->rx_desc_malloc); - port_info->rx_desc_malloc = NULL; - } - - if (port_info->rx_buf_malloc) { - free(port_info->rx_buf_malloc); - port_info->rx_buf_malloc = NULL; - } -} - -static int sh_eth_desc_init(struct sh_eth_dev *eth) -{ - int ret = 0; - - ret = sh_eth_tx_desc_init(eth); - if (ret) - goto err_tx_init; - - ret = sh_eth_rx_desc_init(eth); - if (ret) - goto err_rx_init; - - return ret; -err_rx_init: - sh_eth_tx_desc_free(eth); - -err_tx_init: - return ret; -} - -static int sh_eth_phy_config(struct sh_eth_dev *eth) -{ - int port = eth->port, ret = 0; - struct sh_eth_info *port_info = ð->port_info[port]; - struct eth_device *dev = port_info->dev; - struct phy_device *phydev; - - phydev = phy_connect( - miiphy_get_dev_by_name(dev->name), - port_info->phy_addr, dev, CONFIG_SH_ETHER_PHY_MODE); - port_info->phydev = phydev; - phy_config(phydev); - - return ret; -} - -static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd) -{ - int port = eth->port, ret = 0; - u32 val; - struct sh_eth_info *port_info = ð->port_info[port]; - struct eth_device *dev = port_info->dev; - struct phy_device *phy; - - /* Configure e-dmac registers */ - sh_eth_write(eth, (sh_eth_read(eth, EDMR) & ~EMDR_DESC_R) | - (EMDR_DESC | EDMR_EL), EDMR); - - sh_eth_write(eth, 0, EESIPR); - sh_eth_write(eth, 0, TRSCER); - sh_eth_write(eth, 0, TFTR); - sh_eth_write(eth, (FIFO_SIZE_T | FIFO_SIZE_R), FDR); - sh_eth_write(eth, RMCR_RST, RMCR); -#if defined(SH_ETH_TYPE_GETHER) - sh_eth_write(eth, 0, RPADIR); -#endif - sh_eth_write(eth, (FIFO_F_D_RFF | FIFO_F_D_RFD), FCFTR); - - /* Configure e-mac registers */ - sh_eth_write(eth, 0, ECSIPR); - - /* Set Mac address */ - val = dev->enetaddr[0] << 24 | dev->enetaddr[1] << 16 | - dev->enetaddr[2] << 8 | dev->enetaddr[3]; - sh_eth_write(eth, val, MAHR); - - val = dev->enetaddr[4] << 8 | dev->enetaddr[5]; - sh_eth_write(eth, val, MALR); - - sh_eth_write(eth, RFLR_RFL_MIN, RFLR); -#if defined(SH_ETH_TYPE_GETHER) - sh_eth_write(eth, 0, PIPR); - sh_eth_write(eth, APR_AP, APR); - sh_eth_write(eth, MPR_MP, MPR); - sh_eth_write(eth, TPAUSER_TPAUSE, TPAUSER); -#endif - -#if defined(CONFIG_CPU_SH7734) || defined(CONFIG_R8A7740) - sh_eth_write(eth, CONFIG_SH_ETHER_SH7734_MII, RMII_MII); -#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) - sh_eth_write(eth, sh_eth_read(eth, RMIIMR) | 0x1, RMIIMR); -#endif - /* Configure phy */ - ret = sh_eth_phy_config(eth); - if (ret) { - printf(SHETHER_NAME ": phy config timeout\n"); - goto err_phy_cfg; - } - phy = port_info->phydev; - ret = phy_startup(phy); - if (ret) { - printf(SHETHER_NAME ": phy startup failure\n"); - return ret; - } - - val = 0; - - /* Set the transfer speed */ - if (phy->speed == 100) { - printf(SHETHER_NAME ": 100Base/"); -#if defined(SH_ETH_TYPE_GETHER) - sh_eth_write(eth, GECMR_100B, GECMR); -#elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752) - sh_eth_write(eth, 1, RTRATE); -#elif defined(CONFIG_CPU_SH7724) || defined(CONFIG_R8A7790) || \ - defined(CONFIG_R8A7791) - val = ECMR_RTM; -#endif - } else if (phy->speed == 10) { - printf(SHETHER_NAME ": 10Base/"); -#if defined(SH_ETH_TYPE_GETHER) - sh_eth_write(eth, GECMR_10B, GECMR); -#elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752) - sh_eth_write(eth, 0, RTRATE); -#endif - } -#if defined(SH_ETH_TYPE_GETHER) - else if (phy->speed == 1000) { - printf(SHETHER_NAME ": 1000Base/"); - sh_eth_write(eth, GECMR_1000B, GECMR); - } -#endif - - /* Check if full duplex mode is supported by the phy */ - if (phy->duplex) { - printf("Full\n"); - sh_eth_write(eth, val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE|ECMR_DM), - ECMR); - } else { - printf("Half\n"); - sh_eth_write(eth, val | (ECMR_CHG_DM|ECMR_RE|ECMR_TE), ECMR); - } - - return ret; - -err_phy_cfg: - return ret; -} - -static void sh_eth_start(struct sh_eth_dev *eth) -{ - /* - * Enable the e-dmac receiver only. The transmitter will be enabled when - * we have something to transmit - */ - sh_eth_write(eth, EDRRR_R, EDRRR); -} - -static void sh_eth_stop(struct sh_eth_dev *eth) -{ - sh_eth_write(eth, ~EDRRR_R, EDRRR); -} - -int sh_eth_init(struct eth_device *dev, bd_t *bd) -{ - int ret = 0; - struct sh_eth_dev *eth = dev->priv; - - ret = sh_eth_reset(eth); - if (ret) - goto err; - - ret = sh_eth_desc_init(eth); - if (ret) - goto err; - - ret = sh_eth_config(eth, bd); - if (ret) - goto err_config; - - sh_eth_start(eth); - - return ret; - -err_config: - sh_eth_tx_desc_free(eth); - sh_eth_rx_desc_free(eth); - -err: - return ret; -} - -void sh_eth_halt(struct eth_device *dev) -{ - struct sh_eth_dev *eth = dev->priv; - sh_eth_stop(eth); -} - -int sh_eth_initialize(bd_t *bd) -{ - int ret = 0; - struct sh_eth_dev *eth = NULL; - struct eth_device *dev = NULL; - - eth = (struct sh_eth_dev *)malloc(sizeof(struct sh_eth_dev)); - if (!eth) { - printf(SHETHER_NAME ": %s: malloc failed\n", __func__); - ret = -ENOMEM; - goto err; - } - - dev = (struct eth_device *)malloc(sizeof(struct eth_device)); - if (!dev) { - printf(SHETHER_NAME ": %s: malloc failed\n", __func__); - ret = -ENOMEM; - goto err; - } - memset(dev, 0, sizeof(struct eth_device)); - memset(eth, 0, sizeof(struct sh_eth_dev)); - - eth->port = CONFIG_SH_ETHER_USE_PORT; - eth->port_info[eth->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR; - - dev->priv = (void *)eth; - dev->iobase = 0; - dev->init = sh_eth_init; - dev->halt = sh_eth_halt; - dev->send = sh_eth_send; - dev->recv = sh_eth_recv; - eth->port_info[eth->port].dev = dev; - - sprintf(dev->name, SHETHER_NAME); - - /* Register Device to EtherNet subsystem */ - eth_register(dev); - - bb_miiphy_buses[0].priv = eth; - miiphy_register(dev->name, bb_miiphy_read, bb_miiphy_write); - - if (!eth_getenv_enetaddr("ethaddr", dev->enetaddr)) - puts("Please set MAC address\n"); - - return ret; - -err: - if (dev) - free(dev); - - if (eth) - free(eth); - - printf(SHETHER_NAME ": Failed\n"); - return ret; -} - -/******* for bb_miiphy *******/ -static int sh_eth_bb_init(struct bb_miiphy_bus *bus) -{ - return 0; -} - -static int sh_eth_bb_mdio_active(struct bb_miiphy_bus *bus) -{ - struct sh_eth_dev *eth = bus->priv; - - sh_eth_write(eth, sh_eth_read(eth, PIR) | PIR_MMD, PIR); - - return 0; -} - -static int sh_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus) -{ - struct sh_eth_dev *eth = bus->priv; - - sh_eth_write(eth, sh_eth_read(eth, PIR) & ~PIR_MMD, PIR); - - return 0; -} - -static int sh_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v) -{ - struct sh_eth_dev *eth = bus->priv; - - if (v) - sh_eth_write(eth, sh_eth_read(eth, PIR) | PIR_MDO, PIR); - else - sh_eth_write(eth, sh_eth_read(eth, PIR) & ~PIR_MDO, PIR); - - return 0; -} - -static int sh_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v) -{ - struct sh_eth_dev *eth = bus->priv; - - *v = (sh_eth_read(eth, PIR) & PIR_MDI) >> 3; - - return 0; -} - -static int sh_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v) -{ - struct sh_eth_dev *eth = bus->priv; - - if (v) - sh_eth_write(eth, sh_eth_read(eth, PIR) | PIR_MDC, PIR); - else - sh_eth_write(eth, sh_eth_read(eth, PIR) & ~PIR_MDC, PIR); - - return 0; -} - -static int sh_eth_bb_delay(struct bb_miiphy_bus *bus) -{ - udelay(10); - - return 0; -} - -struct bb_miiphy_bus bb_miiphy_buses[] = { - { - .name = "sh_eth", - .init = sh_eth_bb_init, - .mdio_active = sh_eth_bb_mdio_active, - .mdio_tristate = sh_eth_bb_mdio_tristate, - .set_mdio = sh_eth_bb_set_mdio, - .get_mdio = sh_eth_bb_get_mdio, - .set_mdc = sh_eth_bb_set_mdc, - .delay = sh_eth_bb_delay, - } -}; -int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses); diff --git a/qemu/roms/u-boot/drivers/net/sh_eth.h b/qemu/roms/u-boot/drivers/net/sh_eth.h deleted file mode 100644 index 331c07cb5..000000000 --- a/qemu/roms/u-boot/drivers/net/sh_eth.h +++ /dev/null @@ -1,624 +0,0 @@ -/* - * sh_eth.h - Driver for Renesas SuperH ethernet controler. - * - * Copyright (C) 2008 - 2012 Renesas Solutions Corp. - * Copyright (c) 2008 - 2012 Nobuhiro Iwamatsu - * Copyright (c) 2007 Carlos Munoz <carlos@kenati.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <netdev.h> -#include <asm/types.h> - -#define SHETHER_NAME "sh_eth" - -#if defined(CONFIG_SH) -/* Malloc returns addresses in the P1 area (cacheable). However we need to - use area P2 (non-cacheable) */ -#define ADDR_TO_P2(addr) ((((int)(addr) & ~0xe0000000) | 0xa0000000)) - -/* The ethernet controller needs to use physical addresses */ -#if defined(CONFIG_SH_32BIT) -#define ADDR_TO_PHY(addr) ((((int)(addr) & ~0xe0000000) | 0x40000000)) -#else -#define ADDR_TO_PHY(addr) ((int)(addr) & ~0xe0000000) -#endif -#elif defined(CONFIG_ARM) -#define inl readl -#define outl writel -#define ADDR_TO_PHY(addr) ((int)(addr)) -#define ADDR_TO_P2(addr) (addr) -#endif /* defined(CONFIG_SH) */ - -/* base padding size is 16 */ -#ifndef CONFIG_SH_ETHER_ALIGNE_SIZE -#define CONFIG_SH_ETHER_ALIGNE_SIZE 16 -#endif - -/* Number of supported ports */ -#define MAX_PORT_NUM 2 - -/* Buffers must be big enough to hold the largest ethernet frame. Also, rx - buffers must be a multiple of 32 bytes */ -#define MAX_BUF_SIZE (48 * 32) - -/* The number of tx descriptors must be large enough to point to 5 or more - frames. If each frame uses 2 descriptors, at least 10 descriptors are needed. - We use one descriptor per frame */ -#define NUM_TX_DESC 8 - -/* The size of the tx descriptor is determined by how much padding is used. - 4, 20, or 52 bytes of padding can be used */ -#define TX_DESC_PADDING (CONFIG_SH_ETHER_ALIGNE_SIZE - 12) -/* same as CONFIG_SH_ETHER_ALIGNE_SIZE */ -#define TX_DESC_SIZE (12 + TX_DESC_PADDING) - -/* Tx descriptor. We always use 3 bytes of padding */ -struct tx_desc_s { - volatile u32 td0; - u32 td1; - u32 td2; /* Buffer start */ - u8 padding[TX_DESC_PADDING]; /* aligned cache line size */ -}; - -/* There is no limitation in the number of rx descriptors */ -#define NUM_RX_DESC 8 - -/* The size of the rx descriptor is determined by how much padding is used. - 4, 20, or 52 bytes of padding can be used */ -#define RX_DESC_PADDING (CONFIG_SH_ETHER_ALIGNE_SIZE - 12) -/* same as CONFIG_SH_ETHER_ALIGNE_SIZE */ -#define RX_DESC_SIZE (12 + RX_DESC_PADDING) -/* aligned cache line size */ -#define RX_BUF_ALIGNE_SIZE (CONFIG_SH_ETHER_ALIGNE_SIZE > 32 ? 64 : 32) - -/* Rx descriptor. We always use 4 bytes of padding */ -struct rx_desc_s { - volatile u32 rd0; - volatile u32 rd1; - u32 rd2; /* Buffer start */ - u8 padding[TX_DESC_PADDING]; /* aligned cache line size */ -}; - -struct sh_eth_info { - struct tx_desc_s *tx_desc_malloc; - struct tx_desc_s *tx_desc_base; - struct tx_desc_s *tx_desc_cur; - struct rx_desc_s *rx_desc_malloc; - struct rx_desc_s *rx_desc_base; - struct rx_desc_s *rx_desc_cur; - u8 *rx_buf_malloc; - u8 *rx_buf_base; - u8 mac_addr[6]; - u8 phy_addr; - struct eth_device *dev; - struct phy_device *phydev; -}; - -struct sh_eth_dev { - int port; - struct sh_eth_info port_info[MAX_PORT_NUM]; -}; - -/* from linux/drivers/net/ethernet/renesas/sh_eth.h */ -enum { - /* E-DMAC registers */ - EDSR = 0, - EDMR, - EDTRR, - EDRRR, - EESR, - EESIPR, - TDLAR, - TDFAR, - TDFXR, - TDFFR, - RDLAR, - RDFAR, - RDFXR, - RDFFR, - TRSCER, - RMFCR, - TFTR, - FDR, - RMCR, - EDOCR, - TFUCR, - RFOCR, - FCFTR, - RPADIR, - TRIMD, - RBWAR, - TBRAR, - - /* Ether registers */ - ECMR, - ECSR, - ECSIPR, - PIR, - PSR, - RDMLR, - PIPR, - RFLR, - IPGR, - APR, - MPR, - PFTCR, - PFRCR, - RFCR, - RFCF, - TPAUSER, - TPAUSECR, - BCFR, - BCFRR, - GECMR, - BCULR, - MAHR, - MALR, - TROCR, - CDCR, - LCCR, - CNDCR, - CEFCR, - FRECR, - TSFRCR, - TLFRCR, - CERCR, - CEECR, - RMIIMR, /* R8A7790 */ - MAFCR, - RTRATE, - CSMR, - RMII_MII, - - /* This value must be written at last. */ - SH_ETH_MAX_REGISTER_OFFSET, -}; - -static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = { - [EDSR] = 0x0000, - [EDMR] = 0x0400, - [EDTRR] = 0x0408, - [EDRRR] = 0x0410, - [EESR] = 0x0428, - [EESIPR] = 0x0430, - [TDLAR] = 0x0010, - [TDFAR] = 0x0014, - [TDFXR] = 0x0018, - [TDFFR] = 0x001c, - [RDLAR] = 0x0030, - [RDFAR] = 0x0034, - [RDFXR] = 0x0038, - [RDFFR] = 0x003c, - [TRSCER] = 0x0438, - [RMFCR] = 0x0440, - [TFTR] = 0x0448, - [FDR] = 0x0450, - [RMCR] = 0x0458, - [RPADIR] = 0x0460, - [FCFTR] = 0x0468, - [CSMR] = 0x04E4, - - [ECMR] = 0x0500, - [ECSR] = 0x0510, - [ECSIPR] = 0x0518, - [PIR] = 0x0520, - [PSR] = 0x0528, - [PIPR] = 0x052c, - [RFLR] = 0x0508, - [APR] = 0x0554, - [MPR] = 0x0558, - [PFTCR] = 0x055c, - [PFRCR] = 0x0560, - [TPAUSER] = 0x0564, - [GECMR] = 0x05b0, - [BCULR] = 0x05b4, - [MAHR] = 0x05c0, - [MALR] = 0x05c8, - [TROCR] = 0x0700, - [CDCR] = 0x0708, - [LCCR] = 0x0710, - [CEFCR] = 0x0740, - [FRECR] = 0x0748, - [TSFRCR] = 0x0750, - [TLFRCR] = 0x0758, - [RFCR] = 0x0760, - [CERCR] = 0x0768, - [CEECR] = 0x0770, - [MAFCR] = 0x0778, - [RMII_MII] = 0x0790, -}; - -static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = { - [ECMR] = 0x0100, - [RFLR] = 0x0108, - [ECSR] = 0x0110, - [ECSIPR] = 0x0118, - [PIR] = 0x0120, - [PSR] = 0x0128, - [RDMLR] = 0x0140, - [IPGR] = 0x0150, - [APR] = 0x0154, - [MPR] = 0x0158, - [TPAUSER] = 0x0164, - [RFCF] = 0x0160, - [TPAUSECR] = 0x0168, - [BCFRR] = 0x016c, - [MAHR] = 0x01c0, - [MALR] = 0x01c8, - [TROCR] = 0x01d0, - [CDCR] = 0x01d4, - [LCCR] = 0x01d8, - [CNDCR] = 0x01dc, - [CEFCR] = 0x01e4, - [FRECR] = 0x01e8, - [TSFRCR] = 0x01ec, - [TLFRCR] = 0x01f0, - [RFCR] = 0x01f4, - [MAFCR] = 0x01f8, - [RTRATE] = 0x01fc, - - [EDMR] = 0x0000, - [EDTRR] = 0x0008, - [EDRRR] = 0x0010, - [TDLAR] = 0x0018, - [RDLAR] = 0x0020, - [EESR] = 0x0028, - [EESIPR] = 0x0030, - [TRSCER] = 0x0038, - [RMFCR] = 0x0040, - [TFTR] = 0x0048, - [FDR] = 0x0050, - [RMCR] = 0x0058, - [TFUCR] = 0x0064, - [RFOCR] = 0x0068, - [RMIIMR] = 0x006C, - [FCFTR] = 0x0070, - [RPADIR] = 0x0078, - [TRIMD] = 0x007c, - [RBWAR] = 0x00c8, - [RDFAR] = 0x00cc, - [TBRAR] = 0x00d4, - [TDFAR] = 0x00d8, -}; - -/* Register Address */ -#if defined(CONFIG_CPU_SH7763) || defined(CONFIG_CPU_SH7734) -#define SH_ETH_TYPE_GETHER -#define BASE_IO_ADDR 0xfee00000 -#elif defined(CONFIG_CPU_SH7757) || \ - defined(CONFIG_CPU_SH7752) || \ - defined(CONFIG_CPU_SH7753) -#if defined(CONFIG_SH_ETHER_USE_GETHER) -#define SH_ETH_TYPE_GETHER -#define BASE_IO_ADDR 0xfee00000 -#else -#define SH_ETH_TYPE_ETHER -#define BASE_IO_ADDR 0xfef00000 -#endif -#elif defined(CONFIG_CPU_SH7724) -#define SH_ETH_TYPE_ETHER -#define BASE_IO_ADDR 0xA4600000 -#elif defined(CONFIG_R8A7740) -#define SH_ETH_TYPE_GETHER -#define BASE_IO_ADDR 0xE9A00000 -#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) -#define SH_ETH_TYPE_ETHER -#define BASE_IO_ADDR 0xEE700200 -#endif - -/* - * Register's bits - * Copy from Linux driver source code - */ -#if defined(SH_ETH_TYPE_GETHER) -/* EDSR */ -enum EDSR_BIT { - EDSR_ENT = 0x01, EDSR_ENR = 0x02, -}; -#define EDSR_ENALL (EDSR_ENT|EDSR_ENR) -#endif - -/* EDMR */ -enum DMAC_M_BIT { - EDMR_DL1 = 0x20, EDMR_DL0 = 0x10, -#if defined(SH_ETH_TYPE_GETHER) - EDMR_SRST = 0x03, /* Receive/Send reset */ - EMDR_DESC_R = 0x30, /* Descriptor reserve size */ - EDMR_EL = 0x40, /* Litte endian */ -#elif defined(SH_ETH_TYPE_ETHER) - EDMR_SRST = 0x01, - EMDR_DESC_R = 0x30, /* Descriptor reserve size */ - EDMR_EL = 0x40, /* Litte endian */ -#else - EDMR_SRST = 0x01, -#endif -}; - -#if CONFIG_SH_ETHER_ALIGNE_SIZE == 64 -# define EMDR_DESC EDMR_DL1 -#elif CONFIG_SH_ETHER_ALIGNE_SIZE == 32 -# define EMDR_DESC EDMR_DL0 -#elif CONFIG_SH_ETHER_ALIGNE_SIZE == 16 /* Default */ -# define EMDR_DESC 0 -#endif - -/* RFLR */ -#define RFLR_RFL_MIN 0x05EE /* Recv Frame length 1518 byte */ - -/* EDTRR */ -enum DMAC_T_BIT { -#if defined(SH_ETH_TYPE_GETHER) - EDTRR_TRNS = 0x03, -#else - EDTRR_TRNS = 0x01, -#endif -}; - -/* GECMR */ -enum GECMR_BIT { -#if defined(CONFIG_CPU_SH7757) || \ - defined(CONFIG_CPU_SH7752) || \ - defined(CONFIG_CPU_SH7753) - GECMR_1000B = 0x20, GECMR_100B = 0x01, GECMR_10B = 0x00, -#else - GECMR_1000B = 0x01, GECMR_100B = 0x04, GECMR_10B = 0x00, -#endif -}; - -/* EDRRR*/ -enum EDRRR_R_BIT { - EDRRR_R = 0x01, -}; - -/* TPAUSER */ -enum TPAUSER_BIT { - TPAUSER_TPAUSE = 0x0000ffff, - TPAUSER_UNLIMITED = 0, -}; - -/* BCFR */ -enum BCFR_BIT { - BCFR_RPAUSE = 0x0000ffff, - BCFR_UNLIMITED = 0, -}; - -/* PIR */ -enum PIR_BIT { - PIR_MDI = 0x08, PIR_MDO = 0x04, PIR_MMD = 0x02, PIR_MDC = 0x01, -}; - -/* PSR */ -enum PHY_STATUS_BIT { PHY_ST_LINK = 0x01, }; - -/* EESR */ -enum EESR_BIT { - -#if defined(SH_ETH_TYPE_ETHER) - EESR_TWB = 0x40000000, -#else - EESR_TWB = 0xC0000000, - EESR_TC1 = 0x20000000, - EESR_TUC = 0x10000000, - EESR_ROC = 0x80000000, -#endif - EESR_TABT = 0x04000000, - EESR_RABT = 0x02000000, EESR_RFRMER = 0x01000000, -#if defined(SH_ETH_TYPE_ETHER) - EESR_ADE = 0x00800000, -#endif - EESR_ECI = 0x00400000, - EESR_FTC = 0x00200000, EESR_TDE = 0x00100000, - EESR_TFE = 0x00080000, EESR_FRC = 0x00040000, - EESR_RDE = 0x00020000, EESR_RFE = 0x00010000, -#if defined(SH_ETH_TYPE_ETHER) - EESR_CND = 0x00000800, -#endif - EESR_DLC = 0x00000400, - EESR_CD = 0x00000200, EESR_RTO = 0x00000100, - EESR_RMAF = 0x00000080, EESR_CEEF = 0x00000040, - EESR_CELF = 0x00000020, EESR_RRF = 0x00000010, - rESR_RTLF = 0x00000008, EESR_RTSF = 0x00000004, - EESR_PRE = 0x00000002, EESR_CERF = 0x00000001, -}; - - -#if defined(SH_ETH_TYPE_GETHER) -# define TX_CHECK (EESR_TC1 | EESR_FTC) -# define EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \ - | EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI) -# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE) - -#else -# define TX_CHECK (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO) -# define EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \ - | EESR_RFRMER | EESR_ADE | EESR_TFE | EESR_TDE | EESR_ECI) -# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE) -#endif - -/* EESIPR */ -enum DMAC_IM_BIT { - DMAC_M_TWB = 0x40000000, DMAC_M_TABT = 0x04000000, - DMAC_M_RABT = 0x02000000, - DMAC_M_RFRMER = 0x01000000, DMAC_M_ADF = 0x00800000, - DMAC_M_ECI = 0x00400000, DMAC_M_FTC = 0x00200000, - DMAC_M_TDE = 0x00100000, DMAC_M_TFE = 0x00080000, - DMAC_M_FRC = 0x00040000, DMAC_M_RDE = 0x00020000, - DMAC_M_RFE = 0x00010000, DMAC_M_TINT4 = 0x00000800, - DMAC_M_TINT3 = 0x00000400, DMAC_M_TINT2 = 0x00000200, - DMAC_M_TINT1 = 0x00000100, DMAC_M_RINT8 = 0x00000080, - DMAC_M_RINT5 = 0x00000010, DMAC_M_RINT4 = 0x00000008, - DMAC_M_RINT3 = 0x00000004, DMAC_M_RINT2 = 0x00000002, - DMAC_M_RINT1 = 0x00000001, -}; - -/* Receive descriptor bit */ -enum RD_STS_BIT { - RD_RACT = 0x80000000, RD_RDLE = 0x40000000, - RD_RFP1 = 0x20000000, RD_RFP0 = 0x10000000, - RD_RFE = 0x08000000, RD_RFS10 = 0x00000200, - RD_RFS9 = 0x00000100, RD_RFS8 = 0x00000080, - RD_RFS7 = 0x00000040, RD_RFS6 = 0x00000020, - RD_RFS5 = 0x00000010, RD_RFS4 = 0x00000008, - RD_RFS3 = 0x00000004, RD_RFS2 = 0x00000002, - RD_RFS1 = 0x00000001, -}; -#define RDF1ST RD_RFP1 -#define RDFEND RD_RFP0 -#define RD_RFP (RD_RFP1|RD_RFP0) - -/* RDFFR*/ -enum RDFFR_BIT { - RDFFR_RDLF = 0x01, -}; - -/* FCFTR */ -enum FCFTR_BIT { - FCFTR_RFF2 = 0x00040000, FCFTR_RFF1 = 0x00020000, - FCFTR_RFF0 = 0x00010000, FCFTR_RFD2 = 0x00000004, - FCFTR_RFD1 = 0x00000002, FCFTR_RFD0 = 0x00000001, -}; -#define FIFO_F_D_RFF (FCFTR_RFF2|FCFTR_RFF1|FCFTR_RFF0) -#define FIFO_F_D_RFD (FCFTR_RFD2|FCFTR_RFD1|FCFTR_RFD0) - -/* Transfer descriptor bit */ -enum TD_STS_BIT { -#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_ETHER) - TD_TACT = 0x80000000, -#else - TD_TACT = 0x7fffffff, -#endif - TD_TDLE = 0x40000000, TD_TFP1 = 0x20000000, - TD_TFP0 = 0x10000000, -}; -#define TDF1ST TD_TFP1 -#define TDFEND TD_TFP0 -#define TD_TFP (TD_TFP1|TD_TFP0) - -/* RMCR */ -enum RECV_RST_BIT { RMCR_RST = 0x01, }; -/* ECMR */ -enum FELIC_MODE_BIT { -#if defined(SH_ETH_TYPE_GETHER) - ECMR_TRCCM=0x04000000, ECMR_RCSC= 0x00800000, ECMR_DPAD= 0x00200000, - ECMR_RZPF = 0x00100000, -#endif - ECMR_ZPF = 0x00080000, ECMR_PFR = 0x00040000, ECMR_RXF = 0x00020000, - ECMR_TXF = 0x00010000, ECMR_MCT = 0x00002000, ECMR_PRCEF = 0x00001000, - ECMR_PMDE = 0x00000200, ECMR_RE = 0x00000040, ECMR_TE = 0x00000020, - ECMR_ILB = 0x00000008, ECMR_ELB = 0x00000004, ECMR_DM = 0x00000002, - ECMR_PRM = 0x00000001, -#ifdef CONFIG_CPU_SH7724 - ECMR_RTM = 0x00000010, -#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) - ECMR_RTM = 0x00000004, -#endif - -}; - -#if defined(SH_ETH_TYPE_GETHER) -#define ECMR_CHG_DM (ECMR_TRCCM | ECMR_RZPF | ECMR_ZPF | ECMR_PFR | ECMR_RXF | \ - ECMR_TXF | ECMR_MCT) -#elif defined(SH_ETH_TYPE_ETHER) -#define ECMR_CHG_DM (ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF) -#else -#define ECMR_CHG_DM (ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT) -#endif - -/* ECSR */ -enum ECSR_STATUS_BIT { -#if defined(SH_ETH_TYPE_ETHER) - ECSR_BRCRX = 0x20, ECSR_PSRTO = 0x10, -#endif - ECSR_LCHNG = 0x04, - ECSR_MPD = 0x02, ECSR_ICD = 0x01, -}; - -#if defined(SH_ETH_TYPE_GETHER) -# define ECSR_INIT (ECSR_ICD | ECSIPR_MPDIP) -#else -# define ECSR_INIT (ECSR_BRCRX | ECSR_PSRTO | \ - ECSR_LCHNG | ECSR_ICD | ECSIPR_MPDIP) -#endif - -/* ECSIPR */ -enum ECSIPR_STATUS_MASK_BIT { -#if defined(SH_ETH_TYPE_ETHER) - ECSIPR_BRCRXIP = 0x20, - ECSIPR_PSRTOIP = 0x10, -#elif defined(SH_ETY_TYPE_GETHER) - ECSIPR_PSRTOIP = 0x10, - ECSIPR_PHYIP = 0x08, -#endif - ECSIPR_LCHNGIP = 0x04, - ECSIPR_MPDIP = 0x02, - ECSIPR_ICDIP = 0x01, -}; - -#if defined(SH_ETH_TYPE_GETHER) -# define ECSIPR_INIT (ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP) -#else -# define ECSIPR_INIT (ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | \ - ECSIPR_ICDIP | ECSIPR_MPDIP) -#endif - -/* APR */ -enum APR_BIT { - APR_AP = 0x00000004, -}; - -/* MPR */ -enum MPR_BIT { - MPR_MP = 0x00000006, -}; - -/* TRSCER */ -enum DESC_I_BIT { - DESC_I_TINT4 = 0x0800, DESC_I_TINT3 = 0x0400, DESC_I_TINT2 = 0x0200, - DESC_I_TINT1 = 0x0100, DESC_I_RINT8 = 0x0080, DESC_I_RINT5 = 0x0010, - DESC_I_RINT4 = 0x0008, DESC_I_RINT3 = 0x0004, DESC_I_RINT2 = 0x0002, - DESC_I_RINT1 = 0x0001, -}; - -/* RPADIR */ -enum RPADIR_BIT { - RPADIR_PADS1 = 0x20000, RPADIR_PADS0 = 0x10000, - RPADIR_PADR = 0x0003f, -}; - -#if defined(SH_ETH_TYPE_GETHER) -# define RPADIR_INIT (0x00) -#else -# define RPADIR_INIT (RPADIR_PADS1) -#endif - -/* FDR */ -enum FIFO_SIZE_BIT { - FIFO_SIZE_T = 0x00000700, FIFO_SIZE_R = 0x00000007, -}; - -static inline unsigned long sh_eth_reg_addr(struct sh_eth_dev *eth, - int enum_index) -{ -#if defined(SH_ETH_TYPE_GETHER) - const u16 *reg_offset = sh_eth_offset_gigabit; -#elif defined(SH_ETH_TYPE_ETHER) - const u16 *reg_offset = sh_eth_offset_fast_sh4; -#else -#error -#endif - return BASE_IO_ADDR + reg_offset[enum_index] + 0x800 * eth->port; -} - -static inline void sh_eth_write(struct sh_eth_dev *eth, unsigned long data, - int enum_index) -{ - outl(data, sh_eth_reg_addr(eth, enum_index)); -} - -static inline unsigned long sh_eth_read(struct sh_eth_dev *eth, - int enum_index) -{ - return inl(sh_eth_reg_addr(eth, enum_index)); -} diff --git a/qemu/roms/u-boot/drivers/net/smc91111.c b/qemu/roms/u-boot/drivers/net/smc91111.c deleted file mode 100644 index 57c667a58..000000000 --- a/qemu/roms/u-boot/drivers/net/smc91111.c +++ /dev/null @@ -1,1355 +0,0 @@ -/*------------------------------------------------------------------------ - . smc91111.c - . This is a driver for SMSC's 91C111 single-chip Ethernet device. - . - . (C) Copyright 2002 - . Sysgo Real-Time Solutions, GmbH <www.elinos.com> - . Rolf Offermanns <rof@sysgo.de> - . - . Copyright (C) 2001 Standard Microsystems Corporation (SMSC) - . Developed by Simple Network Magic Corporation (SNMC) - . Copyright (C) 1996 by Erik Stahlman (ES) - . - * SPDX-License-Identifier: GPL-2.0+ - . - . Information contained in this file was obtained from the LAN91C111 - . manual from SMC. To get a copy, if you really want one, you can find - . information under www.smsc.com. - . - . - . "Features" of the SMC chip: - . Integrated PHY/MAC for 10/100BaseT Operation - . Supports internal and external MII - . Integrated 8K packet memory - . EEPROM interface for configuration - . - . Arguments: - . io = for the base address - . irq = for the IRQ - . - . author: - . Erik Stahlman ( erik@vt.edu ) - . Daris A Nevil ( dnevil@snmc.com ) - . - . - . Hardware multicast code from Peter Cammaert ( pc@denkart.be ) - . - . Sources: - . o SMSC LAN91C111 databook (www.smsc.com) - . o smc9194.c by Erik Stahlman - . o skeleton.c by Donald Becker ( becker@cesdis.gsfc.nasa.gov ) - . - . History: - . 06/19/03 Richard Woodruff Made u-boot environment aware and added mac addr checks. - . 10/17/01 Marco Hasewinkel Modify for DNP/1110 - . 07/25/01 Woojung Huh Modify for ADS Bitsy - . 04/25/01 Daris A Nevil Initial public release through SMSC - . 03/16/01 Daris A Nevil Modified smc9194.c for use with LAN91C111 - ----------------------------------------------------------------------------*/ - -#include <common.h> -#include <command.h> -#include <config.h> -#include <malloc.h> -#include "smc91111.h" -#include <net.h> - -/* Use power-down feature of the chip */ -#define POWER_DOWN 0 - -#define NO_AUTOPROBE - -#define SMC_DEBUG 0 - -#if SMC_DEBUG > 1 -static const char version[] = - "smc91111.c:v1.0 04/25/01 by Daris A Nevil (dnevil@snmc.com)\n"; -#endif - -/* Autonegotiation timeout in seconds */ -#ifndef CONFIG_SMC_AUTONEG_TIMEOUT -#define CONFIG_SMC_AUTONEG_TIMEOUT 10 -#endif - -/*------------------------------------------------------------------------ - . - . Configuration options, for the experienced user to change. - . - -------------------------------------------------------------------------*/ - -/* - . Wait time for memory to be free. This probably shouldn't be - . tuned that much, as waiting for this means nothing else happens - . in the system -*/ -#define MEMORY_WAIT_TIME 16 - - -#if (SMC_DEBUG > 2 ) -#define PRINTK3(args...) printf(args) -#else -#define PRINTK3(args...) -#endif - -#if SMC_DEBUG > 1 -#define PRINTK2(args...) printf(args) -#else -#define PRINTK2(args...) -#endif - -#ifdef SMC_DEBUG -#define PRINTK(args...) printf(args) -#else -#define PRINTK(args...) -#endif - - -/*------------------------------------------------------------------------ - . - . The internal workings of the driver. If you are changing anything - . here with the SMC stuff, you should have the datasheet and know - . what you are doing. - . - -------------------------------------------------------------------------*/ - -/* Memory sizing constant */ -#define LAN91C111_MEMORY_MULTIPLIER (1024*2) - -#ifndef CONFIG_SMC91111_BASE -#error "SMC91111 Base address must be passed to initialization funciton" -/* #define CONFIG_SMC91111_BASE 0x20000300 */ -#endif - -#define SMC_DEV_NAME "SMC91111" -#define SMC_PHY_ADDR 0x0000 -#define SMC_ALLOC_MAX_TRY 5 -#define SMC_TX_TIMEOUT 30 - -#define SMC_PHY_CLOCK_DELAY 1000 - -#define ETH_ZLEN 60 - -#ifdef CONFIG_SMC_USE_32_BIT -#define USE_32_BIT 1 -#else -#undef USE_32_BIT -#endif - -#ifdef SHARED_RESOURCES -extern void swap_to(int device_id); -#else -# define swap_to(x) -#endif - -#ifndef CONFIG_SMC91111_EXT_PHY -static void smc_phy_configure(struct eth_device *dev); -#endif /* !CONFIG_SMC91111_EXT_PHY */ - -/* - ------------------------------------------------------------ - . - . Internal routines - . - ------------------------------------------------------------ -*/ - -#ifdef CONFIG_SMC_USE_IOFUNCS -/* - * input and output functions - * - * Implemented due to inx,outx macros accessing the device improperly - * and putting the device into an unkown state. - * - * For instance, on Sharp LPD7A400 SDK, affects were chip memory - * could not be free'd (hence the alloc failures), duplicate packets, - * packets being corrupt (shifted) on the wire, etc. Switching to the - * inx,outx functions fixed this problem. - */ - -static inline word SMC_inw(struct eth_device *dev, dword offset) -{ - word v; - v = *((volatile word*)(dev->iobase + offset)); - barrier(); *(volatile u32*)(0xc0000000); - return v; -} - -static inline void SMC_outw(struct eth_device *dev, word value, dword offset) -{ - *((volatile word*)(dev->iobase + offset)) = value; - barrier(); *(volatile u32*)(0xc0000000); -} - -static inline byte SMC_inb(struct eth_device *dev, dword offset) -{ - word _w; - - _w = SMC_inw(dev, offset & ~((dword)1)); - return (offset & 1) ? (byte)(_w >> 8) : (byte)(_w); -} - -static inline void SMC_outb(struct eth_device *dev, byte value, dword offset) -{ - word _w; - - _w = SMC_inw(dev, offset & ~((dword)1)); - if (offset & 1) - *((volatile word*)(dev->iobase + (offset & ~((dword)1)))) = - (value<<8) | (_w & 0x00ff); - else - *((volatile word*)(dev->iobase + offset)) = - value | (_w & 0xff00); -} - -static inline void SMC_insw(struct eth_device *dev, dword offset, - volatile uchar* buf, dword len) -{ - volatile word *p = (volatile word *)buf; - - while (len-- > 0) { - *p++ = SMC_inw(dev, offset); - barrier(); - *((volatile u32*)(0xc0000000)); - } -} - -static inline void SMC_outsw(struct eth_device *dev, dword offset, - uchar* buf, dword len) -{ - volatile word *p = (volatile word *)buf; - - while (len-- > 0) { - SMC_outw(dev, *p++, offset); - barrier(); - *(volatile u32*)(0xc0000000); - } -} -#endif /* CONFIG_SMC_USE_IOFUNCS */ - -/* - . A rather simple routine to print out a packet for debugging purposes. -*/ -#if SMC_DEBUG > 2 -static void print_packet( byte *, int ); -#endif - -#define tx_done(dev) 1 - -static int poll4int (struct eth_device *dev, byte mask, int timeout) -{ - int tmo = get_timer (0) + timeout * CONFIG_SYS_HZ; - int is_timeout = 0; - word old_bank = SMC_inw (dev, BSR_REG); - - PRINTK2 ("Polling...\n"); - SMC_SELECT_BANK (dev, 2); - while ((SMC_inw (dev, SMC91111_INT_REG) & mask) == 0) { - if (get_timer (0) >= tmo) { - is_timeout = 1; - break; - } - } - - /* restore old bank selection */ - SMC_SELECT_BANK (dev, old_bank); - - if (is_timeout) - return 1; - else - return 0; -} - -/* Only one release command at a time, please */ -static inline void smc_wait_mmu_release_complete (struct eth_device *dev) -{ - int count = 0; - - /* assume bank 2 selected */ - while (SMC_inw (dev, MMU_CMD_REG) & MC_BUSY) { - udelay (1); /* Wait until not busy */ - if (++count > 200) - break; - } -} - -/* - . Function: smc_reset( void ) - . Purpose: - . This sets the SMC91111 chip to its normal state, hopefully from whatever - . mess that any other DOS driver has put it in. - . - . Maybe I should reset more registers to defaults in here? SOFTRST should - . do that for me. - . - . Method: - . 1. send a SOFT RESET - . 2. wait for it to finish - . 3. enable autorelease mode - . 4. reset the memory management unit - . 5. clear all interrupts - . -*/ -static void smc_reset (struct eth_device *dev) -{ - PRINTK2 ("%s: smc_reset\n", SMC_DEV_NAME); - - /* This resets the registers mostly to defaults, but doesn't - affect EEPROM. That seems unnecessary */ - SMC_SELECT_BANK (dev, 0); - SMC_outw (dev, RCR_SOFTRST, RCR_REG); - - /* Setup the Configuration Register */ - /* This is necessary because the CONFIG_REG is not affected */ - /* by a soft reset */ - - SMC_SELECT_BANK (dev, 1); -#if defined(CONFIG_SMC91111_EXT_PHY) - SMC_outw (dev, CONFIG_DEFAULT | CONFIG_EXT_PHY, CONFIG_REG); -#else - SMC_outw (dev, CONFIG_DEFAULT, CONFIG_REG); -#endif - - - /* Release from possible power-down state */ - /* Configuration register is not affected by Soft Reset */ - SMC_outw (dev, SMC_inw (dev, CONFIG_REG) | CONFIG_EPH_POWER_EN, - CONFIG_REG); - - SMC_SELECT_BANK (dev, 0); - - /* this should pause enough for the chip to be happy */ - udelay (10); - - /* Disable transmit and receive functionality */ - SMC_outw (dev, RCR_CLEAR, RCR_REG); - SMC_outw (dev, TCR_CLEAR, TCR_REG); - - /* set the control register */ - SMC_SELECT_BANK (dev, 1); - SMC_outw (dev, CTL_DEFAULT, CTL_REG); - - /* Reset the MMU */ - SMC_SELECT_BANK (dev, 2); - smc_wait_mmu_release_complete (dev); - SMC_outw (dev, MC_RESET, MMU_CMD_REG); - while (SMC_inw (dev, MMU_CMD_REG) & MC_BUSY) - udelay (1); /* Wait until not busy */ - - /* Note: It doesn't seem that waiting for the MMU busy is needed here, - but this is a place where future chipsets _COULD_ break. Be wary - of issuing another MMU command right after this */ - - /* Disable all interrupts */ - SMC_outb (dev, 0, IM_REG); -} - -/* - . Function: smc_enable - . Purpose: let the chip talk to the outside work - . Method: - . 1. Enable the transmitter - . 2. Enable the receiver - . 3. Enable interrupts -*/ -static void smc_enable(struct eth_device *dev) -{ - PRINTK2("%s: smc_enable\n", SMC_DEV_NAME); - SMC_SELECT_BANK( dev, 0 ); - /* see the header file for options in TCR/RCR DEFAULT*/ - SMC_outw( dev, TCR_DEFAULT, TCR_REG ); - SMC_outw( dev, RCR_DEFAULT, RCR_REG ); - - /* clear MII_DIS */ -/* smc_write_phy_register(PHY_CNTL_REG, 0x0000); */ -} - -/* - . Function: smc_halt - . Purpose: closes down the SMC91xxx chip. - . Method: - . 1. zero the interrupt mask - . 2. clear the enable receive flag - . 3. clear the enable xmit flags - . - . TODO: - . (1) maybe utilize power down mode. - . Why not yet? Because while the chip will go into power down mode, - . the manual says that it will wake up in response to any I/O requests - . in the register space. Empirical results do not show this working. -*/ -static void smc_halt(struct eth_device *dev) -{ - PRINTK2("%s: smc_halt\n", SMC_DEV_NAME); - - /* no more interrupts for me */ - SMC_SELECT_BANK( dev, 2 ); - SMC_outb( dev, 0, IM_REG ); - - /* and tell the card to stay away from that nasty outside world */ - SMC_SELECT_BANK( dev, 0 ); - SMC_outb( dev, RCR_CLEAR, RCR_REG ); - SMC_outb( dev, TCR_CLEAR, TCR_REG ); - - swap_to(FLASH); -} - - -/* - . Function: smc_send(struct net_device * ) - . Purpose: - . This sends the actual packet to the SMC9xxx chip. - . - . Algorithm: - . First, see if a saved_skb is available. - . ( this should NOT be called if there is no 'saved_skb' - . Now, find the packet number that the chip allocated - . Point the data pointers at it in memory - . Set the length word in the chip's memory - . Dump the packet to chip memory - . Check if a last byte is needed ( odd length packet ) - . if so, set the control flag right - . Tell the card to send it - . Enable the transmit interrupt, so I know if it failed - . Free the kernel data if I actually sent it. -*/ -static int smc_send(struct eth_device *dev, void *packet, int packet_length) -{ - byte packet_no; - byte *buf; - int length; - int numPages; - int try = 0; - int time_out; - byte status; - byte saved_pnr; - word saved_ptr; - - /* save PTR and PNR registers before manipulation */ - SMC_SELECT_BANK (dev, 2); - saved_pnr = SMC_inb( dev, PN_REG ); - saved_ptr = SMC_inw( dev, PTR_REG ); - - PRINTK3 ("%s: smc_hardware_send_packet\n", SMC_DEV_NAME); - - length = ETH_ZLEN < packet_length ? packet_length : ETH_ZLEN; - - /* allocate memory - ** The MMU wants the number of pages to be the number of 256 bytes - ** 'pages', minus 1 ( since a packet can't ever have 0 pages :) ) - ** - ** The 91C111 ignores the size bits, but the code is left intact - ** for backwards and future compatibility. - ** - ** Pkt size for allocating is data length +6 (for additional status - ** words, length and ctl!) - ** - ** If odd size then last byte is included in this header. - */ - numPages = ((length & 0xfffe) + 6); - numPages >>= 8; /* Divide by 256 */ - - if (numPages > 7) { - printf ("%s: Far too big packet error. \n", SMC_DEV_NAME); - return 0; - } - - /* now, try to allocate the memory */ - SMC_SELECT_BANK (dev, 2); - SMC_outw (dev, MC_ALLOC | numPages, MMU_CMD_REG); - - /* FIXME: the ALLOC_INT bit never gets set * - * so the following will always give a * - * memory allocation error. * - * same code works in armboot though * - * -ro - */ - -again: - try++; - time_out = MEMORY_WAIT_TIME; - do { - status = SMC_inb (dev, SMC91111_INT_REG); - if (status & IM_ALLOC_INT) { - /* acknowledge the interrupt */ - SMC_outb (dev, IM_ALLOC_INT, SMC91111_INT_REG); - break; - } - } while (--time_out); - - if (!time_out) { - PRINTK2 ("%s: memory allocation, try %d failed ...\n", - SMC_DEV_NAME, try); - if (try < SMC_ALLOC_MAX_TRY) - goto again; - else - return 0; - } - - PRINTK2 ("%s: memory allocation, try %d succeeded ...\n", - SMC_DEV_NAME, try); - - buf = (byte *) packet; - - /* If I get here, I _know_ there is a packet slot waiting for me */ - packet_no = SMC_inb (dev, AR_REG); - if (packet_no & AR_FAILED) { - /* or isn't there? BAD CHIP! */ - printf ("%s: Memory allocation failed. \n", SMC_DEV_NAME); - return 0; - } - - /* we have a packet address, so tell the card to use it */ -#ifndef CONFIG_XAENIAX - SMC_outb (dev, packet_no, PN_REG); -#else - /* On Xaeniax board, we can't use SMC_outb here because that way - * the Allocate MMU command will end up written to the command register - * as well, which will lead to a problem. - */ - SMC_outl (dev, packet_no << 16, 0); -#endif - /* do not write new ptr value if Write data fifo not empty */ - while ( saved_ptr & PTR_NOTEMPTY ) - printf ("Write data fifo not empty!\n"); - - /* point to the beginning of the packet */ - SMC_outw (dev, PTR_AUTOINC, PTR_REG); - - PRINTK3 ("%s: Trying to xmit packet of length %x\n", - SMC_DEV_NAME, length); - -#if SMC_DEBUG > 2 - printf ("Transmitting Packet\n"); - print_packet (buf, length); -#endif - - /* send the packet length ( +6 for status, length and ctl byte ) - and the status word ( set to zeros ) */ -#ifdef USE_32_BIT - SMC_outl (dev, (length + 6) << 16, SMC91111_DATA_REG); -#else - SMC_outw (dev, 0, SMC91111_DATA_REG); - /* send the packet length ( +6 for status words, length, and ctl */ - SMC_outw (dev, (length + 6), SMC91111_DATA_REG); -#endif - - /* send the actual data - . I _think_ it's faster to send the longs first, and then - . mop up by sending the last word. It depends heavily - . on alignment, at least on the 486. Maybe it would be - . a good idea to check which is optimal? But that could take - . almost as much time as is saved? - */ -#ifdef USE_32_BIT - SMC_outsl (dev, SMC91111_DATA_REG, buf, length >> 2); -#ifndef CONFIG_XAENIAX - if (length & 0x2) - SMC_outw (dev, *((word *) (buf + (length & 0xFFFFFFFC))), - SMC91111_DATA_REG); -#else - /* On XANEIAX, we can only use 32-bit writes, so we need to handle - * unaligned tail part specially. The standard code doesn't work. - */ - if ((length & 3) == 3) { - u16 * ptr = (u16*) &buf[length-3]; - SMC_outl(dev, (*ptr) | ((0x2000 | buf[length-1]) << 16), - SMC91111_DATA_REG); - } else if ((length & 2) == 2) { - u16 * ptr = (u16*) &buf[length-2]; - SMC_outl(dev, *ptr, SMC91111_DATA_REG); - } else if (length & 1) { - SMC_outl(dev, (0x2000 | buf[length-1]), SMC91111_DATA_REG); - } else { - SMC_outl(dev, 0, SMC91111_DATA_REG); - } -#endif -#else - SMC_outsw (dev, SMC91111_DATA_REG, buf, (length) >> 1); -#endif /* USE_32_BIT */ - -#ifndef CONFIG_XAENIAX - /* Send the last byte, if there is one. */ - if ((length & 1) == 0) { - SMC_outw (dev, 0, SMC91111_DATA_REG); - } else { - SMC_outw (dev, buf[length - 1] | 0x2000, SMC91111_DATA_REG); - } -#endif - - /* and let the chipset deal with it */ - SMC_outw (dev, MC_ENQUEUE, MMU_CMD_REG); - - /* poll for TX INT */ - /* if (poll4int (dev, IM_TX_INT, SMC_TX_TIMEOUT)) { */ - /* poll for TX_EMPTY INT - autorelease enabled */ - if (poll4int(dev, IM_TX_EMPTY_INT, SMC_TX_TIMEOUT)) { - /* sending failed */ - PRINTK2 ("%s: TX timeout, sending failed...\n", SMC_DEV_NAME); - - /* release packet */ - /* no need to release, MMU does that now */ -#ifdef CONFIG_XAENIAX - SMC_outw (dev, MC_FREEPKT, MMU_CMD_REG); -#endif - - /* wait for MMU getting ready (low) */ - while (SMC_inw (dev, MMU_CMD_REG) & MC_BUSY) { - udelay (10); - } - - PRINTK2 ("MMU ready\n"); - - - return 0; - } else { - /* ack. int */ - SMC_outb (dev, IM_TX_EMPTY_INT, SMC91111_INT_REG); - /* SMC_outb (IM_TX_INT, SMC91111_INT_REG); */ - PRINTK2 ("%s: Sent packet of length %d \n", SMC_DEV_NAME, - length); - - /* release packet */ - /* no need to release, MMU does that now */ -#ifdef CONFIG_XAENIAX - SMC_outw (dev, MC_FREEPKT, MMU_CMD_REG); -#endif - - /* wait for MMU getting ready (low) */ - while (SMC_inw (dev, MMU_CMD_REG) & MC_BUSY) { - udelay (10); - } - - PRINTK2 ("MMU ready\n"); - - - } - - /* restore previously saved registers */ -#ifndef CONFIG_XAENIAX - SMC_outb( dev, saved_pnr, PN_REG ); -#else - /* On Xaeniax board, we can't use SMC_outb here because that way - * the Allocate MMU command will end up written to the command register - * as well, which will lead to a problem. - */ - SMC_outl(dev, saved_pnr << 16, 0); -#endif - SMC_outw( dev, saved_ptr, PTR_REG ); - - return length; -} - -static int smc_write_hwaddr(struct eth_device *dev) -{ - int i; - - swap_to(ETHERNET); - SMC_SELECT_BANK (dev, 1); -#ifdef USE_32_BIT - for (i = 0; i < 6; i += 2) { - word address; - - address = dev->enetaddr[i + 1] << 8; - address |= dev->enetaddr[i]; - SMC_outw(dev, address, (ADDR0_REG + i)); - } -#else - for (i = 0; i < 6; i++) - SMC_outb(dev, dev->enetaddr[i], (ADDR0_REG + i)); -#endif - swap_to(FLASH); - return 0; -} - -/* - * Open and Initialize the board - * - * Set up everything, reset the card, etc .. - * - */ -static int smc_init(struct eth_device *dev, bd_t *bd) -{ - swap_to(ETHERNET); - - PRINTK2 ("%s: smc_init\n", SMC_DEV_NAME); - - /* reset the hardware */ - smc_reset (dev); - smc_enable (dev); - - /* Configure the PHY */ -#ifndef CONFIG_SMC91111_EXT_PHY - smc_phy_configure (dev); -#endif - - /* conservative setting (10Mbps, HalfDuplex, no AutoNeg.) */ -/* SMC_SELECT_BANK(dev, 0); */ -/* SMC_outw(dev, 0, RPC_REG); */ - - printf(SMC_DEV_NAME ": MAC %pM\n", dev->enetaddr); - - return 0; -} - -/*------------------------------------------------------------- - . - . smc_rcv - receive a packet from the card - . - . There is ( at least ) a packet waiting to be read from - . chip-memory. - . - . o Read the status - . o If an error, record it - . o otherwise, read in the packet - -------------------------------------------------------------- -*/ -static int smc_rcv(struct eth_device *dev) -{ - int packet_number; - word status; - word packet_length; - int is_error = 0; -#ifdef USE_32_BIT - dword stat_len; -#endif - byte saved_pnr; - word saved_ptr; - - SMC_SELECT_BANK(dev, 2); - /* save PTR and PTR registers */ - saved_pnr = SMC_inb( dev, PN_REG ); - saved_ptr = SMC_inw( dev, PTR_REG ); - - packet_number = SMC_inw( dev, RXFIFO_REG ); - - if ( packet_number & RXFIFO_REMPTY ) { - - return 0; - } - - PRINTK3("%s: smc_rcv\n", SMC_DEV_NAME); - /* start reading from the start of the packet */ - SMC_outw( dev, PTR_READ | PTR_RCV | PTR_AUTOINC, PTR_REG ); - - /* First two words are status and packet_length */ -#ifdef USE_32_BIT - stat_len = SMC_inl(dev, SMC91111_DATA_REG); - status = stat_len & 0xffff; - packet_length = stat_len >> 16; -#else - status = SMC_inw( dev, SMC91111_DATA_REG ); - packet_length = SMC_inw( dev, SMC91111_DATA_REG ); -#endif - - packet_length &= 0x07ff; /* mask off top bits */ - - PRINTK2("RCV: STATUS %4x LENGTH %4x\n", status, packet_length ); - - if ( !(status & RS_ERRORS ) ){ - /* Adjust for having already read the first two words */ - packet_length -= 4; /*4; */ - - - /* set odd length for bug in LAN91C111, */ - /* which never sets RS_ODDFRAME */ - /* TODO ? */ - - -#ifdef USE_32_BIT - PRINTK3(" Reading %d dwords (and %d bytes) \n", - packet_length >> 2, packet_length & 3 ); - /* QUESTION: Like in the TX routine, do I want - to send the DWORDs or the bytes first, or some - mixture. A mixture might improve already slow PIO - performance */ - SMC_insl( dev, SMC91111_DATA_REG, NetRxPackets[0], - packet_length >> 2 ); - /* read the left over bytes */ - if (packet_length & 3) { - int i; - - byte *tail = (byte *)(NetRxPackets[0] + - (packet_length & ~3)); - dword leftover = SMC_inl(dev, SMC91111_DATA_REG); - for (i=0; i<(packet_length & 3); i++) - *tail++ = (byte) (leftover >> (8*i)) & 0xff; - } -#else - PRINTK3(" Reading %d words and %d byte(s) \n", - (packet_length >> 1 ), packet_length & 1 ); - SMC_insw(dev, SMC91111_DATA_REG , NetRxPackets[0], - packet_length >> 1); - -#endif /* USE_32_BIT */ - -#if SMC_DEBUG > 2 - printf("Receiving Packet\n"); - print_packet( NetRxPackets[0], packet_length ); -#endif - } else { - /* error ... */ - /* TODO ? */ - is_error = 1; - } - - while ( SMC_inw( dev, MMU_CMD_REG ) & MC_BUSY ) - udelay(1); /* Wait until not busy */ - - /* error or good, tell the card to get rid of this packet */ - SMC_outw( dev, MC_RELEASE, MMU_CMD_REG ); - - while ( SMC_inw( dev, MMU_CMD_REG ) & MC_BUSY ) - udelay(1); /* Wait until not busy */ - - /* restore saved registers */ -#ifndef CONFIG_XAENIAX - SMC_outb( dev, saved_pnr, PN_REG ); -#else - /* On Xaeniax board, we can't use SMC_outb here because that way - * the Allocate MMU command will end up written to the command register - * as well, which will lead to a problem. - */ - SMC_outl( dev, saved_pnr << 16, 0); -#endif - SMC_outw( dev, saved_ptr, PTR_REG ); - - if (!is_error) { - /* Pass the packet up to the protocol layers. */ - NetReceive(NetRxPackets[0], packet_length); - return packet_length; - } else { - return 0; - } - -} - - -#if 0 -/*------------------------------------------------------------ - . Modify a bit in the LAN91C111 register set - .-------------------------------------------------------------*/ -static word smc_modify_regbit(struct eth_device *dev, int bank, int ioaddr, int reg, - unsigned int bit, int val) -{ - word regval; - - SMC_SELECT_BANK( dev, bank ); - - regval = SMC_inw( dev, reg ); - if (val) - regval |= bit; - else - regval &= ~bit; - - SMC_outw( dev, regval, 0 ); - return(regval); -} - - -/*------------------------------------------------------------ - . Retrieve a bit in the LAN91C111 register set - .-------------------------------------------------------------*/ -static int smc_get_regbit(struct eth_device *dev, int bank, int ioaddr, int reg, unsigned int bit) -{ - SMC_SELECT_BANK( dev, bank ); - if ( SMC_inw( dev, reg ) & bit) - return(1); - else - return(0); -} - - -/*------------------------------------------------------------ - . Modify a LAN91C111 register (word access only) - .-------------------------------------------------------------*/ -static void smc_modify_reg(struct eth_device *dev, int bank, int ioaddr, int reg, word val) -{ - SMC_SELECT_BANK( dev, bank ); - SMC_outw( dev, val, reg ); -} - - -/*------------------------------------------------------------ - . Retrieve a LAN91C111 register (word access only) - .-------------------------------------------------------------*/ -static int smc_get_reg(struct eth_device *dev, int bank, int ioaddr, int reg) -{ - SMC_SELECT_BANK( dev, bank ); - return(SMC_inw( dev, reg )); -} - -#endif /* 0 */ - -/*---PHY CONTROL AND CONFIGURATION----------------------------------------- */ - -#if (SMC_DEBUG > 2 ) - -/*------------------------------------------------------------ - . Debugging function for viewing MII Management serial bitstream - .-------------------------------------------------------------*/ -static void smc_dump_mii_stream (byte * bits, int size) -{ - int i; - - printf ("BIT#:"); - for (i = 0; i < size; ++i) { - printf ("%d", i % 10); - } - - printf ("\nMDOE:"); - for (i = 0; i < size; ++i) { - if (bits[i] & MII_MDOE) - printf ("1"); - else - printf ("0"); - } - - printf ("\nMDO :"); - for (i = 0; i < size; ++i) { - if (bits[i] & MII_MDO) - printf ("1"); - else - printf ("0"); - } - - printf ("\nMDI :"); - for (i = 0; i < size; ++i) { - if (bits[i] & MII_MDI) - printf ("1"); - else - printf ("0"); - } - - printf ("\n"); -} -#endif - -/*------------------------------------------------------------ - . Reads a register from the MII Management serial interface - .-------------------------------------------------------------*/ -#ifndef CONFIG_SMC91111_EXT_PHY -static word smc_read_phy_register (struct eth_device *dev, byte phyreg) -{ - int oldBank; - int i; - byte mask; - word mii_reg; - byte bits[64]; - int clk_idx = 0; - int input_idx; - word phydata; - byte phyaddr = SMC_PHY_ADDR; - - /* 32 consecutive ones on MDO to establish sync */ - for (i = 0; i < 32; ++i) - bits[clk_idx++] = MII_MDOE | MII_MDO; - - /* Start code <01> */ - bits[clk_idx++] = MII_MDOE; - bits[clk_idx++] = MII_MDOE | MII_MDO; - - /* Read command <10> */ - bits[clk_idx++] = MII_MDOE | MII_MDO; - bits[clk_idx++] = MII_MDOE; - - /* Output the PHY address, msb first */ - mask = (byte) 0x10; - for (i = 0; i < 5; ++i) { - if (phyaddr & mask) - bits[clk_idx++] = MII_MDOE | MII_MDO; - else - bits[clk_idx++] = MII_MDOE; - - /* Shift to next lowest bit */ - mask >>= 1; - } - - /* Output the phy register number, msb first */ - mask = (byte) 0x10; - for (i = 0; i < 5; ++i) { - if (phyreg & mask) - bits[clk_idx++] = MII_MDOE | MII_MDO; - else - bits[clk_idx++] = MII_MDOE; - - /* Shift to next lowest bit */ - mask >>= 1; - } - - /* Tristate and turnaround (2 bit times) */ - bits[clk_idx++] = 0; - /*bits[clk_idx++] = 0; */ - - /* Input starts at this bit time */ - input_idx = clk_idx; - - /* Will input 16 bits */ - for (i = 0; i < 16; ++i) - bits[clk_idx++] = 0; - - /* Final clock bit */ - bits[clk_idx++] = 0; - - /* Save the current bank */ - oldBank = SMC_inw (dev, BANK_SELECT); - - /* Select bank 3 */ - SMC_SELECT_BANK (dev, 3); - - /* Get the current MII register value */ - mii_reg = SMC_inw (dev, MII_REG); - - /* Turn off all MII Interface bits */ - mii_reg &= ~(MII_MDOE | MII_MCLK | MII_MDI | MII_MDO); - - /* Clock all 64 cycles */ - for (i = 0; i < sizeof bits; ++i) { - /* Clock Low - output data */ - SMC_outw (dev, mii_reg | bits[i], MII_REG); - udelay (SMC_PHY_CLOCK_DELAY); - - - /* Clock Hi - input data */ - SMC_outw (dev, mii_reg | bits[i] | MII_MCLK, MII_REG); - udelay (SMC_PHY_CLOCK_DELAY); - bits[i] |= SMC_inw (dev, MII_REG) & MII_MDI; - } - - /* Return to idle state */ - /* Set clock to low, data to low, and output tristated */ - SMC_outw (dev, mii_reg, MII_REG); - udelay (SMC_PHY_CLOCK_DELAY); - - /* Restore original bank select */ - SMC_SELECT_BANK (dev, oldBank); - - /* Recover input data */ - phydata = 0; - for (i = 0; i < 16; ++i) { - phydata <<= 1; - - if (bits[input_idx++] & MII_MDI) - phydata |= 0x0001; - } - -#if (SMC_DEBUG > 2 ) - printf ("smc_read_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n", - phyaddr, phyreg, phydata); - smc_dump_mii_stream (bits, sizeof bits); -#endif - - return (phydata); -} - - -/*------------------------------------------------------------ - . Writes a register to the MII Management serial interface - .-------------------------------------------------------------*/ -static void smc_write_phy_register (struct eth_device *dev, byte phyreg, - word phydata) -{ - int oldBank; - int i; - word mask; - word mii_reg; - byte bits[65]; - int clk_idx = 0; - byte phyaddr = SMC_PHY_ADDR; - - /* 32 consecutive ones on MDO to establish sync */ - for (i = 0; i < 32; ++i) - bits[clk_idx++] = MII_MDOE | MII_MDO; - - /* Start code <01> */ - bits[clk_idx++] = MII_MDOE; - bits[clk_idx++] = MII_MDOE | MII_MDO; - - /* Write command <01> */ - bits[clk_idx++] = MII_MDOE; - bits[clk_idx++] = MII_MDOE | MII_MDO; - - /* Output the PHY address, msb first */ - mask = (byte) 0x10; - for (i = 0; i < 5; ++i) { - if (phyaddr & mask) - bits[clk_idx++] = MII_MDOE | MII_MDO; - else - bits[clk_idx++] = MII_MDOE; - - /* Shift to next lowest bit */ - mask >>= 1; - } - - /* Output the phy register number, msb first */ - mask = (byte) 0x10; - for (i = 0; i < 5; ++i) { - if (phyreg & mask) - bits[clk_idx++] = MII_MDOE | MII_MDO; - else - bits[clk_idx++] = MII_MDOE; - - /* Shift to next lowest bit */ - mask >>= 1; - } - - /* Tristate and turnaround (2 bit times) */ - bits[clk_idx++] = 0; - bits[clk_idx++] = 0; - - /* Write out 16 bits of data, msb first */ - mask = 0x8000; - for (i = 0; i < 16; ++i) { - if (phydata & mask) - bits[clk_idx++] = MII_MDOE | MII_MDO; - else - bits[clk_idx++] = MII_MDOE; - - /* Shift to next lowest bit */ - mask >>= 1; - } - - /* Final clock bit (tristate) */ - bits[clk_idx++] = 0; - - /* Save the current bank */ - oldBank = SMC_inw (dev, BANK_SELECT); - - /* Select bank 3 */ - SMC_SELECT_BANK (dev, 3); - - /* Get the current MII register value */ - mii_reg = SMC_inw (dev, MII_REG); - - /* Turn off all MII Interface bits */ - mii_reg &= ~(MII_MDOE | MII_MCLK | MII_MDI | MII_MDO); - - /* Clock all cycles */ - for (i = 0; i < sizeof bits; ++i) { - /* Clock Low - output data */ - SMC_outw (dev, mii_reg | bits[i], MII_REG); - udelay (SMC_PHY_CLOCK_DELAY); - - - /* Clock Hi - input data */ - SMC_outw (dev, mii_reg | bits[i] | MII_MCLK, MII_REG); - udelay (SMC_PHY_CLOCK_DELAY); - bits[i] |= SMC_inw (dev, MII_REG) & MII_MDI; - } - - /* Return to idle state */ - /* Set clock to low, data to low, and output tristated */ - SMC_outw (dev, mii_reg, MII_REG); - udelay (SMC_PHY_CLOCK_DELAY); - - /* Restore original bank select */ - SMC_SELECT_BANK (dev, oldBank); - -#if (SMC_DEBUG > 2 ) - printf ("smc_write_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n", - phyaddr, phyreg, phydata); - smc_dump_mii_stream (bits, sizeof bits); -#endif -} -#endif /* !CONFIG_SMC91111_EXT_PHY */ - - -/*------------------------------------------------------------ - . Configures the specified PHY using Autonegotiation. Calls - . smc_phy_fixed() if the user has requested a certain config. - .-------------------------------------------------------------*/ -#ifndef CONFIG_SMC91111_EXT_PHY -static void smc_phy_configure (struct eth_device *dev) -{ - int timeout; - word my_phy_caps; /* My PHY capabilities */ - word my_ad_caps; /* My Advertised capabilities */ - word status = 0; /*;my status = 0 */ - - PRINTK3 ("%s: smc_program_phy()\n", SMC_DEV_NAME); - - /* Reset the PHY, setting all other bits to zero */ - smc_write_phy_register (dev, PHY_CNTL_REG, PHY_CNTL_RST); - - /* Wait for the reset to complete, or time out */ - timeout = 6; /* Wait up to 3 seconds */ - while (timeout--) { - if (!(smc_read_phy_register (dev, PHY_CNTL_REG) - & PHY_CNTL_RST)) { - /* reset complete */ - break; - } - - mdelay(500); /* wait 500 millisecs */ - } - - if (timeout < 1) { - printf ("%s:PHY reset timed out\n", SMC_DEV_NAME); - goto smc_phy_configure_exit; - } - - /* Read PHY Register 18, Status Output */ - /* lp->lastPhy18 = smc_read_phy_register(PHY_INT_REG); */ - - /* Enable PHY Interrupts (for register 18) */ - /* Interrupts listed here are disabled */ - smc_write_phy_register (dev, PHY_MASK_REG, 0xffff); - - /* Configure the Receive/Phy Control register */ - SMC_SELECT_BANK (dev, 0); - SMC_outw (dev, RPC_DEFAULT, RPC_REG); - - /* Copy our capabilities from PHY_STAT_REG to PHY_AD_REG */ - my_phy_caps = smc_read_phy_register (dev, PHY_STAT_REG); - my_ad_caps = PHY_AD_CSMA; /* I am CSMA capable */ - - if (my_phy_caps & PHY_STAT_CAP_T4) - my_ad_caps |= PHY_AD_T4; - - if (my_phy_caps & PHY_STAT_CAP_TXF) - my_ad_caps |= PHY_AD_TX_FDX; - - if (my_phy_caps & PHY_STAT_CAP_TXH) - my_ad_caps |= PHY_AD_TX_HDX; - - if (my_phy_caps & PHY_STAT_CAP_TF) - my_ad_caps |= PHY_AD_10_FDX; - - if (my_phy_caps & PHY_STAT_CAP_TH) - my_ad_caps |= PHY_AD_10_HDX; - - /* Update our Auto-Neg Advertisement Register */ - smc_write_phy_register (dev, PHY_AD_REG, my_ad_caps); - - /* Read the register back. Without this, it appears that when */ - /* auto-negotiation is restarted, sometimes it isn't ready and */ - /* the link does not come up. */ - smc_read_phy_register(dev, PHY_AD_REG); - - PRINTK2 ("%s: phy caps=%x\n", SMC_DEV_NAME, my_phy_caps); - PRINTK2 ("%s: phy advertised caps=%x\n", SMC_DEV_NAME, my_ad_caps); - - /* Restart auto-negotiation process in order to advertise my caps */ - smc_write_phy_register (dev, PHY_CNTL_REG, - PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST); - - /* Wait for the auto-negotiation to complete. This may take from */ - /* 2 to 3 seconds. */ - /* Wait for the reset to complete, or time out */ - timeout = CONFIG_SMC_AUTONEG_TIMEOUT * 2; - while (timeout--) { - - status = smc_read_phy_register (dev, PHY_STAT_REG); - if (status & PHY_STAT_ANEG_ACK) { - /* auto-negotiate complete */ - break; - } - - mdelay(500); /* wait 500 millisecs */ - - /* Restart auto-negotiation if remote fault */ - if (status & PHY_STAT_REM_FLT) { - printf ("%s: PHY remote fault detected\n", - SMC_DEV_NAME); - - /* Restart auto-negotiation */ - printf ("%s: PHY restarting auto-negotiation\n", - SMC_DEV_NAME); - smc_write_phy_register (dev, PHY_CNTL_REG, - PHY_CNTL_ANEG_EN | - PHY_CNTL_ANEG_RST | - PHY_CNTL_SPEED | - PHY_CNTL_DPLX); - } - } - - if (timeout < 1) { - printf ("%s: PHY auto-negotiate timed out\n", SMC_DEV_NAME); - } - - /* Fail if we detected an auto-negotiate remote fault */ - if (status & PHY_STAT_REM_FLT) { - printf ("%s: PHY remote fault detected\n", SMC_DEV_NAME); - } - - /* Re-Configure the Receive/Phy Control register */ - SMC_outw (dev, RPC_DEFAULT, RPC_REG); - -smc_phy_configure_exit: ; - -} -#endif /* !CONFIG_SMC91111_EXT_PHY */ - - -#if SMC_DEBUG > 2 -static void print_packet( byte * buf, int length ) -{ - int i; - int remainder; - int lines; - - printf("Packet of length %d \n", length ); - -#if SMC_DEBUG > 3 - lines = length / 16; - remainder = length % 16; - - for ( i = 0; i < lines ; i ++ ) { - int cur; - - for ( cur = 0; cur < 8; cur ++ ) { - byte a, b; - - a = *(buf ++ ); - b = *(buf ++ ); - printf("%02x%02x ", a, b ); - } - printf("\n"); - } - for ( i = 0; i < remainder/2 ; i++ ) { - byte a, b; - - a = *(buf ++ ); - b = *(buf ++ ); - printf("%02x%02x ", a, b ); - } - printf("\n"); -#endif -} -#endif - -int smc91111_initialize(u8 dev_num, int base_addr) -{ - struct smc91111_priv *priv; - struct eth_device *dev; - int i; - - priv = malloc(sizeof(*priv)); - if (!priv) - return 0; - dev = malloc(sizeof(*dev)); - if (!dev) { - free(priv); - return 0; - } - - memset(dev, 0, sizeof(*dev)); - priv->dev_num = dev_num; - dev->priv = priv; - dev->iobase = base_addr; - - swap_to(ETHERNET); - SMC_SELECT_BANK(dev, 1); - for (i = 0; i < 6; ++i) - dev->enetaddr[i] = SMC_inb(dev, (ADDR0_REG + i)); - swap_to(FLASH); - - dev->init = smc_init; - dev->halt = smc_halt; - dev->send = smc_send; - dev->recv = smc_rcv; - dev->write_hwaddr = smc_write_hwaddr; - sprintf(dev->name, "%s-%hu", SMC_DEV_NAME, dev_num); - - eth_register(dev); - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/smc91111.h b/qemu/roms/u-boot/drivers/net/smc91111.h deleted file mode 100644 index d9135cb57..000000000 --- a/qemu/roms/u-boot/drivers/net/smc91111.h +++ /dev/null @@ -1,789 +0,0 @@ -/*------------------------------------------------------------------------ - . smc91111.h - macros for the LAN91C111 Ethernet Driver - . - . (C) Copyright 2002 - . Sysgo Real-Time Solutions, GmbH <www.elinos.com> - . Rolf Offermanns <rof@sysgo.de> - . Copyright (C) 2001 Standard Microsystems Corporation (SMSC) - . Developed by Simple Network Magic Corporation (SNMC) - . Copyright (C) 1996 by Erik Stahlman (ES) - . - * SPDX-License-Identifier: GPL-2.0+ - . - . This file contains register information and access macros for - . the LAN91C111 single chip ethernet controller. It is a modified - . version of the smc9194.h file. - . - . Information contained in this file was obtained from the LAN91C111 - . manual from SMC. To get a copy, if you really want one, you can find - . information under www.smsc.com. - . - . Authors - . Erik Stahlman ( erik@vt.edu ) - . Daris A Nevil ( dnevil@snmc.com ) - . - . History - . 03/16/01 Daris A Nevil Modified for use with LAN91C111 device - . - ---------------------------------------------------------------------------*/ -#ifndef _SMC91111_H_ -#define _SMC91111_H_ - -#include <asm/types.h> -#include <config.h> - -/* - * This function may be called by the board specific initialisation code - * in order to override the default mac address. - */ - -void smc_set_mac_addr (const unsigned char *addr); - - -/* I want some simple types */ - -typedef unsigned char byte; -typedef unsigned short word; -typedef unsigned long int dword; - -struct smc91111_priv{ - u8 dev_num; -}; - -/* - . DEBUGGING LEVELS - . - . 0 for normal operation - . 1 for slightly more details - . >2 for various levels of increasingly useless information - . 2 for interrupt tracking, status flags - . 3 for packet info - . 4 for complete packet dumps -*/ -/*#define SMC_DEBUG 0 */ - -/* Because of bank switching, the LAN91xxx uses only 16 I/O ports */ - -#define SMC_IO_EXTENT 16 - -#ifdef CONFIG_CPU_PXA25X - -#ifdef CONFIG_XSENGINE -#define SMC_inl(a,r) (*((volatile dword *)((a)->iobase+((r)<<1)))) -#define SMC_inw(a,r) (*((volatile word *)((a)->iobase+((r)<<1)))) -#define SMC_inb(a,p) ({ \ - unsigned int __p = (unsigned int)((a)->iobase + ((p)<<1)); \ - unsigned int __v = *(volatile unsigned short *)((__p) & ~2); \ - if (__p & 2) __v >>= 8; \ - else __v &= 0xff; \ - __v; }) -#elif defined(CONFIG_XAENIAX) -#define SMC_inl(a,r) (*((volatile dword *)((a)->iobase+(r)))) -#define SMC_inw(a,z) ({ \ - unsigned int __p = (unsigned int)((a)->iobase + (z)); \ - unsigned int __v = *(volatile unsigned int *)((__p) & ~3); \ - if (__p & 3) __v >>= 16; \ - else __v &= 0xffff; \ - __v; }) -#define SMC_inb(a,p) ({ \ - unsigned int ___v = SMC_inw((a),(p) & ~1); \ - if ((p) & 1) ___v >>= 8; \ - else ___v &= 0xff; \ - ___v; }) -#else -#define SMC_inl(a,r) (*((volatile dword *)((a)->iobase+(r)))) -#define SMC_inw(a,r) (*((volatile word *)((a)->iobase+(r)))) -#define SMC_inb(a,p) ({ \ - unsigned int __p = (unsigned int)((a)->iobase + (p)); \ - unsigned int __v = *(volatile unsigned short *)((__p) & ~1); \ - if (__p & 1) __v >>= 8; \ - else __v &= 0xff; \ - __v; }) -#endif - -#ifdef CONFIG_XSENGINE -#define SMC_outl(a,d,r) (*((volatile dword *)((a)->iobase+(r<<1))) = d) -#define SMC_outw(a,d,r) (*((volatile word *)((a)->iobase+(r<<1))) = d) -#elif defined (CONFIG_XAENIAX) -#define SMC_outl(a,d,r) (*((volatile dword *)((a)->iobase+(r))) = d) -#define SMC_outw(a,d,p) ({ \ - dword __dwo = SMC_inl((a),(p) & ~3); \ - dword __dwn = (word)(d); \ - __dwo &= ((p) & 3) ? 0x0000ffff : 0xffff0000; \ - __dwo |= ((p) & 3) ? __dwn << 16 : __dwn; \ - SMC_outl((a), __dwo, (p) & ~3); \ -}) -#else -#define SMC_outl(a,d,r) (*((volatile dword *)((a)->iobase+(r))) = d) -#define SMC_outw(a,d,r) (*((volatile word *)((a)->iobase+(r))) = d) -#endif - -#define SMC_outb(a,d,r) ({ word __d = (byte)(d); \ - word __w = SMC_inw((a),(r)&~1); \ - __w &= ((r)&1) ? 0x00FF : 0xFF00; \ - __w |= ((r)&1) ? __d<<8 : __d; \ - SMC_outw((a),__w,(r)&~1); \ - }) - -#define SMC_outsl(a,r,b,l) ({ int __i; \ - dword *__b2; \ - __b2 = (dword *) b; \ - for (__i = 0; __i < l; __i++) { \ - SMC_outl((a), *(__b2 + __i), r); \ - } \ - }) - -#define SMC_outsw(a,r,b,l) ({ int __i; \ - word *__b2; \ - __b2 = (word *) b; \ - for (__i = 0; __i < l; __i++) { \ - SMC_outw((a), *(__b2 + __i), r); \ - } \ - }) - -#define SMC_insl(a,r,b,l) ({ int __i ; \ - dword *__b2; \ - __b2 = (dword *) b; \ - for (__i = 0; __i < l; __i++) { \ - *(__b2 + __i) = SMC_inl((a),(r)); \ - SMC_inl((a),0); \ - }; \ - }) - -#define SMC_insw(a,r,b,l) ({ int __i ; \ - word *__b2; \ - __b2 = (word *) b; \ - for (__i = 0; __i < l; __i++) { \ - *(__b2 + __i) = SMC_inw((a),(r)); \ - SMC_inw((a),0); \ - }; \ - }) - -#define SMC_insb(a,r,b,l) ({ int __i ; \ - byte *__b2; \ - __b2 = (byte *) b; \ - for (__i = 0; __i < l; __i++) { \ - *(__b2 + __i) = SMC_inb((a),(r)); \ - SMC_inb((a),0); \ - }; \ - }) - -#elif defined(CONFIG_LEON) /* if not CONFIG_CPU_PXA25X */ - -#define SMC_LEON_SWAP16(_x_) ({ word _x = (_x_); ((_x << 8) | (_x >> 8)); }) - -#define SMC_LEON_SWAP32(_x_) \ - ({ dword _x = (_x_); \ - ((_x << 24) | \ - ((0x0000FF00UL & _x) << 8) | \ - ((0x00FF0000UL & _x) >> 8) | \ - (_x >> 24)); }) - -#define SMC_inl(a,r) (SMC_LEON_SWAP32((*(volatile dword *)((a)->iobase+((r)<<0))))) -#define SMC_inl_nosw(a,r) ((*(volatile dword *)((a)->iobase+((r)<<0)))) -#define SMC_inw(a,r) (SMC_LEON_SWAP16((*(volatile word *)((a)->iobase+((r)<<0))))) -#define SMC_inw_nosw(a,r) ((*(volatile word *)((a)->iobase+((r)<<0)))) -#define SMC_inb(a,p) ({ \ - word ___v = SMC_inw((a),(p) & ~1); \ - if ((p) & 1) ___v >>= 8; \ - else ___v &= 0xff; \ - ___v; }) - -#define SMC_outl(a,d,r) (*(volatile dword *)((a)->iobase+((r)<<0))=SMC_LEON_SWAP32(d)) -#define SMC_outl_nosw(a,d,r) (*(volatile dword *)((a)->iobase+((r)<<0))=(d)) -#define SMC_outw(a,d,r) (*(volatile word *)((a)->iobase+((r)<<0))=SMC_LEON_SWAP16(d)) -#define SMC_outw_nosw(a,d,r) (*(volatile word *)((a)->iobase+((r)<<0))=(d)) -#define SMC_outb(a,d,r) do{ word __d = (byte)(d); \ - word __w = SMC_inw((a),(r)&~1); \ - __w &= ((r)&1) ? 0x00FF : 0xFF00; \ - __w |= ((r)&1) ? __d<<8 : __d; \ - SMC_outw((a),__w,(r)&~1); \ - }while(0) -#define SMC_outsl(a,r,b,l) do{ int __i; \ - dword *__b2; \ - __b2 = (dword *) b; \ - for (__i = 0; __i < l; __i++) { \ - SMC_outl_nosw((a), *(__b2 + __i), r); \ - } \ - }while(0) -#define SMC_outsw(a,r,b,l) do{ int __i; \ - word *__b2; \ - __b2 = (word *) b; \ - for (__i = 0; __i < l; __i++) { \ - SMC_outw_nosw((a), *(__b2 + __i), r); \ - } \ - }while(0) -#define SMC_insl(a,r,b,l) do{ int __i ; \ - dword *__b2; \ - __b2 = (dword *) b; \ - for (__i = 0; __i < l; __i++) { \ - *(__b2 + __i) = SMC_inl_nosw((a),(r)); \ - }; \ - }while(0) - -#define SMC_insw(a,r,b,l) do{ int __i ; \ - word *__b2; \ - __b2 = (word *) b; \ - for (__i = 0; __i < l; __i++) { \ - *(__b2 + __i) = SMC_inw_nosw((a),(r)); \ - }; \ - }while(0) - -#define SMC_insb(a,r,b,l) do{ int __i ; \ - byte *__b2; \ - __b2 = (byte *) b; \ - for (__i = 0; __i < l; __i++) { \ - *(__b2 + __i) = SMC_inb((a),(r)); \ - }; \ - }while(0) - -#else /* if not CONFIG_CPU_PXA25X and not CONFIG_LEON */ - -#ifndef CONFIG_SMC_USE_IOFUNCS /* these macros don't work on some boards */ -/* - * We have only 16 Bit PCMCIA access on Socket 0 - */ - -#ifdef CONFIG_ADNPESC1 -#define SMC_inw(a,r) (*((volatile word *)((a)->iobase+((r)<<1)))) -#elif CONFIG_BLACKFIN -#define SMC_inw(a,r) ({ word __v = (*((volatile word *)((a)->iobase+(r)))); SSYNC(); __v;}) -#elif CONFIG_ARM64 -#define SMC_inw(a, r) (*((volatile word*)((a)->iobase+((dword)(r))))) -#else -#define SMC_inw(a, r) (*((volatile word*)((a)->iobase+(r)))) -#endif -#define SMC_inb(a,r) (((r)&1) ? SMC_inw((a),(r)&~1)>>8 : SMC_inw((a),(r)&0xFF)) - -#ifdef CONFIG_ADNPESC1 -#define SMC_outw(a,d,r) (*((volatile word *)((a)->iobase+((r)<<1))) = d) -#elif CONFIG_BLACKFIN -#define SMC_outw(a, d, r) \ - ({ (*((volatile word*)((a)->iobase+((r)))) = d); \ - SSYNC(); \ - }) -#elif CONFIG_ARM64 -#define SMC_outw(a, d, r) \ - (*((volatile word*)((a)->iobase+((dword)(r)))) = d) -#else -#define SMC_outw(a, d, r) \ - (*((volatile word*)((a)->iobase+(r))) = d) -#endif -#define SMC_outb(a,d,r) ({ word __d = (byte)(d); \ - word __w = SMC_inw((a),(r)&~1); \ - __w &= ((r)&1) ? 0x00FF : 0xFF00; \ - __w |= ((r)&1) ? __d<<8 : __d; \ - SMC_outw((a),__w,(r)&~1); \ - }) -#if 0 -#define SMC_outsw(a,r,b,l) outsw((a)->iobase+(r), (b), (l)) -#else -#define SMC_outsw(a,r,b,l) ({ int __i; \ - word *__b2; \ - __b2 = (word *) b; \ - for (__i = 0; __i < l; __i++) { \ - SMC_outw((a), *(__b2 + __i), r); \ - } \ - }) -#endif - -#if 0 -#define SMC_insw(a,r,b,l) insw((a)->iobase+(r), (b), (l)) -#else -#define SMC_insw(a,r,b,l) ({ int __i ; \ - word *__b2; \ - __b2 = (word *) b; \ - for (__i = 0; __i < l; __i++) { \ - *(__b2 + __i) = SMC_inw((a),(r)); \ - SMC_inw((a),0); \ - }; \ - }) -#endif - -#endif /* CONFIG_SMC_USE_IOFUNCS */ - -#if defined(CONFIG_SMC_USE_32_BIT) - -#ifdef CONFIG_XSENGINE -#define SMC_inl(a,r) (*((volatile dword *)((a)->iobase+(r<<1)))) -#else -#define SMC_inl(a,r) (*((volatile dword *)((a)->iobase+(r)))) -#endif - -#define SMC_insl(a,r,b,l) ({ int __i ; \ - dword *__b2; \ - __b2 = (dword *) b; \ - for (__i = 0; __i < l; __i++) { \ - *(__b2 + __i) = SMC_inl((a),(r)); \ - SMC_inl((a),0); \ - }; \ - }) - -#ifdef CONFIG_XSENGINE -#define SMC_outl(a,d,r) (*((volatile dword *)((a)->iobase+(r<<1))) = d) -#else -#define SMC_outl(a,d,r) (*((volatile dword *)((a)->iobase+(r))) = d) -#endif -#define SMC_outsl(a,r,b,l) ({ int __i; \ - dword *__b2; \ - __b2 = (dword *) b; \ - for (__i = 0; __i < l; __i++) { \ - SMC_outl((a), *(__b2 + __i), r); \ - } \ - }) - -#endif /* CONFIG_SMC_USE_32_BIT */ - -#endif - -/*--------------------------------------------------------------- - . - . A description of the SMSC registers is probably in order here, - . although for details, the SMC datasheet is invaluable. - . - . Basically, the chip has 4 banks of registers ( 0 to 3 ), which - . are accessed by writing a number into the BANK_SELECT register - . ( I also use a SMC_SELECT_BANK macro for this ). - . - . The banks are configured so that for most purposes, bank 2 is all - . that is needed for simple run time tasks. - -----------------------------------------------------------------------*/ - -/* - . Bank Select Register: - . - . yyyy yyyy 0000 00xx - . xx = bank number - . yyyy yyyy = 0x33, for identification purposes. -*/ -#define BANK_SELECT 14 - -/* Transmit Control Register */ -/* BANK 0 */ -#define TCR_REG 0x0000 /* transmit control register */ -#define TCR_ENABLE 0x0001 /* When 1 we can transmit */ -#define TCR_LOOP 0x0002 /* Controls output pin LBK */ -#define TCR_FORCOL 0x0004 /* When 1 will force a collision */ -#define TCR_PAD_EN 0x0080 /* When 1 will pad tx frames < 64 bytes w/0 */ -#define TCR_NOCRC 0x0100 /* When 1 will not append CRC to tx frames */ -#define TCR_MON_CSN 0x0400 /* When 1 tx monitors carrier */ -#define TCR_FDUPLX 0x0800 /* When 1 enables full duplex operation */ -#define TCR_STP_SQET 0x1000 /* When 1 stops tx if Signal Quality Error */ -#define TCR_EPH_LOOP 0x2000 /* When 1 enables EPH block loopback */ -#define TCR_SWFDUP 0x8000 /* When 1 enables Switched Full Duplex mode */ - -#define TCR_CLEAR 0 /* do NOTHING */ -/* the default settings for the TCR register : */ -/* QUESTION: do I want to enable padding of short packets ? */ -#define TCR_DEFAULT TCR_ENABLE - - -/* EPH Status Register */ -/* BANK 0 */ -#define EPH_STATUS_REG 0x0002 -#define ES_TX_SUC 0x0001 /* Last TX was successful */ -#define ES_SNGL_COL 0x0002 /* Single collision detected for last tx */ -#define ES_MUL_COL 0x0004 /* Multiple collisions detected for last tx */ -#define ES_LTX_MULT 0x0008 /* Last tx was a multicast */ -#define ES_16COL 0x0010 /* 16 Collisions Reached */ -#define ES_SQET 0x0020 /* Signal Quality Error Test */ -#define ES_LTXBRD 0x0040 /* Last tx was a broadcast */ -#define ES_TXDEFR 0x0080 /* Transmit Deferred */ -#define ES_LATCOL 0x0200 /* Late collision detected on last tx */ -#define ES_LOSTCARR 0x0400 /* Lost Carrier Sense */ -#define ES_EXC_DEF 0x0800 /* Excessive Deferral */ -#define ES_CTR_ROL 0x1000 /* Counter Roll Over indication */ -#define ES_LINK_OK 0x4000 /* Driven by inverted value of nLNK pin */ -#define ES_TXUNRN 0x8000 /* Tx Underrun */ - - -/* Receive Control Register */ -/* BANK 0 */ -#define RCR_REG 0x0004 -#define RCR_RX_ABORT 0x0001 /* Set if a rx frame was aborted */ -#define RCR_PRMS 0x0002 /* Enable promiscuous mode */ -#define RCR_ALMUL 0x0004 /* When set accepts all multicast frames */ -#define RCR_RXEN 0x0100 /* IFF this is set, we can receive packets */ -#define RCR_STRIP_CRC 0x0200 /* When set strips CRC from rx packets */ -#define RCR_ABORT_ENB 0x0200 /* When set will abort rx on collision */ -#define RCR_FILT_CAR 0x0400 /* When set filters leading 12 bit s of carrier */ -#define RCR_SOFTRST 0x8000 /* resets the chip */ - -/* the normal settings for the RCR register : */ -#define RCR_DEFAULT (RCR_STRIP_CRC | RCR_RXEN) -#define RCR_CLEAR 0x0 /* set it to a base state */ - -/* Counter Register */ -/* BANK 0 */ -#define COUNTER_REG 0x0006 - -/* Memory Information Register */ -/* BANK 0 */ -#define MIR_REG 0x0008 - -/* Receive/Phy Control Register */ -/* BANK 0 */ -#define RPC_REG 0x000A -#define RPC_SPEED 0x2000 /* When 1 PHY is in 100Mbps mode. */ -#define RPC_DPLX 0x1000 /* When 1 PHY is in Full-Duplex Mode */ -#define RPC_ANEG 0x0800 /* When 1 PHY is in Auto-Negotiate Mode */ -#define RPC_LSXA_SHFT 5 /* Bits to shift LS2A,LS1A,LS0A to lsb */ -#define RPC_LSXB_SHFT 2 /* Bits to get LS2B,LS1B,LS0B to lsb */ -#define RPC_LED_100_10 (0x00) /* LED = 100Mbps OR's with 10Mbps link detect */ -#define RPC_LED_RES (0x01) /* LED = Reserved */ -#define RPC_LED_10 (0x02) /* LED = 10Mbps link detect */ -#define RPC_LED_FD (0x03) /* LED = Full Duplex Mode */ -#define RPC_LED_TX_RX (0x04) /* LED = TX or RX packet occurred */ -#define RPC_LED_100 (0x05) /* LED = 100Mbps link dectect */ -#define RPC_LED_TX (0x06) /* LED = TX packet occurred */ -#define RPC_LED_RX (0x07) /* LED = RX packet occurred */ -#if defined(CONFIG_DK1C20) || defined(CONFIG_DK1S10) -/* buggy schematic: LEDa -> yellow, LEDb --> green */ -#define RPC_DEFAULT ( RPC_SPEED | RPC_DPLX | RPC_ANEG \ - | (RPC_LED_TX_RX << RPC_LSXA_SHFT) \ - | (RPC_LED_100_10 << RPC_LSXB_SHFT) ) -#elif defined(CONFIG_ADNPESC1) -/* SSV ADNP/ESC1 has only one LED: LEDa -> Rx/Tx indicator */ -#define RPC_DEFAULT ( RPC_SPEED | RPC_DPLX | RPC_ANEG \ - | (RPC_LED_TX_RX << RPC_LSXA_SHFT) \ - | (RPC_LED_100_10 << RPC_LSXB_SHFT) ) -#else -/* SMSC reference design: LEDa --> green, LEDb --> yellow */ -#define RPC_DEFAULT ( RPC_SPEED | RPC_DPLX | RPC_ANEG \ - | (RPC_LED_100_10 << RPC_LSXA_SHFT) \ - | (RPC_LED_TX_RX << RPC_LSXB_SHFT) ) -#endif - -/* Bank 0 0x000C is reserved */ - -/* Bank Select Register */ -/* All Banks */ -#define BSR_REG 0x000E - - -/* Configuration Reg */ -/* BANK 1 */ -#define CONFIG_REG 0x0000 -#define CONFIG_EXT_PHY 0x0200 /* 1=external MII, 0=internal Phy */ -#define CONFIG_GPCNTRL 0x0400 /* Inverse value drives pin nCNTRL */ -#define CONFIG_NO_WAIT 0x1000 /* When 1 no extra wait states on ISA bus */ -#define CONFIG_EPH_POWER_EN 0x8000 /* When 0 EPH is placed into low power mode. */ - -/* Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low */ -#define CONFIG_DEFAULT (CONFIG_EPH_POWER_EN) - - -/* Base Address Register */ -/* BANK 1 */ -#define BASE_REG 0x0002 - - -/* Individual Address Registers */ -/* BANK 1 */ -#define ADDR0_REG 0x0004 -#define ADDR1_REG 0x0006 -#define ADDR2_REG 0x0008 - - -/* General Purpose Register */ -/* BANK 1 */ -#define GP_REG 0x000A - - -/* Control Register */ -/* BANK 1 */ -#define CTL_REG 0x000C -#define CTL_RCV_BAD 0x4000 /* When 1 bad CRC packets are received */ -#define CTL_AUTO_RELEASE 0x0800 /* When 1 tx pages are released automatically */ -#define CTL_LE_ENABLE 0x0080 /* When 1 enables Link Error interrupt */ -#define CTL_CR_ENABLE 0x0040 /* When 1 enables Counter Rollover interrupt */ -#define CTL_TE_ENABLE 0x0020 /* When 1 enables Transmit Error interrupt */ -#define CTL_EEPROM_SELECT 0x0004 /* Controls EEPROM reload & store */ -#define CTL_RELOAD 0x0002 /* When set reads EEPROM into registers */ -#define CTL_STORE 0x0001 /* When set stores registers into EEPROM */ -#define CTL_DEFAULT (0x1A10) /* Autorelease enabled*/ - -/* MMU Command Register */ -/* BANK 2 */ -#define MMU_CMD_REG 0x0000 -#define MC_BUSY 1 /* When 1 the last release has not completed */ -#define MC_NOP (0<<5) /* No Op */ -#define MC_ALLOC (1<<5) /* OR with number of 256 byte packets */ -#define MC_RESET (2<<5) /* Reset MMU to initial state */ -#define MC_REMOVE (3<<5) /* Remove the current rx packet */ -#define MC_RELEASE (4<<5) /* Remove and release the current rx packet */ -#define MC_FREEPKT (5<<5) /* Release packet in PNR register */ -#define MC_ENQUEUE (6<<5) /* Enqueue the packet for transmit */ -#define MC_RSTTXFIFO (7<<5) /* Reset the TX FIFOs */ - - -/* Packet Number Register */ -/* BANK 2 */ -#define PN_REG 0x0002 - - -/* Allocation Result Register */ -/* BANK 2 */ -#define AR_REG 0x0003 -#define AR_FAILED 0x80 /* Alocation Failed */ - - -/* RX FIFO Ports Register */ -/* BANK 2 */ -#define RXFIFO_REG 0x0004 /* Must be read as a word */ -#define RXFIFO_REMPTY 0x8000 /* RX FIFO Empty */ - - -/* TX FIFO Ports Register */ -/* BANK 2 */ -#define TXFIFO_REG RXFIFO_REG /* Must be read as a word */ -#define TXFIFO_TEMPTY 0x80 /* TX FIFO Empty */ - - -/* Pointer Register */ -/* BANK 2 */ -#define PTR_REG 0x0006 -#define PTR_RCV 0x8000 /* 1=Receive area, 0=Transmit area */ -#define PTR_AUTOINC 0x4000 /* Auto increment the pointer on each access */ -#define PTR_READ 0x2000 /* When 1 the operation is a read */ -#define PTR_NOTEMPTY 0x0800 /* When 1 _do not_ write fifo DATA REG */ - - -/* Data Register */ -/* BANK 2 */ -#define SMC91111_DATA_REG 0x0008 - - -/* Interrupt Status/Acknowledge Register */ -/* BANK 2 */ -#define SMC91111_INT_REG 0x000C - - -/* Interrupt Mask Register */ -/* BANK 2 */ -#define IM_REG 0x000D -#define IM_MDINT 0x80 /* PHY MI Register 18 Interrupt */ -#define IM_ERCV_INT 0x40 /* Early Receive Interrupt */ -#define IM_EPH_INT 0x20 /* Set by Etheret Protocol Handler section */ -#define IM_RX_OVRN_INT 0x10 /* Set by Receiver Overruns */ -#define IM_ALLOC_INT 0x08 /* Set when allocation request is completed */ -#define IM_TX_EMPTY_INT 0x04 /* Set if the TX FIFO goes empty */ -#define IM_TX_INT 0x02 /* Transmit Interrrupt */ -#define IM_RCV_INT 0x01 /* Receive Interrupt */ - - -/* Multicast Table Registers */ -/* BANK 3 */ -#define MCAST_REG1 0x0000 -#define MCAST_REG2 0x0002 -#define MCAST_REG3 0x0004 -#define MCAST_REG4 0x0006 - - -/* Management Interface Register (MII) */ -/* BANK 3 */ -#define MII_REG 0x0008 -#define MII_MSK_CRS100 0x4000 /* Disables CRS100 detection during tx half dup */ -#define MII_MDOE 0x0008 /* MII Output Enable */ -#define MII_MCLK 0x0004 /* MII Clock, pin MDCLK */ -#define MII_MDI 0x0002 /* MII Input, pin MDI */ -#define MII_MDO 0x0001 /* MII Output, pin MDO */ - - -/* Revision Register */ -/* BANK 3 */ -#define REV_REG 0x000A /* ( hi: chip id low: rev # ) */ - - -/* Early RCV Register */ -/* BANK 3 */ -/* this is NOT on SMC9192 */ -#define ERCV_REG 0x000C -#define ERCV_RCV_DISCRD 0x0080 /* When 1 discards a packet being received */ -#define ERCV_THRESHOLD 0x001F /* ERCV Threshold Mask */ - -/* External Register */ -/* BANK 7 */ -#define EXT_REG 0x0000 - - -#define CHIP_9192 3 -#define CHIP_9194 4 -#define CHIP_9195 5 -#define CHIP_9196 6 -#define CHIP_91100 7 -#define CHIP_91100FD 8 -#define CHIP_91111FD 9 - -#if 0 -static const char * chip_ids[ 15 ] = { - NULL, NULL, NULL, - /* 3 */ "SMC91C90/91C92", - /* 4 */ "SMC91C94", - /* 5 */ "SMC91C95", - /* 6 */ "SMC91C96", - /* 7 */ "SMC91C100", - /* 8 */ "SMC91C100FD", - /* 9 */ "SMC91C111", - NULL, NULL, - NULL, NULL, NULL}; -#endif - -/* - . Transmit status bits -*/ -#define TS_SUCCESS 0x0001 -#define TS_LOSTCAR 0x0400 -#define TS_LATCOL 0x0200 -#define TS_16COL 0x0010 - -/* - . Receive status bits -*/ -#define RS_ALGNERR 0x8000 -#define RS_BRODCAST 0x4000 -#define RS_BADCRC 0x2000 -#define RS_ODDFRAME 0x1000 /* bug: the LAN91C111 never sets this on receive */ -#define RS_TOOLONG 0x0800 -#define RS_TOOSHORT 0x0400 -#define RS_MULTICAST 0x0001 -#define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT) - - -/* PHY Types */ -enum { - PHY_LAN83C183 = 1, /* LAN91C111 Internal PHY */ - PHY_LAN83C180 -}; - - -/* PHY Register Addresses (LAN91C111 Internal PHY) */ - -/* PHY Control Register */ -#define PHY_CNTL_REG 0x00 -#define PHY_CNTL_RST 0x8000 /* 1=PHY Reset */ -#define PHY_CNTL_LPBK 0x4000 /* 1=PHY Loopback */ -#define PHY_CNTL_SPEED 0x2000 /* 1=100Mbps, 0=10Mpbs */ -#define PHY_CNTL_ANEG_EN 0x1000 /* 1=Enable Auto negotiation */ -#define PHY_CNTL_PDN 0x0800 /* 1=PHY Power Down mode */ -#define PHY_CNTL_MII_DIS 0x0400 /* 1=MII 4 bit interface disabled */ -#define PHY_CNTL_ANEG_RST 0x0200 /* 1=Reset Auto negotiate */ -#define PHY_CNTL_DPLX 0x0100 /* 1=Full Duplex, 0=Half Duplex */ -#define PHY_CNTL_COLTST 0x0080 /* 1= MII Colision Test */ - -/* PHY Status Register */ -#define PHY_STAT_REG 0x01 -#define PHY_STAT_CAP_T4 0x8000 /* 1=100Base-T4 capable */ -#define PHY_STAT_CAP_TXF 0x4000 /* 1=100Base-X full duplex capable */ -#define PHY_STAT_CAP_TXH 0x2000 /* 1=100Base-X half duplex capable */ -#define PHY_STAT_CAP_TF 0x1000 /* 1=10Mbps full duplex capable */ -#define PHY_STAT_CAP_TH 0x0800 /* 1=10Mbps half duplex capable */ -#define PHY_STAT_CAP_SUPR 0x0040 /* 1=recv mgmt frames with not preamble */ -#define PHY_STAT_ANEG_ACK 0x0020 /* 1=ANEG has completed */ -#define PHY_STAT_REM_FLT 0x0010 /* 1=Remote Fault detected */ -#define PHY_STAT_CAP_ANEG 0x0008 /* 1=Auto negotiate capable */ -#define PHY_STAT_LINK 0x0004 /* 1=valid link */ -#define PHY_STAT_JAB 0x0002 /* 1=10Mbps jabber condition */ -#define PHY_STAT_EXREG 0x0001 /* 1=extended registers implemented */ - -/* PHY Identifier Registers */ -#define PHY_ID1_REG 0x02 /* PHY Identifier 1 */ -#define PHY_ID2_REG 0x03 /* PHY Identifier 2 */ - -/* PHY Auto-Negotiation Advertisement Register */ -#define PHY_AD_REG 0x04 -#define PHY_AD_NP 0x8000 /* 1=PHY requests exchange of Next Page */ -#define PHY_AD_ACK 0x4000 /* 1=got link code word from remote */ -#define PHY_AD_RF 0x2000 /* 1=advertise remote fault */ -#define PHY_AD_T4 0x0200 /* 1=PHY is capable of 100Base-T4 */ -#define PHY_AD_TX_FDX 0x0100 /* 1=PHY is capable of 100Base-TX FDPLX */ -#define PHY_AD_TX_HDX 0x0080 /* 1=PHY is capable of 100Base-TX HDPLX */ -#define PHY_AD_10_FDX 0x0040 /* 1=PHY is capable of 10Base-T FDPLX */ -#define PHY_AD_10_HDX 0x0020 /* 1=PHY is capable of 10Base-T HDPLX */ -#define PHY_AD_CSMA 0x0001 /* 1=PHY is capable of 802.3 CMSA */ - -/* PHY Auto-negotiation Remote End Capability Register */ -#define PHY_RMT_REG 0x05 -/* Uses same bit definitions as PHY_AD_REG */ - -/* PHY Configuration Register 1 */ -#define PHY_CFG1_REG 0x10 -#define PHY_CFG1_LNKDIS 0x8000 /* 1=Rx Link Detect Function disabled */ -#define PHY_CFG1_XMTDIS 0x4000 /* 1=TP Transmitter Disabled */ -#define PHY_CFG1_XMTPDN 0x2000 /* 1=TP Transmitter Powered Down */ -#define PHY_CFG1_BYPSCR 0x0400 /* 1=Bypass scrambler/descrambler */ -#define PHY_CFG1_UNSCDS 0x0200 /* 1=Unscramble Idle Reception Disable */ -#define PHY_CFG1_EQLZR 0x0100 /* 1=Rx Equalizer Disabled */ -#define PHY_CFG1_CABLE 0x0080 /* 1=STP(150ohm), 0=UTP(100ohm) */ -#define PHY_CFG1_RLVL0 0x0040 /* 1=Rx Squelch level reduced by 4.5db */ -#define PHY_CFG1_TLVL_SHIFT 2 /* Transmit Output Level Adjust */ -#define PHY_CFG1_TLVL_MASK 0x003C -#define PHY_CFG1_TRF_MASK 0x0003 /* Transmitter Rise/Fall time */ - - -/* PHY Configuration Register 2 */ -#define PHY_CFG2_REG 0x11 -#define PHY_CFG2_APOLDIS 0x0020 /* 1=Auto Polarity Correction disabled */ -#define PHY_CFG2_JABDIS 0x0010 /* 1=Jabber disabled */ -#define PHY_CFG2_MREG 0x0008 /* 1=Multiple register access (MII mgt) */ -#define PHY_CFG2_INTMDIO 0x0004 /* 1=Interrupt signaled with MDIO pulseo */ - -/* PHY Status Output (and Interrupt status) Register */ -#define PHY_INT_REG 0x12 /* Status Output (Interrupt Status) */ -#define PHY_INT_INT 0x8000 /* 1=bits have changed since last read */ -#define PHY_INT_LNKFAIL 0x4000 /* 1=Link Not detected */ -#define PHY_INT_LOSSSYNC 0x2000 /* 1=Descrambler has lost sync */ -#define PHY_INT_CWRD 0x1000 /* 1=Invalid 4B5B code detected on rx */ -#define PHY_INT_SSD 0x0800 /* 1=No Start Of Stream detected on rx */ -#define PHY_INT_ESD 0x0400 /* 1=No End Of Stream detected on rx */ -#define PHY_INT_RPOL 0x0200 /* 1=Reverse Polarity detected */ -#define PHY_INT_JAB 0x0100 /* 1=Jabber detected */ -#define PHY_INT_SPDDET 0x0080 /* 1=100Base-TX mode, 0=10Base-T mode */ -#define PHY_INT_DPLXDET 0x0040 /* 1=Device in Full Duplex */ - -/* PHY Interrupt/Status Mask Register */ -#define PHY_MASK_REG 0x13 /* Interrupt Mask */ -/* Uses the same bit definitions as PHY_INT_REG */ - - -/*------------------------------------------------------------------------- - . I define some macros to make it easier to do somewhat common - . or slightly complicated, repeated tasks. - --------------------------------------------------------------------------*/ - -/* select a register bank, 0 to 3 */ - -#define SMC_SELECT_BANK(a,x) { SMC_outw((a), (x), BANK_SELECT ); } - -/* this enables an interrupt in the interrupt mask register */ -#define SMC_ENABLE_INT(a,x) {\ - unsigned char mask;\ - SMC_SELECT_BANK((a),2);\ - mask = SMC_inb((a), IM_REG );\ - mask |= (x);\ - SMC_outb( (a), mask, IM_REG ); \ -} - -/* this disables an interrupt from the interrupt mask register */ - -#define SMC_DISABLE_INT(a,x) {\ - unsigned char mask;\ - SMC_SELECT_BANK(2);\ - mask = SMC_inb( (a), IM_REG );\ - mask &= ~(x);\ - SMC_outb( (a), mask, IM_REG ); \ -} - -/*---------------------------------------------------------------------- - . Define the interrupts that I want to receive from the card - . - . I want: - . IM_EPH_INT, for nasty errors - . IM_RCV_INT, for happy received packets - . IM_RX_OVRN_INT, because I have to kick the receiver - . IM_MDINT, for PHY Register 18 Status Changes - --------------------------------------------------------------------------*/ -#define SMC_INTERRUPT_MASK (IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT | \ - IM_MDINT) - -#endif /* _SMC_91111_H_ */ diff --git a/qemu/roms/u-boot/drivers/net/smc911x.c b/qemu/roms/u-boot/drivers/net/smc911x.c deleted file mode 100644 index b097c1a56..000000000 --- a/qemu/roms/u-boot/drivers/net/smc911x.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - * SMSC LAN9[12]1[567] Network driver - * - * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <command.h> -#include <malloc.h> -#include <net.h> -#include <miiphy.h> - -#include "smc911x.h" - -u32 pkt_data_pull(struct eth_device *dev, u32 addr) \ - __attribute__ ((weak, alias ("smc911x_reg_read"))); -void pkt_data_push(struct eth_device *dev, u32 addr, u32 val) \ - __attribute__ ((weak, alias ("smc911x_reg_write"))); - -static void smc911x_handle_mac_address(struct eth_device *dev) -{ - unsigned long addrh, addrl; - uchar *m = dev->enetaddr; - - addrl = m[0] | (m[1] << 8) | (m[2] << 16) | (m[3] << 24); - addrh = m[4] | (m[5] << 8); - smc911x_set_mac_csr(dev, ADDRL, addrl); - smc911x_set_mac_csr(dev, ADDRH, addrh); - - printf(DRIVERNAME ": MAC %pM\n", m); -} - -static int smc911x_eth_phy_read(struct eth_device *dev, - u8 phy, u8 reg, u16 *val) -{ - while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) - ; - - smc911x_set_mac_csr(dev, MII_ACC, phy << 11 | reg << 6 | - MII_ACC_MII_BUSY); - - while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) - ; - - *val = smc911x_get_mac_csr(dev, MII_DATA); - - return 0; -} - -static int smc911x_eth_phy_write(struct eth_device *dev, - u8 phy, u8 reg, u16 val) -{ - while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) - ; - - smc911x_set_mac_csr(dev, MII_DATA, val); - smc911x_set_mac_csr(dev, MII_ACC, - phy << 11 | reg << 6 | MII_ACC_MII_BUSY | MII_ACC_MII_WRITE); - - while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) - ; - return 0; -} - -static int smc911x_phy_reset(struct eth_device *dev) -{ - u32 reg; - - reg = smc911x_reg_read(dev, PMT_CTRL); - reg &= ~0xfffff030; - reg |= PMT_CTRL_PHY_RST; - smc911x_reg_write(dev, PMT_CTRL, reg); - - mdelay(100); - - return 0; -} - -static void smc911x_phy_configure(struct eth_device *dev) -{ - int timeout; - u16 status; - - smc911x_phy_reset(dev); - - smc911x_eth_phy_write(dev, 1, MII_BMCR, BMCR_RESET); - mdelay(1); - smc911x_eth_phy_write(dev, 1, MII_ADVERTISE, 0x01e1); - smc911x_eth_phy_write(dev, 1, MII_BMCR, BMCR_ANENABLE | - BMCR_ANRESTART); - - timeout = 5000; - do { - mdelay(1); - if ((timeout--) == 0) - goto err_out; - - if (smc911x_eth_phy_read(dev, 1, MII_BMSR, &status) != 0) - goto err_out; - } while (!(status & BMSR_LSTATUS)); - - printf(DRIVERNAME ": phy initialized\n"); - - return; - -err_out: - printf(DRIVERNAME ": autonegotiation timed out\n"); -} - -static void smc911x_enable(struct eth_device *dev) -{ - /* Enable TX */ - smc911x_reg_write(dev, HW_CFG, 8 << 16 | HW_CFG_SF); - - smc911x_reg_write(dev, GPT_CFG, GPT_CFG_TIMER_EN | 10000); - - smc911x_reg_write(dev, TX_CFG, TX_CFG_TX_ON); - - /* no padding to start of packets */ - smc911x_reg_write(dev, RX_CFG, 0); - - smc911x_set_mac_csr(dev, MAC_CR, MAC_CR_TXEN | MAC_CR_RXEN | - MAC_CR_HBDIS); - -} - -static int smc911x_init(struct eth_device *dev, bd_t * bd) -{ - struct chip_id *id = dev->priv; - - printf(DRIVERNAME ": detected %s controller\n", id->name); - - smc911x_reset(dev); - - /* Configure the PHY, initialize the link state */ - smc911x_phy_configure(dev); - - smc911x_handle_mac_address(dev); - - /* Turn on Tx + Rx */ - smc911x_enable(dev); - - return 0; -} - -static int smc911x_send(struct eth_device *dev, void *packet, int length) -{ - u32 *data = (u32*)packet; - u32 tmplen; - u32 status; - - smc911x_reg_write(dev, TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG | - TX_CMD_A_INT_LAST_SEG | length); - smc911x_reg_write(dev, TX_DATA_FIFO, length); - - tmplen = (length + 3) / 4; - - while (tmplen--) - pkt_data_push(dev, TX_DATA_FIFO, *data++); - - /* wait for transmission */ - while (!((smc911x_reg_read(dev, TX_FIFO_INF) & - TX_FIFO_INF_TSUSED) >> 16)); - - /* get status. Ignore 'no carrier' error, it has no meaning for - * full duplex operation - */ - status = smc911x_reg_read(dev, TX_STATUS_FIFO) & - (TX_STS_LOC | TX_STS_LATE_COLL | TX_STS_MANY_COLL | - TX_STS_MANY_DEFER | TX_STS_UNDERRUN); - - if (!status) - return 0; - - printf(DRIVERNAME ": failed to send packet: %s%s%s%s%s\n", - status & TX_STS_LOC ? "TX_STS_LOC " : "", - status & TX_STS_LATE_COLL ? "TX_STS_LATE_COLL " : "", - status & TX_STS_MANY_COLL ? "TX_STS_MANY_COLL " : "", - status & TX_STS_MANY_DEFER ? "TX_STS_MANY_DEFER " : "", - status & TX_STS_UNDERRUN ? "TX_STS_UNDERRUN" : ""); - - return -1; -} - -static void smc911x_halt(struct eth_device *dev) -{ - smc911x_reset(dev); -} - -static int smc911x_rx(struct eth_device *dev) -{ - u32 *data = (u32 *)NetRxPackets[0]; - u32 pktlen, tmplen; - u32 status; - - if ((smc911x_reg_read(dev, RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16) { - status = smc911x_reg_read(dev, RX_STATUS_FIFO); - pktlen = (status & RX_STS_PKT_LEN) >> 16; - - smc911x_reg_write(dev, RX_CFG, 0); - - tmplen = (pktlen + 3) / 4; - while (tmplen--) - *data++ = pkt_data_pull(dev, RX_DATA_FIFO); - - if (status & RX_STS_ES) - printf(DRIVERNAME - ": dropped bad packet. Status: 0x%08x\n", - status); - else - NetReceive(NetRxPackets[0], pktlen); - } - - return 0; -} - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) -/* wrapper for smc911x_eth_phy_read */ -static int smc911x_miiphy_read(const char *devname, u8 phy, u8 reg, u16 *val) -{ - struct eth_device *dev = eth_get_dev_by_name(devname); - if (dev) - return smc911x_eth_phy_read(dev, phy, reg, val); - return -1; -} -/* wrapper for smc911x_eth_phy_write */ -static int smc911x_miiphy_write(const char *devname, u8 phy, u8 reg, u16 val) -{ - struct eth_device *dev = eth_get_dev_by_name(devname); - if (dev) - return smc911x_eth_phy_write(dev, phy, reg, val); - return -1; -} -#endif - -int smc911x_initialize(u8 dev_num, int base_addr) -{ - unsigned long addrl, addrh; - struct eth_device *dev; - - dev = malloc(sizeof(*dev)); - if (!dev) { - return -1; - } - memset(dev, 0, sizeof(*dev)); - - dev->iobase = base_addr; - - /* Try to detect chip. Will fail if not present. */ - if (smc911x_detect_chip(dev)) { - free(dev); - return 0; - } - - addrh = smc911x_get_mac_csr(dev, ADDRH); - addrl = smc911x_get_mac_csr(dev, ADDRL); - if (!(addrl == 0xffffffff && addrh == 0x0000ffff)) { - /* address is obtained from optional eeprom */ - dev->enetaddr[0] = addrl; - dev->enetaddr[1] = addrl >> 8; - dev->enetaddr[2] = addrl >> 16; - dev->enetaddr[3] = addrl >> 24; - dev->enetaddr[4] = addrh; - dev->enetaddr[5] = addrh >> 8; - } - - dev->init = smc911x_init; - dev->halt = smc911x_halt; - dev->send = smc911x_send; - dev->recv = smc911x_rx; - sprintf(dev->name, "%s-%hu", DRIVERNAME, dev_num); - - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - miiphy_register(dev->name, smc911x_miiphy_read, smc911x_miiphy_write); -#endif - - return 1; -} diff --git a/qemu/roms/u-boot/drivers/net/smc911x.h b/qemu/roms/u-boot/drivers/net/smc911x.h deleted file mode 100644 index acae0cfb8..000000000 --- a/qemu/roms/u-boot/drivers/net/smc911x.h +++ /dev/null @@ -1,500 +0,0 @@ -/* - * SMSC LAN9[12]1[567] Network driver - * - * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _SMC911X_H_ -#define _SMC911X_H_ - -#include <linux/types.h> - -#define DRIVERNAME "smc911x" - -#if defined (CONFIG_SMC911X_32_BIT) && \ - defined (CONFIG_SMC911X_16_BIT) -#error "SMC911X: Only one of CONFIG_SMC911X_32_BIT and \ - CONFIG_SMC911X_16_BIT shall be set" -#endif - -#if defined (CONFIG_SMC911X_32_BIT) -static inline u32 __smc911x_reg_read(struct eth_device *dev, u32 offset) -{ - return *(volatile u32*)(dev->iobase + offset); -} -u32 smc911x_reg_read(struct eth_device *dev, u32 offset) - __attribute__((weak, alias("__smc911x_reg_read"))); - -static inline void __smc911x_reg_write(struct eth_device *dev, - u32 offset, u32 val) -{ - *(volatile u32*)(dev->iobase + offset) = val; -} -void smc911x_reg_write(struct eth_device *dev, u32 offset, u32 val) - __attribute__((weak, alias("__smc911x_reg_write"))); -#elif defined (CONFIG_SMC911X_16_BIT) -static inline u32 smc911x_reg_read(struct eth_device *dev, u32 offset) -{ - volatile u16 *addr_16 = (u16 *)(dev->iobase + offset); - return ((*addr_16 & 0x0000ffff) | (*(addr_16 + 1) << 16)); -} -static inline void smc911x_reg_write(struct eth_device *dev, - u32 offset, u32 val) -{ - *(volatile u16 *)(dev->iobase + offset) = (u16)val; - *(volatile u16 *)(dev->iobase + offset + 2) = (u16)(val >> 16); -} -#else -#error "SMC911X: undefined bus width" -#endif /* CONFIG_SMC911X_16_BIT */ - -/* Below are the register offsets and bit definitions - * of the Lan911x memory space - */ -#define RX_DATA_FIFO 0x00 - -#define TX_DATA_FIFO 0x20 -#define TX_CMD_A_INT_ON_COMP 0x80000000 -#define TX_CMD_A_INT_BUF_END_ALGN 0x03000000 -#define TX_CMD_A_INT_4_BYTE_ALGN 0x00000000 -#define TX_CMD_A_INT_16_BYTE_ALGN 0x01000000 -#define TX_CMD_A_INT_32_BYTE_ALGN 0x02000000 -#define TX_CMD_A_INT_DATA_OFFSET 0x001F0000 -#define TX_CMD_A_INT_FIRST_SEG 0x00002000 -#define TX_CMD_A_INT_LAST_SEG 0x00001000 -#define TX_CMD_A_BUF_SIZE 0x000007FF -#define TX_CMD_B_PKT_TAG 0xFFFF0000 -#define TX_CMD_B_ADD_CRC_DISABLE 0x00002000 -#define TX_CMD_B_DISABLE_PADDING 0x00001000 -#define TX_CMD_B_PKT_BYTE_LENGTH 0x000007FF - -#define RX_STATUS_FIFO 0x40 -#define RX_STS_PKT_LEN 0x3FFF0000 -#define RX_STS_ES 0x00008000 -#define RX_STS_BCST 0x00002000 -#define RX_STS_LEN_ERR 0x00001000 -#define RX_STS_RUNT_ERR 0x00000800 -#define RX_STS_MCAST 0x00000400 -#define RX_STS_TOO_LONG 0x00000080 -#define RX_STS_COLL 0x00000040 -#define RX_STS_ETH_TYPE 0x00000020 -#define RX_STS_WDOG_TMT 0x00000010 -#define RX_STS_MII_ERR 0x00000008 -#define RX_STS_DRIBBLING 0x00000004 -#define RX_STS_CRC_ERR 0x00000002 -#define RX_STATUS_FIFO_PEEK 0x44 -#define TX_STATUS_FIFO 0x48 -#define TX_STS_TAG 0xFFFF0000 -#define TX_STS_ES 0x00008000 -#define TX_STS_LOC 0x00000800 -#define TX_STS_NO_CARR 0x00000400 -#define TX_STS_LATE_COLL 0x00000200 -#define TX_STS_MANY_COLL 0x00000100 -#define TX_STS_COLL_CNT 0x00000078 -#define TX_STS_MANY_DEFER 0x00000004 -#define TX_STS_UNDERRUN 0x00000002 -#define TX_STS_DEFERRED 0x00000001 -#define TX_STATUS_FIFO_PEEK 0x4C -#define ID_REV 0x50 -#define ID_REV_CHIP_ID 0xFFFF0000 /* RO */ -#define ID_REV_REV_ID 0x0000FFFF /* RO */ - -#define INT_CFG 0x54 -#define INT_CFG_INT_DEAS 0xFF000000 /* R/W */ -#define INT_CFG_INT_DEAS_CLR 0x00004000 -#define INT_CFG_INT_DEAS_STS 0x00002000 -#define INT_CFG_IRQ_INT 0x00001000 /* RO */ -#define INT_CFG_IRQ_EN 0x00000100 /* R/W */ - /* R/W Not Affected by SW Reset */ -#define INT_CFG_IRQ_POL 0x00000010 - /* R/W Not Affected by SW Reset */ -#define INT_CFG_IRQ_TYPE 0x00000001 - -#define INT_STS 0x58 -#define INT_STS_SW_INT 0x80000000 /* R/WC */ -#define INT_STS_TXSTOP_INT 0x02000000 /* R/WC */ -#define INT_STS_RXSTOP_INT 0x01000000 /* R/WC */ -#define INT_STS_RXDFH_INT 0x00800000 /* R/WC */ -#define INT_STS_RXDF_INT 0x00400000 /* R/WC */ -#define INT_STS_TX_IOC 0x00200000 /* R/WC */ -#define INT_STS_RXD_INT 0x00100000 /* R/WC */ -#define INT_STS_GPT_INT 0x00080000 /* R/WC */ -#define INT_STS_PHY_INT 0x00040000 /* RO */ -#define INT_STS_PME_INT 0x00020000 /* R/WC */ -#define INT_STS_TXSO 0x00010000 /* R/WC */ -#define INT_STS_RWT 0x00008000 /* R/WC */ -#define INT_STS_RXE 0x00004000 /* R/WC */ -#define INT_STS_TXE 0x00002000 /* R/WC */ -/*#define INT_STS_ERX 0x00001000*/ /* R/WC */ -#define INT_STS_TDFU 0x00000800 /* R/WC */ -#define INT_STS_TDFO 0x00000400 /* R/WC */ -#define INT_STS_TDFA 0x00000200 /* R/WC */ -#define INT_STS_TSFF 0x00000100 /* R/WC */ -#define INT_STS_TSFL 0x00000080 /* R/WC */ -/*#define INT_STS_RXDF 0x00000040*/ /* R/WC */ -#define INT_STS_RDFO 0x00000040 /* R/WC */ -#define INT_STS_RDFL 0x00000020 /* R/WC */ -#define INT_STS_RSFF 0x00000010 /* R/WC */ -#define INT_STS_RSFL 0x00000008 /* R/WC */ -#define INT_STS_GPIO2_INT 0x00000004 /* R/WC */ -#define INT_STS_GPIO1_INT 0x00000002 /* R/WC */ -#define INT_STS_GPIO0_INT 0x00000001 /* R/WC */ -#define INT_EN 0x5C -#define INT_EN_SW_INT_EN 0x80000000 /* R/W */ -#define INT_EN_TXSTOP_INT_EN 0x02000000 /* R/W */ -#define INT_EN_RXSTOP_INT_EN 0x01000000 /* R/W */ -#define INT_EN_RXDFH_INT_EN 0x00800000 /* R/W */ -/*#define INT_EN_RXDF_INT_EN 0x00400000*/ /* R/W */ -#define INT_EN_TIOC_INT_EN 0x00200000 /* R/W */ -#define INT_EN_RXD_INT_EN 0x00100000 /* R/W */ -#define INT_EN_GPT_INT_EN 0x00080000 /* R/W */ -#define INT_EN_PHY_INT_EN 0x00040000 /* R/W */ -#define INT_EN_PME_INT_EN 0x00020000 /* R/W */ -#define INT_EN_TXSO_EN 0x00010000 /* R/W */ -#define INT_EN_RWT_EN 0x00008000 /* R/W */ -#define INT_EN_RXE_EN 0x00004000 /* R/W */ -#define INT_EN_TXE_EN 0x00002000 /* R/W */ -/*#define INT_EN_ERX_EN 0x00001000*/ /* R/W */ -#define INT_EN_TDFU_EN 0x00000800 /* R/W */ -#define INT_EN_TDFO_EN 0x00000400 /* R/W */ -#define INT_EN_TDFA_EN 0x00000200 /* R/W */ -#define INT_EN_TSFF_EN 0x00000100 /* R/W */ -#define INT_EN_TSFL_EN 0x00000080 /* R/W */ -/*#define INT_EN_RXDF_EN 0x00000040*/ /* R/W */ -#define INT_EN_RDFO_EN 0x00000040 /* R/W */ -#define INT_EN_RDFL_EN 0x00000020 /* R/W */ -#define INT_EN_RSFF_EN 0x00000010 /* R/W */ -#define INT_EN_RSFL_EN 0x00000008 /* R/W */ -#define INT_EN_GPIO2_INT 0x00000004 /* R/W */ -#define INT_EN_GPIO1_INT 0x00000002 /* R/W */ -#define INT_EN_GPIO0_INT 0x00000001 /* R/W */ - -#define BYTE_TEST 0x64 -#define FIFO_INT 0x68 -#define FIFO_INT_TX_AVAIL_LEVEL 0xFF000000 /* R/W */ -#define FIFO_INT_TX_STS_LEVEL 0x00FF0000 /* R/W */ -#define FIFO_INT_RX_AVAIL_LEVEL 0x0000FF00 /* R/W */ -#define FIFO_INT_RX_STS_LEVEL 0x000000FF /* R/W */ - -#define RX_CFG 0x6C -#define RX_CFG_RX_END_ALGN 0xC0000000 /* R/W */ -#define RX_CFG_RX_END_ALGN4 0x00000000 /* R/W */ -#define RX_CFG_RX_END_ALGN16 0x40000000 /* R/W */ -#define RX_CFG_RX_END_ALGN32 0x80000000 /* R/W */ -#define RX_CFG_RX_DMA_CNT 0x0FFF0000 /* R/W */ -#define RX_CFG_RX_DUMP 0x00008000 /* R/W */ -#define RX_CFG_RXDOFF 0x00001F00 /* R/W */ -/*#define RX_CFG_RXBAD 0x00000001*/ /* R/W */ - -#define TX_CFG 0x70 -/*#define TX_CFG_TX_DMA_LVL 0xE0000000*/ /* R/W */ - /* R/W Self Clearing */ -/*#define TX_CFG_TX_DMA_CNT 0x0FFF0000*/ -#define TX_CFG_TXS_DUMP 0x00008000 /* Self Clearing */ -#define TX_CFG_TXD_DUMP 0x00004000 /* Self Clearing */ -#define TX_CFG_TXSAO 0x00000004 /* R/W */ -#define TX_CFG_TX_ON 0x00000002 /* R/W */ -#define TX_CFG_STOP_TX 0x00000001 /* Self Clearing */ - -#define HW_CFG 0x74 -#define HW_CFG_TTM 0x00200000 /* R/W */ -#define HW_CFG_SF 0x00100000 /* R/W */ -#define HW_CFG_TX_FIF_SZ 0x000F0000 /* R/W */ -#define HW_CFG_TR 0x00003000 /* R/W */ -#define HW_CFG_PHY_CLK_SEL 0x00000060 /* R/W */ -#define HW_CFG_PHY_CLK_SEL_INT_PHY 0x00000000 /* R/W */ -#define HW_CFG_PHY_CLK_SEL_EXT_PHY 0x00000020 /* R/W */ -#define HW_CFG_PHY_CLK_SEL_CLK_DIS 0x00000040 /* R/W */ -#define HW_CFG_SMI_SEL 0x00000010 /* R/W */ -#define HW_CFG_EXT_PHY_DET 0x00000008 /* RO */ -#define HW_CFG_EXT_PHY_EN 0x00000004 /* R/W */ -#define HW_CFG_32_16_BIT_MODE 0x00000004 /* RO */ -#define HW_CFG_SRST_TO 0x00000002 /* RO */ -#define HW_CFG_SRST 0x00000001 /* Self Clearing */ - -#define RX_DP_CTRL 0x78 -#define RX_DP_CTRL_RX_FFWD 0x80000000 /* R/W */ -#define RX_DP_CTRL_FFWD_BUSY 0x80000000 /* RO */ - -#define RX_FIFO_INF 0x7C -#define RX_FIFO_INF_RXSUSED 0x00FF0000 /* RO */ -#define RX_FIFO_INF_RXDUSED 0x0000FFFF /* RO */ - -#define TX_FIFO_INF 0x80 -#define TX_FIFO_INF_TSUSED 0x00FF0000 /* RO */ -#define TX_FIFO_INF_TDFREE 0x0000FFFF /* RO */ - -#define PMT_CTRL 0x84 -#define PMT_CTRL_PM_MODE 0x00003000 /* Self Clearing */ -#define PMT_CTRL_PHY_RST 0x00000400 /* Self Clearing */ -#define PMT_CTRL_WOL_EN 0x00000200 /* R/W */ -#define PMT_CTRL_ED_EN 0x00000100 /* R/W */ - /* R/W Not Affected by SW Reset */ -#define PMT_CTRL_PME_TYPE 0x00000040 -#define PMT_CTRL_WUPS 0x00000030 /* R/WC */ -#define PMT_CTRL_WUPS_NOWAKE 0x00000000 /* R/WC */ -#define PMT_CTRL_WUPS_ED 0x00000010 /* R/WC */ -#define PMT_CTRL_WUPS_WOL 0x00000020 /* R/WC */ -#define PMT_CTRL_WUPS_MULTI 0x00000030 /* R/WC */ -#define PMT_CTRL_PME_IND 0x00000008 /* R/W */ -#define PMT_CTRL_PME_POL 0x00000004 /* R/W */ - /* R/W Not Affected by SW Reset */ -#define PMT_CTRL_PME_EN 0x00000002 -#define PMT_CTRL_READY 0x00000001 /* RO */ - -#define GPIO_CFG 0x88 -#define GPIO_CFG_LED3_EN 0x40000000 /* R/W */ -#define GPIO_CFG_LED2_EN 0x20000000 /* R/W */ -#define GPIO_CFG_LED1_EN 0x10000000 /* R/W */ -#define GPIO_CFG_GPIO2_INT_POL 0x04000000 /* R/W */ -#define GPIO_CFG_GPIO1_INT_POL 0x02000000 /* R/W */ -#define GPIO_CFG_GPIO0_INT_POL 0x01000000 /* R/W */ -#define GPIO_CFG_EEPR_EN 0x00700000 /* R/W */ -#define GPIO_CFG_GPIOBUF2 0x00040000 /* R/W */ -#define GPIO_CFG_GPIOBUF1 0x00020000 /* R/W */ -#define GPIO_CFG_GPIOBUF0 0x00010000 /* R/W */ -#define GPIO_CFG_GPIODIR2 0x00000400 /* R/W */ -#define GPIO_CFG_GPIODIR1 0x00000200 /* R/W */ -#define GPIO_CFG_GPIODIR0 0x00000100 /* R/W */ -#define GPIO_CFG_GPIOD4 0x00000010 /* R/W */ -#define GPIO_CFG_GPIOD3 0x00000008 /* R/W */ -#define GPIO_CFG_GPIOD2 0x00000004 /* R/W */ -#define GPIO_CFG_GPIOD1 0x00000002 /* R/W */ -#define GPIO_CFG_GPIOD0 0x00000001 /* R/W */ - -#define GPT_CFG 0x8C -#define GPT_CFG_TIMER_EN 0x20000000 /* R/W */ -#define GPT_CFG_GPT_LOAD 0x0000FFFF /* R/W */ - -#define GPT_CNT 0x90 -#define GPT_CNT_GPT_CNT 0x0000FFFF /* RO */ - -#define ENDIAN 0x98 -#define FREE_RUN 0x9C -#define RX_DROP 0xA0 -#define MAC_CSR_CMD 0xA4 -#define MAC_CSR_CMD_CSR_BUSY 0x80000000 /* Self Clearing */ -#define MAC_CSR_CMD_R_NOT_W 0x40000000 /* R/W */ -#define MAC_CSR_CMD_CSR_ADDR 0x000000FF /* R/W */ - -#define MAC_CSR_DATA 0xA8 -#define AFC_CFG 0xAC -#define AFC_CFG_AFC_HI 0x00FF0000 /* R/W */ -#define AFC_CFG_AFC_LO 0x0000FF00 /* R/W */ -#define AFC_CFG_BACK_DUR 0x000000F0 /* R/W */ -#define AFC_CFG_FCMULT 0x00000008 /* R/W */ -#define AFC_CFG_FCBRD 0x00000004 /* R/W */ -#define AFC_CFG_FCADD 0x00000002 /* R/W */ -#define AFC_CFG_FCANY 0x00000001 /* R/W */ - -#define E2P_CMD 0xB0 -#define E2P_CMD_EPC_BUSY 0x80000000 /* Self Clearing */ -#define E2P_CMD_EPC_CMD 0x70000000 /* R/W */ -#define E2P_CMD_EPC_CMD_READ 0x00000000 /* R/W */ -#define E2P_CMD_EPC_CMD_EWDS 0x10000000 /* R/W */ -#define E2P_CMD_EPC_CMD_EWEN 0x20000000 /* R/W */ -#define E2P_CMD_EPC_CMD_WRITE 0x30000000 /* R/W */ -#define E2P_CMD_EPC_CMD_WRAL 0x40000000 /* R/W */ -#define E2P_CMD_EPC_CMD_ERASE 0x50000000 /* R/W */ -#define E2P_CMD_EPC_CMD_ERAL 0x60000000 /* R/W */ -#define E2P_CMD_EPC_CMD_RELOAD 0x70000000 /* R/W */ -#define E2P_CMD_EPC_TIMEOUT 0x00000200 /* RO */ -#define E2P_CMD_MAC_ADDR_LOADED 0x00000100 /* RO */ -#define E2P_CMD_EPC_ADDR 0x000000FF /* R/W */ - -#define E2P_DATA 0xB4 -#define E2P_DATA_EEPROM_DATA 0x000000FF /* R/W */ -/* end of LAN register offsets and bit definitions */ - -/* MAC Control and Status registers */ -#define MAC_CR 0x01 /* R/W */ - -/* MAC_CR - MAC Control Register */ -#define MAC_CR_RXALL 0x80000000 -/* TODO: delete this bit? It is not described in the data sheet. */ -#define MAC_CR_HBDIS 0x10000000 -#define MAC_CR_RCVOWN 0x00800000 -#define MAC_CR_LOOPBK 0x00200000 -#define MAC_CR_FDPX 0x00100000 -#define MAC_CR_MCPAS 0x00080000 -#define MAC_CR_PRMS 0x00040000 -#define MAC_CR_INVFILT 0x00020000 -#define MAC_CR_PASSBAD 0x00010000 -#define MAC_CR_HFILT 0x00008000 -#define MAC_CR_HPFILT 0x00002000 -#define MAC_CR_LCOLL 0x00001000 -#define MAC_CR_BCAST 0x00000800 -#define MAC_CR_DISRTY 0x00000400 -#define MAC_CR_PADSTR 0x00000100 -#define MAC_CR_BOLMT_MASK 0x000000C0 -#define MAC_CR_DFCHK 0x00000020 -#define MAC_CR_TXEN 0x00000008 -#define MAC_CR_RXEN 0x00000004 - -#define ADDRH 0x02 /* R/W mask 0x0000FFFFUL */ -#define ADDRL 0x03 /* R/W mask 0xFFFFFFFFUL */ -#define HASHH 0x04 /* R/W */ -#define HASHL 0x05 /* R/W */ - -#define MII_ACC 0x06 /* R/W */ -#define MII_ACC_PHY_ADDR 0x0000F800 -#define MII_ACC_MIIRINDA 0x000007C0 -#define MII_ACC_MII_WRITE 0x00000002 -#define MII_ACC_MII_BUSY 0x00000001 - -#define MII_DATA 0x07 /* R/W mask 0x0000FFFFUL */ - -#define FLOW 0x08 /* R/W */ -#define FLOW_FCPT 0xFFFF0000 -#define FLOW_FCPASS 0x00000004 -#define FLOW_FCEN 0x00000002 -#define FLOW_FCBSY 0x00000001 - -#define VLAN1 0x09 /* R/W mask 0x0000FFFFUL */ -#define VLAN1_VTI1 0x0000ffff - -#define VLAN2 0x0A /* R/W mask 0x0000FFFFUL */ -#define VLAN2_VTI2 0x0000ffff - -#define WUFF 0x0B /* WO */ - -#define WUCSR 0x0C /* R/W */ -#define WUCSR_GUE 0x00000200 -#define WUCSR_WUFR 0x00000040 -#define WUCSR_MPR 0x00000020 -#define WUCSR_WAKE_EN 0x00000004 -#define WUCSR_MPEN 0x00000002 - -/* Chip ID values */ -#define CHIP_89218 0x218a -#define CHIP_9115 0x115 -#define CHIP_9116 0x116 -#define CHIP_9117 0x117 -#define CHIP_9118 0x118 -#define CHIP_9211 0x9211 -#define CHIP_9215 0x115a -#define CHIP_9216 0x116a -#define CHIP_9217 0x117a -#define CHIP_9218 0x118a -#define CHIP_9220 0x9220 -#define CHIP_9221 0x9221 - -struct chip_id { - u16 id; - char *name; -}; - -static const struct chip_id chip_ids[] = { - { CHIP_89218, "LAN89218" }, - { CHIP_9115, "LAN9115" }, - { CHIP_9116, "LAN9116" }, - { CHIP_9117, "LAN9117" }, - { CHIP_9118, "LAN9118" }, - { CHIP_9211, "LAN9211" }, - { CHIP_9215, "LAN9215" }, - { CHIP_9216, "LAN9216" }, - { CHIP_9217, "LAN9217" }, - { CHIP_9218, "LAN9218" }, - { CHIP_9220, "LAN9220" }, - { CHIP_9221, "LAN9221" }, - { 0, NULL }, -}; - -static u32 smc911x_get_mac_csr(struct eth_device *dev, u8 reg) -{ - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) - ; - smc911x_reg_write(dev, MAC_CSR_CMD, - MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg); - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) - ; - - return smc911x_reg_read(dev, MAC_CSR_DATA); -} - -static void smc911x_set_mac_csr(struct eth_device *dev, u8 reg, u32 data) -{ - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) - ; - smc911x_reg_write(dev, MAC_CSR_DATA, data); - smc911x_reg_write(dev, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg); - while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) - ; -} - -static int smc911x_detect_chip(struct eth_device *dev) -{ - unsigned long val, i; - - val = smc911x_reg_read(dev, BYTE_TEST); - if (val == 0xffffffff) { - /* Special case -- no chip present */ - return -1; - } else if (val != 0x87654321) { - printf(DRIVERNAME ": Invalid chip endian 0x%08lx\n", val); - return -1; - } - - val = smc911x_reg_read(dev, ID_REV) >> 16; - for (i = 0; chip_ids[i].id != 0; i++) { - if (chip_ids[i].id == val) break; - } - if (!chip_ids[i].id) { - printf(DRIVERNAME ": Unknown chip ID %04lx\n", val); - return -1; - } - - dev->priv = (void *)&chip_ids[i]; - - return 0; -} - -static void smc911x_reset(struct eth_device *dev) -{ - int timeout; - - /* - * Take out of PM setting first - * Device is already wake up if PMT_CTRL_READY bit is set - */ - if ((smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY) == 0) { - /* Write to the bytetest will take out of powerdown */ - smc911x_reg_write(dev, BYTE_TEST, 0x0); - - timeout = 10; - - while (timeout-- && - !(smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY)) - udelay(10); - if (timeout < 0) { - printf(DRIVERNAME - ": timeout waiting for PM restore\n"); - return; - } - } - - /* Disable interrupts */ - smc911x_reg_write(dev, INT_EN, 0); - - smc911x_reg_write(dev, HW_CFG, HW_CFG_SRST); - - timeout = 1000; - while (timeout-- && smc911x_reg_read(dev, E2P_CMD) & E2P_CMD_EPC_BUSY) - udelay(10); - - if (timeout < 0) { - printf(DRIVERNAME ": reset timeout\n"); - return; - } - - /* Reset the FIFO level and flow control settings */ - smc911x_set_mac_csr(dev, FLOW, FLOW_FCPT | FLOW_FCEN); - smc911x_reg_write(dev, AFC_CFG, 0x0050287F); - - /* Set to LED outputs */ - smc911x_reg_write(dev, GPIO_CFG, 0x70070000); -} - -#endif diff --git a/qemu/roms/u-boot/drivers/net/sunxi_wemac.c b/qemu/roms/u-boot/drivers/net/sunxi_wemac.c deleted file mode 100644 index 699a38158..000000000 --- a/qemu/roms/u-boot/drivers/net/sunxi_wemac.c +++ /dev/null @@ -1,525 +0,0 @@ -/* - * sunxi_wemac.c -- Allwinner A10 ethernet driver - * - * (C) Copyright 2012, Stefan Roese <sr@denx.de> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <miiphy.h> -#include <linux/err.h> -#include <asm/io.h> -#include <asm/arch/clock.h> -#include <asm/arch/gpio.h> - -/* EMAC register */ -struct wemac_regs { - u32 ctl; /* 0x00 */ - u32 tx_mode; /* 0x04 */ - u32 tx_flow; /* 0x08 */ - u32 tx_ctl0; /* 0x0c */ - u32 tx_ctl1; /* 0x10 */ - u32 tx_ins; /* 0x14 */ - u32 tx_pl0; /* 0x18 */ - u32 tx_pl1; /* 0x1c */ - u32 tx_sta; /* 0x20 */ - u32 tx_io_data; /* 0x24 */ - u32 tx_io_data1; /* 0x28 */ - u32 tx_tsvl0; /* 0x2c */ - u32 tx_tsvh0; /* 0x30 */ - u32 tx_tsvl1; /* 0x34 */ - u32 tx_tsvh1; /* 0x38 */ - u32 rx_ctl; /* 0x3c */ - u32 rx_hash0; /* 0x40 */ - u32 rx_hash1; /* 0x44 */ - u32 rx_sta; /* 0x48 */ - u32 rx_io_data; /* 0x4c */ - u32 rx_fbc; /* 0x50 */ - u32 int_ctl; /* 0x54 */ - u32 int_sta; /* 0x58 */ - u32 mac_ctl0; /* 0x5c */ - u32 mac_ctl1; /* 0x60 */ - u32 mac_ipgt; /* 0x64 */ - u32 mac_ipgr; /* 0x68 */ - u32 mac_clrt; /* 0x6c */ - u32 mac_maxf; /* 0x70 */ - u32 mac_supp; /* 0x74 */ - u32 mac_test; /* 0x78 */ - u32 mac_mcfg; /* 0x7c */ - u32 mac_mcmd; /* 0x80 */ - u32 mac_madr; /* 0x84 */ - u32 mac_mwtd; /* 0x88 */ - u32 mac_mrdd; /* 0x8c */ - u32 mac_mind; /* 0x90 */ - u32 mac_ssrr; /* 0x94 */ - u32 mac_a0; /* 0x98 */ - u32 mac_a1; /* 0x9c */ -}; - -/* SRAMC register */ -struct sunxi_sramc_regs { - u32 ctrl0; - u32 ctrl1; -}; - -/* 0: Disable 1: Aborted frame enable(default) */ -#define EMAC_TX_AB_M (0x1 << 0) -/* 0: CPU 1: DMA(default) */ -#define EMAC_TX_TM (0x1 << 1) - -#define EMAC_TX_SETUP (0) - -/* 0: DRQ asserted 1: DRQ automatically(default) */ -#define EMAC_RX_DRQ_MODE (0x1 << 1) -/* 0: CPU 1: DMA(default) */ -#define EMAC_RX_TM (0x1 << 2) -/* 0: Normal(default) 1: Pass all Frames */ -#define EMAC_RX_PA (0x1 << 4) -/* 0: Normal(default) 1: Pass Control Frames */ -#define EMAC_RX_PCF (0x1 << 5) -/* 0: Normal(default) 1: Pass Frames with CRC Error */ -#define EMAC_RX_PCRCE (0x1 << 6) -/* 0: Normal(default) 1: Pass Frames with Length Error */ -#define EMAC_RX_PLE (0x1 << 7) -/* 0: Normal 1: Pass Frames length out of range(default) */ -#define EMAC_RX_POR (0x1 << 8) -/* 0: Not accept 1: Accept unicast Packets(default) */ -#define EMAC_RX_UCAD (0x1 << 16) -/* 0: Normal(default) 1: DA Filtering */ -#define EMAC_RX_DAF (0x1 << 17) -/* 0: Not accept 1: Accept multicast Packets(default) */ -#define EMAC_RX_MCO (0x1 << 20) -/* 0: Disable(default) 1: Enable Hash filter */ -#define EMAC_RX_MHF (0x1 << 21) -/* 0: Not accept 1: Accept Broadcast Packets(default) */ -#define EMAC_RX_BCO (0x1 << 22) -/* 0: Disable(default) 1: Enable SA Filtering */ -#define EMAC_RX_SAF (0x1 << 24) -/* 0: Normal(default) 1: Inverse Filtering */ -#define EMAC_RX_SAIF (0x1 << 25) - -#define EMAC_RX_SETUP (EMAC_RX_POR | EMAC_RX_UCAD | EMAC_RX_DAF | \ - EMAC_RX_MCO | EMAC_RX_BCO) - -/* 0: Disable 1: Enable Receive Flow Control(default) */ -#define EMAC_MAC_CTL0_RFC (0x1 << 2) -/* 0: Disable 1: Enable Transmit Flow Control(default) */ -#define EMAC_MAC_CTL0_TFC (0x1 << 3) - -#define EMAC_MAC_CTL0_SETUP (EMAC_MAC_CTL0_RFC | EMAC_MAC_CTL0_TFC) - -/* 0: Disable 1: Enable MAC Frame Length Checking(default) */ -#define EMAC_MAC_CTL1_FLC (0x1 << 1) -/* 0: Disable(default) 1: Enable Huge Frame */ -#define EMAC_MAC_CTL1_HF (0x1 << 2) -/* 0: Disable(default) 1: Enable MAC Delayed CRC */ -#define EMAC_MAC_CTL1_DCRC (0x1 << 3) -/* 0: Disable 1: Enable MAC CRC(default) */ -#define EMAC_MAC_CTL1_CRC (0x1 << 4) -/* 0: Disable 1: Enable MAC PAD Short frames(default) */ -#define EMAC_MAC_CTL1_PC (0x1 << 5) -/* 0: Disable(default) 1: Enable MAC PAD Short frames and append CRC */ -#define EMAC_MAC_CTL1_VC (0x1 << 6) -/* 0: Disable(default) 1: Enable MAC auto detect Short frames */ -#define EMAC_MAC_CTL1_ADP (0x1 << 7) -/* 0: Disable(default) 1: Enable */ -#define EMAC_MAC_CTL1_PRE (0x1 << 8) -/* 0: Disable(default) 1: Enable */ -#define EMAC_MAC_CTL1_LPE (0x1 << 9) -/* 0: Disable(default) 1: Enable no back off */ -#define EMAC_MAC_CTL1_NB (0x1 << 12) -/* 0: Disable(default) 1: Enable */ -#define EMAC_MAC_CTL1_BNB (0x1 << 13) -/* 0: Disable(default) 1: Enable */ -#define EMAC_MAC_CTL1_ED (0x1 << 14) - -#define EMAC_MAC_CTL1_SETUP (EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC | \ - EMAC_MAC_CTL1_PC) - -#define EMAC_MAC_IPGT 0x15 - -#define EMAC_MAC_NBTB_IPG1 0xC -#define EMAC_MAC_NBTB_IPG2 0x12 - -#define EMAC_MAC_CW 0x37 -#define EMAC_MAC_RM 0xF - -#define EMAC_MAC_MFL 0x0600 - -/* Receive status */ -#define EMAC_CRCERR (1 << 4) -#define EMAC_LENERR (3 << 5) - -#define DMA_CPU_TRRESHOLD 2000 - -struct wemac_eth_dev { - u32 speed; - u32 duplex; - u32 phy_configured; - int link_printed; -}; - -struct wemac_rxhdr { - s16 rx_len; - u16 rx_status; -}; - -static void wemac_inblk_32bit(void *reg, void *data, int count) -{ - int cnt = (count + 3) >> 2; - - if (cnt) { - u32 *buf = data; - - do { - u32 x = readl(reg); - *buf++ = x; - } while (--cnt); - } -} - -static void wemac_outblk_32bit(void *reg, void *data, int count) -{ - int cnt = (count + 3) >> 2; - - if (cnt) { - const u32 *buf = data; - - do { - writel(*buf++, reg); - } while (--cnt); - } -} - -/* - * Read a word from phyxcer - */ -static int wemac_phy_read(const char *devname, unsigned char addr, - unsigned char reg, unsigned short *value) -{ - struct eth_device *dev = eth_get_dev_by_name(devname); - struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; - - /* issue the phy address and reg */ - writel(addr << 8 | reg, ®s->mac_madr); - - /* pull up the phy io line */ - writel(0x1, ®s->mac_mcmd); - - /* Wait read complete */ - mdelay(1); - - /* push down the phy io line */ - writel(0x0, ®s->mac_mcmd); - - /* and write data */ - *value = readl(®s->mac_mrdd); - - return 0; -} - -/* - * Write a word to phyxcer - */ -static int wemac_phy_write(const char *devname, unsigned char addr, - unsigned char reg, unsigned short value) -{ - struct eth_device *dev = eth_get_dev_by_name(devname); - struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; - - /* issue the phy address and reg */ - writel(addr << 8 | reg, ®s->mac_madr); - - /* pull up the phy io line */ - writel(0x1, ®s->mac_mcmd); - - /* Wait write complete */ - mdelay(1); - - /* push down the phy io line */ - writel(0x0, ®s->mac_mcmd); - - /* and write data */ - writel(value, ®s->mac_mwtd); - - return 0; -} - -static void emac_setup(struct eth_device *dev) -{ - struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; - u32 reg_val; - u16 phy_val; - u32 duplex_flag; - - /* Set up TX */ - writel(EMAC_TX_SETUP, ®s->tx_mode); - - /* Set up RX */ - writel(EMAC_RX_SETUP, ®s->rx_ctl); - - /* Set MAC */ - /* Set MAC CTL0 */ - writel(EMAC_MAC_CTL0_SETUP, ®s->mac_ctl0); - - /* Set MAC CTL1 */ - wemac_phy_read(dev->name, 1, 0, &phy_val); - debug("PHY SETUP, reg 0 value: %x\n", phy_val); - duplex_flag = !!(phy_val & (1 << 8)); - - reg_val = 0; - if (duplex_flag) - reg_val = (0x1 << 0); - writel(EMAC_MAC_CTL1_SETUP | reg_val, ®s->mac_ctl1); - - /* Set up IPGT */ - writel(EMAC_MAC_IPGT, ®s->mac_ipgt); - - /* Set up IPGR */ - writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), ®s->mac_ipgr); - - /* Set up Collison window */ - writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), ®s->mac_clrt); - - /* Set up Max Frame Length */ - writel(EMAC_MAC_MFL, ®s->mac_maxf); -} - -static void wemac_reset(struct eth_device *dev) -{ - struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; - - debug("resetting device\n"); - - /* RESET device */ - writel(0, ®s->ctl); - udelay(200); - - writel(1, ®s->ctl); - udelay(200); -} - -static int sunxi_wemac_eth_init(struct eth_device *dev, bd_t *bd) -{ - struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; - struct wemac_eth_dev *priv = dev->priv; - u16 phy_reg; - - /* Init EMAC */ - - /* Flush RX FIFO */ - setbits_le32(®s->rx_ctl, 0x8); - udelay(1); - - /* Init MAC */ - - /* Soft reset MAC */ - clrbits_le32(®s->mac_ctl0, 1 << 15); - - /* Set MII clock */ - clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); - - /* Clear RX counter */ - writel(0x0, ®s->rx_fbc); - udelay(1); - - /* Set up EMAC */ - emac_setup(dev); - - writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 | - dev->enetaddr[2], ®s->mac_a1); - writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 | - dev->enetaddr[5], ®s->mac_a0); - - mdelay(1); - - wemac_reset(dev); - - /* PHY POWER UP */ - wemac_phy_read(dev->name, 1, 0, &phy_reg); - wemac_phy_write(dev->name, 1, 0, phy_reg & (~(1 << 11))); - mdelay(1); - - wemac_phy_read(dev->name, 1, 0, &phy_reg); - - priv->speed = miiphy_speed(dev->name, 0); - priv->duplex = miiphy_duplex(dev->name, 0); - - /* Print link status only once */ - if (!priv->link_printed) { - printf("ENET Speed is %d Mbps - %s duplex connection\n", - priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL"); - priv->link_printed = 1; - } - - /* Set EMAC SPEED depend on PHY */ - clrsetbits_le32(®s->mac_supp, 1 << 8, - ((phy_reg & (1 << 13)) >> 13) << 8); - - /* Set duplex depend on phy */ - clrsetbits_le32(®s->mac_ctl1, 1 << 0, - ((phy_reg & (1 << 8)) >> 8) << 0); - - /* Enable RX/TX */ - setbits_le32(®s->ctl, 0x7); - - return 0; -} - -static void sunxi_wemac_eth_halt(struct eth_device *dev) -{ - /* Nothing to do here */ -} - -static int sunxi_wemac_eth_recv(struct eth_device *dev) -{ - struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; - struct wemac_rxhdr rxhdr; - u32 rxcount; - u32 reg_val; - int rx_len; - int rx_status; - int good_packet; - - /* Check packet ready or not */ - - /* - * Race warning: The first packet might arrive with - * the interrupts disabled, but the second will fix - */ - rxcount = readl(®s->rx_fbc); - if (!rxcount) { - /* Had one stuck? */ - rxcount = readl(®s->rx_fbc); - if (!rxcount) - return 0; - } - - reg_val = readl(®s->rx_io_data); - if (reg_val != 0x0143414d) { - /* Disable RX */ - clrbits_le32(®s->ctl, 1 << 2); - - /* Flush RX FIFO */ - setbits_le32(®s->rx_ctl, 1 << 3); - while (readl(®s->rx_ctl) & (1 << 3)) - ; - - /* Enable RX */ - setbits_le32(®s->ctl, 1 << 2); - - return 0; - } - - /* - * A packet ready now - * Get status/length - */ - good_packet = 1; - - wemac_inblk_32bit(®s->rx_io_data, &rxhdr, sizeof(rxhdr)); - - rx_len = rxhdr.rx_len; - rx_status = rxhdr.rx_status; - - /* Packet Status check */ - if (rx_len < 0x40) { - good_packet = 0; - debug("RX: Bad Packet (runt)\n"); - } - - /* rx_status is identical to RSR register. */ - if (0 & rx_status & (EMAC_CRCERR | EMAC_LENERR)) { - good_packet = 0; - if (rx_status & EMAC_CRCERR) - printf("crc error\n"); - if (rx_status & EMAC_LENERR) - printf("length error\n"); - } - - /* Move data from WEMAC */ - if (good_packet) { - if (rx_len > DMA_CPU_TRRESHOLD) { - printf("Received packet is too big (len=%d)\n", rx_len); - } else { - wemac_inblk_32bit((void *)®s->rx_io_data, - NetRxPackets[0], rx_len); - - /* Pass to upper layer */ - NetReceive(NetRxPackets[0], rx_len); - return rx_len; - } - } - - return 0; -} - -static int sunxi_wemac_eth_send(struct eth_device *dev, void *packet, int len) -{ - struct wemac_regs *regs = (struct wemac_regs *)dev->iobase; - - /* Select channel 0 */ - writel(0, ®s->tx_ins); - - /* Write packet */ - wemac_outblk_32bit((void *)®s->tx_io_data, packet, len); - - /* Set TX len */ - writel(len, ®s->tx_pl0); - - /* Start translate from fifo to phy */ - setbits_le32(®s->tx_ctl0, 1); - - return 0; -} - -int sunxi_wemac_initialize(void) -{ - struct sunxi_ccm_reg *const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - struct sunxi_sramc_regs *sram = - (struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE; - struct eth_device *dev; - struct wemac_eth_dev *priv; - int pin; - - dev = malloc(sizeof(*dev)); - if (dev == NULL) - return -ENOMEM; - - priv = (struct wemac_eth_dev *)malloc(sizeof(struct wemac_eth_dev)); - if (!priv) { - free(dev); - return -ENOMEM; - } - - memset(dev, 0, sizeof(*dev)); - memset(priv, 0, sizeof(struct wemac_eth_dev)); - - /* Map SRAM to EMAC */ - setbits_le32(&sram->ctrl1, 0x5 << 2); - - /* Configure pin mux settings for MII Ethernet */ - for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++) - sunxi_gpio_set_cfgpin(pin, 2); - - /* Set up clock gating */ - setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_EMAC); - - dev->iobase = SUNXI_EMAC_BASE; - dev->priv = priv; - dev->init = sunxi_wemac_eth_init; - dev->halt = sunxi_wemac_eth_halt; - dev->send = sunxi_wemac_eth_send; - dev->recv = sunxi_wemac_eth_recv; - strcpy(dev->name, "wemac"); - - eth_register(dev); - - miiphy_register(dev->name, wemac_phy_read, wemac_phy_write); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/tsec.c b/qemu/roms/u-boot/drivers/net/tsec.c deleted file mode 100644 index e9138f033..000000000 --- a/qemu/roms/u-boot/drivers/net/tsec.c +++ /dev/null @@ -1,688 +0,0 @@ -/* - * Freescale Three Speed Ethernet Controller driver - * - * This software may be used and distributed according to the - * terms of the GNU Public License, Version 2, incorporated - * herein by reference. - * - * Copyright 2004-2011, 2013 Freescale Semiconductor, Inc. - * (C) Copyright 2003, Motorola, Inc. - * author Andy Fleming - * - */ - -#include <config.h> -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <command.h> -#include <tsec.h> -#include <fsl_mdio.h> -#include <asm/errno.h> -#include <asm/processor.h> - -DECLARE_GLOBAL_DATA_PTR; - -#define TX_BUF_CNT 2 - -static uint rx_idx; /* index of the current RX buffer */ -static uint tx_idx; /* index of the current TX buffer */ - -#ifdef __GNUC__ -static struct txbd8 __iomem txbd[TX_BUF_CNT] __aligned(8); -static struct rxbd8 __iomem rxbd[PKTBUFSRX] __aligned(8); - -#else -#error "rtx must be 64-bit aligned" -#endif - -static int tsec_send(struct eth_device *dev, void *packet, int length); - -/* Default initializations for TSEC controllers. */ - -static struct tsec_info_struct tsec_info[] = { -#ifdef CONFIG_TSEC1 - STD_TSEC_INFO(1), /* TSEC1 */ -#endif -#ifdef CONFIG_TSEC2 - STD_TSEC_INFO(2), /* TSEC2 */ -#endif -#ifdef CONFIG_MPC85XX_FEC - { - .regs = TSEC_GET_REGS(2, 0x2000), - .devname = CONFIG_MPC85XX_FEC_NAME, - .phyaddr = FEC_PHY_ADDR, - .flags = FEC_FLAGS, - .mii_devname = DEFAULT_MII_NAME - }, /* FEC */ -#endif -#ifdef CONFIG_TSEC3 - STD_TSEC_INFO(3), /* TSEC3 */ -#endif -#ifdef CONFIG_TSEC4 - STD_TSEC_INFO(4), /* TSEC4 */ -#endif -}; - -#define TBIANA_SETTINGS ( \ - TBIANA_ASYMMETRIC_PAUSE \ - | TBIANA_SYMMETRIC_PAUSE \ - | TBIANA_FULL_DUPLEX \ - ) - -/* By default force the TBI PHY into 1000Mbps full duplex when in SGMII mode */ -#ifndef CONFIG_TSEC_TBICR_SETTINGS -#define CONFIG_TSEC_TBICR_SETTINGS ( \ - TBICR_PHY_RESET \ - | TBICR_ANEG_ENABLE \ - | TBICR_FULL_DUPLEX \ - | TBICR_SPEED1_SET \ - ) -#endif /* CONFIG_TSEC_TBICR_SETTINGS */ - -/* Configure the TBI for SGMII operation */ -static void tsec_configure_serdes(struct tsec_private *priv) -{ - /* Access TBI PHY registers at given TSEC register offset as opposed - * to the register offset used for external PHY accesses */ - tsec_local_mdio_write(priv->phyregs_sgmii, in_be32(&priv->regs->tbipa), - 0, TBI_ANA, TBIANA_SETTINGS); - tsec_local_mdio_write(priv->phyregs_sgmii, in_be32(&priv->regs->tbipa), - 0, TBI_TBICON, TBICON_CLK_SELECT); - tsec_local_mdio_write(priv->phyregs_sgmii, in_be32(&priv->regs->tbipa), - 0, TBI_CR, CONFIG_TSEC_TBICR_SETTINGS); -} - -#ifdef CONFIG_MCAST_TFTP - -/* CREDITS: linux gianfar driver, slightly adjusted... thanx. */ - -/* Set the appropriate hash bit for the given addr */ - -/* The algorithm works like so: - * 1) Take the Destination Address (ie the multicast address), and - * do a CRC on it (little endian), and reverse the bits of the - * result. - * 2) Use the 8 most significant bits as a hash into a 256-entry - * table. The table is controlled through 8 32-bit registers: - * gaddr0-7. gaddr0's MSB is entry 0, and gaddr7's LSB is entry - * 255. This means that the 3 most significant bits in the - * hash index which gaddr register to use, and the 5 other bits - * indicate which bit (assuming an IBM numbering scheme, which - * for PowerPC (tm) is usually the case) in the register holds - * the entry. */ -static int -tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set) -{ - struct tsec_private *priv = (struct tsec_private *)dev->priv; - struct tsec __iomem *regs = priv->regs; - u32 result, value; - u8 whichbit, whichreg; - - result = ether_crc(MAC_ADDR_LEN, mcast_mac); - whichbit = (result >> 24) & 0x1f; /* the 5 LSB = which bit to set */ - whichreg = result >> 29; /* the 3 MSB = which reg to set it in */ - - value = 1 << (31-whichbit); - - if (set) - setbits_be32(®s->hash.gaddr0 + whichreg, value); - else - clrbits_be32(®s->hash.gaddr0 + whichreg, value); - - return 0; -} -#endif /* Multicast TFTP ? */ - -/* Initialized required registers to appropriate values, zeroing - * those we don't care about (unless zero is bad, in which case, - * choose a more appropriate value) - */ -static void init_registers(struct tsec __iomem *regs) -{ - /* Clear IEVENT */ - out_be32(®s->ievent, IEVENT_INIT_CLEAR); - - out_be32(®s->imask, IMASK_INIT_CLEAR); - - out_be32(®s->hash.iaddr0, 0); - out_be32(®s->hash.iaddr1, 0); - out_be32(®s->hash.iaddr2, 0); - out_be32(®s->hash.iaddr3, 0); - out_be32(®s->hash.iaddr4, 0); - out_be32(®s->hash.iaddr5, 0); - out_be32(®s->hash.iaddr6, 0); - out_be32(®s->hash.iaddr7, 0); - - out_be32(®s->hash.gaddr0, 0); - out_be32(®s->hash.gaddr1, 0); - out_be32(®s->hash.gaddr2, 0); - out_be32(®s->hash.gaddr3, 0); - out_be32(®s->hash.gaddr4, 0); - out_be32(®s->hash.gaddr5, 0); - out_be32(®s->hash.gaddr6, 0); - out_be32(®s->hash.gaddr7, 0); - - out_be32(®s->rctrl, 0x00000000); - - /* Init RMON mib registers */ - memset((void *)®s->rmon, 0, sizeof(regs->rmon)); - - out_be32(®s->rmon.cam1, 0xffffffff); - out_be32(®s->rmon.cam2, 0xffffffff); - - out_be32(®s->mrblr, MRBLR_INIT_SETTINGS); - - out_be32(®s->minflr, MINFLR_INIT_SETTINGS); - - out_be32(®s->attr, ATTR_INIT_SETTINGS); - out_be32(®s->attreli, ATTRELI_INIT_SETTINGS); - -} - -/* Configure maccfg2 based on negotiated speed and duplex - * reported by PHY handling code - */ -static void adjust_link(struct tsec_private *priv, struct phy_device *phydev) -{ - struct tsec __iomem *regs = priv->regs; - u32 ecntrl, maccfg2; - - if (!phydev->link) { - printf("%s: No link.\n", phydev->dev->name); - return; - } - - /* clear all bits relative with interface mode */ - ecntrl = in_be32(®s->ecntrl); - ecntrl &= ~ECNTRL_R100; - - maccfg2 = in_be32(®s->maccfg2); - maccfg2 &= ~(MACCFG2_IF | MACCFG2_FULL_DUPLEX); - - if (phydev->duplex) - maccfg2 |= MACCFG2_FULL_DUPLEX; - - switch (phydev->speed) { - case 1000: - maccfg2 |= MACCFG2_GMII; - break; - case 100: - case 10: - maccfg2 |= MACCFG2_MII; - - /* Set R100 bit in all modes although - * it is only used in RGMII mode - */ - if (phydev->speed == 100) - ecntrl |= ECNTRL_R100; - break; - default: - printf("%s: Speed was bad\n", phydev->dev->name); - break; - } - - out_be32(®s->ecntrl, ecntrl); - out_be32(®s->maccfg2, maccfg2); - - printf("Speed: %d, %s duplex%s\n", phydev->speed, - (phydev->duplex) ? "full" : "half", - (phydev->port == PORT_FIBRE) ? ", fiber mode" : ""); -} - -#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129 -/* - * When MACCFG1[Rx_EN] is enabled during system boot as part - * of the eTSEC port initialization sequence, - * the eTSEC Rx logic may not be properly initialized. - */ -void redundant_init(struct eth_device *dev) -{ - struct tsec_private *priv = dev->priv; - struct tsec __iomem *regs = priv->regs; - uint t, count = 0; - int fail = 1; - static const u8 pkt[] = { - 0x00, 0x1e, 0x4f, 0x12, 0xcb, 0x2c, 0x00, 0x25, - 0x64, 0xbb, 0xd1, 0xab, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x5c, 0xdd, 0x22, 0x00, 0x00, 0x80, 0x01, - 0x1f, 0x71, 0x0a, 0xc1, 0x14, 0x22, 0x0a, 0xc1, - 0x14, 0x6a, 0x08, 0x00, 0xef, 0x7e, 0x02, 0x00, - 0x94, 0x05, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, - 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, - 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, - 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, - 0x71, 0x72}; - - /* Enable promiscuous mode */ - setbits_be32(®s->rctrl, 0x8); - /* Enable loopback mode */ - setbits_be32(®s->maccfg1, MACCFG1_LOOPBACK); - /* Enable transmit and receive */ - setbits_be32(®s->maccfg1, MACCFG1_RX_EN | MACCFG1_TX_EN); - - /* Tell the DMA it is clear to go */ - setbits_be32(®s->dmactrl, DMACTRL_INIT_SETTINGS); - out_be32(®s->tstat, TSTAT_CLEAR_THALT); - out_be32(®s->rstat, RSTAT_CLEAR_RHALT); - clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS); - - do { - uint16_t status; - tsec_send(dev, (void *)pkt, sizeof(pkt)); - - /* Wait for buffer to be received */ - for (t = 0; in_be16(&rxbd[rx_idx].status) & RXBD_EMPTY; t++) { - if (t >= 10 * TOUT_LOOP) { - printf("%s: tsec: rx error\n", dev->name); - break; - } - } - - if (!memcmp(pkt, (void *)NetRxPackets[rx_idx], sizeof(pkt))) - fail = 0; - - out_be16(&rxbd[rx_idx].length, 0); - status = RXBD_EMPTY; - if ((rx_idx + 1) == PKTBUFSRX) - status |= RXBD_WRAP; - out_be16(&rxbd[rx_idx].status, status); - rx_idx = (rx_idx + 1) % PKTBUFSRX; - - if (in_be32(®s->ievent) & IEVENT_BSY) { - out_be32(®s->ievent, IEVENT_BSY); - out_be32(®s->rstat, RSTAT_CLEAR_RHALT); - } - if (fail) { - printf("loopback recv packet error!\n"); - clrbits_be32(®s->maccfg1, MACCFG1_RX_EN); - udelay(1000); - setbits_be32(®s->maccfg1, MACCFG1_RX_EN); - } - } while ((count++ < 4) && (fail == 1)); - - if (fail) - panic("eTSEC init fail!\n"); - /* Disable promiscuous mode */ - clrbits_be32(®s->rctrl, 0x8); - /* Disable loopback mode */ - clrbits_be32(®s->maccfg1, MACCFG1_LOOPBACK); -} -#endif - -/* Set up the buffers and their descriptors, and bring up the - * interface - */ -static void startup_tsec(struct eth_device *dev) -{ - struct tsec_private *priv = (struct tsec_private *)dev->priv; - struct tsec __iomem *regs = priv->regs; - uint16_t status; - int i; - - /* reset the indices to zero */ - rx_idx = 0; - tx_idx = 0; -#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129 - uint svr; -#endif - - /* Point to the buffer descriptors */ - out_be32(®s->tbase, (u32)&txbd[0]); - out_be32(®s->rbase, (u32)&rxbd[0]); - - /* Initialize the Rx Buffer descriptors */ - for (i = 0; i < PKTBUFSRX; i++) { - out_be16(&rxbd[i].status, RXBD_EMPTY); - out_be16(&rxbd[i].length, 0); - out_be32(&rxbd[i].bufptr, (u32)NetRxPackets[i]); - } - status = in_be16(&rxbd[PKTBUFSRX - 1].status); - out_be16(&rxbd[PKTBUFSRX - 1].status, status | RXBD_WRAP); - - /* Initialize the TX Buffer Descriptors */ - for (i = 0; i < TX_BUF_CNT; i++) { - out_be16(&txbd[i].status, 0); - out_be16(&txbd[i].length, 0); - out_be32(&txbd[i].bufptr, 0); - } - status = in_be16(&txbd[TX_BUF_CNT - 1].status); - out_be16(&txbd[TX_BUF_CNT - 1].status, status | TXBD_WRAP); - -#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129 - svr = get_svr(); - if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0)) - redundant_init(dev); -#endif - /* Enable Transmit and Receive */ - setbits_be32(®s->maccfg1, MACCFG1_RX_EN | MACCFG1_TX_EN); - - /* Tell the DMA it is clear to go */ - setbits_be32(®s->dmactrl, DMACTRL_INIT_SETTINGS); - out_be32(®s->tstat, TSTAT_CLEAR_THALT); - out_be32(®s->rstat, RSTAT_CLEAR_RHALT); - clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS); -} - -/* This returns the status bits of the device. The return value - * is never checked, and this is what the 8260 driver did, so we - * do the same. Presumably, this would be zero if there were no - * errors - */ -static int tsec_send(struct eth_device *dev, void *packet, int length) -{ - struct tsec_private *priv = (struct tsec_private *)dev->priv; - struct tsec __iomem *regs = priv->regs; - uint16_t status; - int result = 0; - int i; - - /* Find an empty buffer descriptor */ - for (i = 0; in_be16(&txbd[tx_idx].status) & TXBD_READY; i++) { - if (i >= TOUT_LOOP) { - debug("%s: tsec: tx buffers full\n", dev->name); - return result; - } - } - - out_be32(&txbd[tx_idx].bufptr, (u32)packet); - out_be16(&txbd[tx_idx].length, length); - status = in_be16(&txbd[tx_idx].status); - out_be16(&txbd[tx_idx].status, status | - (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT)); - - /* Tell the DMA to go */ - out_be32(®s->tstat, TSTAT_CLEAR_THALT); - - /* Wait for buffer to be transmitted */ - for (i = 0; in_be16(&txbd[tx_idx].status) & TXBD_READY; i++) { - if (i >= TOUT_LOOP) { - debug("%s: tsec: tx error\n", dev->name); - return result; - } - } - - tx_idx = (tx_idx + 1) % TX_BUF_CNT; - result = in_be16(&txbd[tx_idx].status) & TXBD_STATS; - - return result; -} - -static int tsec_recv(struct eth_device *dev) -{ - struct tsec_private *priv = (struct tsec_private *)dev->priv; - struct tsec __iomem *regs = priv->regs; - - while (!(in_be16(&rxbd[rx_idx].status) & RXBD_EMPTY)) { - int length = in_be16(&rxbd[rx_idx].length); - uint16_t status = in_be16(&rxbd[rx_idx].status); - - /* Send the packet up if there were no errors */ - if (!(status & RXBD_STATS)) - NetReceive(NetRxPackets[rx_idx], length - 4); - else - printf("Got error %x\n", (status & RXBD_STATS)); - - out_be16(&rxbd[rx_idx].length, 0); - - status = RXBD_EMPTY; - /* Set the wrap bit if this is the last element in the list */ - if ((rx_idx + 1) == PKTBUFSRX) - status |= RXBD_WRAP; - out_be16(&rxbd[rx_idx].status, status); - - rx_idx = (rx_idx + 1) % PKTBUFSRX; - } - - if (in_be32(®s->ievent) & IEVENT_BSY) { - out_be32(®s->ievent, IEVENT_BSY); - out_be32(®s->rstat, RSTAT_CLEAR_RHALT); - } - - return -1; - -} - -/* Stop the interface */ -static void tsec_halt(struct eth_device *dev) -{ - struct tsec_private *priv = (struct tsec_private *)dev->priv; - struct tsec __iomem *regs = priv->regs; - - clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS); - setbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS); - - while ((in_be32(®s->ievent) & (IEVENT_GRSC | IEVENT_GTSC)) - != (IEVENT_GRSC | IEVENT_GTSC)) - ; - - clrbits_be32(®s->maccfg1, MACCFG1_TX_EN | MACCFG1_RX_EN); - - /* Shut down the PHY, as needed */ - phy_shutdown(priv->phydev); -} - -/* Initializes data structures and registers for the controller, - * and brings the interface up. Returns the link status, meaning - * that it returns success if the link is up, failure otherwise. - * This allows u-boot to find the first active controller. - */ -static int tsec_init(struct eth_device *dev, bd_t * bd) -{ - struct tsec_private *priv = (struct tsec_private *)dev->priv; - struct tsec __iomem *regs = priv->regs; - u32 tempval; - int ret; - - /* Make sure the controller is stopped */ - tsec_halt(dev); - - /* Init MACCFG2. Defaults to GMII */ - out_be32(®s->maccfg2, MACCFG2_INIT_SETTINGS); - - /* Init ECNTRL */ - out_be32(®s->ecntrl, ECNTRL_INIT_SETTINGS); - - /* Copy the station address into the address registers. - * For a station address of 0x12345678ABCD in transmission - * order (BE), MACnADDR1 is set to 0xCDAB7856 and - * MACnADDR2 is set to 0x34120000. - */ - tempval = (dev->enetaddr[5] << 24) | (dev->enetaddr[4] << 16) | - (dev->enetaddr[3] << 8) | dev->enetaddr[2]; - - out_be32(®s->macstnaddr1, tempval); - - tempval = (dev->enetaddr[1] << 24) | (dev->enetaddr[0] << 16); - - out_be32(®s->macstnaddr2, tempval); - - /* Clear out (for the most part) the other registers */ - init_registers(regs); - - /* Ready the device for tx/rx */ - startup_tsec(dev); - - /* Start up the PHY */ - ret = phy_startup(priv->phydev); - if (ret) { - printf("Could not initialize PHY %s\n", - priv->phydev->dev->name); - return ret; - } - - adjust_link(priv, priv->phydev); - - /* If there's no link, fail */ - return priv->phydev->link ? 0 : -1; -} - -static phy_interface_t tsec_get_interface(struct tsec_private *priv) -{ - struct tsec __iomem *regs = priv->regs; - u32 ecntrl; - - ecntrl = in_be32(®s->ecntrl); - - if (ecntrl & ECNTRL_SGMII_MODE) - return PHY_INTERFACE_MODE_SGMII; - - if (ecntrl & ECNTRL_TBI_MODE) { - if (ecntrl & ECNTRL_REDUCED_MODE) - return PHY_INTERFACE_MODE_RTBI; - else - return PHY_INTERFACE_MODE_TBI; - } - - if (ecntrl & ECNTRL_REDUCED_MODE) { - if (ecntrl & ECNTRL_REDUCED_MII_MODE) - return PHY_INTERFACE_MODE_RMII; - else { - phy_interface_t interface = priv->interface; - - /* - * This isn't autodetected, so it must - * be set by the platform code. - */ - if ((interface == PHY_INTERFACE_MODE_RGMII_ID) || - (interface == PHY_INTERFACE_MODE_RGMII_TXID) || - (interface == PHY_INTERFACE_MODE_RGMII_RXID)) - return interface; - - return PHY_INTERFACE_MODE_RGMII; - } - } - - if (priv->flags & TSEC_GIGABIT) - return PHY_INTERFACE_MODE_GMII; - - return PHY_INTERFACE_MODE_MII; -} - - -/* Discover which PHY is attached to the device, and configure it - * properly. If the PHY is not recognized, then return 0 - * (failure). Otherwise, return 1 - */ -static int init_phy(struct eth_device *dev) -{ - struct tsec_private *priv = (struct tsec_private *)dev->priv; - struct phy_device *phydev; - struct tsec __iomem *regs = priv->regs; - u32 supported = (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full); - - if (priv->flags & TSEC_GIGABIT) - supported |= SUPPORTED_1000baseT_Full; - - /* Assign a Physical address to the TBI */ - out_be32(®s->tbipa, CONFIG_SYS_TBIPA_VALUE); - - priv->interface = tsec_get_interface(priv); - - if (priv->interface == PHY_INTERFACE_MODE_SGMII) - tsec_configure_serdes(priv); - - phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface); - - phydev->supported &= supported; - phydev->advertising = phydev->supported; - - priv->phydev = phydev; - - phy_config(phydev); - - return 1; -} - -/* Initialize device structure. Returns success if PHY - * initialization succeeded (i.e. if it recognizes the PHY) - */ -static int tsec_initialize(bd_t *bis, struct tsec_info_struct *tsec_info) -{ - struct eth_device *dev; - int i; - struct tsec_private *priv; - - dev = (struct eth_device *)malloc(sizeof *dev); - - if (NULL == dev) - return 0; - - memset(dev, 0, sizeof *dev); - - priv = (struct tsec_private *)malloc(sizeof(*priv)); - - if (NULL == priv) - return 0; - - priv->regs = tsec_info->regs; - priv->phyregs_sgmii = tsec_info->miiregs_sgmii; - - priv->phyaddr = tsec_info->phyaddr; - priv->flags = tsec_info->flags; - - sprintf(dev->name, tsec_info->devname); - priv->interface = tsec_info->interface; - priv->bus = miiphy_get_dev_by_name(tsec_info->mii_devname); - dev->iobase = 0; - dev->priv = priv; - dev->init = tsec_init; - dev->halt = tsec_halt; - dev->send = tsec_send; - dev->recv = tsec_recv; -#ifdef CONFIG_MCAST_TFTP - dev->mcast = tsec_mcast_addr; -#endif - - /* Tell u-boot to get the addr from the env */ - for (i = 0; i < 6; i++) - dev->enetaddr[i] = 0; - - eth_register(dev); - - /* Reset the MAC */ - setbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET); - udelay(2); /* Soft Reset must be asserted for 3 TX clocks */ - clrbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET); - - /* Try to initialize PHY here, and return */ - return init_phy(dev); -} - -/* - * Initialize all the TSEC devices - * - * Returns the number of TSEC devices that were initialized - */ -int tsec_eth_init(bd_t *bis, struct tsec_info_struct *tsecs, int num) -{ - int i; - int ret, count = 0; - - for (i = 0; i < num; i++) { - ret = tsec_initialize(bis, &tsecs[i]); - if (ret > 0) - count += ret; - } - - return count; -} - -int tsec_standard_init(bd_t *bis) -{ - struct fsl_pq_mdio_info info; - - info.regs = TSEC_GET_MDIO_REGS_BASE(1); - info.name = DEFAULT_MII_NAME; - - fsl_pq_mdio_init(bis, &info); - - return tsec_eth_init(bis, tsec_info, ARRAY_SIZE(tsec_info)); -} diff --git a/qemu/roms/u-boot/drivers/net/tsi108_eth.c b/qemu/roms/u-boot/drivers/net/tsi108_eth.c deleted file mode 100644 index 72b8159d8..000000000 --- a/qemu/roms/u-boot/drivers/net/tsi108_eth.c +++ /dev/null @@ -1,1016 +0,0 @@ -/*********************************************************************** - * - * Copyright (c) 2005 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Description: - * Ethernet interface for Tundra TSI108 bridge chip - * - ***********************************************************************/ - -#include <config.h> - -#if !defined(CONFIG_TSI108_ETH_NUM_PORTS) || (CONFIG_TSI108_ETH_NUM_PORTS > 2) -#error "CONFIG_TSI108_ETH_NUM_PORTS must be defined as 1 or 2" -#endif - -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <asm/cache.h> - -#ifdef DEBUG -#define TSI108_ETH_DEBUG 7 -#else -#define TSI108_ETH_DEBUG 0 -#endif - -#if TSI108_ETH_DEBUG > 0 -#define debug_lev(lev, fmt, args...) \ -if (lev <= TSI108_ETH_DEBUG) \ -printf ("%s %d: " fmt, __FUNCTION__, __LINE__, ##args) -#else -#define debug_lev(lev, fmt, args...) do{}while(0) -#endif - -#define RX_PRINT_ERRORS -#define TX_PRINT_ERRORS - -#define ETH_BASE (CONFIG_SYS_TSI108_CSR_BASE + 0x6000) - -#define ETH_PORT_OFFSET 0x400 - -#define __REG32(base, offset) (*((volatile u32 *)((char *)(base) + (offset)))) - -#define reg_MAC_CONFIG_1(base) __REG32(base, 0x00000000) -#define MAC_CONFIG_1_TX_ENABLE (0x00000001) -#define MAC_CONFIG_1_SYNC_TX_ENABLE (0x00000002) -#define MAC_CONFIG_1_RX_ENABLE (0x00000004) -#define MAC_CONFIG_1_SYNC_RX_ENABLE (0x00000008) -#define MAC_CONFIG_1_TX_FLOW_CONTROL (0x00000010) -#define MAC_CONFIG_1_RX_FLOW_CONTROL (0x00000020) -#define MAC_CONFIG_1_LOOP_BACK (0x00000100) -#define MAC_CONFIG_1_RESET_TX_FUNCTION (0x00010000) -#define MAC_CONFIG_1_RESET_RX_FUNCTION (0x00020000) -#define MAC_CONFIG_1_RESET_TX_MAC (0x00040000) -#define MAC_CONFIG_1_RESET_RX_MAC (0x00080000) -#define MAC_CONFIG_1_SIM_RESET (0x40000000) -#define MAC_CONFIG_1_SOFT_RESET (0x80000000) - -#define reg_MAC_CONFIG_2(base) __REG32(base, 0x00000004) -#define MAC_CONFIG_2_FULL_DUPLEX (0x00000001) -#define MAC_CONFIG_2_CRC_ENABLE (0x00000002) -#define MAC_CONFIG_2_PAD_CRC (0x00000004) -#define MAC_CONFIG_2_LENGTH_CHECK (0x00000010) -#define MAC_CONFIG_2_HUGE_FRAME (0x00000020) -#define MAC_CONFIG_2_INTERFACE_MODE(val) (((val) & 0x3) << 8) -#define MAC_CONFIG_2_PREAMBLE_LENGTH(val) (((val) & 0xf) << 12) -#define INTERFACE_MODE_NIBBLE 1 /* 10/100 Mb/s MII) */ -#define INTERFACE_MODE_BYTE 2 /* 1000 Mb/s GMII/TBI */ - -#define reg_MAXIMUM_FRAME_LENGTH(base) __REG32(base, 0x00000010) - -#define reg_MII_MGMT_CONFIG(base) __REG32(base, 0x00000020) -#define MII_MGMT_CONFIG_MGMT_CLOCK_SELECT(val) ((val) & 0x7) -#define MII_MGMT_CONFIG_NO_PREAMBLE (0x00000010) -#define MII_MGMT_CONFIG_SCAN_INCREMENT (0x00000020) -#define MII_MGMT_CONFIG_RESET_MGMT (0x80000000) - -#define reg_MII_MGMT_COMMAND(base) __REG32(base, 0x00000024) -#define MII_MGMT_COMMAND_READ_CYCLE (0x00000001) -#define MII_MGMT_COMMAND_SCAN_CYCLE (0x00000002) - -#define reg_MII_MGMT_ADDRESS(base) __REG32(base, 0x00000028) -#define reg_MII_MGMT_CONTROL(base) __REG32(base, 0x0000002c) -#define reg_MII_MGMT_STATUS(base) __REG32(base, 0x00000030) - -#define reg_MII_MGMT_INDICATORS(base) __REG32(base, 0x00000034) -#define MII_MGMT_INDICATORS_BUSY (0x00000001) -#define MII_MGMT_INDICATORS_SCAN (0x00000002) -#define MII_MGMT_INDICATORS_NOT_VALID (0x00000004) - -#define reg_INTERFACE_STATUS(base) __REG32(base, 0x0000003c) -#define INTERFACE_STATUS_LINK_FAIL (0x00000008) -#define INTERFACE_STATUS_EXCESS_DEFER (0x00000200) - -#define reg_STATION_ADDRESS_1(base) __REG32(base, 0x00000040) -#define reg_STATION_ADDRESS_2(base) __REG32(base, 0x00000044) - -#define reg_PORT_CONTROL(base) __REG32(base, 0x00000200) -#define PORT_CONTROL_PRI (0x00000001) -#define PORT_CONTROL_BPT (0x00010000) -#define PORT_CONTROL_SPD (0x00040000) -#define PORT_CONTROL_RBC (0x00080000) -#define PORT_CONTROL_PRB (0x00200000) -#define PORT_CONTROL_DIS (0x00400000) -#define PORT_CONTROL_TBI (0x00800000) -#define PORT_CONTROL_STE (0x10000000) -#define PORT_CONTROL_ZOR (0x20000000) -#define PORT_CONTROL_CLR (0x40000000) -#define PORT_CONTROL_SRT (0x80000000) - -#define reg_TX_CONFIG(base) __REG32(base, 0x00000220) -#define TX_CONFIG_START_Q (0x00000003) -#define TX_CONFIG_EHP (0x00400000) -#define TX_CONFIG_CHP (0x00800000) -#define TX_CONFIG_RST (0x80000000) - -#define reg_TX_CONTROL(base) __REG32(base, 0x00000224) -#define TX_CONTROL_GO (0x00008000) -#define TX_CONTROL_MP (0x01000000) -#define TX_CONTROL_EAI (0x20000000) -#define TX_CONTROL_ABT (0x40000000) -#define TX_CONTROL_EII (0x80000000) - -#define reg_TX_STATUS(base) __REG32(base, 0x00000228) -#define TX_STATUS_QUEUE_USABLE (0x0000000f) -#define TX_STATUS_CURR_Q (0x00000300) -#define TX_STATUS_ACT (0x00008000) -#define TX_STATUS_QUEUE_IDLE (0x000f0000) -#define TX_STATUS_EOQ_PENDING (0x0f000000) - -#define reg_TX_EXTENDED_STATUS(base) __REG32(base, 0x0000022c) -#define TX_EXTENDED_STATUS_END_OF_QUEUE_CONDITION (0x0000000f) -#define TX_EXTENDED_STATUS_END_OF_FRAME_CONDITION (0x00000f00) -#define TX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION (0x000f0000) -#define TX_EXTENDED_STATUS_ERROR_FLAG (0x0f000000) - -#define reg_TX_THRESHOLDS(base) __REG32(base, 0x00000230) - -#define reg_TX_DIAGNOSTIC_ADDR(base) __REG32(base, 0x00000270) -#define TX_DIAGNOSTIC_ADDR_INDEX (0x0000007f) -#define TX_DIAGNOSTIC_ADDR_DFR (0x40000000) -#define TX_DIAGNOSTIC_ADDR_AI (0x80000000) - -#define reg_TX_DIAGNOSTIC_DATA(base) __REG32(base, 0x00000274) - -#define reg_TX_ERROR_STATUS(base) __REG32(base, 0x00000278) -#define TX_ERROR_STATUS (0x00000278) -#define TX_ERROR_STATUS_QUEUE_0_ERROR_RESPONSE (0x0000000f) -#define TX_ERROR_STATUS_TEA_ON_QUEUE_0 (0x00000010) -#define TX_ERROR_STATUS_RER_ON_QUEUE_0 (0x00000020) -#define TX_ERROR_STATUS_TER_ON_QUEUE_0 (0x00000040) -#define TX_ERROR_STATUS_DER_ON_QUEUE_0 (0x00000080) -#define TX_ERROR_STATUS_QUEUE_1_ERROR_RESPONSE (0x00000f00) -#define TX_ERROR_STATUS_TEA_ON_QUEUE_1 (0x00001000) -#define TX_ERROR_STATUS_RER_ON_QUEUE_1 (0x00002000) -#define TX_ERROR_STATUS_TER_ON_QUEUE_1 (0x00004000) -#define TX_ERROR_STATUS_DER_ON_QUEUE_1 (0x00008000) -#define TX_ERROR_STATUS_QUEUE_2_ERROR_RESPONSE (0x000f0000) -#define TX_ERROR_STATUS_TEA_ON_QUEUE_2 (0x00100000) -#define TX_ERROR_STATUS_RER_ON_QUEUE_2 (0x00200000) -#define TX_ERROR_STATUS_TER_ON_QUEUE_2 (0x00400000) -#define TX_ERROR_STATUS_DER_ON_QUEUE_2 (0x00800000) -#define TX_ERROR_STATUS_QUEUE_3_ERROR_RESPONSE (0x0f000000) -#define TX_ERROR_STATUS_TEA_ON_QUEUE_3 (0x10000000) -#define TX_ERROR_STATUS_RER_ON_QUEUE_3 (0x20000000) -#define TX_ERROR_STATUS_TER_ON_QUEUE_3 (0x40000000) -#define TX_ERROR_STATUS_DER_ON_QUEUE_3 (0x80000000) - -#define reg_TX_QUEUE_0_CONFIG(base) __REG32(base, 0x00000280) -#define TX_QUEUE_0_CONFIG_OCN_PORT (0x0000003f) -#define TX_QUEUE_0_CONFIG_BSWP (0x00000400) -#define TX_QUEUE_0_CONFIG_WSWP (0x00000800) -#define TX_QUEUE_0_CONFIG_AM (0x00004000) -#define TX_QUEUE_0_CONFIG_GVI (0x00008000) -#define TX_QUEUE_0_CONFIG_EEI (0x00010000) -#define TX_QUEUE_0_CONFIG_ELI (0x00020000) -#define TX_QUEUE_0_CONFIG_ENI (0x00040000) -#define TX_QUEUE_0_CONFIG_ESI (0x00080000) -#define TX_QUEUE_0_CONFIG_EDI (0x00100000) - -#define reg_TX_QUEUE_0_BUF_CONFIG(base) __REG32(base, 0x00000284) -#define TX_QUEUE_0_BUF_CONFIG_OCN_PORT (0x0000003f) -#define TX_QUEUE_0_BUF_CONFIG_BURST (0x00000300) -#define TX_QUEUE_0_BUF_CONFIG_BSWP (0x00000400) -#define TX_QUEUE_0_BUF_CONFIG_WSWP (0x00000800) - -#define OCN_PORT_HLP 0 /* HLP Interface */ -#define OCN_PORT_PCI_X 1 /* PCI-X Interface */ -#define OCN_PORT_PROCESSOR_MASTER 2 /* Processor Interface (master) */ -#define OCN_PORT_PROCESSOR_SLAVE 3 /* Processor Interface (slave) */ -#define OCN_PORT_MEMORY 4 /* Memory Controller */ -#define OCN_PORT_DMA 5 /* DMA Controller */ -#define OCN_PORT_ETHERNET 6 /* Ethernet Controller */ -#define OCN_PORT_PRINT 7 /* Print Engine Interface */ - -#define reg_TX_QUEUE_0_PTR_LOW(base) __REG32(base, 0x00000288) - -#define reg_TX_QUEUE_0_PTR_HIGH(base) __REG32(base, 0x0000028c) -#define TX_QUEUE_0_PTR_HIGH_VALID (0x80000000) - -#define reg_RX_CONFIG(base) __REG32(base, 0x00000320) -#define RX_CONFIG_DEF_Q (0x00000003) -#define RX_CONFIG_EMF (0x00000100) -#define RX_CONFIG_EUF (0x00000200) -#define RX_CONFIG_BFE (0x00000400) -#define RX_CONFIG_MFE (0x00000800) -#define RX_CONFIG_UFE (0x00001000) -#define RX_CONFIG_SE (0x00002000) -#define RX_CONFIG_ABF (0x00200000) -#define RX_CONFIG_APE (0x00400000) -#define RX_CONFIG_CHP (0x00800000) -#define RX_CONFIG_RST (0x80000000) - -#define reg_RX_CONTROL(base) __REG32(base, 0x00000324) -#define GE_E0_RX_CONTROL_QUEUE_ENABLES (0x0000000f) -#define GE_E0_RX_CONTROL_GO (0x00008000) -#define GE_E0_RX_CONTROL_EAI (0x20000000) -#define GE_E0_RX_CONTROL_ABT (0x40000000) -#define GE_E0_RX_CONTROL_EII (0x80000000) - -#define reg_RX_EXTENDED_STATUS(base) __REG32(base, 0x0000032c) -#define RX_EXTENDED_STATUS (0x0000032c) -#define RX_EXTENDED_STATUS_EOQ (0x0000000f) -#define RX_EXTENDED_STATUS_EOQ_0 (0x00000001) -#define RX_EXTENDED_STATUS_EOF (0x00000f00) -#define RX_EXTENDED_STATUS_DESCRIPTOR_INTERRUPT_CONDITION (0x000f0000) -#define RX_EXTENDED_STATUS_ERROR_FLAG (0x0f000000) - -#define reg_RX_THRESHOLDS(base) __REG32(base, 0x00000330) - -#define reg_RX_DIAGNOSTIC_ADDR(base) __REG32(base, 0x00000370) -#define RX_DIAGNOSTIC_ADDR_INDEX (0x0000007f) -#define RX_DIAGNOSTIC_ADDR_DFR (0x40000000) -#define RX_DIAGNOSTIC_ADDR_AI (0x80000000) - -#define reg_RX_DIAGNOSTIC_DATA(base) __REG32(base, 0x00000374) - -#define reg_RX_QUEUE_0_CONFIG(base) __REG32(base, 0x00000380) -#define RX_QUEUE_0_CONFIG_OCN_PORT (0x0000003f) -#define RX_QUEUE_0_CONFIG_BSWP (0x00000400) -#define RX_QUEUE_0_CONFIG_WSWP (0x00000800) -#define RX_QUEUE_0_CONFIG_AM (0x00004000) -#define RX_QUEUE_0_CONFIG_EEI (0x00010000) -#define RX_QUEUE_0_CONFIG_ELI (0x00020000) -#define RX_QUEUE_0_CONFIG_ENI (0x00040000) -#define RX_QUEUE_0_CONFIG_ESI (0x00080000) -#define RX_QUEUE_0_CONFIG_EDI (0x00100000) - -#define reg_RX_QUEUE_0_BUF_CONFIG(base) __REG32(base, 0x00000384) -#define RX_QUEUE_0_BUF_CONFIG_OCN_PORT (0x0000003f) -#define RX_QUEUE_0_BUF_CONFIG_BURST (0x00000300) -#define RX_QUEUE_0_BUF_CONFIG_BSWP (0x00000400) -#define RX_QUEUE_0_BUF_CONFIG_WSWP (0x00000800) - -#define reg_RX_QUEUE_0_PTR_LOW(base) __REG32(base, 0x00000388) - -#define reg_RX_QUEUE_0_PTR_HIGH(base) __REG32(base, 0x0000038c) -#define RX_QUEUE_0_PTR_HIGH_VALID (0x80000000) - -/* - * PHY register definitions - */ -/* the first 15 PHY registers are standard. */ -#define PHY_CTRL_REG 0 /* Control Register */ -#define PHY_STATUS_REG 1 /* Status Regiser */ -#define PHY_ID1_REG 2 /* Phy Id Reg (word 1) */ -#define PHY_ID2_REG 3 /* Phy Id Reg (word 2) */ -#define PHY_AN_ADV_REG 4 /* Autoneg Advertisement */ -#define PHY_LP_ABILITY_REG 5 /* Link Partner Ability (Base Page) */ -#define PHY_AUTONEG_EXP_REG 6 /* Autoneg Expansion Reg */ -#define PHY_NEXT_PAGE_TX_REG 7 /* Next Page TX */ -#define PHY_LP_NEXT_PAGE_REG 8 /* Link Partner Next Page */ -#define PHY_1000T_CTRL_REG 9 /* 1000Base-T Control Reg */ -#define PHY_1000T_STATUS_REG 10 /* 1000Base-T Status Reg */ -#define PHY_EXT_STATUS_REG 11 /* Extended Status Reg */ - -/* - * PHY Register bit masks. - */ -#define PHY_CTRL_RESET (1 << 15) -#define PHY_CTRL_LOOPBACK (1 << 14) -#define PHY_CTRL_SPEED0 (1 << 13) -#define PHY_CTRL_AN_EN (1 << 12) -#define PHY_CTRL_PWR_DN (1 << 11) -#define PHY_CTRL_ISOLATE (1 << 10) -#define PHY_CTRL_RESTART_AN (1 << 9) -#define PHY_CTRL_FULL_DUPLEX (1 << 8) -#define PHY_CTRL_CT_EN (1 << 7) -#define PHY_CTRL_SPEED1 (1 << 6) - -#define PHY_STAT_100BASE_T4 (1 << 15) -#define PHY_STAT_100BASE_X_FD (1 << 14) -#define PHY_STAT_100BASE_X_HD (1 << 13) -#define PHY_STAT_10BASE_T_FD (1 << 12) -#define PHY_STAT_10BASE_T_HD (1 << 11) -#define PHY_STAT_100BASE_T2_FD (1 << 10) -#define PHY_STAT_100BASE_T2_HD (1 << 9) -#define PHY_STAT_EXT_STAT (1 << 8) -#define PHY_STAT_RESERVED (1 << 7) -#define PHY_STAT_MFPS (1 << 6) /* Management Frames Preamble Suppression */ -#define PHY_STAT_AN_COMPLETE (1 << 5) -#define PHY_STAT_REM_FAULT (1 << 4) -#define PHY_STAT_AN_CAP (1 << 3) -#define PHY_STAT_LINK_UP (1 << 2) -#define PHY_STAT_JABBER (1 << 1) -#define PHY_STAT_EXT_CAP (1 << 0) - -#define TBI_CONTROL_2 0x11 -#define TBI_CONTROL_2_ENABLE_COMMA_DETECT 0x0001 -#define TBI_CONTROL_2_ENABLE_WRAP 0x0002 -#define TBI_CONTROL_2_G_MII_MODE 0x0010 -#define TBI_CONTROL_2_RECEIVE_CLOCK_SELECT 0x0020 -#define TBI_CONTROL_2_AUTO_NEGOTIATION_SENSE 0x0100 -#define TBI_CONTROL_2_DISABLE_TRANSMIT_RUNNING_DISPARITY 0x1000 -#define TBI_CONTROL_2_DISABLE_RECEIVE_RUNNING_DISPARITY 0x2000 -#define TBI_CONTROL_2_SHORTCUT_LINK_TIMER 0x4000 -#define TBI_CONTROL_2_SOFT_RESET 0x8000 - -/* marvel specific */ -#define MV1111_EXT_CTRL1_REG 16 /* PHY Specific Control Reg */ -#define MV1111_SPEC_STAT_REG 17 /* PHY Specific Status Reg */ -#define MV1111_EXT_CTRL2_REG 20 /* Extended PHY Specific Control Reg */ - -/* - * MARVELL 88E1111 PHY register bit masks - */ -/* PHY Specific Status Register (MV1111_EXT_CTRL1_REG) */ - -#define SPEC_STAT_SPEED_MASK (3 << 14) -#define SPEC_STAT_FULL_DUP (1 << 13) -#define SPEC_STAT_PAGE_RCVD (1 << 12) -#define SPEC_STAT_RESOLVED (1 << 11) /* Speed and Duplex Resolved */ -#define SPEC_STAT_LINK_UP (1 << 10) -#define SPEC_STAT_CABLE_LEN_MASK (7 << 7)/* Cable Length (100/1000 modes only) */ -#define SPEC_STAT_MDIX (1 << 6) -#define SPEC_STAT_POLARITY (1 << 1) -#define SPEC_STAT_JABBER (1 << 0) - -#define SPEED_1000 (2 << 14) -#define SPEED_100 (1 << 14) -#define SPEED_10 (0 << 14) - -#define TBI_ADDR 0x1E /* Ten Bit Interface address */ - -/* negotiated link parameters */ -#define LINK_SPEED_UNKNOWN 0 -#define LINK_SPEED_10 1 -#define LINK_SPEED_100 2 -#define LINK_SPEED_1000 3 - -#define LINK_DUPLEX_UNKNOWN 0 -#define LINK_DUPLEX_HALF 1 -#define LINK_DUPLEX_FULL 2 - -static unsigned int phy_address[] = { 8, 9 }; - -#define vuint32 volatile u32 - -/* TX/RX buffer descriptors. MUST be cache line aligned in memory. (32 byte) - * This structure is accessed by the ethernet DMA engine which means it - * MUST be in LITTLE ENDIAN format */ -struct dma_descriptor { - vuint32 start_addr0; /* buffer address, least significant bytes. */ - vuint32 start_addr1; /* buffer address, most significant bytes. */ - vuint32 next_descr_addr0;/* next descriptor address, least significant bytes. Must be 64-bit aligned. */ - vuint32 next_descr_addr1;/* next descriptor address, most significant bytes. */ - vuint32 vlan_byte_count;/* VLAN tag(top 2 bytes) and byte countt (bottom 2 bytes). */ - vuint32 config_status; /* Configuration/Status. */ - vuint32 reserved1; /* reserved to make the descriptor cache line aligned. */ - vuint32 reserved2; /* reserved to make the descriptor cache line aligned. */ -}; - -/* last next descriptor address flag */ -#define DMA_DESCR_LAST (1 << 31) - -/* TX DMA descriptor config status bits */ -#define DMA_DESCR_TX_EOF (1 << 0) /* end of frame */ -#define DMA_DESCR_TX_SOF (1 << 1) /* start of frame */ -#define DMA_DESCR_TX_PFVLAN (1 << 2) -#define DMA_DESCR_TX_HUGE (1 << 3) -#define DMA_DESCR_TX_PAD (1 << 4) -#define DMA_DESCR_TX_CRC (1 << 5) -#define DMA_DESCR_TX_DESCR_INT (1 << 14) -#define DMA_DESCR_TX_RETRY_COUNT 0x000F0000 -#define DMA_DESCR_TX_ONE_COLLISION (1 << 20) -#define DMA_DESCR_TX_LATE_COLLISION (1 << 24) -#define DMA_DESCR_TX_UNDERRUN (1 << 25) -#define DMA_DESCR_TX_RETRY_LIMIT (1 << 26) -#define DMA_DESCR_TX_OK (1 << 30) -#define DMA_DESCR_TX_OWNER (1 << 31) - -/* RX DMA descriptor status bits */ -#define DMA_DESCR_RX_EOF (1 << 0) -#define DMA_DESCR_RX_SOF (1 << 1) -#define DMA_DESCR_RX_VTF (1 << 2) -#define DMA_DESCR_RX_FRAME_IS_TYPE (1 << 3) -#define DMA_DESCR_RX_SHORT_FRAME (1 << 4) -#define DMA_DESCR_RX_HASH_MATCH (1 << 7) -#define DMA_DESCR_RX_BAD_FRAME (1 << 8) -#define DMA_DESCR_RX_OVERRUN (1 << 9) -#define DMA_DESCR_RX_MAX_FRAME_LEN (1 << 11) -#define DMA_DESCR_RX_CRC_ERROR (1 << 12) -#define DMA_DESCR_RX_DESCR_INT (1 << 13) -#define DMA_DESCR_RX_OWNER (1 << 15) - -#define RX_BUFFER_SIZE PKTSIZE -#define NUM_RX_DESC PKTBUFSRX - -static struct dma_descriptor tx_descriptor __attribute__ ((aligned(32))); - -static struct dma_descriptor rx_descr_array[NUM_RX_DESC] - __attribute__ ((aligned(32))); - -static struct dma_descriptor *rx_descr_current; - -static int tsi108_eth_probe (struct eth_device *dev, bd_t * bis); -static int tsi108_eth_send(struct eth_device *dev, void *packet, int length); -static int tsi108_eth_recv (struct eth_device *dev); -static void tsi108_eth_halt (struct eth_device *dev); -static unsigned int read_phy (unsigned int base, - unsigned int phy_addr, unsigned int phy_reg); -static void write_phy (unsigned int base, - unsigned int phy_addr, - unsigned int phy_reg, unsigned int phy_data); - -#if TSI108_ETH_DEBUG > 100 -/* - * print phy debug infomation - */ -static void dump_phy_regs (unsigned int phy_addr) -{ - int i; - - printf ("PHY %d registers\n", phy_addr); - for (i = 0; i <= 30; i++) { - printf ("%2d 0x%04x\n", i, read_phy (ETH_BASE, phy_addr, i)); - } - printf ("\n"); - -} -#else -#define dump_phy_regs(base) do{}while(0) -#endif - -#if TSI108_ETH_DEBUG > 100 -/* - * print debug infomation - */ -static void tx_diag_regs (unsigned int base) -{ - int i; - unsigned long dummy; - - printf ("TX diagnostics registers\n"); - reg_TX_DIAGNOSTIC_ADDR(base) = 0x00 | TX_DIAGNOSTIC_ADDR_AI; - udelay (1000); - dummy = reg_TX_DIAGNOSTIC_DATA(base); - for (i = 0x00; i <= 0x05; i++) { - udelay (1000); - printf ("0x%02x 0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base)); - } - reg_TX_DIAGNOSTIC_ADDR(base) = 0x40 | TX_DIAGNOSTIC_ADDR_AI; - udelay (1000); - dummy = reg_TX_DIAGNOSTIC_DATA(base); - for (i = 0x40; i <= 0x47; i++) { - udelay (1000); - printf ("0x%02x 0x%08x\n", i, reg_TX_DIAGNOSTIC_DATA(base)); - } - printf ("\n"); - -} -#else -#define tx_diag_regs(base) do{}while(0) -#endif - -#if TSI108_ETH_DEBUG > 100 -/* - * print debug infomation - */ -static void rx_diag_regs (unsigned int base) -{ - int i; - unsigned long dummy; - - printf ("RX diagnostics registers\n"); - reg_RX_DIAGNOSTIC_ADDR(base) = 0x00 | RX_DIAGNOSTIC_ADDR_AI; - udelay (1000); - dummy = reg_RX_DIAGNOSTIC_DATA(base); - for (i = 0x00; i <= 0x05; i++) { - udelay (1000); - printf ("0x%02x 0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base)); - } - reg_RX_DIAGNOSTIC_ADDR(base) = 0x40 | RX_DIAGNOSTIC_ADDR_AI; - udelay (1000); - dummy = reg_RX_DIAGNOSTIC_DATA(base); - for (i = 0x08; i <= 0x0a; i++) { - udelay (1000); - printf ("0x%02x 0x%08x\n", i, reg_RX_DIAGNOSTIC_DATA(base)); - } - printf ("\n"); - -} -#else -#define rx_diag_regs(base) do{}while(0) -#endif - -#if TSI108_ETH_DEBUG > 100 -/* - * print debug infomation - */ -static void debug_mii_regs (unsigned int base) -{ - printf ("MII_MGMT_CONFIG 0x%08x\n", reg_MII_MGMT_CONFIG(base)); - printf ("MII_MGMT_COMMAND 0x%08x\n", reg_MII_MGMT_COMMAND(base)); - printf ("MII_MGMT_ADDRESS 0x%08x\n", reg_MII_MGMT_ADDRESS(base)); - printf ("MII_MGMT_CONTROL 0x%08x\n", reg_MII_MGMT_CONTROL(base)); - printf ("MII_MGMT_STATUS 0x%08x\n", reg_MII_MGMT_STATUS(base)); - printf ("MII_MGMT_INDICATORS 0x%08x\n", reg_MII_MGMT_INDICATORS(base)); - printf ("\n"); - -} -#else -#define debug_mii_regs(base) do{}while(0) -#endif - -/* - * Wait until the phy bus is non-busy - */ -static void phy_wait (unsigned int base, unsigned int condition) -{ - int timeout; - - timeout = 0; - while (reg_MII_MGMT_INDICATORS(base) & condition) { - udelay (10); - if (++timeout > 10000) { - printf ("ERROR: timeout waiting for phy bus (%d)\n", - condition); - break; - } - } -} - -/* - * read phy register - */ -static unsigned int read_phy (unsigned int base, - unsigned int phy_addr, unsigned int phy_reg) -{ - unsigned int value; - - phy_wait (base, MII_MGMT_INDICATORS_BUSY); - - reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg; - - /* Ensure that the Read Cycle bit is cleared prior to next read cycle */ - reg_MII_MGMT_COMMAND(base) = 0; - - /* start the read */ - reg_MII_MGMT_COMMAND(base) = MII_MGMT_COMMAND_READ_CYCLE; - - /* wait for the read to complete */ - phy_wait (base, - MII_MGMT_INDICATORS_NOT_VALID | MII_MGMT_INDICATORS_BUSY); - - value = reg_MII_MGMT_STATUS(base); - - reg_MII_MGMT_COMMAND(base) = 0; - - return value; -} - -/* - * write phy register - */ -static void write_phy (unsigned int base, - unsigned int phy_addr, - unsigned int phy_reg, unsigned int phy_data) -{ - phy_wait (base, MII_MGMT_INDICATORS_BUSY); - - reg_MII_MGMT_ADDRESS(base) = (phy_addr << 8) | phy_reg; - - /* Ensure that the Read Cycle bit is cleared prior to next cycle */ - reg_MII_MGMT_COMMAND(base) = 0; - - /* start the write */ - reg_MII_MGMT_CONTROL(base) = phy_data; -} - -/* - * configure the marvell 88e1111 phy - */ -static int marvell_88e_phy_config (struct eth_device *dev, int *speed, - int *duplex) -{ - unsigned long base; - unsigned long phy_addr; - unsigned int phy_status; - unsigned int phy_spec_status; - int timeout; - int phy_speed; - int phy_duplex; - unsigned int value; - - phy_speed = LINK_SPEED_UNKNOWN; - phy_duplex = LINK_DUPLEX_UNKNOWN; - - base = dev->iobase; - phy_addr = (unsigned long)dev->priv; - - /* Take the PHY out of reset. */ - write_phy (ETH_BASE, phy_addr, PHY_CTRL_REG, PHY_CTRL_RESET); - - /* Wait for the reset process to complete. */ - udelay (10); - timeout = 0; - while ((phy_status = - read_phy (ETH_BASE, phy_addr, PHY_CTRL_REG)) & PHY_CTRL_RESET) { - udelay (10); - if (++timeout > 10000) { - printf ("ERROR: timeout waiting for phy reset\n"); - break; - } - } - - /* TBI Configuration. */ - write_phy (base, TBI_ADDR, TBI_CONTROL_2, TBI_CONTROL_2_G_MII_MODE | - TBI_CONTROL_2_RECEIVE_CLOCK_SELECT); - /* Wait for the link to be established. */ - timeout = 0; - do { - udelay (20000); - phy_status = read_phy (ETH_BASE, phy_addr, PHY_STATUS_REG); - if (++timeout > 100) { - debug_lev(1, "ERROR: unable to establish link!!!\n"); - break; - } - } while ((phy_status & PHY_STAT_LINK_UP) == 0); - - if ((phy_status & PHY_STAT_LINK_UP) == 0) - return 0; - - value = 0; - phy_spec_status = read_phy (ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG); - if (phy_spec_status & SPEC_STAT_RESOLVED) { - switch (phy_spec_status & SPEC_STAT_SPEED_MASK) { - case SPEED_1000: - phy_speed = LINK_SPEED_1000; - value |= PHY_CTRL_SPEED1; - break; - case SPEED_100: - phy_speed = LINK_SPEED_100; - value |= PHY_CTRL_SPEED0; - break; - case SPEED_10: - phy_speed = LINK_SPEED_10; - break; - } - if (phy_spec_status & SPEC_STAT_FULL_DUP) { - phy_duplex = LINK_DUPLEX_FULL; - value |= PHY_CTRL_FULL_DUPLEX; - } else - phy_duplex = LINK_DUPLEX_HALF; - } - /* set TBI speed */ - write_phy (base, TBI_ADDR, PHY_CTRL_REG, value); - write_phy (base, TBI_ADDR, PHY_AN_ADV_REG, 0x0060); - -#if TSI108_ETH_DEBUG > 0 - printf ("%s link is up", dev->name); - phy_spec_status = read_phy (ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG); - if (phy_spec_status & SPEC_STAT_RESOLVED) { - switch (phy_speed) { - case LINK_SPEED_1000: - printf (", 1000 Mbps"); - break; - case LINK_SPEED_100: - printf (", 100 Mbps"); - break; - case LINK_SPEED_10: - printf (", 10 Mbps"); - break; - } - if (phy_duplex == LINK_DUPLEX_FULL) - printf (", Full duplex"); - else - printf (", Half duplex"); - } - printf ("\n"); -#endif - - dump_phy_regs (TBI_ADDR); - if (speed) - *speed = phy_speed; - if (duplex) - *duplex = phy_duplex; - - return 1; -} - -/* - * External interface - * - * register the tsi108 ethernet controllers with the multi-ethernet system - */ -int tsi108_eth_initialize (bd_t * bis) -{ - struct eth_device *dev; - int index; - - for (index = 0; index < CONFIG_TSI108_ETH_NUM_PORTS; index++) { - dev = (struct eth_device *)malloc(sizeof(struct eth_device)); - if (!dev) { - printf("tsi108: Can not allocate memory\n"); - break; - } - memset(dev, 0, sizeof(*dev)); - sprintf (dev->name, "TSI108_eth%d", index); - - dev->iobase = ETH_BASE + (index * ETH_PORT_OFFSET); - dev->priv = (void *)(phy_address[index]); - dev->init = tsi108_eth_probe; - dev->halt = tsi108_eth_halt; - dev->send = tsi108_eth_send; - dev->recv = tsi108_eth_recv; - - eth_register(dev); - } - return index; -} - -/* - * probe for and initialize a single ethernet interface - */ -static int tsi108_eth_probe (struct eth_device *dev, bd_t * bis) -{ - unsigned long base; - unsigned long value; - int index; - struct dma_descriptor *tx_descr; - struct dma_descriptor *rx_descr; - int speed; - int duplex; - - base = dev->iobase; - - reg_PORT_CONTROL(base) = PORT_CONTROL_STE | PORT_CONTROL_BPT; - - /* Bring DMA/FIFO out of reset. */ - reg_TX_CONFIG(base) = 0x00000000; - reg_RX_CONFIG(base) = 0x00000000; - - reg_TX_THRESHOLDS(base) = (192 << 16) | 192; - reg_RX_THRESHOLDS(base) = (192 << 16) | 112; - - /* Bring MAC out of reset. */ - reg_MAC_CONFIG_1(base) = 0x00000000; - - /* DMA MAC configuration. */ - reg_MAC_CONFIG_1(base) = - MAC_CONFIG_1_RX_ENABLE | MAC_CONFIG_1_TX_ENABLE; - - reg_MII_MGMT_CONFIG(base) = MII_MGMT_CONFIG_NO_PREAMBLE; - reg_MAXIMUM_FRAME_LENGTH(base) = RX_BUFFER_SIZE; - - /* Note: Early tsi108 manual did not have correct byte order - * for the station address.*/ - reg_STATION_ADDRESS_1(base) = (dev->enetaddr[5] << 24) | - (dev->enetaddr[4] << 16) | - (dev->enetaddr[3] << 8) | (dev->enetaddr[2] << 0); - - reg_STATION_ADDRESS_2(base) = (dev->enetaddr[1] << 24) | - (dev->enetaddr[0] << 16); - - if (marvell_88e_phy_config(dev, &speed, &duplex) == 0) - return -1; - - value = - MAC_CONFIG_2_PREAMBLE_LENGTH(7) | MAC_CONFIG_2_PAD_CRC | - MAC_CONFIG_2_CRC_ENABLE; - if (speed == LINK_SPEED_1000) - value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_BYTE); - else { - value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_NIBBLE); - reg_PORT_CONTROL(base) |= PORT_CONTROL_SPD; - } - if (duplex == LINK_DUPLEX_FULL) { - value |= MAC_CONFIG_2_FULL_DUPLEX; - reg_PORT_CONTROL(base) &= ~PORT_CONTROL_BPT; - } else - reg_PORT_CONTROL(base) |= PORT_CONTROL_BPT; - reg_MAC_CONFIG_2(base) = value; - - reg_RX_CONFIG(base) = RX_CONFIG_SE; - reg_RX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY; - reg_RX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY; - - /* initialize the RX DMA descriptors */ - rx_descr = &rx_descr_array[0]; - rx_descr_current = rx_descr; - for (index = 0; index < NUM_RX_DESC; index++) { - /* make sure the receive buffers are not in cache */ - invalidate_dcache_range((unsigned long)NetRxPackets[index], - (unsigned long)NetRxPackets[index] + - RX_BUFFER_SIZE); - rx_descr->start_addr0 = - cpu_to_le32((vuint32) NetRxPackets[index]); - rx_descr->start_addr1 = 0; - rx_descr->next_descr_addr0 = - cpu_to_le32((vuint32) (rx_descr + 1)); - rx_descr->next_descr_addr1 = 0; - rx_descr->vlan_byte_count = 0; - rx_descr->config_status = cpu_to_le32((RX_BUFFER_SIZE << 16) | - DMA_DESCR_RX_OWNER); - rx_descr++; - } - rx_descr--; - rx_descr->next_descr_addr0 = 0; - rx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST); - /* Push the descriptors to RAM so the ethernet DMA can see them */ - invalidate_dcache_range((unsigned long)rx_descr_array, - (unsigned long)rx_descr_array + - sizeof(rx_descr_array)); - - /* enable RX queue */ - reg_RX_CONTROL(base) = TX_CONTROL_GO | 0x01; - reg_RX_QUEUE_0_PTR_LOW(base) = (u32) rx_descr_current; - /* enable receive DMA */ - reg_RX_QUEUE_0_PTR_HIGH(base) = RX_QUEUE_0_PTR_HIGH_VALID; - - reg_TX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY; - reg_TX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY; - - /* initialize the TX DMA descriptor */ - tx_descr = &tx_descriptor; - - tx_descr->start_addr0 = 0; - tx_descr->start_addr1 = 0; - tx_descr->next_descr_addr0 = 0; - tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST); - tx_descr->vlan_byte_count = 0; - tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OK | - DMA_DESCR_TX_SOF | - DMA_DESCR_TX_EOF); - /* enable TX queue */ - reg_TX_CONTROL(base) = TX_CONTROL_GO | 0x01; - - return 0; -} - -/* - * send a packet - */ -static int tsi108_eth_send(struct eth_device *dev, void *packet, int length) -{ - unsigned long base; - int timeout; - struct dma_descriptor *tx_descr; - unsigned long status; - - base = dev->iobase; - tx_descr = &tx_descriptor; - - /* Wait until the last packet has been transmitted. */ - timeout = 0; - do { - /* make sure we see the changes made by the DMA engine */ - invalidate_dcache_range((unsigned long)tx_descr, - (unsigned long)tx_descr + - sizeof(struct dma_descriptor)); - - if (timeout != 0) - udelay (15); - if (++timeout > 10000) { - tx_diag_regs(base); - debug_lev(1, - "ERROR: timeout waiting for last transmit packet to be sent\n"); - return 0; - } - } while (tx_descr->config_status & cpu_to_le32(DMA_DESCR_TX_OWNER)); - - status = le32_to_cpu(tx_descr->config_status); - if ((status & DMA_DESCR_TX_OK) == 0) { -#ifdef TX_PRINT_ERRORS - printf ("TX packet error: 0x%08lx\n %s%s%s%s\n", status, - status & DMA_DESCR_TX_OK ? "tx error, " : "", - status & DMA_DESCR_TX_RETRY_LIMIT ? - "retry limit reached, " : "", - status & DMA_DESCR_TX_UNDERRUN ? "underrun, " : "", - status & DMA_DESCR_TX_LATE_COLLISION ? "late collision, " - : ""); -#endif - } - - debug_lev (9, "sending packet %d\n", length); - tx_descr->start_addr0 = cpu_to_le32((vuint32) packet); - tx_descr->start_addr1 = 0; - tx_descr->next_descr_addr0 = 0; - tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST); - tx_descr->vlan_byte_count = cpu_to_le32(length); - tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OWNER | - DMA_DESCR_TX_CRC | - DMA_DESCR_TX_PAD | - DMA_DESCR_TX_SOF | - DMA_DESCR_TX_EOF); - - invalidate_dcache_range((unsigned long)tx_descr, - (unsigned long)tx_descr + - sizeof(struct dma_descriptor)); - - invalidate_dcache_range((unsigned long)packet, - (unsigned long)packet + length); - - reg_TX_QUEUE_0_PTR_LOW(base) = (u32) tx_descr; - reg_TX_QUEUE_0_PTR_HIGH(base) = TX_QUEUE_0_PTR_HIGH_VALID; - - return length; -} - -/* - * Check for received packets and send them up the protocal stack - */ -static int tsi108_eth_recv (struct eth_device *dev) -{ - struct dma_descriptor *rx_descr; - unsigned long base; - int length = 0; - unsigned long status; - uchar *buffer; - - base = dev->iobase; - - /* make sure we see the changes made by the DMA engine */ - invalidate_dcache_range ((unsigned long)rx_descr_array, - (unsigned long)rx_descr_array + - sizeof(rx_descr_array)); - - /* process all of the received packets */ - rx_descr = rx_descr_current; - while ((rx_descr->config_status & cpu_to_le32(DMA_DESCR_RX_OWNER)) == 0) { - /* check for error */ - status = le32_to_cpu(rx_descr->config_status); - if (status & DMA_DESCR_RX_BAD_FRAME) { -#ifdef RX_PRINT_ERRORS - printf ("RX packet error: 0x%08lx\n %s%s%s%s%s%s\n", - status, - status & DMA_DESCR_RX_FRAME_IS_TYPE ? "too big, " - : "", - status & DMA_DESCR_RX_SHORT_FRAME ? "too short, " - : "", - status & DMA_DESCR_RX_BAD_FRAME ? "bad frame, " : - "", - status & DMA_DESCR_RX_OVERRUN ? "overrun, " : "", - status & DMA_DESCR_RX_MAX_FRAME_LEN ? - "max length, " : "", - status & DMA_DESCR_RX_CRC_ERROR ? "CRC error, " : - ""); -#endif - } else { - length = - le32_to_cpu(rx_descr->vlan_byte_count) & 0xFFFF; - - /*** process packet ***/ - buffer = (uchar *)(le32_to_cpu(rx_descr->start_addr0)); - NetReceive(buffer, length); - - invalidate_dcache_range ((unsigned long)buffer, - (unsigned long)buffer + - RX_BUFFER_SIZE); - } - /* Give this buffer back to the DMA engine */ - rx_descr->vlan_byte_count = 0; - rx_descr->config_status = cpu_to_le32 ((RX_BUFFER_SIZE << 16) | - DMA_DESCR_RX_OWNER); - /* move descriptor pointer forward */ - rx_descr = - (struct dma_descriptor - *)(le32_to_cpu (rx_descr->next_descr_addr0)); - if (rx_descr == 0) - rx_descr = &rx_descr_array[0]; - } - /* remember where we are for next time */ - rx_descr_current = rx_descr; - - /* If the DMA engine has reached the end of the queue - * start over at the begining */ - if (reg_RX_EXTENDED_STATUS(base) & RX_EXTENDED_STATUS_EOQ_0) { - - reg_RX_EXTENDED_STATUS(base) = RX_EXTENDED_STATUS_EOQ_0; - reg_RX_QUEUE_0_PTR_LOW(base) = (u32) & rx_descr_array[0]; - reg_RX_QUEUE_0_PTR_HIGH(base) = RX_QUEUE_0_PTR_HIGH_VALID; - } - - return length; -} - -/* - * disable an ethernet interface - */ -static void tsi108_eth_halt (struct eth_device *dev) -{ - unsigned long base; - - base = dev->iobase; - - /* Put DMA/FIFO into reset state. */ - reg_TX_CONFIG(base) = TX_CONFIG_RST; - reg_RX_CONFIG(base) = RX_CONFIG_RST; - - /* Put MAC into reset state. */ - reg_MAC_CONFIG_1(base) = MAC_CONFIG_1_SOFT_RESET; -} diff --git a/qemu/roms/u-boot/drivers/net/uli526x.c b/qemu/roms/u-boot/drivers/net/uli526x.c deleted file mode 100644 index 538f11e3e..000000000 --- a/qemu/roms/u-boot/drivers/net/uli526x.c +++ /dev/null @@ -1,996 +0,0 @@ -/* - * Copyright 2007, 2010 Freescale Semiconductor, Inc. - * - * Author: Roy Zang <tie-fei.zang@freescale.com>, Sep, 2007 - * - * Description: - * ULI 526x Ethernet port driver. - * Based on the Linux driver: drivers/net/tulip/uli526x.c - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <net.h> -#include <netdev.h> -#include <asm/io.h> -#include <pci.h> -#include <miiphy.h> - -/* some kernel function compatible define */ - -#undef DEBUG - -/* Board/System/Debug information/definition */ -#define ULI_VENDOR_ID 0x10B9 -#define ULI5261_DEVICE_ID 0x5261 -#define ULI5263_DEVICE_ID 0x5263 -/* ULi M5261 ID*/ -#define PCI_ULI5261_ID (ULI5261_DEVICE_ID << 16 | ULI_VENDOR_ID) -/* ULi M5263 ID*/ -#define PCI_ULI5263_ID (ULI5263_DEVICE_ID << 16 | ULI_VENDOR_ID) - -#define ULI526X_IO_SIZE 0x100 -#define TX_DESC_CNT 0x10 /* Allocated Tx descriptors */ -#define RX_DESC_CNT PKTBUFSRX /* Allocated Rx descriptors */ -#define TX_FREE_DESC_CNT (TX_DESC_CNT - 2) /* Max TX packet count */ -#define TX_WAKE_DESC_CNT (TX_DESC_CNT - 3) /* TX wakeup count */ -#define DESC_ALL_CNT (TX_DESC_CNT + RX_DESC_CNT) -#define TX_BUF_ALLOC 0x300 -#define RX_ALLOC_SIZE PKTSIZE -#define ULI526X_RESET 1 -#define CR0_DEFAULT 0 -#define CR6_DEFAULT 0x22200000 -#define CR7_DEFAULT 0x180c1 -#define CR15_DEFAULT 0x06 /* TxJabber RxWatchdog */ -#define TDES0_ERR_MASK 0x4302 /* TXJT, LC, EC, FUE */ -#define MAX_PACKET_SIZE 1514 -#define ULI5261_MAX_MULTICAST 14 -#define RX_COPY_SIZE 100 -#define MAX_CHECK_PACKET 0x8000 - -#define ULI526X_10MHF 0 -#define ULI526X_100MHF 1 -#define ULI526X_10MFD 4 -#define ULI526X_100MFD 5 -#define ULI526X_AUTO 8 - -#define ULI526X_TXTH_72 0x400000 /* TX TH 72 byte */ -#define ULI526X_TXTH_96 0x404000 /* TX TH 96 byte */ -#define ULI526X_TXTH_128 0x0000 /* TX TH 128 byte */ -#define ULI526X_TXTH_256 0x4000 /* TX TH 256 byte */ -#define ULI526X_TXTH_512 0x8000 /* TX TH 512 byte */ -#define ULI526X_TXTH_1K 0xC000 /* TX TH 1K byte */ - -/* CR9 definition: SROM/MII */ -#define CR9_SROM_READ 0x4800 -#define CR9_SRCS 0x1 -#define CR9_SRCLK 0x2 -#define CR9_CRDOUT 0x8 -#define SROM_DATA_0 0x0 -#define SROM_DATA_1 0x4 -#define PHY_DATA_1 0x20000 -#define PHY_DATA_0 0x00000 -#define MDCLKH 0x10000 - -#define PHY_POWER_DOWN 0x800 - -#define SROM_V41_CODE 0x14 - -#define SROM_CLK_WRITE(data, ioaddr) do { \ - outl(data|CR9_SROM_READ|CR9_SRCS, ioaddr); \ - udelay(5); \ - outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK, ioaddr); \ - udelay(5); \ - outl(data|CR9_SROM_READ|CR9_SRCS, ioaddr); \ - udelay(5); \ - } while (0) - -/* Structure/enum declaration */ - -struct tx_desc { - u32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */ - char *tx_buf_ptr; /* Data for us */ - struct tx_desc *next_tx_desc; -}; - -struct rx_desc { - u32 rdes0, rdes1, rdes2, rdes3; /* Data for the card */ - char *rx_buf_ptr; /* Data for us */ - struct rx_desc *next_rx_desc; -}; - -struct uli526x_board_info { - u32 chip_id; /* Chip vendor/Device ID */ - pci_dev_t pdev; - - long ioaddr; /* I/O base address */ - u32 cr0_data; - u32 cr5_data; - u32 cr6_data; - u32 cr7_data; - u32 cr15_data; - - /* pointer for memory physical address */ - dma_addr_t buf_pool_dma_ptr; /* Tx buffer pool memory */ - dma_addr_t buf_pool_dma_start; /* Tx buffer pool align dword */ - dma_addr_t desc_pool_dma_ptr; /* descriptor pool memory */ - dma_addr_t first_tx_desc_dma; - dma_addr_t first_rx_desc_dma; - - /* descriptor pointer */ - unsigned char *buf_pool_ptr; /* Tx buffer pool memory */ - unsigned char *buf_pool_start; /* Tx buffer pool align dword */ - unsigned char *desc_pool_ptr; /* descriptor pool memory */ - struct tx_desc *first_tx_desc; - struct tx_desc *tx_insert_ptr; - struct tx_desc *tx_remove_ptr; - struct rx_desc *first_rx_desc; - struct rx_desc *rx_ready_ptr; /* packet come pointer */ - unsigned long tx_packet_cnt; /* transmitted packet count */ - - u16 PHY_reg4; /* Saved Phyxcer register 4 value */ - - u8 media_mode; /* user specify media mode */ - u8 op_mode; /* real work dedia mode */ - u8 phy_addr; - - /* NIC SROM data */ - unsigned char srom[128]; -}; - -enum uli526x_offsets { - DCR0 = 0x00, DCR1 = 0x08, DCR2 = 0x10, DCR3 = 0x18, DCR4 = 0x20, - DCR5 = 0x28, DCR6 = 0x30, DCR7 = 0x38, DCR8 = 0x40, DCR9 = 0x48, - DCR10 = 0x50, DCR11 = 0x58, DCR12 = 0x60, DCR13 = 0x68, DCR14 = 0x70, - DCR15 = 0x78 -}; - -enum uli526x_CR6_bits { - CR6_RXSC = 0x2, CR6_PBF = 0x8, CR6_PM = 0x40, CR6_PAM = 0x80, - CR6_FDM = 0x200, CR6_TXSC = 0x2000, CR6_STI = 0x100000, - CR6_SFT = 0x200000, CR6_RXA = 0x40000000, CR6_NO_PURGE = 0x20000000 -}; - -/* Global variable declaration -- */ - -static unsigned char uli526x_media_mode = ULI526X_AUTO; - -static struct tx_desc desc_pool_array[DESC_ALL_CNT + 0x20] - __attribute__ ((aligned(32))); -static char buf_pool[TX_BUF_ALLOC * TX_DESC_CNT + 4]; - -/* For module input parameter */ -static int mode = 8; - -/* function declaration -- */ -static int uli526x_start_xmit(struct eth_device *dev, void *packet, int length); -static const struct ethtool_ops netdev_ethtool_ops; -static u16 read_srom_word(long, int); -static void uli526x_descriptor_init(struct uli526x_board_info *, unsigned long); -static void allocate_rx_buffer(struct uli526x_board_info *); -static void update_cr6(u32, unsigned long); -static u16 uli_phy_read(unsigned long, u8, u8, u32); -static u16 phy_readby_cr10(unsigned long, u8, u8); -static void uli_phy_write(unsigned long, u8, u8, u16, u32); -static void phy_writeby_cr10(unsigned long, u8, u8, u16); -static void phy_write_1bit(unsigned long, u32, u32); -static u16 phy_read_1bit(unsigned long, u32); -static int uli526x_rx_packet(struct eth_device *); -static void uli526x_free_tx_pkt(struct eth_device *, - struct uli526x_board_info *); -static void uli526x_reuse_buf(struct rx_desc *); -static void uli526x_init(struct eth_device *); -static void uli526x_set_phyxcer(struct uli526x_board_info *); - - -static int uli526x_init_one(struct eth_device *, bd_t *); -static void uli526x_disable(struct eth_device *); -static void set_mac_addr(struct eth_device *); - -static struct pci_device_id uli526x_pci_tbl[] = { - { ULI_VENDOR_ID, ULI5261_DEVICE_ID}, /* 5261 device */ - { ULI_VENDOR_ID, ULI5263_DEVICE_ID}, /* 5263 device */ - {} -}; - -/* ULI526X network board routine */ - -/* - * Search ULI526X board, register it - */ - -int uli526x_initialize(bd_t *bis) -{ - pci_dev_t devno; - int card_number = 0; - struct eth_device *dev; - struct uli526x_board_info *db; /* board information structure */ - - u32 iobase; - int idx = 0; - - while (1) { - /* Find PCI device */ - devno = pci_find_devices(uli526x_pci_tbl, idx++); - if (devno < 0) - break; - - pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase); - iobase &= ~0xf; - - dev = (struct eth_device *)malloc(sizeof *dev); - if (!dev) { - printf("uli526x: Can not allocate memory\n"); - break; - } - memset(dev, 0, sizeof(*dev)); - sprintf(dev->name, "uli526x#%d", card_number); - db = (struct uli526x_board_info *) - malloc(sizeof(struct uli526x_board_info)); - - dev->priv = db; - db->pdev = devno; - dev->iobase = iobase; - - dev->init = uli526x_init_one; - dev->halt = uli526x_disable; - dev->send = uli526x_start_xmit; - dev->recv = uli526x_rx_packet; - - /* init db */ - db->ioaddr = dev->iobase; - /* get chip id */ - - pci_read_config_dword(devno, PCI_VENDOR_ID, &db->chip_id); -#ifdef DEBUG - printf("uli526x: uli526x @0x%x\n", iobase); - printf("uli526x: chip_id%x\n", db->chip_id); -#endif - eth_register(dev); - card_number++; - pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20); - udelay(10 * 1000); - } - return card_number; -} - -static int uli526x_init_one(struct eth_device *dev, bd_t *bis) -{ - - struct uli526x_board_info *db = dev->priv; - int i; - - switch (mode) { - case ULI526X_10MHF: - case ULI526X_100MHF: - case ULI526X_10MFD: - case ULI526X_100MFD: - uli526x_media_mode = mode; - break; - default: - uli526x_media_mode = ULI526X_AUTO; - break; - } - - /* Allocate Tx/Rx descriptor memory */ - db->desc_pool_ptr = (uchar *)&desc_pool_array[0]; - db->desc_pool_dma_ptr = (dma_addr_t)&desc_pool_array[0]; - if (db->desc_pool_ptr == NULL) - return -1; - - db->buf_pool_ptr = (uchar *)&buf_pool[0]; - db->buf_pool_dma_ptr = (dma_addr_t)&buf_pool[0]; - if (db->buf_pool_ptr == NULL) - return -1; - - db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr; - db->first_tx_desc_dma = db->desc_pool_dma_ptr; - - db->buf_pool_start = db->buf_pool_ptr; - db->buf_pool_dma_start = db->buf_pool_dma_ptr; - -#ifdef DEBUG - printf("%s(): db->ioaddr= 0x%x\n", - __FUNCTION__, db->ioaddr); - printf("%s(): media_mode= 0x%x\n", - __FUNCTION__, uli526x_media_mode); - printf("%s(): db->desc_pool_ptr= 0x%x\n", - __FUNCTION__, db->desc_pool_ptr); - printf("%s(): db->desc_pool_dma_ptr= 0x%x\n", - __FUNCTION__, db->desc_pool_dma_ptr); - printf("%s(): db->buf_pool_ptr= 0x%x\n", - __FUNCTION__, db->buf_pool_ptr); - printf("%s(): db->buf_pool_dma_ptr= 0x%x\n", - __FUNCTION__, db->buf_pool_dma_ptr); -#endif - - /* read 64 word srom data */ - for (i = 0; i < 64; i++) - ((u16 *) db->srom)[i] = cpu_to_le16(read_srom_word(db->ioaddr, - i)); - - /* Set Node address */ - if (((db->srom[0] == 0xff) && (db->srom[1] == 0xff)) || - ((db->srom[0] == 0x00) && (db->srom[1] == 0x00))) - /* SROM absent, so write MAC address to ID Table */ - set_mac_addr(dev); - else { /*Exist SROM*/ - for (i = 0; i < 6; i++) - dev->enetaddr[i] = db->srom[20 + i]; - } -#ifdef DEBUG - for (i = 0; i < 6; i++) - printf("%c%02x", i ? ':' : ' ', dev->enetaddr[i]); -#endif - db->PHY_reg4 = 0x1e0; - - /* system variable init */ - db->cr6_data = CR6_DEFAULT ; - db->cr6_data |= ULI526X_TXTH_256; - db->cr0_data = CR0_DEFAULT; - uli526x_init(dev); - return 0; -} - -static void uli526x_disable(struct eth_device *dev) -{ -#ifdef DEBUG - printf("uli526x_disable\n"); -#endif - struct uli526x_board_info *db = dev->priv; - - if (!((inl(db->ioaddr + DCR12)) & 0x8)) { - /* Reset & stop ULI526X board */ - outl(ULI526X_RESET, db->ioaddr + DCR0); - udelay(5); - uli_phy_write(db->ioaddr, db->phy_addr, 0, 0x8000, db->chip_id); - - /* reset the board */ - db->cr6_data &= ~(CR6_RXSC | CR6_TXSC); /* Disable Tx/Rx */ - update_cr6(db->cr6_data, dev->iobase); - outl(0, dev->iobase + DCR7); /* Disable Interrupt */ - outl(inl(dev->iobase + DCR5), dev->iobase + DCR5); - } -} - -/* Initialize ULI526X board - * Reset ULI526X board - * Initialize TX/Rx descriptor chain structure - * Send the set-up frame - * Enable Tx/Rx machine - */ - -static void uli526x_init(struct eth_device *dev) -{ - - struct uli526x_board_info *db = dev->priv; - u8 phy_tmp; - u16 phy_value; - u16 phy_reg_reset; - - /* Reset M526x MAC controller */ - outl(ULI526X_RESET, db->ioaddr + DCR0); /* RESET MAC */ - udelay(100); - outl(db->cr0_data, db->ioaddr + DCR0); - udelay(5); - - /* Phy addr : In some boards,M5261/M5263 phy address != 1 */ - db->phy_addr = 1; - db->tx_packet_cnt = 0; - for (phy_tmp = 0; phy_tmp < 32; phy_tmp++) { - /* peer add */ - phy_value = uli_phy_read(db->ioaddr, phy_tmp, 3, db->chip_id); - if (phy_value != 0xffff && phy_value != 0) { - db->phy_addr = phy_tmp; - break; - } - } - -#ifdef DEBUG - printf("%s(): db->ioaddr= 0x%x\n", __FUNCTION__, db->ioaddr); - printf("%s(): db->phy_addr= 0x%x\n", __FUNCTION__, db->phy_addr); -#endif - if (phy_tmp == 32) - printf("Can not find the phy address!!!"); - - /* Parser SROM and media mode */ - db->media_mode = uli526x_media_mode; - - if (!(inl(db->ioaddr + DCR12) & 0x8)) { - /* Phyxcer capability setting */ - phy_reg_reset = uli_phy_read(db->ioaddr, - db->phy_addr, 0, db->chip_id); - phy_reg_reset = (phy_reg_reset | 0x8000); - uli_phy_write(db->ioaddr, db->phy_addr, 0, - phy_reg_reset, db->chip_id); - udelay(500); - - /* Process Phyxcer Media Mode */ - uli526x_set_phyxcer(db); - } - /* Media Mode Process */ - if (!(db->media_mode & ULI526X_AUTO)) - db->op_mode = db->media_mode; /* Force Mode */ - - /* Initialize Transmit/Receive decriptor and CR3/4 */ - uli526x_descriptor_init(db, db->ioaddr); - - /* Init CR6 to program M526X operation */ - update_cr6(db->cr6_data, db->ioaddr); - - /* Init CR7, interrupt active bit */ - db->cr7_data = CR7_DEFAULT; - outl(db->cr7_data, db->ioaddr + DCR7); - - /* Init CR15, Tx jabber and Rx watchdog timer */ - outl(db->cr15_data, db->ioaddr + DCR15); - - /* Enable ULI526X Tx/Rx function */ - db->cr6_data |= CR6_RXSC | CR6_TXSC; - update_cr6(db->cr6_data, db->ioaddr); - while (!(inl(db->ioaddr + DCR12) & 0x8)) - udelay(10); -} - -/* - * Hardware start transmission. - * Send a packet to media from the upper layer. - */ - -static int uli526x_start_xmit(struct eth_device *dev, void *packet, int length) -{ - struct uli526x_board_info *db = dev->priv; - struct tx_desc *txptr; - unsigned int len = length; - /* Too large packet check */ - if (len > MAX_PACKET_SIZE) { - printf(": big packet = %d\n", len); - return 0; - } - - /* No Tx resource check, it never happen nromally */ - if (db->tx_packet_cnt >= TX_FREE_DESC_CNT) { - printf("No Tx resource %ld\n", db->tx_packet_cnt); - return 0; - } - - /* Disable NIC interrupt */ - outl(0, dev->iobase + DCR7); - - /* transmit this packet */ - txptr = db->tx_insert_ptr; - memcpy((char *)txptr->tx_buf_ptr, (char *)packet, (int)length); - txptr->tdes1 = cpu_to_le32(0xe1000000 | length); - - /* Point to next transmit free descriptor */ - db->tx_insert_ptr = txptr->next_tx_desc; - - /* Transmit Packet Process */ - if ((db->tx_packet_cnt < TX_DESC_CNT)) { - txptr->tdes0 = cpu_to_le32(0x80000000); /* Set owner bit */ - db->tx_packet_cnt++; /* Ready to send */ - outl(0x1, dev->iobase + DCR1); /* Issue Tx polling */ - } - - /* Got ULI526X status */ - db->cr5_data = inl(db->ioaddr + DCR5); - outl(db->cr5_data, db->ioaddr + DCR5); - -#ifdef TX_DEBUG - printf("%s(): length = 0x%x\n", __FUNCTION__, length); - printf("%s(): cr5_data=%x\n", __FUNCTION__, db->cr5_data); -#endif - - outl(db->cr7_data, dev->iobase + DCR7); - uli526x_free_tx_pkt(dev, db); - - return length; -} - -/* - * Free TX resource after TX complete - */ - -static void uli526x_free_tx_pkt(struct eth_device *dev, - struct uli526x_board_info *db) -{ - struct tx_desc *txptr; - u32 tdes0; - - txptr = db->tx_remove_ptr; - while (db->tx_packet_cnt) { - tdes0 = le32_to_cpu(txptr->tdes0); - /* printf(DRV_NAME ": tdes0=%x\n", tdes0); */ - if (tdes0 & 0x80000000) - break; - - /* A packet sent completed */ - db->tx_packet_cnt--; - - if (tdes0 != 0x7fffffff) { -#ifdef TX_DEBUG - printf("%s()tdes0=%x\n", __FUNCTION__, tdes0); -#endif - if (tdes0 & TDES0_ERR_MASK) { - if (tdes0 & 0x0002) { /* UnderRun */ - if (!(db->cr6_data & CR6_SFT)) { - db->cr6_data = db->cr6_data | - CR6_SFT; - update_cr6(db->cr6_data, - db->ioaddr); - } - } - } - } - - txptr = txptr->next_tx_desc; - }/* End of while */ - - /* Update TX remove pointer to next */ - db->tx_remove_ptr = txptr; -} - - -/* - * Receive the come packet and pass to upper layer - */ - -static int uli526x_rx_packet(struct eth_device *dev) -{ - struct uli526x_board_info *db = dev->priv; - struct rx_desc *rxptr; - int rxlen = 0; - u32 rdes0; - - rxptr = db->rx_ready_ptr; - - rdes0 = le32_to_cpu(rxptr->rdes0); -#ifdef RX_DEBUG - printf("%s(): rxptr->rdes0=%x:%x\n", __FUNCTION__, rxptr->rdes0); -#endif - if (!(rdes0 & 0x80000000)) { /* packet owner check */ - if ((rdes0 & 0x300) != 0x300) { - /* A packet without First/Last flag */ - /* reuse this buf */ - printf("A packet without First/Last flag"); - uli526x_reuse_buf(rxptr); - } else { - /* A packet with First/Last flag */ - rxlen = ((rdes0 >> 16) & 0x3fff) - 4; -#ifdef RX_DEBUG - printf("%s(): rxlen =%x\n", __FUNCTION__, rxlen); -#endif - /* error summary bit check */ - if (rdes0 & 0x8000) { - /* This is a error packet */ - printf("Error: rdes0: %x\n", rdes0); - } - - if (!(rdes0 & 0x8000) || - ((db->cr6_data & CR6_PM) && (rxlen > 6))) { - -#ifdef RX_DEBUG - printf("%s(): rx_skb_ptr =%x\n", - __FUNCTION__, rxptr->rx_buf_ptr); - printf("%s(): rxlen =%x\n", - __FUNCTION__, rxlen); - - printf("%s(): buf addr =%x\n", - __FUNCTION__, rxptr->rx_buf_ptr); - printf("%s(): rxlen =%x\n", - __FUNCTION__, rxlen); - int i; - for (i = 0; i < 0x20; i++) - printf("%s(): data[%x] =%x\n", - __FUNCTION__, i, rxptr->rx_buf_ptr[i]); -#endif - - NetReceive((uchar *)rxptr->rx_buf_ptr, rxlen); - uli526x_reuse_buf(rxptr); - - } else { - /* Reuse SKB buffer when the packet is error */ - printf("Reuse buffer, rdes0"); - uli526x_reuse_buf(rxptr); - } - } - - rxptr = rxptr->next_rx_desc; - } - - db->rx_ready_ptr = rxptr; - return rxlen; -} - -/* - * Reuse the RX buffer - */ - -static void uli526x_reuse_buf(struct rx_desc *rxptr) -{ - - if (!(rxptr->rdes0 & cpu_to_le32(0x80000000))) - rxptr->rdes0 = cpu_to_le32(0x80000000); - else - printf("Buffer reuse method error"); -} -/* - * Initialize transmit/Receive descriptor - * Using Chain structure, and allocate Tx/Rx buffer - */ - -static void uli526x_descriptor_init(struct uli526x_board_info *db, - unsigned long ioaddr) -{ - struct tx_desc *tmp_tx; - struct rx_desc *tmp_rx; - unsigned char *tmp_buf; - dma_addr_t tmp_tx_dma, tmp_rx_dma; - dma_addr_t tmp_buf_dma; - int i; - /* tx descriptor start pointer */ - db->tx_insert_ptr = db->first_tx_desc; - db->tx_remove_ptr = db->first_tx_desc; - - outl(db->first_tx_desc_dma, ioaddr + DCR4); /* TX DESC address */ - - /* rx descriptor start pointer */ - db->first_rx_desc = (void *)db->first_tx_desc + - sizeof(struct tx_desc) * TX_DESC_CNT; - db->first_rx_desc_dma = db->first_tx_desc_dma + - sizeof(struct tx_desc) * TX_DESC_CNT; - db->rx_ready_ptr = db->first_rx_desc; - outl(db->first_rx_desc_dma, ioaddr + DCR3); /* RX DESC address */ -#ifdef DEBUG - printf("%s(): db->first_tx_desc= 0x%x\n", - __FUNCTION__, db->first_tx_desc); - printf("%s(): db->first_rx_desc_dma= 0x%x\n", - __FUNCTION__, db->first_rx_desc_dma); -#endif - /* Init Transmit chain */ - tmp_buf = db->buf_pool_start; - tmp_buf_dma = db->buf_pool_dma_start; - tmp_tx_dma = db->first_tx_desc_dma; - for (tmp_tx = db->first_tx_desc, i = 0; - i < TX_DESC_CNT; i++, tmp_tx++) { - tmp_tx->tx_buf_ptr = (char *)tmp_buf; - tmp_tx->tdes0 = cpu_to_le32(0); - tmp_tx->tdes1 = cpu_to_le32(0x81000000); /* IC, chain */ - tmp_tx->tdes2 = cpu_to_le32(tmp_buf_dma); - tmp_tx_dma += sizeof(struct tx_desc); - tmp_tx->tdes3 = cpu_to_le32(tmp_tx_dma); - tmp_tx->next_tx_desc = tmp_tx + 1; - tmp_buf = tmp_buf + TX_BUF_ALLOC; - tmp_buf_dma = tmp_buf_dma + TX_BUF_ALLOC; - } - (--tmp_tx)->tdes3 = cpu_to_le32(db->first_tx_desc_dma); - tmp_tx->next_tx_desc = db->first_tx_desc; - - /* Init Receive descriptor chain */ - tmp_rx_dma = db->first_rx_desc_dma; - for (tmp_rx = db->first_rx_desc, i = 0; i < RX_DESC_CNT; - i++, tmp_rx++) { - tmp_rx->rdes0 = cpu_to_le32(0); - tmp_rx->rdes1 = cpu_to_le32(0x01000600); - tmp_rx_dma += sizeof(struct rx_desc); - tmp_rx->rdes3 = cpu_to_le32(tmp_rx_dma); - tmp_rx->next_rx_desc = tmp_rx + 1; - } - (--tmp_rx)->rdes3 = cpu_to_le32(db->first_rx_desc_dma); - tmp_rx->next_rx_desc = db->first_rx_desc; - - /* pre-allocate Rx buffer */ - allocate_rx_buffer(db); -} - -/* - * Update CR6 value - * Firstly stop ULI526X, then written value and start - */ - -static void update_cr6(u32 cr6_data, unsigned long ioaddr) -{ - - outl(cr6_data, ioaddr + DCR6); - udelay(5); -} - -/* - * Allocate rx buffer, - */ - -static void allocate_rx_buffer(struct uli526x_board_info *db) -{ - int index; - struct rx_desc *rxptr; - rxptr = db->first_rx_desc; - u32 addr; - - for (index = 0; index < RX_DESC_CNT; index++) { - addr = (u32)NetRxPackets[index]; - addr += (16 - (addr & 15)); - rxptr->rx_buf_ptr = (char *) addr; - rxptr->rdes2 = cpu_to_le32(addr); - rxptr->rdes0 = cpu_to_le32(0x80000000); -#ifdef DEBUG - printf("%s(): Number 0x%x:\n", __FUNCTION__, index); - printf("%s(): addr 0x%x:\n", __FUNCTION__, addr); - printf("%s(): rxptr address = 0x%x\n", __FUNCTION__, rxptr); - printf("%s(): rxptr buf address = 0x%x\n", \ - __FUNCTION__, rxptr->rx_buf_ptr); - printf("%s(): rdes2 = 0x%x\n", __FUNCTION__, rxptr->rdes2); -#endif - rxptr = rxptr->next_rx_desc; - } -} - -/* - * Read one word data from the serial ROM - */ - -static u16 read_srom_word(long ioaddr, int offset) -{ - int i; - u16 srom_data = 0; - long cr9_ioaddr = ioaddr + DCR9; - - outl(CR9_SROM_READ, cr9_ioaddr); - outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); - - /* Send the Read Command 110b */ - SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr); - SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr); - SROM_CLK_WRITE(SROM_DATA_0, cr9_ioaddr); - - /* Send the offset */ - for (i = 5; i >= 0; i--) { - srom_data = (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0; - SROM_CLK_WRITE(srom_data, cr9_ioaddr); - } - - outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); - - for (i = 16; i > 0; i--) { - outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr); - udelay(5); - srom_data = (srom_data << 1) | ((inl(cr9_ioaddr) & CR9_CRDOUT) - ? 1 : 0); - outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); - udelay(5); - } - - outl(CR9_SROM_READ, cr9_ioaddr); - return srom_data; -} - -/* - * Set 10/100 phyxcer capability - * AUTO mode : phyxcer register4 is NIC capability - * Force mode: phyxcer register4 is the force media - */ - -static void uli526x_set_phyxcer(struct uli526x_board_info *db) -{ - u16 phy_reg; - - /* Phyxcer capability setting */ - phy_reg = uli_phy_read(db->ioaddr, - db->phy_addr, 4, db->chip_id) & ~0x01e0; - - if (db->media_mode & ULI526X_AUTO) { - /* AUTO Mode */ - phy_reg |= db->PHY_reg4; - } else { - /* Force Mode */ - switch (db->media_mode) { - case ULI526X_10MHF: phy_reg |= 0x20; break; - case ULI526X_10MFD: phy_reg |= 0x40; break; - case ULI526X_100MHF: phy_reg |= 0x80; break; - case ULI526X_100MFD: phy_reg |= 0x100; break; - } - - } - - /* Write new capability to Phyxcer Reg4 */ - if (!(phy_reg & 0x01e0)) { - phy_reg |= db->PHY_reg4; - db->media_mode |= ULI526X_AUTO; - } - uli_phy_write(db->ioaddr, db->phy_addr, 4, phy_reg, db->chip_id); - - /* Restart Auto-Negotiation */ - uli_phy_write(db->ioaddr, db->phy_addr, 0, 0x1200, db->chip_id); - udelay(50); -} - -/* - * Write a word to Phy register - */ - -static void uli_phy_write(unsigned long iobase, u8 phy_addr, u8 offset, - u16 phy_data, u32 chip_id) -{ - u16 i; - unsigned long ioaddr; - - if (chip_id == PCI_ULI5263_ID) { - phy_writeby_cr10(iobase, phy_addr, offset, phy_data); - return; - } - /* M5261/M5263 Chip */ - ioaddr = iobase + DCR9; - - /* Send 33 synchronization clock to Phy controller */ - for (i = 0; i < 35; i++) - phy_write_1bit(ioaddr, PHY_DATA_1, chip_id); - - /* Send start command(01) to Phy */ - phy_write_1bit(ioaddr, PHY_DATA_0, chip_id); - phy_write_1bit(ioaddr, PHY_DATA_1, chip_id); - - /* Send write command(01) to Phy */ - phy_write_1bit(ioaddr, PHY_DATA_0, chip_id); - phy_write_1bit(ioaddr, PHY_DATA_1, chip_id); - - /* Send Phy address */ - for (i = 0x10; i > 0; i = i >> 1) - phy_write_1bit(ioaddr, phy_addr & i ? - PHY_DATA_1 : PHY_DATA_0, chip_id); - - /* Send register address */ - for (i = 0x10; i > 0; i = i >> 1) - phy_write_1bit(ioaddr, offset & i ? - PHY_DATA_1 : PHY_DATA_0, chip_id); - - /* written trasnition */ - phy_write_1bit(ioaddr, PHY_DATA_1, chip_id); - phy_write_1bit(ioaddr, PHY_DATA_0, chip_id); - - /* Write a word data to PHY controller */ - for (i = 0x8000; i > 0; i >>= 1) - phy_write_1bit(ioaddr, phy_data & i ? - PHY_DATA_1 : PHY_DATA_0, chip_id); -} - -/* - * Read a word data from phy register - */ - -static u16 uli_phy_read(unsigned long iobase, u8 phy_addr, u8 offset, - u32 chip_id) -{ - int i; - u16 phy_data; - unsigned long ioaddr; - - if (chip_id == PCI_ULI5263_ID) - return phy_readby_cr10(iobase, phy_addr, offset); - /* M5261/M5263 Chip */ - ioaddr = iobase + DCR9; - - /* Send 33 synchronization clock to Phy controller */ - for (i = 0; i < 35; i++) - phy_write_1bit(ioaddr, PHY_DATA_1, chip_id); - - /* Send start command(01) to Phy */ - phy_write_1bit(ioaddr, PHY_DATA_0, chip_id); - phy_write_1bit(ioaddr, PHY_DATA_1, chip_id); - - /* Send read command(10) to Phy */ - phy_write_1bit(ioaddr, PHY_DATA_1, chip_id); - phy_write_1bit(ioaddr, PHY_DATA_0, chip_id); - - /* Send Phy address */ - for (i = 0x10; i > 0; i = i >> 1) - phy_write_1bit(ioaddr, phy_addr & i ? - PHY_DATA_1 : PHY_DATA_0, chip_id); - - /* Send register address */ - for (i = 0x10; i > 0; i = i >> 1) - phy_write_1bit(ioaddr, offset & i ? - PHY_DATA_1 : PHY_DATA_0, chip_id); - - /* Skip transition state */ - phy_read_1bit(ioaddr, chip_id); - - /* read 16bit data */ - for (phy_data = 0, i = 0; i < 16; i++) { - phy_data <<= 1; - phy_data |= phy_read_1bit(ioaddr, chip_id); - } - - return phy_data; -} - -static u16 phy_readby_cr10(unsigned long iobase, u8 phy_addr, u8 offset) -{ - unsigned long ioaddr, cr10_value; - - ioaddr = iobase + DCR10; - cr10_value = phy_addr; - cr10_value = (cr10_value<<5) + offset; - cr10_value = (cr10_value<<16) + 0x08000000; - outl(cr10_value, ioaddr); - udelay(1); - while (1) { - cr10_value = inl(ioaddr); - if (cr10_value & 0x10000000) - break; - } - return (cr10_value&0x0ffff); -} - -static void phy_writeby_cr10(unsigned long iobase, u8 phy_addr, - u8 offset, u16 phy_data) -{ - unsigned long ioaddr, cr10_value; - - ioaddr = iobase + DCR10; - cr10_value = phy_addr; - cr10_value = (cr10_value<<5) + offset; - cr10_value = (cr10_value<<16) + 0x04000000 + phy_data; - outl(cr10_value, ioaddr); - udelay(1); -} -/* - * Write one bit data to Phy Controller - */ - -static void phy_write_1bit(unsigned long ioaddr, u32 phy_data, u32 chip_id) -{ - outl(phy_data , ioaddr); /* MII Clock Low */ - udelay(1); - outl(phy_data | MDCLKH, ioaddr); /* MII Clock High */ - udelay(1); - outl(phy_data , ioaddr); /* MII Clock Low */ - udelay(1); -} - -/* - * Read one bit phy data from PHY controller - */ - -static u16 phy_read_1bit(unsigned long ioaddr, u32 chip_id) -{ - u16 phy_data; - - outl(0x50000 , ioaddr); - udelay(1); - phy_data = (inl(ioaddr) >> 19) & 0x1; - outl(0x40000 , ioaddr); - udelay(1); - - return phy_data; -} - -/* - * Set MAC address to ID Table - */ - -static void set_mac_addr(struct eth_device *dev) -{ - int i; - u16 addr; - struct uli526x_board_info *db = dev->priv; - outl(0x10000, db->ioaddr + DCR0); /* Diagnosis mode */ - /* Reset dianostic pointer port */ - outl(0x1c0, db->ioaddr + DCR13); - outl(0, db->ioaddr + DCR14); /* Clear reset port */ - outl(0x10, db->ioaddr + DCR14); /* Reset ID Table pointer */ - outl(0, db->ioaddr + DCR14); /* Clear reset port */ - outl(0, db->ioaddr + DCR13); /* Clear CR13 */ - /* Select ID Table access port */ - outl(0x1b0, db->ioaddr + DCR13); - /* Read MAC address from CR14 */ - for (i = 0; i < 3; i++) { - addr = dev->enetaddr[2 * i] | (dev->enetaddr[2 * i + 1] << 8); - outl(addr, db->ioaddr + DCR14); - } - /* write end */ - outl(0, db->ioaddr + DCR13); /* Clear CR13 */ - outl(0, db->ioaddr + DCR0); /* Clear CR0 */ - udelay(10); - return; -} diff --git a/qemu/roms/u-boot/drivers/net/vsc7385.c b/qemu/roms/u-boot/drivers/net/vsc7385.c deleted file mode 100644 index a5110e516..000000000 --- a/qemu/roms/u-boot/drivers/net/vsc7385.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Vitesse 7385 Switch Firmware Upload - * - * Author: Timur Tabi <timur@freescale.com> - * - * Copyright 2008 Freescale Semiconductor, Inc. This file is licensed - * under the terms of the GNU General Public License version 2. This - * program is licensed "as is" without any warranty of any kind, whether - * express or implied. - * - * This module uploads proprietary firmware for the Vitesse VSC7385 5-port - * switch. - */ - -#include <config.h> -#include <common.h> -#include <asm/io.h> -#include <asm/errno.h> -#include "vsc7385.h" - -/* - * Upload a Vitesse VSC7385 firmware image to the hardware - * - * This function takes a pointer to a VSC7385 firmware image and a size, and - * uploads that firmware to the VSC7385. - * - * This firmware is typically located at a board-specific flash address, - * and the size is typically 8KB. - * - * The firmware is Vitesse proprietary. - * - * Further details on the register information can be obtained from Vitesse. - */ -int vsc7385_upload_firmware(void *firmware, unsigned int size) -{ - u8 *fw = firmware; - unsigned int i; - - u32 *gloreset = (u32 *) (CONFIG_SYS_VSC7385_BASE + 0x1c050); - u32 *icpu_ctrl = (u32 *) (CONFIG_SYS_VSC7385_BASE + 0x1c040); - u32 *icpu_addr = (u32 *) (CONFIG_SYS_VSC7385_BASE + 0x1c044); - u32 *icpu_data = (u32 *) (CONFIG_SYS_VSC7385_BASE + 0x1c048); - u32 *icpu_rom_map = (u32 *) (CONFIG_SYS_VSC7385_BASE + 0x1c070); -#ifdef DEBUG - u32 *chipid = (u32 *) (CONFIG_SYS_VSC7385_BASE + 0x1c060); -#endif - - out_be32(gloreset, 3); - udelay(200); - - out_be32(icpu_ctrl, 0x8E); - udelay(20); - - out_be32(icpu_rom_map, 1); - udelay(20); - - /* Write the firmware to I-RAM */ - out_be32(icpu_addr, 0); - udelay(20); - - for (i = 0; i < size; i++) { - out_be32(icpu_data, fw[i]); - udelay(20); - if (ctrlc()) - return -EINTR; - } - - /* Read back and compare */ - out_be32(icpu_addr, 0); - udelay(20); - - for (i = 0; i < size; i++) { - u8 value; - - value = (u8) in_be32(icpu_data); - udelay(20); - if (value != fw[i]) { - debug("VSC7385: Upload mismatch: address 0x%x, " - "read value 0x%x, image value 0x%x\n", - i, value, fw[i]); - - return -EIO; - } - if (ctrlc()) - break; - } - - out_be32(icpu_ctrl, 0x0B); - udelay(20); - -#ifdef DEBUG - printf("VSC7385: Chip ID is %08x\n", in_be32(chipid)); - udelay(20); -#endif - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/xilinx_axi_emac.c b/qemu/roms/u-boot/drivers/net/xilinx_axi_emac.c deleted file mode 100644 index 262b67b6c..000000000 --- a/qemu/roms/u-boot/drivers/net/xilinx_axi_emac.c +++ /dev/null @@ -1,656 +0,0 @@ -/* - * Copyright (C) 2011 Michal Simek <monstr@monstr.eu> - * Copyright (C) 2011 PetaLogix - * Copyright (C) 2010 Xilinx, Inc. All rights reserved. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <config.h> -#include <common.h> -#include <net.h> -#include <malloc.h> -#include <asm/io.h> -#include <phy.h> -#include <miiphy.h> - -#if !defined(CONFIG_PHYLIB) -# error AXI_ETHERNET requires PHYLIB -#endif - -/* Link setup */ -#define XAE_EMMC_LINKSPEED_MASK 0xC0000000 /* Link speed */ -#define XAE_EMMC_LINKSPD_10 0x00000000 /* Link Speed mask for 10 Mbit */ -#define XAE_EMMC_LINKSPD_100 0x40000000 /* Link Speed mask for 100 Mbit */ -#define XAE_EMMC_LINKSPD_1000 0x80000000 /* Link Speed mask for 1000 Mbit */ - -/* Interrupt Status/Enable/Mask Registers bit definitions */ -#define XAE_INT_RXRJECT_MASK 0x00000008 /* Rx frame rejected */ -#define XAE_INT_MGTRDY_MASK 0x00000080 /* MGT clock Lock */ - -/* Receive Configuration Word 1 (RCW1) Register bit definitions */ -#define XAE_RCW1_RX_MASK 0x10000000 /* Receiver enable */ - -/* Transmitter Configuration (TC) Register bit definitions */ -#define XAE_TC_TX_MASK 0x10000000 /* Transmitter enable */ - -#define XAE_UAW1_UNICASTADDR_MASK 0x0000FFFF - -/* MDIO Management Configuration (MC) Register bit definitions */ -#define XAE_MDIO_MC_MDIOEN_MASK 0x00000040 /* MII management enable*/ - -/* MDIO Management Control Register (MCR) Register bit definitions */ -#define XAE_MDIO_MCR_PHYAD_MASK 0x1F000000 /* Phy Address Mask */ -#define XAE_MDIO_MCR_PHYAD_SHIFT 24 /* Phy Address Shift */ -#define XAE_MDIO_MCR_REGAD_MASK 0x001F0000 /* Reg Address Mask */ -#define XAE_MDIO_MCR_REGAD_SHIFT 16 /* Reg Address Shift */ -#define XAE_MDIO_MCR_OP_READ_MASK 0x00008000 /* Op Code Read Mask */ -#define XAE_MDIO_MCR_OP_WRITE_MASK 0x00004000 /* Op Code Write Mask */ -#define XAE_MDIO_MCR_INITIATE_MASK 0x00000800 /* Ready Mask */ -#define XAE_MDIO_MCR_READY_MASK 0x00000080 /* Ready Mask */ - -#define XAE_MDIO_DIV_DFT 29 /* Default MDIO clock divisor */ - -/* DMA macros */ -/* Bitmasks of XAXIDMA_CR_OFFSET register */ -#define XAXIDMA_CR_RUNSTOP_MASK 0x00000001 /* Start/stop DMA channel */ -#define XAXIDMA_CR_RESET_MASK 0x00000004 /* Reset DMA engine */ - -/* Bitmasks of XAXIDMA_SR_OFFSET register */ -#define XAXIDMA_HALTED_MASK 0x00000001 /* DMA channel halted */ - -/* Bitmask for interrupts */ -#define XAXIDMA_IRQ_IOC_MASK 0x00001000 /* Completion intr */ -#define XAXIDMA_IRQ_DELAY_MASK 0x00002000 /* Delay interrupt */ -#define XAXIDMA_IRQ_ALL_MASK 0x00007000 /* All interrupts */ - -/* Bitmasks of XAXIDMA_BD_CTRL_OFFSET register */ -#define XAXIDMA_BD_CTRL_TXSOF_MASK 0x08000000 /* First tx packet */ -#define XAXIDMA_BD_CTRL_TXEOF_MASK 0x04000000 /* Last tx packet */ - -#define DMAALIGN 128 - -static u8 rxframe[PKTSIZE_ALIGN] __attribute((aligned(DMAALIGN))); - -/* Reflect dma offsets */ -struct axidma_reg { - u32 control; /* DMACR */ - u32 status; /* DMASR */ - u32 current; /* CURDESC */ - u32 reserved; - u32 tail; /* TAILDESC */ -}; - -/* Private driver structures */ -struct axidma_priv { - struct axidma_reg *dmatx; - struct axidma_reg *dmarx; - int phyaddr; - - struct phy_device *phydev; - struct mii_dev *bus; -}; - -/* BD descriptors */ -struct axidma_bd { - u32 next; /* Next descriptor pointer */ - u32 reserved1; - u32 phys; /* Buffer address */ - u32 reserved2; - u32 reserved3; - u32 reserved4; - u32 cntrl; /* Control */ - u32 status; /* Status */ - u32 app0; - u32 app1; /* TX start << 16 | insert */ - u32 app2; /* TX csum seed */ - u32 app3; - u32 app4; - u32 sw_id_offset; - u32 reserved5; - u32 reserved6; -}; - -/* Static BDs - driver uses only one BD */ -static struct axidma_bd tx_bd __attribute((aligned(DMAALIGN))); -static struct axidma_bd rx_bd __attribute((aligned(DMAALIGN))); - -struct axi_regs { - u32 reserved[3]; - u32 is; /* 0xC: Interrupt status */ - u32 reserved2; - u32 ie; /* 0x14: Interrupt enable */ - u32 reserved3[251]; - u32 rcw1; /* 0x404: Rx Configuration Word 1 */ - u32 tc; /* 0x408: Tx Configuration */ - u32 reserved4; - u32 emmc; /* 0x410: EMAC mode configuration */ - u32 reserved5[59]; - u32 mdio_mc; /* 0x500: MII Management Config */ - u32 mdio_mcr; /* 0x504: MII Management Control */ - u32 mdio_mwd; /* 0x508: MII Management Write Data */ - u32 mdio_mrd; /* 0x50C: MII Management Read Data */ - u32 reserved6[124]; - u32 uaw0; /* 0x700: Unicast address word 0 */ - u32 uaw1; /* 0x704: Unicast address word 1 */ -}; - -/* Use MII register 1 (MII status register) to detect PHY */ -#define PHY_DETECT_REG 1 - -/* - * Mask used to verify certain PHY features (or register contents) - * in the register above: - * 0x1000: 10Mbps full duplex support - * 0x0800: 10Mbps half duplex support - * 0x0008: Auto-negotiation support - */ -#define PHY_DETECT_MASK 0x1808 - -static inline int mdio_wait(struct eth_device *dev) -{ - struct axi_regs *regs = (struct axi_regs *)dev->iobase; - u32 timeout = 200; - - /* Wait till MDIO interface is ready to accept a new transaction. */ - while (timeout && (!(in_be32(®s->mdio_mcr) - & XAE_MDIO_MCR_READY_MASK))) { - timeout--; - udelay(1); - } - if (!timeout) { - printf("%s: Timeout\n", __func__); - return 1; - } - return 0; -} - -static u32 phyread(struct eth_device *dev, u32 phyaddress, u32 registernum, - u16 *val) -{ - struct axi_regs *regs = (struct axi_regs *)dev->iobase; - u32 mdioctrlreg = 0; - - if (mdio_wait(dev)) - return 1; - - mdioctrlreg = ((phyaddress << XAE_MDIO_MCR_PHYAD_SHIFT) & - XAE_MDIO_MCR_PHYAD_MASK) | - ((registernum << XAE_MDIO_MCR_REGAD_SHIFT) - & XAE_MDIO_MCR_REGAD_MASK) | - XAE_MDIO_MCR_INITIATE_MASK | - XAE_MDIO_MCR_OP_READ_MASK; - - out_be32(®s->mdio_mcr, mdioctrlreg); - - if (mdio_wait(dev)) - return 1; - - /* Read data */ - *val = in_be32(®s->mdio_mrd); - return 0; -} - -static u32 phywrite(struct eth_device *dev, u32 phyaddress, u32 registernum, - u32 data) -{ - struct axi_regs *regs = (struct axi_regs *)dev->iobase; - u32 mdioctrlreg = 0; - - if (mdio_wait(dev)) - return 1; - - mdioctrlreg = ((phyaddress << XAE_MDIO_MCR_PHYAD_SHIFT) & - XAE_MDIO_MCR_PHYAD_MASK) | - ((registernum << XAE_MDIO_MCR_REGAD_SHIFT) - & XAE_MDIO_MCR_REGAD_MASK) | - XAE_MDIO_MCR_INITIATE_MASK | - XAE_MDIO_MCR_OP_WRITE_MASK; - - /* Write data */ - out_be32(®s->mdio_mwd, data); - - out_be32(®s->mdio_mcr, mdioctrlreg); - - if (mdio_wait(dev)) - return 1; - - return 0; -} - -/* Setting axi emac and phy to proper setting */ -static int setup_phy(struct eth_device *dev) -{ - u16 phyreg; - u32 i, speed, emmc_reg, ret; - struct axidma_priv *priv = dev->priv; - struct axi_regs *regs = (struct axi_regs *)dev->iobase; - struct phy_device *phydev; - - u32 supported = SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full; - - if (priv->phyaddr == -1) { - /* Detect the PHY address */ - for (i = 31; i >= 0; i--) { - ret = phyread(dev, i, PHY_DETECT_REG, &phyreg); - if (!ret && (phyreg != 0xFFFF) && - ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { - /* Found a valid PHY address */ - priv->phyaddr = i; - debug("axiemac: Found valid phy address, %x\n", - phyreg); - break; - } - } - } - - /* Interface - look at tsec */ - phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0); - - phydev->supported &= supported; - phydev->advertising = phydev->supported; - priv->phydev = phydev; - phy_config(phydev); - if (phy_startup(phydev)) { - printf("axiemac: could not initialize PHY %s\n", - phydev->dev->name); - return 0; - } - if (!phydev->link) { - printf("%s: No link.\n", phydev->dev->name); - return 0; - } - - switch (phydev->speed) { - case 1000: - speed = XAE_EMMC_LINKSPD_1000; - break; - case 100: - speed = XAE_EMMC_LINKSPD_100; - break; - case 10: - speed = XAE_EMMC_LINKSPD_10; - break; - default: - return 0; - } - - /* Setup the emac for the phy speed */ - emmc_reg = in_be32(®s->emmc); - emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK; - emmc_reg |= speed; - - /* Write new speed setting out to Axi Ethernet */ - out_be32(®s->emmc, emmc_reg); - - /* - * Setting the operating speed of the MAC needs a delay. There - * doesn't seem to be register to poll, so please consider this - * during your application design. - */ - udelay(1); - - return 1; -} - -/* STOP DMA transfers */ -static void axiemac_halt(struct eth_device *dev) -{ - struct axidma_priv *priv = dev->priv; - u32 temp; - - /* Stop the hardware */ - temp = in_be32(&priv->dmatx->control); - temp &= ~XAXIDMA_CR_RUNSTOP_MASK; - out_be32(&priv->dmatx->control, temp); - - temp = in_be32(&priv->dmarx->control); - temp &= ~XAXIDMA_CR_RUNSTOP_MASK; - out_be32(&priv->dmarx->control, temp); - - debug("axiemac: Halted\n"); -} - -static int axi_ethernet_init(struct eth_device *dev) -{ - struct axi_regs *regs = (struct axi_regs *)dev->iobase; - u32 timeout = 200; - - /* - * Check the status of the MgtRdy bit in the interrupt status - * registers. This must be done to allow the MGT clock to become stable - * for the Sgmii and 1000BaseX PHY interfaces. No other register reads - * will be valid until this bit is valid. - * The bit is always a 1 for all other PHY interfaces. - */ - while (timeout && (!(in_be32(®s->is) & XAE_INT_MGTRDY_MASK))) { - timeout--; - udelay(1); - } - if (!timeout) { - printf("%s: Timeout\n", __func__); - return 1; - } - - /* Stop the device and reset HW */ - /* Disable interrupts */ - out_be32(®s->ie, 0); - - /* Disable the receiver */ - out_be32(®s->rcw1, in_be32(®s->rcw1) & ~XAE_RCW1_RX_MASK); - - /* - * Stopping the receiver in mid-packet causes a dropped packet - * indication from HW. Clear it. - */ - /* Set the interrupt status register to clear the interrupt */ - out_be32(®s->is, XAE_INT_RXRJECT_MASK); - - /* Setup HW */ - /* Set default MDIO divisor */ - out_be32(®s->mdio_mc, XAE_MDIO_DIV_DFT | XAE_MDIO_MC_MDIOEN_MASK); - - debug("axiemac: InitHw done\n"); - return 0; -} - -static int axiemac_setup_mac(struct eth_device *dev) -{ - struct axi_regs *regs = (struct axi_regs *)dev->iobase; - - /* Set the MAC address */ - int val = ((dev->enetaddr[3] << 24) | (dev->enetaddr[2] << 16) | - (dev->enetaddr[1] << 8) | (dev->enetaddr[0])); - out_be32(®s->uaw0, val); - - val = (dev->enetaddr[5] << 8) | dev->enetaddr[4] ; - val |= in_be32(®s->uaw1) & ~XAE_UAW1_UNICASTADDR_MASK; - out_be32(®s->uaw1, val); - return 0; -} - -/* Reset DMA engine */ -static void axi_dma_init(struct eth_device *dev) -{ - struct axidma_priv *priv = dev->priv; - u32 timeout = 500; - - /* Reset the engine so the hardware starts from a known state */ - out_be32(&priv->dmatx->control, XAXIDMA_CR_RESET_MASK); - out_be32(&priv->dmarx->control, XAXIDMA_CR_RESET_MASK); - - /* At the initialization time, hardware should finish reset quickly */ - while (timeout--) { - /* Check transmit/receive channel */ - /* Reset is done when the reset bit is low */ - if (!(in_be32(&priv->dmatx->control) | - in_be32(&priv->dmarx->control)) - & XAXIDMA_CR_RESET_MASK) { - break; - } - } - if (!timeout) - printf("%s: Timeout\n", __func__); -} - -static int axiemac_init(struct eth_device *dev, bd_t * bis) -{ - struct axidma_priv *priv = dev->priv; - struct axi_regs *regs = (struct axi_regs *)dev->iobase; - u32 temp; - - debug("axiemac: Init started\n"); - /* - * Initialize AXIDMA engine. AXIDMA engine must be initialized before - * AxiEthernet. During AXIDMA engine initialization, AXIDMA hardware is - * reset, and since AXIDMA reset line is connected to AxiEthernet, this - * would ensure a reset of AxiEthernet. - */ - axi_dma_init(dev); - - /* Initialize AxiEthernet hardware. */ - if (axi_ethernet_init(dev)) - return -1; - - /* Disable all RX interrupts before RxBD space setup */ - temp = in_be32(&priv->dmarx->control); - temp &= ~XAXIDMA_IRQ_ALL_MASK; - out_be32(&priv->dmarx->control, temp); - - /* Start DMA RX channel. Now it's ready to receive data.*/ - out_be32(&priv->dmarx->current, (u32)&rx_bd); - - /* Setup the BD. */ - memset(&rx_bd, 0, sizeof(rx_bd)); - rx_bd.next = (u32)&rx_bd; - rx_bd.phys = (u32)&rxframe; - rx_bd.cntrl = sizeof(rxframe); - /* Flush the last BD so DMA core could see the updates */ - flush_cache((u32)&rx_bd, sizeof(rx_bd)); - - /* It is necessary to flush rxframe because if you don't do it - * then cache can contain uninitialized data */ - flush_cache((u32)&rxframe, sizeof(rxframe)); - - /* Start the hardware */ - temp = in_be32(&priv->dmarx->control); - temp |= XAXIDMA_CR_RUNSTOP_MASK; - out_be32(&priv->dmarx->control, temp); - - /* Rx BD is ready - start */ - out_be32(&priv->dmarx->tail, (u32)&rx_bd); - - /* Enable TX */ - out_be32(®s->tc, XAE_TC_TX_MASK); - /* Enable RX */ - out_be32(®s->rcw1, XAE_RCW1_RX_MASK); - - /* PHY setup */ - if (!setup_phy(dev)) { - axiemac_halt(dev); - return -1; - } - - debug("axiemac: Init complete\n"); - return 0; -} - -static int axiemac_send(struct eth_device *dev, void *ptr, int len) -{ - struct axidma_priv *priv = dev->priv; - u32 timeout; - - if (len > PKTSIZE_ALIGN) - len = PKTSIZE_ALIGN; - - /* Flush packet to main memory to be trasfered by DMA */ - flush_cache((u32)ptr, len); - - /* Setup Tx BD */ - memset(&tx_bd, 0, sizeof(tx_bd)); - /* At the end of the ring, link the last BD back to the top */ - tx_bd.next = (u32)&tx_bd; - tx_bd.phys = (u32)ptr; - /* Save len */ - tx_bd.cntrl = len | XAXIDMA_BD_CTRL_TXSOF_MASK | - XAXIDMA_BD_CTRL_TXEOF_MASK; - - /* Flush the last BD so DMA core could see the updates */ - flush_cache((u32)&tx_bd, sizeof(tx_bd)); - - if (in_be32(&priv->dmatx->status) & XAXIDMA_HALTED_MASK) { - u32 temp; - out_be32(&priv->dmatx->current, (u32)&tx_bd); - /* Start the hardware */ - temp = in_be32(&priv->dmatx->control); - temp |= XAXIDMA_CR_RUNSTOP_MASK; - out_be32(&priv->dmatx->control, temp); - } - - /* Start transfer */ - out_be32(&priv->dmatx->tail, (u32)&tx_bd); - - /* Wait for transmission to complete */ - debug("axiemac: Waiting for tx to be done\n"); - timeout = 200; - while (timeout && (!in_be32(&priv->dmatx->status) & - (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK))) { - timeout--; - udelay(1); - } - if (!timeout) { - printf("%s: Timeout\n", __func__); - return 1; - } - - debug("axiemac: Sending complete\n"); - return 0; -} - -static int isrxready(struct eth_device *dev) -{ - u32 status; - struct axidma_priv *priv = dev->priv; - - /* Read pending interrupts */ - status = in_be32(&priv->dmarx->status); - - /* Acknowledge pending interrupts */ - out_be32(&priv->dmarx->status, status & XAXIDMA_IRQ_ALL_MASK); - - /* - * If Reception done interrupt is asserted, call RX call back function - * to handle the processed BDs and then raise the according flag. - */ - if ((status & (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK))) - return 1; - - return 0; -} - -static int axiemac_recv(struct eth_device *dev) -{ - u32 length; - struct axidma_priv *priv = dev->priv; - u32 temp; - - /* Wait for an incoming packet */ - if (!isrxready(dev)) - return 0; - - debug("axiemac: RX data ready\n"); - - /* Disable IRQ for a moment till packet is handled */ - temp = in_be32(&priv->dmarx->control); - temp &= ~XAXIDMA_IRQ_ALL_MASK; - out_be32(&priv->dmarx->control, temp); - - length = rx_bd.app4 & 0xFFFF; /* max length mask */ -#ifdef DEBUG - print_buffer(&rxframe, &rxframe[0], 1, length, 16); -#endif - /* Pass the received frame up for processing */ - if (length) - NetReceive(rxframe, length); - -#ifdef DEBUG - /* It is useful to clear buffer to be sure that it is consistent */ - memset(rxframe, 0, sizeof(rxframe)); -#endif - /* Setup RxBD */ - /* Clear the whole buffer and setup it again - all flags are cleared */ - memset(&rx_bd, 0, sizeof(rx_bd)); - rx_bd.next = (u32)&rx_bd; - rx_bd.phys = (u32)&rxframe; - rx_bd.cntrl = sizeof(rxframe); - - /* Write bd to HW */ - flush_cache((u32)&rx_bd, sizeof(rx_bd)); - - /* It is necessary to flush rxframe because if you don't do it - * then cache will contain previous packet */ - flush_cache((u32)&rxframe, sizeof(rxframe)); - - /* Rx BD is ready - start again */ - out_be32(&priv->dmarx->tail, (u32)&rx_bd); - - debug("axiemac: RX completed, framelength = %d\n", length); - - return length; -} - -static int axiemac_miiphy_read(const char *devname, uchar addr, - uchar reg, ushort *val) -{ - struct eth_device *dev = eth_get_dev(); - u32 ret; - - ret = phyread(dev, addr, reg, val); - debug("axiemac: Read MII 0x%x, 0x%x, 0x%x\n", addr, reg, *val); - return ret; -} - -static int axiemac_miiphy_write(const char *devname, uchar addr, - uchar reg, ushort val) -{ - struct eth_device *dev = eth_get_dev(); - - debug("axiemac: Write MII 0x%x, 0x%x, 0x%x\n", addr, reg, val); - return phywrite(dev, addr, reg, val); -} - -static int axiemac_bus_reset(struct mii_dev *bus) -{ - debug("axiemac: Bus reset\n"); - return 0; -} - -int xilinx_axiemac_initialize(bd_t *bis, unsigned long base_addr, - unsigned long dma_addr) -{ - struct eth_device *dev; - struct axidma_priv *priv; - - dev = calloc(1, sizeof(struct eth_device)); - if (dev == NULL) - return -1; - - dev->priv = calloc(1, sizeof(struct axidma_priv)); - if (dev->priv == NULL) { - free(dev); - return -1; - } - priv = dev->priv; - - sprintf(dev->name, "aximac.%lx", base_addr); - - dev->iobase = base_addr; - priv->dmatx = (struct axidma_reg *)dma_addr; - /* RX channel offset is 0x30 */ - priv->dmarx = (struct axidma_reg *)(dma_addr + 0x30); - dev->init = axiemac_init; - dev->halt = axiemac_halt; - dev->send = axiemac_send; - dev->recv = axiemac_recv; - dev->write_hwaddr = axiemac_setup_mac; - -#ifdef CONFIG_PHY_ADDR - priv->phyaddr = CONFIG_PHY_ADDR; -#else - priv->phyaddr = -1; -#endif - - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) - miiphy_register(dev->name, axiemac_miiphy_read, axiemac_miiphy_write); - priv->bus = miiphy_get_dev_by_name(dev->name); - priv->bus->reset = axiemac_bus_reset; -#endif - return 1; -} diff --git a/qemu/roms/u-boot/drivers/net/xilinx_emaclite.c b/qemu/roms/u-boot/drivers/net/xilinx_emaclite.c deleted file mode 100644 index 2a5cc4455..000000000 --- a/qemu/roms/u-boot/drivers/net/xilinx_emaclite.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * (C) Copyright 2007-2009 Michal Simek - * (C) Copyright 2003 Xilinx Inc. - * - * Michal SIMEK <monstr@monstr.eu> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <net.h> -#include <config.h> -#include <malloc.h> -#include <asm/io.h> -#include <fdtdec.h> - -#undef DEBUG - -#define ENET_ADDR_LENGTH 6 - -/* EmacLite constants */ -#define XEL_BUFFER_OFFSET 0x0800 /* Next buffer's offset */ -#define XEL_TPLR_OFFSET 0x07F4 /* Tx packet length */ -#define XEL_TSR_OFFSET 0x07FC /* Tx status */ -#define XEL_RSR_OFFSET 0x17FC /* Rx status */ -#define XEL_RXBUFF_OFFSET 0x1000 /* Receive Buffer */ - -/* Xmit complete */ -#define XEL_TSR_XMIT_BUSY_MASK 0x00000001UL -/* Xmit interrupt enable bit */ -#define XEL_TSR_XMIT_IE_MASK 0x00000008UL -/* Buffer is active, SW bit only */ -#define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000UL -/* Program the MAC address */ -#define XEL_TSR_PROGRAM_MASK 0x00000002UL -/* define for programming the MAC address into the EMAC Lite */ -#define XEL_TSR_PROG_MAC_ADDR (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_PROGRAM_MASK) - -/* Transmit packet length upper byte */ -#define XEL_TPLR_LENGTH_MASK_HI 0x0000FF00UL -/* Transmit packet length lower byte */ -#define XEL_TPLR_LENGTH_MASK_LO 0x000000FFUL - -/* Recv complete */ -#define XEL_RSR_RECV_DONE_MASK 0x00000001UL -/* Recv interrupt enable bit */ -#define XEL_RSR_RECV_IE_MASK 0x00000008UL - -struct xemaclite { - u32 nexttxbuffertouse; /* Next TX buffer to write to */ - u32 nextrxbuffertouse; /* Next RX buffer to read from */ - u32 txpp; /* TX ping pong buffer */ - u32 rxpp; /* RX ping pong buffer */ -}; - -static u32 etherrxbuff[PKTSIZE_ALIGN/4]; /* Receive buffer */ - -static void xemaclite_alignedread(u32 *srcptr, void *destptr, u32 bytecount) -{ - u32 i; - u32 alignbuffer; - u32 *to32ptr; - u32 *from32ptr; - u8 *to8ptr; - u8 *from8ptr; - - from32ptr = (u32 *) srcptr; - - /* Word aligned buffer, no correction needed. */ - to32ptr = (u32 *) destptr; - while (bytecount > 3) { - *to32ptr++ = *from32ptr++; - bytecount -= 4; - } - to8ptr = (u8 *) to32ptr; - - alignbuffer = *from32ptr++; - from8ptr = (u8 *) &alignbuffer; - - for (i = 0; i < bytecount; i++) - *to8ptr++ = *from8ptr++; -} - -static void xemaclite_alignedwrite(void *srcptr, u32 destptr, u32 bytecount) -{ - u32 i; - u32 alignbuffer; - u32 *to32ptr = (u32 *) destptr; - u32 *from32ptr; - u8 *to8ptr; - u8 *from8ptr; - - from32ptr = (u32 *) srcptr; - while (bytecount > 3) { - - *to32ptr++ = *from32ptr++; - bytecount -= 4; - } - - alignbuffer = 0; - to8ptr = (u8 *) &alignbuffer; - from8ptr = (u8 *) from32ptr; - - for (i = 0; i < bytecount; i++) - *to8ptr++ = *from8ptr++; - - *to32ptr++ = alignbuffer; -} - -static void emaclite_halt(struct eth_device *dev) -{ - debug("eth_halt\n"); -} - -static int emaclite_init(struct eth_device *dev, bd_t *bis) -{ - struct xemaclite *emaclite = dev->priv; - debug("EmacLite Initialization Started\n"); - -/* - * TX - TX_PING & TX_PONG initialization - */ - /* Restart PING TX */ - out_be32 (dev->iobase + XEL_TSR_OFFSET, 0); - /* Copy MAC address */ - xemaclite_alignedwrite(dev->enetaddr, dev->iobase, ENET_ADDR_LENGTH); - /* Set the length */ - out_be32 (dev->iobase + XEL_TPLR_OFFSET, ENET_ADDR_LENGTH); - /* Update the MAC address in the EMAC Lite */ - out_be32 (dev->iobase + XEL_TSR_OFFSET, XEL_TSR_PROG_MAC_ADDR); - /* Wait for EMAC Lite to finish with the MAC address update */ - while ((in_be32 (dev->iobase + XEL_TSR_OFFSET) & - XEL_TSR_PROG_MAC_ADDR) != 0) - ; - - if (emaclite->txpp) { - /* The same operation with PONG TX */ - out_be32 (dev->iobase + XEL_TSR_OFFSET + XEL_BUFFER_OFFSET, 0); - xemaclite_alignedwrite(dev->enetaddr, dev->iobase + - XEL_BUFFER_OFFSET, ENET_ADDR_LENGTH); - out_be32 (dev->iobase + XEL_TPLR_OFFSET, ENET_ADDR_LENGTH); - out_be32 (dev->iobase + XEL_TSR_OFFSET + XEL_BUFFER_OFFSET, - XEL_TSR_PROG_MAC_ADDR); - while ((in_be32 (dev->iobase + XEL_TSR_OFFSET + - XEL_BUFFER_OFFSET) & XEL_TSR_PROG_MAC_ADDR) != 0) - ; - } - -/* - * RX - RX_PING & RX_PONG initialization - */ - /* Write out the value to flush the RX buffer */ - out_be32 (dev->iobase + XEL_RSR_OFFSET, XEL_RSR_RECV_IE_MASK); - - if (emaclite->rxpp) - out_be32 (dev->iobase + XEL_RSR_OFFSET + XEL_BUFFER_OFFSET, - XEL_RSR_RECV_IE_MASK); - - debug("EmacLite Initialization complete\n"); - return 0; -} - -static int xemaclite_txbufferavailable(struct eth_device *dev) -{ - u32 reg; - u32 txpingbusy; - u32 txpongbusy; - struct xemaclite *emaclite = dev->priv; - - /* - * Read the other buffer register - * and determine if the other buffer is available - */ - reg = in_be32 (dev->iobase + - emaclite->nexttxbuffertouse + 0); - txpingbusy = ((reg & XEL_TSR_XMIT_BUSY_MASK) == - XEL_TSR_XMIT_BUSY_MASK); - - reg = in_be32 (dev->iobase + - (emaclite->nexttxbuffertouse ^ XEL_TSR_OFFSET) + 0); - txpongbusy = ((reg & XEL_TSR_XMIT_BUSY_MASK) == - XEL_TSR_XMIT_BUSY_MASK); - - return !(txpingbusy && txpongbusy); -} - -static int emaclite_send(struct eth_device *dev, void *ptr, int len) -{ - u32 reg; - u32 baseaddress; - struct xemaclite *emaclite = dev->priv; - - u32 maxtry = 1000; - - if (len > PKTSIZE) - len = PKTSIZE; - - while (!xemaclite_txbufferavailable(dev) && maxtry) { - udelay(10); - maxtry--; - } - - if (!maxtry) { - printf("Error: Timeout waiting for ethernet TX buffer\n"); - /* Restart PING TX */ - out_be32 (dev->iobase + XEL_TSR_OFFSET, 0); - if (emaclite->txpp) { - out_be32 (dev->iobase + XEL_TSR_OFFSET + - XEL_BUFFER_OFFSET, 0); - } - return -1; - } - - /* Determine the expected TX buffer address */ - baseaddress = (dev->iobase + emaclite->nexttxbuffertouse); - - /* Determine if the expected buffer address is empty */ - reg = in_be32 (baseaddress + XEL_TSR_OFFSET); - if (((reg & XEL_TSR_XMIT_BUSY_MASK) == 0) - && ((in_be32 ((baseaddress) + XEL_TSR_OFFSET) - & XEL_TSR_XMIT_ACTIVE_MASK) == 0)) { - - if (emaclite->txpp) - emaclite->nexttxbuffertouse ^= XEL_BUFFER_OFFSET; - - debug("Send packet from 0x%x\n", baseaddress); - /* Write the frame to the buffer */ - xemaclite_alignedwrite(ptr, baseaddress, len); - out_be32 (baseaddress + XEL_TPLR_OFFSET,(len & - (XEL_TPLR_LENGTH_MASK_HI | XEL_TPLR_LENGTH_MASK_LO))); - reg = in_be32 (baseaddress + XEL_TSR_OFFSET); - reg |= XEL_TSR_XMIT_BUSY_MASK; - if ((reg & XEL_TSR_XMIT_IE_MASK) != 0) - reg |= XEL_TSR_XMIT_ACTIVE_MASK; - out_be32 (baseaddress + XEL_TSR_OFFSET, reg); - return 0; - } - - if (emaclite->txpp) { - /* Switch to second buffer */ - baseaddress ^= XEL_BUFFER_OFFSET; - /* Determine if the expected buffer address is empty */ - reg = in_be32 (baseaddress + XEL_TSR_OFFSET); - if (((reg & XEL_TSR_XMIT_BUSY_MASK) == 0) - && ((in_be32 ((baseaddress) + XEL_TSR_OFFSET) - & XEL_TSR_XMIT_ACTIVE_MASK) == 0)) { - debug("Send packet from 0x%x\n", baseaddress); - /* Write the frame to the buffer */ - xemaclite_alignedwrite(ptr, baseaddress, len); - out_be32 (baseaddress + XEL_TPLR_OFFSET, (len & - (XEL_TPLR_LENGTH_MASK_HI | - XEL_TPLR_LENGTH_MASK_LO))); - reg = in_be32 (baseaddress + XEL_TSR_OFFSET); - reg |= XEL_TSR_XMIT_BUSY_MASK; - if ((reg & XEL_TSR_XMIT_IE_MASK) != 0) - reg |= XEL_TSR_XMIT_ACTIVE_MASK; - out_be32 (baseaddress + XEL_TSR_OFFSET, reg); - return 0; - } - } - - puts("Error while sending frame\n"); - return -1; -} - -static int emaclite_recv(struct eth_device *dev) -{ - u32 length; - u32 reg; - u32 baseaddress; - struct xemaclite *emaclite = dev->priv; - - baseaddress = dev->iobase + emaclite->nextrxbuffertouse; - reg = in_be32 (baseaddress + XEL_RSR_OFFSET); - debug("Testing data at address 0x%x\n", baseaddress); - if ((reg & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) { - if (emaclite->rxpp) - emaclite->nextrxbuffertouse ^= XEL_BUFFER_OFFSET; - } else { - - if (!emaclite->rxpp) { - debug("No data was available - address 0x%x\n", - baseaddress); - return 0; - } else { - baseaddress ^= XEL_BUFFER_OFFSET; - reg = in_be32 (baseaddress + XEL_RSR_OFFSET); - if ((reg & XEL_RSR_RECV_DONE_MASK) != - XEL_RSR_RECV_DONE_MASK) { - debug("No data was available - address 0x%x\n", - baseaddress); - return 0; - } - } - } - /* Get the length of the frame that arrived */ - switch(((ntohl(in_be32 (baseaddress + XEL_RXBUFF_OFFSET + 0xC))) & - 0xFFFF0000 ) >> 16) { - case 0x806: - length = 42 + 20; /* FIXME size of ARP */ - debug("ARP Packet\n"); - break; - case 0x800: - length = 14 + 14 + - (((ntohl(in_be32 (baseaddress + XEL_RXBUFF_OFFSET + - 0x10))) & 0xFFFF0000) >> 16); - /* FIXME size of IP packet */ - debug ("IP Packet\n"); - break; - default: - debug("Other Packet\n"); - length = PKTSIZE; - break; - } - - xemaclite_alignedread((u32 *) (baseaddress + XEL_RXBUFF_OFFSET), - etherrxbuff, length); - - /* Acknowledge the frame */ - reg = in_be32 (baseaddress + XEL_RSR_OFFSET); - reg &= ~XEL_RSR_RECV_DONE_MASK; - out_be32 (baseaddress + XEL_RSR_OFFSET, reg); - - debug("Packet receive from 0x%x, length %dB\n", baseaddress, length); - NetReceive((uchar *) etherrxbuff, length); - return length; - -} - -int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr, - int txpp, int rxpp) -{ - struct eth_device *dev; - struct xemaclite *emaclite; - - dev = calloc(1, sizeof(*dev)); - if (dev == NULL) - return -1; - - emaclite = calloc(1, sizeof(struct xemaclite)); - if (emaclite == NULL) { - free(dev); - return -1; - } - - dev->priv = emaclite; - - emaclite->txpp = txpp; - emaclite->rxpp = rxpp; - - sprintf(dev->name, "Xelite.%lx", base_addr); - - dev->iobase = base_addr; - dev->init = emaclite_init; - dev->halt = emaclite_halt; - dev->send = emaclite_send; - dev->recv = emaclite_recv; - - eth_register(dev); - - return 1; -} - -#ifdef CONFIG_OF_CONTROL -int xilinx_emaclite_of_init(const void *blob) -{ - int offset = 0; - u32 ret = 0; - u32 reg; - - do { - offset = fdt_node_offset_by_compatible(blob, offset, - "xlnx,xps-ethernetlite-1.00.a"); - if (offset != -1) { - reg = fdtdec_get_addr(blob, offset, "reg"); - if (reg != FDT_ADDR_T_NONE) { - u32 rxpp = fdtdec_get_int(blob, offset, - "xlnx,rx-ping-pong", 0); - u32 txpp = fdtdec_get_int(blob, offset, - "xlnx,tx-ping-pong", 0); - ret |= xilinx_emaclite_initialize(NULL, reg, - txpp, rxpp); - } else { - debug("EMACLITE: Can't get base address\n"); - return -1; - } - } - } while (offset != -1); - - return ret; -} -#endif diff --git a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac.c b/qemu/roms/u-boot/drivers/net/xilinx_ll_temac.c deleted file mode 100644 index dab78d073..000000000 --- a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Xilinx xps_ll_temac ethernet driver for u-boot - * - * supports SDMA or FIFO access and MDIO bus communication - * - * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net> - * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu> - * Copyright (C) 2008 - 2011 PetaLogix - * - * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver - * Copyright (C) 2008 Nissin Systems Co.,Ltd. - * March 2008 created - * - * SPDX-License-Identifier: GPL-2.0+ - * - * [0]: http://www.xilinx.com/support/documentation - * - * [S]: [0]/ip_documentation/xps_ll_temac.pdf - * [A]: [0]/application_notes/xapp1041.pdf - */ - -#include <config.h> -#include <common.h> -#include <net.h> -#include <netdev.h> -#include <malloc.h> -#include <asm/io.h> -#include <miiphy.h> - -#include "xilinx_ll_temac.h" -#include "xilinx_ll_temac_fifo.h" -#include "xilinx_ll_temac_sdma.h" -#include "xilinx_ll_temac_mdio.h" - -#if !defined(CONFIG_MII) -# error "LL_TEMAC requires MII -- missing CONFIG_MII" -#endif - -#if !defined(CONFIG_PHYLIB) -# error "LL_TEMAC requires PHYLIB -- missing CONFIG_PHYLIB" -#endif - -struct ll_temac_info { - int flags; - unsigned long base_addr; - unsigned long ctrl_addr; - char *devname; - unsigned int phyaddr; - char *mdio_busname; -}; - -/* Ethernet interface ready status */ -int ll_temac_check_status(struct temac_reg *regs, u32 mask) -{ - unsigned timeout = 50; /* 1usec * 50 = 50usec */ - - /* - * Quote from LL TEMAC documentation: The bits in the RDY - * register are asserted when there is no access in progress. - * When an access is in progress, a bit corresponding to the - * type of access is automatically de-asserted. The bit is - * automatically re-asserted when the access is complete. - */ - while (timeout && (!(in_be32(®s->rdy) & mask))) { - timeout--; - udelay(1); - } - - if (!timeout) { - printf("%s: Timeout on 0x%08x @%p\n", __func__, - mask, ®s->rdy); - return 1; - } - - return 0; -} - -/* - * Indirect write to ll_temac. - * - * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf - * page 23, second paragraph, The use of CTL0 register or CTL1 register - */ -int ll_temac_indirect_set(struct temac_reg *regs, u16 regn, u32 reg_data) -{ - out_be32(®s->lsw, (reg_data & MLSW_MASK)); - out_be32(®s->ctl, CTL_WEN | (regn & CTL_ADDR_MASK)); - - if (ll_temac_check_status(regs, RSE_CFG_WR)) - return 0; - - return 1; -} - -/* - * Indirect read from ll_temac. - * - * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf - * page 23, second paragraph, The use of CTL0 register or CTL1 register - */ -int ll_temac_indirect_get(struct temac_reg *regs, u16 regn, u32* reg_data) -{ - out_be32(®s->ctl, (regn & CTL_ADDR_MASK)); - - if (ll_temac_check_status(regs, RSE_CFG_RR)) - return 0; - - *reg_data = in_be32(®s->lsw) & MLSW_MASK; - return 1; -} - -/* setting sub-controller and ll_temac to proper setting */ -static int ll_temac_setup_ctrl(struct eth_device *dev) -{ - struct ll_temac *ll_temac = dev->priv; - struct temac_reg *regs = (struct temac_reg *)dev->iobase; - - if (ll_temac->ctrlreset && ll_temac->ctrlreset(dev)) - return 0; - - if (ll_temac->ctrlinit && ll_temac->ctrlinit(dev)) - return 0; - - /* Promiscuous mode disable */ - if (!ll_temac_indirect_set(regs, TEMAC_AFM, 0)) - return 0; - - /* Enable Receiver - RX bit */ - if (!ll_temac_indirect_set(regs, TEMAC_RCW1, RCW1_RX)) - return 0; - - /* Enable Transmitter - TX bit */ - if (!ll_temac_indirect_set(regs, TEMAC_TC, TC_TX)) - return 0; - - return 1; -} - -/* - * Configure ll_temac based on negotiated speed and duplex - * reported by PHY handling code - */ -static int ll_temac_adjust_link(struct eth_device *dev) -{ - unsigned int speed, emmc_reg; - struct temac_reg *regs = (struct temac_reg *)dev->iobase; - struct ll_temac *ll_temac = dev->priv; - struct phy_device *phydev = ll_temac->phydev; - - if (!phydev->link) { - printf("%s: No link.\n", phydev->dev->name); - return 0; - } - - switch (phydev->speed) { - case 1000: - speed = EMMC_LSPD_1000; - break; - case 100: - speed = EMMC_LSPD_100; - break; - case 10: - speed = EMMC_LSPD_10; - break; - default: - return 0; - } - - if (!ll_temac_indirect_get(regs, TEMAC_EMMC, &emmc_reg)) - return 0; - - emmc_reg &= ~EMMC_LSPD_MASK; - emmc_reg |= speed; - - if (!ll_temac_indirect_set(regs, TEMAC_EMMC, emmc_reg)) - return 0; - - printf("%s: PHY is %s with %dbase%s, %s%s\n", - dev->name, phydev->drv->name, - phydev->speed, (phydev->port == PORT_TP) ? "T" : "X", - (phydev->duplex) ? "FDX" : "HDX", - (phydev->port == PORT_OTHER) ? ", unkown mode" : ""); - - return 1; -} - -/* setup mac addr */ -static int ll_temac_setup_mac_addr(struct eth_device *dev) -{ - struct temac_reg *regs = (struct temac_reg *)dev->iobase; - u32 val; - - /* set up unicast MAC address filter */ - val = ((dev->enetaddr[3] << 24) | (dev->enetaddr[2] << 16) | - (dev->enetaddr[1] << 8) | (dev->enetaddr[0])); - val &= UAW0_UADDR_MASK; - - if (!ll_temac_indirect_set(regs, TEMAC_UAW0, val)) - return 1; - - val = ((dev->enetaddr[5] << 8) | dev->enetaddr[4]); - val &= UAW1_UADDR_MASK; - - if (!ll_temac_indirect_set(regs, TEMAC_UAW1, val)) - return 1; - - return 0; -} - -/* halt device */ -static void ll_temac_halt(struct eth_device *dev) -{ - struct ll_temac *ll_temac = dev->priv; - struct temac_reg *regs = (struct temac_reg *)dev->iobase; - - /* Disable Receiver */ - ll_temac_indirect_set(regs, TEMAC_RCW0, 0); - - /* Disable Transmitter */ - ll_temac_indirect_set(regs, TEMAC_TC, 0); - - if (ll_temac->ctrlhalt) - ll_temac->ctrlhalt(dev); - - /* Shut down the PHY, as needed */ - phy_shutdown(ll_temac->phydev); -} - -static int ll_temac_init(struct eth_device *dev, bd_t *bis) -{ - struct ll_temac *ll_temac = dev->priv; - int ret; - - printf("%s: Xilinx XPS LocalLink Tri-Mode Ether MAC #%d at 0x%08X.\n", - dev->name, dev->index, dev->iobase); - - if (!ll_temac_setup_ctrl(dev)) - return -1; - - /* Start up the PHY */ - ret = phy_startup(ll_temac->phydev); - if (ret) { - printf("%s: Could not initialize PHY %s\n", - dev->name, ll_temac->phydev->dev->name); - return ret; - } - - if (!ll_temac_adjust_link(dev)) { - ll_temac_halt(dev); - return -1; - } - - /* If there's no link, fail */ - return ll_temac->phydev->link ? 0 : -1; -} - -/* - * Discover which PHY is attached to the device, and configure it - * properly. If the PHY is not recognized, then return 0 - * (failure). Otherwise, return 1 - */ -static int ll_temac_phy_init(struct eth_device *dev) -{ - struct ll_temac *ll_temac = dev->priv; - struct phy_device *phydev; - unsigned int supported = PHY_GBIT_FEATURES; - - /* interface - look at driver/net/tsec.c */ - phydev = phy_connect(ll_temac->bus, ll_temac->phyaddr, - dev, PHY_INTERFACE_MODE_NONE); - - phydev->supported &= supported; - phydev->advertising = phydev->supported; - - ll_temac->phydev = phydev; - - phy_config(phydev); - - return 1; -} - -/* - * Initialize a single ll_temac devices - * - * Returns the result of ll_temac phy interface that were initialized - */ -int xilinx_ll_temac_initialize(bd_t *bis, struct ll_temac_info *devinf) -{ - struct eth_device *dev; - struct ll_temac *ll_temac; - - dev = calloc(1, sizeof(*dev)); - if (dev == NULL) - return 0; - - ll_temac = calloc(1, sizeof(struct ll_temac)); - if (ll_temac == NULL) { - free(dev); - return 0; - } - - /* use given name or generate its own unique name */ - if (devinf->devname) { - strncpy(dev->name, devinf->devname, sizeof(dev->name)); - } else { - snprintf(dev->name, sizeof(dev->name), "lltemac.%lx", devinf->base_addr); - devinf->devname = dev->name; - } - - dev->iobase = devinf->base_addr; - - dev->priv = ll_temac; - dev->init = ll_temac_init; - dev->halt = ll_temac_halt; - dev->write_hwaddr = ll_temac_setup_mac_addr; - - ll_temac->ctrladdr = devinf->ctrl_addr; - if (devinf->flags & XILINX_LL_TEMAC_M_SDMA_PLB) { -#if defined(CONFIG_XILINX_440) || defined(CONFIG_XILINX_405) - if (devinf->flags & XILINX_LL_TEMAC_M_SDMA_DCR) { - ll_temac_collect_xldcr_sdma_reg_addr(dev); - ll_temac->in32 = ll_temac_xldcr_in32; - ll_temac->out32 = ll_temac_xldcr_out32; - } else -#endif - { - ll_temac_collect_xlplb_sdma_reg_addr(dev); - ll_temac->in32 = ll_temac_xlplb_in32; - ll_temac->out32 = ll_temac_xlplb_out32; - } - ll_temac->ctrlinit = ll_temac_init_sdma; - ll_temac->ctrlhalt = ll_temac_halt_sdma; - ll_temac->ctrlreset = ll_temac_reset_sdma; - dev->recv = ll_temac_recv_sdma; - dev->send = ll_temac_send_sdma; - } else { - ll_temac->in32 = NULL; - ll_temac->out32 = NULL; - ll_temac->ctrlinit = NULL; - ll_temac->ctrlhalt = NULL; - ll_temac->ctrlreset = ll_temac_reset_fifo; - dev->recv = ll_temac_recv_fifo; - dev->send = ll_temac_send_fifo; - } - - /* Link to specified MDIO bus */ - strncpy(ll_temac->mdio_busname, devinf->mdio_busname, MDIO_NAME_LEN); - ll_temac->bus = miiphy_get_dev_by_name(ll_temac->mdio_busname); - - /* Looking for a valid PHY address if it is not yet set */ - if (devinf->phyaddr == -1) - ll_temac->phyaddr = ll_temac_phy_addr(ll_temac->bus); - else - ll_temac->phyaddr = devinf->phyaddr; - - eth_register(dev); - - /* Try to initialize PHY here, and return */ - return ll_temac_phy_init(dev); -} - -/* - * Initialize a single ll_temac device with its mdio bus behind ll_temac - * - * Returns 1 if the ll_temac device and the mdio bus were initialized - * otherwise returns 0 - */ -int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags, - unsigned long ctrl_addr) -{ - struct ll_temac_info devinf; - struct ll_temac_mdio_info mdioinf; - int ret; - - /* prepare the internal driver informations */ - devinf.flags = flags; - devinf.base_addr = base_addr; - devinf.ctrl_addr = ctrl_addr; - devinf.devname = NULL; - devinf.phyaddr = -1; - - mdioinf.name = devinf.mdio_busname = NULL; - mdioinf.regs = (struct temac_reg *)devinf.base_addr; - - ret = xilinx_ll_temac_mdio_initialize(bis, &mdioinf); - if (ret >= 0) { - - /* - * If there was no MDIO bus name then take over the - * new automaticaly generated by the MDIO init code. - */ - if (mdioinf.name != devinf.mdio_busname) - devinf.mdio_busname = mdioinf.name; - - ret = xilinx_ll_temac_initialize(bis, &devinf); - if (ret > 0) - return 1; - - } - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac.h b/qemu/roms/u-boot/drivers/net/xilinx_ll_temac.h deleted file mode 100644 index 56362ba20..000000000 --- a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac.h +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Xilinx xps_ll_temac ethernet driver for u-boot - * - * LL_TEMAC interface - * - * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net> - * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu> - * Copyright (C) 2008 - 2011 PetaLogix - * - * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver - * Copyright (C) 2008 Nissin Systems Co.,Ltd. - * March 2008 created - * - * SPDX-License-Identifier: GPL-2.0+ - * - * [0]: http://www.xilinx.com/support/documentation - * - * [S]: [0]/ip_documentation/xps_ll_temac.pdf - * [A]: [0]/application_notes/xapp1041.pdf - */ -#ifndef _XILINX_LL_TEMAC_ -#define _XILINX_LL_TEMAC_ - -#include <config.h> -#include <net.h> -#include <phy.h> -#include <miiphy.h> - -#include <asm/types.h> -#include <asm/byteorder.h> - -#include "xilinx_ll_temac_sdma.h" - -#if !defined(__BIG_ENDIAN) -# error LL_TEMAC requires big endianess -#endif - -/* - * TEMAC Memory and Register Definition - * - * [1]: [0]/ip_documentation/xps_ll_temac.pdf - * page 19, Memory and Register Descriptions - */ -struct temac_reg { - /* direct soft registers (low part) */ - u32 raf; /* Reset and Address Filter */ - u32 tpf; /* Transmit Pause Frame */ - u32 ifgp; /* Transmit Inter Frame Gap Adjustment */ - u32 is; /* Interrupt Status */ - u32 ip; /* Interrupt Pending */ - u32 ie; /* Interrupt Enable */ - u32 ttag; /* Transmit VLAN Tag */ - u32 rtag; /* Receive VLAN Tag */ - /* hard TEMAC registers */ - u32 msw; /* Most Significant Word Data */ - u32 lsw; /* Least Significant Word Data */ - u32 ctl; /* Control */ - u32 rdy; /* Ready Status */ - /* direct soft registers (high part) */ - u32 uawl; /* Unicast Address Word Lower */ - u32 uawu; /* Unicast Address Word Upper */ - u32 tpid0; /* VLAN TPID Word 0 */ - u32 tpid1; /* VLAN TPID Word 1 */ -}; - -/* Reset and Address Filter Registers (raf), [1] p25 */ -#define RAF_SR (1 << 13) -#define RAF_EMFE (1 << 12) -#define RAF_NFE (1 << 11) -#define RAF_RVSTM_POS 9 -#define RAF_RVSTM_MASK (3 << RAF_RVSTM_POS) -#define RAF_TVSTM_POS 7 -#define RAF_TVSTM_MASK (3 << RAF_TVSTM_POS) -#define RAF_RVTM_POS 5 -#define RAF_RVTM_MASK (3 << RAF_RVTM_POS) -#define RAF_TVTM_POS 3 -#define RAF_TVTM_MASK (3 << RAF_TVTM_POS) -#define RAF_BCREJ (1 << 2) -#define RAF_MCREJ (1 << 1) -#define RAF_HTRST (1 << 0) - -/* Transmit Pause Frame Registers (tpf), [1] p28 */ -#define TPF_TPFV_POS 0 -#define TPF_TPFV_MASK (0xFFFF << TPF_TPFV_POS) - -/* Transmit Inter Frame Gap Adjustment Registers (ifgp), [1] p28 */ -#define IFGP_POS 0 -#define IFGP_MASK (0xFF << IFGP_POS) - -/* Interrupt Status, Pending, Enable Registers (is, ip, ie), [1] p29-33 */ -#define ISPE_MR (1 << 7) -#define ISPE_RDL (1 << 6) -#define ISPE_TC (1 << 5) -#define ISPE_RFO (1 << 4) -#define ISPE_RR (1 << 3) -#define ISPE_RC (1 << 2) -#define ISPE_AN (1 << 1) -#define ISPE_HAC (1 << 0) - -/* Transmit, Receive VLAN Tag Registers (ttag, rtag), [1] p34-35 */ -#define TRTAG_TPID_POS 16 -#define TRTAG_TPID_MASK (0xFFFF << TRTAG_TPID_POS) -#define TRTAG_PRIO_POS 13 -#define TRTAG_PRIO_MASK (7 << TRTAG_PRIO_POS) -#define TRTAG_CFI (1 << 12) -#define TRTAG_VID_POS 0 -#define TRTAG_VID_MASK (0xFFF << TRTAG_VID_POS) - -/* Most, Least Significant Word Data Register (msw, lsw), [1] p46 */ -#define MLSW_POS 0 -#define MLSW_MASK (~0UL << MLSW_POS) - -/* LSW Data Register for PHY addresses (lsw), [1] p66 */ -#define LSW_REGAD_POS 0 -#define LSW_REGAD_MASK (0x1F << LSW_REGAD_POS) -#define LSW_PHYAD_POS 5 -#define LSW_PHYAD_MASK (0x1F << LSW_PHYAD_POS) - -/* LSW Data Register for PHY data (lsw), [1] p66 */ -#define LSW_REGDAT_POS 0 -#define LSW_REGDAT_MASK (0xFFFF << LSW_REGDAT_POS) - -/* Control Register (ctl), [1] p47 */ -#define CTL_WEN (1 << 15) -#define CTL_ADDR_POS 0 -#define CTL_ADDR_MASK (0x3FF << CTL_ADDR_POS) - -/* Ready Status Register Ethernet (rdy), [1] p48 */ -#define RSE_HACS_RDY (1 << 14) -#define RSE_CFG_WR (1 << 6) -#define RSE_CFG_RR (1 << 5) -#define RSE_AF_WR (1 << 4) -#define RSE_AF_RR (1 << 3) -#define RSE_MIIM_WR (1 << 2) -#define RSE_MIIM_RR (1 << 1) -#define RSE_FABR_RR (1 << 0) - -/* Unicast Address Word Lower, Upper Registers (uawl, uawu), [1] p35-36 */ -#define UAWL_UADDR_POS 0 -#define UAWL_UADDR_MASK (~0UL << UAWL_UADDR_POS) -#define UAWU_UADDR_POS 0 -#define UAWU_UADDR_MASK (0xFFFF << UAWU_UADDR_POS) - -/* VLAN TPID Word 0, 1 Registers (tpid0, tpid1), [1] p37 */ -#define TPID0_V0_POS 0 -#define TPID0_V0_MASK (0xFFFF << TPID0_V0_POS) -#define TPID0_V1_POS 16 -#define TPID0_V1_MASK (0xFFFF << TPID0_V1_POS) -#define TPID1_V2_POS 0 -#define TPID1_V2_MASK (0xFFFF << TPID1_V2_POS) -#define TPID1_V3_POS 16 -#define TPID1_V3_MASK (0xFFFF << TPID1_V3_POS) - -/* - * TEMAC Indirectly Addressable Register Index Enumeration - * - * [0]: http://www.xilinx.com/support/documentation - * - * [1]: [0]/ip_documentation/xps_ll_temac.pdf - * page 23, PLB Indirectly Addressable TEMAC Registers - */ -enum temac_ctrl { - TEMAC_RCW0 = 0x200, - TEMAC_RCW1 = 0x240, - TEMAC_TC = 0x280, - TEMAC_FCC = 0x2C0, - TEMAC_EMMC = 0x300, - TEMAC_PHYC = 0x320, - TEMAC_MC = 0x340, - TEMAC_UAW0 = 0x380, - TEMAC_UAW1 = 0x384, - TEMAC_MAW0 = 0x388, - TEMAC_MAW1 = 0x38C, - TEMAC_AFM = 0x390, - TEMAC_TIS = 0x3A0, - TEMAC_TIE = 0x3A4, - TEMAC_MIIMWD = 0x3B0, - TEMAC_MIIMAI = 0x3B4 -}; - -/* Receive Configuration Word 0, 1 Registers (RCW0, RCW1), [1] p50-51 */ -#define RCW0_PADDR_POS 0 -#define RCW0_PADDR_MASK (~0UL << RCW_PADDR_POS) -#define RCW1_RST (1 << 31) -#define RCW1_JUM (1 << 30) -#define RCW1_FCS (1 << 29) -#define RCW1_RX (1 << 28) -#define RCW1_VLAN (1 << 27) -#define RCW1_HD (1 << 26) -#define RCW1_LT_DIS (1 << 25) -#define RCW1_PADDR_POS 0 -#define RCW1_PADDR_MASK (0xFFFF << RCW_PADDR_POS) - -/* Transmit Configuration Registers (TC), [1] p52 */ -#define TC_RST (1 << 31) -#define TC_JUM (1 << 30) -#define TC_FCS (1 << 29) -#define TC_TX (1 << 28) -#define TC_VLAN (1 << 27) -#define TC_HD (1 << 26) -#define TC_IFG (1 << 25) - -/* Flow Control Configuration Registers (FCC), [1] p54 */ -#define FCC_FCTX (1 << 30) -#define FCC_FCRX (1 << 29) - -/* Ethernet MAC Mode Configuration Registers (EMMC), [1] p54 */ -#define EMMC_LSPD_POS 30 -#define EMMC_LSPD_MASK (3 << EMMC_LSPD_POS) -#define EMMC_LSPD_1000 (2 << EMMC_LSPD_POS) -#define EMMC_LSPD_100 (1 << EMMC_LSPD_POS) -#define EMMC_LSPD_10 0 -#define EMMC_RGMII (1 << 29) -#define EMMC_SGMII (1 << 28) -#define EMMC_GPCS (1 << 27) -#define EMMC_HOST (1 << 26) -#define EMMC_TX16 (1 << 25) -#define EMMC_RX16 (1 << 24) - -/* RGMII/SGMII Configuration Registers (PHYC), [1] p56 */ -#define PHYC_SLSPD_POS 30 -#define PHYC_SLSPD_MASK (3 << EMMC_SLSPD_POS) -#define PHYC_SLSPD_1000 (2 << EMMC_SLSPD_POS) -#define PHYC_SLSPD_100 (1 << EMMC_SLSPD_POS) -#define PHYC_SLSPD_10 0 -#define PHYC_RLSPD_POS 2 -#define PHYC_RLSPD_MASK (3 << EMMC_RLSPD_POS) -#define PHYC_RLSPD_1000 (2 << EMMC_RLSPD_POS) -#define PHYC_RLSPD_100 (1 << EMMC_RLSPD_POS) -#define PHYC_RLSPD_10 0 -#define PHYC_RGMII_HD (1 << 1) -#define PHYC_RGMII_LINK (1 << 0) - -/* Management Configuration Registers (MC), [1] p57 */ -#define MC_MDIOEN (1 << 6) -#define MC_CLKDIV_POS 0 -#define MC_CLKDIV_MASK (0x3F << MC_CLKDIV_POS) - -/* - * fHOSTCLK fMDC = fHOSTCLK - * fMDC = ------------------- ---------> MC_CLKDIV = -------- - 1 - * (1 + MC_CLKDIV) * 2 2.5 MHz 5MHz - */ -#define MC_CLKDIV(f, m) ((f / (2 * m)) - 1) -#define MC_CLKDIV_25(f) MC_CLKDIV(f, 2500000) -#define MC_CLKDIV_20(f) MC_CLKDIV(f, 2000000) -#define MC_CLKDIV_15(f) MC_CLKDIV(f, 1500000) -#define MC_CLKDIV_10(f) MC_CLKDIV(f, 1000000) - -/* Unicast Address Word 0, 1 Registers (UAW0, UAW1), [1] p58-59 */ -#define UAW0_UADDR_POS 0 -#define UAW0_UADDR_MASK (~0UL << UAW0_UADDR_POS) -#define UAW1_UADDR_POS 0 -#define UAW1_UADDR_MASK (0xFFFF << UAW1_UADDR_POS) - -/* Multicast Address Word 0, 1 Registers (MAW0, MAW1), [1] p60 */ -#define MAW0_MADDR_POS 0 -#define MAW0_MADDR_MASK (~0UL << MAW0_MADDR_POS) -#define MAW1_RNW (1 << 23) -#define MAW1_MAIDX_POS 16 -#define MAW1_MAIDX_MASK (3 << MAW1_MAIDX_POS) -#define MAW1_MADDR_POS 0 -#define MAW1_MADDR_MASK (0xFFFF << MAW1_MADDR_POS) - -/* Address Filter Mode Registers (AFM), [1] p63 */ -#define AFM_PM (1 << 31) - -/* Interrupt Status, Enable Registers (TIS, TIE), [1] p63-65 */ -#define TISE_CFG_W (1 << 6) -#define TISE_CFG_R (1 << 5) -#define TISE_AF_W (1 << 4) -#define TISE_AF_R (1 << 3) -#define TISE_MIIM_W (1 << 2) -#define TISE_MIIM_R (1 << 1) -#define TISE_FABR_R (1 << 0) - -/* MII Management Write Data Registers (MIIMWD), [1] p66 */ -#define MIIMWD_DATA_POS 0 -#define MIIMWD_DATA_MASK (0xFFFF << MIIMWD_DATA_POS) - -/* Ethernet interface ready status */ -int ll_temac_check_status(struct temac_reg *regs, u32 mask); - -/* Indirect write to ll_temac. */ -int ll_temac_indirect_set(struct temac_reg *regs, u16 regn, u32 reg_data); - -/* Indirect read from ll_temac. */ -int ll_temac_indirect_get(struct temac_reg *regs, u16 regn, u32* reg_data); - -struct ll_temac { - phys_addr_t ctrladdr; - phys_addr_t sdma_reg_addr[SDMA_CTRL_REGNUMS]; - - unsigned (*in32)(phys_addr_t); - void (*out32)(phys_addr_t, unsigned); - - int (*ctrlinit) (struct eth_device *); - int (*ctrlhalt) (struct eth_device *); - int (*ctrlreset) (struct eth_device *); - - int phyaddr; - struct phy_device *phydev; - struct mii_dev *bus; - char mdio_busname[MDIO_NAME_LEN]; -}; - -#endif /* _XILINX_LL_TEMAC_ */ diff --git a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_fifo.c b/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_fifo.c deleted file mode 100644 index b8993cdb2..000000000 --- a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_fifo.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Xilinx xps_ll_temac ethernet driver for u-boot - * - * FIFO sub-controller - * - * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net> - * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu> - * Copyright (C) 2008 - 2011 PetaLogix - * - * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver - * Copyright (C) 2008 Nissin Systems Co.,Ltd. - * March 2008 created - * - * CREDITS: tsec driver - * - * SPDX-License-Identifier: GPL-2.0+ - * - * [0]: http://www.xilinx.com/support/documentation - * - * [F]: [0]/ip_documentation/xps_ll_fifo.pdf - * [S]: [0]/ip_documentation/xps_ll_temac.pdf - * [A]: [0]/application_notes/xapp1041.pdf - */ - -#include <config.h> -#include <common.h> -#include <net.h> - -#include <asm/types.h> -#include <asm/io.h> - -#include "xilinx_ll_temac.h" -#include "xilinx_ll_temac_fifo.h" - -int ll_temac_reset_fifo(struct eth_device *dev) -{ - struct ll_temac *ll_temac = dev->priv; - struct fifo_ctrl *fifo_ctrl = (void *)ll_temac->ctrladdr; - - out_be32(&fifo_ctrl->tdfr, LL_FIFO_TDFR_KEY); - out_be32(&fifo_ctrl->rdfr, LL_FIFO_RDFR_KEY); - out_be32(&fifo_ctrl->isr, ~0UL); - out_be32(&fifo_ctrl->ier, 0); - - return 0; -} - -int ll_temac_recv_fifo(struct eth_device *dev) -{ - int i, length = 0; - u32 *buf = (u32 *)NetRxPackets[0]; - struct ll_temac *ll_temac = dev->priv; - struct fifo_ctrl *fifo_ctrl = (void *)ll_temac->ctrladdr; - - if (in_be32(&fifo_ctrl->isr) & LL_FIFO_ISR_RC) { - - /* reset isr */ - out_be32(&fifo_ctrl->isr, ~0UL); - - /* - * MAYBE here: - * while (fifo_ctrl->isr); - */ - - /* - * The length is written (into RLR) by the XPS LL FIFO - * when the packet is received across the RX LocalLink - * interface and the receive data FIFO had enough - * locations that all of the packet data has been saved. - * The RLR should only be read when a receive packet is - * available for processing (the receive occupancy is - * not zero). Once the RLR is read, the receive packet - * data should be read from the receive data FIFO before - * the RLR is read again. - * - * [F] page 17, Receive Length Register (RLR) - */ - if (in_be32(&fifo_ctrl->rdfo) & LL_FIFO_RDFO_MASK) { - length = in_be32(&fifo_ctrl->rlf) & LL_FIFO_RLF_MASK; - } else { - printf("%s: Got error, no receive occupancy\n", - __func__); - return -1; - } - - if (length > PKTSIZE_ALIGN) { - printf("%s: Got error, receive package too big (%i)\n", - __func__, length); - ll_temac_reset_fifo(dev); - return -1; - } - - for (i = 0; i < length; i += 4) - *buf++ = in_be32(&fifo_ctrl->rdfd); - - NetReceive(NetRxPackets[0], length); - } - - return 0; -} - -int ll_temac_send_fifo(struct eth_device *dev, void *packet, int length) -{ - int i; - u32 *buf = (u32 *)packet; - struct ll_temac *ll_temac = dev->priv; - struct fifo_ctrl *fifo_ctrl = (void *)ll_temac->ctrladdr; - - if (length < LL_FIFO_TLF_MIN) { - printf("%s: Got error, transmit package too small (%i)\n", - __func__, length); - return -1; - } - - if (length > LL_FIFO_TLF_MAX) { - printf("%s: Got error, transmit package too big (%i)\n", - __func__, length); - return -1; - } - - for (i = 0; i < length; i += 4) - out_be32(&fifo_ctrl->tdfd, *buf++); - - /* - * Once the packet length is written to the TLR it is - * automatically moved to the transmit data FIFO with - * the packet data freeing up the TLR for another value. - * The packet length must be written to the TLR after - * the packet data is written to the transmit data FIFO. - * It is not valid to write data for multiple packets - * to the transmit data FIFO before writing the packet - * length values. - * - * [F] page 17, Transmit Length Register (TLR) - */ - out_be32(&fifo_ctrl->tlf, length); - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_fifo.h b/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_fifo.h deleted file mode 100644 index c1bf7cc64..000000000 --- a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_fifo.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Xilinx xps_ll_temac ethernet driver for u-boot - * - * FIFO sub-controller interface - * - * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net> - * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu> - * Copyright (C) 2008 - 2011 PetaLogix - * - * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver - * Copyright (C) 2008 Nissin Systems Co.,Ltd. - * March 2008 created - * - * SPDX-License-Identifier: GPL-2.0+ - * - * [0]: http://www.xilinx.com/support/documentation - * - * [S]: [0]/ip_documentation/xps_ll_temac.pdf - * [A]: [0]/application_notes/xapp1041.pdf - */ -#ifndef _XILINX_LL_TEMAC_FIFO_ -#define _XILINX_LL_TEMAC_FIFO_ - -#include <net.h> - -#include <asm/types.h> -#include <asm/byteorder.h> - -#if !defined(__BIG_ENDIAN) -# error LL_TEMAC requires big endianess -#endif - -/* - * FIFO Register Definition - * - * Used for memory mapped access from and to (Rd/Td) the LocalLink (LL) - * Tri-Mode Ether MAC (TEMAC) via the 2 kb full duplex FIFO Controller, - * one for each. - * - * [1]: [0]/ip_documentation/xps_ll_fifo.pdf - * page 10, Registers Definition - */ -struct fifo_ctrl { - u32 isr; /* Interrupt Status Register (RW) */ - u32 ier; /* Interrupt Enable Register (RW) */ - u32 tdfr; /* Transmit Data FIFO Reset (WO) */ - u32 tdfv; /* Transmit Data FIFO Vacancy (RO) */ - u32 tdfd; /* Transmit Data FIFO 32bit wide Data write port (WO) */ - u32 tlf; /* Transmit Length FIFO (WO) */ - u32 rdfr; /* Receive Data FIFO Reset (WO) */ - u32 rdfo; /* Receive Data FIFO Occupancy (RO) */ - u32 rdfd; /* Receive Data FIFO 32bit wide Data read port (RO) */ - u32 rlf; /* Receive Length FIFO (RO) */ - u32 llr; /* LocalLink Reset (WO) */ -}; - -/* Interrupt Status Register (ISR), [1] p11 */ -#define LL_FIFO_ISR_RPURE (1 << 31) /* Receive Packet Underrun Read Err */ -#define LL_FIFO_ISR_RPORE (1 << 30) /* Receive Packet Overrun Read Err */ -#define LL_FIFO_ISR_RPUE (1 << 29) /* Receive Packet Underrun Error */ -#define LL_FIFO_ISR_TPOE (1 << 28) /* Transmit Packet Overrun Error */ -#define LL_FIFO_ISR_TC (1 << 27) /* Transmit Complete */ -#define LL_FIFO_ISR_RC (1 << 26) /* Receive Complete */ -#define LL_FIFO_ISR_TSE (1 << 25) /* Transmit Size Error */ -#define LL_FIFO_ISR_TRC (1 << 24) /* Transmit Reset Complete */ -#define LL_FIFO_ISR_RRC (1 << 23) /* Receive Reset Complete */ - -/* Interrupt Enable Register (IER), [1] p12/p13 */ -#define LL_FIFO_IER_RPURE (1 << 31) /* Receive Packet Underrun Read Err */ -#define LL_FIFO_IER_RPORE (1 << 30) /* Receive Packet Overrun Read Err */ -#define LL_FIFO_IER_RPUE (1 << 29) /* Receive Packet Underrun Error */ -#define LL_FIFO_IER_TPOE (1 << 28) /* Transmit Packet Overrun Error */ -#define LL_FIFO_IER_TC (1 << 27) /* Transmit Complete */ -#define LL_FIFO_IER_RC (1 << 26) /* Receive Complete */ -#define LL_FIFO_IER_TSE (1 << 25) /* Transmit Size Error */ -#define LL_FIFO_IER_TRC (1 << 24) /* Transmit Reset Complete */ -#define LL_FIFO_IER_RRC (1 << 23) /* Receive Reset Complete */ - -/* Transmit Data FIFO Reset (TDFR), [1] p13/p14 */ -#define LL_FIFO_TDFR_KEY 0x000000A5UL - -/* Transmit Data FIFO Vacancy (TDFV), [1] p14 */ -#define LL_FIFO_TDFV_POS 0 -#define LL_FIFO_TDFV_MASK (0x000001FFUL << LL_FIFO_TDFV_POS) - -/* Transmit Length FIFO (TLF), [1] p16/p17 */ -#define LL_FIFO_TLF_POS 0 -#define LL_FIFO_TLF_MASK (0x000007FFUL << LL_FIFO_TLF_POS) -#define LL_FIFO_TLF_MIN ((4 * sizeof(u32)) & LL_FIFO_TLF_MASK) -#define LL_FIFO_TLF_MAX ((510 * sizeof(u32)) & LL_FIFO_TLF_MASK) - -/* Receive Data FIFO Reset (RDFR), [1] p15 */ -#define LL_FIFO_RDFR_KEY 0x000000A5UL - -/* Receive Data FIFO Occupancy (RDFO), [1] p16 */ -#define LL_FIFO_RDFO_POS 0 -#define LL_FIFO_RDFO_MASK (0x000001FFUL << LL_FIFO_RDFO_POS) - -/* Receive Length FIFO (RLF), [1] p17/p18 */ -#define LL_FIFO_RLF_POS 0 -#define LL_FIFO_RLF_MASK (0x000007FFUL << LL_FIFO_RLF_POS) -#define LL_FIFO_RLF_MIN ((4 * sizeof(uint32)) & LL_FIFO_RLF_MASK) -#define LL_FIFO_RLF_MAX ((510 * sizeof(uint32)) & LL_FIFO_RLF_MASK) - -/* LocalLink Reset (LLR), [1] p18 */ -#define LL_FIFO_LLR_KEY 0x000000A5UL - - -/* reset FIFO and IRQ, disable interrupts */ -int ll_temac_reset_fifo(struct eth_device *dev); - -/* receive buffered data from FIFO (polling ISR) */ -int ll_temac_recv_fifo(struct eth_device *dev); - -/* send buffered data to FIFO */ -int ll_temac_send_fifo(struct eth_device *dev, void *packet, int length); - -#endif /* _XILINX_LL_TEMAC_FIFO_ */ diff --git a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_mdio.c b/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_mdio.c deleted file mode 100644 index b7bab794e..000000000 --- a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_mdio.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Xilinx xps_ll_temac ethernet driver for u-boot - * - * MDIO bus access - * - * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net> - * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu> - * Copyright (C) 2008 - 2011 PetaLogix - * - * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver - * Copyright (C) 2008 Nissin Systems Co.,Ltd. - * March 2008 created - * - * CREDITS: tsec driver - * - * SPDX-License-Identifier: GPL-2.0+ - * - * [0]: http://www.xilinx.com/support/documentation - * - * [S]: [0]/ip_documentation/xps_ll_temac.pdf - * [A]: [0]/application_notes/xapp1041.pdf - */ - -#include <config.h> -#include <common.h> -#include <miiphy.h> -#include <phy.h> -#include <malloc.h> -#include <asm/io.h> - -#include "xilinx_ll_temac.h" -#include "xilinx_ll_temac_mdio.h" - -#if !defined(CONFIG_MII) -# error "LL_TEMAC requires MII -- missing CONFIG_MII" -#endif - -#if !defined(CONFIG_PHYLIB) -# error "LL_TEMAC requires PHYLIB -- missing CONFIG_PHYLIB" -#endif - -/* - * Prior to PHY access, the MDIO clock must be setup. This driver will set a - * safe default that should work with PLB bus speeds of up to 150 MHz and keep - * the MDIO clock below 2.5 MHz. If the user wishes faster access to the PHY - * then the clock divisor can be set to a different value by setting the - * correct bus speed value with CONFIG_XILINX_LL_TEMAC_CLK. - */ -#if !defined(CONFIG_XILINX_LL_TEMAC_CLK) -#define MDIO_CLOCK_DIV MC_CLKDIV_10(150000000) -#else -#define MDIO_CLOCK_DIV MC_CLKDIV_25(CONFIG_XILINX_LL_TEMAC_CLK) -#endif - -static int ll_temac_mdio_setup(struct mii_dev *bus) -{ - struct temac_reg *regs = (struct temac_reg *)bus->priv; - - /* setup MDIO clock */ - ll_temac_indirect_set(regs, TEMAC_MC, - MC_MDIOEN | (MDIO_CLOCK_DIV & MC_CLKDIV_MASK)); - - return 0; -} - -/* - * Indirect MII PHY read via ll_temac. - * - * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf - * page 67, Using the MII Management to Access PHY Registers - */ -int ll_temac_local_mdio_read(struct temac_reg *regs, int addr, int devad, - int regnum) -{ - out_be32(®s->lsw, - ((addr << LSW_PHYAD_POS) & LSW_PHYAD_MASK) | - (regnum & LSW_REGAD_MASK)); - out_be32(®s->ctl, TEMAC_MIIMAI); - - ll_temac_check_status(regs, RSE_MIIM_RR); - - return in_be32(®s->lsw) & LSW_REGDAT_MASK; -} - -/* - * Indirect MII PHY write via ll_temac. - * - * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf - * page 67, Using the MII Management to Access PHY Registers - */ -void ll_temac_local_mdio_write(struct temac_reg *regs, int addr, int devad, - int regnum, u16 value) -{ - out_be32(®s->lsw, (value & LSW_REGDAT_MASK)); - out_be32(®s->ctl, CTL_WEN | TEMAC_MIIMWD); - - out_be32(®s->lsw, - ((addr << LSW_PHYAD_POS) & LSW_PHYAD_MASK) | - (regnum & LSW_REGAD_MASK)); - out_be32(®s->ctl, CTL_WEN | TEMAC_MIIMAI); - - ll_temac_check_status(regs, RSE_MIIM_WR); -} - -int ll_temac_phy_read(struct mii_dev *bus, int addr, int devad, int regnum) -{ - struct temac_reg *regs = (struct temac_reg *)bus->priv; - - return ll_temac_local_mdio_read(regs, addr, devad, regnum); -} - -int ll_temac_phy_write(struct mii_dev *bus, int addr, int devad, int regnum, - u16 value) -{ - struct temac_reg *regs = (struct temac_reg *)bus->priv; - - ll_temac_local_mdio_write(regs, addr, devad, regnum, value); - - return 0; -} - -/* - * Use MII register 1 (MII status register) to detect PHY - * - * A Mask used to verify certain PHY features (register content) - * in the PHY detection register: - * Auto-negotiation support, 10Mbps half/full duplex support - */ -#define PHY_DETECT_REG MII_BMSR -#define PHY_DETECT_MASK (BMSR_10FULL | BMSR_10HALF | BMSR_ANEGCAPABLE) - -/* Looking for a valid PHY address */ -int ll_temac_phy_addr(struct mii_dev *bus) -{ - struct temac_reg *regs = (struct temac_reg *)bus->priv; - unsigned short val; - unsigned int phy; - - for (phy = PHY_MAX_ADDR; phy >= 0; phy--) { - val = ll_temac_local_mdio_read(regs, phy, 0, PHY_DETECT_REG); - if ((val != 0xFFFF) && - ((val & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { - /* Found a valid PHY address */ - return phy; - } - } - - return -1; -} - -int xilinx_ll_temac_mdio_initialize(bd_t *bis, struct ll_temac_mdio_info *info) -{ - struct mii_dev *bus = mdio_alloc(); - - if (!bus) { - printf("Failed to allocate LL_TEMAC MDIO bus: %s\n", - info->name); - return -1; - } - - bus->read = ll_temac_phy_read; - bus->write = ll_temac_phy_write; - bus->reset = NULL; - - /* use given name or generate its own unique name */ - if (info->name) { - strncpy(bus->name, info->name, MDIO_NAME_LEN); - } else { - snprintf(bus->name, MDIO_NAME_LEN, "lltemii.%p", info->regs); - info->name = bus->name; - } - - bus->priv = info->regs; - - ll_temac_mdio_setup(bus); - return mdio_register(bus); -} diff --git a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_mdio.h b/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_mdio.h deleted file mode 100644 index 0603c6445..000000000 --- a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_mdio.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Xilinx xps_ll_temac ethernet driver for u-boot - * - * MDIO bus access interface - * - * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net> - * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu> - * Copyright (C) 2008 - 2011 PetaLogix - * - * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver - * Copyright (C) 2008 Nissin Systems Co.,Ltd. - * March 2008 created - * - * SPDX-License-Identifier: GPL-2.0+ - * - * [0]: http://www.xilinx.com/support/documentation - * - * [S]: [0]/ip_documentation/xps_ll_temac.pdf - * [A]: [0]/application_notes/xapp1041.pdf - */ -#ifndef _XILINX_LL_TEMAC_MDIO_ -#define _XILINX_LL_TEMAC_MDIO_ - -#include <net.h> -#include <miiphy.h> - -#include <asm/types.h> -#include <asm/byteorder.h> - -#include "xilinx_ll_temac.h" - -int ll_temac_local_mdio_read(struct temac_reg *regs, int addr, int devad, - int regnum); -void ll_temac_local_mdio_write(struct temac_reg *regs, int addr, int devad, - int regnum, u16 value); - -int ll_temac_phy_read(struct mii_dev *bus, int addr, int devad, int regnum); -int ll_temac_phy_write(struct mii_dev *bus, int addr, int devad, int regnum, - u16 value); - -int ll_temac_phy_addr(struct mii_dev *bus); - -struct ll_temac_mdio_info { - struct temac_reg *regs; - char *name; -}; - -int xilinx_ll_temac_mdio_initialize(bd_t *bis, struct ll_temac_mdio_info *info); - -#endif /* _XILINX_LL_TEMAC_MDIO_ */ diff --git a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_sdma.c b/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_sdma.c deleted file mode 100644 index 32a822eea..000000000 --- a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_sdma.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Xilinx xps_ll_temac ethernet driver for u-boot - * - * SDMA sub-controller - * - * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net> - * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu> - * Copyright (C) 2008 - 2011 PetaLogix - * - * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver - * Copyright (C) 2008 Nissin Systems Co.,Ltd. - * March 2008 created - * - * CREDITS: tsec driver - * - * SPDX-License-Identifier: GPL-2.0+ - * - * [0]: http://www.xilinx.com/support/documentation - * - * [M]: [0]/ip_documentation/mpmc.pdf - * [S]: [0]/ip_documentation/xps_ll_temac.pdf - * [A]: [0]/application_notes/xapp1041.pdf - */ - -#include <config.h> -#include <common.h> -#include <net.h> - -#include <asm/types.h> -#include <asm/io.h> - -#include "xilinx_ll_temac.h" -#include "xilinx_ll_temac_sdma.h" - -#define TX_BUF_CNT 2 - -static unsigned int rx_idx; /* index of the current RX buffer */ -static unsigned int tx_idx; /* index of the current TX buffer */ - -struct rtx_cdmac_bd { - struct cdmac_bd rx[PKTBUFSRX]; - struct cdmac_bd tx[TX_BUF_CNT]; -}; - -/* - * DMA Buffer Descriptor alignment - * - * If the address contained in the Next Descriptor Pointer register is not - * 8-word aligned or reaches beyond the range of available memory, the SDMA - * halts processing and sets the CDMAC_BD_STCTRL_ERROR bit in the respective - * status register (tx_chnl_sts or rx_chnl_sts). - * - * [1]: [0]/ip_documentation/mpmc.pdf - * page 161, Next Descriptor Pointer - */ -static struct rtx_cdmac_bd cdmac_bd __aligned(32); - -#if defined(CONFIG_XILINX_440) || defined(CONFIG_XILINX_405) - -/* - * Indirect DCR access operations mi{ft}dcr_xilinx() espacialy - * for Xilinx PowerPC implementations on FPGA. - * - * FIXME: This part should go up to arch/powerpc -- but where? - */ -#include <asm/processor.h> -#define XILINX_INDIRECT_DCR_ADDRESS_REG 0 -#define XILINX_INDIRECT_DCR_ACCESS_REG 1 -inline unsigned mifdcr_xilinx(const unsigned dcrn) -{ - mtdcr(XILINX_INDIRECT_DCR_ADDRESS_REG, dcrn); - return mfdcr(XILINX_INDIRECT_DCR_ACCESS_REG); -} -inline void mitdcr_xilinx(const unsigned dcrn, int val) -{ - mtdcr(XILINX_INDIRECT_DCR_ADDRESS_REG, dcrn); - mtdcr(XILINX_INDIRECT_DCR_ACCESS_REG, val); -} - -/* Xilinx Device Control Register (DCR) in/out accessors */ -inline unsigned ll_temac_xldcr_in32(phys_addr_t addr) -{ - return mifdcr_xilinx((const unsigned)addr); -} -inline void ll_temac_xldcr_out32(phys_addr_t addr, unsigned value) -{ - mitdcr_xilinx((const unsigned)addr, value); -} - -void ll_temac_collect_xldcr_sdma_reg_addr(struct eth_device *dev) -{ - struct ll_temac *ll_temac = dev->priv; - phys_addr_t dmac_ctrl = ll_temac->ctrladdr; - phys_addr_t *ra = ll_temac->sdma_reg_addr; - - ra[TX_NXTDESC_PTR] = dmac_ctrl + TX_NXTDESC_PTR; - ra[TX_CURBUF_ADDR] = dmac_ctrl + TX_CURBUF_ADDR; - ra[TX_CURBUF_LENGTH] = dmac_ctrl + TX_CURBUF_LENGTH; - ra[TX_CURDESC_PTR] = dmac_ctrl + TX_CURDESC_PTR; - ra[TX_TAILDESC_PTR] = dmac_ctrl + TX_TAILDESC_PTR; - ra[TX_CHNL_CTRL] = dmac_ctrl + TX_CHNL_CTRL; - ra[TX_IRQ_REG] = dmac_ctrl + TX_IRQ_REG; - ra[TX_CHNL_STS] = dmac_ctrl + TX_CHNL_STS; - ra[RX_NXTDESC_PTR] = dmac_ctrl + RX_NXTDESC_PTR; - ra[RX_CURBUF_ADDR] = dmac_ctrl + RX_CURBUF_ADDR; - ra[RX_CURBUF_LENGTH] = dmac_ctrl + RX_CURBUF_LENGTH; - ra[RX_CURDESC_PTR] = dmac_ctrl + RX_CURDESC_PTR; - ra[RX_TAILDESC_PTR] = dmac_ctrl + RX_TAILDESC_PTR; - ra[RX_CHNL_CTRL] = dmac_ctrl + RX_CHNL_CTRL; - ra[RX_IRQ_REG] = dmac_ctrl + RX_IRQ_REG; - ra[RX_CHNL_STS] = dmac_ctrl + RX_CHNL_STS; - ra[DMA_CONTROL_REG] = dmac_ctrl + DMA_CONTROL_REG; -} - -#endif /* CONFIG_XILINX_440 || ONFIG_XILINX_405 */ - -/* Xilinx Processor Local Bus (PLB) in/out accessors */ -inline unsigned ll_temac_xlplb_in32(phys_addr_t addr) -{ - return in_be32((void *)addr); -} -inline void ll_temac_xlplb_out32(phys_addr_t addr, unsigned value) -{ - out_be32((void *)addr, value); -} - -/* collect all register addresses for Xilinx PLB in/out accessors */ -void ll_temac_collect_xlplb_sdma_reg_addr(struct eth_device *dev) -{ - struct ll_temac *ll_temac = dev->priv; - struct sdma_ctrl *sdma_ctrl = (void *)ll_temac->ctrladdr; - phys_addr_t *ra = ll_temac->sdma_reg_addr; - - ra[TX_NXTDESC_PTR] = (phys_addr_t)&sdma_ctrl->tx_nxtdesc_ptr; - ra[TX_CURBUF_ADDR] = (phys_addr_t)&sdma_ctrl->tx_curbuf_addr; - ra[TX_CURBUF_LENGTH] = (phys_addr_t)&sdma_ctrl->tx_curbuf_length; - ra[TX_CURDESC_PTR] = (phys_addr_t)&sdma_ctrl->tx_curdesc_ptr; - ra[TX_TAILDESC_PTR] = (phys_addr_t)&sdma_ctrl->tx_taildesc_ptr; - ra[TX_CHNL_CTRL] = (phys_addr_t)&sdma_ctrl->tx_chnl_ctrl; - ra[TX_IRQ_REG] = (phys_addr_t)&sdma_ctrl->tx_irq_reg; - ra[TX_CHNL_STS] = (phys_addr_t)&sdma_ctrl->tx_chnl_sts; - ra[RX_NXTDESC_PTR] = (phys_addr_t)&sdma_ctrl->rx_nxtdesc_ptr; - ra[RX_CURBUF_ADDR] = (phys_addr_t)&sdma_ctrl->rx_curbuf_addr; - ra[RX_CURBUF_LENGTH] = (phys_addr_t)&sdma_ctrl->rx_curbuf_length; - ra[RX_CURDESC_PTR] = (phys_addr_t)&sdma_ctrl->rx_curdesc_ptr; - ra[RX_TAILDESC_PTR] = (phys_addr_t)&sdma_ctrl->rx_taildesc_ptr; - ra[RX_CHNL_CTRL] = (phys_addr_t)&sdma_ctrl->rx_chnl_ctrl; - ra[RX_IRQ_REG] = (phys_addr_t)&sdma_ctrl->rx_irq_reg; - ra[RX_CHNL_STS] = (phys_addr_t)&sdma_ctrl->rx_chnl_sts; - ra[DMA_CONTROL_REG] = (phys_addr_t)&sdma_ctrl->dma_control_reg; -} - -/* Check for TX and RX channel errors. */ -static inline int ll_temac_sdma_error(struct eth_device *dev) -{ - int err; - struct ll_temac *ll_temac = dev->priv; - phys_addr_t *ra = ll_temac->sdma_reg_addr; - - err = ll_temac->in32(ra[TX_CHNL_STS]) & CHNL_STS_ERROR; - err |= ll_temac->in32(ra[RX_CHNL_STS]) & CHNL_STS_ERROR; - - return err; -} - -int ll_temac_init_sdma(struct eth_device *dev) -{ - struct ll_temac *ll_temac = dev->priv; - struct cdmac_bd *rx_dp; - struct cdmac_bd *tx_dp; - phys_addr_t *ra = ll_temac->sdma_reg_addr; - int i; - - printf("%s: SDMA: %d Rx buffers, %d Tx buffers\n", - dev->name, PKTBUFSRX, TX_BUF_CNT); - - /* Initialize the Rx Buffer descriptors */ - for (i = 0; i < PKTBUFSRX; i++) { - rx_dp = &cdmac_bd.rx[i]; - memset(rx_dp, 0, sizeof(*rx_dp)); - rx_dp->next_p = rx_dp; - rx_dp->buf_len = PKTSIZE_ALIGN; - rx_dp->phys_buf_p = (u8 *)NetRxPackets[i]; - flush_cache((u32)rx_dp->phys_buf_p, PKTSIZE_ALIGN); - } - flush_cache((u32)cdmac_bd.rx, sizeof(cdmac_bd.rx)); - - /* Initialize the TX Buffer Descriptors */ - for (i = 0; i < TX_BUF_CNT; i++) { - tx_dp = &cdmac_bd.tx[i]; - memset(tx_dp, 0, sizeof(*tx_dp)); - tx_dp->next_p = tx_dp; - } - flush_cache((u32)cdmac_bd.tx, sizeof(cdmac_bd.tx)); - - /* Reset index counter to the Rx and Tx Buffer descriptors */ - rx_idx = tx_idx = 0; - - /* initial Rx DMA start by writing to respective TAILDESC_PTR */ - ll_temac->out32(ra[RX_CURDESC_PTR], (int)&cdmac_bd.rx[rx_idx]); - ll_temac->out32(ra[RX_TAILDESC_PTR], (int)&cdmac_bd.rx[rx_idx]); - - return 0; -} - -int ll_temac_halt_sdma(struct eth_device *dev) -{ - unsigned timeout = 50; /* 1usec * 50 = 50usec */ - struct ll_temac *ll_temac = dev->priv; - phys_addr_t *ra = ll_temac->sdma_reg_addr; - - /* - * Soft reset the DMA - * - * Quote from MPMC documentation: Writing a 1 to this field - * forces the DMA engine to shutdown and reset itself. After - * setting this bit, software must poll it until the bit is - * cleared by the DMA. This indicates that the reset process - * is done and the pipeline has been flushed. - */ - ll_temac->out32(ra[DMA_CONTROL_REG], DMA_CONTROL_RESET); - while (timeout && (ll_temac->in32(ra[DMA_CONTROL_REG]) - & DMA_CONTROL_RESET)) { - timeout--; - udelay(1); - } - - if (!timeout) { - printf("%s: Timeout\n", __func__); - return -1; - } - - return 0; -} - -int ll_temac_reset_sdma(struct eth_device *dev) -{ - u32 r; - struct ll_temac *ll_temac = dev->priv; - phys_addr_t *ra = ll_temac->sdma_reg_addr; - - /* Soft reset the DMA. */ - if (ll_temac_halt_sdma(dev)) - return -1; - - /* Now clear the interrupts. */ - r = ll_temac->in32(ra[TX_CHNL_CTRL]); - r &= ~CHNL_CTRL_IRQ_MASK; - ll_temac->out32(ra[TX_CHNL_CTRL], r); - - r = ll_temac->in32(ra[RX_CHNL_CTRL]); - r &= ~CHNL_CTRL_IRQ_MASK; - ll_temac->out32(ra[RX_CHNL_CTRL], r); - - /* Now ACK pending IRQs. */ - ll_temac->out32(ra[TX_IRQ_REG], IRQ_REG_IRQ_MASK); - ll_temac->out32(ra[RX_IRQ_REG], IRQ_REG_IRQ_MASK); - - /* Set tail-ptr mode, disable errors for both channels. */ - ll_temac->out32(ra[DMA_CONTROL_REG], - /* Enable use of tail pointer register */ - DMA_CONTROL_TPE | - /* Disable error when 2 or 4 bit coalesce cnt overfl */ - DMA_CONTROL_RXOCEID | - /* Disable error when 2 or 4 bit coalesce cnt overfl */ - DMA_CONTROL_TXOCEID); - - return 0; -} - -int ll_temac_recv_sdma(struct eth_device *dev) -{ - int length, pb_idx; - struct cdmac_bd *rx_dp = &cdmac_bd.rx[rx_idx]; - struct ll_temac *ll_temac = dev->priv; - phys_addr_t *ra = ll_temac->sdma_reg_addr; - - if (ll_temac_sdma_error(dev)) { - - if (ll_temac_reset_sdma(dev)) - return -1; - - ll_temac_init_sdma(dev); - } - - flush_cache((u32)rx_dp, sizeof(*rx_dp)); - - if (!(rx_dp->sca.stctrl & CDMAC_BD_STCTRL_COMPLETED)) - return 0; - - if (rx_dp->sca.stctrl & (CDMAC_BD_STCTRL_SOP | CDMAC_BD_STCTRL_EOP)) { - pb_idx = rx_idx; - length = rx_dp->sca.app[4] & CDMAC_BD_APP4_RXBYTECNT_MASK; - } else { - pb_idx = -1; - length = 0; - printf("%s: Got part of package, unsupported (%x)\n", - __func__, rx_dp->sca.stctrl); - } - - /* flip the buffer */ - flush_cache((u32)rx_dp->phys_buf_p, length); - - /* reset the current descriptor */ - rx_dp->sca.stctrl = 0; - rx_dp->sca.app[4] = 0; - flush_cache((u32)rx_dp, sizeof(*rx_dp)); - - /* Find next empty buffer descriptor, preparation for next iteration */ - rx_idx = (rx_idx + 1) % PKTBUFSRX; - rx_dp = &cdmac_bd.rx[rx_idx]; - flush_cache((u32)rx_dp, sizeof(*rx_dp)); - - /* DMA start by writing to respective TAILDESC_PTR */ - ll_temac->out32(ra[RX_CURDESC_PTR], (int)&cdmac_bd.rx[rx_idx]); - ll_temac->out32(ra[RX_TAILDESC_PTR], (int)&cdmac_bd.rx[rx_idx]); - - if (length > 0 && pb_idx != -1) - NetReceive(NetRxPackets[pb_idx], length); - - return 0; -} - -int ll_temac_send_sdma(struct eth_device *dev, void *packet, int length) -{ - unsigned timeout = 50; /* 1usec * 50 = 50usec */ - struct cdmac_bd *tx_dp = &cdmac_bd.tx[tx_idx]; - struct ll_temac *ll_temac = dev->priv; - phys_addr_t *ra = ll_temac->sdma_reg_addr; - - if (ll_temac_sdma_error(dev)) { - - if (ll_temac_reset_sdma(dev)) - return -1; - - ll_temac_init_sdma(dev); - } - - tx_dp->phys_buf_p = (u8 *)packet; - tx_dp->buf_len = length; - tx_dp->sca.stctrl = CDMAC_BD_STCTRL_SOP | CDMAC_BD_STCTRL_EOP | - CDMAC_BD_STCTRL_STOP_ON_END; - - flush_cache((u32)packet, length); - flush_cache((u32)tx_dp, sizeof(*tx_dp)); - - /* DMA start by writing to respective TAILDESC_PTR */ - ll_temac->out32(ra[TX_CURDESC_PTR], (int)tx_dp); - ll_temac->out32(ra[TX_TAILDESC_PTR], (int)tx_dp); - - /* Find next empty buffer descriptor, preparation for next iteration */ - tx_idx = (tx_idx + 1) % TX_BUF_CNT; - tx_dp = &cdmac_bd.tx[tx_idx]; - - do { - flush_cache((u32)tx_dp, sizeof(*tx_dp)); - udelay(1); - } while (timeout-- && !(tx_dp->sca.stctrl & CDMAC_BD_STCTRL_COMPLETED)); - - if (!timeout) { - printf("%s: Timeout\n", __func__); - return -1; - } - - return 0; -} diff --git a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_sdma.h b/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_sdma.h deleted file mode 100644 index 41659c0ee..000000000 --- a/qemu/roms/u-boot/drivers/net/xilinx_ll_temac_sdma.h +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Xilinx xps_ll_temac ethernet driver for u-boot - * - * SDMA sub-controller interface - * - * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net> - * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu> - * Copyright (C) 2008 - 2011 PetaLogix - * - * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver - * Copyright (C) 2008 Nissin Systems Co.,Ltd. - * March 2008 created - * - * SPDX-License-Identifier: GPL-2.0+ - * - * [0]: http://www.xilinx.com/support/documentation - * - * [S]: [0]/ip_documentation/xps_ll_temac.pdf - * [A]: [0]/application_notes/xapp1041.pdf - */ -#ifndef _XILINX_LL_TEMAC_SDMA_ -#define _XILINX_LL_TEMAC_SDMA_ - -#include <net.h> - -#include <asm/types.h> -#include <asm/byteorder.h> - -#include <linux/compiler.h> - -#if !defined(__BIG_ENDIAN) -# error LL_TEMAC requires big endianess -#endif - -/* - * DMA Buffer Descriptor for CDMAC - * - * Used for data connection from and to (Rx/Tx) the LocalLink (LL) TEMAC via - * the Communications Direct Memory Access Controller (CDMAC) -- one for each. - * - * overview: - * ftp://ftp.xilinx.com/pub/documentation/misc/mpmc_getting_started.pdf - * - * [1]: [0]/ip_documentation/mpmc.pdf - * page 140, DMA Operation Descriptors - * - * [2]: [0]/user_guides/ug200.pdf - * page 229, DMA Controller -- Descriptor Format - * - * [3]: [0]/ip_documentation/xps_ll_temac.pdf - * page 72, Transmit LocalLink Frame Format - * page 73, Receive LocalLink Frame Format - */ -struct cdmac_bd { - struct cdmac_bd *next_p; /* Next Descriptor Pointer */ - u8 *phys_buf_p; /* Buffer Address */ - u32 buf_len; /* Buffer Length */ - union { - u8 stctrl; /* Status/Control the DMA transfer */ - u32 app[5]; /* application specific data */ - } __packed __aligned(1) sca; -}; - -/* CDMAC Descriptor Status and Control (stctrl), [1] p140, [2] p230 */ -#define CDMAC_BD_STCTRL_ERROR (1 << 7) -#define CDMAC_BD_STCTRL_IRQ_ON_END (1 << 6) -#define CDMAC_BD_STCTRL_STOP_ON_END (1 << 5) -#define CDMAC_BD_STCTRL_COMPLETED (1 << 4) -#define CDMAC_BD_STCTRL_SOP (1 << 3) -#define CDMAC_BD_STCTRL_EOP (1 << 2) -#define CDMAC_BD_STCTRL_DMACHBUSY (1 << 1) - -/* CDMAC Descriptor APP0: Transmit LocalLink Footer Word 3, [3] p72 */ -#define CDMAC_BD_APP0_TXCSCNTRL (1 << 0) - -/* CDMAC Descriptor APP1: Transmit LocalLink Footer Word 4, [3] p73 */ -#define CDMAC_BD_APP1_TXCSBEGIN_POS 16 -#define CDMAC_BD_APP1_TXCSBEGIN_MASK (0xFFFF << CDMAC_BD_APP1_TXCSBEGIN_POS) -#define CDMAC_BD_APP1_TXCSINSERT_POS 0 -#define CDMAC_BD_APP1_TXCSINSERT_MASK (0xFFFF << CDMAC_BD_APP1_TXCSINSERT_POS) - -/* CDMAC Descriptor APP2: Transmit LocalLink Footer Word 5, [3] p73 */ -#define CDMAC_BD_APP2_TXCSINIT_POS 0 -#define CDMAC_BD_APP2_TXCSINIT_MASK (0xFFFF << CDMAC_BD_APP2_TXCSINIT_POS) - -/* CDMAC Descriptor APP0: Receive LocalLink Footer Word 3, [3] p73 */ -#define CDMAC_BD_APP0_MADDRU_POS 0 -#define CDMAC_BD_APP0_MADDRU_MASK (0xFFFF << CDMAC_BD_APP0_MADDRU_POS) - -/* CDMAC Descriptor APP1: Receive LocalLink Footer Word 4, [3] p74 */ -#define CDMAC_BD_APP1_MADDRL_POS 0 -#define CDMAC_BD_APP1_MADDRL_MASK (~0UL << CDMAC_BD_APP1_MADDRL_POS) - -/* CDMAC Descriptor APP2: Receive LocalLink Footer Word 5, [3] p74 */ -#define CDMAC_BD_APP2_BCAST_FRAME (1 << 2) -#define CDMAC_BD_APP2_IPC_MCAST_FRAME (1 << 1) -#define CDMAC_BD_APP2_MAC_MCAST_FRAME (1 << 0) - -/* CDMAC Descriptor APP3: Receive LocalLink Footer Word 6, [3] p74 */ -#define CDMAC_BD_APP3_TLTPID_POS 16 -#define CDMAC_BD_APP3_TLTPID_MASK (0xFFFF << CDMAC_BD_APP3_TLTPID_POS) -#define CDMAC_BD_APP3_RXCSRAW_POS 0 -#define CDMAC_BD_APP3_RXCSRAW_MASK (0xFFFF << CDMAC_BD_APP3_RXCSRAW_POS) - -/* CDMAC Descriptor APP4: Receive LocalLink Footer Word 7, [3] p74 */ -#define CDMAC_BD_APP4_VLANTAG_POS 16 -#define CDMAC_BD_APP4_VLANTAG_MASK (0xFFFF << CDMAC_BD_APP4_VLANTAG_POS) -#define CDMAC_BD_APP4_RXBYTECNT_POS 0 -#define CDMAC_BD_APP4_RXBYTECNT_MASK (0x3FFF << CDMAC_BD_APP4_RXBYTECNT_POS) - -/* - * SDMA Register Definition - * - * [0]: http://www.xilinx.com/support/documentation - * - * [1]: [0]/ip_documentation/mpmc.pdf - * page 54, SDMA Register Summary - * page 160, SDMA Registers - * - * [2]: [0]/user_guides/ug200.pdf - * page 244, DMA Controller -- Programming Interface and Registers - */ -#define SDMA_CTRL_REGTYPE u32 -#define SDMA_CTRL_REGSIZE sizeof(SDMA_CTRL_REGTYPE) -struct sdma_ctrl { - /* Transmit Registers */ - SDMA_CTRL_REGTYPE tx_nxtdesc_ptr; /* TX Next Description Pointer */ - SDMA_CTRL_REGTYPE tx_curbuf_addr; /* TX Current Buffer Address */ - SDMA_CTRL_REGTYPE tx_curbuf_length; /* TX Current Buffer Length */ - SDMA_CTRL_REGTYPE tx_curdesc_ptr; /* TX Current Descriptor Pointer */ - SDMA_CTRL_REGTYPE tx_taildesc_ptr; /* TX Tail Descriptor Pointer */ - SDMA_CTRL_REGTYPE tx_chnl_ctrl; /* TX Channel Control */ - SDMA_CTRL_REGTYPE tx_irq_reg; /* TX Interrupt Register */ - SDMA_CTRL_REGTYPE tx_chnl_sts; /* TX Status Register */ - /* Receive Registers */ - SDMA_CTRL_REGTYPE rx_nxtdesc_ptr; /* RX Next Descriptor Pointer */ - SDMA_CTRL_REGTYPE rx_curbuf_addr; /* RX Current Buffer Address */ - SDMA_CTRL_REGTYPE rx_curbuf_length; /* RX Current Buffer Length */ - SDMA_CTRL_REGTYPE rx_curdesc_ptr; /* RX Current Descriptor Pointer */ - SDMA_CTRL_REGTYPE rx_taildesc_ptr; /* RX Tail Descriptor Pointer */ - SDMA_CTRL_REGTYPE rx_chnl_ctrl; /* RX Channel Control */ - SDMA_CTRL_REGTYPE rx_irq_reg; /* RX Interrupt Register */ - SDMA_CTRL_REGTYPE rx_chnl_sts; /* RX Status Register */ - /* Control Registers */ - SDMA_CTRL_REGTYPE dma_control_reg; /* DMA Control Register */ -}; - -#define SDMA_CTRL_REGNUMS sizeof(struct sdma_ctrl)/SDMA_CTRL_REGSIZE - -/* - * DMAC Register Index Enumeration - * - * [2]: http://www.xilinx.com/support/documentation/user_guides/ug200.pdf - * page 244, DMA Controller -- Programming Interface and Registers - */ -enum dmac_ctrl { - /* Transmit Registers */ - TX_NXTDESC_PTR = 0, /* TX Next Description Pointer */ - TX_CURBUF_ADDR, /* TX Current Buffer Address */ - TX_CURBUF_LENGTH, /* TX Current Buffer Length */ - TX_CURDESC_PTR, /* TX Current Descriptor Pointer */ - TX_TAILDESC_PTR, /* TX Tail Descriptor Pointer */ - TX_CHNL_CTRL, /* TX Channel Control */ - TX_IRQ_REG, /* TX Interrupt Register */ - TX_CHNL_STS, /* TX Status Register */ - /* Receive Registers */ - RX_NXTDESC_PTR, /* RX Next Descriptor Pointer */ - RX_CURBUF_ADDR, /* RX Current Buffer Address */ - RX_CURBUF_LENGTH, /* RX Current Buffer Length */ - RX_CURDESC_PTR, /* RX Current Descriptor Pointer */ - RX_TAILDESC_PTR, /* RX Tail Descriptor Pointer */ - RX_CHNL_CTRL, /* RX Channel Control */ - RX_IRQ_REG, /* RX Interrupt Register */ - RX_CHNL_STS, /* RX Status Register */ - /* Control Registers */ - DMA_CONTROL_REG /* DMA Control Register */ -}; - -/* Rx/Tx Channel Control Register (*_chnl_ctrl), [1] p163, [2] p246/p252 */ -#define CHNL_CTRL_ITO_POS 24 -#define CHNL_CTRL_ITO_MASK (0xFF << CHNL_CTRL_ITO_POS) -#define CHNL_CTRL_IC_POS 16 -#define CHNL_CTRL_IC_MASK (0xFF << CHNL_CTRL_IC_POS) -#define CHNL_CTRL_MSBADDR_POS 12 -#define CHNL_CTRL_MSBADDR_MASK (0xF << CHNL_CTRL_MSBADDR_POS) -#define CHNL_CTRL_AME (1 << 11) -#define CHNL_CTRL_OBWC (1 << 10) -#define CHNL_CTRL_IOE (1 << 9) -#define CHNL_CTRL_LIC (1 << 8) -#define CHNL_CTRL_IE (1 << 7) -#define CHNL_CTRL_IEE (1 << 2) -#define CHNL_CTRL_IDE (1 << 1) -#define CHNL_CTRL_ICE (1 << 0) - -/* All interrupt enable bits */ -#define CHNL_CTRL_IRQ_MASK (CHNL_CTRL_IE | \ - CHNL_CTRL_IEE | \ - CHNL_CTRL_IDE | \ - CHNL_CTRL_ICE) - -/* Rx/Tx Interrupt Status Register (*_irq_reg), [1] p164, [2] p247/p253 */ -#define IRQ_REG_DTV_POS 24 -#define IRQ_REG_DTV_MASK (0xFF << IRQ_REG_DTV_POS) -#define IRQ_REG_CCV_POS 16 -#define IRQ_REG_CCV_MASK (0xFF << IRQ_REG_CCV_POS) -#define IRQ_REG_WRCQ_EMPTY (1 << 14) -#define IRQ_REG_CIC_POS 10 -#define IRQ_REG_CIC_MASK (0xF << IRQ_REG_CIC_POS) -#define IRQ_REG_DIC_POS 8 -#define IRQ_REG_DIC_MASK (3 << 8) -#define IRQ_REG_PLB_RD_NMI (1 << 4) -#define IRQ_REG_PLB_WR_NMI (1 << 3) -#define IRQ_REG_EI (1 << 2) -#define IRQ_REG_DI (1 << 1) -#define IRQ_REG_CI (1 << 0) - -/* All interrupt bits */ -#define IRQ_REG_IRQ_MASK (IRQ_REG_PLB_RD_NMI | \ - IRQ_REG_PLB_WR_NMI | \ - IRQ_REG_EI | IRQ_REG_DI | IRQ_REG_CI) - -/* Rx/Tx Channel Status Register (*_chnl_sts), [1] p165, [2] p249/p255 */ -#define CHNL_STS_ERROR_TAIL (1 << 21) -#define CHNL_STS_ERROR_CMP (1 << 20) -#define CHNL_STS_ERROR_ADDR (1 << 19) -#define CHNL_STS_ERROR_NXTP (1 << 18) -#define CHNL_STS_ERROR_CURP (1 << 17) -#define CHNL_STS_ERROR_BSYWR (1 << 16) -#define CHNL_STS_ERROR (1 << 7) -#define CHNL_STS_IOE (1 << 6) -#define CHNL_STS_SOE (1 << 5) -#define CHNL_STS_CMPLT (1 << 4) -#define CHNL_STS_SOP (1 << 3) -#define CHNL_STS_EOP (1 << 2) -#define CHNL_STS_EBUSY (1 << 1) - -/* DMA Control Register (dma_control_reg), [1] p166, [2] p256 */ -#define DMA_CONTROL_PLBED (1 << 5) -#define DMA_CONTROL_RXOCEID (1 << 4) -#define DMA_CONTROL_TXOCEID (1 << 3) -#define DMA_CONTROL_TPE (1 << 2) -#define DMA_CONTROL_RESET (1 << 0) - -#if defined(CONFIG_XILINX_440) || defined(CONFIG_XILINX_405) - -/* Xilinx Device Control Register (DCR) in/out accessors */ -unsigned ll_temac_xldcr_in32(phys_addr_t addr); -void ll_temac_xldcr_out32(phys_addr_t addr, unsigned value); - -/* collect all register addresses for Xilinx DCR in/out accessors */ -void ll_temac_collect_xldcr_sdma_reg_addr(struct eth_device *dev); - -#endif /* CONFIG_XILINX_440 || CONFIG_XILINX_405 */ - -/* Xilinx Processor Local Bus (PLB) in/out accessors */ -unsigned ll_temac_xlplb_in32(phys_addr_t base); -void ll_temac_xlplb_out32(phys_addr_t base, unsigned value); - -/* collect all register addresses for Xilinx PLB in/out accessors */ -void ll_temac_collect_xlplb_sdma_reg_addr(struct eth_device *dev); - -/* initialize both Rx/Tx buffer descriptors */ -int ll_temac_init_sdma(struct eth_device *dev); - -/* halt both Rx/Tx transfers */ -int ll_temac_halt_sdma(struct eth_device *dev); - -/* reset SDMA and IRQ, disable interrupts and errors */ -int ll_temac_reset_sdma(struct eth_device *dev); - -/* receive buffered data from SDMA (polling ISR) */ -int ll_temac_recv_sdma(struct eth_device *dev); - -/* send buffered data to SDMA */ -int ll_temac_send_sdma(struct eth_device *dev, void *packet, int length); - -#endif /* _XILINX_LL_TEMAC_SDMA_ */ diff --git a/qemu/roms/u-boot/drivers/net/zynq_gem.c b/qemu/roms/u-boot/drivers/net/zynq_gem.c deleted file mode 100644 index 3cadd23bb..000000000 --- a/qemu/roms/u-boot/drivers/net/zynq_gem.c +++ /dev/null @@ -1,580 +0,0 @@ -/* - * (C) Copyright 2011 Michal Simek - * - * Michal SIMEK <monstr@monstr.eu> - * - * Based on Xilinx gmac driver: - * (C) Copyright 2011 Xilinx - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <net.h> -#include <netdev.h> -#include <config.h> -#include <fdtdec.h> -#include <libfdt.h> -#include <malloc.h> -#include <asm/io.h> -#include <phy.h> -#include <miiphy.h> -#include <watchdog.h> -#include <asm/arch/hardware.h> -#include <asm/arch/sys_proto.h> - -#if !defined(CONFIG_PHYLIB) -# error XILINX_GEM_ETHERNET requires PHYLIB -#endif - -/* Bit/mask specification */ -#define ZYNQ_GEM_PHYMNTNC_OP_MASK 0x40020000 /* operation mask bits */ -#define ZYNQ_GEM_PHYMNTNC_OP_R_MASK 0x20000000 /* read operation */ -#define ZYNQ_GEM_PHYMNTNC_OP_W_MASK 0x10000000 /* write operation */ -#define ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK 23 /* Shift bits for PHYAD */ -#define ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK 18 /* Shift bits for PHREG */ - -#define ZYNQ_GEM_RXBUF_EOF_MASK 0x00008000 /* End of frame. */ -#define ZYNQ_GEM_RXBUF_SOF_MASK 0x00004000 /* Start of frame. */ -#define ZYNQ_GEM_RXBUF_LEN_MASK 0x00003FFF /* Mask for length field */ - -#define ZYNQ_GEM_RXBUF_WRAP_MASK 0x00000002 /* Wrap bit, last BD */ -#define ZYNQ_GEM_RXBUF_NEW_MASK 0x00000001 /* Used bit.. */ -#define ZYNQ_GEM_RXBUF_ADD_MASK 0xFFFFFFFC /* Mask for address */ - -/* Wrap bit, last descriptor */ -#define ZYNQ_GEM_TXBUF_WRAP_MASK 0x40000000 -#define ZYNQ_GEM_TXBUF_LAST_MASK 0x00008000 /* Last buffer */ - -#define ZYNQ_GEM_NWCTRL_TXEN_MASK 0x00000008 /* Enable transmit */ -#define ZYNQ_GEM_NWCTRL_RXEN_MASK 0x00000004 /* Enable receive */ -#define ZYNQ_GEM_NWCTRL_MDEN_MASK 0x00000010 /* Enable MDIO port */ -#define ZYNQ_GEM_NWCTRL_STARTTX_MASK 0x00000200 /* Start tx (tx_go) */ - -#define ZYNQ_GEM_NWCFG_SPEED100 0x000000001 /* 100 Mbps operation */ -#define ZYNQ_GEM_NWCFG_SPEED1000 0x000000400 /* 1Gbps operation */ -#define ZYNQ_GEM_NWCFG_FDEN 0x000000002 /* Full Duplex mode */ -#define ZYNQ_GEM_NWCFG_FSREM 0x000020000 /* FCS removal */ -#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x000080000 /* Div pclk by 32, 80MHz */ -#define ZYNQ_GEM_NWCFG_MDCCLKDIV2 0x0000c0000 /* Div pclk by 48, 120MHz */ - -#define ZYNQ_GEM_NWCFG_INIT (ZYNQ_GEM_NWCFG_FDEN | \ - ZYNQ_GEM_NWCFG_FSREM | \ - ZYNQ_GEM_NWCFG_MDCCLKDIV) - -#define ZYNQ_GEM_NWSR_MDIOIDLE_MASK 0x00000004 /* PHY management idle */ - -#define ZYNQ_GEM_DMACR_BLENGTH 0x00000004 /* INCR4 AHB bursts */ -/* Use full configured addressable space (8 Kb) */ -#define ZYNQ_GEM_DMACR_RXSIZE 0x00000300 -/* Use full configured addressable space (4 Kb) */ -#define ZYNQ_GEM_DMACR_TXSIZE 0x00000400 -/* Set with binary 00011000 to use 1536 byte(1*max length frame/buffer) */ -#define ZYNQ_GEM_DMACR_RXBUF 0x00180000 - -#define ZYNQ_GEM_DMACR_INIT (ZYNQ_GEM_DMACR_BLENGTH | \ - ZYNQ_GEM_DMACR_RXSIZE | \ - ZYNQ_GEM_DMACR_TXSIZE | \ - ZYNQ_GEM_DMACR_RXBUF) - -/* Use MII register 1 (MII status register) to detect PHY */ -#define PHY_DETECT_REG 1 - -/* Mask used to verify certain PHY features (or register contents) - * in the register above: - * 0x1000: 10Mbps full duplex support - * 0x0800: 10Mbps half duplex support - * 0x0008: Auto-negotiation support - */ -#define PHY_DETECT_MASK 0x1808 - -/* TX BD status masks */ -#define ZYNQ_GEM_TXBUF_FRMLEN_MASK 0x000007ff -#define ZYNQ_GEM_TXBUF_EXHAUSTED 0x08000000 -#define ZYNQ_GEM_TXBUF_UNDERRUN 0x10000000 - -/* Clock frequencies for different speeds */ -#define ZYNQ_GEM_FREQUENCY_10 2500000UL -#define ZYNQ_GEM_FREQUENCY_100 25000000UL -#define ZYNQ_GEM_FREQUENCY_1000 125000000UL - -/* Device registers */ -struct zynq_gem_regs { - u32 nwctrl; /* Network Control reg */ - u32 nwcfg; /* Network Config reg */ - u32 nwsr; /* Network Status reg */ - u32 reserved1; - u32 dmacr; /* DMA Control reg */ - u32 txsr; /* TX Status reg */ - u32 rxqbase; /* RX Q Base address reg */ - u32 txqbase; /* TX Q Base address reg */ - u32 rxsr; /* RX Status reg */ - u32 reserved2[2]; - u32 idr; /* Interrupt Disable reg */ - u32 reserved3; - u32 phymntnc; /* Phy Maintaince reg */ - u32 reserved4[18]; - u32 hashl; /* Hash Low address reg */ - u32 hashh; /* Hash High address reg */ -#define LADDR_LOW 0 -#define LADDR_HIGH 1 - u32 laddr[4][LADDR_HIGH + 1]; /* Specific1 addr low/high reg */ - u32 match[4]; /* Type ID1 Match reg */ - u32 reserved6[18]; - u32 stat[44]; /* Octects transmitted Low reg - stat start */ -}; - -/* BD descriptors */ -struct emac_bd { - u32 addr; /* Next descriptor pointer */ - u32 status; -}; - -#define RX_BUF 3 -/* Page table entries are set to 1MB, or multiples of 1MB - * (not < 1MB). driver uses less bd's so use 1MB bdspace. - */ -#define BD_SPACE 0x100000 -/* BD separation space */ -#define BD_SEPRN_SPACE 64 - -/* Initialized, rxbd_current, rx_first_buf must be 0 after init */ -struct zynq_gem_priv { - struct emac_bd *tx_bd; - struct emac_bd *rx_bd; - char *rxbuffers; - u32 rxbd_current; - u32 rx_first_buf; - int phyaddr; - u32 emio; - int init; - struct phy_device *phydev; - struct mii_dev *bus; -}; - -static inline int mdio_wait(struct eth_device *dev) -{ - struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; - u32 timeout = 200; - - /* Wait till MDIO interface is ready to accept a new transaction. */ - while (--timeout) { - if (readl(®s->nwsr) & ZYNQ_GEM_NWSR_MDIOIDLE_MASK) - break; - WATCHDOG_RESET(); - } - - if (!timeout) { - printf("%s: Timeout\n", __func__); - return 1; - } - - return 0; -} - -static u32 phy_setup_op(struct eth_device *dev, u32 phy_addr, u32 regnum, - u32 op, u16 *data) -{ - u32 mgtcr; - struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; - - if (mdio_wait(dev)) - return 1; - - /* Construct mgtcr mask for the operation */ - mgtcr = ZYNQ_GEM_PHYMNTNC_OP_MASK | op | - (phy_addr << ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK) | - (regnum << ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK) | *data; - - /* Write mgtcr and wait for completion */ - writel(mgtcr, ®s->phymntnc); - - if (mdio_wait(dev)) - return 1; - - if (op == ZYNQ_GEM_PHYMNTNC_OP_R_MASK) - *data = readl(®s->phymntnc); - - return 0; -} - -static u32 phyread(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 *val) -{ - return phy_setup_op(dev, phy_addr, regnum, - ZYNQ_GEM_PHYMNTNC_OP_R_MASK, val); -} - -static u32 phywrite(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 data) -{ - return phy_setup_op(dev, phy_addr, regnum, - ZYNQ_GEM_PHYMNTNC_OP_W_MASK, &data); -} - -static void phy_detection(struct eth_device *dev) -{ - int i; - u16 phyreg; - struct zynq_gem_priv *priv = dev->priv; - - if (priv->phyaddr != -1) { - phyread(dev, priv->phyaddr, PHY_DETECT_REG, &phyreg); - if ((phyreg != 0xFFFF) && - ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { - /* Found a valid PHY address */ - debug("Default phy address %d is valid\n", - priv->phyaddr); - return; - } else { - debug("PHY address is not setup correctly %d\n", - priv->phyaddr); - priv->phyaddr = -1; - } - } - - debug("detecting phy address\n"); - if (priv->phyaddr == -1) { - /* detect the PHY address */ - for (i = 31; i >= 0; i--) { - phyread(dev, i, PHY_DETECT_REG, &phyreg); - if ((phyreg != 0xFFFF) && - ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { - /* Found a valid PHY address */ - priv->phyaddr = i; - debug("Found valid phy address, %d\n", i); - return; - } - } - } - printf("PHY is not detected\n"); -} - -static int zynq_gem_setup_mac(struct eth_device *dev) -{ - u32 i, macaddrlow, macaddrhigh; - struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; - - /* Set the MAC bits [31:0] in BOT */ - macaddrlow = dev->enetaddr[0]; - macaddrlow |= dev->enetaddr[1] << 8; - macaddrlow |= dev->enetaddr[2] << 16; - macaddrlow |= dev->enetaddr[3] << 24; - - /* Set MAC bits [47:32] in TOP */ - macaddrhigh = dev->enetaddr[4]; - macaddrhigh |= dev->enetaddr[5] << 8; - - for (i = 0; i < 4; i++) { - writel(0, ®s->laddr[i][LADDR_LOW]); - writel(0, ®s->laddr[i][LADDR_HIGH]); - /* Do not use MATCHx register */ - writel(0, ®s->match[i]); - } - - writel(macaddrlow, ®s->laddr[0][LADDR_LOW]); - writel(macaddrhigh, ®s->laddr[0][LADDR_HIGH]); - - return 0; -} - -static int zynq_gem_init(struct eth_device *dev, bd_t * bis) -{ - u32 i; - unsigned long clk_rate = 0; - struct phy_device *phydev; - const u32 stat_size = (sizeof(struct zynq_gem_regs) - - offsetof(struct zynq_gem_regs, stat)) / 4; - struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; - struct zynq_gem_priv *priv = dev->priv; - const u32 supported = SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full; - - if (!priv->init) { - /* Disable all interrupts */ - writel(0xFFFFFFFF, ®s->idr); - - /* Disable the receiver & transmitter */ - writel(0, ®s->nwctrl); - writel(0, ®s->txsr); - writel(0, ®s->rxsr); - writel(0, ®s->phymntnc); - - /* Clear the Hash registers for the mac address - * pointed by AddressPtr - */ - writel(0x0, ®s->hashl); - /* Write bits [63:32] in TOP */ - writel(0x0, ®s->hashh); - - /* Clear all counters */ - for (i = 0; i <= stat_size; i++) - readl(®s->stat[i]); - - /* Setup RxBD space */ - memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd)); - - for (i = 0; i < RX_BUF; i++) { - priv->rx_bd[i].status = 0xF0000000; - priv->rx_bd[i].addr = - ((u32)(priv->rxbuffers) + - (i * PKTSIZE_ALIGN)); - } - /* WRAP bit to last BD */ - priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK; - /* Write RxBDs to IP */ - writel((u32)priv->rx_bd, ®s->rxqbase); - - /* Setup for DMA Configuration register */ - writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); - - /* Setup for Network Control register, MDIO, Rx and Tx enable */ - setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK); - - priv->init++; - } - - phy_detection(dev); - - /* interface - look at tsec */ - phydev = phy_connect(priv->bus, priv->phyaddr, dev, - PHY_INTERFACE_MODE_MII); - - phydev->supported = supported | ADVERTISED_Pause | - ADVERTISED_Asym_Pause; - phydev->advertising = phydev->supported; - priv->phydev = phydev; - phy_config(phydev); - phy_startup(phydev); - - if (!phydev->link) { - printf("%s: No link.\n", phydev->dev->name); - return -1; - } - - switch (phydev->speed) { - case SPEED_1000: - writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED1000, - ®s->nwcfg); - clk_rate = ZYNQ_GEM_FREQUENCY_1000; - break; - case SPEED_100: - clrsetbits_le32(®s->nwcfg, ZYNQ_GEM_NWCFG_SPEED1000, - ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED100); - clk_rate = ZYNQ_GEM_FREQUENCY_100; - break; - case SPEED_10: - clk_rate = ZYNQ_GEM_FREQUENCY_10; - break; - } - - /* Change the rclk and clk only not using EMIO interface */ - if (!priv->emio) - zynq_slcr_gem_clk_setup(dev->iobase != - ZYNQ_GEM_BASEADDR0, clk_rate); - - setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK | - ZYNQ_GEM_NWCTRL_TXEN_MASK); - - return 0; -} - -static int zynq_gem_send(struct eth_device *dev, void *ptr, int len) -{ - u32 addr, size; - struct zynq_gem_priv *priv = dev->priv; - struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; - - /* setup BD */ - writel((u32)priv->tx_bd, ®s->txqbase); - - /* Setup Tx BD */ - memset(priv->tx_bd, 0, sizeof(struct emac_bd)); - - priv->tx_bd->addr = (u32)ptr; - priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) | - ZYNQ_GEM_TXBUF_LAST_MASK; - - addr = (u32) ptr; - addr &= ~(ARCH_DMA_MINALIGN - 1); - size = roundup(len, ARCH_DMA_MINALIGN); - flush_dcache_range(addr, addr + size); - barrier(); - - /* Start transmit */ - setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK); - - /* Read TX BD status */ - if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_UNDERRUN) - printf("TX underrun\n"); - if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_EXHAUSTED) - printf("TX buffers exhausted in mid frame\n"); - - return 0; -} - -/* Do not check frame_recd flag in rx_status register 0x20 - just poll BD */ -static int zynq_gem_recv(struct eth_device *dev) -{ - int frame_len; - struct zynq_gem_priv *priv = dev->priv; - struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current]; - struct emac_bd *first_bd; - - if (!(current_bd->addr & ZYNQ_GEM_RXBUF_NEW_MASK)) - return 0; - - if (!(current_bd->status & - (ZYNQ_GEM_RXBUF_SOF_MASK | ZYNQ_GEM_RXBUF_EOF_MASK))) { - printf("GEM: SOF or EOF not set for last buffer received!\n"); - return 0; - } - - frame_len = current_bd->status & ZYNQ_GEM_RXBUF_LEN_MASK; - if (frame_len) { - u32 addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK; - addr &= ~(ARCH_DMA_MINALIGN - 1); - u32 size = roundup(frame_len, ARCH_DMA_MINALIGN); - invalidate_dcache_range(addr, addr + size); - - NetReceive((u8 *)addr, frame_len); - - if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK) - priv->rx_first_buf = priv->rxbd_current; - else { - current_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK; - current_bd->status = 0xF0000000; /* FIXME */ - } - - if (current_bd->status & ZYNQ_GEM_RXBUF_EOF_MASK) { - first_bd = &priv->rx_bd[priv->rx_first_buf]; - first_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK; - first_bd->status = 0xF0000000; - } - - if ((++priv->rxbd_current) >= RX_BUF) - priv->rxbd_current = 0; - } - - return frame_len; -} - -static void zynq_gem_halt(struct eth_device *dev) -{ - struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; - - clrsetbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK | - ZYNQ_GEM_NWCTRL_TXEN_MASK, 0); -} - -static int zynq_gem_miiphyread(const char *devname, uchar addr, - uchar reg, ushort *val) -{ - struct eth_device *dev = eth_get_dev(); - int ret; - - ret = phyread(dev, addr, reg, val); - debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, *val); - return ret; -} - -static int zynq_gem_miiphy_write(const char *devname, uchar addr, - uchar reg, ushort val) -{ - struct eth_device *dev = eth_get_dev(); - - debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, val); - return phywrite(dev, addr, reg, val); -} - -int zynq_gem_initialize(bd_t *bis, int base_addr, int phy_addr, u32 emio) -{ - struct eth_device *dev; - struct zynq_gem_priv *priv; - void *bd_space; - - dev = calloc(1, sizeof(*dev)); - if (dev == NULL) - return -1; - - dev->priv = calloc(1, sizeof(struct zynq_gem_priv)); - if (dev->priv == NULL) { - free(dev); - return -1; - } - priv = dev->priv; - - /* Align rxbuffers to ARCH_DMA_MINALIGN */ - priv->rxbuffers = memalign(ARCH_DMA_MINALIGN, RX_BUF * PKTSIZE_ALIGN); - memset(priv->rxbuffers, 0, RX_BUF * PKTSIZE_ALIGN); - - /* Align bd_space to 1MB */ - bd_space = memalign(1 << MMU_SECTION_SHIFT, BD_SPACE); - mmu_set_region_dcache_behaviour((u32)bd_space, BD_SPACE, DCACHE_OFF); - - /* Initialize the bd spaces for tx and rx bd's */ - priv->tx_bd = (struct emac_bd *)bd_space; - priv->rx_bd = (struct emac_bd *)((u32)bd_space + BD_SEPRN_SPACE); - - priv->phyaddr = phy_addr; - priv->emio = emio; - - sprintf(dev->name, "Gem.%x", base_addr); - - dev->iobase = base_addr; - - dev->init = zynq_gem_init; - dev->halt = zynq_gem_halt; - dev->send = zynq_gem_send; - dev->recv = zynq_gem_recv; - dev->write_hwaddr = zynq_gem_setup_mac; - - eth_register(dev); - - miiphy_register(dev->name, zynq_gem_miiphyread, zynq_gem_miiphy_write); - priv->bus = miiphy_get_dev_by_name(dev->name); - - return 1; -} - -#ifdef CONFIG_OF_CONTROL -int zynq_gem_of_init(const void *blob) -{ - int offset = 0; - u32 ret = 0; - u32 reg, phy_reg; - - debug("ZYNQ GEM: Initialization\n"); - - do { - offset = fdt_node_offset_by_compatible(blob, offset, - "xlnx,ps7-ethernet-1.00.a"); - if (offset != -1) { - reg = fdtdec_get_addr(blob, offset, "reg"); - if (reg != FDT_ADDR_T_NONE) { - offset = fdtdec_lookup_phandle(blob, offset, - "phy-handle"); - if (offset != -1) - phy_reg = fdtdec_get_addr(blob, offset, - "reg"); - else - phy_reg = 0; - - debug("ZYNQ GEM: addr %x, phyaddr %x\n", - reg, phy_reg); - - ret |= zynq_gem_initialize(NULL, reg, - phy_reg, 0); - - } else { - debug("ZYNQ GEM: Can't get base address\n"); - return -1; - } - } - } while (offset != -1); - - return ret; -} -#endif |