Statistics
| Branch: | Revision:

root / hw / pcnet.c @ 6ee093c9

History | View | Annotate | Download (65 kB)

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 "sysbus.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
    VLANClientState *vc;
64
    uint8_t macaddr[6];
65
    QEMUTimer *poll_timer;
66
    int rap, isr, lnkst;
67
    uint32_t rdra, tdra;
68
    uint8_t prom[16];
69
    uint16_t csr[128];
70
    uint16_t bcr[32];
71
    uint64_t timer;
72
    int mmio_index, xmit_pos, recv_pos;
73
    uint8_t buffer[4096];
74
    int tx_busy;
75
    qemu_irq irq;
76
    void (*phys_mem_read)(void *dma_opaque, target_phys_addr_t addr,
77
                         uint8_t *buf, int len, int do_bswap);
78
    void (*phys_mem_write)(void *dma_opaque, target_phys_addr_t addr,
79
                          uint8_t *buf, int len, int do_bswap);
80
    void *dma_opaque;
81
    int looptest;
82
};
83

    
84
typedef struct {
85
    PCIDevice pci_dev;
86
    PCNetState state;
87
} PCIPCNetState;
88

    
89
typedef struct {
90
    SysBusDevice busdev;
91
    PCNetState state;
92
} SysBusPCNetState;
93

    
94
struct qemu_ether_header {
95
    uint8_t ether_dhost[6];
96
    uint8_t ether_shost[6];
97
    uint16_t ether_type;
98
};
99

    
100
/* BUS CONFIGURATION REGISTERS */
101
#define BCR_MSRDA    0
102
#define BCR_MSWRA    1
103
#define BCR_MC       2
104
#define BCR_LNKST    4
105
#define BCR_LED1     5
106
#define BCR_LED2     6
107
#define BCR_LED3     7
108
#define BCR_FDC      9
109
#define BCR_BSBC     18
110
#define BCR_EECAS    19
111
#define BCR_SWS      20
112
#define BCR_PLAT     22
113

    
114
#define BCR_DWIO(S)      !!((S)->bcr[BCR_BSBC] & 0x0080)
115
#define BCR_SSIZE32(S)   !!((S)->bcr[BCR_SWS ] & 0x0100)
116
#define BCR_SWSTYLE(S)     ((S)->bcr[BCR_SWS ] & 0x00FF)
117

    
118
#define CSR_INIT(S)      !!(((S)->csr[0])&0x0001)
119
#define CSR_STRT(S)      !!(((S)->csr[0])&0x0002)
120
#define CSR_STOP(S)      !!(((S)->csr[0])&0x0004)
121
#define CSR_TDMD(S)      !!(((S)->csr[0])&0x0008)
122
#define CSR_TXON(S)      !!(((S)->csr[0])&0x0010)
123
#define CSR_RXON(S)      !!(((S)->csr[0])&0x0020)
124
#define CSR_INEA(S)      !!(((S)->csr[0])&0x0040)
125
#define CSR_BSWP(S)      !!(((S)->csr[3])&0x0004)
126
#define CSR_LAPPEN(S)    !!(((S)->csr[3])&0x0020)
127
#define CSR_DXSUFLO(S)   !!(((S)->csr[3])&0x0040)
128
#define CSR_ASTRP_RCV(S) !!(((S)->csr[4])&0x0800)
129
#define CSR_DPOLL(S)     !!(((S)->csr[4])&0x1000)
130
#define CSR_SPND(S)      !!(((S)->csr[5])&0x0001)
131
#define CSR_LTINTEN(S)   !!(((S)->csr[5])&0x4000)
132
#define CSR_TOKINTD(S)   !!(((S)->csr[5])&0x8000)
133
#define CSR_DRX(S)       !!(((S)->csr[15])&0x0001)
134
#define CSR_DTX(S)       !!(((S)->csr[15])&0x0002)
135
#define CSR_LOOP(S)      !!(((S)->csr[15])&0x0004)
136
#define CSR_DXMTFCS(S)   !!(((S)->csr[15])&0x0008)
137
#define CSR_DRCVPA(S)    !!(((S)->csr[15])&0x2000)
138
#define CSR_DRCVBC(S)    !!(((S)->csr[15])&0x4000)
139
#define CSR_PROM(S)      !!(((S)->csr[15])&0x8000)
140

    
141
#define CSR_CRBC(S)      ((S)->csr[40])
142
#define CSR_CRST(S)      ((S)->csr[41])
143
#define CSR_CXBC(S)      ((S)->csr[42])
144
#define CSR_CXST(S)      ((S)->csr[43])
145
#define CSR_NRBC(S)      ((S)->csr[44])
146
#define CSR_NRST(S)      ((S)->csr[45])
147
#define CSR_POLL(S)      ((S)->csr[46])
148
#define CSR_PINT(S)      ((S)->csr[47])
149
#define CSR_RCVRC(S)     ((S)->csr[72])
150
#define CSR_XMTRC(S)     ((S)->csr[74])
151
#define CSR_RCVRL(S)     ((S)->csr[76])
152
#define CSR_XMTRL(S)     ((S)->csr[78])
153
#define CSR_MISSC(S)     ((S)->csr[112])
154

    
155
#define CSR_IADR(S)      ((S)->csr[ 1] | ((S)->csr[ 2] << 16))
156
#define CSR_CRBA(S)      ((S)->csr[18] | ((S)->csr[19] << 16))
157
#define CSR_CXBA(S)      ((S)->csr[20] | ((S)->csr[21] << 16))
158
#define CSR_NRBA(S)      ((S)->csr[22] | ((S)->csr[23] << 16))
159
#define CSR_BADR(S)      ((S)->csr[24] | ((S)->csr[25] << 16))
160
#define CSR_NRDA(S)      ((S)->csr[26] | ((S)->csr[27] << 16))
161
#define CSR_CRDA(S)      ((S)->csr[28] | ((S)->csr[29] << 16))
162
#define CSR_BADX(S)      ((S)->csr[30] | ((S)->csr[31] << 16))
163
#define CSR_NXDA(S)      ((S)->csr[32] | ((S)->csr[33] << 16))
164
#define CSR_CXDA(S)      ((S)->csr[34] | ((S)->csr[35] << 16))
165
#define CSR_NNRD(S)      ((S)->csr[36] | ((S)->csr[37] << 16))
166
#define CSR_NNXD(S)      ((S)->csr[38] | ((S)->csr[39] << 16))
167
#define CSR_PXDA(S)      ((S)->csr[60] | ((S)->csr[61] << 16))
168
#define CSR_NXBA(S)      ((S)->csr[64] | ((S)->csr[65] << 16))
169

    
170
#define PHYSADDR(S,A) \
171
  (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(s)->csr[2])<<16))
