Statistics
| Branch: | Revision:

root / hw / pcnet.c @ 72da4208

History | View | Annotate | Download (63.5 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 "hw.h"
39
#include "pci.h"
40
#include "net.h"
41
#include "qemu-timer.h"
42
#include "qemu_socket.h"
43

    
44
//#define PCNET_DEBUG
45
//#define PCNET_DEBUG_IO
46
//#define PCNET_DEBUG_BCR
47
//#define PCNET_DEBUG_CSR
48
//#define PCNET_DEBUG_RMD
49
//#define PCNET_DEBUG_TMD
50
//#define PCNET_DEBUG_MATCH
51

    
52

    
53
#define PCNET_IOPORT_SIZE       0x20
54
#define PCNET_PNPMMIO_SIZE      0x20
55

    
56
#define PCNET_LOOPTEST_CRC        1
57
#define PCNET_LOOPTEST_NOCRC        2
58

    
59

    
60
typedef struct PCNetState_st PCNetState;
61

    
62
struct PCNetState_st {
63
    PCIDevice dev;
64
    PCIDevice *pci_dev;
65
    VLANClientState *vc;
66
    NICInfo *nd;
67
    QEMUTimer *poll_timer;
68
    int mmio_index, rap, isr, lnkst;
69
    uint32_t rdra, tdra;
70
    uint8_t prom[16];
71
    uint16_t csr[128];
72
    uint16_t bcr[32];
73
    uint64_t timer;
74
    int xmit_pos, recv_pos;
75
    uint8_t buffer[4096];
76
    int tx_busy;
77
    qemu_irq irq;
78
    void (*phys_mem_read)(void *dma_opaque, target_phys_addr_t addr,
79
                         uint8_t *buf, int len, int do_bswap);
80
    void (*phys_mem_write)(void *dma_opaque, target_phys_addr_t addr,
81
                          uint8_t *buf, int len, int do_bswap);
82
    void *dma_opaque;
83
    int looptest;
84
};
85

    
86
struct qemu_ether_header {
87
    uint8_t ether_dhost[6];
88
    uint8_t ether_shost[6];
89
    uint16_t ether_type;
90
};
91

    
92
/* BUS CONFIGURATION REGISTERS */
93
#define BCR_MSRDA    0
94
#define BCR_MSWRA    1
95
#define BCR_MC       2
96
#define BCR_LNKST    4
97
#define BCR_LED1     5
98
#define BCR_LED2     6
99
#define BCR_LED3     7
100
#define BCR_FDC      9
101
#define BCR_BSBC     18
102
#define BCR_EECAS    19
103
#define BCR_SWS      20
104
#define BCR_PLAT     22
105

    
106
#define BCR_DWIO(S)      !!((S)->bcr[BCR_BSBC] & 0x0080)
107
#define BCR_SSIZE32(S)   !!((S)->bcr[BCR_SWS ] & 0x0100)
108
#define BCR_SWSTYLE(S)     ((S)->bcr[BCR_SWS ] & 0x00FF)
109

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

    
133
#define CSR_CRBC(S)      ((S)->csr[40])
134
#define CSR_CRST(S)      ((S)->csr[41])
135
#define CSR_CXBC(S)      ((S)->csr[42])
136
#define CSR_CXST(S)      ((S)->csr[43])
137
#define CSR_NRBC(S)      ((S)->csr[44])
138
#define CSR_NRST(S)      ((S)->csr[45])
139
#define CSR_POLL(S)      ((S)->csr[46])
140
#define CSR_PINT(S)      ((S)->csr[47])
141
#define CSR_RCVRC(S)     ((S)->csr[72])
142
#define CSR_XMTRC(S)     ((S)->csr[74])
143
#define CSR_RCVRL(S)     ((S)->csr[76])
144
#define CSR_XMTRL(S)     ((S)->csr[78])
145
#define CSR_MISSC(S)     ((S)->csr[112])
146

    
147
#define CSR_IADR(S)      ((S)->csr[ 1] | ((S)->csr[ 2] << 16))
148
#define CSR_CRBA(S)      ((S)->csr[18] | ((S)->csr[19] << 16))
149
#define CSR_CXBA(S)      ((S)->csr[20] | ((S)->csr[21] << 16))
150
#define CSR_NRBA(S)      ((S)->csr[22] | ((S)->csr[23] << 16))
151
#define CSR_BADR(S)      ((S)->csr[24] | ((S)->csr[25] << 16))
152
#define CSR_NRDA(S)      ((S)->csr[26] | ((S)->csr[27] << 16))
153
#define CSR_CRDA(S)      ((S)->csr[28] | ((S)->csr[29] << 16))
154
#define CSR_BADX(S)      ((S)->csr[30] | ((S)->csr[31] << 16))
155
#define CSR_NXDA(S)      ((S)->csr[32] | ((S)->csr[33] << 16))
156
#define CSR_CXDA(S)      ((S)->csr[34] | ((S)->csr[35] << 16))
157
#define CSR_NNRD(S)      ((S)->csr[36] | ((S)->csr[37] << 16))
158
#define CSR_NNXD(S)      ((S)->csr[38] | ((S)->csr[39] << 16))
159
#define CSR_PXDA(S)      ((S)->csr[60] | ((S)->csr[61] << 16))
160
#define CSR_NXBA(S)      ((S)->csr[64] | ((S)->csr[65] << 16))
161

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

    
165
struct pcnet_initblk16 {
166
    uint16_t mode;
167
    uint16_t padr[3];
168
    uint16_t ladrf[4];
169
    uint32_t rdra;
170
    uint32_t tdra;
171
};
172

    
173
struct pcnet_initblk32 {
174
    uint16_t mode;
175
    uint8_t rlen;
176
    uint8_t tlen;
177
    uint16_t padr[3];
178
    uint16_t _res;
179
    uint16_t ladrf[4];
180
    uint32_t rdra;
181
    uint32_t tdra;
182
};
183

    
184
struct pcnet_TMD {
185
    uint32_t tbadr;
186
    int16_t length;
187
    int16_t status;
188
    uint32_t misc;
189
    uint32_t res;
190
};
191

    
192
#define TMDL_BCNT_MASK  0x0fff
193
#define TMDL_BCNT_SH    0
194
#define TMDL_ONES_MASK  0xf000
195
#define TMDL_ONES_SH    12
196

    
197
#define TMDS_BPE_MASK   0x0080
198
#define TMDS_BPE_SH     7
199
#define TMDS_ENP_MASK   0x0100
200
#define TMDS_ENP_SH     8
201
#define TMDS_STP_MASK   0x0200
202
#define TMDS_STP_SH     9
203
#define TMDS_DEF_MASK   0x0400
204
#define TMDS_DEF_SH     10
205
#define TMDS_ONE_MASK   0x0800
206
#define TMDS_ONE_SH     11
207
#define TMDS_LTINT_MASK 0x1000
208
#define TMDS_LTINT_SH   12
209
#define TMDS_NOFCS_MASK 0x2000
210
#define TMDS_NOFCS_SH   13
211
#define TMDS_ADDFCS_MASK TMDS_NOFCS_MASK
212
#define TMDS_ADDFCS_SH  TMDS_NOFCS_SH
213
#define TMDS_ERR_MASK   0x4000
214
#define TMDS_ERR_SH     14
215
#define TMDS_OWN_MASK   0x8000
216
#define TMDS_OWN_SH     15
217

    
218
#define TMDM_TRC_MASK   0x0000000f
219
#define TMDM_TRC_SH     0
220
#define TMDM_TDR_MASK   0x03ff0000
221
#define TMDM_TDR_SH     16
222
#define TMDM_RTRY_MASK  0x04000000
223
#define TMDM_RTRY_SH    26
224
#define TMDM_LCAR_MASK  0x08000000
225
#define TMDM_LCAR_SH    27
226
#define TMDM_LCOL_MASK  0x10000000
227
#define TMDM_LCOL_SH    28
228
#define TMDM_EXDEF_MASK 0x20000000
229
#define TMDM_EXDEF_SH   29
230
#define TMDM_UFLO_MASK  0x40000000
231
#define TMDM_UFLO_SH    30
232
#define TMDM_BUFF_MASK  0x80000000
233
#define TMDM_BUFF_SH    31
234

    
235
struct pcnet_RMD {
236
    uint32_t rbadr;
237
    int16_t buf_length;
238
    int16_t status;
239
    uint32_t msg_length;
240
    uint32_t res;
241
};
242

    
243
#define RMDL_BCNT_MASK  0x0fff
244
#define RMDL_BCNT_SH    0
245
#define RMDL_ONES_MASK  0xf000
246
#define RMDL_ONES_SH    12
247

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

    
273
#define RMDM_MCNT_MASK  0x00000fff
274
#define RMDM_MCNT_SH    0
275
#define RMDM_ZEROS_MASK 0x0000f000
276
#define RMDM_ZEROS_SH   12
277
#define RMDM_RPC_MASK   0x00ff0000
278
#define RMDM_RPC_SH     16
279
#define RMDM_RCC_MASK   0xff000000
280
#define RMDM_RCC_SH     24
281

    
282
#define SET_FIELD(regp, name, field, value)             \
283
  (*(regp) = (*(regp) & ~(name ## _ ## field ## _MASK)) \
284
             | ((value) << name ## _ ## field ## _SH))
285

    
286
#define GET_FIELD(reg, name, field)                     \
287
  (((reg) & name ## _ ## field ## _MASK) >> name ## _ ## field ## _SH)
288

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

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

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

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

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

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

    
475

    
476
#define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
477

    
478
#define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
479

    
480
#define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
481

    
482
#define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
483

    
484
#if 1
485

    
486
#define CHECK_RMD(ADDR,RES) do {                \
487
    struct pcnet_RMD rmd;                       \
488
    RMDLOAD(&rmd,(ADDR));                       \
489
    (RES) |= (GET_FIELD(rmd.buf_length, RMDL, ONES) != 15) \
490
          || (GET_FIELD(rmd.msg_length, RMDM, ZEROS) != 0); \
491
} while (0)
492

    
493
#define CHECK_TMD(ADDR,RES) do {                \
494
    struct pcnet_TMD tmd;                       \
495
    TMDLOAD(&tmd,(ADDR));                       \
496
    (RES) |= (GET_FIELD(tmd.length, TMDL, ONES) != 15); \
497
} while (0)
498

    
499
#else
500

    
501
#define CHECK_RMD(ADDR,RES) do {                \
502
    switch (BCR_SWSTYLE(s)) {                   \
503
    case 0x00:                                  \
504
        do {                                    \
505
            uint16_t rda[4];                    \
506
            s->phys_mem_read(s->dma_opaque, (ADDR), \
507
                (void *)&rda[0], sizeof(rda), 0); \
508
            (RES) |= (rda[2] & 0xf000)!=0xf000; \
509
            (RES) |= (rda[3] & 0xf000)!=0x0000; \
510
        } while (0);                            \
511
        break;                                  \
512
    case 0x01:                                  \
513
    case 0x02:                                  \
514
        do {                                    \
515
            uint32_t rda[4];                    \
516
            s->phys_mem_read(s->dma_opaque, (ADDR), \
517
                (void *)&rda[0], sizeof(rda), 0); \
518
            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
519
            (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
520
        } while (0);                            \
521
        break;                                  \
522
    case 0x03:                                  \
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[0] & 0x0000f000L)!=0x00000000L; \
528
            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
529
        } while (0);                            \
530
        break;                                  \
531
    }                                           \
532
} while (0)
533

    
534
#define CHECK_TMD(ADDR,RES) do {                \
535
    switch (BCR_SWSTYLE(s)) {                   \
536
    case 0x00:                                  \
537
        do {                                    \
538
            uint16_t xda[4];                    \
539
            s->phys_mem_read(s->dma_opaque, (ADDR), \
540
                (void *)&xda[0], sizeof(xda), 0); \
541
            (RES) |= (xda[2] & 0xf000)!=0xf000; \
542
        } while (0);                            \
543
        break;                                  \
544
    case 0x01:                                  \
545
    case 0x02:                                  \
546
    case 0x03:                                  \
547
        do {                                    \
548
            uint32_t xda[4];                    \
549
            s->phys_mem_read(s->dma_opaque, (ADDR), \
550
                (void *)&xda[0], sizeof(xda), 0); \
551
            (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
552
        } while (0);                            \
553
        break;                                  \
554
    }                                           \
555
} while (0)
556

    
557
#endif
558

    
559
#define PRINT_PKTHDR(BUF) do {                  \
560
    struct qemu_ether_header *hdr = (void *)(BUF); \
561
    printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \
562
           "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \
563
           "type=0x%04x\n",                     \
564
           hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
565
           hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
566
           hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
567
           hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
568
           be16_to_cpu(hdr->ether_type));       \
569
} while (0)
570

    
571
#define MULTICAST_FILTER_LEN 8
572

    
573
static inline uint32_t lnc_mchash(const uint8_t *ether_addr)
574
{
575
#define LNC_POLYNOMIAL          0xEDB88320UL
576
    uint32_t crc = 0xFFFFFFFF;
577
    int idx, bit;
578
    uint8_t data;
579

    
580
    for (idx = 0; idx < 6; idx++) {
581
        for (data = *ether_addr++, bit = 0; bit < MULTICAST_FILTER_LEN; bit++) {
582
            crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LNC_POLYNOMIAL : 0);
583
            data >>= 1;
584
        }
585
    }
586
    return crc;
587
#undef LNC_POLYNOMIAL
588
}
589

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

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

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

    
683
static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size)
684
{
685
    static const uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
686
    struct qemu_ether_header *hdr = (void *)buf;
687
    int result = !CSR_DRCVBC(s) && !memcmp(hdr->ether_dhost, BCAST, 6);
688
#ifdef PCNET_DEBUG_MATCH
689
    printf("padr_bcast result=%d\n", result);
690
#endif
691
    return result;
692
}
693

    
694
static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
695
{
696
    struct qemu_ether_header *hdr = (void *)buf;
697
    if ((*(hdr->ether_dhost)&0x01) &&
698
        ((uint64_t *)&s->csr[8])[0] != 0LL) {
699
        uint8_t ladr[8] = {
700
            s->csr[8] & 0xff, s->csr[8] >> 8,
701
            s->csr[9] & 0xff, s->csr[9] >> 8,
702
            s->csr[10] & 0xff, s->csr[10] >> 8,
703
            s->csr[11] & 0xff, s->csr[11] >> 8
704
        };
705
        int index = lnc_mchash(hdr->ether_dhost) >> 26;
706
        return !!(ladr[index >> 3] & (1 << (index & 7)));
707
    }
708
    return 0;
709
}
710

    
711
static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx)
712
{
713
    while (idx < 1) idx += CSR_RCVRL(s);
714
    return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
715
}
716

    
717
static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
718
{
719
    int64_t next_time = current_time +
720
        muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)),
