Statistics
| Branch: | Revision:

root / hw / pcnet.c @ 1eed09cb

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

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

    
52

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

    
56
#define PCNET_LOOPTEST_CRC        1
57
#define PCNET_LOOPTEST_NOCRC        2
58

    
59

    
60
typedef struct PCNetState_st PCNetState;
61

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
484

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

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

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

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

    
493
#if 1
494

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

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

    
508
#else
509

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

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

    
566
#endif
567

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

    
580
#define MULTICAST_FILTER_LEN 8
581

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
786
    s->tx_busy = 0;
787
}
788

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1025
}
1026

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

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

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

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

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

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

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

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

    
1077
#define MIN_BUF_SIZE 60
1078

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

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

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

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

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

    
1108
        pcnet_rdte_poll(s);
1109

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

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

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

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

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

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

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

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

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

    
1213
#undef PCNET_RECV_STORE
1214

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

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

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

    
1249
            pcnet_rdte_poll(s);
1250

    
1251
        }
1252
    }
1253

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

    
1257
    return size_;
1258
}
1259

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

    
1266
    s->xmit_pos = -1;
1267

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

    
1273
    s->tx_busy = 1;
1274

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

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

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

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

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

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

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

    
1348
    s->tx_busy = 0;
1349
}
1350

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

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

    
1364
        pcnet_transmit(s);
1365
    }
1366
}
1367

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

    
1372
    qemu_del_timer(s->poll_timer);
1373

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

    
1378
    pcnet_update_irq(s);
1379

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

    
1397

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1605
    /* Initialize the PROM */
1606

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

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

    
1615

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

    
1629
    pcnet_s_reset(s);
1630
}
1631

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1882

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

    
1888
    if (s->pci_dev)
1889
        pci_device_save(s->pci_dev, f);
1890

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

    
1909
static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
1910
{
1911
    PCNetState *s = opaque;
1912
    int i, ret;
1913

    
1914
    if (version_id != 2)
1915
        return -EINVAL;
1916

    
1917
    if (s->pci_dev) {
1918
        ret = pci_device_load(s->pci_dev, f);
1919
        if (ret < 0)
1920
            return ret;
1921
    }
1922

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

    
1940
    return 0;
1941
}
1942

    
1943
static void pcnet_common_cleanup(PCNetState *d)
1944
{
1945
    unregister_savevm("pcnet", d);
1946

    
1947
    qemu_del_timer(d->poll_timer);
1948
    qemu_free_timer(d->poll_timer);
1949
}
1950

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

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

    
1964
/* PCI interface */
1965

    
1966
static CPUWriteMemoryFunc *pcnet_mmio_write[] = {
1967
    (CPUWriteMemoryFunc *)&pcnet_mmio_writeb,
1968
    (CPUWriteMemoryFunc *)&pcnet_mmio_writew,
1969
    (CPUWriteMemoryFunc *)&pcnet_mmio_writel
1970
};
1971

    
1972
static CPUReadMemoryFunc *pcnet_mmio_read[] = {
1973
    (CPUReadMemoryFunc *)&pcnet_mmio_readb,
1974
    (CPUReadMemoryFunc *)&pcnet_mmio_readw,
1975
    (CPUReadMemoryFunc *)&pcnet_mmio_readl
1976
};
1977

    
1978
static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
1979
                            uint32_t addr, uint32_t size, int type)
1980
{
1981
    PCIPCNetState *d = (PCIPCNetState *)pci_dev;
1982

    
1983
#ifdef PCNET_DEBUG_IO
1984
    printf("pcnet_mmio_map addr=0x%08x 0x%08x\n", addr, size);
1985
#endif
1986

    
1987
    cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->state.mmio_index);
1988
}
1989

    
1990
static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
1991
                                      uint8_t *buf, int len, int do_bswap)
1992
{
1993
    cpu_physical_memory_write(addr, buf, len);
1994
}
1995

    
1996
static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
1997
                                     uint8_t *buf, int len, int do_bswap)
1998
{
1999
    cpu_physical_memory_read(addr, buf, len);
2000
}
2001

    
2002
static void pci_pcnet_cleanup(VLANClientState *vc)
2003
{
2004
    PCNetState *d = vc->opaque;
2005

    
2006
    pcnet_common_cleanup(d);
2007
}
2008

    
2009
static int pci_pcnet_uninit(PCIDevice *dev)
2010
{
2011
    PCIPCNetState *d = (PCIPCNetState *)dev;
2012

    
2013
    cpu_unregister_io_memory(d->state.mmio_index);
2014

    
2015
    return 0;
2016
}
2017

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

    
2024
#if 0
2025
    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
2026
        sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
2027
#endif
2028

    
2029
    pci_dev->unregister = pci_pcnet_uninit;
2030

    
2031
    pci_conf = pci_dev->config;
2032

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

    
2042
    *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
2043
    *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
2044

    
2045
    pci_conf[0x3d] = 1; // interrupt pin 0
2046
    pci_conf[0x3e] = 0x06;
2047
    pci_conf[0x3f] = 0xff;
2048

    
2049
    /* Handler for memory-mapped I/O */
2050
    s->mmio_index =
2051
      cpu_register_io_memory(pcnet_mmio_read, pcnet_mmio_write, &d->state);
2052

    
2053
    pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
2054
                           PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
2055

    
2056
    pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,
2057
                           PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
2058

    
2059
    s->irq = pci_dev->irq[0];
2060
    s->phys_mem_read = pci_physical_memory_read;
2061
    s->phys_mem_write = pci_physical_memory_write;
2062
    s->pci_dev = pci_dev;
2063

    
2064
    pcnet_common_init(&pci_dev->qdev, s, pci_pcnet_cleanup);
2065
}
2066

    
2067
/* SPARC32 interface */
2068

    
2069
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
2070
#include "sun4m.h"
2071

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

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

    
2090
static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
2091
{
2092
    SysBusPCNetState *d = opaque;
2093
    uint32_t val;
2094

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

    
2101
    return val & 0xffff;
2102
}
2103

    
2104
static CPUReadMemoryFunc *lance_mem_read[3] = {
2105
    NULL,
2106
    lance_mem_readw,
2107
    NULL,
2108
};
2109

    
2110
static CPUWriteMemoryFunc *lance_mem_write[3] = {
2111
    NULL,
2112
    lance_mem_writew,
2113
    NULL,
2114
};
2115

    
2116
static void lance_cleanup(VLANClientState *vc)
2117
{
2118
    PCNetState *d = vc->opaque;
2119

    
2120
    pcnet_common_cleanup(d);
2121
}
2122

    
2123
static void lance_init(SysBusDevice *dev)
2124
{
2125
    SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev);
2126
    PCNetState *s = &d->state;
2127

    
2128
    s->mmio_index =
2129
        cpu_register_io_memory(lance_mem_read, lance_mem_write, d);
2130

    
2131
    s->dma_opaque = qdev_get_prop_ptr(&dev->qdev, "dma");
2132

    
2133
    qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1);
2134

    
2135
    sysbus_init_mmio(dev, 4, s->mmio_index);
2136

    
2137
    sysbus_init_irq(dev, &s->irq);
2138

    
2139
    s->phys_mem_read = ledma_memory_read;
2140
    s->phys_mem_write = ledma_memory_write;
2141

    
2142
    pcnet_common_init(&dev->qdev, s, lance_cleanup);
2143
}
2144
#endif /* TARGET_SPARC */
2145

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

    
2154
device_init(pcnet_register_devices)