172

    
173
struct pcnet_initblk16 {
174
    uint16_t mode;
175
    uint16_t padr[3];
176
    uint16_t ladrf[4];
177
    uint32_t rdra;
178
    uint32_t tdra;
179
};
180

    
181
struct pcnet_initblk32 {
182
    uint16_t mode;
183
    uint8_t rlen;
184
    uint8_t tlen;
185
    uint16_t padr[3];
186
    uint16_t _res;
187
    uint16_t ladrf[4];
188
    uint32_t rdra;
189
    uint32_t tdra;
190
};
191

    
192
struct pcnet_TMD {
193
    uint32_t tbadr;
194
    int16_t length;
195
    int16_t status;
196
    uint32_t misc;
197
    uint32_t res;
198
};
199

    
200
#define TMDL_BCNT_MASK  0x0fff
201
#define TMDL_BCNT_SH    0
202
#define TMDL_ONES_MASK  0xf000
203
#define TMDL_ONES_SH    12
204

    
205
#define TMDS_BPE_MASK   0x0080
206
#define TMDS_BPE_SH     7
207
#define TMDS_ENP_MASK   0x0100
208
#define TMDS_ENP_SH     8
209
#define TMDS_STP_MASK   0x0200
210
#define TMDS_STP_SH     9
211
#define TMDS_DEF_MASK   0x0400
212
#define TMDS_DEF_SH     10
213
#define TMDS_ONE_MASK   0x0800
214
#define TMDS_ONE_SH     11
215
#define TMDS_LTINT_MASK 0x1000
216
#define TMDS_LTINT_SH   12
217
#define TMDS_NOFCS_MASK 0x2000
218
#define TMDS_NOFCS_SH   13
219
#define TMDS_ADDFCS_MASK TMDS_NOFCS_MASK
220
#define TMDS_ADDFCS_SH  TMDS_NOFCS_SH
221
#define TMDS_ERR_MASK   0x4000
222
#define TMDS_ERR_SH     14
223
#define TMDS_OWN_MASK   0x8000
224
#define TMDS_OWN_SH     15
225

    
226
#define TMDM_TRC_MASK   0x0000000f
227
#define TMDM_TRC_SH     0
228
#define TMDM_TDR_MASK   0x03ff0000
229
#define TMDM_TDR_SH     16
230
#define TMDM_RTRY_MASK  0x04000000
231
#define TMDM_RTRY_SH    26
232
#define TMDM_LCAR_MASK  0x08000000
233
#define TMDM_LCAR_SH    27
234
#define TMDM_LCOL_MASK  0x10000000
235
#define TMDM_LCOL_SH    28
236
#define TMDM_EXDEF_MASK 0x20000000
237
#define TMDM_EXDEF_SH   29
238
#define TMDM_UFLO_MASK  0x40000000
239
#define TMDM_UFLO_SH    30
240
#define TMDM_BUFF_MASK  0x80000000
241
#define TMDM_BUFF_SH    31
242

    
243
struct pcnet_RMD {
244
    uint32_t rbadr;
245
    int16_t buf_length;
246
    int16_t status;
247
    uint32_t msg_length;
248
    uint32_t res;
249
};
250

    
251
#define RMDL_BCNT_MASK  0x0fff
252
#define RMDL_BCNT_SH    0
253
#define RMDL_ONES_MASK  0xf000
254
#define RMDL_ONES_SH    12
255

    
256
#define RMDS_BAM_MASK   0x0010
257
#define RMDS_BAM_SH     4
258
#define RMDS_LFAM_MASK  0x0020
259
#define RMDS_LFAM_SH    5
260
#define RMDS_PAM_MASK   0x0040
261
#define RMDS_PAM_SH     6
262
#define RMDS_BPE_MASK   0x0080
263
#define RMDS_BPE_SH     7
264
#define RMDS_ENP_MASK   0x0100
265
#define RMDS_ENP_SH     8
266
#define RMDS_STP_MASK   0x0200
267
#define RMDS_STP_SH     9
268
#define RMDS_BUFF_MASK  0x0400
269
#define RMDS_BUFF_SH    10
270
#define RMDS_CRC_MASK   0x0800
271
#define RMDS_CRC_SH     11
272
#define RMDS_OFLO_MASK  0x1000
273
#define RMDS_OFLO_SH    12
274
#define RMDS_FRAM_MASK  0x2000
275
#define RMDS_FRAM_SH    13
276
#define RMDS_ERR_MASK   0x4000
277
#define RMDS_ERR_SH     14
278
#define RMDS_OWN_MASK   0x8000
279
#define RMDS_OWN_SH     15
280

    
281
#define RMDM_MCNT_MASK  0x00000fff
282
#define RMDM_MCNT_SH    0
283
#define RMDM_ZEROS_MASK 0x0000f000
284
#define RMDM_ZEROS_SH   12
285
#define RMDM_RPC_MASK   0x00ff0000
286
#define RMDM_RPC_SH     16
287
#define RMDM_RCC_MASK   0xff000000
288
#define RMDM_RCC_SH     24
289

    
290
#define SET_FIELD(regp, name, field, value)             \
291
  (*(regp) = (*(regp) & ~(name ## _ ## field ## _MASK)) \
292
             | ((value) << name ## _ ## field ## _SH))
293

    
294
#define GET_FIELD(reg, name, field)                     \
295
  (((reg) & name ## _ ## field ## _MASK) >> name ## _ ## field ## _SH)
296

    
297
#define PRINT_TMD(T) printf(                            \
298
        "TMD0 : TBADR=0x%08x\n"                         \
299
        "TMD1 : OWN=%d, ERR=%d, FCS=%d, LTI=%d, "       \
300
        "ONE=%d, DEF=%d, STP=%d, ENP=%d,\n"             \
301
        "       BPE=%d, BCNT=%d\n"                      \
302
        "TMD2 : BUF=%d, UFL=%d, EXD=%d, LCO=%d, "       \
303
        "LCA=%d, RTR=%d,\n"                             \
304
        "       TDR=%d, TRC=%d\n",                      \
305
        (T)->tbadr,                                     \
306
        GET_FIELD((T)->status, TMDS, OWN),              \
307
        GET_FIELD((T)->status, TMDS, ERR),              \
308
        GET_FIELD((T)->status, TMDS, NOFCS),            \
309
        GET_FIELD((T)->status, TMDS, LTINT),            \
310
        GET_FIELD((T)->status, TMDS, ONE),              \
311
        GET_FIELD((T)->status, TMDS, DEF),              \
312
        GET_FIELD((T)->status, TMDS, STP),              \
313
        GET_FIELD((T)->status, TMDS, ENP),              \
314
        GET_FIELD((T)->status, TMDS, BPE),              \
315
        4096-GET_FIELD((T)->length, TMDL, BCNT),        \
316
        GET_FIELD((T)->misc, TMDM, BUFF),               \
317
        GET_FIELD((T)->misc, TMDM, UFLO),               \
318
        GET_FIELD((T)->misc, TMDM, EXDEF),              \
319
        GET_FIELD((T)->misc, TMDM, LCOL),               \
320
        GET_FIELD((T)->misc, TMDM, LCAR),               \
321
        GET_FIELD((T)->misc, TMDM, RTRY),               \
322
        GET_FIELD((T)->misc, TMDM, TDR),                \
323
        GET_FIELD((T)->misc, TMDM, TRC))
324

    
325
#define PRINT_RMD(R) printf(                            \
326
        "RMD0 : RBADR=0x%08x\n"                         \
327
        "RMD1 : OWN=%d, ERR=%d, FRAM=%d, OFLO=%d, "     \
328
        "CRC=%d, BUFF=%d, STP=%d, ENP=%d,\n       "     \
329
        "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n" \
330
        "RMD2 : RCC=%d, RPC=%d, MCNT=%d, ZEROS=%d\n",   \
331
        (R)->rbadr,                                     \
332
        GET_FIELD((R)->status, RMDS, OWN),              \
333
        GET_FIELD((R)->status, RMDS, ERR),              \
334
        GET_FIELD((R)->status, RMDS, FRAM),             \
335
        GET_FIELD((R)->status, RMDS, OFLO),             \
336
        GET_FIELD((R)->status, RMDS, CRC),              \
337
        GET_FIELD((R)->status, RMDS, BUFF),             \
338
        GET_FIELD((R)->status, RMDS, STP),              \
339
        GET_FIELD((R)->status, RMDS, ENP),              \
340
        GET_FIELD((R)->status, RMDS, BPE),              \
341
        GET_FIELD((R)->status, RMDS, PAM),              \
342
        GET_FIELD((R)->status, RMDS, LFAM),             \
343
        GET_FIELD((R)->status, RMDS, BAM),              \
344
        GET_FIELD((R)->buf_length, RMDL, ONES),         \
345
        4096-GET_FIELD((R)->buf_length, RMDL, BCNT),    \
346
        GET_FIELD((R)->msg_length, RMDM, RCC),          \
347
        GET_FIELD((R)->msg_length, RMDM, RPC),          \
348
        GET_FIELD((R)->msg_length, RMDM, MCNT),         \
349
        GET_FIELD((R)->msg_length, RMDM, ZEROS))
350

    
351
static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd,
352
                                  target_phys_addr_t addr)
353
{
354
    if (!BCR_SSIZE32(s)) {
355
        struct {
356
            uint32_t tbadr;
357
            int16_t length;
358
            int16_t status;
359
        } xda;
360
        s->phys_mem_read(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
361
        tmd->tbadr = le32_to_cpu(xda.tbadr) & 0xffffff;
362
        tmd->length = le16_to_cpu(xda.length);
363
        tmd->status = (le32_to_cpu(xda.tbadr) >> 16) & 0xff00;
364
        tmd->misc = le16_to_cpu(xda.status) << 16;
365
        tmd->res = 0;
366
    } else {
367
        s->phys_mem_read(s->dma_opaque, addr, (void *)tmd, sizeof(*tmd), 0);
368
        le32_to_cpus(&tmd->tbadr);
369
        le16_to_cpus((uint16_t *)&tmd->length);
370
        le16_to_cpus((uint16_t *)&tmd->status);
371
        le32_to_cpus(&tmd->misc);
372
        le32_to_cpus(&tmd->res);
373
        if (BCR_SWSTYLE(s) == 3) {
374
            uint32_t tmp = tmd->tbadr;
375
            tmd->tbadr = tmd->misc;
376
            tmd->misc = tmp;
377
        }
378
    }
379
}
380

    
381
static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd,
382
                                   target_phys_addr_t addr)
383
{
384
    if (!BCR_SSIZE32(s)) {
385
        struct {
386
            uint32_t tbadr;
387
            int16_t length;
388
            int16_t status;
389
        } xda;
390
        xda.tbadr = cpu_to_le32((tmd->tbadr & 0xffffff) |
391
                                ((tmd->status & 0xff00) << 16));
392
        xda.length = cpu_to_le16(tmd->length);
393
        xda.status = cpu_to_le16(tmd->misc >> 16);
394
        s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
395
    } else {
396
        struct {
397
            uint32_t tbadr;
398
            int16_t length;
399
            int16_t status;
400
            uint32_t misc;
401
            uint32_t res;
402
        } xda;
403
        xda.tbadr = cpu_to_le32(tmd->tbadr);
404
        xda.length = cpu_to_le16(tmd->length);
405
        xda.status = cpu_to_le16(tmd->status);
406
        xda.misc = cpu_to_le32(tmd->misc);
407
        xda.res = cpu_to_le32(tmd->res);
408
        if (BCR_SWSTYLE(s) == 3) {
409
            uint32_t tmp = xda.tbadr;
410
            xda.tbadr = xda.misc;
411
            xda.misc = tmp;
412
        }
413
        s->phys_mem_write(s->dma_opaque, addr, (void *)&xda, sizeof(xda), 0);
414
    }
415
}
416

    
417
static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd,
418
                                  target_phys_addr_t addr)
419
{
420
    if (!BCR_SSIZE32(s)) {
421
        struct {
422
            uint32_t rbadr;
423
            int16_t buf_length;
424
            int16_t msg_length;
425
        } rda;
426
        s->phys_mem_read(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
427
        rmd->rbadr = le32_to_cpu(rda.rbadr) & 0xffffff;
428
        rmd->buf_length = le16_to_cpu(rda.buf_length);
429
        rmd->status = (le32_to_cpu(rda.rbadr) >> 16) & 0xff00;
430
        rmd->msg_length = le16_to_cpu(rda.msg_length);
431
        rmd->res = 0;
432
    } else {
433
        s->phys_mem_read(s->dma_opaque, addr, (void *)rmd, sizeof(*rmd), 0);
434
        le32_to_cpus(&rmd->rbadr);
435
        le16_to_cpus((uint16_t *)&rmd->buf_length);
436
        le16_to_cpus((uint16_t *)&rmd->status);
437
        le32_to_cpus(&rmd->msg_length);
438
        le32_to_cpus(&rmd->res);
439
        if (BCR_SWSTYLE(s) == 3) {
440
            uint32_t tmp = rmd->rbadr;
441
            rmd->rbadr = rmd->msg_length;
442
            rmd->msg_length = tmp;
443
        }
444
    }
445
}
446

    
447
static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
448
                                   target_phys_addr_t addr)
449
{
450
    if (!BCR_SSIZE32(s)) {
451
        struct {
452
            uint32_t rbadr;
453
            int16_t buf_length;
454
            int16_t msg_length;
455
        } rda;
456
        rda.rbadr = cpu_to_le32((rmd->rbadr & 0xffffff) |
457
                                ((rmd->status & 0xff00) << 16));
458
        rda.buf_length = cpu_to_le16(rmd->buf_length);
459
        rda.msg_length = cpu_to_le16(rmd->msg_length);
460
        s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
461
    } else {
462
        struct {
463
            uint32_t rbadr;
464
            int16_t buf_length;
465
            int16_t status;
466
            uint32_t msg_length;
467
            uint32_t res;
468
        } rda;
469
        rda.rbadr = cpu_to_le32(rmd->rbadr);
470
        rda.buf_length = cpu_to_le16(rmd->buf_length);
471
        rda.status = cpu_to_le16(rmd->status);
472
        rda.msg_length = cpu_to_le32(rmd->msg_length);
473
        rda.res = cpu_to_le32(rmd->res);
474
        if (BCR_SWSTYLE(s) == 3) {
475
            uint32_t tmp = rda.rbadr;
476
            rda.rbadr = rda.msg_length;
477
            rda.msg_length = tmp;
478
        }
479
        s->phys_mem_write(s->dma_opaque, addr, (void *)&rda, sizeof(rda), 0);
480
    }
481
}
482

    
483

    
484
#define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
485

    
486
#define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
487

    
488
#define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
489

    
490
#define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
491

    
492
#if 1
493

    
494
#define CHECK_RMD(ADDR,RES) do {                \
495
    struct pcnet_RMD rmd;                       \
496
    RMDLOAD(&rmd,(ADDR));                       \
497
    (RES) |= (GET_FIELD(rmd.buf_length, RMDL, ONES) != 15) \
498
          || (GET_FIELD(rmd.msg_length, RMDM, ZEROS) != 0); \
499
} while (0)
500

    
501
#define CHECK_TMD(ADDR,RES) do {                \
502
    struct pcnet_TMD tmd;                       \
503
    TMDLOAD(&tmd,(ADDR));                       \
504
    (RES) |= (GET_FIELD(tmd.length, TMDL, ONES) != 15); \
505
} while (0)
506

    
507
#else
508

    
509
#define CHECK_RMD(ADDR,RES) do {                \
510
    switch (BCR_SWSTYLE(s)) {                   \
511
    case 0x00:                                  \
512
        do {                                    \
513
            uint16_t rda[4];                    \
514
            s->phys_mem_read(s->dma_opaque, (ADDR), \
515
                (void *)&rda[0], sizeof(rda), 0); \
516
            (RES) |= (rda[2] & 0xf000)!=0xf000; \
517
            (RES) |= (rda[3] & 0xf000)!=0x0000; \
518
        } while (0);                            \
519
        break;                                  \
520
    case 0x01:                                  \
521
    case 0x02:                                  \
522
        do {                                    \
523
            uint32_t rda[4];                    \
524
            s->phys_mem_read(s->dma_opaque, (ADDR), \
525
                (void *)&rda[0], sizeof(rda), 0); \
526
            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
527
            (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
528
        } while (0);                            \
529
        break;                                  \
530
    case 0x03:                                  \
531
        do {                                    \
532
            uint32_t rda[4];                    \
533
            s->phys_mem_read(s->dma_opaque, (ADDR), \
534
                (void *)&rda[0], sizeof(rda), 0); \
535
            (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
536
            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
537
        } while (0);                            \
538
        break;                                  \
539
    }                                           \
540
} while (0)
541

    
542
#define CHECK_TMD(ADDR,RES) do {                \
543
    switch (BCR_SWSTYLE(s)) {                   \
544
    case 0x00:                                  \
545
        do {                                    \
546
            uint16_t xda[4];                    \
547
            s->phys_mem_read(s->dma_opaque, (ADDR), \
548
                (void *)&xda[0], sizeof(xda), 0); \
549
            (RES) |= (xda[2] & 0xf000)!=0xf000; \
550
        } while (0);                            \
551
        break;                                  \
552
    case 0x01:                                  \
553
    case 0x02:                                  \
554
    case 0x03:                                  \
555
        do {                                    \
556
            uint32_t xda[4];                    \
557
            s->phys_mem_read(s->dma_opaque, (ADDR), \
558
                (void *)&xda[0], sizeof(xda), 0); \
559
            (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
560
        } while (0);                            \
561
        break;                                  \
562
    }                                           \
563
} while (0)
564

    
565
#endif
566

    
567
#define PRINT_PKTHDR(BUF) do {                  \
568
    struct qemu_ether_header *hdr = (void *)(BUF); \
569
    printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \
570
           "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \
571
           "type=0x%04x\n",                     \
572
           hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
573
           hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
574
           hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
575
           hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
576
           be16_to_cpu(hdr->ether_type));       \
