145 lines
3.4 KiB
C
145 lines
3.4 KiB
C
#include "drv_eth.h"
|
||
#include "lwip/opt.h"
|
||
#include "lwip/mem.h"
|
||
#include "lwip/memp.h"
|
||
#include "lwip/timeouts.h"
|
||
#include "netif/etharp.h"
|
||
#include "lwip/ethip6.h"
|
||
#include "osal.h"
|
||
#include "hal.h"
|
||
#include <string.h>
|
||
|
||
/* 硬件抽象层操作结构体 */
|
||
static const hal_ops_t *hal_ops = NULL;
|
||
|
||
static err_t low_level_output(struct netif *netif, struct pbuf *p)
|
||
{
|
||
(void)netif;
|
||
err_t errval;
|
||
uint8_t *buffer = NULL;
|
||
uint32_t len = p->tot_len;
|
||
|
||
/* 分配缓冲区 */
|
||
buffer = (uint8_t *)mem_malloc(len);
|
||
if (buffer == NULL) {
|
||
return ERR_MEM;
|
||
}
|
||
|
||
/* 复制数据到缓冲区 */
|
||
pbuf_copy_partial(p, buffer, len, 0);
|
||
|
||
/* 使用硬件抽象层发送数据 */
|
||
if (hal_ops && hal_ops->eth && hal_ops->eth->send(buffer, len) == HAL_STATUS_OK) {
|
||
errval = ERR_OK;
|
||
} else {
|
||
errval = ERR_IF;
|
||
}
|
||
|
||
/* 释放缓冲区 */
|
||
mem_free(buffer);
|
||
|
||
return errval;
|
||
}
|
||
|
||
static struct pbuf * low_level_input(struct netif *netif)
|
||
{
|
||
(void)netif;
|
||
struct pbuf *p = NULL;
|
||
uint8_t *buffer = NULL;
|
||
uint32_t rxLength = 0;
|
||
|
||
/* 分配缓冲区 */
|
||
buffer = (uint8_t *)mem_malloc(ETH_RX_BUF_SIZE);
|
||
if (buffer == NULL) {
|
||
return NULL;
|
||
}
|
||
|
||
/* 使用硬件抽象层接收数据 */
|
||
if (hal_ops && hal_ops->eth && hal_ops->eth->recv(buffer, &rxLength, 100) == HAL_STATUS_OK)
|
||
{
|
||
if (rxLength > 0 && buffer != NULL) {
|
||
/* 尝试使用 PBUF_REF 模式创建 pbuf,实现零拷贝 */
|
||
p = pbuf_alloc(PBUF_RAW, rxLength, PBUF_POOL);
|
||
if (p != NULL) {
|
||
pbuf_take(p, buffer, rxLength);
|
||
} else {
|
||
osal_log_e("pbuf_alloc failed");
|
||
}
|
||
}
|
||
} else {
|
||
/* ReadData failed, maybe no data available */
|
||
}
|
||
|
||
/* 释放缓冲区 */
|
||
mem_free(buffer);
|
||
|
||
return p;
|
||
}
|
||
|
||
void ethernetif_input(struct netif *netif)
|
||
{
|
||
struct pbuf *p;
|
||
|
||
do {
|
||
p = low_level_input(netif);
|
||
if (p != NULL)
|
||
{
|
||
// osal_log_i("Rx: len=%d", p->tot_len); // Debug print
|
||
if (netif->input(p, netif) != ERR_OK)
|
||
{
|
||
pbuf_free(p);
|
||
}
|
||
}
|
||
} while(p != NULL);
|
||
}
|
||
|
||
err_t ethernetif_init(struct netif *netif)
|
||
{
|
||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||
|
||
#if LWIP_NETIF_HOSTNAME
|
||
netif->hostname = "lwip";
|
||
#endif
|
||
|
||
netif->name[0] = 'e';
|
||
netif->name[1] = 't';
|
||
|
||
netif->output = etharp_output;
|
||
netif->linkoutput = low_level_output;
|
||
|
||
/* 获取硬件抽象层操作结构体 */
|
||
hal_ops = hal_get_ops();
|
||
if (hal_ops == NULL) {
|
||
osal_log_e("Failed to get HAL ops");
|
||
return ERR_IF;
|
||
}
|
||
|
||
/* 配置网络接口 */
|
||
netif->hwaddr_len = 6;
|
||
/* MAC地址由硬件抽象层初始化 */
|
||
netif->mtu = 1500;
|
||
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
|
||
#if LWIP_IPV6
|
||
netif->flags |= NETIF_FLAG_IGMP;
|
||
#endif
|
||
|
||
return ERR_OK;
|
||
}
|
||
|
||
void ethernet_link_check_state(struct netif *netif)
|
||
{
|
||
if (hal_ops && hal_ops->eth) {
|
||
if (hal_ops->eth->get_link_status() == HAL_STATUS_OK) {
|
||
if (!netif_is_link_up(netif)) {
|
||
netif_set_link_up(netif);
|
||
osal_log_i("Ethernet Link Up");
|
||
}
|
||
} else {
|
||
if (netif_is_link_up(netif)) {
|
||
netif_set_link_down(netif);
|
||
osal_log_i("Ethernet Link Down");
|
||
}
|
||
}
|
||
}
|
||
}
|