Statistics
| Branch: | Revision:

root / hw / pcnet.c @ 89b190a2

History | View | Annotate | Download (63.9 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 <netinet/in.h>
39

    
40
#include "hw.h"
41
#include "pci.h"
42
#include "net.h"
43
#include "qemu-timer.h"
44

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

    
53

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

    
57
#define PCNET_LOOPTEST_CRC        1
58
#define PCNET_LOOPTEST_NOCRC        2
59

    
60

    
61
typedef struct PCNetState_st PCNetState;
62

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
476

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

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

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

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

    
485
#if 1
486

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

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

    
500
#else
501

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

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

    
558
#endif
559

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

    
572
#define MULTICAST_FILTER_LEN 8
573

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
778
    s->tx_busy = 0;
779
}
780

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1017
}
1018

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

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

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

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

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

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

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

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

    
1069
#define MIN_BUF_SIZE 60
1070

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

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

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

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

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

    
1099
        pcnet_rdte_poll(s);
1100

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

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

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

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

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

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

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

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

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

    
1204
#undef PCNET_RECV_STORE
1205

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

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

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

    
1240
            pcnet_rdte_poll(s);
1241

    
1242
        }
1243
    }
1244

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

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

    
1255
    s->xmit_pos = -1;
1256

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

    
1262
    s->tx_busy = 1;
1263

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

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

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

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

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

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

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

    
1337
    s->tx_busy = 0;
1338
}
1339

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

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

    
1353
        pcnet_transmit(s);
1354
    }
1355
}
1356

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

    
1361
    qemu_del_timer(s->poll_timer);
1362

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

    
1367
    pcnet_update_irq(s);
1368

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

    
1386

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1594
    /* Initialize the PROM */
1595

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

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

    
1605

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

    
1619
    pcnet_s_reset(s);
1620
}
1621

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1872

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

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

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

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

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

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

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

    
1930
    return 0;
1931
}
1932

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

    
1937
    d->nd = nd;
1938

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

    
1943
        snprintf(d->vc->info_str, sizeof(d->vc->info_str),
1944
                 "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
1945
                 d->nd->macaddr[0],
1946
                 d->nd->macaddr[1],
1947
                 d->nd->macaddr[2],
1948
                 d->nd->macaddr[3],
1949
                 d->nd->macaddr[4],
1950
                 d->nd->macaddr[5]);
1951
    } else {
1952
        d->vc = NULL;
1953
    }
1954
    pcnet_h_reset(d);
1955
    register_savevm("pcnet", -1, 2, pcnet_save, pcnet_load, d);
1956
}
1957

    
1958
/* PCI interface */
1959

    
1960
static CPUWriteMemoryFunc *pcnet_mmio_write[] = {
1961
    (CPUWriteMemoryFunc *)&pcnet_mmio_writeb,
1962
    (CPUWriteMemoryFunc *)&pcnet_mmio_writew,
1963
    (CPUWriteMemoryFunc *)&pcnet_mmio_writel
1964
};
1965

    
1966
static CPUReadMemoryFunc *pcnet_mmio_read[] = {
1967
    (CPUReadMemoryFunc *)&pcnet_mmio_readb,
1968
    (CPUReadMemoryFunc *)&pcnet_mmio_readw,
1969
    (CPUReadMemoryFunc *)&pcnet_mmio_readl
1970
};
1971

    
1972
static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
1973
                            uint32_t addr, uint32_t size, int type)
1974
{
1975
    PCNetState *d = (PCNetState *)pci_dev;
1976

    
1977
#ifdef PCNET_DEBUG_IO
1978
    printf("pcnet_mmio_map addr=0x%08x 0x%08x\n", addr, size);
1979
#endif
1980

    
1981
    cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_index);
1982
}
1983

    
1984
static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
1985
                                      uint8_t *buf, int len, int do_bswap)
