Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/Hardware/SAME5x/Ethernet/GmacInterface.cpp')
-rw-r--r--src/Hardware/SAME5x/Ethernet/GmacInterface.cpp137
1 files changed, 67 insertions, 70 deletions
diff --git a/src/Hardware/SAME5x/Ethernet/GmacInterface.cpp b/src/Hardware/SAME5x/Ethernet/GmacInterface.cpp
index 2f6a5988..b2c4ebc3 100644
--- a/src/Hardware/SAME5x/Ethernet/GmacInterface.cpp
+++ b/src/Hardware/SAME5x/Ethernet/GmacInterface.cpp
@@ -27,6 +27,8 @@ extern "C" {
#include <RepRapFirmware.h>
#include <RTOSIface/RTOSIface.h>
#include <Platform/TaskPriorities.h>
+#include <Platform/RepRap.h>
+#include <Platform/Platform.h>
extern Mutex lwipMutex;
@@ -39,11 +41,12 @@ constexpr size_t EthernetTaskStackWords = 300;
static Task<EthernetTaskStackWords> ethernetTask;
// Error counters
-unsigned int rxErrorCount;
-unsigned int rxBuffersNotFullyPopulatedCount;
-unsigned int txErrorCount;
-unsigned int txBufferNotFreeCount;
-unsigned int txBufferTooShortCount;
+static unsigned int rxErrorCount = 0;
+static unsigned int rxBuffersNotFullyPopulatedCount = 0;
+static unsigned int rxBufferNotAvailableCount = 0;
+static unsigned int txErrorCount = 0;
+static unsigned int txBufferNotFreeCount = 0;
+static unsigned int txBufferTooShortCount = 0;
/** Network interface identifier. */
#define IFNAME0 'e'
@@ -160,7 +163,7 @@ static void gmac_rx_populate_queue(struct gmac_device *p_gmac_dev, uint32_t star
if (p_gmac_dev->rx_pbuf[ul_index] == nullptr)
{
/* Allocate a new pbuf with the maximum size. */
- pbuf * const p = pbuf_alloc(PBUF_RAW, (u16_t) GMAC_FRAME_LENTGH_MAX, PBUF_POOL);
+ pbuf * const p = pbuf_alloc(PBUF_RAW, (u16_t) GMAC_FRAME_LENGTH_MAX, PBUF_POOL);
if (p == nullptr)
{
LWIP_DEBUGF(NETIF_DEBUG, ("gmac_rx_populate_queue: pbuf allocation failure\n"));
@@ -173,28 +176,18 @@ static void gmac_rx_populate_queue(struct gmac_device *p_gmac_dev, uint32_t star
LWIP_ASSERT("gmac_rx_populate_queue: pbuf size too small!", pbuf_clen(p) <= 1);
/* Make sure that the payload buffer is properly aligned. */
- LWIP_ASSERT("gmac_rx_populate_queue: unaligned p->payload buffer address",
- (((uint32_t)p->payload & 0xFFFFFFFC) == (uint32_t)p->payload));
-
- // dc42 do this first to avoid a race condition with DMA, because writing addr.val transfers ownership back to the GMAC, so it should be the last thing we do
- /* Reset status value. */
- p_gmac_dev->rx_desc[ul_index].status.val = 0;
+ LWIP_ASSERT("gmac_rx_populate_queue: unaligned p->payload buffer address", (((uint32_t)p->payload & 0xFFFFFFFC) == (uint32_t)p->payload));
/* Save pbuf pointer to be sent to lwIP upper layer. */
p_gmac_dev->rx_pbuf[ul_index] = p;
- if (ul_index == GMAC_RX_BUFFERS - 1)
- {
- p_gmac_dev->rx_desc[ul_index].addr.val = (u32_t) p->payload | GMAC_RXD_WRAP;
- }
- else
- {
- p_gmac_dev->rx_desc[ul_index].addr.val = (u32_t) p->payload;
- }
+ // dc42 do this first to avoid a race condition with DMA, because writing addr.val transfers ownership back to the GMAC, so it should be the last thing we do
+ p_gmac_dev->rx_desc[ul_index].status.val = 0; // reset status value
+
+ __DSB();
+ p_gmac_dev->rx_desc[ul_index].addr.val = (ul_index == GMAC_RX_BUFFERS - 1) ? (u32_t) p->payload | GMAC_RXD_WRAP : (u32_t) p->payload;
Cache::FlushBeforeDMASend(&p_gmac_dev->rx_desc[ul_index], sizeof(p_gmac_dev->rx_desc[ul_index]));
- LWIP_DEBUGF(NETIF_DEBUG,
- ("gmac_rx_populate_queue: new pbuf allocated: %p [idx=%u]\n",
- p, (unsigned int)ul_index));
+ LWIP_DEBUGF(NETIF_DEBUG, ("gmac_rx_populate_queue: new pbuf allocated: %p [idx=%u]\n", p, (unsigned int)ul_index));
}
++ul_index;
@@ -258,9 +251,13 @@ static void gmac_tx_init(struct gmac_device *ps_gmac_dev) noexcept
ps_gmac_dev->tx_desc[ul_index].status.val = GMAC_TXD_USED | GMAC_TXD_LAST;
}
ps_gmac_dev->tx_desc[ul_index - 1].status.val |= GMAC_TXD_WRAP;
+ Cache::FlushBeforeDMASend(ps_gmac_dev->tx_desc, sizeof(ps_gmac_dev->tx_desc));
/* Set transmit buffer queue base address pointer. */
gmac_set_tx_queue(GMAC, (uint32_t) &ps_gmac_dev->tx_desc[0]);
+
+ /* Clear error status. */
+ gmac_clear_tx_status(GMAC, GMAC_TX_ERRORS);
}
/**
@@ -308,16 +305,8 @@ static void gmac_low_level_init(struct netif *netif) noexcept
* an err_t value if the packet couldn't be sent.
*/
-#include <General/Portability.h>
static err_t gmac_low_level_output(netif *p_netif, struct pbuf *p) noexcept
{
-#if 0
- debugPrintf("%u %u %" PRIu32 "\n",
- LoadBE16((const uint8_t*)p->payload + 0x24), // destination port
- LoadBE16((const uint8_t*)p->payload + 0x10), // length
- LoadBE32((const uint8_t*)p->payload + 0x26) // sequence number
- );
-#endif
gmac_device *const ps_gmac_dev = static_cast<gmac_device *>(p_netif->state);
while (true)
@@ -334,10 +323,7 @@ static err_t gmac_low_level_output(netif *p_netif, struct pbuf *p) noexcept
LINK_STATS_INC(link.drop);
/* Reinit TX descriptors. */
- gmac_tx_init(ps_gmac_dev);
-
- /* Clear error status. */
- gmac_clear_tx_status(GMAC, GMAC_TX_ERRORS);
+ gmac_tx_init(ps_gmac_dev); // this also clears the Tx errors
gmac_enable_transmit(GMAC, true);
}
@@ -397,11 +383,11 @@ static err_t gmac_low_level_output(netif *p_netif, struct pbuf *p) noexcept
* \param netif the lwIP network interface structure for this ethernetif.
*
* \return a pbuf filled with the received packet (including MAC header).
- * 0 on memory error.
+ * nullptr if no received packet available.
*/
static pbuf *gmac_low_level_input(struct netif *netif) noexcept
{
- gmac_device *ps_gmac_dev = static_cast<gmac_device *>(netif->state);
+ gmac_device *const ps_gmac_dev = static_cast<gmac_device *>(netif->state);
if (gmac_get_rx_status(GMAC) & GMAC_RX_ERRORS)
{
@@ -432,44 +418,55 @@ static pbuf *gmac_low_level_input(struct netif *netif) noexcept
return nullptr;
}
- volatile gmac_rx_descriptor_t * const p_rx = &ps_gmac_dev->rx_desc[ps_gmac_dev->us_rx_idx];
+ if (gmac_get_rx_status(GMAC) & GMAC_RSR_BNA)
+ {
+ ++rxBufferNotAvailableCount;
+ gmac_clear_rx_status(GMAC, GMAC_RSR_BNA);
+ }
+
+ /* Check if a packet has been received and processed by GMAC. */
+ uint32_t rxIdx = ps_gmac_dev->us_rx_idx;
+ volatile gmac_rx_descriptor_t * const p_rx = &ps_gmac_dev->rx_desc[rxIdx];
Cache::InvalidateAfterDMAReceive(p_rx, sizeof(gmac_rx_descriptor_t));
- pbuf * const p = ((p_rx->addr.val & GMAC_RXD_OWNERSHIP) == GMAC_RXD_OWNERSHIP)
- ? ps_gmac_dev->rx_pbuf[ps_gmac_dev->us_rx_idx]
+ pbuf * p = ((p_rx->addr.val & GMAC_RXD_OWNERSHIP) != 0)
+ ? ps_gmac_dev->rx_pbuf[rxIdx]
: nullptr;
/* Check if a packet has been received and processed by GMAC. */
if (p != nullptr)
{
- /* Packet is a SOF since packet size is set to maximum. */
- const uint32_t length = p_rx->status.val & GMAC_RXD_LEN_MASK;
+ const uint32_t status = p_rx->status.val;
+ const uint32_t length = status & GMAC_RXD_LEN_MASK;
/* Fetch pre-allocated pbuf. */
Cache::InvalidateAfterDMAReceive(p->payload, length);
- p->len = length;
/* Remove this pbuf from its descriptor. */
- ps_gmac_dev->rx_pbuf[ps_gmac_dev->us_rx_idx] = nullptr;
+ ps_gmac_dev->rx_pbuf[rxIdx] = nullptr;
ps_gmac_dev->rxPbufsFullyPopulated = false;
- LWIP_DEBUGF(NETIF_DEBUG,
- ("gmac_low_level_input: DMA buffer %p received, size=%u [idx=%u]\n",
- p, (unsigned int)length, (unsigned int)ps_gmac_dev->us_rx_idx));
- /* Set pbuf total packet size. */
- p->tot_len = length;
+ p->tot_len = p->len = length;
LINK_STATS_INC(link.recv);
- ps_gmac_dev->us_rx_idx = (ps_gmac_dev->us_rx_idx + 1) % GMAC_RX_BUFFERS;
+ ps_gmac_dev->us_rx_idx = rxIdx = (rxIdx + 1) % GMAC_RX_BUFFERS;
+ if ((status & (GMAC_RXD_SOF | GMAC_RXD_EOF)) == (GMAC_RXD_SOF | GMAC_RXD_EOF))
+ {
#if LWIP_STATS
- lwip_rx_count += length;
+ lwip_rx_count += length;
#endif
+ }
+ else
+ {
+ pbuf_free(p);
+ p = nullptr;
+ }
}
/* Fill empty descriptors with new pbufs. */
if (!ps_gmac_dev->rxPbufsFullyPopulated)
{
- gmac_rx_populate_queue(ps_gmac_dev, ps_gmac_dev->us_rx_idx);
+ gmac_rx_populate_queue(ps_gmac_dev, rxIdx);
}
return p;
@@ -511,20 +508,18 @@ extern "C" [[noreturn]] void gmac_task(void *pvParameters) noexcept
*/
bool ethernetif_input(struct netif *netif) noexcept
{
- struct eth_hdr *ethhdr;
- struct pbuf *p;
-
/* Move received packet into a new pbuf. */
- p = gmac_low_level_input(netif);
+ pbuf *const p = gmac_low_level_input(netif);
if (p == nullptr)
{
return false;
}
/* Points to packet payload, which starts with an Ethernet header. */
- ethhdr = static_cast<struct eth_hdr*>(p->payload);
+ const eth_hdr *ethhdr = static_cast<struct eth_hdr*>(p->payload);
- switch (lwip_htons(ethhdr->type)) {
+ switch (lwip_htons(ethhdr->type))
+ {
case ETHTYPE_IP:
case ETHTYPE_ARP:
#if defined(PPPOE_SUPPORT) && PPPOE_SUPPORT
@@ -532,7 +527,8 @@ bool ethernetif_input(struct netif *netif) noexcept
case ETHTYPE_PPPOE:
#endif /* PPPOE_SUPPORT */
/* Send packet to lwIP for processing. */
- if (netif->input(p, netif) != ERR_OK) {
+ if (netif->input(p, netif) != ERR_OK)
+ {
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
/* Free buffer. */
pbuf_free(p);
@@ -723,12 +719,13 @@ void ethernetif_hardware_init() noexcept
/* Enable the copy of data into the buffers ignore broadcasts, and not copy FCS. */
gmac_enable_copy_all(GMAC, false);
gmac_disable_broadcast(GMAC, false);
+ GMAC->NCR.reg |= GMAC_NCFGR_RXCOEN; // check IP, UDP and TCP checksums so that we don't need to do it in lwip
#if SUPPORT_MULTICAST_DISCOVERY
// Without this code, we don't receive any multicast packets
- GMAC->GMAC_NCFGR |= GMAC_NCFGR_MTIHEN; // enable multicast hash reception
- GMAC->GMAC_HRB = 0xFFFFFFFF; // enable reception of all multicast frames
- GMAC->GMAC_HRT = 0xFFFFFFFF;
+ GMAC->NCR.reg |= GMAC_NCFGR_MTIHEN; // enable multicast hash reception
+ GMAC->HRB.reg = 0xFFFFFFFF; // enable reception of all multicast frames
+ GMAC->HRT.reg = 0xFFFFFFFF;
#endif
/* Set RX buffer size to 1536. */
@@ -758,7 +755,7 @@ void ethernetif_hardware_init() noexcept
bool ethernetif_establish_link() noexcept
{
/* Auto Negotiate, work in RMII mode. */
- uint8_t result = ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
+ const uint8_t result = ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
if (result != GMAC_OK)
{
if (result != GMAC_TIMEOUT)
@@ -769,13 +766,6 @@ bool ethernetif_establish_link() noexcept
return false;
}
- /* Establish ethernet link. */
- if (ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1) != GMAC_OK)
- {
- LWIP_DEBUGF(NETIF_DEBUG, ("gmac_low_level_init: set link ERROR!\n"));
- return false;
- }
-
return true;
}
@@ -825,4 +815,11 @@ extern "C" uint32_t sys_now() noexcept
return millis();
}
+void ethernetif_diagnostics(MessageType mtype) noexcept
+{
+ reprap.GetPlatform().MessageF(mtype, "Error counts: %u %u %u %u %u %u\nSocket states:",
+ rxErrorCount, rxBuffersNotFullyPopulatedCount, rxBufferNotAvailableCount, txErrorCount, txBufferNotFreeCount, txBufferTooShortCount);
+ rxErrorCount = rxBuffersNotFullyPopulatedCount = rxBufferNotAvailableCount = txErrorCount = txBufferNotFreeCount = txBufferTooShortCount = 0;
+}
+
// End