summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Ted Green <tedgreen99@users.noreply.github.com>2019-01-08 12:39:03 -0700
committer Ted Green <tedgreen99@users.noreply.github.com>2019-01-08 12:40:08 -0700
commitac01e295c00e6a9631c22b4432484105ef7f706c (patch)
tree60c5f8786effd09e471d2a8fb4a8295596013a2a
parent7501d499aa17d692a3c65b788f1bc9a4b521a399 (diff)
smc91c9x: Added initial MAC filter and fixed multicast address filtering. WIP. (nw)
-rw-r--r--src/devices/machine/smc91c9x.cpp21
-rw-r--r--src/devices/machine/smc91c9x.h13
2 files changed, 25 insertions, 9 deletions
diff --git a/src/devices/machine/smc91c9x.cpp b/src/devices/machine/smc91c9x.cpp
index d3ac80003df..21fcb11d1f7 100644
--- a/src/devices/machine/smc91c9x.cpp
+++ b/src/devices/machine/smc91c9x.cpp
@@ -71,6 +71,7 @@ smc91c9x_device::smc91c9x_device(const machine_config &mconfig, device_type type
}
const u8 smc91c9x_device::ETH_BROADCAST[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+const u8 smc91c9x_device::WMS_OUI[] = { 0x00, 0xA0, 0xAF };
//-------------------------------------------------
// device_start - device-specific startup
@@ -338,15 +339,21 @@ int smc91c9x_device::address_filter(u8 *buf)
return ADDR_MULTICAST;
u32 const crc = util::crc32_creator::simple(buf, 6);
- m_rx_hash = (crc >> 26);
+ // The hash is based on the top 6 MSBs of the CRC
+ // The CRC needs to be inverted and reflected
+ m_rx_hash = 0x0;
+ for (int i = 0; i < 6; i++)
+ m_rx_hash |= (((~crc) >> i) & 1) << (5 - i);
u64 multicast_addr = *(u64*)&m_reg[B3_MT0_1];
- if (BIT(multicast_addr, 63 - m_rx_hash))
+ if (BIT(multicast_addr, m_rx_hash))
{
- LOGMASKED(LOG_FILTER, "address_filter accepted (logical address match) %02x-%02x-%02x-%02x-%02x-%02x\n",
+ LOGMASKED(LOG_FILTER, "address_filter accepted (multicast address match) %02x-%02x-%02x-%02x-%02x-%02x\n",
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
return ADDR_MULTICAST;
}
+ LOGMASKED(LOG_FILTER, "address_filter rejected multicast %02x-%02x-%02x-%02x-%02x-%02x crc: %08x hash: %02x multi: %16ullx\n",
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], crc, m_rx_hash, *(u64*)&m_reg[B3_MT0_1]);
}
else
{
@@ -385,6 +392,14 @@ int smc91c9x_device::recv_start_cb(u8 *buf, int length)
return 0;
}
+ // discard packets not from WMS
+ if (memcmp(WMS_OUI, &buf[6], 3))
+ {
+ LOGMASKED(LOG_RX, "received non-WMS packet OUI: %02x:%02x:%02x length %d discarded\n", buf[6], buf[7], buf[8], length);
+
+ return 0;
+ }
+
// Check for active transmission
if (m_tx_active)
{
diff --git a/src/devices/machine/smc91c9x.h b/src/devices/machine/smc91c9x.h
index c05f06d1a5e..51b520fe971 100644
--- a/src/devices/machine/smc91c9x.h
+++ b/src/devices/machine/smc91c9x.h
@@ -217,6 +217,7 @@ private:
static constexpr unsigned ETHER_BUFFER_SIZE = 256 * 6;
static const u8 ETH_BROADCAST[];
+ static const u8 WMS_OUI[];
// mmu
@@ -275,8 +276,8 @@ private:
void reset_queued_tx() { m_queued_tx_t = m_queued_tx_h = 0; };
void push_queued_tx(const u8 &data) { m_queued_tx[m_queued_tx_h++] = data; m_queued_tx_h &= FIFO_SIZE - 1; };
u8 pop_queued_tx() { u8 val = m_queued_tx[m_queued_tx_t++]; m_queued_tx_t &= FIFO_SIZE - 1; return val; };
- bool empty_queued_tx() { return m_queued_tx_h == m_queued_tx_t; };
- u8 curr_queued_tx() { return m_queued_tx[m_queued_tx_t]; };
+ bool empty_queued_tx() const { return m_queued_tx_h == m_queued_tx_t; };
+ u8 curr_queued_tx() const { return m_queued_tx[m_queued_tx_t]; };
// FIFO for completed transmit packets
u8 m_completed_tx[FIFO_SIZE];
@@ -284,8 +285,8 @@ private:
void reset_completed_tx() { m_completed_tx_t = m_completed_tx_h = 0; };
void push_completed_tx(const u8 &data) { m_completed_tx[m_completed_tx_h++] = data; m_completed_tx_h &= FIFO_SIZE - 1; };
u8 pop_completed_tx() { u8 val = m_completed_tx[m_completed_tx_t++]; m_completed_tx_t &= FIFO_SIZE - 1; return val; };
- bool empty_completed_tx() { return m_completed_tx_h == m_completed_tx_t; };
- u8 curr_completed_tx() { return m_completed_tx[m_completed_tx_t]; };
+ bool empty_completed_tx() const { return m_completed_tx_h == m_completed_tx_t; };
+ u8 curr_completed_tx() const { return m_completed_tx[m_completed_tx_t]; };
// FIFO for completed receive packets
u8 m_completed_rx[FIFO_SIZE];
@@ -293,8 +294,8 @@ private:
void reset_completed_rx() { m_completed_rx_t = m_completed_rx_h = 0; };
void push_completed_rx(const u8 &data) { m_completed_rx[m_completed_rx_h++] = data; m_completed_rx_h &= FIFO_SIZE - 1; };
u8 pop_completed_rx() { u8 val = m_completed_rx[m_completed_rx_t++]; m_completed_rx_t &= FIFO_SIZE - 1; return val; };
- bool empty_completed_rx() { return m_completed_rx_h == m_completed_rx_t; };
- u8 curr_completed_rx() { return m_completed_rx[m_completed_rx_t]; };
+ bool empty_completed_rx() const { return m_completed_rx_h == m_completed_rx_t; };
+ u8 curr_completed_rx() const { return m_completed_rx[m_completed_rx_t]; };
};