smc91c9x: Added initial MAC filter and fixed multicast address filtering. WIP. (nw)

This commit is contained in:
Ted Green 2019-01-08 12:39:03 -07:00
parent 7501d499aa
commit ac01e295c0
2 changed files with 25 additions and 9 deletions

View File

@ -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)
{

View File

@ -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]; };
};