]> granicus.if.org Git - esp-idf/commitdiff
feat(emac): add support for emac to use internal (APLL) clock outputs.
authorFrank Sautter <github@sautter.com>
Mon, 16 Oct 2017 21:05:27 +0000 (05:05 +0800)
committermichael <xiaoxufeng@espressif.com>
Mon, 13 Nov 2017 06:18:58 +0000 (14:18 +0800)
components/ethernet/emac_common.h
components/ethernet/emac_dev.c
components/ethernet/emac_dev.h
components/ethernet/emac_main.c
components/ethernet/eth_phy/phy_lan8720.c
components/ethernet/eth_phy/phy_tlk110.c
components/ethernet/include/esp_eth.h
examples/ethernet/ethernet/README.md
examples/ethernet/ethernet/main/Kconfig.projbuild
examples/ethernet/ethernet/main/ethernet_example_main.c

index d70abdd77ad3a3f17b243bfad7116337c905db5b..4b20c6aca305bf47952b7902d7d2432512cd7130 100644 (file)
@@ -53,6 +53,7 @@ enum {
 struct emac_config_data {
     eth_phy_base_t phy_addr;
     eth_mode_t mac_mode;
+    eth_clock_mode_t clock_mode;
     struct dma_extended_desc *dma_etx;
     uint32_t cur_tx;
     uint32_t dirty_tx;
index e4896af34cb4ec4cc6564af2daf67819634081c2..5a8b61cba0f803b11c210aa69f957484f5e778e3 100644 (file)
@@ -101,18 +101,6 @@ void emac_enable_clk(bool enable)
     }
 }
 
-void emac_set_clk_mii(void)
-{
-    //select ex clock source
-    REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_EXT_OSC_EN);
-    //ex clk enable
-    REG_SET_BIT(EMAC_EX_OSCCLK_CONF_REG, EMAC_EX_OSC_CLK_SEL);
-
-    //set mii mode rx/tx clk enable
-    REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_MII_CLK_RX_EN);
-    REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_MII_CLK_TX_EN);
-}
-
 void emac_dma_init(void)
 {
     REG_SET_BIT(EMAC_DMAOPERATION_MODE_REG, EMAC_FORWARD_UNDERSIZED_GOOD_FRAMES);
@@ -134,11 +122,3 @@ void emac_mac_init(void)
     REG_CLR_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACFESPEED);
     REG_SET_BIT(EMAC_GMACFRAMEFILTER_REG, EMAC_PROMISCUOUS_MODE);
 }
-
-void emac_set_clk_rmii(void)
-{
-    //select ex clock source
-    REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_EXT_OSC_EN);
-    //ex clk enable
-    REG_SET_BIT(EMAC_EX_OSCCLK_CONF_REG, EMAC_EX_OSC_CLK_SEL);
-}
index dc1045b92fe97b6d6609c4016397e6fa614e16bb..d29ab07534b086fabd047ae75a999c9841e3ea79 100644 (file)
@@ -40,8 +40,6 @@ struct dma_extended_desc {
 };
 
 void emac_enable_clk(bool enable);
-void emac_set_clk_rmii(void);
-void emac_set_clk_mii(void);
 void emac_reset(void);
 void emac_set_gpio_pin_rmii(void);
 void emac_set_gpio_pin_mii(void);
@@ -113,4 +111,3 @@ void inline emac_send_pause_zero_frame_enable(void)
 #endif
 
 #endif
-
index e0a5428294910e2d02947a996926b51c2a9048d7..044c0337bdde43c9c2b643f0f61d54bf6a7ab70c 100644 (file)
@@ -19,6 +19,7 @@
 #include "rom/gpio.h"
 #include "soc/dport_reg.h"
 #include "soc/io_mux_reg.h"
+#include "soc/rtc.h"
 #include "soc/rtc_cntl_reg.h"
 #include "soc/gpio_reg.h"
 #include "soc/dport_reg.h"
@@ -130,10 +131,10 @@ static void emac_set_rx_base_reg(void)
 *
 * (1) Initializing the Linked List. Connect the numerable nodes to a circular linked list, appoint one of the nodes as the head node, mark* the dirty_rx and cur_rx into the node, and mount the node on the hardware base address. Initialize cnt_rx into 0.
 *
