xref: /openbmc/qemu/hw/net/pcnet.c (revision 8e6fe6b8)
1 /*
2  * QEMU AMD PC-Net II (Am79C970A) emulation
3  *
4  * Copyright (c) 2004 Antony T Curtis
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
25 /* This software was written to be compatible with the specification:
26  * AMD Am79C970A PCnet-PCI II Ethernet Controller Data-Sheet
27  * AMD Publication# 19436  Rev:E  Amendment/0  Issue Date: June 2000
28  */
29 
30 /*
31  * On Sparc32, this is the Lance (Am7990) part of chip STP2000 (Master I/O), also
32  * produced as NCR89C100. See
33  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
34  * and
35  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR92C990.txt
36  */
37 
38 #include "qemu/osdep.h"
39 #include "qemu/log.h"
40 #include "hw/qdev.h"
41 #include "net/net.h"
42 #include "net/eth.h"
43 #include "qemu/timer.h"
44 #include "sysemu/sysemu.h"
45 #include "trace.h"
46 
47 #include "pcnet.h"
48 
49 //#define PCNET_DEBUG
50 //#define PCNET_DEBUG_IO
51 //#define PCNET_DEBUG_BCR
52 //#define PCNET_DEBUG_CSR
53 //#define PCNET_DEBUG_RMD
54 //#define PCNET_DEBUG_TMD
55 //#define PCNET_DEBUG_MATCH
56 
57 
58 struct qemu_ether_header {
59     uint8_t ether_dhost[6];
60     uint8_t ether_shost[6];
61     uint16_t ether_type;
62 };
63 
64 #define CSR_INIT(S)      !!(((S)->csr[0])&0x0001)
65 #define CSR_STRT(S)      !!(((S)->csr[0])&0x0002)
66 #define CSR_STOP(S)      !!(((S)->csr[0])&0x0004)
67 #define CSR_TDMD(S)      !!(((S)->csr[0])&0x0008)
68 #define CSR_TXON(S)      !!(((S)->csr[0])&0x0010)
69 #define CSR_RXON(S)      !!(((S)->csr[0])&0x0020)
70 #define CSR_INEA(S)      !!(((S)->csr[0])&0x0040)
71 #define CSR_BSWP(S)      !!(((S)->csr[3])&0x0004)
72 #define CSR_LAPPEN(S)    !!(((S)->csr[3])&0x0020)
73 #define CSR_DXSUFLO(S)   !!(((S)->csr[3])&0x0040)
74 #define CSR_ASTRP_RCV(S) !!(((S)->csr[4])&0x0800)
75 #define CSR_DPOLL(S)     !!(((S)->csr[4])&0x1000)
76 #define CSR_SPND(S)      !!(((S)->csr[5])&0x0001)
77 #define CSR_LTINTEN(S)   !!(((S)->csr[5])&0x4000)
78 #define CSR_TOKINTD(S)   !!(((S)->csr[5])&0x8000)
79 #define CSR_DRX(S)       !!(((S)->csr[15])&0x0001)
80 #define CSR_DTX(S)       !!(((S)->csr[15])&0x0002)
81 #define CSR_LOOP(S)      !!(((S)->csr[15])&0x0004)
82 #define CSR_DXMTFCS(S)   !!(((S)->csr[15])&0x0008)
83 #define CSR_INTL(S)      !!(((S)->csr[15])&0x0040)
84 #define CSR_DRCVPA(S)    !!(((S)->csr[15])&0x2000)
85 #define CSR_DRCVBC(S)    !!(((S)->csr[15])&0x4000)
86 #define CSR_PROM(S)      !!(((S)->csr[15])&0x8000)
87 
88 #define CSR_CRBC(S)      ((S)->csr[40])
89 #define CSR_CRST(S)      ((S)->csr[41])
90 #define CSR_CXBC(S)      ((S)->csr[42])
91 #define CSR_CXST(S)      ((S)->csr[43])
92 #define CSR_NRBC(S)      ((S)->csr[44])
93 #define CSR_NRST(S)      ((S)->csr[45])
94 #define CSR_POLL(S)      ((S)->csr[46])
95 #define CSR_PINT(S)      ((S)->csr[47])
96 #define CSR_RCVRC(S)     ((S)->csr[72])
97 #define CSR_XMTRC(S)     ((S)->csr[74])
98 #define CSR_RCVRL(S)     ((S)->csr[76])
99 #define CSR_XMTRL(S)     ((S)->csr[78])
100 #define CSR_MISSC(S)     ((S)->csr[112])
101 
102 #define CSR_IADR(S)      ((S)->csr[ 1] | ((uint32_t)(S)->csr[ 2] << 16))
103 #define CSR_CRBA(S)      ((S)->csr[18] | ((uint32_t)(S)->csr[19] << 16))
104 #define CSR_CXBA(S)      ((S)->csr[20] | ((uint32_t)(S)->csr[21] << 16))
105 #define CSR_NRBA(S)      ((S)->csr[22] | ((uint32_t)(S)->csr[23] << 16))
106 #define CSR_BADR(S)      ((S)->csr[24] | ((uint32_t)(S)->csr[25] << 16))
107 #define CSR_NRDA(S)      ((S)->csr[26] | ((uint32_t)(S)->csr[27] << 16))
108 #define CSR_CRDA(S)      ((S)->csr[28] | ((uint32_t)(S)->csr[29] << 16))
109 #define CSR_BADX(S)      ((S)->csr[30] | ((uint32_t)(S)->csr[31] << 16))
110 #define CSR_NXDA(S)      ((S)->csr[32] | ((uint32_t)(S)->csr[33] << 16))
111 #define CSR_CXDA(S)      ((S)->csr[34] | ((uint32_t)(S)->csr[35] << 16))
112 #define CSR_NNRD(S)      ((S)->csr[36] | ((uint32_t)(S)->csr[37] << 16))
113 #define CSR_NNXD(S)      ((S)->csr[38] | ((uint32_t)(S)->csr[39] << 16))
114 #define CSR_PXDA(S)      ((S)->csr[60] | ((uint32_t)(S)->csr[61] << 16))
115 #define CSR_NXBA(S)      ((S)->csr[64] | ((uint32_t)(S)->csr[65] << 16))
116 
117 #define PHYSADDR(S,A) \
118   (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(S)->csr[2])<<16))
119 
120 struct pcnet_initblk16 {
121     uint16_t mode;
122     uint16_t padr[3];
123     uint16_t ladrf[4];
124     uint32_t rdra;
125     uint32_t tdra;
126 };
127 
128 struct pcnet_initblk32 {
129     uint16_t mode;
130     uint8_t rlen;
131     uint8_t tlen;
132     uint16_t padr[3];
133     uint16_t _res;
134     uint16_t ladrf[4];
135     uint32_t rdra;
136     uint32_t tdra;
137 };
138 
139 struct pcnet_TMD {
140     uint32_t tbadr;
141     int16_t length;
142     int16_t status;
143     uint32_t misc;
144     uint32_t res;
145 };
146 
147 #define TMDL_BCNT_MASK  0x0fff
148 #define TMDL_BCNT_SH    0
149 #define TMDL_ONES_MASK  0xf000
150 #define TMDL_ONES_SH    12
151 
152 #define TMDS_BPE_MASK   0x0080
153 #define TMDS_BPE_SH     7
154 #define TMDS_ENP_MASK   0x0100
155 #define TMDS_ENP_SH     8
156 #define TMDS_STP_MASK   0x0200
157 #define TMDS_STP_SH     9
158 #define TMDS_DEF_MASK   0x0400
159 #define TMDS_DEF_SH     10
160 #define TMDS_ONE_MASK   0x0800
161 #define TMDS_ONE_SH     11
162 #define TMDS_LTINT_MASK 0x1000
163 #define TMDS_LTINT_SH   12
164 #define TMDS_NOFCS_MASK 0x2000
165 #define TMDS_NOFCS_SH   13
166 #define TMDS_ADDFCS_MASK TMDS_NOFCS_MASK
167 #define TMDS_ADDFCS_SH  TMDS_NOFCS_SH
168 #define TMDS_ERR_MASK   0x4000
169 #define TMDS_ERR_SH     14
170 #define TMDS_OWN_MASK   0x8000
171 #define TMDS_OWN_SH     15
172 
173 #define TMDM_TRC_MASK   0x0000000f
174 #define TMDM_TRC_SH     0
175 #define TMDM_TDR_MASK   0x03ff0000
176 #define TMDM_TDR_SH     16
177 #define TMDM_RTRY_MASK  0x04000000
178 #define TMDM_RTRY_SH    26
179 #define TMDM_LCAR_MASK  0x08000000
180 #define TMDM_LCAR_SH    27
181 #define TMDM_LCOL_MASK  0x10000000
182 #define TMDM_LCOL_SH    28
183 #define TMDM_EXDEF_MASK 0x20000000
184 #define TMDM_EXDEF_SH   29
185 #define TMDM_UFLO_MASK  0x40000000
186 #define TMDM_UFLO_SH    30
187 #define TMDM_BUFF_MASK  0x80000000
188 #define TMDM_BUFF_SH    31
189 
190 struct pcnet_RMD {
191     uint32_t rbadr;
192     int16_t buf_length;
193     int16_t status;
194     uint32_t msg_length;
195     uint32_t res;
196 };
197 
198 #define RMDL_BCNT_MASK  0x0fff
199 #define RMDL_BCNT_SH    0
200 #define RMDL_ONES_MASK  0xf000
201 #define RMDL_ONES_SH    12
202 
203 #define RMDS_BAM_MASK   0x0010
204 #define RMDS_BAM_SH     4
205 #define RMDS_LFAM_MASK  0x0020
206 #define RMDS_LFAM_SH    5
207 #define RMDS_PAM_MASK   0x0040
208 #define RMDS_PAM_SH     6
209 #define RMDS_BPE_MASK   0x0080
210 #define RMDS_BPE_SH     7
211 #define RMDS_ENP_MASK   0x0100
212 #define RMDS_ENP_SH     8
213 #define RMDS_STP_MASK   0x0200
214 #define RMDS_STP_SH     9
215 #define RMDS_BUFF_MASK  0x0400
216 #define RMDS_BUFF_SH    10
217 #define RMDS_CRC_MASK   0x0800
218 #define RMDS_CRC_SH     11
219 #define RMDS_OFLO_MASK  0x1000
220 #define RMDS_OFLO_SH    12
221 #define RMDS_FRAM_MASK  0x2000
222 #define RMDS_FRAM_SH    13
223 #define RMDS_ERR_MASK   0x4000
224 #define RMDS_ERR_SH     14
225 #define RMDS_OWN_MASK   0x8000
226 #define RMDS_OWN_SH     15
227 
228 #define RMDM_MCNT_MASK  0x00000fff
229 #define RMDM_MCNT_SH    0
230 #define RMDM_ZEROS_MASK 0x0000f000
231 #define RMDM_ZEROS_SH   12
232 #define RMDM_RPC_MASK   0x00ff0000
233 #define RMDM_RPC_SH     16
234 #define RMDM_RCC_MASK   0xff000000
235 #define RMDM_RCC_SH     24
236 
237 #define SET_FIELD(regp, name, field, value)             \
238   (*(regp) = (*(regp) & ~(name ## _ ## field ## _MASK)) \
239              | ((value) << name ## _ ## field ## _SH))
240 
241 #define GET_FIELD(reg, name, field)                     \
242   (((reg) & name ## _ ## field ## _MASK) >> name ## _ ## field ## _SH)
243 
244 #define PRINT_TMD(T) printf(                            \
245         "TMD0 : TBADR=0x%08x\n"                         \
246         "TMD1 : OWN=%d, ERR=%d, FCS=%d, LTI=%d, "       \
247         "ONE=%d, DEF=%d, STP=%d, ENP=%d,\n"             \
248         "       BPE=%d, BCNT=%d\n"                      \
249         "TMD2 : BUF=%d, UFL=%d, EXD=%d, LCO=%d, "       \
250         "LCA=%d, RTR=%d,\n"                             \
251         "       TDR=%d, TRC=%d\n",                      \
252         (T)->tbadr,                                     \
253         GET_FIELD((T)->status, TMDS, OWN),              \
254         GET_FIELD((T)->status, TMDS, ERR),              \
255         GET_FIELD((T)->status, TMDS, NOFCS),            \
256         GET_FIELD((T)->status, TMDS, LTINT),            \
257         GET_FIELD((T)->status, TMDS, ONE),              \
258         GET_FIELD((T)->status, TMDS, DEF),              \
259         GET_FIELD((T)->status, TMDS, STP),              \
260         GET_FIELD((T)->status, TMDS, ENP),              \
261         GET_FIELD((T)->status, TMDS, BPE),              \
262         4096-GET_FIELD((T)->length, TMDL, BCNT),        \
263         GET_FIELD((T)->misc, TMDM, BUFF),               \
264         GET_FIELD((T)->misc, TMDM, UFLO),               \
265         GET_FIELD((T)->misc, TMDM, EXDEF),              \
266         GET_FIELD((T)->misc, TMDM, LCOL),               \
267         GET_FIELD((T)->misc, TMDM, LCAR),               \
268         GET_FIELD((T)->misc, TMDM, RTRY),               \
269         GET_FIELD((T)->misc, TMDM, TDR),                \
270         GET_FIELD((T)->misc, TMDM, TRC))
271 
272 #define PRINT_RMD(R) printf(                            \
273         "RMD0 : RBADR=0x%08x\n"                         \
274         "RMD1 : OWN=%d, ERR=%d, FRAM=%d, OFLO=%d, "     \
275         "CRC=%d, BUFF=%d, STP=%d, ENP=%d,\n       "     \
276         "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n" \
277         "RMD2 : RCC=%d, RPC=%d, MCNT=%d, ZEROS=%d\n",   \
278         (R)->rbadr,                                     \
279         GET_FIELD((R)->status, RMDS, OWN),              \
280         GET_FIELD((R)->status, RMDS, ERR),              \
281         GET_FIELD((R)->status, RMDS, FRAM),             \
282         GET_FIELD((R)->status, RMDS, OFLO),             \
283         GET_FIELD((R)->status, RMDS, CRC),              \
284         GET_FIELD((R)->status, RMDS, BUFF),             \
285         GET_FIELD((R)->status, RMDS, STP),              \
286         GET_FIELD((R)->status, RMDS, ENP),              \
287         GET_FIELD((R)->status, RMDS, BPE),              \
288         GET_FIELD((R)->status, RMDS, PAM),              \
289         GET_FIELD((R)->status, RMDS, LFAM),             \
290         GET_FIELD((R)->status, RMDS, BAM),              \
291         GET_FIELD((R)->buf_length, RMDL, ONES),         \
292         4096-GET_FIELD((R)->buf_length, RMDL, BCNT),    \
293         GET_FIELD((R)->msg_length, RMDM, RCC),          \
294         GET_FIELD((R)->msg_length, RMDM, RPC),          \
295         GET_FIELD((R)->msg_length, RMDM, MCNT),         \
296         GET_FIELD((R)->msg_length, RMDM, ZEROS))
297 
298 static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd,
299                                   hwaddr addr)
300 {
301     if (!BCR_SSIZE32(s)) {
302         struct {
303             uint32_t tbadr;
304             int16_t length;
305             int16_t status;
306         } xda;
307         s->phys_mem_read(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
308         tmd->tbadr = le32_to_cpu(xda.tbadr) & 0xffffff;
309         tmd->length = le16_to_cpu(xda.length);
310         tmd->status = (le32_to_cpu(xda.tbadr) >> 16) & 0xff00;
311         tmd->misc = le16_to_cpu(xda.status) << 16;
312         tmd->res = 0;
313     } else {
314         s->phys_mem_read(s->dma_opaque, addr, (void *)tmd, sizeof(*tmd), 0);
315         le32_to_cpus(&tmd->tbadr);
316         le16_to_cpus((uint16_t *)&tmd->length);
317         le16_to_cpus((uint16_t *)&tmd->status);
318         le32_to_cpus(&tmd->misc);
319         le32_to_cpus(&tmd->res);
320         if (BCR_SWSTYLE(s) == 3) {
321             uint32_t tmp = tmd->tbadr;
322             tmd->tbadr = tmd->misc;
323             tmd->misc = tmp;
324         }
325     }
326 }
327 
328 static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd,
329                                    hwaddr addr)
330 {
331     if (!BCR_SSIZE32(s)) {
332         struct {
333             uint32_t tbadr;
334             int16_t length;
335             int16_t status;
336         } xda;
337         xda.tbadr = cpu_to_le32((tmd->tbadr & 0xffffff) |
338                                 ((tmd->status & 0xff00) << 16));
339         xda.length = cpu_to_le16(tmd->length);
340         xda.status = cpu_to_le16(tmd->misc >> 16);
341         s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
342     } else {
343         struct {
344             uint32_t tbadr;
345             int16_t length;
346             int16_t status;
347             uint32_t misc;
348             uint32_t res;
349         } xda;
350         xda.tbadr = cpu_to_le32(tmd->tbadr);
351         xda.length = cpu_to_le16(tmd->length);
352         xda.status = cpu_to_le16(tmd->status);
353         xda.misc = cpu_to_le32(tmd->misc);
354         xda.res = cpu_to_le32(tmd->res);
355         if (BCR_SWSTYLE(s) == 3) {
356             uint32_t tmp = xda.tbadr;
357             xda.tbadr = xda.misc;
358             xda.misc = tmp;
359         }
360         s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
361     }
362 }
363 
364 static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd,
365                                   hwaddr addr)
366 {
367     if (!BCR_SSIZE32(s)) {
368         struct {
369             uint32_t rbadr;
370             int16_t buf_length;
371             int16_t msg_length;
372 	} rda;
373         s->phys_mem_read(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
374         rmd->rbadr = le32_to_cpu(rda.rbadr) & 0xffffff;
375         rmd->buf_length = le16_to_cpu(rda.buf_length);
376         rmd->status = (le32_to_cpu(rda.rbadr) >> 16) & 0xff00;
377         rmd->msg_length = le16_to_cpu(rda.msg_length);
378         rmd->res = 0;
379     } else {
380         s->phys_mem_read(s->dma_opaque, addr, (void *)rmd, sizeof(*rmd), 0);
381         le32_to_cpus(&rmd->rbadr);
382         le16_to_cpus((uint16_t *)&rmd->buf_length);
383         le16_to_cpus((uint16_t *)&rmd->status);
384         le32_to_cpus(&rmd->msg_length);
385         le32_to_cpus(&rmd->res);
386         if (BCR_SWSTYLE(s) == 3) {
387             uint32_t tmp = rmd->rbadr;
388             rmd->rbadr = rmd->msg_length;
389             rmd->msg_length = tmp;
390         }
391     }
392 }
393 
394 static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
395                                    hwaddr addr)
396 {
397     if (!BCR_SSIZE32(s)) {
398         struct {
399             uint32_t rbadr;
400             int16_t buf_length;
401             int16_t msg_length;
402         } rda;
403         rda.rbadr = cpu_to_le32((rmd->rbadr & 0xffffff) |
404                                 ((rmd->status & 0xff00) << 16));
405         rda.buf_length = cpu_to_le16(rmd->buf_length);
406         rda.msg_length = cpu_to_le16(rmd->msg_length);
407         s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
408     } else {
409         struct {
410             uint32_t rbadr;
411             int16_t buf_length;
412             int16_t status;
413             uint32_t msg_length;
414             uint32_t res;
415         } rda;
416         rda.rbadr = cpu_to_le32(rmd->rbadr);
417         rda.buf_length = cpu_to_le16(rmd->buf_length);
418         rda.status = cpu_to_le16(rmd->status);
419         rda.msg_length = cpu_to_le32(rmd->msg_length);
420         rda.res = cpu_to_le32(rmd->res);
421         if (BCR_SWSTYLE(s) == 3) {
422             uint32_t tmp = rda.rbadr;
423             rda.rbadr = rda.msg_length;
424             rda.msg_length = tmp;
425         }
426         s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
427     }
428 }
429 
430 
431 #define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
432 
433 #define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
434 
435 #define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
436 
437 #define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
438 
439 #if 1
440 
441 #define CHECK_RMD(ADDR,RES) do {                \
442     struct pcnet_RMD rmd;                       \
443     RMDLOAD(&rmd,(ADDR));                       \
444     (RES) |= (GET_FIELD(rmd.buf_length, RMDL, ONES) != 15) \
445           || (GET_FIELD(rmd.msg_length, RMDM, ZEROS) != 0); \
446 } while (0)
447 
448 #define CHECK_TMD(ADDR,RES) do {                \
449     struct pcnet_TMD tmd;                       \
450     TMDLOAD(&tmd,(ADDR));                       \
451     (RES) |= (GET_FIELD(tmd.length, TMDL, ONES) != 15); \
452 } while (0)
453 
454 #else
455 
456 #define CHECK_RMD(ADDR,RES) do {                \
457     switch (BCR_SWSTYLE(s)) {                   \
458     case 0x00:                                  \
459         {                                       \
460             uint16_t rda[4];                    \
461             s->phys_mem_read(s->dma_opaque, (ADDR), \
462                 (void *)&rda[0], sizeof(rda), 0); \
463             (RES) |= (rda[2] & 0xf000)!=0xf000; \
464             (RES) |= (rda[3] & 0xf000)!=0x0000; \
465         }                                       \
466         break;                                  \
467     case 0x01:                                  \
468     case 0x02:                                  \
469         {                                       \
470             uint32_t rda[4];                    \
471             s->phys_mem_read(s->dma_opaque, (ADDR), \
472                 (void *)&rda[0], sizeof(rda), 0); \
473             (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
474             (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
475         }                                       \
476         break;                                  \
477     case 0x03:                                  \
478         {                                       \
479             uint32_t rda[4];                    \
480             s->phys_mem_read(s->dma_opaque, (ADDR), \
481                 (void *)&rda[0], sizeof(rda), 0); \
482             (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
483             (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
484         }                                       \
485         break;                                  \
486     }                                           \
487 } while (0)
488 
489 #define CHECK_TMD(ADDR,RES) do {                \
490     switch (BCR_SWSTYLE(s)) {                   \
491     case 0x00:                                  \
492         {                                       \
493             uint16_t xda[4];                    \
494             s->phys_mem_read(s->dma_opaque, (ADDR), \
495                 (void *)&xda[0], sizeof(xda), 0); \
496             (RES) |= (xda[2] & 0xf000)!=0xf000; \
497         }                                       \
498         break;                                  \
499     case 0x01:                                  \
500     case 0x02:                                  \
501     case 0x03:                                  \
502         {                                       \
503             uint32_t xda[4];                    \
504             s->phys_mem_read(s->dma_opaque, (ADDR), \
505                 (void *)&xda[0], sizeof(xda), 0); \
506             (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
507         }                                       \
508         break;                                  \
509     }                                           \
510 } while (0)
511 
512 #endif
513 
514 #define PRINT_PKTHDR(BUF) do {                  \
515     struct qemu_ether_header *hdr = (void *)(BUF); \
516     printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \
517            "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \
518            "type=0x%04x\n",                     \
519            hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
520            hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
521            hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
522            hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
523            be16_to_cpu(hdr->ether_type));       \
524 } while (0)
525 
526 #define CRC(crc, ch)	 (crc = (crc >> 8) ^ crctab[(crc ^ (ch)) & 0xff])
527 
528 /* generated using the AUTODIN II polynomial
529  *	x^32 + x^26 + x^23 + x^22 + x^16 +
530  *	x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
531  */
532 static const uint32_t crctab[256] = {
533 	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
534 	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
535 	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
536 	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
537 	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
538 	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
539 	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
540 	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
541 	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
542 	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
543 	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
544 	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
545 	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
546 	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
547 	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
548 	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
549 	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
550 	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
551 	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
552 	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
553 	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
554 	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
555 	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
556 	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
557 	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
558 	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
559 	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
560 	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
561 	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
562 	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
563 	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
564 	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
565 	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
566 	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
567 	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
568 	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
569 	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
570 	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
571 	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
572 	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
573 	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
574 	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
575 	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
576 	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
577 	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
578 	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
579 	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
580 	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
581 	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
582 	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
583 	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
584 	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
585 	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
586 	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
587 	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
588 	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
589 	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
590 	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
591 	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
592 	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
593 	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
594 	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
595 	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
596 	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
597 };
598 
599 static inline int padr_match(PCNetState *s, const uint8_t *buf, int size)
600 {
601     struct qemu_ether_header *hdr = (void *)buf;
602     uint8_t padr[6] = {
603         s->csr[12] & 0xff, s->csr[12] >> 8,
604         s->csr[13] & 0xff, s->csr[13] >> 8,
605         s->csr[14] & 0xff, s->csr[14] >> 8
606     };
607     int result = (!CSR_DRCVPA(s)) && !memcmp(hdr->ether_dhost, padr, 6);
608 #ifdef PCNET_DEBUG_MATCH
609     printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "
610            "padr=%02x:%02x:%02x:%02x:%02x:%02x\n",
611            hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2],
612            hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5],
613            padr[0],padr[1],padr[2],padr[3],padr[4],padr[5]);
614     printf("padr_match result=%d\n", result);
615 #endif
616     return result;
617 }
618 
619 static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size)
620 {
621     static const uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
622     struct qemu_ether_header *hdr = (void *)buf;
623     int result = !CSR_DRCVBC(s) && !memcmp(hdr->ether_dhost, BCAST, 6);
624 #ifdef PCNET_DEBUG_MATCH
625     printf("padr_bcast result=%d\n", result);
626 #endif
627     return result;
628 }
629 
630 static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
631 {
632     struct qemu_ether_header *hdr = (void *)buf;
633     if ((*(hdr->ether_dhost)&0x01) &&
634         ((uint64_t *)&s->csr[8])[0] != 0LL) {
635         uint8_t ladr[8] = {
636             s->csr[8] & 0xff, s->csr[8] >> 8,
637             s->csr[9] & 0xff, s->csr[9] >> 8,
638             s->csr[10] & 0xff, s->csr[10] >> 8,
639             s->csr[11] & 0xff, s->csr[11] >> 8
640         };
641         int index = net_crc32_le(hdr->ether_dhost, ETH_ALEN) >> 26;
642         return !!(ladr[index >> 3] & (1 << (index & 7)));
643     }
644     return 0;
645 }
646 
647 static inline hwaddr pcnet_rdra_addr(PCNetState *s, int idx)
648 {
649     while (idx < 1) {
650         idx += CSR_RCVRL(s);
651     }
652     return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
653 }
654 
655 static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
656 {
657     int64_t next_time = current_time +
658                         (65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s))) * 30;
659 
660     if (next_time <= current_time) {
661         next_time = current_time + 1;
662     }
663     return next_time;
664 }
665 
666 static void pcnet_poll(PCNetState *s);
667 static void pcnet_poll_timer(void *opaque);
668 
669 static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
670 static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
671 static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
672 
673 static void pcnet_s_reset(PCNetState *s)
674 {
675     trace_pcnet_s_reset(s);
676 
677     s->rdra = 0;
678     s->tdra = 0;
679     s->rap = 0;
680 
681     s->bcr[BCR_BSBC] &= ~0x0080;
682 
683     s->csr[0]   = 0x0004;
684     s->csr[3]   = 0x0000;
685     s->csr[4]   = 0x0115;
686     s->csr[5]   = 0x0000;
687     s->csr[6]   = 0x0000;
688     s->csr[8]   = 0;
689     s->csr[9]   = 0;
690     s->csr[10]  = 0;
691     s->csr[11]  = 0;
692     s->csr[12]  = le16_to_cpu(((uint16_t *)&s->prom[0])[0]);
693     s->csr[13]  = le16_to_cpu(((uint16_t *)&s->prom[0])[1]);
694     s->csr[14]  = le16_to_cpu(((uint16_t *)&s->prom[0])[2]);
695     s->csr[15] &= 0x21c4;
696     s->csr[72]  = 1;
697     s->csr[74]  = 1;
698     s->csr[76]  = 1;
699     s->csr[78]  = 1;
700     s->csr[80]  = 0x1410;
701     s->csr[88]  = 0x1003;
702     s->csr[89]  = 0x0262;
703     s->csr[94]  = 0x0000;
704     s->csr[100] = 0x0200;
705     s->csr[103] = 0x0105;
706     s->csr[112] = 0x0000;
707     s->csr[114] = 0x0000;
708     s->csr[122] = 0x0000;
709     s->csr[124] = 0x0000;
710 
711     s->tx_busy = 0;
712 }
713 
714 static void pcnet_update_irq(PCNetState *s)
715 {
716     int isr = 0;
717     s->csr[0] &= ~0x0080;
718 
719 #if 1
720     if (((s->csr[0] & ~s->csr[3]) & 0x5f00) ||
721         (((s->csr[4]>>1) & ~s->csr[4]) & 0x0115) ||
722         (((s->csr[5]>>1) & s->csr[5]) & 0x0048))
723 #else
724     if ((!(s->csr[3] & 0x4000) && !!(s->csr[0] & 0x4000)) /* BABL */ ||
725         (!(s->csr[3] & 0x1000) && !!(s->csr[0] & 0x1000)) /* MISS */ ||
726         (!(s->csr[3] & 0x0100) && !!(s->csr[0] & 0x0100)) /* IDON */ ||
727         (!(s->csr[3] & 0x0200) && !!(s->csr[0] & 0x0200)) /* TINT */ ||
728         (!(s->csr[3] & 0x0400) && !!(s->csr[0] & 0x0400)) /* RINT */ ||
729         (!(s->csr[3] & 0x0800) && !!(s->csr[0] & 0x0800)) /* MERR */ ||
730         (!(s->csr[4] & 0x0001) && !!(s->csr[4] & 0x0002)) /* JAB */ ||
731         (!(s->csr[4] & 0x0004) && !!(s->csr[4] & 0x0008)) /* TXSTRT */ ||
732         (!(s->csr[4] & 0x0010) && !!(s->csr[4] & 0x0020)) /* RCVO */ ||
733         (!(s->csr[4] & 0x0100) && !!(s->csr[4] & 0x0200)) /* MFCO */ ||
734         (!!(s->csr[5] & 0x0040) && !!(s->csr[5] & 0x0080)) /* EXDINT */ ||
735         (!!(s->csr[5] & 0x0008) && !!(s->csr[5] & 0x0010)) /* MPINT */)
736 #endif
737     {
738 
739         isr = CSR_INEA(s);
740         s->csr[0] |= 0x0080;
741     }
742 
743     if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
744         s->csr[4] &= ~0x0080;
745         s->csr[4] |= 0x0040;
746         s->csr[0] |= 0x0080;
747         isr = 1;
748         trace_pcnet_user_int(s);
749     }
750 
751 #if 1
752     if (((s->csr[5]>>1) & s->csr[5]) & 0x0500)
753 #else
754     if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
755         (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
756 #endif
757     {
758         isr = 1;
759         s->csr[0] |= 0x0080;
760     }
761 
762     if (isr != s->isr) {
763         trace_pcnet_isr_change(s, isr, s->isr);
764     }
765     qemu_set_irq(s->irq, isr);
766     s->isr = isr;
767 }
768 
769 static void pcnet_init(PCNetState *s)
770 {
771     int rlen, tlen;
772     uint16_t padr[3], ladrf[4], mode;
773     uint32_t rdra, tdra;
774 
775     trace_pcnet_init(s, PHYSADDR(s, CSR_IADR(s)));
776 
777     if (BCR_SSIZE32(s)) {
778         struct pcnet_initblk32 initblk;
779         s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
780                 (uint8_t *)&initblk, sizeof(initblk), 0);
781         mode = le16_to_cpu(initblk.mode);
782         rlen = initblk.rlen >> 4;
783         tlen = initblk.tlen >> 4;
784         ladrf[0] = le16_to_cpu(initblk.ladrf[0]);
785         ladrf[1] = le16_to_cpu(initblk.ladrf[1]);
786         ladrf[2] = le16_to_cpu(initblk.ladrf[2]);
787         ladrf[3] = le16_to_cpu(initblk.ladrf[3]);
788         padr[0] = le16_to_cpu(initblk.padr[0]);
789         padr[1] = le16_to_cpu(initblk.padr[1]);
790         padr[2] = le16_to_cpu(initblk.padr[2]);
791         rdra = le32_to_cpu(initblk.rdra);
792         tdra = le32_to_cpu(initblk.tdra);
793     } else {
794         struct pcnet_initblk16 initblk;
795         s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
796                 (uint8_t *)&initblk, sizeof(initblk), 0);
797         mode = le16_to_cpu(initblk.mode);
798         ladrf[0] = le16_to_cpu(initblk.ladrf[0]);
799         ladrf[1] = le16_to_cpu(initblk.ladrf[1]);
800         ladrf[2] = le16_to_cpu(initblk.ladrf[2]);
801         ladrf[3] = le16_to_cpu(initblk.ladrf[3]);
802         padr[0] = le16_to_cpu(initblk.padr[0]);
803         padr[1] = le16_to_cpu(initblk.padr[1]);
804         padr[2] = le16_to_cpu(initblk.padr[2]);
805         rdra = le32_to_cpu(initblk.rdra);
806         tdra = le32_to_cpu(initblk.tdra);
807         rlen = rdra >> 29;
808         tlen = tdra >> 29;
809         rdra &= 0x00ffffff;
810         tdra &= 0x00ffffff;
811     }
812 
813     trace_pcnet_rlen_tlen(s, rlen, tlen);
814 
815     CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512;
816     CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512;
817     s->csr[ 6] = (tlen << 12) | (rlen << 8);
818     s->csr[15] = mode;
819     s->csr[ 8] = ladrf[0];
820     s->csr[ 9] = ladrf[1];
821     s->csr[10] = ladrf[2];
822     s->csr[11] = ladrf[3];
823     s->csr[12] = padr[0];
824     s->csr[13] = padr[1];
825     s->csr[14] = padr[2];
826     s->rdra = PHYSADDR(s, rdra);
827     s->tdra = PHYSADDR(s, tdra);
828 
829     CSR_RCVRC(s) = CSR_RCVRL(s);
830     CSR_XMTRC(s) = CSR_XMTRL(s);
831 
832     trace_pcnet_ss32_rdra_tdra(s, BCR_SSIZE32(s),
833                                s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
834 
835     s->csr[0] |= 0x0101;
836     s->csr[0] &= ~0x0004;       /* clear STOP bit */
837 
838     qemu_flush_queued_packets(qemu_get_queue(s->nic));
839 }
840 
841 static void pcnet_start(PCNetState *s)
842 {
843 #ifdef PCNET_DEBUG
844     printf("pcnet_start\n");
845 #endif
846 
847     if (!CSR_DTX(s)) {
848         s->csr[0] |= 0x0010;    /* set TXON */
849     }
850     if (!CSR_DRX(s)) {
851         s->csr[0] |= 0x0020;    /* set RXON */
852     }
853     s->csr[0] &= ~0x0004;       /* clear STOP bit */
854     s->csr[0] |= 0x0002;
855     pcnet_poll_timer(s);
856 
857     qemu_flush_queued_packets(qemu_get_queue(s->nic));
858 }
859 
860 static void pcnet_stop(PCNetState *s)
861 {
862 #ifdef PCNET_DEBUG
863     printf("pcnet_stop\n");
864 #endif
865     s->csr[0] &= ~0xffeb;
866     s->csr[0] |= 0x0014;
867     s->csr[4] &= ~0x02c2;
868     s->csr[5] &= ~0x0011;
869     pcnet_poll_timer(s);
870 }
871 
872 static void pcnet_rdte_poll(PCNetState *s)
873 {
874     s->csr[28] = s->csr[29] = 0;
875     if (s->rdra) {
876         int bad = 0;
877 #if 1
878         hwaddr crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
879         hwaddr nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
880         hwaddr nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
881 #else
882         hwaddr crda = s->rdra +
883             (CSR_RCVRL(s) - CSR_RCVRC(s)) *
884             (BCR_SWSTYLE(s) ? 16 : 8 );
885         int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
886         hwaddr nrda = s->rdra +
887             (CSR_RCVRL(s) - nrdc) *
888             (BCR_SWSTYLE(s) ? 16 : 8 );
889         int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
890         hwaddr nnrd = s->rdra +
891             (CSR_RCVRL(s) - nnrc) *
892             (BCR_SWSTYLE(s) ? 16 : 8 );
893 #endif
894 
895         CHECK_RMD(crda, bad);
896         if (!bad) {
897             CHECK_RMD(nrda, bad);
898             if (bad || (nrda == crda)) nrda = 0;
899             CHECK_RMD(nnrd, bad);
900             if (bad || (nnrd == crda)) nnrd = 0;
901 
902             s->csr[28] = crda & 0xffff;
903             s->csr[29] = crda >> 16;
904             s->csr[26] = nrda & 0xffff;
905             s->csr[27] = nrda >> 16;
906             s->csr[36] = nnrd & 0xffff;
907             s->csr[37] = nnrd >> 16;
908 #ifdef PCNET_DEBUG
909             if (bad) {
910                 printf("pcnet: BAD RMD RECORDS AFTER 0x" TARGET_FMT_plx "\n",
911                        crda);
912             }
913         } else {
914             printf("pcnet: BAD RMD RDA=0x" TARGET_FMT_plx "\n", crda);
915 #endif
916         }
917     }
918 
919     if (CSR_CRDA(s)) {
920         struct pcnet_RMD rmd;
921         RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
922         CSR_CRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
923         CSR_CRST(s) = rmd.status;
924 #ifdef PCNET_DEBUG_RMD_X
925         printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMDL=0x%04x RMDS=0x%04x RMDM=0x%08x\n",
926                 PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
927                 rmd.buf_length, rmd.status, rmd.msg_length);
928         PRINT_RMD(&rmd);
929 #endif
930     } else {
931         CSR_CRBC(s) = CSR_CRST(s) = 0;
932     }
933 
934     if (CSR_NRDA(s)) {
935         struct pcnet_RMD rmd;
936         RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
937         CSR_NRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
938         CSR_NRST(s) = rmd.status;
939     } else {
940         CSR_NRBC(s) = CSR_NRST(s) = 0;
941     }
942 
943 }
944 
945 static int pcnet_tdte_poll(PCNetState *s)
946 {
947     s->csr[34] = s->csr[35] = 0;
948     if (s->tdra) {
949         hwaddr cxda = s->tdra +
950             (CSR_XMTRL(s) - CSR_XMTRC(s)) *
951             (BCR_SWSTYLE(s) ? 16 : 8);
952         int bad = 0;
953         CHECK_TMD(cxda, bad);
954         if (!bad) {
955             if (CSR_CXDA(s) != cxda) {
956                 s->csr[60] = s->csr[34];
957                 s->csr[61] = s->csr[35];
958                 s->csr[62] = CSR_CXBC(s);
959                 s->csr[63] = CSR_CXST(s);
960             }
961             s->csr[34] = cxda & 0xffff;
962             s->csr[35] = cxda >> 16;
963 #ifdef PCNET_DEBUG_X
964             printf("pcnet: BAD TMD XDA=0x%08x\n", cxda);
965 #endif
966         }
967     }
968 
969     if (CSR_CXDA(s)) {
970         struct pcnet_TMD tmd;
971 
972         TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
973 
974         CSR_CXBC(s) = GET_FIELD(tmd.length, TMDL, BCNT);
975         CSR_CXST(s) = tmd.status;
976     } else {
977         CSR_CXBC(s) = CSR_CXST(s) = 0;
978     }
979 
980     return !!(CSR_CXST(s) & 0x8000);
981 }
982 
983 #define MIN_BUF_SIZE 60
984 
985 ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
986 {
987     PCNetState *s = qemu_get_nic_opaque(nc);
988     int is_padr = 0, is_bcast = 0, is_ladr = 0;
989     uint8_t buf1[60];
990     int remaining;
991     int crc_err = 0;
992     size_t size = size_;
993 
994     if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size ||
995         (CSR_LOOP(s) && !s->looptest)) {
996         return -1;
997     }
998 #ifdef PCNET_DEBUG
999     printf("pcnet_receive size=%zu\n", size);
1000 #endif
1001 
1002     /* if too small buffer, then expand it */
1003     if (size < MIN_BUF_SIZE) {
1004         memcpy(buf1, buf, size);
1005         memset(buf1 + size, 0, MIN_BUF_SIZE - size);
1006         buf = buf1;
1007         size = MIN_BUF_SIZE;
1008     }
1009 
1010     if (CSR_PROM(s)
1011         || (is_padr=padr_match(s, buf, size))
1012         || (is_bcast=padr_bcast(s, buf, size))
1013         || (is_ladr=ladr_match(s, buf, size))) {
1014 
1015         pcnet_rdte_poll(s);
1016 
1017         if (!(CSR_CRST(s) & 0x8000) && s->rdra) {
1018             struct pcnet_RMD rmd;
1019             int rcvrc = CSR_RCVRC(s)-1,i;
1020             hwaddr nrda;
1021             for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {
1022                 if (rcvrc <= 1)
1023                     rcvrc = CSR_RCVRL(s);
1024                 nrda = s->rdra +
1025                     (CSR_RCVRL(s) - rcvrc) *
1026                     (BCR_SWSTYLE(s) ? 16 : 8 );
1027                 RMDLOAD(&rmd, nrda);
1028                 if (GET_FIELD(rmd.status, RMDS, OWN)) {
1029 #ifdef PCNET_DEBUG_RMD
1030                     printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",
1031                                 rcvrc, CSR_RCVRC(s));
1032 #endif
1033                     CSR_RCVRC(s) = rcvrc;
1034                     pcnet_rdte_poll(s);
1035                     break;
1036                 }
1037             }
1038         }
1039 
1040         if (!(CSR_CRST(s) & 0x8000)) {
1041 #ifdef PCNET_DEBUG_RMD
1042             printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));
1043 #endif
1044             s->csr[0] |= 0x1000; /* Set MISS flag */
1045             CSR_MISSC(s)++;
1046         } else {
1047             uint8_t *src = s->buffer;
1048             hwaddr crda = CSR_CRDA(s);
1049             struct pcnet_RMD rmd;
1050             int pktcount = 0;
1051 
1052             if (!s->looptest) {
1053                 if (size > 4092) {
1054 #ifdef PCNET_DEBUG_RMD
1055                     fprintf(stderr, "pcnet: truncates rx packet.\n");
1056 #endif
1057                     size = 4092;
1058                 }
1059                 memcpy(src, buf, size);
1060                 /* no need to compute the CRC */
1061                 src[size] = 0;
1062                 src[size + 1] = 0;
1063                 src[size + 2] = 0;
1064                 src[size + 3] = 0;
1065                 size += 4;
1066             } else if (s->looptest == PCNET_LOOPTEST_CRC ||
1067                        !CSR_DXMTFCS(s) || size < MIN_BUF_SIZE+4) {
1068                 uint32_t fcs = ~0;
1069                 uint8_t *p = src;
1070 
1071                 while (p != &src[size])
1072                     CRC(fcs, *p++);
1073                 *(uint32_t *)p = htonl(fcs);
1074                 size += 4;
1075             } else {
1076                 uint32_t fcs = ~0;
1077                 uint8_t *p = src;
1078 
1079                 while (p != &src[size])
1080                     CRC(fcs, *p++);
1081                 crc_err = (*(uint32_t *)p != htonl(fcs));
1082             }
1083 
1084 #ifdef PCNET_DEBUG_MATCH
1085             PRINT_PKTHDR(buf);
1086 #endif
1087 
1088             RMDLOAD(&rmd, PHYSADDR(s,crda));
1089             /*if (!CSR_LAPPEN(s))*/
1090                 SET_FIELD(&rmd.status, RMDS, STP, 1);
1091 
1092 #define PCNET_RECV_STORE() do {                                 \
1093     int count = MIN(4096 - GET_FIELD(rmd.buf_length, RMDL, BCNT),remaining); \
1094     hwaddr rbadr = PHYSADDR(s, rmd.rbadr);          \
1095     s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \
1096     src += count; remaining -= count;                           \
1097     SET_FIELD(&rmd.status, RMDS, OWN, 0);                       \
1098     RMDSTORE(&rmd, PHYSADDR(s,crda));                           \
1099     pktcount++;                                                 \
1100 } while (0)
1101 
1102             remaining = size;
1103             PCNET_RECV_STORE();
1104             if ((remaining > 0) && CSR_NRDA(s)) {
1105                 hwaddr nrda = CSR_NRDA(s);
1106 #ifdef PCNET_DEBUG_RMD
1107                 PRINT_RMD(&rmd);
1108 #endif
1109                 RMDLOAD(&rmd, PHYSADDR(s,nrda));
1110                 if (GET_FIELD(rmd.status, RMDS, OWN)) {
1111                     crda = nrda;
1112                     PCNET_RECV_STORE();
1113 #ifdef PCNET_DEBUG_RMD
1114                     PRINT_RMD(&rmd);
1115 #endif
1116                     if ((remaining > 0) && (nrda=CSR_NNRD(s))) {
1117                         RMDLOAD(&rmd, PHYSADDR(s,nrda));
1118                         if (GET_FIELD(rmd.status, RMDS, OWN)) {
1119                             crda = nrda;
1120                             PCNET_RECV_STORE();
1121                         }
1122                     }
1123                 }
1124             }
1125 
1126 #undef PCNET_RECV_STORE
1127 
1128             RMDLOAD(&rmd, PHYSADDR(s,crda));
1129             if (remaining == 0) {
1130                 SET_FIELD(&rmd.msg_length, RMDM, MCNT, size);
1131                 SET_FIELD(&rmd.status, RMDS, ENP, 1);
1132                 SET_FIELD(&rmd.status, RMDS, PAM, !CSR_PROM(s) && is_padr);
1133                 SET_FIELD(&rmd.status, RMDS, LFAM, !CSR_PROM(s) && is_ladr);
1134                 SET_FIELD(&rmd.status, RMDS, BAM, !CSR_PROM(s) && is_bcast);
1135                 if (crc_err) {
1136                     SET_FIELD(&rmd.status, RMDS, CRC, 1);
1137                     SET_FIELD(&rmd.status, RMDS, ERR, 1);
1138                 }
1139             } else {
1140                 SET_FIELD(&rmd.status, RMDS, OFLO, 1);
1141                 SET_FIELD(&rmd.status, RMDS, BUFF, 1);
1142                 SET_FIELD(&rmd.status, RMDS, ERR, 1);
1143             }
1144             RMDSTORE(&rmd, PHYSADDR(s,crda));
1145             s->csr[0] |= 0x0400;
1146 
1147 #ifdef PCNET_DEBUG
1148             printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",
1149                 CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
1150 #endif
1151 #ifdef PCNET_DEBUG_RMD
1152             PRINT_RMD(&rmd);
1153 #endif
1154 
1155             while (pktcount--) {
1156                 if (CSR_RCVRC(s) <= 1) {
1157                     CSR_RCVRC(s) = CSR_RCVRL(s);
1158                 } else {
1159                     CSR_RCVRC(s)--;
1160                 }
1161             }
1162 
1163             pcnet_rdte_poll(s);
1164 
1165         }
1166     }
1167 
1168     pcnet_poll(s);
1169     pcnet_update_irq(s);
1170 
1171     return size_;
1172 }
1173 
1174 void pcnet_set_link_status(NetClientState *nc)
1175 {
1176     PCNetState *d = qemu_get_nic_opaque(nc);
1177 
1178     d->lnkst = nc->link_down ? 0 : 0x40;
1179 }
1180 
1181 static void pcnet_transmit(PCNetState *s)
1182 {
1183     hwaddr xmit_cxda = 0;
1184     int count = CSR_XMTRL(s)-1;
1185     int add_crc = 0;
1186     int bcnt;
1187     s->xmit_pos = -1;
1188 
1189     if (!CSR_TXON(s)) {
1190         s->csr[0] &= ~0x0008;
1191         return;
1192     }
1193 
1194     s->tx_busy = 1;
1195 
1196 txagain:
1197     if (pcnet_tdte_poll(s)) {
1198         struct pcnet_TMD tmd;
1199 
1200         TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1201 
1202 #ifdef PCNET_DEBUG_TMD
1203         printf("  TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
1204         PRINT_TMD(&tmd);
1205 #endif
1206         if (GET_FIELD(tmd.status, TMDS, STP)) {
1207             s->xmit_pos = 0;
1208             xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
1209             if (BCR_SWSTYLE(s) != 1)
1210                 add_crc = GET_FIELD(tmd.status, TMDS, ADDFCS);
1211         }
1212         if (s->lnkst == 0 &&
1213             (!CSR_LOOP(s) || (!CSR_INTL(s) && !BCR_TMAULOOP(s)))) {
1214             SET_FIELD(&tmd.misc, TMDM, LCAR, 1);
1215             SET_FIELD(&tmd.status, TMDS, ERR, 1);
1216             SET_FIELD(&tmd.status, TMDS, OWN, 0);
1217             s->csr[0] |= 0xa000; /* ERR | CERR */
1218             s->xmit_pos = -1;
1219             goto txdone;
1220         }
1221 
1222         if (s->xmit_pos < 0) {
1223             goto txdone;
1224         }
1225 
1226         bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
1227 
1228         /* if multi-tmd packet outsizes s->buffer then skip it silently.
1229          * Note: this is not what real hw does.
1230          * Last four bytes of s->buffer are used to store CRC FCS code.
1231          */
1232         if (s->xmit_pos + bcnt > sizeof(s->buffer) - 4) {
1233             s->xmit_pos = -1;
1234             goto txdone;
1235         }
1236 
1237         s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
1238                          s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
1239         s->xmit_pos += bcnt;
1240 
1241         if (!GET_FIELD(tmd.status, TMDS, ENP)) {
1242             goto txdone;
1243         }
1244 
1245 #ifdef PCNET_DEBUG
1246         printf("pcnet_transmit size=%d\n", s->xmit_pos);
1247 #endif
1248         if (CSR_LOOP(s)) {
1249             if (BCR_SWSTYLE(s) == 1)
1250                 add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
1251             s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
1252             pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos);
1253             s->looptest = 0;
1254         } else {
1255             if (s->nic) {
1256                 qemu_send_packet(qemu_get_queue(s->nic), s->buffer,
1257                                  s->xmit_pos);
1258             }
1259         }
1260 
1261         s->csr[0] &= ~0x0008;   /* clear TDMD */
1262         s->csr[4] |= 0x0004;    /* set TXSTRT */
1263         s->xmit_pos = -1;
1264 
1265 txdone:
1266         SET_FIELD(&tmd.status, TMDS, OWN, 0);
1267         TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1268         if (!CSR_TOKINTD(s)
1269             || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT))) {
1270             s->csr[0] |= 0x0200;    /* set TINT */
1271         }
1272         if (CSR_XMTRC(s) <= 1) {
1273             CSR_XMTRC(s) = CSR_XMTRL(s);
1274         } else {
1275             CSR_XMTRC(s)--;
1276         }
1277         if (count--) {
1278             goto txagain;
1279         }
1280     } else if (s->xmit_pos >= 0) {
1281         struct pcnet_TMD tmd;
1282         TMDLOAD(&tmd, xmit_cxda);
1283         SET_FIELD(&tmd.misc, TMDM, BUFF, 1);
1284         SET_FIELD(&tmd.misc, TMDM, UFLO, 1);
1285         SET_FIELD(&tmd.status, TMDS, ERR, 1);
1286         SET_FIELD(&tmd.status, TMDS, OWN, 0);
1287         TMDSTORE(&tmd, xmit_cxda);
1288         s->csr[0] |= 0x0200;    /* set TINT */
1289         if (!CSR_DXSUFLO(s)) {
1290             s->csr[0] &= ~0x0010;
1291         } else if (count--) {
1292             goto txagain;
1293         }
1294     }
1295 
1296     s->tx_busy = 0;
1297 }
1298 
1299 static void pcnet_poll(PCNetState *s)
1300 {
1301     if (CSR_RXON(s)) {
1302         pcnet_rdte_poll(s);
1303     }
1304 
1305     if (CSR_TDMD(s) || (CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s))) {
1306         /* prevent recursion */
1307         if (s->tx_busy) {
1308             return;
1309         }
1310         pcnet_transmit(s);
1311     }
1312 }
1313 
1314 static void pcnet_poll_timer(void *opaque)
1315 {
1316     PCNetState *s = opaque;
1317 
1318     timer_del(s->poll_timer);
1319 
1320     if (CSR_TDMD(s)) {
1321         pcnet_transmit(s);
1322     }
1323 
1324     pcnet_update_irq(s);
1325 
1326     if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
1327         uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) * 33;
1328         if (!s->timer || !now) {
1329             s->timer = now;
1330         } else {
1331             uint64_t t = now - s->timer + CSR_POLL(s);
1332             if (t > 0xffffLL) {
1333                 pcnet_poll(s);
1334                 CSR_POLL(s) = CSR_PINT(s);
1335             } else {
1336                 CSR_POLL(s) = t;
1337             }
1338         }
1339         timer_mod(s->poll_timer,
1340             pcnet_get_next_poll_time(s,qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)));
1341     }
1342 }
1343 
1344 
1345 static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value)
1346 {
1347     uint16_t val = new_value;
1348 #ifdef PCNET_DEBUG_CSR
1349     printf("pcnet_csr_writew rap=%d val=0x%04x\n", rap, val);
1350 #endif
1351     switch (rap) {
1352     case 0:
1353         s->csr[0] &= ~(val & 0x7f00); /* Clear any interrupt flags */
1354 
1355         s->csr[0] = (s->csr[0] & ~0x0040) | (val & 0x0048);
1356 
1357         val = (val & 0x007f) | (s->csr[0] & 0x7f00);
1358 
1359         /* IFF STOP, STRT and INIT are set, clear STRT and INIT */
1360         if ((val & 7) == 7) {
1361             val &= ~3;
1362         }
1363         if (!CSR_STOP(s) && (val & 4)) {
1364             pcnet_stop(s);
1365         }
1366         if (!CSR_INIT(s) && (val & 1)) {
1367             pcnet_init(s);
1368         }
1369         if (!CSR_STRT(s) && (val & 2)) {
1370             pcnet_start(s);
1371         }
1372         if (CSR_TDMD(s)) {
1373             pcnet_transmit(s);
1374         }
1375         return;
1376     case 1:
1377     case 2:
1378     case 8:
1379     case 9:
1380     case 10:
1381     case 11:
1382     case 12:
1383     case 13:
1384     case 14:
1385     case 15:
1386     case 18: /* CRBAL */
1387     case 19: /* CRBAU */
1388     case 20: /* CXBAL */
1389     case 21: /* CXBAU */
1390     case 22: /* NRBAU */
1391     case 23: /* NRBAU */
1392     case 24:
1393     case 25:
1394     case 26:
1395     case 27:
1396     case 28:
1397     case 29:
1398     case 30:
1399     case 31:
1400     case 32:
1401     case 33:
1402     case 34:
1403     case 35:
1404     case 36:
1405     case 37:
1406     case 38:
1407     case 39:
1408     case 40: /* CRBC */
1409     case 41:
1410     case 42: /* CXBC */
1411     case 43:
1412     case 44:
1413     case 45:
1414     case 46: /* POLL */
1415     case 47: /* POLLINT */
1416     case 72:
1417     case 74:
1418         break;
1419     case 76: /* RCVRL */
1420     case 78: /* XMTRL */
1421         val = (val > 0) ? val : 512;
1422         break;
1423     case 112:
1424         if (CSR_STOP(s) || CSR_SPND(s)) {
1425             break;
1426         }
1427         return;
1428     case 3:
1429         break;
1430     case 4:
1431         s->csr[4] &= ~(val & 0x026a);
1432         val &= ~0x026a; val |= s->csr[4] & 0x026a;
1433         break;
1434     case 5:
1435         s->csr[5] &= ~(val & 0x0a90);
1436         val &= ~0x0a90; val |= s->csr[5] & 0x0a90;
1437         break;
1438     case 16:
1439         pcnet_csr_writew(s,1,val);
1440         return;
1441     case 17:
1442         pcnet_csr_writew(s,2,val);
1443         return;
1444     case 58:
1445         pcnet_bcr_writew(s,BCR_SWS,val);
1446         break;
1447     default:
1448         return;
1449     }
1450     s->csr[rap] = val;
1451 }
1452 
1453 static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap)
1454 {
1455     uint32_t val;
1456     switch (rap) {
1457     case 0:
1458         pcnet_update_irq(s);
1459         val = s->csr[0];
1460         val |= (val & 0x7800) ? 0x8000 : 0;
1461         break;
1462     case 16:
1463         return pcnet_csr_readw(s,1);
1464     case 17:
1465         return pcnet_csr_readw(s,2);
1466     case 58:
1467         return pcnet_bcr_readw(s,BCR_SWS);
1468     case 88:
1469         val = s->csr[89];
1470         val <<= 16;
1471         val |= s->csr[88];
1472         break;
1473     default:
1474         val = s->csr[rap];
1475     }
1476 #ifdef PCNET_DEBUG_CSR
1477     printf("pcnet_csr_readw rap=%d val=0x%04x\n", rap, val);
1478 #endif
1479     return val;
1480 }
1481 
1482 static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val)
1483 {
1484     rap &= 127;
1485 #ifdef PCNET_DEBUG_BCR
1486     printf("pcnet_bcr_writew rap=%d val=0x%04x\n", rap, val);
1487 #endif
1488     switch (rap) {
1489     case BCR_SWS:
1490         if (!(CSR_STOP(s) || CSR_SPND(s)))
1491             return;
1492         val &= ~0x0300;
1493         switch (val & 0x00ff) {
1494         case 0:
1495             val |= 0x0200;
1496             break;
1497         case 1:
1498             val |= 0x0100;
1499             break;
1500         case 2:
1501         case 3:
1502             val |= 0x0300;
1503             break;
1504         default:
1505             qemu_log_mask(LOG_GUEST_ERROR, "pcnet: Bad SWSTYLE=0x%02x\n",
1506                           val & 0xff);
1507             val = 0x0200;
1508             break;
1509         }
1510 #ifdef PCNET_DEBUG
1511        printf("BCR_SWS=0x%04x\n", val);
1512 #endif
1513         /* fall through */
1514     case BCR_LNKST:
1515     case BCR_LED1:
1516     case BCR_LED2:
1517     case BCR_LED3:
1518     case BCR_MC:
1519     case BCR_FDC:
1520     case BCR_BSBC:
1521     case BCR_EECAS:
1522     case BCR_PLAT:
1523         s->bcr[rap] = val;
1524         break;
1525     default:
1526         break;
1527     }
1528 }
1529 
1530 uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap)
1531 {
1532     uint32_t val;
1533     rap &= 127;
1534     switch (rap) {
1535     case BCR_LNKST:
1536     case BCR_LED1:
1537     case BCR_LED2:
1538     case BCR_LED3:
1539         val = s->bcr[rap] & ~0x8000;
1540         val |= (val & 0x017f & s->lnkst) ? 0x8000 : 0;
1541         break;
1542     default:
1543         val = rap < 32 ? s->bcr[rap] : 0;
1544         break;
1545     }
1546 #ifdef PCNET_DEBUG_BCR
1547     printf("pcnet_bcr_readw rap=%d val=0x%04x\n", rap, val);
1548 #endif
1549     return val;
1550 }
1551 
1552 void pcnet_h_reset(void *opaque)
1553 {
1554     PCNetState *s = opaque;
1555 
1556     s->bcr[BCR_MSRDA] = 0x0005;
1557     s->bcr[BCR_MSWRA] = 0x0005;
1558     s->bcr[BCR_MC   ] = 0x0002;
1559     s->bcr[BCR_LNKST] = 0x00c0;
1560     s->bcr[BCR_LED1 ] = 0x0084;
1561     s->bcr[BCR_LED2 ] = 0x0088;
1562     s->bcr[BCR_LED3 ] = 0x0090;
1563     s->bcr[BCR_FDC  ] = 0x0000;
1564     s->bcr[BCR_BSBC ] = 0x9001;
1565     s->bcr[BCR_EECAS] = 0x0002;
1566     s->bcr[BCR_SWS  ] = 0x0200;
1567     s->bcr[BCR_PLAT ] = 0xff06;
1568 
1569     pcnet_s_reset(s);
1570     pcnet_update_irq(s);
1571     pcnet_poll_timer(s);
1572 }
1573 
1574 void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
1575 {
1576     PCNetState *s = opaque;
1577     pcnet_poll_timer(s);
1578 #ifdef PCNET_DEBUG_IO
1579     printf("pcnet_ioport_writew addr=0x%08x val=0x%04x\n", addr, val);
1580 #endif
1581     if (!BCR_DWIO(s)) {
1582         switch (addr & 0x0f) {
1583         case 0x00: /* RDP */
1584             pcnet_csr_writew(s, s->rap, val);
1585             break;
1586         case 0x02:
1587             s->rap = val & 0x7f;
1588             break;
1589         case 0x06:
1590             pcnet_bcr_writew(s, s->rap, val);
1591             break;
1592         }
1593     }
1594     pcnet_update_irq(s);
1595 }
1596 
1597 uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr)
1598 {
1599     PCNetState *s = opaque;
1600     uint32_t val = -1;
1601     pcnet_poll_timer(s);
1602     if (!BCR_DWIO(s)) {
1603         switch (addr & 0x0f) {
1604         case 0x00: /* RDP */
1605             val = pcnet_csr_readw(s, s->rap);
1606             break;
1607         case 0x02:
1608             val = s->rap;
1609             break;
1610         case 0x04:
1611             pcnet_s_reset(s);
1612             val = 0;
1613             break;
1614         case 0x06:
1615             val = pcnet_bcr_readw(s, s->rap);
1616             break;
1617         }
1618     }
1619     pcnet_update_irq(s);
1620 #ifdef PCNET_DEBUG_IO
1621     printf("pcnet_ioport_readw addr=0x%08x val=0x%04x\n", addr, val & 0xffff);
1622 #endif
1623     return val;
1624 }
1625 
1626 void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
1627 {
1628     PCNetState *s = opaque;
1629     pcnet_poll_timer(s);
1630 #ifdef PCNET_DEBUG_IO
1631     printf("pcnet_ioport_writel addr=0x%08x val=0x%08x\n", addr, val);
1632 #endif
1633     if (BCR_DWIO(s)) {
1634         switch (addr & 0x0f) {
1635         case 0x00: /* RDP */
1636             pcnet_csr_writew(s, s->rap, val & 0xffff);
1637             break;
1638         case 0x04:
1639             s->rap = val & 0x7f;
1640             break;
1641         case 0x0c:
1642             pcnet_bcr_writew(s, s->rap, val & 0xffff);
1643             break;
1644         }
1645     } else if ((addr & 0x0f) == 0) {
1646         /* switch device to dword i/o mode */
1647         pcnet_bcr_writew(s, BCR_BSBC, pcnet_bcr_readw(s, BCR_BSBC) | 0x0080);
1648 #ifdef PCNET_DEBUG_IO
1649         printf("device switched into dword i/o mode\n");
1650 #endif
1651     }
1652     pcnet_update_irq(s);
1653 }
1654 
1655 uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr)
1656 {
1657     PCNetState *s = opaque;
1658     uint32_t val = -1;
1659     pcnet_poll_timer(s);
1660     if (BCR_DWIO(s)) {
1661         switch (addr & 0x0f) {
1662         case 0x00: /* RDP */
1663             val = pcnet_csr_readw(s, s->rap);
1664             break;
1665         case 0x04:
1666             val = s->rap;
1667             break;
1668         case 0x08:
1669             pcnet_s_reset(s);
1670             val = 0;
1671             break;
1672         case 0x0c:
1673             val = pcnet_bcr_readw(s, s->rap);
1674             break;
1675         }
1676     }
1677     pcnet_update_irq(s);
1678 #ifdef PCNET_DEBUG_IO
1679     printf("pcnet_ioport_readl addr=0x%08x val=0x%08x\n", addr, val);
1680 #endif
1681     return val;
1682 }
1683 
1684 static bool is_version_2(void *opaque, int version_id)
1685 {
1686     return version_id == 2;
1687 }
1688 
1689 const VMStateDescription vmstate_pcnet = {
1690     .name = "pcnet",
1691     .version_id = 3,
1692     .minimum_version_id = 2,
1693     .fields = (VMStateField[]) {
1694         VMSTATE_INT32(rap, PCNetState),
1695         VMSTATE_INT32(isr, PCNetState),
1696         VMSTATE_INT32(lnkst, PCNetState),
1697         VMSTATE_UINT32(rdra, PCNetState),
1698         VMSTATE_UINT32(tdra, PCNetState),
1699         VMSTATE_BUFFER(prom, PCNetState),
1700         VMSTATE_UINT16_ARRAY(csr, PCNetState, 128),
1701         VMSTATE_UINT16_ARRAY(bcr, PCNetState, 32),
1702         VMSTATE_UINT64(timer, PCNetState),
1703         VMSTATE_INT32(xmit_pos, PCNetState),
1704         VMSTATE_BUFFER(buffer, PCNetState),
1705         VMSTATE_UNUSED_TEST(is_version_2, 4),
1706         VMSTATE_INT32(tx_busy, PCNetState),
1707         VMSTATE_TIMER_PTR(poll_timer, PCNetState),
1708         VMSTATE_END_OF_LIST()
1709     }
1710 };
1711 
1712 void pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
1713 {
1714     int i;
1715     uint16_t checksum;
1716 
1717     s->poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pcnet_poll_timer, s);
1718 
1719     qemu_macaddr_default_if_unset(&s->conf.macaddr);
1720     s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s);
1721     qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
1722 
1723     /* Initialize the PROM */
1724 
1725     /*
1726       Datasheet: http://pdfdata.datasheetsite.com/web/24528/AM79C970A.pdf
1727       page 95
1728     */
1729     memcpy(s->prom, s->conf.macaddr.a, 6);
1730     /* Reserved Location: must be 00h */
1731     s->prom[6] = s->prom[7] = 0x00;
1732     /* Reserved Location: must be 00h */
1733     s->prom[8] = 0x00;
1734     /* Hardware ID: must be 11h if compatibility to AMD drivers is desired */
1735     s->prom[9] = 0x11;
1736     /* User programmable space, init with 0 */
1737     s->prom[10] = s->prom[11] = 0x00;
1738     /* LSByte of two-byte checksum, which is the sum of bytes 00h-0Bh
1739        and bytes 0Eh and 0Fh, must therefore be initialized with 0! */
1740     s->prom[12] = s->prom[13] = 0x00;
1741     /* Must be ASCII W (57h) if compatibility to AMD
1742        driver software is desired */
1743     s->prom[14] = s->prom[15] = 0x57;
1744 
1745     for (i = 0, checksum = 0; i < 16; i++) {
1746         checksum += s->prom[i];
1747     }
1748     *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);
1749 
1750     s->lnkst = 0x40; /* initial link state: up */
1751 }
1752