qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2] ne2000: Drop ne2000_can_receive


From: Fam Zheng
Subject: [Qemu-devel] [PATCH v2] ne2000: Drop ne2000_can_receive
Date: Fri, 3 Jul 2015 09:08:41 +0800

This moves the behavior of ne2000_can_receive to ne2000_receive. The
logic is when the NIC is stopped we drop the packet, when the buffer is
full we queue it and try flush later.

ne2000_buffer_full is determined by s->curpag, s->boundary, s->start and
s->stop. Add a flush in ne2000_ioport_write as they are all updated
there, except the advancing of s->curpag in ne2000_receive where
ne2000_buffer_full is already false.

Signed-off-by: Fam Zheng <address@hidden>
---
 hw/net/ne2000-isa.c |  1 -
 hw/net/ne2000.c     | 27 ++++++++++++++++-----------
 2 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c
index 17e7199..18b0644 100644
--- a/hw/net/ne2000-isa.c
+++ b/hw/net/ne2000-isa.c
@@ -44,7 +44,6 @@ typedef struct ISANE2000State {
 static NetClientInfo net_ne2000_isa_info = {
     .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
-    .can_receive = ne2000_can_receive,
     .receive = ne2000_receive,
 };
 
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index 3492db3..182e7ca 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -165,15 +165,6 @@ static int ne2000_buffer_full(NE2000State *s)
     return 0;
 }
 
-int ne2000_can_receive(NetClientState *nc)
-{
-    NE2000State *s = qemu_get_nic_opaque(nc);
-
-    if (s->cmd & E8390_STOP)
-        return 1;
-    return !ne2000_buffer_full(s);
-}
-
 #define MIN_BUF_SIZE 60
 
 ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
@@ -190,8 +181,12 @@ ssize_t ne2000_receive(NetClientState *nc, const uint8_t 
*buf, size_t size_)
     printf("NE2000: received len=%d\n", size);
 #endif
 
-    if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
+    if (s->cmd & E8390_STOP) {
         return -1;
+    }
+    if (ne2000_buffer_full(s)) {
+        return 0;
+    }
 
     /* XXX: check this */
     if (s->rxcr & 0x10) {
@@ -277,6 +272,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t 
addr, uint32_t val)
 {
     NE2000State *s = opaque;
     int offset, page, index;
+    bool try_flush = false;
 
     addr &= 0xf;
 #ifdef DEBUG_NE2000
@@ -309,19 +305,25 @@ static void ne2000_ioport_write(void *opaque, uint32_t 
addr, uint32_t val)
                 s->cmd &= ~E8390_TRANS;
                 ne2000_update_irq(s);
             }
+        } else {
+            try_flush = true;
         }
+
     } else {
         page = s->cmd >> 6;
         offset = addr | (page << 4);
         switch(offset) {
         case EN0_STARTPG:
             s->start = val << 8;
+            try_flush = true;
             break;
         case EN0_STOPPG:
             s->stop = val << 8;
+            try_flush = true;
             break;
         case EN0_BOUNDARY:
             s->boundary = val;
+            try_flush = true;
             break;
         case EN0_IMR:
             s->imr = val;
@@ -363,12 +365,16 @@ static void ne2000_ioport_write(void *opaque, uint32_t 
addr, uint32_t val)
             break;
         case EN1_CURPAG:
             s->curpag = val;
+            try_flush = true;
             break;
         case EN1_MULT ... EN1_MULT + 7:
             s->mult[offset - EN1_MULT] = val;
             break;
         }
     }
+    if (try_flush && !ne2000_buffer_full(s)) {
+        qemu_flush_queued_packets(qemu_get_queue(s->nic));
+    }
 }
 
 static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
@@ -705,7 +711,6 @@ void ne2000_setup_io(NE2000State *s, DeviceState *dev, 
unsigned size)
 static NetClientInfo net_ne2000_info = {
     .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
-    .can_receive = ne2000_can_receive,
     .receive = ne2000_receive,
 };
 
-- 
2.4.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]