static int pci_rocker_init(PCIDevice *dev)

{

    Rocker *r = to_rocker(dev);

    const MACAddr zero = { .a = { 0, 0, 0, 0, 0, 0 } };

    const MACAddr dflt = { .a = { 0x52, 0x54, 0x00, 0x12, 0x35, 0x01 } };

    static int sw_index;

    int i, err = 0;



    /* allocate worlds */



    r->worlds[ROCKER_WORLD_TYPE_OF_DPA] = of_dpa_world_alloc(r);



    if (!r->world_name) {

        r->world_name = g_strdup(world_name(r->worlds[ROCKER_WORLD_TYPE_OF_DPA]));

    }



    r->world_dflt = rocker_world_type_by_name(r, r->world_name);

    if (!r->world_dflt) {

        fprintf(stderr,

                "rocker: requested world \"%s\" does not exist\n",

                r->world_name);

        err = -EINVAL;

        goto err_world_type_by_name;

    }



    /* set up memory-mapped region at BAR0 */



    memory_region_init_io(&r->mmio, OBJECT(r), &rocker_mmio_ops, r,

                          "rocker-mmio", ROCKER_PCI_BAR0_SIZE);

    pci_register_bar(dev, ROCKER_PCI_BAR0_IDX,

                     PCI_BASE_ADDRESS_SPACE_MEMORY, &r->mmio);



    /* set up memory-mapped region for MSI-X */



    memory_region_init(&r->msix_bar, OBJECT(r), "rocker-msix-bar",

                       ROCKER_PCI_MSIX_BAR_SIZE);

    pci_register_bar(dev, ROCKER_PCI_MSIX_BAR_IDX,

                     PCI_BASE_ADDRESS_SPACE_MEMORY, &r->msix_bar);



    /* MSI-X init */



    err = rocker_msix_init(r);

    if (err) {

        goto err_msix_init;

    }



    /* validate switch properties */



    if (!r->name) {

        r->name = g_strdup(ROCKER);

    }



    if (rocker_find(r->name)) {

        err = -EEXIST;

        goto err_duplicate;

    }



    /* Rocker name is passed in port name requests to OS with the intention

     * that the name is used in interface names. Limit the length of the

     * rocker name to avoid naming problems in the OS. Also, adding the

     * port number as p# and unganged breakout b#, where # is at most 2

     * digits, so leave room for it too (-1 for string terminator, -3 for

     * p# and -3 for b#)

     */

#define ROCKER_IFNAMSIZ 16

#define MAX_ROCKER_NAME_LEN  (ROCKER_IFNAMSIZ - 1 - 3 - 3)

    if (strlen(r->name) > MAX_ROCKER_NAME_LEN) {

        fprintf(stderr,

                "rocker: name too long; please shorten to at most %d chars\n",

                MAX_ROCKER_NAME_LEN);

        return -EINVAL;

    }



    if (memcmp(&r->fp_start_macaddr, &zero, sizeof(zero)) == 0) {

        memcpy(&r->fp_start_macaddr, &dflt, sizeof(dflt));

        r->fp_start_macaddr.a[4] += (sw_index++);

    }



    if (!r->switch_id) {

        memcpy(&r->switch_id, &r->fp_start_macaddr,

               sizeof(r->fp_start_macaddr));

    }



    if (r->fp_ports > ROCKER_FP_PORTS_MAX) {

        r->fp_ports = ROCKER_FP_PORTS_MAX;

    }



    r->rings = g_new(DescRing *, rocker_pci_ring_count(r));



    /* Rings are ordered like this:

     * - command ring

     * - event ring

     * - port0 tx ring

     * - port0 rx ring

     * - port1 tx ring

     * - port1 rx ring

     * .....

     */



    for (i = 0; i < rocker_pci_ring_count(r); i++) {

        DescRing *ring = desc_ring_alloc(r, i);



        if (i == ROCKER_RING_CMD) {

            desc_ring_set_consume(ring, cmd_consume, ROCKER_MSIX_VEC_CMD);

        } else if (i == ROCKER_RING_EVENT) {

            desc_ring_set_consume(ring, NULL, ROCKER_MSIX_VEC_EVENT);

        } else if (i % 2 == 0) {

            desc_ring_set_consume(ring, tx_consume,

                                  ROCKER_MSIX_VEC_TX((i - 2) / 2));

        } else if (i % 2 == 1) {

            desc_ring_set_consume(ring, NULL, ROCKER_MSIX_VEC_RX((i - 3) / 2));

        }



        r->rings[i] = ring;

    }



    for (i = 0; i < r->fp_ports; i++) {

        FpPort *port =

            fp_port_alloc(r, r->name, &r->fp_start_macaddr,

                          i, &r->fp_ports_peers[i]);



        r->fp_port[i] = port;

        fp_port_set_world(port, r->world_dflt);

    }



    QLIST_INSERT_HEAD(&rockers, r, next);



    return 0;



err_duplicate:

    rocker_msix_uninit(r);

err_msix_init:

    object_unparent(OBJECT(&r->msix_bar));

    object_unparent(OBJECT(&r->mmio));

err_world_type_by_name:

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

        if (r->worlds[i]) {

            world_free(r->worlds[i]);

        }

    }

    return err;

}