577
} while (0)
578

    
579
#define MULTICAST_FILTER_LEN 8
580

    
581
static inline uint32_t lnc_mchash(const uint8_t *ether_addr)
582
{
583
#define LNC_POLYNOMIAL          0xEDB88320UL
584
    uint32_t crc = 0xFFFFFFFF;
585
    int idx, bit;
586
    uint8_t data;
587

    
588
    for (idx = 0; idx < 6; idx++) {
589
        for (data = *ether_addr++, bit = 0; bit < MULTICAST_FILTER_LEN; bit++) {
590
            crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LNC_POLYNOMIAL : 0);
591
            data >>= 1;
592
        }
593
    }
594
    return crc;
595
#undef LNC_POLYNOMIAL
596
}
597

    
598
#define CRC(crc, ch)         (crc = (crc >> 8) ^ crctab[(crc ^ (ch)) & 0xff])
599

    
600
/* generated using the AUTODIN II polynomial
601
 *        x^32 + x^26 + x^23 + x^22 + x^16 +
602
 *        x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
603
 */
604
static const uint32_t crctab[256] = {
605
        0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
606
        0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
607
        0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
608
        0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
609
        0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
610
        0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
611
        0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
612
        0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
613
        0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
614
        0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
615
        0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
616
        0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
617
        0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
618
        0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
619
        0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
620
        0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
621
        0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
622
        0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
623
        0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
624
        0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
625
        0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
626
        0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
627
        0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
628
        0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
629
        0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
630
        0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
631
        0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
632
        0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
633
        0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
634
        0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
635
        0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
636
        0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
637
        0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
638
        0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
639
        0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
640
        0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
641
        0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
642
        0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
643
        0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
644
        0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
645
        0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
646
        0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
647
        0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
648
        0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
649
        0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
650
        0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
651
        0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
652
        0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
653
        0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
654
        0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
655
        0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
656
        0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
657
        0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
658
        0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
659
        0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
660
        0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
661
        0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
662
        0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
663
        0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
664
        0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
665
        0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
666
        0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
667
        0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
668
        0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
669
};
670

    
671
static inline int padr_match(PCNetState *s, const uint8_t *buf, int size)
672
{
673
    struct qemu_ether_header *hdr = (void *)buf;
674
    uint8_t padr[6] = {
675
        s->csr[12] & 0xff, s->csr[12] >> 8,
676
        s->csr[13] & 0xff, s->csr[13] >> 8,
677
        s->csr[14] & 0xff, s->csr[14] >> 8
678
    };
679
    int result = (!CSR_DRCVPA(s)) && !memcmp(hdr->ether_dhost, padr, 6);
680
#ifdef PCNET_DEBUG_MATCH
681
    printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "
682
           "padr=%02x:%02x:%02x:%02x:%02x:%02x\n",
683
           hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2],
684
           hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5],
685
           padr[0],padr[1],padr[2],padr[3],padr[4],padr[5]);
686
    printf("padr_match result=%d\n", result);
687
#endif
688
    return result;
689
}
690

    
691
static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size)
692
{
693
    static const uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
694
    struct qemu_ether_header *hdr = (void *)buf;
695
    int result = !CSR_DRCVBC(s) && !memcmp(hdr->ether_dhost, BCAST, 6);
696
#ifdef PCNET_DEBUG_MATCH
697
    printf("padr_bcast result=%d\n", result);
698
#endif
699
    return result;
700
}
701

    
702
static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
703
{
704
    struct qemu_ether_header *hdr = (void *)buf;
705
    if ((*(hdr->ether_dhost)&0x01) &&
706
        ((uint64_t *)&s->csr[8])[0] != 0LL) {
707
        uint8_t ladr[8] = {
708
            s->csr[8] & 0xff, s->csr[8] >> 8,
709
            s->csr[9] & 0xff, s->csr[9] >> 8,
710
            s->csr[10] & 0xff, s->csr[10] >> 8,
711
            s->csr[11] & 0xff, s->csr[11] >> 8
712
        };
713
        int index = lnc_mchash(hdr->ether_dhost) >> 26;
714
        return !!(ladr[index >> 3] & (1 << (index & 7)));
715
    }
716
    return 0;
717
}
718

    
719
static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx)
720
{
721
    while (idx < 1) idx += CSR_RCVRL(s);
722
    return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
723
}
724

    
725
static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
726
{
727
    int64_t next_time = current_time +
728
        muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)),
729
                 get_ticks_per_sec(), 33000000L);
730
    if (next_time <= current_time)
731
        next_time = current_time + 1;
732
    return next_time;
