diff options
author | David Crocker <dcrocker@eschertech.com> | 2020-06-16 13:56:31 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2020-06-16 13:56:31 +0300 |
commit | 11293866589245174b8914b304726bb70ffa6a82 (patch) | |
tree | 2ae669fa2aacc318e31b61d8e634d406172b7acb /src/Networking/LwipEthernet/GMAC | |
parent | da9c9f5f56dec2cbf13c2f0cdc1681d11375fa68 (diff) |
Moved SAME70 GMAC files to Hardware/SAME70
Diffstat (limited to 'src/Networking/LwipEthernet/GMAC')
-rw-r--r-- | src/Networking/LwipEthernet/GMAC/ethernet_sam.cpp | 10 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/GMAC/ethernet_sam.h | 5 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/GMAC/same70_gmac.cpp | 797 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/GMAC/same70_gmac.h | 83 |
4 files changed, 11 insertions, 884 deletions
diff --git a/src/Networking/LwipEthernet/GMAC/ethernet_sam.cpp b/src/Networking/LwipEthernet/GMAC/ethernet_sam.cpp index ef0aa4aa..96d6f202 100644 --- a/src/Networking/LwipEthernet/GMAC/ethernet_sam.cpp +++ b/src/Networking/LwipEthernet/GMAC/ethernet_sam.cpp @@ -42,6 +42,10 @@ */ #include "ethernet_sam.h" + +#include <Hardware/SAME70/same70_gmac.h> +#include "lwip/netif.h" + #include <cstring> extern "C" { @@ -166,6 +170,12 @@ void init_ethernet(IPAddress ipAddress, IPAddress netMask, IPAddress gateWay) no netif_set_up(&gs_net_if); } +// Terminate Ethernet and stop any interrupts, tasks etc. Used when shutting down the whole system. +void ethernet_terminate() noexcept +{ + ethernetif_terminate(); +} + /** \brief Configure the Ethernet subsystem. Should be called after init_ethernet() * */ diff --git a/src/Networking/LwipEthernet/GMAC/ethernet_sam.h b/src/Networking/LwipEthernet/GMAC/ethernet_sam.h index 41350fb2..756a2c6c 100644 --- a/src/Networking/LwipEthernet/GMAC/ethernet_sam.h +++ b/src/Networking/LwipEthernet/GMAC/ethernet_sam.h @@ -48,14 +48,11 @@ #include <cstddef> #include <General/IPAddress.h> -#include "same70_gmac.h" -#include "lwip/netif.h" - // Perform low-level initialisation of the network interface void init_ethernet(IPAddress ipAddress, IPAddress netMask, IPAddress gateWay) noexcept; // Terminate Ethernet and stop any interrupts, tasks etc. Used when shutting down the whole system. -inline void ethernet_terminate() noexcept { ethernetif_terminate(); } +void ethernet_terminate() noexcept; // Configure the ethernet interface void ethernet_configure_interface(const uint8_t macAddress[], const char *hostname) noexcept; diff --git a/src/Networking/LwipEthernet/GMAC/same70_gmac.cpp b/src/Networking/LwipEthernet/GMAC/same70_gmac.cpp deleted file mode 100644 index 33212834..00000000 --- a/src/Networking/LwipEthernet/GMAC/same70_gmac.cpp +++ /dev/null @@ -1,797 +0,0 @@ -/** - * \file - * - * \brief GMAC (Gigabit MAC) driver for lwIP. - * - * Copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. - * - * \asf_license_start - * - * \page License - * - * Subject to your compliance with these terms, you may use Microchip - * software and any derivatives exclusively with Microchip products. - * It is your responsibility to comply with third party license terms applicable - * to your use of third party software (including open source software) that - * may accompany Microchip software. - * - * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, - * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, - * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE - * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL - * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE - * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE - * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT - * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY - * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, - * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. - * - * \asf_license_stop - * - */ - -#include "same70_gmac.h" - -#if defined(SAME70) && SAME70 -#include "pmc/pmc.h" -#endif - -#include "conf_eth.h" -#include <cstring> - -extern "C" { -#include <Hardware/ksz8081rna/ethernet_phy.h> -#include "lwip/opt.h" -#include "lwip/sys.h" -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/pbuf.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "netif/etharp.h" -} - -#define __nocache __attribute__((section(".ram_nocache"))) - -extern void delay(uint32_t ms); - -// We can't #include RepRapFirmware.h here because that leads to a duplicate definition of ERR_TIMEOUT -#include <RTOSIface/RTOSIface.h> -#include <TaskPriorities.h> - -extern Mutex lwipMutex; - -constexpr size_t EthernetTaskStackWords = 250; -static Task<EthernetTaskStackWords> ethernetTask; - -// Error counters -unsigned int rxErrorCount; -unsigned int rxBuffersNotFullyPopulatedCount; -unsigned int txErrorCount; -unsigned int txBufferNotFreeCount; -unsigned int txBufferTooShortCount; - -/** Network interface identifier. */ -#define IFNAME0 'e' -#define IFNAME1 'n' - -/** Maximum transfer unit. */ -#define NET_MTU 1500 - -/** Network link speed. */ -#define NET_LINK_SPEED 100000000 - -/* Interrupt priorities. (lowest value = highest priority) */ -/* ISRs using FreeRTOS *FromISR APIs must have priorities below or equal to */ -/* configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY. */ - -/** The GMAC interrupts to enable */ -#define GMAC_INT_GROUP (GMAC_ISR_RCOMP | GMAC_ISR_ROVR | GMAC_ISR_HRESP | GMAC_ISR_TCOMP | GMAC_ISR_TUR | GMAC_ISR_TFC) - -/** The GMAC TX errors to handle */ -#define GMAC_TX_ERRORS (GMAC_TSR_TFC | GMAC_TSR_HRESP) - -/** The GMAC RX errors to handle */ -#define GMAC_RX_ERRORS (GMAC_RSR_RXOVR | GMAC_RSR_HNO) - -/** TX descriptor lists */ -alignas(8) static gmac_tx_descriptor_t gs_tx_desc_null; -/** RX descriptors lists */ -alignas(8) static gmac_rx_descriptor_t gs_rx_desc_null; -/** - * GMAC driver structure. - */ -struct gmac_device { - /** - * Pointer to allocated TX buffer. - * Section 3.6 of AMBA 2.0 spec states that burst should not cross - * 1K Boundaries. - * Receive buffer manager writes are burst of 2 words => 3 lsb bits - * of the address shall be set to 0. - */ - /** Pointer to Rx descriptor list (must be 8-byte aligned). */ - volatile gmac_rx_descriptor_t rx_desc[GMAC_RX_BUFFERS]; - /** Pointer to Tx descriptor list (must be 8-byte aligned). */ - volatile gmac_tx_descriptor_t tx_desc[GMAC_TX_BUFFERS]; - /** RX pbuf pointer list. */ - struct pbuf *rx_pbuf[GMAC_RX_BUFFERS]; - /** TX buffers. */ - uint8_t tx_buf[GMAC_TX_BUFFERS][GMAC_TX_UNITSIZE]; - - /** RX index for current processing TD. */ - uint32_t us_rx_idx; - /** Circular buffer head pointer by upper layer (buffer to be sent). */ - uint32_t us_tx_idx; - - /** Reference to lwIP netif structure. */ - struct netif *netif; -}; - -/** - * GMAC driver instance. - */ -__nocache __aligned(8) static struct gmac_device gs_gmac_dev; - -/** - * MAC address to use. - */ -static uint8_t gs_uc_mac_address[] = -{ - ETHERNET_CONF_ETHADDR0, - ETHERNET_CONF_ETHADDR1, - ETHERNET_CONF_ETHADDR2, - ETHERNET_CONF_ETHADDR3, - ETHERNET_CONF_ETHADDR4, - ETHERNET_CONF_ETHADDR5 -}; - -static bool rxPbufsFullyPopulated = false; - -#if LWIP_STATS -/** Used to compute lwIP bandwidth. */ -uint32_t lwip_tx_count = 0; -uint32_t lwip_rx_count = 0; -uint32_t lwip_tx_rate = 0; -uint32_t lwip_rx_rate = 0; -#endif - -/** - * \brief GMAC interrupt handler. - */ -extern "C" void GMAC_Handler() noexcept -{ - /* Get interrupt status. */ - const uint32_t ul_isr = gmac_get_interrupt_status(GMAC); - - /* RX interrupts. */ - if (ul_isr & GMAC_INT_GROUP) - { - ethernetTask.GiveFromISR(); - } -} - -/** - * \brief Populate the RX descriptor ring buffers with pbufs. - * - * \note Make sure that the p->payload pointer is 32 bits aligned. - * (since the lsb are used as status bits by GMAC). - * - * \param p_gmac_dev Pointer to driver data structure. - * \param startAt The index to start populating from - */ -static void gmac_rx_populate_queue(struct gmac_device *p_gmac_dev, uint32_t startAt) noexcept -{ - uint32_t ul_index = startAt; - - /* Set up the RX descriptors. */ - do - { - 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); - if (p == nullptr) - { - LWIP_DEBUGF(NETIF_DEBUG, ("gmac_rx_populate_queue: pbuf allocation failure\n")); - rxPbufsFullyPopulated = false; - ++rxBuffersNotFullyPopulatedCount; - return; - } - - /* Make sure lwIP is well configured so one pbuf can contain the maximum packet size. */ - 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; - - /* 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; - } - - LWIP_DEBUGF(NETIF_DEBUG, - ("gmac_rx_populate_queue: new pbuf allocated: %p [idx=%u]\n", - p, ul_index)); - } - - ++ul_index; - if (ul_index == GMAC_RX_BUFFERS) - { - ul_index = 0; - } - } while (ul_index != startAt); - - rxPbufsFullyPopulated = true; -} - -/** - * \brief Set up the RX descriptor ring buffers. - * - * This function sets up the descriptor list used for receive packets. - * - * \param ps_gmac_dev Pointer to driver data structure. - */ -static void gmac_rx_init(struct gmac_device *ps_gmac_dev) noexcept -{ - uint32_t ul_index = 0; - - /* Init RX index. */ - ps_gmac_dev->us_rx_idx = 0; - - /* Set up the RX descriptors. */ - for (ul_index = 0; ul_index < GMAC_RX_BUFFERS; ul_index++) - { - ps_gmac_dev->rx_pbuf[ul_index] = nullptr; - ps_gmac_dev->rx_desc[ul_index].addr.val = GMAC_RXD_OWNERSHIP; // mark it as not free for hardware to use, until we have allocated the pbuf - ps_gmac_dev->rx_desc[ul_index].status.val = 0; - } - ps_gmac_dev->rx_desc[ul_index - 1].addr.val |= GMAC_RXD_WRAP; - - /* Build RX buffer and descriptors. */ - gmac_rx_populate_queue(ps_gmac_dev, 0); - - /* Set receive buffer queue base address pointer. */ - gmac_set_rx_queue(GMAC, (uint32_t) &ps_gmac_dev->rx_desc[0]); -} - -/** - * \brief Set up the TX descriptor ring buffers. - * - * This function sets up the descriptor list used for receive packets. - * - * \param ps_gmac_dev Pointer to driver data structure. - */ -static void gmac_tx_init(struct gmac_device *ps_gmac_dev) noexcept -{ - uint32_t ul_index; - - /* Init TX index pointer. */ - ps_gmac_dev->us_tx_idx = 0; - - /* Set up the TX descriptors. */ - for (ul_index = 0; ul_index < GMAC_TX_BUFFERS; ul_index++) - { - ps_gmac_dev->tx_desc[ul_index].addr = reinterpret_cast<uint32_t>(&ps_gmac_dev->tx_buf[ul_index][0]); - 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; - - /* Set receive buffer queue base address pointer. */ - gmac_set_tx_queue(GMAC, (uint32_t) &ps_gmac_dev->tx_desc[0]); -} - -/** - * \brief Initialize GMAC and PHY. - * - * \note Called from ethernetif_init(). - * - * \param netif the lwIP network interface structure for this ethernetif. - */ -static void gmac_low_level_init(struct netif *netif) noexcept -{ -#if 0 // chrishamm - volatile uint32_t ul_delay; -#endif - - /* Set MAC hardware address length. */ - netif->hwaddr_len = sizeof(gs_uc_mac_address); - /* Set MAC hardware address. */ - netif->hwaddr[0] = gs_uc_mac_address[0]; - netif->hwaddr[1] = gs_uc_mac_address[1]; - netif->hwaddr[2] = gs_uc_mac_address[2]; - netif->hwaddr[3] = gs_uc_mac_address[3]; - netif->hwaddr[4] = gs_uc_mac_address[4]; - netif->hwaddr[5] = gs_uc_mac_address[5]; - - /* Set maximum transfer unit. */ - netif->mtu = NET_MTU; - - /* Device capabilities. */ - netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP -#if LWIP_IGMP // chrishamm - | NETIF_FLAG_IGMP -#endif - ; - -#if 0 // chrishamm: Just like with the EMAC on the Duet, we initialise the GMAC step-by-step to avoid blocking - /* Wait for PHY to be ready (CAT811: Max400ms). */ - ul_delay = sysclk_get_cpu_hz() / 1000 / 3 * 400; - while (ul_delay--) { - } -#endif - - /* Init MAC PHY driver. */ - if (ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, SystemCoreClock) != GMAC_OK) { - LWIP_DEBUGF(NETIF_DEBUG, ("gmac_low_level_init: PHY init ERROR!\n")); - return; - } - -#if 0 // chrishamm: See ethernetif_establish_link() - /* Auto Negotiate, work in RMII mode. */ - if (ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR) != GMAC_OK) { - LWIP_DEBUGF(NETIF_DEBUG, ("gmac_low_level_init: auto negotiate ERROR!\n")); - return; - } - - /* Establish ethernet link. */ - while (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; - } - - /* Set link up*/ - netif->flags |= NETIF_FLAG_LINK_UP; -#endif -} - -/** - * \brief This function should do the actual transmission of the packet. The - * packet is contained in the pbuf that is passed to the function. This pbuf - * might be chained. - * - * \param netif the lwIP network interface structure for this ethernetif. - * \param p the MAC packet to send (e.g. IP packet including MAC addresses and type). - * - * \return ERR_OK if the packet could be sent. - * an err_t value if the packet couldn't be sent. - */ -static err_t gmac_low_level_output(netif *p_netif, struct pbuf *p) noexcept -{ - gmac_device *const ps_gmac_dev = static_cast<gmac_device *>(p_netif->state); - - /* Handle GMAC underrun or AHB errors. */ - if (gmac_get_tx_status(GMAC) & GMAC_TX_ERRORS) - { - ++txErrorCount; - LWIP_DEBUGF(NETIF_DEBUG, ("gmac_low_level_output: GMAC ERROR, reinit TX...\n")); - - gmac_enable_transmit(GMAC, false); - - LINK_STATS_INC(link.err); - 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_enable_transmit(GMAC, true); - } - - while ((ps_gmac_dev->tx_desc[ps_gmac_dev->us_tx_idx].status.val & GMAC_TXD_USED) == 0) - { - ++txBufferNotFreeCount; - delay(1); - } - - // Copy pbuf chain into TX buffer - { - uint8_t *buffer = reinterpret_cast<uint8_t*>(ps_gmac_dev->tx_desc[ps_gmac_dev->us_tx_idx].addr); - size_t totalLength = 0; - for (const pbuf *q = p; q != NULL; q = q->next) - { - totalLength += q->len; - if (totalLength > GMAC_TX_UNITSIZE) - { - ++txBufferTooShortCount; - return ERR_BUF; - } - memcpy(buffer, q->payload, q->len); - buffer += q->len; - } - } - - // Set length and mark the buffer to be sent by GMAC - uint32_t txStat = p->tot_len | GMAC_TXD_LAST; - if (ps_gmac_dev->us_tx_idx == GMAC_TX_BUFFERS - 1) - { - txStat |= GMAC_TXD_WRAP; - } - ps_gmac_dev->tx_desc[ps_gmac_dev->us_tx_idx].status.val = txStat; - - LWIP_DEBUGF(NETIF_DEBUG, - ("gmac_low_level_output: DMA buffer sent, size=%d [idx=%u]\n", - p->tot_len, ps_gmac_dev->us_tx_idx)); - - ps_gmac_dev->us_tx_idx = (ps_gmac_dev->us_tx_idx + 1) % GMAC_TX_BUFFERS; - - /* Now start to transmission. */ - gmac_start_transmission(GMAC); - -#if LWIP_STATS - lwip_tx_count += p->tot_len; -#endif - LINK_STATS_INC(link.xmit); - - return ERR_OK; -} - -/** - * \brief Use pre-allocated pbuf as DMA source and return the incoming packet. - * - * \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. - */ -static pbuf *gmac_low_level_input(struct netif *netif) noexcept -{ - gmac_device *ps_gmac_dev = static_cast<gmac_device *>(netif->state); - - if (gmac_get_rx_status(GMAC) & GMAC_RX_ERRORS) - { - // Handle GMAC overrun or AHB errors - ++rxErrorCount; - gmac_enable_receive(GMAC, false); - - LINK_STATS_INC(link.err); - LINK_STATS_INC(link.drop); - - /* Free all RX pbufs. */ - for (uint32_t ul_index = 0; ul_index < GMAC_RX_BUFFERS; ul_index++) - { - if (ps_gmac_dev->rx_pbuf[ul_index] != 0) - { - pbuf_free(ps_gmac_dev->rx_pbuf[ul_index]); - ps_gmac_dev->rx_pbuf[ul_index] = nullptr; - } - } - - /* Reinit RX descriptors. */ - gmac_rx_init(ps_gmac_dev); - - /* Clear error status. */ - gmac_clear_rx_status(GMAC, GMAC_RX_ERRORS); - - gmac_enable_receive(GMAC, true); - return nullptr; - } - - volatile gmac_rx_descriptor_t * const p_rx = &ps_gmac_dev->rx_desc[ps_gmac_dev->us_rx_idx]; - pbuf * const p = ((p_rx->addr.val & GMAC_RXD_OWNERSHIP) == GMAC_RXD_OWNERSHIP) - ? ps_gmac_dev->rx_pbuf[ps_gmac_dev->us_rx_idx] - : 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; - - /* Fetch pre-allocated pbuf. */ - p->len = length; - - /* Remove this pbuf from its descriptor. */ - ps_gmac_dev->rx_pbuf[ps_gmac_dev->us_rx_idx] = nullptr; - rxPbufsFullyPopulated = false; - - LWIP_DEBUGF(NETIF_DEBUG, - ("gmac_low_level_input: DMA buffer %p received, size=%u [idx=%u]\n", - p, length, ps_gmac_dev->us_rx_idx)); - - /* Set pbuf total packet size. */ - p->tot_len = length; - LINK_STATS_INC(link.recv); - - ps_gmac_dev->us_rx_idx = (ps_gmac_dev->us_rx_idx + 1) % GMAC_RX_BUFFERS; - -#if LWIP_STATS - lwip_rx_count += length; -#endif - } - - /* Fill empty descriptors with new pbufs. */ - if (!rxPbufsFullyPopulated) - { - gmac_rx_populate_queue(ps_gmac_dev, ps_gmac_dev->us_rx_idx); - } - - return p; -} - -/** - * \brief GMAC task function. This function waits for the notification - * semaphore from the interrupt, processes the incoming packet and then - * passes it to the lwIP stack. - * - * \param pvParameters A pointer to the gmac_device instance. - */ -extern "C" [[noreturn]] void gmac_task(void *pvParameters) noexcept -{ - gmac_device * const ps_gmac_dev = static_cast<gmac_device*>(pvParameters); - netif * const p_netif = ps_gmac_dev->netif; - - while (1) - { - // Process the incoming packets - { - MutexLocker lock(lwipMutex); - while (ethernetif_input(p_netif)) { } - } - - // Wait for the RX notification from the ISR - TaskBase::Take((rxPbufsFullyPopulated) ? 1000 : 20); - } -} - -/** - * \brief This function should be called when a packet is ready to be - * read from the interface. It uses the function gmac_low_level_input() - * that handles the actual reception of bytes from the network interface. - * Then the type of the received packet is determined and the appropriate - * input function is called. - * - * \param netif the lwIP network interface structure for this ethernetif. - */ -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); - if (p == nullptr) - { - return false; - } - - /* Points to packet payload, which starts with an Ethernet header. */ - ethhdr = static_cast<struct eth_hdr*>(p->payload); - - switch (htons(ethhdr->type)) { - case ETHTYPE_IP: - case ETHTYPE_ARP: -#if defined(PPPOE_SUPPORT) && PPPOE_SUPPORT - case ETHTYPE_PPPOEDISC: - case ETHTYPE_PPPOE: -#endif /* PPPOE_SUPPORT */ - /* Send packet to lwIP for processing. */ - if (netif->input(p, netif) != ERR_OK) { - LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); - /* Free buffer. */ - pbuf_free(p); - } - break; - - default: - /* Free buffer. */ - pbuf_free(p); - break; - } - return true; -} - -/** - * \brief Should be called at the beginning of the program to set up the - * network interface. It calls the function gmac_low_level_init() to do the - * actual setup of the hardware. - * - * \param netif the lwIP network interface structure for this ethernetif. - * - * \return ERR_OK if the loopif is initialized. - * ERR_MEM if private data couldn't be allocated. - * any other err_t on error. - */ -err_t ethernetif_init(struct netif *netif) noexcept -{ - LWIP_ASSERT("netif != NULL", (netif != NULL)); - - gs_gmac_dev.netif = netif; - -#if LWIP_NETIF_HOSTNAME && 0 // chrishamm: RRF sets the hostname explicitly - /* Initialize interface hostname. */ - netif->hostname = "gmacdev"; -#endif /* LWIP_NETIF_HOSTNAME */ - - /* - * Initialize the snmp variables and counters inside the struct netif. - * The last argument should be replaced with your link speed, in units - * of bits per second. - */ -#if defined(LWIP_SNMP) && LWIP_SNMP - NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, NET_LINK_SPEED); -#endif /* LWIP_SNMP */ - - netif->state = &gs_gmac_dev; - netif->name[0] = IFNAME0; - netif->name[1] = IFNAME1; - - /* We directly use etharp_output() here to save a function call. - * You can instead declare your own function an call etharp_output() - * from it if you have to do some checks before sending (e.g. if link - * is available...) */ - netif->output = etharp_output; - netif->linkoutput = gmac_low_level_output; - - /* Initialize the hardware */ - gmac_low_level_init(netif); - - ethernetTask.Create(gmac_task, "ETHERNET", &gs_gmac_dev, TaskPriority::EthernetPriority); - return ERR_OK; -} - -void ethernetif_hardware_init() noexcept -{ - /* Enable GMAC clock. */ - pmc_enable_periph_clk(ID_GMAC); - - /* Disable TX & RX and more. */ - gmac_network_control(GMAC, 0); - gmac_disable_interrupt(GMAC, ~0u); - - gmac_clear_statistics(GMAC); - - /* Clear all status bits in the receive status register. */ - gmac_clear_rx_status(GMAC, GMAC_RSR_BNA | GMAC_RSR_REC | GMAC_RSR_RXOVR - | GMAC_RSR_HNO); - - /* Clear all status bits in the transmit status register. */ - gmac_clear_tx_status(GMAC, GMAC_TSR_UBR | GMAC_TSR_COL | GMAC_TSR_RLE - | GMAC_TSR_TXGO | GMAC_TSR_TFC | GMAC_TSR_TXCOMP - | GMAC_TSR_HRESP); - - /* Clear interrupts. */ - gmac_get_interrupt_status(GMAC); - - /* 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); - - /* Set RX buffer size to 1536. */ - gmac_set_rx_bufsize(GMAC, 0x18); - - /* Clear interrupts */ - gmac_get_priority_interrupt_status(GMAC, GMAC_QUE_2); - gmac_get_priority_interrupt_status(GMAC, GMAC_QUE_1); -#if (SAMV71B || SAME70B) - gmac_get_priority_interrupt_status(GMAC, GMAC_QUE_3); - gmac_get_priority_interrupt_status(GMAC, GMAC_QUE_4); - gmac_get_priority_interrupt_status(GMAC, GMAC_QUE_5); -#endif - - /* Set Tx Priority */ - gs_tx_desc_null.addr = (uint32_t)0xFFFFFFFF; - gs_tx_desc_null.status.val = GMAC_TXD_WRAP | GMAC_TXD_USED; - gmac_set_tx_priority_queue(GMAC, (uint32_t)&gs_tx_desc_null, GMAC_QUE_2); - gmac_set_tx_priority_queue(GMAC, (uint32_t)&gs_tx_desc_null, GMAC_QUE_1); -#if (SAMV71B || SAME70B) - gmac_set_tx_priority_queue(GMAC, (uint32_t)&gs_tx_desc_null, GMAC_QUE_3); - gmac_set_tx_priority_queue(GMAC, (uint32_t)&gs_tx_desc_null, GMAC_QUE_4); - gmac_set_tx_priority_queue(GMAC, (uint32_t)&gs_tx_desc_null, GMAC_QUE_5); -#endif - - /* Set Rx Priority */ - gs_rx_desc_null.addr.val = (uint32_t)0xFFFFFFFF & GMAC_RXD_ADDR_MASK; - gs_rx_desc_null.addr.val |= GMAC_RXD_WRAP; - gs_rx_desc_null.status.val = 0; - gmac_set_rx_priority_queue(GMAC, (uint32_t)&gs_rx_desc_null, GMAC_QUE_2); - gmac_set_rx_priority_queue(GMAC, (uint32_t)&gs_rx_desc_null, GMAC_QUE_1); -#if (SAMV71B || SAME70B) - gmac_set_rx_priority_queue(GMAC, (uint32_t)&gs_rx_desc_null, GMAC_QUE_3); - gmac_set_rx_priority_queue(GMAC, (uint32_t)&gs_rx_desc_null, GMAC_QUE_4); - gmac_set_rx_priority_queue(GMAC, (uint32_t)&gs_rx_desc_null, GMAC_QUE_5); -#endif - - gmac_rx_init(&gs_gmac_dev); - gmac_tx_init(&gs_gmac_dev); - - /* Enable Rx, Tx and the statistics register. */ - gmac_enable_transmit(GMAC, true); - gmac_enable_receive(GMAC, true); - gmac_enable_statistics_write(GMAC, true); - - /* Set up the interrupts for transmission and errors. */ - gmac_enable_interrupt(GMAC, GMAC_INT_GROUP); - - /* Set GMAC address. */ - gmac_set_address(GMAC, 0, gs_uc_mac_address); - - /* Enable NVIC GMAC interrupt. */ -#if 0 // chrishamm: NVIC priorities are assigned by RepRapFirmware - NVIC_SetPriority(GMAC_IRQn, INT_PRIORITY_GMAC); -#endif - NVIC_EnableIRQ(GMAC_IRQn); -} - -bool ethernetif_establish_link() noexcept -{ - /* Auto Negotiate, work in RMII mode. */ - uint8_t result = ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR); - if (result != GMAC_OK) { - if (result != GMAC_TIMEOUT) - { - // chrishamm: It is expected that the function above will return ERR_TIMEOUT a few times - LWIP_DEBUGF(NETIF_DEBUG, ("gmac_low_level_init: auto negotiate ERROR!\n")); - } - 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; -} - -// Ask the PHY if the link is still up -bool ethernetif_link_established() noexcept -{ - gmac_enable_management(GMAC, true); - - uint32_t ul_stat1; - if (gmac_phy_read(GMAC, BOARD_GMAC_PHY_ADDR, GMII_BMSR, &ul_stat1) != GMAC_OK) { - gmac_enable_management(GMAC, false); - return false; - } - - if ((ul_stat1 & GMII_LINK_STATUS) == 0) { - gmac_enable_management(GMAC, false); - return false; - } - - gmac_enable_management(GMAC, false); - return true; -} - -void ethernetif_set_mac_address(const uint8_t macAddress[]) noexcept -{ - // This function must be called once before low_level_init(), because that is where the - // MAC address of the netif is assigned - for (size_t i = 0; i < 6; ++i) - { - gs_uc_mac_address[i] = macAddress[i]; - } -} - -// This is called when we shut down -void ethernetif_terminate() noexcept -{ - NVIC_DisableIRQ(GMAC_IRQn); - ethernetTask.TerminateAndUnlink(); -} - -extern "C" u32_t millis() noexcept; - -extern "C" u32_t sys_now() noexcept -{ - return millis(); -} - -// End diff --git a/src/Networking/LwipEthernet/GMAC/same70_gmac.h b/src/Networking/LwipEthernet/GMAC/same70_gmac.h deleted file mode 100644 index dfdaca6d..00000000 --- a/src/Networking/LwipEthernet/GMAC/same70_gmac.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * - * \file - * - * \brief GMAC (Gigabit MAC) driver for lwIP. - * - * Copyright (c) 2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ - -#ifndef ETHERNETIF_H_INCLUDED -#define ETHERNETIF_H_INCLUDED - -#ifdef __cplusplus -extern "C" { -#endif - -#include "lwip/err.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "netif/etharp.h" - -#ifdef __cplusplus -} - -err_t ethernetif_init(struct netif *netif) noexcept; // called by LwIP to initialise the interface - -void ethernetif_terminate() noexcept; // called when we shut down - -bool ethernetif_input(struct netif *netif) noexcept; // checks for a new packet and returns true if one was processed - -void ethernetif_hardware_init() noexcept; // initialises the low-level hardware interface - -bool ethernetif_establish_link() noexcept; // attempts to establish link and returns true on success - -bool ethernetif_link_established() noexcept; // asks the PHY if the link is still up - -void ethernetif_set_mac_address(const uint8_t macAddress[]) noexcept; - -#endif - -// Error counters -extern unsigned int rxErrorCount; -extern unsigned int rxBuffersNotFullyPopulatedCount; -extern unsigned int txErrorCount; -extern unsigned int txBufferNotFreeCount; -extern unsigned int txBufferTooShortCount; - -#endif /* ETHERNETIF_H_INCLUDED */ |