static void mcf_fec_receive(void *opaque, const uint8_t *buf, size_t size)

{

    mcf_fec_state *s = (mcf_fec_state *)opaque;

    mcf_fec_bd bd;

    uint32_t flags = 0;

    uint32_t addr;

    uint32_t crc;

    uint32_t buf_addr;

    uint8_t *crc_ptr;

    unsigned int buf_len;



    DPRINTF("do_rx len %d\n", size);

    if (!s->rx_enabled) {

        fprintf(stderr, "mcf_fec_receive: Unexpected packet\n");

    }

    /* 4 bytes for the CRC.  */

    size += 4;

    crc = cpu_to_be32(crc32(~0, buf, size));

    crc_ptr = (uint8_t *)&crc;

    /* Huge frames are truncted.  */

    if (size > FEC_MAX_FRAME_SIZE) {

        size = FEC_MAX_FRAME_SIZE;

        flags |= FEC_BD_TR | FEC_BD_LG;

    }

    /* Frames larger than the user limit just set error flags.  */

    if (size > (s->rcr >> 16)) {

        flags |= FEC_BD_LG;

    }

    addr = s->rx_descriptor;

    while (size > 0) {

        mcf_fec_read_bd(&bd, addr);

        if ((bd.flags & FEC_BD_E) == 0) {

            /* No descriptors available.  Bail out.  */

            /* FIXME: This is wrong.  We should probably either save the

               remainder for when more RX buffers are available, or

               flag an error.  */

            fprintf(stderr, "mcf_fec: Lost end of frame\n");

            break;

        }

        buf_len = (size <= s->emrbr) ? size: s->emrbr;

        bd.length = buf_len;

        size -= buf_len;

        DPRINTF("rx_bd %x length %d\n", addr, bd.length);

        /* The last 4 bytes are the CRC.  */

        if (size < 4)

            buf_len += size - 4;

        buf_addr = bd.data;

        cpu_physical_memory_write(buf_addr, buf, buf_len);

        buf += buf_len;

        if (size < 4) {

            cpu_physical_memory_write(buf_addr + buf_len, crc_ptr, 4 - size);

            crc_ptr += 4 - size;

        }

        bd.flags &= ~FEC_BD_E;

        if (size == 0) {

            /* Last buffer in frame.  */

            bd.flags |= flags | FEC_BD_L;

            DPRINTF("rx frame flags %04x\n", bd.flags);

            s->eir |= FEC_INT_RXF;

        } else {

            s->eir |= FEC_INT_RXB;

        }

        mcf_fec_write_bd(&bd, addr);

        /* Advance to the next descriptor.  */

        if ((bd.flags & FEC_BD_W) != 0) {

            addr = s->erdsr;

        } else {

            addr += 8;

        }

    }

    s->rx_descriptor = addr;

    mcf_fec_enable_rx(s);

    mcf_fec_update(s);

}

static void mcf_fec_receive(void *opaque, const uint8_t *buf, size_t size)

{

    mcf_fec_state *s = (mcf_fec_state *)opaque;

    mcf_fec_bd bd;

    uint32_t flags = 0;

    uint32_t addr;

    uint32_t crc;

    uint32_t buf_addr;

    uint8_t *crc_ptr;

    unsigned int buf_len;



    DPRINTF("do_rx len %d\n", size);

    if (!s->rx_enabled) {

        fprintf(stderr, "mcf_fec_receive: Unexpected packet\n");

    }

    

    size += 4;

    crc = cpu_to_be32(crc32(~0, buf, size));

    crc_ptr = (uint8_t *)&crc;

    

    if (size > FEC_MAX_FRAME_SIZE) {

        size = FEC_MAX_FRAME_SIZE;

        flags |= FEC_BD_TR | FEC_BD_LG;

    }

    

    if (size > (s->rcr >> 16)) {

        flags |= FEC_BD_LG;

    }

    addr = s->rx_descriptor;

    while (size > 0) {

        mcf_fec_read_bd(&bd, addr);

        if ((bd.flags & FEC_BD_E) == 0) {

            

            





            fprintf(stderr, "mcf_fec: Lost end of frame\n");

            break;

        }

        buf_len = (size <= s->emrbr) ? size: s->emrbr;

        bd.length = buf_len;

        size -= buf_len;

        DPRINTF("rx_bd %x length %d\n", addr, bd.length);

        

        if (size < 4)

            buf_len += size - 4;

        buf_addr = bd.data;

        cpu_physical_memory_write(buf_addr, buf, buf_len);

        buf += buf_len;

        if (size < 4) {

            cpu_physical_memory_write(buf_addr + buf_len, crc_ptr, 4 - size);

            crc_ptr += 4 - size;

        }

        bd.flags &= ~FEC_BD_E;

        if (size == 0) {

            

            bd.flags |= flags | FEC_BD_L;

            DPRINTF("rx frame flags %04x\n", bd.flags);

            s->eir |= FEC_INT_RXF;

        } else {

            s->eir |= FEC_INT_RXB;

        }

        mcf_fec_write_bd(&bd, addr);

        

        if ((bd.flags & FEC_BD_W) != 0) {

            addr = s->erdsr;

        } else {

            addr += 8;

        }

    }

    s->rx_descriptor = addr;

    mcf_fec_enable_rx(s);

    mcf_fec_update(s);

}

