diff options
Diffstat (limited to 'bsps/powerpc/gen83xx/net/network.c')
-rw-r--r-- | bsps/powerpc/gen83xx/net/network.c | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/bsps/powerpc/gen83xx/net/network.c b/bsps/powerpc/gen83xx/net/network.c new file mode 100644 index 0000000000..b870673cd3 --- /dev/null +++ b/bsps/powerpc/gen83xx/net/network.c @@ -0,0 +1,255 @@ +/*===============================================================*\ +| Project: RTEMS support for MPC83xx | ++-----------------------------------------------------------------+ +| Copyright (c) 2007 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.org/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the board specific portion | +| of the network interface driver | +\*===============================================================*/ + +#define __INSIDE_RTEMS_BSD_TCPIP_STACK__ + +#include <rtems.h> +#include <rtems/rtems_bsdnet.h> +#include <rtems/rtems_bsdnet_internal.h> +#include <bsp.h> +#include <bsp/tsec.h> +#include <bsp/u-boot.h> +#include <mpc83xx/mpc83xx.h> +#include <string.h> +#include <libcpu/spr.h> + +#if MPC83XX_CHIP_TYPE / 10 != 830 + +#define TSEC_IFMODE_RGMII 0 +#define TSEC_IFMODE_GMII 1 + +#if defined( MPC83XX_BOARD_MPC8313ERDB) + +#define TSEC_IFMODE TSEC_IFMODE_RGMII + +#elif defined( MPC83XX_BOARD_MPC8349EAMDS) + +#define TSEC_IFMODE TSEC_IFMODE_GMII + +#elif defined( MPC83XX_BOARD_HSC_CM01) + +#define TSEC_IFMODE TSEC_IFMODE_RGMII + +#else + +#warning No TSEC configuration available + +#endif + +/* System Version Register */ +#define SVR 286 +SPR_RO( SVR) + +/* Processor Version Register */ +SPR_RO( PPC_PVR) + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +int BSP_tsec_attach +( +/*-------------------------------------------------------------------------*\ +| Purpose: | +| attach or detach the driver | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ + struct rtems_bsdnet_ifconfig *config, /* interface configuration */ + int attaching /* 0 = detach, else attach */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| 1, if success | +\*=========================================================================*/ +{ + tsec_config tsec_cfg; + int unitNumber; + char *unitName; + uint32_t svr = _read_SVR(); + uint32_t pvr = _read_PPC_PVR(); + + memset(&tsec_cfg, 0, sizeof(tsec_cfg)); + config->drv_ctrl = &tsec_cfg; + + /* + * Parse driver name + */ + if((unitNumber = rtems_bsdnet_parse_driver_name(config, &unitName)) < 0) { + return 0; + } + + tsec_cfg.reg_ptr = &mpc83xx.tsec [unitNumber - 1]; + tsec_cfg.mdio_ptr = &mpc83xx.tsec [0]; + + if (attaching) { +#if (TSEC_IFMODE==TSEC_IFMODE_GMII) +#if !defined(MPC83XX_BOARD_HSC_CM01) + + /* + * do not change system I/O configuration registers on HSC board + * because should initialize from RCW + */ + + + if (unitNumber == 1) { + /* + * init system I/O configuration registers + * to ensure proper pin functions + */ + mpc83xx.syscon.sicrh = mpc83xx.syscon.sicrh & ~0x1F800000; + /* + * init port registers (GPIO2DIR) for TSEC1 + */ + mpc83xx.gpio[1].gpdir = ((mpc83xx.gpio[1].gpdir & ~0x00000FFF) + | 0x0000001f); + } + if (unitNumber == 2) { + /* + * init system I/O configuration registers + * to ensure proper pin functions + */ + mpc83xx.syscon.sicrh = mpc83xx.syscon.sicrh & ~0x007f8000; + /* + * init port registers (GPIO2DIR) for TSEC2 + */ + mpc83xx.gpio[0].gpdir = ((mpc83xx.gpio[0].gpdir & ~0x000FFFFF) + | 0x00087881); + } +#endif /* !defined(MPC83XX_BOARD_HSC_CM01) */ +#endif +#if (TSEC_IFMODE==TSEC_IFMODE_RGMII) + + /* + * Nothing special needed for TSEC1 operation + */ +#endif + } + /* + * add MAC address into config->hardware_adderss + * FIXME: get the real address we need + */ + if (config->hardware_address == NULL) { +#if !defined(HAS_UBOOT) + static char hw_addr [TSEC_COUNT][6]; + volatile tsec_registers *reg_ptr = tsec_cfg.reg_ptr; + + /* read MAC address from hardware register */ + /* we expect it htere from the boot loader */ + config->hardware_address = hw_addr[unitNumber-1]; + + hw_addr[unitNumber-1][5] = (reg_ptr->macstnaddr[0] >> 24) & 0xff; + hw_addr[unitNumber-1][4] = (reg_ptr->macstnaddr[0] >> 16) & 0xff; + hw_addr[unitNumber-1][3] = (reg_ptr->macstnaddr[0] >> 8) & 0xff; + hw_addr[unitNumber-1][2] = (reg_ptr->macstnaddr[0] >> 0) & 0xff; + hw_addr[unitNumber-1][1] = (reg_ptr->macstnaddr[1] >> 24) & 0xff; + hw_addr[unitNumber-1][0] = (reg_ptr->macstnaddr[1] >> 16) & 0xff; +#endif + +#if defined(HAS_UBOOT) + switch (unitNumber) { + case 1: + config->hardware_address = bsp_uboot_board_info.bi_enetaddr; + break; + +#ifdef CONFIG_HAS_ETH1 + case 2: + config->hardware_address = bsp_uboot_board_info.bi_enet1addr; + break; +#endif /* CONFIG_HAS_ETH1 */ + +#ifdef CONFIG_HAS_ETH2 + case 3: + config->hardware_address = bsp_uboot_board_info.bi_enet2addr; + break; +#endif /* CONFIG_HAS_ETH2 */ + +#ifdef CONFIG_HAS_ETH3 + case 4: + config->hardware_address = bsp_uboot_board_info.bi_enet3addr; + break; +#endif /* CONFIG_HAS_ETH3 */ + + default: + return 0; + } + +#endif /* HAS_UBOOT */ + + } + /* + * set interrupt number for given interface + */ + config->irno = (unsigned) ( + unitNumber == 1 + ? BSP_IPIC_IRQ_TSEC1_TX + : BSP_IPIC_IRQ_TSEC2_TX + ); + + if (svr == 0x80b00010 && pvr == 0x80850010) { + /* + * This is a special case for MPC8313ERDB with silicon revision 1. Look in + * "MPC8313ECE Rev. 3, 3/2008" errata for "IPIC 1". + */ + if (unitNumber == 1) { + tsec_cfg.irq_num_tx = 37; + tsec_cfg.irq_num_rx = 36; + tsec_cfg.irq_num_err = 35; + } else if (unitNumber == 2) { + tsec_cfg.irq_num_tx = 34; + tsec_cfg.irq_num_rx = 33; + tsec_cfg.irq_num_err = 32; + } else { + return 0; + } + } else { + rtems_irq_number irno = unitNumber == 1 ? + BSP_IPIC_IRQ_TSEC1_TX : BSP_IPIC_IRQ_TSEC2_TX; + + /* get base interrupt number (for Tx irq, Rx=base+1,Err=base+2) */ + tsec_cfg.irq_num_tx = irno + 0; + tsec_cfg.irq_num_rx = irno + 1; + tsec_cfg.irq_num_err = irno + 2; + } + + /* + * XXX: Although most hardware builders will assign the PHY addresses + * like this, this should be more configurable + */ +#ifdef MPC83XX_BOARD_MPC8313ERDB + if (unitNumber == 2) { + tsec_cfg.phy_default = 4; + } else { + /* TODO */ + return 0; + } +#else /* MPC83XX_BOARD_MPC8313ERDB */ + tsec_cfg.phy_default = unitNumber-1; +#endif /* MPC83XX_BOARD_MPC8313ERDB */ + + tsec_cfg.unit_number = unitNumber; + tsec_cfg.unit_name = unitName; + + /* + * call attach function of board independent driver + */ + return tsec_driver_attach_detach(config, attaching); +} + +#endif /* MPC83XX_CHIP_TYPE / 10 != 830 */ |