Statistics
| Branch: | Revision:

root / hw / pcnet.c @ 067a3ddc

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
484

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

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

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

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

    
493
#if 1
494

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

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

    
508
#else
509

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

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

    
566
#endif
567

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

    
580
#define MULTICAST_FILTER_LEN 8
581

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
786
    s->tx_busy = 0;
787
}
788

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1025
}
1026

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

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

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

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

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

    
1065
static int pcnet_can_receive(void *opaque)
1066
{
1067
    PCNetState *s = opaque;
1068
    if (CSR_STOP(s) || CSR_SPND(s))
1069
        return 0;
1070

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

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

    
1077
#define MIN_BUF_SIZE 60
1078

    
1079
static void pcnet_receive(void *opaque, const uint8_t *buf, int size)
1080
{
1081
    PCNetState *s = opaque;
1082
    int is_padr = 0, is_bcast = 0, is_ladr = 0;
1083
    uint8_t buf1[60];
1084
    int remaining;
1085
    int crc_err = 0;
1086

    
1087
    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
1088
        return;
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

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

    
1263
    s->xmit_pos = -1;
1264

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

    
1270
    s->tx_busy = 1;
1271

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

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

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

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

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

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

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

    
1345
    s->tx_busy = 0;
1346
}
1347

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

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

    
1361
        pcnet_transmit(s);
1362
    }
1363
}
1364

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

    
1369
    qemu_del_timer(s->poll_timer);
1370

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

    
1375
    pcnet_update_irq(s);
1376

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

    
1394

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1602
    /* Initialize the PROM */
1603

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

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

    
1612

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

    
1626
    pcnet_s_reset(s);
1627
}
1628

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1879

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

    
1885
    if (s->pci_dev)
1886
        pci_device_save(s->pci_dev, f);
1887

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

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

    
1911
    if (version_id != 2)
1912
        return -EINVAL;
1913

    
1914
    if (s->pci_dev) {
1915
        ret = pci_device_load(s->pci_dev, f);
1916
        if (ret < 0)
1917
            return ret;
1918
    }
1919

    
1920
    qemu_get_sbe32s(f, &s->rap);
1921
    qemu_get_sbe32s(f, &s->isr);
1922
    qemu_get_sbe32s(f, &s->lnkst);
1923
    qemu_get_be32s(f, &s->rdra);
1924
    qemu_get_be32s(f, &s->tdra);
1925
    qemu_get_buffer(f, s->prom, 16);
1926
    for (i = 0; i < 128; i++)
1927
        qemu_get_be16s(f, &s->csr[i]);
1928
    for (i = 0; i < 32; i++)
1929
        qemu_get_be16s(f, &s->bcr[i]);
1930
    qemu_get_be64s(f, &s->timer);
1931
    qemu_get_sbe32s(f, &s->xmit_pos);
1932
    qemu_get_sbe32s(f, &s->recv_pos);
1933
    qemu_get_buffer(f, s->buffer, 4096);
1934
    qemu_get_sbe32s(f, &s->tx_busy);
1935
    qemu_get_timer(f, s->poll_timer);
1936

    
1937
    return 0;
1938
}
1939

    
1940
static void pcnet_common_cleanup(PCNetState *d)
1941
{
1942
    unregister_savevm("pcnet", d);
1943

    
1944
    qemu_del_timer(d->poll_timer);
1945
    qemu_free_timer(d->poll_timer);
1946
}
1947

    
1948
static void pcnet_common_init(DeviceState *dev, PCNetState *s,
1949
                              NetCleanup *cleanup)
1950
{
1951
    s->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, s);
1952

    
1953
    qdev_get_macaddr(dev, s->macaddr);
1954
    s->vc = qdev_get_vlan_client(dev,
1955
                                 pcnet_receive, pcnet_can_receive,
1956
                                 cleanup, s);
1957
    pcnet_h_reset(s);
1958
    register_savevm("pcnet", -1, 2, pcnet_save, pcnet_load, s);
1959
}
1960

    
1961
/* PCI interface */
1962

    
1963
static CPUWriteMemoryFunc *pcnet_mmio_write[] = {
1964
    (CPUWriteMemoryFunc *)&pcnet_mmio_writeb,
1965
    (CPUWriteMemoryFunc *)&pcnet_mmio_writew,
1966
    (CPUWriteMemoryFunc *)&pcnet_mmio_writel
1967
};
1968

    
1969
static CPUReadMemoryFunc *pcnet_mmio_read[] = {
1970
    (CPUReadMemoryFunc *)&pcnet_mmio_readb,
1971
    (CPUReadMemoryFunc *)&pcnet_mmio_readw,
1972
    (CPUReadMemoryFunc *)&pcnet_mmio_readl
1973
};
1974

    
1975
static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
1976
                            uint32_t addr, uint32_t size, int type)
1977
{
1978
    PCIPCNetState *d = (PCIPCNetState *)pci_dev;
1979

    
1980
#ifdef PCNET_DEBUG_IO
1981
    printf("pcnet_mmio_map addr=0x%08x 0x%08x\n", addr, size);
1982
#endif
1983

    
1984
    cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->state.mmio_index);
1985
}
1986

    
1987
static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
1988
                                      uint8_t *buf, int len, int do_bswap)
