From: Stefan Hajnoczi <stefanha@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
Stefan Hajnoczi <stefanha@redhat.com>,
Greg Ungerer <gerg@uclinux.org>
Subject: [Qemu-devel] [PULL for-2.4 1/2] hw/net: handle flow control in mcf_fec driver receiver
Date: Tue, 28 Jul 2015 13:26:06 +0100 [thread overview]
Message-ID: <1438086367-25905-2-git-send-email-stefanha@redhat.com> (raw)
In-Reply-To: <1438086367-25905-1-git-send-email-stefanha@redhat.com>
From: Greg Ungerer <gerg@uclinux.org>
The network mcf_fec driver emulated receive side method is not dealing
with network queue flow control properly.
Modify the receive side to check if we have enough space in the
descriptors to store the current packet. If not we process none of it
and return 0. When the guest frees up some buffers through its descriptors
we signal the qemu net layer to send more packets.
[Fixed coding style: 4-space indent and curly braces on if statement.
--Stefan]
Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Message-id: 1438045374-10358-1-git-send-email-gerg@uclinux.org
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
hw/net/mcf_fec.c | 44 ++++++++++++++++++++++++++++++++++----------
1 file changed, 34 insertions(+), 10 deletions(-)
diff --git a/hw/net/mcf_fec.c b/hw/net/mcf_fec.c
index 4e6939f..21928f9 100644
--- a/hw/net/mcf_fec.c
+++ b/hw/net/mcf_fec.c
@@ -196,12 +196,14 @@ static void mcf_fec_do_tx(mcf_fec_state *s)
static void mcf_fec_enable_rx(mcf_fec_state *s)
{
+ NetClientState *nc = qemu_get_queue(s->nic);
mcf_fec_bd bd;
mcf_fec_read_bd(&bd, s->rx_descriptor);
s->rx_enabled = ((bd.flags & FEC_BD_E) != 0);
- if (!s->rx_enabled)
- DPRINTF("RX buffer full\n");
+ if (s->rx_enabled) {
+ qemu_flush_queued_packets(nc);
+ }
}
static void mcf_fec_reset(mcf_fec_state *s)
@@ -397,6 +399,32 @@ static void mcf_fec_write(void *opaque, hwaddr addr,
mcf_fec_update(s);
}
+static int mcf_fec_have_receive_space(mcf_fec_state *s, size_t want)
+{
+ mcf_fec_bd bd;
+ uint32_t addr;
+
+ /* Walk descriptor list to determine if we have enough buffer */
+ addr = s->rx_descriptor;
+ while (want > 0) {
+ mcf_fec_read_bd(&bd, addr);
+ if ((bd.flags & FEC_BD_E) == 0) {
+ return 0;
+ }
+ if (want < s->emrbr) {
+ return 1;
+ }
+ want -= s->emrbr;
+ /* Advance to the next descriptor. */
+ if ((bd.flags & FEC_BD_W) != 0) {
+ addr = s->erdsr;
+ } else {
+ addr += 8;
+ }
+ }
+ return 0;
+}
+
static ssize_t mcf_fec_receive(NetClientState *nc, const uint8_t *buf, size_t size)
{
mcf_fec_state *s = qemu_get_nic_opaque(nc);
@@ -426,18 +454,14 @@ static ssize_t mcf_fec_receive(NetClientState *nc, const uint8_t *buf, size_t si
if (size > (s->rcr >> 16)) {
flags |= FEC_BD_LG;
}
+ /* Check if we have enough space in current descriptors */
+ if (!mcf_fec_have_receive_space(s, size)) {
+ return 0;
+ }
addr = s->rx_descriptor;
retsize = size;
while (size > 0) {
mcf_fec_read_bd(&bd, addr);
- if ((bd.flags & FEC_BD_E) == 0) {
- /* No descriptors available. Bail out. */
- /* FIXME: This is wrong. We should probably either save the
- remainder for when more RX buffers are available, or
- flag an error. */
- fprintf(stderr, "mcf_fec: Lost end of frame\n");
- break;
- }
buf_len = (size <= s->emrbr) ? size: s->emrbr;
bd.length = buf_len;
size -= buf_len;
--
2.4.3
next prev parent reply other threads:[~2015-07-28 12:26 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-28 12:26 [Qemu-devel] [PULL for-2.4 0/2] Net patches Stefan Hajnoczi
2015-07-28 12:26 ` Stefan Hajnoczi [this message]
2015-07-28 12:26 ` [Qemu-devel] [PULL for-2.4 2/2] xen: Drop net_rx_ok Stefan Hajnoczi
2015-07-28 20:09 ` [Qemu-devel] [PULL for-2.4 0/2] Net patches Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1438086367-25905-2-git-send-email-stefanha@redhat.com \
--to=stefanha@redhat.com \
--cc=gerg@uclinux.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).