Statistics
| Branch: | Revision:

root / hw / pcnet.c @ bee8d684

History | View | Annotate | Download (62.6 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

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

    
51

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

    
55

    
56
typedef struct PCNetState_st PCNetState;
57

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

    
81
struct qemu_ether_header {
82
    uint8_t ether_dhost[6];
83
    uint8_t ether_shost[6];
84
    uint16_t ether_type;
85
};
86

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

    
101
#define BCR_DWIO(S)      !!((S)->bcr[BCR_BSBC] & 0x0080)
102
#define BCR_SSIZE32(S)   !!((S)->bcr[BCR_SWS ] & 0x0100)
103
#define BCR_SWSTYLE(S)     ((S)->bcr[BCR_SWS ] & 0x00FF)
104

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

    
127
#define CSR_CRBC(S)      ((S)->csr[40])
128
#define CSR_CRST(S)      ((S)->csr[41])
129
#define CSR_CXBC(S)      ((S)->csr[42])
130
#define CSR_CXST(S)      ((S)->csr[43])
131
#define CSR_NRBC(S)      ((S)->csr[44])
132
#define CSR_NRST(S)      ((S)->csr[45])
133
#define CSR_POLL(S)      ((S)->csr[46])
134
#define CSR_PINT(S)      ((S)->csr[47])
135
#define CSR_RCVRC(S)     ((S)->csr[72])
136
#define CSR_XMTRC(S)     ((S)->csr[74])
137
#define CSR_RCVRL(S)     ((S)->csr[76])
138
#define CSR_XMTRL(S)     ((S)->csr[78])
139
#define CSR_MISSC(S)     ((S)->csr[112])
140

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

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

    
159
struct pcnet_initblk16 {
160
    uint16_t mode;
161
    uint16_t padr[3];
162
    uint16_t ladrf[4];
163
    uint32_t rdra;
164
    uint32_t tdra;
165
};
166

    
167
struct pcnet_initblk32 {
168
    uint16_t mode;
169
    uint8_t rlen;
170
    uint8_t tlen;
171
    uint16_t padr[3];
172
    uint16_t _res;
173
    uint16_t ladrf[4];
174
    uint32_t rdra;
175
    uint32_t tdra;
176
};
177

    
178
struct pcnet_TMD {
179
    uint32_t tbadr;
180
    int16_t length;
181
    int16_t status;
182
    uint32_t misc;
183
    uint32_t res;
184
};
185

    
186
#define TMDL_BCNT_MASK  0x0fff
187
#define TMDL_BCNT_SH    0
188
#define TMDL_ONES_MASK  0xf000
189
#define TMDL_ONES_SH    12
190

    
191
#define TMDS_BPE_MASK   0x0080
192
#define TMDS_BPE_SH     7
193
#define TMDS_ENP_MASK   0x0100
194
#define TMDS_ENP_SH     8
195
#define TMDS_STP_MASK   0x0200
196
#define TMDS_STP_SH     9
197
#define TMDS_DEF_MASK   0x0400
198
#define TMDS_DEF_SH     10
199
#define TMDS_ONE_MASK   0x0800
200
#define TMDS_ONE_SH     11
201
#define TMDS_LTINT_MASK 0x1000
202
#define TMDS_LTINT_SH   12
203
#define TMDS_NOFCS_MASK 0x2000
204
#define TMDS_NOFCS_SH   13
205
#define TMDS_ERR_MASK   0x4000
206
#define TMDS_ERR_SH     14
207
#define TMDS_OWN_MASK   0x8000
208
#define TMDS_OWN_SH     15
209

    
210
#define TMDM_TRC_MASK   0x0000000f
211
#define TMDM_TRC_SH     0
212
#define TMDM_TDR_MASK   0x03ff0000
213
#define TMDM_TDR_SH     16
214
#define TMDM_RTRY_MASK  0x04000000
215
#define TMDM_RTRY_SH    26
216
#define TMDM_LCAR_MASK  0x08000000
217
#define TMDM_LCAR_SH    27
218
#define TMDM_LCOL_MASK  0x10000000
219
#define TMDM_LCOL_SH    28
220
#define TMDM_EXDEF_MASK 0x20000000
221
#define TMDM_EXDEF_SH   29
222
#define TMDM_UFLO_MASK  0x40000000
223
#define TMDM_UFLO_SH    30
224
#define TMDM_BUFF_MASK  0x80000000
225
#define TMDM_BUFF_SH    31
226

    
227
struct pcnet_RMD {
228
    uint32_t rbadr;
229
    int16_t buf_length;
230
    int16_t status;
231
    uint32_t msg_length;
232
    uint32_t res;
233
};
234

    
235
#define RMDL_BCNT_MASK  0x0fff
236
#define RMDL_BCNT_SH    0
237
#define RMDL_ONES_MASK  0xf000
238
#define RMDL_ONES_SH    12
239

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

    
265
#define RMDM_MCNT_MASK  0x00000fff
266
#define RMDM_MCNT_SH    0
267
#define RMDM_ZEROS_MASK 0x0000f000
268
#define RMDM_ZEROS_SH   12
269
#define RMDM_RPC_MASK   0x00ff0000
270
#define RMDM_RPC_SH     16
271
#define RMDM_RCC_MASK   0xff000000
272
#define RMDM_RCC_SH     24
273

    
274
#define SET_FIELD(regp, name, field, value)             \
275
  (*(regp) = (*(regp) & ~(name ## _ ## field ## _MASK)) \
276
             | ((value) << name ## _ ## field ## _SH))
277

    
278
#define GET_FIELD(reg, name, field)                     \
279
  (((reg) & name ## _ ## field ## _MASK) >> name ## _ ## field ## _SH)
280

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

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

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

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

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

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

    
467

    
468
#define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
469

    
470
#define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
471

    
472
#define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
473

    
474
#define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
475

    
476
#if 1
477

    
478
#define CHECK_RMD(ADDR,RES) do {                \
479
    struct pcnet_RMD rmd;                       \
480
    RMDLOAD(&rmd,(ADDR));                       \
481
    (RES) |= (GET_FIELD(rmd.buf_length, RMDL, ONES) != 15) \
482
          || (GET_FIELD(rmd.msg_length, RMDM, ZEROS) != 0); \
483
} while (0)
484

    
485
#define CHECK_TMD(ADDR,RES) do {                \
486
    struct pcnet_TMD tmd;                       \
487
    TMDLOAD(&tmd,(ADDR));                       \
488
    (RES) |= (GET_FIELD(tmd.length, TMDL, ONES) != 15); \
489
} while (0)
490

    
491
#else
492

    
493
#define CHECK_RMD(ADDR,RES) do {                \
494
    switch (BCR_SWSTYLE(s)) {                   \
495
    case 0x00:                                  \
496
        do {                                    \
497
            uint16_t rda[4];                    \
498
            s->phys_mem_read(s->dma_opaque, (ADDR), \
499
                (void *)&rda[0], sizeof(rda), 0); \
500
            (RES) |= (rda[2] & 0xf000)!=0xf000; \
501
            (RES) |= (rda[3] & 0xf000)!=0x0000; \
502
        } while (0);                            \
503
        break;                                  \
504
    case 0x01:                                  \
505
    case 0x02:                                  \
506
        do {                                    \
507
            uint32_t rda[4];                    \
508
            s->phys_mem_read(s->dma_opaque, (ADDR), \
509
                (void *)&rda[0], sizeof(rda), 0); \
510
            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
511
            (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
512
        } while (0);                            \
513
        break;                                  \
514
    case 0x03:                                  \
515
        do {                                    \
516
            uint32_t rda[4];                    \
517
            s->phys_mem_read(s->dma_opaque, (ADDR), \
518
                (void *)&rda[0], sizeof(rda), 0); \
519
            (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
520
            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
521
        } while (0);                            \
522
        break;                                  \
523
    }                                           \
524
} while (0)
525

    
526
#define CHECK_TMD(ADDR,RES) do {                \
527
    switch (BCR_SWSTYLE(s)) {                   \
528
    case 0x00:                                  \
529
        do {                                    \
530
            uint16_t xda[4];                    \
531
            s->phys_mem_read(s->dma_opaque, (ADDR), \
532
                (void *)&xda[0], sizeof(xda), 0); \
533
            (RES) |= (xda[2] & 0xf000)!=0xf000; \
534
        } while (0);                            \
535
        break;                                  \
536
    case 0x01:                                  \
537
    case 0x02:                                  \
538
    case 0x03:                                  \
539
        do {                                    \
540
            uint32_t xda[4];                    \
541
            s->phys_mem_read(s->dma_opaque, (ADDR), \
542
                (void *)&xda[0], sizeof(xda), 0); \
543
            (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
544
        } while (0);                            \
545
        break;                                  \
546
    }                                           \
547
} while (0)
548

    
549
#endif
550

    
551
#define PRINT_PKTHDR(BUF) do {                  \
552
    struct qemu_ether_header *hdr = (void *)(BUF); \
553
    printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \
554
           "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \
555
           "type=0x%04x\n",                     \
556
           hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
557
           hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
558
           hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
559
           hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
560
           be16_to_cpu(hdr->ether_type));       \
561
} while (0)
562

    
563
#define MULTICAST_FILTER_LEN 8
564

    
565
static inline uint32_t lnc_mchash(const uint8_t *ether_addr)
566
{
567
#define LNC_POLYNOMIAL          0xEDB88320UL
568
    uint32_t crc = 0xFFFFFFFF;
569
    int idx, bit;
570
    uint8_t data;
571

    
572
    for (idx = 0; idx < 6; idx++) {
573
        for (data = *ether_addr++, bit = 0; bit < MULTICAST_FILTER_LEN; bit++) {
574
            crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LNC_POLYNOMIAL : 0);
575
            data >>= 1;
576
        }
577
    }
578
    return crc;
579
#undef LNC_POLYNOMIAL
580
}
581

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

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

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

    
675
static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size)
676
{
677
    static const uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
678
    struct qemu_ether_header *hdr = (void *)buf;
679
    int result = !CSR_DRCVBC(s) && !memcmp(hdr->ether_dhost, BCAST, 6);
680
#ifdef PCNET_DEBUG_MATCH
681
    printf("padr_bcast result=%d\n", result);
682
#endif
683
    return result;
684
}
685

    
686
static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
687
{
688
    struct qemu_ether_header *hdr = (void *)buf;
689
    if ((*(hdr->ether_dhost)&0x01) &&
690
        ((uint64_t *)&s->csr[8])[0] != 0LL) {
691
        uint8_t ladr[8] = {
692
            s->csr[8] & 0xff, s->csr[8] >> 8,
693
            s->csr[9] & 0xff, s->csr[9] >> 8,
694
            s->csr[10] & 0xff, s->csr[10] >> 8,
695
            s->csr[11] & 0xff, s->csr[11] >> 8
696
        };
697
        int index = lnc_mchash(hdr->ether_dhost) >> 26;
698
        return !!(ladr[index >> 3] & (1 << (index & 7)));
699
    }
700
    return 0;
701
}
702

    
703
static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx)
704
{
705
    while (idx < 1) idx += CSR_RCVRL(s);
706
    return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
707
}
708

    
709
static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
710
{
711
    int64_t next_time = current_time +
712
        muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)),
