summaryrefslogtreecommitdiffstats
path: root/qemu/hw/net/rocker
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/hw/net/rocker')
-rw-r--r--qemu/hw/net/rocker/qmp-norocker.c1
-rw-r--r--qemu/hw/net/rocker/rocker.c59
-rw-r--r--qemu/hw/net/rocker/rocker_desc.c13
-rw-r--r--qemu/hw/net/rocker/rocker_fp.c8
-rw-r--r--qemu/hw/net/rocker/rocker_fp.h1
-rw-r--r--qemu/hw/net/rocker/rocker_of_dpa.c23
-rw-r--r--qemu/hw/net/rocker/rocker_world.c8
-rw-r--r--qemu/hw/net/rocker/rocker_world.h1
8 files changed, 72 insertions, 42 deletions
diff --git a/qemu/hw/net/rocker/qmp-norocker.c b/qemu/hw/net/rocker/qmp-norocker.c
index 49b498b64..6acbcdb02 100644
--- a/qemu/hw/net/rocker/qmp-norocker.c
+++ b/qemu/hw/net/rocker/qmp-norocker.c
@@ -15,6 +15,7 @@
* GNU General Public License for more details.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qmp-commands.h"
#include "qapi/qmp/qerror.h"
diff --git a/qemu/hw/net/rocker/rocker.c b/qemu/hw/net/rocker/rocker.c
index 47d080fd3..30f2ce417 100644
--- a/qemu/hw/net/rocker/rocker.c
+++ b/qemu/hw/net/rocker/rocker.c
@@ -15,6 +15,7 @@
* GNU General Public License for more details.
*/
+#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/pci/pci.h"
#include "hw/pci/msix.h"
@@ -42,6 +43,7 @@ struct rocker {
/* switch configuration */
char *name; /* switch name */
+ char *world_name; /* world name */
uint32_t fp_ports; /* front-panel port count */
NICPeers *fp_ports_peers;
MACAddr fp_start_macaddr; /* front-panel port 0 mac addr */
@@ -101,8 +103,7 @@ RockerSwitch *qmp_query_rocker(const char *name, Error **errp)
r = rocker_find(name);
if (!r) {
- error_set(errp, ERROR_CLASS_GENERIC_ERROR,
- "rocker %s not found", name);
+ error_setg(errp, "rocker %s not found", name);
return NULL;
}
@@ -122,8 +123,7 @@ RockerPortList *qmp_query_rocker_ports(const char *name, Error **errp)
r = rocker_find(name);
if (!r) {
- error_set(errp, ERROR_CLASS_GENERIC_ERROR,
- "rocker %s not found", name);
+ error_setg(errp, "rocker %s not found", name);
return NULL;
}
@@ -234,6 +234,9 @@ static int tx_consume(Rocker *r, DescInfo *info)
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]);
+ if (iovcnt >= ROCKER_TX_FRAGS_MAX) {
+ goto err_too_many_frags;
+ }
iov[iovcnt].iov_len = frag_len;
iov[iovcnt].iov_base = g_malloc(frag_len);
if (!iov[iovcnt].iov_base) {
@@ -246,10 +249,7 @@ static int tx_consume(Rocker *r, DescInfo *info)
err = -ROCKER_ENXIO;
goto err_bad_io;
}
-
- if (++iovcnt > ROCKER_TX_FRAGS_MAX) {
- goto err_too_many_frags;
- }
+ iovcnt++;
}
if (iovcnt) {
@@ -265,9 +265,7 @@ err_bad_io:
err_no_mem:
err_bad_attr:
for (i = 0; i < ROCKER_TX_FRAGS_MAX; i++) {
- if (iov[i].iov_base) {
- g_free(iov[i].iov_base);
- }
+ g_free(iov[i].iov_base);
}
return err;
@@ -403,7 +401,13 @@ static int cmd_set_port_settings(Rocker *r,
if (tlvs[ROCKER_TLV_CMD_PORT_SETTINGS_MODE]) {
mode = rocker_tlv_get_u8(tlvs[ROCKER_TLV_CMD_PORT_SETTINGS_MODE]);
- fp_port_set_world(fp_port, r->worlds[mode]);
+ if (mode >= ROCKER_WORLD_TYPE_MAX) {
+ return -ROCKER_EINVAL;
+ }
+ /* We don't support world change. */
+ if (!fp_port_check_world(fp_port, r->worlds[mode])) {
+ return -ROCKER_EINVAL;
+ }
}
if (tlvs[ROCKER_TLV_CMD_PORT_SETTINGS_LEARNING]) {
@@ -1283,6 +1287,18 @@ static void rocker_msix_uninit(Rocker *r)
rocker_msix_vectors_unuse(r, ROCKER_MSIX_VEC_COUNT(r->fp_ports));
}
+static World *rocker_world_type_by_name(Rocker *r, const char *name)
+{
+ int i;
+
+ for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
+ if (strcmp(name, world_name(r->worlds[i])) == 0) {
+ return r->worlds[i];
+ }
+ }
+ return NULL;
+}
+
static int pci_rocker_init(PCIDevice *dev)
{
Rocker *r = to_rocker(dev);
@@ -1294,14 +1310,27 @@ static int pci_rocker_init(PCIDevice *dev)
/* allocate worlds */
r->worlds[ROCKER_WORLD_TYPE_OF_DPA] = of_dpa_world_alloc(r);
- r->world_dflt = r->worlds[ROCKER_WORLD_TYPE_OF_DPA];
for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
if (!r->worlds[i]) {
+ err = -ENOMEM;
goto err_world_alloc;
}
}
+ 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,
@@ -1364,7 +1393,7 @@ static int pci_rocker_init(PCIDevice *dev)
r->fp_ports = ROCKER_FP_PORTS_MAX;
}
- r->rings = g_malloc(sizeof(DescRing *) * rocker_pci_ring_count(r));
+ r->rings = g_new(DescRing *, rocker_pci_ring_count(r));
if (!r->rings) {
goto err_rings_alloc;
}
@@ -1435,6 +1464,7 @@ err_duplicate:
err_msix_init:
object_unparent(OBJECT(&r->msix_bar));
object_unparent(OBJECT(&r->mmio));
+err_world_type_by_name:
err_world_alloc:
for (i = 0; i < ROCKER_WORLD_TYPE_MAX; i++) {
if (r->worlds[i]) {
@@ -1506,6 +1536,7 @@ static void rocker_reset(DeviceState *dev)
static Property rocker_properties[] = {
DEFINE_PROP_STRING("name", Rocker, name),
+ DEFINE_PROP_STRING("world", Rocker, world_name),
DEFINE_PROP_MACADDR("fp_start_macaddr", Rocker,
fp_start_macaddr),
DEFINE_PROP_UINT64("switch_id", Rocker,
diff --git a/qemu/hw/net/rocker/rocker_desc.c b/qemu/hw/net/rocker/rocker_desc.c
index 9d896fe47..ac02797b7 100644
--- a/qemu/hw/net/rocker/rocker_desc.c
+++ b/qemu/hw/net/rocker/rocker_desc.c
@@ -14,6 +14,7 @@
* GNU General Public License for more details.
*/
+#include "qemu/osdep.h"
#include "net/net.h"
#include "hw/hw.h"
#include "hw/pci/pci.h"
@@ -136,15 +137,13 @@ bool desc_ring_set_size(DescRing *ring, uint32_t size)
}
for (i = 0; i < ring->size; i++) {
- if (ring->info[i].buf) {
- g_free(ring->info[i].buf);
- }
+ g_free(ring->info[i].buf);
}
ring->size = size;
ring->head = ring->tail = 0;
- ring->info = g_realloc(ring->info, size * sizeof(DescInfo));
+ ring->info = g_renew(DescInfo, ring->info, size);
if (!ring->info) {
return false;
}
@@ -347,7 +346,7 @@ DescRing *desc_ring_alloc(Rocker *r, int index)
{
DescRing *ring;
- ring = g_malloc0(sizeof(DescRing));
+ ring = g_new0(DescRing, 1);
if (!ring) {
return NULL;
}
@@ -360,9 +359,7 @@ DescRing *desc_ring_alloc(Rocker *r, int index)
void desc_ring_free(DescRing *ring)
{
- if (ring->info) {
- g_free(ring->info);
- }
+ g_free(ring->info);
g_free(ring);
}
diff --git a/qemu/hw/net/rocker/rocker_fp.c b/qemu/hw/net/rocker/rocker_fp.c
index c693ae508..0149899c6 100644
--- a/qemu/hw/net/rocker/rocker_fp.c
+++ b/qemu/hw/net/rocker/rocker_fp.c
@@ -14,6 +14,7 @@
* GNU General Public License for more details.
*/
+#include "qemu/osdep.h"
#include "net/clients.h"
#include "rocker.h"
@@ -185,6 +186,11 @@ void fp_port_set_world(FpPort *port, World *world)
port->world = world;
}
+bool fp_port_check_world(FpPort *port, World *world)
+{
+ return port->world == world;
+}
+
bool fp_port_enabled(FpPort *port)
{
return port->enabled;
@@ -218,7 +224,7 @@ FpPort *fp_port_alloc(Rocker *r, char *sw_name,
MACAddr *start_mac, unsigned int index,
NICPeers *peers)
{
- FpPort *port = g_malloc0(sizeof(FpPort));
+ FpPort *port = g_new0(FpPort, 1);
if (!port) {
return NULL;
diff --git a/qemu/hw/net/rocker/rocker_fp.h b/qemu/hw/net/rocker/rocker_fp.h
index ab80fd833..04592bbfd 100644
--- a/qemu/hw/net/rocker/rocker_fp.h
+++ b/qemu/hw/net/rocker/rocker_fp.h
@@ -40,6 +40,7 @@ int fp_port_set_settings(FpPort *port, uint32_t speed,
bool fp_port_from_pport(uint32_t pport, uint32_t *port);
World *fp_port_get_world(FpPort *port);
void fp_port_set_world(FpPort *port, World *world);
+bool fp_port_check_world(FpPort *port, World *world);
bool fp_port_enabled(FpPort *port);
void fp_port_enable(FpPort *port);
void fp_port_disable(FpPort *port);
diff --git a/qemu/hw/net/rocker/rocker_of_dpa.c b/qemu/hw/net/rocker/rocker_of_dpa.c
index 874fb01d6..0a134ebca 100644
--- a/qemu/hw/net/rocker/rocker_of_dpa.c
+++ b/qemu/hw/net/rocker/rocker_of_dpa.c
@@ -14,6 +14,7 @@
* GNU General Public License for more details.
*/
+#include "qemu/osdep.h"
#include "net/eth.h"
#include "qemu/iov.h"
#include "qemu/timer.h"
@@ -367,7 +368,7 @@ static OfDpaFlow *of_dpa_flow_alloc(uint64_t cookie)
OfDpaFlow *flow;
int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) / 1000;
- flow = g_malloc0(sizeof(OfDpaFlow));
+ flow = g_new0(OfDpaFlow, 1);
if (!flow) {
return NULL;
}
@@ -811,7 +812,7 @@ static int of_dpa_group_get_stats(OfDpa *of_dpa, uint32_t id)
static OfDpaGroup *of_dpa_group_alloc(uint32_t id)
{
- OfDpaGroup *group = g_malloc0(sizeof(OfDpaGroup));
+ OfDpaGroup *group = g_new0(OfDpaGroup, 1);
if (!group) {
return NULL;
@@ -2039,15 +2040,14 @@ static int of_dpa_cmd_add_l2_flood(OfDpa *of_dpa, OfDpaGroup *group,
group->l2_flood.group_count =
rocker_tlv_get_le16(group_tlvs[ROCKER_TLV_OF_DPA_GROUP_COUNT]);
- tlvs = g_malloc0((group->l2_flood.group_count + 1) *
- sizeof(RockerTlv *));
+ tlvs = g_new0(RockerTlv *, group->l2_flood.group_count + 1);
if (!tlvs) {
return -ROCKER_ENOMEM;
}
g_free(group->l2_flood.group_ids);
group->l2_flood.group_ids =
- g_malloc0(group->l2_flood.group_count * sizeof(uint32_t));
+ g_new0(uint32_t, group->l2_flood.group_count);
if (!group->l2_flood.group_ids) {
err = -ROCKER_ENOMEM;
goto err_out;
@@ -2463,15 +2463,13 @@ RockerOfDpaFlowList *qmp_query_rocker_of_dpa_flows(const char *name,
r = rocker_find(name);
if (!r) {
- error_set(errp, ERROR_CLASS_GENERIC_ERROR,
- "rocker %s not found", name);
+ error_setg(errp, "rocker %s not found", name);
return NULL;
}
w = rocker_get_world(r, ROCKER_WORLD_TYPE_OF_DPA);
if (!w) {
- error_set(errp, ERROR_CLASS_GENERIC_ERROR,
- "rocker %s doesn't have OF-DPA world", name);
+ error_setg(errp, "rocker %s doesn't have OF-DPA world", name);
return NULL;
}
@@ -2598,15 +2596,13 @@ RockerOfDpaGroupList *qmp_query_rocker_of_dpa_groups(const char *name,
r = rocker_find(name);
if (!r) {
- error_set(errp, ERROR_CLASS_GENERIC_ERROR,
- "rocker %s not found", name);
+ error_setg(errp, "rocker %s not found", name);
return NULL;
}
w = rocker_get_world(r, ROCKER_WORLD_TYPE_OF_DPA);
if (!w) {
- error_set(errp, ERROR_CLASS_GENERIC_ERROR,
- "rocker %s doesn't have OF-DPA world", name);
+ error_setg(errp, "rocker %s doesn't have OF-DPA world", name);
return NULL;
}
@@ -2618,6 +2614,7 @@ RockerOfDpaGroupList *qmp_query_rocker_of_dpa_groups(const char *name,
}
static WorldOps of_dpa_ops = {
+ .name = "ofdpa",
.init = of_dpa_init,
.uninit = of_dpa_uninit,
.ig = of_dpa_ig,
diff --git a/qemu/hw/net/rocker/rocker_world.c b/qemu/hw/net/rocker/rocker_world.c
index a6b18f175..89777e968 100644
--- a/qemu/hw/net/rocker/rocker_world.c
+++ b/qemu/hw/net/rocker/rocker_world.c
@@ -14,6 +14,7 @@
* GNU General Public License for more details.
*/
+#include "qemu/osdep.h"
#include "qemu/iov.h"
#include "rocker.h"
@@ -97,10 +98,5 @@ enum rocker_world_type world_type(World *world)
const char *world_name(World *world)
{
- switch (world->type) {
- case ROCKER_WORLD_TYPE_OF_DPA:
- return "OF_DPA";
- default:
- return "unknown";
- }
+ return world->ops->name;
}
diff --git a/qemu/hw/net/rocker/rocker_world.h b/qemu/hw/net/rocker/rocker_world.h
index 18d277b92..58ade4733 100644
--- a/qemu/hw/net/rocker/rocker_world.h
+++ b/qemu/hw/net/rocker/rocker_world.h
@@ -33,6 +33,7 @@ typedef int (world_cmd)(World *world, DescInfo *info,
RockerTlv *cmd_info_tlv);
typedef struct world_ops {
+ const char *name;
world_init *init;
world_uninit *uninit;
world_ig *ig;