[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 05/18] hw: add QEMU model for Faraday 10/100Mbps Eth
From: |
Dante |
Subject: |
[Qemu-devel] [PATCH 05/18] hw: add QEMU model for Faraday 10/100Mbps Ethernet MAC |
Date: |
Fri, 18 Jan 2013 14:28:13 +0800 |
Signed-off-by: Kuo-Jung Su <address@hidden>
---
hw/ftmac110.c | 567 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/ftmac110.h | 130 +++++++++++++
2 files changed, 697 insertions(+)
create mode 100644 hw/ftmac110.c
create mode 100644 hw/ftmac110.h
diff --git a/hw/ftmac110.c b/hw/ftmac110.c
new file mode 100644
index 0000000..ab264dd
--- /dev/null
+++ b/hw/ftmac110.c
@@ -0,0 +1,567 @@
+/*
+ * QEMU model of the FTMAC110 Controller
+ *
+ * Copyright (C) 2012 Faraday Technology
+ * Copyright (C) 2012 Dante Su <address@hidden>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "sysbus.h"
+#include "sysemu/sysemu.h"
+#include "net/net.h"
+
+#include "ftmac110.h"
+
+/* For crc32 */
+#include <zlib.h>
+
+typedef struct {
+ SysBusDevice busdev;
+ MemoryRegion mmio;
+
+ QEMUTimer *qtimer;
+ qemu_irq irq;
+ NICState *nic;
+ NICConf conf;
+
+ uint32_t isr;
+ uint32_t ier;
+ uint32_t mhash[2];
+ uint32_t tx_bar;
+ uint32_t rx_bar;
+ uint32_t tx_idx;
+ uint32_t rx_idx;
+ uint32_t maccr;
+ uint32_t macsr;
+ uint32_t phycr;
+ uint32_t phycr_rd;
+
+ struct {
+ uint8_t buf[2048];
+ uint32_t len;
+ } txbuff;
+
+ uint32_t rx_pkt;
+ uint32_t rx_bcst;
+ uint32_t rx_mcst;
+ uint16_t rx_runt;
+ uint16_t rx_drop;
+ uint16_t rx_crc;
+ uint16_t rx_ftl;
+ uint32_t tx_pkt;
+
+} ftmac110_state;
+
+static inline uint8_t bitrev8(uint8_t v)
+{
+ uint8_t r = 0;
+ int i;
+ for(i = 0; i < 8; ++i) {
+ if (v & (1 << i))
+ r |= (1 << (7 - i));
+ }
+ return r;
+}
+
+static int ftmac110_mcast_hash (int len, const uint8_t *p)
+{
+#define CRCPOLY_LE 0xedb88320
+ int i;
+ uint32_t crc = 0xFFFFFFFF;
+
+ while (len--) {
+ crc ^= *p++;
+ for (i = 0; i < 8; i++)
+ crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
+ }
+
+ /* Reverse CRC32 and return MSB 6 bits only */
+ return bitrev8(crc >> 24) >> 2;
+}
+
+static inline void ftmac110_update_irq(ftmac110_state *s)
+{
+ if (s->isr & s->ier)
+ qemu_set_irq(s->irq, 1);
+ else
+ qemu_set_irq(s->irq, 0);
+}
+
+static int ftmac110_can_receive(NetClientState *nc)
+{
+ ftmac110_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
+ ftmac110_rxdesc_t rxd;
+ hwaddr off = s->rx_bar + s->rx_idx * sizeof(rxd);
+
+ if ((s->maccr & (MACCR_RCV_EN | MACCR_RDMA_EN)) != (MACCR_RCV_EN |
MACCR_RDMA_EN))
+ return 0;
+
+ cpu_physical_memory_read(off, (uint8_t *)&rxd, sizeof(rxd));
+
+ return rxd.owner;
+}
+
+static ssize_t ftmac110_receive(NetClientState *nc, const uint8_t *buf, size_t
size)
+{
+ const uint8_t *ptr = buf;
+ hwaddr off;
+ size_t len;
+ ftmac110_rxdesc_t rxd;
+ ftmac110_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
+ int bcst, mcst;
+
+ if ((s->maccr & (MACCR_RCV_EN | MACCR_RDMA_EN)) != (MACCR_RCV_EN |
MACCR_RDMA_EN))
+ return -1;
+
+ /* if it's a broadcast */
+ if ((buf[0] == 0xff) && (buf[1] == 0xff) && (buf[2] == 0xff)
+ && (buf[3] == 0xff) && (buf[4] == 0xff) && (buf[5] == 0xff)) {
+ bcst = 1;
+ if (!(s->maccr & MACCR_RCV_ALL) && !(s->maccr & MACCR_RX_BROADPKT)) {
+ printf("[qemu] ftmac110_receive: bcst filtered\n");
+ return -1;
+ }
+ } else {
+ bcst = 0;
+ }
+
+ /* if it's a multicast */
+ if ((buf[0] == 0x01) && (buf[1] == 0x00) && (buf[2] == 0x5e)
+ && (buf[3] <= 0x7f)) {
+ mcst = 1;
+ if (!(s->maccr & MACCR_RCV_ALL) && !(s->maccr & MACCR_RX_MULTIPKT)) {
+ int hash;
+ if (!(s->maccr & MACCR_HT_MULTI_EN)) {
+ printf("[qemu] ftmac110_receive: mcst filtered\n");
+ return -1;
+ }
+ hash = ftmac110_mcast_hash(6, buf);
+ if (!(s->mhash[hash / 32] & (1 << (hash % 32)))) {
+ printf("[qemu] ftmac110_receive: mcst filtered\n");
+ return -1;
+ }
+ }
+ } else {
+ mcst = 0;
+ }
+
+ /* check if the destination matches NIC mac address */
+ if (!(s->maccr & MACCR_RCV_ALL) && !bcst && !mcst) {
+ if (memcmp(s->conf.macaddr.a, buf, 6)) {
+#if 0
+ printf("[qemu] ftmac110_receive: pkt filtered\n");
+ printf("[qemu] packet dump: (IF
MAC=%02X:%02X:%02X:%02X:%02X:%02X)\n",
+ s->conf.macaddr.a[0], s->conf.macaddr.a[1],
+ s->conf.macaddr.a[2], s->conf.macaddr.a[3],
+ s->conf.macaddr.a[4], s->conf.macaddr.a[5]);
+ for (off = 0; off < 14; ++off) {
+ printf("%02X ", buf[off]);
+ }
+ printf("\n");
+#endif
+ return -1;
+ }
+ }
+
+ while (size > 0) {
+ off = s->rx_bar + s->rx_idx * sizeof(rxd);
+ cpu_physical_memory_read(off, (uint8_t *)&rxd, sizeof(rxd));
+ if (!rxd.owner) {
+ s->isr |= ISR_NORXBUF;
+ printf("[qemu] ftmac110: out of rxd!? (ptr=%p, buf=%p)\n", ptr,
buf);
+ return -1;
+ }
+
+ if (ptr == buf)
+ rxd.frs = 1;
+ else
+ rxd.frs = 0;
+
+ len = size > rxd.bufsz ? rxd.bufsz : size;
+ cpu_physical_memory_write(rxd.buf, (uint8_t *)ptr, len);
+ ptr += len;
+ size -= len;
+
+ if (size <= 0)
+ rxd.lrs = 1;
+ else
+ rxd.lrs = 0;
+
+ rxd.len = len;
+ rxd.bcast = bcst;
+ rxd.mcast = mcst;
+ rxd.owner = 0;
+
+ /* write-back the rx descriptor */
+ cpu_physical_memory_write(off, (uint8_t *)&rxd, sizeof(rxd));
+
+ if (rxd.end)
+ s->rx_idx = 0;
+ else
+ s->rx_idx += 1;
+ }
+
+ /* 3. update interrupt signal */
+ s->isr |= ISR_RPKT_OK | ISR_RPKT_FINISH;
+ ftmac110_update_irq(s);
+
+ return (ssize_t)((uint32_t)ptr - (uint32_t)buf);
+}
+
+static void ftmac110_transmit(ftmac110_state *s, uint32_t *bar, uint32_t *idx)
+{
+ hwaddr off;
+ uint8_t *buf;
+ ftmac110_txdesc_t txd;
+
+ if ((s->maccr & (MACCR_XMT_EN | MACCR_XDMA_EN)) != (MACCR_XMT_EN |
MACCR_XDMA_EN))
+ return;
+
+ do {
+ off = (*bar) + (*idx) * sizeof(txd);
+ cpu_physical_memory_read(off, (uint8_t *)&txd, sizeof(txd));
+ if (!txd.owner) {
+ s->isr |= ISR_NOTXBUF;
+ break;
+ }
+ if (txd.fts)
+ s->txbuff.len = 0;
+ buf = s->txbuff.buf + s->txbuff.len;
+ cpu_physical_memory_read(txd.buf, (uint8_t *)buf, txd.len);
+ s->txbuff.len += txd.len;
+ if (txd.lts) {
+ if (s->maccr & MACCR_LOOP_EN) {
+ ftmac110_receive(&s->nic->nc, s->txbuff.buf, s->txbuff.len);
+ } else {
+ qemu_send_packet(&s->nic->nc, s->txbuff.buf, s->txbuff.len);
+ }
+ }
+ if (txd.end)
+ *idx = 0;
+ else
+ *idx += 1;
+ if (txd.tx2fic)
+ s->isr |= ISR_XPKT_OK;
+ if (txd.txic)
+ s->isr |= ISR_XPKT_FINISH;
+
+ txd.owner = 0;
+ cpu_physical_memory_write(off, (uint8_t *)&txd, sizeof(txd));
+ } while(1);
+}
+
+static void ftmac110_timer_tick(void *opaque)
+{
+ ftmac110_state *s = opaque;
+
+ if (s->tx_bar) {
+ ftmac110_transmit(s, &s->tx_bar, &s->tx_idx);
+ }
+
+ ftmac110_update_irq(s);
+}
+
+static uint64_t ftmac110_mem_read(void *opaque, hwaddr addr, unsigned int size)
+{
+ ftmac110_state *s = opaque;
+ uint32_t rc = 0;
+
+ switch (addr) {
+ case REG_ISR:
+ rc = s->isr;
+ s->isr = 0;
+ ftmac110_update_irq(s);
+ break;
+ case REG_IMR:
+ return s->ier;
+ case REG_HMAC:
+ return s->conf.macaddr.a[1]
+ | (s->conf.macaddr.a[0] << 8);
+ case REG_LMAC:
+ return s->conf.macaddr.a[5]
+ | (s->conf.macaddr.a[4] << 8)
+ | (s->conf.macaddr.a[3] << 16)
+ | (s->conf.macaddr.a[2] << 24);
+ case REG_MHASH0:
+ return s->mhash[0];
+ case REG_MHASH1:
+ return s->mhash[1];
+ case REG_TXBAR:
+ return s->tx_bar;
+ case REG_RXBAR:
+ return s->rx_bar;
+ case REG_MACCR:
+ return s->maccr;
+ case REG_MACSR:
+ rc = s->macsr;
+ s->macsr = 0;
+ break;
+ case REG_PHYCTRL:
+ do {
+ uint8_t dev = (s->phycr >> 16) & 0x1f;
+ uint8_t reg = (s->phycr >> 21) & 0x1f;
+ if (dev != 0)
+ break;
+ if (s->phycr_rd) {
+ switch(reg) {
+ case 0: /* PHY control register */
+ return s->phycr | 0x1140;
+ case 1: /* PHY status register */
+ return s->phycr | 0x796d;
+ case 2: /* PHY ID 1 register */
+ return s->phycr | 0x0141;
+ case 3: /* PHY ID 2 register */
+ return s->phycr | 0x0cc2;
+ case 4: /* Autonegotiation advertisement register */
+ return s->phycr | 0x0de1;
+ case 5: /* Autonegotiation partner abilities register */
+ return s->phycr | 0x45e1;
+ }
+ }
+ } while(0);
+ break;
+ case REG_FCR:
+ return 0x0000a400;
+ case REG_BPR:
+ return 0x00000400;
+ case REG_TXPKT:
+ return s->tx_pkt;
+ case REG_RXPKT:
+ return s->rx_pkt;
+ case REG_RXBCST:
+ return s->rx_bcst;
+ case REG_RXMCST:
+ return s->rx_mcst;
+ case REG_RXRUNT:
+ return (s->rx_runt << 16);
+ case REG_RXCRCFTL:
+ return (s->rx_crc << 16) | (s->rx_ftl);
+ case REG_REV:
+ return 0x00000700;
+ case REG_FEA:
+ return 0x00000007;
+ default:
+ break;
+ }
+
+ return rc;
+}
+
+static void ftmac110_chip_reset(ftmac110_state *s)
+{
+ s->isr = 0;
+ s->ier = 0;
+ s->mhash[0] = 0;
+ s->mhash[1] = 0;
+ s->tx_bar = 0;
+ s->rx_bar = 0;
+ s->tx_idx = 0;
+ s->rx_idx = 0;
+ s->maccr = 0;
+ s->macsr = 0;
+ s->phycr = 0;
+ s->txbuff.len = 0;
+ s->rx_pkt = 0;
+ s->rx_bcst = 0;
+ s->rx_mcst = 0;
+ s->rx_runt = 0;
+ s->rx_drop = 0;
+ s->rx_crc = 0;
+ s->rx_ftl = 0;
+ s->tx_pkt = 0;
+
+ if (s->qtimer)
+ qemu_del_timer(s->qtimer);
+
+ ftmac110_update_irq(s);
+}
+
+static void ftmac110_mem_write(void *opaque, hwaddr addr, uint64_t val,
unsigned int size)
+{
+ ftmac110_state *s = opaque;
+
+ switch (addr) {
+ case REG_IMR:
+ s->ier = (uint32_t)val;
+ ftmac110_update_irq(s);
+ break;
+ case REG_HMAC:
+ s->conf.macaddr.a[1] = (val >> 0) & 0xff;
+ s->conf.macaddr.a[0] = (val >> 8) & 0xff;
+ break;
+ case REG_LMAC:
+ s->conf.macaddr.a[5] = (val >> 0) & 0xff;
+ s->conf.macaddr.a[4] = (val >> 8) & 0xff;
+ s->conf.macaddr.a[3] = (val >> 16) & 0xff;
+ s->conf.macaddr.a[2] = (val >> 24) & 0xff;
+ break;
+ case REG_MHASH0:
+ s->mhash[0] = (uint32_t)val;
+ break;
+ case REG_MHASH1:
+ s->mhash[1] = (uint32_t)val;
+ break;
+ case REG_TXBAR:
+ s->tx_bar = (uint32_t)val;
+ break;
+ case REG_RXBAR:
+ s->rx_bar = (uint32_t)val;
+ break;
+ case REG_MACCR:
+ s->maccr = (uint32_t)val;
+ if (s->maccr & MACCR_SW_RST) {
+ ftmac110_chip_reset(s);
+ s->maccr &= ~MACCR_SW_RST;
+ }
+ break;
+ case REG_PHYCTRL:
+ s->phycr = (uint32_t)val;
+ if (s->phycr & PHYCR_MDIORD)
+ s->phycr_rd = 1;
+ else
+ s->phycr_rd = 0;
+ s->phycr &= ~(PHYCR_MDIOWR | PHYCR_MDIORD);
+ break;
+ case REG_TXPD:
+ qemu_mod_timer(s->qtimer, qemu_get_clock_ns(vm_clock) + 1);
+ break;
+ default:
+ break;
+ }
+}
+
+static const MemoryRegionOps bus_ops = {
+ .read = ftmac110_mem_read,
+ .write = ftmac110_mem_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4
+ }
+};
+
+static void ftmac110_cleanup(NetClientState *nc)
+{
+ ftmac110_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
+
+ s->nic = NULL;
+}
+
+static NetClientInfo net_ftmac110_info = {
+ .type = NET_CLIENT_OPTIONS_KIND_NIC,
+ .size = sizeof(NICState),
+ .can_receive = ftmac110_can_receive,
+ .receive = ftmac110_receive,
+ .cleanup = ftmac110_cleanup,
+};
+
+static void ftmac110_reset(DeviceState *dev)
+{
+ ftmac110_state *s = FROM_SYSBUS(ftmac110_state, sysbus_from_qdev(dev));
+
+ ftmac110_chip_reset(s);
+}
+
+static int ftmac110_init1(SysBusDevice *dev)
+{
+ ftmac110_state *s = FROM_SYSBUS(typeof(*s), dev);
+
+ memory_region_init_io(&s->mmio, &bus_ops, s, "ftmac110", 0x1000);
+ sysbus_init_mmio(dev, &s->mmio);
+ sysbus_init_irq(dev, &s->irq);
+
+ qemu_macaddr_default_if_unset(&s->conf.macaddr);
+ s->nic = qemu_new_nic(&net_ftmac110_info, &s->conf,
+ object_get_typename(OBJECT(dev)), dev->qdev.id, s);
+ qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
+
+ s->qtimer = qemu_new_timer_ns(vm_clock, ftmac110_timer_tick, s);
+
+ ftmac110_chip_reset(s);
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_ftmac110 = {
+ .name = "ftmac110",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(ier, ftmac110_state),
+ VMSTATE_UINT32(tx_bar, ftmac110_state),
+ VMSTATE_UINT32(rx_bar, ftmac110_state),
+ VMSTATE_UINT32(tx_idx, ftmac110_state),
+ VMSTATE_UINT32(rx_idx, ftmac110_state),
+ VMSTATE_UINT32(maccr, ftmac110_state),
+ VMSTATE_UINT32(macsr, ftmac110_state),
+ VMSTATE_UINT32(phycr, ftmac110_state),
+ VMSTATE_UINT32_ARRAY(mhash, ftmac110_state, 2),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static Property ftmac110_properties[] = {
+ DEFINE_NIC_PROPERTIES(ftmac110_state, conf),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ftmac110_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+ k->init = ftmac110_init1;
+ dc->reset = ftmac110_reset;
+ dc->vmsd = &vmstate_ftmac110;
+ dc->props = ftmac110_properties;
+}
+
+static TypeInfo ftmac110_info = {
+ .name = "ftmac110",
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(ftmac110_state),
+ .class_init = ftmac110_class_init,
+};
+
+static void ftmac110_register_types(void)
+{
+ type_register_static(&ftmac110_info);
+}
+
+/* Legacy helper function. Should go away when machine config files are
+ implemented. */
+void ftmac110_init(NICInfo *nd, uint32_t base, qemu_irq irq);
+
+void ftmac110_init(NICInfo *nd, uint32_t base, qemu_irq irq)
+{
+ DeviceState *dev;
+ SysBusDevice *s;
+
+ qemu_check_nic_model(nd, "ftmac110");
+ dev = qdev_create(NULL, "ftmac110");
+ qdev_set_nic_properties(dev, nd);
+ qdev_init_nofail(dev);
+ s = sysbus_from_qdev(dev);
+ sysbus_mmio_map(s, 0, base);
+ sysbus_connect_irq(s, 0, irq);
+}
+
+type_init(ftmac110_register_types)
diff --git a/hw/ftmac110.h b/hw/ftmac110.h
new file mode 100644
index 0000000..4187150
--- /dev/null
+++ b/hw/ftmac110.h
@@ -0,0 +1,130 @@
+#ifndef FTMAC110_H
+#define FTMAC110_H
+
+// --------------------------------------------------------------------
+// FTMAC110 MAC Registers
+// --------------------------------------------------------------------
+
+#define REG_ISR 0x00 // interrups status register
+#define REG_IMR 0x04 // interrupt maks register
+#define REG_HMAC 0x08 // MAC address (Most significant)
+#define REG_LMAC 0x0c // MAC address (Least significant)
+#define REG_MHASH0 0x10 // Multicast Address Hash Table 0
register
+#define REG_MHASH1 0x14 // Multicast Address Hash Table 1
register
+#define REG_TXPD 0x18 // Transmit Poll Demand register
+#define REG_RXPD 0x1c // Receive Poll Demand register
+#define REG_TXBAR 0x20 // Transmit Ring Base Address
register
+#define REG_RXBAR 0x24 // Receive Ring Base Address
register
+#define REG_ITC 0x28 // interrupt timer control register
+#define REG_APTC 0x2C // Automatic Polling Timer control
register
+#define REG_DBLAC 0x30 // DMA Burst Length and
Arbitration control register
+#define REG_REV 0x34 // Revision Register
+#define REG_FEA 0x38 // Feature Register
+
+#define REG_MACCR 0x88 // MAC control register
+#define REG_MACSR 0x8C // MAC status register
+#define REG_PHYCTRL 0x90 // PHY control register
+#define REG_PHYDATA 0x94 // PHY Write Data register
+#define REG_FCR 0x98 // Flow Control register
+#define REG_BPR 0x9c // back pressure register
+
+#define REG_TXPKT 0xf8
+#define REG_RXPKT 0xf4
+#define REG_RXBCST 0xec
+#define REG_RXMCST 0xf0
+#define REG_RXRUNT 0xe0
+#define REG_RXCRCFTL 0xe4
+
+//Interrupt status register(ISR), Interrupt mask register(IMR) bit setting
+#define ISR_PHYSTS_CHG (1UL<<9)
+#define ISR_AHB_ERR (1UL<<8)
+#define ISR_RPKT_LOST (1UL<<7)
+#define ISR_RPKT_OK (1UL<<6)
+#define ISR_XPKT_LOST (1UL<<5)
+#define ISR_XPKT_OK (1UL<<4)
+#define ISR_NOTXBUF (1UL<<3)
+#define ISR_XPKT_FINISH (1UL<<2)
+#define ISR_NORXBUF (1UL<<1)
+#define ISR_RPKT_FINISH (1UL<<0)
+
+/* MACC control bits */
+#define MACCR_100M (1UL<<18)
+#define MACCR_RX_BROADPKT (1UL<<17) // Receiving broadcast
packet
+#define MACCR_RX_MULTIPKT (1UL<<16) // receiving multicast
packet
+#define MACCR_FULLDUP (1UL<<15) // full duplex
+#define MACCR_CRC_APD (1UL<<14) // append crc to transmit
packet
+#define MACCR_RCV_ALL (1UL<<12) // not check incoming
packet's destination address
+#define MACCR_RX_FTL (1UL<<11) // Store incoming packet
even its length is les than 64 byte
+#define MACCR_RX_RUNT (1UL<<10) // Store incoming packet
even its length is les than 64 byte
+#define MACCR_HT_MULTI_EN (1UL<<9)
+#define MACCR_RCV_EN (1UL<<8) // receiver enable
+#define MACCR_ENRX_IN_HALFTX (1UL<<6) // rx in half tx
+#define MACCR_XMT_EN (1UL<<5) // transmitter enable
+#define MACCR_CRC_DIS (1UL<<4)
+#define MACCR_LOOP_EN (1UL<<3) // Internal loop-back
+#define MACCR_SW_RST (1UL<<2)
+#define MACCR_RDMA_EN (1UL<<1) // enable DMA receiving
channel
+#define MACCR_XDMA_EN (1UL<<0) // enable DMA transmitting
channel
+
+// --------------------------------------------------------------------
+// MII PHY Registers
+// --------------------------------------------------------------------
+
+//
+// Bits related to the MII interface
+//
+#define PHYCR_MDIOWR (1 << 27)
+#define PHYCR_MDIORD (1 << 26)
+
+// --------------------------------------------------------------------
+// Receive Ring descriptor structure
+// --------------------------------------------------------------------
+typedef struct {
+ // RXDES0
+ uint32_t len: 11; // BIT: 0 - 10
+ uint32_t rsvd1: 5; // BIT: 11 - 15
+ uint32_t mcast: 1; // BIT: 16
+ uint32_t bcast: 1; // BIT: 17
+ uint32_t error: 5;
+ uint32_t rsvd2: 5; // BIT: 23 - 27
+ uint32_t lrs: 1; // BIT: 28
+ uint32_t frs: 1; // BIT: 29
+ uint32_t rsvd3: 1; // BIT: 30
+ uint32_t owner: 1; // BIT: 31 - 1:Hardware, 0: Software
+
+ // RXDES1
+ uint32_t bufsz: 11; // BIT: 0 - 10
+ uint32_t rsvd4: 20; // BIT: 11 - 30
+ uint32_t end: 1; // BIT: 31
+
+ // RXDES2
+ uint32_t buf;
+
+ // RXDES3
+ void *skb;
+} ftmac110_rxdesc_t;
+
+typedef struct {
+ // TXDES0
+ uint32_t error : 2;
+ uint32_t rsvd1 : 29;
+ uint32_t owner : 1; // BIT: 31 - 1:Hardware, 0: Software
+
+ // TXDES1
+ uint32_t len : 11; // BIT: 0 - 10
+ uint32_t rsvd2 : 16;
+ uint32_t lts: 1; // BIT: 27
+ uint32_t fts: 1; // BIT: 28
+ uint32_t tx2fic: 1; // BIT: 29
+ uint32_t txic: 1; // BIT: 30
+ uint32_t end: 1; // BIT: 31
+
+ // TXDES2
+ uint32_t buf;
+
+ // TXDES3
+ void *skb;
+
+} ftmac110_txdesc_t;
+
+#endif /* FTMAC_H */
--
1.7.9.5
********************* Confidentiality Notice ************************
This electronic message and any attachments may contain
confidential and legally privileged information or
information which is otherwise protected from disclosure.
If you are not the intended recipient,please do not disclose
the contents, either in whole or in part, to anyone,and
immediately delete the message and any attachments from
your computer system and destroy all hard copies.
Thank you for your cooperation.
***********************************************************************
- [Qemu-devel] [PATCH 01/18] hw: add Faraday a369 SoC platform support, Dante, 2013/01/18
- [Qemu-devel] [PATCH 02/18] hw: add QEMU model for Faraday APB DMA, Dante, 2013/01/18
- [Qemu-devel] [PATCH 03/18] hw: add QEMU model for Faraday AHB DMA, Dante, 2013/01/18
- [Qemu-devel] [PATCH 04/18] hw: add QEMU model for Faraday 1Gbps Ethernet MAC, Dante, 2013/01/18
- [Qemu-devel] [PATCH 05/18] hw: add QEMU model for Faraday 10/100Mbps Ethernet MAC,
Dante <=
- Re: [Qemu-devel] [PATCH 01/18] hw: add Faraday a369 SoC platform support, Blue Swirl, 2013/01/19
- [Qemu-devel] [PATCH v2 00/20] Add Faraday A36x SoC platform support, Kuo-Jung Su, 2013/01/25
- [Qemu-devel] [PATCH v2 01/20] arm: add Faraday a36x SoC platform support, Kuo-Jung Su, 2013/01/25
- Re: [Qemu-devel] [PATCH v2 01/20] arm: add Faraday a36x SoC platform support, Blue Swirl, 2013/01/25
- Re: [Qemu-devel] [PATCH v2 01/20] arm: add Faraday a36x SoC platform support, Igor Mitsyanko, 2013/01/31