summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorJason Wang <jasowang@redhat.com>2012-03-05 11:09:08 +0800
committerMichael S. Tsirkin <mst@redhat.com>2012-03-16 01:04:51 +0200
commitff71f2e8cacefae99179993204172bc65e4303df (patch)
treee5793810fac0ff2597c02aba8ddfc393603a1782 /hw
parenteb46c5eda7d8b38c1407dd55f67cf4a6aa3b7b23 (diff)
rtl8139: do the network/host communication only in normal operating mode
According the spec, the card works in network/host communication mode only when both EEM1 and EEM0 are unset in 93C46 Command Register (normal op mode). So this patch check these bits before trying to receive packets. As some guest driver (such as linux, see cp_init_hw() in 8139cp.c) allocate rx ring after the recevier were enabled, this would cause our emulation codes tries to dma into guest memory when the rx descriptor is not properly configured. This patch fixes this. Signed-off-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/rtl8139.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index f3322ea167..4d553a8a59 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -791,6 +791,9 @@ static int rtl8139_can_receive(VLANClientState *nc)
return 1;
if (!rtl8139_receiver_enabled(s))
return 1;
+ /* network/host communication happens only in normal mode */
+ if ((s->Cfg9346 & Chip9346_op_mask) != Cfg9346_Normal)
+ return 0;
if (rtl8139_cp_receiver_enabled(s)) {
/* ??? Flow control not implemented in c+ mode.
@@ -833,6 +836,12 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
return -1;
}
+ /* check whether we are in normal mode */
+ if ((s->Cfg9346 & Chip9346_op_mask) != Cfg9346_Normal) {
+ DPRINTF("not in normal op mode\n");
+ return -1;
+ }
+
/* XXX: check this */
if (s->RxConfig & AcceptAllPhys) {
/* promiscuous: receive all */