From: Stefan Weil <weil@mail.berlios.de>
To: QEMU Developers <qemu-devel@nongnu.org>
Subject: [Qemu-devel] [PATCH 3/3] eepro100: Fix multicast support
Date: Sun, 20 Dec 2009 16:52:24 +0100 [thread overview]
Message-ID: <1261324344-10642-3-git-send-email-weil@mail.berlios.de> (raw)
In-Reply-To: <1261324344-10642-2-git-send-email-weil@mail.berlios.de>
* Handling of multicast list was missing.
* Multicast all was missing.
* Promiscuous mode for multicast frames was wrong.
This patch is a step to synchronize my maintainer version
of eepro100.c (git://repo.or.cz/qemu/ar7.git) with the
version integrated in QEMU.
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
hw/eepro100.c | 52 +++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 39 insertions(+), 13 deletions(-)
diff --git a/hw/eepro100.c b/hw/eepro100.c
index fb455a4..5a77409 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -141,7 +141,7 @@ typedef struct {
uint16_t status;
uint16_t command;
uint32_t link; /* void * */
- uint32_t tx_desc_addr; /* transmit buffer decsriptor array address. */
+ uint32_t tbd_array_addr; /* transmit buffer descriptor array address. */
uint16_t tcb_bytes; /* transmit command block byte count (in lower 14 bits */
uint8_t tx_threshold; /* transmit threshold */
uint8_t tbd_count; /* TBD number */
@@ -268,7 +268,7 @@ static void stl_le_phys(target_phys_addr_t addr, uint32_t val)
/* From FreeBSD */
/* XXX: optimize */
-static int compute_mcast_idx(const uint8_t * ep)
+static unsigned compute_mcast_idx(const uint8_t * ep)
{
uint32_t crc;
int carry, i, j;
@@ -286,7 +286,7 @@ static int compute_mcast_idx(const uint8_t * ep)
}
}
}
- return (crc >> 26);
+ return (crc & BITS(7, 2)) >> 2;
}
#if defined(DEBUG_EEPRO100)
@@ -636,6 +636,8 @@ static void nic_reset(void *opaque)
{
EEPRO100State *s = opaque;
TRACE(OTHER, logout("%p\n", s));
+ /* TODO: Clearing of multicast table for selective reset, too? */
+ memset(&s->mult[0], 0, sizeof(s->mult));
nic_selective_reset(s);
}
@@ -755,7 +757,7 @@ static void dump_statistics(EEPRO100State * s)
static void tx_command(EEPRO100State *s)
{
- uint32_t tbd_array = le32_to_cpu(s->tx.tx_desc_addr);
+ uint32_t tbd_array = le32_to_cpu(s->tx.tbd_array_addr);
uint16_t tcb_bytes = (le16_to_cpu(s->tx.tcb_bytes) & 0x3fff);
/* Sends larger than MAX_ETH_FRAME_SIZE are allowed, up to 2600 bytes. */
uint8_t buf[2600];
@@ -837,6 +839,22 @@ static void tx_command(EEPRO100State *s)
//~ eepro100_cx_interrupt(s);
}
+static void set_multicast_list(EEPRO100State *s)
+{
+ uint16_t multicast_count = s->tx.tbd_array_addr & BITS(13, 0);
+ uint16_t i;
+ memset(&s->mult[0], 0, sizeof(s->mult));
+ TRACE(OTHER, logout("multicast list, multicast count = %u\n", multicast_count));
+ for (i = 0; i < multicast_count; i += 6) {
+ uint8_t multicast_addr[6];
+ cpu_physical_memory_read(s->cb_address + 10 + i, multicast_addr, 6);
+ TRACE(OTHER, logout("multicast entry %s\n", nic_dump(multicast_addr, 6)));
+ unsigned mcast_idx = compute_mcast_idx(multicast_addr);
+ assert(mcast_idx < 64);
+ s->mult[mcast_idx >> 3] |= (1 << (mcast_idx & 7));
+ }
+}
+
static void action_command(EEPRO100State *s)
{
for (;;) {
@@ -869,7 +887,7 @@ static void action_command(EEPRO100State *s)
TRACE(OTHER, logout("configuration: %s\n", nic_dump(&s->configuration[0], 16)));
break;
case CmdMulticastList:
- //~ missing("multicast list");
+ set_multicast_list(s);
break;
case CmdTx:
if (bit_nc) {
@@ -1652,17 +1670,25 @@ static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size
/* Broadcast frame. */
TRACE(RXTX, logout("%p received broadcast, len=%zu\n", s, size));
rfd_status |= 0x0002;
- } else if (buf[0] & 0x01) { // !!!
+ } else if (buf[0] & 0x01) {
/* Multicast frame. */
- TRACE(RXTX, logout("%p received multicast, len=%zu\n", s, size));
- /* TODO: check multicast all bit. */
+ TRACE(RXTX, logout("%p received multicast, len=%zu,%s\n", s, size, nic_dump(buf, size)));
if (s->configuration[21] & BIT(3)) {
- missing("Multicast All bit");
- }
- int mcast_idx = compute_mcast_idx(buf);
- if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) {
- return size;
+ /* Multicast all bit is set, receive all multicast frames. */
+ } else {
+ unsigned mcast_idx = compute_mcast_idx(buf);
+ assert(mcast_idx < 64);
+ if (s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))) {
+ /* Multicast frame is allowed in hash table. */
+ } else if (s->configuration[15] & 1) {
+ /* Promiscuous: receive all. */
+ rfd_status |= 0x0004;
+ } else {
+ TRACE(RXTX, logout("%p multicast ignored\n", s));
+ return -1;
+ }
}
+ /* TODO: Next not for promiscuous mode? */
rfd_status |= 0x0002;
} else if (s->configuration[15] & 1) {
/* Promiscuous: receive all. */
--
1.6.5
next prev parent reply other threads:[~2009-12-20 15:52 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-12-19 15:08 [Qemu-devel] eepro100.c patches Stefan Weil
2009-12-20 14:51 ` Anthony Liguori
2009-12-20 15:46 ` Stefan Weil
2009-12-20 15:52 ` [Qemu-devel] [PATCH 1/3] eepro100: Restructure code (new function tx_command) Stefan Weil
2009-12-20 15:52 ` [Qemu-devel] [PATCH 2/3] eepro100: Better documentation for temporary data Stefan Weil
2009-12-20 15:52 ` Stefan Weil [this message]
2009-12-20 16:23 ` Andreas Färber
2009-12-20 18:05 ` Stefan Weil
2010-01-14 11:19 ` [Qemu-devel] Re: [PATCH 1/3] eepro100: Restructure code (new function tx_command) Michael S. Tsirkin
2009-12-20 16:19 ` [Qemu-devel] eepro100.c patches Anthony Liguori
2010-01-05 21:28 ` Stefan Weil
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1261324344-10642-3-git-send-email-weil@mail.berlios.de \
--to=weil@mail.berlios.de \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).