733
}
734

    
735
static void pcnet_poll(PCNetState *s);
736
static void pcnet_poll_timer(void *opaque);
737

    
738
static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
739
static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
740
static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
741
static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
742

    
743
static void pcnet_s_reset(PCNetState *s)
744
{
745
#ifdef PCNET_DEBUG
746
    printf("pcnet_s_reset\n");
747
#endif
748

    
749
    s->lnkst = 0x40;
750
    s->rdra = 0;
751
    s->tdra = 0;
752
    s->rap = 0;
753

    
754
    s->bcr[BCR_BSBC] &= ~0x0080;
755

    
756
    s->csr[0]   = 0x0004;
757
    s->csr[3]   = 0x0000;
758
    s->csr[4]   = 0x0115;
759
    s->csr[5]   = 0x0000;
760
    s->csr[6]   = 0x0000;
761
    s->csr[8]   = 0;
762
    s->csr[9]   = 0;
763
    s->csr[10]  = 0;
764
    s->csr[11]  = 0;
765
    s->csr[12]  = le16_to_cpu(((uint16_t *)&s->prom[0])[0]);
766
    s->csr[13]  = le16_to_cpu(((uint16_t *)&s->prom[0])[1]);
767
    s->csr[14]  = le16_to_cpu(((uint16_t *)&s->prom[0])[2]);
768
    s->csr[15] &= 0x21c4;
769
    s->csr[72]  = 1;
770
    s->csr[74]  = 1;
771
    s->csr[76]  = 1;
772
    s->csr[78]  = 1;
773
    s->csr[80]  = 0x1410;
774
    s->csr[88]  = 0x1003;
775
    s->csr[89]  = 0x0262;
776
    s->csr[94]  = 0x0000;
777
    s->csr[100] = 0x0200;
778
    s->csr[103] = 0x0105;
779
    s->csr[103] = 0x0105;
780
    s->csr[112] = 0x0000;
781
    s->csr[114] = 0x0000;
782
    s->csr[122] = 0x0000;
783
    s->csr[124] = 0x0000;
784

    
785
    s->tx_busy = 0;
786
}
787

    
788
static void pcnet_update_irq(PCNetState *s)
789
{
790
    int isr = 0;
791
    s->csr[0] &= ~0x0080;
792

    
793
#if 1
794
    if (((s->csr[0] & ~s->csr[3]) & 0x5f00) ||
795
        (((s->csr[4]>>1) & ~s->csr[4]) & 0x0115) ||
796
        (((s->csr[5]>>1) & s->csr[5]) & 0x0048))
797
#else
798
    if ((!(s->csr[3] & 0x4000) && !!(s->csr[0] & 0x4000)) /* BABL */ ||
799
        (!(s->csr[3] & 0x1000) && !!(s->csr[0] & 0x1000)) /* MISS */ ||
800
        (!(s->csr[3] & 0x0100) && !!(s->csr[0] & 0x0100)) /* IDON */ ||
801
        (!(s->csr[3] & 0x0200) && !!(s->csr[0] & 0x0200)) /* TINT */ ||
802
        (!(s->csr[3] & 0x0400) && !!(s->csr[0] & 0x0400)) /* RINT */ ||
803
        (!(s->csr[3] & 0x0800) && !!(s->csr[0] & 0x0800)) /* MERR */ ||
804
        (!(s->csr[4] & 0x0001) && !!(s->csr[4] & 0x0002)) /* JAB */ ||
805
        (!(s->csr[4] & 0x0004) && !!(s->csr[4] & 0x0008)) /* TXSTRT */ ||
806
        (!(s->csr[4] & 0x0010) && !!(s->csr[4] & 0x0020)) /* RCVO */ ||
807
        (!(s->csr[4] & 0x0100) && !!(s->csr[4] & 0x0200)) /* MFCO */ ||
808
        (!!(s->csr[5] & 0x0040) && !!(s->csr[5] & 0x0080)) /* EXDINT */ ||
809
        (!!(s->csr[5] & 0x0008) && !!(s->csr[5] & 0x0010)) /* MPINT */)
810
#endif
811
    {
812

    
813
        isr = CSR_INEA(s);
814
        s->csr[0] |= 0x0080;
815
    }
816

    
817
    if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
818
        s->csr[4] &= ~0x0080;
819
        s->csr[4] |= 0x0040;
820
        s->csr[0] |= 0x0080;
821
        isr = 1;
822
#ifdef PCNET_DEBUG
823
        printf("pcnet user int\n");
824
#endif
825
    }
826

    
827
#if 1
828
    if (((s->csr[5]>>1) & s->csr[5]) & 0x0500)
829
#else
830
    if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
831
        (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
832
#endif
833
    {
834
        isr = 1;
835
        s->csr[0] |= 0x0080;
836
    }
837

    
838
    if (isr != s->isr) {
839
#ifdef PCNET_DEBUG
840
        printf("pcnet: INTA=%d\n", isr);
841
#endif
842
    }
843
    qemu_set_irq(s->irq, isr);
844
    s->isr = isr;
845
}
846

    
847
static void pcnet_init(PCNetState *s)
848
{
849
    int rlen, tlen;
850
    uint16_t padr[3], ladrf[4], mode;
851
    uint32_t rdra, tdra;
852

    
853
#ifdef PCNET_DEBUG
854
    printf("pcnet_init init_addr=0x%08x\n", PHYSADDR(s,CSR_IADR(s)));
855
#endif
856

    
857
    if (BCR_SSIZE32(s)) {
858
        struct pcnet_initblk32 initblk;
859
        s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
860
                (uint8_t *)&initblk, sizeof(initblk), 0);
861
        mode = le16_to_cpu(initblk.mode);
862
        rlen = initblk.rlen >> 4;
863
        tlen = initblk.tlen >> 4;
864
        ladrf[0] = le16_to_cpu(initblk.ladrf[0]);
865
        ladrf[1] = le16_to_cpu(initblk.ladrf[1]);
866
        ladrf[2] = le16_to_cpu(initblk.ladrf[2]);
867
        ladrf[3] = le16_to_cpu(initblk.ladrf[3]);
868
        padr[0] = le16_to_cpu(initblk.padr[0]);
869
        padr[1] = le16_to_cpu(initblk.padr[1]);
870
        padr[2] = le16_to_cpu(initblk.padr[2]);
871
        rdra = le32_to_cpu(initblk.rdra);
872
        tdra = le32_to_cpu(initblk.tdra);
873
    } else {
874
        struct pcnet_initblk16 initblk;
875
        s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
876
                (uint8_t *)&initblk, sizeof(initblk), 0);
877
        mode = le16_to_cpu(initblk.mode);
878
        ladrf[0] = le16_to_cpu(initblk.ladrf[0]);
879
        ladrf[1] = le16_to_cpu(initblk.ladrf[1]);
880
        ladrf[2] = le16_to_cpu(initblk.ladrf[2]);
881
        ladrf[3] = le16_to_cpu(initblk.ladrf[3]);
882
        padr[0] = le16_to_cpu(initblk.padr[0]);
883
        padr[1] = le16_to_cpu(initblk.padr[1]);
884
        padr[2] = le16_to_cpu(initblk.padr[2]);
885
        rdra = le32_to_cpu(initblk.rdra);
886
        tdra = le32_to_cpu(initblk.tdra);
887
        rlen = rdra >> 29;
888
        tlen = tdra >> 29;
889
        rdra &= 0x00ffffff;
890
        tdra &= 0x00ffffff;
891
    }
892

    
893
#if defined(PCNET_DEBUG)
894
    printf("rlen=%d tlen=%d\n", rlen, tlen);
895
#endif
896

    
897
    CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512;
898
    CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512;
899
    s->csr[ 6] = (tlen << 12) | (rlen << 8);
900
    s->csr[15] = mode;
901
    s->csr[ 8] = ladrf[0];
902
    s->csr[ 9] = ladrf[1];
903
    s->csr[10] = ladrf[2];
904
    s->csr[11] = ladrf[3];
905
    s->csr[12] = padr[0];
906
    s->csr[13] = padr[1];
907
    s->csr[14] = padr[2];
908
    s->rdra = PHYSADDR(s, rdra);
909
    s->tdra = PHYSADDR(s, tdra);
910

    
911
    CSR_RCVRC(s) = CSR_RCVRL(s);
912
    CSR_XMTRC(s) = CSR_XMTRL(s);
913

    
914
#ifdef PCNET_DEBUG
915
    printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n",
916
        BCR_SSIZE32(s),
917
        s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
918
#endif
919

    
920
    s->csr[0] |= 0x0101;
921
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
922
}
923

    
924
static void pcnet_start(PCNetState *s)
925
{
926
#ifdef PCNET_DEBUG
927
    printf("pcnet_start\n");
928
#endif
929

    
930
    if (!CSR_DTX(s))
931
        s->csr[0] |= 0x0010;    /* set TXON */
932

    
933
    if (!CSR_DRX(s))
934
        s->csr[0] |= 0x0020;    /* set RXON */
935

    
936
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
937
    s->csr[0] |= 0x0002;
938
}
939

    
940
static void pcnet_stop(PCNetState *s)
941
{
942
#ifdef PCNET_DEBUG
943
    printf("pcnet_stop\n");
944
#endif
945
    s->csr[0] &= ~0x7feb;
946
    s->csr[0] |= 0x0014;
947
    s->csr[4] &= ~0x02c2;
948
    s->csr[5] &= ~0x0011;
949
    pcnet_poll_timer(s);
950
}
951

    
952
static void pcnet_rdte_poll(PCNetState *s)
953
{
954
    s->csr[28] = s->csr[29] = 0;
955
    if (s->rdra) {
956
        int bad = 0;
957
#if 1
958
        target_phys_addr_t crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
959
        target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
960
        target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
961
#else
962
        target_phys_addr_t crda = s->rdra +
963
            (CSR_RCVRL(s) - CSR_RCVRC(s)) *
964
            (BCR_SWSTYLE(s) ? 16 : 8 );
965
        int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
966
        target_phys_addr_t nrda = s->rdra +
967
            (CSR_RCVRL(s) - nrdc) *
968
            (BCR_SWSTYLE(s) ? 16 : 8 );
969
        int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
970
        target_phys_addr_t nnrd = s->rdra +
971
            (CSR_RCVRL(s) - nnrc) *
972
            (BCR_SWSTYLE(s) ? 16 : 8 );
973
#endif
974

    
975
        CHECK_RMD(crda, bad);
976
        if (!bad) {
977
            CHECK_RMD(nrda, bad);
978
            if (bad || (nrda == crda)) nrda = 0;
979
            CHECK_RMD(nnrd, bad);
980
            if (bad || (nnrd == crda)) nnrd = 0;
981

    
982
            s->csr[28] = crda & 0xffff;
983
            s->csr[29] = crda >> 16;
984
            s->csr[26] = nrda & 0xffff;
985
            s->csr[27] = nrda >> 16;
986
            s->csr[36] = nnrd & 0xffff;
987
            s->csr[37] = nnrd >> 16;
988
#ifdef PCNET_DEBUG
989
            if (bad) {
990
                printf("pcnet: BAD RMD RECORDS AFTER 0x" TARGET_FMT_plx "\n",
991
                       crda);
992
            }
993
        } else {
994
            printf("pcnet: BAD RMD RDA=0x" TARGET_FMT_plx "\n",
995
                   crda);
996
#endif
997
        }
998
    }
999

    
1000
    if (CSR_CRDA(s)) {
1001
        struct pcnet_RMD rmd;
1002
        RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
1003
        CSR_CRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
1004
        CSR_CRST(s) = rmd.status;
1005
#ifdef PCNET_DEBUG_RMD_X
1006
        printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMDL=0x%04x RMDS=0x%04x RMDM=0x%08x\n",
1007
                PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
1008
                rmd.buf_length, rmd.status, rmd.msg_length);
1009
        PRINT_RMD(&rmd);
1010
#endif
1011
    } else {
1012
        CSR_CRBC(s) = CSR_CRST(s) = 0;
1013
    }
1014

    
1015
    if (CSR_NRDA(s)) {
1016
        struct pcnet_RMD rmd;
1017
        RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
1018
        CSR_NRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
1019
        CSR_NRST(s) = rmd.status;
1020
    } else {
1021
        CSR_NRBC(s) = CSR_NRST(s) = 0;
1022
    }