713
                 ticks_per_sec, 33000000L);
714
    if (next_time <= current_time)
715
        next_time = current_time + 1;
716
    return next_time;
717
}
718

    
719
static void pcnet_poll(PCNetState *s);
720
static void pcnet_poll_timer(void *opaque);
721

    
722
static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
723
static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
724
static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
725
static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
726

    
727
static void pcnet_s_reset(PCNetState *s)
728
{
729
#ifdef PCNET_DEBUG
730
    printf("pcnet_s_reset\n");
731
#endif
732

    
733
    s->lnkst = 0x40;
734
    s->rdra = 0;
735
    s->tdra = 0;
736
    s->rap = 0;
737

    
738
    s->bcr[BCR_BSBC] &= ~0x0080;
739

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

    
769
    s->tx_busy = 0;
770
}
771

    
772
static void pcnet_update_irq(PCNetState *s)
773
{
774
    int isr = 0;
775
    s->csr[0] &= ~0x0080;
776

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

    
797
        isr = CSR_INEA(s);
798
        s->csr[0] |= 0x0080;
799
    }
800

    
801
    if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
802
        s->csr[4] &= ~0x0080;
803
        s->csr[4] |= 0x0040;
804
        s->csr[0] |= 0x0080;
805
        isr = 1;
806
#ifdef PCNET_DEBUG
807
        printf("pcnet user int\n");
808
#endif
809
    }
810

    
811
#if 1
812
    if (((s->csr[5]>>1) & s->csr[5]) & 0x0500)
813
#else
814
    if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
