summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-01-03 06:52:19 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-01-03 06:52:19 -0600
commitb9a1ad8cf2d7334b7f83a508c883ebd5a9ed8725 (patch)
tree6022e2ec1ae23c537ff4465a4125840e454b3f6e
parentedb53c7ea434cce32a19adb289cf06bec7ecc4e0 (diff)
downloadnuttx-b9a1ad8cf2d7334b7f83a508c883ebd5a9ed8725.tar.gz
nuttx-b9a1ad8cf2d7334b7f83a508c883ebd5a9ed8725.tar.bz2
nuttx-b9a1ad8cf2d7334b7f83a508c883ebd5a9ed8725.zip
Tive Ethernet: Wait for EMAC to come out of reset before accessing any registers
-rw-r--r--nuttx/arch/arm/src/tiva/tm4c_ethernet.c119
1 files changed, 61 insertions, 58 deletions
diff --git a/nuttx/arch/arm/src/tiva/tm4c_ethernet.c b/nuttx/arch/arm/src/tiva/tm4c_ethernet.c
index 07ee3fbc9..e5fe71dff 100644
--- a/nuttx/arch/arm/src/tiva/tm4c_ethernet.c
+++ b/nuttx/arch/arm/src/tiva/tm4c_ethernet.c
@@ -248,7 +248,7 @@
#endif
/* Clocking *****************************************************************/
-/* Set MIIADDR CR bits depending on SysClk freuency */
+/* Set MIIADDR CR bits depending on SysClk frequency */
#if SYSCLK_FREQUENCY >= 20000000 && SYSCLK_FREQUENCY < 35000000
# define EMAC_MIIADDR_CR EMAC_MIIADDR_CR_20_35
@@ -1038,8 +1038,8 @@ static int tiva_transmit(FAR struct tiva_ethmac_s *priv)
txdesc = priv->txhead;
txfirst = txdesc;
- nllvdbg("d_len: %d d_buf: %p txhead: %p tdes0: %08x\n",
- priv->dev.d_len, priv->dev.d_buf, txdesc, txdesc->tdes0);
+ nvdbg("d_len: %d d_buf: %p txhead: %p tdes0: %08x\n",
+ priv->dev.d_len, priv->dev.d_buf, txdesc, txdesc->tdes0);
DEBUGASSERT(txdesc && (txdesc->tdes0 & EMAC_TDES0_OWN) == 0);
@@ -1055,7 +1055,7 @@ static int tiva_transmit(FAR struct tiva_ethmac_s *priv)
bufcount = (priv->dev.d_len + (OPTIMAL_EMAC_BUFSIZE-1)) / OPTIMAL_EMAC_BUFSIZE;
lastsize = priv->dev.d_len - (bufcount - 1) * OPTIMAL_EMAC_BUFSIZE;
- nllvdbg("bufcount: %d lastsize: %d\n", bufcount, lastsize);
+ nvdbg("bufcount: %d lastsize: %d\n", bufcount, lastsize);
/* Set the first segment bit in the first TX descriptor */
@@ -1165,8 +1165,8 @@ static int tiva_transmit(FAR struct tiva_ethmac_s *priv)
priv->inflight++;
- nllvdbg("txhead: %p txtail: %p inflight: %d\n",
- priv->txhead, priv->txtail, priv->inflight);
+ nvdbg("txhead: %p txtail: %p inflight: %d\n",
+ priv->txhead, priv->txtail, priv->inflight);
/* If all TX descriptors are in-flight, then we have to disable receive interrupts
* too. This is because receive events can trigger more un-stoppable transmit
@@ -1438,7 +1438,7 @@ static void tiva_freesegment(FAR struct tiva_ethmac_s *priv,
struct emac_rxdesc_s *rxdesc;
int i;
- nllvdbg("rxfirst: %p segments: %d\n", rxfirst, segments);
+ nvdbg("rxfirst: %p segments: %d\n", rxfirst, segments);
/* Set OWN bit in RX descriptors. This gives the buffers back to DMA */
@@ -1496,8 +1496,8 @@ static int tiva_recvframe(FAR struct tiva_ethmac_s *priv)
uint8_t *buffer;
int i;
- nllvdbg("rxhead: %p rxcurr: %p segments: %d\n",
- priv->rxhead, priv->rxcurr, priv->segments);
+ nvdbg("rxhead: %p rxcurr: %p segments: %d\n",
+ priv->rxhead, priv->rxcurr, priv->segments);
/* Check if there are free buffers. We cannot receive new frames in this
* design unless there is at least one free buffer.
@@ -1562,8 +1562,8 @@ static int tiva_recvframe(FAR struct tiva_ethmac_s *priv)
rxcurr = priv->rxcurr;
}
- nllvdbg("rxhead: %p rxcurr: %p segments: %d\n",
- priv->rxhead, priv->rxcurr, priv->segments);
+ nvdbg("rxhead: %p rxcurr: %p segments: %d\n",
+ priv->rxhead, priv->rxcurr, priv->segments);
/* Check if any errors are reported in the frame */
@@ -1601,8 +1601,8 @@ static int tiva_recvframe(FAR struct tiva_ethmac_s *priv)
priv->rxhead = (struct emac_rxdesc_s*)rxdesc->rdes3;
tiva_freesegment(priv, rxcurr, priv->segments);
- nllvdbg("rxhead: %p d_buf: %p d_len: %d\n",
- priv->rxhead, dev->d_buf, dev->d_len);
+ nvdbg("rxhead: %p d_buf: %p d_len: %d\n",
+ priv->rxhead, dev->d_buf, dev->d_len);
return OK;
}
@@ -1628,8 +1628,8 @@ static int tiva_recvframe(FAR struct tiva_ethmac_s *priv)
priv->rxhead = rxdesc;
- nllvdbg("rxhead: %p rxcurr: %p segments: %d\n",
- priv->rxhead, priv->rxcurr, priv->segments);
+ nvdbg("rxhead: %p rxcurr: %p segments: %d\n",
+ priv->rxhead, priv->rxcurr, priv->segments);
return -EAGAIN;
}
@@ -1684,7 +1684,7 @@ static void tiva_receive(FAR struct tiva_ethmac_s *priv)
else if (BUF->type == HTONS(ETHTYPE_IP))
#endif
{
- nllvdbg("IP frame\n");
+ nvdbg("IP frame\n");
/* Handle ARP on input then give the IP packet to uIP */
@@ -1703,7 +1703,7 @@ static void tiva_receive(FAR struct tiva_ethmac_s *priv)
}
else if (BUF->type == htons(ETHTYPE_ARP))
{
- nllvdbg("ARP frame\n");
+ nvdbg("ARP frame\n");
/* Handle ARP packet */
@@ -1761,8 +1761,8 @@ static void tiva_freeframe(FAR struct tiva_ethmac_s *priv)
struct emac_txdesc_s *txdesc;
int i;
- nllvdbg("txhead: %p txtail: %p inflight: %d\n",
- priv->txhead, priv->txtail, priv->inflight);
+ nvdbg("txhead: %p txtail: %p inflight: %d\n",
+ priv->txhead, priv->txtail, priv->inflight);
/* Scan for "in-flight" descriptors owned by the CPU */
@@ -1777,8 +1777,8 @@ static void tiva_freeframe(FAR struct tiva_ethmac_s *priv)
* TX descriptors.
*/
- nllvdbg("txtail: %p tdes0: %08x tdes2: %08x tdes3: %08x\n",
- txdesc, txdesc->tdes0, txdesc->tdes2, txdesc->tdes3);
+ nvdbg("txtail: %p tdes0: %08x tdes2: %08x tdes3: %08x\n",
+ txdesc, txdesc->tdes0, txdesc->tdes2, txdesc->tdes3);
DEBUGASSERT(txdesc->tdes2 != 0);
@@ -1830,8 +1830,8 @@ static void tiva_freeframe(FAR struct tiva_ethmac_s *priv)
priv->txtail = txdesc;
- nllvdbg("txhead: %p txtail: %p inflight: %d\n",
- priv->txhead, priv->txtail, priv->inflight);
+ nvdbg("txhead: %p txtail: %p inflight: %d\n",
+ priv->txhead, priv->txtail, priv->inflight);
}
}
@@ -2390,7 +2390,7 @@ static int tiva_ifdown(struct net_driver_s *dev)
FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)dev->d_private;
irqstate_t flags;
- ndbg("Taking the network down\n");
+ nvdbg("Taking the network down\n");
/* Disable the Ethernet interrupt */
@@ -2440,7 +2440,7 @@ static int tiva_txavail(struct net_driver_s *dev)
FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)dev->d_private;
irqstate_t flags;
- nllvdbg("ifup: %d\n", priv->ifup);
+ nvdbg("ifup: %d\n", priv->ifup);
/* Disable interrupts because this function may be called from interrupt
* level processing.
@@ -2531,8 +2531,8 @@ static int tiva_addmac(struct net_driver_s *dev, FAR const uint8_t *mac)
uint32_t temp;
uint32_t registeraddress;
- nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ nvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
/* Add the MAC address to the hardware multicast hash table */
@@ -2588,8 +2588,8 @@ static int tiva_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac)
uint32_t temp;
uint32_t registeraddress;
- nllvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ nvdbg("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
/* Remove the MAC address to the hardware multicast hash table */
@@ -3047,7 +3047,7 @@ static int tiva_phyinit(FAR struct tiva_ethmac_s *priv)
tiva_phy_release(priv);
- /* Setup up PHY clocking by setting the SR field in the MIIADDR register */
+ /* Setup up PHY clocking by setting the CR field in the MIIADDR register */
regval = tiva_getreg(TIVA_EMAC_MIIADDR);
regval &= ~EMAC_MIIADDR_CR_MASK;
@@ -3375,12 +3375,6 @@ static void tiva_phy_configure(FAR struct tiva_ethmac_s *priv)
static inline void tiva_phy_initialize(FAR struct tiva_ethmac_s *priv)
{
- /* Hold the Ethernet PHY from transmitting energy on the line during
- * configuration by setting the PHYHOLD bit in the EMACPC register.
- */
-
- tiva_phy_hold(priv);
-
/* Enable the clock to the PHY module */
nllvdbg("Enable EPHY clocking\n");
@@ -3405,9 +3399,10 @@ static inline void tiva_phy_initialize(FAR struct tiva_ethmac_s *priv)
while (!tiva_ephy_periphrdy());
up_udelay(250);
- nllvdbg("RCGCEPHY: %08x PREPHY: %08x\n",
- getreg32(TIVA_SYSCON_RCGCEPHY), getreg32(TIVA_SYSCON_PREPHY));
-
+ nllvdbg("RCGCEPHY: %08x PCEPHY: %08x PREPHY: %08x\n",
+ getreg32(TIVA_SYSCON_RCGCEPHY),
+ getreg32(TIVA_SYSCON_PCEPHY),
+ getreg32(TIVA_SYSCON_PREPHY));
nllvdbg("Configure PHY GPIOs\n");
#ifdef CONFIG_TIVA_PHY_INTERNAL
@@ -3581,7 +3576,7 @@ static void tiva_ethreset(FAR struct tiva_ethmac_s *priv)
while (!tiva_emac_periphrdy());
up_udelay(250);
- /* Perform a software reset by setting the SR bit in the DMABUSMOD register.
+ /* Perform a software reset by setting the SWR bit in the DMABUSMOD register.
* This Resets all MAC subsystem internal registers and logic. After this
* reset all the registers holds their reset values.
*/
@@ -3590,7 +3585,7 @@ static void tiva_ethreset(FAR struct tiva_ethmac_s *priv)
regval |= EMAC_DMABUSMOD_SWR;
tiva_putreg(regval, TIVA_EMAC_DMABUSMOD);
- /* Wait for software reset to complete. The SR bit is cleared automatically
+ /* Wait for software reset to complete. The SWR bit is cleared automatically
* after the reset operation has completed in all of the core clock domains.
*/
@@ -3708,11 +3703,11 @@ static void tiva_macaddress(FAR struct tiva_ethmac_s *priv)
FAR struct net_driver_s *dev = &priv->dev;
uint32_t regval;
- nllvdbg("%s MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
- dev->d_ifname,
- dev->d_mac.ether_addr_octet[0], dev->d_mac.ether_addr_octet[1],
- dev->d_mac.ether_addr_octet[2], dev->d_mac.ether_addr_octet[3],
- dev->d_mac.ether_addr_octet[4], dev->d_mac.ether_addr_octet[5]);
+ nvdbg("%s MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ dev->d_ifname,
+ dev->d_mac.ether_addr_octet[0], dev->d_mac.ether_addr_octet[1],
+ dev->d_mac.ether_addr_octet[2], dev->d_mac.ether_addr_octet[3],
+ dev->d_mac.ether_addr_octet[4], dev->d_mac.ether_addr_octet[5]);
/* Set the MAC address high register */
@@ -3827,12 +3822,12 @@ static int tive_emac_configure(FAR struct tiva_ethmac_s *priv)
/* Reset the Ethernet block */
- nllvdbg("Reset the Ethernet block\n");
+ nvdbg("Reset the Ethernet block\n");
tiva_ethreset(priv);
/* Initialize the PHY */
- nllvdbg("Initialize the PHY\n");
+ nvdbg("Initialize the PHY\n");
ret = tiva_phyinit(priv);
if (ret < 0)
{
@@ -3841,7 +3836,7 @@ static int tive_emac_configure(FAR struct tiva_ethmac_s *priv)
/* Initialize the MAC and DMA */
- nllvdbg("Initialize the MAC and DMA\n");
+ nvdbg("Initialize the MAC and DMA\n");
ret = tiva_macconfig(priv);
if (ret < 0)
{
@@ -3862,7 +3857,7 @@ static int tive_emac_configure(FAR struct tiva_ethmac_s *priv)
/* Enable normal MAC operation */
- nllvdbg("Enable normal operation\n");
+ nvdbg("Enable normal operation\n");
return tiva_macenable(priv);
}
@@ -3955,12 +3950,16 @@ int tiva_ethinitialize(int intf)
while (!tiva_emac_periphrdy());
up_udelay(250);
- nllvdbg("RCGCEMAC: %08x PREMAC: %08x\n",
- getreg32(TIVA_SYSCON_RCGCEMAC), getreg32(TIVA_SYSCON_PREMAC));
+ /* Show all EMAC clocks */
+
+ nllvdbg("RCGCEMAC: %08x PCEMAC: %08x PREMAC: %08x MOSCCTL: %08x\n",
+ getreg32(TIVA_SYSCON_RCGCEMAC),
+ getreg32(TIVA_SYSCON_PCEMAC),
+ getreg32(TIVA_SYSCON_PREMAC),
+ getreg32(TIVA_SYSCON_MOSCCTL));
- /* Configure GPIOs to support the internal/eternal PHY */
+ /* Configure clocking and GPIOs to support the internal/eternal PHY */
- nllvdbg("Calling tiva_phy_initialize\n");
tiva_phy_initialize(priv);
/* Attach the IRQ to the driver */
@@ -3972,17 +3971,21 @@ int tiva_ethinitialize(int intf)
return -EAGAIN;
}
+ /* Wait for EMAC to come out of reset. The SWR bit is cleared automatically
+ * after the reset operation has completed in all of the core clock domains.
+ */
+
+ while ((tiva_getreg(TIVA_EMAC_DMABUSMOD) & EMAC_DMABUSMOD_SWR) != 0);
+ up_udelay(250);
+
/* Put the interface in the down state. */
- nllvdbg("Calling tiva_ifdown\n");
tiva_ifdown(&priv->dev);
/* Register the device with the OS so that socket IOCTLs can be performed */
nllvdbg("Registering Ethernet device\n");
- (void)netdev_register(&priv->dev, NET_LL_ETHERNET);
-
- return OK;
+ return netdev_register(&priv->dev, NET_LL_ETHERNET);
}
/****************************************************************************