Revision 010ec629

b/hw/eepro100.c
219 219

  
220 220
typedef struct {
221 221
    PCIDevice dev;
222
    uint8_t mult[8];            /* multicast mask array */
222
    /* Hash register (multicast mask array, multiple individual addresses). */
223
    uint8_t mult[8];
223 224
    int mmio_index;
224 225
    NICState *nic;
225 226
    NICConf conf;
......
599 600
{
600 601
    EEPRO100State *s = opaque;
601 602
    TRACE(OTHER, logout("%p\n", s));
602
    /* TODO: Clearing of multicast table for selective reset, too? */
603
    /* TODO: Clearing of hash register for selective reset, too? */
603 604
    memset(&s->mult[0], 0, sizeof(s->mult));
604 605
    nic_selective_reset(s);
605 606
}
......
851 852
        case CmdConfigure:
852 853
            cpu_physical_memory_read(s->cb_address + 8, &s->configuration[0],
853 854
                                     sizeof(s->configuration));
854
            TRACE(OTHER, logout("configuration: %s\n", nic_dump(&s->configuration[0], 16)));
855
            TRACE(OTHER, logout("configuration: %s\n",
856
                                nic_dump(&s->configuration[0], 16)));
857
            TRACE(OTHER, logout("configuration: %s\n",
858
                                nic_dump(&s->configuration[16],
859
                                ARRAY_SIZE(s->configuration) - 16)));
860
            if (s->configuration[20] & BIT(6)) {
861
                TRACE(OTHER, logout("Multiple IA bit\n"));
862
            }
855 863
            break;
856 864
        case CmdMulticastList:
857 865
            set_multicast_list(s);
......
1647 1655
    static const uint8_t broadcast_macaddr[6] =
1648 1656
        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1649 1657

  
1650
    /* TODO: check multiple IA bit. */
1651
    if (s->configuration[20] & BIT(6)) {
1652
        missing("Multiple IA bit");
1653
        return -1;
1654
    }
1655

  
1656 1658
    if (s->configuration[8] & 0x80) {
1657 1659
        /* CSMA is disabled. */
1658 1660
        logout("%p received while CSMA is disabled\n", s);
......
1702 1704
        /* Promiscuous: receive all. */
1703 1705
        TRACE(RXTX, logout("%p received frame in promiscuous mode, len=%zu\n", s, size));
1704 1706
        rfd_status |= 0x0004;
1707
    } else if (s->configuration[20] & BIT(6)) {
1708
        /* Multiple IA bit set. */
1709
        unsigned mcast_idx = compute_mcast_idx(buf);
1710
        assert(mcast_idx < 64);
1711
        if (s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))) {
1712
            TRACE(RXTX, logout("%p accepted, multiple IA bit set\n", s));
1713
        } else {
1714
            TRACE(RXTX, logout("%p frame ignored, multiple IA bit set\n", s));
1715
            return -1;
1716
        }
1705 1717
    } else {
1706 1718
        TRACE(RXTX, logout("%p received frame, ignored, len=%zu,%s\n", s, size,
1707 1719
              nic_dump(buf, size)));

Also available in: Unified diff