* [Qemu-devel] [PATCH] hw/net: handle flow control in mcf_fec driver receiver
@ 2015-07-28 1:02 Greg Ungerer
2015-07-28 10:29 ` Stefan Hajnoczi
0 siblings, 1 reply; 2+ messages in thread
From: Greg Ungerer @ 2015-07-28 1:02 UTC (permalink / raw)
To: qemu-devel; +Cc: stefanha, Greg Ungerer
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.
Signed-off-by: Greg Ungerer <gerg@uclinux.org>
---
hw/net/mcf_fec.c | 45 ++++++++++++++++++++++++++++++++++-----------
1 file changed, 34 insertions(+), 11 deletions(-)
diff --git a/hw/net/mcf_fec.c b/hw/net/mcf_fec.c
index e63af1b..1775e76 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)
@@ -403,6 +405,31 @@ static int mcf_fec_can_receive(NetClientState *nc)
return s->rx_enabled;
}
+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);
@@ -417,7 +444,7 @@ static ssize_t mcf_fec_receive(NetClientState *nc, const uint8_t *buf, size_t si
DPRINTF("do_rx len %d\n", size);
if (!s->rx_enabled) {
- fprintf(stderr, "mcf_fec_receive: Unexpected packet\n");
+ return -1;
}
/* 4 bytes for the CRC. */
size += 4;
@@ -432,18 +459,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;
--
1.9.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [Qemu-devel] [PATCH] hw/net: handle flow control in mcf_fec driver receiver
2015-07-28 1:02 [Qemu-devel] [PATCH] hw/net: handle flow control in mcf_fec driver receiver Greg Ungerer
@ 2015-07-28 10:29 ` Stefan Hajnoczi
0 siblings, 0 replies; 2+ messages in thread
From: Stefan Hajnoczi @ 2015-07-28 10:29 UTC (permalink / raw)
To: Greg Ungerer; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 736 bytes --]
On Tue, Jul 28, 2015 at 11:02:54AM +1000, Greg Ungerer wrote:
> 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.
>
> Signed-off-by: Greg Ungerer <gerg@uclinux.org>
> ---
> hw/net/mcf_fec.c | 45 ++++++++++++++++++++++++++++++++++-----------
> 1 file changed, 34 insertions(+), 11 deletions(-)
Thanks, applied to my net tree:
https://github.com/stefanha/qemu/commits/net
Stefan
[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-07-28 10:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-28 1:02 [Qemu-devel] [PATCH] hw/net: handle flow control in mcf_fec driver receiver Greg Ungerer
2015-07-28 10:29 ` Stefan Hajnoczi
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).