721
                 ticks_per_sec, 33000000L);
722
    if (next_time <= current_time)
723
        next_time = current_time + 1;
724
    return next_time;
725
}
726

    
727
static void pcnet_poll(PCNetState *s);
728
static void pcnet_poll_timer(void *opaque);
729

    
730
static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
731
static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
732
static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
733
static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
734

    
735
static void pcnet_s_reset(PCNetState *s)
736
{
737
#ifdef PCNET_DEBUG
738
    printf("pcnet_s_reset\n");
739
#endif
740

    
741
    s->lnkst = 0x40;
742
    s->rdra = 0;
743
    s->tdra = 0;
744
    s->rap = 0;
745

    
746
    s->bcr[BCR_BSBC] &= ~0x0080;
747

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

    
777
    s->tx_busy = 0;
778
}
779

    
780
static void pcnet_update_irq(PCNetState *s)
781
{
782
    int isr = 0;
783
    s->csr[0] &= ~0x0080;
784

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

    
805
        isr = CSR_INEA(s);
806
        s->csr[0] |= 0x0080;
807
    }
808

    
809
    if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
810
        s->csr[4] &= ~0x0080;
811
        s->csr[4] |= 0x0040;
812
        s->csr[0] |= 0x0080;
813
        isr = 1;
814
#ifdef PCNET_DEBUG
815
        printf("pcnet user int\n");