1023

    
1024
}
1025

    
1026
static int pcnet_tdte_poll(PCNetState *s)
1027
{
1028
    s->csr[34] = s->csr[35] = 0;
1029
    if (s->tdra) {
1030
        target_phys_addr_t cxda = s->tdra +
1031
            (CSR_XMTRL(s) - CSR_XMTRC(s)) *
1032
            (BCR_SWSTYLE(s) ? 16 : 8);
1033
        int bad = 0;
1034
        CHECK_TMD(cxda, bad);
1035
        if (!bad) {
1036
            if (CSR_CXDA(s) != cxda) {
1037
                s->csr[60] = s->csr[34];
1038
                s->csr[61] = s->csr[35];
1039
                s->csr[62] = CSR_CXBC(s);
1040
                s->csr[63] = CSR_CXST(s);
1041
            }
1042
            s->csr[34] = cxda & 0xffff;
1043
            s->csr[35] = cxda >> 16;
1044
#ifdef PCNET_DEBUG_X
1045
            printf("pcnet: BAD TMD XDA=0x%08x\n", cxda);
1046
#endif
1047
        }
1048
    }
1049

    
1050
    if (CSR_CXDA(s)) {
1051
        struct pcnet_TMD tmd;
1052

    
1053
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1054

    
1055
        CSR_CXBC(s) = GET_FIELD(tmd.length, TMDL, BCNT);
1056
        CSR_CXST(s) = tmd.status;
1057
    } else {
1058
        CSR_CXBC(s) = CSR_CXST(s) = 0;
1059
    }
1060

    
1061
    return !!(CSR_CXST(s) & 0x8000);
1062
}
1063

    
1064
static int pcnet_can_receive(VLANClientState *vc)
1065
{
1066
    PCNetState *s = vc->opaque;
1067
    if (CSR_STOP(s) || CSR_SPND(s))
1068
        return 0;
1069

    
1070
    if (s->recv_pos > 0)
1071
        return 0;
1072

    
1073
    return sizeof(s->buffer)-16;
1074
}
1075

    
1076
#define MIN_BUF_SIZE 60
1077

    
1078
static ssize_t pcnet_receive(VLANClientState *vc, const uint8_t *buf, size_t size_)
1079
{
1080
    PCNetState *s = vc->opaque;
1081
    int is_padr = 0, is_bcast = 0, is_ladr = 0;
1082
    uint8_t buf1[60];
1083
    int remaining;
1084
    int crc_err = 0;
1085
    int size = size_;
1086

    
1087
    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
1088
        return -1;
1089

    
1090
#ifdef PCNET_DEBUG
1091
    printf("pcnet_receive size=%d\n", size);
1092
#endif
1093

    
1094
    /* if too small buffer, then expand it */
1095
    if (size < MIN_BUF_SIZE) {
1096
        memcpy(buf1, buf, size);
1097
        memset(buf1 + size, 0, MIN_BUF_SIZE - size);
1098
        buf = buf1;
1099
        size = MIN_BUF_SIZE;
1100
    }
1101

    
1102
    if (CSR_PROM(s)
1103
        || (is_padr=padr_match(s, buf, size))
1104
        || (is_bcast=padr_bcast(s, buf, size))
1105
        || (is_ladr=ladr_match(s, buf, size))) {
1106

    
1107
        pcnet_rdte_poll(s);
1108

    
1109
        if (!(CSR_CRST(s) & 0x8000) && s->rdra) {
1110
            struct pcnet_RMD rmd;
1111
            int rcvrc = CSR_RCVRC(s)-1,i;
1112
            target_phys_addr_t nrda;
1113
            for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {
1114
                if (rcvrc <= 1)
1115
                    rcvrc = CSR_RCVRL(s);
1116
                nrda = s->rdra +
1117
                    (CSR_RCVRL(s) - rcvrc) *
1118
                    (BCR_SWSTYLE(s) ? 16 : 8 );
1119
                RMDLOAD(&rmd, nrda);
1120
                if (GET_FIELD(rmd.status, RMDS, OWN)) {
1121
#ifdef PCNET_DEBUG_RMD
1122
                    printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",
1123
                                rcvrc, CSR_RCVRC(s));
1124
#endif
1125
                    CSR_RCVRC(s) = rcvrc;
1126
                    pcnet_rdte_poll(s);
1127
                    break;
1128
                }
1129
            }
1130
        }
1131

    
1132
        if (!(CSR_CRST(s) & 0x8000)) {
1133
#ifdef PCNET_DEBUG_RMD
1134
            printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));
1135
#endif
1136
            s->csr[0] |= 0x1000; /* Set MISS flag */
1137
            CSR_MISSC(s)++;
1138
        } else {
1139
            uint8_t *src = s->buffer;
1140
            target_phys_addr_t crda = CSR_CRDA(s);
1141
            struct pcnet_RMD rmd;
1142
            int pktcount = 0;
1143

    
1144
            if (!s->looptest) {
1145
                memcpy(src, buf, size);
1146
                /* no need to compute the CRC */
1147
                src[size] = 0;
1148
                src[size + 1] = 0;
1149
                src[size + 2] = 0;
1150
                src[size + 3] = 0;
1151
                size += 4;
1152
            } else if (s->looptest == PCNET_LOOPTEST_CRC ||
1153
                       !CSR_DXMTFCS(s) || size < MIN_BUF_SIZE+4) {
1154
                uint32_t fcs = ~0;
1155
                uint8_t *p = src;
1156

    
1157
                while (p != &src[size])
1158
                    CRC(fcs, *p++);
1159
                *(uint32_t *)p = htonl(fcs);
1160
                size += 4;
1161
            } else {
1162
                uint32_t fcs = ~0;
1163
                uint8_t *p = src;
1164

    
1165
                while (p != &src[size-4])
1166
                    CRC(fcs, *p++);
1167
                crc_err = (*(uint32_t *)p != htonl(fcs));
1168
            }
1169

    
1170
#ifdef PCNET_DEBUG_MATCH
1171
            PRINT_PKTHDR(buf);
1172
#endif
1173

    
1174
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1175
            /*if (!CSR_LAPPEN(s))*/
1176
                SET_FIELD(&rmd.status, RMDS, STP, 1);
1177

    
1178
#define PCNET_RECV_STORE() do {                                 \
1179
    int count = MIN(4096 - GET_FIELD(rmd.buf_length, RMDL, BCNT),remaining); \
1180
    target_phys_addr_t rbadr = PHYSADDR(s, rmd.rbadr);          \
1181
    s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \
1182
    src += count; remaining -= count;                           \
1183
    SET_FIELD(&rmd.status, RMDS, OWN, 0);                       \
1184
    RMDSTORE(&rmd, PHYSADDR(s,crda));                           \
1185
    pktcount++;                                                 \
1186
} while (0)
1187

    
1188
            remaining = size;
1189
            PCNET_RECV_STORE();
1190
            if ((remaining > 0) && CSR_NRDA(s)) {
1191
                target_phys_addr_t nrda = CSR_NRDA(s);
1192
#ifdef PCNET_DEBUG_RMD
1193
                PRINT_RMD(&rmd);
1194
#endif
1195
                RMDLOAD(&rmd, PHYSADDR(s,nrda));
1196
                if (GET_FIELD(rmd.status, RMDS, OWN)) {
1197
                    crda = nrda;
1198
                    PCNET_RECV_STORE();
1199
#ifdef PCNET_DEBUG_RMD
1200
                    PRINT_RMD(&rmd);
1201
#endif
1202
                    if ((remaining > 0) && (nrda=CSR_NNRD(s))) {
1203
                        RMDLOAD(&rmd, PHYSADDR(s,nrda));
1204
                        if (GET_FIELD(rmd.status, RMDS, OWN)) {
1205
                            crda = nrda;
1206
                            PCNET_RECV_STORE();
1207
                        }
1208
                    }
1209
                }
1210
            }
1211

    
1212
#undef PCNET_RECV_STORE
1213

    
1214
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1215
            if (remaining == 0) {
1216
                SET_FIELD(&rmd.msg_length, RMDM, MCNT, size);
1217
                SET_FIELD(&rmd.status, RMDS, ENP, 1);
1218
                SET_FIELD(&rmd.status, RMDS, PAM, !CSR_PROM(s) && is_padr);
1219
                SET_FIELD(&rmd.status, RMDS, LFAM, !CSR_PROM(s) && is_ladr);
1220
                SET_FIELD(&rmd.status, RMDS, BAM, !CSR_PROM(s) && is_bcast);
1221
                if (crc_err) {
1222
                    SET_FIELD(&rmd.status, RMDS, CRC, 1);
1223
                    SET_FIELD(&rmd.status, RMDS, ERR, 1);
1224
                }
1225
            } else {
1226
                SET_FIELD(&rmd.status, RMDS, OFLO, 1);
1227
                SET_FIELD(&rmd.status, RMDS, BUFF, 1);
1228
                SET_FIELD(&rmd.status, RMDS, ERR, 1);
1229
            }
1230
            RMDSTORE(&rmd, PHYSADDR(s,crda));
1231
            s->csr[0] |= 0x0400;
1232

    
1233
#ifdef PCNET_DEBUG
1234
            printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",
1235
                CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
1236
#endif
1237
#ifdef PCNET_DEBUG_RMD
1238
            PRINT_RMD(&rmd);
1239
#endif
1240

    
1241
            while (pktcount--) {
1242
                if (CSR_RCVRC(s) <= 1)
1243
                    CSR_RCVRC(s) = CSR_RCVRL(s);
1244
                else
1245
                    CSR_RCVRC(s)--;
1246
            }
1247

    
1248
            pcnet_rdte_poll(s);
1249

    
1250
        }
1251
    }
1252

    
1253
    pcnet_poll(s);
1254
    pcnet_update_irq(s);
1255

    
1256
    return size_;