815
        (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
816
#endif
817
    {
818
        isr = 1;
819
        s->csr[0] |= 0x0080;
820
    }
821

    
822
    if (isr != s->isr) {
823
#ifdef PCNET_DEBUG
824
        printf("pcnet: INTA=%d\n", isr);
825
#endif
826
    }
827
    qemu_set_irq(s->irq, isr);
828
    s->isr = isr;
829
}
830

    
831
static void pcnet_init(PCNetState *s)
832
{
833
    int rlen, tlen;
834
    uint16_t padr[3], ladrf[4], mode;
835
    uint32_t rdra, tdra;
836

    
837
#ifdef PCNET_DEBUG
838
    printf("pcnet_init init_addr=0x%08x\n", PHYSADDR(s,CSR_IADR(s)));
839
#endif
840

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

    
877
#if defined(PCNET_DEBUG)
878
    printf("rlen=%d tlen=%d\n", rlen, tlen);
879
#endif
880

    
881
    CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512;
882
    CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512;
883
    s->csr[ 6] = (tlen << 12) | (rlen << 8);
884
    s->csr[15] = mode;
885
    s->csr[ 8] = ladrf[0];
886
    s->csr[ 9] = ladrf[1];
887
    s->csr[10] = ladrf[2];
888
    s->csr[11] = ladrf[3];
889
    s->csr[12] = padr[0];
890
    s->csr[13] = padr[1];
891
    s->csr[14] = padr[2];
892
    s->rdra = PHYSADDR(s, rdra);
893
    s->tdra = PHYSADDR(s, tdra);
894

    
895
    CSR_RCVRC(s) = CSR_RCVRL(s);
896
    CSR_XMTRC(s) = CSR_XMTRL(s);
897

    
898
#ifdef PCNET_DEBUG
899
    printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n",
900
        BCR_SSIZE32(s),
901
        s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
902
#endif
903

    
904
    s->csr[0] |= 0x0101;
905
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
906
}
907

    
908
static void pcnet_start(PCNetState *s)
909
{
910
#ifdef PCNET_DEBUG
911
    printf("pcnet_start\n");
912
#endif
913

    
914
    if (!CSR_DTX(s))
915
        s->csr[0] |= 0x0010;    /* set TXON */
916

    
917
    if (!CSR_DRX(s))
918
        s->csr[0] |= 0x0020;    /* set RXON */
919

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

    
924
static void pcnet_stop(PCNetState *s)
925
{
926
#ifdef PCNET_DEBUG
927
    printf("pcnet_stop\n");
928
#endif
929
    s->csr[0] &= ~0x7feb;
930
    s->csr[0] |= 0x0014;
931
    s->csr[4] &= ~0x02c2;
932
    s->csr[5] &= ~0x0011;
933
    pcnet_poll_timer(s);
934
}
935

    
936
static void pcnet_rdte_poll(PCNetState *s)
937
{
938
    s->csr[28] = s->csr[29] = 0;
939
    if (s->rdra) {
940
        int bad = 0;
941
#if 1
942
        target_phys_addr_t crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
943
        target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
944
        target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
945
#else
946
        target_phys_addr_t crda = s->rdra +
947
            (CSR_RCVRL(s) - CSR_RCVRC(s)) *
948
            (BCR_SWSTYLE(s) ? 16 : 8 );
949
        int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
950
        target_phys_addr_t nrda = s->rdra +
951
            (CSR_RCVRL(s) - nrdc) *
952
            (BCR_SWSTYLE(s) ? 16 : 8 );
953
        int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
954
        target_phys_addr_t nnrd = s->rdra +
955
            (CSR_RCVRL(s) - nnrc) *
956
            (BCR_SWSTYLE(s) ? 16 : 8 );
957
#endif
958

    
959
        CHECK_RMD(PHYSADDR(s,crda), bad);
960
        if (!bad) {
961
            CHECK_RMD(PHYSADDR(s,nrda), bad);
962
            if (bad || (nrda == crda)) nrda = 0;
963
            CHECK_RMD(PHYSADDR(s,nnrd), bad);
964
            if (bad || (nnrd == crda)) nnrd = 0;
965

    
966
            s->csr[28] = crda & 0xffff;
967
            s->csr[29] = crda >> 16;
968
            s->csr[26] = nrda & 0xffff;
969
            s->csr[27] = nrda >> 16;
970
            s->csr[36] = nnrd & 0xffff;
971
            s->csr[37] = nnrd >> 16;
972
#ifdef PCNET_DEBUG
973
            if (bad) {
974
                printf("pcnet: BAD RMD RECORDS AFTER 0x%08x\n",
975
                       PHYSADDR(s,crda));
976
            }
977
        } else {
978
            printf("pcnet: BAD RMD RDA=0x%08x\n", PHYSADDR(s,crda));
979
#endif
980
        }
981
    }
982

    
983
    if (CSR_CRDA(s)) {
984
        struct pcnet_RMD rmd;
985
        RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
986
        CSR_CRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
987
        CSR_CRST(s) = rmd.status;
988
#ifdef PCNET_DEBUG_RMD_X
989
        printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMDL=0x%04x RMDS=0x%04x RMDM=0x%08x\n",
990
                PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
991
                rmd.buf_length, rmd.status, rmd.msg_length);
992
        PRINT_RMD(&rmd);
993
#endif
994
    } else {
995
        CSR_CRBC(s) = CSR_CRST(s) = 0;
996
    }
997

    
998
    if (CSR_NRDA(s)) {
999
        struct pcnet_RMD rmd;
1000
        RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
1001
        CSR_NRBC(s) = GET_FIELD(rmd.buf_length, RMDL, BCNT);
1002
        CSR_NRST(s) = rmd.status;
1003
    } else {
1004
        CSR_NRBC(s) = CSR_NRST(s) = 0;
1005
    }
1006

    
1007
}
1008

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

    
1033
    if (CSR_CXDA(s)) {
1034
        struct pcnet_TMD tmd;
1035

    
1036
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1037

    
1038
        CSR_CXBC(s) = GET_FIELD(tmd.length, TMDL, BCNT);
1039
        CSR_CXST(s) = tmd.status;
1040
    } else {
1041
        CSR_CXBC(s) = CSR_CXST(s) = 0;
1042
    }
1043

    
1044
    return !!(CSR_CXST(s) & 0x8000);
1045
}
1046

    
1047
static int pcnet_can_receive(void *opaque)
1048
{
1049
    PCNetState *s = opaque;
1050
    if (CSR_STOP(s) || CSR_SPND(s))
1051
        return 0;
1052

    
1053
    if (s->recv_pos > 0)
1054
        return 0;
1055

    
1056
    return sizeof(s->buffer)-16;
1057
}
1058

    
1059
#define MIN_BUF_SIZE 60
1060

    
1061
static void pcnet_receive(void *opaque, const uint8_t *buf, int size)
1062
{
1063
    PCNetState *s = opaque;
1064
    int is_padr = 0, is_bcast = 0, is_ladr = 0;
1065
    uint8_t buf1[60];
1066

    
1067
    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
1068
        return;
1069

    
1070
#ifdef PCNET_DEBUG
1071
    printf("pcnet_receive size=%d\n", size);
1072
#endif
1073

    
1074
    /* if too small buffer, then expand it */
1075
    if (size < MIN_BUF_SIZE) {
1076
        memcpy(buf1, buf, size);
1077
        memset(buf1 + size, 0, MIN_BUF_SIZE - size);
1078
        buf = buf1;
1079
        size = MIN_BUF_SIZE;
1080
    }
1081

    
1082
    if (CSR_PROM(s)
1083
        || (is_padr=padr_match(s, buf, size))
1084
        || (is_bcast=padr_bcast(s, buf, size))
1085
        || (is_ladr=ladr_match(s, buf, size))) {
1086

    
1087
        pcnet_rdte_poll(s);
1088

    
1089
        if (!(CSR_CRST(s) & 0x8000) && s->rdra) {
1090
            struct pcnet_RMD rmd;
1091
            int rcvrc = CSR_RCVRC(s)-1,i;
1092
            target_phys_addr_t nrda;
1093
            for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {
1094
                if (rcvrc <= 1)
1095
                    rcvrc = CSR_RCVRL(s);
1096
                nrda = s->rdra +
1097
                    (CSR_RCVRL(s) - rcvrc) *
1098
                    (BCR_SWSTYLE(s) ? 16 : 8 );
1099
                RMDLOAD(&rmd, PHYSADDR(s,nrda));
1100
                if (GET_FIELD(rmd.status, RMDS, OWN)) {
1101
#ifdef PCNET_DEBUG_RMD
1102
                    printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",
1103
                                rcvrc, CSR_RCVRC(s));
1104
#endif
1105
                    CSR_RCVRC(s) = rcvrc;
1106
                    pcnet_rdte_poll(s);
1107
                    break;
1108
                }
1109
            }
1110
        }
1111

    
1112
        if (!(CSR_CRST(s) & 0x8000)) {
1113
#ifdef PCNET_DEBUG_RMD
1114
            printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));
