diff --git a/README.md b/README.md index 41ac3fff217d5da69c2cb4336f2653c4b5d7947c..62b4566ab0b43eed9388ebfd9a9a1acc831866db 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Phytium-FreeRTOS-SDK -**v1.1.0** [ReleaseNote](./docs/ChangeLog.md) +**v1.2.0** [ReleaseNote](./docs/ChangeLog.md) **如需Phytium全系CPU的软件适配支持,请联系 ``linan1284@phytium.com.cn``** @@ -52,48 +52,51 @@ | Feature | Platform Supported | Platform Developing | Component | | -------------------| ------------------------------------------| ------------------------------------ | ---------------------- | -| EVENTGROUP | PD1904
PD2008
PE220X | | eventgroup | -| INTERRUPT | PD1904
PE220X
PD2008 | | interrupt | -| QUEUE | PD1904
PD2008
PE220X | | queue | -| RESOURCE | PD1904
PE220X
PD2008 | | resource | -| SOFTWARE_TIMER | PD1904
PD2008
PE220X | | software_timer | -| TASK | PD1904
PE220X
PD2008 | | task | -| TASK_NOTIFY | PD1904
PD2008
PE220X | | task_notify | +| EVENTGROUP | PD1904
PD2008
PE220X
PD2308
PD2408 | | eventgroup | +| INTERRUPT | PD1904
PE220X
PD2008
PD2308
PD2408 | | interrupt | +| QUEUE | PD1904
PD2008
PE220X
PD2308
PD2408 | | queue | +| RESOURCE | PD1904
PE220X
PD2008
PD2308
PD2408 | | resource | +| SOFTWARE_TIMER | PD1904
PD2008
PE220X
PD2308
PD2408 | | software_timer | +| TASK | PD1904
PE220X
PD2008
PD2308
PD2408 | | task | +| TASK_NOTIFY | PD1904
PD2008
PE220X
PD2308
PD2408 | | task_notify | | Network | Platform Supported | Platform Developing | Component | | -------------------| ------------------------------------------| ------------------------------------ | ---------------------- | -| LWIP | PD1904
PD2008
PE220X
PD2408| | lwip_startup | -| UDP | PD1904
PE220X
PD2008
PD2408| | sockets/udp_multicast | - -| Peripherals | Platform Supported | Platform Developing | Component | -| ------------------------------ | ------------------------------------------| ------------------------------------ | -------------------- | -| ADC | | PE220X | adc | -| CAN | PD1904
PE220X
PD2008 | | can/can | -| DDMA | PE220X | | dma/ddma | -| GDMA | PE220X | | dma/gdma | -| GPIO | PE220X
PD2408 | | gpio | -| I2C | PE220X
PD2408 | FT2004/PD2008 | i2c | -| MEDIA | PE220X | | media | -| QSPI (Nor Flash) | PE220X
PD2008
PD1904
PD2408 | | qspi | -| SPI | PE220X
PD2408 | | spi | -| TIMER & TACHO | PE220X | | timer&tacho | -| SDIF | PE220X
PD2408 | | sd | -| PWM | PE220X
PD2408 | | pwm | -| USB(Host/Device) | PE220X
PD2408 | | usb | -| WDT | PD1904
PD2008
PE220X | | wdt | +| LWIP | PD1904
PD2008
PE220X
PD2308
PD2408 | | lwip_startup | +| UDP | PD1904
PE220X
PD2008
PD2308
PD2408 | | sockets/udp_multicast | +| WLAN | PE220X | | wlan/wlan_hostapd | + +| Peripherals | Platform Supported | Platform Developing | Component | +| ------------------------------ | ---------------------------------------------------| ------------------------------------ | -------------------- | +| ADC | | PE220X | adc | +| CAN | PD1904
PE220X
PD2308
PD2008 | | can/can | +| DDMA | PE220X
PD2308 | | dma/ddma | +| GDMA | PE220X
PD2008 | | dma/gdma | +| GPIO | PE220X
PD2008
PD2308
PD2408 | | gpio | +| I2C | PE220X
PD2308
PD2408 | FT2004/PD2008 | i2c | +| I2S | PE220X | | i2s | +| MEDIA | PE220X | | media | +| QSPI (Nor Flash) | PE220X
PD2008
PD1904
PD2408 | | qspi | +| SPI | PE220X
PD2308
PD2408 | | spi | +| TIMER & TACHO | PE220X
PD2308 | | timer&tacho | +| SDIF | PE220X
PD2408 | | sd | +| PWM | PE2204
PD2308
PD2408 | | pwm | +| USB(Host/Device) | PE220X
PD2408 | | usb | +| WDT | PD1904
PD2008
PD2308
PE220X
PD2408 | | wdt | | Storage | Platform Supported | Platform Developing | Component | | -------------------| ------------------------------------------| ------------------------------------ | ---------------------- | -| FATFS | PE220X
PD2408 | | fatfs | -| QSPI_SPIFFS | PD1904
PE220X
PD2008 | | qspi_spiffs | -| SPIM_SPIFFS | PE220X
PD2408 | | spim_spiffs | - -| System | Platform Supported | Platform Developing | Component | -| -------------------| ------------------------------------------| ------------------------------------ | ---------------------- | -| AMP | PE220X
PD2408 | PD2008
PD1904 | amp/openamp | -| ATOMIC | PD1904
PD2008
PE220X
PD2408| | atomic | -| EXCEPTION_DEBUG | PD1904
PD2008
PE220X
PD2408| | exception_debug | -| NESTED_INTERRUPT | PD1904
PD2008
PE220X
PD2408| | nested_interrupt | +| FATFS | PE220X
PD2308
PD2408 | | fatfs | +| QSPI_SPIFFS | PD1904
PD2308
PE220X
PD2008 | | qspi_spiffs | +| SPIM_SPIFFS | PE220X
PD2308
PD2408 | | spim_spiffs | + +| System | Platform Supported | Platform Developing | Component | +| -------------------| ---------------------------------------------------| ------------------------------------ | ---------------------- | +| AMP | PE220X
PD2008
PD2308
PD2408 |
PD1904 | amp/openamp | +| ATOMIC | PD1904
PD2008
PE220X
PD2308
PD2408 | | atomic | +| EXCEPTION_DEBUG | PD1904
PD2008
PE220X
PD2308
PD2408 | | exception_debug | +| NESTED_INTERRUPT | PD1904
PD2008
PE220X
PD2308
PD2408 | | nested_interrupt | +| POSIX | PD1904
PD2008
PE220X
PD2308
PD2408 | | posix | --- ## 5. 参考资料 @@ -122,4 +125,4 @@ liushengming1118@phytium.com.cn ## 7. 许可协议 -Phytium Public License 1.0 (PPL-1.0) \ No newline at end of file +[Phytium Public License](./LICENSE) \ No newline at end of file diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md index 00a151dcc2e6bca2e6b7dce9d8bb5049bc06dcdf..2d79376acddc666a5c5cc33a1bcc76d311223f98 100644 --- a/docs/ChangeLog.md +++ b/docs/ChangeLog.md @@ -1,3 +1,23 @@ +# Phytium FreeRTOS SDK 2025-10-28 v1.2.0 ChangeLog + +Change Log since 2025-10-22 + +## docs + +- update changelog,release note, and readme + +# Phytium FreeRTOS SDK 2025-10-22 ChangeLog + +Change Log since 2025-09-04 + +## driver + +- add e1000e + +## example + +- support e1000e iperf test + # Phytium FreeRTOS SDK 2025-09-04 ChangeLog Change Log since 2025-09-03 @@ -81,7 +101,7 @@ Change Log since 2025-07-02 ## example -- Add D3000M configuration for each use case in the feature module, improve the README documentation, and complete testing +- Add PD2408 configuration for each use case in the feature module, improve the README documentation, and complete testing # Phytium FreeRTOS SDK 2025-06-30 ChangeLog @@ -110,7 +130,7 @@ Change Log since 2025-06-19 ## example -- add D3000M example config +- add PD2408 example config # Phytium FreeRTOS SDK 2025-06-19 ChangeLog diff --git a/drivers/Kconfig b/drivers/Kconfig index 4da89b3783ace73e13335a40fa37e747daa7f0fc..5bf3b68856a823eec09f1022ac99778a26401412 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -58,6 +58,12 @@ menu "FreeRTOS Eth Drivers" select ENABLE_FXMAC_V2 bool prompt "Use Freertos xmac v2 driver" + default n + + config FREERTOS_USE_E1000E + select ENABLE_E1000E + bool + prompt "Use Freertos e1000e driver" default n endmenu diff --git a/drivers/eth/e1000e/e1000e_os.c b/drivers/eth/e1000e/e1000e_os.c new file mode 100644 index 0000000000000000000000000000000000000000..a90151f7912663d471c971a939a7524bfcc11749 --- /dev/null +++ b/drivers/eth/e1000e/e1000e_os.c @@ -0,0 +1,766 @@ +/* + * Copyright (C) 2025, Phytium Technology Co., Ltd. All Rights Reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + * FilePath: e1000e_os.c + * Date: 2025-10-21 16:33:13 + * LastEditTime: 2025-10-21 16:33:13 + * Description: This file is for e1000e driver.Functions in this file are the minimum required functions for drivers. + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 huangjin 2025/10/21 first release + */ + +#include "fparameters.h" +#include "fassert.h" +#include "e1000e_os.h" +#include "e1000e_phy.h" +#include "e1000e.h" +#include "e1000e_hw.h" +#include "fcache.h" +#include "lwip_port.h" +#include "netif/etharp.h" +#include "eth_ieee_reg.h" +#include "fcpu_info.h" +#include "faarch.h" + +#include "FreeRTOS.h" +#include "semphr.h" + +#include "fdebug.h" + +#include "../include/lwip/sys.h" + +#include "fpcie_ecam.h" +#include "fpcie_ecam_common.h" +#include "fpcie_ecam_msi.h" + +#define OS_MAC_DEBUG_TAG "OS_E1000E" +#define FE1000E_OS_PRINT_E(format, ...) FT_DEBUG_PRINT_E(OS_MAC_DEBUG_TAG, format, ##__VA_ARGS__) +#define FE1000E_OS_PRINT_I(format, ...) FT_DEBUG_PRINT_I(OS_MAC_DEBUG_TAG, format, ##__VA_ARGS__) +#define FE1000E_OS_PRINT_D(format, ...) FT_DEBUG_PRINT_D(OS_MAC_DEBUG_TAG, format, ##__VA_ARGS__) +#define FE1000E_OS_PRINT_W(format, ...) FT_DEBUG_PRINT_W(OS_MAC_DEBUG_TAG, format, ##__VA_ARGS__) + + +extern void sys_sem_signal(sys_sem_t *sem); +static FE1000EOs fe1000e_lwip_port_instance[FE1000E_NUM] = { + [FE1000E0_ID] = {{{0}}}, +}; + +#define PCIE_MSI_DEVICE_MAX_NUM 32 +extern FE1000EConfig FE1000E_CONFIG_TBL[FE1000E_NUM]; +FPcieMsiVector msi_vector[FE1000E_NUM][PCIE_MSI_DEVICE_MAX_NUM] = {0}; +#define PCI_CLASS_STORAGE_NET_AHCI 0x020000 +/*max support 16 ahci controllers*/ +static FPcieEcam pcie_device; + +/* queue */ + +void FE1000EQueueInit(PqQueue *q) +{ + FASSERT(q != NULL); + q->head = q->tail = q->len = 0; +} + +int FE1000EPqEnqueue(PqQueue *q, void *p) +{ + if (q->len == PQ_QUEUE_SIZE) + { + return -1; + } + + q->data[q->head] = (uintptr)p; + q->head = (q->head + 1) % PQ_QUEUE_SIZE; + q->len++; + + return 0; +} + +void *FE1000EPqDequeue(PqQueue *q) +{ + int ptail; + + if (q->len == 0) + { + return NULL; + } + + ptail = q->tail; + q->tail = (q->tail + 1) % PQ_QUEUE_SIZE; + q->len--; + + return (void *)q->data[ptail]; +} + +int FE1000EPqQlength(PqQueue *q) +{ + return q->len; +} + +int FE1000ELwipPortRxComplete(FE1000EOs *instance_p) +{ + FE1000ECtrl *e1000e_p = &instance_p->instance; + int temp = 0; + u32 rx_idx = e1000e_p->rx_ring.desc_idx; + + SYS_ARCH_DECL_PROTECT(lev); + SYS_ARCH_PROTECT(lev); + + /* 判断是否成功接收 */ + if (e1000e_p->rx[rx_idx].sta & RDESC_STA_DD) + { + temp = 1; + } + else + { + temp = 0; + } + + + SYS_ARCH_UNPROTECT(lev); + return temp; +} + +static FError FE1000ELwipPortConfigConvert(FE1000EOs *instance_p, FE1000EConfig *e1000e_config_p) +{ + FE1000EConfig *mac_config_p; + FE1000EPhyInterface interface = FE1000E_PHY_INTERFACE_MODE_SGMII; + + mac_config_p = FE1000ELookupConfig(instance_p->e1000e_port_config.instance_id); + if (mac_config_p == NULL) + { + FE1000E_OS_PRINT_E("FE1000ELookupConfig is error , instance_id " + "is %d", + instance_p->e1000e_port_config.instance_id); + return FREERTOS_E1000E_INIT_ERROR; + } + + memcpy(e1000e_config_p, mac_config_p, sizeof(FE1000EConfig)); + + switch (instance_p->e1000e_port_config.interface) + { + case FE1000E_OS_INTERFACE_SGMII: + interface = FE1000E_PHY_INTERFACE_MODE_SGMII; + FE1000E_OS_PRINT_I("SGMII select"); + break; + case FE1000E_OS_INTERFACE_RMII: + interface = FE1000E_PHY_INTERFACE_MODE_RMII; + FE1000E_OS_PRINT_I("RMII select"); + break; + case FE1000E_OS_INTERFACE_RGMII: + FE1000E_OS_PRINT_I("RGMII select"); + interface = FE1000E_PHY_INTERFACE_MODE_RGMII; + break; + case FE1000E_OS_INTERFACE_USXGMII: + FE1000E_OS_PRINT_I("USXGMII select"); + instance_p->e1000e_port_config.phy_speed = FE1000E_PHY_SPEED_10G; + interface = FE1000E_PHY_INTERFACE_MODE_USXGMII; + break; + default: + FE1000E_OS_PRINT_E("update interface is error , interface is " + "%d", + instance_p->e1000e_port_config.interface); + return FREERTOS_E1000E_INIT_ERROR; + } + e1000e_config_p->interface = interface; + + if (instance_p->e1000e_port_config.autonegotiation) + { + e1000e_config_p->auto_neg = 1; + } + else + { + e1000e_config_p->auto_neg = 0; + } + + switch (instance_p->e1000e_port_config.phy_speed) + { + case FE1000E_PHY_SPEED_10M: + e1000e_config_p->speed = FE1000E_SPEED_10; + break; + case FE1000E_PHY_SPEED_100M: + e1000e_config_p->speed = FE1000E_SPEED_100; + break; + case FE1000E_PHY_SPEED_1000M: + e1000e_config_p->speed = FE1000E_SPEED_1000; + FE1000E_OS_PRINT_I("select FE1000E_PHY_SPEED_1000M"); + break; + case FE1000E_PHY_SPEED_10G: + FE1000E_OS_PRINT_I("select FE1000E_PHY_SPEED_10G"); + e1000e_config_p->speed = FE1000E_SPEED_10000; + break; + default: + FE1000E_OS_PRINT_E("setting speed is not valid , speed is %d", + instance_p->e1000e_port_config.phy_speed); + return FREERTOS_E1000E_INIT_ERROR; + } + + switch (instance_p->e1000e_port_config.phy_duplex) + { + case FE1000E_PHY_HALF_DUPLEX: + e1000e_config_p->duplex = 0; + FE1000E_OS_PRINT_I("select Half Duplex"); + break; + case FE1000E_PHY_FULL_DUPLEX: + e1000e_config_p->duplex = 1; + FE1000E_OS_PRINT_I("select Full Duplex"); + break; + default: + FE1000E_OS_PRINT_E("setting duplex is not valid , duplex is %d", + instance_p->e1000e_port_config.phy_duplex); + return FREERTOS_E1000E_INIT_ERROR; + } + + return FT_SUCCESS; +} + +static FError FE1000EGetIeeePhySpeed(FE1000ECtrl *instance_p) +{ + u16 temp; + u16 control; + u16 status; + u32 negotiation_timeout_cnt = 0; + FError ret; + + FE1000E_OS_PRINT_I("Start phy auto negotiation."); + + control = FE1000EPhyRead(instance_p->config.base_addr, PHY_CONTROL_REG_OFFSET); + control |= PHY_CONTROL_AUTONEGOTIATE_ENABLE; + control |= PHY_CONTROL_AUTONEGOTIATE_RESTART; + ret = FE1000EPhyWrite(instance_p->config.base_addr, PHY_CONTROL_REG_OFFSET, control); + if (ret != FT_SUCCESS) + { + FE1000E_OS_PRINT_E("%s:%d,write PHY_CONTROL_REG_OFFSET is error", + __func__, __LINE__); + return ret; + } + + FE1000E_OS_PRINT_I("Waiting for phy to complete auto negotiation."); + + do + { + FDriverMdelay(50); + status = FE1000EPhyRead(instance_p->config.base_addr, PHY_STATUS_REG_OFFSET); + + + if (negotiation_timeout_cnt++ >= 0xff) + { + FE1000E_OS_PRINT_E("Auto negotiation is error."); + return FE1000E_ERR_PHY_AUTO_FAILED; + } + } while (!(status & PHY_STATUS_AUTONEGOTIATE_COMPLETE)); + + FE1000E_OS_PRINT_I("Auto negotiation complete."); + + temp = FE1000EPhyRead(instance_p->config.base_addr, PHY_SPECIFIC_STATUS_REG); + FE1000E_OS_PRINT_I("Temp is 0x%x", temp); + + if (temp & (1 << 13)) + { + FE1000E_OS_PRINT_I("Duplex is full."); + instance_p->config.duplex = 1; + } + else + { + FE1000E_OS_PRINT_I("Duplex is half."); + instance_p->config.duplex = 0; + } + + if ((temp & 0xC000) == PHY_SPECIFIC_STATUS_SPEED_1000M) + { + FE1000E_OS_PRINT_I("Speed is 1000M."); + instance_p->config.speed = 1000; + } + else if ((temp & 0xC000) == PHY_SPECIFIC_STATUS_SPEED_100M) + { + FE1000E_OS_PRINT_I("Speed is 100M."); + instance_p->config.speed = 100; + } + else + { + FE1000E_OS_PRINT_I("Speed is 10M."); + instance_p->config.speed = 10; + } + + return FT_SUCCESS; +} + +enum lwip_port_link_status FE1000EPhyReconnect(struct LwipPort *e1000e_netif_p) +{ + FE1000ECtrl *e1000e_p; + FE1000EOs *instance_p; + FASSERT(e1000e_netif_p != NULL); + FASSERT(e1000e_netif_p->state != NULL); + + instance_p = (FE1000EOs *)(e1000e_netif_p->state); + + e1000e_p = &instance_p->instance; + + if (e1000e_p->config.interface == FE1000E_PHY_INTERFACE_MODE_SGMII) + { + if (e1000e_p->link_status == FE1000E_NEGOTIATION) + { + FE1000EIrqDisable(e1000e_p, IMS_LSC | IMS_RXQ0); + FE1000EGetIeeePhySpeed(e1000e_p); + FE1000EStart(e1000e_p); + e1000e_p->link_status = FE1000E_LINKUP; + FE1000EIrqEnable(e1000e_p, IMS_LSC | IMS_RXQ0); + } + + switch (e1000e_p->link_status) + { + case FE1000E_LINKDOWN: + return ETH_LINK_DOWN; + case FE1000E_LINKUP: + return ETH_LINK_UP; + default: + return ETH_LINK_DOWN; + } + } + else + { + switch (e1000e_p->link_status) + { + case FE1000E_LINKDOWN: + return ETH_LINK_DOWN; + case FE1000E_LINKUP: + return ETH_LINK_UP; + default: + return ETH_LINK_DOWN; + } + } +} + +/* msi irq */ +static void FE1000EPCIeMsiIrqHandler(s32 vector, void *param) +{ + FE1000EIrqHandler(0, param); +} + +static void FE1000ETransDoneCallback(void *param) +{ + FE1000E_OS_PRINT_D("FE1000ETransDoneCallback called"); +} + +static void FE1000EReceiveDoneCallBack(void *args) +{ + FE1000E_OS_PRINT_D("FE1000EReceiveDoneCallBack called"); + struct LwipPort *e1000e_netif_p; + FE1000EOs *instance_p = (FE1000EOs *)args; + e1000e_netif_p = (struct LwipPort *)instance_p->stack_pointer; + FE1000EIrqDisable(&instance_p->instance, IMS_RXQ0); + sys_sem_signal(&(e1000e_netif_p->sem_rx_data_available)); +} + +static void FE1000ELinkChangeCallBack(void *args) +{ + u32 ctrl; + u32 link, link_status; + + FE1000ECtrl *e1000e_p; + FE1000EOs *instance_p; + + instance_p = (FE1000EOs *)args; + e1000e_p = &instance_p->instance; + + if (e1000e_p->config.interface == FE1000E_PHY_INTERFACE_MODE_SGMII) + { + FE1000E_OS_PRINT_I("e1000e_p->config.base_address is %p", + e1000e_p->config.base_addr); + ctrl = FE1000E_READREG32(e1000e_p->config.base_addr, E1000_STATUS); + FE1000E_OS_PRINT_I("E1000_STATUS is 0x%x", ctrl); + link = (ctrl & STATUS_LU) >> STATUS_LU_SHFT; + + switch (link) + { + case 0: + FE1000E_OS_PRINT_I("link status is down"); + link_status = FE1000E_LINKDOWN; + break; + case 1: + FE1000E_OS_PRINT_I("link status is up"); + link_status = FE1000E_LINKUP; + break; + default: + FE1000E_OS_PRINT_E("link status is error 0x%x \r\n", link); + return; + } + + if (link_status == FE1000E_LINKUP) + { + if (link_status != e1000e_p->link_status) + { + e1000e_p->link_status = FE1000E_NEGOTIATION; + FE1000E_OS_PRINT_I("need NEGOTIATING"); + } + } + else + { + e1000e_p->link_status = FE1000E_LINKDOWN; + } + } +} + +static FError FPcieInit(FPcieEcam *pcie_device) +{ + FError ret = FE1000E_SUCCESS; + + ret = FPcieEcamCfgInitialize(pcie_device, FPcieEcamLookupConfig(FPCIE_ECAM_INSTANCE0), NULL); + if (ret != FT_SUCCESS) + { + return ret; + } + FE1000E_OS_PRINT_D("\n"); + FE1000E_OS_PRINT_D(" PCI:\n"); + FE1000E_OS_PRINT_D(" B:D:F VID:PID parent_BDF " + " class_code\n"); + ret = FPcieEcamEnumerateBus(pcie_device, 0); + if (ret != FT_SUCCESS) + { + return ret; + } + + return ret; +} + +static FError FNetPcieMsiIrqInstall(FE1000ECtrl *net_device, FPcieEcam *pcie_device, u8 bus, + u8 device, u8 function, FPcieMsiVector *msi_vector) +{ + FError ret = FE1000E_SUCCESS; + u8 ret_msi = 0; + + u32 cpu_id; + GetCpuId(&cpu_id); + printf("bus %d device %d function %d\n", bus, device, function); + ret_msi = FPcieEcamVectorsAllocate(pcie_device, bus, device, function, msi_vector); + printf("start FPcieEcamVectorsAllocate is here , ret_msi = %d\r\n", ret_msi); + FPcieEcamMsiEnable(pcie_device, msi_vector); + /* 中断回调函数 */ + FE1000ERegisterEvtHandler(net_device, FE1000E_TX_COMPLETE_EVT, FE1000ETransDoneCallback); + FE1000ERegisterEvtHandler(net_device, FE1000E_RX_COMPLETE_EVT, FE1000EReceiveDoneCallBack); + FE1000ERegisterEvtHandler(net_device, FE1000E_LINK_STATUS_EVT, FE1000ELinkChangeCallBack); + for (int i = 0; i < ret_msi; i++) + { + /* 注册中断服务函数 */ + InterruptSetPriority(msi_vector->msi[i].irq, E1000E_OS_IRQ_PRIORITY_VALUE); + InterruptSetTargetCpus(msi_vector->msi[i].irq, cpu_id); + InterruptInstall(msi_vector->msi[i].irq, (IrqHandler)FE1000EPCIeMsiIrqHandler, + net_device, "pciemsi"); + InterruptUmask(msi_vector->msi[i].irq); + } + + return ret; +} + +FError FE1000ELwipPortInit(FE1000EOs *instance_p) +{ + s32 host; + u32 pci_class = 0; + const u32 class_code = PCI_CLASS_STORAGE_NET_AHCI; + uintptr bar_addr = 0; + u8 bus = 0; + u8 device = 0; + u8 function = 0; + u32 config_data; + u32 cmdstat; + + FE1000EConfig mac_config; + FE1000ECtrl *e1000e_p; + FError status; + FASSERT(instance_p != NULL); + FASSERT(instance_p->e1000e_port_config.instance_id < FE1000E_NUM); + + e1000e_p = &instance_p->instance; + FE1000E_OS_PRINT_I("instance_id IS %d \r\n", + instance_p->e1000e_port_config.instance_id); + + + status = FE1000ELwipPortConfigConvert(instance_p, &mac_config); + if (status != FT_SUCCESS) + { + FE1000E_OS_PRINT_E("In %s: FE1000ELwipPortControl Convert to " + "FE1000EConfig Failed....\r\n", + __func__); + } + + /* pcie init */ + status = FPcieInit(&pcie_device); + if (status != FE1000E_SUCCESS) + { + FE1000E_OS_PRINT_E("FPcieInit failed."); + return FE1000E_ERR_FAILED; + } + + /* find xhci host from pcie instance */ + for (host = 0; host < pcie_device.scans_bdf_count; host++) + { + bus = pcie_device.scans_bdf[host].bus; + device = pcie_device.scans_bdf[host].device; + function = pcie_device.scans_bdf[host].function; + + FPcieEcamReadConfigSpace(&pcie_device, bus, device, function, + FPCIE_CCR_REV_CLASSID_REGS, &config_data); + FE1000E_OS_PRINT_D("FPCIE_CCR_REV_CLASSID_REGS = %x\n", config_data); + pci_class = config_data >> 8; + + if (pci_class == class_code) + { + FPcieEcamReadConfigSpace(&pcie_device, bus, device, function, + FPCIE_CCR_ID_REG, &config_data); + + FE1000E_OS_PRINT_D("AHCI-PCI HOST found !!!, b.d.f = " + "%x.%x.%x\n", + bus, device, function); + + FPcieEcamReadConfigSpace(&pcie_device, bus, device, function, + FPCIE_CCR_BAR_ADDR0_REGS, (u32 *)&bar_addr); + if (0x0 == bar_addr) + { + FE1000E_OS_PRINT_E("Bar address: 0x%lx", bar_addr); + return -1; + } + FE1000E_OS_PRINT_D("FNetPcieIntrInstall BarAddress %p", bar_addr); + FE1000E_CONFIG_TBL[FE1000E0_ID].base_addr = bar_addr; + e1000e_p->config.base_addr = bar_addr; + mac_config.base_addr = bar_addr; + break; + } + } + if (pci_class != class_code) + { + FE1000E_OS_PRINT_E("class_code: 0x%06x is not pcie net card!", pci_class); + return -1; + } + + status = FE1000ECfgInitialize(e1000e_p, (FE1000EConfig *)&mac_config); + if (status != FT_SUCCESS) + { + FE1000E_OS_PRINT_E("In %s:E1000E Configuration Failed....\r\n", __func__); + } + + /* 设置cmd reg */ + FPcieEcamReadConfigSpace(&pcie_device, bus, device, function, FPCIE_CCR_CMD_STATUS_REGS, &cmdstat); + cmdstat |= (FPCIE_CCR_CMD_MEMORY_ACCESS_ENABLED | FPCIE_CCR_CMD_BUS_MASTER_ENABLED); + FPcieEcamWriteConfigSpace(&pcie_device, bus, device, function, FPCIE_CCR_CMD_STATUS_REGS, cmdstat); + + /* Initialize Rx Description list : ring Mode */ + status = FE1000ESetupRxDescRing(e1000e_p); + if (FT_SUCCESS != status) + { + FE1000E_OS_PRINT_E("e1000e setup rx return err code %d\r\n", status); + FASSERT(FT_SUCCESS == status); + } + + /* Initialize Tx Description list : ring Mode */ + status = FE1000ESetupTxDescRing(e1000e_p); + if (FT_SUCCESS != status) + { + FE1000E_OS_PRINT_E("e1000e setup tx return err code %d\r\n", status); + FASSERT(FT_SUCCESS == status); + } + + FNetPcieMsiIrqInstall(e1000e_p, &pcie_device, bus, device, function, + (FPcieMsiVector *)&msi_vector[FE1000E0_ID]); + FE1000EIrqEnable(e1000e_p, IMS_LSC | IMS_RXQ0); + + /* 打印寄存器的值 */ + FE1000EDebugPrint(e1000e_p); + + return FT_SUCCESS; +} + +void *FE1000ELwipPortRx(FE1000EOs *instance_p) +{ + struct pbuf *p = NULL; + u16 length = 0; + FE1000ECtrl *e1000e_p = &instance_p->instance; + u32 rx_idx = e1000e_p->rx_ring.desc_idx; + + /* get received frame */ + if (FE1000ERecvFrame(e1000e_p) != FT_SUCCESS) + { + return NULL; + } + else + { + FE1000E_OS_PRINT_D("FE1000ERecvFrame is ok!"); + } + + length = e1000e_p->rx[rx_idx].len; + +#if ETH_PAD_SIZE + length += ETH_PAD_SIZE; /* allow room for Ethernet padding */ +#endif + + p = (struct pbuf *)e1000e_p->rxb[rx_idx]; + +#ifdef RAW_DATA_PRINT + dump_hex(Buffer, (u32)length); +#endif + if (p != NULL) + { +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + /* zero copy */ + FCacheDCacheInvalidateRange((uintptr)p->payload, length); + + /* entry queue */ + if (FE1000EPqEnqueue(&instance_p->recv_q, (void *)p) < 0) + { +#if LINK_STATS + lwip_stats.link.memerr++; + lwip_stats.link.drop++; +#endif + pbuf_free(p); + } + + e1000e_p->rxb[rx_idx] = (uintptr)NULL; + p = pbuf_alloc(PBUF_RAW, FE1000E_MAX_FRAME_SIZE, PBUF_POOL); + FCacheDCacheInvalidateRange((uintptr)p->payload, FE1000E_MAX_FRAME_SIZE); + e1000e_p->rx[rx_idx].addr = (uintptr)p->payload; + e1000e_p->rxb[rx_idx] = (uintptr)p; + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + } + else + { + FE1000E_OS_PRINT_E("error: pbuf alloc failed the alloc length is " + "%d", + length); + } + + return p; +} + +void *FE1000ELwipPortQueueRx(FE1000EOs *instance_p) +{ + FASSERT(instance_p != NULL); + struct pbuf *p; + + /* see if there is data to process */ + if (FE1000EPqQlength(&instance_p->recv_q) == 0) + { + return NULL; + } + /* return one packet from receive q */ + p = (struct pbuf *)FE1000EPqDequeue(&instance_p->recv_q); + + return p; +} + +FError FE1000ELwipPortTx(FE1000EOs *instance_p, void *tx_buf) +{ + FASSERT(instance_p != NULL); + FASSERT(tx_buf != NULL); + err_t errval = ERR_OK; + struct pbuf *q; + struct pbuf *p = tx_buf; + FError ret; + u32 bytes_left_to_copy = 0; + FE1000ECtrl *e1000e_p = &instance_p->instance; + + sys_prot_t lev; + lev = sys_arch_protect(); + + for (q = p; q != NULL; q = q->next) + { + /* Get bytes in current lwIP buffer */ + bytes_left_to_copy = q->len; + FE1000E_OS_PRINT_D("bytes_left_to_copy = %d", bytes_left_to_copy); + + /* Copy the remaining bytes */ + e1000e_p->txb[e1000e_p->tx_ring.desc_idx] = (uintptr)q->payload; + } + + ret = FE1000ESendFrame(e1000e_p, bytes_left_to_copy); + + if (ret != FE1000E_SUCCESS) + { + errval = ERR_USE; + FE1000E_OS_PRINT_I("error errval = ERR_USE; FE1000ESendFrame"); + goto error; + } + else + { + FE1000E_OS_PRINT_I("FE1000ESendFrame is ok!!!"); + } + + sys_arch_unprotect(lev); +error: + return errval; +} + +FE1000EOs *FE1000ELwipPortGetInstancePointer(u32 FE1000ELwipPortInstanceID) +{ + FASSERT(FE1000ELwipPortInstanceID < FE1000E_NUM); + + FE1000EOs *instance_p; + instance_p = &fe1000e_lwip_port_instance[FE1000ELwipPortInstanceID]; + return instance_p; +} + +static void FreeOnlyRxPbufs(FE1000EOs *instance_p) +{ + u32 index; + struct pbuf *p; + + for (index = 0; index < (FE1000E_RX_DESCRIPTORS); index++) + { + if (instance_p->instance.rxb[index] != 0) + { + p = (struct pbuf *)instance_p->instance.rxb[index]; + pbuf_free(p); + instance_p->instance.rxb[index] = (uintptr)NULL; + } + } +} + +void FE1000ELwipPortStop(FE1000EOs *instance_p) +{ + u32 rx_queue_len = 0; + struct pbuf *p; + FASSERT(instance_p != NULL); + + /* close mac controler */ + FE1000EStop(&instance_p->instance); + + /* */ + rx_queue_len = FE1000EPqQlength(&instance_p->recv_q); + while (rx_queue_len) + { + /* return one packet from receive q */ + p = (struct pbuf *)FE1000EPqDequeue(&instance_p->recv_q); + pbuf_free(p); + FE1000E_OS_PRINT_W("delete queue %p", p); + rx_queue_len--; + } + + /* free all pbuf */ + FreeOnlyRxPbufs(instance_p); +} + +void FE1000ELwipPortStart(FE1000EOs *instance_p) +{ + FASSERT(instance_p != NULL); + + /* start mac */ + FE1000EStart(&instance_p->instance); +} diff --git a/drivers/eth/e1000e/e1000e_os.h b/drivers/eth/e1000e/e1000e_os.h new file mode 100644 index 0000000000000000000000000000000000000000..c5479951c65756aa868e8c0aac1759cb3dcf7e9c --- /dev/null +++ b/drivers/eth/e1000e/e1000e_os.h @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2025, Phytium Technology Co., Ltd. All Rights Reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + * FilePath: e1000e_os.h + * Date: 2025-10-21 16:33:19 + * LastEditTime: 2025-10-21 16:33:19 + * Description: This file is for e1000e driver.Functions in this file are the minimum required functions for drivers. + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 huangjin 2025/10/21 first release + */ + +#ifndef FE1000E_OS_H +#define FE1000E_OS_H + +#include +#include +#include +#include "e1000e.h" +#include "fkernel.h" +#include "ferror_code.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define FREERTOS_E1000E_INIT_ERROR FT_CODE_ERR(ErrModPort, 0, 0x1) +#define FREERTOS_E1000E_PARAM_ERROR FT_CODE_ERR(ErrModPort, 0, 0x2) +#define FREERTOS_E1000E_NO_VALID_SPACE FT_CODE_ERR(ErrModPort, 0, 0x3) + +#define FE1000E_RX_BDSPACE_LENGTH 0x20000 /* default set 128KB*/ +#define FE1000E_TX_BDSPACE_LENGTH 0x20000 /* default set 128KB*/ + +#define FE1000E_RX_PBUFS_LENGTH 128 +#define FE1000E_TX_PBUFS_LENGTH 128 + +#define FE1000E_RX_DESCRIPTORS 128 +#define FE1000E_TX_DESCRIPTORS 128 + +#define FE1000E_RX_BUFFER_SIZE 2048 +#define FE1000E_TX_BUFFER_SIZE 2048 + +#define FE1000E_MAX_HARDWARE_ADDRESS_LENGTH 6 + +#define E1000E_PHY_RESET_ENABLE 1 +#define E1000E_PHY_RESET_DISABLE 0 + +/* configuration */ +#define FE1000E_OS_CONFIG_JUMBO BIT(0) +#define FE1000E_OS_CONFIG_MULTICAST_ADDRESS_FILITER BIT(1) /* Allow multicast address filtering */ +#define FE1000E_OS_CONFIG_COPY_ALL_FRAMES BIT(2) /* enable copy all frames */ +#define FE1000E_OS_CONFIG_CLOSE_FCS_CHECK BIT(3) /* close fcs check */ +#define FE1000E_OS_CONFIG_UNICAST_ADDRESS_FILITER BIT(5) /* Allow unicast address filtering */ + +/* Phy */ +#define FE1000E_PHY_SPEED_10M 10 +#define FE1000E_PHY_SPEED_100M 100 +#define FE1000E_PHY_SPEED_1000M 1000 +#define FE1000E_PHY_SPEED_10G 10000 + +#define FE1000E_PHY_HALF_DUPLEX 0 +#define FE1000E_PHY_FULL_DUPLEX 1 + +#define MAX_FRAME_SIZE_JUMBO (FE1000E_MTU_JUMBO + FE1000E_HDR_SIZE + FE1000E_TRL_SIZE) + +/* Byte alignment of BDs */ +#define BD_ALIGNMENT (FE1000E_DMABD_MINIMUM_ALIGNMENT*2) + +/* frame queue */ +#define PQ_QUEUE_SIZE 4096 + +/*irq priority value*/ +#define E1000E_OS_IRQ_PRIORITY_VALUE (configMAX_API_CALL_INTERRUPT_PRIORITY+1) +FASSERT_STATIC((E1000E_OS_IRQ_PRIORITY_VALUE <= IRQ_PRIORITY_VALUE_15)&&(E1000E_OS_IRQ_PRIORITY_VALUE >= configMAX_API_CALL_INTERRUPT_PRIORITY)); + +typedef struct +{ + uintptr data[PQ_QUEUE_SIZE]; + int head, tail, len; +} PqQueue; + +typedef enum +{ + FE1000E_OS_INTERFACE_SGMII = 0, + FE1000E_OS_INTERFACE_RMII, + FE1000E_OS_INTERFACE_RGMII, + FE1000E_OS_INTERFACE_USXGMII, + FE1000E_OS_INTERFACE_LENGTH +} FE1000ELwipPortInterface; + + +typedef struct +{ + volatile struct FE1000ETxDesc tx[FE1000E_TX_DESCRIPTORS] __aligned(16); + volatile struct FE1000ERxDesc rx[FE1000E_RX_DESCRIPTORS] __aligned(16); + + uint8_t txb[FE1000E_TX_DESCRIPTORS * FE1000E_TX_BUFFER_SIZE]; + uint8_t rxb[FE1000E_RX_DESCRIPTORS * FE1000E_RX_BUFFER_SIZE]; +} FE1000ENetifBuffer; + +typedef struct +{ + u32 instance_id; + FE1000ELwipPortInterface interface; + u32 autonegotiation; /* 1 is autonegotiation ,0 is manually set */ + u32 phy_speed; /* FE1000E_PHY_SPEED_XXX */ + u32 phy_duplex; /* FE1000E_PHY_XXX_DUPLEX */ +} FE1000ELwipPortConfig; + +typedef struct +{ + FE1000ECtrl instance; + FE1000ELwipPortConfig e1000e_port_config; + + FE1000ENetifBuffer buffer; + + /* queue to store overflow packets */ + PqQueue recv_q; + PqQueue send_q; + + /* indicates whether to enbale e1000e run in special mode,such as jumbo */ + u32 feature; + + struct LwipPort *stack_pointer; /* Docking data stack data structure */ + u8 hwaddr[FE1000E_MAX_HARDWARE_ADDRESS_LENGTH]; + void * netif; /* Pointing to the netif */ +} FE1000EOs; + +FE1000EOs *FE1000ELwipPortGetInstancePointer(u32 FE1000ELwipPortInstanceID); +FError FE1000ELwipPortInit(FE1000EOs *instance_p); +void *FE1000ELwipPortRx(FE1000EOs *instance_p); +FError FE1000ELwipPortTx(FE1000EOs *instance_p, void *tx_buf); +void FE1000ELwipPortStop(FE1000EOs *instance_p); +void FE1000ELwipPortStart(FE1000EOs *instance_p); +void ResetDma(FE1000EOs *instance_p); +enum lwip_port_link_status FE1000EPhyReconnect(struct LwipPort *xmac_netif_p); +enum lwip_port_link_status FE1000EPhyStatus(struct LwipPort *e1000e_netif_p); +void FE1000ERecvHandler(void *arg); +void *FE1000ELwipPortQueueRx(FE1000EOs *instance_p); +int FE1000ELwipPortRxComplete(FE1000EOs *instance_p); + +#ifdef __cplusplus +} +#endif + +#endif // ! diff --git a/drivers/eth/src.mk b/drivers/eth/src.mk index ee605b83ee317387e3c0a0a57a056e5ee39d9c79..7cd302806388493ac9775fec4420d8b0257f3e1e 100644 --- a/drivers/eth/src.mk +++ b/drivers/eth/src.mk @@ -11,4 +11,9 @@ endif ifdef CONFIG_ENABLE_FXMAC_V2 DRIVERS_CSRCS += \ eth/xmac_v2_0/fxmac_msg_os.c +endif + +ifdef CONFIG_ENABLE_E1000E +DRIVERS_CSRCS += \ + eth/e1000e/e1000e_os.c endif \ No newline at end of file diff --git a/drivers/eth/xmac_v2_0/fxmac_msg_os.h b/drivers/eth/xmac_v2_0/fxmac_msg_os.h index 537ab602050433481747042b35f8d3be885ea172..7f0f271ae783d21d23e978753f2912ca873ff529 100644 --- a/drivers/eth/xmac_v2_0/fxmac_msg_os.h +++ b/drivers/eth/xmac_v2_0/fxmac_msg_os.h @@ -46,8 +46,8 @@ extern "C" { #define FXMAC_MSG_RX_BDSPACE_LENGTH 0x20000 /* default set 128KB*/ #define FXMAC_MSG_TX_BDSPACE_LENGTH 0x20000 /* default set 128KB*/ -#define FXMAC_MSG_TX_PBUFS_LENGTH 64 -#define FXMAC_MSG_RX_PBUFS_LENGTH 64 +#define FXMAC_MSG_TX_PBUFS_LENGTH 128 +#define FXMAC_MSG_RX_PBUFS_LENGTH 128 #define FXMAC_MSG_MAX_HARDWARE_ADDRESS_LENGTH 6 diff --git a/drivers/include.mk b/drivers/include.mk index 6b3ec1c96fc94337b1270e33a75989e48f2bb90e..2c34e7744422248b196be2fe3016f40cff0bac0a 100644 --- a/drivers/include.mk +++ b/drivers/include.mk @@ -53,6 +53,10 @@ ifdef CONFIG_ENABLE_FXMAC_V2 BUILD_INC_PATH_DIR += $(OS_DRV_CUR_DIR)/eth/xmac_v2_0 endif +ifdef CONFIG_ENABLE_E1000E + BUILD_INC_PATH_DIR += $(OS_DRV_CUR_DIR)/eth/e1000e +endif + # can ifdef CONFIG_USE_FCAN BUILD_INC_PATH_DIR += $(OS_DRV_CUR_DIR)/can diff --git a/example/network/lwip_https/configs/pd1904_aarch32_dsk_lwip_https.config b/example/network/lwip_https/configs/pd1904_aarch32_dsk_lwip_https.config index 63faaee5229541c0fc1793ff3886634c691e2973..151cb689cf8c37e400ef19126e8f8d4e12164de4 100644 --- a/example/network/lwip_https/configs/pd1904_aarch32_dsk_lwip_https.config +++ b/example/network/lwip_https/configs/pd1904_aarch32_dsk_lwip_https.config @@ -5,6 +5,7 @@ CONFIG_USE_ETH=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FGMAC=y # CONFIG_LWIP_NO_SYS is not set CONFIG_LWIP_USE_MEM_HEAP=y CONFIG_MEM_SIZE=2 diff --git a/example/network/lwip_https/configs/pd1904_aarch64_dsk_lwip_https.config b/example/network/lwip_https/configs/pd1904_aarch64_dsk_lwip_https.config index e9a9be9cb1ea2ba5f77cef0cf06d127dc5e726d2..9c5d607cc736b928522e0cc7f48e5ed2d8297332 100644 --- a/example/network/lwip_https/configs/pd1904_aarch64_dsk_lwip_https.config +++ b/example/network/lwip_https/configs/pd1904_aarch64_dsk_lwip_https.config @@ -5,6 +5,7 @@ CONFIG_USE_ETH=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FGMAC=y # CONFIG_LWIP_NO_SYS is not set CONFIG_LWIP_USE_MEM_HEAP=y CONFIG_MEM_SIZE=2 diff --git a/example/network/lwip_https/configs/pd2008_aarch32_test_lwip_https.config b/example/network/lwip_https/configs/pd2008_aarch32_test_lwip_https.config index 1c6fdb863ee954fa0ebd6d681b9d1039484b786e..7c02805f69afa30fac9eb93c8b66be712211bb6d 100644 --- a/example/network/lwip_https/configs/pd2008_aarch32_test_lwip_https.config +++ b/example/network/lwip_https/configs/pd2008_aarch32_test_lwip_https.config @@ -5,6 +5,7 @@ CONFIG_USE_ETH=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FGMAC=y # CONFIG_LWIP_NO_SYS is not set CONFIG_LWIP_USE_MEM_HEAP=y CONFIG_MEM_SIZE=2 diff --git a/example/network/lwip_https/configs/pd2008_aarch64_test_lwip_https.config b/example/network/lwip_https/configs/pd2008_aarch64_test_lwip_https.config index 557f8c8d17402eb8372ac67f550f50b26b02ca96..de96d716dbaef4c8b0a71682b179aff9d7fdea82 100644 --- a/example/network/lwip_https/configs/pd2008_aarch64_test_lwip_https.config +++ b/example/network/lwip_https/configs/pd2008_aarch64_test_lwip_https.config @@ -5,6 +5,7 @@ CONFIG_USE_ETH=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FGMAC=y # CONFIG_LWIP_NO_SYS is not set CONFIG_LWIP_USE_MEM_HEAP=y CONFIG_MEM_SIZE=2 diff --git a/example/network/lwip_iperf/configs/pd1904_aarch32_dsk_lwip_iperf.config b/example/network/lwip_iperf/configs/pd1904_aarch32_dsk_lwip_iperf.config index 60fd22bf158266445021a6846d867b5a0eee754c..c786041dabfb8969d2a04e3fa9c203739ec8acc7 100644 --- a/example/network/lwip_iperf/configs/pd1904_aarch32_dsk_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/pd1904_aarch32_dsk_lwip_iperf.config @@ -1,11 +1,16 @@ CONFIG_ARCH_ARMV8_AARCH32=y +CONFIG_ENABLE_GIC_ITS=y CONFIG_TARGET_PD1904=y CONFIG_TARGET_NAME="lwip_iperf" CONFIG_USE_ETH=y +CONFIG_USE_PCIE=y +CONFIG_ENABLE_FPCIE_ECAM=y CONFIG_OUTPUT_ASM_DIS=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FGMAC=y +CONFIG_LWIP_E1000E=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y CONFIG_LWIP_USE_MEM_HEAP=y diff --git a/example/network/lwip_iperf/configs/pd1904_aarch64_dsk_lwip_iperf.config b/example/network/lwip_iperf/configs/pd1904_aarch64_dsk_lwip_iperf.config index 1729ae4531b1e73fdd56dc9c1ebdcfb905587c0a..7859ccfa65bfd9b7088c867fa623ff5c44a4ee45 100644 --- a/example/network/lwip_iperf/configs/pd1904_aarch64_dsk_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/pd1904_aarch64_dsk_lwip_iperf.config @@ -1,10 +1,15 @@ +CONFIG_ENABLE_GIC_ITS=y CONFIG_TARGET_PD1904=y CONFIG_TARGET_NAME="lwip_iperf" CONFIG_USE_ETH=y +CONFIG_USE_PCIE=y +CONFIG_ENABLE_FPCIE_ECAM=y CONFIG_OUTPUT_ASM_DIS=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FGMAC=y +CONFIG_LWIP_E1000E=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y CONFIG_LWIP_USE_MEM_HEAP=y diff --git a/example/network/lwip_iperf/configs/pd2008_aarch32_test_lwip_iperf.config b/example/network/lwip_iperf/configs/pd2008_aarch32_test_lwip_iperf.config index 607d0d917074b543a12a8a55555b4d834e46093d..9c26bff9b476b600e34fe857f0942b534d9df10b 100644 --- a/example/network/lwip_iperf/configs/pd2008_aarch32_test_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/pd2008_aarch32_test_lwip_iperf.config @@ -1,11 +1,16 @@ CONFIG_ARCH_ARMV8_AARCH32=y +CONFIG_ENABLE_GIC_ITS=y CONFIG_TARGET_PD2008=y CONFIG_TARGET_NAME="lwip_iperf" CONFIG_USE_ETH=y +CONFIG_USE_PCIE=y +CONFIG_ENABLE_FPCIE_ECAM=y CONFIG_OUTPUT_ASM_DIS=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FGMAC=y +CONFIG_LWIP_E1000E=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y CONFIG_LWIP_USE_MEM_HEAP=y diff --git a/example/network/lwip_iperf/configs/pd2008_aarch64_test_lwip_iperf.config b/example/network/lwip_iperf/configs/pd2008_aarch64_test_lwip_iperf.config index 36c6d9bc2baa022e64588748ae89c6b83e0f3f8e..17cd52873a7f176389aeacd53e9b06d04ff8adad 100644 --- a/example/network/lwip_iperf/configs/pd2008_aarch64_test_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/pd2008_aarch64_test_lwip_iperf.config @@ -1,10 +1,15 @@ +CONFIG_ENABLE_GIC_ITS=y CONFIG_TARGET_PD2008=y CONFIG_TARGET_NAME="lwip_iperf" CONFIG_USE_ETH=y +CONFIG_USE_PCIE=y +CONFIG_ENABLE_FPCIE_ECAM=y CONFIG_OUTPUT_ASM_DIS=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FGMAC=y +CONFIG_LWIP_E1000E=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y CONFIG_LWIP_USE_MEM_HEAP=y diff --git a/example/network/lwip_iperf/configs/pd2308_aarch64_demo_lwip_iperf.config b/example/network/lwip_iperf/configs/pd2308_aarch64_demo_lwip_iperf.config index 34c9796dc92cc692af2bf96e0fe4813f376a4e87..669c791951c234aa294a436a82ee83fdde73bdfe 100644 --- a/example/network/lwip_iperf/configs/pd2308_aarch64_demo_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/pd2308_aarch64_demo_lwip_iperf.config @@ -1,13 +1,17 @@ +CONFIG_ENABLE_GIC_ITS=y CONFIG_TARGET_PD2308=y CONFIG_TARGET_NAME="lwip_iperf" CONFIG_ENABLE_IOPAD=y CONFIG_USE_ETH=y +CONFIG_USE_PCIE=y +CONFIG_ENABLE_FPCIE_ECAM=y CONFIG_DEBUG_CUSTOMOPT=y CONFIG_OUTPUT_ASM_DIS=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y CONFIG_LWIP_FXMAC=y +CONFIG_LWIP_E1000E=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y CONFIG_LWIP_USE_MEM_HEAP=y diff --git a/example/network/lwip_iperf/configs/pd2408_aarch64_test_a_lwip_iperf.config b/example/network/lwip_iperf/configs/pd2408_aarch64_test_a_lwip_iperf.config index b966a233deb106be192cfb843f9cba8cf398ed62..7e65cbec7a7e7fee11fbb9ed33f3643f77457bcb 100644 --- a/example/network/lwip_iperf/configs/pd2408_aarch64_test_a_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/pd2408_aarch64_test_a_lwip_iperf.config @@ -1,8 +1,11 @@ +CONFIG_ENABLE_GIC_ITS=y CONFIG_TARGET_PD2408=y CONFIG_TARGET_NAME="lwip_iperf" CONFIG_USE_IOMUX=y CONFIG_ENABLE_IOPAD=y CONFIG_USE_ETH=y +CONFIG_USE_PCIE=y +CONFIG_ENABLE_FPCIE_ECAM=y CONFIG_USE_MSG=y CONFIG_DEBUG_CUSTOMOPT=y CONFIG_OUTPUT_ASM_DIS=y @@ -10,6 +13,7 @@ CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y CONFIG_LWIP_FXMAC_V2=y +CONFIG_LWIP_E1000E=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y CONFIG_LWIP_USE_MEM_HEAP=y diff --git a/example/network/lwip_iperf/configs/pd2408_aarch64_test_b_lwip_iperf.config b/example/network/lwip_iperf/configs/pd2408_aarch64_test_b_lwip_iperf.config index 0f8de4da2a8f7cc57271096c1e127727ab417fd7..31758a5e9e7652b7abcf348305d32c603be6d9e2 100644 --- a/example/network/lwip_iperf/configs/pd2408_aarch64_test_b_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/pd2408_aarch64_test_b_lwip_iperf.config @@ -1,9 +1,12 @@ +CONFIG_ENABLE_GIC_ITS=y CONFIG_TARGET_PD2408=y CONFIG_PD2408_TEST_B_BOARD=y CONFIG_TARGET_NAME="lwip_iperf" CONFIG_USE_IOMUX=y CONFIG_ENABLE_IOPAD=y CONFIG_USE_ETH=y +CONFIG_USE_PCIE=y +CONFIG_ENABLE_FPCIE_ECAM=y CONFIG_USE_MSG=y CONFIG_DEBUG_CUSTOMOPT=y CONFIG_OUTPUT_ASM_DIS=y @@ -11,6 +14,7 @@ CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y CONFIG_LWIP_FXMAC_V2=y +CONFIG_LWIP_E1000E=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y CONFIG_LWIP_USE_MEM_HEAP=y diff --git a/example/network/lwip_iperf/configs/pe2202_aarch32_demo_lwip_iperf.config b/example/network/lwip_iperf/configs/pe2202_aarch32_demo_lwip_iperf.config index f7dae437f11bfbcdf10bc4d92854c1a313ea62f9..bdd0222e09ef84f2a7eae3f47e0841a1c1db0ea6 100644 --- a/example/network/lwip_iperf/configs/pe2202_aarch32_demo_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/pe2202_aarch32_demo_lwip_iperf.config @@ -1,13 +1,17 @@ CONFIG_ARCH_ARMV8_AARCH32=y +CONFIG_ENABLE_GIC_ITS=y CONFIG_TARGET_PE2202=y CONFIG_TARGET_NAME="lwip_iperf" CONFIG_USE_ETH=y +CONFIG_USE_PCIE=y +CONFIG_ENABLE_FPCIE_ECAM=y CONFIG_DEBUG_CUSTOMOPT=y CONFIG_OUTPUT_ASM_DIS=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y CONFIG_LWIP_FXMAC=y +CONFIG_LWIP_E1000E=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y CONFIG_LWIP_USE_MEM_HEAP=y diff --git a/example/network/lwip_iperf/configs/pe2202_aarch64_demo_lwip_iperf.config b/example/network/lwip_iperf/configs/pe2202_aarch64_demo_lwip_iperf.config index 657fc024fa2f922593b6af334a3d9e4c6dbdc1cc..8ed8860c887c22f276715fa66115778ebe366cf8 100644 --- a/example/network/lwip_iperf/configs/pe2202_aarch64_demo_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/pe2202_aarch64_demo_lwip_iperf.config @@ -1,12 +1,16 @@ +CONFIG_ENABLE_GIC_ITS=y CONFIG_TARGET_PE2202=y CONFIG_TARGET_NAME="lwip_iperf" CONFIG_USE_ETH=y +CONFIG_USE_PCIE=y +CONFIG_ENABLE_FPCIE_ECAM=y CONFIG_DEBUG_CUSTOMOPT=y CONFIG_OUTPUT_ASM_DIS=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y CONFIG_LWIP_FXMAC=y +CONFIG_LWIP_E1000E=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y CONFIG_LWIP_USE_MEM_HEAP=y diff --git a/example/network/lwip_iperf/configs/pe2204_aarch32_demo_lwip_iperf.config b/example/network/lwip_iperf/configs/pe2204_aarch32_demo_lwip_iperf.config index a3794f2bd2fb1615eba09309e55e9c992ff57a5c..c683258b687cd1109dfd0f6ba9ef9c78e38a0e50 100644 --- a/example/network/lwip_iperf/configs/pe2204_aarch32_demo_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/pe2204_aarch32_demo_lwip_iperf.config @@ -1,12 +1,16 @@ CONFIG_ARCH_ARMV8_AARCH32=y +CONFIG_ENABLE_GIC_ITS=y CONFIG_TARGET_NAME="lwip_iperf" CONFIG_USE_ETH=y +CONFIG_USE_PCIE=y +CONFIG_ENABLE_FPCIE_ECAM=y CONFIG_DEBUG_CUSTOMOPT=y CONFIG_OUTPUT_ASM_DIS=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y CONFIG_LWIP_FXMAC=y +CONFIG_LWIP_E1000E=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y CONFIG_LWIP_USE_MEM_HEAP=y diff --git a/example/network/lwip_iperf/configs/pe2204_aarch32_phytiumpi_lwip_iperf.config b/example/network/lwip_iperf/configs/pe2204_aarch32_phytiumpi_lwip_iperf.config index e90a91e229c27e72706b632134c851d836372563..de9031014b9ed06dbb98b7da7585a76ba2178dca 100644 --- a/example/network/lwip_iperf/configs/pe2204_aarch32_phytiumpi_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/pe2204_aarch32_phytiumpi_lwip_iperf.config @@ -1,13 +1,17 @@ CONFIG_ARCH_ARMV8_AARCH32=y +CONFIG_ENABLE_GIC_ITS=y CONFIG_PHYTIUMPI_FIREFLY_BOARD=y CONFIG_TARGET_NAME="lwip_iperf" CONFIG_USE_ETH=y +CONFIG_USE_PCIE=y +CONFIG_ENABLE_FPCIE_ECAM=y CONFIG_DEBUG_CUSTOMOPT=y CONFIG_OUTPUT_ASM_DIS=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y CONFIG_LWIP_FXMAC=y +CONFIG_LWIP_E1000E=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y CONFIG_LWIP_USE_MEM_HEAP=y diff --git a/example/network/lwip_iperf/configs/pe2204_aarch64_demo_lwip_iperf.config b/example/network/lwip_iperf/configs/pe2204_aarch64_demo_lwip_iperf.config index b490dd86d9ddad931f7d7823a359aa9c1e6ffad3..3ae001dd7355471e20e49b382060c5bf19e02fad 100644 --- a/example/network/lwip_iperf/configs/pe2204_aarch64_demo_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/pe2204_aarch64_demo_lwip_iperf.config @@ -1,11 +1,16 @@ +CONFIG_ENABLE_GIC_ITS=y CONFIG_TARGET_NAME="lwip_iperf" CONFIG_USE_ETH=y +CONFIG_USE_PCIE=y +CONFIG_ENABLE_FPCIE_ECAM=y CONFIG_DEBUG_CUSTOMOPT=y +CONFIG_DEBUG_OPTLEVEL="-O3" CONFIG_OUTPUT_ASM_DIS=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y CONFIG_LWIP_FXMAC=y +CONFIG_LWIP_E1000E=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y CONFIG_LWIP_USE_MEM_HEAP=y diff --git a/example/network/lwip_iperf/configs/pe2204_aarch64_phytiumpi_lwip_iperf.config b/example/network/lwip_iperf/configs/pe2204_aarch64_phytiumpi_lwip_iperf.config index 1a854b8044d89e177d15475305b842cea4220e9c..b6353c2840f8e1eab65dfc1e24653cfb88fb5389 100644 --- a/example/network/lwip_iperf/configs/pe2204_aarch64_phytiumpi_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/pe2204_aarch64_phytiumpi_lwip_iperf.config @@ -1,12 +1,16 @@ +CONFIG_ENABLE_GIC_ITS=y CONFIG_PHYTIUMPI_FIREFLY_BOARD=y CONFIG_TARGET_NAME="lwip_iperf" CONFIG_USE_ETH=y +CONFIG_USE_PCIE=y +CONFIG_ENABLE_FPCIE_ECAM=y CONFIG_DEBUG_CUSTOMOPT=y CONFIG_OUTPUT_ASM_DIS=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y CONFIG_LWIP_FXMAC=y +CONFIG_LWIP_E1000E=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y CONFIG_LWIP_USE_MEM_HEAP=y diff --git a/example/network/lwip_iperf/inc/net_pcie_common.h b/example/network/lwip_iperf/inc/net_pcie_common.h new file mode 100644 index 0000000000000000000000000000000000000000..dde9dcb419786234b5498593a9c71f70445a61a5 --- /dev/null +++ b/example/network/lwip_iperf/inc/net_pcie_common.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2025, Phytium Technology Co., Ltd. All Rights Reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + * FilePath: net_pcie_common.h + * Date: 2025-01-13 14:53:42 + * LastEditTime: 2025-01-13 17:46:03 + * Description:  This file is for net pcie example common definition + * + * Modify History: + * Ver Who Date Changes + * ----- ---------- -------- --------------------------------- + * 1.0 huangjin 2025/01/13 first release + */ +#ifndef NET_PCIE_COMMON_H +#define NET_PCIE_COMMON_H + +#include "fdebug.h" +#include "e1000e.h" +#include "fpcie_ecam.h" +#include "lwip_port.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define FNET_DEBUG_TAG "NET_PCIE_TEST" +#define FNET_ERROR(format, ...) FT_DEBUG_PRINT_E(FNET_DEBUG_TAG, format, ##__VA_ARGS__) +#define FNET_WARN(format, ...) FT_DEBUG_PRINT_W(FNET_DEBUG_TAG, format, ##__VA_ARGS__) +#define FNET_INFO(format, ...) FT_DEBUG_PRINT_I(FNET_DEBUG_TAG, format, ##__VA_ARGS__) +#define FNET_DEBUG(format, ...) FT_DEBUG_PRINT_D(FNET_DEBUG_TAG, format, ##__VA_ARGS__) + +#define PCI_CLASS_STORAGE_NET_AHCI 0x020000 + +#define ETH_NAME_PREFIX 'e' +#define PCIE_ETH_NAME_PREFIX 'p' + +#define CONFIG_DEFAULT_INIT(config, driver_config, instance_id, interface_type) \ + .config.magic_code = LWIP_PORT_CONFIG_MAGIC_CODE, .config.driver_type = driver_config, \ + .config.mac_instance = instance_id, .config.mii_interface = interface_type, \ + .config.autonegotiation = 1, .config.phy_speed = LWIP_PORT_SPEED_1000M, \ + .config.phy_duplex = LWIP_PORT_FULL_DUPLEX, .config.capability = LWIP_PORT_MODE_NAIVE, + +typedef struct +{ + UserConfig lwip_mac_config; + u32 dhcp_en; + char *ipaddr; + char *netmask; + char *gw; + unsigned char mac_address[6]; + struct netif netif; +} BoardMacConfig; + +/* 转化地址格式 */ +void SetIP(ip_addr_t *ipaddr, ip_addr_t *gw, ip_addr_t *netmask, BoardMacConfig mac_config); + +/* PCIE and net init function */ +FError FNetPcieInit(void); + +/* PCIE and net MSI init function */ +FError FNetPcieMsiInit(void); + +void LwipIperfE1000EClientDeinit(void); + +void LwipIperfE1000EServerDeinit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/example/network/lwip_iperf/src/cmd_lwip_iperf.c b/example/network/lwip_iperf/src/cmd_lwip_iperf.c index 89c2103acd459e407ef3a3dd6888e58c6926347c..1b42adf9723f7b350440bd6d15a0b997f62dc6ef 100644 --- a/example/network/lwip_iperf/src/cmd_lwip_iperf.c +++ b/example/network/lwip_iperf/src/cmd_lwip_iperf.c @@ -40,7 +40,7 @@ #include "lwip_iperf_client_example.h" #include "lwip_iperf_server_example.h" - +#include "net_pcie_common.h" @@ -58,11 +58,13 @@ static void LwipIperfExampleCheckState(void) { case CLIENT_EXAMPLE_RUNNING: printf("Lwip iperf client example is running, we need to deinitialize it first! \r\n"); + LwipIperfE1000EClientDeinit(); LwipIperfClientDeinit(); init_flag_mask=EXAMPLE_IDLE; break; case SERVER_EXAMPLE_RUNNING: printf("Lwip iperf server example is running, we need to deinitialize it first! \r\n"); + LwipIperfE1000EServerDeinit(); LwipIperfServerDeinit(); init_flag_mask=EXAMPLE_IDLE; break; diff --git a/example/network/lwip_iperf/src/lwip_iperf_client_example.c b/example/network/lwip_iperf/src/lwip_iperf_client_example.c index 3c86630bb03d1ce805867bdc79b51f4a9e6c8cbd..1510444828539806b9ae0870c0478287a0380c92 100644 --- a/example/network/lwip_iperf/src/lwip_iperf_client_example.c +++ b/example/network/lwip_iperf/src/lwip_iperf_client_example.c @@ -48,6 +48,8 @@ #include "lwip/inet.h" #include "lwiperf.h" +#include "net_pcie_common.h" + #define LWIPERF_TCP_PORT_REMOTE 5001 const ip_addr_t remote= IPADDR4_INIT_BYTES(192,168,4,50); @@ -72,17 +74,6 @@ enum }; static QueueHandle_t xQueue = NULL; -typedef struct -{ - UserConfig lwip_mac_config; - u32 dhcp_en; - char* ipaddr; - char* netmask; - char* gw; - unsigned char mac_address[6]; - struct netif netif; -} BoardMacConfig; - static BoardMacConfig board_mac_config[MAC_NUM] = { #if defined(MAC_NUM0) @@ -107,36 +98,21 @@ static BoardMacConfig board_mac_config[MAC_NUM] = #endif }; - - -static void SetIP(ip_addr_t* ipaddr,ip_addr_t* gw,ip_addr_t* netmask,u32 mac_id) -{ - - if(inet_aton(board_mac_config[mac_id].ipaddr,ipaddr)==0) - printf("The addr of ipaddr is wrong\r\n"); - if(inet_aton(board_mac_config[mac_id].gw,gw)==0) - printf("The addr of gw is wrong\r\n"); - if(inet_aton(board_mac_config[mac_id].netmask,netmask)==0) - printf("The addr of netmask is wrong\r\n"); - -} - void LwipIperfClientTestTask(void) { int task_res = LWIP_IPERF_CLIENT_EXAMPLE_SUCCESS; /* mac init */ for (int i = 0; i < MAC_NUM; i++) { - struct netif *netif_p = NULL; ip_addr_t ipaddr,netmask, gw; board_mac_config[i].lwip_mac_config.name[0] = ETH_NAME_PREFIX; itoa(board_mac_config[i].lwip_mac_config.mac_instance, &(board_mac_config[i].lwip_mac_config.name[1]), 10); /* mac ip addr set: char* -> ip_addr_t */ - SetIP(&ipaddr,&gw,&netmask,i); - /* ******************************************************************* */ + SetIP(&ipaddr,&gw,&netmask,board_mac_config[i]); + /*********************************************************************/ netif_p= &board_mac_config[i].netif; /* Add network interface to the netif_list, and set it as default */ if (!LwipPortAdd(netif_p, &ipaddr, &netmask, &gw, board_mac_config[i].mac_address, (UserConfig *)&board_mac_config[i])) @@ -163,9 +139,15 @@ void LwipIperfClientTestTask(void) /* 当netif链接关闭时,必须调用该函数 */ netif_set_down(netif_p); } + } - + /* init pcie & msi net */ + if (FNetPcieMsiInit() != FT_SUCCESS) + { + FNET_ERROR("Net Pcie msi init failed, please check if the e1000e is " + "successfully connected"); } + printf("Network setup complete.\n"); printf("Now start iperf client test\r\n"); @@ -173,6 +155,7 @@ void LwipIperfClientTestTask(void) NULL, NULL)) { printf("Start iperf client test success !!! \r\n"); + task_res = LWIP_IPERF_CLIENT_EXAMPLE_SUCCESS; } else { diff --git a/example/network/lwip_iperf/src/lwip_iperf_server_example.c b/example/network/lwip_iperf/src/lwip_iperf_server_example.c index 1eaac7d88245ced272c33465a968b0cc8cbfc351..df26828993f2ab738e9e68ef647621e46308868f 100644 --- a/example/network/lwip_iperf/src/lwip_iperf_server_example.c +++ b/example/network/lwip_iperf/src/lwip_iperf_server_example.c @@ -48,6 +48,7 @@ #include "lwip/tcpip.h" #include "lwip/inet.h" #include "lwiperf.h" +#include "net_pcie_common.h" #define LWIPERF_TCP_LISTEN_PORT 5001 @@ -72,17 +73,6 @@ enum }; static QueueHandle_t xQueue = NULL; -typedef struct -{ - UserConfig lwip_mac_config; - u32 dhcp_en; - char* ipaddr; - char* netmask; - char* gw; - unsigned char mac_address[6]; - struct netif netif; -} BoardMacConfig; - static BoardMacConfig board_mac_config[MAC_NUM] = { #if defined(MAC_NUM0) @@ -107,36 +97,21 @@ static BoardMacConfig board_mac_config[MAC_NUM] = #endif }; - - -static void SetIP(ip_addr_t* ipaddr,ip_addr_t* gw,ip_addr_t* netmask,u32 mac_id) -{ - - if(inet_aton(board_mac_config[mac_id].ipaddr,ipaddr)==0) - printf("The addr of ipaddr is wrong\r\n"); - if(inet_aton(board_mac_config[mac_id].gw,gw)==0) - printf("The addr of gw is wrong\r\n"); - if(inet_aton(board_mac_config[mac_id].netmask,netmask)==0) - printf("The addr of netmask is wrong\r\n"); - -} - void LwipIperfServerTestTask(void) { int task_res = LWIP_IPERF_SERVER_EXAMPLE_SUCCESS; /* mac init */ for (int i = 0; i < MAC_NUM; i++) { - struct netif *netif_p = NULL; ip_addr_t ipaddr,netmask, gw; board_mac_config[i].lwip_mac_config.name[0] = ETH_NAME_PREFIX; itoa(board_mac_config[i].lwip_mac_config.mac_instance, &(board_mac_config[i].lwip_mac_config.name[1]), 10); /* mac ip addr set: char* -> ip_addr_t */ - SetIP(&ipaddr,&gw,&netmask,i); - /* ******************************************************************* */ + SetIP(&ipaddr,&gw,&netmask,board_mac_config[i]); + /*********************************************************************/ netif_p= &board_mac_config[i].netif; /* Add network interface to the netif_list, and set it as default */ if (!LwipPortAdd(netif_p, &ipaddr, &netmask, &gw, board_mac_config[i].mac_address, (UserConfig *)&board_mac_config[i])) @@ -163,8 +138,15 @@ void LwipIperfServerTestTask(void) /* 当netif链接关闭时,必须调用该函数 */ netif_set_down(netif_p); } + } + /* init pcie & msi net */ + if (FNetPcieMsiInit() != FT_SUCCESS) + { + FNET_ERROR("Net Pcie msi init failed, please check if the e1000e is " + "successfully connected"); } + printf("Network setup complete.\n"); printf("Now start iperf sever \r\n"); @@ -172,6 +154,7 @@ void LwipIperfServerTestTask(void) NULL, NULL)) { printf("Start iperf server success !!! \r\n"); + task_res = LWIP_IPERF_SERVER_EXAMPLE_SUCCESS; } else { diff --git a/example/network/lwip_iperf/src/net_pcie_common.c b/example/network/lwip_iperf/src/net_pcie_common.c new file mode 100644 index 0000000000000000000000000000000000000000..ff520d0a48668e212f3c0727e56ebf65843278d0 --- /dev/null +++ b/example/network/lwip_iperf/src/net_pcie_common.c @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2025, Phytium Technology Co., Ltd. All Rights Reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * See the Phytium Public License for more details. + * + * + * FilePath: net_pcie_common.c + * Date: 2025-01-13 14:53:42 + * LastEditTime: 2025-01-13 17:46:03 + * Description:  This file is for net pcie common functions + * + * Modify History: + * Ver Who Date Changes + * ----- ---------- -------- --------------------------------- + * 1.0 huangjin 2025/01/13 first release + */ + +/***************************** Include Files *********************************/ +#include +#include +#include "sdkconfig.h" +#ifndef SDK_CONFIG_H__ +#warning "Please include sdkconfig.h" +#endif +#include "finterrupt.h" +#include "fpcie_ecam.h" +#include "fpcie_ecam_common.h" +#include "e1000e.h" +#include "e1000e_hw.h" +#include "fcpu_info.h" +#include "ferror_code.h" +#include "fpcie_ecam_msi.h" +#include "net_pcie_common.h" + +#include "lwip/ip4_addr.h" +#include "lwip/inet.h" +#include "lwip/netif.h" + +#include "lwiperf.h" + + +/************************** Constant Definitions *****************************/ + +/**************************** Type Definitions *******************************/ + +extern FE1000EConfig FE1000E_CONFIG_TBL[FE1000E_NUM]; + +/*max support 16 ahci controllers*/ +static FPcieEcam pcie_device; +static boolean e1000e_up_flag = TRUE; + +static BoardMacConfig pcie_mac_config = { + CONFIG_DEFAULT_INIT(lwip_mac_config, LWIP_PORT_TYPE_E1000E, 0, LWIP_PORT_INTERFACE_SGMII) + .dhcp_en = 0, + .ipaddr = "192.168.4.12", + .gw = "192.168.4.1", + .netmask = "255.255.255.0", + .mac_address = {0x6c, 0xb3, 0x11, 0x0f, 0x9a, 0x44}, +}; +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/************************** Function *****************************************/ + +void SetIP(ip_addr_t *ipaddr, ip_addr_t *gw, ip_addr_t *netmask, BoardMacConfig mac_config) +{ + if (inet_aton(mac_config.ipaddr, ipaddr) == 0) + { + printf("The addr of ipaddr is wrong\r\n"); + } + if (inet_aton(mac_config.gw, gw) == 0) + { + printf("The addr of gw is wrong\r\n"); + } + if (inet_aton(mac_config.netmask, netmask) == 0) + { + printf("The addr of netmask is wrong\r\n"); + } +} + +static FError FPcieInit(FPcieEcam *pcie_device) +{ + FError ret = FE1000E_SUCCESS; + + ret = FPcieEcamCfgInitialize(pcie_device, FPcieEcamLookupConfig(FPCIE_ECAM_INSTANCE0), NULL); + if (ret != FT_SUCCESS) + { + return ret; + } + FNET_DEBUG("\n"); + FNET_DEBUG(" PCI:\n"); + FNET_DEBUG(" B:D:F VID:PID parent_BDF class_code\n"); + ret = FPcieEcamEnumerateBus(pcie_device, 0); + if (ret != FT_SUCCESS) + { + return ret; + } + + return ret; +} + +FError FNetPcieInit(void) +{ + FError ret = FE1000E_SUCCESS; + s32 host; + u32 pci_class = 0; + const u32 class_code = PCI_CLASS_STORAGE_NET_AHCI; + uintptr bar_addr = 0; + u8 bus = 0; + u8 device = 0; + u8 function = 0; + u32 config_data; + u32 cmdstat; + + struct netif *netif_p = NULL; + ip_addr_t ipaddr, netmask, gw; + + /* pcie init */ + ret = FPcieInit(&pcie_device); + if (ret != FE1000E_SUCCESS) + { + FNET_ERROR("FPcieInit failed."); + return FE1000E_ERR_FAILED; + } + + /* find xhci host from pcie instance */ + for (host = 0; host < pcie_device.scans_bdf_count; host++) + { + bus = pcie_device.scans_bdf[host].bus; + device = pcie_device.scans_bdf[host].device; + function = pcie_device.scans_bdf[host].function; + + FPcieEcamReadConfigSpace(&pcie_device, bus, device, function, + FPCIE_CCR_REV_CLASSID_REGS, &config_data); + FNET_DEBUG("FPCIE_CCR_REV_CLASSID_REGS = %x\n", config_data); + pci_class = config_data >> 8; + + if (pci_class == class_code) + { + FPcieEcamReadConfigSpace(&pcie_device, bus, device, function, + FPCIE_CCR_ID_REG, &config_data); + + FNET_DEBUG("AHCI-PCI HOST found !!!, b.d.f = %x.%x.%x\n", bus, device, function); + + FPcieEcamReadConfigSpace(&pcie_device, bus, device, function, + FPCIE_CCR_BAR_ADDR0_REGS, (u32 *)&bar_addr); + FNET_DEBUG("FNetPcieIntrInstall BarAddress %p", bar_addr); + FE1000E_CONFIG_TBL[FE1000E0_ID].base_addr = bar_addr; + + if (0x0 == bar_addr) + { + FNET_ERROR("Bar address: 0x%lx", bar_addr); + return FE1000E_ERR_FAILED; + } + + break; + } + } + if (pci_class != class_code) + { + FNET_ERROR("class_code: 0x%06x is not pcie net card!", pci_class); + return FE1000E_ERR_FAILED; + } + + /* 设置cmd reg */ + FPcieEcamReadConfigSpace(&pcie_device, bus, device, function, FPCIE_CCR_CMD_STATUS_REGS, &cmdstat); + cmdstat |= (FPCIE_CCR_CMD_MEMORY_ACCESS_ENABLED | FPCIE_CCR_CMD_BUS_MASTER_ENABLED); + FPcieEcamWriteConfigSpace(&pcie_device, bus, device, function, FPCIE_CCR_CMD_STATUS_REGS, cmdstat); + + /* pcie net init */ + pcie_mac_config.lwip_mac_config.name[0] = PCIE_ETH_NAME_PREFIX; + itoa(pcie_mac_config.lwip_mac_config.mac_instance, + &(pcie_mac_config.lwip_mac_config.name[1]), 10); + SetIP(&ipaddr, &gw, &netmask, pcie_mac_config); + netif_p = &pcie_mac_config.netif; + /* Add network interface to the netif_list, and set it as default */ + if (!LwipPortAdd(netif_p, &ipaddr, &netmask, &gw, pcie_mac_config.mac_address, + (UserConfig *)&pcie_mac_config)) + { + printf("Error adding N/W interface %d.\n\r", pcie_mac_config.lwip_mac_config.mac_instance); + ret = ERR_GENERAL; + return FE1000E_ERR_FAILED; + } + printf("LwipPortAdd pcie_mac_instance %d is over.\n\r", + pcie_mac_config.lwip_mac_config.mac_instance); + + netif_set_default(netif_p); + + if (netif_is_link_up(netif_p)) + { + /* 当netif完全配置好时,必须调用该函数 */ + netif_set_up(netif_p); + if (pcie_mac_config.dhcp_en == 1) + { + LwipPortDhcpSet(netif_p, TRUE); + } + } + else + { + /* 当netif链接关闭时,必须调用该函数 */ + netif_set_down(netif_p); + } + + return ret; +} + +FError FNetPcieMsiInit(void) +{ + FError ret = FE1000E_SUCCESS; + struct netif *netif_p = NULL; + ip_addr_t ipaddr, netmask, gw; + + /* net init */ + pcie_mac_config.lwip_mac_config.name[0] = PCIE_ETH_NAME_PREFIX; + itoa(pcie_mac_config.lwip_mac_config.mac_instance, + &(pcie_mac_config.lwip_mac_config.name[1]), 10); + SetIP(&ipaddr, &gw, &netmask, pcie_mac_config); + netif_p = &pcie_mac_config.netif; + /* Add network interface to the netif_list, and set it as default */ + if (!LwipPortAdd(netif_p, &ipaddr, &netmask, &gw, pcie_mac_config.mac_address, + (UserConfig *)&pcie_mac_config)) + { + printf("Error adding N/W interface %d.\n\r", pcie_mac_config.lwip_mac_config.mac_instance); + ret = ERR_GENERAL; + e1000e_up_flag = FALSE; + return ret; + } + printf("LwipPortAdd pcie_mac_instance %d is over.\n\r", + pcie_mac_config.lwip_mac_config.mac_instance); + + netif_set_default(netif_p); + + if (netif_is_link_up(netif_p)) + { + /* 当netif完全配置好时,必须调用该函数 */ + netif_set_up(netif_p); + if (pcie_mac_config.dhcp_en == 1) + { + LwipPortDhcpSet(netif_p, TRUE); + } + } + else + { + /* 当netif链接关闭时,必须调用该函数 */ + netif_set_down(netif_p); + } + + return ret; +} + +void LwipIperfE1000EClientDeinit(void) +{ + if (e1000e_up_flag == TRUE) + { + printf("Now reset E1000E all active iperf session. \r\n"); + lwiperf_reset(); + printf("Reset E1000E all active iperf session complete! \r\n"); + + struct netif *netif_p = NULL; + netif_p = &pcie_mac_config.netif; + LwipPortStop(netif_p, pcie_mac_config.dhcp_en); + } +} + +void LwipIperfE1000EServerDeinit(void) +{ + if (e1000e_up_flag == TRUE) + { + printf("Now reset E1000E all active iperf session. \r\n"); + lwiperf_reset(); + printf("Reset E1000E all active iperf session complete! \r\n"); + + struct netif *netif_p = NULL; + netif_p = &pcie_mac_config.netif; + LwipPortStop(netif_p, pcie_mac_config.dhcp_en); + } +} diff --git a/example/network/sockets/udp_multicast/configs/pd1904_aarch32_dsk_udp_multicast.config b/example/network/sockets/udp_multicast/configs/pd1904_aarch32_dsk_udp_multicast.config index 678977a1d821fcef0280819f93df7cca7538b538..bf99adde3a8ca34da7353e0a4f5dd9e6451f5cdb 100644 --- a/example/network/sockets/udp_multicast/configs/pd1904_aarch32_dsk_udp_multicast.config +++ b/example/network/sockets/udp_multicast/configs/pd1904_aarch32_dsk_udp_multicast.config @@ -7,6 +7,7 @@ CONFIG_USE_ETH=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FGMAC=y # CONFIG_LWIP_NO_SYS is not set CONFIG_LWIP_USE_MEM_HEAP=y CONFIG_LWIP_IP4_REASSEMBLY=y diff --git a/example/network/sockets/udp_multicast/configs/pd1904_aarch64_dsk_udp_multicast.config b/example/network/sockets/udp_multicast/configs/pd1904_aarch64_dsk_udp_multicast.config index e412c352712ed6f60d4a4e582453fdb83b7e38ad..4926819376b56c0bd7c7a96d994dadbf909dd8e0 100644 --- a/example/network/sockets/udp_multicast/configs/pd1904_aarch64_dsk_udp_multicast.config +++ b/example/network/sockets/udp_multicast/configs/pd1904_aarch64_dsk_udp_multicast.config @@ -7,6 +7,7 @@ CONFIG_USE_ETH=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FGMAC=y # CONFIG_LWIP_NO_SYS is not set CONFIG_LWIP_USE_MEM_HEAP=y CONFIG_LWIP_IP4_REASSEMBLY=y diff --git a/example/network/sockets/udp_multicast/configs/pd2008_aarch32_test_udp_multicast.config b/example/network/sockets/udp_multicast/configs/pd2008_aarch32_test_udp_multicast.config index e9dd95b2ef3bf7a2e95736caef52843d5d3c012c..26aeac74e5467c74ad6d43f3da5c2b79e037e6c9 100644 --- a/example/network/sockets/udp_multicast/configs/pd2008_aarch32_test_udp_multicast.config +++ b/example/network/sockets/udp_multicast/configs/pd2008_aarch32_test_udp_multicast.config @@ -7,6 +7,7 @@ CONFIG_USE_ETH=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FGMAC=y # CONFIG_LWIP_NO_SYS is not set CONFIG_LWIP_USE_MEM_HEAP=y CONFIG_LWIP_IP4_REASSEMBLY=y diff --git a/example/network/sockets/udp_multicast/configs/pd2008_aarch64_test_udp_multicast.config b/example/network/sockets/udp_multicast/configs/pd2008_aarch64_test_udp_multicast.config index c5e5470a1961cbdd390b882f235c6e3264393da9..d71d0d4533068a00b491a7ef1685546000dff5dd 100644 --- a/example/network/sockets/udp_multicast/configs/pd2008_aarch64_test_udp_multicast.config +++ b/example/network/sockets/udp_multicast/configs/pd2008_aarch64_test_udp_multicast.config @@ -7,6 +7,7 @@ CONFIG_USE_ETH=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FGMAC=y # CONFIG_LWIP_NO_SYS is not set CONFIG_LWIP_USE_MEM_HEAP=y CONFIG_LWIP_IP4_REASSEMBLY=y diff --git a/example/network/wlan/configs/pe2202_aarch32_demo_wlan.config b/example/network/wlan/configs/pe2202_aarch32_demo_wlan.config index 96893085521489b85aa7a1ba93ee7755c3e78597..ebd53cbd8b3ac61ebfe2e5a119674501f6b0d4b3 100644 --- a/example/network/wlan/configs/pe2202_aarch32_demo_wlan.config +++ b/example/network/wlan/configs/pe2202_aarch32_demo_wlan.config @@ -8,6 +8,7 @@ CONFIG_OUTPUT_ASM_DIS=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FXMAC=y CONFIG_LWIP_FSDIF=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y diff --git a/example/network/wlan/configs/pe2202_aarch64_demo_wlan.config b/example/network/wlan/configs/pe2202_aarch64_demo_wlan.config index 94bb888618456b098b0ac280e666b42c11439a9d..f50e48ff592fd29afc370eacb6a86aa180412425 100644 --- a/example/network/wlan/configs/pe2202_aarch64_demo_wlan.config +++ b/example/network/wlan/configs/pe2202_aarch64_demo_wlan.config @@ -7,6 +7,7 @@ CONFIG_OUTPUT_ASM_DIS=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FXMAC=y CONFIG_LWIP_FSDIF=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y diff --git a/example/network/wlan/configs/pe2204_aarch32_demo_wlan.config b/example/network/wlan/configs/pe2204_aarch32_demo_wlan.config index 9ebb13dc29d074d2107db05e86006a20379c0461..971ccbface66a8d5cd58717bb5b8a2e41aee0850 100644 --- a/example/network/wlan/configs/pe2204_aarch32_demo_wlan.config +++ b/example/network/wlan/configs/pe2204_aarch32_demo_wlan.config @@ -7,6 +7,7 @@ CONFIG_OUTPUT_ASM_DIS=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FXMAC=y CONFIG_LWIP_FSDIF=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y diff --git a/example/network/wlan/configs/pe2204_aarch64_demo_wlan.config b/example/network/wlan/configs/pe2204_aarch64_demo_wlan.config index 23f3da201a8175679d3c32c25f8c2443bbba95d7..1f13cf476c50b6bb850ddbadcc5d390b1328774a 100644 --- a/example/network/wlan/configs/pe2204_aarch64_demo_wlan.config +++ b/example/network/wlan/configs/pe2204_aarch64_demo_wlan.config @@ -6,6 +6,7 @@ CONFIG_OUTPUT_ASM_DIS=y CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_USE_LWIP=y +CONFIG_LWIP_FXMAC=y CONFIG_LWIP_FSDIF=y # CONFIG_LWIP_NO_SYS is not set CONFIG_USE_LWIP_APP_LWIPERF=y diff --git a/install.py b/install.py index b035ae65e3c62a97bc47aeae4a93385b21f2e67b..a2b07662522d2ad69d2b098834a10b56b90ff614 100755 --- a/install.py +++ b/install.py @@ -28,7 +28,7 @@ curr_path = os.getcwd() freertos_sdk_path = install_path # Add standalone sdk -standalone_sdk_v="16c19e5a8b157e1fedb6f40a014a2c4a95f804a9" +standalone_sdk_v="99a24f246c1a623fce2e2de82d183342d7fe154c" if (install_platform == windows_x64): standalone_path=freertos_sdk_path + '\\standalone' else: diff --git a/third-party/freertos/portable/freertos_configs.c b/third-party/freertos/portable/freertos_configs.c index a61e1e26e2d84bee9e9b98b871e9adf7b9f68101..d40bcde2d62f7200991b1b143046963977bce27d 100644 --- a/third-party/freertos/portable/freertos_configs.c +++ b/third-party/freertos/portable/freertos_configs.c @@ -110,15 +110,18 @@ volatile unsigned int gCpuRuntime; void vApplicationInterruptHandler(uint32_t ulICCIAR) { - int ulInterruptID; is_in_irq ++; - /* Interrupts cannot be re-enabled until the source of the interrupt is - cleared. The ID of the interrupt is obtained by bitwise ANDing the ICCIAR - value with 0x3FF. */ - ulInterruptID = ulICCIAR & 0x3FFUL; + + if (ulICCIAR < 8192) + { + /* Interrupts cannot be re-enabled until the source of the interrupt is + cleared. The ID of the interrupt is obtained by bitwise ANDing the ICCIAR + value with 0x3FF. */ + ulICCIAR = ulICCIAR & 0x3FFUL; + } /* call handler function */ - if (ulInterruptID == USING_GENERIC_TIMER_IRQ_ID) + if (ulICCIAR == USING_GENERIC_TIMER_IRQ_ID) { /* Generic Timer */ gCpuRuntime++; @@ -126,7 +129,7 @@ void vApplicationInterruptHandler(uint32_t ulICCIAR) } else { - FExceptionInterruptHandler((void *)(uintptr)ulInterruptID); + FExceptionInterruptHandler((void *)(uintptr)ulICCIAR); } is_in_irq --; } diff --git a/third-party/lwip-2.1.2/include.mk b/third-party/lwip-2.1.2/include.mk index f463698d6875bdb1c8c9bf0eb2ca5cb9a0b9b8cf..873023bc6bf6b78160d372e69894f15eeb49c9a9 100644 --- a/third-party/lwip-2.1.2/include.mk +++ b/third-party/lwip-2.1.2/include.mk @@ -21,6 +21,10 @@ BUILD_INC_PATH_DIR += $(THIRDP_CUR_DIR)/lwip-2.1.2/ports BUILD_INC_PATH_DIR += $(THIRDP_CUR_DIR)/lwip-2.1.2/ports/fxmac_v2_0 endif + ifdef CONFIG_LWIP_E1000E + BUILD_INC_PATH_DIR += $(THIRDP_CUR_DIR)/lwip-2.1.2/ports/e1000e + endif + endif BUILD_INC_PATH_DIR += $(SDK_DIR)/third-party/lwip-2.1.2 \ diff --git a/third-party/lwip-2.1.2/lwip_freertos.mk b/third-party/lwip-2.1.2/lwip_freertos.mk index 85acaeb5a6692a48f0c85f5e8ce7016b3262e779..7910f940cba432a2d1892a99cdc36c81002d51db 100644 --- a/third-party/lwip-2.1.2/lwip_freertos.mk +++ b/third-party/lwip-2.1.2/lwip_freertos.mk @@ -26,6 +26,13 @@ ifdef CONFIG_LWIP_FXMAC_V2 $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports endif +ifdef CONFIG_LWIP_E1000E + INC_DIR += $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports/e1000e \ + $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports + SRC_DIR += $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports/e1000e \ + $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports +endif + INC_DIR += $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports/arch SRC_DIR += $(LWIP_FREERTOS_CUR_DIR)/lwip-2.1.2/ports/arch diff --git a/third-party/lwip-2.1.2/ports/e1000e/ethernetif.c b/third-party/lwip-2.1.2/ports/e1000e/ethernetif.c new file mode 100644 index 0000000000000000000000000000000000000000..9e9735a54fc512655877ad39fb155e0ceb3072b9 --- /dev/null +++ b/third-party/lwip-2.1.2/ports/e1000e/ethernetif.c @@ -0,0 +1,461 @@ +/* + * Copyright (C) 2025, Phytium Technology Co., Ltd. All Rights Reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + * FilePath: ethernetif.c + * Date: 2025-10-21 10:38:46 + * LastEditTime: 2025-10-21 10:38:46 + * Description: This file is the function file of the e1000e adaptation to lwip stack. + * + * Modify History: + * Ver Who Date Changes + * ----- ------ -------- -------------------------------------- + * 1.0 huangjin 2025/10/21 first release + */ + + +#include +#include + +#include "lwipopts.h" +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include "lwip/stats.h" +#include "lwip/igmp.h" +#include "netif/etharp.h" +#include "lwip_port.h" +#include "e1000e_os.h" +#include "fdebug.h" +#include "e1000e_hw.h" + + +#define E1000E_LWIP_NET_DEBUG_TAG "E1000E_LWIP_NET" +#define E1000E_LWIP_NET_PRINT_E(format, ...) FT_DEBUG_PRINT_E(E1000E_LWIP_NET_DEBUG_TAG, format, ##__VA_ARGS__) +#define E1000E_LWIP_NET_PRINT_I(format, ...) FT_DEBUG_PRINT_I(E1000E_LWIP_NET_DEBUG_TAG, format, ##__VA_ARGS__) +#define E1000E_LWIP_NET_PRINT_D(format, ...) FT_DEBUG_PRINT_D(E1000E_LWIP_NET_DEBUG_TAG, format, ##__VA_ARGS__) +#define E1000E_LWIP_NET_PRINT_W(format, ...) FT_DEBUG_PRINT_W(E1000E_LWIP_NET_DEBUG_TAG, format, ##__VA_ARGS__) + + +#if LWIP_IPV6 + #include "lwip/ethip6.h" +#endif + +static void e1000e_ethernetif_input(struct netif *netif); + +enum lwip_port_link_status e1000e_ethernetif_link_detect(struct netif *netif) +{ + struct LwipPort *lwip_port = (struct LwipPort *)(netif->state); + FE1000EOs *instance_p; + if (lwip_port == NULL) + { + return ETH_LINK_UNDEFINED; + } + instance_p = (FE1000EOs *)lwip_port->state; + if (instance_p->instance.is_ready != FT_COMPONENT_IS_READY) + { + return ETH_LINK_UNDEFINED; + } + + return FE1000EPhyReconnect(lwip_port); +} + +void e1000e_ethernetif_debug(struct netif *netif) +{ + struct LwipPort *lwip_port = (struct LwipPort *)(netif->state); + FE1000EOs *instance_p; + if (lwip_port == NULL) + { + E1000E_LWIP_NET_PRINT_E("lwip_port is an NULL pointer"); + return; + } + instance_p = (FE1000EOs *)lwip_port->state; + if (instance_p->instance.is_ready != FT_COMPONENT_IS_READY) + { + E1000E_LWIP_NET_PRINT_E("The drive is not ready"); + return; + } + + FE1000EDebugPrint(&instance_p->instance); +} + +static void e1000e_ethernetif_start(struct netif *netif) +{ + struct LwipPort *xmac_netif_p = (struct LwipPort *)(netif->state); + if (xmac_netif_p == NULL) + { + E1000E_LWIP_NET_PRINT_E("%s,xmac_netif_p is NULL\n", __FUNCTION__); + return; + } + FE1000EOs *instance_p = (FE1000EOs *)(xmac_netif_p->state); + FE1000ELwipPortStart(instance_p); +} + +static void e1000e_ethernetif_deinit(struct netif *netif) +{ + struct LwipPort *xmac_netif_p = (struct LwipPort *)(netif->state); + if (xmac_netif_p == NULL) + { + E1000E_LWIP_NET_PRINT_E("%s,xmac_netif_p is NULL\n", __FUNCTION__); + return; + } + + FE1000EOs *instance_p = (FE1000EOs *)(xmac_netif_p->state); + FE1000ELwipPortStop(instance_p); +} + +/* + * low_level_output(): + * + * 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. + * + */ +static err_t low_level_output(struct netif *netif, struct pbuf *p) +{ + FError ret ; + FE1000EOs *instance_p = NULL; + FASSERT(netif != NULL); + FASSERT(netif->state != NULL); + struct LwipPort *xmac_netif_p = (struct LwipPort *)(netif->state); + FASSERT(xmac_netif_p != NULL); + + instance_p = (FE1000EOs *)(xmac_netif_p->state) ; + + portENTER_CRITICAL(); +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + ret = FE1000ELwipPortTx(instance_p, (void *)p); + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + portEXIT_CRITICAL(); + + if (ret != FT_SUCCESS) + { + return ERR_MEM; + } + + return ERR_OK; +} + +/* + * low_level_input(): + * + * Should allocate a pbuf and transfer the bytes of the incoming + * packet from the interface into the pbuf. + * + */ +static struct pbuf *low_level_input(struct netif *netif) +{ + FE1000EOs *instance_p = NULL; + FASSERT(netif != NULL); + FASSERT(netif->state != NULL); + struct LwipPort *lwip_port = (struct LwipPort *)(netif->state); + FASSERT(lwip_port != NULL); + instance_p = (FE1000EOs *)(lwip_port->state); + + return FE1000ELwipPortQueueRx(instance_p); +} + +/* + * e1000e_ethernetif_input(): + * + * This function should be called when a packet is ready to be read + * from the interface. It uses the function FE1000ELwipPortRx() that + * should handle the actual reception of bytes from the network + * interface. + * + */ +static void e1000e_ethernetif_input(struct netif *netif) +{ + struct eth_hdr *ethhdr; + struct pbuf *p; + struct LwipPort *e1000e_netif_p = (struct LwipPort *)(netif->state); + FASSERT(e1000e_netif_p != NULL); + FE1000EOs *instance_p = NULL; + instance_p = (FE1000EOs *)(e1000e_netif_p->state); + + SYS_ARCH_DECL_PROTECT(lev); + + while (1) + { + SYS_ARCH_PROTECT(lev); + FE1000EIrqEnable(&instance_p->instance, IMS_RXQ0); + if (FE1000ELwipPortRxComplete(instance_p)) + { + SYS_ARCH_UNPROTECT(lev); + FE1000ELwipPortRx(instance_p); + } + else + { + SYS_ARCH_UNPROTECT(lev); + break; + } + xSemaphoreTake(e1000e_netif_p->sem_rx_data_available,0); + } + + while (1) + { + /* move received packet into a new pbuf */ + p = low_level_input(netif); + + /* no packet could be read, silently ignore this */ + if (p == NULL) + { + return; + } + + /* points to packet payload, which starts with an Ethernet header */ + ethhdr = p->payload; + +#if LINK_STATS + lwip_stats.link.recv++; +#endif /* LINK_STATS */ + switch (htons(ethhdr->type)) + { + /* IP or ARP packet? */ + case ETHTYPE_IP: + case ETHTYPE_ARP: +#if LWIP_IPV6 + /*IPv6 Packet?*/ + case ETHTYPE_IPV6: +#endif +#if PPPOE_SUPPORT + /* PPPoE packet? */ + case ETHTYPE_PPPOEDISC: + case ETHTYPE_PPPOE: +#endif /* PPPOE_SUPPORT */ + + /* 处理数据包,调用网络接口的input函数将数据包交给lwip协议栈内核 */ + if (netif->input(p, netif) != ERR_OK) + { + LWIP_DEBUGF(NETIF_DEBUG, + ("e1000e_ethernetif_input: IP input error\r\n")); + pbuf_free(p); + p = NULL; + } + break; + + default: + LWIP_DEBUGF(NETIF_DEBUG, ("e1000e_ethernetif_input: default\r\n")); + pbuf_free(p); + p = NULL; + break; + } + } + + return; +} + +static void UserConfigConvert(FE1000EOs *instance_p, UserConfig *config_p) +{ + FASSERT(config_p != NULL); + FASSERT_MSG(config_p->autonegotiation <= 1, + "config_p->autonegotiation %d is over 1", config_p->autonegotiation); + FASSERT_MSG(config_p->phy_speed <= FE1000E_PHY_SPEED_10G, + "config_p->phy_speed %d is over 1000", config_p->phy_speed); + FASSERT_MSG(config_p->phy_duplex <= FE1000E_PHY_FULL_DUPLEX, + "config_p->phy_duplex %d is over FE1000E_PHY_FULL_DUPLEX", config_p->phy_duplex); + + FE1000ELwipPortConfig mac_lwip_port_config; + + switch (config_p->mii_interface) + { + case LWIP_PORT_INTERFACE_RGMII: + mac_lwip_port_config.interface = FE1000E_OS_INTERFACE_RGMII; + break; + case LWIP_PORT_INTERFACE_SGMII: + mac_lwip_port_config.interface = FE1000E_OS_INTERFACE_SGMII; + break; + case LWIP_PORT_INTERFACE_USX: + mac_lwip_port_config.interface = FE1000E_OS_INTERFACE_USXGMII; + break; + default: + mac_lwip_port_config.interface = FE1000E_OS_INTERFACE_RGMII; + break; + } + + mac_lwip_port_config.instance_id = config_p->mac_instance; + mac_lwip_port_config.autonegotiation = config_p->autonegotiation; /* 1 is autonegotiation ,0 is manually set */ + mac_lwip_port_config.phy_speed = config_p->phy_speed; /* FE1000E_PHY_SPEED_XXX */ + mac_lwip_port_config.phy_duplex = config_p->phy_duplex; /* FE1000E_PHY_XXX_DUPLEX */ + + instance_p->e1000e_port_config = mac_lwip_port_config; + instance_p->feature = config_p->capability; +} + +static err_t low_level_init(struct netif *netif) +{ + struct LwipPort *lwip_port; + FE1000EOs *instance_p; + FError ret; + UserConfig *user_config; + + FASSERT(netif != NULL); + FASSERT(netif->state != NULL); + /* step 1:malloc lwip port object */ + lwip_port = mem_malloc(sizeof *lwip_port); + if (lwip_port == NULL) + { + LWIP_DEBUGF(NETIF_DEBUG, ("lwip_port init: out of memory\r\n")); + return ERR_MEM; + } + + /* obtain config of this emac */ + E1000E_LWIP_NET_PRINT_I("netif->state is %p \r\n", netif->state); + + user_config = (UserConfig *)netif->state; + if (user_config == NULL) + { + E1000E_LWIP_NET_PRINT_E("UserConfig is NULL"); + mem_free(lwip_port); + return ERR_MEM; + } + + instance_p = FE1000ELwipPortGetInstancePointer(user_config->mac_instance); + if (instance_p == NULL) + { + E1000E_LWIP_NET_PRINT_E("FE1000ELwipPortGetInstancePointer is error\r\n"); + mem_free(lwip_port); + return ERR_ARG; + } + + UserConfigConvert(instance_p, user_config); + + for (int i = 0; i < FE1000E_MAX_HARDWARE_ADDRESS_LENGTH; i++) + { + instance_p->hwaddr[i] = netif->hwaddr[i]; + instance_p->instance.mac[i] = netif->hwaddr[i]; + } + + ret = FE1000ELwipPortInit(instance_p); + if (ret != FT_SUCCESS) + { + E1000E_LWIP_NET_PRINT_E("FE1000ELwipPortInit is error\r\n"); + mem_free(lwip_port); + return ERR_ARG; + } + E1000E_LWIP_NET_PRINT_D("FE1000ELwipPortInit is success\r\n"); + + lwip_port->state = (void *)instance_p; + netif->state = (void *)lwip_port; /* update state */ + instance_p->stack_pointer = lwip_port; + + /* maximum transfer unit */ + if (instance_p->feature & FE1000E_OS_CONFIG_JUMBO) + { + netif->mtu = FE1000E_MTU_JUMBO; + } + else + { + netif->mtu = FE1000E_MTU; + } + + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + +#if LWIP_IPV6 && LWIP_IPV6_MLD + netif->flags |= NETIF_FLAG_MLD6; +#endif + +#if LWIP_IGMP + netif->flags |= NETIF_FLAG_IGMP; +#endif + + lwip_port->ops.eth_detect = e1000e_ethernetif_link_detect; + lwip_port->ops.eth_input = e1000e_ethernetif_input; + lwip_port->ops.eth_deinit = e1000e_ethernetif_deinit; + lwip_port->ops.eth_start = e1000e_ethernetif_start; + lwip_port->ops.eth_debug = e1000e_ethernetif_debug; + E1000E_LWIP_NET_PRINT_I("ready to leave netif \r\n"); + return ERR_OK; +} + + +#if !LWIP_ARP +/** + * This function has to be completed by user in case of ARP OFF. + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if ... + */ +static err_t low_level_output_arp_off(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) +{ + err_t errval; + errval = ERR_OK; + + + return errval; + +} +#endif /* LWIP_ARP */ + +/* + * ethernetif_e1000e_init(): + * + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + */ +err_t ethernetif_e1000e_init(struct netif *netif) +{ + err_t err; + LWIP_DEBUGF(NETIF_DEBUG, ("*******start init e1000e eth\n")); + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = "lwip"; +#endif /* LWIP_NETIF_HOSTNAME */ + +#if LWIP_IPV4 +#if LWIP_ARP || LWIP_ETHERNET +#if LWIP_ARP + netif->output = etharp_output; +#else + /* The user should write ist own code in low_level_output_arp_off function */ + netif->output = low_level_output_arp_off; +#endif /* LWIP_ARP */ +#endif /* LWIP_ARP || LWIP_ETHERNET */ + +#if LWIP_IGMP + printf("netif_set_igmp_mac_filter !!!!\r\n"); + netif_set_igmp_mac_filter(netif, xmac_filter_update); +#endif + +#endif /* LWIP_IPV4 */ + + netif->linkoutput = low_level_output; +#if LWIP_IPV6 + netif->output_ip6 = ethip6_output; +#endif + + err = low_level_init(netif); + if (err != ERR_OK) + { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_e1000e_init is error\r\n")); + return err; + } + + return ERR_OK; +} + + diff --git a/third-party/lwip-2.1.2/src.mk b/third-party/lwip-2.1.2/src.mk index 4b7aebd801481908357b37ab42420e8fb65ff40d..56b0e8873c3a1cfe146d97438237d5764b526533 100644 --- a/third-party/lwip-2.1.2/src.mk +++ b/third-party/lwip-2.1.2/src.mk @@ -13,7 +13,11 @@ ifdef CONFIG_USE_FREERTOS ifdef CONFIG_LWIP_FXMAC_V2 CSRCS_RELATIVE_FILES += $(wildcard ports/fxmac_v2_0/*.c) - endif + endif + + ifdef CONFIG_LWIP_E1000E + CSRCS_RELATIVE_FILES += $(wildcard ports/e1000e/*.c) + endif endif