mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 23:40:19 +08:00
SAMA5 EMAC: Add some need D-Cache Flush/Invalidate operations. Add support for CONFIG_NET_DUMPPACKET
This commit is contained in:
@@ -215,7 +215,11 @@
|
|||||||
# undef CONFIG_SAMA5_EMAC_REGDEBUG
|
# undef CONFIG_SAMA5_EMAC_REGDEBUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Clocking *****************************************************************/
|
#ifdef CONFIG_NET_DUMPPACKET
|
||||||
|
# define sam_dumppacket(m,a,n) lib_dumpbuffer(m,a,n)
|
||||||
|
#else
|
||||||
|
# define sam_dumppacket(m,a,n)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Timing *******************************************************************/
|
/* Timing *******************************************************************/
|
||||||
/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per
|
/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per
|
||||||
@@ -695,6 +699,7 @@ static int sam_transmit(struct sam_emac_s *priv)
|
|||||||
uint32_t status;
|
uint32_t status;
|
||||||
|
|
||||||
nllvdbg("d_len: %d txhead: %d\n", dev->d_len, priv->txhead);
|
nllvdbg("d_len: %d txhead: %d\n", dev->d_len, priv->txhead);
|
||||||
|
sam_dumppacket("Transmit packet", dev->d_buf, dev->d_len);
|
||||||
|
|
||||||
/* Check parameter */
|
/* Check parameter */
|
||||||
|
|
||||||
@@ -724,7 +729,7 @@ static int sam_transmit(struct sam_emac_s *priv)
|
|||||||
|
|
||||||
virtaddr = sam_virtramaddr(txdesc->addr);
|
virtaddr = sam_virtramaddr(txdesc->addr);
|
||||||
memcpy((void *)virtaddr, dev->d_buf, dev->d_len);
|
memcpy((void *)virtaddr, dev->d_buf, dev->d_len);
|
||||||
cp15_flush_dcache((uint32_t)virtaddr, ((uint32_t)virtaddr + dev->d_len));
|
cp15_clean_dcache((uint32_t)virtaddr, (uint32_t)virtaddr + dev->d_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update TX descriptor status. */
|
/* Update TX descriptor status. */
|
||||||
@@ -735,7 +740,11 @@ static int sam_transmit(struct sam_emac_s *priv)
|
|||||||
status |= EMACTXD_STA_WRAP;
|
status |= EMACTXD_STA_WRAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update the descriptor status and flush the updated value to RAM */
|
||||||
|
|
||||||
txdesc->status = status;
|
txdesc->status = status;
|
||||||
|
cp15_clean_dcache((uint32_t)txdesc,
|
||||||
|
(uint32_t)txdesc + sizeof(struct emac_txdesc_s));
|
||||||
|
|
||||||
/* Increment the head index */
|
/* Increment the head index */
|
||||||
|
|
||||||
@@ -867,7 +876,9 @@ static void sam_dopoll(struct sam_emac_s *priv)
|
|||||||
* further packets available
|
* further packets available
|
||||||
*
|
*
|
||||||
* Assumptions:
|
* Assumptions:
|
||||||
* Global interrupts are disabled by interrupt handling logic.
|
* - Global interrupts are disabled by interrupt handling logic.
|
||||||
|
* - The RX descriptor D-cache list has been invalided to force fetching
|
||||||
|
* from RAM.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
@@ -894,7 +905,12 @@ static int sam_recvframe(struct sam_emac_s *priv)
|
|||||||
rxdesc = &priv->rxdesc[rxndx];
|
rxdesc = &priv->rxdesc[rxndx];
|
||||||
isframe = false;
|
isframe = false;
|
||||||
|
|
||||||
nllvdbg("rxndx: %d: %d\n", rxndx);
|
/* Invalidate the RX descriptor to force re-fetching from RAM */
|
||||||
|
|
||||||
|
cp15_invalidate_dcache((uintptr_t)rxdesc,
|
||||||
|
(uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s));
|
||||||
|
|
||||||
|
nllvdbg("rxndx: %d\n", rxndx);
|
||||||
|
|
||||||
while ((rxdesc->addr & EMACRXD_ADDR_OWNER) != 0)
|
while ((rxdesc->addr & EMACRXD_ADDR_OWNER) != 0)
|
||||||
{
|
{
|
||||||
@@ -908,9 +924,17 @@ static int sam_recvframe(struct sam_emac_s *priv)
|
|||||||
|
|
||||||
while (rxndx != priv->rxndx)
|
while (rxndx != priv->rxndx)
|
||||||
{
|
{
|
||||||
|
/* Give ownership back to the EMAC */
|
||||||
|
|
||||||
rxdesc = &priv->rxdesc[priv->rxndx];
|
rxdesc = &priv->rxdesc[priv->rxndx];
|
||||||
rxdesc->addr &= ~(EMACRXD_ADDR_OWNER);
|
rxdesc->addr &= ~(EMACRXD_ADDR_OWNER);
|
||||||
|
|
||||||
|
/* Flush the modified RX descriptor to RAM */
|
||||||
|
|
||||||
|
cp15_clean_dcache((uintptr_t)rxdesc,
|
||||||
|
(uintptr_t)rxdesc +
|
||||||
|
sizeof(struct emac_rxdesc_s));
|
||||||
|
|
||||||
/* Increment the RX index */
|
/* Increment the RX index */
|
||||||
|
|
||||||
if (++priv->rxndx >= CONFIG_SAMA5_EMAC_NRXBUFFERS)
|
if (++priv->rxndx >= CONFIG_SAMA5_EMAC_NRXBUFFERS)
|
||||||
@@ -945,9 +969,17 @@ static int sam_recvframe(struct sam_emac_s *priv)
|
|||||||
nllvdbg("ERROR: No EOF (Invalid of buffers too small)\n");
|
nllvdbg("ERROR: No EOF (Invalid of buffers too small)\n");
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
/* Give ownership back to the EMAC */
|
||||||
|
|
||||||
rxdesc = &priv->rxdesc[priv->rxndx];
|
rxdesc = &priv->rxdesc[priv->rxndx];
|
||||||
rxdesc->addr &= ~(EMACRXD_ADDR_OWNER);
|
rxdesc->addr &= ~(EMACRXD_ADDR_OWNER);
|
||||||
|
|
||||||
|
/* Flush the modified RX descriptor to RAM */
|
||||||
|
|
||||||
|
cp15_clean_dcache((uintptr_t)rxdesc,
|
||||||
|
(uintptr_t)rxdesc +
|
||||||
|
sizeof(struct emac_rxdesc_s));
|
||||||
|
|
||||||
/* Increment the RX index */
|
/* Increment the RX index */
|
||||||
|
|
||||||
if (++priv->rxndx >= CONFIG_SAMA5_EMAC_NRXBUFFERS)
|
if (++priv->rxndx >= CONFIG_SAMA5_EMAC_NRXBUFFERS)
|
||||||
@@ -974,7 +1006,7 @@ static int sam_recvframe(struct sam_emac_s *priv)
|
|||||||
physaddr = (uintptr_t)(rxdesc->addr & EMACRXD_ADDR_MASK);
|
physaddr = (uintptr_t)(rxdesc->addr & EMACRXD_ADDR_MASK);
|
||||||
src = (const uint8_t *)sam_virtramaddr(physaddr);
|
src = (const uint8_t *)sam_virtramaddr(physaddr);
|
||||||
|
|
||||||
cp15_invalidate_dcache((uintptr_t)src, copylen);
|
cp15_invalidate_dcache((uintptr_t)src, (uintptr_t)src + copylen);
|
||||||
|
|
||||||
/* And do the copy */
|
/* And do the copy */
|
||||||
|
|
||||||
@@ -997,9 +1029,17 @@ static int sam_recvframe(struct sam_emac_s *priv)
|
|||||||
|
|
||||||
while (priv->rxndx != rxndx)
|
while (priv->rxndx != rxndx)
|
||||||
{
|
{
|
||||||
|
/* Give ownership back to the EMAC */
|
||||||
|
|
||||||
rxdesc = &priv->rxdesc[priv->rxndx];
|
rxdesc = &priv->rxdesc[priv->rxndx];
|
||||||
rxdesc->addr &= ~(EMACRXD_ADDR_OWNER);
|
rxdesc->addr &= ~(EMACRXD_ADDR_OWNER);
|
||||||
|
|
||||||
|
/* Flush the modified RX descriptor to RAM */
|
||||||
|
|
||||||
|
cp15_clean_dcache((uintptr_t)rxdesc,
|
||||||
|
(uintptr_t)rxdesc +
|
||||||
|
sizeof(struct emac_rxdesc_s));
|
||||||
|
|
||||||
/* Increment the RX index */
|
/* Increment the RX index */
|
||||||
|
|
||||||
if (++priv->rxndx >= CONFIG_SAMA5_EMAC_NRXBUFFERS)
|
if (++priv->rxndx >= CONFIG_SAMA5_EMAC_NRXBUFFERS)
|
||||||
@@ -1024,17 +1064,31 @@ static int sam_recvframe(struct sam_emac_s *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have not encount the SOF yet... discard this frament and keep looking */
|
/* We have not encount the SOF yet... discard this fragment and keep looking */
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Give ownership back to the EMAC */
|
||||||
|
|
||||||
rxdesc->addr &= ~(EMACRXD_ADDR_OWNER);
|
rxdesc->addr &= ~(EMACRXD_ADDR_OWNER);
|
||||||
|
|
||||||
|
/* Flush the modified RX descriptor to RAM */
|
||||||
|
|
||||||
|
cp15_clean_dcache((uintptr_t)rxdesc,
|
||||||
|
(uintptr_t)rxdesc +
|
||||||
|
sizeof(struct emac_rxdesc_s));
|
||||||
|
|
||||||
priv->rxndx = rxndx;
|
priv->rxndx = rxndx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process the next buffer */
|
/* Process the next buffer */
|
||||||
|
|
||||||
rxdesc = &priv->rxdesc[rxndx];
|
rxdesc = &priv->rxdesc[rxndx];
|
||||||
|
|
||||||
|
/* Invalidate the RX descriptor to force re-fetching from RAM */
|
||||||
|
|
||||||
|
cp15_invalidate_dcache((uintptr_t)rxdesc,
|
||||||
|
(uintptr_t)rxdesc + sizeof(struct emac_rxdesc_s));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No packet was found */
|
/* No packet was found */
|
||||||
@@ -1072,6 +1126,8 @@ static void sam_receive(struct sam_emac_s *priv)
|
|||||||
|
|
||||||
while (sam_recvframe(priv) == OK)
|
while (sam_recvframe(priv) == OK)
|
||||||
{
|
{
|
||||||
|
sam_dumppacket("Received packet", dev->d_buf, dev->d_len);
|
||||||
|
|
||||||
/* Check if the packet is a valid size for the uIP buffer configuration
|
/* Check if the packet is a valid size for the uIP buffer configuration
|
||||||
* (this should not happen)
|
* (this should not happen)
|
||||||
*/
|
*/
|
||||||
@@ -2539,6 +2595,12 @@ static void sam_rxreset(struct sam_emac_s *priv)
|
|||||||
|
|
||||||
rxdesc[CONFIG_SAMA5_EMAC_NRXBUFFERS - 1].addr |= EMACRXD_ADDR_WRAP;
|
rxdesc[CONFIG_SAMA5_EMAC_NRXBUFFERS - 1].addr |= EMACRXD_ADDR_WRAP;
|
||||||
|
|
||||||
|
/* Flush the entire RX descriptor table to RAM */
|
||||||
|
|
||||||
|
cp15_clean_dcache((uintptr_t)rxdesc,
|
||||||
|
(uintptr_t)rxdesc +
|
||||||
|
CONFIG_SAMA5_EMAC_NRXBUFFERS * sizeof(struct emac_rxdesc_s));
|
||||||
|
|
||||||
/* Set the Receive Buffer Queue Pointer Register */
|
/* Set the Receive Buffer Queue Pointer Register */
|
||||||
|
|
||||||
physaddr = sam_physramaddr((uint32_t)rxdesc);
|
physaddr = sam_physramaddr((uint32_t)rxdesc);
|
||||||
|
|||||||
Reference in New Issue
Block a user