[PATCH] STM32 lwIP addition and CMake support

Vijay Kumar Banerjee vijay at rtems.org
Sat Apr 24 16:31:27 UTC 2021


Hi Robin,

These patches look great!
Since these patches are for the lwip repository which is still not
under rtems top directory, I'll merge these soon and will get the waf
system compatible with these changes, so that a user can use both the
build systems. I had a quick look and just had one question below ...

On Sat, Apr 24, 2021 at 6:08 AM Robin Müller <robin.mueller.m at gmail.com> wrote:
>
> Some additional information about how to add new ports:
>
> I tried to make the rtems_lwip_init function as generic as possible and usable for all major APIs. The eth_lwip_init_fnc defined as extern in the rtems_lwip.c file is the adaption point for other BSPs.
> This function contains hardware specific initialization code and is set in a port source file.
>
> Kind Regards
> Robin Müller
>
> On Sat, 24 Apr 2021 at 13:42, Robin Mueller <robin.mueller.m at gmail.com> wrote:
>>
>> This patch adds CMake support to RTEMS lwIP.
>> 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.
>>
>> More information can also be found in the README, which also specifies
>> how to build with CMake. The waf build system still needs to be adapted
>> to perform the same function.
>> ---
>>  .gitignore                                    |  10 +
>>  .gitmodules                                   |   1 +
>>  CMakeLists.txt                                |  76 ++
>>  README.md                                     |  32 +
>>  cmake/PortSelect.cmake                        |  12 +
>>  lwip-to-rtems.py                              |   0
>>  lwip/CMakeLists.txt                           |   2 +
>>  lwip/ports/CMakeLists.txt                     |   2 +
>>  lwip/ports/drivers/CMakeLists.txt             |  20 +
>>  .../drivers/{eth_lwip.c => rtems_lwip.c}      | 212 +++--
>>  .../drivers/{eth_lwip.h => rtems_lwip.h}      |  79 +-
>>  .../{eth_lwip_default.h => rtems_lwip_conf.h} |  30 +-
>>  lwip/ports/drivers/stm32h7/CMakeLists.txt     |  14 +
>>  lwip/ports/drivers/stm32h7/app_dhcp.c         | 217 +++++
>>  lwip/ports/drivers/stm32h7/app_ethernet.c     | 187 +++++
>>  lwip/ports/drivers/stm32h7/ethernetif.c       | 758 ++++++++++++++++++
>>  .../drivers/stm32h7/include/CMakeLists.txt    |   7 +
>>  .../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 +++++++
>>  lwip/ports/drivers/tms570/CMakeLists.txt      |   4 +
>>  .../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/CMakeLists.txt                  |   1 +
>>  lwip/ports/os/rtems/CMakeLists.txt            |   9 +
>>  lwip/ports/os/rtems/arch/CMakeLists.txt       |   4 +
>>  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/CMakeLists.txt                       |   4 +
>>  lwip/src/api/CMakeLists.txt                   |  11 +
>>  lwip/src/core/CMakeLists.txt                  |  28 +
>>  lwip/src/core/ipv4/CMakeLists.txt             |  10 +
>>  lwip/src/core/ipv6/CMakeLists.txt             |  11 +
>>  lwip/src/include/CMakeLists.txt               |   7 +
>>  lwip/src/include/lwip/sys.h                   |   1 -
>>  lwip/src/netif/CMakeLists.txt                 |  10 +
>>  lwip/{ports/os => test}/lwipopts.h            |   0
>>  waf                                           |   0
>>  48 files changed, 3350 insertions(+), 130 deletions(-)
>>  create mode 100644 CMakeLists.txt
>>  create mode 100644 README.md
>>  create mode 100644 cmake/PortSelect.cmake
>>  mode change 100755 => 100644 lwip-to-rtems.py
>>  create mode 100644 lwip/CMakeLists.txt
>>  create mode 100644 lwip/ports/CMakeLists.txt
>>  create mode 100644 lwip/ports/drivers/CMakeLists.txt
>>  rename lwip/ports/drivers/{eth_lwip.c => rtems_lwip.c} (51%)
>>  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/CMakeLists.txt
>>  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/CMakeLists.txt
>>  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
>>  create mode 100644 lwip/ports/drivers/tms570/CMakeLists.txt
>>  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%)
>>  create mode 100644 lwip/ports/os/CMakeLists.txt
>>  create mode 100644 lwip/ports/os/rtems/CMakeLists.txt
>>  create mode 100644 lwip/ports/os/rtems/arch/CMakeLists.txt
>>  create mode 100644 lwip/src/CMakeLists.txt
>>  create mode 100644 lwip/src/api/CMakeLists.txt
>>  create mode 100644 lwip/src/core/CMakeLists.txt
>>  create mode 100644 lwip/src/core/ipv4/CMakeLists.txt
>>  create mode 100644 lwip/src/core/ipv6/CMakeLists.txt
>>  create mode 100644 lwip/src/include/CMakeLists.txt
>>  create mode 100644 lwip/src/netif/CMakeLists.txt
>>  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/CMakeLists.txt b/CMakeLists.txt
>> new file mode 100644
>> index 0000000..e1ef8f0
>> --- /dev/null
>> +++ b/CMakeLists.txt
>> @@ -0,0 +1,76 @@
>> +#################################################################################
>> +# CMake support for RTEMS lwIP
>> +#
>> +# Author: R.Mueller
>> +#################################################################################
>> +cmake_minimum_required(VERSION 3.13)
>> +
>> +#################################################################################
>> +# lwIP options
>> +#################################################################################
>> +
>> +option(LWIP_GENERATE_SECTIONS "Generate function and data sections" ON)
>> +if(LWIP_GENERATE_SECTIONS)
>> +    option(LWIP_REMOVE_UNUSED_CODE "Remove unused sections" ON)
>> +endif()
>> +
>> +option(LWIP_ADD_IPV6 "Compile IPv6 sourcces" ON)
>> +
>> +#################################################################################
>> +# Port select
>> +#################################################################################
>> +
>> +if(NOT RTEMS_BSP)
>> +    message(
>> +        FATAL_ERROR "RTEMS BSP variable not set. "
>> +        "Please make sure to pass it with -DRTEMS_BSP=<arch/bsp>"
>> +   )
>> +endif()
>> +
>> +set(LWIP_CMAKE_CONFIG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
>> +include("${LWIP_CMAKE_CONFIG_DIR}/PortSelect.cmake")
>> +
>> +rtems_lwip_port_select(${RTEMS_BSP})
>> +
>> +set(LWIP_LIB_NAME lwip)
>> +add_library(${LWIP_LIB_NAME})
>> +
>> +add_subdirectory(lwip)
>> +
>> +# The user needs to supply the lwipopts.h file. The user can do this by supplying the
>> +# path of this file in the LWIP_CONFIG_PATH variable
>> +if(NOT LWIP_CONFIG_PATH)
>> +       message(WARNING "lwIP configuration include path LWIP_CONFIG_PATH not set!")
>> +endif()
>> +
>> +if(IS_ABSOLUTE ${LWIP_CONFIG_PATH})
>> +       set(LWIP_CONFIG_PATH_ABS "${LWIP_CONFIG_PATH}")
>> +else()
>> +       get_filename_component(LWIP_CONFIG_PATH_ABS
>> +               ${LWIP_CONFIG_PATH} REALPATH BASE_DIR ${CMAKE_SOURCE_DIR}
>> +       )
>> +endif()
>> +
>> +if(CMAKE_VERBOSE)
>> +       message(STATUS "lwIP configuration path: ${LWIP_CONFIG_PATH}")
>> +endif()
>> +
>> +target_include_directories(${LWIP_LIB_NAME} PRIVATE
>> +       ${LWIP_CONFIG_PATH_ABS}
>> +)
>> +
>> +# Remove unused sections
>> +if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
>> +    if(LWIP_GENERATE_SECTIONS)
>> +        target_compile_options(${LWIP_LIB_NAME} PRIVATE
>> +            "-ffunction-sections"
>> +            "-fdata-sections"
>> +        )
>> +    endif()
>> +
>> +    if(LWIP_REMOVE_UNUSED_CODE)
>> +        target_link_options(${LWIP_LIB_NAME} PRIVATE
>> +            "Wl,--gc-sections"
>> +        )
>> +    endif()
>> +endif()
>> diff --git a/README.md b/README.md
>> new file mode 100644
>> index 0000000..e4b0060
>> --- /dev/null
>> +++ b/README.md
>> @@ -0,0 +1,32 @@
>> +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
>> +
>> +It is recommended to add this repository as a submodule. After that, you can use
>> +`add_subdirectory` to add the repository and then link against the `lwip` target.
>> +
>> +Following steps have to be taken by the application `CMakeLists.txt` for this to work:
>> +
>> + 1. The CMake variable `RTEMS_BSP` has to be set to the used BSP
>> + 2. The CMake variable `LWIP_CONFIG_PATH` needs to be set to the path including the `lwipopts.h`
>> +    configuration file which is provided by the user.
>> +
>> +# Compiling with waf
>> +
>> diff --git a/cmake/PortSelect.cmake b/cmake/PortSelect.cmake
>> new file mode 100644
>> index 0000000..3f440f8
>> --- /dev/null
>> +++ b/cmake/PortSelect.cmake
>> @@ -0,0 +1,12 @@
>> +function(rtems_lwip_port_select RTEMS_BSP)
>> +    if(RTEMS_BSP MATCHES "arm/nucleo-h743zi" OR RTEMS_BSP MATCHES "arm/stm32h7")
>> +        set(RTEMS_LWIP_ADD_STM32H7_DRV ON CACHE INTERNAL "Add STM32H7 lwIP drivers")
>> +        if(RTEMS_BSP MATCHES "arm/nucleo-h743zi")
>> +            set(RTEMS_LWIP_NUCLEO_H743ZI_VARIANT ON CACHE INTERNAL "Nucleo-H743ZI board variant")
>> +        endif()
>> +    endif()
>> +
>> +    if(RTEMS_BSP MATCHES "arm/tms570")
>> +        set(RTEMS_LWIP_ADD_TMS_570_DRV ON CACHE INTERNAL "Add TMS570 lwIP drivers")
>> +    endif()
>> +endfunction()
>> diff --git a/lwip-to-rtems.py b/lwip-to-rtems.py
>> old mode 100755
>> new mode 100644
>> diff --git a/lwip/CMakeLists.txt b/lwip/CMakeLists.txt
>> new file mode 100644
>> index 0000000..69cffec
>> --- /dev/null
>> +++ b/lwip/CMakeLists.txt
>> @@ -0,0 +1,2 @@
>> +add_subdirectory(ports)
>> +add_subdirectory(src)
>> diff --git a/lwip/ports/CMakeLists.txt b/lwip/ports/CMakeLists.txt
>> new file mode 100644
>> index 0000000..ecb2e95
>> --- /dev/null
>> +++ b/lwip/ports/CMakeLists.txt
>> @@ -0,0 +1,2 @@
>> +add_subdirectory(os)
>> +add_subdirectory(drivers)
>> diff --git a/lwip/ports/drivers/CMakeLists.txt b/lwip/ports/drivers/CMakeLists.txt
>> new file mode 100644
>> index 0000000..d060385
>> --- /dev/null
>> +++ b/lwip/ports/drivers/CMakeLists.txt
>> @@ -0,0 +1,20 @@
>> +target_sources(${LIB_LWIP_NAME} PRIVATE
>> +    rtems_lwip.c
>> +)
>> +
>> +if(RTEMS_LWIP_ADD_TMS_570_DRV)
>> +    add_subdirectory(tms570)
>> +endif()
>> +
>> +if(RTEMS_LWIP_ADD_STM32H7_DRV)
>> +    option(RTEMS_LWIP_NUCLEO_H743ZI_VARIANT OFF "Can be set for Nucleo H743 ZI board variant")
>> +    add_subdirectory(stm32h7)
>> +endif()
>> +
>> +target_include_directories(${LIB_LWIP_NAME} PRIVATE
>> +    ${CMAKE_CURRENT_SOURCE_DIR}
>> +)
>> +
>> +target_include_directories(${LIB_LWIP_NAME} INTERFACE
>> +    ${CMAKE_CURRENT_SOURCE_DIR}
>> +)
>> diff --git a/lwip/ports/drivers/eth_lwip.c b/lwip/ports/drivers/rtems_lwip.c
>> similarity index 51%
>> rename from lwip/ports/drivers/eth_lwip.c
>> rename to lwip/ports/drivers/rtems_lwip.c
>> index b1ae4bb..a106616 100644
>> --- a/lwip/ports/drivers/eth_lwip.c
>> +++ b/lwip/ports/drivers/rtems_lwip.c
>> @@ -31,53 +31,48 @@
>>   * 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*/
>> +struct netif eth_lwip_netifs[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");
>> -  }
>> -}
>> +//static void rtems_lwip_conv_ip_decimal_str(ip_addr_t ip, char *ipStr);
>>
>>  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 +84,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 +162,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 +180,91 @@ 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_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 */
>> +}
>> +
>> +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/CMakeLists.txt b/lwip/ports/drivers/stm32h7/CMakeLists.txt
>> new file mode 100644
>> index 0000000..b977008
>> --- /dev/null
>> +++ b/lwip/ports/drivers/stm32h7/CMakeLists.txt
>> @@ -0,0 +1,14 @@
>> +target_sources(${LIB_LWIP_NAME} PRIVATE
>> +    lan8742.c
>> +    app_dhcp.c
>> +    app_ethernet.c
>> +    ethernetif.c
>> +)
>> +
>> +if(RTEMS_LWIP_NUCLEO_H743ZI_VARIANT)
>> +    target_compile_definitions(${LIB_LWIP_NAME} PRIVATE
>> +        NUCLEO_H743ZI=1
>> +    )
>> +endif()
>> +
>> +add_subdirectory(include)
>> \ No newline at end of file
>> 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
>> +  *