1986
{
1987
    cpu_physical_memory_write(addr, buf, len);
1988
}
1989

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

    
1996
void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
1997
{
1998
    PCNetState *d;
1999
    uint8_t *pci_conf;
2000

    
2001
#if 0
2002
    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",
2003
        sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
2004
#endif
2005

    
2006
    d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
2007
                                          devfn, NULL, NULL);
2008

    
2009
    pci_conf = d->dev.config;
2010

    
2011
    *(uint16_t *)&pci_conf[0x00] = cpu_to_le16(0x1022);
2012
    *(uint16_t *)&pci_conf[0x02] = cpu_to_le16(0x2000);
2013
    *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007);
2014
    *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
2015
    pci_conf[0x08] = 0x10;
2016
    pci_conf[0x09] = 0x00;
2017
    pci_conf[0x0a] = 0x00; // ethernet network controller
2018
    pci_conf[0x0b] = 0x02;
2019
    pci_conf[0x0e] = 0x00; // header_type
2020

    
2021
    *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
2022
    *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
2023

    
2024
    pci_conf[0x3d] = 1; // interrupt pin 0
2025
    pci_conf[0x3e] = 0x06;
2026
    pci_conf[0x3f] = 0xff;
2027

    
2028
    /* Handler for memory-mapped I/O */
2029
    d->mmio_index =
2030
      cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);
2031

    
2032
    pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
2033
                           PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
2034

    
2035
    pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,
2036
                           PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
2037

    
2038
    d->irq = d->dev.irq[0];
2039
    d->phys_mem_read = pci_physical_memory_read;
2040
    d->phys_mem_write = pci_physical_memory_write;
2041
    d->pci_dev = &d->dev;
2042

    
2043
    pcnet_common_init(d, nd, "pcnet");
2044
}
2045

    
2046
/* SPARC32 interface */
2047

    
2048
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
2049
#include "sun4m.h"
2050

    
2051
static void parent_lance_reset(void *opaque, int irq, int level)
2052
{
2053
    if (level)
2054
        pcnet_h_reset(opaque);
2055
}
2056

    
2057
static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
2058
                             uint32_t val)
2059
{
2060
#ifdef PCNET_DEBUG_IO
2061
    printf("lance_mem_writew addr=" TARGET_FMT_plx " val=0x%04x\n", addr,
2062
           val & 0xffff);
2063
#endif
2064
    pcnet_ioport_writew(opaque, addr & 7, val & 0xffff);
2065
}
2066

    
2067
static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
2068
{
2069
    uint32_t val;
2070

    
2071
    val = pcnet_ioport_readw(opaque, addr & 7);
2072
#ifdef PCNET_DEBUG_IO
2073
    printf("lance_mem_readw addr=" TARGET_FMT_plx " val = 0x%04x\n", addr,
2074
           val & 0xffff);
2075
#endif
2076

    
2077
    return val & 0xffff;
2078
}
2079

    
2080
static CPUReadMemoryFunc *lance_mem_read[3] = {
2081
    NULL,
2082
    lance_mem_readw,
2083
    NULL,
2084
};
2085

    
2086
static CPUWriteMemoryFunc *lance_mem_write[3] = {
2087
    NULL,
2088
    lance_mem_writew,
2089
    NULL,
2090
};
2091

    
2092
void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
2093
                qemu_irq irq, qemu_irq *reset)
2094
{
2095
    PCNetState *d;
2096
    int lance_io_memory;
2097

    
2098
    d = qemu_mallocz(sizeof(PCNetState));
2099
    if (!d)
2100
        return;
2101

    
2102
    lance_io_memory =
2103
        cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
2104

    
2105
    d->dma_opaque = dma_opaque;
2106

    
2107
    *reset = *qemu_allocate_irqs(parent_lance_reset, d, 1);
2108

    
2109
    cpu_register_physical_memory(leaddr, 4, lance_io_memory);
2110

    
2111
    d->irq = irq;
2112
    d->phys_mem_read = ledma_memory_read;
2113
    d->phys_mem_write = ledma_memory_write;
2114

    
2115
    pcnet_common_init(d, nd, "lance");
2116
}
2117
#endif /* TARGET_SPARC */