1257
}
1258

    
1259
static void pcnet_transmit(PCNetState *s)
1260
{
1261
    target_phys_addr_t xmit_cxda = 0;
1262
    int count = CSR_XMTRL(s)-1;
1263
    int add_crc = 0;
1264

    
1265
    s->xmit_pos = -1;
1266

    
1267
    if (!CSR_TXON(s)) {
1268
        s->csr[0] &= ~0x0008;
1269
        return;
1270
    }
1271

    
1272
    s->tx_busy = 1;
1273

    
1274
    txagain:
1275
    if (pcnet_tdte_poll(s)) {
1276
        struct pcnet_TMD tmd;
1277

    
1278
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1279

    
1280
#ifdef PCNET_DEBUG_TMD
1281
        printf("  TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
1282
        PRINT_TMD(&tmd);
1283
#endif
1284
        if (GET_FIELD(tmd.status, TMDS, STP)) {
1285
            s->xmit_pos = 0;
1286
            xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
1287
            if (BCR_SWSTYLE(s) != 1)
1288
                add_crc = GET_FIELD(tmd.status, TMDS, ADDFCS);
1289
        }
1290
        if (!GET_FIELD(tmd.status, TMDS, ENP)) {
1291
            int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
1292
            s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
1293
                             s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
1294
            s->xmit_pos += bcnt;
1295
        } else if (s->xmit_pos >= 0) {
1296
            int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
1297
            s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
1298
                             s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
1299
            s->xmit_pos += bcnt;
1300
#ifdef PCNET_DEBUG
1301
            printf("pcnet_transmit size=%d\n", s->xmit_pos);
1302
#endif
1303
            if (CSR_LOOP(s)) {
1304
                if (BCR_SWSTYLE(s) == 1)
1305
                    add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
1306
                s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
1307
                pcnet_receive(s->vc, s->buffer, s->xmit_pos);
1308
                s->looptest = 0;
1309
            } else
1310
                if (s->vc)
1311
                    qemu_send_packet(s->vc, s->buffer, s->xmit_pos);
1312

    
1313
            s->csr[0] &= ~0x0008;   /* clear TDMD */
1314
            s->csr[4] |= 0x0004;    /* set TXSTRT */
1315
            s->xmit_pos = -1;
1316
        }
1317

    
1318
        SET_FIELD(&tmd.status, TMDS, OWN, 0);
1319
        TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1320
        if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT)))
1321
            s->csr[0] |= 0x0200;    /* set TINT */
1322

    
1323
        if (CSR_XMTRC(s)<=1)
1324
            CSR_XMTRC(s) = CSR_XMTRL(s);
1325
        else
1326
            CSR_XMTRC(s)--;
1327
        if (count--)
1328
            goto txagain;
1329

    
1330
    } else
1331
    if (s->xmit_pos >= 0) {
1332
        struct pcnet_TMD tmd;
1333
        TMDLOAD(&tmd, xmit_cxda);
1334
        SET_FIELD(&tmd.misc, TMDM, BUFF, 1);
1335
        SET_FIELD(&tmd.misc, TMDM, UFLO, 1);
1336
        SET_FIELD(&tmd.status, TMDS, ERR, 1);
1337
        SET_FIELD(&tmd.status, TMDS, OWN, 0);
1338
        TMDSTORE(&tmd, xmit_cxda);
1339
        s->csr[0] |= 0x0200;    /* set TINT */
1340
        if (!CSR_DXSUFLO(s)) {
1341
            s->csr[0] &= ~0x0010;
1342
        } else
1343
        if (count--)
1344
          goto txagain;
1345
    }
1346

    
1347
    s->tx_busy = 0;
1348
}
1349

    
1350
static void pcnet_poll(PCNetState *s)
1351
{
1352
    if (CSR_RXON(s)) {
1353
        pcnet_rdte_poll(s);
1354
    }
1355

    
1356
    if (CSR_TDMD(s) ||
1357
        (CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s)))
1358
    {
1359
        /* prevent recursion */
1360
        if (s->tx_busy)
1361
            return;
1362

    
1363
        pcnet_transmit(s);
1364
    }
1365
}
1366

    
1367
static void pcnet_poll_timer(void *opaque)
1368
{
1369
    PCNetState *s = opaque;
1370

    
1371
    qemu_del_timer(s->poll_timer);
1372

    
1373
    if (CSR_TDMD(s)) {
1374
        pcnet_transmit(s);
1375
    }
1376

    
1377
    pcnet_update_irq(s);
1378

    
1379
    if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
1380
        uint64_t now = qemu_get_clock(vm_clock) * 33;
1381
        if (!s->timer || !now)
1382
            s->timer = now;
1383
        else {
1384
            uint64_t t = now - s->timer + CSR_POLL(s);
1385
            if (t > 0xffffLL) {
1386
                pcnet_poll(s);
1387
                CSR_POLL(s) = CSR_PINT(s);
1388
            } else
1389
                CSR_POLL(s) = t;
1390
        }
1391
        qemu_mod_timer(s->poll_timer,
1392
            pcnet_get_next_poll_time(s,qemu_get_clock(vm_clock)));
1393
    }
1394
}
1395

    
1396

    
1397
static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value)
1398
{
1399
    uint16_t val = new_value;
1400
#ifdef PCNET_DEBUG_CSR
1401
    printf("pcnet_csr_writew rap=%d val=0x%04x\n", rap, val);
1402
#endif
1403
    switch (rap) {
1404
    case 0:
1405
        s->csr[0] &= ~(val & 0x7f00); /* Clear any interrupt flags */
1406

    
1407
        s->csr[0] = (s->csr[0] & ~0x0040) | (val & 0x0048);
1408

    
1409
        val = (val & 0x007f) | (s->csr[0] & 0x7f00);
1410

    
1411
        /* IFF STOP, STRT and INIT are set, clear STRT and INIT */
1412
        if ((val&7) == 7)
1413
          val &= ~3;
1414

    
1415
        if (!CSR_STOP(s) && (val & 4))
1416
            pcnet_stop(s);
1417

    
1418
        if (!CSR_INIT(s) && (val & 1))
1419
            pcnet_init(s);
1420

    
1421
        if (!CSR_STRT(s) && (val & 2))
1422
            pcnet_start(s);
1423

    
1424
        if (CSR_TDMD(s))
1425
            pcnet_transmit(s);
1426

    
1427
        return;
1428
    case 1:
1429
    case 2:
1430
    case 8:
1431
    case 9:
1432
    case 10:
1433
    case 11:
1434
    case 12:
1435
    case 13:
1436
    case 14:
1437
    case 15:
1438
    case 18: /* CRBAL */
1439
    case 19: /* CRBAU */
1440
    case 20: /* CXBAL */
1441
    case 21: /* CXBAU */
1442
    case 22: /* NRBAU */
1443
    case 23: /* NRBAU */
1444
    case 24:
1445
    case 25:
1446
    case 26:
1447
    case 27:
1448
    case 28:
1449
    case 29:
1450
    case 30:
1451
    case 31:
1452
    case 32:
1453
    case 33:
1454
    case 34:
1455
    case 35:
1456
    case 36:
1457
    case 37:
1458
    case 38:
1459
    case 39:
1460
    case 40: /* CRBC */
1461
    case 41:
1462
    case 42: /* CXBC */
1463
    case 43:
1464
    case 44:
1465
    case 45:
1466
    case 46: /* POLL */
1467
    case 47: /* POLLINT */
1468
    case 72:
1469
    case 74:
1470
    case 76: /* RCVRL */
1471
    case 78: /* XMTRL */
1472
    case 112:
1473
       if (CSR_STOP(s) || CSR_SPND(s))
1474
           break;
1475
       return;
1476
    case 3:
1477
        break;
1478
    case 4:
1479
        s->csr[4] &= ~(val & 0x026a);
1480
        val &= ~0x026a; val |= s->csr[4] & 0x026a;
1481
        break;
1482
    case 5:
1483
        s->csr[5] &= ~(val & 0x0a90);
1484
        val &= ~0x0a90; val |= s->csr[5] & 0x0a90;
1485
        break;
1486
    case 16:
1487
        pcnet_csr_writew(s,1,val);
1488
        return;
1489
    case 17:
1490
        pcnet_csr_writew(s,2,val);
1491
        return;
1492
    case 58:
1493
        pcnet_bcr_writew(s,BCR_SWS,val);
1494
        break;
1495
    default:
1496
        return;
1497
    }
1498
    s->csr[rap] = val;
1499
}
1500

    
1501
static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap)
1502
{
1503
    uint32_t val;
1504
    switch (rap) {
1505
    case 0:
1506
        pcnet_update_irq(s);
1507
        val = s->csr[0];
1508
        val |= (val & 0x7800) ? 0x8000 : 0;
1509
        break;
1510
    case 16:
1511
        return pcnet_csr_readw(s,1);
1512
    case 17:
1513
        return pcnet_csr_readw(s,2);
1514
    case 58:
1515
        return pcnet_bcr_readw(s,BCR_SWS);
1516
    case 88:
1517
        val = s->csr[89];
1518
        val <<= 16;
1519
        val |= s->csr[88];
1520
        break;
1521
    default:
1522
        val = s->csr[rap];
1523
    }
1524
#ifdef PCNET_DEBUG_CSR
1525
    printf("pcnet_csr_readw rap=%d val=0x%04x\n", rap, val);
1526
#endif
1527
    return val;
1528
}
1529

    
1530
static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val)
1531
{
1532
    rap &= 127;
1533
#ifdef PCNET_DEBUG_BCR
1534
    printf("pcnet_bcr_writew rap=%d val=0x%04x\n", rap, val);
1535
#endif
1536
    switch (rap) {
1537
    case BCR_SWS:
1538
        if (!(CSR_STOP(s) || CSR_SPND(s)))
1539
            return;
1540
        val &= ~0x0300;
1541
        switch (val & 0x00ff) {
1542
        case 0:
1543
            val |= 0x0200;
1544
            break;
1545
        case 1:
1546
            val |= 0x0100;
1547
            break;
1548
        case 2:
1549
        case 3:
1550
            val |= 0x0300;
1551
            break;
1552
        default:
1553
            printf("Bad SWSTYLE=0x%02x\n", val & 0xff);
1554
            val = 0x0200;
1555
            break;
1556
        }
1557
#ifdef PCNET_DEBUG
1558
       printf("BCR_SWS=0x%04x\n", val);
1559
#endif
1560
    case BCR_LNKST:
1561
    case BCR_LED1:
1562
    case BCR_LED2:
1563
    case BCR_LED3:
1564
    case BCR_MC:
1565
    case BCR_FDC:
1566
    case BCR_BSBC:
1567
    case BCR_EECAS:
1568
    case BCR_PLAT:
1569
        s->bcr[rap] = val;
1570
        break;
1571
    default:
1572
        break;
1573
    }
1574
}
1575

    
1576
static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap)
1577
{
1578
    uint32_t val;
1579
    rap &= 127;
1580
    switch (rap) {
1581
    case BCR_LNKST:
1582
    case BCR_LED1:
1583
    case BCR_LED2:
1584
    case BCR_LED3:
1585
        val = s->bcr[rap] & ~0x8000;
1586
        val |= (val & 0x017f & s->lnkst) ? 0x8000 : 0;
1587
        break;
1588
    default:
1589
        val = rap < 32 ? s->bcr[rap] : 0;
1590
        break;
1591
    }
1592
#ifdef PCNET_DEBUG_BCR
1593
    printf("pcnet_bcr_readw rap=%d val=0x%04x\n", rap, val);
1594
#endif
1595
    return val;
1596
}
1597

    
1598
static void pcnet_h_reset(void *opaque)
1599
{
1600
    PCNetState *s = opaque;
1601
    int i;
1602
    uint16_t checksum;
1603

    
1604
    /* Initialize the PROM */
1605

    
1606
    memcpy(s->prom, s->macaddr, 6);
1607
    s->prom[12] = s->prom[13] = 0x00;
1608
    s->prom[14] = s->prom[15] = 0x57;
1609

    
1610
    for (i = 0,checksum = 0; i < 16; i++)
1611
        checksum += s->prom[i];
1612
    *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);