-* (2) When hardware receives packets, nodes of linked lists will be fed with data packets from the base address by turns, marks the node 
+* (2) When hardware receives packets, nodes of linked lists will be fed with data packets from the base address by turns, marks the node
 * of linked lists as “HARDWARE UNUSABLE” and reports interrupts.
 *
-* (3) When the software receives the interrupts, it will handle the linked lists by turns from dirty_rx, send data packets to protocol 
+* (3) When the software receives the interrupts, it will handle the linked lists by turns from dirty_rx, send data packets to protocol
 * stack. dirty_rx will deviate backwards by turns and cnt_rx will by turns ++.
 *
 * (4) After the protocol stack handles all the data and calls the free function, it will deviate backwards by turns from cur_rx, mark the * node of linked lists as “HARDWARE USABLE” and cnt_rx will by turns --.
@@ -252,6 +253,7 @@ static void emac_set_user_config_data(eth_config_t *config )
 {
     emac_config.phy_addr = config->phy_addr;
     emac_config.mac_mode = config->mac_mode;
+    emac_config.clock_mode = config->clock_mode;
     emac_config.phy_init = config->phy_init;
     emac_config.emac_tcpip_input = config->tcpip_input;
     emac_config.emac_gpio_config = config->gpio_config;
@@ -291,7 +293,12 @@ static esp_err_t emac_verify_args(void)
     }
 
     if (emac_config.mac_mode != ETH_MODE_RMII) {
-        ESP_LOGE(TAG, "mac mode err,now only support RMII");
+        ESP_LOGE(TAG, "mac mode err, currently only support for RMII");
+        ret = ESP_FAIL;
+    }
+
+    if (emac_config.clock_mode > ETH_CLOCK_GPIO17_OUT) {
+        ESP_LOGE(TAG, "emac clock mode err");
         ret = ESP_FAIL;
     }
 
@@ -480,7 +487,7 @@ static void emac_process_rx_unavail(void)
         }
         uint32_t tmp_dirty = emac_config.dirty_rx;
         emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM;
+
         //copy data to lwip
         emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[tmp_dirty].basic.desc2),
                                      (((emac_config.dma_erx[tmp_dirty].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL);
@@ -529,7 +536,7 @@ static void emac_process_rx(void)
                     }
                     uint32_t tmp_dirty = emac_config.dirty_rx;
                     emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM;
+
                     //copy data to lwip
                     emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[tmp_dirty].basic.desc2),
                                                  (((emac_config.dma_erx[tmp_dirty].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL);
@@ -1036,14 +1043,46 @@ esp_err_t esp_eth_init_internal(eth_config_t *config)
 
     //before set emac reg must enable clk
     periph_module_enable(PERIPH_EMAC_MODULE);
+
+    if (emac_config.clock_mode != ETH_CLOCK_GPIO0_IN) {
+        // 50 MHz = 40MHz * (6 + 4) / (2 * (2 + 2) = 400MHz / 8
+        rtc_clk_apll_enable(1, 0, 0, 6, 2);
+        // the next to values have to be set AFTER "periph_module_enable" is called
+        REG_SET_FIELD(EMAC_EX_CLKOUT_CONF_REG, EMAC_EX_CLK_OUT_H_DIV_NUM, 0);
+        REG_SET_FIELD(EMAC_EX_CLKOUT_CONF_REG, EMAC_EX_CLK_OUT_DIV_NUM, 0);
+
+        if (emac_config.clock_mode == ETH_CLOCK_GPIO0_OUT) {
+            PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1);
+            REG_WRITE(PIN_CTRL, 6);
+            ESP_LOGD(TAG, "EMAC 50MHz clock output on GPIO0");
+        } else if (emac_config.clock_mode == ETH_CLOCK_GPIO16_OUT) {
+            PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO16_U, FUNC_GPIO16_EMAC_CLK_OUT);
+            ESP_LOGD(TAG, "EMAC 50MHz clock output on GPIO16");
+        } else if (emac_config.clock_mode == ETH_CLOCK_GPIO17_OUT) {
+            PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO17_U, FUNC_GPIO17_EMAC_CLK_OUT_180);
+            ESP_LOGD(TAG, "EMAC 50MHz inverted clock output on GPIO17");
+        }
+    }
+
     emac_enable_clk(true);
     REG_SET_FIELD(EMAC_EX_PHYINF_CONF_REG, EMAC_EX_PHY_INTF_SEL, EMAC_EX_PHY_INTF_RMII);
