forked from xuos/xiuos
				
			add ethernet for imxrt1176-sbc board and keep compatible with other boards
This commit is contained in:
		
							parent
							
								
									85ed3a2c10
								
							
						
					
					
						commit
						088bf02fbd
					
				|  | @ -15,6 +15,8 @@ | ||||||
| // #include <user_api.h>
 | // #include <user_api.h>
 | ||||||
| #include <transform.h> | #include <transform.h> | ||||||
| 
 | 
 | ||||||
|  | extern void ShowTask(); | ||||||
|  | 
 | ||||||
| extern int FrameworkInit(); | extern int FrameworkInit(); | ||||||
| extern void ApplicationOtaTaskInit(void); | extern void ApplicationOtaTaskInit(void); | ||||||
| int main(void) | int main(void) | ||||||
|  | @ -24,6 +26,10 @@ int main(void) | ||||||
| #ifdef APPLICATION_OTA | #ifdef APPLICATION_OTA | ||||||
| 	ApplicationOtaTaskInit(); | 	ApplicationOtaTaskInit(); | ||||||
| #endif | #endif | ||||||
|  | 	while(1){ | ||||||
|  | 		// ShowTask();
 | ||||||
|  | 		PrivTaskDelay(2000); | ||||||
|  | 	} | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| // int cppmain(void);
 | // int cppmain(void);
 | ||||||
|  |  | ||||||
|  | @ -139,6 +139,8 @@ This function initializes the Ethernet driver. | ||||||
| //------------------------------------------------------------------------------
 | //------------------------------------------------------------------------------
 | ||||||