1115
#endif
1116
            s->csr[0] |= 0x1000; /* Set MISS flag */
1117
            CSR_MISSC(s)++;
1118
        } else {
1119
            uint8_t *src = &s->buffer[8];
1120
            target_phys_addr_t crda = CSR_CRDA(s);
1121
            struct pcnet_RMD rmd;
1122
            int pktcount = 0;
1123

    
1124
            memcpy(src, buf, size);
1125

    
1126
#if 1
1127
            /* no need to compute the CRC */
1128
            src[size] = 0;
1129
            src[size + 1] = 0;
1130
            src[size + 2] = 0;
1131
            src[size + 3] = 0;
1132
            size += 4;
1133
#else
1134
            /* XXX: avoid CRC generation */
1135
            if (!CSR_ASTRP_RCV(s)) {
1136
                uint32_t fcs = ~0;
1137
                uint8_t *p = src;
1138

    
1139
                while (size < 46) {
1140
                    src[size++] = 0;
1141
                }
1142

    
1143
                while (p != &src[size]) {
1144
                    CRC(fcs, *p++);
1145
                }
1146
                ((uint32_t *)&src[size])[0] = htonl(fcs);
1147
                size += 4; /* FCS at end of packet */
1148
            } else size += 4;
1149
#endif
1150

    
1151
#ifdef PCNET_DEBUG_MATCH
1152
            PRINT_PKTHDR(buf);
1153
#endif
1154

    
1155
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1156
            /*if (!CSR_LAPPEN(s))*/
1157
                SET_FIELD(&rmd.status, RMDS, STP, 1);
1158

    
1159
#define PCNET_RECV_STORE() do {                                 \
1160
    int count = MIN(4096 - GET_FIELD(rmd.buf_length, RMDL, BCNT),size); \
1161
    target_phys_addr_t rbadr = PHYSADDR(s, rmd.rbadr);          \
1162
    s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \
1163
    src += count; size -= count;                                \
1164
    SET_FIELD(&rmd.msg_length, RMDM, MCNT, count);              \
1165
    SET_FIELD(&rmd.status, RMDS, OWN, 0);                       \
1166
    RMDSTORE(&rmd, PHYSADDR(s,crda));                           \
1167
    pktcount++;                                                 \
1168
} while (0)
1169

    
1170
            PCNET_RECV_STORE();
1171
            if ((size > 0) && CSR_NRDA(s)) {
1172
                target_phys_addr_t nrda = CSR_NRDA(s);
1173
                RMDLOAD(&rmd, PHYSADDR(s,nrda));
1174
                if (GET_FIELD(rmd.status, RMDS, OWN)) {
1175
                    crda = nrda;
1176
                    PCNET_RECV_STORE();
1177
                    if ((size > 0) && (nrda=CSR_NNRD(s))) {
1178
                        RMDLOAD(&rmd, PHYSADDR(s,nrda));
1179
                        if (GET_FIELD(rmd.status, RMDS, OWN)) {
1180
                            crda = nrda;
1181
                            PCNET_RECV_STORE();
1182
                        }
1183
                    }
1184
                }
1185
            }
1186

    
1187
#undef PCNET_RECV_STORE
1188

    
1189
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1190
            if (size == 0) {
1191
                SET_FIELD(&rmd.status, RMDS, ENP, 1);
1192
                SET_FIELD(&rmd.status, RMDS, PAM, !CSR_PROM(s) && is_padr);
1193
                SET_FIELD(&rmd.status, RMDS, LFAM, !CSR_PROM(s) && is_ladr);
1194
                SET_FIELD(&rmd.status, RMDS, BAM, !CSR_PROM(s) && is_bcast);
1195
            } else {
1196
                SET_FIELD(&rmd.status, RMDS, OFLO, 1);
1197
                SET_FIELD(&rmd.status, RMDS, BUFF, 1);
1198
                SET_FIELD(&rmd.status, RMDS, ERR, 1);
1199
            }
1200
            RMDSTORE(&rmd, PHYSADDR(s,crda));
1201
            s->csr[0] |= 0x0400;
1202

    
1203
#ifdef PCNET_DEBUG
1204
            printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",
1205
                CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
1206
#endif
1207
#ifdef PCNET_DEBUG_RMD
1208
            PRINT_RMD(&rmd);
1209
#endif
1210

    
1211
            while (pktcount--) {
1212
                if (CSR_RCVRC(s) <= 1)
1213
                    CSR_RCVRC(s) = CSR_RCVRL(s);
1214
                else
1215
                    CSR_RCVRC(s)--;
1216
            }
1217

    
1218
            pcnet_rdte_poll(s);
1219

    
1220
        }
1221
    }
1222

    
1223
    pcnet_poll(s);
1224
    pcnet_update_irq(s);
1225
}
1226

    
1227
static void pcnet_transmit(PCNetState *s)
1228
{
1229
    target_phys_addr_t xmit_cxda = 0;
1230
    int count = CSR_XMTRL(s)-1;
1231
    s->xmit_pos = -1;
1232

    
1233
    if (!CSR_TXON(s)) {
1234
        s->csr[0] &= ~0x0008;
1235
        return;
1236
    }
1237

    
1238
    s->tx_busy = 1;
1239

    
1240
    txagain:
1241
    if (pcnet_tdte_poll(s)) {
1242
        struct pcnet_TMD tmd;
1243

    
1244
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1245

    
1246
#ifdef PCNET_DEBUG_TMD
1247
        printf("  TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
1248
        PRINT_TMD(&tmd);
1249
#endif
1250
        if (GET_FIELD(tmd.status, TMDS, STP)) {
1251
            s->xmit_pos = 0;
1252
            if (!GET_FIELD(tmd.status, TMDS, ENP)) {
1253
                int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
1254
                s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
1255
                                 s->buffer, bcnt, CSR_BSWP(s));
1256
                s->xmit_pos += bcnt;
1257
            }
1258
            xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
1259
        }
1260
        if (GET_FIELD(tmd.status, TMDS, ENP) && (s->xmit_pos >= 0)) {
1261
            int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
1262
            s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
1263
                             s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
1264
            s->xmit_pos += bcnt;
1265
#ifdef PCNET_DEBUG
1266
            printf("pcnet_transmit size=%d\n", s->xmit_pos);
1267
#endif
1268
            if (CSR_LOOP(s))
1269
                pcnet_receive(s, s->buffer, s->xmit_pos);
1270
            else
1271
                if (s->vc)
1272
                    qemu_send_packet(s->vc, s->buffer, s->xmit_pos);
1273

    
1274
            s->csr[0] &= ~0x0008;   /* clear TDMD */
1275
            s->csr[4] |= 0x0004;    /* set TXSTRT */
1276
            s->xmit_pos = -1;
1277
        }
1278

    
1279
        SET_FIELD(&tmd.status, TMDS, OWN, 0);
1280
        TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1281
        if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT)))
