diff --git a/cpu/esp32/doc.txt b/cpu/esp32/doc.txt
index b363bdd10a..8f6e703dd2 100644
--- a/cpu/esp32/doc.txt
+++ b/cpu/esp32/doc.txt
@@ -1142,7 +1142,7 @@ ESP32 provides different built-in possibilities to realize network devices:
\anchor esp32_ethernet_network_interface
## Ethernet MAC Network Interface [[TOC](#esp32_toc)]
-ESP32 provides an Ethernet MAC layer module (EMAC) according to the IEEE 802.3 standard which can be used together with an external physical layer chip (PHY) to realize a 100/10 Mbps Ethernet interface. Supported PHY chips are the Microchip LAN8710/LAN8720 and the Texas Instruments TLK110.
+ESP32 provides an Ethernet MAC layer module (EMAC) according to the IEEE 802.3 standard which can be used together with an external physical layer chip (PHY) to realize a 100/10 Mbps Ethernet interface. Supported PHY chips are the Microchip LAN8710/LAN8720, the IC Plus 101G, and the Texas Instruments TLK110.
The RIOT port for ESP32 realizes with module ```esp_eth``` a ```netdev``` driver for the EMAC which uses RIOT's standard Ethernet interface.
diff --git a/cpu/esp32/esp-eth/doc.txt b/cpu/esp32/esp-eth/doc.txt
index fc2ab09bcf..01b88a1b08 100644
--- a/cpu/esp32/esp-eth/doc.txt
+++ b/cpu/esp32/esp-eth/doc.txt
@@ -16,7 +16,7 @@
*
* @author Gunar Schorcht
-ESP32 provides an Ethernet MAC layer module (EMAC) according to the IEEE 802.3 standard which can be used together with an external physical layer chip (PHY) to realize a 100/10 Mbps Ethernet interface. Supported PHY chips are the Microchip LAN8710/LAN8720 and the Texas Instruments TLK110.
+ESP32 provides an Ethernet MAC layer module (EMAC) according to the IEEE 802.3 standard which can be used together with an external physical layer chip (PHY) to realize a 100/10 Mbps Ethernet interface. Supported PHY chips are the Microchip LAN8710/LAN8720, the IC Plus 101G, and the Texas Instruments TLK110.
The RIOT port for ESP32 realizes with module ```esp_eth``` a ```netdev``` driver for the EMAC which uses RIOT's standard Ethernet interface.
diff --git a/cpu/esp32/esp-eth/esp_eth_netdev.c b/cpu/esp32/esp-eth/esp_eth_netdev.c
index 3e0c1cbaf7..507da80c95 100644
--- a/cpu/esp32/esp-eth/esp_eth_netdev.c
+++ b/cpu/esp32/esp-eth/esp_eth_netdev.c
@@ -56,6 +56,10 @@
#include "eth_phy/phy_lan8720.h"
#define EMAC_ETHERNET_PHY_CONFIG phy_lan8720_default_ethernet_config
#endif
+#ifdef EMAC_PHY_IP101G
+#include "eth_phy/phy_ip101g.h"
+#define EMAC_ETHERNET_PHY_CONFIG phy_ip101g_default_ethernet_config
+#endif
#ifdef EMAC_PHY_TLK110
#include "eth_phy/phy_tlk110.h"
#define EMAC_ETHERNET_PHY_CONFIG phy_tlk110_default_ethernet_config
diff --git a/cpu/esp32/vendor/esp-idf/ethernet/eth_phy/phy_ip101g.c b/cpu/esp32/vendor/esp-idf/ethernet/eth_phy/phy_ip101g.c
new file mode 100644
index 0000000000..5ac1404274
--- /dev/null
+++ b/cpu/esp32/vendor/esp-idf/ethernet/eth_phy/phy_ip101g.c
@@ -0,0 +1,154 @@
+// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#define ENABLE_DEBUG (0)
+#include "debug.h"
+
+#include "esp_attr.h"
+#include "esp_log.h"
+#include "esp_eth.h"
+
+#include "eth_phy/phy_ip101g.h"
+#include "eth_phy/phy_reg.h"
+
+/* Value of MII_PHY_IDENTIFIER_REGs for IC Plus IP101G
+ * (Except for bottom 4 bits of ID2, used for model revision)
+ */
+#define IP101G_PHY_ID1 0x0243
+#define IP101G_PHY_ID2 0x0C50
+#define IP101G_PHY_ID2_MASK 0xFFF0
+
+/* IP101G-specific registers */
+#define PAGE_CONTROL_REG (0x14)
+
+#define POWER_DOWN BIT(11)
+
+#define PHY_SPECIAL_CONTROL_STATUS_REG (0x12)
+#define AUTO_NEGOTIATION_DONE BIT(11)
+
+#define PHY_CTRL_AND_SPECIFIC_STATUS_REG (0x1e)
+#define SPEED_DUPLEX_INDICATION_MASK (0x7)
+#define SPEED_DUPLEX_INDICATION_10T_HALF 0x01
+#define SPEED_DUPLEX_INDICATION_10T_FULL 0x05
+#define SPEED_DUPLEX_INDICATION_100T_HALF 0x02
+#define SPEED_DUPLEX_INDICATION_100T_FULL 0x06
+
+static const char *TAG = "ip101";
+
+static void phy_ip101g_page_select(uint8_t page)
+{
+ ESP_LOGD(TAG, "phy_ip101g_page_select(%u)", page);
+ esp_eth_smi_write(PAGE_CONTROL_REG, page);
+}
+
+void phy_ip101g_check_phy_init(void)
+{
+ phy_ip101g_dump_registers();
+
+ esp_eth_smi_wait_set(MII_BASIC_MODE_STATUS_REG, MII_AUTO_NEGOTIATION_COMPLETE, 0);
+ phy_ip101g_page_select(16);
+ esp_eth_smi_wait_set(PHY_SPECIAL_CONTROL_STATUS_REG, AUTO_NEGOTIATION_DONE, 0);
+}
+
+eth_speed_mode_t phy_ip101g_get_speed_mode(void)
+{
+ phy_ip101g_page_select(16);
+ uint16_t speed = esp_eth_smi_read(PHY_CTRL_AND_SPECIFIC_STATUS_REG) & SPEED_DUPLEX_INDICATION_MASK;
+ if (speed == SPEED_DUPLEX_INDICATION_100T_HALF || speed == SPEED_DUPLEX_INDICATION_100T_FULL) {
+ ESP_LOGD(TAG, "phy_ip101g_get_speed_mode(100)");
+ return ETH_SPEED_MODE_100M;
+ }
+ ESP_LOGD(TAG, "phy_ip101g_get_speed_mode(10)");
+ return ETH_SPEED_MODE_10M;
+}
+
+eth_duplex_mode_t phy_ip101g_get_duplex_mode(void)
+{
+ phy_ip101g_page_select(16);
+ uint16_t speed = esp_eth_smi_read(PHY_CTRL_AND_SPECIFIC_STATUS_REG) & SPEED_DUPLEX_INDICATION_MASK;
+ if (speed == SPEED_DUPLEX_INDICATION_10T_FULL || speed == SPEED_DUPLEX_INDICATION_100T_FULL) {
+ ESP_LOGD(TAG, "phy_ip101g_get_duplex_mode(FULL)");
+ return ETH_MODE_FULLDUPLEX;
+ }
+ ESP_LOGD(TAG, "phy_ip101g_get_duplex_mode(HALF)");
+ return ETH_MODE_HALFDUPLEX;
+}
+
+void phy_ip101g_power_enable(bool enable)
+{
+ ESP_LOGD(TAG, "phy_ip101g_power_enable(%d)", enable);
+ uint16_t cfg = esp_eth_smi_read(MII_BASIC_MODE_CONTROL_REG);
+ if (enable) {
+ cfg &= (UINT16_MAX ^ POWER_DOWN);
+ } else {
+ cfg |= POWER_DOWN;
+ }
+ esp_eth_smi_write(MII_BASIC_MODE_CONTROL_REG, cfg);
+ // TODO: only enable if config.flow_ctrl_enable == true
+ phy_mii_enable_flow_ctrl();
+}
+
+void phy_ip101g_init(void)
+{
+ ESP_LOGD(TAG, "phy_ip101g_init()");
+ phy_ip101g_dump_registers();
+
+ esp_eth_smi_write(MII_BASIC_MODE_CONTROL_REG, MII_SOFTWARE_RESET);
+
+ esp_err_t res1, res2;
+ do {
+ // Call esp_eth_smi_wait_value() with a timeout so it prints an error periodically
+ res1 = esp_eth_smi_wait_value(MII_PHY_IDENTIFIER_1_REG, IP101G_PHY_ID1, UINT16_MAX, 1000);
+ res2 = esp_eth_smi_wait_value(MII_PHY_IDENTIFIER_2_REG, IP101G_PHY_ID2, IP101G_PHY_ID2_MASK, 1000);
+ } while(res1 != ESP_OK || res2 != ESP_OK);
+
+ ets_delay_us(300);
+
+ // TODO: only enable if config.flow_ctrl_enable == true
+ phy_mii_enable_flow_ctrl();
+}
+
+const eth_config_t phy_ip101g_default_ethernet_config = {
+ // By default, the PHY address is 0 or 1 based on PHYAD0
+ // pin. Can also be overriden in software. See datasheet
+ // for defaults.
+ .phy_addr = 1,
+ .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_ip101g_init,
+ .phy_check_init = phy_ip101g_check_phy_init,
+ .phy_power_enable = phy_ip101g_power_enable,
+ .phy_check_link = phy_mii_check_link_status,
+ .phy_get_speed_mode = phy_ip101g_get_speed_mode,
+ .phy_get_duplex_mode = phy_ip101g_get_duplex_mode,
+ .phy_get_partner_pause_enable = phy_mii_get_partner_pause_enable,
+};
+
+void phy_ip101g_dump_registers(void)
+{
+ ESP_LOGD(TAG, "IP101G Registers:");
+ ESP_LOGD(TAG, "BCR 0x%04x", esp_eth_smi_read(0x0));
+ ESP_LOGD(TAG, "BSR 0x%04x", esp_eth_smi_read(0x1));
+ ESP_LOGD(TAG, "PHY1 0x%04x", esp_eth_smi_read(0x2));
+ ESP_LOGD(TAG, "PHY2 0x%04x", esp_eth_smi_read(0x3));
+ ESP_LOGD(TAG, "ANAR 0x%04x", esp_eth_smi_read(0x4));
+ ESP_LOGD(TAG, "ANLPAR 0x%04x", esp_eth_smi_read(0x5));
+ ESP_LOGD(TAG, "ANER 0x%04x", esp_eth_smi_read(0x6));
+ phy_ip101g_page_select(16);
+ ESP_LOGD(TAG, "PSCR 0x%04x", esp_eth_smi_read(0x10));
+ ESP_LOGD(TAG, "PSMR 0x%04x", esp_eth_smi_read(0x18));
+ ESP_LOGD(TAG, "PMCSSR 0x%04x", esp_eth_smi_read(0x1e));
+}
diff --git a/cpu/esp32/vendor/esp-idf/include/ethernet/eth_phy/phy_ip101g.h b/cpu/esp32/vendor/esp-idf/include/ethernet/eth_phy/phy_ip101g.h
new file mode 100644
index 0000000000..45a96d788a
--- /dev/null
+++ b/cpu/esp32/vendor/esp-idf/include/ethernet/eth_phy/phy_ip101g.h
@@ -0,0 +1,73 @@
+// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ETHERNET_ETH_PHY_PHY_IP101G_H
+#define ETHERNET_ETH_PHY_PHY_IP101G_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef RIOT_VERSION
+#include "eth_phy/phy.h"
+#else
+#include "phy.h"
+#endif
+
+/** @brief Dump all IP101G PHY SMI configuration registers
+ *
+ * @note These registers are dumped at 'debug' level, so output
+ * may not be visible depending on default log levels.
+ */
+void phy_ip101g_dump_registers(void);
+
+/** @brief Default IP101G phy_check_init function.
+ */
+void phy_ip101g_check_phy_init(void);
+
+/** @brief Default IP101G phy_get_speed_mode function.
+ */
+eth_speed_mode_t phy_ip101g_get_speed_mode(void);
+
+/** @brief Default IP101G phy_get_duplex_mode function.
+ */
+eth_duplex_mode_t phy_ip101g_get_duplex_mode(void);
+
+/** @brief Default IP101G phy_power_enable function.
+ *
+ * @note This function may need to be replaced with a custom function
+ * if the PHY has a GPIO to enable power or start a clock.
+ *
+ * Consult the ethernet example to see how this is done.
+ */
+void phy_ip101g_power_enable(bool);
+
+/** @brief Default IP101G phy_init function.
+ */
+void phy_ip101g_init(void);
+
+/** @brief Default IP101G PHY configuration
+ *
+ * This configuration is not suitable for use as-is, it will need
+ * to be modified for your particular PHY hardware setup.
+ *
+ * Consult the Ethernet example to see how this is done.
+ */
+extern const eth_config_t phy_ip101g_default_ethernet_config;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ETHERNET_ETH_PHY_PHY_IP101G_H */