-
     emac_dma_init();
-    if (emac_config.mac_mode == ETH_MODE_RMII) {
-        emac_set_clk_rmii();
+
+    if (emac_config.clock_mode == ETH_CLOCK_GPIO0_IN) {
+        // external clock on GPIO0
+        REG_SET_BIT(EMAC_EX_CLK_CTRL_REG,    EMAC_EX_EXT_OSC_EN);
+        REG_CLR_BIT(EMAC_EX_CLK_CTRL_REG,    EMAC_EX_INT_OSC_EN);
+        REG_SET_BIT(EMAC_EX_OSCCLK_CONF_REG, EMAC_EX_OSC_CLK_SEL);
+        ESP_LOGD(TAG, "External clock input 50MHz on GPIO0");
+        if (emac_config.mac_mode == ETH_MODE_MII) {
+            REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_MII_CLK_RX_EN);
+            REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_MII_CLK_TX_EN);
+        }
     } else {
-        emac_set_clk_mii();
+        // internal clock by APLL
+        REG_CLR_BIT(EMAC_EX_CLK_CTRL_REG,    EMAC_EX_EXT_OSC_EN);
+        REG_SET_BIT(EMAC_EX_CLK_CTRL_REG,    EMAC_EX_INT_OSC_EN);
+        REG_CLR_BIT(EMAC_EX_OSCCLK_CONF_REG, EMAC_EX_OSC_CLK_SEL);
     }
 
     emac_config.emac_gpio_config();
@@ -1068,4 +1107,3 @@ esp_err_t esp_eth_init_internal(eth_config_t *config)
 _exit:
     return ret;
 }
