* Patch by Mark Jonas, 08 June 2004:
[oweals/u-boot.git] / cpu / at91rm9200 / at91rm9200_ether.c
index 6e44150090cabcbc056a2aca444a6c6eaf577e3e..544b3175b84eacceeb5d6176189c871bf97c85c3 100644 (file)
@@ -69,15 +69,15 @@ AT91PS_EMAC p_mac;
 /** functions to interface the DAVICOM 10/100Mbps ethernet phy **********/
 
 /*
- * Name: 
+ * Name:
  *     dm9161_IsPhyConnected
- * Description: 
+ * Description:
  *     Reads the 2 PHY ID registers
- * Arguments: 
+ * Arguments:
  *     p_mac - pointer to AT91S_EMAC struct
- * Return value: 
+ * Return value:
  *     TRUE - if id read successfully
- *     FALSE- if error 
+ *     FALSE- if error
  */
 static unsigned int dm9161_IsPhyConnected (AT91PS_EMAC p_mac)
 {
@@ -96,14 +96,14 @@ static unsigned int dm9161_IsPhyConnected (AT91PS_EMAC p_mac)
 }
 
 /*
- * Name: 
+ * Name:
  *     dm9161_GetLinkSpeed
- * Description: 
- *     Link parallel detection status of MAC is checked and set in the 
+ * Description:
+ *     Link parallel detection status of MAC is checked and set in the
  *     MAC configuration registers
- * Arguments: 
- *     p_mac - pointer to MAC 
- * Return value: 
+ * Arguments:
+ *     p_mac - pointer to MAC
+ * Return value:
  *     TRUE - if link status set succesfully
  *     FALSE - if link status not set
  */
@@ -152,14 +152,14 @@ static UCHAR dm9161_GetLinkSpeed (AT91PS_EMAC p_mac)
 
 
 /*
- * Name: 
+ * Name:
  *     dm9161_InitPhy
- * Description: 
- *     MAC starts checking its link by using parallel detection and 
+ * Description:
+ *     MAC starts checking its link by using parallel detection and
  *     Autonegotiation and the same is set in the MAC configuration registers
- * Arguments: 
+ * Arguments:
  *     p_mac - pointer to struct AT91S_EMAC
- * Return value: 
+ * Return value:
  *     TRUE - if link status set succesfully
  *     FALSE - if link status not set
  */
@@ -188,14 +188,14 @@ static UCHAR dm9161_InitPhy (AT91PS_EMAC p_mac)
 
 
 /*
- * Name: 
+ * Name:
  *     dm9161_AutoNegotiate
- * Description: 
- *     MAC Autonegotiates with the partner status of same is set in the 
+ * Description:
+ *     MAC Autonegotiates with the partner status of same is set in the
  *     MAC configuration registers
- * Arguments: 
+ * Arguments:
  *     dev - pointer to struct net_device
- * Return value: 
+ * Return value:
  *     TRUE - if link status set successfully
  *     FALSE - if link status not set
  */
@@ -259,17 +259,15 @@ static UCHAR dm9161_AutoNegotiate (AT91PS_EMAC p_mac, int *status)
 }
 
 
-
-
 /*********** EMAC Phy layer Management functions *************************/
 /*
- * Name: 
+ * Name:
  *     at91rm9200_EmacEnableMDIO
- * Description: 
+ * Description:
  *     Enables the MDIO bit in MAC control register
- * Arguments: 
+ * Arguments:
  *     p_mac - pointer to struct AT91S_EMAC
- * Return value: 
+ * Return value:
  *     none
  */
 static void at91rm9200_EmacEnableMDIO (AT91PS_EMAC p_mac)
@@ -279,13 +277,13 @@ static void at91rm9200_EmacEnableMDIO (AT91PS_EMAC p_mac)
 }
 
 /*
- * Name: 
+ * Name:
  *     at91rm9200_EmacDisableMDIO
- * Description: 
+ * Description:
  *     Disables the MDIO bit in MAC control register
- * Arguments: 
+ * Arguments:
  *     p_mac - pointer to struct AT91S_EMAC
- * Return value: 
+ * Return value:
  *     none
  */
 static void at91rm9200_EmacDisableMDIO (AT91PS_EMAC p_mac)