static int pci_rocker_init(PCIDevice *dev)

{

    Rocker *r = to_rocker(dev);

    const MACAddr zero = { .a = { 0, 0, 0, 0, 0, 0 } };

    const MACAddr dflt = { .a = { 0x52, 0x54, 0x00, 0x12, 0x35, 0x01 } };

    static int sw_index;

    int i, err = 0;



    



    r->worlds[ROCKER_WORLD_TYPE_OF_DPA] = of_dpa_world_alloc(r);



    if (!r->world_name) {

        r->world_name = g_strdup(world_name(r->worlds[ROCKER_WORLD_TYPE_OF_DPA]));

    }



    r->world_dflt = rocker_world_type_by_name(r, r->world_name);

    if (!r->world_dflt) {

        fprintf(stderr,

                "rocker: requested world \"%s\" does not exist\n",

                r->world_name);

        err = -EINVAL;

        goto err_world_type_by_name;

    }



    



    memory_region_init_io(&r->mmio, OBJECT(r), &rocker_mmio_ops, r,

                          "rocker-mmio", ROCKER_PCI_BAR0_SIZE);

    pci_register_bar(dev, ROCKER_PCI_BAR0_IDX,

                     PCI_BASE_ADDRESS_SPACE_MEMORY, &r->mmio);



    



    memory_region_init(&r->msix_bar, OBJECT(r), "rocker-msix-bar",

                       ROCKER_PCI_MSIX_BAR_SIZE);

    pci_register_bar(dev, ROCKER_PCI_MSIX_BAR_IDX,

                     PCI_BASE_ADDRESS_SPACE_MEMORY, &r->msix_bar);



    



    err = rocker_msix_init(r);

    if (err) {

        goto err_msix_init;

    }



    



    if (!r->name) {

        r->name = g_strdup(ROCKER);

    }



    if (rocker_find(r->name)) {

        err = -EEXIST;

        goto err_duplicate;

    }



    













#define ROCKER_IFNAMSIZ 16

#define MAX_ROCKER_NAME_LEN  (ROCKER_IFNAMSIZ - 1 - 3 - 3)

    if (strlen(r->name) > MAX_ROCKER_NAME_LEN) {

        fprintf(stderr,

                "rocker: name too long; please shorten to at most %d chars\n",

                MAX_ROCKER_NAME_LEN);

        return -EINVAL;

    }



    if (memcmp(&r->fp_start_macaddr, &zero, sizeof(zero)) == 0) {

        memcpy(&r->fp_start_macaddr, &dflt, sizeof(dflt));

        r->fp_start_macaddr.a[4] += (sw_index++);

    }



    if (!r->switch_id) {

        memcpy(&r->switch_id, &r->fp_start_macaddr,

               sizeof(r->fp_start_macaddr));

    }



    if (r->fp_ports > ROCKER_FP_PORTS_MAX) {

        r->fp_ports = ROCKER_FP_PORTS_MAX;

    }



    r->rings = g_new(DescRing *, rocker_pci_ring_count(r));



    



















    for (i = 0; i < rocker_pci_ring_count(r); i++) {

        DescRing *ring = desc_ring_alloc(r, i);



        if (i == ROCKER_RING_CMD) {

            desc_ring_set_consume(ring, cmd_consume, ROCKER_MSIX_VEC_CMD);

        } else if (i == ROCKER_RING_EVENT) {

            desc_ring_set_consume(ring, NULL, ROCKER_MSIX_VEC_EVENT);

        } else if (i % 2 == 0) {

            desc_ring_set_consume(ring, tx_consume,

                                  ROCKER_MSIX_VEC_TX((i - 2) / 2));

        } else if (i % 2 == 1) {

            desc_ring_set_consume(ring, NULL, ROCKER_MSIX_VEC_RX((i - 3) / 2));

        }



        r->rings[i] = ring;

    }



    for (i = 0; i < r->fp_ports; i++) {

        FpPort *port =

            fp_port_alloc(r, r->name, &r->fp_start_macaddr,

                          i, &r->fp_ports_peers[i]);



        r->fp_port[i] = port;

        fp_port_set_world(port, r->world_dflt);

    }



    QLIST_INSERT_HEAD(&rockers, r, next);



    return 0;



err_duplicate:

    rocker_msix_uninit(r);

err_msix_init:

    object_unparent(OBJECT(&r->msix_bar));

    object_unparent(OBJECT(&r->mmio));

err_world_type_by_name:

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

        if (r->worlds[i]) {

            world_free(r->worlds[i]);

        }

    }

    return err;

}

        return -EINVAL;
