]> Git Repo - qemu.git/blob - hw/pcnet.c
initial sparc32 lance and pcnet merge
[qemu.git] / hw / pcnet.c
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 /* TODO: remove little endian host assumptions */
39  
40 #include "vl.h"
41
42 //#define PCNET_DEBUG
43 //#define PCNET_DEBUG_IO
44 //#define PCNET_DEBUG_BCR
45 //#define PCNET_DEBUG_CSR
46 //#define PCNET_DEBUG_RMD
47 //#define PCNET_DEBUG_TMD
48 //#define PCNET_DEBUG_MATCH
49
50
51 #define PCNET_IOPORT_SIZE       0x20
52 #define PCNET_PNPMMIO_SIZE      0x20
53
54
55 typedef struct PCNetState_st PCNetState;
56
57 struct PCNetState_st {
58     PCIDevice dev;
59     PCIDevice *pci_dev;
60     VLANClientState *vc;
61     NICInfo *nd;
62     QEMUTimer *poll_timer;
63     int mmio_index, rap, isr, lnkst;
64     uint32_t rdra, tdra;
65     uint8_t prom[16];
66     uint16_t csr[128];
67     uint16_t bcr[32];
68     uint64_t timer;
69     int xmit_pos, recv_pos;
70     uint8_t buffer[4096];
71     int tx_busy;
72     void (*set_irq_cb)(void *s, int isr);
73     void (*phys_mem_read)(void *dma_opaque, target_phys_addr_t addr,
74                          uint8_t *buf, int len);
75     void (*phys_mem_write)(void *dma_opaque, target_phys_addr_t addr,
76                           uint8_t *buf, int len);
77     void *dma_opaque;
78 };
79
80 /* XXX: using bitfields for target memory structures is almost surely
81    not portable, so it should be suppressed ASAP */
82 #ifdef __GNUC__
83 #define PACKED_FIELD(A) A __attribute__ ((packed))
84 #else
85 #error FixMe
86 #endif
87
88 struct qemu_ether_header {
89     uint8_t ether_dhost[6];
90     uint8_t ether_shost[6];
91     uint16_t ether_type;
92 };
93
94 /* BUS CONFIGURATION REGISTERS */
95 #define BCR_MSRDA    0
96 #define BCR_MSWRA    1
97 #define BCR_MC       2
98 #define BCR_LNKST    4
99 #define BCR_LED1     5
100 #define BCR_LED2     6
101 #define BCR_LED3     7
102 #define BCR_FDC      9
103 #define BCR_BSBC     18
104 #define BCR_EECAS    19
105 #define BCR_SWS      20
106 #define BCR_PLAT     22
107
108 #define BCR_DWIO(S)      !!((S)->bcr[BCR_BSBC] & 0x0080)
109 #define BCR_SSIZE32(S)   !!((S)->bcr[BCR_SWS ] & 0x0100)
110 #define BCR_SWSTYLE(S)     ((S)->bcr[BCR_SWS ] & 0x00FF)
111
112 #define CSR_INIT(S)      !!(((S)->csr[0])&0x0001)
113 #define CSR_STRT(S)      !!(((S)->csr[0])&0x0002)
114 #define CSR_STOP(S)      !!(((S)->csr[0])&0x0004)
115 #define CSR_TDMD(S)      !!(((S)->csr[0])&0x0008)
116 #define CSR_TXON(S)      !!(((S)->csr[0])&0x0010)
117 #define CSR_RXON(S)      !!(((S)->csr[0])&0x0020)
118 #define CSR_INEA(S)      !!(((S)->csr[0])&0x0040)
119 #define CSR_BIGENDIAN(S) !!(((S)->csr[3])&0x0004)
120 #define CSR_LAPPEN(S)    !!(((S)->csr[3])&0x0020)
121 #define CSR_DXSUFLO(S)   !!(((S)->csr[3])&0x0040)
122 #define CSR_ASTRP_RCV(S) !!(((S)->csr[4])&0x0800)
123 #define CSR_DPOLL(S)     !!(((S)->csr[4])&0x1000)
124 #define CSR_SPND(S)      !!(((S)->csr[5])&0x0001)
125 #define CSR_LTINTEN(S)   !!(((S)->csr[5])&0x4000)
126 #define CSR_TOKINTD(S)   !!(((S)->csr[5])&0x8000)
127 #define CSR_DRX(S)       !!(((S)->csr[15])&0x0001)
128 #define CSR_DTX(S)       !!(((S)->csr[15])&0x0002)
129 #define CSR_LOOP(S)      !!(((S)->csr[15])&0x0004)
130 #define CSR_DRCVPA(S)    !!(((S)->csr[15])&0x2000)
131 #define CSR_DRCVBC(S)    !!(((S)->csr[15])&0x4000)
132 #define CSR_PROM(S)      !!(((S)->csr[15])&0x8000)
133
134 #define CSR_CRBC(S)      ((S)->csr[40])
135 #define CSR_CRST(S)      ((S)->csr[41])
136 #define CSR_CXBC(S)      ((S)->csr[42])
137 #define CSR_CXST(S)      ((S)->csr[43])
138 #define CSR_NRBC(S)      ((S)->csr[44])
139 #define CSR_NRST(S)      ((S)->csr[45])
140 #define CSR_POLL(S)      ((S)->csr[46])
141 #define CSR_PINT(S)      ((S)->csr[47])
142 #define CSR_RCVRC(S)     ((S)->csr[72])
143 #define CSR_XMTRC(S)     ((S)->csr[74])
144 #define CSR_RCVRL(S)     ((S)->csr[76])
145 #define CSR_XMTRL(S)     ((S)->csr[78])
146 #define CSR_MISSC(S)     ((S)->csr[112])
147
148 #define CSR_IADR(S)      ((S)->csr[ 1] | ((S)->csr[ 2] << 16))
149 #define CSR_CRBA(S)      ((S)->csr[18] | ((S)->csr[19] << 16))
150 #define CSR_CXBA(S)      ((S)->csr[20] | ((S)->csr[21] << 16))
151 #define CSR_NRBA(S)      ((S)->csr[22] | ((S)->csr[23] << 16))
152 #define CSR_BADR(S)      ((S)->csr[24] | ((S)->csr[25] << 16))
153 #define CSR_NRDA(S)      ((S)->csr[26] | ((S)->csr[27] << 16))
154 #define CSR_CRDA(S)      ((S)->csr[28] | ((S)->csr[29] << 16))
155 #define CSR_BADX(S)      ((S)->csr[30] | ((S)->csr[31] << 16))
156 #define CSR_NXDA(S)      ((S)->csr[32] | ((S)->csr[33] << 16))
157 #define CSR_CXDA(S)      ((S)->csr[34] | ((S)->csr[35] << 16))
158 #define CSR_NNRD(S)      ((S)->csr[36] | ((S)->csr[37] << 16))
159 #define CSR_NNXD(S)      ((S)->csr[38] | ((S)->csr[39] << 16))
160 #define CSR_PXDA(S)      ((S)->csr[60] | ((S)->csr[61] << 16))
161 #define CSR_NXBA(S)      ((S)->csr[64] | ((S)->csr[65] << 16))
162
163 #define PHYSADDR(S,A) \
164   (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(s)->csr[2])<<16))
165
166 struct pcnet_initblk16 {
167     uint16_t mode;
168     uint16_t padr[3];
169     uint16_t ladrf[4];
170     uint32_t rdra;
171     uint32_t tdra;
172 };
173
174 struct pcnet_initblk32 {
175     uint16_t mode;
176     uint8_t rlen;
177     uint8_t tlen;
178     uint16_t padr[3];
179     uint16_t _res;
180     uint16_t ladrf[4];
181     uint32_t rdra;
182     uint32_t tdra;
183 };
184
185 struct pcnet_TMD {
186     struct {
187         unsigned tbadr:32;
188     } tmd0;
189     struct {
190         unsigned PACKED_FIELD(bcnt:12), PACKED_FIELD(ones:4), PACKED_FIELD(res:7), PACKED_FIELD(bpe:1);
191         unsigned PACKED_FIELD(enp:1), PACKED_FIELD(stp:1), PACKED_FIELD(def:1), PACKED_FIELD(one:1);
192         unsigned PACKED_FIELD(ltint:1), PACKED_FIELD(nofcs:1), PACKED_FIELD(err:1), PACKED_FIELD(own:1);
193     } tmd1;
194     struct {
195         unsigned PACKED_FIELD(trc:4), PACKED_FIELD(res:12);
196         unsigned PACKED_FIELD(tdr:10), PACKED_FIELD(rtry:1), PACKED_FIELD(lcar:1);
197         unsigned PACKED_FIELD(lcol:1), PACKED_FIELD(exdef:1), PACKED_FIELD(uflo:1), PACKED_FIELD(buff:1);
198     } tmd2;
199     struct {
200         unsigned res:32;
201     } tmd3;    
202 };
203
204 struct pcnet_RMD {
205     struct {
206         unsigned rbadr:32;
207     } rmd0;
208     struct {
209         unsigned PACKED_FIELD(bcnt:12), PACKED_FIELD(ones:4), PACKED_FIELD(res:4);
210         unsigned PACKED_FIELD(bam:1), PACKED_FIELD(lafm:1), PACKED_FIELD(pam:1), PACKED_FIELD(bpe:1);
211         unsigned PACKED_FIELD(enp:1), PACKED_FIELD(stp:1), PACKED_FIELD(buff:1), PACKED_FIELD(crc:1);
212         unsigned PACKED_FIELD(oflo:1), PACKED_FIELD(fram:1), PACKED_FIELD(err:1), PACKED_FIELD(own:1);
213     } rmd1;
214     struct {
215         unsigned PACKED_FIELD(mcnt:12), PACKED_FIELD(zeros:4);
216         unsigned PACKED_FIELD(rpc:8), PACKED_FIELD(rcc:8);
217     } rmd2;    
218     struct {
219         unsigned res:32;
220     } rmd3;    
221 };
222
223
224 #define PRINT_TMD(T) printf(    \
225         "TMD0 : TBADR=0x%08x\n" \
226         "TMD1 : OWN=%d, ERR=%d, FCS=%d, LTI=%d, "       \
227         "ONE=%d, DEF=%d, STP=%d, ENP=%d,\n"             \
228         "       BPE=%d, BCNT=%d\n"                      \
229         "TMD2 : BUF=%d, UFL=%d, EXD=%d, LCO=%d, "       \
230         "LCA=%d, RTR=%d,\n"                             \
231         "       TDR=%d, TRC=%d\n",                      \
232         (T)->tmd0.tbadr,                                \
233         (T)->tmd1.own, (T)->tmd1.err, (T)->tmd1.nofcs,  \
234         (T)->tmd1.ltint, (T)->tmd1.one, (T)->tmd1.def,  \
235         (T)->tmd1.stp, (T)->tmd1.enp, (T)->tmd1.bpe,    \
236         4096-(T)->tmd1.bcnt,                            \
237         (T)->tmd2.buff, (T)->tmd2.uflo, (T)->tmd2.exdef,\
238         (T)->tmd2.lcol, (T)->tmd2.lcar, (T)->tmd2.rtry, \
239         (T)->tmd2.tdr, (T)->tmd2.trc)
240
241 #define PRINT_RMD(R) printf(    \
242         "RMD0 : RBADR=0x%08x\n" \
243         "RMD1 : OWN=%d, ERR=%d, FRAM=%d, OFLO=%d, "     \
244         "CRC=%d, BUFF=%d, STP=%d, ENP=%d,\n       "     \
245         "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n"    \
246         "RMD2 : RCC=%d, RPC=%d, MCNT=%d, ZEROS=%d\n",   \
247         (R)->rmd0.rbadr,                                \
248         (R)->rmd1.own, (R)->rmd1.err, (R)->rmd1.fram,   \
249         (R)->rmd1.oflo, (R)->rmd1.crc, (R)->rmd1.buff,  \
250         (R)->rmd1.stp, (R)->rmd1.enp, (R)->rmd1.bpe,    \
251         (R)->rmd1.pam, (R)->rmd1.lafm, (R)->rmd1.bam,   \
252         (R)->rmd1.ones, 4096-(R)->rmd1.bcnt,            \
253         (R)->rmd2.rcc, (R)->rmd2.rpc, (R)->rmd2.mcnt,   \
254         (R)->rmd2.zeros)
255
256 static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd, target_phys_addr_t addr)
257 {
258     if (!BCR_SWSTYLE(s)) {
259         uint16_t xda[4];
260         s->phys_mem_read(s->dma_opaque, addr,
261                 (void *)&xda[0], sizeof(xda));
262         if (CSR_BIGENDIAN(s)) {
263             ((uint32_t *)tmd)[0] = be16_to_cpu(xda[0]) |
264                 ((be16_to_cpu(xda[1]) & 0x00ff) << 16);
265             ((uint32_t *)tmd)[1] = be16_to_cpu(xda[2]) |
266                 ((be16_to_cpu(xda[1]) & 0xff00) << 16);
267             ((uint32_t *)tmd)[2] =
268                 (be16_to_cpu(xda[3]) & 0xffff) << 16;
269             ((uint32_t *)tmd)[3] = 0;
270         } else {
271             ((uint32_t *)tmd)[0] = (xda[0]&0xffff) |
272                 ((xda[1]&0x00ff) << 16);
273             ((uint32_t *)tmd)[1] = (xda[2]&0xffff)|
274                 ((xda[1] & 0xff00) << 16);
275             ((uint32_t *)tmd)[2] =
276                 (xda[3] & 0xffff) << 16;
277             ((uint32_t *)tmd)[3] = 0;
278         }
279     }
280     else
281     if (BCR_SWSTYLE(s) != 3)
282         s->phys_mem_read(s->dma_opaque, addr, (void *)tmd, 16);
283     else {
284         uint32_t xda[4];
285         s->phys_mem_read(s->dma_opaque, addr,
286                 (void *)&xda[0], sizeof(xda));
287         ((uint32_t *)tmd)[0] = xda[2];
288         ((uint32_t *)tmd)[1] = xda[1];
289         ((uint32_t *)tmd)[2] = xda[0];
290         ((uint32_t *)tmd)[3] = xda[3];
291     }
292 }
293
294 static inline void pcnet_tmd_store(PCNetState *s, struct pcnet_TMD *tmd, target_phys_addr_t addr)
295 {
296     if (!BCR_SWSTYLE(s)) {
297         uint16_t xda[4];
298         if (CSR_BIGENDIAN(s)) {
299             xda[0] = cpu_to_be16(((uint32_t *)tmd)[0] & 0xffff);
300             xda[1] = cpu_to_be16(((((uint32_t *)tmd)[0] >> 16) & 0x00ff) |
301                                  ((((uint32_t *)tmd)[1] >> 16) & 0xff00));
302             xda[2] = cpu_to_be16(((uint32_t *)tmd)[1] & 0xffff);
303             xda[3] = cpu_to_be16(((uint32_t *)tmd)[2] >> 16);
304         } else {
305             xda[0] = ((uint32_t *)tmd)[0] & 0xffff;
306             xda[1] = ((((uint32_t *)tmd)[0]>>16)&0x00ff) |
307                 ((((uint32_t *)tmd)[1]>>16)&0xff00);
308             xda[2] = ((uint32_t *)tmd)[1] & 0xffff;
309             xda[3] = ((uint32_t *)tmd)[2] >> 16;
310         }
311         s->phys_mem_write(s->dma_opaque, addr,
312                 (void *)&xda[0], sizeof(xda));
313     }
314     else {
315         if (BCR_SWSTYLE(s) != 3)
316             s->phys_mem_write(s->dma_opaque, addr, (void *)tmd, 16);
317         else {
318             uint32_t xda[4];
319             xda[0] = ((uint32_t *)tmd)[2];
320             xda[1] = ((uint32_t *)tmd)[1];
321             xda[2] = ((uint32_t *)tmd)[0];
322             xda[3] = ((uint32_t *)tmd)[3];
323             s->phys_mem_write(s->dma_opaque, addr,
324                     (void *)&xda[0], sizeof(xda));
325         }
326     }
327 }
328
329 static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd, target_phys_addr_t addr)
330 {
331     if (!BCR_SWSTYLE(s)) {
332         uint16_t rda[4];
333         s->phys_mem_read(s->dma_opaque, addr,
334                 (void *)&rda[0], sizeof(rda));
335         if (CSR_BIGENDIAN(s)) {
336             ((uint32_t *)rmd)[0] = (be16_to_cpu(rda[0]) & 0xffff) |
337                 ((be16_to_cpu(rda[1]) & 0x00ff) << 16);
338             ((uint32_t *)rmd)[1] = (be16_to_cpu(rda[2]) & 0xffff) |
339                 ((be16_to_cpu(rda[1]) & 0xff00) << 16);
340             ((uint32_t *)rmd)[2] = be16_to_cpu(rda[3]) & 0xffff;
341             ((uint32_t *)rmd)[3] = 0;
342         } else {
343             ((uint32_t *)rmd)[0] = (rda[0]&0xffff)|
344                 ((rda[1] & 0x00ff) << 16);
345             ((uint32_t *)rmd)[1] = (rda[2]&0xffff)|
346                 ((rda[1] & 0xff00) << 16);
347             ((uint32_t *)rmd)[2] = rda[3] & 0xffff;
348             ((uint32_t *)rmd)[3] = 0;
349         }
350     }
351     else
352     if (BCR_SWSTYLE(s) != 3)
353         s->phys_mem_read(s->dma_opaque, addr, (void *)rmd, 16);
354     else {
355         uint32_t rda[4];
356         s->phys_mem_read(s->dma_opaque, addr,
357                 (void *)&rda[0], sizeof(rda));
358         ((uint32_t *)rmd)[0] = rda[2];
359         ((uint32_t *)rmd)[1] = rda[1];
360         ((uint32_t *)rmd)[2] = rda[0];
361         ((uint32_t *)rmd)[3] = rda[3];
362     }
363 }
364
365 static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd, target_phys_addr_t addr)
366 {
367     if (!BCR_SWSTYLE(s)) {
368         uint16_t rda[4];
369         if (CSR_BIGENDIAN(s)) {
370             rda[0] = cpu_to_be16(((uint32_t *)rmd)[0] & 0xffff);
371             rda[1] = cpu_to_be16(((((uint32_t *)rmd)[0] >> 16) & 0xff) |
372                                  ((((uint32_t *)rmd)[1] >> 16) & 0xff00));
373             rda[2] = cpu_to_be16(((uint32_t *)rmd)[1] & 0xffff);
374             rda[3] = cpu_to_be16(((uint32_t *)rmd)[2] & 0xffff);
375         } else {
376             rda[0] = ((uint32_t *)rmd)[0] & 0xffff;
377             rda[1] = ((((uint32_t *)rmd)[0]>>16)&0xff)|
378                 ((((uint32_t *)rmd)[1]>>16)&0xff00);
379             rda[2] = ((uint32_t *)rmd)[1] & 0xffff;
380             rda[3] = ((uint32_t *)rmd)[2] & 0xffff;
381         }
382         s->phys_mem_write(s->dma_opaque, addr,
383                 (void *)&rda[0], sizeof(rda));
384     }
385     else {
386         if (BCR_SWSTYLE(s) != 3)
387             s->phys_mem_write(s->dma_opaque, addr, (void *)rmd, 16);
388         else {
389             uint32_t rda[4];
390             rda[0] = ((uint32_t *)rmd)[2];
391             rda[1] = ((uint32_t *)rmd)[1];
392             rda[2] = ((uint32_t *)rmd)[0];
393             rda[3] = ((uint32_t *)rmd)[3];
394             s->phys_mem_write(s->dma_opaque, addr,
395                     (void *)&rda[0], sizeof(rda));
396         }
397     }
398 }
399
400
401 #define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
402
403 #define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
404
405 #define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
406
407 #define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
408
409 #if 1
410
411 #define CHECK_RMD(ADDR,RES) do {                \
412     struct pcnet_RMD rmd;                       \
413     RMDLOAD(&rmd,(ADDR));                       \
414     (RES) |= (rmd.rmd1.ones != 15)              \
415           || (rmd.rmd2.zeros != 0);             \
416 } while (0)
417
418 #define CHECK_TMD(ADDR,RES) do {                \
419     struct pcnet_TMD tmd;                       \
420     TMDLOAD(&tmd,(ADDR));                       \
421     (RES) |= (tmd.tmd1.ones != 15);             \
422 } while (0)
423
424 #else
425
426 #define CHECK_RMD(ADDR,RES) do {                \
427     switch (BCR_SWSTYLE(s)) {                   \
428     case 0x00:                                  \
429         do {                                    \
430             uint16_t rda[4];                    \
431             s->phys_mem_read(s->dma_opaque, (ADDR),    \
432                 (void *)&rda[0], sizeof(rda));  \
433             (RES) |= (rda[2] & 0xf000)!=0xf000; \
434             (RES) |= (rda[3] & 0xf000)!=0x0000; \
435         } while (0);                            \
436         break;                                  \
437     case 0x01:                                  \
438     case 0x02:                                  \
439         do {                                    \
440             uint32_t rda[4];                    \
441             s->phys_mem_read(s->dma_opaque, (ADDR),    \
442                 (void *)&rda[0], sizeof(rda)); \
443             (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
444             (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
445         } while (0);                            \
446         break;                                  \
447     case 0x03:                                  \
448         do {                                    \
449             uint32_t rda[4];                    \
450             s->phys_mem_read(s->dma_opaque, (ADDR),    \
451                 (void *)&rda[0], sizeof(rda)); \
452             (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
453             (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
454         } while (0);                            \
455         break;                                  \
456     }                                           \
457 } while (0)
458
459 #define CHECK_TMD(ADDR,RES) do {                \
460     switch (BCR_SWSTYLE(s)) {                   \
461     case 0x00:                                  \
462         do {                                    \
463             uint16_t xda[4];                    \
464             s->phys_mem_read(s->dma_opaque, (ADDR),    \
465                 (void *)&xda[0], sizeof(xda));  \
466             (RES) |= (xda[2] & 0xf000)!=0xf000;\
467         } while (0);                            \
468         break;                                  \
469     case 0x01:                                  \
470     case 0x02:                                  \
471     case 0x03:                                  \
472         do {                                    \
473             uint32_t xda[4];                    \
474             s->phys_mem_read(s->dma_opaque, (ADDR),    \
475                 (void *)&xda[0], sizeof(xda));  \
476             (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
477         } while (0);                            \
478         break;                                  \
479     }                                           \
480 } while (0)
481
482 #endif
483
484 #define PRINT_PKTHDR(BUF) do {                  \
485     struct qemu_ether_header *hdr = (void *)(BUF);   \
486     printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "       \
487            "shost=%02x:%02x:%02x:%02x:%02x:%02x, "              \
488            "type=0x%04x (bcast=%d)\n",                          \
489            hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
490            hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
491            hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
492            hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
493            be16_to_cpu(hdr->ether_type),                                \
494            !!ETHER_IS_MULTICAST(hdr->ether_dhost));                     \
495 } while (0)
496
497 #define MULTICAST_FILTER_LEN 8
498
499 static inline uint32_t lnc_mchash(const uint8_t *ether_addr)
500 {
501 #define LNC_POLYNOMIAL          0xEDB88320UL
502     uint32_t crc = 0xFFFFFFFF;
503     int idx, bit;
504     uint8_t data;
505
506     for (idx = 0; idx < 6; idx++) {
507         for (data = *ether_addr++, bit = 0; bit < MULTICAST_FILTER_LEN; bit++) {
508             crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LNC_POLYNOMIAL : 0);
509             data >>= 1;
510         }
511     }
512     return crc;
513 #undef LNC_POLYNOMIAL
514 }
515
516 #define CRC(crc, ch)     (crc = (crc >> 8) ^ crctab[(crc ^ (ch)) & 0xff])
517
518 /* generated using the AUTODIN II polynomial
519  *      x^32 + x^26 + x^23 + x^22 + x^16 +
520  *      x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
521  */
522 static const uint32_t crctab[256] = {
523         0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
524         0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
525         0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
526         0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
527         0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
528         0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
529         0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
530         0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
531         0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
532         0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
533         0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
534         0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
535         0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
536         0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
537         0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
538         0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
539         0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
540         0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
541         0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
542         0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
543         0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
544         0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
545         0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
546         0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
547         0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
548         0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
549         0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
550         0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
551         0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
552         0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
553         0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
554         0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
555         0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
556         0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
557         0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
558         0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
559         0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
560         0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
561         0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
562         0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
563         0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
564         0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
565         0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
566         0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
567         0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
568         0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
569         0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
570         0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
571         0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
572         0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
573         0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
574         0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
575         0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
576         0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
577         0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
578         0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
579         0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
580         0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
581         0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
582         0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
583         0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
584         0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
585         0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
586         0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
587 };
588
589 static inline int padr_match(PCNetState *s, const uint8_t *buf, int size)
590 {
591     struct qemu_ether_header *hdr = (void *)buf;
592     uint8_t padr[6] = { 
593         s->csr[12] & 0xff, s->csr[12] >> 8,
594         s->csr[13] & 0xff, s->csr[13] >> 8,
595         s->csr[14] & 0xff, s->csr[14] >> 8 
596     };
597     int result = (!CSR_DRCVPA(s)) && !memcmp(hdr->ether_dhost, padr, 6);
598 #ifdef PCNET_DEBUG_MATCH
599     printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "
600            "padr=%02x:%02x:%02x:%02x:%02x:%02x\n",
601            hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2],
602            hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5],
603            padr[0],padr[1],padr[2],padr[3],padr[4],padr[5]);
604     printf("padr_match result=%d\n", result);
605 #endif
606     return result;
607 }
608
609 static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size)
610 {
611     static uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
612     struct qemu_ether_header *hdr = (void *)buf;
613     int result = !CSR_DRCVBC(s) && !memcmp(hdr->ether_dhost, BCAST, 6);
614 #ifdef PCNET_DEBUG_MATCH
615     printf("padr_bcast result=%d\n", result);
616 #endif
617     return result;
618 }
619
620 static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
621 {
622     struct qemu_ether_header *hdr = (void *)buf;
623     if ((*(hdr->ether_dhost)&0x01) && 
624         ((uint64_t *)&s->csr[8])[0] != 0LL) {
625         uint8_t ladr[8] = { 
626             s->csr[8] & 0xff, s->csr[8] >> 8,
627             s->csr[9] & 0xff, s->csr[9] >> 8,
628             s->csr[10] & 0xff, s->csr[10] >> 8, 
629             s->csr[11] & 0xff, s->csr[11] >> 8 
630         };
631         int index = lnc_mchash(hdr->ether_dhost) >> 26;
632         return !!(ladr[index >> 3] & (1 << (index & 7)));
633     }
634     return 0;
635 }
636
637 static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx) 
638 {
639     while (idx < 1) idx += CSR_RCVRL(s);
640     return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
641 }
642
643 static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
644 {
645     int64_t next_time = current_time + 
646         muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)), 
647                  ticks_per_sec, 33000000L);
648     if (next_time <= current_time)
649         next_time = current_time + 1;
650     return next_time;
651 }
652
653 static void pcnet_poll(PCNetState *s);
654 static void pcnet_poll_timer(void *opaque);
655
656 static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
657 static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
658 static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
659 static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
660
661 static void pcnet_s_reset(PCNetState *s)
662 {
663 #ifdef PCNET_DEBUG
664     printf("pcnet_s_reset\n");
665 #endif
666
667     s->lnkst = 0x40;
668     s->rdra = 0;
669     s->tdra = 0;
670     s->rap = 0;
671     
672     s->bcr[BCR_BSBC] &= ~0x0080;
673
674     s->csr[0]   = 0x0004;
675     s->csr[3]   = 0x0000;
676     s->csr[4]   = 0x0115;
677     s->csr[5]   = 0x0000;
678     s->csr[6]   = 0x0000;
679     s->csr[8]   = 0;
680     s->csr[9]   = 0;
681     s->csr[10]  = 0;
682     s->csr[11]  = 0;
683     s->csr[12]  = le16_to_cpu(((uint16_t *)&s->prom[0])[0]);
684     s->csr[13]  = le16_to_cpu(((uint16_t *)&s->prom[0])[1]);
685     s->csr[14]  = le16_to_cpu(((uint16_t *)&s->prom[0])[2]);
686     s->csr[15] &= 0x21c4;
687     s->csr[72]  = 1;
688     s->csr[74]  = 1;
689     s->csr[76]  = 1;
690     s->csr[78]  = 1;
691     s->csr[80]  = 0x1410;
692     s->csr[88]  = 0x1003;
693     s->csr[89]  = 0x0262;
694     s->csr[94]  = 0x0000;
695     s->csr[100] = 0x0200;
696     s->csr[103] = 0x0105;
697     s->csr[103] = 0x0105;
698     s->csr[112] = 0x0000;
699     s->csr[114] = 0x0000;
700     s->csr[122] = 0x0000;
701     s->csr[124] = 0x0000;
702
703     s->tx_busy = 0;
704 }
705
706 static void pcnet_update_irq(PCNetState *s)
707 {
708     int isr = 0;
709     s->csr[0] &= ~0x0080;
710     
711 #if 1
712     if (((s->csr[0] & ~s->csr[3]) & 0x5f00) ||
713         (((s->csr[4]>>1) & ~s->csr[4]) & 0x0115) ||
714         (((s->csr[5]>>1) & s->csr[5]) & 0x0048))
715 #else
716     if ((!(s->csr[3] & 0x4000) && !!(s->csr[0] & 0x4000)) /* BABL */ ||
717         (!(s->csr[3] & 0x1000) && !!(s->csr[0] & 0x1000)) /* MISS */ ||
718         (!(s->csr[3] & 0x0100) && !!(s->csr[0] & 0x0100)) /* IDON */ ||
719         (!(s->csr[3] & 0x0200) && !!(s->csr[0] & 0x0200)) /* TINT */ ||
720         (!(s->csr[3] & 0x0400) && !!(s->csr[0] & 0x0400)) /* RINT */ ||
721         (!(s->csr[3] & 0x0800) && !!(s->csr[0] & 0x0800)) /* MERR */ ||
722         (!(s->csr[4] & 0x0001) && !!(s->csr[4] & 0x0002)) /* JAB */ ||
723         (!(s->csr[4] & 0x0004) && !!(s->csr[4] & 0x0008)) /* TXSTRT */ ||
724         (!(s->csr[4] & 0x0010) && !!(s->csr[4] & 0x0020)) /* RCVO */ ||
725         (!(s->csr[4] & 0x0100) && !!(s->csr[4] & 0x0200)) /* MFCO */ ||
726         (!!(s->csr[5] & 0x0040) && !!(s->csr[5] & 0x0080)) /* EXDINT */ ||
727         (!!(s->csr[5] & 0x0008) && !!(s->csr[5] & 0x0010)) /* MPINT */)
728 #endif
729     {
730        
731         isr = CSR_INEA(s);
732         s->csr[0] |= 0x0080;
733     }
734     
735     if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
736         s->csr[4] &= ~0x0080;
737         s->csr[4] |= 0x0040;
738         s->csr[0] |= 0x0080;
739         isr = 1;
740 #ifdef PCNET_DEBUG
741         printf("pcnet user int\n");
742 #endif
743     }
744
745 #if 1
746     if (((s->csr[5]>>1) & s->csr[5]) & 0x0500) 
747 #else
748     if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
749         (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
750 #endif
751     {
752         isr = 1;
753         s->csr[0] |= 0x0080;
754     }
755
756     if (isr != s->isr) {
757 #ifdef PCNET_DEBUG
758         printf("pcnet: INTA=%d\n", isr);
759 #endif
760     }
761     s->set_irq_cb(s, isr);
762     s->isr = isr;
763 }
764
765 static void pcnet_init(PCNetState *s)
766 {
767     int rlen, tlen;
768     uint16_t *padr, *ladrf, mode;
769     uint32_t rdra, tdra;
770
771 #ifdef PCNET_DEBUG
772     printf("pcnet_init init_addr=0x%08x\n", PHYSADDR(s,CSR_IADR(s)));
773 #endif
774     
775     if (BCR_SSIZE32(s)) {
776         struct pcnet_initblk32 initblk;
777         s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
778                 (uint8_t *)&initblk, sizeof(initblk));
779         mode = initblk.mode;
780         rlen = initblk.rlen >> 4;
781         tlen = initblk.tlen >> 4;
782         ladrf = initblk.ladrf;
783         padr = initblk.padr;
784         if (CSR_BIGENDIAN(s)) {
785             rdra = be32_to_cpu(initblk.rdra);
786             tdra = be32_to_cpu(initblk.tdra);
787         } else {
788             rdra = le32_to_cpu(initblk.rdra);
789             tdra = le32_to_cpu(initblk.tdra);
790         }
791         s->rdra = PHYSADDR(s,initblk.rdra);
792         s->tdra = PHYSADDR(s,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));
797         mode = initblk.mode;
798         ladrf = initblk.ladrf;
799         padr = initblk.padr;
800         if (CSR_BIGENDIAN(s)) {
801             rdra = be32_to_cpu(initblk.rdra);
802             tdra = be32_to_cpu(initblk.tdra);
803         } else {
804             rdra = le32_to_cpu(initblk.rdra);
805             tdra = le32_to_cpu(initblk.tdra);
806         }
807         rlen = rdra >> 29;
808         tlen = tdra >> 29;
809         rdra &= 0x00ffffff;
810         tdra &= 0x00ffffff;
811     }
812     
813 #if defined(PCNET_DEBUG)
814     printf("rlen=%d tlen=%d\n",
815            rlen, tlen);
816 #endif
817     CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512;
818     CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512;
819     s->csr[ 6] = (tlen << 12) | (rlen << 8);
820     if (CSR_BIGENDIAN(s)) {
821         s->csr[15] = be16_to_cpu(mode);
822         s->csr[ 8] = be16_to_cpu(ladrf[0]);
823         s->csr[ 9] = be16_to_cpu(ladrf[1]);
824         s->csr[10] = be16_to_cpu(ladrf[2]);
825         s->csr[11] = be16_to_cpu(ladrf[3]);
826         s->csr[12] = be16_to_cpu(padr[0]);
827         s->csr[13] = be16_to_cpu(padr[1]);
828         s->csr[14] = be16_to_cpu(padr[2]);
829     } else {
830         s->csr[15] = le16_to_cpu(mode);
831         s->csr[ 8] = le16_to_cpu(ladrf[0]);
832         s->csr[ 9] = le16_to_cpu(ladrf[1]);
833         s->csr[10] = le16_to_cpu(ladrf[2]);
834         s->csr[11] = le16_to_cpu(ladrf[3]);
835         s->csr[12] = le16_to_cpu(padr[0]);
836         s->csr[13] = le16_to_cpu(padr[1]);
837         s->csr[14] = le16_to_cpu(padr[2]);
838     }
839     s->rdra = PHYSADDR(s, rdra);
840     s->tdra = PHYSADDR(s, tdra);
841
842     CSR_RCVRC(s) = CSR_RCVRL(s);
843     CSR_XMTRC(s) = CSR_XMTRL(s);
844
845 #ifdef PCNET_DEBUG
846     printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n", 
847         BCR_SSIZE32(s),
848         s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
849 #endif
850
851     s->csr[0] |= 0x0101;    
852     s->csr[0] &= ~0x0004;       /* clear STOP bit */
853 }
854
855 static void pcnet_start(PCNetState *s)
856 {
857 #ifdef PCNET_DEBUG
858     printf("pcnet_start\n");
859 #endif
860
861     if (!CSR_DTX(s))
862         s->csr[0] |= 0x0010;    /* set TXON */
863         
864     if (!CSR_DRX(s))
865         s->csr[0] |= 0x0020;    /* set RXON */
866
867     s->csr[0] &= ~0x0004;       /* clear STOP bit */
868     s->csr[0] |= 0x0002;
869 }
870
871 static void pcnet_stop(PCNetState *s)
872 {
873 #ifdef PCNET_DEBUG
874     printf("pcnet_stop\n");
875 #endif
876     s->csr[0] &= ~0x7feb;
877     s->csr[0] |= 0x0014;
878     s->csr[4] &= ~0x02c2;
879     s->csr[5] &= ~0x0011;
880     pcnet_poll_timer(s);
881 }
882
883 static void pcnet_rdte_poll(PCNetState *s)
884 {
885     s->csr[28] = s->csr[29] = 0;
886     if (s->rdra) {
887         int bad = 0;
888 #if 1
889         target_phys_addr_t crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
890         target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
891         target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
892 #else
893         target_phys_addr_t crda = s->rdra + 
894             (CSR_RCVRL(s) - CSR_RCVRC(s)) *
895             (BCR_SWSTYLE(s) ? 16 : 8 );
896         int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
897         target_phys_addr_t nrda = s->rdra + 
898             (CSR_RCVRL(s) - nrdc) *
899             (BCR_SWSTYLE(s) ? 16 : 8 );
900         int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
901         target_phys_addr_t nnrd = s->rdra + 
902             (CSR_RCVRL(s) - nnrc) *
903             (BCR_SWSTYLE(s) ? 16 : 8 );
904 #endif
905
906         CHECK_RMD(PHYSADDR(s,crda), bad);
907         if (!bad) {
908             CHECK_RMD(PHYSADDR(s,nrda), bad);
909             if (bad || (nrda == crda)) nrda = 0;
910             CHECK_RMD(PHYSADDR(s,nnrd), bad);
911             if (bad || (nnrd == crda)) nnrd = 0;
912
913             s->csr[28] = crda & 0xffff;
914             s->csr[29] = crda >> 16;
915             s->csr[26] = nrda & 0xffff;
916             s->csr[27] = nrda >> 16;
917             s->csr[36] = nnrd & 0xffff;
918             s->csr[37] = nnrd >> 16;
919 #ifdef PCNET_DEBUG
920             if (bad) {
921                 printf("pcnet: BAD RMD RECORDS AFTER 0x%08x\n",
922                        PHYSADDR(s,crda));
923             }
924         } else {
925             printf("pcnet: BAD RMD RDA=0x%08x\n", PHYSADDR(s,crda));
926 #endif
927         }
928     }
929     
930     if (CSR_CRDA(s)) {
931         struct pcnet_RMD rmd;
932         RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
933         CSR_CRBC(s) = rmd.rmd1.bcnt;
934         CSR_CRST(s) = ((uint32_t *)&rmd)[1] >> 16;
935 #ifdef PCNET_DEBUG_RMD_X
936         printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMD1=0x%08x RMD2=0x%08x\n",
937                 PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
938                 ((uint32_t *)&rmd)[1], ((uint32_t *)&rmd)[2]);
939         PRINT_RMD(&rmd);
940 #endif
941     } else {
942         CSR_CRBC(s) = CSR_CRST(s) = 0;
943     }
944     
945     if (CSR_NRDA(s)) {
946         struct pcnet_RMD rmd;
947         RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
948         CSR_NRBC(s) = rmd.rmd1.bcnt;
949         CSR_NRST(s) = ((uint32_t *)&rmd)[1] >> 16;
950     } else {
951         CSR_NRBC(s) = CSR_NRST(s) = 0;
952     }
953
954 }
955
956 static int pcnet_tdte_poll(PCNetState *s)
957 {
958     s->csr[34] = s->csr[35] = 0;
959     if (s->tdra) {
960         target_phys_addr_t cxda = s->tdra + 
961             (CSR_XMTRL(s) - CSR_XMTRC(s)) *
962             (BCR_SWSTYLE(s) ? 16 : 8 );
963         int bad = 0;
964         CHECK_TMD(PHYSADDR(s, cxda),bad);
965         if (!bad) {
966             if (CSR_CXDA(s) != cxda) {
967                 s->csr[60] = s->csr[34];
968                 s->csr[61] = s->csr[35];
969                 s->csr[62] = CSR_CXBC(s);
970                 s->csr[63] = CSR_CXST(s);
971             }
972             s->csr[34] = cxda & 0xffff;
973             s->csr[35] = cxda >> 16;
974 #ifdef PCNET_DEBUG
975         } else {
976             printf("pcnet: BAD TMD XDA=0x%08x\n", PHYSADDR(s,cxda));
977 #endif
978         }
979     }
980
981     if (CSR_CXDA(s)) {
982         struct pcnet_TMD tmd;
983
984         TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));                
985
986         CSR_CXBC(s) = tmd.tmd1.bcnt;
987         CSR_CXST(s) = ((uint32_t *)&tmd)[1] >> 16;
988     } else {
989         CSR_CXBC(s) = CSR_CXST(s) = 0;
990     }
991     
992     return !!(CSR_CXST(s) & 0x8000);
993 }
994
995 static int pcnet_can_receive(void *opaque)
996 {
997     PCNetState *s = opaque;
998     if (CSR_STOP(s) || CSR_SPND(s))
999         return 0;
1000         
1001     if (s->recv_pos > 0)
1002         return 0;
1003
1004     return sizeof(s->buffer)-16;
1005 }
1006
1007 #define MIN_BUF_SIZE 60
1008
1009 static void pcnet_receive(void *opaque, const uint8_t *buf, int size)
1010 {
1011     PCNetState *s = opaque;
1012     int is_padr = 0, is_bcast = 0, is_ladr = 0;
1013     uint8_t buf1[60];
1014
1015     if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
1016         return;
1017
1018 #ifdef PCNET_DEBUG
1019     printf("pcnet_receive size=%d\n", size);
1020 #endif
1021
1022     /* if too small buffer, then expand it */
1023     if (size < MIN_BUF_SIZE) {
1024         memcpy(buf1, buf, size);
1025         memset(buf1 + size, 0, MIN_BUF_SIZE - size);
1026         buf = buf1;
1027         size = MIN_BUF_SIZE;
1028     }
1029
1030     if (CSR_PROM(s) 
1031         || (is_padr=padr_match(s, buf, size)) 
1032         || (is_bcast=padr_bcast(s, buf, size))
1033         || (is_ladr=ladr_match(s, buf, size))) {
1034
1035         pcnet_rdte_poll(s);
1036
1037         if (!(CSR_CRST(s) & 0x8000) && s->rdra) {
1038             struct pcnet_RMD rmd;
1039             int rcvrc = CSR_RCVRC(s)-1,i;
1040             target_phys_addr_t nrda;
1041             for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {
1042                 if (rcvrc <= 1)
1043                     rcvrc = CSR_RCVRL(s);
1044                 nrda = s->rdra +
1045                     (CSR_RCVRL(s) - rcvrc) *
1046                     (BCR_SWSTYLE(s) ? 16 : 8 );
1047                 RMDLOAD(&rmd, PHYSADDR(s,nrda));                  
1048                 if (rmd.rmd1.own) {                
1049 #ifdef PCNET_DEBUG_RMD
1050                     printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n", 
1051                                 rcvrc, CSR_RCVRC(s));
1052 #endif
1053                     CSR_RCVRC(s) = rcvrc;
1054                     pcnet_rdte_poll(s);
1055                     break;
1056                 }
1057             }
1058         }
1059
1060         if (!(CSR_CRST(s) & 0x8000)) {
1061 #ifdef PCNET_DEBUG_RMD
1062             printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));
1063 #endif
1064             s->csr[0] |= 0x1000; /* Set MISS flag */
1065             CSR_MISSC(s)++;
1066         } else {
1067             uint8_t *src = &s->buffer[8];
1068             target_phys_addr_t crda = CSR_CRDA(s);
1069             struct pcnet_RMD rmd;
1070             int pktcount = 0;
1071
1072             memcpy(src, buf, size);
1073             
1074 #if 1
1075             /* no need to compute the CRC */
1076             src[size] = 0;
1077             src[size + 1] = 0;
1078             src[size + 2] = 0;
1079             src[size + 3] = 0;
1080             size += 4;
1081 #else
1082             /* XXX: avoid CRC generation */
1083             if (!CSR_ASTRP_RCV(s)) {
1084                 uint32_t fcs = ~0;
1085                 uint8_t *p = src;
1086
1087                 while (size < 46) {
1088                     src[size++] = 0;
1089                 }
1090                 
1091                 while (p != &src[size]) {
1092                     CRC(fcs, *p++);
1093                 }
1094                 ((uint32_t *)&src[size])[0] = htonl(fcs);
1095                 size += 4; /* FCS at end of packet */
1096             } else size += 4;
1097 #endif
1098
1099 #ifdef PCNET_DEBUG_MATCH
1100             PRINT_PKTHDR(buf);
1101 #endif
1102
1103             RMDLOAD(&rmd, PHYSADDR(s,crda));
1104             /*if (!CSR_LAPPEN(s))*/
1105                 rmd.rmd1.stp = 1;
1106
1107 #define PCNET_RECV_STORE() do {                                 \
1108     int count = MIN(4096 - rmd.rmd1.bcnt,size);                 \
1109     target_phys_addr_t rbadr = PHYSADDR(s, rmd.rmd0.rbadr);     \
1110     s->phys_mem_write(s->dma_opaque, rbadr, src, count);               \
1111     src += count; size -= count;                                \
1112     rmd.rmd2.mcnt = count; rmd.rmd1.own = 0;                    \
1113     RMDSTORE(&rmd, PHYSADDR(s,crda));                           \
1114     pktcount++;                                                 \
1115 } while (0)
1116
1117             PCNET_RECV_STORE();
1118             if ((size > 0) && CSR_NRDA(s)) {
1119                 target_phys_addr_t nrda = CSR_NRDA(s);
1120                 RMDLOAD(&rmd, PHYSADDR(s,nrda));
1121                 if (rmd.rmd1.own) {
1122                     crda = nrda;
1123                     PCNET_RECV_STORE();
1124                     if ((size > 0) && (nrda=CSR_NNRD(s))) {
1125                         RMDLOAD(&rmd, PHYSADDR(s,nrda));
1126                         if (rmd.rmd1.own) {
1127                             crda = nrda;
1128                             PCNET_RECV_STORE();
1129                         }
1130                     }
1131                 }                
1132             }
1133
1134 #undef PCNET_RECV_STORE
1135
1136             RMDLOAD(&rmd, PHYSADDR(s,crda));
1137             if (size == 0) {
1138                 rmd.rmd1.enp = 1;
1139                 rmd.rmd1.pam = !CSR_PROM(s) && is_padr;
1140                 rmd.rmd1.lafm = !CSR_PROM(s) && is_ladr;
1141                 rmd.rmd1.bam = !CSR_PROM(s) && is_bcast;
1142             } else {
1143                 rmd.rmd1.oflo = 1;
1144                 rmd.rmd1.buff = 1;
1145                 rmd.rmd1.err = 1;
1146             }
1147             RMDSTORE(&rmd, PHYSADDR(s,crda));
1148             s->csr[0] |= 0x0400;
1149
1150 #ifdef PCNET_DEBUG
1151             printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n", 
1152                 CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
1153 #endif
1154 #ifdef PCNET_DEBUG_RMD
1155             PRINT_RMD(&rmd);
1156 #endif        
1157
1158             while (pktcount--) {
1159                 if (CSR_RCVRC(s) <= 1)
1160                     CSR_RCVRC(s) = CSR_RCVRL(s);
1161                 else
1162                     CSR_RCVRC(s)--;            
1163             }
1164             
1165             pcnet_rdte_poll(s);
1166
1167         }        
1168     }
1169
1170     pcnet_poll(s);
1171     pcnet_update_irq(s);    
1172 }
1173
1174 static void pcnet_transmit(PCNetState *s)
1175 {
1176     target_phys_addr_t xmit_cxda = 0;
1177     int count = CSR_XMTRL(s)-1;
1178     s->xmit_pos = -1;
1179     
1180     if (!CSR_TXON(s)) {
1181         s->csr[0] &= ~0x0008;
1182         return;
1183     }
1184
1185     s->tx_busy = 1;
1186
1187     txagain:
1188     if (pcnet_tdte_poll(s)) {
1189         struct pcnet_TMD tmd;
1190
1191         TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));                
1192
1193 #ifdef PCNET_DEBUG_TMD
1194         printf("  TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
1195         PRINT_TMD(&tmd);
1196 #endif
1197         if (tmd.tmd1.stp) {
1198             s->xmit_pos = 0;                
1199             if (!tmd.tmd1.enp) {
1200                 s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr),
1201                         s->buffer, 4096 - tmd.tmd1.bcnt);
1202                 s->xmit_pos += 4096 - tmd.tmd1.bcnt;
1203             } 
1204             xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
1205         }
1206         if (tmd.tmd1.enp && (s->xmit_pos >= 0)) {
1207             s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr),
1208                     s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt);
1209             s->xmit_pos += 4096 - tmd.tmd1.bcnt;
1210 #ifdef PCNET_DEBUG
1211             printf("pcnet_transmit size=%d\n", s->xmit_pos);
1212 #endif            
1213             if (CSR_LOOP(s))
1214                 pcnet_receive(s, s->buffer, s->xmit_pos);
1215             else
1216                 qemu_send_packet(s->vc, s->buffer, s->xmit_pos);
1217
1218             s->csr[0] &= ~0x0008;   /* clear TDMD */
1219             s->csr[4] |= 0x0004;    /* set TXSTRT */
1220             s->xmit_pos = -1;
1221         }
1222
1223         tmd.tmd1.own = 0;
1224         TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1225         if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && tmd.tmd1.ltint))
1226             s->csr[0] |= 0x0200;    /* set TINT */
1227
1228         if (CSR_XMTRC(s)<=1)
1229             CSR_XMTRC(s) = CSR_XMTRL(s);
1230         else
1231             CSR_XMTRC(s)--;
1232         if (count--)
1233             goto txagain;
1234
1235     } else 
1236     if (s->xmit_pos >= 0) {
1237         struct pcnet_TMD tmd;
1238         TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));                
1239         tmd.tmd2.buff = tmd.tmd2.uflo = tmd.tmd1.err = 1;
1240         tmd.tmd1.own = 0;
1241         TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda));
1242         s->csr[0] |= 0x0200;    /* set TINT */
1243         if (!CSR_DXSUFLO(s)) {
1244             s->csr[0] &= ~0x0010;
1245         } else
1246         if (count--)
1247           goto txagain;
1248     }
1249
1250     s->tx_busy = 0;
1251 }
1252
1253 static void pcnet_poll(PCNetState *s)
1254 {
1255     if (CSR_RXON(s)) {
1256         pcnet_rdte_poll(s);
1257     }
1258
1259     if (CSR_TDMD(s) || 
1260         (CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s)))
1261     {
1262         /* prevent recursion */
1263         if (s->tx_busy)
1264             return;
1265
1266         pcnet_transmit(s);
1267     }
1268 }
1269
1270 static void pcnet_poll_timer(void *opaque)
1271 {
1272     PCNetState *s = opaque;
1273
1274     qemu_del_timer(s->poll_timer);
1275
1276     if (CSR_TDMD(s)) {
1277         pcnet_transmit(s);
1278     }
1279
1280     pcnet_update_irq(s);    
1281
1282     if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
1283         uint64_t now = qemu_get_clock(vm_clock) * 33;
1284         if (!s->timer || !now)
1285             s->timer = now;
1286         else {
1287             uint64_t t = now - s->timer + CSR_POLL(s);
1288             if (t > 0xffffLL) {
1289                 pcnet_poll(s);
1290                 CSR_POLL(s) = CSR_PINT(s);
1291             } else
1292                 CSR_POLL(s) = t;
1293         }
1294         qemu_mod_timer(s->poll_timer, 
1295             pcnet_get_next_poll_time(s,qemu_get_clock(vm_clock)));
1296     }
1297 }
1298
1299
1300 static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value)
1301 {
1302     uint16_t val = new_value;
1303 #ifdef PCNET_DEBUG_CSR
1304     printf("pcnet_csr_writew rap=%d val=0x%04x\n", rap, val);
1305 #endif
1306     switch (rap) {
1307     case 0:
1308         s->csr[0] &= ~(val & 0x7f00); /* Clear any interrupt flags */
1309
1310         s->csr[0] = (s->csr[0] & ~0x0040) | (val & 0x0048);
1311
1312         val = (val & 0x007f) | (s->csr[0] & 0x7f00);
1313
1314         /* IFF STOP, STRT and INIT are set, clear STRT and INIT */
1315         if ((val&7) == 7)
1316           val &= ~3;
1317
1318         if (!CSR_STOP(s) && (val & 4))
1319             pcnet_stop(s);
1320
1321         if (!CSR_INIT(s) && (val & 1))
1322             pcnet_init(s);
1323
1324         if (!CSR_STRT(s) && (val & 2))
1325             pcnet_start(s);
1326
1327         if (CSR_TDMD(s)) 
1328             pcnet_transmit(s);
1329
1330         return;
1331     case 1:
1332     case 2:
1333     case 8:
1334     case 9:
1335     case 10:
1336     case 11:
1337     case 12:
1338     case 13:
1339     case 14:
1340     case 15:
1341     case 18: /* CRBAL */
1342     case 19: /* CRBAU */
1343     case 20: /* CXBAL */
1344     case 21: /* CXBAU */
1345     case 22: /* NRBAU */
1346     case 23: /* NRBAU */
1347     case 24:
1348     case 25:
1349     case 26:
1350     case 27:
1351     case 28:
1352     case 29:
1353     case 30:
1354     case 31:
1355     case 32:
1356     case 33:
1357     case 34:
1358     case 35:
1359     case 36:
1360     case 37:
1361     case 38:
1362     case 39:
1363     case 40: /* CRBC */
1364     case 41:
1365     case 42: /* CXBC */
1366     case 43:
1367     case 44:
1368     case 45:
1369     case 46: /* POLL */
1370     case 47: /* POLLINT */
1371     case 72:
1372     case 74:
1373     case 76: /* RCVRL */
1374     case 78: /* XMTRL */
1375     case 112:
1376        if (CSR_STOP(s) || CSR_SPND(s))
1377            break;
1378        return;
1379     case 3:
1380         break;
1381     case 4:
1382         s->csr[4] &= ~(val & 0x026a); 
1383         val &= ~0x026a; val |= s->csr[4] & 0x026a;
1384         break;
1385     case 5:
1386         s->csr[5] &= ~(val & 0x0a90); 
1387         val &= ~0x0a90; val |= s->csr[5] & 0x0a90;
1388         break;
1389     case 16:
1390         pcnet_csr_writew(s,1,val);
1391         return;
1392     case 17:
1393         pcnet_csr_writew(s,2,val);
1394         return;
1395     case 58:
1396         pcnet_bcr_writew(s,BCR_SWS,val);
1397         break;
1398     default:
1399         return;
1400     }
1401     s->csr[rap] = val;
1402 }
1403
1404 static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap)
1405 {
1406     uint32_t val;
1407     switch (rap) {
1408     case 0:
1409         pcnet_update_irq(s);
1410         val = s->csr[0];
1411         val |= (val & 0x7800) ? 0x8000 : 0;
1412         break;
1413     case 16:
1414         return pcnet_csr_readw(s,1);
1415     case 17:
1416         return pcnet_csr_readw(s,2);
1417     case 58:
1418         return pcnet_bcr_readw(s,BCR_SWS);
1419     case 88:
1420         val = s->csr[89];
1421         val <<= 16;
1422         val |= s->csr[88];
1423         break;
1424     default:
1425         val = s->csr[rap];
1426     }
1427 #ifdef PCNET_DEBUG_CSR
1428     printf("pcnet_csr_readw rap=%d val=0x%04x\n", rap, val);
1429 #endif
1430     return val;
1431 }
1432
1433 static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val)
1434 {
1435     rap &= 127;
1436 #ifdef PCNET_DEBUG_BCR
1437     printf("pcnet_bcr_writew rap=%d val=0x%04x\n", rap, val);
1438 #endif
1439     switch (rap) {
1440     case BCR_SWS:
1441         if (!(CSR_STOP(s) || CSR_SPND(s)))
1442             return;
1443         val &= ~0x0300;
1444         switch (val & 0x00ff) {
1445         case 0:
1446             val |= 0x0200;
1447             break;
1448         case 1:
1449             val |= 0x0100;
1450             break;
1451         case 2:
1452         case 3:
1453             val |= 0x0300;
1454             break;
1455         default:
1456             printf("Bad SWSTYLE=0x%02x\n", val & 0xff);
1457             val = 0x0200;
1458             break;
1459         }
1460 #ifdef PCNET_DEBUG
1461        printf("BCR_SWS=0x%04x\n", val);
1462 #endif
1463     case BCR_LNKST:
1464     case BCR_LED1:
1465     case BCR_LED2:
1466     case BCR_LED3:
1467     case BCR_MC:
1468     case BCR_FDC:
1469     case BCR_BSBC:
1470     case BCR_EECAS:
1471     case BCR_PLAT:
1472         s->bcr[rap] = val;
1473         break;
1474     default:
1475         break;
1476     }
1477 }
1478
1479 static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap)
1480 {
1481     uint32_t val;
1482     rap &= 127;
1483     switch (rap) {
1484     case BCR_LNKST:
1485     case BCR_LED1:
1486     case BCR_LED2:
1487     case BCR_LED3:
1488         val = s->bcr[rap] & ~0x8000;
1489         val |= (val & 0x017f & s->lnkst) ? 0x8000 : 0;
1490         break;
1491     default:
1492         val = rap < 32 ? s->bcr[rap] : 0;
1493         break;
1494     }
1495 #ifdef PCNET_DEBUG_BCR
1496     printf("pcnet_bcr_readw rap=%d val=0x%04x\n", rap, val);
1497 #endif
1498     return val;
1499 }
1500
1501 void pcnet_h_reset(void *opaque)
1502 {
1503     PCNetState *s = opaque;
1504     int i;
1505     uint16_t checksum;
1506
1507     /* Initialize the PROM */
1508
1509     memcpy(s->prom, s->nd->macaddr, 6);
1510     s->prom[12] = s->prom[13] = 0x00;
1511     s->prom[14] = s->prom[15] = 0x57;
1512
1513     for (i = 0,checksum = 0; i < 16; i++)
1514         checksum += s->prom[i];
1515     *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);
1516
1517
1518     s->bcr[BCR_MSRDA] = 0x0005;
1519     s->bcr[BCR_MSWRA] = 0x0005;
1520     s->bcr[BCR_MC   ] = 0x0002;
1521     s->bcr[BCR_LNKST] = 0x00c0;
1522     s->bcr[BCR_LED1 ] = 0x0084;
1523     s->bcr[BCR_LED2 ] = 0x0088;
1524     s->bcr[BCR_LED3 ] = 0x0090;
1525     s->bcr[BCR_FDC  ] = 0x0000;
1526     s->bcr[BCR_BSBC ] = 0x9001;
1527     s->bcr[BCR_EECAS] = 0x0002;
1528     s->bcr[BCR_SWS  ] = 0x0200;
1529     s->bcr[BCR_PLAT ] = 0xff06;
1530
1531     pcnet_s_reset(s);
1532 }
1533
1534 static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
1535 {
1536     PCNetState *s = opaque;
1537 #ifdef PCNET_DEBUG
1538     printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);
1539 #endif    
1540     /* Check APROMWE bit to enable write access */
1541     if (pcnet_bcr_readw(s,2) & 0x80)
1542         s->prom[addr & 15] = val;
1543 }       
1544
1545 static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
1546 {
1547     PCNetState *s = opaque;
1548     uint32_t val = s->prom[addr &= 15];
1549 #ifdef PCNET_DEBUG
1550     printf("pcnet_aprom_readb addr=0x%08x val=0x%02x\n", addr, val);
1551 #endif
1552     return val;
1553 }
1554
1555 static void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
1556 {
1557     PCNetState *s = opaque;
1558     pcnet_poll_timer(s);
1559 #ifdef PCNET_DEBUG_IO
1560     printf("pcnet_ioport_writew addr=0x%08x val=0x%04x\n", addr, val);
1561 #endif
1562     if (!BCR_DWIO(s)) {
1563         switch (addr & 0x0f) {
1564         case 0x00: /* RDP */
1565             pcnet_csr_writew(s, s->rap, val);
1566             break;
1567         case 0x02:
1568             s->rap = val & 0x7f;
1569             break;
1570         case 0x06:
1571             pcnet_bcr_writew(s, s->rap, val);
1572             break;
1573         }
1574     }
1575     pcnet_update_irq(s);
1576 }
1577
1578 static uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr)
1579 {
1580     PCNetState *s = opaque;
1581     uint32_t val = -1;
1582     pcnet_poll_timer(s);
1583     if (!BCR_DWIO(s)) {
1584         switch (addr & 0x0f) {
1585         case 0x00: /* RDP */
1586             val = pcnet_csr_readw(s, s->rap);
1587             break;
1588         case 0x02:
1589             val = s->rap;
1590             break;
1591         case 0x04:
1592             pcnet_s_reset(s);
1593             val = 0;
1594             break;
1595         case 0x06:
1596             val = pcnet_bcr_readw(s, s->rap);
1597             break;
1598         }
1599     }
1600     pcnet_update_irq(s);
1601 #ifdef PCNET_DEBUG_IO
1602     printf("pcnet_ioport_readw addr=0x%08x val=0x%04x\n", addr, val & 0xffff);
1603 #endif
1604     return val;
1605 }
1606
1607 static void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
1608 {
1609     PCNetState *s = opaque;
1610     pcnet_poll_timer(s);
1611 #ifdef PCNET_DEBUG_IO
1612     printf("pcnet_ioport_writel addr=0x%08x val=0x%08x\n", addr, val);
1613 #endif
1614     if (BCR_DWIO(s)) {
1615         switch (addr & 0x0f) {
1616         case 0x00: /* RDP */
1617             pcnet_csr_writew(s, s->rap, val & 0xffff);
1618             break;
1619         case 0x04:
1620             s->rap = val & 0x7f;
1621             break;
1622         case 0x0c:
1623             pcnet_bcr_writew(s, s->rap, val & 0xffff);
1624             break;
1625         }
1626     } else
1627     if ((addr & 0x0f) == 0) {
1628         /* switch device to dword i/o mode */
1629         pcnet_bcr_writew(s, BCR_BSBC, pcnet_bcr_readw(s, BCR_BSBC) | 0x0080);
1630 #ifdef PCNET_DEBUG_IO
1631         printf("device switched into dword i/o mode\n");
1632 #endif        
1633     }
1634     pcnet_update_irq(s);
1635 }
1636
1637 static uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr)
1638 {
1639     PCNetState *s = opaque;
1640     uint32_t val = -1;
1641     pcnet_poll_timer(s);
1642     if (BCR_DWIO(s)) {  
1643         switch (addr & 0x0f) {
1644         case 0x00: /* RDP */
1645             val = pcnet_csr_readw(s, s->rap);
1646             break;
1647         case 0x04:
1648             val = s->rap;
1649             break;
1650         case 0x08:
1651             pcnet_s_reset(s);
1652             val = 0;
1653             break;
1654         case 0x0c:
1655             val = pcnet_bcr_readw(s, s->rap);
1656             break;
1657         }
1658     }
1659     pcnet_update_irq(s);
1660 #ifdef PCNET_DEBUG_IO
1661     printf("pcnet_ioport_readl addr=0x%08x val=0x%08x\n", addr, val);
1662 #endif
1663     return val;
1664 }
1665
1666 static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num, 
1667                              uint32_t addr, uint32_t size, int type)
1668 {
1669     PCNetState *d = (PCNetState *)pci_dev;
1670
1671 #ifdef PCNET_DEBUG_IO
1672     printf("pcnet_ioport_map addr=0x%04x size=0x%04x\n", addr, size);
1673 #endif
1674
1675     register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
1676     register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
1677     
1678     register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
1679     register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
1680     register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
1681     register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
1682 }
1683
1684 static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
1685 {
1686     PCNetState *d = opaque;
1687 #ifdef PCNET_DEBUG_IO
1688     printf("pcnet_mmio_writeb addr=0x%08x val=0x%02x\n", addr, val);
1689 #endif
1690     if (!(addr & 0x10))
1691         pcnet_aprom_writeb(d, addr & 0x0f, val);
1692 }
1693
1694 static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr) 
1695 {
1696     PCNetState *d = opaque;
1697     uint32_t val = -1;
1698     if (!(addr & 0x10))
1699         val = pcnet_aprom_readb(d, addr & 0x0f);
1700 #ifdef PCNET_DEBUG_IO
1701     printf("pcnet_mmio_readb addr=0x%08x val=0x%02x\n", addr, val & 0xff);
1702 #endif
1703     return val;
1704 }
1705
1706 static void pcnet_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
1707 {
1708     PCNetState *d = opaque;
1709 #ifdef PCNET_DEBUG_IO
1710     printf("pcnet_mmio_writew addr=0x%08x val=0x%04x\n", addr, val);
1711 #endif
1712     if (addr & 0x10)
1713         pcnet_ioport_writew(d, addr & 0x0f, val);
1714     else {
1715         addr &= 0x0f;
1716         pcnet_aprom_writeb(d, addr, val & 0xff);
1717         pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
1718     }
1719 }
1720
1721 static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr) 
1722 {
1723     PCNetState *d = opaque;
1724     uint32_t val = -1;
1725     if (addr & 0x10)
1726         val = pcnet_ioport_readw(d, addr & 0x0f);
1727     else {
1728         addr &= 0x0f;
1729         val = pcnet_aprom_readb(d, addr+1);
1730         val <<= 8;
1731         val |= pcnet_aprom_readb(d, addr);
1732     }
1733 #ifdef PCNET_DEBUG_IO
1734     printf("pcnet_mmio_readw addr=0x%08x val = 0x%04x\n", addr, val & 0xffff);
1735 #endif
1736     return val;
1737 }
1738
1739 static void pcnet_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
1740 {
1741     PCNetState *d = opaque;
1742 #ifdef PCNET_DEBUG_IO
1743     printf("pcnet_mmio_writel addr=0x%08x val=0x%08x\n", addr, val);
1744 #endif
1745     if (addr & 0x10)
1746         pcnet_ioport_writel(d, addr & 0x0f, val);
1747     else {
1748         addr &= 0x0f;
1749         pcnet_aprom_writeb(d, addr, val & 0xff);
1750         pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
1751         pcnet_aprom_writeb(d, addr+2, (val & 0xff0000) >> 16);
1752         pcnet_aprom_writeb(d, addr+3, (val & 0xff000000) >> 24);
1753     }
1754 }
1755
1756 static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr) 
1757 {
1758     PCNetState *d = opaque;
1759     uint32_t val;
1760     if (addr & 0x10)
1761         val = pcnet_ioport_readl(d, addr & 0x0f);
1762     else {
1763         addr &= 0x0f;
1764         val = pcnet_aprom_readb(d, addr+3);
1765         val <<= 8;
1766         val |= pcnet_aprom_readb(d, addr+2);
1767         val <<= 8;
1768         val |= pcnet_aprom_readb(d, addr+1);
1769         val <<= 8;
1770         val |= pcnet_aprom_readb(d, addr);
1771     }
1772 #ifdef PCNET_DEBUG_IO
1773     printf("pcnet_mmio_readl addr=0x%08x val=0x%08x\n", addr, val);
1774 #endif
1775     return val;
1776 }
1777
1778
1779 static void pcnet_save(QEMUFile *f, void *opaque)
1780 {
1781     PCNetState *s = opaque;
1782     unsigned int i;
1783
1784     if (s->pci_dev)
1785         pci_device_save(s->pci_dev, f);
1786
1787     qemu_put_be32s(f, &s->rap);
1788     qemu_put_be32s(f, &s->isr);
1789     qemu_put_be32s(f, &s->lnkst);
1790     qemu_put_be32s(f, &s->rdra);
1791     qemu_put_be32s(f, &s->tdra);
1792     qemu_put_buffer(f, s->prom, 16);
1793     for (i = 0; i < 128; i++)
1794         qemu_put_be16s(f, &s->csr[i]);
1795     for (i = 0; i < 32; i++)
1796         qemu_put_be16s(f, &s->bcr[i]);
1797     qemu_put_be64s(f, &s->timer);
1798     qemu_put_be32s(f, &s->xmit_pos);
1799     qemu_put_be32s(f, &s->recv_pos);
1800     qemu_put_buffer(f, s->buffer, 4096);
1801     qemu_put_be32s(f, &s->tx_busy);
1802     qemu_put_timer(f, s->poll_timer);
1803 }
1804
1805 static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
1806 {
1807     PCNetState *s = opaque;
1808     int i, ret;
1809
1810     if (version_id != 2)
1811         return -EINVAL;
1812
1813     if (s->pci_dev) {
1814         ret = pci_device_load(s->pci_dev, f);
1815         if (ret < 0)
1816             return ret;
1817     }
1818
1819     qemu_get_be32s(f, &s->rap);
1820     qemu_get_be32s(f, &s->isr);
1821     qemu_get_be32s(f, &s->lnkst);
1822     qemu_get_be32s(f, &s->rdra);
1823     qemu_get_be32s(f, &s->tdra);
1824     qemu_get_buffer(f, s->prom, 16);
1825     for (i = 0; i < 128; i++)
1826         qemu_get_be16s(f, &s->csr[i]);
1827     for (i = 0; i < 32; i++)
1828         qemu_get_be16s(f, &s->bcr[i]);
1829     qemu_get_be64s(f, &s->timer);
1830     qemu_get_be32s(f, &s->xmit_pos);
1831     qemu_get_be32s(f, &s->recv_pos);
1832     qemu_get_buffer(f, s->buffer, 4096);
1833     qemu_get_be32s(f, &s->tx_busy);
1834     qemu_get_timer(f, s->poll_timer);
1835
1836     return 0;
1837 }
1838
1839 static void pcnet_common_init(PCNetState *d, NICInfo *nd, const char *info_str)
1840 {
1841     d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d);
1842
1843     d->nd = nd;
1844
1845     d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive, 
1846                                  pcnet_can_receive, d);
1847     
1848     snprintf(d->vc->info_str, sizeof(d->vc->info_str),
1849              "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
1850              d->nd->macaddr[0],
1851              d->nd->macaddr[1],
1852              d->nd->macaddr[2],
1853              d->nd->macaddr[3],
1854              d->nd->macaddr[4],
1855              d->nd->macaddr[5]);
1856
1857     pcnet_h_reset(d);
1858     register_savevm("pcnet", 0, 2, pcnet_save, pcnet_load, d);
1859 }
1860
1861 /* PCI interface */
1862
1863 static CPUWriteMemoryFunc *pcnet_mmio_write[] = {
1864     (CPUWriteMemoryFunc *)&pcnet_mmio_writeb,
1865     (CPUWriteMemoryFunc *)&pcnet_mmio_writew,
1866     (CPUWriteMemoryFunc *)&pcnet_mmio_writel
1867 };
1868
1869 static CPUReadMemoryFunc *pcnet_mmio_read[] = {
1870     (CPUReadMemoryFunc *)&pcnet_mmio_readb,
1871     (CPUReadMemoryFunc *)&pcnet_mmio_readw,
1872     (CPUReadMemoryFunc *)&pcnet_mmio_readl
1873 };
1874
1875 static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num, 
1876                             uint32_t addr, uint32_t size, int type)
1877 {
1878     PCNetState *d = (PCNetState *)pci_dev;
1879
1880 #ifdef PCNET_DEBUG_IO
1881     printf("pcnet_ioport_map addr=0x%08x 0x%08x\n", addr, size);
1882 #endif
1883
1884     cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_index);
1885 }
1886
1887 static void pcnet_pci_set_irq_cb(void *opaque, int isr)
1888 {
1889     PCNetState *s = opaque;
1890
1891     pci_set_irq(&s->dev, 0, isr);
1892 }
1893
1894 static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
1895                            uint8_t *buf, int len)
1896 {
1897     cpu_physical_memory_write(addr, buf, len);
1898 }
1899
1900 static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
1901                            uint8_t *buf, int len)
1902 {
1903     cpu_physical_memory_read(addr, buf, len);
1904 }
1905
1906 void pci_pcnet_init(PCIBus *bus, NICInfo *nd)
1907 {
1908     PCNetState *d;
1909     uint8_t *pci_conf;
1910
1911 #if 0
1912     printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n", 
1913         sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
1914 #endif
1915
1916     d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
1917                                           -1, NULL, NULL);
1918                                           
1919     pci_conf = d->dev.config;
1920     
1921     *(uint16_t *)&pci_conf[0x00] = cpu_to_le16(0x1022);
1922     *(uint16_t *)&pci_conf[0x02] = cpu_to_le16(0x2000);    
1923     *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007); 
1924     *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
1925     pci_conf[0x08] = 0x10;
1926     pci_conf[0x09] = 0x00;
1927     pci_conf[0x0a] = 0x00; // ethernet network controller 
1928     pci_conf[0x0b] = 0x02;
1929     pci_conf[0x0e] = 0x00; // header_type
1930     
1931     *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
1932     *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
1933     
1934     pci_conf[0x3d] = 1; // interrupt pin 0
1935     pci_conf[0x3e] = 0x06;
1936     pci_conf[0x3f] = 0xff;
1937
1938     /* Handler for memory-mapped I/O */
1939     d->mmio_index =
1940       cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);
1941
1942     pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE, 
1943                            PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
1944                            
1945     pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE, 
1946                            PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
1947                            
1948     d->set_irq_cb = pcnet_pci_set_irq_cb;
1949     d->phys_mem_read = pci_physical_memory_read;
1950     d->phys_mem_write = pci_physical_memory_write;
1951     d->pci_dev = &d->dev;
1952
1953     pcnet_common_init(d, nd, "pcnet");
1954 }
1955
1956 /* SPARC32 interface */
1957
1958 #if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
1959
1960 static CPUReadMemoryFunc *lance_mem_read[3] = {
1961     (CPUReadMemoryFunc *)&pcnet_ioport_readw,
1962     (CPUReadMemoryFunc *)&pcnet_ioport_readw,
1963     (CPUReadMemoryFunc *)&pcnet_ioport_readw,
1964 };
1965
1966 static CPUWriteMemoryFunc *lance_mem_write[3] = {
1967     (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
1968     (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
1969     (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
1970 };
1971
1972 static void pcnet_sparc_set_irq_cb(void *opaque, int isr)
1973 {
1974     PCNetState *s = opaque;
1975
1976     ledma_set_irq(s->dma_opaque, isr);
1977 }
1978
1979 void *lance_init(NICInfo *nd, uint32_t leaddr, void *dma_opaque)
1980 {
1981     PCNetState *d;
1982     int lance_io_memory;
1983
1984     d = qemu_mallocz(sizeof(PCNetState));
1985     if (!d)
1986         return NULL;
1987
1988     lance_io_memory =
1989         cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
1990
1991     d->dma_opaque = dma_opaque;
1992     cpu_register_physical_memory(leaddr, 4, lance_io_memory);
1993
1994     d->set_irq_cb = pcnet_sparc_set_irq_cb;
1995     d->phys_mem_read = ledma_memory_read;
1996     d->phys_mem_write = ledma_memory_write;
1997
1998     pcnet_common_init(d, nd, "lance");
1999
2000     return d;
2001 }
2002 #endif /* TARGET_SPARC */
This page took 0.137392 seconds and 4 git commands to generate.