816
#endif
817
    }
818

    
819
#if 1
820
    if (((s->csr[5]>>1) & s->csr[5]) & 0x0500)
821
#else
822
    if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
823
        (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
824
#endif
825
    {
826
        isr = 1;
827
        s->csr[0] |= 0x0080;
828
    }
829

    
830
    if (isr != s->isr) {
831
#ifdef PCNET_DEBUG
832
        printf("pcnet: INTA=%d\n", isr);
833
#endif
834
    }
835
    qemu_set_irq(s->irq, isr);
836
    s->isr = isr;
837
}
838

    
839
static void pcnet_init(PCNetState *s)
840
{
841
    int rlen, tlen;
842
    uint16_t padr[3], ladrf[4], mode;
843
    uint32_t rdra, tdra;
844

    
845
#ifdef PCNET_DEBUG
846
    printf("pcnet_init init_addr=0x%08x\n", PHYSADDR(s,CSR_IADR(s)));
847
#endif
848

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

    
885
#if defined(PCNET_DEBUG)
886
    printf("rlen=%d tlen=%d\n", rlen, tlen);
887
#endif
888

    
889
    CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512;
890
    CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512;
891
    s->csr[ 6] = (tlen << 12) | (rlen << 8);
892
    s->csr[15] = mode;
893
    s->csr[ 8] = ladrf[0];
894
    s->csr[ 9] = ladrf[1];
895
    s->csr[10] = ladrf[2];
896
    s->csr[11] = ladrf[3];
897
    s->csr[12] = padr[0];
898
    s->csr[13] = padr[1];
899
    s->csr[14] = padr[2];
900
    s->rdra = PHYSADDR(s, rdra);
901
    s->tdra = PHYSADDR(s, tdra);
902

    
903
    CSR_RCVRC(s) = CSR_RCVRL(s);
904
    CSR_XMTRC(s) = CSR_XMTRL(s);
905

    
906
#ifdef PCNET_DEBUG
907
    printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n",
908
        BCR_SSIZE32(s),
909
        s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
910
#endif
911

    
912
    s->csr[0] |= 0x0101;
913
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
914
}
915

    
916
static void pcnet_start(PCNetState *s)
917
{
918
#ifdef PCNET_DEBUG
919
    printf("pcnet_start\n");
920
#endif
921

    
922
    if (!CSR_DTX(s))
923
        s->csr[0] |= 0x0010;    /* set TXON */
924

    
925
    if (!CSR_DRX(s))
926
        s->csr[0] |= 0x0020;    /* set RXON */
927

    
928
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
929
    s->csr[0] |= 0x0002;
930
}
931

    
932
static void pcnet_stop(PCNetState *s)
933
{
934
#ifdef PCNET_DEBUG
935
    printf("pcnet_stop\n");
936
#endif
937
    s->csr[0] &= ~0x7feb;
938
    s->csr[0] |= 0x0014;
939
    s->csr[4] &= ~0x02c2;
940
    s->csr[5] &= ~0x0011;
941
    pcnet_poll_timer(s);
942
}
943

    
944
static void pcnet_rdte_poll(PCNetState *s)
945
{
946
    s->csr[28] = s->csr[29] = 0;
947
    if (s->rdra) {
948
        int bad = 0;
949
#if 1
950
        target_phys_addr_t crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
951
        target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
952
        target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
953
#else
954
        target_phys_addr_t crda = s->rdra +
955
            (CSR_RCVRL(s) - CSR_RCVRC(s)) *
956
            (BCR_SWSTYLE(s) ? 16 : 8 );
957
        int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
958
        target_phys_addr_t nrda = s->rdra +
959
            (CSR_RCVRL(s) - nrdc) *
960
            (BCR_SWSTYLE(s) ? 16 : 8 );
961
        int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
962
        target_phys_addr_t nnrd = s->rdra +
963
            (CSR_RCVRL(s) - nnrc) *
964
            (BCR_SWSTYLE(s) ? 16 : 8 );
965
#endif
966

    
967
        CHECK_RMD(PHYSADDR(s,crda), bad);
968
        if (!bad) {
969
            CHECK_RMD(PHYSADDR(s,nrda), bad);
970
            if (bad || (nrda == crda)) nrda = 0;
971
            CHECK_RMD(PHYSADDR(s,nnrd), bad);
972
            if (bad || (nnrd == crda)) nnrd = 0;
973

    
974
            s->csr[28] = crda & 0xffff;
975
            s->csr[29] = crda >> 16;
976
            s->csr[26] = nrda & 0xffff;
977
            s->csr[27] = nrda >> 16;
978
            s->csr[36] = nnrd & 0xffff;
979
            s->csr[37] = nnrd >> 16;
980
#ifdef PCNET_DEBUG
981
            if (bad) {
982
                printf("pcnet: BAD RMD RECORDS AFTER 0x" TARGET_FMT_plx "\n",
983
                       PHYSADDR(s,crda));
984
            }
985
        } else {
986
            printf("pcnet: BAD RMD RDA=0x" TARGET_FMT_plx "\n",
987
                   PHYSADDR(s,crda));
988
#endif
989
        }
990
    }
991

    
992
    if (CSR_CRDA(s)) {
993
        struct pcnet_RMD rmd;
994
        RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
995
        CSR_CRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
996
        CSR_CRST(s) = rmd.status;
997
#ifdef PCNET_DEBUG_RMD_X
998
        printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMDL=0x%04x RMDS=0x%04x RMDM=0x%08x\n",
999
                PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
1000
                rmd.buf_length, rmd.status, rmd.msg_length);
1001
        PRINT_RMD(&rmd);
1002
#endif
1003
    } else {
1004
        CSR_CRBC(s) = CSR_CRST(s) = 0;
1005
    }