1282
            s->csr[0] |= 0x0200;    /* set TINT */
1283

    
1284
        if (CSR_XMTRC(s)<=1)
1285
            CSR_XMTRC(s) = CSR_XMTRL(s);
1286
        else
1287
            CSR_XMTRC(s)--;
1288
        if (count--)
1289
            goto txagain;
1290

    
1291
    } else
1292
    if (s->xmit_pos >= 0) {
1293
        struct pcnet_TMD tmd;
1294
        TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));
1295
        SET_FIELD(&tmd.misc, TMDM, BUFF, 1);
1296
        SET_FIELD(&tmd.misc, TMDM, UFLO, 1);
1297
        SET_FIELD(&tmd.status, TMDS, ERR, 1);
1298
        SET_FIELD(&tmd.status, TMDS, OWN, 0);
1299
        TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda));
1300
        s->csr[0] |= 0x0200;    /* set TINT */
1301
        if (!CSR_DXSUFLO(s)) {
1302
            s->csr[0] &= ~0x0010;
1303
        } else
1304
        if (count--)
1305
          goto txagain;
1306
    }
1307

    
1308
    s->tx_busy = 0;
1309
}
1310

    
1311
static void pcnet_poll(PCNetState *s)
1312
{
1313
    if (CSR_RXON(s)) {
1314
        pcnet_rdte_poll(s);
1315
    }
1316

    
1317
    if (CSR_TDMD(s) ||
1318
        (CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s)))
1319
    {
1320
        /* prevent recursion */
1321
        if (s->tx_busy)
1322
            return;
1323

    
1324
        pcnet_transmit(s);
1325
    }
1326
}
1327

    
1328
static void pcnet_poll_timer(void *opaque)
1329
{
1330
    PCNetState *s = opaque;
1331

    
1332
    qemu_del_timer(s->poll_timer);
1333

    
1334
    if (CSR_TDMD(s)) {
1335
        pcnet_transmit(s);
1336
    }
1337

    
1338
    pcnet_update_irq(s);
1339

    
1340
    if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
1341
        uint64_t now = qemu_get_clock(vm_clock) * 33;
1342
        if (!s->timer || !now)
1343
            s->timer = now;
1344
        else {
1345
            uint64_t t = now - s->timer + CSR_POLL(s);
1346
            if (t > 0xffffLL) {
1347
                pcnet_poll(s);
1348
                CSR_POLL(s) = CSR_PINT(s);
1349
            } else
1350
                CSR_POLL(s) = t;
1351
        }
1352
        qemu_mod_timer(s->poll_timer,
1353
            pcnet_get_next_poll_time(s,qemu_get_clock(vm_clock)));
1354
    }
1355
}
1356

    
1357

    
1358
static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value)
1359
{
1360
    uint16_t val = new_value;
1361
#ifdef PCNET_DEBUG_CSR
1362
    printf("pcnet_csr_writew rap=%d val=0x%04x\n", rap, val);
1363
#endif
1364
    switch (rap) {
1365
    case 0:
1366
        s->csr[0] &= ~(val & 0x7f00); /* Clear any interrupt flags */
1367

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

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

    
1372
        /* IFF STOP, STRT and INIT are set, clear STRT and INIT */
1373
        if ((val&7) == 7)
1374
          val &= ~3;
1375

    
1376
        if (!CSR_STOP(s) && (val & 4))
1377
            pcnet_stop(s);
1378

    
1379
        if (!CSR_INIT(s) && (val & 1))
1380
            pcnet_init(s);
1381

    
1382
        if (!CSR_STRT(s) && (val & 2))
1383
            pcnet_start(s);
1384

    
1385
        if (CSR_TDMD(s))
1386
            pcnet_transmit(s);
1387

    
1388
        return;
1389
    case 1:
1390
    case 2:
1391
    case 8:
1392
    case 9:
1393
    case 10:
1394
    case 11:
1395
    case 12:
1396
    case 13:
1397
    case 14:
1398
    case 15:
1399
    case 18: /* CRBAL */
1400
    case 19: /* CRBAU */
1401
    case 20: /* CXBAL */
1402
    case 21: /* CXBAU */
1403
    case 22: /* NRBAU */
1404
    case 23: /* NRBAU */
1405
    case 24:
1406
    case 25:
1407
    case 26:
1408
    case 27:
1409
    case 28:
1410
    case 29:
1411
    case 30:
1412
    case 31:
1413
    case 32:
1414
    case 33:
1415
    case 34:
1416
    case 35:
1417
    case 36:
1418
    case 37:
1419
    case 38:
1420
    case 39:
1421
    case 40: /* CRBC */
1422
    case 41:
1423
    case 42: /* CXBC */
1424
    case 43:
1425
    case 44:
1426
    case 45:
1427
    case 46: /* POLL */
1428
    case 47: /* POLLINT */
1429
    case 72:
1430
    case 74:
1431
    case 76: /* RCVRL */
1432
    case 78: /* XMTRL */
1433
    case 112:
1434
       if (CSR_STOP(s) || CSR_SPND(s))
1435
           break;
1436
       return;
1437
    case 3:
1438
        break;
1439
    case 4:
1440
        s->csr[4] &= ~(val & 0x026a);
1441
        val &= ~0x026a; val |= s->csr[4] & 0x026a;
1442
        break;
1443
    case 5:
1444
        s->csr[5] &= ~(val & 0x0a90);
1445
        val &= ~0x0a90; val |= s->csr[5] & 0x0a90;
1446
        break;
1447
    case 16:
1448
        pcnet_csr_writew(s,1,val);
1449
        return;
1450
    case 17:
1451
        pcnet_csr_writew(s,2,val);
1452
        return;
1453
    case 58:
1454
        pcnet_bcr_writew(s,BCR_SWS,val);
1455
        break;
1456
    default:
1457
        return;
1458
    }
1459
    s->csr[rap] = val;
1460
}
1461

    
1462
static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap)
1463
{
1464
    uint32_t val;
1465
    switch (rap) {
1466
    case 0:
1467
        pcnet_update_irq(s);
1468
        val = s->csr[0];
1469
        val |= (val & 0x7800) ? 0x8000 : 0;
1470
        break;
1471
    case 16:
1472
        return pcnet_csr_readw(s,1);
1473
    case 17:
1474
        return pcnet_csr_readw(s,2);
1475
    case 58:
1476
        return pcnet_bcr_readw(s,BCR_SWS);
1477
    case 88:
1478
        val = s->csr[89];
1479
        val <<= 16;
1480
        val |= s->csr[88];
1481
        break;
1482
    default:
1483
        val = s->csr[rap];
1484
    }
1485
#ifdef PCNET_DEBUG_CSR
1486
    printf("pcnet_csr_readw rap=%d val=0x%04x\n", rap, val);
1487
#endif
1488
    return val;
1489
}
1490

    
1491
static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val)
1492
{
1493
    rap &= 127;
1494
#ifdef PCNET_DEBUG_BCR
1495
    printf("pcnet_bcr_writew rap=%d val=0x%04x\n", rap, val);
1496
#endif
1497
    switch (rap) {
1498
    case BCR_SWS:
1499
        if (!(CSR_STOP(s) || CSR_SPND(s)))
1500
            return;
1501
        val &= ~0x0300;
1502
        switch (val & 0x00ff) {
1503
        case 0:
1504
            val |= 0x0200;
1505
            break;
1506
        case 1:
1507
            val |= 0x0100;
1508
            break;
1509
        case 2:
1510
        case 3:
1511
            val |= 0x0300;
1512
            break;
1513
        default:
1514
            printf("Bad SWSTYLE=0x%02x\n", val & 0xff);
1515
            val = 0x0200;
1516
            break;
1517
        }
1518
#ifdef PCNET_DEBUG
1519
       printf("BCR_SWS=0x%04x\n", val);
1520
#endif
1521
    case BCR_LNKST:
1522
    case BCR_LED1:
1523
    case BCR_LED2:
1524
    case BCR_LED3:
1525
    case BCR_MC:
1526
    case BCR_FDC:
1527
    case BCR_BSBC:
1528
    case BCR_EECAS:
1529
    case BCR_PLAT:
1530
        s->bcr[rap] = val;
1531
        break;
1532
    default:
1533
        break;
1534
    }
1535
}
1536

    
1537
static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap)
1538
{
1539
    uint32_t val;
1540
    rap &= 127;
1541
    switch (rap) {
1542
    case BCR_LNKST:
1543
    case BCR_LED1:
1544
    case BCR_LED2:
1545
    case BCR_LED3:
1546
        val = s->bcr[rap] & ~0x8000;
1547
        val |= (val & 0x017f & s->lnkst) ? 0x8000 : 0;
1548
        break;
1549
    default:
1550
        val = rap < 32 ? s->bcr[rap] : 0;
1551
        break;
1552
    }
1553
#ifdef PCNET_DEBUG_BCR
1554
    printf("pcnet_bcr_readw rap=%d val=0x%04x\n", rap, val);
1555
#endif
1556
    return val;
1557
}
1558

    
1559
static void pcnet_h_reset(void *opaque)
1560
{
1561
    PCNetState *s = opaque;
1562
    int i;
1563
    uint16_t checksum;
1564

    
1565
    /* Initialize the PROM */
1566

    
1567
    if (s->nd)
1568
        memcpy(s->prom, s->nd->macaddr, 6);
1569
    s->prom[12] = s->prom[13] = 0x00;
1570
    s->prom[14] = s->prom[15] = 0x57;
1571

    
1572
    for (i = 0,checksum = 0; i < 16; i++)
1573
        checksum += s->prom[i];
1574
    *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);
