Hi Darius, On Wed, Oct 21, 2015 at 11:22:30AM +0300, Darius Babrauskas wrote: > > (...) > > – there is a transmit error such as too many retries or a transmit > under run. > > (...)
I have two patches against the AVR32 MACB driver in my tree, and it look like it might fix your issues. - macb-nonblocking-asf-3.5.1-0000.patch The MACB driver does not set the correct speed/duplex from MAC to PHY in case of speed/duplex link change (i.e. if the remote device is replaced or if a damaged cable make a negotiation restart and set the speed from 100 to 10). Here is my patch against ASF 3.5.1 which fixes this issue as well as being non blocking if ETHERNET_CONF_USE_PHY_IT is set, otherwise it behaves the same as before. It is working with or without FreeRTOS. It was discussed on the avrfreaks forum[1]. - 0001-fixed-crash-if-MACB-failed-to-sent-a-frame-a-failed-.patch Fix a crash if MACB failed to sent a frame, a failed frame does not set the USED/OK bit, so the current implementation locked the circular buffer Hope it helps ! :) Sylvain [1] http://www.avrfreaks.net/forum/non-blocking-asf-macb-driver
Date: Fri, 22 Feb 2013 14:15:06 +0000
Subject: [PATCH] fixed crash if MACB failed to sent a frame, a failed
frame does not set the USED/OK bit, so the current implementation locked the
circular buffer
---
src/asf/avr32/drivers/macb/macb.c | 32 +++++++++++++++-----------------
1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/src/asf/avr32/drivers/macb/macb.c b/src/asf/avr32/drivers/macb/macb.c
index ac07afe..4fe19e3 100644
--- a/src/asf/avr32/drivers/macb/macb.c
+++ b/src/asf/avr32/drivers/macb/macb.c
@@ -572,30 +572,28 @@ void vClearMACBTxBuffer(void)
// Tx buffer within the frame just transmitted. This marks all the buffers
// as available again.
- // The first buffer in the frame should have the bit set automatically. */
- if( xTxDescriptors[ uxNextBufferToClear ].U_Status.status & AVR32_TRANSMIT_OK )
- {
- // Loop through the other buffers in the frame.
- while( !( xTxDescriptors[ uxNextBufferToClear ].U_Status.status & AVR32_LAST_BUFFER ) )
- {
- uxNextBufferToClear++;
-
- if( uxNextBufferToClear >= ETHERNET_CONF_NB_TX_BUFFERS )
- {
- uxNextBufferToClear = 0;
- }
-
- xTxDescriptors[ uxNextBufferToClear ].U_Status.status |= AVR32_TRANSMIT_OK;
- }
+ xTxDescriptors[ uxNextBufferToClear ].U_Status.status |= AVR32_TRANSMIT_OK;
- // Start with the next buffer the next time a Tx interrupt is called.
+ // Loop through the other buffers in the frame.
+ while( !( xTxDescriptors[ uxNextBufferToClear ].U_Status.status & AVR32_LAST_BUFFER ) )
+ {
uxNextBufferToClear++;
- // Do we need to wrap back to the first buffer?
if( uxNextBufferToClear >= ETHERNET_CONF_NB_TX_BUFFERS )
{
uxNextBufferToClear = 0;
}
+
+ xTxDescriptors[ uxNextBufferToClear ].U_Status.status |= AVR32_TRANSMIT_OK;
+ }
+
+ // Start with the next buffer the next time a Tx interrupt is called.
+ uxNextBufferToClear++;
+
+ // Do we need to wrap back to the first buffer?
+ if( uxNextBufferToClear >= ETHERNET_CONF_NB_TX_BUFFERS )
+ {
+ uxNextBufferToClear = 0;
}
}
--
2.5.1
Index: src/asf/avr32/drivers/macb/macb.c
===================================================================
--- src/asf/avr32/drivers/macb/macb.c (revision 307)
+++ src/asf/avr32/drivers/macb/macb.c (working copy)
@@ -782,11 +782,67 @@
macb->ncr &= ~AVR32_MACB_NCR_MPE_MASK;
}
+static void prvSetupMACBConfig(volatile avr32_macb_t *macb)
+{
+ volatile unsigned long lpa, config, advertise;
+
+ // read the LPA configuration of the PHY
+ lpa = ulReadMDIO(macb, PHY_LPA);
+
+ // read the MACB config register
+ config = macb->ncfgr;
+
+ // set advertise register
+#if ETHERNET_CONF_AN_ENABLE == 1
+ advertise = ADVERTISE_CSMA | ADVERTISE_ALL;
+#else
+ advertise = ADVERTISE_CSMA;
+ #if ETHERNET_CONF_USE_100MB
+ #if ETHERNET_CONF_USE_FULL_DUPLEX
+ advertise |= ADVERTISE_100FULL;
+ #else
+ advertise |= ADVERTISE_100HALF;
+ #endif
+ #else
+ #if ETHERNET_CONF_USE_FULL_DUPLEX
+ advertise |= ADVERTISE_10FULL;
+ #else
+ advertise |= ADVERTISE_10HALF;
+ #endif
+ #endif
+#endif
+
+ // if 100MB needed
+ if ((lpa & advertise) & (LPA_100HALF | LPA_100FULL))
+ {
+ config |= AVR32_MACB_SPD_MASK;
+ }
+ else
+ {
+ config &= ~(AVR32_MACB_SPD_MASK);
+ }
+
+ // if FULL DUPLEX needed
+ if ((lpa & advertise) & (LPA_10FULL | LPA_100FULL))
+ {
+ config |= AVR32_MACB_FD_MASK;
+ }
+ else
+ {
+ config &= ~(AVR32_MACB_FD_MASK);
+ }
+
+ // write the MACB config register
+ macb->ncfgr = config;
+}
+
static bool prvProbePHY(volatile avr32_macb_t *macb)
{
+#if ETHERNET_CONF_USE_PHY_IT == 0
volatile unsigned long mii_status;
+#endif /* ETHERNET_CONF_USE_PHY_IT == 0 */
volatile unsigned long config;
- unsigned long upper, lower, advertise, lpa;
+ unsigned long upper, lower, advertise;
volatile unsigned long physID;
// Read Phy Identifier register 1 & 2
@@ -832,40 +888,15 @@
// update ctrl register
vWriteMDIO(macb, PHY_BMCR, config);
+#if ETHERNET_CONF_USE_PHY_IT == 0
// loop while link status isn't OK
do {
mii_status = ulReadMDIO(macb, PHY_BMSR);
} while (!(mii_status & BMSR_LSTATUS));
- // read the LPA configuration of the PHY
- lpa = ulReadMDIO(macb, PHY_LPA);
+ prvSetupMACBConfig(macb);
+#endif /* ETHERNET_CONF_USE_PHY_IT == 0 */
- // read the MACB config register
- config = AVR32_MACB.ncfgr;
-
- // if 100MB needed
- if ((lpa & advertise) & (LPA_100HALF | LPA_100FULL))
- {
- config |= AVR32_MACB_SPD_MASK;
- }
- else
- {
- config &= ~(AVR32_MACB_SPD_MASK);
- }
-
- // if FULL DUPLEX needed
- if ((lpa & advertise) & (LPA_10FULL | LPA_100FULL))
- {
- config |= AVR32_MACB_FD_MASK;
- }
- else
- {
- config &= ~(AVR32_MACB_FD_MASK);
- }
-
- // write the MACB config register
- macb->ncfgr = config;
-
return true;
}
return false;
@@ -1045,6 +1076,10 @@
// dummy read
ulEventStatus = ulReadMDIO(&AVR32_MACB, PHY_BMSR);
+ if(ulEventStatus & BMSR_LSTATUS) {
+ prvSetupMACBConfig(&AVR32_MACB);
+ }
+
// clear interrupt flag on GPIO
gpio_port->ifrc = 1 << (EXTPHY_MACB_INTERRUPT_PIN%32);
signature.asc
Description: Digital signature
_______________________________________________ lwip-users mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/lwip-users