1006

    
1007
    if (CSR_NRDA(s)) {
1008
        struct pcnet_RMD rmd;
1009
        RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
1010
        CSR_NRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
1011
        CSR_NRST(s) = rmd.status;
1012
    } else {
1013
        CSR_NRBC(s) = CSR_NRST(s) = 0;
1014
    }
1015

    
1016
}
1017

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

    
1042
    if (CSR_CXDA(s)) {
1043
        struct pcnet_TMD tmd;
1044

    
1045
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1046

    
1047
        CSR_CXBC(s) = GET_FIELD(tmd.length, TMDL, BCNT);
1048
        CSR_CXST(s) = tmd.status;
1049
    } else {
1050
        CSR_CXBC(s) = CSR_CXST(s) = 0;
1051
    }
1052

    
1053
    return !!(CSR_CXST(s) & 0x8000);
1054
}
1055

    
1056
static int pcnet_can_receive(void *opaque)
1057
{
1058
    PCNetState *s = opaque;
1059
    if (CSR_STOP(s) || CSR_SPND(s))
1060
        return 0;
1061

    
1062
    if (s->recv_pos > 0)
1063
        return 0;
1064

    
1065
    return sizeof(s->buffer)-16;
1066
}
1067

    
1068
#define MIN_BUF_SIZE 60
1069

    
1070
static void pcnet_receive(void *opaque, const uint8_t *buf, int size)
1071
{
1072
    PCNetState *s = opaque;
1073
    int is_padr = 0, is_bcast = 0, is_ladr = 0;
1074
    uint8_t buf1[60];
1075
    int remaining;
1076
    int crc_err = 0;
1077

    
1078
    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
1079
        return;
1080

    
1081
#ifdef PCNET_DEBUG
1082
    printf("pcnet_receive size=%d\n", size);
1083
#endif
1084

    
1085
    /* if too small buffer, then expand it */
1086
    if (size < MIN_BUF_SIZE) {
1087
        memcpy(buf1, buf, size);
1088
        memset(buf1 + size, 0, MIN_BUF_SIZE - size);
1089
        buf = buf1;
1090
        size = MIN_BUF_SIZE;
1091
    }
1092

    
1093
    if (CSR_PROM(s)
1094
        || (is_padr=padr_match(s, buf, size))
1095
        || (is_bcast=padr_bcast(s, buf, size))
1096
        || (is_ladr=ladr_match(s, buf, size))) {
1097

    
1098
        pcnet_rdte_poll(s);
1099

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

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

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

    
1148
                while (p != &src[size])
1149
                    CRC(fcs, *p++);
1150
                *(uint32_t *)p = htonl(fcs);
1151
                size += 4;
1152
            } else {
1153
                uint32_t fcs = ~0;
1154
                uint8_t *p = src;
1155

    
1156
                while (p != &src[size-4])
1157
                    CRC(fcs, *p++);
1158
                crc_err = (*(uint32_t *)p != htonl(fcs));
1159
            }
1160

    
1161
#ifdef PCNET_DEBUG_MATCH
1162
            PRINT_PKTHDR(buf);
1163
#endif
1164

    
1165
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1166
            /*if (!CSR_LAPPEN(s))*/
1167
                SET_FIELD(&rmd.status, RMDS, STP, 1);
1168

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

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

    
1203
#undef PCNET_RECV_STORE
1204

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

    
1224
#ifdef PCNET_DEBUG
1225
            printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",
1226
                CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
1227
#endif
1228
#ifdef PCNET_DEBUG_RMD
1229
            PRINT_RMD(&rmd);
1230
#endif
1231

    
1232
            while (pktcount--) {
1233
                if (CSR_RCVRC(s) <= 1)
1234
                    CSR_RCVRC(s) = CSR_RCVRL(s);
1235
                else
1236
                    CSR_RCVRC(s)--;
1237
            }
1238

    
1239
            pcnet_rdte_poll(s);
1240

    
1241
        }
