static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,

                               size_t len)

{

    IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));

    IMXFECBufDesc bd;

    uint32_t flags = 0;

    uint32_t addr;

    uint32_t crc;

    uint32_t buf_addr;

    uint8_t *crc_ptr;

    unsigned int buf_len;

    size_t size = len;



    FEC_PRINTF("len %d\n", (int)size);



    if (!s->regs[ENET_RDAR]) {

        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Unexpected packet\n",

                      TYPE_IMX_FEC, __func__);

        return 0;

    }



    /* 4 bytes for the CRC.  */

    size += 4;

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

    crc_ptr = (uint8_t *) &crc;



    /* Huge frames are truncated.  */

    if (size > ENET_MAX_FRAME_SIZE) {

        size = ENET_MAX_FRAME_SIZE;

        flags |= ENET_BD_TR | ENET_BD_LG;

    }



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

    if (size > (s->regs[ENET_RCR] >> 16)) {

        flags |= ENET_BD_LG;

    }



    addr = s->rx_descriptor;

    while (size > 0) {

        imx_fec_read_bd(&bd, addr);

        if ((bd.flags & ENET_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.

             */

            qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Lost end of frame\n",

                          TYPE_IMX_FEC, __func__);

            break;

        }

        buf_len = (size <= s->regs[ENET_MRBR]) ? size : s->regs[ENET_MRBR];

        bd.length = buf_len;

        size -= buf_len;



        FEC_PRINTF("rx_bd 0x%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;

        dma_memory_write(&address_space_memory, buf_addr, buf, buf_len);

        buf += buf_len;

        if (size < 4) {

            dma_memory_write(&address_space_memory, buf_addr + buf_len,

                             crc_ptr, 4 - size);

            crc_ptr += 4 - size;

        }

        bd.flags &= ~ENET_BD_E;

        if (size == 0) {

            /* Last buffer in frame.  */

            bd.flags |= flags | ENET_BD_L;

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

            s->regs[ENET_EIR] |= ENET_INT_RXF;

        } else {

            s->regs[ENET_EIR] |= ENET_INT_RXB;

        }

        imx_fec_write_bd(&bd, addr);

        /* Advance to the next descriptor.  */

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

            addr = s->regs[ENET_RDSR];

        } else {

            addr += sizeof(bd);

        }

    }

    s->rx_descriptor = addr;

    imx_eth_enable_rx(s);

    imx_eth_update(s);

    return len;

}

static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,

                               size_t len)

{

    IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));

    IMXFECBufDesc bd;

    uint32_t flags = 0;

    uint32_t addr;

    uint32_t crc;

    uint32_t buf_addr;

    uint8_t *crc_ptr;

    unsigned int buf_len;

    size_t size = len;



    FEC_PRINTF("len %d\n", (int)size);



    if (!s->regs[ENET_RDAR]) {

        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Unexpected packet\n",

                      TYPE_IMX_FEC, __func__);

        return 0;

    }



    

    size += 4;

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

    crc_ptr = (uint8_t *) &crc;



    

    if (size > ENET_MAX_FRAME_SIZE) {

        size = ENET_MAX_FRAME_SIZE;

        flags |= ENET_BD_TR | ENET_BD_LG;

    }



    

    if (size > (s->regs[ENET_RCR] >> 16)) {

        flags |= ENET_BD_LG;

    }



    addr = s->rx_descriptor;

    while (size > 0) {

        imx_fec_read_bd(&bd, addr);

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

            

            









            qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Lost end of frame\n",

                          TYPE_IMX_FEC, __func__);

            break;

        }

        buf_len = (size <= s->regs[ENET_MRBR]) ? size : s->regs[ENET_MRBR];

        bd.length = buf_len;

        size -= buf_len;



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



        

        if (size < 4) {

            buf_len += size - 4;

        }

        buf_addr = bd.data;

        dma_memory_write(&address_space_memory, buf_addr, buf, buf_len);

        buf += buf_len;

        if (size < 4) {

            dma_memory_write(&address_space_memory, buf_addr + buf_len,

                             crc_ptr, 4 - size);

            crc_ptr += 4 - size;

        }

        bd.flags &= ~ENET_BD_E;

        if (size == 0) {

            

            bd.flags |= flags | ENET_BD_L;

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

            s->regs[ENET_EIR] |= ENET_INT_RXF;

        } else {

            s->regs[ENET_EIR] |= ENET_INT_RXB;

        }

        imx_fec_write_bd(&bd, addr);

        

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

            addr = s->regs[ENET_RDSR];

        } else {

            addr += sizeof(bd);

        }

    }

    s->rx_descriptor = addr;

    imx_eth_enable_rx(s);

    imx_eth_update(s);

    return len;

}

    imx_eth_enable_rx(s);     imx_eth_enable_rx(s);
