From 34281aa232f5bbd820932b20c121b4a39f06bc50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Sat, 4 Jan 2014 09:07:09 +0000 Subject: [PATCH] added missing files --- BaS_gcc/include/bcm5222.h | 71 +++++++++++++++ BaS_gcc/net/bcm5222.c | 180 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 251 insertions(+) create mode 100644 BaS_gcc/include/bcm5222.h create mode 100644 BaS_gcc/net/bcm5222.c diff --git a/BaS_gcc/include/bcm5222.h b/BaS_gcc/include/bcm5222.h new file mode 100644 index 0000000..f7dc81e --- /dev/null +++ b/BaS_gcc/include/bcm5222.h @@ -0,0 +1,71 @@ +/* + * File: bcm5222.h + * Purpose: Driver for the BCM5222 10/100 Ethernet PHY + * + * Notes: + */ + +#ifndef _BCM5222_H_ +#define _BCM5222_H_ + +extern int bcm5222_init(uint8_t, uint8_t, uint8_t, uint8_t); +extern void bcm5222_get_reg(uint16_t*, uint16_t*); + +/********************************************************************/ + +/* MII Register Addresses */ +#define BCM5222_CTRL (0x00) +#define BCM5222_STAT (0x01) +#define BCM5222_PHY_ID1 (0x02) +#define BCM5222_PHY_ID2 (0x03) +#define BCM5222_AN_ADV (0x04) +#define BCM5222_AN_LINK_PAR (0x05) +#define BCM5222_AN_EXP (0x06) +#define BCM5222_AN_NPR (0x07) +#define BCM5222_LINK_NPA (0x08) +#define BCM5222_ACSR (0x18) + +/* Bit definitions and macros for BCM5222_CTRL */ +#define BCM5222_CTRL_RESET (0x8000) +#define BCM5222_CTRL_LOOP (0x4000) +#define BCM5222_CTRL_SPEED (0x2000) +#define BCM5222_CTRL_ANE (0x1000) +#define BCM5222_CTRL_PD (0x0800) +#define BCM5222_CTRL_ISOLATE (0x0400) +#define BCM5222_CTRL_RESTART_AN (0x0200) +#define BCM5222_CTRL_FDX (0x0100) +#define BCM5222_CTRL_COL_TEST (0x0080) + + +/* Bit definitions and macros for BCM5222_STAT */ +#define BCM5222_STAT_100BT4 (0x8000) +#define BCM5222_STAT_100BTX_FDX (0x4000) +#define BCM5222_STAT_100BTX (0x2000) +#define BCM5222_STAT_10BT_FDX (0x1000) +#define BCM5222_STAT_10BT (0x0800) +#define BCM5222_STAT_NO_PREAMBLE (0x0040) +#define BCM5222_STAT_AN_COMPLETE (0x0020) +#define BCM5222_STAT_REMOTE_FAULT (0x0010) +#define BCM5222_STAT_AN_ABILITY (0x0008) +#define BCM5222_STAT_LINK (0x0004) +#define BCM5222_STAT_JABBER (0x0002) +#define BCM5222_STAT_EXTENDED (0x0001) + +/* Bit definitions and macros for BCM5222_AN_ADV */ +#define BCM5222_AN_ADV_NEXT_PAGE (0x8001) +#define BCM5222_AN_ADV_REM_FAULT (0x2001) +#define BCM5222_AN_ADV_PAUSE (0x0401) +#define BCM5222_AN_ADV_100BT4 (0x0201) +#define BCM5222_AN_ADV_100BTX_FDX (0x0101) +#define BCM5222_AN_ADV_100BTX (0x0081) +#define BCM5222_AN_ADV_10BT_FDX (0x0041) +#define BCM5222_AN_ADV_10BT (0x0021) +#define BCM5222_AN_ADV_802_3 (0x0001) + +/* Bit definitions and macros for BCM5222_ACSR */ +#define BCM5222_ACSR_100BTX (0x0002) +#define BCM5222_ACSR_FDX (0x0001) + +/********************************************************************/ + +#endif /* _BCM5222_H_ */ diff --git a/BaS_gcc/net/bcm5222.c b/BaS_gcc/net/bcm5222.c new file mode 100644 index 0000000..9dedc65 --- /dev/null +++ b/BaS_gcc/net/bcm5222.c @@ -0,0 +1,180 @@ +/* + * File: bcm5222.c + * Purpose: Driver for the Micrel BCM5222 10/100 Ethernet PHY + * + * Notes: This driver was written specifically for the M5475EVB + * and M5485EVB. These boards use the MII signals from + * FEC0 to control the PHY. Therefore the fec_ch parameter + * is ignored when doing MII reads and writes. + */ + +#include "net.h" +#include "fec.h" +#include "bcm5222.h" + +#include "bas_printf.h" + +#if defined(MACHINE_FIREBEE) +#include "firebee.h" +#elif defined(MACHINE_M5484LITE) +#include "m5484l.h" +#else +#error "Unknown machine!" +#endif + +#define DBG_BCM +#ifdef DBG_BCM +#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) +#else +#define dbg(format, arg...) do { ; } while (0) +#endif /* DBG_BCM */ + +/* + * Initialize the BCM5222 PHY + * + * This function sets up the Auto-Negotiate Advertisement register + * within the PHY and then forces the PHY to auto-negotiate for + * it's settings. + * + * Params: + * fec_ch FEC channel + * phy_addr Address of the PHY. + * speed Desired speed (10BaseT or 100BaseTX) + * duplex Desired duplex (Full or Half) + * + * Return Value: + * 0 if MII commands fail + * 1 otherwise + */ +int bcm5222_init(uint8_t fec_ch, uint8_t phy_addr, uint8_t speed, uint8_t duplex) +{ + int timeout; + uint16_t settings; + + /* Initialize the MII interface */ + fec_mii_init(fec_ch, SYSCLK / 1000); + dbg("%s: PHY reset\r\n", __FUNCTION__); + + /* Reset the PHY */ + if (!fec_mii_write(fec_ch, phy_addr, BCM5222_CTRL, BCM5222_CTRL_RESET | BCM5222_CTRL_ANE)) + return 0; + + /* Wait for the PHY to reset */ + for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) + { + fec_mii_read(fec_ch, phy_addr, BCM5222_CTRL, &settings); + if (!(settings & BCM5222_CTRL_RESET)) + break; + } + if(timeout >= FEC_MII_TIMEOUT) + return 0; + + dbg("%s: PHY reset OK\r\n", __FUNCTION__); + + settings = (BCM5222_AN_ADV_NEXT_PAGE | BCM5222_AN_ADV_PAUSE); + + if (speed == FEC_MII_10BASE_T) + settings |= (uint16_t)((duplex == FEC_MII_FULL_DUPLEX) + ? (BCM5222_AN_ADV_10BT_FDX | BCM5222_AN_ADV_10BT) + : BCM5222_AN_ADV_10BT); + else /* (speed == FEC_MII_100BASE_TX) */ + settings = (uint16_t)((duplex == FEC_MII_FULL_DUPLEX) + ? (BCM5222_AN_ADV_100BTX_FDX | BCM5222_AN_ADV_100BTX + | BCM5222_AN_ADV_10BT_FDX | BCM5222_AN_ADV_10BT) + : (BCM5222_AN_ADV_100BTX | BCM5222_AN_ADV_10BT)); + + /* Set the Auto-Negotiation Advertisement Register */ + if (!fec_mii_write(fec_ch, phy_addr, BCM5222_AN_ADV, settings)) + return 0; + + dbg("%s: PHY Enable Auto-Negotiation\r\n", __FUNCTION__); + + /* Enable Auto-Negotiation */ + if (!fec_mii_write(fec_ch, phy_addr, BCM5222_CTRL, (BCM5222_CTRL_ANE | BCM5222_CTRL_RESTART_AN))) + return 0; + + dbg("%s: PHY Wait for auto-negotiation to complete\r\n", __FUNCTION__); + + /* Wait for auto-negotiation to complete */ + for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) + { + if (!fec_mii_read(fec_ch, phy_addr, BCM5222_STAT, &settings)) + return 0; + if (settings & BCM5222_STAT_AN_COMPLETE) + break; + } + + if (timeout < FEC_MII_TIMEOUT) + { + dbg("%s: PHY auto-negociation complete\r\n", __FUNCTION__); + + /* Read Auxiliary Control/Status Register */ + if (!fec_mii_read(fec_ch, phy_addr, BCM5222_ACSR, &settings)) + return 0; + } + else + { + dbg("%s: auto negotiation failed, PHY Set the default mode\r\n", __FUNCTION__); + + /* Set the default mode (Full duplex, 100 Mbps) */ + if (!fec_mii_write(fec_ch, phy_addr, BCM5222_ACSR, settings = (BCM5222_ACSR_100BTX | BCM5222_ACSR_FDX))) + return 0; + } + + /* Set the proper duplex in the FEC now that we have auto-negotiated */ + if (settings & BCM5222_ACSR_FDX) + fec_duplex(fec_ch, FEC_MII_FULL_DUPLEX); + else + fec_duplex(fec_ch, FEC_MII_HALF_DUPLEX); + + dbg("%s: PHY Mode: ", __FUNCTION__); + + if (settings & BCM5222_ACSR_100BTX) + dbg("%s: 100Mbps\r\n", __FUNCTION__); + else + dbg("%s: 10Mbps\r\n", __FUNCTION__); + + if (settings & BCM5222_ACSR_FDX) + dbg("%s: Full-duplex\r\n", __FUNCTION__); + else + dbg("%s: Half-duplex\r\n", __FUNCTION__); + + return 1; +} + +void bcm5222_get_reg(uint16_t* status0, uint16_t* status1) +{ + fec_mii_read(0, 0x00, 0x00000000, &status0[0]); + fec_mii_read(0, 0x00, 0x00000001, &status0[1]); + fec_mii_read(0, 0x00, 0x00000004, &status0[4]); + fec_mii_read(0, 0x00, 0x00000005, &status0[5]); + fec_mii_read(0, 0x00, 0x00000006, &status0[6]); + fec_mii_read(0, 0x00, 0x00000007, &status0[7]); + fec_mii_read(0, 0x00, 0x00000008, &status0[8]); + fec_mii_read(0, 0x00, 0x00000010, &status0[16]); + fec_mii_read(0, 0x00, 0x00000011, &status0[17]); + fec_mii_read(0, 0x00, 0x00000012, &status0[18]); + fec_mii_read(0, 0x00, 0x00000013, &status0[19]); + fec_mii_read(0, 0x00, 0x00000018, &status0[24]); + fec_mii_read(0, 0x00, 0x00000019, &status0[25]); + fec_mii_read(0, 0x00, 0x0000001B, &status0[27]); + fec_mii_read(0, 0x00, 0x0000001C, &status0[28]); + fec_mii_read(0, 0x00, 0x0000001E, &status0[30]); + fec_mii_read(0, 0x01, 0x00000000, &status1[0]); + fec_mii_read(0, 0x01, 0x00000001, &status1[1]); + fec_mii_read(0, 0x01, 0x00000004, &status1[4]); + fec_mii_read(0, 0x01, 0x00000005, &status1[5]); + fec_mii_read(0, 0x01, 0x00000006, &status1[6]); + fec_mii_read(0, 0x01, 0x00000007, &status1[7]); + fec_mii_read(0, 0x01, 0x00000008, &status1[8]); + fec_mii_read(0, 0x01, 0x00000010, &status1[16]); + fec_mii_read(0, 0x01, 0x00000011, &status1[17]); + fec_mii_read(0, 0x01, 0x00000012, &status1[18]); + fec_mii_read(0, 0x01, 0x00000013, &status1[19]); + fec_mii_read(0, 0x01, 0x00000018, &status1[24]); + fec_mii_read(0, 0x01, 0x00000019, &status1[25]); + fec_mii_read(0, 0x01, 0x0000001B, &status1[27]); + fec_mii_read(0, 0x01, 0x0000001C, &status1[28]); + fec_mii_read(0, 0x01, 0x0000001E, &status1[30]); +} +