1989
{
1990
    cpu_physical_memory_write(addr, buf, len);
1991
}
1992

    
1993
static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
1994
                                     uint8_t *buf, int len, int do_bswap)
1995
{
1996
    cpu_physical_memory_read(addr, buf, len);
1997
}
1998

    
1999
static void pci_pcnet_cleanup(VLANClientState *vc)
2000
{
2001
    PCNetState *d = vc->opaque;
2002

    
2003
    pcnet_common_cleanup(d);
2004
}
2005

    
2006
static int pci_pcnet_uninit(PCIDevice *dev)
2007
{
2008
    PCIPCNetState *d = (PCIPCNetState *)dev;
2009

    
2010
    cpu_unregister_io_memory(d->state.mmio_index);
2011

    
2012
    return 0;
2013
}
2014

    
2015
static void pci_pcnet_init(PCIDevice *pci_dev)
2016
{
2017
    PCIPCNetState *d = (PCIPCNetState *)pci_dev;
2018
    PCNetState *s = &d->state;
2019
    uint8_t *pci_conf;
2020

    
2021
#if 0
2022
    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
2023
        sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
2024
#endif
2025

    
2026
    pci_dev->unregister = pci_pcnet_uninit;
2027

    
2028
    pci_conf = pci_dev->config;
2029

    
2030
    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_AMD);
2031
    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_AMD_LANCE);
2032
    *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007);
2033
    *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
2034
    pci_conf[0x08] = 0x10;
2035
    pci_conf[0x09] = 0x00;
2036
    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
2037
    pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
2038

    
2039
    *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
2040
    *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
2041

    
2042
    pci_conf[0x3d] = 1; // interrupt pin 0
2043
    pci_conf[0x3e] = 0x06;
2044
    pci_conf[0x3f] = 0xff;
2045

    
2046
    /* Handler for memory-mapped I/O */
2047
    s->mmio_index =
2048
      cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, &d->state);
2049

    
2050
    pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
2051
                           PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
2052

    
2053
    pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,
2054
                           PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
2055

    
2056
    s->irq = pci_dev->irq[0];
2057
    s->phys_mem_read = pci_physical_memory_read;
2058
    s->phys_mem_write = pci_physical_memory_write;
2059
    s->pci_dev = pci_dev;
2060

    
2061
    pcnet_common_init(&pci_dev->qdev, s, pci_pcnet_cleanup);
2062
}
2063

    
2064
/* SPARC32 interface */
2065

    
2066
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
2067
#include "sun4m.h"
2068

    
2069
static void parent_lance_reset(void *opaque, int irq, int level)
2070
{
2071
    SysBusPCNetState *d = opaque;
2072
    if (level)
2073
        pcnet_h_reset(&d->state);
2074
}
2075

    
2076
static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
2077
                             uint32_t val)
2078
{
2079
    SysBusPCNetState *d = opaque;
2080
#ifdef PCNET_DEBUG_IO
2081
    printf("lance_mem_writew addr=" TARGET_FMT_plx " val=0x%04x\n", addr,
2082
           val & 0xffff);
2083
#endif
2084
    pcnet_ioport_writew(&d->state, addr, val & 0xffff);
2085
}
2086

    
2087
static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
2088
{
2089
    SysBusPCNetState *d = opaque;
2090
    uint32_t val;
2091

    
2092
    val = pcnet_ioport_readw(&d->state, addr);
2093
#ifdef PCNET_DEBUG_IO
2094
    printf("lance_mem_readw addr=" TARGET_FMT_plx " val = 0x%04x\n", addr,
2095
           val & 0xffff);
2096
#endif
2097

    
2098
    return val & 0xffff;
2099
}
2100

    
2101
static CPUReadMemoryFunc *lance_mem_read[3] = {
2102
    NULL,
2103
    lance_mem_readw,
2104
    NULL,
2105
};
2106

    
2107
static CPUWriteMemoryFunc *lance_mem_write[3] = {
2108
    NULL,
2109
    lance_mem_writew,
2110
    NULL,
2111
};
2112

    
2113
static void lance_cleanup(VLANClientState *vc)
2114
{
2115
    PCNetState *d = vc->opaque;
2116

    
2117
    pcnet_common_cleanup(d);
2118
}
2119

    
2120
static void lance_init(SysBusDevice *dev)
2121
{
2122
    SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev);
2123
    PCNetState *s = &d->state;
2124

    
2125
    s->mmio_index =
2126
        cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
2127

    
2128
    s->dma_opaque = qdev_get_prop_ptr(&dev->qdev, "dma");
2129

    
2130
    qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1);
2131

    
2132
    sysbus_init_mmio(dev, 4, s->mmio_index);
2133

    
2134
    sysbus_init_irq(dev, &s->irq);
2135

    
2136
    s->phys_mem_read = ledma_memory_read;
2137
    s->phys_mem_write = ledma_memory_write;
2138

    
2139
    pcnet_common_init(&dev->qdev, s, lance_cleanup);
2140
}
2141
#endif /* TARGET_SPARC */
2142

    
2143
static void pcnet_register_devices(void)
2144
{
2145
    pci_qdev_register("pcnet", sizeof(PCIPCNetState), pci_pcnet_init);
2146
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64)
2147
    sysbus_register_dev("lance", sizeof(SysBusPCNetState), lance_init);
2148
#endif
2149
}
2150

    
2151
device_init(pcnet_register_devices)