static void FUNC_0(void *VAR_0, const uint8_t *VAR_1, size_t VAR_2)

{

    mcf_fec_state *s = (mcf_fec_state *)VAR_0;

    mcf_fec_bd bd;

    uint32_t flags = 0;

    uint32_t addr;

    uint32_t crc;

    uint32_t buf_addr;

    uint8_t *crc_ptr;

    unsigned int VAR_3;



    DPRINTF("do_rx len %d\n", VAR_2);

    if (!s->rx_enabled) {

        fprintf(stderr, "FUNC_0: Unexpected packet\n");

    }

    

    VAR_2 += 4;

    crc = cpu_to_be32(crc32(~0, VAR_1, VAR_2));

    crc_ptr = (uint8_t *)&crc;

    

    if (VAR_2 > FEC_MAX_FRAME_SIZE) {

        VAR_2 = FEC_MAX_FRAME_SIZE;

        flags |= FEC_BD_TR | FEC_BD_LG;

    }

    

    if (VAR_2 > (s->rcr >> 16)) {

        flags |= FEC_BD_LG;

    }

    addr = s->rx_descriptor;

    while (VAR_2 > 0) {

        mcf_fec_read_bd(&bd, addr);

        if ((bd.flags & FEC_BD_E) == 0) {

            

            





            fprintf(stderr, "mcf_fec: Lost end of frame\n");

            break;

        }

        VAR_3 = (VAR_2 <= s->emrbr) ? VAR_2: s->emrbr;

        bd.length = VAR_3;

        VAR_2 -= VAR_3;

        DPRINTF("rx_bd %x length %d\n", addr, bd.length);

        

        if (VAR_2 < 4)

            VAR_3 += VAR_2 - 4;

        buf_addr = bd.data;

        cpu_physical_memory_write(buf_addr, VAR_1, VAR_3);

        VAR_1 += VAR_3;

        if (VAR_2 < 4) {

            cpu_physical_memory_write(buf_addr + VAR_3, crc_ptr, 4 - VAR_2);

            crc_ptr += 4 - VAR_2;

        }

        bd.flags &= ~FEC_BD_E;

        if (VAR_2 == 0) {

            

            bd.flags |= flags | FEC_BD_L;

            DPRINTF("rx frame flags %04x\n", bd.flags);

            s->eir |= FEC_INT_RXF;

        } else {

            s->eir |= FEC_INT_RXB;

        }

        mcf_fec_write_bd(&bd, addr);

        

        if ((bd.flags & FEC_BD_W) != 0) {

            addr = s->erdsr;

        } else {

            addr += 8;

        }

    }

    s->rx_descriptor = addr;

    mcf_fec_enable_rx(s);

    mcf_fec_update(s);

}

static void FUNC_0(void *VAR_0, const uint8_t *VAR_1, size_t VAR_2)
{ mcf_fec_state *s = (mcf_fec_state *)VAR_0; mcf_fec_bd bd; uint32_t flags = 0; uint32_t addr; uint32_t crc; uint32_t buf_addr; uint8_t *crc_ptr; unsigned int VAR_3; DPRINTF("do_rx len %d\n", VAR_2); if (!s->rx_enabled) { fprintf(stderr, "FUNC_0: Unexpected packet\n"); } VAR_2 += 4; crc = cpu_to_be32(crc32(~0, VAR_1, VAR_2)); crc_ptr = (uint8_t *)&crc; if (VAR_2 > FEC_MAX_FRAME_SIZE) { VAR_2 = FEC_MAX_FRAME_SIZE; flags |= FEC_BD_TR | FEC_BD_LG; } if (VAR_2 > (s->rcr >> 16)) { flags |= FEC_BD_LG; } addr = s->rx_descriptor; while (VAR_2 > 0) { mcf_fec_read_bd(&bd, addr); if ((bd.flags & FEC_BD_E) == 0) { fprintf(stderr, "mcf_fec: Lost end of frame\n"); break; } VAR_3 = (VAR_2 <= s->emrbr) ? VAR_2: s->emrbr; bd.length = VAR_3; VAR_2 -= VAR_3; DPRINTF("rx_bd %x length %d\n", addr, bd.length); if (VAR_2 < 4)
VAR_3 += VAR_2 - 4; buf_addr = bd.data; cpu_physical_memory_write(buf_addr, VAR_1, VAR_3); VAR_1 += VAR_3; if (VAR_2 < 4) { cpu_physical_memory_write(buf_addr + VAR_3, crc_ptr, 4 - VAR_2); crc_ptr += 4 - VAR_2; } bd.flags &= ~FEC_BD_E; if (VAR_2 == 0) { bd.flags |= flags | FEC_BD_L; DPRINTF("rx frame flags %04x\n", bd.flags); s->eir |= FEC_INT_RXF; } else { s->eir |= FEC_INT_RXB; } mcf_fec_write_bd(&bd, addr); if ((bd.flags & FEC_BD_W) != 0) { addr = s->erdsr; } else { addr += 8; } } s->rx_descriptor = addr; mcf_fec_enable_rx(s); mcf_fec_update(s); }