1242
    }
1243

    
1244
    pcnet_poll(s);
1245
    pcnet_update_irq(s);
1246
}
1247

    
1248
static void pcnet_transmit(PCNetState *s)
1249
{
1250
    target_phys_addr_t xmit_cxda = 0;
1251
    int count = CSR_XMTRL(s)-1;
1252
    int add_crc = 0;
1253

    
1254
    s->xmit_pos = -1;
1255

    
1256
    if (!CSR_TXON(s)) {
1257
        s->csr[0] &= ~0x0008;
1258
        return;
1259
    }
1260

    
1261
    s->tx_busy = 1;
1262

    
1263
    txagain:
1264
    if (pcnet_tdte_poll(s)) {
1265
        struct pcnet_TMD tmd;
1266

    
1267
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1268

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

    
1302
            s->csr[0] &= ~0x0008;   /* clear TDMD */
1303
            s->csr[4] |= 0x0004;    /* set TXSTRT */
1304
            s->xmit_pos = -1;
1305
        }
1306

    
1307
        SET_FIELD(&tmd.status, TMDS, OWN, 0);
1308
        TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1309
        if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT)))
1310
            s->csr[0] |= 0x0200;    /* set TINT */
1311

    
1312
        if (CSR_XMTRC(s)<=1)
1313
            CSR_XMTRC(s) = CSR_XMTRL(s);
