SAMA5D4 EMAC: Add a kludge to work around a suspected hardware issue

This commit is contained in:
Gregory Nutt 2014-07-02 12:17:01 -06:00
parent 5bac493ac3
commit 1c198f6a86
2 changed files with 63 additions and 3 deletions

View File

@ -1402,10 +1402,10 @@ static int sam_recvframe(struct sam_emac_s *priv)
*/
nllvdbg("rxndx: %d d_len: %d\n", priv->rxndx, dev->d_len);
if (pktlen < dev->d_len)
{
nlldbg("ERROR: Buffer size %d; frame size %d\n", dev->d_len, pktlen);
nlldbg("ERROR: Buffer size %d; frame size %d\n",
dev->d_len, pktlen);
return -E2BIG;
}
@ -1558,6 +1558,9 @@ static void sam_receive(struct sam_emac_s *priv)
static void sam_txdone(struct sam_emac_s *priv)
{
struct emac_txdesc_s *txdesc;
#ifndef __NO_KLUDGES__
int ntxdone = 0;
#endif
/* Are there any outstanding transmissions? Loop until either (1) all of
* the TX descriptors have been examined, or (2) until we encounter the
@ -1574,7 +1577,20 @@ static void sam_txdone(struct sam_emac_s *priv)
/* Is this TX descriptor still in use? */
#ifndef __NO_KLUDGES__
# warning REVISIT
/* I have seen cases where we receive interrupts, but the USED
* bit is never set in the TX descriptor. This logic assumes
* that if we got the interrupt, then there most be at least
* one packet that completed. This is not necessarily a safe
* assumption.
*/
ntxdone++;
if ((txdesc->status & EMACTXD_STA_USED) == 0 && ntxdone > 1)
#else
if ((txdesc->status & EMACTXD_STA_USED) == 0)
#endif
{
/* Yes.. the descriptor is still in use. However, I have seen a
* case (only repeatable on start-up) where the USED bit is never
@ -1603,6 +1619,14 @@ static void sam_txdone(struct sam_emac_s *priv)
}
}
#ifndef __NO_KLUDGES__
/* Make sure that the USED bit is set */
txdesc->status = (uint32_t)EMACTXD_STA_USED;
cp15_clean_dcache((uintptr_t)txdesc,
(uintptr_t)txdesc + sizeof(struct emac_txdesc_s));
#endif
/* Increment the tail index */
if (++priv->txtail >= priv->attr->ntxbuffers)

View File

@ -1124,6 +1124,9 @@ Networking
configuration options. The SAMA5D44 supports two different 10/100Base-T
Ethernet MAC peripherals.
NOTE: See the "kludge" for EMAC that is documented in the To-Do
list at the end of this README file.
------------------------------ ------------------- -------------------------
SAMA5D4 PIO SAMA5D4-MB KSZ8081RNB
------------------------------ ------------------- -------------------------
@ -3392,6 +3395,9 @@ Configurations
large if no network is attached (A production design would bring up
the network asynchronously to avoid these start up delays).
See the "kludge" for EMAC that is documented in the To-Do list at
the end of this README file.
12. The SAMA5D4-EK includes for an AT25 serial DataFlash. That support is
NOT enabled in this configuration. Support for that serial FLASH can
be enabled by modifying the NuttX configuration as described above in
@ -3492,7 +3498,37 @@ To-Do List
Also, we should be receiving interrupts when an SD card is inserted or
removed; we are not.
4) Some drivers may require some adjustments if you intend to run from SDRAM.
4) There is a kludge in place in the Ethernet code to work around a problem
that I see. The problem that I see is as follows:
a. To send packets, the software keeps a queue of TX descriptors in
memory.
b. When a packet is ready to be sent, the software clears bit 31 of a
status word in the descriptor meaning that the descriptor now
"belongs" to the hardware.
c. The hardware sets bit 31 in memory when the transfer completes.
The problem that I see is that:
d. Occasionally bit 31 of the status word is not cleared even though
the Ethernet packet was successfully sent.
Since the software does not see bit 31 set, it seems like the transfer
did not complete and the Ethernet locks up.
The workaround/kludge that is in place makes this assumption: If an
Ethernet transfer complete interrupt is received, then at least one
packet must have completed. In this case, the software ignores
checking the USED bit for one packet.
With this kludge in place, the driver appears to work fine. However,
there is a danger to what I have done: If a spurious interrupt
occurs, than the USED bit would not be set and the transfer would be
lost.
5) Some drivers may require some adjustments if you intend to run from SDRAM.
That is because in this case macros like BOARD_MCK_FREQUENCY are not constants
but are instead function calls: The MCK clock frequency is not known in
advance but instead has to be calculated from the bootloader PLL configuration.