1575

    
1576

    
1577
    s->bcr[BCR_MSRDA] = 0x0005;
1578
    s->bcr[BCR_MSWRA] = 0x0005;
1579
    s->bcr[BCR_MC   ] = 0x0002;
1580
    s->bcr[BCR_LNKST] = 0x00c0;
1581
    s->bcr[BCR_LED1 ] = 0x0084;
1582
    s->bcr[BCR_LED2 ] = 0x0088;
1583
    s->bcr[BCR_LED3 ] = 0x0090;
1584
    s->bcr[BCR_FDC  ] = 0x0000;
1585
    s->bcr[BCR_BSBC ] = 0x9001;
1586
    s->bcr[BCR_EECAS] = 0x0002;
1587
    s->bcr[BCR_SWS  ] = 0x0200;
1588
    s->bcr[BCR_PLAT ] = 0xff06;
1589

    
1590
    pcnet_s_reset(s);
1591
}
1592

    
1593
static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
1594
{
1595
    PCNetState *s = opaque;
1596
#ifdef PCNET_DEBUG
1597
    printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);
1598
#endif
1599
    /* Check APROMWE bit to enable write access */
1600
    if (pcnet_bcr_readw(s,2) & 0x80)
1601
        s->prom[addr & 15] = val;
1602
}
1603

    
1604
static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
1605
{
1606
    PCNetState *s = opaque;
1607
    uint32_t val = s->prom[addr &= 15];
1608
#ifdef PCNET_DEBUG
1609
    printf("pcnet_aprom_readb addr=0x%08x val=0x%02x\n", addr, val);
1610
#endif
1611
    return val;
1612
}
1613

    
1614
static void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
1615
{
1616
    PCNetState *s = opaque;
1617
    pcnet_poll_timer(s);
1618
#ifdef PCNET_DEBUG_IO
1619
    printf("pcnet_ioport_writew addr=0x%08x val=0x%04x\n", addr, val);
1620
#endif
1621
    if (!BCR_DWIO(s)) {
1622
        switch (addr & 0x0f) {
1623
        case 0x00: /* RDP */
1624
            pcnet_csr_writew(s, s->rap, val);
1625
            break;
1626
        case 0x02:
1627
            s->rap = val & 0x7f;
1628
            break;
1629
        case 0x06:
1630
            pcnet_bcr_writew(s, s->rap, val);
1631
            break;
1632
        }
1633
    }
1634
    pcnet_update_irq(s);
1635
}
1636

    
1637
static uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr)
1638
{
1639
    PCNetState *s = opaque;
1640
    uint32_t val = -1;
1641
    pcnet_poll_timer(s);
1642
    if (!BCR_DWIO(s)) {
1643
        switch (addr & 0x0f) {
1644
        case 0x00: /* RDP */
1645
            val = pcnet_csr_readw(s, s->rap);
1646
            break;
1647
        case 0x02:
1648
            val = s->rap;
1649
            break;
1650
        case 0x04:
1651
            pcnet_s_reset(s);
1652
            val = 0;
1653
            break;
1654
        case 0x06:
1655
            val = pcnet_bcr_readw(s, s->rap);
1656
            break;
1657
        }
1658
    }
1659
    pcnet_update_irq(s);
1660
#ifdef PCNET_DEBUG_IO
1661
    printf("pcnet_ioport_readw addr=0x%08x val=0x%04x\n", addr, val & 0xffff);
1662
#endif
1663
    return val;
1664
}
1665

    
1666
static void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
1667
{
1668
    PCNetState *s = opaque;
1669
    pcnet_poll_timer(s);
1670
#ifdef PCNET_DEBUG_IO
1671
    printf("pcnet_ioport_writel addr=0x%08x val=0x%08x\n", addr, val);
1672
#endif
1673
    if (BCR_DWIO(s)) {
1674
        switch (addr & 0x0f) {
1675
        case 0x00: /* RDP */
1676
            pcnet_csr_writew(s, s->rap, val & 0xffff);
1677
            break;
1678
        case 0x04:
1679
            s->rap = val & 0x7f;
1680
            break;
1681
        case 0x0c:
1682
            pcnet_bcr_writew(s, s->rap, val & 0xffff);
1683
            break;
1684
        }
1685
    } else
1686
    if ((addr & 0x0f) == 0) {
1687
        /* switch device to dword i/o mode */
1688
        pcnet_bcr_writew(s, BCR_BSBC, pcnet_bcr_readw(s, BCR_BSBC) | 0x0080);
1689
#ifdef PCNET_DEBUG_IO
1690
        printf("device switched into dword i/o mode\n");
1691
#endif
1692
    }
1693
    pcnet_update_irq(s);
1694
}
1695

    
1696
static uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr)
1697
{
1698
    PCNetState *s = opaque;
1699
    uint32_t val = -1;
1700
    pcnet_poll_timer(s);
1701
    if (BCR_DWIO(s)) {
1702
        switch (addr & 0x0f) {
1703
        case 0x00: /* RDP */
1704
            val = pcnet_csr_readw(s, s->rap);
1705
            break;
1706
        case 0x04:
1707
            val = s->rap;
1708
            break;
1709
        case 0x08:
1710
            pcnet_s_reset(s);
1711
            val = 0;
1712
            break;
1713
        case 0x0c:
1714
            val = pcnet_bcr_readw(s, s->rap);
1715
            break;
1716
        }
1717
    }
1718
    pcnet_update_irq(s);
1719
#ifdef PCNET_DEBUG_IO
1720
    printf("pcnet_ioport_readl addr=0x%08x val=0x%08x\n", addr, val);
1721
#endif
1722
    return val;
1723
}
1724

    
1725
static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
1726
                             uint32_t addr, uint32_t size, int type)
