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