1613

    
1614

    
1615
    s->bcr[BCR_MSRDA] = 0x0005;
1616
    s->bcr[BCR_MSWRA] = 0x0005;
1617
    s->bcr[BCR_MC   ] = 0x0002;
1618
    s->bcr[BCR_LNKST] = 0x00c0;
1619
    s->bcr[BCR_LED1 ] = 0x0084;
1620
    s->bcr[BCR_LED2 ] = 0x0088;
1621
    s->bcr[BCR_LED3 ] = 0x0090;
1622
    s->bcr[BCR_FDC  ] = 0x0000;
1623
    s->bcr[BCR_BSBC ] = 0x9001;
1624
    s->bcr[BCR_EECAS] = 0x0002;
1625
    s->bcr[BCR_SWS  ] = 0x0200;
1626
    s->bcr[BCR_PLAT ] = 0xff06;
1627

    
1628
    pcnet_s_reset(s);
1629
}
1630

    
1631
static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
1632
{
1633
    PCNetState *s = opaque;
1634
#ifdef PCNET_DEBUG
1635
    printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);
1636
#endif
1637
    /* Check APROMWE bit to enable write access */
1638
    if (pcnet_bcr_readw(s,2) & 0x80)
1639
        s->prom[addr & 15] = val;
1640
}
1641

    
1642
static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
1643
{
1644
    PCNetState *s = opaque;
1645
    uint32_t val = s->prom[addr &= 15];
1646
#ifdef PCNET_DEBUG
1647
    printf("pcnet_aprom_readb addr=0x%08x val=0x%02x\n", addr, val);
1648
#endif
1649
    return val;
1650
}
1651

    
1652
static void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
1653
{
1654
    PCNetState *s = opaque;
1655
    pcnet_poll_timer(s);
1656
#ifdef PCNET_DEBUG_IO
1657
    printf("pcnet_ioport_writew addr=0x%08x val=0x%04x\n", addr, val);
1658
#endif
1659
    if (!BCR_DWIO(s)) {
1660
        switch (addr & 0x0f) {
1661
        case 0x00: /* RDP */
1662
            pcnet_csr_writew(s, s->rap, val);
1663
            break;
1664
        case 0x02:
1665
            s->rap = val & 0x7f;
1666
            break;
1667
        case 0x06:
1668
            pcnet_bcr_writew(s, s->rap, val);
1669
            break;
1670
        }
1671
    }
1672
    pcnet_update_irq(s);
1673
}
1674

    
1675
static uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr)
1676
{
1677
    PCNetState *s = opaque;
1678
    uint32_t val = -1;
1679
    pcnet_poll_timer(s);
1680
    if (!BCR_DWIO(s)) {
1681
        switch (addr & 0x0f) {
1682
        case 0x00: /* RDP */
1683
            val = pcnet_csr_readw(s, s->rap);
1684
            break;
1685
        case 0x02:
1686
            val = s->rap;
1687
            break;
1688
        case 0x04:
1689
            pcnet_s_reset(s);
1690
            val = 0;
1691
            break;
1692
        case 0x06:
1693
            val = pcnet_bcr_readw(s, s->rap);
1694
            break;
1695
        }
1696
    }
1697
    pcnet_update_irq(s);
1698
#ifdef PCNET_DEBUG_IO
1699
    printf("pcnet_ioport_readw addr=0x%08x val=0x%04x\n", addr, val & 0xffff);
1700
#endif
1701
    return val;
1702
}
1703

    
1704
static void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
1705
{
1706
    PCNetState *s = opaque;
1707
    pcnet_poll_timer(s);
1708
#ifdef PCNET_DEBUG_IO
1709
    printf("pcnet_ioport_writel addr=0x%08x val=0x%08x\n", addr, val);
1710
#endif
1711
    if (BCR_DWIO(s)) {
1712
        switch (addr & 0x0f) {
1713
        case 0x00: /* RDP */
1714
            pcnet_csr_writew(s, s->rap, val & 0xffff);
1715
            break;
1716
        case 0x04:
1717
            s->rap = val & 0x7f;
1718
            break;
1719
        case 0x0c:
1720
            pcnet_bcr_writew(s, s->rap, val & 0xffff);
1721
            break;
1722
        }
1723
    } else
1724
    if ((addr & 0x0f) == 0) {
1725
        /* switch device to dword i/o mode */
1726
        pcnet_bcr_writew(s, BCR_BSBC, pcnet_bcr_readw(s, BCR_BSBC) | 0x0080);
1727
#ifdef PCNET_DEBUG_IO
1728
        printf("device switched into dword i/o mode\n");
1729
#endif
1730
    }
1731
    pcnet_update_irq(s);
1732
}
1733

    
1734
static uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr)
1735
{
1736
    PCNetState *s = opaque;
1737
    uint32_t val = -1;
1738
    pcnet_poll_timer(s);
1739
    if (BCR_DWIO(s)) {
1740
        switch (addr & 0x0f) {
1741
        case 0x00: /* RDP */
1742
            val = pcnet_csr_readw(s, s->rap);
1743
            break;
1744
        case 0x04:
1745
            val = s->rap;
1746
            break;
1747
        case 0x08:
1748
            pcnet_s_reset(s);
1749
            val = 0;
1750
            break;
1751
        case 0x0c:
1752
            val = pcnet_bcr_readw(s, s->rap);
1753
            break;
1754
        }
1755
    }
1756
    pcnet_update_irq(s);
1757
#ifdef PCNET_DEBUG_IO
1758
    printf("pcnet_ioport_readl addr=0x%08x val=0x%08x\n", addr, val);
1759
#endif
1760
    return val;
1761
}
1762

    
1763
static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
1764
                             uint32_t addr, uint32_t size, int type)