1314
        else
1315
            CSR_XMTRC(s)--;
1316
        if (count--)
1317
            goto txagain;
1318

    
1319
    } else
1320
    if (s->xmit_pos >= 0) {
1321
        struct pcnet_TMD tmd;
1322
        TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));
1323
        SET_FIELD(&tmd.misc, TMDM, BUFF, 1);
1324
        SET_FIELD(&tmd.misc, TMDM, UFLO, 1);
1325
        SET_FIELD(&tmd.status, TMDS, ERR, 1);
1326
        SET_FIELD(&tmd.status, TMDS, OWN, 0);
1327
        TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda));
1328
        s->csr[0] |= 0x0200;    /* set TINT */
1329
        if (!CSR_DXSUFLO(s)) {
1330
            s->csr[0] &= ~0x0010;
1331
        } else
1332
        if (count--)
1333
          goto txagain;
1334
    }
1335

    
1336
    s->tx_busy = 0;
1337
}
1338

    
1339
static void pcnet_poll(PCNetState *s)
1340
{
1341
    if (CSR_RXON(s)) {
1342
        pcnet_rdte_poll(s);
1343
    }
1344

    
1345
    if (CSR_TDMD(s) ||
1346
        (CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s)))
1347
    {
1348
        /* prevent recursion */
1349
        if (s->tx_busy)
1350
            return;
1351

    
1352
        pcnet_transmit(s);
1353
    }
1354
}
1355

    
1356
static void pcnet_poll_timer(void *opaque)
1357
{
1358
    PCNetState *s = opaque;
1359

    
1360
    qemu_del_timer(s->poll_timer);
1361

    
1362
    if (CSR_TDMD(s)) {
1363
        pcnet_transmit(s);
1364
    }
1365

    
1366
    pcnet_update_irq(s);
1367

    
1368
    if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
1369
        uint64_t now = qemu_get_clock(vm_clock) * 33;
1370
        if (!s->timer || !now)
1371
            s->timer = now;
1372
        else {
1373
            uint64_t t = now - s->timer + CSR_POLL(s);
1374
            if (t > 0xffffLL) {
1375
                pcnet_poll(s);
1376
                CSR_POLL(s) = CSR_PINT(s);
1377
            } else
1378
                CSR_POLL(s) = t;
1379
        }
1380
        qemu_mod_timer(s->poll_timer,
1381
            pcnet_get_next_poll_time(s,qemu_get_clock(vm_clock)));
1382
    }
