Statistics
| Branch: | Revision:

root / hw / pcnet.c @ efb56cf7

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;
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
    return sizeof(s->buffer)-16;
1071
}
1072

    
1073
#define MIN_BUF_SIZE 60
1074

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

    
1084
    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
1085
        return -1;
1086

    
1087
#ifdef PCNET_DEBUG
1088
    printf("pcnet_receive size=%d\n", size);
1089
#endif
1090

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

    
1099
    if (CSR_PROM(s)
1100
        || (is_padr=padr_match(s, buf, size))
1101
        || (is_bcast=padr_bcast(s, buf, size))
1102
        || (is_ladr=ladr_match(s, buf, size))) {
1103

    
1104
        pcnet_rdte_poll(s);
1105

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

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

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

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

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

    
1167
#ifdef PCNET_DEBUG_MATCH
1168
            PRINT_PKTHDR(buf);
1169
#endif
1170

    
1171
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1172
            /*if (!CSR_LAPPEN(s))*/
1173
                SET_FIELD(&rmd.status, RMDS, STP, 1);
1174

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

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

    
1209
#undef PCNET_RECV_STORE
1210

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

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

    
1238
            while (pktcount--) {
1239
                if (CSR_RCVRC(s) <= 1)
1240
                    CSR_RCVRC(s) = CSR_RCVRL(s);
1241
                else
1242
                    CSR_RCVRC(s)--;
1243
            }
1244

    
1245
            pcnet_rdte_poll(s);
1246

    
1247
        }
1248
    }
1249

    
1250
    pcnet_poll(s);
1251
    pcnet_update_irq(s);
1252

    
1253
    return size_;
