[PATCH] STM32 lwIP addition

Robin Mueller robin.mueller.m at gmail.com
Tue Apr 27 17:41:35 UTC 2021


This patch adds the STM32H7 / NUCLEO-H743ZI lwIP port.
It also improves the architecture to make integration
of new BSPs easier.

https://github.com/rmspacefish/rtems-stm32-lwip is a self-contained
repository to test the lwIP integration for the arm/stm32h7
and arm/nucleo-h743zi BSP.

The STM32 port includes the LAN driver (lan8742.c), the
primary port functions in ethernetif.c and some application code
taken from CubeH7, which can serve as a starting point for
implementations and was also tailored to RTEMS.

The common source file were refactored to be more generic and independent
of the used BSP.
---
 .gitignore                                    |  10 +
 .gitmodules                                   |   1 +
 README.md                                     |  23 +
 lwip-to-rtems.py                              |   0
 .../drivers/{eth_lwip.c => rtems_lwip.c}      | 181 +++--
 .../drivers/{eth_lwip.h => rtems_lwip.h}      |  79 +-
 .../{eth_lwip_default.h => rtems_lwip_conf.h} |  30 +-
 lwip/ports/drivers/stm32h7/app_dhcp.c         | 217 +++++
 lwip/ports/drivers/stm32h7/app_ethernet.c     | 187 +++++
 lwip/ports/drivers/stm32h7/ethernetif.c       | 758 ++++++++++++++++++
 .../stm32h7/include/lwip_port/app_dhcp.h      |  38 +
 .../stm32h7/include/lwip_port/app_ethernet.h  |  56 ++
 .../stm32h7/include/lwip_port/ethernetif.h    |  56 ++
 lwip/ports/drivers/stm32h7/lan8742.c          | 664 +++++++++++++++
 lwip/ports/drivers/stm32h7/lan8742.h          | 448 +++++++++++
 .../stm32h7/template/lwipopts_template.h      | 289 +++++++
 .../ports/drivers/{ => tms570}/phy_dp83848h.c |   0
 .../ports/drivers/{ => tms570}/phy_dp83848h.h |   0
 .../tms570/template/lwipopts_template.h       |  75 ++
 lwip/ports/drivers/{ => tms570}/ti_drv_emac.h |   0
 lwip/ports/drivers/{ => tms570}/ti_drv_mdio.h |   0
 lwip/ports/drivers/{ => tms570}/tms570_emac.h |   0
 .../ports/drivers/{ => tms570}/tms570_netif.c |  11 +-
 .../ports/drivers/{ => tms570}/tms570_netif.h |  31 +
 lwip/ports/os/rtems/arch/cc.h                 |   3 +
 lwip/ports/os/rtems/arch/sys_arch.c           |  32 +-
 lwip/ports/os/rtems/arch/sys_arch.h           |  18 +-
 lwip/src/include/lwip/sys.h                   |   1 -
 lwip/{ports/os => test}/lwipopts.h            |   0
 waf                                           |   0
 30 files changed, 3078 insertions(+), 130 deletions(-)
 create mode 100644 README.md
 mode change 100755 => 100644 lwip-to-rtems.py
 rename lwip/ports/drivers/{eth_lwip.c => rtems_lwip.c} (57%)
 rename lwip/ports/drivers/{eth_lwip.h => rtems_lwip.h} (56%)
 rename lwip/ports/drivers/{eth_lwip_default.h => rtems_lwip_conf.h} (68%)
 create mode 100644 lwip/ports/drivers/stm32h7/app_dhcp.c
 create mode 100644 lwip/ports/drivers/stm32h7/app_ethernet.c
 create mode 100644 lwip/ports/drivers/stm32h7/ethernetif.c
 create mode 100644 lwip/ports/drivers/stm32h7/include/lwip_port/app_dhcp.h
 create mode 100644 lwip/ports/drivers/stm32h7/include/lwip_port/app_ethernet.h
 create mode 100644 lwip/ports/drivers/stm32h7/include/lwip_port/ethernetif.h
 create mode 100644 lwip/ports/drivers/stm32h7/lan8742.c
 create mode 100644 lwip/ports/drivers/stm32h7/lan8742.h
 create mode 100644 lwip/ports/drivers/stm32h7/template/lwipopts_template.h
 rename lwip/ports/drivers/{ => tms570}/phy_dp83848h.c (100%)
 rename lwip/ports/drivers/{ => tms570}/phy_dp83848h.h (100%)
 create mode 100644 lwip/ports/drivers/tms570/template/lwipopts_template.h
 rename lwip/ports/drivers/{ => tms570}/ti_drv_emac.h (100%)
 rename lwip/ports/drivers/{ => tms570}/ti_drv_mdio.h (100%)
 rename lwip/ports/drivers/{ => tms570}/tms570_emac.h (100%)
 rename lwip/ports/drivers/{ => tms570}/tms570_netif.c (99%)
 rename lwip/ports/drivers/{ => tms570}/tms570_netif.h (74%)
 rename lwip/{ports/os => test}/lwipopts.h (100%)
 mode change 100755 => 100644 waf

diff --git a/.gitignore b/.gitignore
index 618d791..31a00bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,14 @@
+# Eclipse files
+/.cproject
+/.project
+/.settings
+
+# Python
 __pycache__
+
+# Waf
 .lock-waf*
 .waf*
+
+# Builds
 build/
diff --git a/.gitmodules b/.gitmodules
index 4ea46da..a98aac6 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,3 +4,4 @@
 [submodule "rtems_waf"]
 	path = rtems_waf
 	url = git://git.rtems.org/rtems_waf.git
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e789219
--- /dev/null
+++ b/README.md
@@ -0,0 +1,23 @@
+RTEMS lwIP Repository
+======
+
+This repository contains the RTEMS lwIP support and all available ports.
+Currently, the following RTEMS BSPs are supported:
+
+ - All `arm/tms*` BSPs.
+ - The `arm/stm32h7` and the `arm/nucleo-h743zi` BSP. An example application can be 
+   found [here](https://github.com/rmspacefish/rtems-stm32-lwip).
+ 
+# Using this repository
+
+The repository contains the lwIP sources, the OS port for RTEMS and port files
+belonging to a RTEMS BSP.
+
+The user still needs to supply the `lwipopts.h` configuration file. The port folders contain
+template option files to get started. The user can copy and rename this files into the application
+and then pass the include path to the build system.
+
+# Compiling with CMake
+
+# Compiling with waf
+
diff --git a/lwip-to-rtems.py b/lwip-to-rtems.py
old mode 100755
new mode 100644
diff --git a/lwip/ports/drivers/eth_lwip.c b/lwip/ports/drivers/rtems_lwip.c
similarity index 57%
rename from lwip/ports/drivers/eth_lwip.c
rename to lwip/ports/drivers/rtems_lwip.c
index b1ae4bb..85b6f07 100644
--- a/lwip/ports/drivers/eth_lwip.c
+++ b/lwip/ports/drivers/rtems_lwip.c
@@ -31,53 +31,47 @@
  * Based on work of Carlos Jenkins, Rostislav Lisovy, Jan Dolezal
  */
 
-//#define DEBUG 1
-#include "lwip/tcpip.h" /* includes - lwip/opt.h, lwip/api_msg.h, lwip/netifapi.h, lwip/pbuf.h, lwip/api.h, lwip/sys.h, lwip/timers.h, lwip/netif.h */
+#include "rtems_lwip.h"
+#include "rtems_lwip_conf.h"
+
+#include "lwip/init.h"
 #include "lwip/stats.h"
 #include "lwip/dhcp.h"
+#include "netif/ethernet.h"
+
+#if LWIP_NETIF_API == 1
 #include "lwip/netifapi.h"
-#include "netif/etharp.h" /* includes - lwip/ip.h, lwip/netif.h, lwip/ip_addr.h, lwip/pbuf.h */
-#include "eth_lwip_default.h"
-#include "eth_lwip.h"
-#include "tms570_netif.h"
-#include <stdio.h>
+#endif
 
-/* The lwIP network interface structure for the Ethernet EMAC. */
-#ifndef MAX_EMAC_INSTANCE
-#define MAX_EMAC_INSTANCE           1
-#endif /*MAX_EMAC_INSTANCE*/
+#if NO_SYS == 0
+#include "lwip/tcpip.h"
+#endif
+
+#include <stdio.h>
 
 #define SUCCESS ERR_OK
 #define FAILURE ERR_IF
 
-static struct netif eth_lwip_netifs[MAX_EMAC_INSTANCE];
-static void eth_lwip_conv_IP_decimal_Str(ip_addr_t ip, uint8_t *ipStr);
-
+/* Assigned in specific port */
+extern netif_init_fn eth_lwip_init_fnc;
 
-void
-eth_lwip_get_dhcp_info(void)
-{
-  struct netif *netif = eth_lwip_get_netif(0);
+/* The lwIP network interface structure for the Ethernet EMAC. */
+#ifndef MAX_EMAC_INSTANCE
+#define MAX_EMAC_INSTANCE           1
+#endif /*MAX_EMAC_INSTANCE*/
 
-  if (dhcp_supplied_address(netif)) {
-    uint8_t ipString[16]; // FIXME change the functions to use char
-    eth_lwip_conv_IP_decimal_Str(netif->ip_addr, ipString);
-    printf("Address: %s\n", ipString);
-    eth_lwip_conv_IP_decimal_Str(netif->netmask, ipString);
-    printf("Netmask: %s\n", ipString);
-    eth_lwip_conv_IP_decimal_Str(netif->gw, ipString);
-    printf("Gateway: %s\n", ipString);
-  } else {
-    printf("dhcp not bound\n");
-  }
-}
+struct netif eth_lwip_netifs[MAX_EMAC_INSTANCE];
 
 int8_t
-eth_lwip_init(uint8_t *mac_addr)
+rtems_lwip_init(uint8_t *mac_addr, netif_status_callback_fn netif_status_cb)
 {
   unsigned int instance_number = 0;
-  int8_t retVal = SUCCESS;
+  int8_t retval = SUCCESS;
 
+#if NO_SYS == 1
+  /* Initialize the lwIP stack */
+  lwip_init();
+#endif
 
   ip4_addr_t ip_addr;
   ip4_addr_t net_mask;
@@ -89,63 +83,77 @@ eth_lwip_init(uint8_t *mac_addr)
   if (mac_addr == NULL)
     mac_addr = default_mac;             /* use default MAC */
 
-  eth_lwip_set_hwaddr(netif, mac_addr);
+  rtems_lwip_set_hwaddr(netif, mac_addr);
+
+#if NO_SYS == 0
   tcpip_init(NULL, NULL);
+#endif
+
+  rtems_lwip_determine_static_ipv4_address(&ip_addr, &net_mask, &gw_addr);
 
-#if STATIC_IP_ADDRESS
-  ip_addr.addr = htonl(ETH_IP_ADDR);
-  net_mask.addr = htonl(ETH_NETMASK);
-  gw_addr.addr = htonl(ETH_GW);
+  netif_input_fn netif_input_fnc = NULL;
+#if NO_SYS == 1
+  netif_input_fnc = &ethernet_input;
 #else
-  ip_addr.addr = 0;
-  net_mask.addr = 0;
-  gw_addr.addr = 0;
+  netif_input_fnc = &tcpip_input;
 #endif
 
   netif_tmp = netif_add(netif, &ip_addr, &net_mask, &gw_addr,
-                        NULL, ETH_LWIP_INIT_NETIF_FNC, tcpip_input);
+                        NULL, eth_lwip_init_fnc, netif_input_fnc);
 
   if (netif_tmp == NULL)
     return NETIF_ADD_ERR;
 
   netif_set_default(netif);
+
+#if LWIP_NETIF_API == 1
   netifapi_netif_set_up(netif);
-#if !STATIC_IP_ADDRESS
+#endif
+
+#if LWIP_NETIF_LINK_CALLBACK
+  if(netif_status_cb != NULL) {
+    netif_status_cb(netif);
+    netif_set_link_callback(netif, netif_status_cb);
+  }
+#endif
+
+#if !STATIC_IP_ADDRESS && NO_SYS == 0 && LWIP_NETIF_API == 1
   netifapi_dhcp_start(netif);
 #endif
 
-  return retVal;
+  return retval;
+}
+
+void
+rtems_lwip_print_dhcp_info(void)
+{
+  struct netif *netif = rtems_lwip_get_netif(0);
+
+  if (dhcp_supplied_address(netif)) {
+    printf("DHCP information: \n\r");
+    printf("Address: %s\n\r", ip4addr_ntoa(netif_ip4_addr(netif)));
+    printf("Netmask: %s\n\r", ip4addr_ntoa(netif_ip4_netmask(netif)));
+    printf("Gateway: %s\n\r", ip4addr_ntoa(netif_ip4_gw(netif)));
+  } else {
+    printf("DHCP not bound\n\r");
+  }
 }
 
 int
-eth_lwip_get_netif_status_cmd(int argc, char *arg[])
+rtems_lwip_get_netif_status_cmd(int argc, char *arg[])
 {
   stats_display();
   return 0;
 }
 
 struct netif *
-eth_lwip_get_netif(uint32_t instance_number)
+rtems_lwip_get_netif(uint32_t instance_number)
 {
   if (instance_number >= MAX_EMAC_INSTANCE)
     return NULL;
   return &eth_lwip_netifs[instance_number];
 }
 
-static void
-eth_lwip_conv_IP_decimal_Str(ip_addr_t ip, uint8_t *ipStr)
-{
-  uint32_t addr;
- #if LWIP_IPV6
-  addr = ip.u_addr.ip4.addr;
- #else
-  addr = ip.addr;
- #endif
-
-  snprintf((char *)ipStr, 16, "%lu.%lu.%lu.%lu",
-           (addr >> 24), ((addr >> 16) & 0xff), ((addr >> 8) & 0xff), (addr & 0xff));
-}
-
 /*
 * Function to set the MAC address to the interface
 * @param   inst_num the instance number
@@ -153,7 +161,7 @@ eth_lwip_conv_IP_decimal_Str(ip_addr_t ip, uint8_t *ipStr)
 * @note    mac_addr[0] is considered MSB
 */
 void
-eth_lwip_set_hwaddr(struct netif *netif, uint8_t *mac_addr)
+rtems_lwip_set_hwaddr(struct netif *netif, uint8_t *mac_addr)
 {
   int i;
 
@@ -171,18 +179,61 @@ eth_lwip_set_hwaddr(struct netif *netif, uint8_t *mac_addr)
 }
 
 void
