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