static int tx_consume(Rocker *r, DescInfo *info)

{

    PCIDevice *dev = PCI_DEVICE(r);

    char *buf = desc_get_buf(info, true);

    RockerTlv *tlv_frag;

    RockerTlv *tlvs[ROCKER_TLV_TX_MAX + 1];

    struct iovec iov[ROCKER_TX_FRAGS_MAX] = { { 0, }, };

    uint32_t pport;

    uint32_t port;

    uint16_t tx_offload = ROCKER_TX_OFFLOAD_NONE;

    uint16_t tx_l3_csum_off = 0;

    uint16_t tx_tso_mss = 0;

    uint16_t tx_tso_hdr_len = 0;

    int iovcnt = 0;

    int err = ROCKER_OK;

    int rem;

    int i;



    if (!buf) {

        return -ROCKER_ENXIO;

    }



    rocker_tlv_parse(tlvs, ROCKER_TLV_TX_MAX, buf, desc_tlv_size(info));



    if (!tlvs[ROCKER_TLV_TX_FRAGS]) {

        return -ROCKER_EINVAL;

    }



    pport = rocker_get_pport_by_tx_ring(r, desc_get_ring(info));

    if (!fp_port_from_pport(pport, &port)) {

        return -ROCKER_EINVAL;

    }



    if (tlvs[ROCKER_TLV_TX_OFFLOAD]) {

        tx_offload = rocker_tlv_get_u8(tlvs[ROCKER_TLV_TX_OFFLOAD]);

    }



    switch (tx_offload) {

    case ROCKER_TX_OFFLOAD_L3_CSUM:

        if (!tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]) {

            return -ROCKER_EINVAL;

        }

        break;

    case ROCKER_TX_OFFLOAD_TSO:

        if (!tlvs[ROCKER_TLV_TX_TSO_MSS] ||

            !tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]) {

            return -ROCKER_EINVAL;

        }

        break;

    }



    if (tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]) {

        tx_l3_csum_off = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]);

    }



    if (tlvs[ROCKER_TLV_TX_TSO_MSS]) {

        tx_tso_mss = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_TSO_MSS]);

    }



    if (tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]) {

        tx_tso_hdr_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]);

    }



    rocker_tlv_for_each_nested(tlv_frag, tlvs[ROCKER_TLV_TX_FRAGS], rem) {

        hwaddr frag_addr;

        uint16_t frag_len;



        if (rocker_tlv_type(tlv_frag) != ROCKER_TLV_TX_FRAG) {

            err = -ROCKER_EINVAL;

            goto err_bad_attr;

        }



        rocker_tlv_parse_nested(tlvs, ROCKER_TLV_TX_FRAG_ATTR_MAX, tlv_frag);



        if (!tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR] ||

            !tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]) {

            err = -ROCKER_EINVAL;

            goto err_bad_attr;

        }



        frag_addr = rocker_tlv_get_le64(tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR]);

        frag_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]);



        iov[iovcnt].iov_len = frag_len;

        iov[iovcnt].iov_base = g_malloc(frag_len);

        if (!iov[iovcnt].iov_base) {

            err = -ROCKER_ENOMEM;

            goto err_no_mem;

        }



        if (pci_dma_read(dev, frag_addr, iov[iovcnt].iov_base,

                     iov[iovcnt].iov_len)) {

            err = -ROCKER_ENXIO;

            goto err_bad_io;

        }



        if (++iovcnt > ROCKER_TX_FRAGS_MAX) {

            goto err_too_many_frags;

        }

    }



    if (iovcnt) {

        /* XXX perform Tx offloads */

        /* XXX   silence compiler for now */

        tx_l3_csum_off += tx_tso_mss = tx_tso_hdr_len = 0;

    }



    err = fp_port_eg(r->fp_port[port], iov, iovcnt);



err_too_many_frags:

err_bad_io:

err_no_mem:

err_bad_attr:

    for (i = 0; i < ROCKER_TX_FRAGS_MAX; i++) {

        g_free(iov[i].iov_base);

    }



    return err;

}