1727
{
1728
    PCNetState *d = (PCNetState *)pci_dev;
1729

    
1730
#ifdef PCNET_DEBUG_IO
1731
    printf("pcnet_ioport_map addr=0x%04x size=0x%04x\n", addr, size);
1732
#endif
1733

    
1734
    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
1735
    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
1736

    
1737
    register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
1738
    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
1739
    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
1740
    register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
1741
}
1742

    
1743
static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
1744
{
1745
    PCNetState *d = opaque;
1746
#ifdef PCNET_DEBUG_IO
1747
    printf("pcnet_mmio_writeb addr=0x%08x val=0x%02x\n", addr, val);
1748
#endif
1749
    if (!(addr & 0x10))
1750
        pcnet_aprom_writeb(d, addr & 0x0f, val);
1751
}
1752

    
1753
static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr)
1754
{
1755
    PCNetState *d = opaque;
1756
    uint32_t val = -1;
1757
    if (!(addr & 0x10))
1758
        val = pcnet_aprom_readb(d, addr & 0x0f);
1759
#ifdef PCNET_DEBUG_IO
1760
    printf("pcnet_mmio_readb addr=0x%08x val=0x%02x\n", addr, val & 0xff);
1761
#endif
1762
    return val;
1763
}
1764

    
1765
static void pcnet_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
1766
{
1767
    PCNetState *d = opaque;
1768
#ifdef PCNET_DEBUG_IO
1769
    printf("pcnet_mmio_writew addr=0x%08x val=0x%04x\n", addr, val);
1770
#endif
1771
    if (addr & 0x10)
1772
        pcnet_ioport_writew(d, addr & 0x0f, val);
1773
    else {
1774
        addr &= 0x0f;
1775
        pcnet_aprom_writeb(d, addr, val & 0xff);
1776
        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
1777
    }
1778
}
1779

    
1780
static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr)
1781
{
1782
    PCNetState *d = opaque;
1783
    uint32_t val = -1;
1784
    if (addr & 0x10)
1785
        val = pcnet_ioport_readw(d, addr & 0x0f);
1786
    else {
1787
        addr &= 0x0f;
1788
        val = pcnet_aprom_readb(d, addr+1);
1789
        val <<= 8;
1790
        val |= pcnet_aprom_readb(d, addr);
1791
    }
1792
#ifdef PCNET_DEBUG_IO
1793
    printf("pcnet_mmio_readw addr=0x%08x val = 0x%04x\n", addr, val & 0xffff);
1794
#endif
1795
    return val;
1796
}
1797

    
1798
static void pcnet_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
1799
{
1800
    PCNetState *d = opaque;
1801
#ifdef PCNET_DEBUG_IO
1802
    printf("pcnet_mmio_writel addr=0x%08x val=0x%08x\n", addr, val);
1803
#endif
1804
    if (addr & 0x10)
1805
        pcnet_ioport_writel(d, addr & 0x0f, val);
1806
    else {
1807
        addr &= 0x0f;
1808
        pcnet_aprom_writeb(d, addr, val & 0xff);
1809
        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
1810
        pcnet_aprom_writeb(d, addr+2, (val & 0xff0000) >> 16);
1811
        pcnet_aprom_writeb(d, addr+3, (val & 0xff000000) >> 24);
1812
    }
1813
}
1814

    
1815
static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr)
1816
{
1817
    PCNetState *d = opaque;
1818
    uint32_t val;
1819
    if (addr & 0x10)
1820
        val = pcnet_ioport_readl(d, addr & 0x0f);
1821
    else {
1822
        addr &= 0x0f;
1823
        val = pcnet_aprom_readb(d, addr+3);
1824
        val <<= 8;
1825
        val |= pcnet_aprom_readb(d, addr+2);
1826
        val <<= 8;
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_readl addr=0x%08x val=0x%08x\n", addr, val);
1833
#endif
1834
    return val;
1835
}
1836

    
1837

    
1838
static void pcnet_save(QEMUFile *f, void *opaque)
1839
{
1840
    PCNetState *s = opaque;
1841
    unsigned int i;
1842

    
1843
    if (s->pci_dev)
1844
        pci_device_save(s->pci_dev, f);
1845

    
1846
    qemu_put_be32(f, s->rap);
1847
    qemu_put_be32(f, s->isr);
1848
    qemu_put_be32(f, s->lnkst);
1849
    qemu_put_be32s(f, &s->rdra);
1850
    qemu_put_be32s(f, &s->tdra);
1851
    qemu_put_buffer(f, s->prom, 16);
1852
    for (i = 0; i < 128; i++)
1853
        qemu_put_be16s(f, &s->csr[i]);
1854
    for (i = 0; i < 32; i++)
1855
        qemu_put_be16s(f, &s->bcr[i]);
1856
    qemu_put_be64s(f, &s->timer);
1857
    qemu_put_be32(f, s->xmit_pos);
1858
    qemu_put_be32(f, s->recv_pos);
1859
    qemu_put_buffer(f, s->buffer, 4096);
1860
    qemu_put_be32(f, s->tx_busy);
1861
    qemu_put_timer(f, s->poll_timer);
1862
}
1863

    
1864
static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
1865
{
1866
    PCNetState *s = opaque;
1867
    int i, ret;
1868

    
1869
    if (version_id != 2)
1870
        return -EINVAL;
1871

    
1872
    if (s->pci_dev) {
1873
        ret = pci_device_load(s->pci_dev, f);
1874
        if (ret < 0)
1875
            return ret;
1876
    }
1877

    
1878
    qemu_get_be32s(f, (uint32_t*)&s->rap);
1879
    qemu_get_be32s(f, (uint32_t*)&s->isr);
1880
    qemu_get_be32s(f, (uint32_t*)&s->lnkst);
1881
    qemu_get_be32s(f, &s->rdra);
1882
    qemu_get_be32s(f, &s->tdra);
1883
    qemu_get_buffer(f, s->prom, 16);
1884
    for (i = 0; i < 128; i++)
1885
        qemu_get_be16s(f, &s->csr[i]);
1886
    for (i = 0; i < 32; i++)
1887
        qemu_get_be16s(f, &s->bcr[i]);
1888
    qemu_get_be64s(f, &s->timer);
1889
    qemu_get_be32s(f, (uint32_t*)&s->xmit_pos);
1890
    qemu_get_be32s(f, (uint32_t*)&s->recv_pos);
1891
    qemu_get_buffer(f, s->buffer, 4096);
1892
    qemu_get_be32s(f, (uint32_t*)&s->tx_busy);
1893
    qemu_get_timer(f, s->poll_timer);
1894

    
1895
    return 0;
1896
}
1897

    
1898
static void pcnet_common_init(PCNetState *d, NICInfo *nd, const char *info_str)
1899
{
1900
    d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d);
1901

    
1902
    d->nd = nd;
1903

    
1904
    if (nd && nd->vlan) {
1905
        d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive,
1906
                                     pcnet_can_receive, d);
1907

    
1908
        snprintf(d->vc->info_str, sizeof(d->vc->info_str),
1909
                 "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
1910
                 d->nd->macaddr[0],
1911
                 d->nd->macaddr[1],
1912
                 d->nd->macaddr[2],
1913
                 d->nd->macaddr[3],
1914
                 d->nd->macaddr[4],
1915
                 d->nd->macaddr[5]);
1916
    } else {
1917
        d->vc = NULL;
1918
    }