1254
}
1255

    
1256
static void pcnet_transmit(PCNetState *s)
1257
{
1258
    target_phys_addr_t xmit_cxda = 0;
1259
    int count = CSR_XMTRL(s)-1;
1260
    int add_crc = 0;
1261

    
1262
    s->xmit_pos = -1;
1263

    
1264
    if (!CSR_TXON(s)) {
1265
        s->csr[0] &= ~0x0008;
1266
        return;
1267
    }
1268

    
1269
    s->tx_busy = 1;
1270

    
1271
    txagain:
1272
    if (pcnet_tdte_poll(s)) {
1273
        struct pcnet_TMD tmd;
1274

    
1275
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1276

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

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

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

    
1320
        if (CSR_XMTRC(s)<=1)
1321
            CSR_XMTRC(s) = CSR_XMTRL(s);
1322
        else
1323
            CSR_XMTRC(s)--;
1324
        if (count--)
1325
            goto txagain;
1326

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

    
1344
    s->tx_busy = 0;
1345
}
1346

    
1347
static void pcnet_poll(PCNetState *s)
1348
{
1349
    if (CSR_RXON(s)) {
1350
        pcnet_rdte_poll(s);
1351
    }
1352

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

    
1360
        pcnet_transmit(s);
1361
    }
1362
}
1363

    
1364
static void pcnet_poll_timer(void *opaque)
1365
{
1366
    PCNetState *s = opaque;
1367

    
1368
    qemu_del_timer(s->poll_timer);
1369

    
1370
    if (CSR_TDMD(s)) {
1371
        pcnet_transmit(s);
1372
    }
1373

    
1374
    pcnet_update_irq(s);
1375

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

    
1393

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

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

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

    
1408
        /* IFF STOP, STRT and INIT are set, clear STRT and INIT */
1409
        if ((val&7) == 7)
1410
          val &= ~3;
1411

    
1412
        if (!CSR_STOP(s) && (val & 4))
1413
            pcnet_stop(s);
1414

    
1415
        if (!CSR_INIT(s) && (val & 1))
1416
            pcnet_init(s);
1417

    
1418
        if (!CSR_STRT(s) && (val & 2))
1419
            pcnet_start(s);
1420

    
1421
        if (CSR_TDMD(s))
1422
            pcnet_transmit(s);
1423

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

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

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

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

    
1595
static void pcnet_h_reset(void *opaque)
1596
{
1597
    PCNetState *s = opaque;
1598
    int i;
1599
    uint16_t checksum;
1600

    
1601
    /* Initialize the PROM */
1602

    
1603
    memcpy(s->prom, s->macaddr, 6);
1604
    s->prom[12] = s->prom[13] = 0x00;
1605
    s->prom[14] = s->prom[15] = 0x57;
1606

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

    
1611

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

    
1625
    pcnet_s_reset(s);
1626
}
1627

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

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

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

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

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

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

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

    
1765
#ifdef PCNET_DEBUG_IO
1766
    printf("pcnet_ioport_map addr=0x%04x size=0x%04x\n", addr, size);
1767
#endif
1768

    
1769
    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
1770
    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
1771

    
1772
    register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
1773
    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
1774
    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
1775
    register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
1776
}
1777

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

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

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

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

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

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

    
1878

    
1879
static void pcnet_save(QEMUFile *f, void *opaque)
1880
{
1881
    PCNetState *s = opaque;
1882
    unsigned int i;
1883

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

    
1901
static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
1902
{
1903
    PCNetState *s = opaque;
1904
    int i, dummy;
1905

    
1906
    if (version_id < 2 || version_id > 3)
1907
        return -EINVAL;
1908

    
1909
    qemu_get_sbe32s(f, &s->rap);
1910
    qemu_get_sbe32s(f, &s->isr);
1911
    qemu_get_sbe32s(f, &s->lnkst);
1912
    qemu_get_be32s(f, &s->rdra);
1913
    qemu_get_be32s(f, &s->tdra);
1914
    qemu_get_buffer(f, s->prom, 16);
1915
    for (i = 0; i < 128; i++)
1916
        qemu_get_be16s(f, &s->csr[i]);
1917
    for (i = 0; i < 32; i++)
1918
        qemu_get_be16s(f, &s->bcr[i]);
1919
    qemu_get_be64s(f, &s->timer);
1920
    qemu_get_sbe32s(f, &s->xmit_pos);
1921
    if (version_id == 2) {
1922
        qemu_get_sbe32s(f, &dummy);
1923
    }
1924
    qemu_get_buffer(f, s->buffer, 4096);
1925
    qemu_get_sbe32s(f, &s->tx_busy);
1926
    qemu_get_timer(f, s->poll_timer);
1927

    
1928
    return 0;
1929
}
1930

    
1931
static void pci_pcnet_save(QEMUFile *f, void *opaque)
1932
{
1933
    PCIPCNetState *s = opaque;
1934

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

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

    
1944
    ret = pci_device_load(&s->pci_dev, f);
1945
    if (ret < 0)
1946
        return ret;
1947

    
1948
    return pcnet_load(f, &s->state, version_id);
1949
}
1950

    
1951
static void pcnet_common_cleanup(PCNetState *d)
1952
{
1953
    unregister_savevm("pcnet", d);
1954

    
1955
    qemu_del_timer(d->poll_timer);
1956
    qemu_free_timer(d->poll_timer);
1957
}
1958

    
1959
static int pcnet_common_init(DeviceState *dev, PCNetState *s,
1960
                              NetCleanup *cleanup)
1961
{
1962
    s->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, s);
1963

    
1964
    qdev_get_macaddr(dev, s->macaddr);
1965
    s->vc = qdev_get_vlan_client(dev,
1966
                                 pcnet_can_receive, pcnet_receive, NULL,
1967
                                 cleanup, s);
1968
    pcnet_h_reset(s);
1969
    return 0;
1970
}
1971

    
1972
/* PCI interface */
1973

    
1974
static CPUWriteMemoryFunc * const pcnet_mmio_write[] = {
1975
    &pcnet_mmio_writeb,
1976
    &pcnet_mmio_writew,
1977
    &pcnet_mmio_writel
1978
};
1979

    
1980
static CPUReadMemoryFunc * const pcnet_mmio_read[] = {
1981
    &pcnet_mmio_readb,
1982
    &pcnet_mmio_readw,
1983
    &pcnet_mmio_readl
1984
};
1985

    
1986
static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
1987
                            uint32_t addr, uint32_t size, int type)
1988
{
1989
    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev);
1990

    
1991
#ifdef PCNET_DEBUG_IO
1992
    printf("pcnet_mmio_map addr=0x%08x 0x%08x\n", addr, size);
1993
#endif
1994

    
1995
    cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->state.mmio_index);
1996
}
1997

    
1998
static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
1999
                                      uint8_t *buf, int len, int do_bswap)
2000
{
2001
    cpu_physical_memory_write(addr, buf, len);
2002
}
2003

    
2004
static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
2005
                                     uint8_t *buf, int len, int do_bswap)
2006
{
2007
    cpu_physical_memory_read(addr, buf, len);
2008
}
2009

    
2010
static void pci_pcnet_cleanup(VLANClientState *vc)
2011
{
2012
    PCNetState *d = vc->opaque;
2013

    
2014
    pcnet_common_cleanup(d);
2015
}
2016

    
2017
static int pci_pcnet_uninit(PCIDevice *dev)
2018
{
2019
    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev);
2020

    
2021
    cpu_unregister_io_memory(d->state.mmio_index);
2022

    
2023
    return 0;
2024
}
2025

    
2026
static int pci_pcnet_init(PCIDevice *pci_dev)
2027
{
2028
    PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, pci_dev);
2029
    PCNetState *s = &d->state;
2030
    uint8_t *pci_conf;
2031

    
2032
#if 0
2033
    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
2034
        sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
2035
#endif
2036

    
2037
    pci_conf = pci_dev->config;
2038

    
2039
    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_AMD);
2040
    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_AMD_LANCE);
2041
    *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007);
2042
    *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
