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