* [Qemu-devel] [PATCH] pcnet32 driver change, please test
@ 2007-03-02 20:09 Thiemo Seufer
2007-03-02 20:29 ` Thiemo Seufer
2007-03-02 23:14 ` Stuart Brady
0 siblings, 2 replies; 13+ messages in thread
From: Thiemo Seufer @ 2007-03-02 20:09 UTC (permalink / raw)
To: qemu-devel
Hello All,
I changed the pcnet32 driver to get rid of bitfields in its
implementation, now it works also on big endian host systems.
I tested only the 32 bit mode which is used by MIPS/Malta, and
I'm not sure if it still works in Lance mode (as e.g. used on SPARC).
So please test if it still works.
Thiemo
Index: qemu-cvs/hw/pcnet.c
===================================================================
--- qemu-cvs.orig/hw/pcnet.c
+++ qemu-cvs/hw/pcnet.c
@@ -77,14 +77,6 @@
void *dma_opaque;
};
-/* XXX: using bitfields for target memory structures is almost surely
- not portable, so it should be suppressed ASAP */
-#ifdef __GNUC__
-#define PACKED_FIELD(A) A __attribute__ ((packed))
-#else
-#error FixMe
-#endif
-
struct qemu_ether_header {
uint8_t ether_dhost[6];
uint8_t ether_shost[6];
@@ -183,223 +175,291 @@
};
struct pcnet_TMD {
- struct {
- unsigned tbadr:32;
- } tmd0;
- struct {
- unsigned PACKED_FIELD(bcnt:12), PACKED_FIELD(ones:4), PACKED_FIELD(res:7), PACKED_FIELD(bpe:1);
- unsigned PACKED_FIELD(enp:1), PACKED_FIELD(stp:1), PACKED_FIELD(def:1), PACKED_FIELD(one:1);
- unsigned PACKED_FIELD(ltint:1), PACKED_FIELD(nofcs:1), PACKED_FIELD(err:1), PACKED_FIELD(own:1);
- } tmd1;
- struct {
- unsigned PACKED_FIELD(trc:4), PACKED_FIELD(res:12);
- unsigned PACKED_FIELD(tdr:10), PACKED_FIELD(rtry:1), PACKED_FIELD(lcar:1);
- unsigned PACKED_FIELD(lcol:1), PACKED_FIELD(exdef:1), PACKED_FIELD(uflo:1), PACKED_FIELD(buff:1);
- } tmd2;
- struct {
- unsigned res:32;
- } tmd3;
+ uint32_t tbadr;
+ int16_t length;
+ int16_t status;
+ uint32_t misc;
+ uint32_t res;
};
+#define TMDL_BCNT_MASK 0x0fff
+#define TMDL_BCNT_SH 0
+#define TMDL_ONES_MASK 0xf000
+#define TMDL_ONES_SH 12
+
+#define TMDS_BPE_MASK 0x0080
+#define TMDS_BPE_SH 7
+#define TMDS_ENP_MASK 0x0100
+#define TMDS_ENP_SH 8
+#define TMDS_STP_MASK 0x0200
+#define TMDS_STP_SH 9
+#define TMDS_DEF_MASK 0x0400
+#define TMDS_DEF_SH 10
+#define TMDS_ONE_MASK 0x0800
+#define TMDS_ONE_SH 11
+#define TMDS_LTINT_MASK 0x1000
+#define TMDS_LTINT_SH 12
+#define TMDS_NOFCS_MASK 0x2000
+#define TMDS_NOFCS_SH 13
+#define TMDS_ERR_MASK 0x4000
+#define TMDS_ERR_SH 14
+#define TMDS_OWN_MASK 0x8000
+#define TMDS_OWN_SH 15
+
+#define TMDM_TRC_MASK 0x0000000f
+#define TMDM_TRC_SH 0
+#define TMDM_TDR_MASK 0x03ff0000
+#define TMDM_TDR_SH 16
+#define TMDM_RTRY_MASK 0x04000000
+#define TMDM_RTRY_SH 26
+#define TMDM_LCAR_MASK 0x08000000
+#define TMDM_LCAR_SH 27
+#define TMDM_LCOL_MASK 0x10000000
+#define TMDM_LCOL_SH 28
+#define TMDM_EXDEF_MASK 0x20000000
+#define TMDM_EXDEF_SH 29
+#define TMDM_UFLO_MASK 0x40000000
+#define TMDM_UFLO_SH 30
+#define TMDM_BUFF_MASK 0x80000000
+#define TMDM_BUFF_SH 31
+
struct pcnet_RMD {
- struct {
- unsigned rbadr:32;
- } rmd0;
- struct {
- unsigned PACKED_FIELD(bcnt:12), PACKED_FIELD(ones:4), PACKED_FIELD(res:4);
- unsigned PACKED_FIELD(bam:1), PACKED_FIELD(lafm:1), PACKED_FIELD(pam:1), PACKED_FIELD(bpe:1);
- unsigned PACKED_FIELD(enp:1), PACKED_FIELD(stp:1), PACKED_FIELD(buff:1), PACKED_FIELD(crc:1);
- unsigned PACKED_FIELD(oflo:1), PACKED_FIELD(fram:1), PACKED_FIELD(err:1), PACKED_FIELD(own:1);
- } rmd1;
- struct {
- unsigned PACKED_FIELD(mcnt:12), PACKED_FIELD(zeros:4);
- unsigned PACKED_FIELD(rpc:8), PACKED_FIELD(rcc:8);
- } rmd2;
- struct {
- unsigned res:32;
- } rmd3;
+ uint32_t rbadr;
+ int16_t buf_length;
+ int16_t status;
+ uint32_t msg_length;
+ uint32_t res;
};
+#define RMDL_BCNT_MASK 0x0fff
+#define RMDL_BCNT_SH 0
+#define RMDL_ONES_MASK 0xf000
+#define RMDL_ONES_SH 12
+
+#define RMDS_BAM_MASK 0x0010
+#define RMDS_BAM_SH 4
+#define RMDS_LFAM_MASK 0x0020
+#define RMDS_LFAM_SH 5
+#define RMDS_PAM_MASK 0x0040
+#define RMDS_PAM_SH 6
+#define RMDS_BPE_MASK 0x0080
+#define RMDS_BPE_SH 7
+#define RMDS_ENP_MASK 0x0100
+#define RMDS_ENP_SH 8
+#define RMDS_STP_MASK 0x0200
+#define RMDS_STP_SH 9
+#define RMDS_BUFF_MASK 0x0400
+#define RMDS_BUFF_SH 10
+#define RMDS_CRC_MASK 0x0800
+#define RMDS_CRC_SH 11
+#define RMDS_OFLO_MASK 0x1000
+#define RMDS_OFLO_SH 12
+#define RMDS_FRAM_MASK 0x2000
+#define RMDS_FRAM_SH 13
+#define RMDS_ERR_MASK 0x4000
+#define RMDS_ERR_SH 14
+#define RMDS_OWN_MASK 0x8000
+#define RMDS_OWN_SH 15
+
+#define RMDM_MCNT_MASK 0x00000fff
+#define RMDM_MCNT_SH 0
+#define RMDM_ZEROS_MASK 0x0000f000
+#define RMDM_ZEROS_SH 12
+#define RMDM_RPC_MASK 0x00ff0000
+#define RMDM_RPC_SH 16
+#define RMDM_RCC_MASK 0xff000000
+#define RMDM_RCC_SH 24
+
+#define SET_FIELD(regp, name, field, value) \
+ (*(regp) = (*(regp) & ~(name ## _ ## field ## _MASK)) \
+ | ((value) << name ## _ ## field ## _SH))
+
+#define GET_FIELD(reg, name, field) \
+ (((reg) & name ## _ ## field ## _MASK) >> name ## _ ## field ## _SH)
-#define PRINT_TMD(T) printf( \
- "TMD0 : TBADR=0x%08x\n" \
+#define PRINT_TMD(T) printf( \
+ "TMD0 : TBADR=0x%08x\n" \
"TMD1 : OWN=%d, ERR=%d, FCS=%d, LTI=%d, " \
"ONE=%d, DEF=%d, STP=%d, ENP=%d,\n" \
" BPE=%d, BCNT=%d\n" \
"TMD2 : BUF=%d, UFL=%d, EXD=%d, LCO=%d, " \
"LCA=%d, RTR=%d,\n" \
" TDR=%d, TRC=%d\n", \
- (T)->tmd0.tbadr, \
- (T)->tmd1.own, (T)->tmd1.err, (T)->tmd1.nofcs, \
- (T)->tmd1.ltint, (T)->tmd1.one, (T)->tmd1.def, \
- (T)->tmd1.stp, (T)->tmd1.enp, (T)->tmd1.bpe, \
- 4096-(T)->tmd1.bcnt, \
- (T)->tmd2.buff, (T)->tmd2.uflo, (T)->tmd2.exdef,\
- (T)->tmd2.lcol, (T)->tmd2.lcar, (T)->tmd2.rtry, \
- (T)->tmd2.tdr, (T)->tmd2.trc)
+ (T)->tbadr, \
+ GET_FIELD((T)->status, TMDS, OWN), \
+ GET_FIELD((T)->status, TMDS, ERR), \
+ GET_FIELD((T)->status, TMDS, NOFCS), \
+ GET_FIELD((T)->status, TMDS, LTINT), \
+ GET_FIELD((T)->status, TMDS, ONE), \
+ GET_FIELD((T)->status, TMDS, DEF), \
+ GET_FIELD((T)->status, TMDS, STP), \
+ GET_FIELD((T)->status, TMDS, ENP), \
+ GET_FIELD((T)->status, TMDS, BPE), \
+ 4096-GET_FIELD((T)->length, TMDL, BCNT), \
+ GET_FIELD((T)->misc, TMDM, BUFF), \
+ GET_FIELD((T)->misc, TMDM, UFLO), \
+ GET_FIELD((T)->misc, TMDM, EXDEF), \
+ GET_FIELD((T)->misc, TMDM, LCOL), \
+ GET_FIELD((T)->misc, TMDM, LCAR), \
+ GET_FIELD((T)->misc, TMDM, RTRY), \
+ GET_FIELD((T)->misc, TMDM, TDR), \
+ GET_FIELD((T)->misc, TMDM, TRC))
-#define PRINT_RMD(R) printf( \
- "RMD0 : RBADR=0x%08x\n" \
+#define PRINT_RMD(R) printf( \
+ "RMD0 : RBADR=0x%08x\n" \
"RMD1 : OWN=%d, ERR=%d, FRAM=%d, OFLO=%d, " \
"CRC=%d, BUFF=%d, STP=%d, ENP=%d,\n " \
- "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n" \
+ "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n" \
"RMD2 : RCC=%d, RPC=%d, MCNT=%d, ZEROS=%d\n", \
- (R)->rmd0.rbadr, \
- (R)->rmd1.own, (R)->rmd1.err, (R)->rmd1.fram, \
- (R)->rmd1.oflo, (R)->rmd1.crc, (R)->rmd1.buff, \
- (R)->rmd1.stp, (R)->rmd1.enp, (R)->rmd1.bpe, \
- (R)->rmd1.pam, (R)->rmd1.lafm, (R)->rmd1.bam, \
- (R)->rmd1.ones, 4096-(R)->rmd1.bcnt, \
- (R)->rmd2.rcc, (R)->rmd2.rpc, (R)->rmd2.mcnt, \
- (R)->rmd2.zeros)
+ (R)->rbadr, \
+ GET_FIELD((R)->status, RMDS, OWN), \
+ GET_FIELD((R)->status, RMDS, ERR), \
+ GET_FIELD((R)->status, RMDS, FRAM), \
+ GET_FIELD((R)->status, RMDS, OFLO), \
+ GET_FIELD((R)->status, RMDS, CRC), \
+ GET_FIELD((R)->status, RMDS, BUFF), \
+ GET_FIELD((R)->status, RMDS, STP), \
+ GET_FIELD((R)->status, RMDS, ENP), \
+ GET_FIELD((R)->status, RMDS, BPE), \
+ GET_FIELD((R)->status, RMDS, PAM), \
+ GET_FIELD((R)->status, RMDS, LFAM), \
+ GET_FIELD((R)->status, RMDS, BAM), \
+ GET_FIELD((R)->buf_length, RMDL, ONES), \
+ 4096-GET_FIELD((R)->buf_length, RMDL, BCNT), \
+ GET_FIELD((R)->msg_length, RMDM, RCC), \
+ GET_FIELD((R)->msg_length, RMDM, RPC), \
+ GET_FIELD((R)->msg_length, RMDM, MCNT), \
+ GET_FIELD((R)->msg_length, RMDM, ZEROS))
-static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd1,
+static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd,
target_phys_addr_t addr)
{
- uint32_t *tmd = (uint32_t *)tmd1;
-
- if (!BCR_SWSTYLE(s)) {
- uint16_t xda[4];
- s->phys_mem_read(s->dma_opaque, addr,
- (void *)&xda[0], sizeof(xda), 0);
- le16_to_cpus(&xda[0]);
- le16_to_cpus(&xda[1]);
- le16_to_cpus(&xda[2]);
- le16_to_cpus(&xda[3]);
- tmd[0] = (xda[0]&0xffff) |
- ((xda[1]&0x00ff) << 16);
- tmd[1] = (xda[2]&0xffff)|
- ((xda[1] & 0xff00) << 16);
- tmd[2] =
- (xda[3] & 0xffff) << 16;
- tmd[3] = 0;
+ if (!BCR_SSIZE32(s)) {
+ struct {
+ uint32_t tbadr;
+ int16_t length;
+ int16_t status;
+ } xda;
+ s->phys_mem_read(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
+ tmd->tbadr = le32_to_cpu(xda.tbadr) & 0xffffff;
+ tmd->length = le16_to_cpu(xda.length);
+ tmd->status = (le32_to_cpu(xda.tbadr) >> 16) & 0xff00;
+ tmd->misc = le16_to_cpu(xda.status) << 16;
+ tmd->res = 0;
} else {
- uint32_t xda[4];
- s->phys_mem_read(s->dma_opaque, addr,
- (void *)&xda[0], sizeof(xda), 0);
- le32_to_cpus(&xda[0]);
- le32_to_cpus(&xda[1]);
- le32_to_cpus(&xda[2]);
- le32_to_cpus(&xda[3]);
- if (BCR_SWSTYLE(s) != 3) {
- memcpy(tmd, xda, sizeof(xda));
- } else {
- tmd[0] = xda[2];
- tmd[1] = xda[1];
- tmd[2] = xda[0];
- tmd[3] = xda[3];
+ s->phys_mem_read(s->dma_opaque, addr, (void *)tmd, sizeof(*tmd), 0);
+ le32_to_cpus(&tmd->tbadr);
+ le16_to_cpus(&tmd->length);
+ le16_to_cpus(&tmd->status);
+ le32_to_cpus(&tmd->misc);
+ le32_to_cpus(&tmd->res);
+ if (BCR_SWSTYLE(s) == 3) {
+ uint32_t tmp = tmd->tbadr;
+ tmd->tbadr = tmd->misc;
+ tmd->misc = tmp;
}
}
}
-static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd1,
+static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd,
target_phys_addr_t addr)
{
- const uint32_t *tmd = (const uint32_t *)tmd1;
- if (!BCR_SWSTYLE(s)) {
- uint16_t xda[4];
- xda[0] = tmd[0] & 0xffff;
- xda[1] = ((tmd[0]>>16)&0x00ff) |
- ((tmd[1]>>16)&0xff00);
- xda[2] = tmd[1] & 0xffff;
- xda[3] = tmd[2] >> 16;
- cpu_to_le16s(&xda[0]);
- cpu_to_le16s(&xda[1]);
- cpu_to_le16s(&xda[2]);
- cpu_to_le16s(&xda[3]);
- s->phys_mem_write(s->dma_opaque, addr,
- (void *)&xda[0], sizeof(xda), 0);
+ if (!BCR_SSIZE32(s)) {
+ struct {
+ uint32_t tbadr;
+ int16_t length;
+ int16_t status;
+ } xda;
+ xda.tbadr = cpu_to_le32((tmd->tbadr & 0xffffff) |
+ ((tmd->status & 0xff00) << 16));
+ xda.length = cpu_to_le16(tmd->length);
+ xda.status = cpu_to_le16(tmd->misc >> 16);
+ s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
} else {
- uint32_t xda[4];
- if (BCR_SWSTYLE(s) != 3) {
- memcpy(xda, tmd, sizeof(xda));
- } else {
- xda[0] = tmd[2];
- xda[1] = tmd[1];
- xda[2] = tmd[0];
- xda[3] = tmd[3];
+ struct {
+ uint32_t tbadr;
+ int16_t length;
+ int16_t status;
+ uint32_t misc;
+ uint32_t res;
+ } xda;
+ xda.tbadr = cpu_to_le32(tmd->tbadr);
+ xda.length = cpu_to_le16(tmd->length);
+ xda.status = cpu_to_le16(tmd->status);
+ xda.misc = cpu_to_le32(tmd->misc);
+ xda.res = cpu_to_le32(tmd->res);
+ if (BCR_SWSTYLE(s) == 3) {
+ uint32_t tmp = xda.tbadr;
+ xda.tbadr = xda.misc;
+ xda.misc = tmp;
}
- cpu_to_le32s(&xda[0]);
- cpu_to_le32s(&xda[1]);
- cpu_to_le32s(&xda[2]);
- cpu_to_le32s(&xda[3]);
- s->phys_mem_write(s->dma_opaque, addr,
- (void *)&xda[0], sizeof(xda), 0);
+ s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
}
}
-static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd1,
+static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd,
target_phys_addr_t addr)
{
- uint32_t *rmd = (uint32_t *)rmd1;
-
- if (!BCR_SWSTYLE(s)) {
- uint16_t rda[4];
- s->phys_mem_read(s->dma_opaque, addr,
- (void *)&rda[0], sizeof(rda), 0);
- le16_to_cpus(&rda[0]);
- le16_to_cpus(&rda[1]);
- le16_to_cpus(&rda[2]);
- le16_to_cpus(&rda[3]);
- rmd[0] = (rda[0]&0xffff)|
- ((rda[1] & 0x00ff) << 16);
- rmd[1] = (rda[2]&0xffff)|
- ((rda[1] & 0xff00) << 16);
- rmd[2] = rda[3] & 0xffff;
- rmd[3] = 0;
+ if (!BCR_SSIZE32(s)) {
+ struct {
+ uint32_t rbadr;
+ int16_t buf_length;
+ int16_t msg_length;
+ } rda;
+ s->phys_mem_read(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
+ rmd->rbadr = le32_to_cpu(rda.rbadr) & 0xffffff;
+ rmd->buf_length = le16_to_cpu(rda.buf_length);
+ rmd->status = (le32_to_cpu(rda.rbadr) >> 16) & 0xff00;
+ rmd->msg_length = le16_to_cpu(rda.msg_length);
+ rmd->res = 0;
} else {
- uint32_t rda[4];
- s->phys_mem_read(s->dma_opaque, addr,
- (void *)&rda[0], sizeof(rda), 0);
- le32_to_cpus(&rda[0]);
- le32_to_cpus(&rda[1]);
- le32_to_cpus(&rda[2]);
- le32_to_cpus(&rda[3]);
- if (BCR_SWSTYLE(s) != 3) {
- memcpy(rmd, rda, sizeof(rda));
- } else {
- rmd[0] = rda[2];
- rmd[1] = rda[1];
- rmd[2] = rda[0];
- rmd[3] = rda[3];
+ s->phys_mem_read(s->dma_opaque, addr, (void *)rmd, sizeof(*rmd), 0);
+ le32_to_cpus(&rmd->rbadr);
+ le16_to_cpus(&rmd->buf_length);
+ le16_to_cpus(&rmd->status);
+ le32_to_cpus(&rmd->msg_length);
+ le32_to_cpus(&rmd->res);
+ if (BCR_SWSTYLE(s) == 3) {
+ uint32_t tmp = rmd->rbadr;
+ rmd->rbadr = rmd->msg_length;
+ rmd->msg_length = tmp;
}
}
}
-static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd1,
+static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
target_phys_addr_t addr)
{
- const uint32_t *rmd = (const uint32_t *)rmd1;
-
- if (!BCR_SWSTYLE(s)) {
- uint16_t rda[4];
- rda[0] = rmd[0] & 0xffff;
- rda[1] = ((rmd[0]>>16)&0xff)|
- ((rmd[1]>>16)&0xff00);
- rda[2] = rmd[1] & 0xffff;
- rda[3] = rmd[2] & 0xffff;
- cpu_to_le16s(&rda[0]);
- cpu_to_le16s(&rda[1]);
- cpu_to_le16s(&rda[2]);
- cpu_to_le16s(&rda[3]);
- s->phys_mem_write(s->dma_opaque, addr,
- (void *)&rda[0], sizeof(rda), 0);
+ if (!BCR_SSIZE32(s)) {
+ struct {
+ uint32_t rbadr;
+ int16_t buf_length;
+ int16_t msg_length;
+ } rda;
+ rda.rbadr = cpu_to_le32((rmd->rbadr & 0xffffff) |
+ ((rmd->status & 0xff00) << 16));
+ rda.buf_length = cpu_to_le16(rmd->buf_length);
+ rda.msg_length = cpu_to_le16(rmd->msg_length);
+ s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
} else {
- uint32_t rda[4];
- if (BCR_SWSTYLE(s) != 3) {
- memcpy(rda, rmd, sizeof(rda));
- } else {
- rda[0] = rmd[2];
- rda[1] = rmd[1];
- rda[2] = rmd[0];
- rda[3] = rmd[3];
+ struct {
+ uint32_t rbadr;
+ int16_t buf_length;
+ int16_t status;
+ uint32_t msg_length;
+ uint32_t res;
+ } rda;
+ rda.rbadr = cpu_to_le32(rmd->rbadr);
+ rda.buf_length = cpu_to_le16(rmd->buf_length);
+ rda.status = cpu_to_le16(rmd->status);
+ rda.msg_length = cpu_to_le32(rmd->msg_length);
+ rda.res = cpu_to_le32(rmd->res);
+ if (BCR_SWSTYLE(s) == 3) {
+ uint32_t tmp = rda.rbadr;
+ rda.rbadr = rda.msg_length;
+ rda.msg_length = tmp;
}
- cpu_to_le32s(&rda[0]);
- cpu_to_le32s(&rda[1]);
- cpu_to_le32s(&rda[2]);
- cpu_to_le32s(&rda[3]);
- s->phys_mem_write(s->dma_opaque, addr,
- (void *)&rda[0], sizeof(rda), 0);
+ s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
}
}
@@ -417,14 +477,14 @@
#define CHECK_RMD(ADDR,RES) do { \
struct pcnet_RMD rmd; \
RMDLOAD(&rmd,(ADDR)); \
- (RES) |= (rmd.rmd1.ones != 15) \
- || (rmd.rmd2.zeros != 0); \
+ (RES) |= (GET_FIELD(rmd.buf_length, RMDL, ONES) != 15) \
+ || (GET_FIELD(rmd.msg_length, RMDM, ZEROS) != 0); \
} while (0)
#define CHECK_TMD(ADDR,RES) do { \
struct pcnet_TMD tmd; \
TMDLOAD(&tmd,(ADDR)); \
- (RES) |= (tmd.tmd1.ones != 15); \
+ (RES) |= (GET_FIELD(tmd.length, TMDL, ONES) != 15); \
} while (0)
#else
@@ -434,8 +494,8 @@
case 0x00: \
do { \
uint16_t rda[4]; \
- s->phys_mem_read(s->dma_opaque, (ADDR), \
- (void *)&rda[0], sizeof(rda), 0); \
+ s->phys_mem_read(s->dma_opaque, (ADDR), \
+ (void *)&rda[0], sizeof(rda), 0); \
(RES) |= (rda[2] & 0xf000)!=0xf000; \
(RES) |= (rda[3] & 0xf000)!=0x0000; \
} while (0); \
@@ -444,7 +504,7 @@
case 0x02: \
do { \
uint32_t rda[4]; \
- s->phys_mem_read(s->dma_opaque, (ADDR), \
+ s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&rda[0], sizeof(rda), 0); \
(RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
(RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
@@ -453,7 +513,7 @@
case 0x03: \
do { \
uint32_t rda[4]; \
- s->phys_mem_read(s->dma_opaque, (ADDR), \
+ s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&rda[0], sizeof(rda), 0); \
(RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
(RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
@@ -467,9 +527,9 @@
case 0x00: \
do { \
uint16_t xda[4]; \
- s->phys_mem_read(s->dma_opaque, (ADDR), \
- (void *)&xda[0], sizeof(xda), 0); \
- (RES) |= (xda[2] & 0xf000)!=0xf000;\
+ s->phys_mem_read(s->dma_opaque, (ADDR), \
+ (void *)&xda[0], sizeof(xda), 0); \
+ (RES) |= (xda[2] & 0xf000)!=0xf000; \
} while (0); \
break; \
case 0x01: \
@@ -477,8 +537,8 @@
case 0x03: \
do { \
uint32_t xda[4]; \
- s->phys_mem_read(s->dma_opaque, (ADDR), \
- (void *)&xda[0], sizeof(xda), 0); \
+ s->phys_mem_read(s->dma_opaque, (ADDR), \
+ (void *)&xda[0], sizeof(xda), 0); \
(RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
} while (0); \
break; \
@@ -488,15 +548,15 @@
#endif
#define PRINT_PKTHDR(BUF) do { \
- struct qemu_ether_header *hdr = (void *)(BUF); \
- printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \
- "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \
- "type=0x%04x\n", \
+ struct qemu_ether_header *hdr = (void *)(BUF); \
+ printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \
+ "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \
+ "type=0x%04x\n", \
hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
- be16_to_cpu(hdr->ether_type)); \
+ be16_to_cpu(hdr->ether_type)); \
} while (0)
#define MULTICAST_FILTER_LEN 8
@@ -770,7 +830,7 @@
static void pcnet_init(PCNetState *s)
{
int rlen, tlen;
- uint16_t *padr, *ladrf, mode;
+ uint16_t padr[3], ladrf[4], mode;
uint32_t rdra, tdra;
#ifdef PCNET_DEBUG
@@ -781,22 +841,30 @@
struct pcnet_initblk32 initblk;
s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
(uint8_t *)&initblk, sizeof(initblk), 0);
- mode = initblk.mode;
+ mode = le16_to_cpu(initblk.mode);
rlen = initblk.rlen >> 4;
tlen = initblk.tlen >> 4;
- ladrf = initblk.ladrf;
- padr = initblk.padr;
+ ladrf[0] = le16_to_cpu(initblk.ladrf[0]);
+ ladrf[1] = le16_to_cpu(initblk.ladrf[1]);
+ ladrf[2] = le16_to_cpu(initblk.ladrf[2]);
+ ladrf[3] = le16_to_cpu(initblk.ladrf[3]);
+ padr[0] = le16_to_cpu(initblk.padr[0]);
+ padr[1] = le16_to_cpu(initblk.padr[1]);
+ padr[2] = le16_to_cpu(initblk.padr[2]);
rdra = le32_to_cpu(initblk.rdra);
tdra = le32_to_cpu(initblk.tdra);
- s->rdra = PHYSADDR(s,initblk.rdra);
- s->tdra = PHYSADDR(s,initblk.tdra);
} else {
struct pcnet_initblk16 initblk;
s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
(uint8_t *)&initblk, sizeof(initblk), 0);
- mode = initblk.mode;
- ladrf = initblk.ladrf;
- padr = initblk.padr;
+ mode = le16_to_cpu(initblk.mode);
+ ladrf[0] = le16_to_cpu(initblk.ladrf[0]);
+ ladrf[1] = le16_to_cpu(initblk.ladrf[1]);
+ ladrf[2] = le16_to_cpu(initblk.ladrf[2]);
+ ladrf[3] = le16_to_cpu(initblk.ladrf[3]);
+ padr[0] = le16_to_cpu(initblk.padr[0]);
+ padr[1] = le16_to_cpu(initblk.padr[1]);
+ padr[2] = le16_to_cpu(initblk.padr[2]);
rdra = le32_to_cpu(initblk.rdra);
tdra = le32_to_cpu(initblk.tdra);
rlen = rdra >> 29;
@@ -804,22 +872,22 @@
rdra &= 0x00ffffff;
tdra &= 0x00ffffff;
}
-
+
#if defined(PCNET_DEBUG)
- printf("rlen=%d tlen=%d\n",
- rlen, tlen);
+ printf("rlen=%d tlen=%d\n", rlen, tlen);
#endif
+
CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512;
CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512;
s->csr[ 6] = (tlen << 12) | (rlen << 8);
- s->csr[15] = le16_to_cpu(mode);
- s->csr[ 8] = le16_to_cpu(ladrf[0]);
- s->csr[ 9] = le16_to_cpu(ladrf[1]);
- s->csr[10] = le16_to_cpu(ladrf[2]);
- s->csr[11] = le16_to_cpu(ladrf[3]);
- s->csr[12] = le16_to_cpu(padr[0]);
- s->csr[13] = le16_to_cpu(padr[1]);
- s->csr[14] = le16_to_cpu(padr[2]);
+ s->csr[15] = mode;
+ s->csr[ 8] = ladrf[0];
+ s->csr[ 9] = ladrf[1];
+ s->csr[10] = ladrf[2];
+ s->csr[11] = ladrf[3];
+ s->csr[12] = padr[0];
+ s->csr[13] = padr[1];
+ s->csr[14] = padr[2];
s->rdra = PHYSADDR(s, rdra);
s->tdra = PHYSADDR(s, tdra);
@@ -914,12 +982,12 @@
if (CSR_CRDA(s)) {
struct pcnet_RMD rmd;
RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
- CSR_CRBC(s) = rmd.rmd1.bcnt;
- CSR_CRST(s) = ((uint32_t *)&rmd)[1] >> 16;
+ CSR_CRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
+ CSR_CRST(s) = rmd.status;
#ifdef PCNET_DEBUG_RMD_X
- printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMD1=0x%08x RMD2=0x%08x\n",
+ printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMDL=0x%04x RMDS=0x%04x RMDM=0x%08x\n",
PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
- ((uint32_t *)&rmd)[1], ((uint32_t *)&rmd)[2]);
+ rmd.buf_length, rmd.status, rmd.msg_length);
PRINT_RMD(&rmd);
#endif
} else {
@@ -929,8 +997,8 @@
if (CSR_NRDA(s)) {
struct pcnet_RMD rmd;
RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
- CSR_NRBC(s) = rmd.rmd1.bcnt;
- CSR_NRST(s) = ((uint32_t *)&rmd)[1] >> 16;
+ CSR_NRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
+ CSR_NRST(s) = rmd.status;
} else {
CSR_NRBC(s) = CSR_NRST(s) = 0;
}
@@ -943,7 +1011,7 @@
if (s->tdra) {
target_phys_addr_t cxda = s->tdra +
(CSR_XMTRL(s) - CSR_XMTRC(s)) *
- (BCR_SWSTYLE(s) ? 16 : 8 );
+ (BCR_SWSTYLE(s) ? 16 : 8);
int bad = 0;
CHECK_TMD(PHYSADDR(s, cxda),bad);
if (!bad) {
@@ -955,8 +1023,7 @@
}
s->csr[34] = cxda & 0xffff;
s->csr[35] = cxda >> 16;
-#ifdef PCNET_DEBUG
- } else {
+#ifdef PCNET_DEBUG_X
printf("pcnet: BAD TMD XDA=0x%08x\n", PHYSADDR(s,cxda));
#endif
}
@@ -967,8 +1034,8 @@
TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
- CSR_CXBC(s) = tmd.tmd1.bcnt;
- CSR_CXST(s) = ((uint32_t *)&tmd)[1] >> 16;
+ CSR_CXBC(s) = GET_FIELD(tmd.length, TMDL, BCNT);
+ CSR_CXST(s) = tmd.status;
} else {
CSR_CXBC(s) = CSR_CXST(s) = 0;
}
@@ -1029,7 +1096,7 @@
(CSR_RCVRL(s) - rcvrc) *
(BCR_SWSTYLE(s) ? 16 : 8 );
RMDLOAD(&rmd, PHYSADDR(s,nrda));
- if (rmd.rmd1.own) {
+ if (GET_FIELD(rmd.status, RMDS, OWN)) {
#ifdef PCNET_DEBUG_RMD
printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",
rcvrc, CSR_RCVRC(s));
@@ -1086,14 +1153,15 @@
RMDLOAD(&rmd, PHYSADDR(s,crda));
/*if (!CSR_LAPPEN(s))*/
- rmd.rmd1.stp = 1;
+ SET_FIELD(&rmd.status, RMDS, STP, 1);
#define PCNET_RECV_STORE() do { \
- int count = MIN(4096 - rmd.rmd1.bcnt,size); \
- target_phys_addr_t rbadr = PHYSADDR(s, rmd.rmd0.rbadr); \
- s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \
+ int count = MIN(4096 - GET_FIELD(rmd.buf_length, RMDL, BCNT),size); \
+ target_phys_addr_t rbadr = PHYSADDR(s, rmd.rbadr); \
+ s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \
src += count; size -= count; \
- rmd.rmd2.mcnt = count; rmd.rmd1.own = 0; \
+ SET_FIELD(&rmd.msg_length, RMDM, MCNT, count); \
+ SET_FIELD(&rmd.status, RMDS, OWN, 0); \
RMDSTORE(&rmd, PHYSADDR(s,crda)); \
pktcount++; \
} while (0)
@@ -1102,12 +1170,12 @@
if ((size > 0) && CSR_NRDA(s)) {
target_phys_addr_t nrda = CSR_NRDA(s);
RMDLOAD(&rmd, PHYSADDR(s,nrda));
- if (rmd.rmd1.own) {
+ if (GET_FIELD(rmd.status, RMDS, OWN)) {
crda = nrda;
PCNET_RECV_STORE();
if ((size > 0) && (nrda=CSR_NNRD(s))) {
RMDLOAD(&rmd, PHYSADDR(s,nrda));
- if (rmd.rmd1.own) {
+ if (GET_FIELD(rmd.status, RMDS, OWN)) {
crda = nrda;
PCNET_RECV_STORE();
}
@@ -1119,14 +1187,14 @@
RMDLOAD(&rmd, PHYSADDR(s,crda));
if (size == 0) {
- rmd.rmd1.enp = 1;
- rmd.rmd1.pam = !CSR_PROM(s) && is_padr;
- rmd.rmd1.lafm = !CSR_PROM(s) && is_ladr;
- rmd.rmd1.bam = !CSR_PROM(s) && is_bcast;
+ SET_FIELD(&rmd.status, RMDS, ENP, 1);
+ SET_FIELD(&rmd.status, RMDS, PAM, !CSR_PROM(s) && is_padr);
+ SET_FIELD(&rmd.status, RMDS, LFAM, !CSR_PROM(s) && is_ladr);
+ SET_FIELD(&rmd.status, RMDS, BAM, !CSR_PROM(s) && is_bcast);
} else {
- rmd.rmd1.oflo = 1;
- rmd.rmd1.buff = 1;
- rmd.rmd1.err = 1;
+ SET_FIELD(&rmd.status, RMDS, OFLO, 1);
+ SET_FIELD(&rmd.status, RMDS, BUFF, 1);
+ SET_FIELD(&rmd.status, RMDS, ERR, 1);
}
RMDSTORE(&rmd, PHYSADDR(s,crda));
s->csr[0] |= 0x0400;
@@ -1172,30 +1240,30 @@
if (pcnet_tdte_poll(s)) {
struct pcnet_TMD tmd;
- TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
+ TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
#ifdef PCNET_DEBUG_TMD
printf(" TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
PRINT_TMD(&tmd);
#endif
- if (tmd.tmd1.stp) {
- s->xmit_pos = 0;
- if (!tmd.tmd1.enp) {
- s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr),
- s->buffer, 4096 - tmd.tmd1.bcnt,
- CSR_BSWP(s));
- s->xmit_pos += 4096 - tmd.tmd1.bcnt;
- }
+ if (GET_FIELD(tmd.status, TMDS, STP)) {
+ s->xmit_pos = 0;
+ 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),
+ s->buffer, bcnt, CSR_BSWP(s));
+ s->xmit_pos += bcnt;
+ }
xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
}
- if (tmd.tmd1.enp && (s->xmit_pos >= 0)) {
- s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr),
- s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt,
- CSR_BSWP(s));
- s->xmit_pos += 4096 - tmd.tmd1.bcnt;
+ if (GET_FIELD(tmd.status, TMDS, ENP) && (s->xmit_pos >= 0)) {
+ int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
+ s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
+ s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
+ s->xmit_pos += bcnt;
#ifdef PCNET_DEBUG
printf("pcnet_transmit size=%d\n", s->xmit_pos);
-#endif
+#endif
if (CSR_LOOP(s))
pcnet_receive(s, s->buffer, s->xmit_pos);
else
@@ -1206,9 +1274,10 @@
s->xmit_pos = -1;
}
- tmd.tmd1.own = 0;
+ SET_FIELD(&tmd.status, TMDS, OWN, 0);
+printf(" TMDSTORE STATUS 0x%04x\n", tmd.status);
TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
- if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && tmd.tmd1.ltint))
+ if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT)))
s->csr[0] |= 0x0200; /* set TINT */
if (CSR_XMTRC(s)<=1)
@@ -1221,9 +1290,11 @@
} else
if (s->xmit_pos >= 0) {
struct pcnet_TMD tmd;
- TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));
- tmd.tmd2.buff = tmd.tmd2.uflo = tmd.tmd1.err = 1;
- tmd.tmd1.own = 0;
+ TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));
+ SET_FIELD(&tmd.misc, TMDM, BUFF, 1);
+ SET_FIELD(&tmd.misc, TMDM, UFLO, 1);
+ SET_FIELD(&tmd.status, TMDS, ERR, 1);
+ SET_FIELD(&tmd.status, TMDS, OWN, 0);
TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda));
s->csr[0] |= 0x0200; /* set TINT */
if (!CSR_DXSUFLO(s)) {
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [Qemu-devel] [PATCH] pcnet32 driver change, please test 2007-03-02 20:09 [Qemu-devel] [PATCH] pcnet32 driver change, please test Thiemo Seufer @ 2007-03-02 20:29 ` Thiemo Seufer 2007-03-03 0:38 ` Fabrice Bellard 2007-03-02 23:14 ` Stuart Brady 1 sibling, 1 reply; 13+ messages in thread From: Thiemo Seufer @ 2007-03-02 20:29 UTC (permalink / raw) To: qemu-devel Thiemo Seufer wrote: > Hello All, > > I changed the pcnet32 driver to get rid of bitfields in its > implementation, now it works also on big endian host systems. > > I tested only the 32 bit mode which is used by MIPS/Malta, and > I'm not sure if it still works in Lance mode (as e.g. used on SPARC). > So please test if it still works. I forgot to delete a line of debug output, updated. Thiemo Index: qemu-work/hw/pcnet.c =================================================================== --- qemu-work.orig/hw/pcnet.c 2007-03-01 21:15:54.000000000 +0000 +++ qemu-work/hw/pcnet.c 2007-03-02 20:13:42.000000000 +0000 @@ -77,14 +77,6 @@ void *dma_opaque; }; -/* XXX: using bitfields for target memory structures is almost surely - not portable, so it should be suppressed ASAP */ -#ifdef __GNUC__ -#define PACKED_FIELD(A) A __attribute__ ((packed)) -#else -#error FixMe -#endif - struct qemu_ether_header { uint8_t ether_dhost[6]; uint8_t ether_shost[6]; @@ -183,223 +175,291 @@ }; struct pcnet_TMD { - struct { - unsigned tbadr:32; - } tmd0; - struct { - unsigned PACKED_FIELD(bcnt:12), PACKED_FIELD(ones:4), PACKED_FIELD(res:7), PACKED_FIELD(bpe:1); - unsigned PACKED_FIELD(enp:1), PACKED_FIELD(stp:1), PACKED_FIELD(def:1), PACKED_FIELD(one:1); - unsigned PACKED_FIELD(ltint:1), PACKED_FIELD(nofcs:1), PACKED_FIELD(err:1), PACKED_FIELD(own:1); - } tmd1; - struct { - unsigned PACKED_FIELD(trc:4), PACKED_FIELD(res:12); - unsigned PACKED_FIELD(tdr:10), PACKED_FIELD(rtry:1), PACKED_FIELD(lcar:1); - unsigned PACKED_FIELD(lcol:1), PACKED_FIELD(exdef:1), PACKED_FIELD(uflo:1), PACKED_FIELD(buff:1); - } tmd2; - struct { - unsigned res:32; - } tmd3; + uint32_t tbadr; + int16_t length; + int16_t status; + uint32_t misc; + uint32_t res; }; +#define TMDL_BCNT_MASK 0x0fff +#define TMDL_BCNT_SH 0 +#define TMDL_ONES_MASK 0xf000 +#define TMDL_ONES_SH 12 + +#define TMDS_BPE_MASK 0x0080 +#define TMDS_BPE_SH 7 +#define TMDS_ENP_MASK 0x0100 +#define TMDS_ENP_SH 8 +#define TMDS_STP_MASK 0x0200 +#define TMDS_STP_SH 9 +#define TMDS_DEF_MASK 0x0400 +#define TMDS_DEF_SH 10 +#define TMDS_ONE_MASK 0x0800 +#define TMDS_ONE_SH 11 +#define TMDS_LTINT_MASK 0x1000 +#define TMDS_LTINT_SH 12 +#define TMDS_NOFCS_MASK 0x2000 +#define TMDS_NOFCS_SH 13 +#define TMDS_ERR_MASK 0x4000 +#define TMDS_ERR_SH 14 +#define TMDS_OWN_MASK 0x8000 +#define TMDS_OWN_SH 15 + +#define TMDM_TRC_MASK 0x0000000f +#define TMDM_TRC_SH 0 +#define TMDM_TDR_MASK 0x03ff0000 +#define TMDM_TDR_SH 16 +#define TMDM_RTRY_MASK 0x04000000 +#define TMDM_RTRY_SH 26 +#define TMDM_LCAR_MASK 0x08000000 +#define TMDM_LCAR_SH 27 +#define TMDM_LCOL_MASK 0x10000000 +#define TMDM_LCOL_SH 28 +#define TMDM_EXDEF_MASK 0x20000000 +#define TMDM_EXDEF_SH 29 +#define TMDM_UFLO_MASK 0x40000000 +#define TMDM_UFLO_SH 30 +#define TMDM_BUFF_MASK 0x80000000 +#define TMDM_BUFF_SH 31 + struct pcnet_RMD { - struct { - unsigned rbadr:32; - } rmd0; - struct { - unsigned PACKED_FIELD(bcnt:12), PACKED_FIELD(ones:4), PACKED_FIELD(res:4); - unsigned PACKED_FIELD(bam:1), PACKED_FIELD(lafm:1), PACKED_FIELD(pam:1), PACKED_FIELD(bpe:1); - unsigned PACKED_FIELD(enp:1), PACKED_FIELD(stp:1), PACKED_FIELD(buff:1), PACKED_FIELD(crc:1); - unsigned PACKED_FIELD(oflo:1), PACKED_FIELD(fram:1), PACKED_FIELD(err:1), PACKED_FIELD(own:1); - } rmd1; - struct { - unsigned PACKED_FIELD(mcnt:12), PACKED_FIELD(zeros:4); - unsigned PACKED_FIELD(rpc:8), PACKED_FIELD(rcc:8); - } rmd2; - struct { - unsigned res:32; - } rmd3; + uint32_t rbadr; + int16_t buf_length; + int16_t status; + uint32_t msg_length; + uint32_t res; }; +#define RMDL_BCNT_MASK 0x0fff +#define RMDL_BCNT_SH 0 +#define RMDL_ONES_MASK 0xf000 +#define RMDL_ONES_SH 12 + +#define RMDS_BAM_MASK 0x0010 +#define RMDS_BAM_SH 4 +#define RMDS_LFAM_MASK 0x0020 +#define RMDS_LFAM_SH 5 +#define RMDS_PAM_MASK 0x0040 +#define RMDS_PAM_SH 6 +#define RMDS_BPE_MASK 0x0080 +#define RMDS_BPE_SH 7 +#define RMDS_ENP_MASK 0x0100 +#define RMDS_ENP_SH 8 +#define RMDS_STP_MASK 0x0200 +#define RMDS_STP_SH 9 +#define RMDS_BUFF_MASK 0x0400 +#define RMDS_BUFF_SH 10 +#define RMDS_CRC_MASK 0x0800 +#define RMDS_CRC_SH 11 +#define RMDS_OFLO_MASK 0x1000 +#define RMDS_OFLO_SH 12 +#define RMDS_FRAM_MASK 0x2000 +#define RMDS_FRAM_SH 13 +#define RMDS_ERR_MASK 0x4000 +#define RMDS_ERR_SH 14 +#define RMDS_OWN_MASK 0x8000 +#define RMDS_OWN_SH 15 + +#define RMDM_MCNT_MASK 0x00000fff +#define RMDM_MCNT_SH 0 +#define RMDM_ZEROS_MASK 0x0000f000 +#define RMDM_ZEROS_SH 12 +#define RMDM_RPC_MASK 0x00ff0000 +#define RMDM_RPC_SH 16 +#define RMDM_RCC_MASK 0xff000000 +#define RMDM_RCC_SH 24 + +#define SET_FIELD(regp, name, field, value) \ + (*(regp) = (*(regp) & ~(name ## _ ## field ## _MASK)) \ + | ((value) << name ## _ ## field ## _SH)) + +#define GET_FIELD(reg, name, field) \ + (((reg) & name ## _ ## field ## _MASK) >> name ## _ ## field ## _SH) -#define PRINT_TMD(T) printf( \ - "TMD0 : TBADR=0x%08x\n" \ +#define PRINT_TMD(T) printf( \ + "TMD0 : TBADR=0x%08x\n" \ "TMD1 : OWN=%d, ERR=%d, FCS=%d, LTI=%d, " \ "ONE=%d, DEF=%d, STP=%d, ENP=%d,\n" \ " BPE=%d, BCNT=%d\n" \ "TMD2 : BUF=%d, UFL=%d, EXD=%d, LCO=%d, " \ "LCA=%d, RTR=%d,\n" \ " TDR=%d, TRC=%d\n", \ - (T)->tmd0.tbadr, \ - (T)->tmd1.own, (T)->tmd1.err, (T)->tmd1.nofcs, \ - (T)->tmd1.ltint, (T)->tmd1.one, (T)->tmd1.def, \ - (T)->tmd1.stp, (T)->tmd1.enp, (T)->tmd1.bpe, \ - 4096-(T)->tmd1.bcnt, \ - (T)->tmd2.buff, (T)->tmd2.uflo, (T)->tmd2.exdef,\ - (T)->tmd2.lcol, (T)->tmd2.lcar, (T)->tmd2.rtry, \ - (T)->tmd2.tdr, (T)->tmd2.trc) + (T)->tbadr, \ + GET_FIELD((T)->status, TMDS, OWN), \ + GET_FIELD((T)->status, TMDS, ERR), \ + GET_FIELD((T)->status, TMDS, NOFCS), \ + GET_FIELD((T)->status, TMDS, LTINT), \ + GET_FIELD((T)->status, TMDS, ONE), \ + GET_FIELD((T)->status, TMDS, DEF), \ + GET_FIELD((T)->status, TMDS, STP), \ + GET_FIELD((T)->status, TMDS, ENP), \ + GET_FIELD((T)->status, TMDS, BPE), \ + 4096-GET_FIELD((T)->length, TMDL, BCNT), \ + GET_FIELD((T)->misc, TMDM, BUFF), \ + GET_FIELD((T)->misc, TMDM, UFLO), \ + GET_FIELD((T)->misc, TMDM, EXDEF), \ + GET_FIELD((T)->misc, TMDM, LCOL), \ + GET_FIELD((T)->misc, TMDM, LCAR), \ + GET_FIELD((T)->misc, TMDM, RTRY), \ + GET_FIELD((T)->misc, TMDM, TDR), \ + GET_FIELD((T)->misc, TMDM, TRC)) -#define PRINT_RMD(R) printf( \ - "RMD0 : RBADR=0x%08x\n" \ +#define PRINT_RMD(R) printf( \ + "RMD0 : RBADR=0x%08x\n" \ "RMD1 : OWN=%d, ERR=%d, FRAM=%d, OFLO=%d, " \ "CRC=%d, BUFF=%d, STP=%d, ENP=%d,\n " \ - "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n" \ + "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n" \ "RMD2 : RCC=%d, RPC=%d, MCNT=%d, ZEROS=%d\n", \ - (R)->rmd0.rbadr, \ - (R)->rmd1.own, (R)->rmd1.err, (R)->rmd1.fram, \ - (R)->rmd1.oflo, (R)->rmd1.crc, (R)->rmd1.buff, \ - (R)->rmd1.stp, (R)->rmd1.enp, (R)->rmd1.bpe, \ - (R)->rmd1.pam, (R)->rmd1.lafm, (R)->rmd1.bam, \ - (R)->rmd1.ones, 4096-(R)->rmd1.bcnt, \ - (R)->rmd2.rcc, (R)->rmd2.rpc, (R)->rmd2.mcnt, \ - (R)->rmd2.zeros) + (R)->rbadr, \ + GET_FIELD((R)->status, RMDS, OWN), \ + GET_FIELD((R)->status, RMDS, ERR), \ + GET_FIELD((R)->status, RMDS, FRAM), \ + GET_FIELD((R)->status, RMDS, OFLO), \ + GET_FIELD((R)->status, RMDS, CRC), \ + GET_FIELD((R)->status, RMDS, BUFF), \ + GET_FIELD((R)->status, RMDS, STP), \ + GET_FIELD((R)->status, RMDS, ENP), \ + GET_FIELD((R)->status, RMDS, BPE), \ + GET_FIELD((R)->status, RMDS, PAM), \ + GET_FIELD((R)->status, RMDS, LFAM), \ + GET_FIELD((R)->status, RMDS, BAM), \ + GET_FIELD((R)->buf_length, RMDL, ONES), \ + 4096-GET_FIELD((R)->buf_length, RMDL, BCNT), \ + GET_FIELD((R)->msg_length, RMDM, RCC), \ + GET_FIELD((R)->msg_length, RMDM, RPC), \ + GET_FIELD((R)->msg_length, RMDM, MCNT), \ + GET_FIELD((R)->msg_length, RMDM, ZEROS)) -static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd1, +static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd, target_phys_addr_t addr) { - uint32_t *tmd = (uint32_t *)tmd1; - - if (!BCR_SWSTYLE(s)) { - uint16_t xda[4]; - s->phys_mem_read(s->dma_opaque, addr, - (void *)&xda[0], sizeof(xda), 0); - le16_to_cpus(&xda[0]); - le16_to_cpus(&xda[1]); - le16_to_cpus(&xda[2]); - le16_to_cpus(&xda[3]); - tmd[0] = (xda[0]&0xffff) | - ((xda[1]&0x00ff) << 16); - tmd[1] = (xda[2]&0xffff)| - ((xda[1] & 0xff00) << 16); - tmd[2] = - (xda[3] & 0xffff) << 16; - tmd[3] = 0; + if (!BCR_SSIZE32(s)) { + struct { + uint32_t tbadr; + int16_t length; + int16_t status; + } xda; + s->phys_mem_read(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0); + tmd->tbadr = le32_to_cpu(xda.tbadr) & 0xffffff; + tmd->length = le16_to_cpu(xda.length); + tmd->status = (le32_to_cpu(xda.tbadr) >> 16) & 0xff00; + tmd->misc = le16_to_cpu(xda.status) << 16; + tmd->res = 0; } else { - uint32_t xda[4]; - s->phys_mem_read(s->dma_opaque, addr, - (void *)&xda[0], sizeof(xda), 0); - le32_to_cpus(&xda[0]); - le32_to_cpus(&xda[1]); - le32_to_cpus(&xda[2]); - le32_to_cpus(&xda[3]); - if (BCR_SWSTYLE(s) != 3) { - memcpy(tmd, xda, sizeof(xda)); - } else { - tmd[0] = xda[2]; - tmd[1] = xda[1]; - tmd[2] = xda[0]; - tmd[3] = xda[3]; + s->phys_mem_read(s->dma_opaque, addr, (void *)tmd, sizeof(*tmd), 0); + le32_to_cpus(&tmd->tbadr); + le16_to_cpus(&tmd->length); + le16_to_cpus(&tmd->status); + le32_to_cpus(&tmd->misc); + le32_to_cpus(&tmd->res); + if (BCR_SWSTYLE(s) == 3) { + uint32_t tmp = tmd->tbadr; + tmd->tbadr = tmd->misc; + tmd->misc = tmp; } } } -static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd1, +static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd, target_phys_addr_t addr) { - const uint32_t *tmd = (const uint32_t *)tmd1; - if (!BCR_SWSTYLE(s)) { - uint16_t xda[4]; - xda[0] = tmd[0] & 0xffff; - xda[1] = ((tmd[0]>>16)&0x00ff) | - ((tmd[1]>>16)&0xff00); - xda[2] = tmd[1] & 0xffff; - xda[3] = tmd[2] >> 16; - cpu_to_le16s(&xda[0]); - cpu_to_le16s(&xda[1]); - cpu_to_le16s(&xda[2]); - cpu_to_le16s(&xda[3]); - s->phys_mem_write(s->dma_opaque, addr, - (void *)&xda[0], sizeof(xda), 0); + if (!BCR_SSIZE32(s)) { + struct { + uint32_t tbadr; + int16_t length; + int16_t status; + } xda; + xda.tbadr = cpu_to_le32((tmd->tbadr & 0xffffff) | + ((tmd->status & 0xff00) << 16)); + xda.length = cpu_to_le16(tmd->length); + xda.status = cpu_to_le16(tmd->misc >> 16); + s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0); } else { - uint32_t xda[4]; - if (BCR_SWSTYLE(s) != 3) { - memcpy(xda, tmd, sizeof(xda)); - } else { - xda[0] = tmd[2]; - xda[1] = tmd[1]; - xda[2] = tmd[0]; - xda[3] = tmd[3]; + struct { + uint32_t tbadr; + int16_t length; + int16_t status; + uint32_t misc; + uint32_t res; + } xda; + xda.tbadr = cpu_to_le32(tmd->tbadr); + xda.length = cpu_to_le16(tmd->length); + xda.status = cpu_to_le16(tmd->status); + xda.misc = cpu_to_le32(tmd->misc); + xda.res = cpu_to_le32(tmd->res); + if (BCR_SWSTYLE(s) == 3) { + uint32_t tmp = xda.tbadr; + xda.tbadr = xda.misc; + xda.misc = tmp; } - cpu_to_le32s(&xda[0]); - cpu_to_le32s(&xda[1]); - cpu_to_le32s(&xda[2]); - cpu_to_le32s(&xda[3]); - s->phys_mem_write(s->dma_opaque, addr, - (void *)&xda[0], sizeof(xda), 0); + s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0); } } -static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd1, +static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd, target_phys_addr_t addr) { - uint32_t *rmd = (uint32_t *)rmd1; - - if (!BCR_SWSTYLE(s)) { - uint16_t rda[4]; - s->phys_mem_read(s->dma_opaque, addr, - (void *)&rda[0], sizeof(rda), 0); - le16_to_cpus(&rda[0]); - le16_to_cpus(&rda[1]); - le16_to_cpus(&rda[2]); - le16_to_cpus(&rda[3]); - rmd[0] = (rda[0]&0xffff)| - ((rda[1] & 0x00ff) << 16); - rmd[1] = (rda[2]&0xffff)| - ((rda[1] & 0xff00) << 16); - rmd[2] = rda[3] & 0xffff; - rmd[3] = 0; + if (!BCR_SSIZE32(s)) { + struct { + uint32_t rbadr; + int16_t buf_length; + int16_t msg_length; + } rda; + s->phys_mem_read(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0); + rmd->rbadr = le32_to_cpu(rda.rbadr) & 0xffffff; + rmd->buf_length = le16_to_cpu(rda.buf_length); + rmd->status = (le32_to_cpu(rda.rbadr) >> 16) & 0xff00; + rmd->msg_length = le16_to_cpu(rda.msg_length); + rmd->res = 0; } else { - uint32_t rda[4]; - s->phys_mem_read(s->dma_opaque, addr, - (void *)&rda[0], sizeof(rda), 0); - le32_to_cpus(&rda[0]); - le32_to_cpus(&rda[1]); - le32_to_cpus(&rda[2]); - le32_to_cpus(&rda[3]); - if (BCR_SWSTYLE(s) != 3) { - memcpy(rmd, rda, sizeof(rda)); - } else { - rmd[0] = rda[2]; - rmd[1] = rda[1]; - rmd[2] = rda[0]; - rmd[3] = rda[3]; + s->phys_mem_read(s->dma_opaque, addr, (void *)rmd, sizeof(*rmd), 0); + le32_to_cpus(&rmd->rbadr); + le16_to_cpus(&rmd->buf_length); + le16_to_cpus(&rmd->status); + le32_to_cpus(&rmd->msg_length); + le32_to_cpus(&rmd->res); + if (BCR_SWSTYLE(s) == 3) { + uint32_t tmp = rmd->rbadr; + rmd->rbadr = rmd->msg_length; + rmd->msg_length = tmp; } } } -static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd1, +static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd, target_phys_addr_t addr) { - const uint32_t *rmd = (const uint32_t *)rmd1; - - if (!BCR_SWSTYLE(s)) { - uint16_t rda[4]; - rda[0] = rmd[0] & 0xffff; - rda[1] = ((rmd[0]>>16)&0xff)| - ((rmd[1]>>16)&0xff00); - rda[2] = rmd[1] & 0xffff; - rda[3] = rmd[2] & 0xffff; - cpu_to_le16s(&rda[0]); - cpu_to_le16s(&rda[1]); - cpu_to_le16s(&rda[2]); - cpu_to_le16s(&rda[3]); - s->phys_mem_write(s->dma_opaque, addr, - (void *)&rda[0], sizeof(rda), 0); + if (!BCR_SSIZE32(s)) { + struct { + uint32_t rbadr; + int16_t buf_length; + int16_t msg_length; + } rda; + rda.rbadr = cpu_to_le32((rmd->rbadr & 0xffffff) | + ((rmd->status & 0xff00) << 16)); + rda.buf_length = cpu_to_le16(rmd->buf_length); + rda.msg_length = cpu_to_le16(rmd->msg_length); + s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0); } else { - uint32_t rda[4]; - if (BCR_SWSTYLE(s) != 3) { - memcpy(rda, rmd, sizeof(rda)); - } else { - rda[0] = rmd[2]; - rda[1] = rmd[1]; - rda[2] = rmd[0]; - rda[3] = rmd[3]; + struct { + uint32_t rbadr; + int16_t buf_length; + int16_t status; + uint32_t msg_length; + uint32_t res; + } rda; + rda.rbadr = cpu_to_le32(rmd->rbadr); + rda.buf_length = cpu_to_le16(rmd->buf_length); + rda.status = cpu_to_le16(rmd->status); + rda.msg_length = cpu_to_le32(rmd->msg_length); + rda.res = cpu_to_le32(rmd->res); + if (BCR_SWSTYLE(s) == 3) { + uint32_t tmp = rda.rbadr; + rda.rbadr = rda.msg_length; + rda.msg_length = tmp; } - cpu_to_le32s(&rda[0]); - cpu_to_le32s(&rda[1]); - cpu_to_le32s(&rda[2]); - cpu_to_le32s(&rda[3]); - s->phys_mem_write(s->dma_opaque, addr, - (void *)&rda[0], sizeof(rda), 0); + s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0); } } @@ -417,14 +477,14 @@ #define CHECK_RMD(ADDR,RES) do { \ struct pcnet_RMD rmd; \ RMDLOAD(&rmd,(ADDR)); \ - (RES) |= (rmd.rmd1.ones != 15) \ - || (rmd.rmd2.zeros != 0); \ + (RES) |= (GET_FIELD(rmd.buf_length, RMDL, ONES) != 15) \ + || (GET_FIELD(rmd.msg_length, RMDM, ZEROS) != 0); \ } while (0) #define CHECK_TMD(ADDR,RES) do { \ struct pcnet_TMD tmd; \ TMDLOAD(&tmd,(ADDR)); \ - (RES) |= (tmd.tmd1.ones != 15); \ + (RES) |= (GET_FIELD(tmd.length, TMDL, ONES) != 15); \ } while (0) #else @@ -434,8 +494,8 @@ case 0x00: \ do { \ uint16_t rda[4]; \ - s->phys_mem_read(s->dma_opaque, (ADDR), \ - (void *)&rda[0], sizeof(rda), 0); \ + s->phys_mem_read(s->dma_opaque, (ADDR), \ + (void *)&rda[0], sizeof(rda), 0); \ (RES) |= (rda[2] & 0xf000)!=0xf000; \ (RES) |= (rda[3] & 0xf000)!=0x0000; \ } while (0); \ @@ -444,7 +504,7 @@ case 0x02: \ do { \ uint32_t rda[4]; \ - s->phys_mem_read(s->dma_opaque, (ADDR), \ + s->phys_mem_read(s->dma_opaque, (ADDR), \ (void *)&rda[0], sizeof(rda), 0); \ (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \ (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \ @@ -453,7 +513,7 @@ case 0x03: \ do { \ uint32_t rda[4]; \ - s->phys_mem_read(s->dma_opaque, (ADDR), \ + s->phys_mem_read(s->dma_opaque, (ADDR), \ (void *)&rda[0], sizeof(rda), 0); \ (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \ (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \ @@ -467,9 +527,9 @@ case 0x00: \ do { \ uint16_t xda[4]; \ - s->phys_mem_read(s->dma_opaque, (ADDR), \ - (void *)&xda[0], sizeof(xda), 0); \ - (RES) |= (xda[2] & 0xf000)!=0xf000;\ + s->phys_mem_read(s->dma_opaque, (ADDR), \ + (void *)&xda[0], sizeof(xda), 0); \ + (RES) |= (xda[2] & 0xf000)!=0xf000; \ } while (0); \ break; \ case 0x01: \ @@ -477,8 +537,8 @@ case 0x03: \ do { \ uint32_t xda[4]; \ - s->phys_mem_read(s->dma_opaque, (ADDR), \ - (void *)&xda[0], sizeof(xda), 0); \ + s->phys_mem_read(s->dma_opaque, (ADDR), \ + (void *)&xda[0], sizeof(xda), 0); \ (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \ } while (0); \ break; \ @@ -488,15 +548,15 @@ #endif #define PRINT_PKTHDR(BUF) do { \ - struct qemu_ether_header *hdr = (void *)(BUF); \ - printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \ - "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \ - "type=0x%04x\n", \ + struct qemu_ether_header *hdr = (void *)(BUF); \ + printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \ + "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \ + "type=0x%04x\n", \ hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \ hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \ hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \ hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \ - be16_to_cpu(hdr->ether_type)); \ + be16_to_cpu(hdr->ether_type)); \ } while (0) #define MULTICAST_FILTER_LEN 8 @@ -770,7 +830,7 @@ static void pcnet_init(PCNetState *s) { int rlen, tlen; - uint16_t *padr, *ladrf, mode; + uint16_t padr[3], ladrf[4], mode; uint32_t rdra, tdra; #ifdef PCNET_DEBUG @@ -781,22 +841,30 @@ struct pcnet_initblk32 initblk; s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)), (uint8_t *)&initblk, sizeof(initblk), 0); - mode = initblk.mode; + mode = le16_to_cpu(initblk.mode); rlen = initblk.rlen >> 4; tlen = initblk.tlen >> 4; - ladrf = initblk.ladrf; - padr = initblk.padr; + ladrf[0] = le16_to_cpu(initblk.ladrf[0]); + ladrf[1] = le16_to_cpu(initblk.ladrf[1]); + ladrf[2] = le16_to_cpu(initblk.ladrf[2]); + ladrf[3] = le16_to_cpu(initblk.ladrf[3]); + padr[0] = le16_to_cpu(initblk.padr[0]); + padr[1] = le16_to_cpu(initblk.padr[1]); + padr[2] = le16_to_cpu(initblk.padr[2]); rdra = le32_to_cpu(initblk.rdra); tdra = le32_to_cpu(initblk.tdra); - s->rdra = PHYSADDR(s,initblk.rdra); - s->tdra = PHYSADDR(s,initblk.tdra); } else { struct pcnet_initblk16 initblk; s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)), (uint8_t *)&initblk, sizeof(initblk), 0); - mode = initblk.mode; - ladrf = initblk.ladrf; - padr = initblk.padr; + mode = le16_to_cpu(initblk.mode); + ladrf[0] = le16_to_cpu(initblk.ladrf[0]); + ladrf[1] = le16_to_cpu(initblk.ladrf[1]); + ladrf[2] = le16_to_cpu(initblk.ladrf[2]); + ladrf[3] = le16_to_cpu(initblk.ladrf[3]); + padr[0] = le16_to_cpu(initblk.padr[0]); + padr[1] = le16_to_cpu(initblk.padr[1]); + padr[2] = le16_to_cpu(initblk.padr[2]); rdra = le32_to_cpu(initblk.rdra); tdra = le32_to_cpu(initblk.tdra); rlen = rdra >> 29; @@ -804,22 +872,22 @@ rdra &= 0x00ffffff; tdra &= 0x00ffffff; } - + #if defined(PCNET_DEBUG) - printf("rlen=%d tlen=%d\n", - rlen, tlen); + printf("rlen=%d tlen=%d\n", rlen, tlen); #endif + CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512; CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512; s->csr[ 6] = (tlen << 12) | (rlen << 8); - s->csr[15] = le16_to_cpu(mode); - s->csr[ 8] = le16_to_cpu(ladrf[0]); - s->csr[ 9] = le16_to_cpu(ladrf[1]); - s->csr[10] = le16_to_cpu(ladrf[2]); - s->csr[11] = le16_to_cpu(ladrf[3]); - s->csr[12] = le16_to_cpu(padr[0]); - s->csr[13] = le16_to_cpu(padr[1]); - s->csr[14] = le16_to_cpu(padr[2]); + s->csr[15] = mode; + s->csr[ 8] = ladrf[0]; + s->csr[ 9] = ladrf[1]; + s->csr[10] = ladrf[2]; + s->csr[11] = ladrf[3]; + s->csr[12] = padr[0]; + s->csr[13] = padr[1]; + s->csr[14] = padr[2]; s->rdra = PHYSADDR(s, rdra); s->tdra = PHYSADDR(s, tdra); @@ -914,12 +982,12 @@ if (CSR_CRDA(s)) { struct pcnet_RMD rmd; RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s))); - CSR_CRBC(s) = rmd.rmd1.bcnt; - CSR_CRST(s) = ((uint32_t *)&rmd)[1] >> 16; + CSR_CRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT); + CSR_CRST(s) = rmd.status; #ifdef PCNET_DEBUG_RMD_X - printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMD1=0x%08x RMD2=0x%08x\n", + printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMDL=0x%04x RMDS=0x%04x RMDM=0x%08x\n", PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s), - ((uint32_t *)&rmd)[1], ((uint32_t *)&rmd)[2]); + rmd.buf_length, rmd.status, rmd.msg_length); PRINT_RMD(&rmd); #endif } else { @@ -929,8 +997,8 @@ if (CSR_NRDA(s)) { struct pcnet_RMD rmd; RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s))); - CSR_NRBC(s) = rmd.rmd1.bcnt; - CSR_NRST(s) = ((uint32_t *)&rmd)[1] >> 16; + CSR_NRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT); + CSR_NRST(s) = rmd.status; } else { CSR_NRBC(s) = CSR_NRST(s) = 0; } @@ -943,7 +1011,7 @@ if (s->tdra) { target_phys_addr_t cxda = s->tdra + (CSR_XMTRL(s) - CSR_XMTRC(s)) * - (BCR_SWSTYLE(s) ? 16 : 8 ); + (BCR_SWSTYLE(s) ? 16 : 8); int bad = 0; CHECK_TMD(PHYSADDR(s, cxda),bad); if (!bad) { @@ -955,8 +1023,7 @@ } s->csr[34] = cxda & 0xffff; s->csr[35] = cxda >> 16; -#ifdef PCNET_DEBUG - } else { +#ifdef PCNET_DEBUG_X printf("pcnet: BAD TMD XDA=0x%08x\n", PHYSADDR(s,cxda)); #endif } @@ -967,8 +1034,8 @@ TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s))); - CSR_CXBC(s) = tmd.tmd1.bcnt; - CSR_CXST(s) = ((uint32_t *)&tmd)[1] >> 16; + CSR_CXBC(s) = GET_FIELD(tmd.length, TMDL, BCNT); + CSR_CXST(s) = tmd.status; } else { CSR_CXBC(s) = CSR_CXST(s) = 0; } @@ -1029,7 +1096,7 @@ (CSR_RCVRL(s) - rcvrc) * (BCR_SWSTYLE(s) ? 16 : 8 ); RMDLOAD(&rmd, PHYSADDR(s,nrda)); - if (rmd.rmd1.own) { + if (GET_FIELD(rmd.status, RMDS, OWN)) { #ifdef PCNET_DEBUG_RMD printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n", rcvrc, CSR_RCVRC(s)); @@ -1086,14 +1153,15 @@ RMDLOAD(&rmd, PHYSADDR(s,crda)); /*if (!CSR_LAPPEN(s))*/ - rmd.rmd1.stp = 1; + SET_FIELD(&rmd.status, RMDS, STP, 1); #define PCNET_RECV_STORE() do { \ - int count = MIN(4096 - rmd.rmd1.bcnt,size); \ - target_phys_addr_t rbadr = PHYSADDR(s, rmd.rmd0.rbadr); \ - s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \ + int count = MIN(4096 - GET_FIELD(rmd.buf_length, RMDL, BCNT),size); \ + target_phys_addr_t rbadr = PHYSADDR(s, rmd.rbadr); \ + s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \ src += count; size -= count; \ - rmd.rmd2.mcnt = count; rmd.rmd1.own = 0; \ + SET_FIELD(&rmd.msg_length, RMDM, MCNT, count); \ + SET_FIELD(&rmd.status, RMDS, OWN, 0); \ RMDSTORE(&rmd, PHYSADDR(s,crda)); \ pktcount++; \ } while (0) @@ -1102,12 +1170,12 @@ if ((size > 0) && CSR_NRDA(s)) { target_phys_addr_t nrda = CSR_NRDA(s); RMDLOAD(&rmd, PHYSADDR(s,nrda)); - if (rmd.rmd1.own) { + if (GET_FIELD(rmd.status, RMDS, OWN)) { crda = nrda; PCNET_RECV_STORE(); if ((size > 0) && (nrda=CSR_NNRD(s))) { RMDLOAD(&rmd, PHYSADDR(s,nrda)); - if (rmd.rmd1.own) { + if (GET_FIELD(rmd.status, RMDS, OWN)) { crda = nrda; PCNET_RECV_STORE(); } @@ -1119,14 +1187,14 @@ RMDLOAD(&rmd, PHYSADDR(s,crda)); if (size == 0) { - rmd.rmd1.enp = 1; - rmd.rmd1.pam = !CSR_PROM(s) && is_padr; - rmd.rmd1.lafm = !CSR_PROM(s) && is_ladr; - rmd.rmd1.bam = !CSR_PROM(s) && is_bcast; + SET_FIELD(&rmd.status, RMDS, ENP, 1); + SET_FIELD(&rmd.status, RMDS, PAM, !CSR_PROM(s) && is_padr); + SET_FIELD(&rmd.status, RMDS, LFAM, !CSR_PROM(s) && is_ladr); + SET_FIELD(&rmd.status, RMDS, BAM, !CSR_PROM(s) && is_bcast); } else { - rmd.rmd1.oflo = 1; - rmd.rmd1.buff = 1; - rmd.rmd1.err = 1; + SET_FIELD(&rmd.status, RMDS, OFLO, 1); + SET_FIELD(&rmd.status, RMDS, BUFF, 1); + SET_FIELD(&rmd.status, RMDS, ERR, 1); } RMDSTORE(&rmd, PHYSADDR(s,crda)); s->csr[0] |= 0x0400; @@ -1172,30 +1240,30 @@ if (pcnet_tdte_poll(s)) { struct pcnet_TMD tmd; - TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s))); + TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s))); #ifdef PCNET_DEBUG_TMD printf(" TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s))); PRINT_TMD(&tmd); #endif - if (tmd.tmd1.stp) { - s->xmit_pos = 0; - if (!tmd.tmd1.enp) { - s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr), - s->buffer, 4096 - tmd.tmd1.bcnt, - CSR_BSWP(s)); - s->xmit_pos += 4096 - tmd.tmd1.bcnt; - } + if (GET_FIELD(tmd.status, TMDS, STP)) { + s->xmit_pos = 0; + 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), + s->buffer, bcnt, CSR_BSWP(s)); + s->xmit_pos += bcnt; + } xmit_cxda = PHYSADDR(s,CSR_CXDA(s)); } - if (tmd.tmd1.enp && (s->xmit_pos >= 0)) { - s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr), - s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt, - CSR_BSWP(s)); - s->xmit_pos += 4096 - tmd.tmd1.bcnt; + if (GET_FIELD(tmd.status, TMDS, ENP) && (s->xmit_pos >= 0)) { + int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); + s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), + s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); + s->xmit_pos += bcnt; #ifdef PCNET_DEBUG printf("pcnet_transmit size=%d\n", s->xmit_pos); -#endif +#endif if (CSR_LOOP(s)) pcnet_receive(s, s->buffer, s->xmit_pos); else @@ -1206,9 +1274,9 @@ s->xmit_pos = -1; } - tmd.tmd1.own = 0; + SET_FIELD(&tmd.status, TMDS, OWN, 0); TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s))); - if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && tmd.tmd1.ltint)) + if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT))) s->csr[0] |= 0x0200; /* set TINT */ if (CSR_XMTRC(s)<=1) @@ -1221,9 +1289,11 @@ } else if (s->xmit_pos >= 0) { struct pcnet_TMD tmd; - TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda)); - tmd.tmd2.buff = tmd.tmd2.uflo = tmd.tmd1.err = 1; - tmd.tmd1.own = 0; + TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda)); + SET_FIELD(&tmd.misc, TMDM, BUFF, 1); + SET_FIELD(&tmd.misc, TMDM, UFLO, 1); + SET_FIELD(&tmd.status, TMDS, ERR, 1); + SET_FIELD(&tmd.status, TMDS, OWN, 0); TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda)); s->csr[0] |= 0x0200; /* set TINT */ if (!CSR_DXSUFLO(s)) { ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH] pcnet32 driver change, please test 2007-03-02 20:29 ` Thiemo Seufer @ 2007-03-03 0:38 ` Fabrice Bellard 2007-03-03 21:44 ` Thiemo Seufer 0 siblings, 1 reply; 13+ messages in thread From: Fabrice Bellard @ 2007-03-03 0:38 UTC (permalink / raw) To: qemu-devel Thiemo Seufer wrote: > Thiemo Seufer wrote: >> Hello All, >> >> I changed the pcnet32 driver to get rid of bitfields in its >> implementation, now it works also on big endian host systems. >> >> I tested only the 32 bit mode which is used by MIPS/Malta, and >> I'm not sure if it still works in Lance mode (as e.g. used on SPARC). >> So please test if it still works. > > I forgot to delete a line of debug output, updated. It seems that you made some unnecessary changes (why did you changed the code in pcnet_init ?). Regards, Fabrice. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH] pcnet32 driver change, please test 2007-03-03 0:38 ` Fabrice Bellard @ 2007-03-03 21:44 ` Thiemo Seufer 0 siblings, 0 replies; 13+ messages in thread From: Thiemo Seufer @ 2007-03-03 21:44 UTC (permalink / raw) To: Fabrice Bellard; +Cc: qemu-devel Fabrice Bellard wrote: > Thiemo Seufer wrote: > >Thiemo Seufer wrote: > >>Hello All, > >> > >>I changed the pcnet32 driver to get rid of bitfields in its > >>implementation, now it works also on big endian host systems. > >> > >>I tested only the 32 bit mode which is used by MIPS/Malta, and > >>I'm not sure if it still works in Lance mode (as e.g. used on SPARC). > >>So please test if it still works. > > > >I forgot to delete a line of debug output, updated. > > It seems that you made some unnecessary changes (why did you changed the > code in pcnet_init ?). That code currently accesses initblk members (padr. ladrf) after the initblk structure went out of scope. I also wanted to keep the data acquisition with its byte swaps in the same place. Thiemo. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH] pcnet32 driver change, please test 2007-03-02 20:09 [Qemu-devel] [PATCH] pcnet32 driver change, please test Thiemo Seufer 2007-03-02 20:29 ` Thiemo Seufer @ 2007-03-02 23:14 ` Stuart Brady 2007-03-03 0:53 ` M. Warner Losh 1 sibling, 1 reply; 13+ messages in thread From: Stuart Brady @ 2007-03-02 23:14 UTC (permalink / raw) To: qemu-devel On Fri, Mar 02, 2007 at 08:09:49PM +0000, Thiemo Seufer wrote: > Hello All, > > I changed the pcnet32 driver to get rid of bitfields in its > implementation, now it works also on big endian host systems. I find this curious... C99 (6.7.2.1) says "the allocation order of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation defined". I can't see any requirement for this, so is it just convention that bitfields on big endian systems start from the most significant bit, and those on little endian systems start from the least significant bit? (My thinking is that endianness usually refers to byte ordering and not so much bit ordering.) I ask this because I'd seen some code of the form: #ifdef WORDS_BIGENDIAN typedef struct { int b7:1; int b6:1; int b5:1; int b4:1; int b3:1; int b2:1; int b1:1; int b0:1; } foo; #else typedef struct { int b0:1; int b1:1; int b2:1; int b3:1; int b4:1; int b5:1; int b6:1; int b7:1; } foo; #endif and I had assumed that this was sheer nonsense... > I tested only the 32 bit mode which is used by MIPS/Malta, and > I'm not sure if it still works in Lance mode (as e.g. used on SPARC). > So please test if it still works. I've tried this patch with a SPARC target running Etch, with an i386 host. No problems so far. (FWIW, I have noticed one bug, but it's *not* a problem with this patch. In the Sarge installer, I see "Error while running 'modprobe -v sunlance'". ISTR that if I use the netinstall iso and persist with the installation, Lance works after the reboot. This problem doesn't seem to affect Etch.) Thanks, -- Stuart Brady ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH] pcnet32 driver change, please test 2007-03-02 23:14 ` Stuart Brady @ 2007-03-03 0:53 ` M. Warner Losh 2007-03-03 1:01 ` Paul Brook 0 siblings, 1 reply; 13+ messages in thread From: M. Warner Losh @ 2007-03-03 0:53 UTC (permalink / raw) To: qemu-devel, sdbrady In message: <20070302231450.GA6741@miranda.arrow> Stuart Brady <sdbrady@ntlworld.com> writes: : On Fri, Mar 02, 2007 at 08:09:49PM +0000, Thiemo Seufer wrote: : > Hello All, : > : > I changed the pcnet32 driver to get rid of bitfields in its : > implementation, now it works also on big endian host systems. : : I find this curious... C99 (6.7.2.1) says "the allocation order of : bit-fields within a unit (high-order to low-order or low-order to : high-order) is implementation defined". I can't see any requirement : for this, so is it just convention that bitfields on big endian systems : start from the most significant bit, and those on little endian systems : start from the least significant bit? (My thinking is that endianness : usually refers to byte ordering and not so much bit ordering.) This is a convention that goes back a very long ways. It was this way in the mid 1980's, and has remained true through today. I've personally observed this to be the case on many different MIPS compilers, ARM compilers and SPARC compilers over the years. Warner ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH] pcnet32 driver change, please test 2007-03-03 0:53 ` M. Warner Losh @ 2007-03-03 1:01 ` Paul Brook 2007-03-03 2:30 ` M. Warner Losh 2007-03-03 10:25 ` Andreas Schwab 0 siblings, 2 replies; 13+ messages in thread From: Paul Brook @ 2007-03-03 1:01 UTC (permalink / raw) To: qemu-devel > : I find this curious... C99 (6.7.2.1) says "the allocation order of > : bit-fields within a unit (high-order to low-order or low-order to > : high-order) is implementation defined". I can't see any requirement > : for this, so is it just convention that bitfields on big endian systems > : start from the most significant bit, and those on little endian systems > : start from the least significant bit? (My thinking is that endianness > : usually refers to byte ordering and not so much bit ordering.) > > This is a convention that goes back a very long ways. It was this way > in the mid 1980's, and has remained true through today. I've > personally observed this to be the case on many different MIPS > compilers, ARM compilers and SPARC compilers over the years. I'm fairly sure I've seen targets that use other bitfield orderings, though I can't remember offhand what they were. Paul ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH] pcnet32 driver change, please test 2007-03-03 1:01 ` Paul Brook @ 2007-03-03 2:30 ` M. Warner Losh 2007-03-03 10:25 ` Andreas Schwab 1 sibling, 0 replies; 13+ messages in thread From: M. Warner Losh @ 2007-03-03 2:30 UTC (permalink / raw) To: paul; +Cc: qemu-devel In message: <200703030101.56126.paul@codesourcery.com> Paul Brook <paul@codesourcery.com> writes: : > : I find this curious... C99 (6.7.2.1) says "the allocation order of : > : bit-fields within a unit (high-order to low-order or low-order to : > : high-order) is implementation defined". I can't see any requirement : > : for this, so is it just convention that bitfields on big endian systems : > : start from the most significant bit, and those on little endian systems : > : start from the least significant bit? (My thinking is that endianness : > : usually refers to byte ordering and not so much bit ordering.) : > : > This is a convention that goes back a very long ways. It was this way : > in the mid 1980's, and has remained true through today. I've : > personally observed this to be the case on many different MIPS : > compilers, ARM compilers and SPARC compilers over the years. : : I'm fairly sure I've seen targets that use other bitfield orderings, though I : can't remember offhand what they were. None of them are supported by FreeBSD and/or NetBSD... Warner ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH] pcnet32 driver change, please test 2007-03-03 1:01 ` Paul Brook 2007-03-03 2:30 ` M. Warner Losh @ 2007-03-03 10:25 ` Andreas Schwab 2007-03-03 13:24 ` M. Warner Losh 1 sibling, 1 reply; 13+ messages in thread From: Andreas Schwab @ 2007-03-03 10:25 UTC (permalink / raw) To: qemu-devel Paul Brook <paul@codesourcery.com> writes: >> : I find this curious... C99 (6.7.2.1) says "the allocation order of >> : bit-fields within a unit (high-order to low-order or low-order to >> : high-order) is implementation defined". I can't see any requirement >> : for this, so is it just convention that bitfields on big endian systems >> : start from the most significant bit, and those on little endian systems >> : start from the least significant bit? (My thinking is that endianness >> : usually refers to byte ordering and not so much bit ordering.) >> >> This is a convention that goes back a very long ways. It was this way >> in the mid 1980's, and has remained true through today. I've >> personally observed this to be the case on many different MIPS >> compilers, ARM compilers and SPARC compilers over the years. > > I'm fairly sure I've seen targets that use other bitfield orderings, though I > can't remember offhand what they were. Bi-endian targets are examples of this. The bitfield ordering is normally independent of the selected byte order. For example, big-endian MIPS has little endian bit order. Andreas. -- Andreas Schwab, SuSE Labs, schwab@suse.de SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH] pcnet32 driver change, please test 2007-03-03 10:25 ` Andreas Schwab @ 2007-03-03 13:24 ` M. Warner Losh 2007-03-03 14:46 ` Andreas Schwab 0 siblings, 1 reply; 13+ messages in thread From: M. Warner Losh @ 2007-03-03 13:24 UTC (permalink / raw) To: qemu-devel, schwab In message: <jemz2uvd2u.fsf@sykes.suse.de> Andreas Schwab <schwab@suse.de> writes: : Paul Brook <paul@codesourcery.com> writes: : : >> : I find this curious... C99 (6.7.2.1) says "the allocation order of : >> : bit-fields within a unit (high-order to low-order or low-order to : >> : high-order) is implementation defined". I can't see any requirement : >> : for this, so is it just convention that bitfields on big endian systems : >> : start from the most significant bit, and those on little endian systems : >> : start from the least significant bit? (My thinking is that endianness : >> : usually refers to byte ordering and not so much bit ordering.) : >> : >> This is a convention that goes back a very long ways. It was this way : >> in the mid 1980's, and has remained true through today. I've : >> personally observed this to be the case on many different MIPS : >> compilers, ARM compilers and SPARC compilers over the years. : > : > I'm fairly sure I've seen targets that use other bitfield orderings, though I : > can't remember offhand what they were. : : Bi-endian targets are examples of this. The bitfield ordering is normally : independent of the selected byte order. For example, big-endian MIPS has : little endian bit order. Except that compilers use the convention that was described above. Big endian MIPS definitely uses a different bit ordering for C bit fields than little endian MIPS. This is true for compilers from SGI, DEC and GNU and NetBSD, FreeBSD, Linux, Ultrix, OSF, and IRIX. All of them use the following, or variants for, say, the IP header: struct ip { #if BYTE_ORDER == LITTLE_ENDIAN unsigned int ip_hl:4, /* header length */ ip_v:4; /* version */ #endif #if BYTE_ORDER == BIG_ENDIAN unsigned int ip_v:4, /* version */ ip_hl:4; /* header length */ #endif ... Warner ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH] pcnet32 driver change, please test 2007-03-03 13:24 ` M. Warner Losh @ 2007-03-03 14:46 ` Andreas Schwab 2007-03-03 15:47 ` M. Warner Losh 0 siblings, 1 reply; 13+ messages in thread From: Andreas Schwab @ 2007-03-03 14:46 UTC (permalink / raw) To: M. Warner Losh; +Cc: qemu-devel "M. Warner Losh" <imp@bsdimp.com> writes: > Except that compilers use the convention that was described above. > Big endian MIPS definitely uses a different bit ordering for C bit > fields than little endian MIPS. There is actually a difference between *bitfield* ordering and *bit* ordering. The former always follows the byte ordering, whereas the latter is only a property of the ISA and has no influence on the ABI or API. Andreas. -- Andreas Schwab, SuSE Labs, schwab@suse.de SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH] pcnet32 driver change, please test 2007-03-03 14:46 ` Andreas Schwab @ 2007-03-03 15:47 ` M. Warner Losh 2007-03-03 17:23 ` Andreas Schwab 0 siblings, 1 reply; 13+ messages in thread From: M. Warner Losh @ 2007-03-03 15:47 UTC (permalink / raw) To: schwab; +Cc: qemu-devel In message: <jefy8ms7tv.fsf@sykes.suse.de> Andreas Schwab <schwab@suse.de> writes: : "M. Warner Losh" <imp@bsdimp.com> writes: : : > Except that compilers use the convention that was described above. : > Big endian MIPS definitely uses a different bit ordering for C bit : > fields than little endian MIPS. : : There is actually a difference between *bitfield* ordering and *bit* : ordering. The former always follows the byte ordering, whereas the latter : is only a property of the ISA and has no influence on the ABI or API. True, but that's not what the original poster in this thread was asking. Answering the different question is just confusing to the original poster. Warner ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH] pcnet32 driver change, please test 2007-03-03 15:47 ` M. Warner Losh @ 2007-03-03 17:23 ` Andreas Schwab 0 siblings, 0 replies; 13+ messages in thread From: Andreas Schwab @ 2007-03-03 17:23 UTC (permalink / raw) To: M. Warner Losh; +Cc: qemu-devel "M. Warner Losh" <imp@bsdimp.com> writes: > True, but that's not what the original poster in this thread was > asking. Right. > Answering the different question is just confusing to the > original poster. It was actually me who was confused. Andreas. -- Andreas Schwab, SuSE Labs, schwab@suse.de SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2007-03-03 21:52 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-03-02 20:09 [Qemu-devel] [PATCH] pcnet32 driver change, please test Thiemo Seufer 2007-03-02 20:29 ` Thiemo Seufer 2007-03-03 0:38 ` Fabrice Bellard 2007-03-03 21:44 ` Thiemo Seufer 2007-03-02 23:14 ` Stuart Brady 2007-03-03 0:53 ` M. Warner Losh 2007-03-03 1:01 ` Paul Brook 2007-03-03 2:30 ` M. Warner Losh 2007-03-03 10:25 ` Andreas Schwab 2007-03-03 13:24 ` M. Warner Losh 2007-03-03 14:46 ` Andreas Schwab 2007-03-03 15:47 ` M. Warner Losh 2007-03-03 17:23 ` Andreas Schwab
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.