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