From 4bf2c138ddefc6ff17f6c4b947320c60aa0c38a0 Mon Sep 17 00:00:00 2001 From: Hani Benhabiles Date: Thu, 9 Jan 2014 19:34:27 +0100 Subject: [PATCH 1/4] net: Use g_strdup_printf instead of snprintf. assign_name() in net/net.c is using snprintf + g_strdup to get the same result as g_strdup_printf. Signed-off-by: Hani Benhabiles Signed-off-by: Stefan Hajnoczi --- net/net.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/net/net.c b/net/net.c index f8db85f30b..2c3af202a6 100644 --- a/net/net.c +++ b/net/net.c @@ -164,7 +164,6 @@ void qemu_macaddr_default_if_unset(MACAddr *macaddr) static char *assign_name(NetClientState *nc1, const char *model) { NetClientState *nc; - char buf[256]; int id = 0; QTAILQ_FOREACH(nc, &net_clients, next) { @@ -176,9 +175,7 @@ static char *assign_name(NetClientState *nc1, const char *model) } } - snprintf(buf, sizeof(buf), "%s.%d", model, id); - - return g_strdup(buf); + return g_strdup_printf("%s.%d", model, id); } static void qemu_net_client_destructor(NetClientState *nc) From 2ad657e3f3af66def47554186a58f1748787a527 Mon Sep 17 00:00:00 2001 From: Roy Franz Date: Tue, 7 Jan 2014 20:19:51 -0800 Subject: [PATCH 2/4] Fix lan9118 TX "CMD A" handling The 9118 ethernet controller supports transmission of multi-buffer packets with arbitrary byte alignment of the start and end bytes. All writes to the packet fifo are 32 bits, so the controller discards bytes at the beginning and end of each buffer based on the 'Data start offset' and 'Buffer size' of the TX command 'A' format. This patch changes the buffer size and offset internal state variables to be updated on every "TX command A" write. Previously they were only updated for the first segment, which resulted incorrect behavior for packets with more than one segment. Each segment of the packet has its own CMD A command, with its own buffer size and start offset. Also update extraction of fields from the CMD A word to use extract32(). Signed-off-by: Roy Franz Reviewed-by: Peter Crosthwaite Signed-off-by: Stefan Hajnoczi --- hw/net/lan9118.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c index 2315f996d4..bb0c503a1b 100644 --- a/hw/net/lan9118.c +++ b/hw/net/lan9118.c @@ -727,14 +727,14 @@ static void tx_fifo_push(lan9118_state *s, uint32_t val) s->txp->cmd_a = val & 0x831f37ff; s->txp->fifo_used++; s->txp->state = TX_B; + s->txp->buffer_size = extract32(s->txp->cmd_a, 0, 11); + s->txp->offset = extract32(s->txp->cmd_a, 16, 5); break; case TX_B: if (s->txp->cmd_a & 0x2000) { /* First segment */ s->txp->cmd_b = val; s->txp->fifo_used++; - s->txp->buffer_size = s->txp->cmd_a & 0x7ff; - s->txp->offset = (s->txp->cmd_a >> 16) & 0x1f; /* End alignment does not include command words. */ n = (s->txp->buffer_size + s->txp->offset + 3) >> 2; switch ((n >> 24) & 3) { From c444dfabfc21cb5f093862100e333b808eea32e4 Mon Sep 17 00:00:00 2001 From: Roy Franz Date: Tue, 7 Jan 2014 20:19:52 -0800 Subject: [PATCH 3/4] Fix lan9118 buffer length handling The 9118 ethernet controller supports transmission of multi-buffer packets with arbitrary byte alignment of the start and end bytes. All writes to the packet fifo are 32 bits, so the controller discards bytes at the beginning and end of each buffer based on the 'Data start offset' and 'Buffer size' of the TX command 'A' format. This patch uses the provided buffer length to limit the bytes transmitted. Previously all the bytes of the last 32-bit word written to the TX fifo were added to the internal transmit buffer structure resulting in more bytes being transmitted than were submitted to the hardware in the command. This resulted in extra bytes being inserted into the middle of multi-buffer packets when the non-final buffers had non-32bit aligned ending addresses. Signed-off-by: Roy Franz Reviewed-by: Peter Crosthwaite Signed-off-by: Stefan Hajnoczi --- hw/net/lan9118.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c index bb0c503a1b..e528290b41 100644 --- a/hw/net/lan9118.c +++ b/hw/net/lan9118.c @@ -763,7 +763,7 @@ static void tx_fifo_push(lan9118_state *s, uint32_t val) if (s->txp->buffer_size <= 0 && s->txp->pad != 0) { s->txp->pad--; } else { - n = 4; + n = MIN(4, s->txp->buffer_size + s->txp->offset); while (s->txp->offset) { val >>= 8; n--; From 1f149e721feb617d14a3ee4f5911c47b29866a54 Mon Sep 17 00:00:00 2001 From: Kusanagi Kouichi Date: Sat, 18 Jan 2014 14:38:45 +0900 Subject: [PATCH 4/4] tap-linux: Get features once and use it many times Signed-off-by: Kusanagi Kouichi Signed-off-by: Stefan Hajnoczi --- net/tap-linux.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/net/tap-linux.c b/net/tap-linux.c index 36c09e24d8..812bf2dfc6 100644 --- a/net/tap-linux.c +++ b/net/tap-linux.c @@ -52,14 +52,17 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - if (ioctl(fd, TUNGETFEATURES, &features) == 0 && - features & IFF_ONE_QUEUE) { + if (ioctl(fd, TUNGETFEATURES, &features) == -1) { + error_report("warning: TUNGETFEATURES failed: %s", strerror(errno)); + features = 0; + } + + if (features & IFF_ONE_QUEUE) { ifr.ifr_flags |= IFF_ONE_QUEUE; } if (*vnet_hdr) { - if (ioctl(fd, TUNGETFEATURES, &features) == 0 && - features & IFF_VNET_HDR) { + if (features & IFF_VNET_HDR) { *vnet_hdr = 1; ifr.ifr_flags |= IFF_VNET_HDR; } else { @@ -82,8 +85,7 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, } if (mq_required) { - if ((ioctl(fd, TUNGETFEATURES, &features) != 0) || - !(features & IFF_MULTI_QUEUE)) { + if (!(features & IFF_MULTI_QUEUE)) { error_report("multiqueue required, but no kernel " "support for IFF_MULTI_QUEUE available"); close(fd);