Browse Source

[bsp][x86] add pcnet32 eth driver

jasonhu 3 years ago
parent
commit
44243aca91

+ 24 - 18
bsp/x86/.config

@@ -416,6 +416,7 @@ CONFIG_LWP_TID_MAX_NR=64
 # CONFIG_PKG_USING_LUA is not set
 # CONFIG_PKG_USING_JERRYSCRIPT is not set
 # CONFIG_PKG_USING_MICROPYTHON is not set
+# CONFIG_PKG_USING_PIKASCRIPT is not set
 
 #
 # multimedia packages
@@ -526,6 +527,7 @@ CONFIG_LWP_TID_MAX_NR=64
 # CONFIG_PKG_USING_LPM is not set
 # CONFIG_PKG_USING_TLSF is not set
 # CONFIG_PKG_USING_EVENT_RECORDER is not set
+# CONFIG_PKG_USING_ARM_2D is not set
 
 #
 # peripheral libraries and drivers
@@ -597,6 +599,7 @@ CONFIG_LWP_TID_MAX_NR=64
 # CONFIG_PKG_USING_ROSSERIAL is not set
 # CONFIG_PKG_USING_MICRO_ROS is not set
 # CONFIG_PKG_USING_MCP23008 is not set
+# CONFIG_PKG_USING_BLUETRUM_SDK is not set
 
 #
 # AI packages
@@ -614,6 +617,27 @@ CONFIG_LWP_TID_MAX_NR=64
 #
 # miscellaneous packages
 #
+
+#
+# samples: kernel and components samples
+#
+# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
+# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
+# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
+# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
+
+#
+# entertainment: terminal games and other interesting software packages
+#
+# CONFIG_PKG_USING_CMATRIX is not set
+# CONFIG_PKG_USING_SL is not set
+# CONFIG_PKG_USING_CAL is not set
+# CONFIG_PKG_USING_ACLOCK is not set
+# CONFIG_PKG_USING_THREES is not set
+# CONFIG_PKG_USING_2048 is not set
+# CONFIG_PKG_USING_SNAKE is not set
+# CONFIG_PKG_USING_TETRIS is not set
+# CONFIG_PKG_USING_DONUT is not set
 # CONFIG_PKG_USING_LIBCSV is not set
 # CONFIG_PKG_USING_OPTPARSE is not set
 # CONFIG_PKG_USING_FASTLZ is not set
@@ -631,14 +655,6 @@ CONFIG_LWP_TID_MAX_NR=64
 # CONFIG_PKG_USING_DIGITALCTRL is not set
 # CONFIG_PKG_USING_UPACKER is not set
 # CONFIG_PKG_USING_UPARAM is not set
-
-#
-# samples: kernel and components samples
-#
-# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
-# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
-# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
-# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
 # CONFIG_PKG_USING_HELLO is not set
 # CONFIG_PKG_USING_VI is not set
 # CONFIG_PKG_USING_KI is not set
@@ -646,16 +662,6 @@ CONFIG_LWP_TID_MAX_NR=64
 # CONFIG_PKG_USING_VT100 is not set
 # CONFIG_PKG_USING_UKAL is not set
 # CONFIG_PKG_USING_CRCLIB is not set
-
-#
-# entertainment: terminal games and other interesting software packages
-#
-# CONFIG_PKG_USING_THREES is not set
-# CONFIG_PKG_USING_2048 is not set
-# CONFIG_PKG_USING_SNAKE is not set
-# CONFIG_PKG_USING_TETRIS is not set
-# CONFIG_PKG_USING_DONUT is not set
-# CONFIG_PKG_USING_ACLOCK is not set
 # CONFIG_PKG_USING_LWGPS is not set
 # CONFIG_PKG_USING_STATE_MACHINE is not set
 # CONFIG_PKG_USING_MCURSES is not set

+ 3 - 1
bsp/x86/Makefile

@@ -21,7 +21,9 @@ QEMU_WINDOW ?= n
 
 # config netcard ? (y/n)
 QEMU_NETCARD ?= y
-QEMU_NETCARD_NAME ?=rtl8139
+
+# netcard name: rtl8139/pcnet
+QEMU_NETCARD_NAME ?=pcnet
 
 # netcard type: tap/user
 QEMU_NET_MODE ?=user

+ 670 - 0
bsp/x86/drivers/drv_pcnet32.c