-
index b0f793b33d8a95ee5f605fc03dd1c49e7574d2ba..0914ce1dc7c77e754bea41a3c652fe7a1d0c77c4 100644 (file)
@@ -118,6 +118,7 @@ const eth_config_t phy_lan8720_default_ethernet_config = {
     // for defaults.
     .phy_addr = 0,
     .mac_mode = ETH_MODE_RMII,
+    .clock_mode = ETH_CLOCK_GPIO0_IN,
     //Only FULLDUPLEX mode support flow ctrl now!
     .flow_ctrl_enable = true,
     .phy_init = phy_lan8720_init,
index 020329a2673daf596612704e685bef1520952b73..2f9cf50b6d7bdd6064f0cfc096c18020834918e6 100644 (file)
@@ -122,6 +122,7 @@ const eth_config_t phy_tlk110_default_ethernet_config = {
     // is used if all pins are unconnected.
     .phy_addr = 0x1,
     .mac_mode = ETH_MODE_RMII,
+    .clock_mode = ETH_CLOCK_GPIO0_IN,
     //Only FULLDUPLEX mode support flow ctrl now!
     .flow_ctrl_enable = true,
     .phy_init = phy_tlk110_init,
index 01cd0e29fa5d5b0ad2d63f140f752140ec5fb39a..0a9f3e770fbb827837be00a8875a979fe8b0aff5 100644 (file)
@@ -28,6 +28,13 @@ typedef enum {
     ETH_MODE_MII,
 } eth_mode_t;
 
+typedef enum  {
+    ETH_CLOCK_GPIO0_IN   = 0,
+    ETH_CLOCK_GPIO0_OUT  = 1,
+    ETH_CLOCK_GPIO16_OUT = 2,
+    ETH_CLOCK_GPIO17_OUT = 3
+} eth_clock_mode_t;
+
 typedef enum {
     ETH_SPEED_MODE_10M = 0,
     ETH_SPEED_MODE_100M,
@@ -90,8 +97,9 @@ typedef void (*eth_phy_power_enable_func)(bool enable);
 typedef struct {
     eth_phy_base_t  phy_addr;                   /*!< phy base addr (0~31) */
     eth_mode_t mac_mode;                        /*!< mac mode only support RMII now */
-    eth_tcpip_input_func tcpip_input;            /*!< tcpip input func  */
-    eth_phy_func phy_init;                       /*!< phy init func  */
+    eth_clock_mode_t clock_mode;                /*!< external/internal clock mode selecton */
+    eth_tcpip_input_func tcpip_input;           /*!< tcpip input func  */
+    eth_phy_func phy_init;                      /*!< phy init func  */
     eth_phy_check_link_func phy_check_link;     /*!< phy check link func  */
     eth_phy_check_init_func phy_check_init;     /*!< phy check init func  */
     eth_phy_get_speed_mode_func phy_get_speed_mode;     /*!< phy check init func  */
@@ -247,4 +255,3 @@ void esp_eth_free_rx_buf(void *buf);
 #endif
 
 #endif
-
index e4a6e5cc7ea0310729cd6e6e54094d07d2882591..cedff71d0168ee6a9165525df4b102d8f3e67157 100644 (file)
@@ -1,36 +1,56 @@
 # Ethernet Example
-
-Initialises the ethernet interface and enables it, then sends DHCP requests and tries to obtain a DHCP lease. If successful then you will be able to ping the device.
+Initialises the Ethernet interface and enables it, then sends DHCP requests and tries to obtain a DHCP lease. If successful then you will be able to ping the device.
 
 # PHY Configuration
-
-Use "make menuconfig" to set the PHY model and the PHY address, and configure the SMI I/O pins (see below). These configuration items will vary depending on the hardware configuration you are using.
+Use `make menuconfig` to set the PHY model and the PHY address, and configure the SMI I/O pins (see below). These configuration items will vary depending on the hardware configuration you are using.
 
 The default example configuration is correct for Espressif's Ethernet board with TLK110 PHY. Other hardware will require different configuration and/or changes to the example.
 
 ## PHY Address
-
 The PHY address depends on the hardware and the PHY configuration. Consult the documentation/datasheet for the PHY hardware you have.
 
-* Default address 31 is correct for Espressif's Ethernet board with TLK110 PHY.
-* Address 1 is correct for the common Waveshare LAN8720 PHY breakout.
-* Other LAN8720 breakouts may take address 0.
+* Address 31 (default) for Espressif's Ethernet board with TLK110 PHY
+* Address 1 for the common Waveshare LAN8720 PHY breakout
+* Address 0 for other LAN8720 breakouts
 
-If the PHY address is incorrect then the EMAC will initialise but all attempts to read/write configuration registers on the PHY will fail.
+If the PHY address is incorrect then the EMAC will initialise, but all attempts to read/write configuration registers on the PHY will fail.
 
-## RMII PHY Wiring
+## PHY Clock Wiring
+The ESP32 and the Ethernet PHY need a common 50MHz reference clock. This clock can either be be provided externally by a crystal oscillator (e.g. crystal connected to the PHY or a seperate crystal oscillator) or internally by using the EPS32's APLL.
+
+Because of its freqency the signal integrity has to be observed (ringing, capacitive load, resisitive load, skew, length of PCB trace). It is recommended to add a 33Ω resistor in series to reduce ringing.
+
+Possible configurations of the 50MHz clock signal:
+
+| Mode     | GPIO Pin | Signal name    | Notes                                                                                              |
+| -------- | -------- | -------------- | -------------------------------------------------------------------------------------------------- |
+| external | `GPIO0`  | `EMAC_TX_CLK`  | Input of 50MHz PHY clock                                                                           |
+| internal | `GPIO0`  | `CLK_OUT1`     | Output of 50MHz APLL clock. Signal quality might be an issue.                                      |
+| internal | `GPIO16` | `EMAC_CLK_OUT` | Output of 50MHz APLL clock.                                                                        |
+| internal | `GPIO17` | `EMAC_CLK_180` | Inverted output of 50MHz APLL clock. Found to be best suitable for LAN8720 with long signal lines. |
 
-The following PHY connections are required for RMII PHY data connections. These GPIO pin assignments cannot be changed.
 
-| GPIO    | RMII Signal | ESP32 EMAC Function | Notes |
-| ------- | ----------- | ------------------- | ----- |
-| 0       | REF_CLK     | EMAC_TX_CLK         | Currently this must be a 50MHz reference clock input from the PHY (ext_osc configuration). |
-| 21      | TX_EN       | EMAC_TX_EN          | |
-| 19      | TX0         | EMAC_TXD0           | |
-| 22      | TX1         | EMAC_TXD1           | |
-| 25      | RX0         | EMAC_RXD0           | |
-| 26      | RX1         | EMAC_RXD1           | |
-| 27      | CRS_DV      | EMAC_RX_DRV         | |
+#### External PHY Clock
+The external reference clock of 50MHz must be supplied on `GPIO0`. See note about `GPIO0` below.
+
+#### Internal PHY Clock
+The ESP32 can generate a 50MHz clock using its APLL. When the APLL is already used as clock source for other purposes (most likely I²S) external PHY has to be used.
+
+On different test setups clock output on `GPIO0` was found unstable because in most designs the signal path is not ideal for this high frequency (the PCB trace has several devices added to it and therefore the capacitive load is relatively high)
+
+The inverted clock signal `EMAC_CLK_180` was found working best with a LAN8720 PHY.
+
+## RMII PHY Wiring
+The following PHY connections are required for RMII PHY data connections. These `GPIO` pin assignments cannot be changed.
+
+| GPIO     | RMII Signal | ESP32 EMAC Function | Notes |
+| -------- | ----------- | ------------------- | ----- |
+| `GPIO21` | `TX_EN`     | `EMAC_TX_EN`        |       |
+| `GPIO19` | `TX0`       | `EMAC_TXD0`         |       |
+| `GPIO22` | `TX1`       | `EMAC_TXD1`         |       |
+| `GPIO25` | `RX0`       | `EMAC_RXD0`         |       |
+| `GPIO26` | `RX1`       | `EMAC_RXD1`         |       |
+| `GPIO27` | `CRS_DV`    | `EMAC_RX_DRV`       |       |
 
 ## RMII PHY SMI Wiring
 
@@ -40,17 +60,17 @@ For the example, these pins are configured via `make menuconfig` under the Examp
 
 | Default Example GPIO | RMII Signal | Notes         |
 | -------------------- | ----------- | ------------- |
-| 23                   | MDC         | Output to PHY |
-| 18                   | MDIO        | Bidirectional |
+| `GPIO23`             | `MDC`       | Output to PHY |
+| `GPIO18`             | `MDIO`      | Bidirectional |
 
 The defaults in the example are correct for Espressif's Ethernet development board.
 
-## Note about GPIO0
+## Note about `GPIO0`
 
-Because GPIO0 is a strapping pin for entering UART flashing mode on reset, care must be taken when also using this pin as EMAC_TX_CLK. If the clock output from the PHY is oscillating during reset, the ESP32 may randomly enter UART flashing mode.
+Because `GPIO0` is a strapping pin for entering UART flashing mode on reset, care must be taken when also using this pin as `EMAC_TX_CLK`. If the clock output from the PHY is oscillating during reset, the ESP32 may randomly enter UART flashing mode.
 
-One solution is to use an additional GPIO as a "power pin", which either powers the PHY on/off or enables/disables the PHY's own oscillator. This prevents the clock signal from being active during a system reset. For this configuration to work, GPIO0 also needs a pullup resistor and the "power pin" GPIO will need a pullup/pulldown resistor - as appropriate in order to keep the PHY clock disabled when the ESP32 is in reset.
+One solution is to use an additional GPIO as a "power pin", which either powers the PHY on/off or enables/disables the PHY's own oscillator. This prevents the clock signal from being active during a system reset. For this configuration to work, `GPIO0` also needs a pullup resistor and the "power pin" GPIO will need a pullup/pulldown resistor - as appropriate in order to keep the PHY clock disabled when the ESP32 is in reset.
 
 See the example source code to see how the "power pin" GPIO can be managed in software.
 
-The example defaults to using GPIO 17 for this function, but it can be overriden. On Espressif's Ethernet development board, GPIO 17 is the power pin used to enable/disable the PHY oscillator.
+The example defaults to using `GPIO17` for this function, but it can be overriden. On Espressif's Ethernet development board, `GPIO17` is the power pin used to enable/disable the PHY oscillator.
index f6c46b54d689358e8603500c01512eebeba74a47..b762dc54ac229bec523973d9ac5824e54b8bb6df 100644 (file)
@@ -18,12 +18,53 @@ config PHY_LAN8720
 
 endchoice
 
+
 config PHY_ADDRESS
     int "PHY Address (0-31)"
     default 31
     range 0 31
     help
         Select the PHY Address (0-31) for the hardware configuration and PHY model.
+        TLK110 default 31
+        LAN8720 default 1 or 0
+
+
+choice PHY_CLOCK_MODE
+    prompt "EMAC clock mode"
+    default PHY_CLOCK_GPIO0_IN
+    help
+        Select external (input on GPIO0) or internal (output on GPIO0, GPIO16 or GPIO17) clock
+
+
+config PHY_CLOCK_GPIO0_IN
+    bool "GPIO0 input"
+    help
+        Input of 50MHz refclock on GPIO0
+
+config PHY_CLOCK_GPIO0_OUT
+    bool "GPIO0 output"
+    help
+        Output the internal 50MHz APLL clock on GPIO0
+
+config PHY_CLOCK_GPIO16_OUT
+    bool "GPIO16 output"
+    help
+        Output the internal 50MHz APLL clock on GPIO16
+
+config PHY_CLOCK_GPIO17_OUT
+    bool "GPIO17 output (inverted)"
+    help
+        Output the internal 50MHz APLL clock on GPIO17 (inverted signal)
+
+endchoice
+
+config PHY_CLOCK_MODE
+    int
+    default 0 if PHY_CLOCK_GPIO0_IN
+    default 1 if PHY_CLOCK_GPIO0_OUT
+    default 2 if PHY_CLOCK_GPIO16_OUT
+    default 3 if PHY_CLOCK_GPIO17_OUT
+
 
 config PHY_USE_POWER_PIN
     bool "Use PHY Power (enable/disable) pin"
@@ -35,6 +76,7 @@ config PHY_USE_POWER_PIN
 config PHY_POWER_PIN
     int "PHY Power GPIO"
     default 17
+    range 0 33
     depends on PHY_USE_POWER_PIN
     help
         GPIO number to use for powering on/off the PHY.
@@ -42,12 +84,14 @@ config PHY_POWER_PIN
 config PHY_SMI_MDC_PIN
     int "SMI MDC Pin"
     default 23
+    range 0 33
     help
         GPIO number to use for SMI clock output MDC to PHY.
 
 config PHY_SMI_MDIO_PIN
     int "SMI MDIO Pin"
     default 18
+    range 0 33
     help
        GPIO number to use for SMI data pin MDIO to/from PHY.
 
index 8345ab6da4b82ac7efb4eb0ae22afc24ed32158c..832be191ee7b2dc3bf758fd8d50e75916f74cc7e 100644 (file)
 #include "nvs_flash.h"
 #include "driver/gpio.h"
 
+#include "soc/emac_ex_reg.h"
+#include "driver/periph_ctrl.h"
+
+
 #ifdef CONFIG_PHY_LAN8720
 #include "eth_phy/phy_lan8720.h"
 #define DEFAULT_ETHERNET_PHY_CONFIG phy_lan8720_default_ethernet_config
@@ -129,6 +133,7 @@ void app_main()
     config.phy_addr = CONFIG_PHY_ADDRESS;
     config.gpio_config = eth_gpio_config_rmii;
     config.tcpip_input = tcpip_adapter_eth_input;
+    config.clock_mode = CONFIG_PHY_CLOCK_MODE;
 
 #ifdef CONFIG_PHY_USE_POWER_PIN
     /* Replace the default 'power enable' function with an example-specific