]> Git Repo - qemu.git/blobdiff - hw/net/xilinx_axienet.c
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
[qemu.git] / hw / net / xilinx_axienet.c
index cd952d2514f5c5ed98514b3d76175b4cfbb8a28c..b6701844d37c8f44828211675bc31f67af46bd38 100644 (file)
  * THE SOFTWARE.
  */
 
+#include "qemu/osdep.h"
 #include "hw/sysbus.h"
+#include "qapi/error.h"
 #include "qemu/log.h"
 #include "net/net.h"
 #include "net/checksum.h"
-#include "qapi/qmp/qerror.h"
 
 #include "hw/stream.h"
 
@@ -402,6 +403,9 @@ struct XilinxAXIEnet {
 
     uint8_t rxapp[CONTROL_PAYLOAD_SIZE];
     uint32_t rxappsize;
+
+    /* Whether axienet_eth_rx_notify should flush incoming queue. */
+    bool need_flush;
 };
 
 static void axienet_rx_reset(XilinxAXIEnet *s)
@@ -659,10 +663,8 @@ static const MemoryRegionOps enet_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static int eth_can_rx(NetClientState *nc)
+static int eth_can_rx(XilinxAXIEnet *s)
 {
-    XilinxAXIEnet *s = qemu_get_nic_opaque(nc);
-
     /* RX enabled?  */
     return !s->rxsize && !axienet_rx_resetting(s) && axienet_rx_enabled(s);
 }
@@ -702,6 +704,10 @@ static void axienet_eth_rx_notify(void *opaque)
         s->rxpos += ret;
         if (!s->rxsize) {
             s->regs[R_IS] |= IS_RX_COMPLETE;
+            if (s->need_flush) {
+                s->need_flush = false;
+                qemu_flush_queued_packets(qemu_get_queue(s->nic));
+            }
         }
     }
     enet_update_irq(s);
@@ -722,6 +728,11 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
 
     DENET(qemu_log("%s: %zd bytes\n", __func__, size));
 
+    if (!eth_can_rx(s)) {
+        s->need_flush = true;
+        return 0;
+    }
+
     unicast = ~buf[0] & 0x1;
     broadcast = memcmp(buf, sa_bcast, 6) == 0;
     multicast = !unicast && !broadcast;
@@ -857,14 +868,6 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
     return size;
 }
 
-static void eth_cleanup(NetClientState *nc)
-{
-    /* FIXME.  */
-    XilinxAXIEnet *s = qemu_get_nic_opaque(nc);
-    g_free(s->rxmem);
-    g_free(s);
-}
-
 static size_t
 xilinx_axienet_control_stream_push(StreamSlave *obj, uint8_t *buf, size_t len)
 {
@@ -932,11 +935,9 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size)
 }
 
 static NetClientInfo net_xilinx_enet_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .type = NET_CLIENT_DRIVER_NIC,
     .size = sizeof(NICState),
-    .can_receive = eth_can_rx,
     .receive = eth_rx,
-    .cleanup = eth_cleanup,
 };
 
 static void xilinx_enet_realize(DeviceState *dev, Error **errp)
This page took 0.025798 seconds and 4 git commands to generate.