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:
authorDavid Crocker <dcrocker@eschertech.com>2020-06-19 15:13:22 +0300
committerDavid Crocker <dcrocker@eschertech.com>2020-06-19 15:13:22 +0300
commit3ad18b88855985bdda69bde27e8c0a4af22054eb (patch)
tree1bd3a93166cedfacf706475e089d97d2e5f60e33 /src/Hardware/SAME70
parent31479abcd5813946826974cf5a0ba660253067cf (diff)
Changes for 5LC
Diffstat (limited to 'src/Hardware/SAME70')
-rw-r--r--src/Hardware/SAME70/ksz8081rna/ethernet_phy.c473
-rw-r--r--src/Hardware/SAME70/ksz8081rna/ethernet_phy.h195
-rw-r--r--src/Hardware/SAME70/same70_gmac.cpp2
3 files changed, 669 insertions, 1 deletions
diff --git a/src/Hardware/SAME70/ksz8081rna/ethernet_phy.c b/src/Hardware/SAME70/ksz8081rna/ethernet_phy.c
new file mode 100644
index 00000000..0ca27033
--- /dev/null
+++ b/src/Hardware/SAME70/ksz8081rna/ethernet_phy.c
@@ -0,0 +1,473 @@
+ /**
+ * \file
+ *
+ * \brief API driver for KSZ8081RNA PHY component.
+ *
+ * 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
+ *
+ */
+/*
+ * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
+ */
+
+#include "ethernet_phy.h"
+
+#if 0 //dc42
+#include "pio/pio.h"
+#endif
+
+#include "gmac/gmac.h"
+#include "conf_eth.h"
+#include "board.h"
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+/**
+ * \defgroup ksz8081rna_ethernet_phy_group PHY component (KSZ8081RNA)
+ *
+ * Driver for the ksz8081rna component. This driver provides access to the main
+ * features of the PHY.
+ *
+ * \section dependencies Dependencies
+ * This driver depends on the following modules:
+ * - \ref gmac_group Ethernet Media Access Controller (GMAC) module.
+ *
+ * @{
+ */
+
+/* Max PHY number */
+#define ETH_PHY_MAX_ADDR 31
+
+#if 0 // chrishamm
+/* Ethernet PHY operation max retry count */
+#define ETH_PHY_RETRY_MAX 1000000
+#endif
+
+/* Ethernet PHY operation timeout */
+#define ETH_PHY_TIMEOUT 10
+
+/**
+ * \brief Find a valid PHY Address ( from addrStart to 31 ).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param uc_start_addr Start address of the PHY to be searched.
+ *
+ * \return 0xFF when no valid PHY address is found.
+ */
+static uint8_t ethernet_phy_find_valid(Gmac *p_gmac, uint8_t uc_phy_addr,
+ uint8_t uc_start_addr)
+{
+ uint32_t ul_value = 0;
+ uint8_t uc_rc = 0;
+ uint8_t uc_cnt;
+ uint8_t uc_phy_address = uc_phy_addr;
+
+ gmac_enable_management(p_gmac, true);
+ uc_rc = uc_phy_address;
+ /* Check the current PHY address */
+ gmac_phy_read(p_gmac, uc_phy_addr, GMII_PHYID1, &ul_value);
+
+ /* Find another one */
+ if (ul_value != GMII_OUI_MSB) {
+ uc_rc = 0xFF;
+ for (uc_cnt = uc_start_addr; uc_cnt <= ETH_PHY_MAX_ADDR; uc_cnt++) {
+ uc_phy_address = (uc_phy_address + 1) & 0x1F;
+ gmac_phy_read(p_gmac, uc_phy_address, GMII_PHYID1, &ul_value);
+ if (ul_value == GMII_OUI_MSB) {
+ uc_rc = uc_phy_address;
+ break;
+ }
+ }
+ }
+
+ gmac_enable_management(p_gmac, false);
+
+ if (uc_rc != 0xFF) {
+ gmac_phy_read(p_gmac, uc_phy_address, GMII_BMSR, &ul_value);
+ }
+ return uc_rc;
+}
+
+
+/**
+ * \brief Perform a HW initialization to the PHY and set up clocks.
+ *
+ * This should be called only once to initialize the PHY pre-settings.
+ * The PHY address is the reset status of CRS, RXD[3:0] (the emacPins' pullups).
+ * The COL pin is used to select MII mode on reset (pulled up for Reduced MII).
+ * The RXDV pin is used to select test mode on reset (pulled up for test mode).
+ * The above pins should be predefined for corresponding settings in resetPins.
+ * The GMAC peripheral pins are configured after the reset is done.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param ul_mck GMAC MCK.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_init(Gmac *p_gmac, uint8_t uc_phy_addr, uint32_t mck)
+{
+ uint8_t uc_rc;
+ uint8_t uc_phy;
+
+#if 0 // chrishamm
+ pio_set_output(PIN_GMAC_RESET_PIO, PIN_GMAC_RESET_MASK, 1, false, true);
+ pio_set_input(PIN_GMAC_INT_PIO, PIN_GMAC_INT_MASK, PIO_PULLUP);
+ pio_set_peripheral(PIN_GMAC_PIO, PIN_GMAC_PERIPH, PIN_GMAC_MASK);
+#endif
+
+ ethernet_phy_reset(GMAC,uc_phy_addr);
+
+ /* Configure GMAC runtime clock */
+ uc_rc = gmac_set_mdc_clock(p_gmac, mck);
+ if (uc_rc != GMAC_OK) {
+ return 0;
+ }
+
+ /* Check PHY Address */
+ uc_phy = ethernet_phy_find_valid(p_gmac, uc_phy_addr, 0);
+ if (uc_phy == 0xFF) {
+ return 0;
+ }
+ if (uc_phy != uc_phy_addr) {
+ ethernet_phy_reset(p_gmac, uc_phy_addr);
+ }
+
+ return uc_rc;
+}
+
+
+/**
+ * \brief Get the Link & speed settings, and automatically set up the GMAC with the
+ * settings.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param uc_apply_setting_flag Set to 0 to not apply the PHY configurations, else to apply.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_set_link(Gmac *p_gmac, uint8_t uc_phy_addr,
+ uint8_t uc_apply_setting_flag)
+{
+ uint32_t ul_stat1;
+ uint32_t ul_stat2;
+ uint8_t uc_phy_address, uc_speed, uc_fd;
+ uint8_t uc_rc;
+
+ gmac_enable_management(p_gmac, true);
+
+ uc_phy_address = uc_phy_addr;
+
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_address, GMII_BMSR, &ul_stat1);
+ if (uc_rc != GMAC_OK) {
+ /* Disable PHY management and start the GMAC transfer */
+ gmac_enable_management(p_gmac, false);
+
+ return uc_rc;
+ }
+
+ if ((ul_stat1 & GMII_LINK_STATUS) == 0) {
+ /* Disable PHY management and start the GMAC transfer */
+ gmac_enable_management(p_gmac, false);
+
+ return GMAC_INVALID;
+ }
+
+ if (uc_apply_setting_flag == 0) {
+ /* Disable PHY management and start the GMAC transfer */
+ gmac_enable_management(p_gmac, false);
+
+ return uc_rc;
+ }
+
+ /* Read advertisement */
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_address, GMII_PCR1, &ul_stat2);
+ if (uc_rc != GMAC_OK) {
+ /* Disable PHY management and start the GMAC transfer */
+ gmac_enable_management(p_gmac, false);
+
+ return uc_rc;
+ }
+
+ if ((ul_stat1 & GMII_100BASE_TX_FD) && (ul_stat2 & GMII_OMI_100BASE_TX_FD)) {
+ /* Set GMAC for 100BaseTX and Full Duplex */
+ uc_speed = true;
+ uc_fd = true;
+ }
+
+ if ((ul_stat1 & GMII_10BASE_T_FD) && (ul_stat2 & GMII_OMI_10BASE_T_FD)) {
+ /* Set MII for 10BaseT and Full Duplex */
+ uc_speed = false;
+ uc_fd = true;
+ }
+
+ if ((ul_stat1 & GMII_100BASE_TX_HD) && (ul_stat2 & GMII_OMI_100BASE_TX_HD)) {
+ /* Set MII for 100BaseTX and Half Duplex */
+ uc_speed = true;
+ uc_fd = false;
+ }
+
+ if ((ul_stat1 & GMII_10BASE_T_HD) && (ul_stat2 & GMII_OMI_10BASE_T_HD)) {
+ /* Set MII for 10BaseT and Half Duplex */
+ uc_speed = false;
+ uc_fd = false;
+ }
+
+ gmac_set_speed(p_gmac, uc_speed);
+ gmac_enable_full_duplex(p_gmac, uc_fd);
+
+ /* Start the GMAC transfers */
+ gmac_enable_management(p_gmac, false);
+ return uc_rc;
+}
+
+
+/**
+ * \brief Issue an auto negotiation of the PHY.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+static bool phyInitialized = false;
+uint8_t ethernet_phy_auto_negotiate(Gmac *p_gmac, uint8_t uc_phy_addr)
+{
+#if 0 // chrishamm
+ uint32_t ul_retry_max = ETH_PHY_RETRY_MAX;
+ uint32_t ul_retry_count = 0;
+#endif
+ uint32_t ul_value;
+ uint32_t ul_phy_anar;
+ uint32_t ul_phy_analpar;
+ uint8_t uc_speed = 0;
+ uint8_t uc_fd=0;
+ uint8_t uc_rc;
+
+ gmac_enable_management(p_gmac, true);
+
+ if (!phyInitialized)
+ {
+ /* Set up control register */
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMCR, &ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+ return uc_rc;
+ }
+
+ ul_value &= ~(uint32_t)GMII_AUTONEG; /* Remove auto-negotiation enable */
+ ul_value &= ~(uint32_t)(GMII_LOOPBACK | GMII_POWER_DOWN);
+ ul_value |= (uint32_t)GMII_ISOLATE; /* Electrically isolate PHY */
+ uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+ return uc_rc;
+ }
+
+ /*
+ * Set the Auto_negotiation Advertisement Register.
+ * MII advertising for Next page.
+ * 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3.
+ */
+ ul_phy_anar = GMII_100TX_FDX | GMII_100TX_HDX | GMII_10_FDX | GMII_10_HDX |
+ GMII_AN_IEEE_802_3;
+ uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_ANAR, ul_phy_anar);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+ return uc_rc;
+ }
+
+ /* Read & modify control register */
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMCR, &ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+ return uc_rc;
+ }
+
+ ul_value |= GMII_SPEED_SELECT | GMII_AUTONEG | GMII_DUPLEX_MODE;
+ uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+ return uc_rc;
+ }
+
+ /* Restart auto negotiation */
+ ul_value |= (uint32_t)GMII_RESTART_AUTONEG;
+ ul_value &= ~(uint32_t)GMII_ISOLATE;
+ uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+ return uc_rc;
+ }
+
+ phyInitialized = true;
+ }
+
+ /* Check if auto negotiation is completed */
+#if 1 // chrishamm
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMSR, &ul_value);
+ if (uc_rc != GMAC_OK)
+ {
+ gmac_enable_management(p_gmac, false);
+ return uc_rc;
+ }
+
+ if ((ul_value & GMII_AUTONEG_COMP) == 0)
+ {
+ gmac_enable_management(p_gmac, false);
+ return GMAC_TIMEOUT;
+ }
+#else
+ while (1) {
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMSR, &ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+ return uc_rc;
+ }
+ /* Done successfully */
+ if (ul_value & GMII_AUTONEG_COMP) {
+ break;
+ }
+
+ /* Timeout check */
+ if (ul_retry_max) {
+ if (++ul_retry_count >= ul_retry_max) {
+ gmac_enable_management(p_gmac, false);
+ return GMAC_TIMEOUT;
+ }
+ }
+ }
+#endif
+
+ /* Get the auto negotiate link partner base page */
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_ANLPAR, &ul_phy_analpar);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+ return uc_rc;
+ }
+
+
+ /* Set up the GMAC link speed */
+ if ((ul_phy_anar & ul_phy_analpar) & GMII_100TX_FDX) {
+ /* Set MII for 100BaseTX and Full Duplex */
+ uc_speed = true;
+ uc_fd = true;
+ } else if ((ul_phy_anar & ul_phy_analpar) & GMII_10_FDX) {
+ /* Set MII for 10BaseT and Full Duplex */
+ uc_speed = false;
+ uc_fd = true;
+ } else if ((ul_phy_anar & ul_phy_analpar) & GMII_100TX_HDX) {
+ /* Set MII for 100BaseTX and half Duplex */
+ uc_speed = true;
+ uc_fd = false;
+ } else if ((ul_phy_anar & ul_phy_analpar) & GMII_10_HDX) {
+ /* Set MII for 10BaseT and half Duplex */
+ uc_speed = false;
+ uc_fd = false;
+ }
+
+ gmac_set_speed(p_gmac, uc_speed);
+ gmac_enable_full_duplex(p_gmac, uc_fd);
+
+ /* Select Media Independent Interface type */
+ gmac_select_mii_mode(p_gmac, ETH_PHY_MODE);
+
+ gmac_enable_transmit(GMAC, true);
+ gmac_enable_receive(GMAC, true);
+
+ phyInitialized = false; // in case the board loses link and needs to run this function again
+ gmac_enable_management(p_gmac, false);
+ return uc_rc;
+}
+
+/**
+ * \brief Issue a SW reset to reset all registers of the PHY.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ *
+ * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_reset(Gmac *p_gmac, uint8_t uc_phy_addr)
+{
+ uint32_t ul_bmcr;
+ uint8_t uc_phy_address = uc_phy_addr;
+ uint32_t ul_timeout = ETH_PHY_TIMEOUT;
+ uint8_t uc_rc = GMAC_TIMEOUT;
+
+ gmac_enable_management(p_gmac, true);
+
+ ul_bmcr = GMII_RESET;
+ gmac_phy_write(p_gmac, uc_phy_address, GMII_BMCR, ul_bmcr);
+
+ do {
+ gmac_phy_read(p_gmac, uc_phy_address, GMII_BMCR, &ul_bmcr);
+ ul_timeout--;
+ } while ((ul_bmcr & GMII_RESET) && ul_timeout);
+
+#if 1 //dc42
+ gmac_phy_write(p_gmac, uc_phy_address, GMII_OMSOR, 0x0002); // to handle missing pulldown resistor on RX_ERR
+#endif
+
+ gmac_enable_management(p_gmac, false);
+
+ if (ul_timeout) {
+ uc_rc = GMAC_OK;
+ }
+
+ return (uc_rc);
+}
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+}
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+/**
+ * \}
+ */
diff --git a/src/Hardware/SAME70/ksz8081rna/ethernet_phy.h b/src/Hardware/SAME70/ksz8081rna/ethernet_phy.h
new file mode 100644
index 00000000..7baa3e63
--- /dev/null
+++ b/src/Hardware/SAME70/ksz8081rna/ethernet_phy.h
@@ -0,0 +1,195 @@
+/**
+ * \file
+ *
+ * \brief KSZ8081RNA (Ethernet PHY) driver for SAM.
+ *
+ * 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
+ *
+ */
+/*
+ * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
+ */
+
+#ifndef ETHERNET_PHY_H_INCLUDED
+#define ETHERNET_PHY_H_INCLUDED
+
+#include "compiler.h"
+
+// IEEE defined Registers
+#define GMII_BMCR 0x00 // Basic Control
+#define GMII_BMSR 0x01 // Basic Status
+#define GMII_PHYID1 0x02 // PHY Idendifier 1
+#define GMII_PHYID2 0x03 // PHY Idendifier 2
+#define GMII_ANAR 0x04 // Auto_Negotiation Advertisement
+#define GMII_ANLPAR 0x05 // Auto_negotiation Link Partner Ability
+#define GMII_ANER 0x06 // Auto-negotiation Expansion
+#define GMII_ANNPR 0x07 // Auto-negotiation Next Page
+#define GMII_ANLPNPAR 0x08 // Link Partner Next Page Ability
+#define GMII_DRCR 0x10 // Digital Reserved Control Register
+#define GMII_AFECR1 0x11 // AFE Control 1
+#define GMII_RXERCR 0x15 // RXER Counter
+#define GMII_OMSOR 0x16 // Operation Mode Strap Override
+#define GMII_OMSSR 0x17 // Operation Mode Strap Status
+#define GMII_ECR 0x18 // Expanded Control
+#define GMII_ICSR 0x1B // Interrupt Control/Status
+#define GMII_LCSR 0x1D // LinkMD Control/Status
+#define GMII_PCR1 0x1E // PHY Control 1
+#define GMII_PCR2 0x1F // PHY Control 2
+
+// Bit definitions: GMII_BMCR 0x00 Basic Control
+#define GMII_RESET (1 << 15) // 1= Software Reset; 0=Normal Operation
+#define GMII_LOOPBACK (1 << 14) // 1=loopback Enabled; 0=Normal Operation
+#define GMII_SPEED_SELECT (1 << 13) // 1=100Mbps; 0=10Mbps
+#define GMII_AUTONEG (1 << 12) // Auto-negotiation Enable
+#define GMII_POWER_DOWN (1 << 11) // 1=Power down 0=Normal operation
+#define GMII_ISOLATE (1 << 10) // 1 = Isolates 0 = Normal operation
+#define GMII_RESTART_AUTONEG (1 << 9) // 1 = Restart auto-negotiation 0 = Normal operation
+#define GMII_DUPLEX_MODE (1 << 8) // 1 = Full duplex operation 0 = Normal operation
+#define GMII_COLLISION_TEST (1 << 7) // 1 = Enable COL test; 0 = Disable COL test
+//#define GMII_SPEED_SELECT_MSB (1 << 6) // Reserved
+// Reserved 6 to 0 // Read as 0, ignore on write
+
+// Bit definitions: GMII_BMSR 0x01 Basic Status
+#define GMII_100BASE_T4 (1 << 15) // 100BASE-T4 Capable
+#define GMII_100BASE_TX_FD (1 << 14) // 100BASE-TX Full Duplex Capable
+#define GMII_100BASE_TX_HD (1 << 13) // 100BASE-TX Half Duplex Capable
+#define GMII_10BASE_T_FD (1 << 12) // 10BASE-T Full Duplex Capable
+#define GMII_10BASE_T_HD (1 << 11) // 10BASE-T Half Duplex Capable
+// Reserved 10 to79 // Read as 0, ignore on write
+//#define GMII_EXTEND_STATUS (1 << 8) // 1 = Extend Status Information In Reg 15
+// Reserved 7
+#define GMII_MF_PREAMB_SUPPR (1 << 6) // MII Frame Preamble Suppression
+#define GMII_AUTONEG_COMP (1 << 5) // Auto-negotiation Complete
+#define GMII_REMOTE_FAULT (1 << 4) // Remote Fault
+#define GMII_AUTONEG_ABILITY (1 << 3) // Auto Configuration Ability
+#define GMII_LINK_STATUS (1 << 2) // Link Status
+#define GMII_JABBER_DETECT (1 << 1) // Jabber Detect
+#define GMII_EXTEND_CAPAB (1 << 0) // Extended Capability
+
+
+// Bit definitions: GMII_PHYID1 0x02 PHY Idendifier 1
+// Bit definitions: GMII_PHYID2 0x03 PHY Idendifier 2
+#define GMII_LSB_MASK 0x3F
+#define GMII_OUI_MSB 0x0022
+#define GMII_OUI_LSB 0x1572
+
+
+// Bit definitions: GMII_ANAR 0x04 Auto_Negotiation Advertisement
+// Bit definitions: GMII_ANLPAR 0x05 Auto_negotiation Link Partner Ability
+#define GMII_NP (1 << 15) // Next page Indication
+// Reserved 7
+#define GMII_RF (1 << 13) // Remote Fault
+// Reserved 12 // Write as 0, ignore on read
+#define GMII_PAUSE_MASK (3 << 10) // 0,0 = No Pause 1,0 = Asymmetric Pause(link partner)
+ // 0,1 = Symmetric Pause 1,1 = Symmetric&Asymmetric Pause(local device)
+#define GMII_100T4 (1 << 9) // 100BASE-T4 Support
+#define GMII_100TX_FDX (1 << 8) // 100BASE-TX Full Duplex Support
+#define GMII_100TX_HDX (1 << 7) // 100BASE-TX Half Duplex Support
+#define GMII_10_FDX (1 << 6) // 10BASE-T Full Duplex Support
+#define GMII_10_HDX (1 << 5) // 10BASE-T Half Duplex Support
+// Selector 4 to 0 // Protocol Selection Bits
+#define GMII_AN_IEEE_802_3 0x0001 // [00001] = IEEE 802.3
+
+
+// Bit definitions: GMII_ANER 0x06 Auto-negotiation Expansion
+// Reserved 15 to 5 // Read as 0, ignore on write
+#define GMII_PDF (1 << 4) // Local Device Parallel Detection Fault
+#define GMII_LP_NP_ABLE (1 << 3) // Link Partner Next Page Able
+#define GMII_NP_ABLE (1 << 2) // Local Device Next Page Able
+#define GMII_PAGE_RX (1 << 1) // New Page Received
+#define GMII_LP_AN_ABLE (1 << 0) // Link Partner Auto-negotiation Able
+
+// Bit definitions: GMII_PCR1 0x1E PHY Control 1
+#define GMII_OMI_10BASE_T_HD 0x0001
+#define GMII_OMI_100BASE_TX_HD 0x0002
+#define GMII_OMI_10BASE_T_FD 0x0005
+#define GMII_OMI_100BASE_TX_FD 0x0006
+
+/**
+ * \brief Perform a HW initialization to the PHY and set up clocks.
+ *
+ * This should be called only once to initialize the PHY pre-settings.
+ * The PHY address is the reset status of CRS, RXD[3:0] (the GmacPins' pullups).
+ * The COL pin is used to select MII mode on reset (pulled up for Reduced MII).
+ * The RXDV pin is used to select test mode on reset (pulled up for test mode).
+ * The above pins should be predefined for corresponding settings in resetPins.
+ * The GMAC peripheral pins are configured after the reset is done.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param ul_mck GMAC MCK.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_init(Gmac *p_gmac, uint8_t uc_phy_addr, uint32_t ul_mck);
+
+
+/**
+ * \brief Get the Link & speed settings, and automatically set up the GMAC with the
+ * settings.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param uc_apply_setting_flag Set to 0 to not apply the PHY configurations, else to apply.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_set_link(Gmac *p_gmac, uint8_t uc_phy_addr,
+ uint8_t uc_apply_setting_flag);
+
+
+/**
+ * \brief Issue an auto negotiation of the PHY.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_auto_negotiate(Gmac *p_gmac, uint8_t uc_phy_addr);
+
+/**
+ * \brief Issue a SW reset to reset all registers of the PHY.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ *
+ * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_reset(Gmac *p_gmac, uint8_t uc_phy_addr);
+
+#endif /* #ifndef ETHERNET_PHY_H_INCLUDED */
diff --git a/src/Hardware/SAME70/same70_gmac.cpp b/src/Hardware/SAME70/same70_gmac.cpp
index 33212834..2232b246 100644
--- a/src/Hardware/SAME70/same70_gmac.cpp
+++ b/src/Hardware/SAME70/same70_gmac.cpp
@@ -41,7 +41,7 @@
#include <cstring>
extern "C" {
-#include <Hardware/ksz8081rna/ethernet_phy.h>
+#include "ksz8081rna/ethernet_phy.h"
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/def.h"