1919
    pcnet_h_reset(d);
1920
    register_savevm("pcnet", 0, 2, pcnet_save, pcnet_load, d);
1921
}
1922

    
1923
/* PCI interface */
1924

    
1925
static CPUWriteMemoryFunc *pcnet_mmio_write[] = {
1926
    (CPUWriteMemoryFunc *)&pcnet_mmio_writeb,
1927
    (CPUWriteMemoryFunc *)&pcnet_mmio_writew,
1928
    (CPUWriteMemoryFunc *)&pcnet_mmio_writel
1929
};
1930

    
1931
static CPUReadMemoryFunc *pcnet_mmio_read[] = {
1932
    (CPUReadMemoryFunc *)&pcnet_mmio_readb,
1933
    (CPUReadMemoryFunc *)&pcnet_mmio_readw,
1934
    (CPUReadMemoryFunc *)&pcnet_mmio_readl
1935
};
1936

    
1937
static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
1938
                            uint32_t addr, uint32_t size, int type)
1939
{
1940
    PCNetState *d = (PCNetState *)pci_dev;
1941

    
1942
#ifdef PCNET_DEBUG_IO
1943
    printf("pcnet_ioport_map addr=0x%08x 0x%08x\n", addr, size);
1944
#endif
1945

    
1946
    cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_index);
1947
}
1948

    
1949
static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
1950
                                      uint8_t *buf, int len, int do_bswap)
1951
{
1952
    cpu_physical_memory_write(addr, buf, len);
1953
}
1954

    
1955
static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
1956
                                     uint8_t *buf, int len, int do_bswap)
1957
{
1958
    cpu_physical_memory_read(addr, buf, len);
1959
}
1960

    
1961
void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
1962
{
1963
    PCNetState *d;
1964
    uint8_t *pci_conf;
1965

    
1966
#if 0
1967
    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
1968
        sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
1969
#endif
1970

    
1971
    d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
1972
                                          devfn, NULL, NULL);
1973

    
1974
    pci_conf = d->dev.config;
1975

    
1976
    *(uint16_t *)&pci_conf[0x00] = cpu_to_le16(0x1022);
1977
    *(uint16_t *)&pci_conf[0x02] = cpu_to_le16(0x2000);
1978
    *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007);
1979
    *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
1980
    pci_conf[0x08] = 0x10;
1981
    pci_conf[0x09] = 0x00;
1982
    pci_conf[0x0a] = 0x00; // ethernet network controller
1983
    pci_conf[0x0b] = 0x02;
1984
    pci_conf[0x0e] = 0x00; // header_type
1985

    
1986
    *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
1987
    *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
1988

    
1989
    pci_conf[0x3d] = 1; // interrupt pin 0
1990
    pci_conf[0x3e] = 0x06;
1991
    pci_conf[0x3f] = 0xff;
1992

    
1993
    /* Handler for memory-mapped I/O */
1994
    d->mmio_index =
1995
      cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);
1996

    
1997
    pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
1998
                           PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
1999

    
2000
    pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,
2001
                           PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
2002

    
2003
    d->irq = d->dev.irq[0];
2004
    d->phys_mem_read = pci_physical_memory_read;
2005
    d->phys_mem_write = pci_physical_memory_write;
2006
    d->pci_dev = &d->dev;
2007

    
2008
    pcnet_common_init(d, nd, "pcnet");
2009
}
2010

    
2011
/* SPARC32 interface */
2012

    
2013
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
2014
#include "sun4m.h"
2015

    
2016
static void parent_lance_reset(void *opaque, int irq, int level)
2017
{
2018
    if (level)
2019
        pcnet_h_reset(opaque);
2020
}
2021

    
2022
static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
2023
                             uint32_t val)
2024
{
2025
#ifdef PCNET_DEBUG_IO
2026
    printf("lance_mem_writew addr=" TARGET_FMT_plx " val=0x%04x\n", addr,
2027
           val & 0xffff);
2028
#endif
2029
    pcnet_ioport_writew(opaque, addr & 7, val & 0xffff);
2030
}
2031

    
2032
static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
2033
{
2034
    uint32_t val;
2035

    
2036
    val = pcnet_ioport_readw(opaque, addr & 7);
2037
#ifdef PCNET_DEBUG_IO
2038
    printf("pcnet_mmio_readw addr=" TARGET_FMT_plx " val = 0x%04x\n", addr,
2039
           val & 0xffff);
2040
#endif
2041

    
2042
    return val & 0xffff;
2043
}
2044

    
2045
static CPUReadMemoryFunc *lance_mem_read[3] = {
2046
    lance_mem_readw,
2047
    lance_mem_readw,
2048
    lance_mem_readw,
2049
};
2050

    
2051
static CPUWriteMemoryFunc *lance_mem_write[3] = {
2052
    lance_mem_writew,
2053
    lance_mem_writew,
2054
    lance_mem_writew,
2055
};
2056

    
2057
void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
2058
                qemu_irq irq, qemu_irq *reset)
2059
{
2060
    PCNetState *d;
2061
    int lance_io_memory;
2062

    
2063
    d = qemu_mallocz(sizeof(PCNetState));
2064
    if (!d)
2065
        return;
2066

    
2067
    lance_io_memory =
2068
        cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
2069

    
2070
    d->dma_opaque = dma_opaque;
2071

    
2072
    *reset = *qemu_allocate_irqs(parent_lance_reset, d, 1);
2073

    
2074
    cpu_register_physical_memory(leaddr, 4, lance_io_memory);
2075

    
2076
    d->irq = irq;
2077
    d->phys_mem_read = ledma_memory_read;
2078
    d->phys_mem_write = ledma_memory_write;
2079

    
2080
    pcnet_common_init(d, nd, "lance");
2081
}
2082
#endif /* TARGET_SPARC */