@@ -0,0 +1,670 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-08-19     JasonHu      first version
+ */
+
+#include <board.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <rthw.h>
+#include <netif/ethernetif.h>
+#include <pci.h>
+#include <mmu.h>
+
+#define DBG_LVL DBG_INFO
+#define DBG_TAG "PCNET32"
+#include <rtdbg.h>
+
+#include "drv_pcnet32.h"
+
+#define DEV_NAME "e0"
+
+#define GET_PCNET32(eth)    (struct eth_device_pcnet32 *)(eth)
+
+/**
+ * rx ring desc struct
+ */
+struct pcnet32_rx_desc
+{
+    rt_uint32_t base;   /* buffer base addr */
+    rt_uint16_t buf_length; /* two`s complement of length */
+    rt_uint16_t status; /* desc status */
+    rt_uint16_t msg_length; /*  Message Byte Count is the length in bytes of the received message. */
+    rt_uint16_t rpc_rcc;
+    rt_uint32_t reserved;
+} __attribute__ ((packed));
+
+/**
+ * tx ring desc struct
+ */
+struct pcnet32_tx_desc
+{
+    rt_uint32_t base;   /* buffer base addr */
+    rt_uint16_t buf_length; /* two`s complement of length */
+    rt_uint16_t status; /* desc status */
+    rt_uint32_t misc;
+    rt_uint32_t reserved;
+} __attribute__ ((packed));
+
+/**
+ * The PCNET32 32-Bit initialization block, described in databook.
+ * The Mode Register (CSR15) allows alteration of the chip's operating
+ * parameters. The Mode field of the Initialization Block is copied directly
+ * into CSR15. Normal operation is the result of configuring the Mode field
+ * with all bits zero.
+ */
+struct pcnet32_init_block
+{
+    rt_uint16_t mode;
+    rt_uint16_t tlen_rlen;
+    rt_uint8_t  phys_addr[6];
+    rt_uint16_t reserved;
+    rt_uint32_t filter[2];
+    /* Receive and transmit ring base, along with extra bits. */
+    rt_uint32_t rx_ring;
+    rt_uint32_t tx_ring;
+} __attribute__ ((packed));
+
+struct eth_device_pcnet32
+{
+    /* inherit from Ethernet device */
+    struct eth_device parent;
+    /* interface address info. */
+    rt_uint8_t dev_addr[ETH_ALEN];         /* MAC address  */
+
+    rt_pci_device_t *pci_dev;   /* pci device info */
+
+    rt_uint32_t iobase; /* io port base */
+    rt_uint32_t irqno;  /* irq number */
+
+    rt_mq_t rx_mqueue;  /* msg queue for rx */
+
+    struct pcnet32_init_block *init_block;
+
+    rt_uint16_t rx_len_bits;
+    rt_uint16_t tx_len_bits;
+
+    rt_ubase_t rx_ring_dma_addr;
+    rt_ubase_t tx_ring_dma_addr;
+
+    rt_ubase_t init_block_dma_addr;
+
+    rt_ubase_t rx_buffer_ptr;
+    rt_ubase_t tx_buffer_ptr;  /* pointers to transmit/receive buffers */
+
+    rt_size_t rx_buffer_count;   /* total number of receive buffers */
+    rt_size_t tx_buffer_count;   /* total number of transmit buffers */
+
+    rt_size_t buffer_size;  /* length of each packet buffer */
+
+    rt_size_t de_size;    /* length of descriptor entry */
+
+    struct pcnet32_rx_desc *rdes;   /* pointer to ring buffer of receive des */
+    struct pcnet32_tx_desc *tdes;   /* pointer to ring buffer of transmit des */
+
+    rt_uint32_t rx_buffers; /* physical address of actual receive buffers (< 4 GiB) */
+    rt_uint32_t tx_buffers; /* physical address of actual transmit buffers (< 4 GiB) */
+};
+static struct eth_device_pcnet32 eth_dev;
+static rt_uint8_t rx_cache_send_buf[RX_MSG_SIZE] = {0};     /* buf for rx packet, put size and data into mq */
+static rt_uint8_t rx_cache_recv_buf[RX_MSG_SIZE] = {0};     /* buf for rx packet, get size and data from mq */
+static rt_uint8_t tx_cache_pbuf[TX_CACHE_BUF_SIZE] = {0};   /* buf for tx packet, get data from pbuf payload */
+
+/**
+ * does the driver own the particular buffer?
+ */
+rt_inline rt_bool_t pcnet32_is_driver_own(struct eth_device_pcnet32 *dev, rt_bool_t is_tx, rt_uint32_t idx)
+{
+    return (rt_bool_t)(is_tx ? ((dev->tdes[idx].status & PCNET32_DESC_STATUS_OWN) == 0) :
+                   ((dev->rdes[idx].status & PCNET32_DESC_STATUS_OWN) == 0));
+}
+
+/*
+ * get the next desc buffer index
+ */
+rt_inline rt_uint32_t pcnet32_get_next_desc(struct eth_device_pcnet32 *dev, rt_uint32_t cur_idx, rt_uint32_t buf_count)
+{
+    return (cur_idx + 1) % buf_count;
+}
+
+static void pcnet32_init_rx_desc_entry(struct eth_device_pcnet32 *dev, rt_uint32_t idx)
+{
+    struct pcnet32_rx_desc *des = dev->rdes + idx;
+    rt_memset(des, 0, dev->de_size);
+
+    des->base = dev->rx_buffers + idx * dev->buffer_size;
+
+    /* next 2 bytes are 0xf000 OR'd with the first 12 bits of the 2s complement of the length */
+    rt_uint16_t bcnt = (rt_uint16_t)(-dev->buffer_size);
+    bcnt &= 0x0fff;
+    bcnt |= 0xf000; /* high 4 bits fixed 1 */
+    des->buf_length = bcnt;
+
+    /* finally, set ownership bit - transmit buffers are owned by us, receive buffers by the card */
+    des->status = PCNET32_DESC_STATUS_OWN;
+}
+
+static void pcnet32_init_tx_desc_entry(struct eth_device_pcnet32 *dev, rt_uint32_t idx)
+{
+    struct pcnet32_tx_desc *des = dev->tdes + idx;
+    rt_memset(des, 0, dev->de_size);
+
+    des->base = dev->tx_buffers + idx * dev->buffer_size;
+
+    /* next 2 bytes are 0xf000 OR'd with the first 12 bits of the 2s complement of the length */
+    rt_uint16_t bcnt = (rt_uint16_t)(-dev->buffer_size);
+    bcnt &= 0x0fff;
+    bcnt |= 0xf000; /* high 4 bits fixed 1 */
+    des->buf_length = bcnt;
+}
+
+static rt_uint16_t pcnet32_wio_read_mac(rt_uint32_t addr, int index)
+{
+    return inw(addr + index);
+}
+
+/*
+ * write index to RAP, read data from RDP
+ */
+static rt_uint16_t pcnet32_wio_read_csr(rt_uint32_t addr, int index)
+{
+    outw(addr + PCNET32_WIO_RAP, index);
+    return inw(addr + PCNET32_WIO_RDP);
+}
+
+/**
+ * write index to RAP, write data to RDP
+ */
+static void pcnet32_wio_write_csr(rt_uint32_t addr, int index, rt_uint16_t val)
+{
+    outw(addr + PCNET32_WIO_RAP, index);
+    outw(addr + PCNET32_WIO_RDP, val);
+}
+
+static void pcnet32_wio_write_bcr(rt_uint32_t addr, int index, rt_uint16_t val)
+{
+    outw(addr + PCNET32_WIO_RAP, index);
+    outw(addr + PCNET32_WIO_BDP, val);
+}
+
+/*
+ * Reset causes the device to cease operation and clear its internal logic.
+ */
+static void pcnet32_wio_reset(rt_uint32_t addr)
+{
+    inw(addr + PCNET32_WIO_RESET);
+}
+
+static int pcnet32_get_pci(struct eth_device_pcnet32 *dev)
+{
+    /* get pci device */
+    rt_pci_device_t *pci_dev = rt_pci_device_get(PCNET32_VENDOR_ID, PCNET32_DEVICE_ID);
+    if (pci_dev == RT_NULL)
+    {
+        LOG_E("device not find on pci device.\n");
+        return -1;
+    }
+    dev->pci_dev = pci_dev;
+    dbg_log(DBG_LOG, "find device, vendor id: 0x%x, device id: 0x%x\n",
+          pci_dev->vendor_id, pci_dev->device_id);
+
+    /* enable bus mastering */
+    rt_pci_enable_bus_mastering(pci_dev);
+
+    /* get io port address */
+    dev->iobase = rt_pci_device_get_io_addr(pci_dev);
+    if (dev->iobase == 0)
+    {
+        LOG_E("invalid pci device io address.\n");
+        return -1;
+    }
+    dbg_log(DBG_LOG, "io base address: 0x%x\n", dev->iobase);
+    /* get irq */
+    dev->irqno = rt_pci_device_get_irq_line(pci_dev);
+    if (dev->irqno == 0xff)
+    {
+        LOG_E("invalid irqno.\n");
+        return -1;
+    }
+    dbg_log(DBG_LOG, "irqno %d\n", dev->irqno);
+    return 0;
+}
+
+static int pcnet32_transmit(struct eth_device_pcnet32 *dev, rt_uint8_t *buf, rt_size_t len)
+{
+    if(len > ETH_FRAME_LEN)
+    {
+        len = ETH_FRAME_LEN;
+    }
+
+    rt_uint32_t tx_retry = PCNET32_TX_RETRY;
+
+    while (tx_retry > 0)
+    {
+        /* the next available descriptor entry index is in tx_buffer_ptr */
+        if(!pcnet32_is_driver_own(dev, RT_TRUE, dev->tx_buffer_ptr))
+        {
+            /* try encourage the card to send all buffers. */
+            pcnet32_wio_write_csr(dev->iobase, CSR0, pcnet32_wio_read_csr(dev->iobase, CSR0) | CSR0_TXPOLL);
+        }
+        else
+        {
+            break;
+        }
+        --tx_retry;
+    }
+
+    if (!tx_retry)  /* retry end, no entry available */
+    {
+        dbg_log(DBG_ERROR, "transmit no available descriptor entry\n")
+        return -1;
+    }
+
+    rt_memcpy((void *)(dev->tx_buffers + dev->tx_buffer_ptr * dev->buffer_size), buf, len);
+
+    struct pcnet32_tx_desc *tdes = dev->tdes + dev->tx_buffer_ptr;
+    /**
+     * set the STP bit in the descriptor entry (signals this is the first
+     * frame in a split packet - we only support single frames)
+     */
+    tdes->status |= PCNET32_DESC_STATUS_STP;
+
+    /* similarly, set the ENP bit to state this is also the end of a packet */
+    tdes->status |= PCNET32_DESC_STATUS_ENP;
+
+    rt_uint16_t bcnt = (rt_uint16_t)(-len);
+    bcnt &= 0xfff;
+    bcnt |= 0xf000; /* high 4 bits fixed 1 */
+    tdes->buf_length = bcnt;
+
+    /* finally, flip the ownership bit back to the card */
+    tdes->status |= PCNET32_DESC_STATUS_OWN;
+
+    dev->tx_buffer_ptr = pcnet32_get_next_desc(dev, dev->tx_buffer_ptr, dev->tx_buffer_count);
+    return 0;
+}
+
+static rt_err_t pcnet32_tx(rt_device_t device, struct pbuf *p)
+{
+    rt_err_t err = RT_EOK;
+    /* copy data from pbuf to tx cache */
+    pbuf_copy_partial(p, (void *)&tx_cache_pbuf[0], p->tot_len, 0);
+    if (pcnet32_transmit(GET_PCNET32(device), tx_cache_pbuf, p->tot_len) < 0)
+    {
+        err = RT_ERROR;
+    }
+    return err;
+}
+
+static struct pbuf *pcnet32_rx(rt_device_t device)
+{
+    struct eth_device_pcnet32 *dev = GET_PCNET32(device);
+    int recv_len = 0;
+    struct pbuf *pbuf = RT_NULL;
+    rt_err_t err;
+
+    /* get data from rx queue. */
+    err = rt_mq_recv_interruptible(dev->rx_mqueue, rx_cache_recv_buf, RX_MSG_SIZE, 0);
+    if (err != RT_EOK)
+    {
+        return pbuf;
+    }
+    /* get recv len from rx cache, 0~3: recv len, 3-n: frame data */
+    recv_len = *(int *)rx_cache_recv_buf;
+    if (recv_len > 0)
+    {
+        pbuf = pbuf_alloc(PBUF_LINK, recv_len, PBUF_RAM);
+        rt_memcpy(pbuf->payload, (char *)rx_cache_recv_buf + 4, recv_len);
+    }
+    return pbuf;
+}
+
+static rt_err_t pcnet32_control(rt_device_t device, int cmd, void *args)
+{
+    struct eth_device_pcnet32 *dev = GET_PCNET32(device);
+    switch(cmd)
+    {
+    case NIOCTL_GADDR:
+        /* get MAC address */
+        if(args)
+        {
+            rt_memcpy(args, dev->dev_addr, ETH_ALEN);
+        }
+        else
+        {
+            return -RT_ERROR;
+        }
+        break;
+    default :
+        break;
+    }
+    return RT_EOK;
+}
+
+static void pcnet32_rx_packet(struct eth_device_pcnet32 *dev)
+{
+    while (pcnet32_is_driver_own(dev, RT_FALSE, dev->rx_buffer_ptr))
+    {
+        struct pcnet32_rx_desc *rdes = dev->rdes + dev->rx_buffer_ptr;
+        rt_uint32_t plen = rdes->msg_length; /* msg len no need to negate it unlike BCNT above */
+
+        void *pbuf = (void *)(dev->rx_buffers + dev->rx_buffer_ptr * dev->buffer_size);
+        dbg_log(DBG_LOG, "recv packet on ring %d: buf=%p, len=%d\n", dev->rx_buffer_ptr, pbuf, plen);
+        /* merge size and data into receive pkg */
+        rt_memcpy(rx_cache_send_buf, &plen, 4);
+        rt_memcpy(&rx_cache_send_buf[4], pbuf, plen);
+
+        rt_mq_send_interrupt(dev->rx_mqueue, rx_cache_send_buf, plen + 4);
+        eth_device_ready(&dev->parent); /* notify eth thread to read packet */
+
+        /* hand the buffer back to the card */
+        rdes->status = PCNET32_DESC_STATUS_OWN;
+
+        dev->rx_buffer_ptr = pcnet32_get_next_desc(dev, dev->rx_buffer_ptr, dev->rx_buffer_count);
+    }
+}
+
+static void rt_hw_pcnet32_isr(int vector, void *param)
+{
+    struct eth_device_pcnet32 *dev = GET_PCNET32(param);
+    rt_uint32_t iobase = dev->iobase;
+    rt_uint32_t csr0 = pcnet32_wio_read_csr(iobase, 0);
+
+    if (csr0 & CSR0_RINT) /* recv packet */
+    {
+        dbg_log(DBG_LOG, "RX intr occur!\n");
+        pcnet32_rx_packet(dev);
+    }
+    else if ((csr0 & CSR0_TINT))    /* packet transmitted */
+    {
+        dbg_log(DBG_LOG, "TX intr occur!\n");
+    }
+    else if ((csr0 & CSR0_IDON))
+    {
+        dbg_log(DBG_INFO, "init done\n");
+    }
+    else if ((csr0 & CSR0_MERR))
+    {
+        dbg_log(DBG_WARNING, "memory error!\n");
+    }
+    else if ((csr0 & CSR0_MISS))
+    {
+        dbg_log(DBG_WARNING, "missed frame!\n");
+    }
+    else if ((csr0 & CSR0_CERR))
+    {
+        dbg_log(DBG_WARNING, "collision error!\n");
+    }
+    else if ((csr0 & CSR0_BABL))
+    {
+        dbg_log(DBG_WARNING, "transmitter time-out error!\n");
+    }
+    else
+    {
+        dbg_log(DBG_WARNING, "unknown intr\n");
+    }
+    /* ack pcnet32 interrupt as handled */
+    pcnet32_wio_write_csr(iobase, 0, csr0);
+}
+
+static rt_err_t pcnet32_alloc_ring_buffer(struct eth_device_pcnet32 *dev)
+{
+    dev->rdes = rt_malloc_align(dev->rx_buffer_count * dev->de_size, 16);
+    if (dev->rdes == RT_NULL)
+    {
+        dbg_log(DBG_ERROR, "alloc memory for rx ring failed!");
+        return RT_ERROR;
+    }
+    dev->tdes = rt_malloc_align(dev->tx_buffer_count * dev->de_size, 16);
+    if (dev->tdes == RT_NULL)
+    {
+        dbg_log(DBG_ERROR, "alloc memory for tx ring failed!");
+        rt_free_align(dev->rdes);
+        return RT_ERROR;
+    }
+
+    dev->rx_buffers = (uint32_t)rt_malloc_align(dev->rx_buffer_count * dev->buffer_size, 16);
+    if (dev->rx_buffers == 0)
+    {
+        dbg_log(DBG_ERROR, "alloc memory for rx ring buffer failed!");
+        rt_free_align(dev->rdes);
+        rt_free_align(dev->tdes);
+        return RT_ERROR;
+    }
+
+    dev->tx_buffers = (uint32_t)rt_malloc_align(dev->tx_buffer_count * dev->buffer_size, 16);
+    if (dev->tx_buffers == 0)
+    {
+        dbg_log(DBG_ERROR, "alloc memory for tx ring buffer failed!");
+        rt_free_align(dev->rdes);
+        rt_free_align(dev->tdes);
+        rt_free_align((void *)dev->rx_buffers);
+        return RT_ERROR;
+    }
+    dbg_log(DBG_LOG, "rdes:%p tdes:%p rbuf:%p tbuf:%p\n", dev->rdes, dev->tdes, dev->rx_buffers, dev->tx_buffers);
+
+    int i = 0;
+    for (i = 0; i < dev->rx_buffer_count; i++)
+    {
+        pcnet32_init_rx_desc_entry(dev, i);
+    }
+    for (i = 0; i < dev->tx_buffer_count; i++)
+    {
+        pcnet32_init_tx_desc_entry(dev, i);
+    }
+    return RT_EOK;
+}
+
+static void pcnet32_free_ring_buffer(struct eth_device_pcnet32 *dev)
+{
+    rt_free_align(dev->rdes);
+    rt_free_align(dev->tdes);
+    rt_free_align((void *)dev->rx_buffers);
+    rt_free_align((void *)dev->tx_buffers);
+}
+
+static void pcnet32_print_init_block(struct eth_device_pcnet32 *dev)
+{
+    rt_uint32_t iobase = dev->iobase;
+
+    struct pcnet32_init_block *init_block = dev->init_block;
+    dbg_log(DBG_LOG, "============\nprint init block\n");
+    dbg_log(DBG_LOG, "mode: %x, tlen_rlen:%x\n", init_block->mode, init_block->tlen_rlen);
+    dbg_log(DBG_LOG, "mac: %x:%x:%x:%x:%x:%x\n",
+            init_block->phys_addr[0],
+            init_block->phys_addr[1],
+            init_block->phys_addr[2],
+            init_block->phys_addr[3],
+            init_block->phys_addr[4],
+            init_block->phys_addr[5]);
+    dbg_log(DBG_LOG, "filter0: %x, filter1: %x\n", init_block->filter[0], init_block->filter[1]);
+    dbg_log(DBG_LOG, "rx ring dma: %x, tx ring dma: %x\n", init_block->rx_ring, init_block->tx_ring);
+    dbg_log(DBG_LOG, "init block dma: %x\n", dev->init_block_dma_addr);
+
+    int i = 0;
+    for (; i <= 46; i++)
+    {
+        dbg_log(DBG_LOG, "csr%d=%x\n", i, pcnet32_wio_read_csr(iobase, i));
+    }
+}
+
+static rt_err_t pcnet32_init(rt_device_t device)
+{
+    struct eth_device_pcnet32 *dev = GET_PCNET32(device);
+    rt_uint32_t iobase = dev->iobase;
+
+    /* init buffer info */
+    dev->rx_buffer_ptr = 0;
+    dev->tx_buffer_ptr = 0;
+
+    dev->rx_buffer_count = PCNET32_RX_BUFFERS;
+    dev->tx_buffer_count = PCNET32_TX_BUFFERS;
+
+    dev->buffer_size = ETH_FRAME_LEN;
+    dev->de_size = PCNET32_RING_DE_SIZE;
+
+    if (pcnet32_alloc_ring_buffer(dev) != RT_EOK)
+    {
+        return RT_ERROR;
+    }
+
+    dev->rx_ring_dma_addr = (rt_ubase_t)rt_hw_vir2phy(dev->rdes);
+    dev->tx_ring_dma_addr = (rt_ubase_t)rt_hw_vir2phy(dev->tdes);
+
+    /* create msg queue for eth rx */
+    dev->rx_mqueue = rt_mq_create("rx_mqueue", RX_MSG_SIZE, RX_MSG_CNT, 0);
+    if (dev->rx_mqueue == RT_NULL)
+    {
+        LOG_E("crete msg queue for rx buffer failed!\n");
+        pcnet32_free_ring_buffer(dev);
+        return RT_ERROR;
+    }
+
+    /* alloc init block, must 16 bit align */
+    dev->init_block = rt_malloc_align(sizeof(struct pcnet32_init_block), 16);
+    if (dev->init_block == RT_NULL)
+    {
+        dbg_log(DBG_ERROR, "alloc memory for init block failed!");
+        rt_mq_delete(dev->rx_mqueue);
+        pcnet32_free_ring_buffer(dev);
+        return RT_ERROR;
+    }
+    dev->init_block_dma_addr = (rt_ubase_t)rt_hw_vir2phy(dev->init_block);
+
+    dbg_log(DBG_LOG, "init block addr:%p size:%d\n", dev->init_block, sizeof(struct pcnet32_init_block));
+
+    /* fill init block */
+    dev->init_block->mode = 0;
+    dev->tx_len_bits = (PCNET32_LOG_TX_BUFFERS << 4);
+    dev->rx_len_bits = (PCNET32_LOG_RX_BUFFERS << 4);
+    dev->init_block->tlen_rlen = (dev->tx_len_bits << 8) | dev->rx_len_bits;
+    int i = 0;
+    for (i = 0; i < ETH_ALEN; i++)
+    {
+        dev->init_block->phys_addr[i] = dev->dev_addr[i];
+    }
+    dev->init_block->filter[0] = 0x00000000;
+    dev->init_block->filter[1] = 0x00000000;
+    dev->init_block->rx_ring = dev->rx_ring_dma_addr;
+    dev->init_block->tx_ring = dev->tx_ring_dma_addr;
+
+    /* register init block, CSR1 save low 16 bit, CSR1 save high 16 bit */
+    pcnet32_wio_write_csr(iobase, CSR1, (dev->init_block_dma_addr & 0xffff));
+    pcnet32_wio_write_csr(iobase, CSR2, (dev->init_block_dma_addr >> 16) & 0xffff);
+
+    /* register intr */
+    if (rt_hw_interrupt_install(dev->irqno, rt_hw_pcnet32_isr, (void *) dev, "pcnet32") < 0)
+    {
+        LOG_E("install IRQ failed!\n");
+        rt_free_align(dev->init_block);
+        rt_mq_delete(dev->rx_mqueue);
+        pcnet32_free_ring_buffer(dev);
+        return RT_ERROR;
+    }
+    rt_hw_interrupt_umask(dev->irqno);
+
+    /* Start init */
+    pcnet32_wio_write_csr(iobase, CSR0, CSR0_INIT | CSR0_INTEN);
+    dbg_log(DBG_LOG, "card init done.\n");
+
+    /* add auto pad amd strip recv */
+    rt_uint16_t csr4 = pcnet32_wio_read_csr(iobase, CSR4);
+    pcnet32_wio_write_csr(iobase, CSR4, csr4 | CSR4_ASTRP_RCV | CSR4_APAD_XMT);
+
+    /* start work */
+    pcnet32_wio_write_csr(iobase, CSR0, CSR0_START | CSR0_INTEN);
+
+    pcnet32_print_init_block(dev);
+
+    eth_device_linkchange(&dev->parent, RT_TRUE);
+    return RT_EOK;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops pcnet32_ops =
+{
+    pcnet32_init,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    pcnet32_control
+};
+#endif
+
+static rt_err_t pcnet32_init_hw(struct eth_device_pcnet32 *dev)
+{
+    rt_uint32_t iobase = dev->iobase;
+
+    /* reset card to 16 bit io mode */
+    pcnet32_wio_reset(iobase);
+
+    /* use dealy to wait reset done, at least 1 microsecond */
+    rt_thread_delay(1);
+
+    /* switch to 32 bit soft-style mode, use 32 bit struct */
+    pcnet32_wio_write_bcr(iobase, 20, 0x102);
+
+    /* stop card work */
+    pcnet32_wio_write_csr(iobase, 0, 0x4);
+
+    /* read mac addr */
+    rt_uint16_t mac0 = pcnet32_wio_read_mac(iobase, 0);
+    rt_uint16_t mac1 = pcnet32_wio_read_mac(iobase, 2);
+    rt_uint16_t mac2 = pcnet32_wio_read_mac(iobase, 4);
+
+    dev->dev_addr[0] = mac0 & 0xff;
+    dev->dev_addr[1] = (mac0 >> 8) & 0xff;
+    dev->dev_addr[2] = mac1 & 0xff;
+    dev->dev_addr[3] = (mac1 >> 8) & 0xff;
+    dev->dev_addr[4] = mac2 & 0xff;
+    dev->dev_addr[5] = (mac2 >> 8) & 0xff;
+
+    dbg_log(DBG_INFO, "MAC addr: %x:%x:%x:%x:%x:%x\n",
+        dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+        dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+    return RT_EOK;
+}
+
+static int rt_hw_pcnet32_init(void)
+{
+    rt_memset(&eth_dev, 0x0, sizeof(eth_dev));
+
+    if (pcnet32_get_pci(&eth_dev) < 0)
+    {
+        return -1;
+    }
+
+    if (pcnet32_init_hw(&eth_dev) != RT_EOK)
+    {
+        return -1;
+    }
+
+    /* set device opts */
+#ifdef RT_USING_DEVICE_OPS
+    eth_dev.parent.parent.ops        = &pcnet32_ops;
+#else
+    eth_dev.parent.parent.init       = pcnet32_init;
+    eth_dev.parent.parent.open       = RT_NULL;
+    eth_dev.parent.parent.close      = RT_NULL;
+    eth_dev.parent.parent.read       = RT_NULL;
+    eth_dev.parent.parent.write      = RT_NULL;
+    eth_dev.parent.parent.control    = pcnet32_control;
+#endif
+    eth_dev.parent.parent.user_data  = RT_NULL;
+    eth_dev.parent.eth_rx     = pcnet32_rx;
+    eth_dev.parent.eth_tx     = pcnet32_tx;
+
+    /* register ETH device */
+    if (eth_device_init(&(eth_dev.parent), DEV_NAME) != RT_EOK)
+    {
+        return -1;
+    }
+    return 0;
+}
+INIT_DEVICE_EXPORT(rt_hw_pcnet32_init);

+ 115 - 0
bsp/x86/drivers/drv_pcnet32.h

@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-08-19     JasonHu      first version
+ */
+
+#ifndef __DRV_PCNET32_H__
+#define __DRV_PCNET32_H__
+
+#include <rtdef.h>
+
+#define ETH_ALEN 6  /* MAC addr */
+#define ETH_ZLEN 60 /* Minimum length of data without CRC check */
+#define ETH_DATA_LEN 1500 /* Maximum length of data in a frame */
+#define ETH_FRAME_LEN 1518 /* Maximum Ethernet data length */
+
+#define RX_MSG_CNT 8  /* 4 msg queue */
+#define RX_MSG_SIZE (ETH_FRAME_LEN + 4)  /* 4 save real msg size */
+
+#define TX_CACHE_BUF_SIZE          (2048)
+
+#define JUMP_TO(label)  goto label
+
+#define PCNET32_VENDOR_ID   0x1022
+#define PCNET32_DEVICE_ID   0x2000
+
+/* Offsets from base I/O address. */
+#define PCNET32_WIO_RDP     0x10
+#define PCNET32_WIO_RAP     0x12
+#define PCNET32_WIO_RESET   0x14
+#define PCNET32_WIO_BDP     0x16
+
+#define CSR0        0
+#define CSR0_INIT   0x1
+#define CSR0_START  0x2
+#define CSR0_STOP   0x4
+#define CSR0_TXPOLL 0x8
+#define CSR0_INTEN  0x40
+#define CSR0_IDON   0x0100
+#define CSR0_NORMAL (CSR0_START | CSR0_INTEN)
+#define CSR0_TINT   0x0200  /* Transmit Interrupt */
+#define CSR0_RINT   0x0400  /* Receive Interrupt */
+#define CSR0_MERR   0x0800  /* Memory Error */
+#define CSR0_MISS   0x1000  /* Missed Frame */
+#define CSR0_CERR   0x2000  /* Collision Error */
+#define CSR0_BABL   0x4000  /* Babble is a transmitter time-out error. */
+
+/* Error is set by the ORing of BABL, CERR, MISS, and MERR.
+ * ERR remains set as long as any of the error flags are true.
+ */
+#define CSR0_ERR   0x8000
+
+#define CSR1        1
+#define CSR2        2
+#define CSR3        3   /*  Interrupt Masks and Deferral Control */
+#define CSR3_IDONM  (1 << 8)   /* Initialization Done Mask. */
+#define CSR4        4   /* Test and Features Control */
+#define CSR4_ASTRP_RCV  (1 << 10)   /* Auto Strip Receive */
+#define CSR4_APAD_XMT   (1 << 11)   /* Auto Pad Transmit */
+
+#define CSR5        5
+#define CSR5_SUSPEND    0x0001
+#define CSR6        6   /* RX/TX Descriptor Table Length */
+
+#define CSR15       15  /* Mode */
+#define CSR18       18  /* Current Receive Buffer Address Lower */
+#define CSR19       19  /* Current Receive Buffer Address Upper */
+#define CSR24       24  /* Base Address of Receive Descriptor Ring Lower */
+#define CSR25       25  /* Base Address of Receive Descriptor Ring Upper */
+#define CSR30       30  /* Base Address of Transmit Descriptor Ring Lower */
+#define CSR31       31  /* Base Address of Transmit Descriptor Ring Upper */
+
+#define CSR58       58  /* Software Style */
+#define CSR58_PCNET_PCI_II   0x02
+
+#define PCNET32_INIT_LOW    1
+#define PCNET32_INIT_HIGH   2
+#define PCNET32_MC_FILTER 8   /* broadcast filter */
+
+#define CSR72       72  /* Receive Descriptor Ring Counter */
+#define CSR74       74  /* Transmit Descriptor Ring Counter */
+
+#define BCR2        2
+#define BCR2_ASEL   (1 << 1)
+
+#define PCNET32_TX_BUFFERS 8
+#define PCNET32_RX_BUFFERS 32
+#define PCNET32_LOG_TX_BUFFERS 3    /* 2^3 = 8 buffers */
+#define PCNET32_LOG_RX_BUFFERS 5    /* 2^5 = 32 buffers */
+
+#define PCNET32_RING_DE_SIZE     16
+
+#define PCNET32_TX_RETRY     10 /* tx retry counter when no available descriptor entry */
+
+#define PCNET32_DESC_STATUS_OWN 0x8000  /* card own the desc */
+
+/**
+ * End of Packet indicates that this is the last buffer used by
+ * the PCnet-PCI II controller for this frame.
+ */
+#define PCNET32_DESC_STATUS_ENP 0x0100
+
+/**
+ * Start of Packet indicates that this
+ * is the first buffer used by the
+ * PCnet-PCI II controller for this
+ * frame.
+ */
+#define PCNET32_DESC_STATUS_STP 0x0200
+
+#endif  /* __DRV_PCNET32_H__ */

+ 33 - 21
bsp/x86/drivers/drv_rtl8139.c

@@ -72,12 +72,25 @@ static rt_uint8_t rx_cache_send_buf[RX_MSG_SIZE] = {0};     /* buf for rx packet
 static rt_uint8_t rx_cache_recv_buf[RX_MSG_SIZE] = {0};     /* buf for rx packet, get size and data from mq */
 static rt_uint8_t tx_cache_pbuf[TX_CACHE_BUF_SIZE] = {0};   /* buf for tx packet, get data from pbuf payload */
 
+/* rx config */
+static const rt_uint32_t rtl8139_rx_config = RX_CFG_RCV_32K | RX_NO_WRAP |
+    (RX_FIFO_THRESH << RX_CFG_FIFO_SHIFT) |
+    (RX_DMA_BURST << RX_CFG_DMA_SHIFT);
+
+/* tx config */
+static const rt_uint32_t rtl8139_tx_config = TX_IFG96 | (TX_DMA_BURST << TX_DMA_SHIFT) |
+    (TX_RETRY << TX_RETRY_SHIFT);
+
+/* intr mask, 1: receive, 0: ignore */
+static const rt_uint16_t rtl8139_intr_mask = PCI_ERR | PCS_TIMEOUT | RX_UNDERRUN | RX_OVERFLOW | RX_FIFO_OVER |
+    TX_ERR | TX_OK | RX_ERR | RX_OK;
+
 static int rtl8139_next_desc(int current_desc)
 {
     return (current_desc == NUM_TX_DESC - 1) ? 0 : (current_desc + 1);
 }
 
-int rtl8139_transmit(struct eth_device_rtl8139 *dev, rt_uint8_t *buf, rt_size_t len)
+static int rtl8139_transmit(struct eth_device_rtl8139 *dev, rt_uint8_t *buf, rt_size_t len)
 {
     rt_uint32_t entry;
     rt_uint32_t length = len;
@@ -112,7 +125,7 @@ int rtl8139_transmit(struct eth_device_rtl8139 *dev, rt_uint8_t *buf, rt_size_t
         */
         rt_hw_dsb();
 
-        outl(dev->iobase + TX_STATUS0 + (entry * 4), dev->tx_flags | ETH_MAX(length, (rt_uint32_t )ETH_ZLEN));
+        outl(dev->iobase + TX_STATUS0 + (entry * 4), dev->tx_flags | ETH_MAX(length, (rt_uint32_t)ETH_ZLEN));
         inl(dev->iobase + TX_STATUS0 + (entry * 4)); // flush
 
         dev->current_tx = rtl8139_next_desc(dev->current_tx);
@@ -130,8 +143,6 @@ int rtl8139_transmit(struct eth_device_rtl8139 *dev, rt_uint8_t *buf, rt_size_t
 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
 static void rtl8139_init_ring(struct eth_device_rtl8139 *dev)
 {
-    int i;
-
     dev->current_rx = 0;
     dev->current_tx = 0;
     dev->dirty_tx = 0;
@@ -139,7 +150,8 @@ static void rtl8139_init_ring(struct eth_device_rtl8139 *dev)
     /* set free counts */
     dev->tx_free_counts = NUM_TX_DESC;
 
-    for (i = 0; i < NUM_TX_DESC; i++)
+    int i = 0;
+    for (; i < NUM_TX_DESC; i++)
     {
         dev->tx_buffer[i] = (unsigned char *)&dev->tx_buffers[i * TX_BUF_SIZE];
     }
@@ -244,8 +256,8 @@ static void rtl8139_hardware_start(struct eth_device_rtl8139 *dev)
     outb(dev->iobase + CFG9346, CFG9346_LOCK);
 
     /* init Tx buffer DMA addresses */
-    int i;
-    for (i = 0; i < NUM_TX_DESC; i++)
+    int i = 0;
+    for (; i < NUM_TX_DESC; i++)
     {
         outl(dev->iobase + TX_ADDR0 + (i * 4), dev->tx_buffer_dma + (dev->tx_buffer[i] - dev->tx_buffers));
         /* flush */
@@ -275,10 +287,9 @@ static int rtl8139_tx_interrupt(struct eth_device_rtl8139 *dev)
     while (dev->tx_free_counts < NUM_TX_DESC)
     {
         int entry = dev->dirty_tx;
-        int tx_status;
 
         /* read tx status */
-        tx_status = inl(dev->iobase + TX_STATUS0 + (entry * 4));
+        int tx_status = inl(dev->iobase + TX_STATUS0 + (entry * 4));
 
         /* no tx intr, exit */
         if (!(tx_status & (TX_STAT_OK | TX_UNDERRUN | TX_ABORTED)))
@@ -387,7 +398,7 @@ static void rtl8139_rx_error(rt_uint32_t rx_status, struct eth_device_rtl8139 *d
     if (!(rx_status & RX_STATUS_OK))
     {
         /* frame error */
-        if (rx_status & (RX_BAD_SYMBOL | RX_BAD_Align))
+        if (rx_status & (RX_BAD_SYMBOL | RX_BAD_ALIGN))
         {
             dev->stats.rx_frame_errors++;
         }
@@ -494,19 +505,19 @@ static int rtl8139_rx_interrupt(struct eth_device_rtl8139 *dev)
                 if (rx_status & RX_CRC_ERR)
                 {
                     dev->stats.rx_crc_errors++;
-                    goto keep_pkt;
+                    JUMP_TO(keep_pkt);
                 }
 
                 if (rx_status & RX_RUNT)
                 {
                     dev->stats.rx_length_errors++;
-                    goto keep_pkt;
+                    JUMP_TO(keep_pkt);
                 }
             }
             /* rx error handle */
             rtl8139_rx_error(rx_status, dev);
             received = -1;
-            goto out;
+            JUMP_TO(out);
         }
 
 keep_pkt:
@@ -566,7 +577,7 @@ static void rt_hw_rtl8139_isr(int vector, void *param)
     {
         /* clear intr mask, don't receive intr forever */
         outw(dev->iobase + INTR_MASK, 0);
-        goto out;
+        JUMP_TO(out);
     }
 
     /* Acknowledge all of the current interrupt sources ASAP, but
@@ -599,7 +610,9 @@ static void rt_hw_rtl8139_isr(int vector, void *param)
         rtl8139_tx_interrupt(dev);
 
         if (status & TX_ERR)
+        {
             outw(dev->iobase + INTR_STATUS, TX_ERR);
+        }
     }
 out:
     rt_spin_unlock(&dev->lock);
@@ -721,12 +734,12 @@ static int rtl8139_init_board(struct eth_device_rtl8139 *dev)
     }
 
     rt_uint32_t version = inl(dev->iobase + TX_CONFIG) & HW_REVID_MASK;
-    int i;
-    for (i = 0; i < CHIP_INFO_NR; i++)
+    int i = 0;
+    for (; i < CHIP_INFO_NR; i++)
     {
         if (version == rtl_chip_info[i].version) {
             dev->chipset = i;
-            goto chip_match;
+            JUMP_TO(chip_match);
         }
     }
 
@@ -775,8 +788,8 @@ static int rtl8139_init_hw(struct eth_device_rtl8139 *dev)
     }
 
     /* get MAC from pci config */
-    int i;
-    for (i = 0; i < ETH_ALEN; i++) {
+    int i = 0;
+    for (; i < ETH_ALEN; i++) {
         dev->dev_addr[i] = inb(dev->iobase + MAC0 + i);
     }
     dbg_log(DBG_INFO, "MAC addr: %x:%x:%x:%x:%x:%x\n", dev->dev_addr[0], dev->dev_addr[1],
@@ -815,7 +828,7 @@ static struct pbuf *rtl8139_rx(rt_device_t device)
     err = rt_mq_recv_interruptible(dev->rx_mqueue, rx_cache_recv_buf, RX_MSG_SIZE, 0);
     if (err != RT_EOK)
     {
-        goto end;
+        return pbuf;
     }
     /* get recv len from rx cache, 0~3: recv len, 3-n: frame data */
     recv_len = *(int *)rx_cache_recv_buf;
@@ -824,7 +837,6 @@ static struct pbuf *rtl8139_rx(rt_device_t device)
         pbuf = pbuf_alloc(PBUF_LINK, recv_len, PBUF_RAM);
         rt_memcpy(pbuf->payload, (char *)rx_cache_recv_buf + 4, recv_len);
     }
-end:
     return pbuf;
 }
 

+ 14 - 25
bsp/x86/drivers/drv_rtl8139.h

@@ -61,6 +61,8 @@
 #define TX_DMA_BURST    6   /* Maximum PCI burst, '6' is 1024 */
 #define TX_RETRY    8   /* 0-15.  retries = 16 + (TX_RETRY * 16) */
 
+#define JUMP_TO(label)  goto label
+
 enum
 {
     HAS_MII_XCVR = 0x010000,
@@ -96,7 +98,7 @@ enum rtl8139_registers
     CONFIG0     = 0x51,
     CONFIG1     = 0x52,
     TIMER_INT   = 0x54,
-    MEDIA_STATUS= 0x58,
+    MEDIA_STATUS = 0x58,
     CONFIG3     = 0x59,
     CONFIG4     = 0x5A,  /* absent on RTL-8139A */
     HLT_CTL     = 0x5B,
@@ -106,13 +108,13 @@ enum rtl8139_registers
     BASIC_MODE_STATUS   = 0x64,
     NWAY_ADVERT = 0x66,
     NWAY_LPAR   = 0x68,
-    NWAY_EXPANSION  = 0x6A,
+    NWAY_EXPANSION = 0x6A,
     /* Undocumented registers, but required for proper operation. */
     FIFOTMS     = 0x70,  /* FIFO Control and test. */
     CSCR        = 0x74,  /* Chip Status and Configuration Register. */
     PARA78      = 0x78,
     FLASH_REG   = 0xD4, /* Communication with Flash ROM, four bytes. */
-    PARA7c      = 0x7c,  /* Magic transceiver parameter register. */
+    PARA7C      = 0x7c,  /* Magic transceiver parameter register. */
     CONFIG5     = 0xD8,  /* absent on RTL-8139A */
 };
 
@@ -120,7 +122,7 @@ enum clear_bit_masks
 {
     MULTI_INTR_CLEAR    = 0xF000,
     CHIP_CMD_CLEAR  = 0xE2,
-    CONFIG1_CLEAR   = (1 <<7 ) | (1 << 6) | (1 << 3) | (1 << 2) | (1 << 1),
+    CONFIG1_CLEAR   = (1 << 7) | (1 << 6) | (1 << 3) | (1 << 2) | (1 << 1),
 };
 
 enum chip_cmd_bits
@@ -165,7 +167,7 @@ enum rx_status_bits
     RX_RUNT         = 0x0010,
     RX_TOO_LONG     = 0x0008,
     RX_CRC_ERR      = 0x0004,
-    RX_BAD_Align    = 0x0002,
+    RX_BAD_ALIGN    = 0x0002,
     RX_STATUS_OK    = 0x0001,
 };
 
@@ -236,13 +238,13 @@ enum config4_bits
 /* Bits in Config5 */
 enum config5_bits
 {
-    Cfg5_PME_STS    = (1 << 0), /* 1    = PCI reset resets PME_Status */
-    Cfg5_LANWake    = (1 << 1), /* 1    = enable LANWake signal */
-    Cfg5_LDPS       = (1 << 2), /* 0    = save power when link is down */
-    Cfg5_FIFOAddrPtr= (1 << 3), /* Realtek internal SRAM testing */
-    Cfg5_UWF        = (1 << 4), /* 1 = accept unicast wakeup frame */
-    Cfg5_MWF        = (1 << 5), /* 1 = accept multicast wakeup frame */
-    Cfg5_BWF        = (1 << 6), /* 1 = accept broadcast wakeup frame */
+    CFG5_PME_STS    = (1 << 0), /* 1    = PCI reset resets PME_Status */
+    CFG5_LAN_WAKE   = (1 << 1), /* 1    = enable LANWake signal */
+    CFG5_LDPS       = (1 << 2), /* 0    = save power when link is down */
+    CFG5_FIFO_ADDR_PTR = (1 << 3), /* Realtek internal SRAM testing */
+    CFG5_UWF        = (1 << 4), /* 1 = accept unicast wakeup frame */
+    CFG5_MWF        = (1 << 5), /* 1 = accept multicast wakeup frame */
+    CFG5_BWF        = (1 << 6), /* 1 = accept broadcast wakeup frame */
 };
 
 enum rx_config_bits
@@ -361,19 +363,6 @@ struct rtl8139_status
     rt_ubase_t bytes;
 };
 
-/* rx config */
-static const rt_uint32_t rtl8139_rx_config = RX_CFG_RCV_32K | RX_NO_WRAP |
-    (RX_FIFO_THRESH << RX_CFG_FIFO_SHIFT) |
-    (RX_DMA_BURST << RX_CFG_DMA_SHIFT);
-
-/* tx config */
-static const rt_uint32_t rtl8139_tx_config = TX_IFG96 | (TX_DMA_BURST << TX_DMA_SHIFT) |
-    (TX_RETRY << TX_RETRY_SHIFT);
-
-/* intr mask, 1: receive, 0: ignore */
-static const rt_uint16_t rtl8139_intr_mask = PCI_ERR | PCS_TIMEOUT | RX_UNDERRUN | RX_OVERFLOW | RX_FIFO_OVER |
-    TX_ERR | TX_OK | RX_ERR | RX_OK;
-
 struct net_device_status
 {
     rt_ubase_t tx_errors;

+ 0 - 1
bsp/x86/rtconfig.h

@@ -243,7 +243,6 @@
 
 /* miscellaneous packages */
 
-
 /* samples: kernel and components samples */
 
 

+ 2 - 2
libcpu/x86/i386/mmu.h

@@ -143,7 +143,7 @@ void rt_hw_mmu_unmap(rt_mmu_info *mmu_info,void *v_addr,rt_size_t size);
 void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info,void *v_addr);
 
 /* used in kernel mmaped area */
-#define rt_hw_phy2vir(p) ((p) + KERNEL_VADDR_START)
-#define rt_hw_vir2phy(v) ((v) - KERNEL_VADDR_START)
+#define rt_hw_phy2vir(p) ((rt_ubase_t)(p) + KERNEL_VADDR_START)
+#define rt_hw_vir2phy(v) ((rt_ubase_t)(v) - KERNEL_VADDR_START)
 
 #endif