-eth_lwip_get_hwaddr_str(struct netif *netif, uint8_t *macStr)
+rtems_lwip_get_hwaddr_str(struct netif *netif, uint8_t *mac_str)
 {
   uint8_t index, outindex = 0;
   char ch;
 
   for (index = 0; index < netif->hwaddr_len; index++) {
     if (index)
-      macStr[outindex++] = ':';
+      mac_str[outindex++] = ':';
     ch = (netif->hwaddr[index] >> 4);
-    macStr[outindex++] = (ch < 10) ? (ch + '0') : (ch - 10 + 'A');
+    mac_str[outindex++] = (ch < 10) ? (ch + '0') : (ch - 10 + 'A');
     ch = (netif->hwaddr[index] & 0xf);
-    macStr[outindex++] = (ch < 10) ? (ch + '0') : (ch - 10 + 'A');
+    mac_str[outindex++] = (ch < 10) ? (ch + '0') : (ch - 10 + 'A');
   }
-  macStr[outindex] = 0;
+  mac_str[outindex] = 0;
+}
+
+void
+rtems_lwip_convert_ip_to_decimal_str(ip_addr_t ip, uint8_t *ip_str)
+{
+  uint32_t addr;
+ #if LWIP_IPV6
+  addr = ip.u_addr.ip4.addr;
+ #else
+  addr = ip.addr;
+ #endif
+
+  snprintf((char *)ip_str, 16, "%lu.%lu.%lu.%lu",
+           (addr >> 24), ((addr >> 16) & 0xff), ((addr >> 8) & 0xff), (addr & 0xff));
+}
+
+void rtems_lwip_determine_static_ipv4_address(ip4_addr_t* ip_addr, ip4_addr_t* netmask,
+        ip4_addr_t* gw_addr) {
+#if STATIC_IP_ADDRESS == 1
+
+#if CALCULATE_ETH_IP_ADDR == 1
+  IP_ADDR4(ip_addr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
+#else
+  ip_addr->addr = htonl(ETH_IP_ADDR);
+#endif
+
+#if CALCULATE_ETH_NETMASK == 1
+  IP_ADDR4(net_mask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
+#else
+  net_mask->addr = htonl(ETH_NETMASK);
+#endif
+
+#if CALCULATE_GW_ADDRESS == 1
+  IP_ADDR4(gw_addr, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
+#else
+  gw_addr->addr = htonl(ETH_GW);
+#endif
+
+#else
+  ip_addr_set_zero_ip4(ip_addr);
+  ip_addr_set_zero_ip4(netmask);
+  ip_addr_set_zero_ip4(gw_addr);
+#endif /* STATIC_IP_ADDRESS == 0 */
 }
diff --git a/lwip/ports/drivers/eth_lwip.h b/lwip/ports/drivers/rtems_lwip.h
similarity index 56%
rename from lwip/ports/drivers/eth_lwip.h
rename to lwip/ports/drivers/rtems_lwip.h
index a9c0325..39a6d16 100644
--- a/lwip/ports/drivers/eth_lwip.h
+++ b/lwip/ports/drivers/rtems_lwip.h
@@ -34,67 +34,64 @@
 #ifndef __ETH_LWIP_H
 #define __ETH_LWIP_H
 
+#include "lwip/netif.h"
+#include "rtems_lwip_conf.h"
+
 #include <stdio.h>
 #include <stdbool.h>
-#include "lwip/netif.h"
 
-
-/**
- * While scanning phy addresses no alive phy was found.
- * Return value of rpp_eth_hw_init() function.
- */
-#define NO_PHY_ALIVE             -1
-/**
- * Scanning default phy address, it was found it's not alive.
- * Return value of rpp_eth_hw_init() function.
- */
-#define DFLT_PHY_NOT_ALIVE       -1
-/**
- * When setting autonegotiation parameters to EMAC module, there was found impossible mode (usually on timeout of autonegotiation).
- * Return value of rpp_eth_hw_init_postInit() function.
- */
-#define UNKN_DUPLEX_MODE         -2 /* this could mean that autonegotiation was not completed yet */
-/**
- * Phy is down error.
- * Return value of rpp_eth_init_postInit() function.
- */
-#define PHY_LINK_DOWN            -3
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /**
  * LwIP netif couldn't be added, it is likely that there was an error during initialization of the hardware.
  */
 #define NETIF_ADD_ERR            -10 /* could be one of previous, except PHY_LINK_DOWN - currently */
+
 /**
- * Memory requirements couldn't be satisfied.
+ * @brief   RTEMS lwIP initialization function.
+ *
+ * Call this method before using this module. This function also takes care of initializing
+ * the lwIP stack by calling lwip_init.
+ * @param   mac_addr            Can be set to NULL to use default mac address
+ * @param   netif_status_cb     Callback function which will be called if the network
+ *                              link status changes
+ * @return
+ *  - SUCCESS if initialization successful.\n
+ *  - NETIF_ADD_ERR Error adding net interface.
  */
-#define DHCP_MEM_ERR             -11
+int8_t rtems_lwip_init(uint8_t *mac_addr, netif_status_callback_fn netif_status_cb);
 
 /**
- * configures whether rpp_eth_get_macAddrStr() creates string with big or small latin letters
+ * @brief   Access to the net interface instances
  */
-#define MAC_BIG_LETTERS           1
+struct netif *rtems_lwip_get_netif(uint32_t instance_number);
 
 /**
- * ETH module system startup initialization.
- *
- * Call this method before using this module.
- * This method starts autonegotiation and doesn't check for end of autoneg.
- * When eth module is about to be used, you have to run rpp_eth_init_postInit()
- * first and you should check whether link is up.
- *
- * @return SUCCESS if initialization successful.\n
- *         FAILURE if module already initialized.
+ * @brief   Print information about the assigned DHCP address.
  */
-int8_t eth_lwip_init(uint8_t *mac_addr);
-void eth_lwip_get_dhcp_info(void);
-int eth_lwip_get_netif_status_cmd(int argc, char *arg[]);
-void eth_lwip_set_hwaddr(struct netif *netif, uint8_t *mac_addr);
-void eth_lwip_get_hwaddr_str(struct netif *netif, uint8_t *macStr);
-struct netif *eth_lwip_get_netif(uint32_t instance_number);
+void rtems_lwip_print_dhcp_info(void);
+
+void rtems_lwip_convert_ip_to_decimal_str(ip_addr_t ip, uint8_t *ip_str);
 
+int rtems_lwip_get_netif_status_cmd(int argc, char *arg[]);
 
+void rtems_lwip_set_hwaddr(struct netif *netif, uint8_t *mac_addr);
 
+void rtems_lwip_get_hwaddr_str(struct netif *netif, uint8_t *mac_str);
 
+/**
+ * @brief   Determines a static IP address from the configuration files.
+ * @param ip_addr
+ * @param netmask
+ * @param gw
+ */
+void rtems_lwip_determine_static_ipv4_address(ip4_addr_t* ip_addr, ip4_addr_t* netmask,
+        ip4_addr_t* gw);
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* __ETH_LWIP_H */
diff --git a/lwip/ports/drivers/eth_lwip_default.h b/lwip/ports/drivers/rtems_lwip_conf.h
similarity index 68%
rename from lwip/ports/drivers/eth_lwip_default.h
rename to lwip/ports/drivers/rtems_lwip_conf.h
index 6194d06..85e48f3 100644
--- a/lwip/ports/drivers/eth_lwip_default.h
+++ b/lwip/ports/drivers/rtems_lwip_conf.h
@@ -1,14 +1,8 @@
 #ifndef __ETH_LWIP_DEFAULT_H
 #define __ETH_LWIP_DEFAULT_H
 
-/* #define DEBUG 1 */
-/* #define STATIC_IP_ADDRESS 1 */
-
-void tms570_eth_memp_avaible(int type);
-
-#define ETH_LWIP_INIT_NETIF_FNC tms570_eth_init_netif
-/*called from memp_free() when a memp pool was empty and an item is now available*/
-#define LWIP_HOOK_MEMP_AVAILABLE tms570_eth_memp_avaible
+#include "lwipopts.h"
+#include "lwip/etharp.h"
 
 /* this MAC address is used when user put NULL on the right place when calling postInit function */
 /**
@@ -20,29 +14,43 @@ void tms570_eth_memp_avaible(int type);
 #define ETH_MAC_ADDR             { 0x12 /* Unicast, Locally administered */, 0x34, 0x56, 0x78, 0x9A, 0xBC }
 #endif
 
-#if STATIC_IP_ADDRESS
-
 /**
  * When static IP is configured in lwipopts.h, this IP address is used for interface.
  */
 #ifndef ETH_IP_ADDR
+
+#if defined(IP_ADDR0) && defined(IP_ADDR1) && defined(IP_ADDR2) && defined(IP_ADDR3)
+#define CALCULATE_ETH_IP_ADDR
+#else
 #define ETH_IP_ADDR               0xC0A8F701 /* 192.168.247.1  */
 #endif
 
+#endif
+
 /**
  * When static IP is configured in lwipopts.h, this NETMASK address is used for interface.
  */
 #ifndef ETH_NETMASK
+
+#if defined(NETMASK_ADDR0) && defined(NETMASK_ADDR1) && defined(NETMASK_ADDR2) && defined(NETMASK_ADDR3)
+#define CALCULATE_ETH_NETMASK
+#else
 #define ETH_NETMASK               0xFFFFFF00 /* 255.255.255.0  */
 #endif
 
+#endif
+
 /**
  * When static IP is configured in lwipopts.h, this Gateway address is used for interface.
  */
 #ifndef ETH_GW
+
+#if defined(GW_ADDR0) && defined(GW_ADDR1) && defined(GW_ADDR2) && defined(GW_ADDR3)
+#define CALCULATE_GW_ADDRESS
+#else
 #define ETH_GW                    0xC0A8F7FE /* 192.168.247.254*/
 #endif
 
-#endif /* STATIC_IP_ADDRESS */
+#endif /* ETH_GW */
 
 #endif /* __ETH_LWIP_DEFAULT_H */
diff --git a/lwip/ports/drivers/stm32h7/app_dhcp.c b/lwip/ports/drivers/stm32h7/app_dhcp.c
new file mode 100644
index 0000000..3889ad7
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/app_dhcp.c
@@ -0,0 +1,217 @@
+/* Includes ------------------------------------------------------------------*/
+#include "app_dhcp.h"
+#include "ethernetif.h"
+#include "stm32h7xx_hal.h"
+#include "lwip/opt.h"
+#include "lwip/dhcp.h"
+#include "lwip/ip_addr.h"
+#include "rtems_lwip.h"
+#include "rtems_lwip_conf.h"
+
+#if NO_SYS == 0
+#include "lwip/sys.h"
+#endif
+#include <sys/unistd.h>
+
+#if LWIP_DHCP
+
+#ifndef MAX_DHCP_TRIES
+#define MAX_DHCP_TRIES  4
+#endif
+
+
+#if NO_SYS == 1
+uint32_t DHCPfineTimer = 0;
+
+#ifndef RTEMS_LWIP_DHCP_TASK_INTERVAL_MS
+#define RTEMS_LWIP_DHCP_TASK_INTERVAL_MS 500
+#endif
+
+#endif
+
+void dhcp_thread(void* argument);
+
+LwipThreadArgs dhcp_args;
+
+uint8_t DHCP_state = DHCP_START;
+
+#if NO_SYS == 0
+
+void rtems_lwip_start_dhcp_thread(uint32_t task_interval_ms,
+    size_t task_stack, uint8_t task_priority) {
+  dhcp_args.netif = rtems_lwip_get_netif(0);
+  dhcp_args.task_interval_ms = task_interval_ms;
+  sys_thread_new("DHCP", dhcp_thread, (void*) &dhcp_args, task_stack, task_priority);
+}
+
+#endif
+
+/**
+ * @brief  DHCP Process
+ * @param  argument: network interface
+ * @retval None
+ */
+void dhcp_thread(void* argument)
+{
+  ip_addr_t ipaddr;
+  ip_addr_t netmask;
+  ip_addr_t gw;
+  struct dhcp *dhcp = NULL;
+  LwipThreadArgs* args = (LwipThreadArgs*) argument;
+  if(args == NULL) {
+    printf("dhcp_thread: Passed arguments are invalid!\n\r");
+    exit(1);
+  }
+
+  struct netif* netif = args->netif;
+  if(netif == NULL) {
+    printf("dhcp_thread: Passed netif is invalid!\n\r");
+    exit(1);
+  }
+
+  for (;;)
+  {
+    switch (DHCP_state)
+    {
+    case DHCP_START:
+    {
+      ip_addr_set_zero_ip4(&netif->ip_addr);
+      ip_addr_set_zero_ip4(&netif->netmask);
+      ip_addr_set_zero_ip4(&netif->gw);
+      DHCP_state = DHCP_WAIT_ADDRESS;
+
+      dhcp_start(netif);
+    }
+    break;
+    case DHCP_WAIT_ADDRESS:
+    {
+      if (dhcp_supplied_address(netif))
+      {
+        DHCP_state = DHCP_ADDRESS_ASSIGNED;
+        printf("IP address assigned by a DHCP server: %s\n\r",
+            ip4addr_ntoa(netif_ip4_addr(netif)));
+      }
+      else
+      {
+        dhcp = (struct dhcp *)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP);
+
+        /* DHCP timeout */
+        if (dhcp->tries > MAX_DHCP_TRIES)
+        {
+          DHCP_state = DHCP_TIMEOUT;
+
+          uint8_t iptxt[20];
+          sprintf((char *)iptxt, "%s", ip4addr_ntoa(netif_ip4_addr(netif)));
+          printf("DHCP timeout\n\r");
+          printf("Setting static IP address %s..\n\r", iptxt);
+          /* Static address used */
+          rtems_lwip_determine_static_ipv4_address(&ipaddr, &netmask, &gw);
+          netif_set_addr(netif, ip_2_ip4(&ipaddr), ip_2_ip4(&netmask), ip_2_ip4(&gw));
+
+        }
+      }
+    }
+    break;
+    case DHCP_LINK_DOWN:
+    {
+      DHCP_state = DHCP_OFF;
+    }
+    break;
+    default: break;
+    }
+
+    usleep(args->task_interval_ms * 1000);
+  }
+}
+
+#if NO_SYS == 1
+
+void DHCP_Process(struct netif *netif);
+
+/**
+ * @brief  DHCP periodic check
+ * @param  netif
+ * @retval None
+ */
+void dhcp_periodic_handle(struct netif *netif)
+{
+  /* Fine DHCP periodic process every 500ms */
+  if (HAL_GetTick() - DHCPfineTimer >= RTEMS_LWIP_DHCP_TASK_INTERVAL_MS)
+  {
+    DHCPfineTimer = HAL_GetTick();
+    /* process DHCP state machine */
+    DHCP_Process(netif);
+  }
+}
+
+/**
+ * @brief  DHCP_Process_Handle
+ * @param  None
+ * @retval None
+ */
+void DHCP_Process(struct netif *netif)
+{
+  ip_addr_t ipaddr;
+  ip_addr_t netmask;
+  ip_addr_t gw;
+  struct dhcp *dhcp = NULL;
+  switch (DHCP_state)
+  {
+  case DHCP_START: {
+
+    ip_addr_set_zero_ip4(&netif->ip_addr);
+    ip_addr_set_zero_ip4(&netif->netmask);
+    ip_addr_set_zero_ip4(&netif->gw);
+    dhcp_start(netif);
+    DHCP_state = DHCP_WAIT_ADDRESS;
+  }
+  break;
+
+  case DHCP_WAIT_ADDRESS: {
+    if (dhcp_supplied_address(netif)) {
+      DHCP_state = DHCP_ADDRESS_ASSIGNED;
+      printf("IP address assigned by a DHCP server: %s\n\r", ip4addr_ntoa(netif_ip4_addr(netif)));
+    }
+    else
+    {
+      dhcp = (struct dhcp *)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP);
+
+      /* DHCP timeout */
+      if (dhcp->tries > MAX_DHCP_TRIES)
+      {
+        DHCP_state = DHCP_TIMEOUT;
+
+        uint8_t iptxt[20];
+        sprintf((char *)iptxt, "%s", ip4addr_ntoa(netif_ip4_addr(netif)));
+        printf("DHCP timeout\n\r");
+        printf("Setting static IP address %s..\n\r", iptxt);
+        /* Static address used */
+        rtems_lwip_determine_static_ipv4_address(&ipaddr, &netmask, &gw);
+        netif_set_addr(netif, &ipaddr, &netmask, &gw);
+
+      }
+    }
+  }
+  break;
+  case DHCP_LINK_DOWN: {
+    /* Stop DHCP */
+    //dhcp_release_and_stop(netif);
+    DHCP_state = DHCP_OFF;
+  }
+  break;
+  default: break;
+  }
+}
+
+#endif /* NO_SYS == 1 */
+
+void set_dhcp_state(uint8_t new_state) {
+  DHCP_state = new_state;
+}
+
+uint8_t get_dhcp_state() {
+  return DHCP_state;
+}
+
+#endif  /* LWIP_DHCP */
+
diff --git a/lwip/ports/drivers/stm32h7/app_ethernet.c b/lwip/ports/drivers/stm32h7/app_ethernet.c
new file mode 100644
index 0000000..bafec01
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/app_ethernet.c
@@ -0,0 +1,187 @@
+/**
+  ******************************************************************************
+  * @file    LwIP/LwIP_HTTP_Server_Netconn_RTOS/Src/app_ethernet.c 
+  * @author  MCD Application Team
+  * @brief   Ethernet specefic module
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>© Copyright (c) 2017 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under Ultimate Liberty license
+  * SLA0044, the "License"; You may not use this file except in compliance with
+  * the License. You may obtain a copy of the License at:
+  *                             www.st.com/SLA0044
+  *
+  ******************************************************************************
+  */
+/* Includes ------------------------------------------------------------------*/
+#include "rtems_lwip_conf.h"
+#include "rtems_lwip.h"
+#include "stm32h7/lan8742.h"
+#include "stm32h7xx_hal.h"
+#include "lwip/opt.h"
+#if LWIP_DHCP
+#include "lwip/dhcp.h"
+#endif
+
+#if NO_SYS == 0
+#include "lwip/sys.h"
+#endif
+
+#include "app_ethernet.h"
+#include "app_dhcp.h"
+#include "ethernetif.h"
+
+void set_dhcp_state(uint8_t new_state);
+
+/* Private typedef -----------------------------------------------------------*/
+LwipThreadArgs linkArgs;
+
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+#if NO_SYS == 1
+uint32_t ethernet_link_timer = 0;
+#endif
+
+/* Private function prototypes -----------------------------------------------*/
+void ethernet_link_thread( void* argument );
+lan8742_Object_t* get_lan_phy_handle();
+ETH_HandleTypeDef* get_eth_handle();
+
+/* Private functions ---------------------------------------------------------*/
+/**
+  * @brief  Notify the User about the nework interface config status 
+  * @param  netif: the network interface
+  * @retval None
+  */
+void ethernet_link_status_updated(struct netif *netif) 
+{
+  if (netif_is_up(netif)) {
+#if LWIP_DHCP
+    printf("Ethernet link up. Setting DHCP state..\n\r");
+    /* Update DHCP state machine */
+    set_dhcp_state(DHCP_START);
+#endif /* LWIP_DHCP */
+  }
+  else {
+#if LWIP_DHCP
+    printf("Ethernet link down. Setting DHCP state..\n\r");
+    /* Update DHCP state machine */
+    set_dhcp_state(DHCP_LINK_DOWN);
+#endif /* LWIP_DHCP */
+  } 
+}
+
+#if LWIP_NETIF_LINK_CALLBACK == 1 && NO_SYS == 1
+/**
+  * @brief  Ethernet Link periodic check
+  * @param  netif
+  * @retval None
+  */
+void ethernet_link_periodic_handle(struct netif *netif)
+{
+  uint32_t time_now = HAL_GetTick();
+  /* Ethernet Link every 100ms */
+  if (time_now - ethernet_link_timer >= 100)
+  {
+    ethernet_link_timer = time_now;
+    ethernet_link_check_state(netif);
+  }
+}
+#endif
+
+#if NO_SYS == 0
+
+void rtems_lwip_start_link_thread(uint32_t task_interval_ms,
+    size_t task_stack, uint8_t task_priority) {
+  linkArgs.netif = rtems_lwip_get_netif(0);
+  linkArgs.task_interval_ms = task_interval_ms;
+  sys_thread_new("LINK", ethernet_link_thread, (void*) &linkArgs, task_stack, task_priority);
+}
+
+#endif
+
+/**
+  * @brief  Check the ETH link state and update netif accordingly.
+  * @param  argument: netif
+  * @retval None
+  */
+void ethernet_link_thread( void* argument )
+{
+  ETH_MACConfigTypeDef MACConf;
+  int32_t PHYLinkState;
+  uint32_t linkchanged = 0, speed = 0, duplex =0;
+  LwipThreadArgs* args = (LwipThreadArgs*) argument;
+  if(args == NULL) {
+    printf("ethernet_link_thread: Passed arguments are invalid!\n\r");
+    exit(1);
+  }
+
+  struct netif *netif = args->netif;
+  if(netif == NULL) {
+    printf("ethernet_link_thread: Passed netif is invalid!\n\r");
+    exit(1);
+  }
+
+  lan8742_Object_t* lan = get_lan_phy_handle();
+  ETH_HandleTypeDef* eth = get_eth_handle();
+  for(;;)
+  {
+
+    PHYLinkState = LAN8742_GetLinkState(lan);
+
+    if(netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN))
+    {
+      HAL_ETH_Stop_IT(eth);
+      netif_set_down(netif);
+      netif_set_link_down(netif);
+    }
+    else if(!netif_is_link_up(netif) && (PHYLinkState > LAN8742_STATUS_LINK_DOWN))
+    {
+      switch (PHYLinkState)
+      {
+      case LAN8742_STATUS_100MBITS_FULLDUPLEX:
+        duplex = ETH_FULLDUPLEX_MODE;
+        speed = ETH_SPEED_100M;
+        linkchanged = 1;
+        break;
+      case LAN8742_STATUS_100MBITS_HALFDUPLEX:
+        duplex = ETH_HALFDUPLEX_MODE;
+        speed = ETH_SPEED_100M;
+        linkchanged = 1;
+        break;
+      case LAN8742_STATUS_10MBITS_FULLDUPLEX:
+        duplex = ETH_FULLDUPLEX_MODE;
+        speed = ETH_SPEED_10M;
+        linkchanged = 1;
+        break;
+      case LAN8742_STATUS_10MBITS_HALFDUPLEX:
+        duplex = ETH_HALFDUPLEX_MODE;
+        speed = ETH_SPEED_10M;
+        linkchanged = 1;
+        break;
+      default:
+        break;
+      }
+
+      if(linkchanged)
+      {
+        /* Get MAC Config MAC */
+        HAL_ETH_GetMACConfig(eth, &MACConf);
+        MACConf.DuplexMode = duplex;
+        MACConf.Speed = speed;
+        HAL_ETH_SetMACConfig(eth, &MACConf);
+        HAL_ETH_Start_IT(eth);
+        netif_set_up(netif);
+        netif_set_link_up(netif);
+      }
+    }
+
+    usleep(args->task_interval_ms * 1000);
+  }
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/lwip/ports/drivers/stm32h7/ethernetif.c b/lwip/ports/drivers/stm32h7/ethernetif.c
new file mode 100644
index 0000000..c6b8820
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/ethernetif.c
@@ -0,0 +1,758 @@
+/**
+  ******************************************************************************
+  * @file    LwIP/LwIP_HTTP_Server_Netconn_RTOS/Src/ethernetif.c
+  * @author  MCD Application Team
+  * @brief   This file implements Ethernet network interface drivers for lwIP
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>© Copyright (c) 2017 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under Ultimate Liberty license
+  * SLA0044, the "License"; You may not use this file except in compliance with
+  * the License. You may obtain a copy of the License at:
+  *                             www.st.com/SLA0044
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+#include "lwip/timeouts.h"
+#include "netif/ethernet.h"
+#include "netif/etharp.h"
+#include "lwip/stats.h"
+#include "lwip/snmp.h"
+#include "lwip/tcpip.h"
+#include "ethernetif.h"
+
+#include "lan8742.h"
+#include <string.h>
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define DMA_DESCRIPTOR_ALIGNMENT                ( 0x20 )
+
+/* RTEMS priorities range from 1 (highest) to 255 (lowest) */
+#ifndef RTEMS_LWIP_INTERFACE_THREAD_PRIORITY
+#define RTEMS_LWIP_INTERFACE_THREAD_PRIORITY    ( 50 )
+#endif
+
+/* Stack size of the interface thread */
+#ifndef RTEMS_LWIP_INTERFACE_THREAD_STACK_SIZE
+#define RTEMS_LWIP_INTERFACE_THREAD_STACK_SIZE  ( RTEMS_MINIMUM_STACK_SIZE )
+#endif
+
+/* Define those to better describe your network interface. */
+#define IFNAME0 's'
+#define IFNAME1 't'
+
+#ifndef RTEMS_LWIP_ETH_DMA_TRANSMIT_TIMEOUT
+#define RTEMS_LWIP_ETH_DMA_TRANSMIT_TIMEOUT     ( 20U )
+#endif
+
+/* The MPU protection is unreliable for the Socket API. The exact cause is not know yet.
+It's safer to always clean data cache for now */
+#ifndef RTEMS_LWIP_PROTECT_LWIP_HEAP_WITH_MPU
+#define RTEMS_LWIP_PROTECT_LWIP_HEAP_WITH_MPU     1
+#endif
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* 
+ at Note: This interface is implemented to operate in zero-copy mode only:
+        - Rx buffers are allocated statically and passed directly to the LwIP stack,
+          they will return back to ETH DMA after been processed by the stack.
+        - Tx Buffers will be allocated from LwIP stack memory heap, 
+          then passed to ETH HAL driver.
+
+ at Notes: 
+  1.a. ETH DMA Rx descriptors must be contiguous, the default count is 4, 
+       to customize it please redefine ETH_RX_DESC_CNT in stm32xxxx_hal_conf.h
+  1.b. ETH DMA Tx descriptors must be contiguous, the default count is 4, 
+       to customize it please redefine ETH_TX_DESC_CNT in stm32xxxx_hal_conf.h
+
+  2.a. Rx Buffers number must be between ETH_RX_DESC_CNT and 2*ETH_RX_DESC_CNT
+  2.b. Rx Buffers must have the same size: ETH_RX_BUFFER_SIZE, this value must
+       passed to ETH DMA in the init field (EthHandle.Init.RxBuffLen)
+  2.c  The RX Ruffers addresses and sizes must be properly defined to be aligned
+       to L1-CACHE line size (32 bytes).
+*/
+
+netif_init_fn eth_lwip_init_fnc = &ethernetif_init;
+
+/* Put into special RTEMS section and align correctly */
+ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".bsp_nocache"), __aligned__(DMA_DESCRIPTOR_ALIGNMENT))); /* Ethernet Rx DMA Descriptors */
+/* Put into special RTEMS section and align correctly */
+ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]  __attribute__((section(".bsp_nocache"), __aligned__(DMA_DESCRIPTOR_ALIGNMENT)));  /* Ethernet Tx DMA Descriptors */
+/* Ethernet Receive Buffers. Just place somewhere is BSS instead of explicitely placing it */
+uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE] RTEMS_ALIGNED(DMA_DESCRIPTOR_ALIGNMENT);
+
+ETH_HandleTypeDef EthHandle;
+ETH_TxPacketConfig TxConfig; 
+
+lan8742_Object_t LAN8742;
+
+#if NO_SYS == 0
+sys_sem_t RxPktSemaphore; /* Semaphore to signal incoming packets */
+#endif
+
+/* Private function prototypes -----------------------------------------------*/
+#if !STATIC_IP_ADDRESS && NO_SYS == 0 && LWIP_NETIF_API == 1
+void set_dhcp_state(uint8_t new_state);
+#endif
+
+uint8_t determine_mpu_region_size_select(size_t lwip_heap_size);
+static void low_level_init(struct netif *netif);
+static err_t low_level_output(struct netif *netif, struct pbuf *p);
+void ethernet_link_check_state(struct netif *netif);
+
+void pbuf_free_custom(struct pbuf *p);
+
+int32_t ETH_PHY_IO_Init(void);
+int32_t ETH_PHY_IO_DeInit (void);
+int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal);
+int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal);
+int32_t ETH_PHY_IO_GetTick(void);
+
+
+lan8742_IOCtx_t  LAN8742_IOCtx = {ETH_PHY_IO_Init,
+                               ETH_PHY_IO_DeInit,
+                               ETH_PHY_IO_WriteReg,
+                               ETH_PHY_IO_ReadReg,
+                               ETH_PHY_IO_GetTick};
+
+LWIP_MEMPOOL_DECLARE(RX_POOL, 10, sizeof(struct pbuf_custom), "Zero-copy RX PBUF pool");
+
+/* Private functions ---------------------------------------------------------*/
+/*******************************************************************************
+                       LL Driver Interface ( LwIP stack --> ETH) 
+*******************************************************************************/
+
+/**
+  * @brief Should be called at the beginning of the program to set up the
+  * network interface. It calls the function low_level_init() to do the
+  * actual setup of the hardware.
+  *
+  * This function should be passed as a parameter to netif_add().
+  *
+  * @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)
+{
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
+
+#if RTEMS_LWIP_PROTECT_LWIP_HEAP_WITH_MPU == 1
+  mpu_config_tx_buffers(LWIP_RAM_HEAP_POINTER, MEM_SIZE);
+#endif
+
+#if LWIP_NETIF_HOSTNAME
+  /* Initialize interface hostname */
+  netif->hostname = "lwip";
+#endif /* LWIP_NETIF_HOSTNAME */
+
+#if NO_SYS == 0
+  /*
+   * 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.
+   */
+  MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
+#endif
+
+  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 = low_level_output;
+
+  /* This is already done by the generic driver, so the internal state machine is set accordingly */
+#if !STATIC_IP_ADDRESS && NO_SYS == 0 && LWIP_NETIF_API == 1
+  set_dhcp_state(DHCP_WAIT_ADDRESS);
+#endif
+
+  /* initialize the hardware */
+  low_level_init(netif);
+
+  return ERR_OK;
+}
+
+/**
+  * @brief In this function, the hardware should be initialized.
+  * Called from ethernetif_init().
+  *
+  * @param netif the already initialized lwip network interface structure
+  *        for this ethernetif
+  */
+static void low_level_init(struct netif *netif)
+{
+#if NO_SYS == 0
+  int32_t PHYLinkState;
+  ETH_MACConfigTypeDef MACConf;
+  uint32_t duplex, speed = 0;
+#endif
+  uint32_t idx = 0;
+  uint8_t macaddress[6]= {ETH_MAC_ADDR0, ETH_MAC_ADDR1, ETH_MAC_ADDR2, ETH_MAC_ADDR3, ETH_MAC_ADDR4, ETH_MAC_ADDR5};
+  
+  EthHandle.Instance = ETH;  
+  EthHandle.Init.MACAddr = macaddress;
+  EthHandle.Init.MediaInterface = HAL_ETH_RMII_MODE;
+  EthHandle.Init.RxDesc = DMARxDscrTab;
+  EthHandle.Init.TxDesc = DMATxDscrTab;
+  EthHandle.Init.RxBuffLen = ETH_RX_BUFFER_SIZE;
+  
+  /* configure ethernet peripheral (GPIOs, clocks, MAC, DMA) */
+  HAL_ETH_Init(&EthHandle);
+  
+#if NO_SYS == 0
+  /* Enable the Ethernet global Interrupt */
+  HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0);
+  HAL_NVIC_EnableIRQ(ETH_IRQn);
+#endif
+
+  /* set MAC hardware address length */
+  netif->hwaddr_len = ETH_HWADDR_LEN;
+  
+  /* set MAC hardware address */
+  netif->hwaddr[0] =  ETH_MAC_ADDR0;
+  netif->hwaddr[1] =  ETH_MAC_ADDR1;
+  netif->hwaddr[2] =  ETH_MAC_ADDR2;
+  netif->hwaddr[3] =  ETH_MAC_ADDR3;
+  netif->hwaddr[4] =  ETH_MAC_ADDR4;
+  netif->hwaddr[5] =  ETH_MAC_ADDR5;
+  
+  /* maximum transfer unit */
+  netif->mtu = ETH_MAX_PAYLOAD;
+  
+  /* device capabilities */
+  /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
+  netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
+  
+  for(idx = 0; idx < ETH_RX_DESC_CNT; idx ++)
+  {
+    HAL_ETH_DescAssignMemory(&EthHandle, idx, Rx_Buff[idx], NULL);
+  }
+  
+  /* Initialize the RX POOL */
+  LWIP_MEMPOOL_INIT(RX_POOL);
+  
+  memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig));  
+  TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
+  TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
+  TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;
+   
+#if NO_SYS == 0
+  /* create a binary semaphore used for informing ethernetif of frame reception */
+  sys_sem_new(&RxPktSemaphore, 1);
+  
+  /* create the task that handles the ETH_MAC */
+  sys_thread_new(
+    "ETHM",
+    (lwip_thread_fn) ethernetif_input,
+    netif,
+    RTEMS_LWIP_INTERFACE_THREAD_STACK_SIZE,
+    RTEMS_LWIP_INTERFACE_THREAD_PRIORITY
+  );
+
+#endif
+  
+  /* Set PHY IO functions */
+  LAN8742_RegisterBusIO(&LAN8742, &LAN8742_IOCtx);
+  
+  /* Initialize the LAN8742 ETH PHY */
+  LAN8742_Init(&LAN8742);
+  
+#if NO_SYS == 0
+  PHYLinkState = LAN8742_GetLinkState(&LAN8742);
+  
+  /* Get link state */  
+  if(PHYLinkState <= LAN8742_STATUS_LINK_DOWN)
+  {
+    netif_set_link_down(netif);
+    netif_set_down(netif);
+  }
+  else 
+  {
+    switch (PHYLinkState)
+    {
+    case LAN8742_STATUS_100MBITS_FULLDUPLEX:
+      duplex = ETH_FULLDUPLEX_MODE;
+      speed = ETH_SPEED_100M;
+      break;
+    case LAN8742_STATUS_100MBITS_HALFDUPLEX:
+      duplex = ETH_HALFDUPLEX_MODE;
+      speed = ETH_SPEED_100M;
+      break;
+    case LAN8742_STATUS_10MBITS_FULLDUPLEX:
+      duplex = ETH_FULLDUPLEX_MODE;
+      speed = ETH_SPEED_10M;
+      break;
+    case LAN8742_STATUS_10MBITS_HALFDUPLEX:
+      duplex = ETH_HALFDUPLEX_MODE;
+      speed = ETH_SPEED_10M;
+      break;
+    default:
+      duplex = ETH_FULLDUPLEX_MODE;
+      speed = ETH_SPEED_100M;
+      break;      
+    }
+    
+    /* Get MAC Config MAC */
+    HAL_ETH_GetMACConfig(&EthHandle, &MACConf); 
+    MACConf.DuplexMode = duplex;
+    MACConf.Speed = speed;
+    HAL_ETH_SetMACConfig(&EthHandle, &MACConf);
+    HAL_ETH_Start_IT(&EthHandle);
+    /* Install the ETH IRQ for RTEMS */
+    rtems_interrupt_handler_install(ETH_IRQn, NULL, RTEMS_INTERRUPT_UNIQUE,
+        (rtems_interrupt_handler) &HAL_ETH_IRQHandler, &EthHandle);
+    netif_set_up(netif);
+    netif_set_link_up(netif);
+  }
+#endif
+
+  ethernet_link_check_state(netif);
+}
+
+/**
+  * @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
+  *
+  * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
+  *       strange results. You might consider waiting for space in the DMA queue
+  *       to become available since the stack doesn't retry to send a packet
+  *       dropped because of memory failure (except for the TCP timers).
+  */
+static err_t low_level_output(struct netif *netif, struct pbuf *p)
+{
+  uint32_t i=0;
+  struct pbuf *q;
+  err_t errval = ERR_OK;
+  ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT];
+  
+  memset(Txbuffer, 0 , ETH_TX_DESC_CNT*sizeof(ETH_BufferTypeDef));
+  
+  for(q = p; q != NULL; q = q->next)
+  {
+    if(i >= ETH_TX_DESC_CNT)	
+      return ERR_IF;
+    
+    Txbuffer[i].buffer = q->payload;
+    Txbuffer[i].len = q->len;
+
+    /* For the socket API, a custom send buffer might be used which is not protected by the
+    MPU. Therefore, clean DCache here as well */
+#if RTEMS_LWIP_PROTECT_LWIP_HEAP_WITH_MPU == 0 || LWIP_SOCKET == 1
+    /* Cleaning cache isn't necessary if the tx buffers are in a not-cacheable MPU region. */
+    uint8_t *dataStart = q->payload;
+    uint8_t *lineStart = (uint8_t *)((uint32_t)dataStart & ~31);
+    SCB_CleanDCache_by_Addr((uint32_t *)lineStart, q->len + (dataStart - lineStart));
+#endif
+
+    if(i>0)
+    {
+      Txbuffer[i-1].next = &Txbuffer[i];
+    }
+    
+    if(q->next == NULL)
+    {
+      Txbuffer[i].next = NULL;
+    }
+
+    i++;
+  }
+
+  TxConfig.Length = p->tot_len;
+  TxConfig.TxBuffer = Txbuffer;
+
+  HAL_ETH_Transmit(&EthHandle, &TxConfig, RTEMS_LWIP_ETH_DMA_TRANSMIT_TIMEOUT);
+  
+  return errval;
+}
+
+/**
+  * @brief Should allocate a pbuf and transfer the bytes of the incoming
+  * packet from the interface into the pbuf.
+  *
+  * @param netif the lwip network interface structure for this ethernetif
+  * @return a pbuf filled with the received packet (including MAC header)
+  *         NULL on memory error
+  */
+static struct pbuf * low_level_input(struct netif *netif)
+{
+  struct pbuf *p = NULL;
+  ETH_BufferTypeDef RxBuff[ETH_RX_DESC_CNT];
+  uint32_t framelength = 0, i = 0;;
+  struct pbuf_custom* custom_pbuf;
+
+  memset(RxBuff, 0 , ETH_RX_DESC_CNT*sizeof(ETH_BufferTypeDef));
+  
+  for(i = 0; i < ETH_RX_DESC_CNT -1; i++)
+  {
+    RxBuff[i].next=&RxBuff[i+1];
+  }
+
+#if NO_SYS == 0
+  if(HAL_ETH_GetRxDataBuffer(&EthHandle, RxBuff) == HAL_OK)
+#else
+  if (HAL_ETH_IsRxDataAvailable(&EthHandle))
+#endif
+  {
+
+#if NO_SYS == 1
+    HAL_ETH_GetRxDataBuffer(&EthHandle, RxBuff);
+#endif
+
+    HAL_ETH_GetRxDataLength(&EthHandle, &framelength);
+
+    /* Build Rx descriptor to be ready for next data reception */
+    HAL_ETH_BuildRxDescriptors(&EthHandle);
+
+    /* Invalidate data cache for ETH Rx Buffers */
+    SCB_InvalidateDCache_by_Addr((uint32_t *)RxBuff->buffer, framelength);
+    
+    custom_pbuf  = (struct pbuf_custom*)LWIP_MEMPOOL_ALLOC(RX_POOL);
+    if(custom_pbuf != NULL)
+    {
+      custom_pbuf->custom_free_function = pbuf_free_custom;
+
+      p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_REF, custom_pbuf, RxBuff->buffer, framelength);
+    }
+
+  }
+  
+  return p;
+}
+
+#if NO_SYS == 0
+/**
+  * @brief This function is the ethernetif_input task, it is processed when a packet 
+  * is ready to be read from the interface. It uses the function low_level_input() 
+  * that should handle 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
+  */
+void ethernetif_input(struct netif *netif)
+{
+  struct pbuf *p;
+  
+  for( ;; )
+  {
+    if (sys_arch_sem_wait(&RxPktSemaphore, 0) != SYS_ARCH_TIMEOUT)
+    {
+      do
+      {
+        p = low_level_input( netif );
+        if (p != NULL)
+        {
+          if (netif->input( p, netif) != ERR_OK )
+          {
+            pbuf_free(p);
+          }
+        }
+
+      }while(p!=NULL);
+    }
+  }
+}
+#else
+/**
+  * @brief This function is the ethernetif_input task, it is processed when a packet
+  * is ready to be read from the interface. It uses the function low_level_input()
+  * that should handle 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
+  */
+void ethernetif_input(struct netif *netif)
+{
+  err_t err;
+  struct pbuf *p;
+
+  /* move received packet into a new pbuf */
+  p = low_level_input(netif);
+
+  /* no packet could be read, silently ignore this */
+  if (p == NULL) return;
+
+  /* entry point to the LwIP stack */
+  err = netif->input(p, netif);
+
+  if (err != ERR_OK)
+  {
+    LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
+    pbuf_free(p);
+    p = NULL;
+  }
+}
+#endif /* NO_SYS == 1 */
+
+/**
+  * @brief  Custom Rx pbuf free callback
+  * @param  pbuf: pbuf to be freed
+  * @retval None
+  */
+void pbuf_free_custom(struct pbuf *p)
+{
+  struct pbuf_custom* custom_pbuf = (struct pbuf_custom*)p;
+  LWIP_MEMPOOL_FREE(RX_POOL, custom_pbuf);
+}
+
+
+/*******************************************************************************
+                       Ethernet MSP Routines
+*******************************************************************************/
+/**
+  * @brief  Note: HAL_ETH_MspInit of RTEMS BSP is used.
+  * @param  heth: ETH handle
+  * @retval None
+*/
+
+#if NO_SYS == 0
+/**
+  * @brief  Ethernet Rx Transfer completed callback
+  * @param  heth: ETH handle
+  * @retval None
+  */
+void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
+{
+  sys_sem_signal(&RxPktSemaphore);
+}
+#endif
+
+/*******************************************************************************
+                       PHI IO Functions
+*******************************************************************************/
+/**
+  * @brief  Initializes the MDIO interface GPIO and clocks.
+  * @param  None
+  * @retval 0 if OK, -1 if ERROR
+  */
+int32_t ETH_PHY_IO_Init(void)
+{  
+  /* We assume that MDIO GPIO configuration is already done
+     in the ETH_MspInit() else it should be done here 
+  */
+  
+  /* Configure the MDIO Clock */
+  HAL_ETH_SetMDIOClockRange(&EthHandle);
+  
+  return 0;
+}
+
+/**
+  * @brief  De-Initializes the MDIO interface .
+  * @param  None
+  * @retval 0 if OK, -1 if ERROR
+  */
+int32_t ETH_PHY_IO_DeInit (void)
+{
+  return 0;
+}
+
+/**
+  * @brief  Read a PHY register through the MDIO interface.
+  * @param  DevAddr: PHY port address
+  * @param  RegAddr: PHY register address
+  * @param  pRegVal: pointer to hold the register value 
+  * @retval 0 if OK -1 if Error
+  */
+int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal)
+{
+  if(HAL_ETH_ReadPHYRegister(&EthHandle, DevAddr, RegAddr, pRegVal) != HAL_OK)
+  {
+    return -1;
+  }
+  
+  return 0;
+}
+
+/**
+  * @brief  Write a value to a PHY register through the MDIO interface.
+  * @param  DevAddr: PHY port address
+  * @param  RegAddr: PHY register address
+  * @param  RegVal: Value to be written 
+  * @retval 0 if OK -1 if Error
+  */
+int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal)
+{
+  if(HAL_ETH_WritePHYRegister(&EthHandle, DevAddr, RegAddr, RegVal) != HAL_OK)
+  {
+    return -1;
+  }
+  
+  return 0;
+}
+
+/**
+  * @brief  Get the time in millisecons used for internal PHY driver process.
+  * @retval Time value
+  */
+int32_t ETH_PHY_IO_GetTick(void)
+{
+  return HAL_GetTick();
+}
+
+void ethernet_link_check_state(struct netif *netif)
+{
+  ETH_MACConfigTypeDef MACConf;
+  uint32_t PHYLinkState;
+  uint32_t linkchanged = 0, speed = 0, duplex =0;
+
+  PHYLinkState = LAN8742_GetLinkState(&LAN8742);
+
+  if(netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN))
+  {
+    HAL_ETH_Stop(&EthHandle);
+    netif_set_down(netif);
+    netif_set_link_down(netif);
+  }
+  else if(!netif_is_link_up(netif) && (PHYLinkState > LAN8742_STATUS_LINK_DOWN))
+  {
+    switch (PHYLinkState)
+    {
+    case LAN8742_STATUS_100MBITS_FULLDUPLEX:
+      duplex = ETH_FULLDUPLEX_MODE;
+      speed = ETH_SPEED_100M;
+      linkchanged = 1;
+      break;
+    case LAN8742_STATUS_100MBITS_HALFDUPLEX:
+      duplex = ETH_HALFDUPLEX_MODE;
+      speed = ETH_SPEED_100M;
+      linkchanged = 1;
+      break;
+    case LAN8742_STATUS_10MBITS_FULLDUPLEX:
+      duplex = ETH_FULLDUPLEX_MODE;
+      speed = ETH_SPEED_10M;
+      linkchanged = 1;
+      break;
+    case LAN8742_STATUS_10MBITS_HALFDUPLEX:
+      duplex = ETH_HALFDUPLEX_MODE;
+      speed = ETH_SPEED_10M;
+      linkchanged = 1;
+      break;
+    default:
+      break;
+    }
+
+    if(linkchanged)
+    {
+      /* Get MAC Config MAC */
+      HAL_ETH_GetMACConfig(&EthHandle, &MACConf);
+      MACConf.DuplexMode = duplex;
+      MACConf.Speed = speed;
+      HAL_ETH_SetMACConfig(&EthHandle, &MACConf);
+      HAL_ETH_Start(&EthHandle);
+      netif_set_up(netif);
+      netif_set_link_up(netif);
+    }
+  }
+}
+
+#if NO_SYS == 1
+/* Even for NO_SYS == 1 this needs to be implemented */
+uint32_t
+sys_now()
+{
+  /* Forward call to HAL function which already implements returning millisecond ticks */
+  return HAL_GetTick();
+}
+
+#endif /* NO_SYS == 1 */
+
+/* Configure the MPU for the lwIP heap. */
+void mpu_config_tx_buffers(uint32_t base_addr, size_t region_size)
+{
+    MPU_Region_InitTypeDef MPU_InitStruct;
+    uint8_t region_select = determine_mpu_region_size_select(region_size);
+
+    /* Disable the MPU */
+    HAL_MPU_Disable();
+
+    /* Configure the MPU attributes as Normal Non Cacheable
+       for LwIP RAM heap which contains the Tx buffers */
+    MPU_InitStruct.Enable = MPU_REGION_ENABLE;
+    MPU_InitStruct.BaseAddress = base_addr;
+    MPU_InitStruct.Size = region_select;
+    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
+    MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
+    MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
+    MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
+    MPU_InitStruct.Number = MPU_REGION_NUMBER1;
+    MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
+    MPU_InitStruct.SubRegionDisable = 0x00;
+    MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
+
+    HAL_MPU_ConfigRegion(&MPU_InitStruct);
+
+    SCB_CleanDCache_by_Addr((uint32_t*) base_addr, region_size);
+
+    /* Enable the MPU */
+    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
+
+}
+
+uint8_t determine_mpu_region_size_select(size_t lwip_heap_size)
+{
+    if(lwip_heap_size <= 1024) {
+        return MPU_REGION_SIZE_1KB;
+    }
+    else if(lwip_heap_size <= 2 * 1024) {
+        return MPU_REGION_SIZE_2KB;
+    }
+    else if(lwip_heap_size <= 4 * 1024) {
+        return MPU_REGION_SIZE_4KB;
+    }
+    else if(lwip_heap_size <= 8 * 1024) {
+        return MPU_REGION_SIZE_8KB;
+    }
+    else if(lwip_heap_size <= 16 * 1024) {
+        return MPU_REGION_SIZE_16KB;
+    }
+    else if(lwip_heap_size <= 32 * 1024) {
+        return MPU_REGION_SIZE_32KB;
+    }
+    else if(lwip_heap_size <= 64 * 1024) {
+        return MPU_REGION_SIZE_64KB;
+    }
+    else if(lwip_heap_size <= 128 * 1024) {
+        return MPU_REGION_SIZE_128KB;
+    }
+    else if(lwip_heap_size <= 256 * 1024) {
+        return MPU_REGION_SIZE_256KB;
+    }
+    else if(lwip_heap_size <= 512 * 1024) {
+        return MPU_REGION_SIZE_512KB;
+    }
+    else {
+        /* There is only 1MB RAM available so a MPU protection of 1MB does not really make sense */
+        return MPU_REGION_SIZE_512KB;
+    }
+}
+
+lan8742_Object_t* get_lan_phy_handle() {
+  return &LAN8742;
+}
+
+ETH_HandleTypeDef* get_eth_handle() {
+  return &EthHandle;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/lwip/ports/drivers/stm32h7/include/lwip_port/app_dhcp.h b/lwip/ports/drivers/stm32h7/include/lwip_port/app_dhcp.h
new file mode 100644
index 0000000..ce51a74
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/include/lwip_port/app_dhcp.h
@@ -0,0 +1,38 @@
+#ifndef LWIP_PORTS_DRIVERS_STM32H7_APP_DHCP_H_
+#define LWIP_PORTS_DRIVERS_STM32H7_APP_DHCP_H_
+
+#include <lwipopts.h>
+#include <stdint.h>
+
+#include <lwip/netif.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint8_t get_dhcp_state();
+
+/* DHCP process states */
+#define DHCP_OFF                   (uint8_t) 0
+#define DHCP_START                 (uint8_t) 1
+#define DHCP_WAIT_ADDRESS          (uint8_t) 2
+#define DHCP_ADDRESS_ASSIGNED      (uint8_t) 3
+#define DHCP_TIMEOUT               (uint8_t) 4
+#define DHCP_LINK_DOWN             (uint8_t) 5
+
+#if NO_SYS == 1
+
+void dhcp_periodic_handle(struct netif *netif);
+
+#else
+
+void rtems_lwip_start_dhcp_thread(uint32_t task_interval_ms,
+    size_t task_stack, uint8_t task_priority);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_PORTS_DRIVERS_STM32H7_APP_DHCP_H_ */
diff --git a/lwip/ports/drivers/stm32h7/include/lwip_port/app_ethernet.h b/lwip/ports/drivers/stm32h7/include/lwip_port/app_ethernet.h
new file mode 100644
index 0000000..b961132
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/include/lwip_port/app_ethernet.h
@@ -0,0 +1,56 @@
+/**
+  ******************************************************************************
+  * @file    LwIP/LwIP_HTTP_Server_Netconn_RTOS/Inc/app_ethernet.h 
+  * @author  MCD Application Team
+  * @brief   Header for app_ethernet.c module
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>© Copyright (c) 2017 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under Ultimate Liberty license
+  * SLA0044, the "License"; You may not use this file except in compliance with
+  * the License. You may obtain a copy of the License at:
+  *                             www.st.com/SLA0044
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __APP_ETHERNET_H
+#define __APP_ETHERNET_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "lwip/netif.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void ethernet_link_status_updated(struct netif *netif);
+#if LWIP_DHCP
+void DHCP_Thread(void const * argument);
+#endif
+
+#if LWIP_NETIF_LINK_CALLBACK == 1 && NO_SYS == 1
+void ethernet_link_periodic_handle(struct netif *netif);
+#endif
+
+void rtems_lwip_start_link_thread(uint32_t task_interval_ms,
+    size_t task_stack, uint8_t task_priority);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APP_ETHERNET_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/lwip/ports/drivers/stm32h7/include/lwip_port/ethernetif.h b/lwip/ports/drivers/stm32h7/include/lwip_port/ethernetif.h
new file mode 100644
index 0000000..33f2129
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/include/lwip_port/ethernetif.h
@@ -0,0 +1,56 @@
+/**
+  ******************************************************************************
+  * @file    LwIP/LwIP_HTTP_Server_Netconn_RTOS/Inc/ethernetif.h 
+  * @author  MCD Application Team
+  * @brief   Header for ethernetif.c module
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>© Copyright (c) 2017 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under Ultimate Liberty license
+  * SLA0044, the "License"; You may not use this file except in compliance with
+  * the License. You may obtain a copy of the License at:
+  *                             www.st.com/SLA0044
+  *
+  ******************************************************************************
+  */
+
+#ifndef __ETHERNETIF_H__
+#define __ETHERNETIF_H__
+
+
+#include "lwip/err.h"
+#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ETH_RX_BUFFER_SIZE                     (1536UL)
+
+/* Exported types ------------------------------------------------------------*/
+typedef struct {
+ struct netif* netif;
+ uint32_t task_interval_ms;
+} LwipThreadArgs;
+
+/* Structure that include link thread parameters */
+/* Exported functions ------------------------------------------------------- */
+err_t ethernetif_init(struct netif *netif);      
+void ethernetif_input(struct netif *netif);
+void ethernet_link_check_state(struct netif *netif);
+
+/**
+ * This function can be used to protect the TX lwIP buffer region (lwIP Heap).
+ * @param base_addr
+ * @param region_size
+ */
+void mpu_config_tx_buffers(uint32_t base_addr, size_t region_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ETHERNETIF_H__ */
diff --git a/lwip/ports/drivers/stm32h7/lan8742.c b/lwip/ports/drivers/stm32h7/lan8742.c
new file mode 100644
index 0000000..a268393
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/lan8742.c
@@ -0,0 +1,664 @@
+/** 
+  ******************************************************************************
+  * @file    lan8742.c
+  * @author  MCD Application Team
+  * @brief   This file provides a set of functions needed to manage the LAN742
+  *          PHY devices.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>© Copyright (c) 2017 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the
+  * License. You may obtain a copy of the License at:
+  *                        opensource.org/licenses/BSD-3-Clause
+  *
+  ******************************************************************************
+  */  
+
+/* Includes ------------------------------------------------------------------*/
+#include "lan8742.h"
+
+/** @addtogroup BSP
+  * @{
+  */
+
+/** @addtogroup Component
+  * @{
+  */ 
+  
+/** @defgroup LAN8742 LAN8742
+  * @{
+  */   
+  
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/** @defgroup LAN8742_Private_Defines LAN8742 Private Defines
+  * @{
+  */
+#define LAN8742_SW_RESET_TO    ((uint32_t)500U)
+#define LAN8742_INIT_TO        ((uint32_t)2000U)
+#define LAN8742_MAX_DEV_ADDR   ((uint32_t)31U)
+/**
+  * @}
+  */
+ 
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup LAN8742_Private_Functions LAN8742 Private Functions
+  * @{
+  */
+    
+/**
+  * @brief  Register IO functions to component object
+  * @param  pObj: device object  of LAN8742_Object_t. 
+  * @param  ioctx: holds device IO functions.  
+  * @retval LAN8742_STATUS_OK  if OK
+  *         LAN8742_STATUS_ERROR if missing mandatory function
+  */
+int32_t  LAN8742_RegisterBusIO(lan8742_Object_t *pObj, lan8742_IOCtx_t *ioctx)
+{
+  if(!pObj || !ioctx->ReadReg || !ioctx->WriteReg || !ioctx->GetTick)
+  {
+    return LAN8742_STATUS_ERROR;
+  }
+  
+  pObj->IO.Init = ioctx->Init;
+  pObj->IO.DeInit = ioctx->DeInit;
+  pObj->IO.ReadReg = ioctx->ReadReg;
+  pObj->IO.WriteReg = ioctx->WriteReg;
+  pObj->IO.GetTick = ioctx->GetTick;
+  
+  return LAN8742_STATUS_OK;
+}
+
+/**
+  * @brief  Initialize the lan8742 and configure the needed hardware resources
+  * @param  pObj: device object LAN8742_Object_t. 
+  * @retval LAN8742_STATUS_OK  if OK
+  *         LAN8742_STATUS_ADDRESS_ERROR if cannot find device address
+  *         LAN8742_STATUS_READ_ERROR if connot read register
+  *         LAN8742_STATUS_WRITE_ERROR if connot write to register
+  *         LAN8742_STATUS_RESET_TIMEOUT if cannot perform a software reset
+  */
+ int32_t LAN8742_Init(lan8742_Object_t *pObj)
+ {
+   uint32_t tickstart = 0, regvalue = 0, addr = 0;
+   int32_t status = LAN8742_STATUS_OK;
+   
+   if(pObj->Is_Initialized == 0)
+   {
+     if(pObj->IO.Init != 0)
+     {
+       /* GPIO and Clocks initialization */
+       pObj->IO.Init();
+     }
+   
+     /* for later check */
+     pObj->DevAddr = LAN8742_MAX_DEV_ADDR + 1;
+   
+     /* Get the device address from special mode register */  
+     for(addr = 0; addr <= LAN8742_MAX_DEV_ADDR; addr ++)
+     {
+       if(pObj->IO.ReadReg(addr, LAN8742_SMR, &regvalue) < 0)
+       { 
+         status = LAN8742_STATUS_READ_ERROR;
+         /* Can't read from this device address 
+            continue with next address */
+         continue;
+       }
+     
+       if((regvalue & LAN8742_SMR_PHY_ADDR) == addr)
+       {
+         pObj->DevAddr = addr;
+         status = LAN8742_STATUS_OK;
+         break;
+       }
+     }
+   
+     if(pObj->DevAddr > LAN8742_MAX_DEV_ADDR)
+     {
+       status = LAN8742_STATUS_ADDRESS_ERROR;
+     }
+     
+     /* if device address is matched */
+     if(status == LAN8742_STATUS_OK)
+     {
+       /* set a software reset  */
+       if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, LAN8742_BCR_SOFT_RESET) >= 0)
+       { 
+         /* get software reset status */
+         if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &regvalue) >= 0)
+         { 
+           tickstart = pObj->IO.GetTick();
+           
+           /* wait until software reset is done or timeout occured  */
+           while(regvalue & LAN8742_BCR_SOFT_RESET)
+           {
+             if((pObj->IO.GetTick() - tickstart) <= LAN8742_SW_RESET_TO)
+             {
+               if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &regvalue) < 0)
+               { 
+                 status = LAN8742_STATUS_READ_ERROR;
+                 break;
+               }
+             }
+             else
+             {
+               status = LAN8742_STATUS_RESET_TIMEOUT;
+               break;
+             }
+           } 
+         }
+         else
+         {
+           status = LAN8742_STATUS_READ_ERROR;
+         }
+       }
+       else
+       {
+         status = LAN8742_STATUS_WRITE_ERROR;
+       }
+     }
+   }
+      
+   if(status == LAN8742_STATUS_OK)
+   {
+     tickstart =  pObj->IO.GetTick();
+     
+     /* Wait for 2s to perform initialization */
+     while((pObj->IO.GetTick() - tickstart) <= LAN8742_INIT_TO)
+     {
+     }
+     pObj->Is_Initialized = 1;
+   }
+   
+   return status;
+ }
+
+/**
+  * @brief  De-Initialize the lan8742 and it's hardware resources
+  * @param  pObj: device object LAN8742_Object_t. 
+  * @retval None
+  */
+int32_t LAN8742_DeInit(lan8742_Object_t *pObj)
+{
+  if(pObj->Is_Initialized)
+  {
+    if(pObj->IO.DeInit != 0)
+    {
+      if(pObj->IO.DeInit() < 0)
+      {
+        return LAN8742_STATUS_ERROR;
+      }
+    }
+  
+    pObj->Is_Initialized = 0;  
+  }
+  
+  return LAN8742_STATUS_OK;
+}
+
+/**
+  * @brief  Disable the LAN8742 power down mode.
+  * @param  pObj: device object LAN8742_Object_t.  
+  * @retval LAN8742_STATUS_OK  if OK
+  *         LAN8742_STATUS_READ_ERROR if connot read register
+  *         LAN8742_STATUS_WRITE_ERROR if connot write to register
+  */
+int32_t LAN8742_DisablePowerDownMode(lan8742_Object_t *pObj)
+{
+  uint32_t readval = 0;
+  int32_t status = LAN8742_STATUS_OK;
+  
+  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) >= 0)
+  {
+    readval &= ~LAN8742_BCR_POWER_DOWN;
+  
+    /* Apply configuration */
+    if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, readval) < 0)
+    {
+      status =  LAN8742_STATUS_WRITE_ERROR;
+    }
+  }
+  else
+  {
+    status = LAN8742_STATUS_READ_ERROR;
+  }
+   
+  return status;
+}
+
+/**
+  * @brief  Enable the LAN8742 power down mode.
+  * @param  pObj: device object LAN8742_Object_t.  
+  * @retval LAN8742_STATUS_OK  if OK
+  *         LAN8742_STATUS_READ_ERROR if connot read register
+  *         LAN8742_STATUS_WRITE_ERROR if connot write to register
+  */
+int32_t LAN8742_EnablePowerDownMode(lan8742_Object_t *pObj)
+{
+  uint32_t readval = 0;
+  int32_t status = LAN8742_STATUS_OK;
+  
+  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) >= 0)
+  {
+    readval |= LAN8742_BCR_POWER_DOWN;
+  
+    /* Apply configuration */
+    if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, readval) < 0)
+    {
+      status =  LAN8742_STATUS_WRITE_ERROR;
+    }
+  }
+  else
+  {
+    status = LAN8742_STATUS_READ_ERROR;
+  }
+   
+  return status;
+}
+
+/**
+  * @brief  Start the auto negotiation process.
+  * @param  pObj: device object LAN8742_Object_t.  
+  * @retval LAN8742_STATUS_OK  if OK
+  *         LAN8742_STATUS_READ_ERROR if connot read register
+  *         LAN8742_STATUS_WRITE_ERROR if connot write to register
+  */
+int32_t LAN8742_StartAutoNego(lan8742_Object_t *pObj)
+{
+  uint32_t readval = 0;
+  int32_t status = LAN8742_STATUS_OK;
+  
+  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) >= 0)
+  {
+    readval |= LAN8742_BCR_AUTONEGO_EN;
+  
+    /* Apply configuration */
+    if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, readval) < 0)
+    {
+      status =  LAN8742_STATUS_WRITE_ERROR;
+    }
+  }
+  else
+  {
+    status = LAN8742_STATUS_READ_ERROR;
+  }
+   
+  return status;
+}
+
+/**
+  * @brief  Get the link state of LAN8742 device.
+  * @param  pObj: Pointer to device object. 
+  * @param  pLinkState: Pointer to link state
+  * @retval LAN8742_STATUS_LINK_DOWN  if link is down
+  *         LAN8742_STATUS_AUTONEGO_NOTDONE if Auto nego not completed 
+  *         LAN8742_STATUS_100MBITS_FULLDUPLEX if 100Mb/s FD
+  *         LAN8742_STATUS_100MBITS_HALFDUPLEX if 100Mb/s HD
+  *         LAN8742_STATUS_10MBITS_FULLDUPLEX  if 10Mb/s FD
+  *         LAN8742_STATUS_10MBITS_HALFDUPLEX  if 10Mb/s HD       
+  *         LAN8742_STATUS_READ_ERROR if connot read register
+  *         LAN8742_STATUS_WRITE_ERROR if connot write to register
+  */
+int32_t LAN8742_GetLinkState(lan8742_Object_t *pObj)
+{
+  uint32_t readval = 0;
+  
+  /* Read Status register  */
+  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval) < 0)
+  {
+    return LAN8742_STATUS_READ_ERROR;
+  }
+  
+  /* Read Status register again */
+  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval) < 0)
+  {
+    return LAN8742_STATUS_READ_ERROR;
+  }
+  
+  if((readval & LAN8742_BSR_LINK_STATUS) == 0)
+  {
+    /* Return Link Down status */
+    return LAN8742_STATUS_LINK_DOWN;    
+  }
+  
+  /* Check Auto negotiaition */
+  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) < 0)
+  {
+    return LAN8742_STATUS_READ_ERROR;
+  }
+  
+  if((readval & LAN8742_BCR_AUTONEGO_EN) != LAN8742_BCR_AUTONEGO_EN)
+  {
+    if(((readval & LAN8742_BCR_SPEED_SELECT) == LAN8742_BCR_SPEED_SELECT) && ((readval & LAN8742_BCR_DUPLEX_MODE) == LAN8742_BCR_DUPLEX_MODE)) 
+    {
+      return LAN8742_STATUS_100MBITS_FULLDUPLEX;
+    }
+    else if ((readval & LAN8742_BCR_SPEED_SELECT) == LAN8742_BCR_SPEED_SELECT)
+    {
+      return LAN8742_STATUS_100MBITS_HALFDUPLEX;
+    }        
+    else if ((readval & LAN8742_BCR_DUPLEX_MODE) == LAN8742_BCR_DUPLEX_MODE)
+    {
+      return LAN8742_STATUS_10MBITS_FULLDUPLEX;
+    }
+    else
+    {
+      return LAN8742_STATUS_10MBITS_HALFDUPLEX;
+    }  		
+  }
+  else /* Auto Nego enabled */
+  {
+    if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_PHYSCSR, &readval) < 0)
+    {
+      return LAN8742_STATUS_READ_ERROR;
+    }
+    
+    /* Check if auto nego not done */
+    if((readval & LAN8742_PHYSCSR_AUTONEGO_DONE) == 0)
+    {
+      return LAN8742_STATUS_AUTONEGO_NOTDONE;
+    }
+    
+    if((readval & LAN8742_PHYSCSR_HCDSPEEDMASK) == LAN8742_PHYSCSR_100BTX_FD)
+    {
+      return LAN8742_STATUS_100MBITS_FULLDUPLEX;
+    }
+    else if ((readval & LAN8742_PHYSCSR_HCDSPEEDMASK) == LAN8742_PHYSCSR_100BTX_HD)
+    {
+      return LAN8742_STATUS_100MBITS_HALFDUPLEX;
+    }
+    else if ((readval & LAN8742_PHYSCSR_HCDSPEEDMASK) == LAN8742_PHYSCSR_10BT_FD)
+    {
+      return LAN8742_STATUS_10MBITS_FULLDUPLEX;
+    }
+    else
+    {
+      return LAN8742_STATUS_10MBITS_HALFDUPLEX;
+    }				
+  }
+}
+
+/**
+  * @brief  Set the link state of LAN8742 device.
+  * @param  pObj: Pointer to device object. 
+  * @param  pLinkState: link state can be one of the following
+  *         LAN8742_STATUS_100MBITS_FULLDUPLEX if 100Mb/s FD
+  *         LAN8742_STATUS_100MBITS_HALFDUPLEX if 100Mb/s HD
+  *         LAN8742_STATUS_10MBITS_FULLDUPLEX  if 10Mb/s FD
+  *         LAN8742_STATUS_10MBITS_HALFDUPLEX  if 10Mb/s HD   
+  * @retval LAN8742_STATUS_OK  if OK
+  *         LAN8742_STATUS_ERROR  if parameter error  
+  *         LAN8742_STATUS_READ_ERROR if connot read register
+  *         LAN8742_STATUS_WRITE_ERROR if connot write to register
+  */
+int32_t LAN8742_SetLinkState(lan8742_Object_t *pObj, uint32_t LinkState)
+{
+  uint32_t bcrvalue = 0;
+  int32_t status = LAN8742_STATUS_OK;
+  
+  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &bcrvalue) >= 0)
+  {
+    /* Disable link config (Auto nego, speed and duplex) */
+    bcrvalue &= ~(LAN8742_BCR_AUTONEGO_EN | LAN8742_BCR_SPEED_SELECT | LAN8742_BCR_DUPLEX_MODE);
+    
+    if(LinkState == LAN8742_STATUS_100MBITS_FULLDUPLEX)
+    {
+      bcrvalue |= (LAN8742_BCR_SPEED_SELECT | LAN8742_BCR_DUPLEX_MODE);
+    }
+    else if (LinkState == LAN8742_STATUS_100MBITS_HALFDUPLEX)
+    {
+      bcrvalue |= LAN8742_BCR_SPEED_SELECT;
+    }
+    else if (LinkState == LAN8742_STATUS_10MBITS_FULLDUPLEX)
+    {
+      bcrvalue |= LAN8742_BCR_DUPLEX_MODE;
+    }
+    else
+    {
+      /* Wrong link status parameter */
+      status = LAN8742_STATUS_ERROR;
+    }	
+  }
+  else
+  {
+    status = LAN8742_STATUS_READ_ERROR;
+  }
+  
+  if(status == LAN8742_STATUS_OK)
+  {
+    /* Apply configuration */
+    if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, bcrvalue) < 0)
+    {
+      status = LAN8742_STATUS_WRITE_ERROR;
+    }
+  }
+  
+  return status;
+}
+
+/**
+  * @brief  Enable loopback mode.
+  * @param  pObj: Pointer to device object. 
+  * @retval LAN8742_STATUS_OK  if OK
+  *         LAN8742_STATUS_READ_ERROR if connot read register
+  *         LAN8742_STATUS_WRITE_ERROR if connot write to register
+  */
+int32_t LAN8742_EnableLoopbackMode(lan8742_Object_t *pObj)
+{
+  uint32_t readval = 0;
+  int32_t status = LAN8742_STATUS_OK;
+  
+  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) >= 0)
+  {
+    readval |= LAN8742_BCR_LOOPBACK;
+    
+    /* Apply configuration */
+    if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, readval) < 0)
+    {
+      status = LAN8742_STATUS_WRITE_ERROR;
+    }
+  }
+  else
+  {
+    status = LAN8742_STATUS_READ_ERROR;
+  }
+  
+  return status;
+}
+
+/**
+  * @brief  Disable loopback mode.
+  * @param  pObj: Pointer to device object. 
+  * @retval LAN8742_STATUS_OK  if OK
+  *         LAN8742_STATUS_READ_ERROR if connot read register
+  *         LAN8742_STATUS_WRITE_ERROR if connot write to register
+  */
+int32_t LAN8742_DisableLoopbackMode(lan8742_Object_t *pObj)
+{
+  uint32_t readval = 0;
+  int32_t status = LAN8742_STATUS_OK;
+  
+  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) >= 0)
+  {
+    readval &= ~LAN8742_BCR_LOOPBACK;
+  
+    /* Apply configuration */
+    if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, readval) < 0)
+    {
+      status =  LAN8742_STATUS_WRITE_ERROR;
+    }
+  }
+  else
+  {
+    status = LAN8742_STATUS_READ_ERROR;
+  }
+   
+  return status;
+}
+
+/**
+  * @brief  Enable IT source.
+  * @param  pObj: Pointer to device object. 
+  * @param  Interrupt: IT source to be enabled
+  *         should be a value or a combination of the following:
+  *         LAN8742_WOL_IT                     
+  *         LAN8742_ENERGYON_IT                
+  *         LAN8742_AUTONEGO_COMPLETE_IT       
+  *         LAN8742_REMOTE_FAULT_IT            
+  *         LAN8742_LINK_DOWN_IT               
+  *         LAN8742_AUTONEGO_LP_ACK_IT         
+  *         LAN8742_PARALLEL_DETECTION_FAULT_IT
+  *         LAN8742_AUTONEGO_PAGE_RECEIVED_IT
+  * @retval LAN8742_STATUS_OK  if OK
+  *         LAN8742_STATUS_READ_ERROR if connot read register
+  *         LAN8742_STATUS_WRITE_ERROR if connot write to register
+  */
+int32_t LAN8742_EnableIT(lan8742_Object_t *pObj, uint32_t Interrupt)
+{
+  uint32_t readval = 0;
+  int32_t status = LAN8742_STATUS_OK;
+  
+  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_IMR, &readval) >= 0)
+  {
+    readval |= Interrupt;
+  
+    /* Apply configuration */
+    if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_IMR, readval) < 0)
+    {
+      status =  LAN8742_STATUS_WRITE_ERROR;
+    }
+  }
+  else
+  {
+    status = LAN8742_STATUS_READ_ERROR;
+  }
+   
+  return status;
+}
+
+/**
+  * @brief  Disable IT source.
+  * @param  pObj: Pointer to device object. 
+  * @param  Interrupt: IT source to be disabled
+  *         should be a value or a combination of the following:
+  *         LAN8742_WOL_IT                     
+  *         LAN8742_ENERGYON_IT                
+  *         LAN8742_AUTONEGO_COMPLETE_IT       
+  *         LAN8742_REMOTE_FAULT_IT            
+  *         LAN8742_LINK_DOWN_IT               
+  *         LAN8742_AUTONEGO_LP_ACK_IT         
+  *         LAN8742_PARALLEL_DETECTION_FAULT_IT
+  *         LAN8742_AUTONEGO_PAGE_RECEIVED_IT
+  * @retval LAN8742_STATUS_OK  if OK
+  *         LAN8742_STATUS_READ_ERROR if connot read register
+  *         LAN8742_STATUS_WRITE_ERROR if connot write to register
+  */
+int32_t LAN8742_DisableIT(lan8742_Object_t *pObj, uint32_t Interrupt)
+{
+  uint32_t readval = 0;
+  int32_t status = LAN8742_STATUS_OK;
+  
+  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_IMR, &readval) >= 0)
+  {
+    readval &= ~Interrupt;
+  
+    /* Apply configuration */
+    if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_IMR, readval) < 0)
+    {
+      status = LAN8742_STATUS_WRITE_ERROR;
+    }
+  }
+  else
+  {
+    status = LAN8742_STATUS_READ_ERROR;
+  }
+   
+  return status;
+}
+
+/**
+  * @brief  Clear IT flag.
+  * @param  pObj: Pointer to device object. 
+  * @param  Interrupt: IT flag to be cleared
+  *         should be a value or a combination of the following:
+  *         LAN8742_WOL_IT                     
+  *         LAN8742_ENERGYON_IT                
+  *         LAN8742_AUTONEGO_COMPLETE_IT       
+  *         LAN8742_REMOTE_FAULT_IT            
+  *         LAN8742_LINK_DOWN_IT               
+  *         LAN8742_AUTONEGO_LP_ACK_IT         
+  *         LAN8742_PARALLEL_DETECTION_FAULT_IT
+  *         LAN8742_AUTONEGO_PAGE_RECEIVED_IT
+  * @retval LAN8742_STATUS_OK  if OK
+  *         LAN8742_STATUS_READ_ERROR if connot read register
+  */
+int32_t  LAN8742_ClearIT(lan8742_Object_t *pObj, uint32_t Interrupt)
+{
+  uint32_t readval = 0;
+  int32_t status = LAN8742_STATUS_OK;  
+  
+  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_ISFR, &readval) < 0)
+  {
+    status =  LAN8742_STATUS_READ_ERROR;
+  }
+  
+  return status;
+}
+
+/**
+  * @brief  Get IT Flag status.
+  * @param  pObj: Pointer to device object. 
+  * @param  Interrupt: IT Flag to be checked, 
+  *         should be a value or a combination of the following:
+  *         LAN8742_WOL_IT                     
+  *         LAN8742_ENERGYON_IT                
+  *         LAN8742_AUTONEGO_COMPLETE_IT       
+  *         LAN8742_REMOTE_FAULT_IT            
+  *         LAN8742_LINK_DOWN_IT               
+  *         LAN8742_AUTONEGO_LP_ACK_IT         
+  *         LAN8742_PARALLEL_DETECTION_FAULT_IT
+  *         LAN8742_AUTONEGO_PAGE_RECEIVED_IT  
+  * @retval 1 IT flag is SET
+  *         0 IT flag is RESET
+  *         LAN8742_STATUS_READ_ERROR if connot read register
+  */
+int32_t LAN8742_GetITStatus(lan8742_Object_t *pObj, uint32_t Interrupt)
+{
+  uint32_t readval = 0;
+  int32_t status = 0;
+
+  if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_ISFR, &readval) >= 0)
+  {
+    status = ((readval & Interrupt) == Interrupt);
+  }
+  else
+  {
+    status = LAN8742_STATUS_READ_ERROR;
+  }
+	
+  return status;
+}
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */      
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/lwip/ports/drivers/stm32h7/lan8742.h b/lwip/ports/drivers/stm32h7/lan8742.h
new file mode 100644
index 0000000..c1620dd
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/lan8742.h
@@ -0,0 +1,448 @@
+/**
+  ******************************************************************************
+  * @file    lan8742.h
+  * @author  MCD Application Team
+  * @brief   This file contains all the functions prototypes for the
+  *          lan8742.c PHY driver.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>© Copyright (c) 2017 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the
+  * License. You may obtain a copy of the License at:
+  *                        opensource.org/licenses/BSD-3-Clause
+  *
+  ******************************************************************************
+  */ 
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef LAN8742_H
+#define LAN8742_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif   
+   
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup Component
+  * @{
+  */
+    
+/** @defgroup LAN8742
+  * @{
+  */    
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup LAN8742_Exported_Constants LAN8742 Exported Constants
+  * @{
+  */ 
+  
+/** @defgroup LAN8742_Registers_Mapping LAN8742 Registers Mapping
+  * @{
+  */ 
+#define LAN8742_BCR      ((uint16_t)0x0000U)
+#define LAN8742_BSR      ((uint16_t)0x0001U)
+#define LAN8742_PHYI1R   ((uint16_t)0x0002U)
+#define LAN8742_PHYI2R   ((uint16_t)0x0003U)
+#define LAN8742_ANAR     ((uint16_t)0x0004U)
+#define LAN8742_ANLPAR   ((uint16_t)0x0005U)
+#define LAN8742_ANER     ((uint16_t)0x0006U)
+#define LAN8742_ANNPTR   ((uint16_t)0x0007U)
+#define LAN8742_ANNPRR   ((uint16_t)0x0008U)
+#define LAN8742_MMDACR   ((uint16_t)0x000DU)
+#define LAN8742_MMDAADR  ((uint16_t)0x000EU)
+#define LAN8742_ENCTR    ((uint16_t)0x0010U)
+#define LAN8742_MCSR     ((uint16_t)0x0011U)
+#define LAN8742_SMR      ((uint16_t)0x0012U)
+#define LAN8742_TPDCR    ((uint16_t)0x0018U)
+#define LAN8742_TCSR     ((uint16_t)0x0019U)
+#define LAN8742_SECR     ((uint16_t)0x001AU)
+#define LAN8742_SCSIR    ((uint16_t)0x001BU)
+#define LAN8742_CLR      ((uint16_t)0x001CU)
+#define LAN8742_ISFR     ((uint16_t)0x001DU)
+#define LAN8742_IMR      ((uint16_t)0x001EU)
+#define LAN8742_PHYSCSR  ((uint16_t)0x001FU)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_BCR_Bit_Definition LAN8742 BCR Bit Definition
+  * @{
+  */    
+#define LAN8742_BCR_SOFT_RESET         ((uint16_t)0x8000U)
+#define LAN8742_BCR_LOOPBACK           ((uint16_t)0x4000U)
+#define LAN8742_BCR_SPEED_SELECT       ((uint16_t)0x2000U)
+#define LAN8742_BCR_AUTONEGO_EN        ((uint16_t)0x1000U)
+#define LAN8742_BCR_POWER_DOWN         ((uint16_t)0x0800U)
+#define LAN8742_BCR_ISOLATE            ((uint16_t)0x0400U)
+#define LAN8742_BCR_RESTART_AUTONEGO   ((uint16_t)0x0200U)
+#define LAN8742_BCR_DUPLEX_MODE        ((uint16_t)0x0100U) 
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_BSR_Bit_Definition LAN8742 BSR Bit Definition
+  * @{
+  */   
+#define LAN8742_BSR_100BASE_T4       ((uint16_t)0x8000U)
+#define LAN8742_BSR_100BASE_TX_FD    ((uint16_t)0x4000U)
+#define LAN8742_BSR_100BASE_TX_HD    ((uint16_t)0x2000U)
+#define LAN8742_BSR_10BASE_T_FD      ((uint16_t)0x1000U)
+#define LAN8742_BSR_10BASE_T_HD      ((uint16_t)0x0800U)
+#define LAN8742_BSR_100BASE_T2_FD    ((uint16_t)0x0400U)
+#define LAN8742_BSR_100BASE_T2_HD    ((uint16_t)0x0200U)
+#define LAN8742_BSR_EXTENDED_STATUS  ((uint16_t)0x0100U)
+#define LAN8742_BSR_AUTONEGO_CPLT    ((uint16_t)0x0020U)
+#define LAN8742_BSR_REMOTE_FAULT     ((uint16_t)0x0010U)
+#define LAN8742_BSR_AUTONEGO_ABILITY ((uint16_t)0x0008U)
+#define LAN8742_BSR_LINK_STATUS      ((uint16_t)0x0004U)
+#define LAN8742_BSR_JABBER_DETECT    ((uint16_t)0x0002U)
+#define LAN8742_BSR_EXTENDED_CAP     ((uint16_t)0x0001U)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_PHYI1R_Bit_Definition LAN8742 PHYI1R Bit Definition
+  * @{
+  */
+#define LAN8742_PHYI1R_OUI_3_18           ((uint16_t)0xFFFFU)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_PHYI2R_Bit_Definition LAN8742 PHYI2R Bit Definition
+  * @{
+  */
+#define LAN8742_PHYI2R_OUI_19_24          ((uint16_t)0xFC00U)
+#define LAN8742_PHYI2R_MODEL_NBR          ((uint16_t)0x03F0U)
+#define LAN8742_PHYI2R_REVISION_NBR       ((uint16_t)0x000FU)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_ANAR_Bit_Definition LAN8742 ANAR Bit Definition
+  * @{
+  */
+#define LAN8742_ANAR_NEXT_PAGE               ((uint16_t)0x8000U)
+#define LAN8742_ANAR_REMOTE_FAULT            ((uint16_t)0x2000U)
+#define LAN8742_ANAR_PAUSE_OPERATION         ((uint16_t)0x0C00U)
+#define LAN8742_ANAR_PO_NOPAUSE              ((uint16_t)0x0000U)
+#define LAN8742_ANAR_PO_SYMMETRIC_PAUSE      ((uint16_t)0x0400U)
+#define LAN8742_ANAR_PO_ASYMMETRIC_PAUSE     ((uint16_t)0x0800U)
+#define LAN8742_ANAR_PO_ADVERTISE_SUPPORT    ((uint16_t)0x0C00U)
+#define LAN8742_ANAR_100BASE_TX_FD           ((uint16_t)0x0100U)
+#define LAN8742_ANAR_100BASE_TX              ((uint16_t)0x0080U)
+#define LAN8742_ANAR_10BASE_T_FD             ((uint16_t)0x0040U)
+#define LAN8742_ANAR_10BASE_T                ((uint16_t)0x0020U)
+#define LAN8742_ANAR_SELECTOR_FIELD          ((uint16_t)0x000FU)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_ANLPAR_Bit_Definition LAN8742 ANLPAR Bit Definition
+  * @{
+  */
+#define LAN8742_ANLPAR_NEXT_PAGE            ((uint16_t)0x8000U)
+#define LAN8742_ANLPAR_REMOTE_FAULT         ((uint16_t)0x2000U)
+#define LAN8742_ANLPAR_PAUSE_OPERATION      ((uint16_t)0x0C00U)
+#define LAN8742_ANLPAR_PO_NOPAUSE           ((uint16_t)0x0000U)
+#define LAN8742_ANLPAR_PO_SYMMETRIC_PAUSE   ((uint16_t)0x0400U)
+#define LAN8742_ANLPAR_PO_ASYMMETRIC_PAUSE  ((uint16_t)0x0800U)
+#define LAN8742_ANLPAR_PO_ADVERTISE_SUPPORT ((uint16_t)0x0C00U)
+#define LAN8742_ANLPAR_100BASE_TX_FD        ((uint16_t)0x0100U)
+#define LAN8742_ANLPAR_100BASE_TX           ((uint16_t)0x0080U)
+#define LAN8742_ANLPAR_10BASE_T_FD          ((uint16_t)0x0040U)
+#define LAN8742_ANLPAR_10BASE_T             ((uint16_t)0x0020U)
+#define LAN8742_ANLPAR_SELECTOR_FIELD       ((uint16_t)0x000FU)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_ANER_Bit_Definition LAN8742 ANER Bit Definition
+  * @{
+  */
+#define LAN8742_ANER_RX_NP_LOCATION_ABLE    ((uint16_t)0x0040U)
+#define LAN8742_ANER_RX_NP_STORAGE_LOCATION ((uint16_t)0x0020U)
+#define LAN8742_ANER_PARALLEL_DETECT_FAULT  ((uint16_t)0x0010U)
+#define LAN8742_ANER_LP_NP_ABLE             ((uint16_t)0x0008U)
+#define LAN8742_ANER_NP_ABLE                ((uint16_t)0x0004U)
+#define LAN8742_ANER_PAGE_RECEIVED          ((uint16_t)0x0002U)
+#define LAN8742_ANER_LP_AUTONEG_ABLE        ((uint16_t)0x0001U)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_ANNPTR_Bit_Definition LAN8742 ANNPTR Bit Definition
+  * @{
+  */
+#define LAN8742_ANNPTR_NEXT_PAGE         ((uint16_t)0x8000U)
+#define LAN8742_ANNPTR_MESSAGE_PAGE      ((uint16_t)0x2000U)
+#define LAN8742_ANNPTR_ACK2              ((uint16_t)0x1000U)
+#define LAN8742_ANNPTR_TOGGLE            ((uint16_t)0x0800U)
+#define LAN8742_ANNPTR_MESSAGGE_CODE     ((uint16_t)0x07FFU)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_ANNPRR_Bit_Definition LAN8742 ANNPRR Bit Definition
+  * @{
+  */
+#define LAN8742_ANNPTR_NEXT_PAGE         ((uint16_t)0x8000U)
+#define LAN8742_ANNPRR_ACK               ((uint16_t)0x4000U)
+#define LAN8742_ANNPRR_MESSAGE_PAGE      ((uint16_t)0x2000U)
+#define LAN8742_ANNPRR_ACK2              ((uint16_t)0x1000U)
+#define LAN8742_ANNPRR_TOGGLE            ((uint16_t)0x0800U)
+#define LAN8742_ANNPRR_MESSAGGE_CODE     ((uint16_t)0x07FFU)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_MMDACR_Bit_Definition LAN8742 MMDACR Bit Definition
+  * @{
+  */
+#define LAN8742_MMDACR_MMD_FUNCTION       ((uint16_t)0xC000U) 
+#define LAN8742_MMDACR_MMD_FUNCTION_ADDR  ((uint16_t)0x0000U)
+#define LAN8742_MMDACR_MMD_FUNCTION_DATA  ((uint16_t)0x4000U)
+#define LAN8742_MMDACR_MMD_DEV_ADDR       ((uint16_t)0x001FU)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_ENCTR_Bit_Definition LAN8742 ENCTR Bit Definition
+  * @{
+  */
+#define LAN8742_ENCTR_TX_ENABLE             ((uint16_t)0x8000U)
+#define LAN8742_ENCTR_TX_TIMER              ((uint16_t)0x6000U)
+#define LAN8742_ENCTR_TX_TIMER_1S           ((uint16_t)0x0000U)
+#define LAN8742_ENCTR_TX_TIMER_768MS        ((uint16_t)0x2000U)
+#define LAN8742_ENCTR_TX_TIMER_512MS        ((uint16_t)0x4000U)
+#define LAN8742_ENCTR_TX_TIMER_265MS        ((uint16_t)0x6000U)
+#define LAN8742_ENCTR_RX_ENABLE             ((uint16_t)0x1000U)
+#define LAN8742_ENCTR_RX_MAX_INTERVAL       ((uint16_t)0x0C00U)
+#define LAN8742_ENCTR_RX_MAX_INTERVAL_64MS  ((uint16_t)0x0000U)
+#define LAN8742_ENCTR_RX_MAX_INTERVAL_256MS ((uint16_t)0x0400U)
+#define LAN8742_ENCTR_RX_MAX_INTERVAL_512MS ((uint16_t)0x0800U)
+#define LAN8742_ENCTR_RX_MAX_INTERVAL_1S    ((uint16_t)0x0C00U)
+#define LAN8742_ENCTR_EX_CROSS_OVER         ((uint16_t)0x0002U)
+#define LAN8742_ENCTR_EX_MANUAL_CROSS_OVER  ((uint16_t)0x0001U)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_MCSR_Bit_Definition LAN8742 MCSR Bit Definition
+  * @{
+  */
+#define LAN8742_MCSR_EDPWRDOWN        ((uint16_t)0x2000U)
+#define LAN8742_MCSR_FARLOOPBACK      ((uint16_t)0x0200U)
+#define LAN8742_MCSR_ALTINT           ((uint16_t)0x0040U)
+#define LAN8742_MCSR_ENERGYON         ((uint16_t)0x0002U)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_SMR_Bit_Definition LAN8742 SMR Bit Definition
+  * @{
+  */
+#define LAN8742_SMR_MODE       ((uint16_t)0x00E0U)
+#define LAN8742_SMR_PHY_ADDR   ((uint16_t)0x001FU)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_TPDCR_Bit_Definition LAN8742 TPDCR Bit Definition
+  * @{
+  */
+#define LAN8742_TPDCR_DELAY_IN                 ((uint16_t)0x8000U)
+#define LAN8742_TPDCR_LINE_BREAK_COUNTER       ((uint16_t)0x7000U)
+#define LAN8742_TPDCR_PATTERN_HIGH             ((uint16_t)0x0FC0U)
+#define LAN8742_TPDCR_PATTERN_LOW              ((uint16_t)0x003FU)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_TCSR_Bit_Definition LAN8742 TCSR Bit Definition
+  * @{
+  */
+#define LAN8742_TCSR_TDR_ENABLE           ((uint16_t)0x8000U)
+#define LAN8742_TCSR_TDR_AD_FILTER_ENABLE ((uint16_t)0x4000U)
+#define LAN8742_TCSR_TDR_CH_CABLE_TYPE    ((uint16_t)0x0600U)
+#define LAN8742_TCSR_TDR_CH_CABLE_DEFAULT ((uint16_t)0x0000U)
+#define LAN8742_TCSR_TDR_CH_CABLE_SHORTED ((uint16_t)0x0200U)
+#define LAN8742_TCSR_TDR_CH_CABLE_OPEN    ((uint16_t)0x0400U)
+#define LAN8742_TCSR_TDR_CH_CABLE_MATCH   ((uint16_t)0x0600U)
+#define LAN8742_TCSR_TDR_CH_STATUS        ((uint16_t)0x0100U)
+#define LAN8742_TCSR_TDR_CH_LENGTH        ((uint16_t)0x00FFU)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_SCSIR_Bit_Definition LAN8742 SCSIR Bit Definition
+  * @{
+  */
+#define LAN8742_SCSIR_AUTO_MDIX_ENABLE    ((uint16_t)0x8000U)
+#define LAN8742_SCSIR_CHANNEL_SELECT      ((uint16_t)0x2000U)
+#define LAN8742_SCSIR_SQE_DISABLE         ((uint16_t)0x0800U)
+#define LAN8742_SCSIR_XPOLALITY           ((uint16_t)0x0010U)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_CLR_Bit_Definition LAN8742 CLR Bit Definition
+  * @{
+  */
+#define LAN8742_CLR_CABLE_LENGTH       ((uint16_t)0xF000U)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_IMR_ISFR_Bit_Definition LAN8742 IMR ISFR Bit Definition
+  * @{
+  */
+#define LAN8742_INT_8       ((uint16_t)0x0100U)
+#define LAN8742_INT_7       ((uint16_t)0x0080U)
+#define LAN8742_INT_6       ((uint16_t)0x0040U)
+#define LAN8742_INT_5       ((uint16_t)0x0020U)
+#define LAN8742_INT_4       ((uint16_t)0x0010U)
+#define LAN8742_INT_3       ((uint16_t)0x0008U)
+#define LAN8742_INT_2       ((uint16_t)0x0004U)
+#define LAN8742_INT_1       ((uint16_t)0x0002U)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_PHYSCSR_Bit_Definition LAN8742 PHYSCSR Bit Definition
+  * @{
+  */
+#define LAN8742_PHYSCSR_AUTONEGO_DONE   ((uint16_t)0x1000U)
+#define LAN8742_PHYSCSR_HCDSPEEDMASK    ((uint16_t)0x001CU)
+#define LAN8742_PHYSCSR_10BT_HD         ((uint16_t)0x0004U)
+#define LAN8742_PHYSCSR_10BT_FD         ((uint16_t)0x0014U)
+#define LAN8742_PHYSCSR_100BTX_HD       ((uint16_t)0x0008U)
+#define LAN8742_PHYSCSR_100BTX_FD       ((uint16_t)0x0018U) 
+/**
+  * @}
+  */
+    
+/** @defgroup LAN8742_Status LAN8742 Status
+  * @{
+  */    
+
+#define  LAN8742_STATUS_READ_ERROR            ((int32_t)-5)
+#define  LAN8742_STATUS_WRITE_ERROR           ((int32_t)-4)
+#define  LAN8742_STATUS_ADDRESS_ERROR         ((int32_t)-3)
+#define  LAN8742_STATUS_RESET_TIMEOUT         ((int32_t)-2)
+#define  LAN8742_STATUS_ERROR                 ((int32_t)-1)
+#define  LAN8742_STATUS_OK                    ((int32_t) 0)
+#define  LAN8742_STATUS_LINK_DOWN             ((int32_t) 1)
+#define  LAN8742_STATUS_100MBITS_FULLDUPLEX   ((int32_t) 2)
+#define  LAN8742_STATUS_100MBITS_HALFDUPLEX   ((int32_t) 3)
+#define  LAN8742_STATUS_10MBITS_FULLDUPLEX    ((int32_t) 4)
+#define  LAN8742_STATUS_10MBITS_HALFDUPLEX    ((int32_t) 5)
+#define  LAN8742_STATUS_AUTONEGO_NOTDONE      ((int32_t) 6)
+/**
+  * @}
+  */
+
+/** @defgroup LAN8742_IT_Flags LAN8742 IT Flags
+  * @{
+  */     
+#define  LAN8742_WOL_IT                        LAN8742_INT_8
+#define  LAN8742_ENERGYON_IT                   LAN8742_INT_7
+#define  LAN8742_AUTONEGO_COMPLETE_IT          LAN8742_INT_6
+#define  LAN8742_REMOTE_FAULT_IT               LAN8742_INT_5
+#define  LAN8742_LINK_DOWN_IT                  LAN8742_INT_4
+#define  LAN8742_AUTONEGO_LP_ACK_IT            LAN8742_INT_3
+#define  LAN8742_PARALLEL_DETECTION_FAULT_IT   LAN8742_INT_2
+#define  LAN8742_AUTONEGO_PAGE_RECEIVED_IT     LAN8742_INT_1
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/* Exported types ------------------------------------------------------------*/ 
+/** @defgroup LAN8742_Exported_Types LAN8742 Exported Types
+  * @{
+  */
+typedef int32_t  (*lan8742_Init_Func) (void); 
+typedef int32_t  (*lan8742_DeInit_Func) (void);
+typedef int32_t  (*lan8742_ReadReg_Func)   (uint32_t, uint32_t, uint32_t *);
+typedef int32_t  (*lan8742_WriteReg_Func)  (uint32_t, uint32_t, uint32_t);
+typedef int32_t  (*lan8742_GetTick_Func)  (void);
+
+typedef struct 
+{                   
+  lan8742_Init_Func      Init; 
+  lan8742_DeInit_Func    DeInit;
+  lan8742_WriteReg_Func  WriteReg;
+  lan8742_ReadReg_Func   ReadReg; 
+  lan8742_GetTick_Func   GetTick;   
+} lan8742_IOCtx_t;  
+
+  
+typedef struct 
+{
+  uint32_t            DevAddr;
+  uint32_t            Is_Initialized;
+  lan8742_IOCtx_t     IO;
+  void               *pData;
+}lan8742_Object_t;
+/**
+  * @}
+  */ 
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup LAN8742_Exported_Functions LAN8742 Exported Functions
+  * @{
+  */
+int32_t LAN8742_RegisterBusIO(lan8742_Object_t *pObj, lan8742_IOCtx_t *ioctx);
+int32_t LAN8742_Init(lan8742_Object_t *pObj);
+int32_t LAN8742_DeInit(lan8742_Object_t *pObj);
+int32_t LAN8742_DisablePowerDownMode(lan8742_Object_t *pObj);
+int32_t LAN8742_EnablePowerDownMode(lan8742_Object_t *pObj);
+int32_t LAN8742_StartAutoNego(lan8742_Object_t *pObj);
+int32_t LAN8742_GetLinkState(lan8742_Object_t *pObj);
+int32_t LAN8742_SetLinkState(lan8742_Object_t *pObj, uint32_t LinkState);
+int32_t LAN8742_EnableLoopbackMode(lan8742_Object_t *pObj);
+int32_t LAN8742_DisableLoopbackMode(lan8742_Object_t *pObj);
+int32_t LAN8742_EnableIT(lan8742_Object_t *pObj, uint32_t Interrupt);
+int32_t LAN8742_DisableIT(lan8742_Object_t *pObj, uint32_t Interrupt);
+int32_t LAN8742_ClearIT(lan8742_Object_t *pObj, uint32_t Interrupt);
+int32_t LAN8742_GetITStatus(lan8742_Object_t *pObj, uint32_t Interrupt);
+/**
+  * @}
+  */ 
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* LAN8742_H */
+
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */       
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/lwip/ports/drivers/stm32h7/template/lwipopts_template.h b/lwip/ports/drivers/stm32h7/template/lwipopts_template.h
new file mode 100644
index 0000000..756060c
--- /dev/null
+++ b/lwip/ports/drivers/stm32h7/template/lwipopts_template.h
@@ -0,0 +1,289 @@
+/**
+  ******************************************************************************
+  * @file    LwIP/LwIP_HTTP_Server_Netconn_RTOS/Inc/lwipopts.h
+  * @author  MCD Application Team
+  * @brief   lwIP Options Configuration.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
+  * All rights reserved.</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted, provided that the following conditions are met:
+  *
+  * 1. Redistribution 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. Neither the name of STMicroelectronics nor the names of other
+  *    contributors to this software may be used to endorse or promote products
+  *    derived from this software without specific written permission.
+  * 4. This software, including modifications and/or derivative works of this
+  *    software, must execute solely and exclusively on microcontroller or
+  *    microprocessor devices manufactured by or for STMicroelectronics.
+  * 5. Redistribution and use of this software other than as permitted under
+  *    this license is void and will automatically terminate your rights under
+  *    this license.
+  *
+  * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
+  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+  * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
+  * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
+  * SHALL STMICROELECTRONICS OR CONTRIBUTORS 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.
+  *
+  ******************************************************************************
+  */
+
+#ifndef __LWIPOPTS_H__
+#define __LWIPOPTS_H__
+
+#include "conf_app.h"
+#include "bsp.h"
+
+/**
+ * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
+ * critical regions during buffer allocation, deallocation and memory
+ * allocation and deallocation.
+ */
+#define SYS_LIGHTWEIGHT_PROT        0
+
+/**
+ * NO_SYS==1: Provides VERY minimal functionality. Otherwise,
+ * use lwIP facilities.
+ */
+#define NO_SYS                      1
+
+#define LWIP_NETIF_API              0
+
+/* ---------- Memory options ---------- */
+/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
+   lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
+   byte alignment -> define MEM_ALIGNMENT to 2. */
+#define MEM_ALIGNMENT               4
+
+/* MEM_SIZE: the size of the heap memory. If the application will send
+a lot of data that needs to be copied, this should be set high. */
+#define MEM_SIZE                    (8*1024)
+
+/* Relocate the LwIP RAM heap pointer. Place in SRAM3 */
+#define LWIP_RAM_HEAP_POINTER       (0x30040000)
+
+/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
+   sends a lot of data out of ROM (or other static memory), this
+   should be set high. */
+#define MEMP_NUM_PBUF               10
+/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
+   per active UDP "connection". */
+#define MEMP_NUM_UDP_PCB            6
+/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
+   connections. */
+#define MEMP_NUM_TCP_PCB            10
+/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
+   connections. */
+#define MEMP_NUM_TCP_PCB_LISTEN     5
+/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
+   segments. */
+#define MEMP_NUM_TCP_SEG            8
+/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
+   timeouts. */
+#define MEMP_NUM_SYS_TIMEOUT        10
+
+
+/* ---------- Pbuf options ---------- */
+/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool.
+   @ note: used to allocate Tx pbufs only */
+#define PBUF_POOL_SIZE              4
+
+/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
+#define PBUF_POOL_BUFSIZE           1528
+
+/* LWIP_SUPPORT_CUSTOM_PBUF == 1: to pass directly MAC Rx buffers to the stack
+   no copy is needed */
+#define LWIP_SUPPORT_CUSTOM_PBUF    1
+
+/* ---------- IPv4 options ---------- */
+#define LWIP_IPV4                   1
+
+/* ---------- TCP options ---------- */
+#define LWIP_TCP                    1
+#define TCP_TTL                     255
+
+/* Controls if TCP should queue segments that arrive out of
+   order. Define to 0 if your device is low on memory. */
+#define TCP_QUEUE_OOSEQ             0
+
+/* TCP Maximum segment size. */
+#define TCP_MSS                     (1500 - 40)   /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */
+
+/* TCP sender buffer space (bytes). */
+#define TCP_SND_BUF                 (4*TCP_MSS)
+
+/*  TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least
+  as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. */
+
+#define TCP_SND_QUEUELEN            (2* TCP_SND_BUF/TCP_MSS)
+
+/* TCP receive window. */
+#define TCP_WND                     (2*TCP_MSS)
+
+/* ---------- ICMP options ---------- */
+#define LWIP_ICMP                   1
+
+/* ---------- DHCP options ---------- */
+#define LWIP_DHCP                   1
+
+/* ---------- UDP options ---------- */
+#define LWIP_UDP                    1
+#define UDP_TTL                     255
+
+/* ---------- link callback options ---------- */
+/* LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface
+ * whenever the link changes (i.e., link down)
+ */
+#define LWIP_NETIF_LINK_CALLBACK    1
+
+
+/* Static IP ADDRESS */
+#define IP_ADDR0   169
+#define IP_ADDR1   254
+#define IP_ADDR2   1
+#define IP_ADDR3   38
+
+/* NETMASK */
+#define NETMASK_ADDR0   255
+#define NETMASK_ADDR1   255
+#define NETMASK_ADDR2   0
+#define NETMASK_ADDR3   0
+
+/* Gateway Address */
+#define GW_ADDR0   192
+#define GW_ADDR1   168
+#define GW_ADDR2   178
+#define GW_ADDR3   1
+
+
+/*
+   --------------------------------------
+   ---------- Checksum options ----------
+   --------------------------------------
+*/
+
+/*
+The STM32H7xx allows computing and verifying the IP, UDP, TCP and ICMP checksums by hardware:
+ - To use this feature let the following define uncommented.
+ - To disable it and process by CPU comment the  the checksum.
+*/
+#define CHECKSUM_BY_HARDWARE
+
+
+#ifdef CHECKSUM_BY_HARDWARE
+  /* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/
+  #define CHECKSUM_GEN_IP                 0
+  /* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/
+  #define CHECKSUM_GEN_UDP                0
+  /* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/
+  #define CHECKSUM_GEN_TCP                0
+  /* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/
+  #define CHECKSUM_CHECK_IP               0
+  /* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/
+  #define CHECKSUM_CHECK_UDP              0
+  /* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/
+  #define CHECKSUM_CHECK_TCP              0
+  /* CHECKSUM_CHECK_ICMP==0: Check checksums by hardware for incoming ICMP packets.*/
+  #define CHECKSUM_GEN_ICMP               0
+#else
+  /* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/
+  #define CHECKSUM_GEN_IP                 1
+  /* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/
+  #define CHECKSUM_GEN_UDP                1
+  /* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/
+  #define CHECKSUM_GEN_TCP                1
+  /* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/
+  #define CHECKSUM_CHECK_IP               1
+  /* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/
+  #define CHECKSUM_CHECK_UDP              1
+  /* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/
+  #define CHECKSUM_CHECK_TCP              1
+  /* CHECKSUM_CHECK_ICMP==1: Check checksums by hardware for incoming ICMP packets.*/
+  #define CHECKSUM_GEN_ICMP               1
+#endif
+
+
+/*
+   ----------------------------------------------
+   ---------- Sequential layer options ----------
+   ----------------------------------------------
+*/
+/**
+ * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
+ */
+#define LWIP_NETCONN                    0
+
+/*
+   ------------------------------------
+   ---------- Socket options ----------
+   ------------------------------------
+*/
+/**
+ * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
+ */
+#define LWIP_SOCKET                     0
+
+/*
+   ------------------------------------
+   ---------- httpd options ----------
+   ------------------------------------
+*/
+/** Set this to 1 to include "fsdata_custom.c" instead of "fsdata.c" for the
+ * file system (to prevent changing the file included in CVS) */
+#define HTTPD_USE_CUSTOM_FSDATA   1
+
+
+/*
+   ---------------------------------
+   ---------- OS options ----------
+   ---------------------------------
+*/
+
+#define TCPIP_THREAD_NAME              "LWIP"
+#define TCPIP_THREAD_STACKSIZE          RTEMS_MINIMUM_STACK_SIZE
+#define TCPIP_MBOX_SIZE                 6
+#define DEFAULT_UDP_RECVMBOX_SIZE       6
+#define DEFAULT_TCP_RECVMBOX_SIZE       6
+#define DEFAULT_ACCEPTMBOX_SIZE         6
+#define DEFAULT_THREAD_STACKSIZE        500
+#define TCPIP_THREAD_PRIO               60
+
+/*
+   ---------------------------------
+   ---------- ASSERT options ----------
+   ---------------------------------
+*/
+#define LWIP_NOASSERT
+
+
+#define ETH_MAC_ADDR0    ((uint8_t)0x02)
+#define ETH_MAC_ADDR1    ((uint8_t)0x00)
+#define ETH_MAC_ADDR2    ((uint8_t)0x00)
+#define ETH_MAC_ADDR3    ((uint8_t)0x00)
+#define ETH_MAC_ADDR4    ((uint8_t)0x00)
+#define ETH_MAC_ADDR5    ((uint8_t)0x00)
+#define ETH_MAC_ADDR     { ETH_MAC_ADDR0, ETH_MAC_ADDR1, \
+                           ETH_MAC_ADDR2, ETH_MAC_ADDR3, \
+                           ETH_MAC_ADDR4, ETH_MAC_ADDR5 }
+
+/* #undef LWIP_DEBUG */
+
+#endif /* __LWIPOPTS_H__ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/lwip/ports/drivers/phy_dp83848h.c b/lwip/ports/drivers/tms570/phy_dp83848h.c
similarity index 100%
rename from lwip/ports/drivers/phy_dp83848h.c
rename to lwip/ports/drivers/tms570/phy_dp83848h.c
diff --git a/lwip/ports/drivers/phy_dp83848h.h b/lwip/ports/drivers/tms570/phy_dp83848h.h
similarity index 100%
rename from lwip/ports/drivers/phy_dp83848h.h
rename to lwip/ports/drivers/tms570/phy_dp83848h.h
diff --git a/lwip/ports/drivers/tms570/template/lwipopts_template.h b/lwip/ports/drivers/tms570/template/lwipopts_template.h
new file mode 100644
index 0000000..fb55e7a
--- /dev/null
+++ b/lwip/ports/drivers/tms570/template/lwipopts_template.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * 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 the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR 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.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Simon Goldschmidt
+ *
+ */
+#ifndef LWIP_HDR_LWIPOPTS_H__
+#define LWIP_HDR_LWIPOPTS_H__
+
+/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */
+#define NO_SYS                          0
+#define LWIP_NETCONN                    1
+#define LWIP_SOCKET                     1
+#define LWIP_DNS                        1
+
+#define LWIP_IPV6                       1
+#define LWIP_IPV4                       1
+
+#define LWIP_ETHERNET                   1
+#define LWIP_NETIF_API                  1
+/* Enable DHCP to test it, disable UDP checksum to easier inject packets */
+#define LWIP_DHCP                       1
+#define LWIP_TIMEVAL_PRIVATE            0
+#define LWIP_POSIX_SOCKETS_IO_NAMES     0
+
+/* Minimal changes to opt.h required for tcp unit tests: */
+#define MEM_SIZE                        16000
+#define TCP_SND_QUEUELEN                40
+#define MEMP_NUM_TCP_SEG                TCP_SND_QUEUELEN
+#define TCP_SND_BUF                     (12 * TCP_MSS)
+#define TCP_WND                         (10 * TCP_MSS)
+#define LWIP_WND_SCALE                  1
+#define TCP_RCV_SCALE                   0
+#define PBUF_POOL_SIZE                  400 // pbuf tests need ~200KByte
+
+/* Minimal changes to opt.h required for etharp unit tests: */
+#define ETHARP_SUPPORT_STATIC_ENTRIES   1
+
+#define ETH_IP_ADDR               0xC0A8F701 /* 192.168.247.1   */
+#define ETH_NETMASK               0xFFFFFF00 /* 255.255.255.0   */
+#define ETH_GW                    0xC0A8F7FE /* 192.168.247.254 */
+
+#define LWIP_NETIF_LINK_CALLBACK        1
+
+void tms570_eth_memp_avaible(int type);
+
+/*called from memp_free() when a memp pool was empty and an item is now available*/
+#define LWIP_HOOK_MEMP_AVAILABLE tms570_eth_memp_avaible
+
+#endif /* LWIP_HDR_LWIPOPTS_H__ */
diff --git a/lwip/ports/drivers/ti_drv_emac.h b/lwip/ports/drivers/tms570/ti_drv_emac.h
similarity index 100%
rename from lwip/ports/drivers/ti_drv_emac.h
rename to lwip/ports/drivers/tms570/ti_drv_emac.h
diff --git a/lwip/ports/drivers/ti_drv_mdio.h b/lwip/ports/drivers/tms570/ti_drv_mdio.h
similarity index 100%
rename from lwip/ports/drivers/ti_drv_mdio.h
rename to lwip/ports/drivers/tms570/ti_drv_mdio.h
diff --git a/lwip/ports/drivers/tms570_emac.h b/lwip/ports/drivers/tms570/tms570_emac.h
similarity index 100%
rename from lwip/ports/drivers/tms570_emac.h
rename to lwip/ports/drivers/tms570/tms570_emac.h
diff --git a/lwip/ports/drivers/tms570_netif.c b/lwip/ports/drivers/tms570/tms570_netif.c
similarity index 99%
rename from lwip/ports/drivers/tms570_netif.c
rename to lwip/ports/drivers/tms570/tms570_netif.c
index 8d14687..2c99362 100644
--- a/lwip/ports/drivers/tms570_netif.c
+++ b/lwip/ports/drivers/tms570/tms570_netif.c
@@ -54,13 +54,15 @@
 #include <bsp/tms570.h>
 #include <bsp/tms570-pinmux.h>
 #include "arch/cc.h"
-#include "eth_lwip.h"
+#include "rtems_lwip.h"
 #include "tms570_netif.h"
 #include "ti_drv_emac.h"
 #include "ti_drv_mdio.h"
 #include "phy_dp83848h.h"
 #include "tms570_emac.h"
 
+netif_init_fn eth_lwip_init_fnc = &tms570_eth_init_netif;
+
 #define LINK_SPEED_OF_YOUR_NETIF_IN_BPS 10000000
 
 /* Number of EMAC Instances */
@@ -150,6 +152,7 @@ static err_t tms570_eth_init_control_structures(struct netif *netif);
 static void tms570_eth_init_netif_fill(struct netif *netif);
 static void tms570_eth_init_buffer_descriptors(struct tms570_netif_state *nf_state);
 static void tms570_eth_init_set_pinmux();
+static void sys_arch_data_sync_barier();
 
 /***** initializing functions **********************************************/
 
@@ -1122,10 +1125,12 @@ tms570_eth_memp_avaible(int type)
     return;
   if (type != MEMP_PBUF_POOL)
     return;
-  netifapi_netif_common(eth_lwip_get_netif(0), tms570_eth_rx_pbuf_refill_single, NULL);
+  netifapi_netif_common(rtems_lwip_get_netif(0), tms570_eth_rx_pbuf_refill_single, NULL);
 }
 
-
+void sys_arch_data_sync_barier() {
+    _ARM_Data_synchronization_barrier();
+}
 
 #if TMS570_NETIF_DEBUG
 
diff --git a/lwip/ports/drivers/tms570_netif.h b/lwip/ports/drivers/tms570/tms570_netif.h
similarity index 74%
rename from lwip/ports/drivers/tms570_netif.h
rename to lwip/ports/drivers/tms570/tms570_netif.h
index 325249a..6636f3f 100644
--- a/lwip/ports/drivers/tms570_netif.h
+++ b/lwip/ports/drivers/tms570/tms570_netif.h
@@ -36,6 +36,37 @@
 
 //#define TMS570_NETIF_DEBUG 1
 
+/**
+ * While scanning phy addresses no alive phy was found.
+ * Return value of rpp_eth_hw_init() function.
+ */
+#define NO_PHY_ALIVE             -1
+/**
+ * Scanning default phy address, it was found it's not alive.
+ * Return value of rpp_eth_hw_init() function.
+ */
+#define DFLT_PHY_NOT_ALIVE       -1
+/**
+ * When setting autonegotiation parameters to EMAC module, there was found impossible mode (usually on timeout of autonegotiation).
+ * Return value of rpp_eth_hw_init_postInit() function.
+ */
+#define UNKN_DUPLEX_MODE         -2 /* this could mean that autonegotiation was not completed yet */
+/**
+ * Phy is down error.
+ * Return value of rpp_eth_init_postInit() function.
+ */
+#define PHY_LINK_DOWN            -3
+
+/**
+ * Memory requirements couldn't be satisfied.
+ */
+#define DHCP_MEM_ERR             -11
+
+/**
+ * configures whether rpp_eth_get_macAddrStr() creates string with big or small latin letters
+ */
+#define MAC_BIG_LETTERS           1
+
 #ifdef TMS570_NETIF_DEBUG
 #define tms570_eth_debug_printf sys_arch_printk
 #else
diff --git a/lwip/ports/os/rtems/arch/cc.h b/lwip/ports/os/rtems/arch/cc.h
index 84138ff..0e298c7 100644
--- a/lwip/ports/os/rtems/arch/cc.h
+++ b/lwip/ports/os/rtems/arch/cc.h
@@ -39,6 +39,9 @@
 #ifndef __CC_H__
 #define __CC_H__
 
+/* Use timeval provided by RTEMS be defining this to 0 */
+#define LWIP_TIMEVAL_PRIVATE 0
+
 #include <stdio.h>
 #include <rtems/malloc.h>  /*printk*/
 #include <inttypes.h>
diff --git a/lwip/ports/os/rtems/arch/sys_arch.c b/lwip/ports/os/rtems/arch/sys_arch.c
index ca7f8be..f845c2c 100644
--- a/lwip/ports/os/rtems/arch/sys_arch.c
+++ b/lwip/ports/os/rtems/arch/sys_arch.c
@@ -37,15 +37,22 @@
  * DETAILS: ./lwip/doc/sys_arch.txt
  */
 
+
+/* lwIP includes. */
+#include "lwip/debug.h"
+#include "lwip/def.h"
+#include "lwip/sys.h"
+#include "lwip/mem.h"
+#include "lwip/stats.h"
+
+#if !NO_SYS
+
+#include "sys_arch.h"
 #include <stdint.h>
 #include <arch/cc.h>
 #include <rtems/rtems/clock.h>
 #include <rtems/rtems/sem.h>
 #include <rtems.h>
-#include "sys_arch.h"
-#include "lwip/err.h"
-#include "lwip/tcpip.h"
-#include "lwipopts.h"
 
 #define SYS_LWIP_MBOX_SIZE (sizeof(void *))
 
@@ -268,8 +275,21 @@ sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stack_s
   rtems_id id;
   rtems_status_code res;
 
+  rtems_name lwip_task_name = 0;
+  if(name == NULL) {
+    lwip_task_name = rtems_build_name('L', 'W', 'I', 'P');
+  }
+  else {
+    if(name[0] == '\0') {
+      lwip_task_name = rtems_build_name('L', 'W', 'I', 'P');
+    }
+    else {
+      lwip_task_name = rtems_build_name(name[0], name[1], name[2], name[3]);
+    }
+  }
+
   res = rtems_task_create(
-    rtems_build_name('L', 'W', 'I', 'P'),
+    lwip_task_name,
     prio,
     stack_size,
     RTEMS_PREEMPT,
@@ -376,3 +396,5 @@ sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg)
   return sys_mbox_trypost(q, msg);
 }
 
+#endif /* NO_SYS == 0 */
+
diff --git a/lwip/ports/os/rtems/arch/sys_arch.h b/lwip/ports/os/rtems/arch/sys_arch.h
index c89abd4..f4a73a7 100644
--- a/lwip/ports/os/rtems/arch/sys_arch.h
+++ b/lwip/ports/os/rtems/arch/sys_arch.h
@@ -39,17 +39,23 @@
 #ifndef __ARCH_SYS_ARCH_H__
 #define __ARCH_SYS_ARCH_H__
 
+#include "lwip/opt.h"
+
+#if (NO_SYS != 0)
+#error "RTEMS SYS_ARCH cannot be compiled in NO_SYS variant"
+#endif
+
 #include <rtems/rtems/sem.h>
 #include <rtems/rtems/intr.h>
 #include <rtems/score/cpu.h>
 #include <bsp/irq-generic.h>
-//#include "eth_lwip_default.h"
 
-/* Typedefs for the various port-specific types. */
-#if defined(NO_SYS) && NO_SYS
-  #error "RTEMS SYS_ARCH cannot be compiled in NO_SYS variant"
+#ifdef __cplusplus
+extern "C" {
 #endif
 
+/* Typedefs for the various port-specific types. */
+
 #define sys_arch_printk printk
 
 typedef struct {
@@ -105,4 +111,8 @@ sys_prot_t sys_arch_protect();
 
 void sys_arch_unprotect(sys_prot_t pval);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* __ARCH_SYS_ARCH_H__ */
diff --git a/lwip/src/include/lwip/sys.h b/lwip/src/include/lwip/sys.h
index 1933590..168e465 100644
--- a/lwip/src/include/lwip/sys.h
+++ b/lwip/src/include/lwip/sys.h
@@ -38,7 +38,6 @@
 #define LWIP_HDR_SYS_H
 
 #include "lwip/opt.h"
-#include "arch/sys_arch.h"
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/lwip/ports/os/lwipopts.h b/lwip/test/lwipopts.h
similarity index 100%
rename from lwip/ports/os/lwipopts.h
rename to lwip/test/lwipopts.h
diff --git a/waf b/waf
old mode 100755
new mode 100644
-- 
2.27.0



More information about the devel mailing list