static ssize_t FUNC_0(NetClientState *nc, const uint8_t *buf,

                               size_t len)

{

    IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));

    IMXFECBufDesc bd;

    uint32_t flags = 0;

    uint32_t addr;

    uint32_t crc;

    uint32_t buf_addr;

    uint8_t *crc_ptr;

    unsigned int VAR_0;

    size_t size = len;



    FEC_PRINTF("len %d\n", (int)size);



    if (!s->regs[ENET_RDAR]) {

        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Unexpected packet\n",

                      TYPE_IMX_FEC, __func__);

        return 0;

    }



    

    size += 4;

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

    crc_ptr = (uint8_t *) &crc;



    

    if (size > ENET_MAX_FRAME_SIZE) {

        size = ENET_MAX_FRAME_SIZE;

        flags |= ENET_BD_TR | ENET_BD_LG;

    }



    

    if (size > (s->regs[ENET_RCR] >> 16)) {

        flags |= ENET_BD_LG;

    }



    addr = s->rx_descriptor;

    while (size > 0) {

        imx_fec_read_bd(&bd, addr);

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

            

            









            qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Lost end of frame\n",

                          TYPE_IMX_FEC, __func__);

            break;

        }

        VAR_0 = (size <= s->regs[ENET_MRBR]) ? size : s->regs[ENET_MRBR];

        bd.length = VAR_0;

        size -= VAR_0;



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



        

        if (size < 4) {

            VAR_0 += size - 4;

        }

        buf_addr = bd.data;

        dma_memory_write(&address_space_memory, buf_addr, buf, VAR_0);

        buf += VAR_0;

        if (size < 4) {

            dma_memory_write(&address_space_memory, buf_addr + VAR_0,

                             crc_ptr, 4 - size);

            crc_ptr += 4 - size;

        }

        bd.flags &= ~ENET_BD_E;

        if (size == 0) {

            

            bd.flags |= flags | ENET_BD_L;

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

            s->regs[ENET_EIR] |= ENET_INT_RXF;

        } else {

            s->regs[ENET_EIR] |= ENET_INT_RXB;

        }

        imx_fec_write_bd(&bd, addr);

        

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

            addr = s->regs[ENET_RDSR];

        } else {

            addr += sizeof(bd);

        }

    }

    s->rx_descriptor = addr;

    imx_eth_enable_rx(s);

    imx_eth_update(s);

    return len;

}

static ssize_t FUNC_0(NetClientState *nc, const uint8_t *buf,
size_t len)
{ IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc)); IMXFECBufDesc bd; uint32_t flags = 0; uint32_t addr; uint32_t crc; uint32_t buf_addr; uint8_t *crc_ptr; unsigned int VAR_0; size_t size = len; FEC_PRINTF("len %d\n", (int)size); if (!s->regs[ENET_RDAR]) { qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Unexpected packet\n",
TYPE_IMX_FEC, __func__); return 0; } size += 4; crc = cpu_to_be32(crc32(~0, buf, size)); crc_ptr = (uint8_t *) &crc; if (size > ENET_MAX_FRAME_SIZE) { size = ENET_MAX_FRAME_SIZE; flags |= ENET_BD_TR | ENET_BD_LG; } if (size > (s->regs[ENET_RCR] >> 16)) { flags |= ENET_BD_LG; } addr = s->rx_descriptor; while (size > 0) { imx_fec_read_bd(&bd, addr); if ((bd.flags & ENET_BD_E) == 0) { qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Lost end of frame\n",
TYPE_IMX_FEC, __func__); break; } VAR_0 = (size <= s->regs[ENET_MRBR]) ? size : s->regs[ENET_MRBR]; bd.length = VAR_0; size -= VAR_0; FEC_PRINTF("rx_bd 0x%x length %d\n", addr, bd.length); if (size < 4) { VAR_0 += size - 4; } buf_addr = bd.data; dma_memory_write(&address_space_memory, buf_addr, buf, VAR_0); buf += VAR_0; if (size < 4) { dma_memory_write(&address_space_memory, buf_addr + VAR_0,
crc_ptr, 4 - size); crc_ptr += 4 - size; } bd.flags &= ~ENET_BD_E; if (size == 0) { bd.flags |= flags | ENET_BD_L; FEC_PRINTF("rx frame flags %04x\n", bd.flags); s->regs[ENET_EIR] |= ENET_INT_RXF; } else { s->regs[ENET_EIR] |= ENET_INT_RXB; } imx_fec_write_bd(&bd, addr); if ((bd.flags & ENET_BD_W) != 0) { addr = s->regs[ENET_RDSR]; } else { addr += sizeof(bd); } } s->rx_descriptor = addr; imx_eth_enable_rx(s); imx_eth_update(s); return len; }