aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-03-08 10:25:50 +0000
committerPeter Maydell <peter.maydell@linaro.org>2016-03-08 10:25:50 +0000
commitd1cc881d54d2abc9c90d92c90deccc8d47966b1c (patch)
treedf46cf293e0e12fdd91068e3aa60b228a8ab061d /hw
parent97556fe80e4f7252300b3498b3477fb4295153a3 (diff)
parent362786f14a753d8a5256ef97d7c10ed576d6572b (diff)
downloadqemu-d1cc881d54d2abc9c90d92c90deccc8d47966b1c.zip
qemu-d1cc881d54d2abc9c90d92c90deccc8d47966b1c.tar.gz
qemu-d1cc881d54d2abc9c90d92c90deccc8d47966b1c.tar.bz2
Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging
# gpg: Signature made Tue 08 Mar 2016 07:46:08 GMT using RSA key ID 398D6211 # gpg: Good signature from "Jason Wang (Jason Wang on RedHat) <jasowang@redhat.com>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 215D 46F4 8246 689E C77F 3562 EF04 965B 398D 6211 * remotes/jasowang/tags/net-pull-request: net: check packet payload length filter-buffer: Add status_changed callback processing filter: Add 'status' property for filter object rocker: allow user to specify rocker world by property rocker: add name field into WorldOps ale let world specify its name rocker: return -ENOMEM in case of some world alloc fails rocker: forbid to change world type net: netmap: probe netmap interface for virtio-net header net: simplify net_init_tap_one logic MAINTAINERS: Add entries for include/net/ files net: filter: correctly remove filter from the list during finalization net: ne2000: check ring buffer control registers Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/net/ne2000.c4
-rw-r--r--hw/net/rocker/rocker.c38
-rw-r--r--hw/net/rocker/rocker_fp.c5
-rw-r--r--hw/net/rocker/rocker_fp.h1
-rw-r--r--hw/net/rocker/rocker_of_dpa.c1
-rw-r--r--hw/net/rocker/rocker_world.c7
-rw-r--r--hw/net/rocker/rocker_world.h1
7 files changed, 49 insertions, 8 deletions
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index e408083..f0feaf9 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -155,6 +155,10 @@ static int ne2000_buffer_full(NE2000State *s)
{
int avail, index, boundary;
+ if (s->stop <= s->start) {
+ return 1;
+ }
+
index = s->curpag << 8;
boundary = s->boundary << 8;
if (index < boundary)
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
index f3e994d..30f2ce4 100644
--- a/hw/net/rocker/rocker.c
+++ b/hw/net/rocker/rocker.c
@@ -43,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 */
@@ -400,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]) {
@@ -1280,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);
@@ -1291,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,
@@ -1432,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]) {
@@ -1503,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/hw/net/rocker/rocker_fp.c b/hw/net/rocker/rocker_fp.c
index af37fef..0149899 100644
--- a/hw/net/rocker/rocker_fp.c
+++ b/hw/net/rocker/rocker_fp.c
@@ -186,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;
diff --git a/hw/net/rocker/rocker_fp.h b/hw/net/rocker/rocker_fp.h
index ab80fd8..04592bb 100644
--- a/hw/net/rocker/rocker_fp.h
+++ b/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/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c
index da3fc54..0a134eb 100644
--- a/hw/net/rocker/rocker_of_dpa.c
+++ b/hw/net/rocker/rocker_of_dpa.c
@@ -2614,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/hw/net/rocker/rocker_world.c b/hw/net/rocker/rocker_world.c
index 1ed0fcd..89777e9 100644
--- a/hw/net/rocker/rocker_world.c
+++ b/hw/net/rocker/rocker_world.c
@@ -98,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/hw/net/rocker/rocker_world.h b/hw/net/rocker/rocker_world.h
index 18d277b..58ade47 100644
--- a/hw/net/rocker/rocker_world.h
+++ b/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;