提交 ef45c914 编写于 作者: J Jan Kiszka

pcnet: Properly handle TX requests during Link Fail

As long as we have no link and we aren't in internal loopback mode, no
packet must be sent. Instead, LCAR needs to be set in any active TX
descriptor and also CERR in CSR0.
Signed-off-by: NJan Kiszka <jan.kiszka@siemens.com>
上级 6655124d
......@@ -77,6 +77,7 @@ struct qemu_ether_header {
#define CSR_DTX(S) !!(((S)->csr[15])&0x0002)
#define CSR_LOOP(S) !!(((S)->csr[15])&0x0004)
#define CSR_DXMTFCS(S) !!(((S)->csr[15])&0x0008)
#define CSR_INTL(S) !!(((S)->csr[15])&0x0040)
#define CSR_DRCVPA(S) !!(((S)->csr[15])&0x2000)
#define CSR_DRCVBC(S) !!(((S)->csr[15])&0x4000)
#define CSR_PROM(S) !!(((S)->csr[15])&0x8000)
......@@ -1234,6 +1235,15 @@ static void pcnet_transmit(PCNetState *s)
if (BCR_SWSTYLE(s) != 1)
add_crc = GET_FIELD(tmd.status, TMDS, ADDFCS);
}
if (s->lnkst == 0 &&
(!CSR_LOOP(s) || (!CSR_INTL(s) && !BCR_TMAULOOP(s)))) {
SET_FIELD(&tmd.misc, TMDM, LCAR, 1);
SET_FIELD(&tmd.status, TMDS, ERR, 1);
SET_FIELD(&tmd.status, TMDS, OWN, 0);
s->csr[0] |= 0xa000; /* ERR | CERR */
s->xmit_pos = -1;
goto txdone;
}
if (!GET_FIELD(tmd.status, TMDS, ENP)) {
int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
......@@ -1262,6 +1272,7 @@ static void pcnet_transmit(PCNetState *s)
s->xmit_pos = -1;
}
txdone:
SET_FIELD(&tmd.status, TMDS, OWN, 0);
TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT)))
......
......@@ -20,6 +20,7 @@
#define BCR_SWS 20
#define BCR_PLAT 22
#define BCR_TMAULOOP(S) !!((S)->bcr[BCR_MC ] & 0x4000)
#define BCR_APROMWE(S) !!((S)->bcr[BCR_MC ] & 0x0100)
#define BCR_DWIO(S) !!((S)->bcr[BCR_BSBC] & 0x0080)
#define BCR_SSIZE32(S) !!((S)->bcr[BCR_SWS ] & 0x0100)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册