uboot/cpu/arm920t/at91rm9200/bcm5221.c
<<
>>
Prefs
   1/*
   2 * Broadcom BCM5221 Ethernet PHY
   3 *
   4 * (C) Copyright 2005 REA Elektronik GmbH <www.rea.de>
   5 * Anders Larsen <alarsen@rea.de>
   6 *
   7 * (C) Copyright 2003
   8 * Author : Hamid Ikdoumi (Atmel)
   9 *
  10 * See file CREDITS for list of people who contributed to this
  11 * project.
  12 *
  13 * This program is free software; you can redistribute it and/or
  14 * modify it under the terms of the GNU General Public License as
  15 * published by the Free Software Foundation; either version 2 of
  16 * the License, or (at your option) any later version.
  17 *
  18 * This program is distributed in the hope that it will be useful,
  19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21 * GNU General Public License for more details.
  22 *
  23 * You should have received a copy of the GNU General Public License
  24 * along with this program; if not, write to the Free Software
  25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  26 * MA 02111-1307 USA
  27 */
  28
  29#include <at91rm9200_net.h>
  30#include <net.h>
  31#include <bcm5221.h>
  32
  33#ifdef CONFIG_DRIVER_ETHER
  34
  35#if defined(CONFIG_CMD_NET)
  36
  37/*
  38 * Name:
  39 *      bcm5221_IsPhyConnected
  40 * Description:
  41 *      Reads the 2 PHY ID registers
  42 * Arguments:
  43 *      p_mac - pointer to AT91S_EMAC struct
  44 * Return value:
  45 *      TRUE - if id read successfully
  46 *      FALSE- if error
  47 */
  48unsigned int bcm5221_IsPhyConnected (AT91PS_EMAC p_mac)
  49{
  50        unsigned short Id1, Id2;
  51
  52        at91rm9200_EmacEnableMDIO (p_mac);
  53        at91rm9200_EmacReadPhy (p_mac, BCM5221_PHYID1, &Id1);
  54        at91rm9200_EmacReadPhy (p_mac, BCM5221_PHYID2, &Id2);
  55        at91rm9200_EmacDisableMDIO (p_mac);
  56
  57        if ((Id1 == (BCM5221_PHYID1_OUI >> 6)) &&
  58                ((Id2 >> 10) == (BCM5221_PHYID1_OUI & BCM5221_LSB_MASK)))
  59                return TRUE;
  60
  61        return FALSE;
  62}
  63
  64/*
  65 * Name:
  66 *      bcm5221_GetLinkSpeed
  67 * Description:
  68 *      Link parallel detection status of MAC is checked and set in the
  69 *      MAC configuration registers
  70 * Arguments:
  71 *      p_mac - pointer to MAC
  72 * Return value:
  73 *      TRUE - if link status set succesfully
  74 *      FALSE - if link status not set
  75 */
  76unsigned char bcm5221_GetLinkSpeed (AT91PS_EMAC p_mac)
  77{
  78        unsigned short stat1, stat2;
  79
  80        if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_BMSR, &stat1))
  81                return FALSE;
  82
  83        if (!(stat1 & BCM5221_LINK_STATUS))     /* link status up? */
  84                return FALSE;
  85
  86        if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_ACSR, &stat2))
  87                return FALSE;
  88
  89        if ((stat1 & BCM5221_100BASE_TX_FD) && (stat2 & BCM5221_100) && (stat2 & BCM5221_FDX)) {
  90                /*set Emac for 100BaseTX and Full Duplex  */
  91                p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
  92                return TRUE;
  93        }
  94
  95        if ((stat1 & BCM5221_10BASE_T_FD) && !(stat2 & BCM5221_100) && (stat2 & BCM5221_FDX)) {
  96                /*set MII for 10BaseT and Full Duplex  */
  97                p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
  98                                ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
  99                                | AT91C_EMAC_FD;
 100                return TRUE;
 101        }
 102
 103        if ((stat1 & BCM5221_100BASE_TX_HD) && (stat2 & BCM5221_100) && !(stat2 & BCM5221_FDX)) {
 104                /*set MII for 100BaseTX and Half Duplex  */
 105                p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
 106                                ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
 107                                | AT91C_EMAC_SPD;
 108                return TRUE;
 109        }
 110
 111        if ((stat1 & BCM5221_10BASE_T_HD) && !(stat2 & BCM5221_100) && !(stat2 & BCM5221_FDX)) {
 112                /*set MII for 10BaseT and Half Duplex  */
 113                p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
 114                return TRUE;
 115        }
 116        return FALSE;
 117}
 118
 119
 120/*
 121 * Name:
 122 *      bcm5221_InitPhy
 123 * Description:
 124 *      MAC starts checking its link by using parallel detection and
 125 *      Autonegotiation and the same is set in the MAC configuration registers
 126 * Arguments:
 127 *      p_mac - pointer to struct AT91S_EMAC
 128 * Return value:
 129 *      TRUE - if link status set succesfully
 130 *      FALSE - if link status not set
 131 */
 132unsigned char bcm5221_InitPhy (AT91PS_EMAC p_mac)
 133{
 134        unsigned char ret = TRUE;
 135        unsigned short IntValue;
 136
 137        at91rm9200_EmacEnableMDIO (p_mac);
 138
 139        if (!bcm5221_GetLinkSpeed (p_mac)) {
 140                /* Try another time */
 141                ret = bcm5221_GetLinkSpeed (p_mac);
 142        }
 143
 144        /* Disable PHY Interrupts */
 145        at91rm9200_EmacReadPhy (p_mac, BCM5221_INTR, &IntValue);
 146        /* clear FDX LED and INTR Enable */
 147        IntValue &= ~(BCM5221_FDX_LED | BCM5221_INTR_ENABLE);
 148        /* set FDX, SPD, Link, INTR masks */
 149        IntValue |= (BCM5221_FDX_MASK  | BCM5221_SPD_MASK |
 150                     BCM5221_LINK_MASK | BCM5221_INTR_MASK);
 151        at91rm9200_EmacWritePhy (p_mac, BCM5221_INTR, &IntValue);
 152        at91rm9200_EmacDisableMDIO (p_mac);
 153
 154        return (ret);
 155}
 156
 157
 158/*
 159 * Name:
 160 *      bcm5221_AutoNegotiate
 161 * Description:
 162 *      MAC Autonegotiates with the partner status of same is set in the
 163 *      MAC configuration registers
 164 * Arguments:
 165 *      dev - pointer to struct net_device
 166 * Return value:
 167 *      TRUE - if link status set successfully
 168 *      FALSE - if link status not set
 169 */
 170unsigned char bcm5221_AutoNegotiate (AT91PS_EMAC p_mac, int *status)
 171{
 172        unsigned short value;
 173        unsigned short PhyAnar;
 174        unsigned short PhyAnalpar;
 175
 176        /* Set bcm5221 control register */
 177        if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_BMCR, &value))
 178                return FALSE;
 179        value &= ~BCM5221_AUTONEG;      /* remove autonegotiation enable */
 180        value |=  BCM5221_ISOLATE;      /* Electrically isolate PHY */
 181        if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_BMCR, &value))
 182                return FALSE;
 183
 184        /* Set the Auto_negotiation Advertisement Register */
 185        /* MII advertising for 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 */
 186        PhyAnar = BCM5221_TX_FDX | BCM5221_TX_HDX |
 187                  BCM5221_10_FDX | BCM5221_10_HDX | BCM5221_AN_IEEE_802_3;
 188        if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_ANAR, &PhyAnar))
 189                return FALSE;
 190
 191        /* Read the Control Register     */
 192        if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_BMCR, &value))
 193                return FALSE;
 194
 195        value |= BCM5221_SPEED_SELECT | BCM5221_AUTONEG | BCM5221_DUPLEX_MODE;
 196        if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_BMCR, &value))
 197                return FALSE;
 198        /* Restart Auto_negotiation  */
 199        value |= BCM5221_RESTART_AUTONEG;
 200        value &= ~BCM5221_ISOLATE;
 201        if (!at91rm9200_EmacWritePhy (p_mac, BCM5221_BMCR, &value))
 202                return FALSE;
 203
 204        /*check AutoNegotiate complete */
 205        udelay (10000);
 206        at91rm9200_EmacReadPhy (p_mac, BCM5221_BMSR, &value);
 207        if (!(value & BCM5221_AUTONEG_COMP))
 208                return FALSE;
 209
 210        /* Get the AutoNeg Link partner base page */
 211        if (!at91rm9200_EmacReadPhy (p_mac, BCM5221_ANLPAR, &PhyAnalpar))
 212                return FALSE;
 213
 214        if ((PhyAnar & BCM5221_TX_FDX) && (PhyAnalpar & BCM5221_TX_FDX)) {
 215                /*set MII for 100BaseTX and Full Duplex  */
 216                p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
 217                return TRUE;
 218        }
 219
 220        if ((PhyAnar & BCM5221_10_FDX) && (PhyAnalpar & BCM5221_10_FDX)) {
 221                /*set MII for 10BaseT and Full Duplex  */
 222                p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
 223                                ~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
 224                                | AT91C_EMAC_FD;
 225                return TRUE;
 226        }
 227        return FALSE;
 228}
 229
 230#endif
 231
 232#endif  /* CONFIG_DRIVER_ETHER */
 233