static int tx_consume(Rocker *r, DescInfo *info)

{

    PCIDevice *dev = PCI_DEVICE(r);

    char *buf = desc_get_buf(info, true);

    RockerTlv *tlv_frag;

    RockerTlv *tlvs[ROCKER_TLV_TX_MAX + 1];

    struct iovec iov[ROCKER_TX_FRAGS_MAX] = { { 0, }, };

    uint32_t pport;

    uint32_t port;

    uint16_t tx_offload = ROCKER_TX_OFFLOAD_NONE;

    uint16_t tx_l3_csum_off = 0;

    uint16_t tx_tso_mss = 0;

    uint16_t tx_tso_hdr_len = 0;

    int iovcnt = 0;

    int err = ROCKER_OK;

    int rem;

    int i;



    if (!buf) {

        return -ROCKER_ENXIO;

    }



    rocker_tlv_parse(tlvs, ROCKER_TLV_TX_MAX, buf, desc_tlv_size(info));



    if (!tlvs[ROCKER_TLV_TX_FRAGS]) {

        return -ROCKER_EINVAL;

    }



    pport = rocker_get_pport_by_tx_ring(r, desc_get_ring(info));

    if (!fp_port_from_pport(pport, &port)) {

        return -ROCKER_EINVAL;

    }



    if (tlvs[ROCKER_TLV_TX_OFFLOAD]) {

        tx_offload = rocker_tlv_get_u8(tlvs[ROCKER_TLV_TX_OFFLOAD]);

    }



    switch (tx_offload) {

    case ROCKER_TX_OFFLOAD_L3_CSUM:

        if (!tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]) {

            return -ROCKER_EINVAL;

        }

        break;

    case ROCKER_TX_OFFLOAD_TSO:

        if (!tlvs[ROCKER_TLV_TX_TSO_MSS] ||

            !tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]) {

            return -ROCKER_EINVAL;

        }

        break;

    }



    if (tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]) {

        tx_l3_csum_off = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]);

    }



    if (tlvs[ROCKER_TLV_TX_TSO_MSS]) {

        tx_tso_mss = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_TSO_MSS]);

    }



    if (tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]) {

        tx_tso_hdr_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]);

    }



    rocker_tlv_for_each_nested(tlv_frag, tlvs[ROCKER_TLV_TX_FRAGS], rem) {

        hwaddr frag_addr;

        uint16_t frag_len;



        if (rocker_tlv_type(tlv_frag) != ROCKER_TLV_TX_FRAG) {

            err = -ROCKER_EINVAL;

            goto err_bad_attr;

        }



        rocker_tlv_parse_nested(tlvs, ROCKER_TLV_TX_FRAG_ATTR_MAX, tlv_frag);



        if (!tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR] ||

            !tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]) {

            err = -ROCKER_EINVAL;

            goto err_bad_attr;

        }



        frag_addr = rocker_tlv_get_le64(tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR]);

        frag_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]);



        iov[iovcnt].iov_len = frag_len;

        iov[iovcnt].iov_base = g_malloc(frag_len);

        if (!iov[iovcnt].iov_base) {

            err = -ROCKER_ENOMEM;

            goto err_no_mem;

        }



        if (pci_dma_read(dev, frag_addr, iov[iovcnt].iov_base,

                     iov[iovcnt].iov_len)) {

            err = -ROCKER_ENXIO;

            goto err_bad_io;

        }



        if (++iovcnt > ROCKER_TX_FRAGS_MAX) {

            goto err_too_many_frags;

        }

    }



    if (iovcnt) {

        

        

        tx_l3_csum_off += tx_tso_mss = tx_tso_hdr_len = 0;

    }



    err = fp_port_eg(r->fp_port[port], iov, iovcnt);



err_too_many_frags:

err_bad_io:

err_no_mem:

