ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)

{

    NE2000State *s = qemu_get_nic_opaque(nc);

    int size = size_;

    uint8_t *p;

    unsigned int total_len, next, avail, len, index, mcast_idx;

    uint8_t buf1[60];

    static const uint8_t broadcast_macaddr[6] =

        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };



#if defined(DEBUG_NE2000)

    printf("NE2000: received len=%d\n", size);

#endif



    if (s->cmd & E8390_STOP || ne2000_buffer_full(s))

        return -1;



    /* XXX: check this */

    if (s->rxcr & 0x10) {

        /* promiscuous: receive all */

    } else {

        if (!memcmp(buf,  broadcast_macaddr, 6)) {

            /* broadcast address */

            if (!(s->rxcr & 0x04))

                return size;

        } else if (buf[0] & 0x01) {

            /* multicast */

            if (!(s->rxcr & 0x08))

                return size;

            mcast_idx = compute_mcast_idx(buf);

            if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))

                return size;

        } else if (s->mem[0] == buf[0] &&

                   s->mem[2] == buf[1] &&

                   s->mem[4] == buf[2] &&

                   s->mem[6] == buf[3] &&

                   s->mem[8] == buf[4] &&

                   s->mem[10] == buf[5]) {

            /* match */

        } else {

            return size;

        }

    }





    /* if too small buffer, then expand it */

    if (size < MIN_BUF_SIZE) {

        memcpy(buf1, buf, size);

        memset(buf1 + size, 0, MIN_BUF_SIZE - size);

        buf = buf1;

        size = MIN_BUF_SIZE;

    }



    index = s->curpag << 8;

    if (index >= NE2000_PMEM_END) {

        index = s->start;

    }

    /* 4 bytes for header */

    total_len = size + 4;

    /* address for next packet (4 bytes for CRC) */

    next = index + ((total_len + 4 + 255) & ~0xff);

    if (next >= s->stop)

        next -= (s->stop - s->start);

    /* prepare packet header */

    p = s->mem + index;

    s->rsr = ENRSR_RXOK; /* receive status */

    /* XXX: check this */

    if (buf[0] & 0x01)

        s->rsr |= ENRSR_PHY;

    p[0] = s->rsr;

    p[1] = next >> 8;

    p[2] = total_len;

    p[3] = total_len >> 8;

    index += 4;



    /* write packet data */

    while (size > 0) {

        if (index <= s->stop)

            avail = s->stop - index;

        else

            avail = 0;

        len = size;

        if (len > avail)

            len = avail;

        memcpy(s->mem + index, buf, len);

        buf += len;

        index += len;

        if (index == s->stop)

            index = s->start;

        size -= len;

    }

    s->curpag = next >> 8;



    /* now we can signal we have received something */

    s->isr |= ENISR_RX;

    ne2000_update_irq(s);



    return size_;

}

ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)

{

    NE2000State *s = qemu_get_nic_opaque(nc);

    int size = size_;

    uint8_t *p;

    unsigned int total_len, next, avail, len, index, mcast_idx;

    uint8_t buf1[60];

    static const uint8_t broadcast_macaddr[6] =

        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };



#if defined(DEBUG_NE2000)

    printf("NE2000: received len=%d\n", size);

#endif



    if (s->cmd & E8390_STOP || ne2000_buffer_full(s))

        return -1;



    

    if (s->rxcr & 0x10) {

        

    } else {

        if (!memcmp(buf,  broadcast_macaddr, 6)) {

            

            if (!(s->rxcr & 0x04))

                return size;

        } else if (buf[0] & 0x01) {

            

            if (!(s->rxcr & 0x08))

                return size;

            mcast_idx = compute_mcast_idx(buf);

            if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))

                return size;

        } else if (s->mem[0] == buf[0] &&

                   s->mem[2] == buf[1] &&

                   s->mem[4] == buf[2] &&

                   s->mem[6] == buf[3] &&

                   s->mem[8] == buf[4] &&

                   s->mem[10] == buf[5]) {

            

        } else {

            return size;

        }

    }





    

    if (size < MIN_BUF_SIZE) {

        memcpy(buf1, buf, size);

        memset(buf1 + size, 0, MIN_BUF_SIZE - size);

        buf = buf1;

        size = MIN_BUF_SIZE;

    }



    index = s->curpag << 8;

    if (index >= NE2000_PMEM_END) {

        index = s->start;

    }

    

    total_len = size + 4;

    

    next = index + ((total_len + 4 + 255) & ~0xff);

    if (next >= s->stop)

        next -= (s->stop - s->start);

    

    p = s->mem + index;

    s->rsr = ENRSR_RXOK; 

    

    if (buf[0] & 0x01)

        s->rsr |= ENRSR_PHY;

    p[0] = s->rsr;

    p[1] = next >> 8;

    p[2] = total_len;

    p[3] = total_len >> 8;

    index += 4;



    

    while (size > 0) {

        if (index <= s->stop)

            avail = s->stop - index;

        else

            avail = 0;

        len = size;

        if (len > avail)

            len = avail;

        memcpy(s->mem + index, buf, len);

        buf += len;

        index += len;

        if (index == s->stop)

            index = s->start;

        size -= len;

    }

    s->curpag = next >> 8;



    

    s->isr |= ENISR_RX;

    ne2000_update_irq(s);



    return size_;

}

            avail = 0;
ssize_t FUNC_0(NetClientState *nc, const uint8_t *buf, size_t size_)

{

    NE2000State *s = qemu_get_nic_opaque(nc);

    int VAR_0 = size_;

    uint8_t *p;

    unsigned int VAR_1, VAR_2, VAR_3, VAR_4, VAR_5, VAR_6;

    uint8_t buf1[60];

    static const uint8_t VAR_7[6] =

        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };



