Revision 7c9d8e07 hw/ne2000.c

b/hw/ne2000.c
122 122
    uint16_t rcnt;
123 123
    uint32_t rsar;
124 124
    uint8_t rsr;
125
    uint8_t rxcr;
125 126
    uint8_t isr;
126 127
    uint8_t dcfg;
127 128
    uint8_t imr;
......
130 131
    uint8_t mult[8]; /* multicast mask array */
131 132
    int irq;
132 133
    PCIDevice *pci_dev;
133
    NetDriverState *nd;
134
    VLANClientState *vc;
135
    uint8_t macaddr[6];
134 136
    uint8_t mem[NE2000_MEM_SIZE];
135 137
} NE2000State;
136 138

  
......
139 141
    int i;
140 142

  
141 143
    s->isr = ENISR_RESET;
142
    memcpy(s->mem, s->nd->macaddr, 6);
144
    memcpy(s->mem, s->macaddr, 6);
143 145
    s->mem[14] = 0x57;
144 146
    s->mem[15] = 0x57;
145 147

  
......
167 169
    }
168 170
}
169 171

  
172
#define POLYNOMIAL 0x04c11db6
173

  
174
/* From FreeBSD */
175
/* XXX: optimize */
176
static int compute_mcast_idx(const uint8_t *ep)
177
{
178
    uint32_t crc;
179
    int carry, i, j;
180
    uint8_t b;
181

  
182
    crc = 0xffffffff;
183
    for (i = 0; i < 6; i++) {
184
        b = *ep++;
185
        for (j = 0; j < 8; j++) {
186
            carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
187
            crc <<= 1;
188
            b >>= 1;
189
            if (carry)
190
                crc = ((crc ^ POLYNOMIAL) | carry);
191
        }
192
    }
193
    return (crc >> 26);
194
}
195

  
170 196
/* return the max buffer size if the NE2000 can receive more data */
171 197
static int ne2000_can_receive(void *opaque)
172 198
{
......
192 218
{
193 219
    NE2000State *s = opaque;
194 220
    uint8_t *p;
195
    int total_len, next, avail, len, index;
221
    int total_len, next, avail, len, index, mcast_idx;
196 222
    uint8_t buf1[60];
223
    static const uint8_t broadcast_macaddr[6] = 
224
        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
197 225
    
198 226
#if defined(DEBUG_NE2000)
199 227
    printf("NE2000: received len=%d\n", size);
200 228
#endif
201 229

  
230
    if (!ne2000_can_receive(s))
231
        return;
232
    
233
    /* XXX: check this */
234
    if (s->rxcr & 0x10) {
235
        /* promiscuous: receive all */
236
    } else {
237
        if (!memcmp(buf,  broadcast_macaddr, 6)) {
238
            /* broadcast address */
239
            if (!(s->rxcr & 0x04))
240
                return;
241
        } else if (buf[0] & 0x01) {
242
            /* multicast */
243
            if (!(s->rxcr & 0x08))
244
                return;
245
            mcast_idx = compute_mcast_idx(buf);
246
            if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
247
                return;
248
        } else if (s->mem[0] == buf[0] &&
249
                   s->mem[2] == buf[1] &&                   
250
                   s->mem[4] == buf[2] &&            
251
                   s->mem[6] == buf[3] &&            
252
                   s->mem[8] == buf[4] &&            
253
                   s->mem[10] == buf[5]) {
254
            /* match */
255
        } else {
256
            return;
257
        }
258
    }
259

  
260

  
202 261
    /* if too small buffer, then expand it */
203 262
    if (size < MIN_BUF_SIZE) {
204 263
        memcpy(buf1, buf, size);
......
273 332
                    index -= NE2000_PMEM_SIZE;
274 333
                /* fail safe: check range on the transmitted length  */
275 334
                if (index + s->tcnt <= NE2000_PMEM_END) {
276
                    qemu_send_packet(s->nd, s->mem + index, s->tcnt);
335
                    qemu_send_packet(s->vc, s->mem + index, s->tcnt);
277 336
                }
278 337
                /* signal end of transfert */
279 338
                s->tsr = ENTSR_PTX;
......
320 379
        case EN0_RCNTHI:
321 380
            s->rcnt = (s->rcnt & 0x00ff) | (val << 8);
322 381
            break;
382
        case EN0_RXCR:
383
            s->rxcr = val;
384
            break;
323 385
        case EN0_DCFG:
324 386
            s->dcfg = val;
325 387
            break;
......
608 670
	return 0;
609 671
}
610 672

  
611
void isa_ne2000_init(int base, int irq, NetDriverState *nd)
673
void isa_ne2000_init(int base, int irq, NICInfo *nd)
612 674
{
613 675
    NE2000State *s;
614

  
676
    
615 677
    s = qemu_mallocz(sizeof(NE2000State));
616 678
    if (!s)
617 679
        return;
......
627 689
    register_ioport_write(base + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
628 690
    register_ioport_read(base + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
629 691
    s->irq = irq;
630
    s->nd = nd;
692
    memcpy(s->macaddr, nd->macaddr, 6);
631 693

  
632 694
    ne2000_reset(s);
633 695

  
634
    qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s);
635

  
696
    s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, s);
697

  
698
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
699
             "ne2000 macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
700
             s->macaddr[0],
701
             s->macaddr[1],
702
             s->macaddr[2],
703
             s->macaddr[3],
704
             s->macaddr[4],
705
             s->macaddr[5]);
706
             
636 707
    register_savevm("ne2000", 0, 1, ne2000_save, ne2000_load, s);
637

  
638 708
}
639 709

  
640 710
/***********************************************************/
......
665 735
    register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
666 736
}
667 737

  
668
void pci_ne2000_init(PCIBus *bus, NetDriverState *nd)
738
void pci_ne2000_init(PCIBus *bus, NICInfo *nd)
669 739
{
670 740
    PCINE2000State *d;
671 741
    NE2000State *s;
......
690 760
    s = &d->ne2000;
691 761
    s->irq = 16; // PCI interrupt
692 762
    s->pci_dev = (PCIDevice *)d;
693
    s->nd = nd;
763
    memcpy(s->macaddr, nd->macaddr, 6);
694 764
    ne2000_reset(s);
695
    qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s);
696

  
765
    s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, s);
766

  
767
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
768
             "ne2000 pci macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
769
             s->macaddr[0],
770
             s->macaddr[1],
771
             s->macaddr[2],
772
             s->macaddr[3],
773
             s->macaddr[4],
774
             s->macaddr[5]);
775
             
697 776
    /* XXX: instance number ? */
698 777
    register_savevm("ne2000", 0, 1, ne2000_save, ne2000_load, s);
699 778
    register_savevm("ne2000_pci", 0, 1, generic_pci_save, generic_pci_load, 

Also available in: Unified diff