1765
{
1766
    PCNetState *d = &DO_UPCAST(PCIPCNetState, pci_dev, pci_dev)->state;
1767

    
1768
#ifdef PCNET_DEBUG_IO
1769
    printf("pcnet_ioport_map addr=0x%04x size=0x%04x\n", addr, size);
1770
#endif
1771

    
1772
    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
1773
    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
1774

    
1775
    register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
1776
    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
1777
    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
1778
    register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
1779
}
1780

    
1781
static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
1782
{
1783
    PCNetState *d = opaque;
1784
#ifdef PCNET_DEBUG_IO
1785
    printf("pcnet_mmio_writeb addr=0x" TARGET_FMT_plx" val=0x%02x\n", addr,
1786
           val);
1787
#endif
1788
    if (!(addr & 0x10))
1789
        pcnet_aprom_writeb(d, addr & 0x0f, val);
1790
}
1791

    
1792
static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr)
1793
{
1794
    PCNetState *d = opaque;
1795
    uint32_t val = -1;
1796
    if (!(addr & 0x10))
1797
        val = pcnet_aprom_readb(d, addr & 0x0f);
1798
#ifdef PCNET_DEBUG_IO
1799
    printf("pcnet_mmio_readb addr=0x" TARGET_FMT_plx " val=0x%02x\n", addr,
1800
           val & 0xff);
1801
#endif
1802
    return val;
1803
}
1804

    
1805
static void pcnet_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
1806
{
1807
    PCNetState *d = opaque;
1808
#ifdef PCNET_DEBUG_IO
1809
    printf("pcnet_mmio_writew addr=0x" TARGET_FMT_plx " val=0x%04x\n", addr,
1810
           val);
1811
#endif
1812
    if (addr & 0x10)
1813
        pcnet_ioport_writew(d, addr & 0x0f, val);
1814
    else {
1815
        addr &= 0x0f;
1816
        pcnet_aprom_writeb(d, addr, val & 0xff);
1817
        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
1818
    }
1819
}
1820

    
1821
static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr)
1822
{
1823
    PCNetState *d = opaque;
1824
    uint32_t val = -1;
1825
    if (addr & 0x10)
1826
        val = pcnet_ioport_readw(d, addr & 0x0f);
1827
    else {
1828
        addr &= 0x0f;
1829
        val = pcnet_aprom_readb(d, addr+1);
1830
        val <<= 8;
1831
        val |= pcnet_aprom_readb(d, addr);
1832
    }
1833
#ifdef PCNET_DEBUG_IO
1834
    printf("pcnet_mmio_readw addr=0x" TARGET_FMT_plx" val = 0x%04x\n", addr,
1835
           val & 0xffff);
1836
#endif
1837
    return val;
1838
}
1839

    
1840
static void pcnet_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
1841
{
1842
    PCNetState *d = opaque;
1843
#ifdef PCNET_DEBUG_IO
1844
    printf("pcnet_mmio_writel addr=0x" TARGET_FMT_plx" val=0x%08x\n", addr,
1845
           val);
1846
#endif
1847
    if (addr & 0x10)
1848
        pcnet_ioport_writel(d, addr & 0x0f, val);
1849
    else {
1850
        addr &= 0x0f;
1851
        pcnet_aprom_writeb(d, addr, val & 0xff);
1852
        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
1853
        pcnet_aprom_writeb(d, addr+2, (val & 0xff0000) >> 16);
1854
        pcnet_aprom_writeb(d, addr+3, (val & 0xff000000) >> 24);
1855
    }
1856
}
1857

    
1858
static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr)
1859
{
1860
    PCNetState *d = opaque;
1861
    uint32_t val;
1862
    if (addr & 0x10)
1863
        val = pcnet_ioport_readl(d, addr & 0x0f);
1864
    else {
1865
        addr &= 0x0f;
1866
        val = pcnet_aprom_readb(d, addr+3);
1867
        val <<= 8;
1868
        val |= pcnet_aprom_readb(d, addr+2);
1869
        val <<= 8;
1870
        val |= pcnet_aprom_readb(d, addr+1);
1871
        val <<= 8;
1872
        val |= pcnet_aprom_readb(d, addr);
1873
    }
1874
#ifdef PCNET_DEBUG_IO
1875
    printf("pcnet_mmio_readl addr=0x" TARGET_FMT_plx " val=0x%08x\n", addr,
1876
           val);
1877
#endif
1878
    return val;
1879
}
1880

    
1881

    
1882
static void pcnet_save(QEMUFile *f, void *opaque)
1883
{
1884
    PCNetState *s = opaque;
1885
    unsigned int i;
1886

    
1887
    qemu_put_sbe32(f, s->rap);
1888
    qemu_put_sbe32(f, s->isr);
1889
    qemu_put_sbe32(f, s->lnkst);
1890
    qemu_put_be32s(f, &s->rdra);
1891
    qemu_put_be32s(f, &s->tdra);
1892
    qemu_put_buffer(f, s->prom, 16);
1893
    for (i = 0; i < 128; i++)
1894
        qemu_put_be16s(f, &s->csr[i]);
1895
    for (i = 0; i < 32; i++)
1896
        qemu_put_be16s(f, &s->bcr[i]);
1897
    qemu_put_be64s(f, &s->timer);
1898
    qemu_put_sbe32(f, s->xmit_pos);
1899
    qemu_put_sbe32(f, s->recv_pos);
1900
    qemu_put_buffer(f, s->buffer, 4096);
1901
    qemu_put_sbe32(f, s->tx_busy);
1902
    qemu_put_timer(f, s->poll_timer);
1903
}
1904

    
1905
static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
1906
{
1907
    PCNetState *s = opaque;
1908
    int i;
1909

    
1910
    if (version_id != 2)
1911
        return -EINVAL;
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 pci_pcnet_save(QEMUFile *f, void *opaque)
1934
{
1935
    PCIPCNetState *s = opaque;
1936

    
1937
    pci_device_save(&s->pci_dev, f);
1938
    pcnet_save(f, &s->state);
1939
}
1940

    
1941
static int pci_pcnet_load(QEMUFile *f, void *opaque, int version_id)
1942
{
1943
    PCIPCNetState *s = opaque;
1944
    int ret;
1945

    
1946
    if (version_id != 2)
1947
        return -EINVAL;
1948

    
1949
    ret = pci_device_load(&s->pci_dev, f);
1950
    if (ret < 0)
1951
        return ret;
1952

    
1953
    return pcnet_load(f, &s->state, version_id);
1954
}
1955

    
1956
static void pcnet_common_cleanup(PCNetState *d)
1957
{
1958
    unregister_savevm("pcnet", d);
1959

    
1960
    qemu_del_timer(d->poll_timer);
1961
    qemu_free_timer(d->poll_timer);
1962
}
1963

    
1964
static int pcnet_common_init(DeviceState *dev, PCNetState *s,
1965
                              NetCleanup *cleanup)
1966
{
1967
    s->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, s);
1968

    
1969
    qdev_get_macaddr(dev, s->macaddr);
1970
    s->vc = qdev_get_vlan_client(dev,
1971
                                 pcnet_can_receive, pcnet_receive, NULL,
1972
                                 cleanup, s);
1973
    pcnet_h_reset(s);
1974
    return 0;
1975
}
1976

    
1977
/* PCI interface */
1978

    
1979
static CPUWriteMemoryFunc * const pcnet_mmio_write[] = {
1980
    &pcnet_mmio_writeb,
1981
    &pcnet_mmio_writew,
1982
    &pcnet_mmio_writel
1983
};
1984

    
1985
static CPUReadMemoryFunc * const pcnet_mmio_read[] = {
1986
    &pcnet_mmio_readb,
1987
    &pcnet_mmio_readw,
1988
    &pcnet_mmio_readl
1989
};
1990

    
1991
static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
1992
                            uint32_t addr, uint32_t size, int type)
1993
{
1994
    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev);
1995

    
1996
#ifdef PCNET_DEBUG_IO
1997
    printf("pcnet_mmio_map addr=0x%08x 0x%08x\n", addr, size);
1998
#endif
1999

    
2000
    cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->state.mmio_index);
2001
}
2002

    
2003
static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
2004
                                      uint8_t *buf, int len, int do_bswap)
2005
{
2006
    cpu_physical_memory_write(addr, buf, len);
2007
}
2008

    
2009
static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
2010
                                     uint8_t *buf, int len, int do_bswap)
2011
{
2012
    cpu_physical_memory_read(addr, buf, len);
2013
}
2014

    
2015
static void pci_pcnet_cleanup(VLANClientState *vc)
2016
{
2017
    PCNetState *d = vc->opaque;
2018

    
2019
    pcnet_common_cleanup(d);
2020
}
2021

    
2022
static int pci_pcnet_uninit(PCIDevice *dev)
2023
{
2024
    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev);
2025

    
2026
    cpu_unregister_io_memory(d->state.mmio_index);
2027

    
2028
    return 0;
2029
}
2030

    
2031
static int pci_pcnet_init(PCIDevice *pci_dev)
2032
{
2033
    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev);
2034
    PCNetState *s = &d->state;
2035
    uint8_t *pci_conf;
2036

    
2037
#if 0
2038
    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
2039
        sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
2040
#endif
2041

    
2042
    pci_dev->unregister = pci_pcnet_uninit;
2043

    
2044
    pci_conf = pci_dev->config;
2045

    
2046
    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_AMD);
2047
    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_AMD_LANCE);
2048
    *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007);
2049
    *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
2050
    pci_conf[0x08] = 0x10;
2051
    pci_conf[0x09] = 0x00;
2052
    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
2053
    pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
2054

    
2055
    *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
2056
    *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
2057

    
2058
    pci_conf[0x3d] = 1; // interrupt pin 0
2059
    pci_conf[0x3e] = 0x06;
2060
    pci_conf[0x3f] = 0xff;
2061

    
2062
    /* Handler for memory-mapped I/O */
2063
    s->mmio_index =
2064
      cpu_register_io_memory(pcnet_mmio_read, pcnet_mmio_write, &d->state);
2065

    
2066
    pci_register_bar((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
2067
                           PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
2068

    
2069
    pci_register_bar((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,
2070
                           PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
2071

    
2072
    s->irq = pci_dev->irq[0];
2073
    s->phys_mem_read = pci_physical_memory_read;
2074
    s->phys_mem_write = pci_physical_memory_write;
2075

    
2076
    register_savevm("pcnet", -1, 2, pci_pcnet_save, pci_pcnet_load, d);
2077
    return pcnet_common_init(&pci_dev->qdev, s, pci_pcnet_cleanup);
2078
}
2079

    
2080
/* SPARC32 interface */
2081

    
2082
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
2083
#include "sun4m.h"
2084

    
2085
static void parent_lance_reset(void *opaque, int irq, int level)
2086
{
2087
    SysBusPCNetState *d = opaque;
2088
    if (level)
2089
        pcnet_h_reset(&d->state);
2090
}
2091

    
2092
static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
2093
                             uint32_t val)
2094
{
2095
    SysBusPCNetState *d = opaque;
2096
#ifdef PCNET_DEBUG_IO
2097
    printf("lance_mem_writew addr=" TARGET_FMT_plx " val=0x%04x\n", addr,
2098
           val & 0xffff);
2099
#endif
2100
    pcnet_ioport_writew(&d->state, addr, val & 0xffff);
2101
}
2102

    
2103
static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
2104
{
2105
    SysBusPCNetState *d = opaque;
2106
    uint32_t val;
2107

    
2108
    val = pcnet_ioport_readw(&d->state, addr);
2109
#ifdef PCNET_DEBUG_IO
2110
    printf("lance_mem_readw addr=" TARGET_FMT_plx " val = 0x%04x\n", addr,
2111
           val & 0xffff);
2112
#endif
2113

    
2114
    return val & 0xffff;
2115
}
2116

    
2117
static CPUReadMemoryFunc * const lance_mem_read[3] = {
2118
    NULL,
2119
    lance_mem_readw,
2120
    NULL,
2121
};
2122

    
2123
static CPUWriteMemoryFunc * const lance_mem_write[3] = {
2124
    NULL,
2125
    lance_mem_writew,
2126
    NULL,
2127
};
2128

    
2129
static void lance_cleanup(VLANClientState *vc)
2130
{
2131
    PCNetState *d = vc->opaque;
2132

    
2133
    pcnet_common_cleanup(d);
2134
}
2135

    
2136
static int lance_init(SysBusDevice *dev)
2137
{
2138
    SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev);
2139
    PCNetState *s = &d->state;
2140

    
2141
    s->mmio_index =
2142
        cpu_register_io_memory(lance_mem_read, lance_mem_write, d);
2143

    
2144
    qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1);
2145

    
2146
    sysbus_init_mmio(dev, 4, s->mmio_index);
2147

    
2148
    sysbus_init_irq(dev, &s->irq);
2149

    
2150
    s->phys_mem_read = ledma_memory_read;
2151
    s->phys_mem_write = ledma_memory_write;
2152

    
2153
    register_savevm("pcnet", -1, 2, pcnet_save, pcnet_load, s);
2154
    return pcnet_common_init(&dev->qdev, s, lance_cleanup);
2155
}
2156

    
2157
static SysBusDeviceInfo lance_info = {
2158
    .init = lance_init,
2159
    .qdev.name  = "lance",
2160
    .qdev.size  = sizeof(SysBusPCNetState),
2161
    .qdev.props = (Property[]) {
2162
        DEFINE_PROP_PTR("dma", SysBusPCNetState, state.dma_opaque),
2163
        DEFINE_PROP_END_OF_LIST(),
2164
    }
2165
};
2166

    
2167
#endif /* TARGET_SPARC */
2168

    
2169
static PCIDeviceInfo pcnet_info = {
2170
    .qdev.name = "pcnet",
2171
    .qdev.size = sizeof(PCIPCNetState),
2172
    .init      = pci_pcnet_init,
2173
};
2174

    
2175
static void pcnet_register_devices(void)
2176
{
2177
    pci_qdev_register(&pcnet_info);
2178
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64)
2179
    sysbus_register_withprop(&lance_info);
2180
#endif
2181
}
2182

    
2183
device_init(pcnet_register_devices)