#if defined(DEBUG_NE2000)

    printf("NE2000: received VAR_4=%d\n", VAR_0);

#endif



    if (s->cmd & E8390_STOP || ne2000_buffer_full(s))

        return -1;



    

    if (s->rxcr & 0x10) {

        

    } else {

        if (!memcmp(buf,  VAR_7, 6)) {

            

            if (!(s->rxcr & 0x04))

                return VAR_0;

        } else if (buf[0] & 0x01) {

            

            if (!(s->rxcr & 0x08))

                return VAR_0;

            VAR_6 = compute_mcast_idx(buf);

            if (!(s->mult[VAR_6 >> 3] & (1 << (VAR_6 & 7))))

                return VAR_0;

        } else if (s->mem[0] == buf[0] &&

                   s->mem[2] == buf[1] &&

                   s->mem[4] == buf[2] &&

                   s->mem[6] == buf[3] &&

                   s->mem[8] == buf[4] &&

                   s->mem[10] == buf[5]) {

            

        } else {

            return VAR_0;

        }

    }





    

    if (VAR_0 < MIN_BUF_SIZE) {

        memcpy(buf1, buf, VAR_0);

        memset(buf1 + VAR_0, 0, MIN_BUF_SIZE - VAR_0);

        buf = buf1;

        VAR_0 = MIN_BUF_SIZE;

    }



    VAR_5 = s->curpag << 8;

    if (VAR_5 >= NE2000_PMEM_END) {

        VAR_5 = s->start;

    }

    

    VAR_1 = VAR_0 + 4;

    

    VAR_2 = VAR_5 + ((VAR_1 + 4 + 255) & ~0xff);

    if (VAR_2 >= s->stop)

        VAR_2 -= (s->stop - s->start);

    

    p = s->mem + VAR_5;

    s->rsr = ENRSR_RXOK; 

    

    if (buf[0] & 0x01)

        s->rsr |= ENRSR_PHY;

    p[0] = s->rsr;

    p[1] = VAR_2 >> 8;

    p[2] = VAR_1;

    p[3] = VAR_1 >> 8;

    VAR_5 += 4;



    

    while (VAR_0 > 0) {

        if (VAR_5 <= s->stop)

            VAR_3 = s->stop - VAR_5;

        else

            VAR_3 = 0;

        VAR_4 = VAR_0;

        if (VAR_4 > VAR_3)

            VAR_4 = VAR_3;

        memcpy(s->mem + VAR_5, buf, VAR_4);

        buf += VAR_4;

        VAR_5 += VAR_4;

        if (VAR_5 == s->stop)

            VAR_5 = s->start;

        VAR_0 -= VAR_4;

    }

    s->curpag = VAR_2 >> 8;



    

    s->isr |= ENISR_RX;

    ne2000_update_irq(s);



    return size_;

}

ssize_t FUNC_0(NetClientState *nc, const uint8_t *buf, size_t size_)
{ NE2000State *s = qemu_get_nic_opaque(nc); int VAR_0 = size_; uint8_t *p; unsigned int VAR_1, VAR_2, VAR_3, VAR_4, VAR_5, VAR_6; uint8_t buf1[60]; static const uint8_t VAR_7[6] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; #if defined(DEBUG_NE2000)
printf("NE2000: received VAR_4=%d\n", VAR_0); #endif
if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
return -1; if (s->rxcr & 0x10) { } else { if (!memcmp(buf,  VAR_7, 6)) { if (!(s->rxcr & 0x04))
return VAR_0; } else if (buf[0] & 0x01) { if (!(s->rxcr & 0x08))
return VAR_0; VAR_6 = compute_mcast_idx(buf); if (!(s->mult[VAR_6 >> 3] & (1 << (VAR_6 & 7))))
return VAR_0; } else if (s->mem[0] == buf[0] && s->mem[2] == buf[1] &&
s->mem[4] == buf[2] &&
s->mem[6] == buf[3] &&
s->mem[8] == buf[4] &&
s->mem[10] == buf[5]) { } else { return VAR_0; } } if (VAR_0 < MIN_BUF_SIZE) { memcpy(buf1, buf, VAR_0); memset(buf1 + VAR_0, 0, MIN_BUF_SIZE - VAR_0); buf = buf1; VAR_0 = MIN_BUF_SIZE; } VAR_5 = s->curpag << 8; if (VAR_5 >= NE2000_PMEM_END) { VAR_5 = s->start; } VAR_1 = VAR_0 + 4; VAR_2 = VAR_5 + ((VAR_1 + 4 + 255) & ~0xff); if (VAR_2 >= s->stop)
VAR_2 -= (s->stop - s->start); p = s->mem + VAR_5; s->rsr = ENRSR_RXOK; if (buf[0] & 0x01)
s->rsr |= ENRSR_PHY; p[0] = s->rsr; p[1] = VAR_2 >> 8; p[2] = VAR_1; p[3] = VAR_1 >> 8; VAR_5 += 4; while (VAR_0 > 0) { if (VAR_5 <= s->stop)
VAR_3 = s->stop - VAR_5; else
VAR_3 = 0; VAR_4 = VAR_0; if (VAR_4 > VAR_3)
VAR_4 = VAR_3; memcpy(s->mem + VAR_5, buf, VAR_4); buf += VAR_4; VAR_5 += VAR_4; if (VAR_5 == s->stop)
VAR_5 = s->start; VAR_0 -= VAR_4; } s->curpag = VAR_2 >> 8; s->isr |= ENISR_RX; ne2000_update_irq(s); return size_; }