1383
}
1384

    
1385

    
1386
static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value)
1387
{
1388
    uint16_t val = new_value;
1389
#ifdef PCNET_DEBUG_CSR
1390
    printf("pcnet_csr_writew rap=%d val=0x%04x\n", rap, val);
1391
#endif
1392
    switch (rap) {
1393
    case 0:
1394
        s->csr[0] &= ~(val & 0x7f00); /* Clear any interrupt flags */
1395

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

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

    
1400
        /* IFF STOP, STRT and INIT are set, clear STRT and INIT */
1401
        if ((val&7) == 7)
1402
          val &= ~3;
1403

    
1404
        if (!CSR_STOP(s) && (val & 4))
1405
            pcnet_stop(s);
1406

    
1407
        if (!CSR_INIT(s) && (val & 1))
1408
            pcnet_init(s);
1409

    
1410
        if (!CSR_STRT(s) && (val & 2))
1411
            pcnet_start(s);
1412

    
1413
        if (CSR_TDMD(s))
1414
            pcnet_transmit(s);
1415

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

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

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

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

    
1587
static void pcnet_h_reset(void *opaque)
1588
{
1589
    PCNetState *s = opaque;
1590
    int i;
1591
    uint16_t checksum;
1592

    
1593
    /* Initialize the PROM */
1594

    
1595
    if (s->nd)
1596
        memcpy(s->prom, s->nd->macaddr, 6);
1597
    s->prom[12] = s->prom[13] = 0x00;
1598
    s->prom[14] = s->prom[15] = 0x57;
1599

    
1600
    for (i = 0,checksum = 0; i < 16; i++)
1601
        checksum += s->prom[i];
1602
    *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);
1603

    
1604

    
1605
    s->bcr[BCR_MSRDA] = 0x0005;
1606
    s->bcr[BCR_MSWRA] = 0x0005;
1607
    s->bcr[BCR_MC   ] = 0x0002;
1608
    s->bcr[BCR_LNKST] = 0x00c0;
1609
    s->bcr[BCR_LED1 ] = 0x0084;
1610
    s->bcr[BCR_LED2 ] = 0x0088;
1611
    s->bcr[BCR_LED3 ] = 0x0090;
1612
    s->bcr[BCR_FDC  ] = 0x0000;
1613
    s->bcr[BCR_BSBC ] = 0x9001;
1614
    s->bcr[BCR_EECAS] = 0x0002;
1615
    s->bcr[BCR_SWS  ] = 0x0200;
1616
    s->bcr[BCR_PLAT ] = 0xff06;
1617

    
1618
    pcnet_s_reset(s);
1619
}
1620

    
1621
static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
1622
{
1623
    PCNetState *s = opaque;
1624
#ifdef PCNET_DEBUG
1625
    printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);
1626
#endif
1627
    /* Check APROMWE bit to enable write access */
1628
    if (pcnet_bcr_readw(s,2) & 0x80)
1629
        s->prom[addr & 15] = val;
1630
}
1631

    
1632
static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
1633
{
1634
    PCNetState *s = opaque;
1635
    uint32_t val = s->prom[addr &= 15];
1636
#ifdef PCNET_DEBUG
1637
    printf("pcnet_aprom_readb addr=0x%08x val=0x%02x\n", addr, val);
1638
#endif
1639
    return val;
1640
}
1641

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

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

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

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

    
1753
static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
1754
                             uint32_t addr, uint32_t size, int type)
1755
{
1756
    PCNetState *d = (PCNetState *)pci_dev;
1757

    
1758
#ifdef PCNET_DEBUG_IO
1759
    printf("pcnet_ioport_map addr=0x%04x size=0x%04x\n", addr, size);
1760
#endif
1761

    
1762
    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
1763
    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
1764

    
1765
    register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
1766
    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
1767
    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
1768
    register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
1769
}
1770

    
1771
static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
1772
{
1773
    PCNetState *d = opaque;
1774
#ifdef PCNET_DEBUG_IO
1775
    printf("pcnet_mmio_writeb addr=0x" TARGET_FMT_plx" val=0x%02x\n", addr,
1776
           val);
1777
#endif
1778
    if (!(addr & 0x10))
1779
        pcnet_aprom_writeb(d, addr & 0x0f, val);
1780
}
1781

    
1782
static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr)
1783
{
1784
    PCNetState *d = opaque;
1785
    uint32_t val = -1;
1786
    if (!(addr & 0x10))
1787
        val = pcnet_aprom_readb(d, addr & 0x0f);
1788
#ifdef PCNET_DEBUG_IO
1789
    printf("pcnet_mmio_readb addr=0x" TARGET_FMT_plx " val=0x%02x\n", addr,
1790
           val & 0xff);
1791
#endif
1792
    return val;
1793
}
1794

    
1795
static void pcnet_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
1796
{
1797
    PCNetState *d = opaque;
1798
#ifdef PCNET_DEBUG_IO
1799
    printf("pcnet_mmio_writew addr=0x" TARGET_FMT_plx " val=0x%04x\n", addr,
1800
           val);
1801
#endif
1802
    if (addr & 0x10)
1803
        pcnet_ioport_writew(d, addr & 0x0f, val);
1804
    else {
1805
        addr &= 0x0f;
1806
        pcnet_aprom_writeb(d, addr, val & 0xff);
1807
        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
1808
    }
1809
}
1810

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

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

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

    
1871

    
1872
static void pcnet_save(QEMUFile *f, void *opaque)
1873
{
1874
    PCNetState *s = opaque;
1875
    unsigned int i;
1876

    
1877
    if (s->pci_dev)
1878
        pci_device_save(s->pci_dev, f);
1879

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

    
1898
static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
1899
{
1900
    PCNetState *s = opaque;
1901
    int i, ret;
1902

    
1903
    if (version_id != 2)
1904
        return -EINVAL;
1905

    
1906
    if (s->pci_dev) {
1907
        ret = pci_device_load(s->pci_dev, f);
1908
        if (ret < 0)
1909
            return ret;
1910
    }
1911

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

    
1929
    return 0;
1930
}
1931

    
1932
static void pcnet_common_init(PCNetState *d, NICInfo *nd)
1933
{
1934
    d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d);
1935

    
1936
    d->nd = nd;
1937

    
1938
    if (nd && nd->vlan) {
1939
        d->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
1940
                                     pcnet_receive, pcnet_can_receive, d);
1941

    
1942
        qemu_format_nic_info_str(d->vc, d->nd->macaddr);
1943
    } else {
1944
        d->vc = NULL;
1945
    }
1946
    pcnet_h_reset(d);
1947
    register_savevm("pcnet", -1, 2, pcnet_save, pcnet_load, d);