@@ -296,15 +294,15 @@ static void at91rm9200_EmacDisableMDIO (AT91PS_EMAC p_mac)
 
 
 /*
- * Name: 
+ * Name:
  *     at91rm9200_EmacReadPhy
- * Description: 
+ * Description:
  *     Reads data from the PHY register
- * Arguments: 
+ * Arguments:
  *     dev - pointer to struct net_device
  *     RegisterAddress - unsigned char
- *     pInput - pointer to value read from register 
- * Return value: 
+ *     pInput - pointer to value read from register
+ * Return value:
  *     TRUE - if data read successfully
  */
 static UCHAR at91rm9200_EmacReadPhy (AT91PS_EMAC p_mac,
@@ -312,8 +310,9 @@ static UCHAR at91rm9200_EmacReadPhy (AT91PS_EMAC p_mac,
                                     unsigned short *pInput)
 {
        p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) |
-                         (AT91C_EMAC_CODE_802_3) | (AT91C_EMAC_RW_R) |
-                         (RegisterAddress << 18);
+                         (AT91C_EMAC_RW_R) |
+                         (RegisterAddress << 18) |
+                         (AT91C_EMAC_CODE_802_3);
 
        udelay (10000);
 
@@ -324,24 +323,24 @@ static UCHAR at91rm9200_EmacReadPhy (AT91PS_EMAC p_mac,
 
 
 /*
- * Name: 
+ * Name:
  *     at91rm9200_EmacWritePhy
- * Description: 
+ * Description:
  *     Writes data to the PHY register
- * Arguments: 
+ * Arguments:
  *     dev - pointer to struct net_device
  *     RegisterAddress - unsigned char
- *     pOutput - pointer to value to be written in the register 
- * Return value: 
+ *     pOutput - pointer to value to be written in the register
+ * Return value:
  *     TRUE - if data read successfully
  */
 static UCHAR at91rm9200_EmacWritePhy (AT91PS_EMAC p_mac,
-                                                                         unsigned char RegisterAddress,
-                                                                         unsigned short *pOutput)
+                                     unsigned char RegisterAddress,
+                                     unsigned short *pOutput)
 {
        p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) |
                        AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_W |
-                       (RegisterAddress << 18);
+                       (RegisterAddress << 18) | *pOutput;
 
        udelay (10000);
 
@@ -349,13 +348,13 @@ static UCHAR at91rm9200_EmacWritePhy (AT91PS_EMAC p_mac,
 }
 
 /*
- * Name: 
+ * Name:
  *     at91rm92000_GetPhyInterface
- * Description: 
- *     Initialise the interface functions to the PHY 
- * Arguments: 
+ * Description:
+ *     Initialise the interface functions to the PHY
+ * Arguments:
  *     None
- * Return value: 
+ * Return value:
  *     None
  */
 void at91rm92000_GetPhyInterface (void)
@@ -379,14 +378,21 @@ int eth_init (bd_t * bd)
 
        p_mac = AT91C_BASE_EMAC;
 
-       *AT91C_PIOA_PDR = AT91C_PA16_EMDIO | AT91C_PA15_EMDC | AT91C_PA14_ERXER | AT91C_PA13_ERX1 | AT91C_PA12_ERX0 | AT91C_PA11_ECRS_ECRSDV | AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN | AT91C_PA7_ETXCK_EREFCK;     /* PIO Disable Register */
+       /* PIO Disable Register */
+       *AT91C_PIOA_PDR = AT91C_PA16_EMDIO | AT91C_PA15_EMDC | AT91C_PA14_ERXER |
+                         AT91C_PA13_ERX1 | AT91C_PA12_ERX0 | AT91C_PA11_ECRS_ECRSDV |
+                         AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN |
+                         AT91C_PA7_ETXCK_EREFCK;
 
        *AT91C_PIOB_PDR = AT91C_PB25_EF100 |
-                       AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV |
-                       AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER |
-                       AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
+                         AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV |
+                         AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER |
+                         AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
 
-       *AT91C_PIOB_BSR = AT91C_PB25_EF100 | AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2;  /* Select B Register */
+       /* Select B Register */
+       *AT91C_PIOB_BSR = AT91C_PB25_EF100 | AT91C_PB19_ERXCK | AT91C_PB18_ECOL |
+                         AT91C_PB17_ERXDV | AT91C_PB16_ERX3 | AT91C_PB15_ERX2 |
+                         AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
 
        *AT91C_PMC_PCER = 1 << AT91C_ID_EMAC;   /* Peripheral Clock Enable Register */
 
@@ -401,6 +407,22 @@ int eth_init (bd_t * bd)
        rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP;
        rbfp = &rbfdt[0];
 
+       p_mac->EMAC_SA2L = (bd->bi_enetaddr[3] << 24) | (bd->bi_enetaddr[2] << 16)
+                        | (bd->bi_enetaddr[1] <<  8) | (bd->bi_enetaddr[0]);
+       p_mac->EMAC_SA2H = (bd->bi_enetaddr[5] <<  8) | (bd->bi_enetaddr[4]);
+
+       p_mac->EMAC_RBQP = (long) (&rbfdt[0]);
+       p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
+
+       p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC)
+                       & ~AT91C_EMAC_CLK;
+
+#ifdef CONFIG_AT91C_USE_RMII
+       p_mac->EMAC_CFG |= AT91C_EMAC_RMII;
+#endif
+
+       p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE;
+
        at91rm92000_GetPhyInterface ();
 
        if (!pPhyOps->IsPhyConnected (p_mac))
@@ -417,16 +439,6 @@ int eth_init (bd_t * bd)
                return 0;
        }
 
-       p_mac->EMAC_SA2L = (bd->bi_enetaddr[3] << 24) | (bd->bi_enetaddr[2] << 16)
-                        | (bd->bi_enetaddr[1] << 8) | (bd->bi_enetaddr[0]);
-       p_mac->EMAC_SA2H = (bd->bi_enetaddr[5] << 8) | (bd->bi_enetaddr[4]);
-
-       p_mac->EMAC_RBQP = (long) (&rbfdt[0]);
-       p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
-       p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC | AT91C_EMAC_RMII)
-                       & ~AT91C_EMAC_CLK;
-       p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE;
-
        return 0;
 }
 
@@ -464,5 +476,25 @@ int eth_rx (void)
 void eth_halt (void)
 {
 };
+
+#if (CONFIG_COMMANDS & CFG_CMD_MII)
+int  miiphy_read(unsigned char addr, unsigned char reg, unsigned short * value)
+{
+       at91rm9200_EmacEnableMDIO (p_mac);
+       at91rm9200_EmacReadPhy (p_mac, reg, value);
+       at91rm9200_EmacDisableMDIO (p_mac);
+       return 0;
+}
+
+int  miiphy_write(unsigned char addr, unsigned char reg, unsigned short value)
+{
+       at91rm9200_EmacEnableMDIO (p_mac);
+       at91rm9200_EmacWritePhy (p_mac, reg, &value);
+       at91rm9200_EmacDisableMDIO (p_mac);
+       return 0;
+}
+#endif /* CONFIG_COMMANDS & CFG_CMD_MII */
+
 #endif /* CONFIG_COMMANDS & CFG_CMD_NET */
+
 #endif /* CONFIG_DRIVER_ETHER */