2043
    pci_conf[0x08] = 0x10;
2044
    pci_conf[0x09] = 0x00;
2045
    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
2046
    pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
2047

    
2048
    *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
2049
    *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
2050

    
2051
    pci_conf[0x3d] = 1; // interrupt pin 0
2052
    pci_conf[0x3e] = 0x06;
2053
    pci_conf[0x3f] = 0xff;
2054

    
2055
    /* Handler for memory-mapped I/O */
2056
    s->mmio_index =
2057
      cpu_register_io_memory(pcnet_mmio_read, pcnet_mmio_write, &d->state);
2058

    
2059
    pci_register_bar((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
2060
                           PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
2061

    
2062
    pci_register_bar((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,
2063
                           PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
2064

    
2065
    s->irq = pci_dev->irq[0];
2066
    s->phys_mem_read = pci_physical_memory_read;
2067
    s->phys_mem_write = pci_physical_memory_write;
2068

    
2069
    register_savevm("pcnet", -1, 3, pci_pcnet_save, pci_pcnet_load, d);
2070
    return pcnet_common_init(&pci_dev->qdev, s, pci_pcnet_cleanup);
2071
}
2072

    
2073
/* SPARC32 interface */
2074

    
2075
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
2076
#include "sun4m.h"
2077

    
2078
static void parent_lance_reset(void *opaque, int irq, int level)
2079
{
2080
    SysBusPCNetState *d = opaque;
2081
    if (level)
2082
        pcnet_h_reset(&d->state);
2083
}
2084

    
2085
static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
2086
                             uint32_t val)
2087
{
2088
    SysBusPCNetState *d = opaque;
2089
#ifdef PCNET_DEBUG_IO
2090
    printf("lance_mem_writew addr=" TARGET_FMT_plx " val=0x%04x\n", addr,
2091
           val & 0xffff);
2092
#endif
2093
    pcnet_ioport_writew(&d->state, addr, val & 0xffff);
2094
}
2095

    
2096
static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
2097
{
2098
    SysBusPCNetState *d = opaque;
2099
    uint32_t val;
2100

    
2101
    val = pcnet_ioport_readw(&d->state, addr);
2102
#ifdef PCNET_DEBUG_IO
2103
    printf("lance_mem_readw addr=" TARGET_FMT_plx " val = 0x%04x\n", addr,
2104
           val & 0xffff);
2105
#endif
2106

    
2107
    return val & 0xffff;
2108
}
2109

    
2110
static CPUReadMemoryFunc * const lance_mem_read[3] = {
2111
    NULL,
2112
    lance_mem_readw,
2113
    NULL,
2114
};
2115

    
2116
static CPUWriteMemoryFunc * const lance_mem_write[3] = {
2117
    NULL,
2118
    lance_mem_writew,
2119
    NULL,
2120
};
2121

    
2122
static void lance_cleanup(VLANClientState *vc)
2123
{
2124
    PCNetState *d = vc->opaque;
2125

    
2126
    pcnet_common_cleanup(d);
2127
}
2128

    
2129
static int lance_init(SysBusDevice *dev)
2130
{
2131
    SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev);
2132
    PCNetState *s = &d->state;
2133

    
2134
    s->mmio_index =
2135
        cpu_register_io_memory(lance_mem_read, lance_mem_write, d);
2136

    
2137
    qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1);
2138

    
2139
    sysbus_init_mmio(dev, 4, s->mmio_index);
2140

    
2141
    sysbus_init_irq(dev, &s->irq);
2142

    
2143
    s->phys_mem_read = ledma_memory_read;
2144
    s->phys_mem_write = ledma_memory_write;
2145

    
2146
    register_savevm("pcnet", -1, 3, pcnet_save, pcnet_load, s);
2147
    return pcnet_common_init(&dev->qdev, s, lance_cleanup);
2148
}
2149

    
2150
static SysBusDeviceInfo lance_info = {
2151
    .init = lance_init,
2152
    .qdev.name  = "lance",
2153
    .qdev.size  = sizeof(SysBusPCNetState),
2154
    .qdev.props = (Property[]) {
2155
        DEFINE_PROP_PTR("dma", SysBusPCNetState, state.dma_opaque),
2156
        DEFINE_PROP_END_OF_LIST(),
2157
    }
2158
};
2159

    
2160
#endif /* TARGET_SPARC */
2161

    
2162
static PCIDeviceInfo pcnet_info = {
2163
    .qdev.name = "pcnet",
2164
    .qdev.size = sizeof(PCIPCNetState),
2165
    .init      = pci_pcnet_init,
2166
    .exit      = pci_pcnet_uninit,
2167
};
2168

    
2169
static void pcnet_register_devices(void)
2170
{
2171
    pci_qdev_register(&pcnet_info);
2172
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64)
2173
    sysbus_register_withprop(&lance_info);
2174
#endif
2175
}
2176

    
2177
device_init(pcnet_register_devices)