Is this license compatible with RTEMS ?


>> +  ******************************************************************************
>> +  */
>> +/* 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/CMakeLists.txt b/lwip/ports/drivers/stm32h7/include/CMakeLists.txt
>> new file mode 100644
>> index 0000000..9601437
>> --- /dev/null
>> +++ b/lwip/ports/drivers/stm32h7/include/CMakeLists.txt
>> @@ -0,0 +1,7 @@
>> +target_include_directories(${LIB_LWIP_NAME} PRIVATE
>> +    lwip_port
>> +)
>> +
>> +target_include_directories(${LIB_LWIP_NAME} INTERFACE
>> +    ${CMAKE_CURRENT_SOURCE_DIR}
>> +)
>> 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/tms570/CMakeLists.txt b/lwip/ports/drivers/tms570/CMakeLists.txt
>> new file mode 100644
>> index 0000000..bf237b5
>> --- /dev/null
>> +++ b/lwip/ports/drivers/tms570/CMakeLists.txt
>> @@ -0,0 +1,4 @@
>> +target_sources(${LIB_LWIP_NAME} PRIVATE
>> +    tms570_netif.c
>> +    phy_dp83848h.c
>> +)
>> 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..019b69a 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/lwip/ports/drivers/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/CMakeLists.txt b/lwip/ports/os/CMakeLists.txt
>> new file mode 100644
>> index 0000000..8fb3d8e
>> --- /dev/null
>> +++ b/lwip/ports/os/CMakeLists.txt
>> @@ -0,0 +1 @@
>> +add_subdirectory(rtems)
>> diff --git a/lwip/ports/os/rtems/CMakeLists.txt b/lwip/ports/os/rtems/CMakeLists.txt
>> new file mode 100644
>> index 0000000..0a3e451
>> --- /dev/null
>> +++ b/lwip/ports/os/rtems/CMakeLists.txt
>> @@ -0,0 +1,9 @@
>> +add_subdirectory(arch)
>> +
>> +target_include_directories(${LIB_LWIP_NAME} PRIVATE
>> +    ${CMAKE_CURRENT_SOURCE_DIR}
>> +)
>> +
>> +target_include_directories(${LIB_LWIP_NAME} INTERFACE
>> +    ${CMAKE_CURRENT_SOURCE_DIR}
>> +)
>> diff --git a/lwip/ports/os/rtems/arch/CMakeLists.txt b/lwip/ports/os/rtems/arch/CMakeLists.txt
>> new file mode 100644
>> index 0000000..8d30c51
>> --- /dev/null
>> +++ b/lwip/ports/os/rtems/arch/CMakeLists.txt
>> @@ -0,0 +1,4 @@
>> +target_sources(${LIB_LWIP_NAME} PRIVATE
>> +    sys_arch.c
>> +)
>> +
>> 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/CMakeLists.txt b/lwip/src/CMakeLists.txt
>> new file mode 100644
>> index 0000000..32c2a14
>> --- /dev/null
>> +++ b/lwip/src/CMakeLists.txt
>> @@ -0,0 +1,4 @@
>> +add_subdirectory(api)
>> +add_subdirectory(core)
>> +add_subdirectory(netif)
>> +add_subdirectory(include)
>> diff --git a/lwip/src/api/CMakeLists.txt b/lwip/src/api/CMakeLists.txt
>> new file mode 100644
>> index 0000000..9b2e34c
>> --- /dev/null
>> +++ b/lwip/src/api/CMakeLists.txt
>> @@ -0,0 +1,11 @@
>> +target_sources(${LWIP_LIB_NAME} PRIVATE
>> +       api_lib.c
>> +       api_msg.c
>> +       err.c
>> +       if_api.c
>> +       netbuf.c
>> +       netdb.c
>> +       netifapi.c
>> +       sockets.c
>> +       tcpip.c
>> +)
>> diff --git a/lwip/src/core/CMakeLists.txt b/lwip/src/core/CMakeLists.txt
>> new file mode 100644
>> index 0000000..4e879ea
>> --- /dev/null
>> +++ b/lwip/src/core/CMakeLists.txt
>> @@ -0,0 +1,28 @@
>> +target_sources(${LWIP_LIB_NAME} PRIVATE
>> +       altcp_alloc.c
>> +       altcp_tcp.c
>> +       altcp.c
>> +       def.c
>> +       dns.c
>> +       inet_chksum.c
>> +       init.c
>> +       ip.c
>> +       mem.c
>> +       memp.c
>> +       netif.c
>> +       pbuf.c
>> +       raw.c
>> +       stats.c
>> +       sys.c
>> +       tcp_in.c
>> +       tcp_out.c
>> +       tcp.c
>> +       timeouts.c
>> +       udp.c
>> +)
>> +
>> +add_subdirectory(ipv4)
>> +
>> +if(LWIP_ADD_IPV6)
>> +    add_subdirectory(ipv6)
>> +endif()
>> diff --git a/lwip/src/core/ipv4/CMakeLists.txt b/lwip/src/core/ipv4/CMakeLists.txt
>> new file mode 100644
>> index 0000000..e0f9e58
>> --- /dev/null
>> +++ b/lwip/src/core/ipv4/CMakeLists.txt
>> @@ -0,0 +1,10 @@
>> +target_sources(${LWIP_LIB_NAME} PRIVATE
>> +       autoip.c
>> +       dhcp.c
>> +       etharp.c
>> +       icmp.c
>> +       igmp.c
>> +       ip4_addr.c
>> +       ip4_frag.c
>> +       ip4.c
>> +)
>> diff --git a/lwip/src/core/ipv6/CMakeLists.txt b/lwip/src/core/ipv6/CMakeLists.txt
>> new file mode 100644
>> index 0000000..fce0b11
>> --- /dev/null
>> +++ b/lwip/src/core/ipv6/CMakeLists.txt
>> @@ -0,0 +1,11 @@
>> +target_sources(${LWIP_LIB_NAME} PRIVATE
>> +       ethip6.c
>> +       dhcp6.c
>> +       icmp6.c
>> +       inet6.c
>> +       ip6_addr.c
>> +       ip6_frag.c
>> +       ip6.c
>> +       mld6.c
>> +       nd6.c
>> +)
>> diff --git a/lwip/src/include/CMakeLists.txt b/lwip/src/include/CMakeLists.txt
>> new file mode 100644
>> index 0000000..a009324
>> --- /dev/null
>> +++ b/lwip/src/include/CMakeLists.txt
>> @@ -0,0 +1,7 @@
>> +target_include_directories(${LIB_LWIP_NAME} PRIVATE
>> +    ${CMAKE_CURRENT_SOURCE_DIR}
>> +)
>> +
>> +target_include_directories(${LIB_LWIP_NAME} INTERFACE
>> +    ${CMAKE_CURRENT_SOURCE_DIR}
>> +)
>> 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/src/netif/CMakeLists.txt b/lwip/src/netif/CMakeLists.txt
>> new file mode 100644
>> index 0000000..7c233ae
>> --- /dev/null
>> +++ b/lwip/src/netif/CMakeLists.txt
>> @@ -0,0 +1,10 @@
>> +target_sources(${LWIP_LIB_NAME} PRIVATE
>> +       bridgeif_fdb.c
>> +       bridgeif.c
>> +       ethernet.c
>> +       lowpan6_ble.c
>> +       lowpan6_common.c
>> +       lowpan6.c
>> +       slipif.c
>> +       zepif.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.25.1
>>


More information about the devel mailing list