static int FUNC_0(PCIDevice *VAR_0)

{

    Rocker *r = to_rocker(VAR_0);

    const MACAddr VAR_1 = { .a = { 0, 0, 0, 0, 0, 0 } };

    const MACAddr VAR_2 = { .a = { 0x52, 0x54, 0x00, 0x12, 0x35, 0x01 } };

    static int VAR_3;

    int VAR_4, VAR_5 = 0;



    



    r->worlds[ROCKER_WORLD_TYPE_OF_DPA] = of_dpa_world_alloc(r);



    if (!r->world_name) {

        r->world_name = g_strdup(world_name(r->worlds[ROCKER_WORLD_TYPE_OF_DPA]));

    }



    r->world_dflt = rocker_world_type_by_name(r, r->world_name);

    if (!r->world_dflt) {

        fprintf(stderr,

                "rocker: requested world \"%s\" does not exist\n",

                r->world_name);

        VAR_5 = -EINVAL;

        goto err_world_type_by_name;

    }



    



    memory_region_init_io(&r->mmio, OBJECT(r), &rocker_mmio_ops, r,

                          "rocker-mmio", ROCKER_PCI_BAR0_SIZE);

    pci_register_bar(VAR_0, ROCKER_PCI_BAR0_IDX,

                     PCI_BASE_ADDRESS_SPACE_MEMORY, &r->mmio);



    



    memory_region_init(&r->msix_bar, OBJECT(r), "rocker-msix-bar",

                       ROCKER_PCI_MSIX_BAR_SIZE);

    pci_register_bar(VAR_0, ROCKER_PCI_MSIX_BAR_IDX,

                     PCI_BASE_ADDRESS_SPACE_MEMORY, &r->msix_bar);



    



    VAR_5 = rocker_msix_init(r);

    if (VAR_5) {

        goto err_msix_init;

    }



    



    if (!r->name) {

        r->name = g_strdup(ROCKER);

    }



    if (rocker_find(r->name)) {

        VAR_5 = -EEXIST;

        goto err_duplicate;

    }



    













#define ROCKER_IFNAMSIZ 16

#define MAX_ROCKER_NAME_LEN  (ROCKER_IFNAMSIZ - 1 - 3 - 3)

    if (strlen(r->name) > MAX_ROCKER_NAME_LEN) {

        fprintf(stderr,

                "rocker: name too long; please shorten to at most %d chars\n",

                MAX_ROCKER_NAME_LEN);

        return -EINVAL;

    }



    if (memcmp(&r->fp_start_macaddr, &VAR_1, sizeof(VAR_1)) == 0) {

        memcpy(&r->fp_start_macaddr, &VAR_2, sizeof(VAR_2));

        r->fp_start_macaddr.a[4] += (VAR_3++);

    }



    if (!r->switch_id) {

        memcpy(&r->switch_id, &r->fp_start_macaddr,

               sizeof(r->fp_start_macaddr));

    }



    if (r->fp_ports > ROCKER_FP_PORTS_MAX) {

        r->fp_ports = ROCKER_FP_PORTS_MAX;

    }



    r->rings = g_new(DescRing *, rocker_pci_ring_count(r));



    



















    for (VAR_4 = 0; VAR_4 < rocker_pci_ring_count(r); VAR_4++) {

        DescRing *ring = desc_ring_alloc(r, VAR_4);



        if (VAR_4 == ROCKER_RING_CMD) {

            desc_ring_set_consume(ring, cmd_consume, ROCKER_MSIX_VEC_CMD);

        } else if (VAR_4 == ROCKER_RING_EVENT) {

            desc_ring_set_consume(ring, NULL, ROCKER_MSIX_VEC_EVENT);

        } else if (VAR_4 % 2 == 0) {

            desc_ring_set_consume(ring, tx_consume,

                                  ROCKER_MSIX_VEC_TX((VAR_4 - 2) / 2));

        } else if (VAR_4 % 2 == 1) {

            desc_ring_set_consume(ring, NULL, ROCKER_MSIX_VEC_RX((VAR_4 - 3) / 2));

        }



        r->rings[VAR_4] = ring;

    }



    for (VAR_4 = 0; VAR_4 < r->fp_ports; VAR_4++) {

        FpPort *port =

            fp_port_alloc(r, r->name, &r->fp_start_macaddr,

                          VAR_4, &r->fp_ports_peers[VAR_4]);



        r->fp_port[VAR_4] = port;

        fp_port_set_world(port, r->world_dflt);

    }



    QLIST_INSERT_HEAD(&rockers, r, next);



    return 0;



err_duplicate:

    rocker_msix_uninit(r);

err_msix_init:

    object_unparent(OBJECT(&r->msix_bar));

    object_unparent(OBJECT(&r->mmio));

err_world_type_by_name:

    for (VAR_4 = 0; VAR_4 < ROCKER_WORLD_TYPE_MAX; VAR_4++) {

        if (r->worlds[VAR_4]) {

            world_free(r->worlds[VAR_4]);

        }

    }

    return VAR_5;

}