err_bad_attr:

    for (i = 0; i < ROCKER_TX_FRAGS_MAX; i++) {

        g_free(iov[i].iov_base);

    }



    return err;

}

        if (++iovcnt > ROCKER_TX_FRAGS_MAX) {             goto err_too_many_frags;
static int FUNC_0(Rocker *VAR_0, DescInfo *VAR_1)

{

    PCIDevice *dev = PCI_DEVICE(VAR_0);

    char *VAR_2 = desc_get_buf(VAR_1, true);

    RockerTlv *tlv_frag;

    RockerTlv *tlvs[ROCKER_TLV_TX_MAX + 1];

    struct iovec VAR_3[ROCKER_TX_FRAGS_MAX] = { { 0, }, };

    uint32_t pport;

    uint32_t port;

    uint16_t tx_offload = ROCKER_TX_OFFLOAD_NONE;

    uint16_t tx_l3_csum_off = 0;

    uint16_t tx_tso_mss = 0;

    uint16_t tx_tso_hdr_len = 0;

    int VAR_4 = 0;

    int VAR_5 = ROCKER_OK;

    int VAR_6;

    int VAR_7;



    if (!VAR_2) {

        return -ROCKER_ENXIO;

    }



    rocker_tlv_parse(tlvs, ROCKER_TLV_TX_MAX, VAR_2, desc_tlv_size(VAR_1));



    if (!tlvs[ROCKER_TLV_TX_FRAGS]) {

        return -ROCKER_EINVAL;

    }



    pport = rocker_get_pport_by_tx_ring(VAR_0, desc_get_ring(VAR_1));

    if (!fp_port_from_pport(pport, &port)) {

        return -ROCKER_EINVAL;

    }



    if (tlvs[ROCKER_TLV_TX_OFFLOAD]) {

        tx_offload = rocker_tlv_get_u8(tlvs[ROCKER_TLV_TX_OFFLOAD]);

    }



    switch (tx_offload) {

    case ROCKER_TX_OFFLOAD_L3_CSUM:

        if (!tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]) {

            return -ROCKER_EINVAL;

        }

        break;

    case ROCKER_TX_OFFLOAD_TSO:

        if (!tlvs[ROCKER_TLV_TX_TSO_MSS] ||

            !tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]) {

            return -ROCKER_EINVAL;

        }

        break;

    }



    if (tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]) {

        tx_l3_csum_off = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]);

    }



    if (tlvs[ROCKER_TLV_TX_TSO_MSS]) {

        tx_tso_mss = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_TSO_MSS]);

    }



    if (tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]) {

        tx_tso_hdr_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]);

    }



    rocker_tlv_for_each_nested(tlv_frag, tlvs[ROCKER_TLV_TX_FRAGS], VAR_6) {

        hwaddr frag_addr;

        uint16_t frag_len;



        if (rocker_tlv_type(tlv_frag) != ROCKER_TLV_TX_FRAG) {

            VAR_5 = -ROCKER_EINVAL;

            goto err_bad_attr;

        }



        rocker_tlv_parse_nested(tlvs, ROCKER_TLV_TX_FRAG_ATTR_MAX, tlv_frag);



        if (!tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR] ||

            !tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]) {

            VAR_5 = -ROCKER_EINVAL;

            goto err_bad_attr;

        }



        frag_addr = rocker_tlv_get_le64(tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR]);

        frag_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]);



        VAR_3[VAR_4].iov_len = frag_len;

        VAR_3[VAR_4].iov_base = g_malloc(frag_len);

        if (!VAR_3[VAR_4].iov_base) {

            VAR_5 = -ROCKER_ENOMEM;

            goto err_no_mem;

        }



        if (pci_dma_read(dev, frag_addr, VAR_3[VAR_4].iov_base,

                     VAR_3[VAR_4].iov_len)) {

            VAR_5 = -ROCKER_ENXIO;

            goto err_bad_io;

        }



        if (++VAR_4 > ROCKER_TX_FRAGS_MAX) {

            goto err_too_many_frags;

        }

    }



    if (VAR_4) {

        

        

        tx_l3_csum_off += tx_tso_mss = tx_tso_hdr_len = 0;

    }



    VAR_5 = fp_port_eg(VAR_0->fp_port[port], VAR_3, VAR_4);



err_too_many_frags:

err_bad_io:

err_no_mem:

err_bad_attr:

    for (VAR_7 = 0; VAR_7 < ROCKER_TX_FRAGS_MAX; VAR_7++) {

        g_free(VAR_3[VAR_7].iov_base);

    }



    return VAR_5;

}

static int FUNC_0(Rocker *VAR_0, DescInfo *VAR_1)
{ PCIDevice *dev = PCI_DEVICE(VAR_0); char *VAR_2 = desc_get_buf(VAR_1, true); RockerTlv *tlv_frag; RockerTlv *tlvs[ROCKER_TLV_TX_MAX + 1]; struct iovec VAR_3[ROCKER_TX_FRAGS_MAX] = { { 0, }, }; uint32_t pport; uint32_t port; uint16_t tx_offload = ROCKER_TX_OFFLOAD_NONE; uint16_t tx_l3_csum_off = 0; uint16_t tx_tso_mss = 0; uint16_t tx_tso_hdr_len = 0; int VAR_4 = 0; int VAR_5 = ROCKER_OK; int VAR_6; int VAR_7; if (!VAR_2) { return -ROCKER_ENXIO; } rocker_tlv_parse(tlvs, ROCKER_TLV_TX_MAX, VAR_2, desc_tlv_size(VAR_1)); if (!tlvs[ROCKER_TLV_TX_FRAGS]) { return -ROCKER_EINVAL; } pport = rocker_get_pport_by_tx_ring(VAR_0, desc_get_ring(VAR_1)); if (!fp_port_from_pport(pport, &port)) { return -ROCKER_EINVAL; } if (tlvs[ROCKER_TLV_TX_OFFLOAD]) { tx_offload = rocker_tlv_get_u8(tlvs[ROCKER_TLV_TX_OFFLOAD]); } switch (tx_offload) { case ROCKER_TX_OFFLOAD_L3_CSUM:
if (!tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]) { return -ROCKER_EINVAL; } break; case ROCKER_TX_OFFLOAD_TSO:
if (!tlvs[ROCKER_TLV_TX_TSO_MSS] ||
!tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]) { return -ROCKER_EINVAL; } break; } if (tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]) { tx_l3_csum_off = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]); } if (tlvs[ROCKER_TLV_TX_TSO_MSS]) { tx_tso_mss = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_TSO_MSS]); } if (tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]) { tx_tso_hdr_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]); } rocker_tlv_for_each_nested(tlv_frag, tlvs[ROCKER_TLV_TX_FRAGS], VAR_6) { hwaddr frag_addr; uint16_t frag_len; if (rocker_tlv_type(tlv_frag) != ROCKER_TLV_TX_FRAG) { VAR_5 = -ROCKER_EINVAL; goto err_bad_attr; } rocker_tlv_parse_nested(tlvs, ROCKER_TLV_TX_FRAG_ATTR_MAX, tlv_frag); if (!tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR] ||
!tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]) { VAR_5 = -ROCKER_EINVAL; goto err_bad_attr; } frag_addr = rocker_tlv_get_le64(tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR]); frag_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]); VAR_3[VAR_4].iov_len = frag_len; VAR_3[VAR_4].iov_base = g_malloc(frag_len); if (!VAR_3[VAR_4].iov_base) { VAR_5 = -ROCKER_ENOMEM; goto err_no_mem; } if (pci_dma_read(dev, frag_addr, VAR_3[VAR_4].iov_base,
VAR_3[VAR_4].iov_len)) { VAR_5 = -ROCKER_ENXIO; goto err_bad_io; } if (++VAR_4 > ROCKER_TX_FRAGS_MAX) { goto err_too_many_frags; } } if (VAR_4) { tx_l3_csum_off += tx_tso_mss = tx_tso_hdr_len = 0; } VAR_5 = fp_port_eg(VAR_0->fp_port[port], VAR_3, VAR_4); err_too_many_frags:
err_bad_io:
err_no_mem:
err_bad_attr:
for (VAR_7 = 0; VAR_7 < ROCKER_TX_FRAGS_MAX; VAR_7++) { g_free(VAR_3[VAR_7].iov_base); } return VAR_5; }