1948
}
1949

    
1950
/* PCI interface */
1951

    
1952
static CPUWriteMemoryFunc *pcnet_mmio_write[] = {
1953
    (CPUWriteMemoryFunc *)&pcnet_mmio_writeb,
1954
    (CPUWriteMemoryFunc *)&pcnet_mmio_writew,
1955
    (CPUWriteMemoryFunc *)&pcnet_mmio_writel
1956
};
1957

    
1958
static CPUReadMemoryFunc *pcnet_mmio_read[] = {
1959
    (CPUReadMemoryFunc *)&pcnet_mmio_readb,
1960
    (CPUReadMemoryFunc *)&pcnet_mmio_readw,
1961
    (CPUReadMemoryFunc *)&pcnet_mmio_readl
1962
};
1963

    
1964
static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
1965
                            uint32_t addr, uint32_t size, int type)
1966
{
1967
    PCNetState *d = (PCNetState *)pci_dev;
1968

    
1969
#ifdef PCNET_DEBUG_IO
1970
    printf("pcnet_mmio_map addr=0x%08x 0x%08x\n", addr, size);
1971
#endif
1972

    
1973
    cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_index);
1974
}
1975

    
1976
static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
1977
                                      uint8_t *buf, int len, int do_bswap)
1978
{
1979
    cpu_physical_memory_write(addr, buf, len);
1980
}
1981

    
1982
static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
1983
                                     uint8_t *buf, int len, int do_bswap)
1984
{
1985
    cpu_physical_memory_read(addr, buf, len);
1986
}
1987

    
1988
PCIDevice *pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
1989
{
1990
    PCNetState *d;
1991
    uint8_t *pci_conf;
1992

    
1993
#if 0
1994
    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
1995
        sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
1996
#endif
1997

    
1998
    d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
1999
                                          devfn, NULL, NULL);
2000

    
2001
    pci_conf = d->dev.config;
2002

    
2003
    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_AMD);
2004
    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_AMD_LANCE);
2005
    *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007);
2006
    *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
2007
    pci_conf[0x08] = 0x10;
2008
    pci_conf[0x09] = 0x00;
2009
    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
2010
    pci_conf[0x0e] = 0x00; // header_type
2011

    
2012
    *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
2013
    *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
2014

    
2015
    pci_conf[0x3d] = 1; // interrupt pin 0
2016
    pci_conf[0x3e] = 0x06;
2017
    pci_conf[0x3f] = 0xff;
2018

    
2019
    /* Handler for memory-mapped I/O */
2020
    d->mmio_index =
2021
      cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);
2022

    
2023
    pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
2024
                           PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
2025

    
2026
    pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,
2027
                           PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
2028

    
2029
    d->irq = d->dev.irq[0];
2030
    d->phys_mem_read = pci_physical_memory_read;
2031
    d->phys_mem_write = pci_physical_memory_write;
2032
    d->pci_dev = &d->dev;
2033

    
2034
    pcnet_common_init(d, nd);
2035
    return (PCIDevice *)d;
2036
}
2037

    
2038
/* SPARC32 interface */
2039

    
2040
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
2041
#include "sun4m.h"
2042

    
2043
static void parent_lance_reset(void *opaque, int irq, int level)
2044
{
2045
    if (level)
2046
        pcnet_h_reset(opaque);
2047
}
2048

    
2049
static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
2050
                             uint32_t val)
2051
{
2052
#ifdef PCNET_DEBUG_IO
2053
    printf("lance_mem_writew addr=" TARGET_FMT_plx " val=0x%04x\n", addr,
2054
           val & 0xffff);
2055
#endif
2056
    pcnet_ioport_writew(opaque, addr, val & 0xffff);
2057
}
2058

    
2059
static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
2060
{
2061
    uint32_t val;
2062

    
2063
    val = pcnet_ioport_readw(opaque, addr);
2064
#ifdef PCNET_DEBUG_IO
2065
    printf("lance_mem_readw addr=" TARGET_FMT_plx " val = 0x%04x\n", addr,
2066
           val & 0xffff);
2067
#endif
2068

    
2069
    return val & 0xffff;
2070
}
2071

    
2072
static CPUReadMemoryFunc *lance_mem_read[3] = {
2073
    NULL,
2074
    lance_mem_readw,
2075
    NULL,
2076
};
2077

    
2078
static CPUWriteMemoryFunc *lance_mem_write[3] = {
2079
    NULL,
2080
    lance_mem_writew,
2081
    NULL,
2082
};
2083

    
2084
void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
2085
                qemu_irq irq, qemu_irq *reset)
2086
{
2087
    PCNetState *d;
2088
    int lance_io_memory;
2089

    
2090
    qemu_check_nic_model(nd, "lance");
2091

    
2092
    d = qemu_mallocz(sizeof(PCNetState));
2093

    
2094
    lance_io_memory =
2095
        cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
2096

    
2097
    d->dma_opaque = dma_opaque;
2098

    
2099
    *reset = *qemu_allocate_irqs(parent_lance_reset, d, 1);
2100

    
2101
    cpu_register_physical_memory(leaddr, 4, lance_io_memory);
2102

    
2103
    d->irq = irq;
2104
    d->phys_mem_read = ledma_memory_read;
2105
    d->phys_mem_write = ledma_memory_write;
2106

    
2107
    pcnet_common_init(d, nd);
2108
}
2109
#endif /* TARGET_SPARC */