static int FUNC_0(PCIDevice *VAR_0)
{ Rocker *r = to_rocker(VAR_0); const MACAddr VAR_1 = { .a = { 0, 0, 0, 0, 0, 0 } }; const MACAddr VAR_2 = { .a = { 0x52, 0x54, 0x00, 0x12, 0x35, 0x01 } }; static int VAR_3; int VAR_4, VAR_5 = 0; r->worlds[ROCKER_WORLD_TYPE_OF_DPA] = of_dpa_world_alloc(r); if (!r->world_name) { r->world_name = g_strdup(world_name(r->worlds[ROCKER_WORLD_TYPE_OF_DPA])); } r->world_dflt = rocker_world_type_by_name(r, r->world_name); if (!r->world_dflt) { fprintf(stderr,
"rocker: requested world \"%s\" does not exist\n",
r->world_name); VAR_5 = -EINVAL; goto err_world_type_by_name; } memory_region_init_io(&r->mmio, OBJECT(r), &rocker_mmio_ops, r,
"rocker-mmio", ROCKER_PCI_BAR0_SIZE); pci_register_bar(VAR_0, ROCKER_PCI_BAR0_IDX,
PCI_BASE_ADDRESS_SPACE_MEMORY, &r->mmio); memory_region_init(&r->msix_bar, OBJECT(r), "rocker-msix-bar",
ROCKER_PCI_MSIX_BAR_SIZE); pci_register_bar(VAR_0, ROCKER_PCI_MSIX_BAR_IDX,
PCI_BASE_ADDRESS_SPACE_MEMORY, &r->msix_bar); VAR_5 = rocker_msix_init(r); if (VAR_5) { goto err_msix_init; } if (!r->name) { r->name = g_strdup(ROCKER); } if (rocker_find(r->name)) { VAR_5 = -EEXIST; goto err_duplicate; } #define ROCKER_IFNAMSIZ 16
#define MAX_ROCKER_NAME_LEN  (ROCKER_IFNAMSIZ - 1 - 3 - 3)
if (strlen(r->name) > MAX_ROCKER_NAME_LEN) { fprintf(stderr,
"rocker: name too long; please shorten to at most %d chars\n", MAX_ROCKER_NAME_LEN); return -EINVAL; } if (memcmp(&r->fp_start_macaddr, &VAR_1, sizeof(VAR_1)) == 0) { memcpy(&r->fp_start_macaddr, &VAR_2, sizeof(VAR_2)); r->fp_start_macaddr.a[4] += (VAR_3++); } if (!r->switch_id) { memcpy(&r->switch_id, &r->fp_start_macaddr,
sizeof(r->fp_start_macaddr)); } if (r->fp_ports > ROCKER_FP_PORTS_MAX) { r->fp_ports = ROCKER_FP_PORTS_MAX; } r->rings = g_new(DescRing *, rocker_pci_ring_count(r)); for (VAR_4 = 0; VAR_4 < rocker_pci_ring_count(r); VAR_4++) { DescRing *ring = desc_ring_alloc(r, VAR_4); if (VAR_4 == ROCKER_RING_CMD) { desc_ring_set_consume(ring, cmd_consume, ROCKER_MSIX_VEC_CMD); } else if (VAR_4 == ROCKER_RING_EVENT) { desc_ring_set_consume(ring, NULL, ROCKER_MSIX_VEC_EVENT); } else if (VAR_4 % 2 == 0) { desc_ring_set_consume(ring, tx_consume,
ROCKER_MSIX_VEC_TX((VAR_4 - 2) / 2)); } else if (VAR_4 % 2 == 1) { desc_ring_set_consume(ring, NULL, ROCKER_MSIX_VEC_RX((VAR_4 - 3) / 2)); } r->rings[VAR_4] = ring; } for (VAR_4 = 0; VAR_4 < r->fp_ports; VAR_4++) { FpPort *port =
fp_port_alloc(r, r->name, &r->fp_start_macaddr,
VAR_4, &r->fp_ports_peers[VAR_4]); r->fp_port[VAR_4] = port; fp_port_set_world(port, r->world_dflt); } QLIST_INSERT_HEAD(&rockers, r, next); return 0; err_duplicate:
rocker_msix_uninit(r); err_msix_init:
object_unparent(OBJECT(&r->msix_bar)); object_unparent(OBJECT(&r->mmio)); err_world_type_by_name:
for (VAR_4 = 0; VAR_4 < ROCKER_WORLD_TYPE_MAX; VAR_4++) { if (r->worlds[VAR_4]) { world_free(r->worlds[VAR_4]); } } return VAR_5; }