| tOplkError edrv_init(const tEdrvInitParam* pEdrvInitParam_p) | tOplkError edrv_init(const tEdrvInitParam* pEdrvInitParam_p) | ||||||
| { | { | ||||||
|  |     uint8_t enet_port = 0; ///< use enet port 0
 | ||||||
|  | 
 | ||||||
|     // Check parameter validity
 |     // Check parameter validity
 | ||||||
|     ASSERT(pEdrvInitParam_p != NULL); |     ASSERT(pEdrvInitParam_p != NULL); | ||||||
| 
 | 
 | ||||||
|  | @ -153,7 +155,7 @@ tOplkError edrv_init(const tEdrvInitParam* pEdrvInitParam_p) | ||||||
| 
 | 
 | ||||||
|     edrvInstance_l.fStartCommunication = TRUE; |     edrvInstance_l.fStartCommunication = TRUE; | ||||||
| 
 | 
 | ||||||
|     lwip_config_net(lwip_ipaddr, lwip_netmask, lwip_gwaddr); |     lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr); | ||||||
|     gnetif.input = ethernetInput; |     gnetif.input = ethernetInput; | ||||||
|     edrvInstance_l.pNetif = &gnetif; |     edrvInstance_l.pNetif = &gnetif; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -347,6 +347,7 @@ void PlcSocketTask(int argc, char *argv[]) | ||||||
| { | { | ||||||
|     int result = 0; |     int result = 0; | ||||||
|     pthread_t th_id; |     pthread_t th_id; | ||||||
|  |     uint8_t enet_port = 0; ///< test enet port 0
 | ||||||
| 
 | 
 | ||||||
|     pthread_attr_t attr; |     pthread_attr_t attr; | ||||||
|     attr.schedparam.sched_priority = LWIP_DEMO_TASK_PRIO; |     attr.schedparam.sched_priority = LWIP_DEMO_TASK_PRIO; | ||||||
|  | @ -355,7 +356,7 @@ void PlcSocketTask(int argc, char *argv[]) | ||||||
| 
 | 
 | ||||||
|     PlcCheckParam(argc, argv); |     PlcCheckParam(argc, argv); | ||||||
| 
 | 
 | ||||||
|     lwip_config_net(lwip_ipaddr, lwip_netmask, param->ip); |     lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, param->ip); | ||||||
|     PrivTaskCreate(&th_id, &attr, PlcSocketStart, param); |     PrivTaskCreate(&th_id, &attr, PlcSocketStart, param); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -35,6 +35,10 @@ Modification: | ||||||
| #include <connect_uart.h> | #include <connect_uart.h> | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #ifdef BSP_USING_LWIP | ||||||
|  | extern int ETH_BSP_Config(); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #if __CORTEX_M == 7 | #if __CORTEX_M == 7 | ||||||
| void BOARD_ConfigMPU(void) | void BOARD_ConfigMPU(void) | ||||||
| { | { | ||||||
|  | @ -368,6 +372,79 @@ void BOARD_ConfigMPU(void) | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | void BOARD_InitModuleClock(void) | ||||||
|  | { | ||||||
|  |     const clock_sys_pll1_config_t sysPll1Config = { | ||||||
|  |         .pllDiv2En = true, | ||||||
|  |     }; | ||||||
|  |     CLOCK_InitSysPll1(&sysPll1Config); | ||||||
|  | 
 | ||||||
|  |     clock_root_config_t rootCfg = {.mux = 4, .div = 10}; | ||||||
|  | 
 | ||||||
|  | #ifdef BOARD_NETWORK_USE_100M_ENET_PORT | ||||||
|  |      /* Generate 50M root clock. */ | ||||||
|  |     CLOCK_SetRootClock(kCLOCK_Root_Enet1, &rootCfg); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef BOARD_NETWORK_USE_1G_ENET_PORT | ||||||
|  |     /* Generate 125M root clock. */ | ||||||
|  |     rootCfg.mux = 4; | ||||||
|  |     rootCfg.div = 4; | ||||||
|  |     CLOCK_SetRootClock(kCLOCK_Root_Enet2, &rootCfg); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     /* Select syspll2pfd3, 528*18/24 = 396M */ | ||||||
|  |     CLOCK_InitPfd(kCLOCK_PllSys2, kCLOCK_Pfd3, 24); | ||||||
|  |     rootCfg.mux = 7; | ||||||
|  |     rootCfg.div = 2; | ||||||
|  |     CLOCK_SetRootClock(kCLOCK_Root_Bus, &rootCfg); /* Generate 198M bus clock. */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void IOMUXC_SelectENETClock(void) | ||||||
|  | { | ||||||
|  | #ifdef BOARD_NETWORK_USE_100M_ENET_PORT | ||||||
|  |     IOMUXC_GPR->GPR4 |= 0x3; /* 50M ENET_REF_CLOCK output to PHY and ENET module. */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef BOARD_NETWORK_USE_1G_ENET_PORT | ||||||
|  |     IOMUXC_GPR->GPR5 |= IOMUXC_GPR_GPR5_ENET1G_RGMII_EN_MASK; /* bit1:iomuxc_gpr_enet_clk_dir
 | ||||||
|  |                                                                  bit0:GPR_ENET_TX_CLK_SEL(internal or OSC) */ | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | /*!
 | ||||||
|  |  * @brief Utility function for comparing arrays | ||||||
|  |  */ | ||||||
|  | static uint8_t compareArrays(uint8_t a[], uint8_t b[], int len) | ||||||
|  | { | ||||||
|  | 	for (int i=0; i<len; i++) | ||||||
|  | 	{ | ||||||
|  | 		if (a[i] != b[i]) | ||||||
|  | 		{ | ||||||
|  | 			return 0; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief configure miiMode, miiSpeed based on the MAC address | ||||||
|  |  */ | ||||||
|  | void BOARD_ENETFlexibleConfigure(enet_config_t *config, uint8_t *hwAddr) | ||||||
|  | { | ||||||
|  | 	uint8_t temp_arr[6] = configMAC_ADDR; | ||||||
|  | 
 | ||||||
|  | 	if (compareArrays(hwAddr, temp_arr, 6)) | ||||||
|  | 	{ | ||||||
|  | 		config->miiMode = kENET_RmiiMode; | ||||||
|  | 		config->miiSpeed = kENET_MiiSpeed100M; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		config->miiMode = kENET_RgmiiMode; | ||||||
|  | 		config->miiSpeed = kENET_MiiSpeed1000M; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* This is the timer interrupt service routine. */ | /* This is the timer interrupt service routine. */ | ||||||
| void SysTick_Handler(int irqn, void *arg) | void SysTick_Handler(int irqn, void *arg) | ||||||
| { | { | ||||||
|  | @ -381,6 +458,10 @@ struct InitSequenceDesc _board_init[] = | ||||||
|     // { "hw_pin", Imxrt1052HwGpioInit },
 |     // { "hw_pin", Imxrt1052HwGpioInit },
 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #ifdef BSP_USING_LWIP | ||||||
|  |     {"ETH_BSP", ETH_BSP_Config}, | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| 	{ " NONE ",NONE }, | 	{ " NONE ",NONE }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -395,6 +476,15 @@ void InitBoardHardware() | ||||||
|     BOARD_ConfigMPU(); |     BOARD_ConfigMPU(); | ||||||
|     BOARD_InitPins(); |     BOARD_InitPins(); | ||||||
|     BOARD_BootClockRUN(); |     BOARD_BootClockRUN(); | ||||||
|  |     BOARD_InitModuleClock(); | ||||||
|  |     IOMUXC_SelectENETClock(); | ||||||
|  | 
 | ||||||
|  | #ifdef BOARD_NETWORK_USE_100M_ENET_PORT | ||||||
|  |     BOARD_InitEnetPins(); | ||||||
|  | #endif | ||||||
|  | #ifdef BOARD_NETWORK_USE_1G_ENET_PORT | ||||||
|  |     BOARD_InitEnet1GPins(); | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
|     // NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
 |     // NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
 | ||||||
|     DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; |     DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; | ||||||
|  |  | ||||||
|  | @ -3,11 +3,22 @@ export CROSS_COMPILE ?=/usr/bin/arm-none-eabi- | ||||||
| export CFLAGS := -mcpu=cortex-m7 -mthumb  -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb | export CFLAGS := -mcpu=cortex-m7 -mthumb  -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb | ||||||
| export AFLAGS := -c -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb  -gdwarf-2 | export AFLAGS := -c -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb  -gdwarf-2 | ||||||
| export LFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-imxrt1176-sbc.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds | export LFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-imxrt1176-sbc.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds | ||||||
|  | 
 | ||||||
|  | ifeq ($(CONFIG_LIB_MUSLLIB), y) | ||||||
|  | export LFLAGS += -nostdlib -nostdinc # -fno-builtin -nodefaultlibs | ||||||
|  | export LIBCC := -lgcc | ||||||
|  | export LINK_MUSLLIB := $(KERNEL_ROOT)/lib/musllib/libmusl.a | ||||||
|  | endif | ||||||
|  | 
 | ||||||
|  | ifeq ($(CONFIG_RESOURCES_LWIP), y) | ||||||
|  | export LINK_LWIP := $(KERNEL_ROOT)/resources/ethernet/LwIP/liblwip.a | ||||||
|  | endif | ||||||
|  | 
 | ||||||
| export CXXFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g | export CXXFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g | ||||||
| 
 | 
 | ||||||
| # export APPLFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-app.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds
 | # export APPLFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-app.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds
 | ||||||
| 
 | 
 | ||||||
| export DEFINES := -DHAVE_CCONFIG_H  -DCPU_MIMXRT1052CVL5B -DSKIP_SYSCLK_INIT -DEVK_MCIMXRM -DFSL_SDK_ENABLE_DRIVER_CACHE_CONTROL=1 -DXIP_EXTERNAL_FLASH=1 -D__STARTUP_INITIALIZE_NONCACHEDATA -D__STARTUP_CLEAR_BSS | export DEFINES := -DHAVE_CCONFIG_H  -DCPU_MIMXRT1176DVMAA_cm7 -DSKIP_SYSCLK_INIT -DEVK_MCIMXRM -DFSL_SDK_ENABLE_DRIVER_CACHE_CONTROL=1 -DXIP_EXTERNAL_FLASH=1 -D__STARTUP_INITIALIZE_NONCACHEDATA -D__STARTUP_CLEAR_BSS | ||||||
| 
 | 
 | ||||||
| export ARCH = arm | export ARCH = arm | ||||||
| export MCU = cortex-m7 | export MCU = cortex-m7 | ||||||
|  |  | ||||||
|  | @ -24,21 +24,31 @@ Modification: | ||||||
| #include "fsl_common.h" | #include "fsl_common.h" | ||||||
| #include "fsl_gpio.h" | #include "fsl_gpio.h" | ||||||
| #include "fsl_clock.h" | #include "fsl_clock.h" | ||||||
| // #include "fsl_enet.h"
 | #include "fsl_enet.h" | ||||||
| #include "clock_config.h" | #include "clock_config.h" | ||||||
|  | #include "pin_mux.h" | ||||||
| #include <xizi.h> | #include <xizi.h> | ||||||
| #include <arch_interrupt.h> | #include <arch_interrupt.h> | ||||||
| 
 | 
 | ||||||
|  | #define BOARD_NET_COUNT (2) | ||||||
|  | /* MAC address configuration. */ | ||||||
|  | #define configMAC_ADDR {0x02, 0x12, 0x13, 0x10, 0x15, 0x11} | ||||||
|  | #define configMAC_ADDR_ETH1 {0x02, 0x12, 0x13, 0x10, 0x15, 0x12} | ||||||
|  | 
 | ||||||
|  | /*! @brief The ENET0 PHY address. */ | ||||||
|  | #define BOARD_ENET0_PHY_ADDRESS (0x02U) /* Phy address of enet port 0. */ | ||||||
|  | 
 | ||||||
|  | /*! @brief The ENET1 PHY address. */ | ||||||
|  | #define BOARD_ENET1_PHY_ADDRESS (0x07U) /* Phy address of enet port 1. */ | ||||||
|  | 
 | ||||||
|  | #define BOARD_FLASH_SIZE    (0x1000000U) | ||||||
|  | 
 | ||||||
| extern int heap_start; | extern int heap_start; | ||||||
| extern int heap_end; | extern int heap_end; | ||||||
| #define HEAP_BEGIN          (&heap_start) | #define HEAP_BEGIN          (&heap_start) | ||||||
| #define HEAP_END            (&heap_end) | #define HEAP_END            (&heap_end) | ||||||
| 
 |  | ||||||
| #define BOARD_FLASH_SIZE    (0x1000000U) |  | ||||||
| 
 |  | ||||||
| #define HEAP_SIZE           ((uint32_t)HEAP_END - (uint32_t)HEAP_BEGIN) | #define HEAP_SIZE           ((uint32_t)HEAP_END - (uint32_t)HEAP_BEGIN) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| void InitBoardHardware(void); | void InitBoardHardware(void); | ||||||
| 
 | 
 | ||||||
| /*******************************************************************************
 | /*******************************************************************************
 | ||||||
|  | @ -57,9 +67,6 @@ void InitBoardHardware(void); | ||||||
|                                                       1 bits for subpriority */ |                                                       1 bits for subpriority */ | ||||||
| #define NVIC_PRIORITYGROUP_4         0x00000003U /*!< 4 bits for pre-emption priority*/ | #define NVIC_PRIORITYGROUP_4         0x00000003U /*!< 4 bits for pre-emption priority*/ | ||||||
| 
 | 
 | ||||||
| /*! @brief The ENET PHY address. */ |  | ||||||
| #define BOARD_ENET0_PHY_ADDRESS (0x0U) /* Phy address of enet port 0. */ |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #if defined(__cplusplus) | #if defined(__cplusplus) | ||||||
|  |  | ||||||
|  | @ -69,6 +69,17 @@ void BOARD_InitBootPins(void); | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| void BOARD_InitPins(void); | void BOARD_InitPins(void); | ||||||
|  | /*!
 | ||||||
|  |  * @brief Configures pin routing and optionally pin electrical features. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | void BOARD_InitEnetPins(void);                /* Function assigned for the Cortex-M7F */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Configures pin routing and optionally pin electrical features. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | void BOARD_InitEnet1GPins(void);              /* Function assigned for the Cortex-M7F */ | ||||||
| 
 | 
 | ||||||
| #if defined(__cplusplus) | #if defined(__cplusplus) | ||||||
| } | } | ||||||
|  | @ -48,16 +48,15 @@ Modification: | ||||||
| /* Entry Point */ | /* Entry Point */ | ||||||
| ENTRY(Reset_Handler) | ENTRY(Reset_Handler) | ||||||
| 
 | 
 | ||||||
| HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x0400; | STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000; | ||||||
| STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000; |  | ||||||
| 
 | 
 | ||||||
| /* Specify the memory areas */ | /* Specify the memory areas- */ | ||||||
| MEMORY | MEMORY | ||||||
| { | { | ||||||
|   /* define flash 32MB */ |   /* define flash 32MB */ | ||||||
|   m_boot_data           (RX)  : ORIGIN = 0x30000000, LENGTH = 0x00001000 |   m_boot_data           (RX)  : ORIGIN = 0x30000000, LENGTH = 0x00001000 | ||||||
|   m_image_vertor_table  (RX)  : ORIGIN = 0x30001000, LENGTH = 0x00001000   |   m_image_vertor_table  (RX)  : ORIGIN = 0x30001000, LENGTH = 0x00001000   | ||||||
|   m_interrupts          (RX)  : ORIGIN = 0x30002000, LENGTH = 0x00000400 |   m_interrupts          (RX)  : ORIGIN = 0x30002000, LENGTH = 0x00001000 | ||||||
|   m_text                (RX)  : ORIGIN = 0x30002400, LENGTH = 0x01FFDC00 |   m_text                (RX)  : ORIGIN = 0x30002400, LENGTH = 0x01FFDC00 | ||||||
| 
 | 
 | ||||||
| /* define itcm 256KB */ | /* define itcm 256KB */ | ||||||
|  | @ -91,12 +90,14 @@ SECTIONS | ||||||
|   { |   { | ||||||
|     KEEP(*(.boot_hdr.conf)) |     KEEP(*(.boot_hdr.conf)) | ||||||
|   } > m_boot_data |   } > m_boot_data | ||||||
| 
 |    | ||||||
|   .image_vertor_table : |   .image_vertor_table : | ||||||
|   { |   { | ||||||
|  |     . = ALIGN(4); | ||||||
|     KEEP(*(.boot_hdr.ivt)) |     KEEP(*(.boot_hdr.ivt)) | ||||||
|     KEEP(*(.boot_hdr.boot_data)) |     KEEP(*(.boot_hdr.boot_data)) | ||||||
|     KEEP(*(.boot_hdr.dcd_data)) |     KEEP(*(.boot_hdr.dcd_data)) | ||||||
|  |     . = ALIGN(4); | ||||||
|   } > m_image_vertor_table |   } > m_image_vertor_table | ||||||
| 
 | 
 | ||||||
|   /* The startup code goes first into internal RAM */ |   /* The startup code goes first into internal RAM */ | ||||||
|  | @ -240,15 +241,15 @@ SECTIONS | ||||||
|     *(NonCacheable.init) |     *(NonCacheable.init) | ||||||
|     . = ALIGN(4); |     . = ALIGN(4); | ||||||
|     __noncachedata_init_end__ = .;   /* create a global symbol at initialized ncache data end */ |     __noncachedata_init_end__ = .;   /* create a global symbol at initialized ncache data end */ | ||||||
|   } > sram_dtcm_cm7 |   } > NCACHE_REGION | ||||||
|   . = __noncachedata_init_end__; |   . = __noncachedata_init_end__; | ||||||
|   .ncache : |   .ncache : | ||||||
|   { |   { | ||||||
|     *(NonCacheable) |     *(NonCacheable) | ||||||
|     . = ALIGN(4); |     . = ALIGN(8192); | ||||||
|     __noncachedata_end__ = .;     /* define a global symbol at ncache data end */ |     __noncachedata_end__ = .;     /* define a global symbol at ncache data end */ | ||||||
|     __NCACHE_REGION_END = .; |     __NCACHE_REGION_END = .; | ||||||
|   } > sram_dtcm_cm7 |   } > NCACHE_REGION | ||||||
| 
 | 
 | ||||||
|   __DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__); |   __DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__); | ||||||
|   text_end = ORIGIN(m_text) + LENGTH(m_text); |   text_end = ORIGIN(m_text) + LENGTH(m_text); | ||||||
|  |  | ||||||
|  | @ -14,3 +14,12 @@ menuconfig BSP_USING_GPIO | ||||||
|     if BSP_USING_GPIO |     if BSP_USING_GPIO | ||||||
|         source "$BSP_DIR/third_party_driver/gpio/Kconfig" |         source "$BSP_DIR/third_party_driver/gpio/Kconfig" | ||||||
|     endif |     endif | ||||||
|  | 
 | ||||||
|  | menuconfig BSP_USING_LWIP | ||||||
|  |     bool "Using LwIP device" | ||||||
|  |     default n | ||||||
|  |     select RESOURCES_LWIP | ||||||
|  | 
 | ||||||
|  |     if BSP_USING_LWIP | ||||||
|  |         source "$BSP_DIR/third_party_driver/ethernet/Kconfig" | ||||||
|  |     endif | ||||||
|  |  | ||||||
|  | @ -1,7 +1,11 @@ | ||||||
| SRC_DIR := common | SRC_DIR := common gpio cm7 | ||||||
| 
 | 
 | ||||||
| ifeq ($(CONFIG_BSP_USING_LPUART),y) | ifeq ($(CONFIG_BSP_USING_LPUART),y) | ||||||
|   SRC_DIR += uart |   SRC_DIR += uart | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
|  | ifeq ($(CONFIG_BSP_USING_LWIP),y) | ||||||
|  |   SRC_DIR += ethernet | ||||||
|  | endif | ||||||
|  | 
 | ||||||
| include $(KERNEL_ROOT)/compiler.mk | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  |  | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | SRC_FILES :=fsl_cache.c | ||||||
|  | 
 | ||||||
|  | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | @ -80,21 +80,172 @@ void BOARD_InitPins(void) { | ||||||
|       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|   IOMUXC_SetPinMux( |   IOMUXC_SetPinMux( | ||||||
|       IOMUXC_GPIO_AD_25_LPUART1_RXD,          /* GPIO_AD_25 is configured as LPUART1_RXD */ |       IOMUXC_GPIO_AD_25_LPUART1_RXD,          /* GPIO_AD_25 is configured as LPUART1_RXD */ | ||||||
|       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ |       1U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|   IOMUXC_SetPinConfig( |   IOMUXC_SetPinConfig( | ||||||
|       IOMUXC_GPIO_AD_24_LPUART1_TXD,          /* GPIO_AD_24 PAD functional properties : */ |       IOMUXC_GPIO_AD_24_LPUART1_TXD,          /* GPIO_AD_24 PAD functional properties : */ | ||||||
|       0x02U);                                 /* Slew Rate Field: Slow Slew Rate
 |       0x00U);                                 /* Slew Rate Field: Slow Slew Rate
 | ||||||
|                                                  Drive Strength Field: high driver |                                                  Drive Strength Field: high driver | ||||||
|                                                  Pull / Keep Select Field: Pull Disable, Highz |                                                  Pull / Keep Select Field: Pull Disable, Highz | ||||||
|                                                  Pull Up / Down Config. Field: Weak pull down |                                                  Pull Up / Down Config. Field: Weak pull down | ||||||
|                                                  Open Drain Field: Disabled */ |                                                  Open Drain Field: Disabled */ | ||||||
|   IOMUXC_SetPinConfig( |   IOMUXC_SetPinConfig( | ||||||
|       IOMUXC_GPIO_AD_25_LPUART1_RXD,          /* GPIO_AD_25 PAD functional properties : */ |       IOMUXC_GPIO_AD_25_LPUART1_RXD,          /* GPIO_AD_25 PAD functional properties : */ | ||||||
|       0x02U);                                 /* Slew Rate Field: Slow Slew Rate
 |       0x00U);                                 /* Slew Rate Field: Slow Slew Rate
 | ||||||
|                                                  Drive Strength Field: high driver |                                                  Drive Strength Field: high driver | ||||||
|                                                  Pull / Keep Select Field: Pull Disable, Highz |                                                  Pull / Keep Select Field: Pull Disable, Highz | ||||||
|                                                  Pull Up / Down Config. Field: Weak pull down |                                                  Pull Up / Down Config. Field: Weak pull down | ||||||
|                                                  Open Drain Field: Disabled */ |                                                  Open Drain Field: Disabled */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_EMC_B2_11_GPIO8_IO21,       /* GPIO_EMC_B2_11 is configured as GPIO8_IO21 */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* | ||||||
|  | BOARD_InitEnetPins: | ||||||
|  | - options: {callFromInitBoot: 'false', coreID: cm7, enableClock: 'true'} | ||||||
|  | - pin_list: | ||||||
|  |   - {pin_num: P17, peripheral: GPIO9, signal: 'gpio_io, 11', pin_signal: GPIO_AD_12} | ||||||
|  |   - {pin_num: U2, peripheral: ENET, signal: enet_mdc, pin_signal: GPIO_EMC_B2_19} | ||||||
|  |   - {pin_num: R3, peripheral: ENET, signal: enet_mdio, pin_signal: GPIO_EMC_B2_20} | ||||||
|  |   - {pin_num: E9, peripheral: ENET, signal: 'enet_tdata, 00', pin_signal: GPIO_DISP_B2_02} | ||||||
|  |   - {pin_num: D7, peripheral: ENET, signal: 'enet_tdata, 01', pin_signal: GPIO_DISP_B2_03} | ||||||
|  |   - {pin_num: C7, peripheral: ENET, signal: enet_tx_en, pin_signal: GPIO_DISP_B2_04} | ||||||
|  |   - {pin_num: C9, peripheral: ENET, signal: enet_ref_clk, pin_signal: GPIO_DISP_B2_05, software_input_on: Enable, slew_rate: Fast} | ||||||
|  |   - {pin_num: C6, peripheral: ENET, signal: 'enet_rdata, 00', pin_signal: GPIO_DISP_B2_06} | ||||||
|  |   - {pin_num: D6, peripheral: ENET, signal: 'enet_rdata, 01', pin_signal: GPIO_DISP_B2_07} | ||||||
|  |   - {pin_num: B5, peripheral: ENET, signal: enet_rx_en, pin_signal: GPIO_DISP_B2_08} | ||||||
|  |   - {pin_num: D8, peripheral: ENET, signal: enet_rx_er, pin_signal: GPIO_DISP_B2_09} | ||||||
|  |  * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /* FUNCTION ************************************************************************************************************
 | ||||||
|  |  * | ||||||
|  |  * Function Name : BOARD_InitEnetPins, assigned for the Cortex-M7F core. | ||||||
|  |  * Description   : Configures pin routing and optionally pin electrical features. | ||||||
|  |  * | ||||||
|  |  * END ****************************************************************************************************************/ | ||||||
|  | void BOARD_InitEnetPins(void) { | ||||||
|  |   CLOCK_EnableClock(kCLOCK_Iomuxc);           /* LPCG on: LPCG is ON. */ | ||||||
|  | 
 | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_AD_12_GPIO9_IO11,           /* GPIO_AD_12 is configured as GPIO9_IO11 */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B2_02_ENET_TX_DATA00,  /* GPIO_DISP_B2_02 is configured as ENET_TX_DATA00 */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B2_03_ENET_TX_DATA01,  /* GPIO_DISP_B2_03 is configured as ENET_TX_DATA01 */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B2_04_ENET_TX_EN,      /* GPIO_DISP_B2_04 is configured as ENET_TX_EN */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B2_05_ENET_REF_CLK,    /* GPIO_DISP_B2_05 is configured as ENET_REF_CLK */ | ||||||
|  |       1U);                                    /* Software Input On Field: Force input path of pad GPIO_DISP_B2_05 */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B2_06_ENET_RX_DATA00,  /* GPIO_DISP_B2_06 is configured as ENET_RX_DATA00 */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B2_07_ENET_RX_DATA01,  /* GPIO_DISP_B2_07 is configured as ENET_RX_DATA01 */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B2_08_ENET_RX_EN,      /* GPIO_DISP_B2_08 is configured as ENET_RX_EN */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B2_09_ENET_RX_ER,      /* GPIO_DISP_B2_09 is configured as ENET_RX_ER */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_EMC_B2_19_ENET_MDC,         /* GPIO_EMC_B2_19 is configured as ENET_MDC */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_EMC_B2_20_ENET_MDIO,        /* GPIO_EMC_B2_20 is configured as ENET_MDIO */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinConfig( | ||||||
|  |       IOMUXC_GPIO_DISP_B2_05_ENET_REF_CLK,    /* GPIO_DISP_B2_05 PAD functional properties : */ | ||||||
|  |       0x03U);                                 /* Slew Rate Field: Fast Slew Rate
 | ||||||
|  |                                                  Drive Strength Field: high drive strength | ||||||
|  |                                                  Pull / Keep Select Field: Pull Disable, Highz | ||||||
|  |                                                  Pull Up / Down Config. Field: Weak pull down | ||||||
|  |                                                  Open Drain Field: Disabled | ||||||
|  |                                                  Domain write protection: Both cores are allowed | ||||||
|  |                                                  Domain write protection lock: Neither of DWP bits is locked */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* | ||||||
|  | BOARD_InitEnet1GPins: | ||||||
|  | - options: {callFromInitBoot: 'false', coreID: cm7, enableClock: 'true'} | ||||||
|  | - pin_list: | ||||||
|  |   - {pin_num: E13, peripheral: ENET_1G, signal: enet_rx_en, pin_signal: GPIO_DISP_B1_00} | ||||||
|  |   - {pin_num: D13, peripheral: ENET_1G, signal: enet_rx_clk, pin_signal: GPIO_DISP_B1_01} | ||||||
|  |   - {pin_num: D11, peripheral: ENET_1G, signal: 'enet_rdata, 00', pin_signal: GPIO_DISP_B1_02} | ||||||
|  |   - {pin_num: E11, peripheral: ENET_1G, signal: 'enet_rdata, 01', pin_signal: GPIO_DISP_B1_03} | ||||||
|  |   - {pin_num: E10, peripheral: ENET_1G, signal: 'enet_rdata, 02', pin_signal: GPIO_DISP_B1_04} | ||||||
|  |   - {pin_num: C11, peripheral: ENET_1G, signal: 'enet_rdata, 03', pin_signal: GPIO_DISP_B1_05} | ||||||
|  |   - {pin_num: D10, peripheral: ENET_1G, signal: 'enet_tdata, 03', pin_signal: GPIO_DISP_B1_06} | ||||||
|  |   - {pin_num: E12, peripheral: ENET_1G, signal: 'enet_tdata, 02', pin_signal: GPIO_DISP_B1_07} | ||||||
|  |   - {pin_num: A15, peripheral: ENET_1G, signal: 'enet_tdata, 01', pin_signal: GPIO_DISP_B1_08} | ||||||
|  |   - {pin_num: C13, peripheral: ENET_1G, signal: 'enet_tdata, 00', pin_signal: GPIO_DISP_B1_09} | ||||||
|  |   - {pin_num: B14, peripheral: ENET_1G, signal: enet_tx_en, pin_signal: GPIO_DISP_B1_10} | ||||||
|  |   - {pin_num: A14, peripheral: ENET_1G, signal: enet_tx_clk_io, pin_signal: GPIO_DISP_B1_11} | ||||||
|  |   - {pin_num: N17, peripheral: ENET_1G, signal: enet_mdc, pin_signal: GPIO_AD_16} | ||||||
|  |   - {pin_num: N15, peripheral: ENET_1G, signal: enet_mdio, pin_signal: GPIO_AD_17} | ||||||
|  |  * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /* FUNCTION ************************************************************************************************************
 | ||||||
|  |  * | ||||||
|  |  * Function Name : BOARD_InitEnet1GPins, assigned for the Cortex-M7F core. | ||||||
|  |  * Description   : Configures pin routing and optionally pin electrical features. | ||||||
|  |  * | ||||||
|  |  * END ****************************************************************************************************************/ | ||||||
|  | void BOARD_InitEnet1GPins(void) { | ||||||
|  |   CLOCK_EnableClock(kCLOCK_Iomuxc);           /* LPCG on: LPCG is ON. */ | ||||||
|  | 
 | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_AD_16_ENET_1G_MDC,          /* GPIO_AD_16 is configured as ENET_1G_MDC */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_AD_17_ENET_1G_MDIO,         /* GPIO_AD_17 is configured as ENET_1G_MDIO */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B1_00_ENET_1G_RX_EN,   /* GPIO_DISP_B1_00 is configured as ENET_1G_RX_EN */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B1_01_ENET_1G_RX_CLK,  /* GPIO_DISP_B1_01 is configured as ENET_1G_RX_CLK */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B1_02_ENET_1G_RX_DATA00,  /* GPIO_DISP_B1_02 is configured as ENET_1G_RX_DATA00 */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B1_03_ENET_1G_RX_DATA01,  /* GPIO_DISP_B1_03 is configured as ENET_1G_RX_DATA01 */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B1_04_ENET_1G_RX_DATA02,  /* GPIO_DISP_B1_04 is configured as ENET_1G_RX_DATA02 */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B1_05_ENET_1G_RX_DATA03,  /* GPIO_DISP_B1_05 is configured as ENET_1G_RX_DATA03 */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B1_06_ENET_1G_TX_DATA03,  /* GPIO_DISP_B1_06 is configured as ENET_1G_TX_DATA03 */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B1_07_ENET_1G_TX_DATA02,  /* GPIO_DISP_B1_07 is configured as ENET_1G_TX_DATA02 */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B1_08_ENET_1G_TX_DATA01,  /* GPIO_DISP_B1_08 is configured as ENET_1G_TX_DATA01 */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B1_09_ENET_1G_TX_DATA00,  /* GPIO_DISP_B1_09 is configured as ENET_1G_TX_DATA00 */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B1_10_ENET_1G_TX_EN,   /* GPIO_DISP_B1_10 is configured as ENET_1G_TX_EN */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
|  |   IOMUXC_SetPinMux( | ||||||
|  |       IOMUXC_GPIO_DISP_B1_11_ENET_1G_TX_CLK_IO,  /* GPIO_DISP_B1_11 is configured as ENET_1G_TX_CLK_IO */ | ||||||
|  |       0U);                                    /* Software Input On Field: Input Path is determined by functionality */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /***********************************************************************************************************************
 | /***********************************************************************************************************************
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,8 @@ | ||||||
|  | config BOARD_NETWORK_USE_100M_ENET_PORT | ||||||
|  |     bool "Enable 100M Enet Port" | ||||||
|  |     default y | ||||||
|  | 
 | ||||||
|  | config BOARD_NETWORK_USE_1G_ENET_PORT | ||||||
|  |     bool "Enable 1000M Enet Port" | ||||||
|  |     default y | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | SRC_FILES := enet_ethernetif.c enet_ethernetif_kinetis.c fsl_enet.c fsl_enet_qos.c | ||||||
|  | SRC_DIR := phy mdio | ||||||
|  | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | @ -0,0 +1,356 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2001-2004 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: Adam Dunkels <adam@sics.se> | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2013-2016, Freescale Semiconductor, Inc. | ||||||
|  |  * Copyright 2016-2020 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "lwip/opt.h" | ||||||
|  | #include "lwip/def.h" | ||||||
|  | #include "lwip/mem.h" | ||||||
|  | #include "lwip/pbuf.h" | ||||||
|  | #include "lwip/stats.h" | ||||||
|  | #include "lwip/snmp.h" | ||||||
|  | #include "lwip/ethip6.h" | ||||||
|  | #include "netif/etharp.h" | ||||||
|  | #include "netif/ppp/pppoe.h" | ||||||
|  | #include "lwip/igmp.h" | ||||||
|  | #include "lwip/mld6.h" | ||||||
|  | 
 | ||||||
|  | #if USE_RTOS && defined(SDK_OS_FREE_RTOS) | ||||||
|  | #include "FreeRTOS.h" | ||||||
|  | #include "event_groups.h" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include "pin_mux.h" | ||||||
|  | #include "enet_ethernetif.h" | ||||||
|  | #include "enet_ethernetif_priv.h" | ||||||
|  | #include "sys_arch.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | static mdio_handle_t mdioHandle = {.ops = &EXAMPLE_MDIO_OPS}; | ||||||
|  | 
 | ||||||
|  | #ifdef BOARD_NETWORK_USE_100M_ENET_PORT | ||||||
|  | static phy_handle_t enet0_phyHandle   = {.phyAddr = EXAMPLE_ENET0_PHY_ADDRESS, .mdioHandle = &mdioHandle, .ops = &EXAMPLE_ENET0_PHY_OPS}; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef BOARD_NETWORK_USE_1G_ENET_PORT | ||||||
|  | static phy_handle_t enet1_phyHandle   = {.phyAddr = EXAMPLE_ENET1_PHY_ADDRESS, .mdioHandle = &mdioHandle, .ops = &EXAMPLE_ENET1_PHY_OPS}; | ||||||
|  | #endif | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Code | ||||||
|  |  ******************************************************************************/ | ||||||
|  | void Time_Update_LwIP(void) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | #ifdef BOARD_NETWORK_USE_100M_ENET_PORT | ||||||
|  | ethernetif_config_t enet0_cfg = { | ||||||
|  |     .phyHandle = &enet0_phyHandle, | ||||||
|  |     .macAddress = configMAC_ADDR, | ||||||
|  | }; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef BOARD_NETWORK_USE_1G_ENET_PORT | ||||||
|  | ethernetif_config_t enet1_cfg = { | ||||||
|  |     .phyHandle = &enet1_phyHandle, | ||||||
|  |     .macAddress = configMAC_ADDR_ETH1, | ||||||
|  | }; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | void *ethernetif_config_enet_set(uint8_t enet_port) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | #ifdef BOARD_NETWORK_USE_100M_ENET_PORT | ||||||
|  |     if(0 == enet_port) { | ||||||
|  |         KPrintf("use 100M enet id[%d]\n",enet_port); | ||||||
|  |         return (void *)&enet0_cfg; | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef BOARD_NETWORK_USE_1G_ENET_PORT | ||||||
|  |     if(1 == enet_port) { | ||||||
|  |         KPrintf("use 1000M enet id[%d]\n",enet_port); | ||||||
|  |         return (void *)&enet1_cfg; | ||||||
|  |     } | ||||||
|  |          | ||||||
|  | #endif | ||||||
|  |         return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int ETH_BSP_Config(void) | ||||||
|  | { | ||||||
|  |     gpio_pin_config_t gpio_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode}; | ||||||
|  | 
 | ||||||
|  | #ifdef BOARD_NETWORK_USE_100M_ENET_PORT | ||||||
|  |      | ||||||
|  |     GPIO_PinInit(GPIO9, 11, &gpio_config); | ||||||
|  |     GPIO_PinInit(GPIO8, 21, &gpio_config); | ||||||
|  |     /* Pull up the ENET_INT before RESET. */ | ||||||
|  |     GPIO_WritePinOutput(GPIO9, 11, 1); | ||||||
|  |     GPIO_WritePinOutput(GPIO8, 21, 0); | ||||||
|  |     SDK_DelayAtLeastUs(10000, CLOCK_GetFreq(kCLOCK_CpuClk)); | ||||||
|  |     GPIO_WritePinOutput(GPIO8, 21, 1); | ||||||
|  |     SDK_DelayAtLeastUs(6, CLOCK_GetFreq(kCLOCK_CpuClk)); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef BOARD_NETWORK_USE_1G_ENET_PORT | ||||||
|  | 
 | ||||||
|  |     EnableIRQ(ENET_1G_MAC0_Tx_Rx_1_IRQn); | ||||||
|  |     EnableIRQ(ENET_1G_MAC0_Tx_Rx_2_IRQn); | ||||||
|  | #endif | ||||||
|  |     mdioHandle.resource.csrClock_Hz = EXAMPLE_CLOCK_FREQ; | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | void ethernetif_phy_init(struct ethernetif *ethernetif, | ||||||
|  |                          const ethernetif_config_t *ethernetifConfig, | ||||||
|  |                          phy_speed_t *speed, | ||||||
|  |                          phy_duplex_t *duplex) | ||||||
|  | { | ||||||
|  |     status_t status; | ||||||
|  |     bool link              = false; | ||||||
|  |     bool autonego          = false; | ||||||
|  |     uint32_t initWaitCount = 0; | ||||||
|  |     uint32_t autoWaitCount = 0; | ||||||
|  |     phy_config_t phyConfig = { | ||||||
|  |         .phyAddr = ethernetifConfig->phyHandle->phyAddr, | ||||||
|  |         .autoNeg = true, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     ethernetifConfig->phyHandle->mdioHandle->resource.base = *ethernetif_enet_ptr(ethernetif); | ||||||
|  | 
 | ||||||
|  |     LWIP_PLATFORM_DIAG(("Initializing PHY...")); | ||||||
|  | 
 | ||||||
|  |     while ((initWaitCount < ENET_ATONEGOTIATION_TIMEOUT) && (!(link && autonego))) | ||||||
|  |     { | ||||||
|  |         status = PHY_Init(ethernetifConfig->phyHandle, &phyConfig); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         if (kStatus_Success != status) | ||||||
|  |         { | ||||||
|  |             LWIP_ASSERT("\r\nCannot initialize PHY.\r\n", 0); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /* Wait for auto-negotiation success and link up */ | ||||||
|  |         autoWaitCount = ENET_ATONEGOTIATION_TIMEOUT; | ||||||
|  |         do | ||||||
|  |         { | ||||||
|  |             PHY_GetAutoNegotiationStatus(ethernetifConfig->phyHandle, &autonego); | ||||||
|  |             PHY_GetLinkStatus(ethernetifConfig->phyHandle, &link); | ||||||
|  |             if (autonego && link) | ||||||
|  |             { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } while (--autoWaitCount); | ||||||
|  |         if (!autonego) | ||||||
|  |         { | ||||||
|  |             LWIP_PLATFORM_DIAG(("PHY Auto-negotiation failed. Please check the cable connection and link partner setting.")); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         initWaitCount++; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (autonego && link) | ||||||
|  |     { | ||||||
|  |         /* Get the actual PHY link speed. */ | ||||||
|  |         PHY_GetLinkSpeedDuplex(ethernetifConfig->phyHandle, speed, duplex); | ||||||
|  |     } | ||||||
|  | #if 0 /* Disable assert. If initial auto-negation is timeout, \ \
 | ||||||
|  |          the ENET is set to default (100Mbs and full-duplex). */ | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         LWIP_ASSERT("\r\nGiving up PHY initialization. Please check the ENET cable connection and link partner setting and reset the board.\r\n", 0); | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * This function should be called when a packet is ready to be read | ||||||
|  |  * from the interface. It uses the function ethernetif_linkinput() 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; | ||||||
|  | 
 | ||||||
|  |     LWIP_ASSERT("netif != NULL", (netif != NULL)); | ||||||
|  | 
 | ||||||
|  |     /* move received packet into a new pbuf */ | ||||||
|  |     while ((p = ethernetif_linkinput(netif)) != NULL) | ||||||
|  |     { | ||||||
|  |         /* pass all packets to ethernet_input, which decides what packets it supports */ | ||||||
|  |         if (netif->input(p, netif) != ERR_OK) | ||||||
|  |         { | ||||||
|  |             LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); | ||||||
|  |             pbuf_free(p); | ||||||
|  |             p = NULL; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void *ethernetif_get_enet_base(const uint8_t enetIdx) | ||||||
|  | { | ||||||
|  |     ENET_Type *enets[] = ENET_BASE_PTRS; | ||||||
|  |     int arrayIdx; | ||||||
|  |     int enetCount; | ||||||
|  | 
 | ||||||
|  |     for (arrayIdx = 0, enetCount = 0; arrayIdx < ARRAY_SIZE(enets); arrayIdx++) | ||||||
|  |     { | ||||||
|  |         if (enets[arrayIdx] != 0U) /* process only defined positions */ | ||||||
|  |         {                          /* (some SOC headers count ENETs from 1 instead of 0) */ | ||||||
|  |             if (enetCount == enetIdx) | ||||||
|  |             { | ||||||
|  |                 return (void *)enets[arrayIdx]; | ||||||
|  |             } | ||||||
|  |             enetCount++; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_SOC_ENET_QOS_COUNT) && (FSL_FEATURE_SOC_ENET_QOS_COUNT > 0) | ||||||
|  | void *ethernetif_get_enet_qos_base(const uint8_t enetIdx) | ||||||
|  | { | ||||||
|  |     ENET_QOS_Type *enets[] = ENET_QOS_BASE_PTRS; | ||||||
|  |     int arrayIdx; | ||||||
|  |     int enetCount; | ||||||
|  | 
 | ||||||
|  |     for (arrayIdx = 0, enetCount = 0; arrayIdx < ARRAY_SIZE(enets); arrayIdx++) | ||||||
|  |     { | ||||||
|  |         if (enets[arrayIdx] != 0U) /* process only defined positions */ | ||||||
|  |         {                          /* (some SOC headers count ENETs from 1 instead of 0) */ | ||||||
|  |             if (enetCount == enetIdx) | ||||||
|  |             { | ||||||
|  |                 return (void *)enets[arrayIdx]; | ||||||
|  |             } | ||||||
|  |             enetCount++; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return NULL; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | err_t ethernetif_init(struct netif *netif, | ||||||
|  |                       struct ethernetif *ethernetif, | ||||||
|  |                       void *enetBase, | ||||||
|  |                       const ethernetif_config_t *ethernetifConfig) | ||||||
|  | { | ||||||
|  |     LWIP_ASSERT("netif != NULL", (netif != NULL)); | ||||||
|  |     LWIP_ASSERT("ethernetifConfig != NULL", (ethernetifConfig != NULL)); | ||||||
|  | 
 | ||||||
|  | #if LWIP_NETIF_HOSTNAME | ||||||
|  |     /* Initialize interface hostname */ | ||||||
|  |     netif->hostname = "lwip"; | ||||||
|  | #endif /* LWIP_NETIF_HOSTNAME */ | ||||||
|  | 
 | ||||||
|  |     /*
 | ||||||
|  |      * 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); | ||||||
|  | 
 | ||||||
|  |     netif->state   = ethernetif; | ||||||
|  |     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...) */ | ||||||
|  | #if LWIP_IPV4 | ||||||
|  |     netif->output = etharp_output; | ||||||
|  | #endif | ||||||
|  | #if LWIP_IPV6 | ||||||
|  |     netif->output_ip6 = ethip6_output; | ||||||
|  | #endif /* LWIP_IPV6 */ | ||||||
|  |     netif->linkoutput = ethernetif_linkoutput; | ||||||
|  | 
 | ||||||
|  | #if LWIP_IPV4 && LWIP_IGMP | ||||||
|  |     netif_set_igmp_mac_filter(netif, ethernetif_igmp_mac_filter); | ||||||
|  |     netif->flags |= NETIF_FLAG_IGMP; | ||||||
|  | #endif | ||||||
|  | #if LWIP_IPV6 && LWIP_IPV6_MLD | ||||||
|  |     netif_set_mld_mac_filter(netif, ethernetif_mld_mac_filter); | ||||||
|  |     netif->flags |= NETIF_FLAG_MLD6; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     /* Init ethernetif parameters.*/ | ||||||
|  |     *ethernetif_enet_ptr(ethernetif) = enetBase; | ||||||
|  |     LWIP_ASSERT("*ethernetif_enet_ptr(ethernetif) != NULL", (*ethernetif_enet_ptr(ethernetif) != NULL)); | ||||||
|  | 
 | ||||||
|  |     /* set MAC hardware address length */ | ||||||
|  |     netif->hwaddr_len = ETH_HWADDR_LEN; | ||||||
|  | 
 | ||||||
|  |     /* set MAC hardware address */ | ||||||
|  |     memcpy(netif->hwaddr, ethernetifConfig->macAddress, NETIF_MAX_HWADDR_LEN); | ||||||
|  | 
 | ||||||
|  |     /* maximum transfer unit */ | ||||||
|  |     netif->mtu = 1500; /* TODO: define a config */ | ||||||
|  | 
 | ||||||
|  |     /* device capabilities */ | ||||||
|  |     /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ | ||||||
|  |     netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; | ||||||
|  | 
 | ||||||
|  |     /* ENET driver initialization.*/ | ||||||
|  |     ethernetif_enet_init(netif, ethernetif, ethernetifConfig); | ||||||
|  | 
 | ||||||
|  | #if LWIP_IPV6 && LWIP_IPV6_MLD | ||||||
|  |     /*
 | ||||||
|  |      * For hardware/netifs that implement MAC filtering. | ||||||
|  |      * All-nodes link-local is handled by default, so we must let the hardware know | ||||||
|  |      * to allow multicast packets in. | ||||||
|  |      * Should set mld_mac_filter previously. */ | ||||||
|  |     if (netif->mld_mac_filter != NULL) | ||||||
|  |     { | ||||||
|  |         ip6_addr_t ip6_allnodes_ll; | ||||||
|  |         ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll); | ||||||
|  |         netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER); | ||||||
|  |     } | ||||||
|  | #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ | ||||||
|  | 
 | ||||||
|  |     return ERR_OK; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,721 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2001-2004 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: Adam Dunkels <adam@sics.se> | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2013-2016, Freescale Semiconductor, Inc. | ||||||
|  |  * Copyright 2016-2020 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "lwip/opt.h" | ||||||
|  | #include "lwip/def.h" | ||||||
|  | #include "lwip/ethip6.h" | ||||||
|  | #include "lwip/igmp.h" | ||||||
|  | #include "lwip/mem.h" | ||||||
|  | #include "lwip/mld6.h" | ||||||
|  | #include "lwip/pbuf.h" | ||||||
|  | #include "lwip/snmp.h" | ||||||
|  | #include "lwip/stats.h" | ||||||
|  | #include "lwip/sys.h" | ||||||
|  | #include "netif/etharp.h" | ||||||
|  | #include "netif/ppp/pppoe.h" | ||||||
|  | 
 | ||||||
|  | #ifdef FSL_RTOS_XIUOS | ||||||
|  | #define USE_RTOS 1 | ||||||
|  | #define FSL_RTOS_FREE_RTOS | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) | ||||||
|  | #include "FreeRTOS.h" | ||||||
|  | #include "event_groups.h" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include "enet_ethernetif.h" | ||||||
|  | #include "enet_ethernetif_priv.h" | ||||||
|  | 
 | ||||||
|  | #include "fsl_enet.h" | ||||||
|  | #include "fsl_phy.h" | ||||||
|  | 
 | ||||||
|  | #define LWIP_ENET_FLEXIBLE_CONFIGURATION | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Padding of ethernet frames has to be disabled for zero-copy functionality | ||||||
|  |  * since ENET driver requires the starting buffer addresses to be aligned. | ||||||
|  |  */ | ||||||
|  | #if ETH_PAD_SIZE != 0 | ||||||
|  | #error "ETH_PAD_SIZE != 0" | ||||||
|  | #endif /* ETH_PAD_SIZE != 0 */ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | #ifndef ENET_RXBD_NUM | ||||||
|  |     #define ENET_RXBD_NUM (5) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef ENET_TXBD_NUM | ||||||
|  |     #define ENET_TXBD_NUM (3) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef ENET_RXBUFF_SIZE | ||||||
|  |     #define ENET_RXBUFF_SIZE ENET_FRAME_MAX_FRAMELEN | ||||||
|  | #endif | ||||||
|  |     | ||||||
|  | #ifndef ENET_TXBUFF_SIZE | ||||||
|  |     #define ENET_TXBUFF_SIZE (ENET_FRAME_MAX_FRAMELEN) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL | ||||||
|  |     #if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) \ | ||||||
|  |         && ((!defined(FSL_SDK_DISBLE_L2CACHE_PRESENT)) || (FSL_SDK_DISBLE_L2CACHE_PRESENT == 0)) | ||||||
|  |         #if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) | ||||||
|  |             #define FSL_CACHE_LINESIZE_MAX MAX(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE, FSL_FEATURE_L2CACHE_LINESIZE_BYTE) | ||||||
|  |             #define FSL_ENET_BUFF_ALIGNMENT MAX(ENET_BUFF_ALIGNMENT, FSL_CACHE_LINESIZE_MAX) | ||||||
|  |         #else | ||||||
|  |             #define FSL_ENET_BUFF_ALIGNMENT MAX(ENET_BUFF_ALIGNMENT, FSL_FEATURE_L2CACHE_LINESIZE_BYTE) | ||||||
|  |         #endif | ||||||
|  |     #elif defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) | ||||||
|  |         #define FSL_ENET_BUFF_ALIGNMENT MAX(ENET_BUFF_ALIGNMENT, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) | ||||||
|  |     #else | ||||||
|  |         #define FSL_ENET_BUFF_ALIGNMENT ENET_BUFF_ALIGNMENT | ||||||
|  |     #endif | ||||||
|  | #else | ||||||
|  |     #define FSL_ENET_BUFF_ALIGNMENT ENET_BUFF_ALIGNMENT | ||||||
|  | #endif     | ||||||
|  | 
 | ||||||
|  | typedef uint8_t rx_buffer_t[SDK_SIZEALIGN(ENET_RXBUFF_SIZE, FSL_ENET_BUFF_ALIGNMENT)]; | ||||||
|  | typedef uint8_t tx_buffer_t[SDK_SIZEALIGN(ENET_TXBUFF_SIZE, FSL_ENET_BUFF_ALIGNMENT)]; | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Used to wrap received data in a pbuf to be passed into lwIP | ||||||
|  |  *        without copying. | ||||||
|  |  * Once last reference is released, RX descriptor will be returned to DMA. | ||||||
|  |  */ | ||||||
|  | typedef struct rx_pbuf_wrapper | ||||||
|  | { | ||||||
|  |     struct pbuf_custom p;          /*!< Pbuf wrapper. Has to be first. */ | ||||||
|  |     void *buffer;                  /*!< Original buffer wrapped by p. */ | ||||||
|  |     struct ethernetif *ethernetif; /*!< Ethernet interface context data. */ | ||||||
|  | } rx_pbuf_wrapper_t; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Helper struct to hold private data used to operate your ethernet interface. | ||||||
|  |  */ | ||||||
|  | struct ethernetif | ||||||
|  | { | ||||||
|  |     ENET_Type *base; | ||||||
|  | #if (defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0)) || \ | ||||||
|  |     (USE_RTOS && defined(FSL_RTOS_FREE_RTOS)) | ||||||
|  |     enet_handle_t handle; | ||||||
|  | #endif | ||||||
|  | #if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) | ||||||
|  |     EventGroupHandle_t enetTransmitAccessEvent; | ||||||
|  |     EventBits_t txFlag; | ||||||
|  | #endif | ||||||
|  |     enet_rx_bd_struct_t *RxBuffDescrip; | ||||||
|  |     enet_tx_bd_struct_t *TxBuffDescrip; | ||||||
|  |     rx_buffer_t *RxDataBuff; | ||||||
|  |     tx_buffer_t *TxDataBuff; | ||||||
|  |     rx_pbuf_wrapper_t RxPbufs[ENET_RXBD_NUM]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Prototypes | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | static void ethernetif_rx_release(struct pbuf *p); | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Code | ||||||
|  |  ******************************************************************************/ | ||||||
|  | #if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) | ||||||
|  | static void ethernet_callback(ENET_Type *base, | ||||||
|  |                               enet_handle_t *handle, | ||||||
|  | #if FSL_FEATURE_ENET_QUEUE > 1 | ||||||
|  |                               uint32_t ringId, | ||||||
|  | #endif /* FSL_FEATURE_ENET_QUEUE */ | ||||||
|  |                               enet_event_t event, | ||||||
|  |                               enet_frame_info_t *frameInfo, | ||||||
|  |                               void *userData) | ||||||
|  | { | ||||||
|  |     struct netif *netif = (struct netif *)userData; | ||||||
|  |     struct ethernetif *ethernetif = netif->state; | ||||||
|  |     BaseType_t xResult; | ||||||
|  |      | ||||||
|  | 
 | ||||||
|  |     switch (event) | ||||||
|  |     { | ||||||
|  |         case kENET_RxEvent: | ||||||
|  |             ethernetif_input(netif); | ||||||
|  |             break; | ||||||
|  |         case kENET_TxEvent: | ||||||
|  |         { | ||||||
|  |             portBASE_TYPE taskToWake = pdFALSE; | ||||||
|  | 
 | ||||||
|  | #ifdef __CA7_REV | ||||||
|  |             if (SystemGetIRQNestingLevel()) | ||||||
|  | #else | ||||||
|  |             if (__get_IPSR()) | ||||||
|  | #endif  | ||||||
|  |             { | ||||||
|  |                 xResult = xEventGroupSetBitsFromISR(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag, &taskToWake); | ||||||
|  |                 if ((pdPASS == xResult) && (pdTRUE == taskToWake)) | ||||||
|  |                 { | ||||||
|  |                     portYIELD_FROM_ISR(taskToWake); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 xEventGroupSetBits(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |         default: | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if LWIP_IPV4 && LWIP_IGMP | ||||||
|  | err_t ethernetif_igmp_mac_filter(struct netif *netif, const ip4_addr_t *group, | ||||||
|  |                                  enum netif_mac_filter_action action) | ||||||
|  | { | ||||||
|  |     struct ethernetif *ethernetif = netif->state; | ||||||
|  |     uint8_t multicastMacAddr[6]; | ||||||
|  |     err_t result; | ||||||
|  | 
 | ||||||
|  |     multicastMacAddr[0] = 0x01U; | ||||||
|  |     multicastMacAddr[1] = 0x00U; | ||||||
|  |     multicastMacAddr[2] = 0x5EU; | ||||||
|  |     multicastMacAddr[3] = (group->addr >> 8) & 0x7FU; | ||||||
|  |     multicastMacAddr[4] = (group->addr >> 16) & 0xFFU; | ||||||
|  |     multicastMacAddr[5] = (group->addr >> 24) & 0xFFU; | ||||||
|  | 
 | ||||||
|  |     switch (action) | ||||||
|  |     { | ||||||
|  |         case IGMP_ADD_MAC_FILTER: | ||||||
|  |             /* Adds the ENET device to a multicast group.*/ | ||||||
|  |             ENET_AddMulticastGroup(ethernetif->base, multicastMacAddr); | ||||||
|  |             result = ERR_OK; | ||||||
|  |             break; | ||||||
|  |         case IGMP_DEL_MAC_FILTER: | ||||||
|  |             /*
 | ||||||
|  |              * Moves the ENET device from a multicast group. | ||||||
|  |              * Since the ENET_LeaveMulticastGroup() could filter out also other | ||||||
|  |              * group addresses having the same hash, the call is commented out. | ||||||
|  |              */ | ||||||
|  |             /* ENET_LeaveMulticastGroup(ethernetif->base, multicastMacAddr); */ | ||||||
|  |             result = ERR_OK; | ||||||
|  |             break; | ||||||
|  |         default: | ||||||
|  |             result = ERR_IF; | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if LWIP_IPV6 && LWIP_IPV6_MLD | ||||||
|  | err_t ethernetif_mld_mac_filter(struct netif *netif, const ip6_addr_t *group, | ||||||
|  |                                 enum netif_mac_filter_action action) | ||||||
|  | { | ||||||
|  |     struct ethernetif *ethernetif = netif->state; | ||||||
|  |     uint8_t multicastMacAddr[6]; | ||||||
|  |     err_t result; | ||||||
|  | 
 | ||||||
|  |     multicastMacAddr[0] = 0x33U; | ||||||
|  |     multicastMacAddr[1] = 0x33U; | ||||||
|  |     multicastMacAddr[2] = (group->addr[3]) & 0xFFU; | ||||||
|  |     multicastMacAddr[3] = (group->addr[3] >> 8) & 0xFFU; | ||||||
|  |     multicastMacAddr[4] = (group->addr[3] >> 16) & 0xFFU; | ||||||
|  |     multicastMacAddr[5] = (group->addr[3] >> 24) & 0xFFU; | ||||||
|  | 
 | ||||||
|  |     switch (action) | ||||||
|  |     { | ||||||
|  |         case NETIF_ADD_MAC_FILTER: | ||||||
|  |             /* Adds the ENET device to a multicast group.*/ | ||||||
|  |             ENET_AddMulticastGroup(ethernetif->base, multicastMacAddr); | ||||||
|  |             result = ERR_OK; | ||||||
|  |             break; | ||||||
|  |         case NETIF_DEL_MAC_FILTER: | ||||||
|  |             /*
 | ||||||
|  |              * Moves the ENET device from a multicast group. | ||||||
|  |              * Since the ENET_LeaveMulticastGroup() could filter out also other | ||||||
|  |              * group addresses having the same hash, the call is commented out. | ||||||
|  |              */ | ||||||
|  |             /* ENET_LeaveMulticastGroup(ethernetif->base, multicastMacAddr); */ | ||||||
|  |             result = ERR_OK; | ||||||
|  |             break; | ||||||
|  |         default: | ||||||
|  |             result = ERR_IF; | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Initializes ENET driver. | ||||||
|  |  */ | ||||||
|  | void ethernetif_enet_init(struct netif *netif, struct ethernetif *ethernetif, | ||||||
|  |                           const ethernetif_config_t *ethernetifConfig) | ||||||
|  | { | ||||||
|  |     enet_config_t config; | ||||||
|  |     uint32_t sysClock; | ||||||
|  |     enet_buffer_config_t buffCfg[ENET_RING_NUM]; | ||||||
|  |     phy_speed_t speed; | ||||||
|  |     phy_duplex_t duplex; | ||||||
|  |     int i; | ||||||
|  | 
 | ||||||
|  |     /* prepare the buffer configuration. */ | ||||||
|  |     buffCfg[0].rxBdNumber = ENET_RXBD_NUM;                      /* Receive buffer descriptor number. */ | ||||||
|  |     buffCfg[0].txBdNumber = ENET_TXBD_NUM;                      /* Transmit buffer descriptor number. */ | ||||||
|  |     buffCfg[0].rxBuffSizeAlign = sizeof(rx_buffer_t);           /* Aligned receive data buffer size. */ | ||||||
|  |     buffCfg[0].txBuffSizeAlign = sizeof(tx_buffer_t);           /* Aligned transmit data buffer size. */ | ||||||
|  |     buffCfg[0].rxBdStartAddrAlign = &(ethernetif->RxBuffDescrip[0]); /* Aligned receive buffer descriptor start address. */ | ||||||
|  |     buffCfg[0].txBdStartAddrAlign = &(ethernetif->TxBuffDescrip[0]); /* Aligned transmit buffer descriptor start address. */ | ||||||
|  |     buffCfg[0].rxBufferAlign = &(ethernetif->RxDataBuff[0][0]); /* Receive data buffer start address. */ | ||||||
|  |     buffCfg[0].txBufferAlign = &(ethernetif->TxDataBuff[0][0]); /* Transmit data buffer start address. */ | ||||||
|  |     buffCfg[0].txFrameInfo = NULL;                              /* Transmit frame information start address. Set only if using zero-copy transmit. */ | ||||||
|  |     buffCfg[0].rxMaintainEnable = true;                         /* Receive buffer cache maintain. */ | ||||||
|  |     buffCfg[0].txMaintainEnable = true;                         /* Transmit buffer cache maintain. */ | ||||||
|  | 
 | ||||||
|  |     sysClock = ethernetifConfig->phyHandle->mdioHandle->resource.csrClock_Hz; | ||||||
|  | 
 | ||||||
|  |     ENET_GetDefaultConfig(&config); | ||||||
|  |     config.ringNum = ENET_RING_NUM; | ||||||
|  | #ifdef LWIP_ENET_FLEXIBLE_CONFIGURATION | ||||||
|  |     extern void BOARD_ENETFlexibleConfigure(enet_config_t *config, uint8_t *hwAddr); | ||||||
|  |     BOARD_ENETFlexibleConfigure(&config, netif->hwaddr); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     ethernetif_phy_init(ethernetif, ethernetifConfig, &speed, &duplex); | ||||||
|  |     //Followings are configured by BOARD_ENETFlexibleConfigure function.
 | ||||||
|  | //    config.miiSpeed = (enet_mii_speed_t)speed;
 | ||||||
|  | //    config.miiDuplex = (enet_mii_duplex_t)duplex;
 | ||||||
|  | 
 | ||||||
|  | #if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) | ||||||
|  |     uint32_t instance; | ||||||
|  |     static ENET_Type *const enetBases[] = ENET_BASE_PTRS; | ||||||
|  |     static const IRQn_Type enetTxIrqId[] = ENET_Transmit_IRQS; | ||||||
|  |     /*! @brief Pointers to enet receive IRQ number for each instance. */ | ||||||
|  |     static const IRQn_Type enetRxIrqId[] = ENET_Receive_IRQS; | ||||||
|  | #if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE | ||||||
|  |     /*! @brief Pointers to enet timestamp IRQ number for each instance. */ | ||||||
|  |     static const IRQn_Type enetTsIrqId[] = ENET_1588_Timer_IRQS; | ||||||
|  | #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ | ||||||
|  | 
 | ||||||
|  |     /* Create the Event for transmit busy release trigger. */ | ||||||
|  |     ethernetif->enetTransmitAccessEvent = xEventGroupCreate(); | ||||||
|  |     ethernetif->txFlag = 0x1; | ||||||
|  | 
 | ||||||
|  |     config.interrupt |= kENET_RxFrameInterrupt | kENET_TxFrameInterrupt | kENET_TxBufferInterrupt | kENET_LateCollisionInterrupt; | ||||||
|  | 
 | ||||||
|  |     for (instance = 0; instance < ARRAY_SIZE(enetBases); instance++) | ||||||
|  |     { | ||||||
|  |         if (enetBases[instance] == ethernetif->base) | ||||||
|  |         { | ||||||
|  | #ifdef __CA7_REV | ||||||
|  |             GIC_SetPriority(enetRxIrqId[instance], ENET_PRIORITY); | ||||||
|  |             GIC_SetPriority(enetTxIrqId[instance], ENET_PRIORITY); | ||||||
|  | #if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE | ||||||
|  |             GIC_SetPriority(enetTsIrqId[instance], ENET_1588_PRIORITY); | ||||||
|  | #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ | ||||||
|  | #else | ||||||
|  |             NVIC_SetPriority(enetRxIrqId[instance], ENET_PRIORITY); | ||||||
|  |             NVIC_SetPriority(enetTxIrqId[instance], ENET_PRIORITY); | ||||||
|  | #if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE | ||||||
|  |             NVIC_SetPriority(enetTsIrqId[instance], ENET_1588_PRIORITY); | ||||||
|  | #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ | ||||||
|  | #endif /* __CA7_REV */ | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     LWIP_ASSERT("Input Ethernet base error!", (instance != ARRAY_SIZE(enetBases))); | ||||||
|  | #endif /* USE_RTOS */ | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < ENET_RXBD_NUM; i++) | ||||||
|  |     { | ||||||
|  |         ethernetif->RxPbufs[i].p.custom_free_function = ethernetif_rx_release; | ||||||
|  |         ethernetif->RxPbufs[i].buffer = &(ethernetif->RxDataBuff[i][0]); | ||||||
|  |         ethernetif->RxPbufs[i].ethernetif = ethernetif; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* Initialize the ENET module. */ | ||||||
|  |     ENET_Init(ethernetif->base, ðernetif->handle, &config, &buffCfg[0], netif->hwaddr, sysClock); | ||||||
|  | 
 | ||||||
|  | #if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) | ||||||
|  |     ENET_SetCallback(ðernetif->handle, ethernet_callback, netif); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     ENET_ActiveRead(ethernetif->base); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void **ethernetif_enet_ptr(struct ethernetif *ethernetif) | ||||||
|  | { | ||||||
|  |     return (void **)&(ethernetif->base); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Returns next buffer for TX. | ||||||
|  |  * Can wait if no buffer available. | ||||||
|  |  */ | ||||||
|  | static unsigned char *enet_get_tx_buffer(struct ethernetif *ethernetif) | ||||||
|  | { | ||||||
|  |     static unsigned char ucBuffer[ENET_FRAME_MAX_FRAMELEN]; | ||||||
|  |     return ucBuffer; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Sends frame via ENET. | ||||||
|  |  */ | ||||||
|  | static err_t enet_send_frame(struct ethernetif *ethernetif, unsigned char *data, const uint32_t length) | ||||||
|  | { | ||||||
|  | #if USE_RTOS && defined(FSL_RTOS_FREE_RTOS) | ||||||
|  |     { | ||||||
|  |         status_t result; | ||||||
|  | 
 | ||||||
|  |         do | ||||||
|  |         { | ||||||
|  |             result = ENET_SendFrame(ethernetif->base, ðernetif->handle, data, length, 0, false, NULL); | ||||||
|  | 
 | ||||||
|  |             if (result == kStatus_ENET_TxFrameBusy) | ||||||
|  |             { | ||||||
|  |                 xEventGroupWaitBits(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag, pdTRUE, (BaseType_t) false, | ||||||
|  |                                     portMAX_DELAY); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } while (result == kStatus_ENET_TxFrameBusy); | ||||||
|  |         return ERR_OK; | ||||||
|  |     } | ||||||
|  | #else | ||||||
|  |     { | ||||||
|  |         uint32_t counter; | ||||||
|  | 
 | ||||||
|  |         for (counter = ENET_TIMEOUT; counter != 0U; counter--) | ||||||
|  |         { | ||||||
|  |             if (ENET_SendFrame(ethernetif->base, ðernetif->handle, data, length, 0, false, NULL) != kStatus_ENET_TxFrameBusy) | ||||||
|  |             { | ||||||
|  |                 return ERR_OK; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return ERR_TIMEOUT; | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Reclaims RX buffer held by the p after p is no longer used | ||||||
|  |  * by the application / lwIP. | ||||||
|  |  */ | ||||||
|  | static void ethernetif_rx_release(struct pbuf *p) | ||||||
|  | { | ||||||
|  |     rx_pbuf_wrapper_t *wrapper = (rx_pbuf_wrapper_t *)p;   | ||||||
|  |     SYS_ARCH_DECL_PROTECT(old_level); | ||||||
|  | 
 | ||||||
|  |     SYS_ARCH_PROTECT(old_level); | ||||||
|  |     ENET_ReleaseRxBuffer(wrapper->ethernetif->base, &wrapper->ethernetif->handle, wrapper->buffer, 0); | ||||||
|  |     SYS_ARCH_UNPROTECT(old_level); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Reads a received frame - wraps its descriptor buffer(s) into a pbuf or a pbuf chain and returns it. | ||||||
|  |  * The descriptors are returned to DMA only once the returned pbuf is released. | ||||||
|  |  * Function can be called only after ENET_GetRxFrameSize() indicates | ||||||
|  |  * that there actually is a received frame. | ||||||
|  |  */ | ||||||
|  | static struct pbuf *ethernetif_read_frame(struct ethernetif *ethernetif, uint32_t length) | ||||||
|  | { | ||||||
|  |     rx_pbuf_wrapper_t *wrapper; | ||||||
|  |     uint32_t len = 0; | ||||||
|  |     uint32_t ts; | ||||||
|  |     struct pbuf *p = NULL; | ||||||
|  |     struct pbuf *q = NULL; | ||||||
|  |     void *buffer; | ||||||
|  |     bool isLastBuff; | ||||||
|  |     status_t status; | ||||||
|  |     int i; | ||||||
|  | 
 | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  |         status = ENET_GetRxBuffer(ethernetif->base, ðernetif->handle, &buffer, &len, 0, &isLastBuff, &ts); | ||||||
|  |         LWIP_UNUSED_ARG(status); /* for LWIP_NOASSERT */ | ||||||
|  |         LWIP_ASSERT("ENET_GetRxBuffer() status != kStatus_Success", status == kStatus_Success); | ||||||
|  | 
 | ||||||
|  |         /* Find pbuf wrapper for the actually read byte buffer */ | ||||||
|  |         wrapper = NULL; | ||||||
|  |         for (i = 0; i < ENET_RXBD_NUM; i++) | ||||||
|  |         { | ||||||
|  |             if (buffer == ethernetif->RxPbufs[i].buffer) | ||||||
|  |             { | ||||||
|  |                 wrapper = ðernetif->RxPbufs[i]; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         LWIP_ASSERT("Buffer returned by ENET_GetRxBuffer() doesn't match any RX buffer descriptor", wrapper != NULL); | ||||||
|  | 
 | ||||||
|  |         /* Wrap the receive buffer in pbuf. */ | ||||||
|  |         if (p == NULL) | ||||||
|  |         { | ||||||
|  |             p = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &wrapper->p, buffer, len); | ||||||
|  |             LWIP_ASSERT("pbuf_alloced_custom() failed", p); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             q = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &wrapper->p, buffer, len); | ||||||
|  |             LWIP_ASSERT("pbuf_alloced_custom() failed", q); | ||||||
|  | 
 | ||||||
|  |             pbuf_cat(p, q); | ||||||
|  |         } | ||||||
|  |     } while (!isLastBuff); | ||||||
|  | 
 | ||||||
|  |     LWIP_ASSERT("p->tot_len != length", p->tot_len == length); | ||||||
|  | 
 | ||||||
|  |     MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); | ||||||
|  |     if (((u8_t *)p->payload)[0] & 1) | ||||||
|  |     { | ||||||
|  |         /* broadcast or multicast packet */ | ||||||
|  |         MIB2_STATS_NETIF_INC(netif, ifinnucastpkts); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         /* unicast packet */ | ||||||
|  |         MIB2_STATS_NETIF_INC(netif, ifinucastpkts); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     LINK_STATS_INC(link.recv); | ||||||
|  | 
 | ||||||
|  |     return p; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Drops (releases) receive descriptors until the last one of a frame is reached. | ||||||
|  |  * Function can be called only after ENET_GetRxFrameSize() indicates | ||||||
|  |  * that there actually is a frame error or a received frame. | ||||||
|  |  */ | ||||||
|  | static void ethernetif_drop_frame(struct ethernetif *ethernetif) | ||||||
|  | { | ||||||
|  |     status_t status; | ||||||
|  |     void *buffer; | ||||||
|  |     uint32_t len; | ||||||
|  |     uint32_t ts; | ||||||
|  |     bool isLastBuff; | ||||||
|  | 
 | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  | #if 0 /* Error statisctics */
 | ||||||
|  |         enet_data_error_stats_t eErrStatic; | ||||||
|  |         /* Get the error information of the received g_frame. */ | ||||||
|  |         ENET_GetRxErrBeforeReadFrame(ðernetif->handle, &eErrStatic); | ||||||
|  | #endif | ||||||
|  |         status = ENET_GetRxBuffer(ethernetif->base, ðernetif->handle, &buffer, &len, 0, &isLastBuff, &ts); | ||||||
|  |         LWIP_UNUSED_ARG(status); /* for LWIP_NOASSERT */ | ||||||
|  |         LWIP_ASSERT("ENET_GetRxBuffer() status != kStatus_Success", status == kStatus_Success); | ||||||
|  |         ENET_ReleaseRxBuffer(ethernetif->base, ðernetif->handle, buffer, 0); | ||||||
|  |     } while (!isLastBuff); | ||||||
|  | 
 | ||||||
|  |     LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_linkinput: RxFrameError\n")); | ||||||
|  | 
 | ||||||
|  |     LINK_STATS_INC(link.drop); | ||||||
|  |     MIB2_STATS_NETIF_INC(netif, ifindiscards); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct pbuf *ethernetif_linkinput(struct netif *netif) | ||||||
|  | { | ||||||
|  |     struct ethernetif *ethernetif = netif->state; | ||||||
|  |     struct pbuf *p = NULL; | ||||||
|  |     status_t status; | ||||||
|  |     uint32_t len; | ||||||
|  | 
 | ||||||
|  |     /* Obtain the size of the packet and put it into the "len" variable. */ | ||||||
|  |     status = ENET_GetRxFrameSize(ðernetif->handle, &len, 0); | ||||||
|  | 
 | ||||||
|  |     if (status == kStatus_Success) | ||||||
|  |     { | ||||||
|  |         /* Read frame. */ | ||||||
|  |         p = ethernetif_read_frame(ethernetif, len); | ||||||
|  |     } | ||||||
|  |     else if (status != kStatus_ENET_RxFrameEmpty) | ||||||
|  |     { | ||||||
|  |         /* Drop the frame when error happened. */ | ||||||
|  |         ethernetif_drop_frame(ethernetif); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return p; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p) | ||||||
|  | { | ||||||
|  |     err_t result; | ||||||
|  |     struct ethernetif *ethernetif = netif->state; | ||||||
|  |     struct pbuf *q; | ||||||
|  |     unsigned char *pucBuffer; | ||||||
|  |     unsigned char *pucChar; | ||||||
|  | 
 | ||||||
|  |     LWIP_ASSERT("Output packet buffer empty", p); | ||||||
|  | 
 | ||||||
|  |     pucBuffer = enet_get_tx_buffer(ethernetif); | ||||||
|  |     if (pucBuffer == NULL) | ||||||
|  |     { | ||||||
|  |         return ERR_BUF; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | /* Initiate transfer. */ | ||||||
|  | 
 | ||||||
|  | #if ETH_PAD_SIZE | ||||||
|  |     pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     if (p->len == p->tot_len) | ||||||
|  |     { | ||||||
|  |         /* No pbuf chain, don't have to copy -> faster. */ | ||||||
|  |         pucBuffer = (unsigned char *)p->payload; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         /* pbuf chain, copy into contiguous ucBuffer. */ | ||||||
|  |         if (p->tot_len > ENET_FRAME_MAX_FRAMELEN) | ||||||
|  |         { | ||||||
|  |             return ERR_BUF; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             pucChar = pucBuffer; | ||||||
|  | 
 | ||||||
|  |             for (q = p; q != NULL; q = q->next) | ||||||
|  |             { | ||||||
|  |                 /* Send the data from the pbuf to the interface, one pbuf at a
 | ||||||
|  |                 time. The size of the data in each pbuf is kept in the ->len | ||||||
|  |                 variable. */ | ||||||
|  |                 /* send data from(q->payload, q->len); */ | ||||||
|  |                 memcpy(pucChar, q->payload, q->len); | ||||||
|  |                 pucChar += q->len; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* Send frame. */ | ||||||
|  |     result = enet_send_frame(ethernetif, pucBuffer, p->tot_len); | ||||||
|  | 
 | ||||||
|  |     MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len); | ||||||
|  |     if (((u8_t *)p->payload)[0] & 1) | ||||||
|  |     { | ||||||
|  |         /* broadcast or multicast packet*/ | ||||||
|  |         MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         /* unicast packet */ | ||||||
|  |         MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); | ||||||
|  |     } | ||||||
|  | /* increase ifoutdiscards or ifouterrors on error */ | ||||||
|  | 
 | ||||||
|  | #if ETH_PAD_SIZE | ||||||
|  |     pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     LINK_STATS_INC(link.xmit); | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Should be called at the beginning of the program to set up the | ||||||
|  |  * first network interface. It calls the function ethernetif_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 ethernetif0_init(struct netif *netif) | ||||||
|  | { | ||||||
|  |     static struct ethernetif ethernetif_0; | ||||||
|  |     AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); | ||||||
|  |     AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); | ||||||
|  | //    SDK_ALIGN(static rx_buffer_t rxDataBuff_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
 | ||||||
|  | //    SDK_ALIGN(static tx_buffer_t txDataBuff_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
 | ||||||
|  | 
 | ||||||
|  |     AT_NONCACHEABLE_SECTION_ALIGN(static rx_buffer_t rxDataBuff_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); | ||||||
|  |     AT_NONCACHEABLE_SECTION_ALIGN(static tx_buffer_t txDataBuff_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); | ||||||
|  | 
 | ||||||
|  |     ethernetif_0.RxBuffDescrip = &(rxBuffDescrip_0[0]); | ||||||
|  |     ethernetif_0.TxBuffDescrip = &(txBuffDescrip_0[0]); | ||||||
|  |     ethernetif_0.RxDataBuff = &(rxDataBuff_0[0]); | ||||||
|  |     ethernetif_0.TxDataBuff = &(txDataBuff_0[0]); | ||||||
|  | 
 | ||||||
|  |     return ethernetif_init(netif, ðernetif_0, ethernetif_get_enet_base(0U), (ethernetif_config_t *)netif->state); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 1) | ||||||
|  | /**
 | ||||||
|  |  * Should be called at the beginning of the program to set up the | ||||||
|  |  * second network interface. It calls the function ethernetif_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 ethernetif1_init(struct netif *netif) | ||||||
|  | { | ||||||
|  |     static struct ethernetif ethernetif_1; | ||||||
|  |     AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); | ||||||
|  |     AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); | ||||||
|  | //    SDK_ALIGN(static rx_buffer_t rxDataBuff_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
 | ||||||
|  | //    SDK_ALIGN(static tx_buffer_t txDataBuff_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
 | ||||||
|  | 
 | ||||||
|  |     AT_NONCACHEABLE_SECTION_ALIGN(static rx_buffer_t rxDataBuff_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); | ||||||
|  |     AT_NONCACHEABLE_SECTION_ALIGN(static tx_buffer_t txDataBuff_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT); | ||||||
|  | 
 | ||||||
|  |     ethernetif_1.RxBuffDescrip = &(rxBuffDescrip_1[0]); | ||||||
|  |     ethernetif_1.TxBuffDescrip = &(txBuffDescrip_1[0]); | ||||||
|  |     ethernetif_1.RxDataBuff = &(rxDataBuff_1[0]); | ||||||
|  |     ethernetif_1.TxDataBuff = &(txDataBuff_1[0]); | ||||||
|  | 
 | ||||||
|  |     return ethernetif_init(netif, ðernetif_1, ethernetif_get_enet_base(1U), (ethernetif_config_t *)netif->state); | ||||||
|  | } | ||||||
|  | #endif /* FSL_FEATURE_SOC_*_ENET_COUNT */ | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | SRC_FILES :=  | ||||||
|  | SRC_DIR := enet enet_qos | ||||||
|  | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | SRC_FILES := fsl_enet_mdio.c | ||||||
|  | 
 | ||||||
|  | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | @ -0,0 +1,133 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2020 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "fsl_enet_mdio.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Prototypes | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | static void ENET_MDIO_Init(mdio_handle_t *handle); | ||||||
|  | static status_t ENET_MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data); | ||||||
|  | static status_t ENET_MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr); | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Variables | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | const mdio_operations_t enet_ops = {.mdioInit     = ENET_MDIO_Init, | ||||||
|  |                                     .mdioWrite    = ENET_MDIO_Write, | ||||||
|  |                                     .mdioRead     = ENET_MDIO_Read, | ||||||
|  |                                     .mdioWriteExt = NULL, | ||||||
|  |                                     .mdioReadExt  = NULL}; | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Code | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | static void ENET_MDIO_Init(mdio_handle_t *handle) | ||||||
|  | { | ||||||
|  |     mdio_resource_t *resource = (mdio_resource_t *)&handle->resource; | ||||||
|  |     ENET_Type *base           = (ENET_Type *)resource->base; | ||||||
|  |     uint32_t instance         = ENET_GetInstance(base); | ||||||
|  | 
 | ||||||
|  | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | ||||||
|  |     /* Set SMI first. */ | ||||||
|  |     (void)CLOCK_EnableClock(s_enetClock[instance]); | ||||||
|  | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | ||||||
|  |     ENET_SetSMI(base, resource->csrClock_Hz, false); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static status_t ENET_MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data) | ||||||
|  | { | ||||||
|  |     mdio_resource_t *resource = (mdio_resource_t *)&handle->resource; | ||||||
|  |     ENET_Type *base           = (ENET_Type *)resource->base; | ||||||
|  |     status_t result           = kStatus_Success; | ||||||
|  | #ifdef MDIO_TIMEOUT_COUNT | ||||||
|  |     uint32_t counter; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     /* Clear the SMI interrupt event. */ | ||||||
|  |     ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); | ||||||
|  | 
 | ||||||
|  |     /* Starts a SMI write command. */ | ||||||
|  |     ENET_StartSMIWrite(base, phyAddr, devAddr, kENET_MiiWriteValidFrame, data); | ||||||
|  | 
 | ||||||
|  |     /* Wait for SMI complete. */ | ||||||
|  | #ifdef MDIO_TIMEOUT_COUNT | ||||||
|  |     for (counter = MDIO_TIMEOUT_COUNT; counter > 0U; counter--) | ||||||
|  |     { | ||||||
|  |         if (ENET_EIR_MII_MASK == (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)) | ||||||
|  |         { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     /* Check for timeout. */ | ||||||
|  |     if (0U == counter) | ||||||
|  |     { | ||||||
|  |         result = kStatus_PHY_SMIVisitTimeout; | ||||||
|  |     } | ||||||
|  | #else | ||||||
|  |     while (ENET_EIR_MII_MASK != (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     /* Clear SMI interrupt event. */ | ||||||
|  |     ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static status_t ENET_MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr) | ||||||
|  | { | ||||||
|  |     assert(dataPtr); | ||||||
|  | 
 | ||||||
|  |     mdio_resource_t *resource = (mdio_resource_t *)&handle->resource; | ||||||
|  |     ENET_Type *base           = (ENET_Type *)resource->base; | ||||||
|  | #ifdef MDIO_TIMEOUT_COUNT | ||||||
|  |     uint32_t counter; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     /* Clear the SMI interrupt event. */ | ||||||
|  |     ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); | ||||||
|  | 
 | ||||||
|  |     /* Starts a SMI read command operation. */ | ||||||
|  |     ENET_StartSMIRead(base, phyAddr, devAddr, kENET_MiiReadValidFrame); | ||||||
|  | 
 | ||||||
|  |     /* Wait for SMI complete. */ | ||||||
|  | #ifdef MDIO_TIMEOUT_COUNT | ||||||
|  |     for (counter = MDIO_TIMEOUT_COUNT; counter > 0U; counter--) | ||||||
|  |     { | ||||||
|  |         if (ENET_EIR_MII_MASK == (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)) | ||||||
|  |         { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     /* Check for timeout. */ | ||||||
|  |     if (0U == counter) | ||||||
|  |     { | ||||||
|  |         return kStatus_PHY_SMIVisitTimeout; | ||||||
|  |     } | ||||||
|  | #else | ||||||
|  |     while (ENET_EIR_MII_MASK != (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     /* Get data from SMI register. */ | ||||||
|  |     *dataPtr = ENET_ReadSMIData(base); | ||||||
|  | 
 | ||||||
|  |     /* Clear SMI interrupt event. */ | ||||||
|  |     ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); | ||||||
|  | 
 | ||||||
|  |     return kStatus_Success; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,21 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2020 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef _FSL_ENET_MDIO_H_ | ||||||
|  | #define _FSL_ENET_MDIO_H_ | ||||||
|  | 
 | ||||||
|  | #include "fsl_enet.h" | ||||||
|  | #include "fsl_mdio.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*! @brief ENET MDIO operations structure. */ | ||||||
|  | extern const mdio_operations_t enet_ops; | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | SRC_FILES := fsl_enet_qos_mdio.c | ||||||
|  | 
 | ||||||
|  | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | @ -0,0 +1,113 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2020-2021 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "fsl_enet_qos_mdio.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Prototypes | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | static void ENET_QOS_MDIO_Init(mdio_handle_t *handle); | ||||||
|  | 
 | ||||||
|  | static status_t ENET_QOS_MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data); | ||||||
|  | 
 | ||||||
|  | static status_t ENET_QOS_MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr); | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Variables | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | const mdio_operations_t enet_qos_ops = {.mdioInit     = ENET_QOS_MDIO_Init, | ||||||
|  |                                         .mdioWrite    = ENET_QOS_MDIO_Write, | ||||||
|  |                                         .mdioRead     = ENET_QOS_MDIO_Read, | ||||||
|  |                                         .mdioWriteExt = NULL, | ||||||
|  |                                         .mdioReadExt  = NULL}; | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Code | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | static void ENET_QOS_MDIO_Init(mdio_handle_t *handle) | ||||||
|  | { | ||||||
|  |     mdio_resource_t *resource = (mdio_resource_t *)&handle->resource; | ||||||
|  |     ENET_QOS_Type *base       = (ENET_QOS_Type *)resource->base; | ||||||
|  |     uint32_t instance         = ENET_QOS_GetInstance(base); | ||||||
|  | 
 | ||||||
|  | #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) | ||||||
|  |     /* Set SMI first. */ | ||||||
|  |     CLOCK_EnableClock(s_enetqosClock[instance]); | ||||||
|  | #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ | ||||||
|  |     ENET_QOS_SetSMI(base, resource->csrClock_Hz); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static status_t ENET_QOS_MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data) | ||||||
|  | { | ||||||
|  |     mdio_resource_t *resource = (mdio_resource_t *)&handle->resource; | ||||||
|  |     ENET_QOS_Type *base       = (ENET_QOS_Type *)resource->base; | ||||||
|  |     status_t result           = kStatus_Success; | ||||||
|  | #ifdef MDIO_TIMEOUT_COUNT | ||||||
|  |     uint32_t counter; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     ENET_QOS_StartSMIWrite(base, phyAddr, devAddr, data); | ||||||
|  | 
 | ||||||
|  | #ifdef MDIO_TIMEOUT_COUNT | ||||||
|  |     for (counter = MDIO_TIMEOUT_COUNT; counter > 0U; counter--) | ||||||
|  |     { | ||||||
|  |         if (!ENET_QOS_IsSMIBusy(base)) | ||||||
|  |         { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     /* Check for timeout. */ | ||||||
|  |     if (0U == counter) | ||||||
|  |     { | ||||||
|  |         result = kStatus_PHY_SMIVisitTimeout; | ||||||
|  |     } | ||||||
|  | #else | ||||||
|  |     while (ENET_QOS_IsSMIBusy(base)) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static status_t ENET_QOS_MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr) | ||||||
|  | { | ||||||
|  |     mdio_resource_t *resource = (mdio_resource_t *)&handle->resource; | ||||||
|  |     ENET_QOS_Type *base       = (ENET_QOS_Type *)resource->base; | ||||||
|  |     status_t result           = kStatus_Success; | ||||||
|  | #ifdef MDIO_TIMEOUT_COUNT | ||||||
|  |     uint32_t counter; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     ENET_QOS_StartSMIRead(base, phyAddr, devAddr); | ||||||
|  | #ifdef MDIO_TIMEOUT_COUNT | ||||||
|  |     for (counter = MDIO_TIMEOUT_COUNT; counter > 0U; counter--) | ||||||
|  |     { | ||||||
|  |         if (!ENET_QOS_IsSMIBusy(base)) | ||||||
|  |         { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     /* Check for timeout. */ | ||||||
|  |     if (0U == counter) | ||||||
|  |     { | ||||||
|  |         result = kStatus_PHY_SMIVisitTimeout; | ||||||
|  |     } | ||||||
|  | #else | ||||||
|  |     while (ENET_QOS_IsSMIBusy(base)) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  |     *dataPtr = ENET_QOS_ReadSMIData(base); | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,21 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2020 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef _FSL_ENET_QOS_MDIO_H_ | ||||||
|  | #define _FSL_ENET_QOS_MDIO_H_ | ||||||
|  | 
 | ||||||
|  | #include "fsl_enet_qos.h" | ||||||
|  | #include "fsl_mdio.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*! @brief ENET_QOS MDIO operations structure. */ | ||||||
|  | extern const mdio_operations_t enet_qos_ops; | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | SRC_FILES :=  | ||||||
|  | SRC_DIR := ksz8081 ksz9131rnx | ||||||
|  | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,2 @@ | ||||||
|  | SRC_FILES := fsl_phyksz8081.c | ||||||
|  | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | @ -0,0 +1,344 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2020 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "fsl_phyksz8081.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | /* define by AIIT lab */ | ||||||
|  | #define FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the PHY KSZ8081 vendor defined registers. */ | ||||||
|  | #define PHY_CONTROL1_REG 0x1EU /*!< The PHY control one register. */ | ||||||
|  | #define PHY_CONTROL2_REG 0x1FU /*!< The PHY control two register. */ | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the PHY KSZ8081 ID number. */ | ||||||
|  | #define PHY_CONTROL_ID1 0x22U /*!< The PHY ID1 */ | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the mask flag of operation mode in control registers */ | ||||||
|  | #define PHY_CTL2_REMOTELOOP_MASK    0x0004U /*!< The PHY remote loopback mask. */ | ||||||
|  | #define PHY_CTL2_REFCLK_SELECT_MASK 0x0080U /*!< The PHY RMII reference clock select. */ | ||||||
|  | #define PHY_CTL1_10HALFDUPLEX_MASK  0x0001U /*!< The PHY 10M half duplex mask. */ | ||||||
|  | #define PHY_CTL1_100HALFDUPLEX_MASK 0x0002U /*!< The PHY 100M half duplex mask. */ | ||||||
|  | #define PHY_CTL1_10FULLDUPLEX_MASK  0x0005U /*!< The PHY 10M full duplex mask. */ | ||||||
|  | #define PHY_CTL1_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */ | ||||||
|  | #define PHY_CTL1_SPEEDUPLX_MASK     0x0007U /*!< The PHY speed and duplex mask. */ | ||||||
|  | #define PHY_CTL1_ENERGYDETECT_MASK  0x10U   /*!< The PHY signal present on rx differential pair. */ | ||||||
|  | #define PHY_CTL1_LINKUP_MASK        0x100U  /*!< The PHY link up. */ | ||||||
|  | #define PHY_LINK_READY_MASK         (PHY_CTL1_ENERGYDETECT_MASK | PHY_CTL1_LINKUP_MASK) | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the timeout macro. */ | ||||||
|  | #define PHY_READID_TIMEOUT_COUNT 1000U | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Prototypes | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Variables | ||||||
|  |  ******************************************************************************/ | ||||||
|  | const phy_operations_t phyksz8081_ops = {.phyInit            = PHY_KSZ8081_Init, | ||||||
|  |                                          .phyWrite           = PHY_KSZ8081_Write, | ||||||
|  |                                          .phyRead            = PHY_KSZ8081_Read, | ||||||
|  |                                          .getAutoNegoStatus  = PHY_KSZ8081_GetAutoNegotiationStatus, | ||||||
|  |                                          .getLinkStatus      = PHY_KSZ8081_GetLinkStatus, | ||||||
|  |                                          .getLinkSpeedDuplex = PHY_KSZ8081_GetLinkSpeedDuplex, | ||||||
|  |                                          .setLinkSpeedDuplex = PHY_KSZ8081_SetLinkSpeedDuplex, | ||||||
|  |                                          .enableLoopback     = PHY_KSZ8081_EnableLoopback}; | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Code | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ8081_Init(phy_handle_t *handle, const phy_config_t *config) | ||||||
|  | { | ||||||
|  |     uint32_t counter  = PHY_READID_TIMEOUT_COUNT; | ||||||
|  |     status_t result   = kStatus_Success; | ||||||
|  |     uint32_t regValue = 0; | ||||||
|  | 
 | ||||||
|  |     /* Init MDIO interface. */ | ||||||
|  |     MDIO_Init(handle->mdioHandle); | ||||||
|  | 
 | ||||||
|  |     /* Assign phy address. */ | ||||||
|  |     handle->phyAddr = config->phyAddr; | ||||||
|  |     /* Check PHY ID. */ | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  |         result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_ID1_REG, ®Value); | ||||||
|  |         if (result != kStatus_Success) | ||||||
|  |         { | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|  |         counter--; | ||||||
|  |     } while ((regValue != PHY_CONTROL_ID1) && (counter != 0U)); | ||||||
|  | 
 | ||||||
|  |     if (counter == 0U) | ||||||
|  |     { | ||||||
|  |         return kStatus_Fail; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* Reset PHY. */ | ||||||
|  |     result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK); | ||||||
|  |     if (result == kStatus_Success) | ||||||
|  |     { | ||||||
|  | #if defined(FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE) | ||||||
|  |         result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, ®Value); | ||||||
|  |         if (result != kStatus_Success) | ||||||
|  |         { | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|  |         result = | ||||||
|  |             MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, (regValue | PHY_CTL2_REFCLK_SELECT_MASK)); | ||||||
|  |         if (result != kStatus_Success) | ||||||
|  |         { | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|  | #endif /* FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE */ | ||||||
|  | 
 | ||||||
|  |         if (config->autoNeg) | ||||||
|  |         { | ||||||
|  |             /* Set the auto-negotiation then start it. */ | ||||||
|  |             result = | ||||||
|  |                 MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_AUTONEG_ADVERTISE_REG, | ||||||
|  |                            (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK | | ||||||
|  |                             PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | PHY_IEEE802_3_SELECTOR_MASK)); | ||||||
|  |             if (result == kStatus_Success) | ||||||
|  |             { | ||||||
|  |                 result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, | ||||||
|  |                                     (PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK)); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             /* This PHY only supports 10/100M speed. */ | ||||||
|  |             assert(config->speed <= kPHY_Speed100M); | ||||||
|  | 
 | ||||||
|  |             /* Disable isolate mode */ | ||||||
|  |             result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); | ||||||
|  |             if (result != kStatus_Success) | ||||||
|  |             { | ||||||
|  |                 return result; | ||||||
|  |             } | ||||||
|  |             regValue &= ~PHY_BCTL_ISOLATE_MASK; | ||||||
|  |             result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); | ||||||
|  |             if (result != kStatus_Success) | ||||||
|  |             { | ||||||
|  |                 return result; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /* Disable the auto-negotiation and set user-defined speed/duplex configuration. */ | ||||||
|  |             result = PHY_KSZ8081_SetLinkSpeedDuplex(handle, config->speed, config->duplex); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ8081_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data) | ||||||
|  | { | ||||||
|  |     return MDIO_Write(handle->mdioHandle, handle->phyAddr, phyReg, data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ8081_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr) | ||||||
|  | { | ||||||
|  |     return MDIO_Read(handle->mdioHandle, handle->phyAddr, phyReg, dataPtr); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ8081_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status) | ||||||
|  | { | ||||||
|  |     assert(status); | ||||||
|  | 
 | ||||||
|  |     status_t result; | ||||||
|  |     uint32_t regValue; | ||||||
|  | 
 | ||||||
|  |     *status = false; | ||||||
|  | 
 | ||||||
|  |     /* Check auto negotiation complete. */ | ||||||
|  |     result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, ®Value); | ||||||
|  |     if (result == kStatus_Success) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         if ((regValue & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0U) | ||||||
|  |         { | ||||||
|  |             *status = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ8081_GetLinkStatus(phy_handle_t *handle, bool *status) | ||||||
|  | { | ||||||
|  |     assert(status); | ||||||
|  | 
 | ||||||
|  |     status_t result; | ||||||
|  |     uint32_t regValue; | ||||||
|  | 
 | ||||||
|  |     /* Read the basic status register. */ | ||||||
|  |     result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, ®Value); | ||||||
|  |     if (result == kStatus_Success) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         if ((PHY_BSTATUS_LINKSTATUS_MASK & regValue) != 0U) | ||||||
|  |         { | ||||||
|  |             /* Link up. */ | ||||||
|  |             *status = true; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             /* Link down. */ | ||||||
|  |             *status = false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ8081_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex) | ||||||
|  | { | ||||||
|  |     assert(!((speed == NULL) && (duplex == NULL))); | ||||||
|  | 
 | ||||||
|  |     status_t result; | ||||||
|  |     uint32_t regValue; | ||||||
|  |     uint32_t flag; | ||||||
|  | 
 | ||||||
|  |     /* Read the control register. */ | ||||||
|  |     result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_CONTROL1_REG, ®Value); | ||||||
|  |     if (result == kStatus_Success) | ||||||
|  |     { | ||||||
|  |         if (speed != NULL) | ||||||
|  |         { | ||||||
|  |             flag = regValue & PHY_CTL1_SPEEDUPLX_MASK; | ||||||
|  |             if ((PHY_CTL1_100HALFDUPLEX_MASK == flag) || (PHY_CTL1_100FULLDUPLEX_MASK == flag)) | ||||||
|  |             { | ||||||
|  |                 *speed = kPHY_Speed100M; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 *speed = kPHY_Speed10M; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (duplex != NULL) | ||||||
|  |         { | ||||||
|  |             flag = regValue & PHY_CTL1_SPEEDUPLX_MASK; | ||||||
|  |             if ((PHY_CTL1_10FULLDUPLEX_MASK == flag) || (PHY_CTL1_100FULLDUPLEX_MASK == flag)) | ||||||
|  |             { | ||||||
|  |                 *duplex = kPHY_FullDuplex; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 *duplex = kPHY_HalfDuplex; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ8081_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex) | ||||||
|  | { | ||||||
|  |     /* This PHY only supports 10/100M speed. */ | ||||||
|  |     assert(speed <= kPHY_Speed100M); | ||||||
|  | 
 | ||||||
|  |     status_t result; | ||||||
|  |     uint32_t regValue; | ||||||
|  | 
 | ||||||
|  |     result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); | ||||||
|  |     if (result == kStatus_Success) | ||||||
|  |     { | ||||||
|  |         /* Disable the auto-negotiation and set according to user-defined configuration. */ | ||||||
|  |         regValue &= ~PHY_BCTL_AUTONEG_MASK; | ||||||
|  |         if (speed == kPHY_Speed100M) | ||||||
|  |         { | ||||||
|  |             regValue |= PHY_BCTL_SPEED0_MASK; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             regValue &= ~PHY_BCTL_SPEED0_MASK; | ||||||
|  |         } | ||||||
|  |         if (duplex == kPHY_FullDuplex) | ||||||
|  |         { | ||||||
|  |             regValue |= PHY_BCTL_DUPLEX_MASK; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             regValue &= ~PHY_BCTL_DUPLEX_MASK; | ||||||
|  |         } | ||||||
|  |         result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); | ||||||
|  |     } | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ8081_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable) | ||||||
|  | { | ||||||
|  |     /* This PHY only supports local/remote loopback and 10/100M speed. */ | ||||||
|  |     assert(mode <= kPHY_RemoteLoop); | ||||||
|  |     assert(speed <= kPHY_Speed100M); | ||||||
|  | 
 | ||||||
|  |     status_t result; | ||||||
|  |     uint32_t regValue; | ||||||
|  | 
 | ||||||
|  |     /* Set the loop mode. */ | ||||||
|  |     if (enable) | ||||||
|  |     { | ||||||
|  |         if (mode == kPHY_LocalLoop) | ||||||
|  |         { | ||||||
|  |             if (speed == kPHY_Speed100M) | ||||||
|  |             { | ||||||
|  |                 regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 regValue = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; | ||||||
|  |             } | ||||||
|  |             return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             /* Remote loopback only supports 100M full-duplex. */ | ||||||
|  |             assert(speed == kPHY_Speed100M); | ||||||
|  | 
 | ||||||
|  |             regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; | ||||||
|  |             result   = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); | ||||||
|  |             if (result != kStatus_Success) | ||||||
|  |             { | ||||||
|  |                 return result; | ||||||
|  |             } | ||||||
|  |             /* Set the remote loopback bit. */ | ||||||
|  |             result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, ®Value); | ||||||
|  |             if (result == kStatus_Success) | ||||||
|  |             { | ||||||
|  |                 return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, | ||||||
|  |                                   (regValue | PHY_CTL2_REMOTELOOP_MASK)); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         /* Disable the loop mode. */ | ||||||
|  |         if (mode == kPHY_LocalLoop) | ||||||
|  |         { | ||||||
|  |             /* First read the current status in control register. */ | ||||||
|  |             result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); | ||||||
|  |             if (result == kStatus_Success) | ||||||
|  |             { | ||||||
|  |                 regValue &= ~PHY_BCTL_LOOP_MASK; | ||||||
|  |                 return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, | ||||||
|  |                                   (regValue | PHY_BCTL_RESTART_AUTONEG_MASK)); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             /* First read the current status in control one register. */ | ||||||
|  |             result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, ®Value); | ||||||
|  |             if (result == kStatus_Success) | ||||||
|  |             { | ||||||
|  |                 return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, | ||||||
|  |                                   (regValue & ~PHY_CTL2_REMOTELOOP_MASK)); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,163 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2020 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*****************************************************************************
 | ||||||
|  |  * PHY KSZ8081 driver change log | ||||||
|  |  *****************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  | @page driver_log Driver Change Log | ||||||
|  | 
 | ||||||
|  | @section phyksz8081 PHYKSZ8081 | ||||||
|  |   The current PHYKSZ8081 driver version is 2.0.0. | ||||||
|  | 
 | ||||||
|  |   - 2.0.0 | ||||||
|  |     - Initial version. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #ifndef _FSL_PHYKSZ8081_H_ | ||||||
|  | #define _FSL_PHYKSZ8081_H_ | ||||||
|  | 
 | ||||||
|  | #include "fsl_phy.h" | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @addtogroup phy_driver | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*! @brief PHY driver version */ | ||||||
|  | #define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) | ||||||
|  | 
 | ||||||
|  | /*! @brief PHY operations structure. */ | ||||||
|  | extern const phy_operations_t phyksz8081_ops; | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * API | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @name PHY Driver | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Initializes PHY. | ||||||
|  |  * | ||||||
|  |  *  This function initialize PHY. | ||||||
|  |  * | ||||||
|  |  * @param handle       PHY device handle. | ||||||
|  |  * @param config       Pointer to structure of phy_config_t. | ||||||
|  |  * @retval kStatus_Success  PHY initialization succeeds | ||||||
|  |  * @retval kStatus_Fail  PHY initialization fails | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ8081_Init(phy_handle_t *handle, const phy_config_t *config); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief PHY Write function. This function writes data over the SMI to | ||||||
|  |  * the specified PHY register. This function is called by all PHY interfaces. | ||||||
|  |  * | ||||||
|  |  * @param handle  PHY device handle. | ||||||
|  |  * @param phyReg  The PHY register. | ||||||
|  |  * @param data    The data written to the PHY register. | ||||||
|  |  * @retval kStatus_Success     PHY write success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ8081_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief PHY Read function. This interface read data over the SMI from the | ||||||
|  |  * specified PHY register. This function is called by all PHY interfaces. | ||||||
|  |  * | ||||||
|  |  * @param handle   PHY device handle. | ||||||
|  |  * @param phyReg   The PHY register. | ||||||
|  |  * @param dataPtr  The address to store the data read from the PHY register. | ||||||
|  |  * @retval kStatus_Success  PHY read success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ8081_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Gets the PHY auto-negotiation status. | ||||||
|  |  * | ||||||
|  |  * @param handle   PHY device handle. | ||||||
|  |  * @param status   The auto-negotiation status of the PHY. | ||||||
|  |  *         - true the auto-negotiation is over. | ||||||
|  |  *         - false the auto-negotiation is on-going or not started. | ||||||
|  |  * @retval kStatus_Success   PHY gets status success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ8081_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Gets the PHY link status. | ||||||
|  |  * | ||||||
|  |  * @param handle   PHY device handle. | ||||||
|  |  * @param status   The link up or down status of the PHY. | ||||||
|  |  *         - true the link is up. | ||||||
|  |  *         - false the link is down. | ||||||
|  |  * @retval kStatus_Success   PHY gets link status success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ8081_GetLinkStatus(phy_handle_t *handle, bool *status); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Gets the PHY link speed and duplex. | ||||||
|  |  * | ||||||
|  |  * @brief This function gets the speed and duplex mode of PHY. User can give one of speed | ||||||
|  |  * and duplex address paramter and set the other as NULL if only wants to get one of them. | ||||||
|  |  * | ||||||
|  |  * @param handle   PHY device handle. | ||||||
|  |  * @param speed    The address of PHY link speed. | ||||||
|  |  * @param duplex   The link duplex of PHY. | ||||||
|  |  * @retval kStatus_Success   PHY gets link speed and duplex success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ8081_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Sets the PHY link speed and duplex. | ||||||
|  |  * | ||||||
|  |  * @param handle   PHY device handle. | ||||||
|  |  * @param speed    Specified PHY link speed. | ||||||
|  |  * @param duplex   Specified PHY link duplex. | ||||||
|  |  * @retval kStatus_Success   PHY gets status success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ8081_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Enables/disables PHY loopback. | ||||||
|  |  * | ||||||
|  |  * @param handle   PHY device handle. | ||||||
|  |  * @param mode     The loopback mode to be enabled, please see "phy_loop_t". | ||||||
|  |  * All loopback modes should not be set together, when one loopback mode is set | ||||||
|  |  * another should be disabled. | ||||||
|  |  * @param speed    PHY speed for loopback mode. | ||||||
|  |  * @param enable   True to enable, false to disable. | ||||||
|  |  * @retval kStatus_Success  PHY loopback success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ8081_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable); | ||||||
|  | 
 | ||||||
|  | /* @} */ | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*! @}*/ | ||||||
|  | 
 | ||||||
|  | #endif /* _FSL_PHYKSZ8081_H_ */ | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | SRC_FILES := fsl_phyksz9131rnx.c | ||||||
|  | 
 | ||||||
|  | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | @ -0,0 +1,302 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2020 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "fsl_phyksz9131rnx.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the PHY RTL8211F vendor defined registers. */ | ||||||
|  | #define PHY_SPECIFIC_STATUS_REG 0x01U /*!< The PHY specific status register. */ | ||||||
|  | #define PHY_PAGE_SELECT_REG     0x1FU /*!< The PHY page select register. */ | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the PHY RTL8211F ID number. */ | ||||||
|  | #define PHY_CONTROL_ID1 0x0022U /*!< The PHY ID1 . */ | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the mask flag in specific status register. */ | ||||||
|  | #define PHY_SSTATUS_LINKSTATUS_MASK 0x04U /*!< The PHY link status mask. */ | ||||||
|  | #define PHY_SSTATUS_LINKSPEED_MASK  0x30U /*!< The PHY link speed mask. */ | ||||||
|  | #define PHY_SSTATUS_LINKDUPLEX_MASK 0x08U /*!< The PHY link duplex mask. */ | ||||||
|  | #define PHY_SSTATUS_LINKSPEED_SHIFT 4U    /*!< The link speed shift */ | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the PHY RTL8211F extra page and the registers in specified page. */ | ||||||
|  | #define PHY_PAGE_RGMII_TXRX_DELAY_ADDR 0xD08U /*!< The register page including RGMII TX/RX delay setting. */ | ||||||
|  | #define PHY_RGMII_TX_DELAY_REG         0x11U  /*!< The RGMII TXC delay register. */ | ||||||
|  | #define PHY_RGMII_RX_DELAY_REG         0x15U  /*!< The RGMII RXC delay register. */ | ||||||
|  | #define PHY_RGMII_TX_DELAY_MASK        0x100U /*!< The RGMII TXC delay mask. */ | ||||||
|  | #define PHY_RGMII_RX_DELAY_MASK        0x8U   /*!< The RGMII RXC delay mask. */ | ||||||
|  | 
 | ||||||
|  | /*! @brief MDIO MMD Devices .*/ | ||||||
|  | #define PHY_MDIO_MMD_PCS 3U | ||||||
|  | #define PHY_MDIO_MMD_AN  7U | ||||||
|  | 
 | ||||||
|  | /*! @brief MDIO MMD Physical Coding layer device registers .*/ | ||||||
|  | #define PHY_MDIO_PCS_EEE_CAP 0x14U /* EEE capability */ | ||||||
|  | 
 | ||||||
|  | /*! @brief MDIO MMD AutoNegotiation device registers .*/ | ||||||
|  | #define PHY_MDIO_AN_EEE_ADV 0x3CU /* EEE advertisement */ | ||||||
|  | 
 | ||||||
|  | /*! @brief MDIO MMD EEE mask flags. (common for adv and cap) */ | ||||||
|  | #define PHY_MDIO_EEE_100TX 0x2U | ||||||
|  | #define PHY_MDIO_EEE_1000T 0x4U | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the timeout macro. */ | ||||||
|  | #define PHY_READID_TIMEOUT_COUNT 1000U | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Prototypes | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Variables | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | const phy_operations_t phyksz9131rnx_ops = {.phyInit            = PHY_KSZ9131RNX_Init, | ||||||
|  |                                           .phyWrite           = PHY_KSZ9131RNX_Write, | ||||||
|  |                                           .phyRead            = PHY_KSZ9131RNX_Read, | ||||||
|  |                                           .getAutoNegoStatus  = PHY_KSZ9131RNX_GetAutoNegotiationStatus, | ||||||
|  |                                           .getLinkStatus      = PHY_KSZ9131RNX_GetLinkStatus, | ||||||
|  |                                           .getLinkSpeedDuplex = PHY_KSZ9131RNX_GetLinkSpeedDuplex, | ||||||
|  |                                           .setLinkSpeedDuplex = PHY_KSZ9131RNX_SetLinkSpeedDuplex, | ||||||
|  |                                           .enableLoopback     = PHY_KSZ9131RNX_EnableLoopback}; | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Code | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ9131RNX_Init(phy_handle_t *handle, const phy_config_t *config) | ||||||
|  | { | ||||||
|  |     uint32_t counter = PHY_READID_TIMEOUT_COUNT; | ||||||
|  |     status_t result; | ||||||
|  |     uint32_t regValue = 0U; | ||||||
|  | 
 | ||||||
|  |     /* Init MDIO interface. */ | ||||||
|  |     MDIO_Init(handle->mdioHandle); | ||||||
|  | 
 | ||||||
|  |     /* Assign phy address. */ | ||||||
|  |     handle->phyAddr = config->phyAddr; | ||||||
|  | 
 | ||||||
|  |     /* Check PHY ID. */ | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  |         result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_ID1_REG, ®Value); | ||||||
|  |         if (result != kStatus_Success) | ||||||
|  |         { | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|  |         counter--; | ||||||
|  |     } while ((regValue != PHY_CONTROL_ID1) && (counter != 0U)); | ||||||
|  | 
 | ||||||
|  |     if (counter == 0U) | ||||||
|  |     { | ||||||
|  |         return kStatus_Fail; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* Reset PHY. */ | ||||||
|  |     result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK); | ||||||
|  |     if (result != kStatus_Success) | ||||||
|  |     { | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* Set the negotiation. */ | ||||||
|  |     result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_AUTONEG_ADVERTISE_REG, | ||||||
|  |                         (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK | PHY_10BASETX_FULLDUPLEX_MASK | | ||||||
|  |                          PHY_10BASETX_HALFDUPLEX_MASK)); | ||||||
|  |     if (result == kStatus_Success) | ||||||
|  |     { | ||||||
|  |         result = | ||||||
|  |             MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_1000BASET_CONTROL_REG, PHY_1000BASET_FULLDUPLEX_MASK); | ||||||
|  |         if (result == kStatus_Success) | ||||||
|  |         { | ||||||
|  |             result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); | ||||||
|  |             result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, | ||||||
|  |                                 (regValue | PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ9131RNX_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data) | ||||||
|  | { | ||||||
|  |     return MDIO_Write(handle->mdioHandle, handle->phyAddr, phyReg, data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ9131RNX_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr) | ||||||
|  | { | ||||||
|  |     return MDIO_Read(handle->mdioHandle, handle->phyAddr, phyReg, dataPtr); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ9131RNX_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status) | ||||||
|  | { | ||||||
|  |     assert(status); | ||||||
|  | 
 | ||||||
|  |     status_t result; | ||||||
|  |     uint32_t regValue; | ||||||
|  | 
 | ||||||
|  |     *status = false; | ||||||
|  | 
 | ||||||
|  |     /* Check auto negotiation complete. */ | ||||||
|  |     result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, ®Value); | ||||||
|  |     if (result == kStatus_Success) | ||||||
|  |     { | ||||||
|  |         if ((regValue & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0U) | ||||||
|  |         { | ||||||
|  |             *status = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ9131RNX_GetLinkStatus(phy_handle_t *handle, bool *status) | ||||||
|  | { | ||||||
|  |     assert(status); | ||||||
|  | 
 | ||||||
|  |     status_t result; | ||||||
|  |     uint32_t regValue; | ||||||
|  | 
 | ||||||
|  |     /* Read the basic status register. */ | ||||||
|  |     result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_SPECIFIC_STATUS_REG, ®Value); | ||||||
|  |     if (result == kStatus_Success) | ||||||
|  |     { | ||||||
|  |         if ((PHY_SSTATUS_LINKSTATUS_MASK & regValue) != 0U) | ||||||
|  |         { | ||||||
|  |             /* Link up. */ | ||||||
|  |             *status = true; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             /* Link down. */ | ||||||
|  |             *status = false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ9131RNX_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex) | ||||||
|  | { | ||||||
|  |     assert(!((speed == NULL) && (duplex == NULL))); | ||||||
|  | 
 | ||||||
|  |     status_t result; | ||||||
|  |     uint32_t regValue; | ||||||
|  | 
 | ||||||
|  |     /* Read the status register. */ | ||||||
|  |     result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_SPECIFIC_STATUS_REG, ®Value); | ||||||
|  |     if (result == kStatus_Success) | ||||||
|  |     { | ||||||
|  |         if (speed != NULL) | ||||||
|  |         { | ||||||
|  |             switch ((regValue & PHY_SSTATUS_LINKSPEED_MASK) >> PHY_SSTATUS_LINKSPEED_SHIFT) | ||||||
|  |             { | ||||||
|  |                 case (uint32_t)kPHY_Speed10M: | ||||||
|  |                     *speed = kPHY_Speed10M; | ||||||
|  |                     break; | ||||||
|  |                 case (uint32_t)kPHY_Speed100M: | ||||||
|  |                     *speed = kPHY_Speed100M; | ||||||
|  |                     break; | ||||||
|  |                 case (uint32_t)kPHY_Speed1000M: | ||||||
|  |                     *speed = kPHY_Speed1000M; | ||||||
|  |                     break; | ||||||
|  |                 default: | ||||||
|  |                     *speed = kPHY_Speed10M; | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (duplex != NULL) | ||||||
|  |         { | ||||||
|  |             if ((regValue & PHY_SSTATUS_LINKDUPLEX_MASK) != 0U) | ||||||
|  |             { | ||||||
|  |                 *duplex = kPHY_FullDuplex; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 *duplex = kPHY_HalfDuplex; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ9131RNX_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex) | ||||||
|  | { | ||||||
|  |     status_t result; | ||||||
|  |     uint32_t regValue; | ||||||
|  | 
 | ||||||
|  |     result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); | ||||||
|  |     if (result == kStatus_Success) | ||||||
|  |     { | ||||||
|  |         /* Disable the auto-negotiation and set according to user-defined configuration. */ | ||||||
|  |         regValue &= ~PHY_BCTL_AUTONEG_MASK; | ||||||
|  |         if (speed == kPHY_Speed1000M) | ||||||
|  |         { | ||||||
|  |             regValue &= PHY_BCTL_SPEED0_MASK; | ||||||
|  |             regValue |= PHY_BCTL_SPEED1_MASK; | ||||||
|  |         } | ||||||
|  |         else if (speed == kPHY_Speed100M) | ||||||
|  |         { | ||||||
|  |             regValue |= PHY_BCTL_SPEED0_MASK; | ||||||
|  |             regValue &= ~PHY_BCTL_SPEED1_MASK; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             regValue &= ~PHY_BCTL_SPEED0_MASK; | ||||||
|  |             regValue &= ~PHY_BCTL_SPEED1_MASK; | ||||||
|  |         } | ||||||
|  |         if (duplex == kPHY_FullDuplex) | ||||||
|  |         { | ||||||
|  |             regValue |= PHY_BCTL_DUPLEX_MASK; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             regValue &= ~PHY_BCTL_DUPLEX_MASK; | ||||||
|  |         } | ||||||
|  |         result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); | ||||||
|  |     } | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | status_t PHY_KSZ9131RNX_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable) | ||||||
|  | { | ||||||
|  |     /* This PHY only supports local loopback. */ | ||||||
|  |     assert(mode == kPHY_LocalLoop); | ||||||
|  | 
 | ||||||
|  |     status_t result; | ||||||
|  |     uint32_t regValue; | ||||||
|  | 
 | ||||||
|  |     /* Set the loop mode. */ | ||||||
|  |     if (enable) | ||||||
|  |     { | ||||||
|  |         if (speed == kPHY_Speed1000M) | ||||||
|  |         { | ||||||
|  |             regValue = PHY_BCTL_SPEED1_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; | ||||||
|  |         } | ||||||
|  |         else if (speed == kPHY_Speed100M) | ||||||
|  |         { | ||||||
|  |             regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             regValue = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; | ||||||
|  |         } | ||||||
|  |         result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         /* First read the current status in control register. */ | ||||||
|  |         result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, ®Value); | ||||||
|  |         if (result == kStatus_Success) | ||||||
|  |         { | ||||||
|  |             regValue &= ~PHY_BCTL_LOOP_MASK; | ||||||
|  |             result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, | ||||||
|  |                                 (regValue | PHY_BCTL_RESTART_AUTONEG_MASK)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,163 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2020 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*****************************************************************************
 | ||||||
|  |  * PHY KSZ9131RNX driver change log | ||||||
|  |  *****************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  | @page driver_log Driver Change Log | ||||||
|  | 
 | ||||||
|  | @section phyrtl8211 PHYKSZ9131RNX | ||||||
|  |   The current PHYKSZ9131RNX driver version is 2.0.0. | ||||||
|  | 
 | ||||||
|  |   - 2.0.0 | ||||||
|  |     - Initial version. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #ifndef _FSL_PHYKSZ9131RNX_H_ | ||||||
|  | #define _FSL_PHYKSZ9131RNX_H_ | ||||||
|  | 
 | ||||||
|  | #include "fsl_phy.h" | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @addtogroup phy_driver | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*! @brief PHY driver version */ | ||||||
|  | #define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) | ||||||
|  | 
 | ||||||
|  | /*! @brief PHY operations structure. */ | ||||||
|  | extern const phy_operations_t phyksz9131rnx_ops; | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * API | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @name PHY Driver | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Initializes PHY. | ||||||
|  |  * | ||||||
|  |  *  This function initialize PHY. | ||||||
|  |  * | ||||||
|  |  * @param handle       PHY device handle. | ||||||
|  |  * @param config       Pointer to structure of phy_config_t. | ||||||
|  |  * @retval kStatus_Success  PHY initialization succeeds | ||||||
|  |  * @retval kStatus_Fail  PHY initialization fails | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ9131RNX_Init(phy_handle_t *handle, const phy_config_t *config); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief PHY Write function. This function writes data over the SMI to | ||||||
|  |  * the specified PHY register. This function is called by all PHY interfaces. | ||||||
|  |  * | ||||||
|  |  * @param handle  PHY device handle. | ||||||
|  |  * @param phyReg  The PHY register. | ||||||
|  |  * @param data    The data written to the PHY register. | ||||||
|  |  * @retval kStatus_Success     PHY write success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ9131RNX_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief PHY Read function. This interface reads data over the SMI from the | ||||||
|  |  * specified PHY register. This function is called by all PHY interfaces. | ||||||
|  |  * | ||||||
|  |  * @param handle   PHY device handle. | ||||||
|  |  * @param phyReg   The PHY register. | ||||||
|  |  * @param dataPtr  The address to store the data read from the PHY register. | ||||||
|  |  * @retval kStatus_Success  PHY read success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ9131RNX_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Gets the PHY auto-negotiation status. | ||||||
|  |  * | ||||||
|  |  * @param handle   PHY device handle. | ||||||
|  |  * @param status   The auto-negotiation status of the PHY. | ||||||
|  |  *         - true the auto-negotiation is over. | ||||||
|  |  *         - false the auto-negotiation is on-going or not started. | ||||||
|  |  * @retval kStatus_Success   PHY gets status success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ9131RNX_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Gets the PHY link status. | ||||||
|  |  * | ||||||
|  |  * @param handle   PHY device handle. | ||||||
|  |  * @param status   The link up or down status of the PHY. | ||||||
|  |  *         - true the link is up. | ||||||
|  |  *         - false the link is down. | ||||||
|  |  * @retval kStatus_Success   PHY gets link status success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ9131RNX_GetLinkStatus(phy_handle_t *handle, bool *status); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Gets the PHY link speed and duplex. | ||||||
|  |  * | ||||||
|  |  * @brief This function gets the speed and duplex mode of PHY. User can give one of speed | ||||||
|  |  * and duplex address paramter and set the other as NULL if only wants to get one of them. | ||||||
|  |  * | ||||||
|  |  * @param handle   PHY device handle. | ||||||
|  |  * @param speed    The address of PHY link speed. | ||||||
|  |  * @param duplex   The link duplex of PHY. | ||||||
|  |  * @retval kStatus_Success   PHY gets link speed and duplex success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ9131RNX_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Sets the PHY link speed and duplex. | ||||||
|  |  * | ||||||
|  |  * @param handle   PHY device handle. | ||||||
|  |  * @param speed    Specified PHY link speed. | ||||||
|  |  * @param duplex   Specified PHY link duplex. | ||||||
|  |  * @retval kStatus_Success   PHY gets status success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ9131RNX_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex); | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Enables/disables PHY loopback. | ||||||
|  |  * | ||||||
|  |  * @param handle   PHY device handle. | ||||||
|  |  * @param mode     The loopback mode to be enabled, please see "phy_loop_t". | ||||||
|  |  * All loopback modes should not be set together, when one loopback mode is set | ||||||
|  |  * another should be disabled. | ||||||
|  |  * @param speed    PHY speed for loopback mode. | ||||||
|  |  * @param enable   True to enable, false to disable. | ||||||
|  |  * @retval kStatus_Success  PHY loopback success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | status_t PHY_KSZ9131RNX_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable); | ||||||
|  | 
 | ||||||
|  | /* @} */ | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*! @}*/ | ||||||
|  | 
 | ||||||
|  | #endif /* _FSL_PHY_H_ */ | ||||||
|  | @ -1,3 +1,3 @@ | ||||||
| SRC_FILES := connect_gpio.c fsl_gpio.c | SRC_FILES := fsl_gpio.c | ||||||
| 
 | 
 | ||||||
| include $(KERNEL_ROOT)/compiler.mk | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | @ -0,0 +1,42 @@ | ||||||
|  | /*
 | ||||||
|  | * Copyright (c) 2021 AIIT XUOS Lab | ||||||
|  | * XiUOS is licensed under Mulan PSL v2. | ||||||
|  | * You can use this software according to the terms and conditions of the Mulan PSL v2. | ||||||
|  | * You may obtain a copy of Mulan PSL v2 at: | ||||||
|  | *        http://license.coscl.org.cn/MulanPSL2
 | ||||||
|  | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||||||
|  | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||||||
|  | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||||||
|  | * See the Mulan PSL v2 for more details. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  | * @file connect_ethernet.h | ||||||
|  | * @brief Adapted network software protocol stack and hardware operation functions | ||||||
|  | * @version 1.0 | ||||||
|  | * @author AIIT XUOS Lab | ||||||
|  | * @date 2021-12-7 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #ifndef __CONNECT_ETHERNET_H_ | ||||||
|  | #define __CONNECT_ETHERNET_H_ | ||||||
|  | 
 | ||||||
|  | #include "enet_ethernetif.h" | ||||||
|  | #include "enet_ethernetif_priv.h" | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  |  extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifndef sourceClock | ||||||
|  | #define sourceClock CLOCK_GetFreq(kCLOCK_CoreSysClk) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,171 @@ | ||||||
|  | /*
 | ||||||
|  |  * 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: Adam Dunkels <adam@sics.se> | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2013-2016, Freescale Semiconductor, Inc. | ||||||
|  |  * Copyright 2016-2021 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef ENET_ETHERNETIF_H | ||||||
|  | #define ENET_ETHERNETIF_H | ||||||
|  | 
 | ||||||
|  | #include "lwip/err.h" | ||||||
|  | #include "lwip/netif.h" | ||||||
|  | #include "fsl_phy.h" | ||||||
|  | #include <board.h> | ||||||
|  | #ifdef BOARD_NETWORK_USE_100M_ENET_PORT | ||||||
|  | #include "fsl_phyksz8081.h" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef BOARD_NETWORK_USE_1G_ENET_PORT | ||||||
|  | #include "fsl_phyksz9131rnx.h" | ||||||
|  | #endif | ||||||
|  | #include "fsl_enet_mdio.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | #ifdef BOARD_NETWORK_USE_100M_ENET_PORT | ||||||
|  | /* Address of PHY interface. */ | ||||||
|  | #define EXAMPLE_ENET0_PHY_ADDRESS BOARD_ENET0_PHY_ADDRESS | ||||||
|  | /* PHY operations. */ | ||||||
|  | #define EXAMPLE_ENET0_PHY_OPS phyksz8081_ops | ||||||
|  | /* ENET instance select. */ | ||||||
|  | #define NETIF_ENET0_INIT_FUNC ethernetif0_init | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef BOARD_NETWORK_USE_1G_ENET_PORT | ||||||
|  | /* Address of PHY interface. */ | ||||||
|  | #define EXAMPLE_ENET1_PHY_ADDRESS   BOARD_ENET1_PHY_ADDRESS | ||||||
|  | /* PHY operations. */ | ||||||
|  | #define EXAMPLE_ENET1_PHY_OPS       phyksz9131rnx_ops | ||||||
|  | /* ENET instance select. */ | ||||||
|  | #define NETIF_ENET1_INIT_FUNC ethernetif1_init | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* MDIO operations. */ | ||||||
|  | #define EXAMPLE_MDIO_OPS enet_ops | ||||||
|  | 
 | ||||||
|  | /* ENET clock frequency. */ | ||||||
|  | #define EXAMPLE_CLOCK_FREQ CLOCK_GetRootClockFreq(kCLOCK_Root_Bus) | ||||||
|  | 
 | ||||||
|  | #define ENET_TIMEOUT        (0xFFFU) | ||||||
|  | 
 | ||||||
|  | /* ENET IRQ priority. Used in FreeRTOS. */ | ||||||
|  | /* Interrupt priorities. */ | ||||||
|  | #ifdef __CA7_REV | ||||||
|  | #ifndef ENET_PRIORITY | ||||||
|  |     #define ENET_PRIORITY       (21U) | ||||||
|  | #endif | ||||||
|  | #ifndef ENET_1588_PRIORITY | ||||||
|  |     #define ENET_1588_PRIORITY  (20U) | ||||||
|  | #endif | ||||||
|  | #else | ||||||
|  | #ifndef ENET_PRIORITY | ||||||
|  |     #define ENET_PRIORITY       (6U) | ||||||
|  | #endif | ||||||
|  | #ifndef ENET_1588_PRIORITY | ||||||
|  |     #define ENET_1588_PRIORITY  (5U) | ||||||
|  | #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*  Defines Ethernet Autonegotiation Timeout during initialization. 
 | ||||||
|  |  *  Set it to 0 to disable the waiting. */  | ||||||
|  | #ifndef ENET_ATONEGOTIATION_TIMEOUT | ||||||
|  |     #define ENET_ATONEGOTIATION_TIMEOUT     (0x2FFFFU) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* Define those to better describe your network interface. */ | ||||||
|  | #define IFNAME0 'e' | ||||||
|  | #define IFNAME1 'n' | ||||||
|  | 
 | ||||||
|  | #define ENET_RING_NUM 1U | ||||||
|  | 
 | ||||||
|  | #if (defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)) | ||||||
|  | typedef struct mem_range | ||||||
|  | { | ||||||
|  |     uint32_t start; | ||||||
|  |     uint32_t end; | ||||||
|  | } mem_range_t; | ||||||
|  | #endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Helper struct to hold data for configuration of ethernet interface. | ||||||
|  |  */ | ||||||
|  | typedef struct ethernetif_config | ||||||
|  | { | ||||||
|  |     phy_handle_t *phyHandle; | ||||||
|  |     uint8_t macAddress[NETIF_MAX_HWADDR_LEN]; | ||||||
|  | #if (defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)) | ||||||
|  |     const mem_range_t *non_dma_memory; | ||||||
|  | #endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */ | ||||||
|  | } ethernetif_config_t; | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | extern "C" { | ||||||
|  | #endif /* __cplusplus */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * This function should be passed as a parameter to netif_add() | ||||||
|  |  * if you initialize the first ENET interface. | ||||||
|  |  */ | ||||||
|  | err_t ethernetif0_init(struct netif *netif); | ||||||
|  | 
 | ||||||
|  | #if (defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 1)) \ | ||||||
|  |  || (defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 1)) | ||||||
|  | /**
 | ||||||
|  |  * This function should be passed as a parameter to netif_add() | ||||||
|  |  * if you initialize the second ENET interface. | ||||||
|  |  */ | ||||||
|  | err_t ethernetif1_init(struct netif *netif); | ||||||
|  | #endif /* FSL_FEATURE_SOC_*_ENET_COUNT */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * This function should be called when a packet is ready to be read | ||||||
|  |  * from the interface.  | ||||||
|  |  * It is used by bare-metal applications. | ||||||
|  |  * | ||||||
|  |  * @param netif the lwip network interface structure for this ethernetif | ||||||
|  |  */ | ||||||
|  | void ethernetif_input( struct netif *netif); | ||||||
|  | 
 | ||||||
|  | int ETH_BSP_Config(void); | ||||||
|  | void *ethernetif_config_enet_set(uint8_t enet_port); | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | } | ||||||
|  | #endif /* __cplusplus */ | ||||||
|  | 
 | ||||||
|  | #endif /* ENET_ETHERNETIF_H */ | ||||||
|  | @ -0,0 +1,80 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2019 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef ENET_ETHERNETIF_PRIV_H | ||||||
|  | #define ENET_ETHERNETIF_PRIV_H | ||||||
|  | 
 | ||||||
|  | #include "lwip/err.h" | ||||||
|  | 
 | ||||||
|  | struct ethernetif; | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | extern "C" { | ||||||
|  | #endif /* __cplusplus */ | ||||||
|  | 
 | ||||||
|  | err_t ethernetif_init(struct netif *netif, struct ethernetif *ethernetif, | ||||||
|  |                       void *enetBase, | ||||||
|  |                       const ethernetif_config_t *ethernetifConfig); | ||||||
|  | 
 | ||||||
|  | void ethernetif_enet_init(struct netif *netif, struct ethernetif *ethernetif, | ||||||
|  |                           const ethernetif_config_t *ethernetifConfig); | ||||||
|  | 
 | ||||||
|  | void ethernetif_phy_init(struct ethernetif *ethernetif, | ||||||
|  |                          const ethernetif_config_t *ethernetifConfig, | ||||||
|  |                          phy_speed_t *speed, | ||||||
|  |                          phy_duplex_t *duplex); | ||||||
|  | 
 | ||||||
|  | void *ethernetif_get_enet_base(const uint8_t enetIdx); | ||||||
|  | 
 | ||||||
|  | #if defined(FSL_FEATURE_SOC_ENET_QOS_COUNT) && (FSL_FEATURE_SOC_ENET_QOS_COUNT > 0) | ||||||
|  | void *ethernetif_get_enet_qos_base(const uint8_t enetIdx); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | void **ethernetif_enet_ptr(struct ethernetif *ethernetif); | ||||||
|  | 
 | ||||||
|  | #if LWIP_IPV4 && LWIP_IGMP | ||||||
|  | err_t ethernetif_igmp_mac_filter(struct netif *netif, const ip4_addr_t *group, | ||||||
|  |                                  enum netif_mac_filter_action action); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if LWIP_IPV6 && LWIP_IPV6_MLD | ||||||
|  | err_t ethernetif_mld_mac_filter(struct netif *netif, const ip6_addr_t *group, | ||||||
|  |                                 enum netif_mac_filter_action action); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * 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 | ||||||
|  |  */ | ||||||
|  | struct pbuf *ethernetif_linkinput(struct netif *netif); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * 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). | ||||||
|  |  */ | ||||||
|  | err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p); | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | } | ||||||
|  | #endif /* __cplusplus */ | ||||||
|  | 
 | ||||||
|  | #endif /* ENET_ETHERNETIF_PRIV_H */ | ||||||
|  | @ -28,7 +28,6 @@ Modification: | ||||||
| #ifndef __FSL_DEVICE_REGISTERS_H__ | #ifndef __FSL_DEVICE_REGISTERS_H__ | ||||||
| #define __FSL_DEVICE_REGISTERS_H__ | #define __FSL_DEVICE_REGISTERS_H__ | ||||||
| 
 | 
 | ||||||
| #define CPU_MIMXRT1176DVMAA_cm7 |  | ||||||
| /*
 | /*
 | ||||||
|  * Include the cpu specific register header files. |  * Include the cpu specific register header files. | ||||||
|  * |  * | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -0,0 +1,128 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2020-2021 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | #ifndef _FSL_MDIO_H_ | ||||||
|  | #define _FSL_MDIO_H_ | ||||||
|  | 
 | ||||||
|  | #include "fsl_common.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the timeout macro. */ | ||||||
|  | #if defined(MDIO_TIMEOUT_COUNT_NUMBER) && MDIO_TIMEOUT_COUNT_NUMBER | ||||||
|  | #define MDIO_TIMEOUT_COUNT MDIO_TIMEOUT_COUNT_NUMBER | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the PHY status. */ | ||||||
|  | enum _mdio_status | ||||||
|  | { | ||||||
|  |     kStatus_PHY_SMIVisitTimeout = MAKE_STATUS(kStatusGroup_PHY, 0), /*!< ENET PHY SMI visit timeout. */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | typedef struct _mdio_operations mdio_operations_t; | ||||||
|  | 
 | ||||||
|  | /*! @brief MDIO resource. */ | ||||||
|  | typedef struct _mdio_resource | ||||||
|  | { | ||||||
|  |     void *base;           /*!< ENET Ip register base. */ | ||||||
|  |     uint32_t csrClock_Hz; /*!< ENET CSR clock. */ | ||||||
|  | } mdio_resource_t; | ||||||
|  | 
 | ||||||
|  | /*! @brief MDIO handle. */ | ||||||
|  | typedef struct _mdio_handle | ||||||
|  | { | ||||||
|  |     mdio_resource_t resource; | ||||||
|  |     const mdio_operations_t *ops; | ||||||
|  | } mdio_handle_t; | ||||||
|  | 
 | ||||||
|  | /*! @brief Camera receiver operations. */ | ||||||
|  | struct _mdio_operations | ||||||
|  | { | ||||||
|  |     void (*mdioInit)(mdio_handle_t *handle); /*!< MDIO interface init. */ | ||||||
|  |     status_t (*mdioWrite)(mdio_handle_t *handle, | ||||||
|  |                           uint32_t phyAddr, | ||||||
|  |                           uint32_t devAddr, | ||||||
|  |                           uint32_t data); /*!< IEEE 802.3 Clause 22 MDIO write data. */ | ||||||
|  |     status_t (*mdioRead)(mdio_handle_t *handle, | ||||||
|  |                          uint32_t phyAddr, | ||||||
|  |                          uint32_t devAddr, | ||||||
|  |                          uint32_t *dataPtr); /*!< IEEE 802.3 Clause 22 MDIO read data. */ | ||||||
|  |     status_t (*mdioWriteExt)(mdio_handle_t *handle, | ||||||
|  |                              uint32_t phyAddr, | ||||||
|  |                              uint32_t devAddr, | ||||||
|  |                              uint32_t data); /*!< IEEE 802.3 Clause 45 MDIO write data. */ | ||||||
|  |     status_t (*mdioReadExt)(mdio_handle_t *handle, | ||||||
|  |                             uint32_t phyAddr, | ||||||
|  |                             uint32_t devAddr, | ||||||
|  |                             uint32_t *dataPtr); /*!< IEEE 802.3 Clause 45 MDIO read data. */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * API | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | /*!
 | ||||||
|  |  * @name MDIO Driver | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief MDIO Write function. This function write data over the SMI to | ||||||
|  |  * the specified MDIO register. This function is called by all MDIO interfaces. | ||||||
|  |  * | ||||||
|  |  * @param handle  MDIO device handle. | ||||||
|  |  * @retval kStatus_Success     MDIO write success | ||||||
|  |  * @retval kStatus_MDIO_SMIVisitTimeout  MDIO SMI visit time out | ||||||
|  |  */ | ||||||
|  | static inline void MDIO_Init(mdio_handle_t *handle) | ||||||
|  | { | ||||||
|  |     handle->ops->mdioInit(handle); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief MDIO Write function. This function write data over the SMI to | ||||||
|  |  * the specified MDIO register. This function is called by all MDIO interfaces. | ||||||
|  |  * | ||||||
|  |  * @param handle  MDIO device handle. | ||||||
|  |  * @param phyAddr  MDIO PHY address handle. | ||||||
|  |  * @param devAddr  The PHY device register. | ||||||
|  |  * @param data    The data written to the MDIO register. | ||||||
|  |  * @retval kStatus_Success     MDIO write success | ||||||
|  |  * @retval kStatus_MDIO_SMIVisitTimeout  MDIO SMI visit time out | ||||||
|  |  */ | ||||||
|  | static inline status_t MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data) | ||||||
|  | { | ||||||
|  |     return handle->ops->mdioWrite(handle, phyAddr, devAddr, data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief MDIO Read function. This interface read data over the SMI from the | ||||||
|  |  * specified MDIO register. This function is called by all MDIO interfaces. | ||||||
|  |  * | ||||||
|  |  * @param handle   MDIO device handle. | ||||||
|  |  * @param phyAddr  MDIO PHY address handle. | ||||||
|  |  * @param devAddr  The PHY device register. | ||||||
|  |  * @param dataPtr  The address to store the data read from the MDIO register. | ||||||
|  |  * @retval kStatus_Success  MDIO read success | ||||||
|  |  * @retval kStatus_MDIO_SMIVisitTimeout  MDIO SMI visit time out | ||||||
|  |  */ | ||||||
|  | static inline status_t MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr) | ||||||
|  | { | ||||||
|  |     return handle->ops->mdioRead(handle, phyAddr, devAddr, dataPtr); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* @} */ | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -0,0 +1,266 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright 2020 NXP | ||||||
|  |  * All rights reserved. | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-3-Clause | ||||||
|  |  */ | ||||||
|  | #ifndef _FSL_PHY_H_ | ||||||
|  | #define _FSL_PHY_H_ | ||||||
|  | 
 | ||||||
|  | #include "fsl_mdio.h" | ||||||
|  | 
 | ||||||
|  | /*! @note The following PHY registers are the IEEE802.3 standard definition, same register and bit field may
 | ||||||
|  |           have different names in various PHYs, but the feature they represent should be same or very similar. */ | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the IEEE802.3 standard PHY registers. */ | ||||||
|  | #define PHY_BASICCONTROL_REG        0x00U /*!< The PHY basic control register. */ | ||||||
|  | #define PHY_BASICSTATUS_REG         0x01U /*!< The PHY basic status register. */ | ||||||
|  | #define PHY_ID1_REG                 0x02U /*!< The PHY ID one register. */ | ||||||
|  | #define PHY_ID2_REG                 0x03U /*!< The PHY ID two register. */ | ||||||
|  | #define PHY_AUTONEG_ADVERTISE_REG   0x04U /*!< The PHY auto-negotiate advertise register. */ | ||||||
|  | #define PHY_AUTONEG_LINKPARTNER_REG 0x05U /*!< The PHY auto negotiation link partner ability register. */ | ||||||
|  | #define PHY_AUTONEG_EXPANSION_REG   0x06U /*!< The PHY auto negotiation expansion register. */ | ||||||
|  | #define PHY_1000BASET_CONTROL_REG   0x09U /*!< The PHY 1000BASE-T control register. */ | ||||||
|  | #define PHY_MMD_ACCESS_CONTROL_REG  0x0DU /*!< The PHY MMD access control register. */ | ||||||
|  | #define PHY_MMD_ACCESS_DATA_REG     0x0EU /*!< The PHY MMD access data register. */ | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the mask flag in basic control register(Address 0x00). */ | ||||||
|  | #define PHY_BCTL_SPEED1_MASK          0x0040U /*!< The PHY speed bit mask(MSB).*/ | ||||||
|  | #define PHY_BCTL_ISOLATE_MASK         0x0400U /*!< The PHY isolate mask.*/ | ||||||
|  | #define PHY_BCTL_DUPLEX_MASK          0x0100U /*!< The PHY duplex bit mask. */ | ||||||
|  | #define PHY_BCTL_RESTART_AUTONEG_MASK 0x0200U /*!< The PHY restart auto negotiation mask. */ | ||||||
|  | #define PHY_BCTL_AUTONEG_MASK         0x1000U /*!< The PHY auto negotiation bit mask. */ | ||||||
|  | #define PHY_BCTL_SPEED0_MASK          0x2000U /*!< The PHY speed bit mask(LSB). */ | ||||||
|  | #define PHY_BCTL_LOOP_MASK            0x4000U /*!< The PHY loop bit mask. */ | ||||||
|  | #define PHY_BCTL_RESET_MASK           0x8000U /*!< The PHY reset bit mask. */ | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the mask flag in basic status register(Address 0x01). */ | ||||||
|  | #define PHY_BSTATUS_LINKSTATUS_MASK  0x0004U /*!< The PHY link status mask. */ | ||||||
|  | #define PHY_BSTATUS_AUTONEGABLE_MASK 0x0008U /*!< The PHY auto-negotiation ability mask. */ | ||||||
|  | #define PHY_BSTATUS_SPEEDUPLX_MASK   0x001CU /*!< The PHY speed and duplex mask. */ | ||||||
|  | #define PHY_BSTATUS_AUTONEGCOMP_MASK 0x0020U /*!< The PHY auto-negotiation complete mask. */ | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the mask flag in PHY auto-negotiation advertise register(Address 0x04). */ | ||||||
|  | #define PHY_100BaseT4_ABILITY_MASK    0x200U /*!< The PHY have the T4 ability. */ | ||||||
|  | #define PHY_100BASETX_FULLDUPLEX_MASK 0x100U /*!< The PHY has the 100M full duplex ability.*/ | ||||||
|  | #define PHY_100BASETX_HALFDUPLEX_MASK 0x080U /*!< The PHY has the 100M full duplex ability.*/ | ||||||
|  | #define PHY_10BASETX_FULLDUPLEX_MASK  0x040U /*!< The PHY has the 10M full duplex ability.*/ | ||||||
|  | #define PHY_10BASETX_HALFDUPLEX_MASK  0x020U /*!< The PHY has the 10M full duplex ability.*/ | ||||||
|  | #define PHY_IEEE802_3_SELECTOR_MASK   0x001U /*!< The message type being sent by Auto-Nego.*/ | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the mask flag in the 1000BASE-T control register(Address 0x09). */ | ||||||
|  | #define PHY_1000BASET_FULLDUPLEX_MASK 0x200U /*!< The PHY has the 1000M full duplex ability.*/ | ||||||
|  | #define PHY_1000BASET_HALFDUPLEX_MASK 0x100U /*!< The PHY has the 1000M half duplex ability.*/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * Definitions | ||||||
|  |  ******************************************************************************/ | ||||||
|  | typedef struct _phy_handle phy_handle_t; | ||||||
|  | /*! @brief Defines the PHY link speed. */ | ||||||
|  | typedef enum _phy_speed | ||||||
|  | { | ||||||
|  |     kPHY_Speed10M = 0U, /*!< ENET PHY 10M speed. */ | ||||||
|  |     kPHY_Speed100M,     /*!< ENET PHY 100M speed. */ | ||||||
|  |     kPHY_Speed1000M     /*!< ENET PHY 1000M speed. */ | ||||||
|  | } phy_speed_t; | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the PHY link duplex. */ | ||||||
|  | typedef enum _phy_duplex | ||||||
|  | { | ||||||
|  |     kPHY_HalfDuplex = 0U, /*!< ENET PHY half duplex. */ | ||||||
|  |     kPHY_FullDuplex       /*!< ENET PHY full duplex. */ | ||||||
|  | } phy_duplex_t; | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the PHY loopback mode. */ | ||||||
|  | typedef enum _phy_loop | ||||||
|  | { | ||||||
|  |     kPHY_LocalLoop = 0U, /*!< ENET PHY local/digital loopback. */ | ||||||
|  |     kPHY_RemoteLoop,     /*!< ENET PHY remote loopback. */ | ||||||
|  |     kPHY_ExternalLoop,   /*!< ENET PHY external loopback. */ | ||||||
|  | } phy_loop_t; | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines the PHY MMD data access mode. */ | ||||||
|  | typedef enum _phy_mmd_access_mode | ||||||
|  | { | ||||||
|  |     kPHY_MMDAccessNoPostIncrement = (1U << 14), /*!< ENET PHY MMD access data with no address post increment. */ | ||||||
|  |     kPHY_MMDAccessRdWrPostIncrement = | ||||||
|  |         (2U << 14),                             /*!< ENET PHY MMD access data with Read/Write address post increment. */ | ||||||
|  |     kPHY_MMDAccessWrPostIncrement = (3U << 14), /*!< ENET PHY MMD access data with Write address post increment. */ | ||||||
|  | } phy_mmd_access_mode_t; | ||||||
|  | 
 | ||||||
|  | /*! @brief Defines PHY configuration. */ | ||||||
|  | typedef struct _phy_config | ||||||
|  | { | ||||||
|  |     uint32_t phyAddr;    /*!< PHY address. */ | ||||||
|  |     phy_speed_t speed;   /*!< PHY speed configuration. */ | ||||||
|  |     phy_duplex_t duplex; /*!< PHY duplex configuration. */ | ||||||
|  |     bool autoNeg;        /*!< PHY auto-negotiation, true: enable, false: disable. */ | ||||||
|  |     bool enableEEE;      /*!< PHY Energy Efficient Ethernet. */ | ||||||
|  | } phy_config_t; | ||||||
|  | 
 | ||||||
|  | /*! @brief PHY device operations. */ | ||||||
|  | typedef struct _phy_operations | ||||||
|  | { | ||||||
|  |     status_t (*phyInit)(phy_handle_t *handle, const phy_config_t *config); | ||||||
|  |     status_t (*phyWrite)(phy_handle_t *handle, uint32_t phyReg, uint32_t data); | ||||||
|  |     status_t (*phyRead)(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr); | ||||||
|  |     status_t (*getAutoNegoStatus)(phy_handle_t *handle, bool *status); | ||||||
|  |     status_t (*getLinkStatus)(phy_handle_t *handle, bool *status); | ||||||
|  |     status_t (*getLinkSpeedDuplex)(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex); | ||||||
|  |     status_t (*setLinkSpeedDuplex)(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex); | ||||||
|  |     status_t (*enableLoopback)(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable); | ||||||
|  | } phy_operations_t; | ||||||
|  | 
 | ||||||
|  | /*! @brief PHY device handle. */ | ||||||
|  | 
 | ||||||
|  | struct _phy_handle | ||||||
|  | { | ||||||
|  |     uint32_t phyAddr;            /*!< PHY address. */ | ||||||
|  |     mdio_handle_t *mdioHandle;   /*!< The MDIO handle used by the phy device, it is specified by device. */ | ||||||
|  |     const phy_operations_t *ops; /*!< The device related operations. */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  |  * API | ||||||
|  |  ******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @name PHY Driver | ||||||
|  |  * @{ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Initializes PHY. | ||||||
|  |  * | ||||||
|  |  *  This function initialize PHY. | ||||||
|  |  * | ||||||
|  |  * @param handle       PHY device handle. | ||||||
|  |  * @param config       Pointer to structure of phy_config_t. | ||||||
|  |  * @retval kStatus_Success  PHY initialization succeeds | ||||||
|  |  * @retval kStatus_Fail  PHY initialization fails | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | static inline status_t PHY_Init(phy_handle_t *handle, const phy_config_t *config) | ||||||
|  | { | ||||||
|  |     return handle->ops->phyInit(handle, config); | ||||||
|  | } | ||||||
|  | /*!
 | ||||||
|  |  * @brief PHY Write function. This function write data over the SMI to | ||||||
|  |  * the specified PHY register. This function is called by all PHY interfaces. | ||||||
|  |  * | ||||||
|  |  * @param handle       PHY device handle. | ||||||
|  |  * @param phyReg  The PHY register. | ||||||
|  |  * @param data    The data written to the PHY register. | ||||||
|  |  * @retval kStatus_Success     PHY write success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | static inline status_t PHY_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data) | ||||||
|  | { | ||||||
|  |     return handle->ops->phyWrite(handle, phyReg, data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief PHY Read function. This interface read data over the SMI from the | ||||||
|  |  * specified PHY register. This function is called by all PHY interfaces. | ||||||
|  |  * | ||||||
|  |  * @param handle       PHY device handle. | ||||||
|  |  * @param phyReg   The PHY register. | ||||||
|  |  * @param dataPtr  The address to store the data read from the PHY register. | ||||||
|  |  * @retval kStatus_Success  PHY read success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | static inline status_t PHY_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr) | ||||||
|  | { | ||||||
|  |     return handle->ops->phyRead(handle, phyReg, dataPtr); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Gets the PHY auto-negotiation status. | ||||||
|  |  * | ||||||
|  |  * @param handle   PHY device handle. | ||||||
|  |  * @param status   The auto-negotiation status of the PHY. | ||||||
|  |  *         - true the auto-negotiation is over. | ||||||
|  |  *         - false the auto-negotiation is on-going or not started. | ||||||
|  |  * @retval kStatus_Success   PHY gets status success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | static inline status_t PHY_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status) | ||||||
|  | { | ||||||
|  |     return handle->ops->getAutoNegoStatus(handle, status); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Gets the PHY link status. | ||||||
|  |  * | ||||||
|  |  * @param handle       PHY device handle. | ||||||
|  |  * @param status   The link up or down status of the PHY. | ||||||
|  |  *         - true the link is up. | ||||||
|  |  *         - false the link is down. | ||||||
|  |  * @retval kStatus_Success   PHY get link status success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | static inline status_t PHY_GetLinkStatus(phy_handle_t *handle, bool *status) | ||||||
|  | { | ||||||
|  |     return handle->ops->getLinkStatus(handle, status); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Gets the PHY link speed and duplex. | ||||||
|  |  * | ||||||
|  |  * @brief This function gets the speed and duplex mode of PHY. User can give one of speed | ||||||
|  |  * and duplex address paramter and set the other as NULL if only wants to get one of them. | ||||||
|  |  * | ||||||
|  |  * @param handle       PHY device handle. | ||||||
|  |  * @param speed    The address of PHY link speed. | ||||||
|  |  * @param duplex   The link duplex of PHY. | ||||||
|  |  * @retval kStatus_Success   PHY get link speed and duplex success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | static inline status_t PHY_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex) | ||||||
|  | { | ||||||
|  |     return handle->ops->getLinkSpeedDuplex(handle, speed, duplex); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Sets the PHY link speed and duplex. | ||||||
|  |  * | ||||||
|  |  * @param handle   PHY device handle. | ||||||
|  |  * @param speed    Specified PHY link speed. | ||||||
|  |  * @param duplex   Specified PHY link duplex. | ||||||
|  |  * @retval kStatus_Success   PHY gets status success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | static inline status_t PHY_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex) | ||||||
|  | { | ||||||
|  |     return handle->ops->setLinkSpeedDuplex(handle, speed, duplex); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*!
 | ||||||
|  |  * @brief Enable PHY loopcback mode. | ||||||
|  |  * | ||||||
|  |  * @param handle   PHY device handle. | ||||||
|  |  * @param mode     The loopback mode to be enabled, please see "phy_loop_t". | ||||||
|  |  * All loopback modes should not be set together, when one loopback mode is set | ||||||
|  |  * another should be disabled. | ||||||
|  |  * @param speed    PHY speed for loopback mode. | ||||||
|  |  * @param enable   True to enable, false to disable. | ||||||
|  |  * @retval kStatus_Success   PHY get link speed and duplex success | ||||||
|  |  * @retval kStatus_PHY_SMIVisitTimeout  PHY SMI visit time out | ||||||
|  |  */ | ||||||
|  | static inline status_t PHY_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable) | ||||||
|  | { | ||||||
|  |     return handle->ops->enableLoopback(handle, mode, speed, enable); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* @} */ | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*! @}*/ | ||||||
|  | #endif | ||||||
|  | @ -4,6 +4,15 @@ export CFLAGS := -mcpu=cortex-m7 -mthumb  -ffunction-sections -fdata-sections -D | ||||||
| export AFLAGS := -c -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb  -gdwarf-2 | export AFLAGS := -c -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb  -gdwarf-2 | ||||||
| 
 | 
 | ||||||
| ### if use USB function, use special lds file because USB uses ITCM
 | ### if use USB function, use special lds file because USB uses ITCM
 | ||||||
|  | ifeq ($(CONFIG_LIB_MUSLLIB), y) | ||||||
|  | export LFLAGS += -nostdlib -nostdinc # -fno-builtin -nodefaultlibs | ||||||
|  | export LIBCC := -lgcc | ||||||
|  | export LINK_MUSLLIB := $(KERNEL_ROOT)/lib/musllib/libmusl.a | ||||||
|  | endif | ||||||
|  | 
 | ||||||
|  | ifeq ($(CONFIG_RESOURCES_LWIP), y) | ||||||
|  | export LINK_LWIP := $(KERNEL_ROOT)/resources/ethernet/LwIP/liblwip.a | ||||||
|  | endif | ||||||
| 
 | 
 | ||||||
| ifeq ($(CONFIG_BSP_USING_USB),y) | ifeq ($(CONFIG_BSP_USING_USB),y) | ||||||
| export LFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-ok1052-c.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link-usb.lds | export LFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-ok1052-c.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link-usb.lds | ||||||
|  |  | ||||||
|  | @ -35,7 +35,10 @@ Modification: | ||||||
| #include "clock_config.h" | #include "clock_config.h" | ||||||
| #include <xizi.h> | #include <xizi.h> | ||||||
| #include <arch_interrupt.h> | #include <arch_interrupt.h> | ||||||
|  | 
 | ||||||
|  | #ifdef BSP_USING_LWIP | ||||||
| #include "enet_ethernetif.h" | #include "enet_ethernetif.h" | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| extern int heap_start; | extern int heap_start; | ||||||
| extern int heap_end; | extern int heap_end; | ||||||
|  | @ -52,6 +55,8 @@ void InitBoardHardware(void); | ||||||
| /*! @brief The board name */ | /*! @brief The board name */ | ||||||
| #define BOARD_NAME "IMXRT1050-EVKB" | #define BOARD_NAME "IMXRT1050-EVKB" | ||||||
| 
 | 
 | ||||||
|  | #define configMAC_ADDR {0x02, 0x12, 0x13, 0x10, 0x15, 0x11} | ||||||
|  | 
 | ||||||
| /* The UART to use for debug messages. */ | /* The UART to use for debug messages. */ | ||||||
| #define BOARD_DEBUG_UART_TYPE kSerialPort_Uart | #define BOARD_DEBUG_UART_TYPE kSerialPort_Uart | ||||||
| #define BOARD_DEBUG_UART_BASEADDR (uint32_t) LPUART1 | #define BOARD_DEBUG_UART_BASEADDR (uint32_t) LPUART1 | ||||||
|  |  | ||||||
|  | @ -62,7 +62,7 @@ | ||||||
| //#include "FreeRTOS.h"
 | //#include "FreeRTOS.h"
 | ||||||
| //#include "event_groups.h"
 | //#include "event_groups.h"
 | ||||||
| #endif | #endif | ||||||
| 
 | #include <board.h> | ||||||
| #include "netif/ethernet.h" | #include "netif/ethernet.h" | ||||||
| #include "enet_ethernetif.h" | #include "enet_ethernetif.h" | ||||||
| #include "enet_ethernetif_priv.h" | #include "enet_ethernetif_priv.h" | ||||||
|  | @ -94,6 +94,19 @@ void enet_delay(void) | ||||||
| void Time_Update_LwIP(void) | void Time_Update_LwIP(void) | ||||||
| { | { | ||||||
| } | } | ||||||
|  | ethernetif_config_t enet_cfg = { | ||||||
|  |     .phyAddress = BOARD_ENET0_PHY_ADDRESS, | ||||||
|  |     .clockName = kCLOCK_CoreSysClk, | ||||||
|  |     .macAddress = configMAC_ADDR, | ||||||
|  | #if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) | ||||||
|  |     .non_dma_memory = non_dma_memory, | ||||||
|  | #endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */  | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void *ethernetif_config_enet_set(uint8_t enet_port) | ||||||
|  | { | ||||||
|  |     return (void *)&enet_cfg; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| void ethernetif_clk_init(void) | void ethernetif_clk_init(void) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -21,6 +21,8 @@ | ||||||
|  * Definitions |  * Definitions | ||||||
|  ******************************************************************************/ |  ******************************************************************************/ | ||||||
| 
 | 
 | ||||||
|  | #define FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE | ||||||
|  | 
 | ||||||
| /*! @brief Defines the timeout macro. */ | /*! @brief Defines the timeout macro. */ | ||||||
| #define PHY_TIMEOUT_COUNT 100000 | #define PHY_TIMEOUT_COUNT 100000 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -21,6 +21,9 @@ | ||||||
| #ifndef __CONNECT_ETHERNET_H_ | #ifndef __CONNECT_ETHERNET_H_ | ||||||
| #define __CONNECT_ETHERNET_H_ | #define __CONNECT_ETHERNET_H_ | ||||||
| 
 | 
 | ||||||
|  | #include "enet_ethernetif.h" | ||||||
|  | #include "enet_ethernetif_priv.h" | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
|  extern "C" { |  extern "C" { | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -182,9 +182,12 @@ err_t ethernetif1_init(struct netif *netif); | ||||||
| void ethernetif_input( struct netif *netif); | void ethernetif_input( struct netif *netif); | ||||||
| 
 | 
 | ||||||
| void ETH_BSP_Config(void); | void ETH_BSP_Config(void); | ||||||
|  | void *ethernetif_config_enet_set(uint8_t enet_port); | ||||||
| 
 | 
 | ||||||
| int32 lwip_obtain_semaphore(struct netif *netif); | int32 lwip_obtain_semaphore(struct netif *netif); | ||||||
| 
 | 
 | ||||||
|  | #define NETIF_ENET0_INIT_FUNC ethernetif0_init | ||||||
|  | 
 | ||||||
| #if defined(__cplusplus) | #if defined(__cplusplus) | ||||||
| } | } | ||||||
| #endif /* __cplusplus */ | #endif /* __cplusplus */ | ||||||
|  |  | ||||||
|  | @ -50,6 +50,9 @@ extern int Stm32HwRtcInit(); | ||||||
| extern int HwSdioInit(); | extern int HwSdioInit(); | ||||||
| extern int Stm32HwAdcInit(void); | extern int Stm32HwAdcInit(void); | ||||||
| extern int Stm32HwDacInit(void); | extern int Stm32HwDacInit(void); | ||||||
|  | #ifdef BSP_USING_LWIP | ||||||
|  | extern int ETH_BSP_Config(); | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| static void ClockConfiguration() | static void ClockConfiguration() | ||||||
| { | { | ||||||
|  | @ -142,6 +145,10 @@ struct InitSequenceDesc _board_init[] = | ||||||
| #ifdef BSP_USING_DAC | #ifdef BSP_USING_DAC | ||||||
|     {"hw dac init", Stm32HwDacInit}, |     {"hw dac init", Stm32HwDacInit}, | ||||||
| #endif | #endif | ||||||
|  | #ifdef BSP_USING_LWIP | ||||||
|  |     {"ETH_BSP", ETH_BSP_Config}, | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| 	{ " NONE ",NONE }, | 	{ " NONE ",NONE }, | ||||||
| }; | }; | ||||||
| void InitBoardHardware() | void InitBoardHardware() | ||||||
|  |  | ||||||
|  | @ -40,6 +40,8 @@ extern int __stack_end__; | ||||||
| extern unsigned int g_service_table_start; | extern unsigned int g_service_table_start; | ||||||
| extern unsigned int g_service_table_end; | extern unsigned int g_service_table_end; | ||||||
| 
 | 
 | ||||||
|  | #define configMAC_ADDR {0x02, 0x12, 0x13, 0x10, 0x15, 0x11} | ||||||
|  | 
 | ||||||
| #define STM32_USE_SDIO			0 | #define STM32_USE_SDIO			0 | ||||||
| 
 | 
 | ||||||
| #define STM32_EXT_SRAM          0 | #define STM32_EXT_SRAM          0 | ||||||
|  |  | ||||||
|  | @ -62,7 +62,10 @@ extern int32 s_xSemaphore; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Private functions ---------------------------------------------------------*/ | /* Private functions ---------------------------------------------------------*/ | ||||||
| 
 | void *ethernetif_config_enet_set(uint8_t enet_port) | ||||||
|  | { | ||||||
|  |   return NONE; | ||||||
|  | } | ||||||
| /**
 | /**
 | ||||||
|   * @brief  ETH_BSP_Config |   * @brief  ETH_BSP_Config | ||||||
|   * @param  None |   * @param  None | ||||||
|  |  | ||||||
|  | @ -48,9 +48,9 @@ | ||||||
| #include "lwip/mem.h" | #include "lwip/mem.h" | ||||||
| #include "lwip/pbuf.h" | #include "lwip/pbuf.h" | ||||||
| #include "lwip/sys.h" | #include "lwip/sys.h" | ||||||
|  | #include "lwip/timeouts.h" | ||||||
| #include "netif/etharp.h" | #include "netif/etharp.h" | ||||||
| #include "err.h" | #include "err.h" | ||||||
| #include "ethernetif.h" |  | ||||||
| 
 | 
 | ||||||
| #include "main.h" | #include "main.h" | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | @ -101,7 +101,7 @@ extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void ethernetif_input( void * pvParameters ); | 
 | ||||||
| void LoopGetMacPkg(void * pvParameters); | void LoopGetMacPkg(void * pvParameters); | ||||||
| 
 | 
 | ||||||
| static void arp_timer(void *arg); | static void arp_timer(void *arg); | ||||||
|  | @ -140,7 +140,7 @@ void LwIP_Pkt_Handle(struct netif *netif) | ||||||
| 
 | 
 | ||||||
| void Time_Update_LwIP(void) | void Time_Update_LwIP(void) | ||||||
| { | { | ||||||
|   LocalTime += MS_PER_SYSTICK_F407; |   LocalTime += MS_PER_SYSTICK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -413,7 +413,7 @@ void LoopGetMacPkg(void * pvParameters) | ||||||
|  *         ERR_MEM if private data couldn't be allocated |  *         ERR_MEM if private data couldn't be allocated | ||||||
|  *         any other err_t on error |  *         any other err_t on error | ||||||
|  */ |  */ | ||||||
| err_t ethernetif_init(struct netif *netif) | err_t ethernetif0_init(struct netif *netif) | ||||||
| { | { | ||||||
|   LWIP_ASSERT("netif != NULL", (netif != NULL)); |   LWIP_ASSERT("netif != NULL", (netif != NULL)); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -43,6 +43,9 @@ | ||||||
| #ifndef __STM32F4x7_ETH_BSP_H | #ifndef __STM32F4x7_ETH_BSP_H | ||||||
| #define __STM32F4x7_ETH_BSP_H | #define __STM32F4x7_ETH_BSP_H | ||||||
| 
 | 
 | ||||||
|  | #include "hardware_eth.h" | ||||||
|  | #include "hardware_conf.h" | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
|  extern "C" { |  extern "C" { | ||||||
| #endif | #endif | ||||||
|  | @ -98,6 +101,7 @@ | ||||||
| /* Exported macro ------------------------------------------------------------*/ | /* Exported macro ------------------------------------------------------------*/ | ||||||
| /* Exported functions ------------------------------------------------------- */ | /* Exported functions ------------------------------------------------------- */ | ||||||
| void  ETH_BSP_Config(void); | void  ETH_BSP_Config(void); | ||||||
|  | void *ethernetif_config_enet_set(uint8_t enet_port); | ||||||
| uint32_t Eth_Link_PHYITConfig(uint16_t PHYAddress); | uint32_t Eth_Link_PHYITConfig(uint16_t PHYAddress); | ||||||
| void Eth_Link_EXTIConfig(void); | void Eth_Link_EXTIConfig(void); | ||||||
| void Eth_Link_ITHandler(unsigned short PHYAddress); | void Eth_Link_ITHandler(unsigned short PHYAddress); | ||||||
|  |  | ||||||
|  | @ -30,6 +30,8 @@ | ||||||
| 
 | 
 | ||||||
| /* Includes ------------------------------------------------------------------*/ | /* Includes ------------------------------------------------------------------*/ | ||||||
| #include "hardware_eth_conf.h" | #include "hardware_eth_conf.h" | ||||||
|  | #include "err.h" | ||||||
|  | #include "netif/ethernet.h" | ||||||
| 
 | 
 | ||||||
| /** @addtogroup STM32F4x7_ETH_Driver
 | /** @addtogroup STM32F4x7_ETH_Driver
 | ||||||
|   * @{ |   * @{ | ||||||
|  | @ -1866,6 +1868,9 @@ void ETH_MMCITConfig(uint32_t ETH_MMC_IT, FunctionalState NewState); | ||||||
| ITStatus ETH_GetMMCITStatus(uint32_t ETH_MMC_IT); | ITStatus ETH_GetMMCITStatus(uint32_t ETH_MMC_IT); | ||||||
| uint32_t ETH_GetMMCRegister(uint32_t ETH_MMCReg); | uint32_t ETH_GetMMCRegister(uint32_t ETH_MMCReg); | ||||||
| 
 | 
 | ||||||
|  | void ethernetif_input( void * pvParameters ); | ||||||
|  | err_t ethernetif0_init(struct netif *netif); | ||||||
|  | #define NETIF_ENET0_INIT_FUNC ethernetif0_init | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -51,6 +51,9 @@ void InitBoardHardware(void); | ||||||
| /*! @brief The board name */ | /*! @brief The board name */ | ||||||
| #define BOARD_NAME "IMXRT1050" | #define BOARD_NAME "IMXRT1050" | ||||||
| 
 | 
 | ||||||
|  | #define configMAC_ADDR {0x02, 0x12, 0x13, 0x10, 0x15, 0x11} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| #define NVIC_PRIORITYGROUP_0         0x00000007U /*!< 0 bits for pre-emption priority | #define NVIC_PRIORITYGROUP_0         0x00000007U /*!< 0 bits for pre-emption priority | ||||||
|                                                       4 bits for subpriority */ |                                                       4 bits for subpriority */ | ||||||
| #define NVIC_PRIORITYGROUP_1         0x00000006U /*!< 1 bits for pre-emption priority | #define NVIC_PRIORITYGROUP_1         0x00000006U /*!< 1 bits for pre-emption priority | ||||||
|  |  | ||||||
|  | @ -66,7 +66,7 @@ | ||||||
| #include "netif/ethernet.h" | #include "netif/ethernet.h" | ||||||
| #include "enet_ethernetif.h" | #include "enet_ethernetif.h" | ||||||
| #include "enet_ethernetif_priv.h" | #include "enet_ethernetif_priv.h" | ||||||
| 
 | #include <board.h> | ||||||
| #include "fsl_enet.h" | #include "fsl_enet.h" | ||||||
| #include "fsl_phy.h" | #include "fsl_phy.h" | ||||||
| #include "fsl_gpio.h" | #include "fsl_gpio.h" | ||||||
|  | @ -95,6 +95,20 @@ void Time_Update_LwIP(void) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | ethernetif_config_t enet_cfg = { | ||||||
|  |     .phyAddress = BOARD_ENET0_PHY_ADDRESS, | ||||||
|  |     .clockName = kCLOCK_CoreSysClk, | ||||||
|  |     .macAddress = configMAC_ADDR, | ||||||
|  | #if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) | ||||||
|  |     .non_dma_memory = non_dma_memory, | ||||||
|  | #endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */  | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void *ethernetif_config_enet_set(uint8_t enet_port) | ||||||
|  | { | ||||||
|  |     return (void *)&enet_cfg; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void ethernetif_clk_init(void) | void ethernetif_clk_init(void) | ||||||
| { | { | ||||||
|     const clock_enet_pll_config_t config = {.enableClkOutput = true, .enableClkOutput25M = false, .loopDivider = 1}; |     const clock_enet_pll_config_t config = {.enableClkOutput = true, .enableClkOutput25M = false, .loopDivider = 1}; | ||||||
|  |  | ||||||
|  | @ -21,6 +21,9 @@ | ||||||
| #ifndef __CONNECT_ETHERNET_H_ | #ifndef __CONNECT_ETHERNET_H_ | ||||||
| #define __CONNECT_ETHERNET_H_ | #define __CONNECT_ETHERNET_H_ | ||||||
| 
 | 
 | ||||||
|  | #include "enet_ethernetif.h" | ||||||
|  | #include "enet_ethernetif_priv.h" | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
|  extern "C" { |  extern "C" { | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -182,9 +182,11 @@ err_t ethernetif1_init(struct netif *netif); | ||||||
| void ethernetif_input( struct netif *netif); | void ethernetif_input( struct netif *netif); | ||||||
| 
 | 
 | ||||||
| int ETH_BSP_Config(void); | int ETH_BSP_Config(void); | ||||||
| 
 | void *ethernetif_config_enet_set(uint8_t enet_port); | ||||||
| int32 lwip_obtain_semaphore(struct netif *netif); | int32 lwip_obtain_semaphore(struct netif *netif); | ||||||
| 
 | 
 | ||||||
|  | #define NETIF_ENET0_INIT_FUNC ethernetif0_init | ||||||
|  | 
 | ||||||
| #if defined(__cplusplus) | #if defined(__cplusplus) | ||||||
| } | } | ||||||
| #endif /* __cplusplus */ | #endif /* __cplusplus */ | ||||||
|  |  | ||||||
|  | @ -289,6 +289,12 @@ KERNELPATHS += \ | ||||||
| 	-I$(BSP_ROOT)/third_party_driver \
 | 	-I$(BSP_ROOT)/third_party_driver \
 | ||||||
| 	-I$(BSP_ROOT)/third_party_driver/include \
 | 	-I$(BSP_ROOT)/third_party_driver/include \
 | ||||||
| 	-I$(BSP_ROOT)/third_party_driver/CMSIS/Include \
 | 	-I$(BSP_ROOT)/third_party_driver/CMSIS/Include \
 | ||||||
|  | 	-I$(BSP_ROOT)/third_party_driver/ethernet \
 | ||||||
|  | 	-I$(BSP_ROOT)/third_party_driver/ethernet/mdio/enet \
 | ||||||
|  | 	-I$(BSP_ROOT)/third_party_driver/ethernet/mdio/enet_qos \
 | ||||||
|  | 	-I$(BSP_ROOT)/third_party_driver/ethernet/phy/ksz8081 \
 | ||||||
|  | 	-I$(BSP_ROOT)/third_party_driver/ethernet/phy/ksz9131rnx \
 | ||||||
|  | 	-I$(BSP_ROOT)/third_party_driver/cm7 \
 | ||||||
| 	-I$(BSP_ROOT)/xip \
 | 	-I$(BSP_ROOT)/xip \
 | ||||||
| 	-I$(KERNEL_ROOT)/include \
 | 	-I$(KERNEL_ROOT)/include \
 | ||||||
| 	-I$(KERNEL_ROOT)/resources/include \
 | 	-I$(KERNEL_ROOT)/resources/include \
 | ||||||
|  |  | ||||||
|  | @ -265,7 +265,6 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums | ||||||
| typedef unsigned int nfds_t; | typedef unsigned int nfds_t; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #define FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE |  | ||||||
| 
 | 
 | ||||||
| #define MEMP_LIB_MALLOC                 1 | #define MEMP_LIB_MALLOC                 1 | ||||||
| #define MEMP_MEM_MALLOC                 1 | #define MEMP_MEM_MALLOC                 1 | ||||||
|  |  | ||||||
|  | @ -67,12 +67,21 @@ | ||||||
| 
 | 
 | ||||||
| #include "board.h" | #include "board.h" | ||||||
| #include "ethernet.h" | #include "ethernet.h" | ||||||
| #include "enet_ethernetif.h" | #include "connect_ethernet.h" | ||||||
| #include <transform.h> | #include <transform.h> | ||||||
| 
 | 
 | ||||||
| char lwip_ipaddr[] = {192, 168, 250, 253}; | char lwip_ipaddr[20] = {192, 168, 131, 77}; | ||||||
| char lwip_netmask[] = {255, 255, 255, 0}; | char lwip_netmask[20] = {255, 255, 254, 0}; | ||||||
| char lwip_gwaddr[] = {192, 168, 250, 252}; | char lwip_gwaddr[20] = {192, 168, 131, 23}; | ||||||
|  | 
 | ||||||
|  | char lwip_eth0_ipaddr[20] = {192, 168, 131, 77}; | ||||||
|  | char lwip_eth0_netmask[20] = {255, 255, 254, 0}; | ||||||
|  | char lwip_eth0_gwaddr[20] = {192, 168, 131, 23}; | ||||||
|  | 
 | ||||||
|  | char lwip_eth1_ipaddr[20] = {192, 168, 131, 99}; | ||||||
|  | char lwip_eth1_netmask[20] = {255, 255, 254, 0}; | ||||||
|  | char lwip_eth1_gwaddr[20] = {192, 168, 131, 23}; | ||||||
|  | 
 | ||||||
| char lwip_flag = 0; | char lwip_flag = 0; | ||||||
| 
 | 
 | ||||||
| x_ticks_t lwip_sys_now; | x_ticks_t lwip_sys_now; | ||||||
|  | @ -389,7 +398,9 @@ void lwip_tcp_init(void) | ||||||
|   /* USER CODE END 0 */ |   /* USER CODE END 0 */ | ||||||
|   /* Initilialize the LwIP stack without RTOS */ |   /* Initilialize the LwIP stack without RTOS */ | ||||||
|   /* add the network interface (IPv4/IPv6) without RTOS */ |   /* add the network interface (IPv4/IPv6) without RTOS */ | ||||||
|   netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif0_init, &tcpip_input); | #ifdef NETIF_ENET0_INIT_FUNC | ||||||
|  |   netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, NETIF_ENET0_INIT_FUNC, &tcpip_input); | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
|   /* Registers the default network interface */ |   /* Registers the default network interface */ | ||||||
|   netif_set_default(&gnetif); |   netif_set_default(&gnetif); | ||||||
|  | @ -463,22 +474,12 @@ void lwip_config_input(struct netif *net) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void lwip_config_net(char *ip, char *mask, char *gw) | void lwip_config_net(uint8_t enet_port, char *ip, char *mask, char *gw) | ||||||
| { | { | ||||||
| #if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) |  | ||||||
|   mem_range_t non_dma_memory[] = NON_DMA_MEMORY_ARRAY; |  | ||||||
| #endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */ |  | ||||||
|   ip4_addr_t net_ipaddr, net_netmask, net_gw; |   ip4_addr_t net_ipaddr, net_netmask, net_gw; | ||||||
|   ethernetif_config_t cfg = { |   char* eth_cfg; | ||||||
|     .phyAddress = BOARD_ENET0_PHY_ADDRESS, |  | ||||||
|     .clockName  = kCLOCK_CoreSysClk, |  | ||||||
|     .macAddress = configMAC_ADDR, |  | ||||||
| #if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) |  | ||||||
|     .non_dma_memory = non_dma_memory, |  | ||||||
| #endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */ |  | ||||||
|   }; |  | ||||||
| 
 | 
 | ||||||
|   ETH_BSP_Config(); |   eth_cfg = ethernetif_config_enet_set(enet_port); | ||||||
| 
 | 
 | ||||||
|   if(chk_lwip_bit(LWIP_INIT_FLAG)) |   if(chk_lwip_bit(LWIP_INIT_FLAG)) | ||||||
|   { |   { | ||||||
|  | @ -506,8 +507,18 @@ void lwip_config_net(char *ip, char *mask, char *gw) | ||||||
| 
 | 
 | ||||||
|   lwip_init(); |   lwip_init(); | ||||||
| 
 | 
 | ||||||
|   netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, &cfg, ethernetif0_init, |   if(0 == enet_port) { | ||||||
|  | #ifdef NETIF_ENET0_INIT_FUNC | ||||||
|  |     netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET0_INIT_FUNC, | ||||||
|         ethernet_input); |         ethernet_input); | ||||||
|  | #endif | ||||||
|  |   } else if (1 == enet_port) { | ||||||
|  | #ifdef NETIF_ENET1_INIT_FUNC | ||||||
|  |     netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET1_INIT_FUNC, | ||||||
|  |         ethernet_input); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  |    | ||||||
|   netif_set_default(&gnetif); |   netif_set_default(&gnetif); | ||||||
|   netif_set_up(&gnetif); |   netif_set_up(&gnetif); | ||||||
| 
 | 
 | ||||||
|  | @ -527,22 +538,12 @@ void lwip_config_net(char *ip, char *mask, char *gw) | ||||||
|   lwip_config_input(&gnetif); |   lwip_config_input(&gnetif); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void lwip_config_tcp(char *ip, char *mask, char *gw) | void lwip_config_tcp(uint8_t enet_port, char *ip, char *mask, char *gw) | ||||||
| { | { | ||||||
| #if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) |  | ||||||
|   mem_range_t non_dma_memory[] = NON_DMA_MEMORY_ARRAY; |  | ||||||
| #endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */ |  | ||||||
|   ip4_addr_t net_ipaddr, net_netmask, net_gw; |   ip4_addr_t net_ipaddr, net_netmask, net_gw; | ||||||
|   ethernetif_config_t cfg = { |   char* eth_cfg; | ||||||
|     .phyAddress = BOARD_ENET0_PHY_ADDRESS, |  | ||||||
|     .clockName  = kCLOCK_CoreSysClk, |  | ||||||
|     .macAddress = configMAC_ADDR, |  | ||||||
| #if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0) |  | ||||||
|     .non_dma_memory = non_dma_memory, |  | ||||||
| #endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */ |  | ||||||
|   }; |  | ||||||
| 
 | 
 | ||||||
|   ETH_BSP_Config(); |   eth_cfg = ethernetif_config_enet_set(enet_port); | ||||||
| 
 | 
 | ||||||
|   if(chk_lwip_bit(LWIP_INIT_FLAG)) |   if(chk_lwip_bit(LWIP_INIT_FLAG)) | ||||||
|   { |   { | ||||||
|  | @ -560,8 +561,17 @@ void lwip_config_tcp(char *ip, char *mask, char *gw) | ||||||
|   IP4_ADDR(&net_netmask, mask[0], mask[1], mask[2], mask[3]); |   IP4_ADDR(&net_netmask, mask[0], mask[1], mask[2], mask[3]); | ||||||
|   IP4_ADDR(&net_gw, gw[0], gw[1], gw[2], gw[3]); |   IP4_ADDR(&net_gw, gw[0], gw[1], gw[2], gw[3]); | ||||||
| 
 | 
 | ||||||
|   netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, &cfg, ethernetif0_init, |   if(0 == enet_port) { | ||||||
|         tcpip_input); | #ifdef NETIF_ENET0_INIT_FUNC | ||||||
|  |     netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET0_INIT_FUNC, | ||||||
|  |         ethernet_input); | ||||||
|  | #endif | ||||||
|  |   } else if (1 == enet_port) { | ||||||
|  | #ifdef NETIF_ENET1_INIT_FUNC | ||||||
|  |     netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET1_INIT_FUNC, | ||||||
|  |         ethernet_input); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   netif_set_default(&gnetif); |   netif_set_default(&gnetif); | ||||||
|   netif_set_up(&gnetif); |   netif_set_up(&gnetif); | ||||||
|  |  | ||||||
|  | @ -53,12 +53,13 @@ | ||||||
| #define LWIP_LOCAL_PORT             4840 | #define LWIP_LOCAL_PORT             4840 | ||||||
| #define LWIP_TARGET_PORT            LWIP_LOCAL_PORT | #define LWIP_TARGET_PORT            LWIP_LOCAL_PORT | ||||||
| 
 | 
 | ||||||
| #define LWIP_DEMO_TIMES             3 | #define LWIP_DEMO_TIMES             10 | ||||||
| #define LWIP_TASK_STACK_SIZE        4096 | #define LWIP_TASK_STACK_SIZE        4096 | ||||||
| #define LWIP_DEMO_TASK_PRIO         20 | #define LWIP_DEMO_TASK_PRIO         20 | ||||||
| 
 | 
 | ||||||
| /* MAC address configuration. */ | // /* MAC address configuration. */
 | ||||||
| #define configMAC_ADDR {0x02, 0x12, 0x13, 0x10, 0x15, 0x11} | // #define configMAC_ADDR {0x02, 0x12, 0x13, 0x10, 0x15, 0x11}
 | ||||||
|  | // #define configMAC_ADDR_ETH1 {0x02, 0x12, 0x13, 0x10, 0x15, 0x12}
 | ||||||
| 
 | 
 | ||||||
| /* USER CODE END 0 */ | /* USER CODE END 0 */ | ||||||
| #define SYS_MBOX_NULL  -1 | #define SYS_MBOX_NULL  -1 | ||||||
|  | @ -88,10 +89,19 @@ extern char lwip_flag; | ||||||
| extern char lwip_ipaddr[]; | extern char lwip_ipaddr[]; | ||||||
| extern char lwip_netmask[]; | extern char lwip_netmask[]; | ||||||
| extern char lwip_gwaddr[]; | extern char lwip_gwaddr[]; | ||||||
|  | 
 | ||||||
|  | extern char lwip_eth0_ipaddr[]; | ||||||
|  | extern char lwip_eth0_netmask[]; | ||||||
|  | extern char lwip_eth0_gwaddr[]; | ||||||
|  | 
 | ||||||
|  | extern char lwip_eth1_ipaddr[]; | ||||||
|  | extern char lwip_eth1_netmask[]; | ||||||
|  | extern char lwip_eth1_gwaddr[]; | ||||||
|  | 
 | ||||||
| extern struct netif gnetif; | extern struct netif gnetif; | ||||||
| 
 | 
 | ||||||
| void lwip_tcp_init(void); | void lwip_tcp_init(void); | ||||||
| void lwip_config_net(char *ip, char *mask, char *gw); | void lwip_config_net(uint8_t enet_port, char *ip, char *mask, char *gw); | ||||||
| void lwip_config_tcp(char *ip, char *mask, char *gw); | void lwip_config_tcp(uint8_t enet_port, char *ip, char *mask, char *gw); | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -24,49 +24,82 @@ | ||||||
| #include <sys.h> | #include <sys.h> | ||||||
| 
 | 
 | ||||||
| /******************************************************************************/ | /******************************************************************************/ | ||||||
| 
 | uint8_t enet_id = 0; | ||||||
| static void LwipSetIPTask(void *param) | static void LwipSetIPTask(void *param) | ||||||
| { | { | ||||||
|     lwip_config_net(lwip_ipaddr, lwip_netmask, lwip_gwaddr); |     uint8_t enet_port = *(uint8_t *)param; ///< test enet port 
 | ||||||
|  |     printf("lw: [%s] config netport id[%d]\n", __func__, enet_port); | ||||||
|  |     lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LwipSetIPTest(int argc, char *argv[]) | void LwipSetIPTest(int argc, char *argv[]) | ||||||
| { | { | ||||||
|     if(argc >= 4) |     if(argc >= 4) | ||||||
|     { |     { | ||||||
|         lw_print("lw: [%s] ip %s mask %s gw %s\n", __func__, argv[1], argv[2], argv[3]); |         printf("lw: [%s] ip %s mask %s gw %s netport %s\n", __func__, argv[1], argv[2], argv[3], argv[4]); | ||||||
|         sscanf(argv[1], "%d.%d.%d.%d", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]); |         sscanf(argv[1], "%d.%d.%d.%d", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]); | ||||||
|         sscanf(argv[2], "%d.%d.%d.%d", &lwip_netmask[0], &lwip_netmask[1], &lwip_netmask[2], &lwip_netmask[3]); |         sscanf(argv[2], "%d.%d.%d.%d", &lwip_netmask[0], &lwip_netmask[1], &lwip_netmask[2], &lwip_netmask[3]); | ||||||
|         sscanf(argv[3], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]); |         sscanf(argv[3], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]); | ||||||
|  |         sscanf(argv[4], "%d", &enet_id); | ||||||
|  | 
 | ||||||
|  |         if(0 == enet_id) | ||||||
|  |         { | ||||||
|  |             printf("save eth0 info\n"); | ||||||
|  |             memcpy(lwip_eth0_ipaddr, lwip_ipaddr, 20); | ||||||
|  |             memcpy(lwip_eth0_netmask, lwip_netmask, 20); | ||||||
|  |             memcpy(lwip_eth0_gwaddr, lwip_gwaddr, 20); | ||||||
|  |         } | ||||||
|  |         else if(1 == enet_id) | ||||||
|  |         { | ||||||
|  |             printf("save eth1 info\n"); | ||||||
|  |             memcpy(lwip_eth1_ipaddr, lwip_ipaddr, 20); | ||||||
|  |             memcpy(lwip_eth1_netmask, lwip_netmask, 20); | ||||||
|  |             memcpy(lwip_eth1_gwaddr, lwip_gwaddr, 20); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     else if(argc == 2) |     else if(argc == 2) | ||||||
|     { |     { | ||||||
|         lw_print("lw: [%s] ipaddr %s\n", __func__, argv[1]); |         printf("lw: [%s] set eth0 ipaddr %s \n", __func__, argv[1]); | ||||||
|         sscanf(argv[1], "%d.%d.%d.%d", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]); |         sscanf(argv[1], "%d.%d.%d.%d", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]); | ||||||
|  |         memcpy(lwip_eth0_ipaddr, lwip_ipaddr, strlen(lwip_ipaddr)); | ||||||
|     } |     } | ||||||
| 
 |     sys_thread_new("SET ip address", LwipSetIPTask, &enet_id, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); | ||||||
|     sys_thread_new("SET ip address", LwipSetIPTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3), | SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(5), | ||||||
|      setip, LwipSetIPTest, SetIp [IP] [Netmask] [Gateway]); |      setip, LwipSetIPTest, setip [IP] [Netmask] [Gateway] [port]); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void LwipShowIPTask(int argc, char *argv[]) | void LwipShowIPTask(int argc, char *argv[]) | ||||||
| { | { | ||||||
|     char mac_addr[] = configMAC_ADDR; |     char mac_addr0[] = configMAC_ADDR; | ||||||
| 
 | 
 | ||||||
|     lw_notice("\r\n************************************************\r\n"); |     lw_notice("\r\n************************************************\r\n"); | ||||||
|     lw_notice(" Network Configuration\r\n"); |     lw_notice(" Network Configuration\r\n"); | ||||||
|     lw_notice("************************************************\r\n"); |     lw_notice("************************************************\r\n"); | ||||||
|     lw_notice(" IPv4 Address   : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_ipaddr)[0], ((u8_t *)&lwip_ipaddr)[1], |     lw_notice(" ETH0 IPv4 Address   : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_eth0_ipaddr)[0], ((u8_t *)&lwip_eth0_ipaddr)[1], | ||||||
|          ((u8_t *)&lwip_ipaddr)[2], ((u8_t *)&lwip_ipaddr)[3]); |         ((u8_t *)&lwip_eth0_ipaddr)[2], ((u8_t *)&lwip_eth0_ipaddr)[3]); | ||||||
|     lw_notice(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_netmask)[0], ((u8_t *)&lwip_netmask)[1], |     lw_notice(" ETH0 IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_eth0_netmask)[0], ((u8_t *)&lwip_eth0_netmask)[1], | ||||||
|          ((u8_t *)&lwip_netmask)[2], ((u8_t *)&lwip_netmask)[3]); |         ((u8_t *)&lwip_eth0_netmask)[2], ((u8_t *)&lwip_eth0_netmask)[3]); | ||||||
|     lw_notice(" IPv4 Gateway   : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_gwaddr)[0], ((u8_t *)&lwip_gwaddr)[1], |     lw_notice(" ETH0 IPv4 Gateway   : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_gwaddr)[0], ((u8_t *)&lwip_eth0_gwaddr)[1], | ||||||
|          ((u8_t *)&lwip_gwaddr)[2], ((u8_t *)&lwip_gwaddr)[3]); |         ((u8_t *)&lwip_eth0_gwaddr)[2], ((u8_t *)&lwip_eth0_gwaddr)[3]); | ||||||
|     lw_notice(" MAC Address    : %x:%x:%x:%x:%x:%x\r\n", mac_addr[0], mac_addr[1], mac_addr[2], |     lw_notice(" ETH0 MAC Address    : %x:%x:%x:%x:%x:%x\r\n", mac_addr0[0], mac_addr0[1], mac_addr0[2], | ||||||
|         mac_addr[3], mac_addr[4], mac_addr[5]); |         mac_addr0[3], mac_addr0[4], mac_addr0[5]); | ||||||
|  | #ifdef BOARD_NET_COUNT | ||||||
|  |     if(BOARD_NET_COUNT > 1) | ||||||
|  |     { | ||||||
|  |         char mac_addr1[] = configMAC_ADDR_ETH1; | ||||||
|  |         lw_notice("\r\n"); | ||||||
|  |         lw_notice(" ETH1 IPv4 Address   : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_eth1_ipaddr)[0], ((u8_t *)&lwip_eth1_ipaddr)[1], | ||||||
|  |             ((u8_t *)&lwip_eth1_ipaddr)[2], ((u8_t *)&lwip_eth1_ipaddr)[3]); | ||||||
|  |         lw_notice(" ETH1 IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_eth1_netmask)[0], ((u8_t *)&lwip_eth1_netmask)[1], | ||||||
|  |             ((u8_t *)&lwip_eth1_netmask)[2], ((u8_t *)&lwip_eth1_netmask)[3]); | ||||||
|  |         lw_notice(" ETH1 IPv4 Gateway   : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_eth1_gwaddr)[0], ((u8_t *)&lwip_eth1_gwaddr)[1], | ||||||
|  |             ((u8_t *)&lwip_eth1_gwaddr)[2], ((u8_t *)&lwip_eth1_gwaddr)[3]); | ||||||
|  |         lw_notice(" ETH1 MAC Address    : %x:%x:%x:%x:%x:%x\r\n", mac_addr1[0], mac_addr1[1], mac_addr1[2], | ||||||
|  |             mac_addr1[3], mac_addr1[4], mac_addr1[5]); | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|     lw_notice("************************************************\r\n"); |     lw_notice("************************************************\r\n"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -29,16 +29,12 @@ | ||||||
| #include "lwip/dhcp.h" | #include "lwip/dhcp.h" | ||||||
| #include "lwip/prot/dhcp.h" | #include "lwip/prot/dhcp.h" | ||||||
| #include "netif/ethernet.h" | #include "netif/ethernet.h" | ||||||
| #include "enet_ethernetif.h" |  | ||||||
| 
 | 
 | ||||||
| #include <shell.h> | #include <shell.h> | ||||||
|  | #include <assert.h> | ||||||
|  | #include <sys_arch.h> | ||||||
| #include "board.h" | #include "board.h" | ||||||
| 
 | #include "connect_ethernet.h" | ||||||
| #include "pin_mux.h" |  | ||||||
| #include "clock_config.h" |  | ||||||
| #include "fsl_gpio.h" |  | ||||||
| #include "fsl_iomuxc.h" |  | ||||||
| #include "sys_arch.h" |  | ||||||
| 
 | 
 | ||||||
| #define LWIP_DHCP_TIME 10000 // 10s
 | #define LWIP_DHCP_TIME 10000 // 10s
 | ||||||
| 
 | 
 | ||||||
|  | @ -123,9 +119,10 @@ void LwipDHCPTest(void) | ||||||
| { | { | ||||||
|     u32_t dhcp_time; |     u32_t dhcp_time; | ||||||
|     static int flag = 0; |     static int flag = 0; | ||||||
|  |     uint8_t enet_port = 0; ///< test enet port 0
 | ||||||
|     char ip_addr[4] = {0, 0, 0, 0}; |     char ip_addr[4] = {0, 0, 0, 0}; | ||||||
| 
 | 
 | ||||||
|     lwip_config_net(ip_addr, ip_addr, ip_addr); |     lwip_config_net(enet_port, ip_addr, ip_addr, ip_addr); | ||||||
|     set_lwip_bit(LWIP_PRINT_FLAG); |     set_lwip_bit(LWIP_PRINT_FLAG); | ||||||
| 
 | 
 | ||||||
|     dhcp_start(&gnetif); |     dhcp_start(&gnetif); | ||||||
|  |  | ||||||
|  | @ -29,15 +29,10 @@ | ||||||
| #include "netif/ethernet.h" | #include "netif/ethernet.h" | ||||||
| #include <shell.h> | #include <shell.h> | ||||||
| #include "board.h" | #include "board.h" | ||||||
| #include "pin_mux.h" |  | ||||||
| #include "clock_config.h" |  | ||||||
| 
 | 
 | ||||||
| #include <sys_arch.h> | #include <sys_arch.h> | ||||||
| #include "connect_ethernet.h" | #include "connect_ethernet.h" | ||||||
| 
 | 
 | ||||||
| char test_ip_addr[] = {192, 168, 145, 220}; |  | ||||||
| char test_net_mask[] = {255, 255, 255, 0}; |  | ||||||
| char test_gw_addr[] = {192, 168, 145, 1}; |  | ||||||
| ip4_addr_t ping_addr; | ip4_addr_t ping_addr; | ||||||
| 
 | 
 | ||||||
| /******************************************************************************/ | /******************************************************************************/ | ||||||
|  | @ -45,17 +40,52 @@ ip4_addr_t ping_addr; | ||||||
| void LwipPingTest(int argc, char *argv[]) | void LwipPingTest(int argc, char *argv[]) | ||||||
| { | { | ||||||
|     int result = 0; |     int result = 0; | ||||||
|  |     uint8_t enet_port = 0; ///< test enet port 0
 | ||||||
| 
 | 
 | ||||||
|     if(argc >= 4) |     if(argc >= 4) | ||||||
|     { |     { | ||||||
|         lw_print("lw: [%s] ip %s mask %s gw %s\n", __func__, argv[1], argv[2], argv[3]); |         printf("lw: [%s] ip %s mask %s gw %s for netport %s\n", __func__, argv[1], argv[2], argv[3], argv[4]); | ||||||
|         sscanf(argv[1], "%d.%d.%d.%d", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]); |         sscanf(argv[1], "%d.%d.%d.%d", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]); | ||||||
|         sscanf(argv[2], "%d.%d.%d.%d", &lwip_netmask[0], &lwip_netmask[1], &lwip_netmask[2], &lwip_netmask[3]); |         sscanf(argv[2], "%d.%d.%d.%d", &lwip_netmask[0], &lwip_netmask[1], &lwip_netmask[2], &lwip_netmask[3]); | ||||||
|         sscanf(argv[3], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]); |         sscanf(argv[3], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]); | ||||||
|  |         sscanf(argv[4], "%d", &enet_port); | ||||||
|  | 
 | ||||||
|  |         if(0 == enet_port) | ||||||
|  |         { | ||||||
|  |             memcpy(lwip_eth0_ipaddr, lwip_ipaddr, strlen(lwip_ipaddr)); | ||||||
|  |             memcpy(lwip_eth0_netmask, lwip_netmask, strlen(lwip_netmask)); | ||||||
|  |             memcpy(lwip_eth0_gwaddr, lwip_gwaddr, strlen(lwip_gwaddr)); | ||||||
|  |         } | ||||||
|  |         if(1 == enet_port) | ||||||
|  |         { | ||||||
|  |             memcpy(lwip_eth1_ipaddr, lwip_ipaddr, strlen(lwip_ipaddr)); | ||||||
|  |             memcpy(lwip_eth1_netmask, lwip_netmask, strlen(lwip_netmask)); | ||||||
|  |             memcpy(lwip_eth1_gwaddr, lwip_gwaddr, strlen(lwip_gwaddr)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     else if(argc == 3) | ||||||
|  |     { | ||||||
|  |         sscanf(argv[2], "%d", &enet_port); | ||||||
|  |         printf("lw: [%s] gw %s netport %d\n", __func__, argv[1], enet_port); | ||||||
|  |         if(isdigit(argv[1][0])) | ||||||
|  |         { | ||||||
|  |             if(sscanf(argv[1], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]) == EOF) | ||||||
|  |             { | ||||||
|  |                 lw_notice("input wrong ip\n"); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | #if (LWIP_DHCP) && (PING_USE_SOCKETS) | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             get_url_ip(argv[1]); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | #endif | ||||||
|     } |     } | ||||||
|     else if(argc == 2) |     else if(argc == 2) | ||||||
|     { |     { | ||||||
|         lw_print("lw: [%s] gw %s\n", __func__, argv[1]); |         printf("lw: [%s] gw %s\n", __func__, argv[1]); | ||||||
|         if(isdigit(argv[1][0])) |         if(isdigit(argv[1][0])) | ||||||
|         { |         { | ||||||
|             if(sscanf(argv[1], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]) == EOF) |             if(sscanf(argv[1], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]) == EOF) | ||||||
|  | @ -73,14 +103,14 @@ void LwipPingTest(int argc, char *argv[]) | ||||||
| #endif | #endif | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     lw_print("lw: [%s] argc %d\n", __func__, argc); |     printf("lw: [%s] argc %d\n", __func__, argc); | ||||||
| 
 | 
 | ||||||
|     IP4_ADDR(&ping_addr, lwip_gwaddr[0], lwip_gwaddr[1], lwip_gwaddr[2], lwip_gwaddr[3]); |     IP4_ADDR(&ping_addr, lwip_gwaddr[0], lwip_gwaddr[1], lwip_gwaddr[2], lwip_gwaddr[3]); | ||||||
|     lwip_config_net(lwip_ipaddr, lwip_netmask, lwip_gwaddr); |     lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr); | ||||||
|     ping_init(&ping_addr); |     ping_init(&ping_addr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3), | SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(5), | ||||||
|      ping, LwipPingTest, ping [IP] 3 times); |      ping, LwipPingTest, ping [IP] 10 times); | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -70,6 +70,7 @@ static void LwipTcpSendTask(void *arg) | ||||||
| void LwipTcpSendTest(int argc, char *argv[]) | void LwipTcpSendTest(int argc, char *argv[]) | ||||||
| { | { | ||||||
|     LwipTcpSocketParamType param; |     LwipTcpSocketParamType param; | ||||||
|  |     uint8_t enet_port = 0; | ||||||
|     memset(tcp_demo_msg, 0, LWIP_TEST_MSG_SIZE); |     memset(tcp_demo_msg, 0, LWIP_TEST_MSG_SIZE); | ||||||
|     if(argc >= 2) |     if(argc >= 2) | ||||||
|     { |     { | ||||||
|  | @ -89,7 +90,7 @@ void LwipTcpSendTest(int argc, char *argv[]) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     lw_notice("get ipaddr %d.%d.%d.%d:%d\n", tcp_demo_ip[0], tcp_demo_ip[1], tcp_demo_ip[2], tcp_demo_ip[3], tcp_demo_port); |     lw_notice("get ipaddr %d.%d.%d.%d:%d\n", tcp_demo_ip[0], tcp_demo_ip[1], tcp_demo_ip[2], tcp_demo_ip[3], tcp_demo_port); | ||||||
|     lwip_config_tcp(lwip_ipaddr, lwip_netmask, tcp_demo_ip); |     lwip_config_tcp(enet_port, lwip_ipaddr, lwip_netmask, tcp_demo_ip); | ||||||
| 
 | 
 | ||||||
|     memcpy(param.ip, tcp_demo_ip, 4); |     memcpy(param.ip, tcp_demo_ip, 4); | ||||||
|     param.port = tcp_demo_port; |     param.port = tcp_demo_port; | ||||||
|  | @ -104,7 +105,9 @@ SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | | ||||||
| 
 | 
 | ||||||
| void LwipTcpRecvTest(void) | void LwipTcpRecvTest(void) | ||||||
| { | { | ||||||
|     lwip_config_net(lwip_ipaddr, lwip_netmask, lwip_gwaddr); |     uint8_t enet_port = 0; ///< test enet port 0
 | ||||||
|  | 
 | ||||||
|  |     lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr); | ||||||
|     tcpecho_raw_init(); |     tcpecho_raw_init(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -75,6 +75,7 @@ static void LwipUDPSendTask(void *arg) | ||||||
| 
 | 
 | ||||||
| void *LwipUdpSendTest(int argc, char *argv[]) | void *LwipUdpSendTest(int argc, char *argv[]) | ||||||
| { | { | ||||||
|  |     uint8_t enet_port = 0; ///< test enet port 0
 | ||||||
|     memset(udp_demo_msg, 0, sizeof(udp_demo_msg)); |     memset(udp_demo_msg, 0, sizeof(udp_demo_msg)); | ||||||
| 
 | 
 | ||||||
|     if(argc == 1) |     if(argc == 1) | ||||||
|  | @ -94,7 +95,7 @@ void *LwipUdpSendTest(int argc, char *argv[]) | ||||||
| 
 | 
 | ||||||
|     lw_print("lw: [%s] gw %d.%d.%d.%d\n", __func__, udp_demo_ip[0], udp_demo_ip[1], udp_demo_ip[2], udp_demo_ip[3]); |     lw_print("lw: [%s] gw %d.%d.%d.%d\n", __func__, udp_demo_ip[0], udp_demo_ip[1], udp_demo_ip[2], udp_demo_ip[3]); | ||||||
| 
 | 
 | ||||||
|     lwip_config_net(lwip_ipaddr, lwip_netmask, udp_demo_ip); |     lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, udp_demo_ip); | ||||||
|     sys_thread_new("udp send", LwipUDPSendTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); |     sys_thread_new("udp send", LwipUDPSendTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -140,8 +141,9 @@ static void LwipUdpRecvTask(void *arg, struct udp_pcb *upcb, struct pbuf *p, | ||||||
| void LwipUdpRecvTest(void) | void LwipUdpRecvTest(void) | ||||||
| { | { | ||||||
|     err_t err; |     err_t err; | ||||||
|  |     uint8_t enet_port = 0; ///< test enet port 0
 | ||||||
| 
 | 
 | ||||||
|     lwip_config_net(lwip_ipaddr, lwip_netmask, lwip_gwaddr); |     lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr); | ||||||
| 
 | 
 | ||||||
|     udpecho_raw_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); |     udpecho_raw_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); | ||||||
|     if (udpecho_raw_pcb == NULL) |     if (udpecho_raw_pcb == NULL) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue