Statistics
| Branch: | Revision:

root / hw / pcnet.c @ a2d4e44b

History | View | Annotate | Download (59.3 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
/* TODO: remove little endian host assumptions */
39
 
40
#include "vl.h"
41

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

    
50

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

    
54

    
55
typedef struct PCNetState_st PCNetState;
56

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

    
80
/* XXX: using bitfields for target memory structures is almost surely
81
   not portable, so it should be suppressed ASAP */
82
#ifdef __GNUC__
83
#define PACKED_FIELD(A) A __attribute__ ((packed))
84
#else
85
#error FixMe
86
#endif
87

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

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

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

    
112
#define CSR_INIT(S)      !!(((S)->csr[0])&0x0001)
113
#define CSR_STRT(S)      !!(((S)->csr[0])&0x0002)
114
#define CSR_STOP(S)      !!(((S)->csr[0])&0x0004)
115
#define CSR_TDMD(S)      !!(((S)->csr[0])&0x0008)
116
#define CSR_TXON(S)      !!(((S)->csr[0])&0x0010)
117
#define CSR_RXON(S)      !!(((S)->csr[0])&0x0020)
118
#define CSR_INEA(S)      !!(((S)->csr[0])&0x0040)
119
#define CSR_BSWP(S)      !!(((S)->csr[3])&0x0004)
120
#define CSR_LAPPEN(S)    !!(((S)->csr[3])&0x0020)
121
#define CSR_DXSUFLO(S)   !!(((S)->csr[3])&0x0040)
122
#define CSR_ASTRP_RCV(S) !!(((S)->csr[4])&0x0800)
123
#define CSR_DPOLL(S)     !!(((S)->csr[4])&0x1000)
124
#define CSR_SPND(S)      !!(((S)->csr[5])&0x0001)
125
#define CSR_LTINTEN(S)   !!(((S)->csr[5])&0x4000)
126
#define CSR_TOKINTD(S)   !!(((S)->csr[5])&0x8000)
127
#define CSR_DRX(S)       !!(((S)->csr[15])&0x0001)
128
#define CSR_DTX(S)       !!(((S)->csr[15])&0x0002)
129
#define CSR_LOOP(S)      !!(((S)->csr[15])&0x0004)
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
    struct {
187
        unsigned tbadr:32;
188
    } tmd0;
189
    struct {
190
        unsigned PACKED_FIELD(bcnt:12), PACKED_FIELD(ones:4), PACKED_FIELD(res:7), PACKED_FIELD(bpe:1);
191
        unsigned PACKED_FIELD(enp:1), PACKED_FIELD(stp:1), PACKED_FIELD(def:1), PACKED_FIELD(one:1);
192
        unsigned PACKED_FIELD(ltint:1), PACKED_FIELD(nofcs:1), PACKED_FIELD(err:1), PACKED_FIELD(own:1);
193
    } tmd1;
194
    struct {
195
        unsigned PACKED_FIELD(trc:4), PACKED_FIELD(res:12);
196
        unsigned PACKED_FIELD(tdr:10), PACKED_FIELD(rtry:1), PACKED_FIELD(lcar:1);
197
        unsigned PACKED_FIELD(lcol:1), PACKED_FIELD(exdef:1), PACKED_FIELD(uflo:1), PACKED_FIELD(buff:1);
198
    } tmd2;
199
    struct {
200
        unsigned res:32;
201
    } tmd3;    
202
};
203

    
204
struct pcnet_RMD {
205
    struct {
206
        unsigned rbadr:32;
207
    } rmd0;
208
    struct {
209
        unsigned PACKED_FIELD(bcnt:12), PACKED_FIELD(ones:4), PACKED_FIELD(res:4);
210
        unsigned PACKED_FIELD(bam:1), PACKED_FIELD(lafm:1), PACKED_FIELD(pam:1), PACKED_FIELD(bpe:1);
211
        unsigned PACKED_FIELD(enp:1), PACKED_FIELD(stp:1), PACKED_FIELD(buff:1), PACKED_FIELD(crc:1);
212
        unsigned PACKED_FIELD(oflo:1), PACKED_FIELD(fram:1), PACKED_FIELD(err:1), PACKED_FIELD(own:1);
213
    } rmd1;
214
    struct {
215
        unsigned PACKED_FIELD(mcnt:12), PACKED_FIELD(zeros:4);
216
        unsigned PACKED_FIELD(rpc:8), PACKED_FIELD(rcc:8);
217
    } rmd2;    
218
    struct {
219
        unsigned res:32;
220
    } rmd3;    
221
};
222

    
223

    
224
#define PRINT_TMD(T) printf(    \
225
        "TMD0 : TBADR=0x%08x\n" \
226
        "TMD1 : OWN=%d, ERR=%d, FCS=%d, LTI=%d, "       \
227
        "ONE=%d, DEF=%d, STP=%d, ENP=%d,\n"             \
228
        "       BPE=%d, BCNT=%d\n"                      \
229
        "TMD2 : BUF=%d, UFL=%d, EXD=%d, LCO=%d, "       \
230
        "LCA=%d, RTR=%d,\n"                             \
231
        "       TDR=%d, TRC=%d\n",                      \
232
        (T)->tmd0.tbadr,                                \
233
        (T)->tmd1.own, (T)->tmd1.err, (T)->tmd1.nofcs,  \
234
        (T)->tmd1.ltint, (T)->tmd1.one, (T)->tmd1.def,  \
235
        (T)->tmd1.stp, (T)->tmd1.enp, (T)->tmd1.bpe,    \
236
        4096-(T)->tmd1.bcnt,                            \
237
        (T)->tmd2.buff, (T)->tmd2.uflo, (T)->tmd2.exdef,\
238
        (T)->tmd2.lcol, (T)->tmd2.lcar, (T)->tmd2.rtry, \
239
        (T)->tmd2.tdr, (T)->tmd2.trc)
240

    
241
#define PRINT_RMD(R) printf(    \
242
        "RMD0 : RBADR=0x%08x\n" \
243
        "RMD1 : OWN=%d, ERR=%d, FRAM=%d, OFLO=%d, "     \
244
        "CRC=%d, BUFF=%d, STP=%d, ENP=%d,\n       "     \
245
        "BPE=%d, PAM=%d, LAFM=%d, BAM=%d, ONES=%d, BCNT=%d\n"    \
246
        "RMD2 : RCC=%d, RPC=%d, MCNT=%d, ZEROS=%d\n",   \
247
        (R)->rmd0.rbadr,                                \
248
        (R)->rmd1.own, (R)->rmd1.err, (R)->rmd1.fram,   \
249
        (R)->rmd1.oflo, (R)->rmd1.crc, (R)->rmd1.buff,  \
250
        (R)->rmd1.stp, (R)->rmd1.enp, (R)->rmd1.bpe,    \
251
        (R)->rmd1.pam, (R)->rmd1.lafm, (R)->rmd1.bam,   \
252
        (R)->rmd1.ones, 4096-(R)->rmd1.bcnt,            \
253
        (R)->rmd2.rcc, (R)->rmd2.rpc, (R)->rmd2.mcnt,   \
254
        (R)->rmd2.zeros)
255

    
256
static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd1, 
257
                                  target_phys_addr_t addr)
258
{
259
    uint32_t *tmd = (uint32_t *)tmd1;
260

    
261
    if (!BCR_SWSTYLE(s)) {
262
        uint16_t xda[4];
263
        s->phys_mem_read(s->dma_opaque, addr,
264
                (void *)&xda[0], sizeof(xda), 0);
265
        le16_to_cpus(&xda[0]);
266
        le16_to_cpus(&xda[1]);
267
        le16_to_cpus(&xda[2]);
268
        le16_to_cpus(&xda[3]);
269
        tmd[0] = (xda[0]&0xffff) |
270
            ((xda[1]&0x00ff) << 16);
271
        tmd[1] = (xda[2]&0xffff)|
272
            ((xda[1] & 0xff00) << 16);
273
        tmd[2] =
274
            (xda[3] & 0xffff) << 16;
275
        tmd[3] = 0;
276
    } else {
277
        uint32_t xda[4];
278
        s->phys_mem_read(s->dma_opaque, addr,
279
                (void *)&xda[0], sizeof(xda), 0);
280
        le32_to_cpus(&xda[0]);
281
        le32_to_cpus(&xda[1]);
282
        le32_to_cpus(&xda[2]);
283
        le32_to_cpus(&xda[3]);
284
        if (BCR_SWSTYLE(s) != 3) {
285
            memcpy(tmd, xda, sizeof(xda));
286
        } else {
287
            tmd[0] = xda[2];
288
            tmd[1] = xda[1];
289
            tmd[2] = xda[0];
290
            tmd[3] = xda[3];
291
        }
292
    }
293
}
294

    
295
static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd1,
296
                                   target_phys_addr_t addr)
297
{
298
    const uint32_t *tmd = (const uint32_t *)tmd1;
299
    if (!BCR_SWSTYLE(s)) {
300
        uint16_t xda[4];
301
        xda[0] = tmd[0] & 0xffff;
302
        xda[1] = ((tmd[0]>>16)&0x00ff) |
303
            ((tmd[1]>>16)&0xff00);
304
        xda[2] = tmd[1] & 0xffff;
305
        xda[3] = tmd[2] >> 16;
306
        cpu_to_le16s(&xda[0]);
307
        cpu_to_le16s(&xda[1]);
308
        cpu_to_le16s(&xda[2]);
309
        cpu_to_le16s(&xda[3]);
310
        s->phys_mem_write(s->dma_opaque, addr,
311
                (void *)&xda[0], sizeof(xda), 0);
312
    } else {
313
        uint32_t xda[4];
314
        if (BCR_SWSTYLE(s) != 3) {
315
            memcpy(xda, tmd, sizeof(xda));
316
        } else {
317
            xda[0] = tmd[2];
318
            xda[1] = tmd[1];
319
            xda[2] = tmd[0];
320
            xda[3] = tmd[3];
321
        }
322
        cpu_to_le32s(&xda[0]);
323
        cpu_to_le32s(&xda[1]);
324
        cpu_to_le32s(&xda[2]);
325
        cpu_to_le32s(&xda[3]);
326
        s->phys_mem_write(s->dma_opaque, addr,
327
                          (void *)&xda[0], sizeof(xda), 0);
328
    }
329
}
330

    
331
static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd1,
332
                                  target_phys_addr_t addr)
333
{
334
    uint32_t *rmd = (uint32_t *)rmd1;
335

    
336
    if (!BCR_SWSTYLE(s)) {
337
        uint16_t rda[4];
338
        s->phys_mem_read(s->dma_opaque, addr, 
339
                         (void *)&rda[0], sizeof(rda), 0);
340
        le16_to_cpus(&rda[0]);
341
        le16_to_cpus(&rda[1]);
342
        le16_to_cpus(&rda[2]);
343
        le16_to_cpus(&rda[3]);
344
        rmd[0] = (rda[0]&0xffff)|
345
            ((rda[1] & 0x00ff) << 16);
346
        rmd[1] = (rda[2]&0xffff)|
347
            ((rda[1] & 0xff00) << 16);
348
        rmd[2] = rda[3] & 0xffff;
349
        rmd[3] = 0;
350
    } else {
351
        uint32_t rda[4];
352
        s->phys_mem_read(s->dma_opaque, addr, 
353
                         (void *)&rda[0], sizeof(rda), 0);
354
        le32_to_cpus(&rda[0]);
355
        le32_to_cpus(&rda[1]);
356
        le32_to_cpus(&rda[2]);
357
        le32_to_cpus(&rda[3]);
358
        if (BCR_SWSTYLE(s) != 3) {
359
            memcpy(rmd, rda, sizeof(rda));
360
        } else {
361
            rmd[0] = rda[2];
362
            rmd[1] = rda[1];
363
            rmd[2] = rda[0];
364
            rmd[3] = rda[3];
365
        }
366
    }
367
}
368

    
369
static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd1, 
370
                                   target_phys_addr_t addr)
371
{
372
    const uint32_t *rmd = (const uint32_t *)rmd1;
373

    
374
    if (!BCR_SWSTYLE(s)) {
375
        uint16_t rda[4];
376
        rda[0] = rmd[0] & 0xffff;
377
        rda[1] = ((rmd[0]>>16)&0xff)|
378
            ((rmd[1]>>16)&0xff00);
379
        rda[2] = rmd[1] & 0xffff;
380
        rda[3] = rmd[2] & 0xffff;
381
        cpu_to_le16s(&rda[0]);
382
        cpu_to_le16s(&rda[1]);
383
        cpu_to_le16s(&rda[2]);
384
        cpu_to_le16s(&rda[3]);
385
        s->phys_mem_write(s->dma_opaque, addr,
386
                (void *)&rda[0], sizeof(rda), 0);
387
    } else {
388
        uint32_t rda[4];
389
        if (BCR_SWSTYLE(s) != 3) {
390
            memcpy(rda, rmd, sizeof(rda));
391
        } else {
392
            rda[0] = rmd[2];
393
            rda[1] = rmd[1];
394
            rda[2] = rmd[0];
395
            rda[3] = rmd[3];
396
        }
397
        cpu_to_le32s(&rda[0]);
398
        cpu_to_le32s(&rda[1]);
399
        cpu_to_le32s(&rda[2]);
400
        cpu_to_le32s(&rda[3]);
401
        s->phys_mem_write(s->dma_opaque, addr,
402
                          (void *)&rda[0], sizeof(rda), 0);
403
    }
404
}
405

    
406

    
407
#define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
408

    
409
#define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
410

    
411
#define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
412

    
413
#define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
414

    
415
#if 1
416

    
417
#define CHECK_RMD(ADDR,RES) do {                \
418
    struct pcnet_RMD rmd;                       \
419
    RMDLOAD(&rmd,(ADDR));                       \
420
    (RES) |= (rmd.rmd1.ones != 15)              \
421
          || (rmd.rmd2.zeros != 0);             \
422
} while (0)
423

    
424
#define CHECK_TMD(ADDR,RES) do {                \
425
    struct pcnet_TMD tmd;                       \
426
    TMDLOAD(&tmd,(ADDR));                       \
427
    (RES) |= (tmd.tmd1.ones != 15);             \
428
} while (0)
429

    
430
#else
431

    
432
#define CHECK_RMD(ADDR,RES) do {                \
433
    switch (BCR_SWSTYLE(s)) {                   \
434
    case 0x00:                                  \
435
        do {                                    \
436
            uint16_t rda[4];                    \
437
            s->phys_mem_read(s->dma_opaque, (ADDR),    \
438
                (void *)&rda[0], sizeof(rda), 0);  \
439
            (RES) |= (rda[2] & 0xf000)!=0xf000; \
440
            (RES) |= (rda[3] & 0xf000)!=0x0000; \
441
        } while (0);                            \
442
        break;                                  \
443
    case 0x01:                                  \
444
    case 0x02:                                  \
445
        do {                                    \
446
            uint32_t rda[4];                    \
447
            s->phys_mem_read(s->dma_opaque, (ADDR),    \
448
                (void *)&rda[0], sizeof(rda), 0); \
449
            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
450
            (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
451
        } while (0);                            \
452
        break;                                  \
453
    case 0x03:                                  \
454
        do {                                    \
455
            uint32_t rda[4];                    \
456
            s->phys_mem_read(s->dma_opaque, (ADDR),    \
457
                (void *)&rda[0], sizeof(rda), 0); \
458
            (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
459
            (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
460
        } while (0);                            \
461
        break;                                  \
462
    }                                           \
463
} while (0)
464

    
465
#define CHECK_TMD(ADDR,RES) do {                \
466
    switch (BCR_SWSTYLE(s)) {                   \
467
    case 0x00:                                  \
468
        do {                                    \
469
            uint16_t xda[4];                    \
470
            s->phys_mem_read(s->dma_opaque, (ADDR),    \
471
                (void *)&xda[0], sizeof(xda), 0);  \
472
            (RES) |= (xda[2] & 0xf000)!=0xf000;\
473
        } while (0);                            \
474
        break;                                  \
475
    case 0x01:                                  \
476
    case 0x02:                                  \
477
    case 0x03:                                  \
478
        do {                                    \
479
            uint32_t xda[4];                    \
480
            s->phys_mem_read(s->dma_opaque, (ADDR),    \
481
                (void *)&xda[0], sizeof(xda), 0);  \
482
            (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
483
        } while (0);                            \
484
        break;                                  \
485
    }                                           \
486
} while (0)
487

    
488
#endif
489

    
490
#define PRINT_PKTHDR(BUF) do {                  \
491
    struct qemu_ether_header *hdr = (void *)(BUF);   \
492
    printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "       \
493
           "shost=%02x:%02x:%02x:%02x:%02x:%02x, "              \
494
           "type=0x%04x\n",                          \
495
           hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
496
           hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
497
           hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
498
           hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
499
           be16_to_cpu(hdr->ether_type));                     \
500
} while (0)
501

    
502
#define MULTICAST_FILTER_LEN 8
503

    
504
static inline uint32_t lnc_mchash(const uint8_t *ether_addr)
505
{
506
#define LNC_POLYNOMIAL          0xEDB88320UL
507
    uint32_t crc = 0xFFFFFFFF;
508
    int idx, bit;
509
    uint8_t data;
510

    
511
    for (idx = 0; idx < 6; idx++) {
512
        for (data = *ether_addr++, bit = 0; bit < MULTICAST_FILTER_LEN; bit++) {
513
            crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LNC_POLYNOMIAL : 0);
514
            data >>= 1;
515
        }
516
    }
517
    return crc;
518
#undef LNC_POLYNOMIAL
519
}
520

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

    
523
/* generated using the AUTODIN II polynomial
524
 *        x^32 + x^26 + x^23 + x^22 + x^16 +
525
 *        x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
526
 */
527
static const uint32_t crctab[256] = {
528
        0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
529
        0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
530
        0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
531
        0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
532
        0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
533
        0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
534
        0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
535
        0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
536
        0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
537
        0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
538
        0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
539
        0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
540
        0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
541
        0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
542
        0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
543
        0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
544
        0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
545
        0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
546
        0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
547
        0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
548
        0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
549
        0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
550
        0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
551
        0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
552
        0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
553
        0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
554
        0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
555
        0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
556
        0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
557
        0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
558
        0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
559
        0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
560
        0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
561
        0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
562
        0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
563
        0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
564
        0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
565
        0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
566
        0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
567
        0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
568
        0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
569
        0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
570
        0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
571
        0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
572
        0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
573
        0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
574
        0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
575
        0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
576
        0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
577
        0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
578
        0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
579
        0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
580
        0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
581
        0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
582
        0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
583
        0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
584
        0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
585
        0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
586
        0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
587
        0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
588
        0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
589
        0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
590
        0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
591
        0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
592
};
593

    
594
static inline int padr_match(PCNetState *s, const uint8_t *buf, int size)
595
{
596
    struct qemu_ether_header *hdr = (void *)buf;
597
    uint8_t padr[6] = { 
598
        s->csr[12] & 0xff, s->csr[12] >> 8,
599
        s->csr[13] & 0xff, s->csr[13] >> 8,
600
        s->csr[14] & 0xff, s->csr[14] >> 8 
601
    };
602
    int result = (!CSR_DRCVPA(s)) && !memcmp(hdr->ether_dhost, padr, 6);
603
#ifdef PCNET_DEBUG_MATCH
604
    printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "
605
           "padr=%02x:%02x:%02x:%02x:%02x:%02x\n",
606
           hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2],
607
           hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5],
608
           padr[0],padr[1],padr[2],padr[3],padr[4],padr[5]);
609
    printf("padr_match result=%d\n", result);
610
#endif
611
    return result;
612
}
613

    
614
static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size)
615
{
616
    static const uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
617
    struct qemu_ether_header *hdr = (void *)buf;
618
    int result = !CSR_DRCVBC(s) && !memcmp(hdr->ether_dhost, BCAST, 6);
619
#ifdef PCNET_DEBUG_MATCH
620
    printf("padr_bcast result=%d\n", result);
621
#endif
622
    return result;
623
}
624

    
625
static inline int ladr_match(PCNetState *s, const uint8_t *buf, int size)
626
{
627
    struct qemu_ether_header *hdr = (void *)buf;
628
    if ((*(hdr->ether_dhost)&0x01) && 
629
        ((uint64_t *)&s->csr[8])[0] != 0LL) {
630
        uint8_t ladr[8] = { 
631
            s->csr[8] & 0xff, s->csr[8] >> 8,
632
            s->csr[9] & 0xff, s->csr[9] >> 8,
633
            s->csr[10] & 0xff, s->csr[10] >> 8, 
634
            s->csr[11] & 0xff, s->csr[11] >> 8 
635
        };
636
        int index = lnc_mchash(hdr->ether_dhost) >> 26;
637
        return !!(ladr[index >> 3] & (1 << (index & 7)));
638
    }
639
    return 0;
640
}
641

    
642
static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx) 
643
{
644
    while (idx < 1) idx += CSR_RCVRL(s);
645
    return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
646
}
647

    
648
static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
649
{
650
    int64_t next_time = current_time + 
651
        muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)), 
652
                 ticks_per_sec, 33000000L);
653
    if (next_time <= current_time)
654
        next_time = current_time + 1;
655
    return next_time;
656
}
657

    
658
static void pcnet_poll(PCNetState *s);
659
static void pcnet_poll_timer(void *opaque);
660

    
661
static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
662
static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
663
static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
664
static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
665

    
666
static void pcnet_s_reset(PCNetState *s)
667
{
668
#ifdef PCNET_DEBUG
669
    printf("pcnet_s_reset\n");
670
#endif
671

    
672
    s->lnkst = 0x40;
673
    s->rdra = 0;
674
    s->tdra = 0;
675
    s->rap = 0;
676
    
677
    s->bcr[BCR_BSBC] &= ~0x0080;
678

    
679
    s->csr[0]   = 0x0004;
680
    s->csr[3]   = 0x0000;
681
    s->csr[4]   = 0x0115;
682
    s->csr[5]   = 0x0000;
683
    s->csr[6]   = 0x0000;
684
    s->csr[8]   = 0;
685
    s->csr[9]   = 0;
686
    s->csr[10]  = 0;
687
    s->csr[11]  = 0;
688
    s->csr[12]  = le16_to_cpu(((uint16_t *)&s->prom[0])[0]);
689
    s->csr[13]  = le16_to_cpu(((uint16_t *)&s->prom[0])[1]);
690
    s->csr[14]  = le16_to_cpu(((uint16_t *)&s->prom[0])[2]);
691
    s->csr[15] &= 0x21c4;
692
    s->csr[72]  = 1;
693
    s->csr[74]  = 1;
694
    s->csr[76]  = 1;
695
    s->csr[78]  = 1;
696
    s->csr[80]  = 0x1410;
697
    s->csr[88]  = 0x1003;
698
    s->csr[89]  = 0x0262;
699
    s->csr[94]  = 0x0000;
700
    s->csr[100] = 0x0200;
701
    s->csr[103] = 0x0105;
702
    s->csr[103] = 0x0105;
703
    s->csr[112] = 0x0000;
704
    s->csr[114] = 0x0000;
705
    s->csr[122] = 0x0000;
706
    s->csr[124] = 0x0000;
707

    
708
    s->tx_busy = 0;
709
}
710

    
711
static void pcnet_update_irq(PCNetState *s)
712
{
713
    int isr = 0;
714
    s->csr[0] &= ~0x0080;
715
    
716
#if 1
717
    if (((s->csr[0] & ~s->csr[3]) & 0x5f00) ||
718
        (((s->csr[4]>>1) & ~s->csr[4]) & 0x0115) ||
719
        (((s->csr[5]>>1) & s->csr[5]) & 0x0048))
720
#else
721
    if ((!(s->csr[3] & 0x4000) && !!(s->csr[0] & 0x4000)) /* BABL */ ||
722
        (!(s->csr[3] & 0x1000) && !!(s->csr[0] & 0x1000)) /* MISS */ ||
723
        (!(s->csr[3] & 0x0100) && !!(s->csr[0] & 0x0100)) /* IDON */ ||
724
        (!(s->csr[3] & 0x0200) && !!(s->csr[0] & 0x0200)) /* TINT */ ||
725
        (!(s->csr[3] & 0x0400) && !!(s->csr[0] & 0x0400)) /* RINT */ ||
726
        (!(s->csr[3] & 0x0800) && !!(s->csr[0] & 0x0800)) /* MERR */ ||
727
        (!(s->csr[4] & 0x0001) && !!(s->csr[4] & 0x0002)) /* JAB */ ||
728
        (!(s->csr[4] & 0x0004) && !!(s->csr[4] & 0x0008)) /* TXSTRT */ ||
729
        (!(s->csr[4] & 0x0010) && !!(s->csr[4] & 0x0020)) /* RCVO */ ||
730
        (!(s->csr[4] & 0x0100) && !!(s->csr[4] & 0x0200)) /* MFCO */ ||
731
        (!!(s->csr[5] & 0x0040) && !!(s->csr[5] & 0x0080)) /* EXDINT */ ||
732
        (!!(s->csr[5] & 0x0008) && !!(s->csr[5] & 0x0010)) /* MPINT */)
733
#endif
734
    {
735
       
736
        isr = CSR_INEA(s);
737
        s->csr[0] |= 0x0080;
738
    }
739
    
740
    if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
741
        s->csr[4] &= ~0x0080;
742
        s->csr[4] |= 0x0040;
743
        s->csr[0] |= 0x0080;
744
        isr = 1;
745
#ifdef PCNET_DEBUG
746
        printf("pcnet user int\n");
747
#endif
748
    }
749

    
750
#if 1
751
    if (((s->csr[5]>>1) & s->csr[5]) & 0x0500) 
752
#else
753
    if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
754
        (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
755
#endif
756
    {
757
        isr = 1;
758
        s->csr[0] |= 0x0080;
759
    }
760

    
761
    if (isr != s->isr) {
762
#ifdef PCNET_DEBUG
763
        printf("pcnet: INTA=%d\n", isr);
764
#endif
765
    }
766
    s->set_irq_cb(s, isr);
767
    s->isr = isr;
768
}
769

    
770
static void pcnet_init(PCNetState *s)
771
{
772
    int rlen, tlen;
773
    uint16_t *padr, *ladrf, mode;
774
    uint32_t rdra, tdra;
775

    
776
#ifdef PCNET_DEBUG
777
    printf("pcnet_init init_addr=0x%08x\n", PHYSADDR(s,CSR_IADR(s)));
778
#endif
779
    
780
    if (BCR_SSIZE32(s)) {
781
        struct pcnet_initblk32 initblk;
782
        s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
783
                (uint8_t *)&initblk, sizeof(initblk), 0);
784
        mode = initblk.mode;
785
        rlen = initblk.rlen >> 4;
786
        tlen = initblk.tlen >> 4;
787
        ladrf = initblk.ladrf;
788
        padr = initblk.padr;
789
        rdra = le32_to_cpu(initblk.rdra);
790
        tdra = le32_to_cpu(initblk.tdra);
791
        s->rdra = PHYSADDR(s,initblk.rdra);
792
        s->tdra = PHYSADDR(s,initblk.tdra);
793
    } else {
794
        struct pcnet_initblk16 initblk;
795
        s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
796
                (uint8_t *)&initblk, sizeof(initblk), 0);
797
        mode = initblk.mode;
798
        ladrf = initblk.ladrf;
799
        padr = initblk.padr;
800
        rdra = le32_to_cpu(initblk.rdra);
801
        tdra = le32_to_cpu(initblk.tdra);
802
        rlen = rdra >> 29;
803
        tlen = tdra >> 29;
804
        rdra &= 0x00ffffff;
805
        tdra &= 0x00ffffff;
806
    }
807
    
808
#if defined(PCNET_DEBUG)
809
    printf("rlen=%d tlen=%d\n",
810
           rlen, tlen);
811
#endif
812
    CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512;
813
    CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512;
814
    s->csr[ 6] = (tlen << 12) | (rlen << 8);
815
    s->csr[15] = le16_to_cpu(mode);
816
    s->csr[ 8] = le16_to_cpu(ladrf[0]);
817
    s->csr[ 9] = le16_to_cpu(ladrf[1]);
818
    s->csr[10] = le16_to_cpu(ladrf[2]);
819
    s->csr[11] = le16_to_cpu(ladrf[3]);
820
    s->csr[12] = le16_to_cpu(padr[0]);
821
    s->csr[13] = le16_to_cpu(padr[1]);
822
    s->csr[14] = le16_to_cpu(padr[2]);
823
    s->rdra = PHYSADDR(s, rdra);
824
    s->tdra = PHYSADDR(s, tdra);
825

    
826
    CSR_RCVRC(s) = CSR_RCVRL(s);
827
    CSR_XMTRC(s) = CSR_XMTRL(s);
828

    
829
#ifdef PCNET_DEBUG
830
    printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n", 
831
        BCR_SSIZE32(s),
832
        s->rdra, CSR_RCVRL(s), s->tdra, CSR_XMTRL(s));
833
#endif
834

    
835
    s->csr[0] |= 0x0101;    
836
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
837
}
838

    
839
static void pcnet_start(PCNetState *s)
840
{
841
#ifdef PCNET_DEBUG
842
    printf("pcnet_start\n");
843
#endif
844

    
845
    if (!CSR_DTX(s))
846
        s->csr[0] |= 0x0010;    /* set TXON */
847
        
848
    if (!CSR_DRX(s))
849
        s->csr[0] |= 0x0020;    /* set RXON */
850

    
851
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
852
    s->csr[0] |= 0x0002;
853
}
854

    
855
static void pcnet_stop(PCNetState *s)
856
{
857
#ifdef PCNET_DEBUG
858
    printf("pcnet_stop\n");
859
#endif
860
    s->csr[0] &= ~0x7feb;
861
    s->csr[0] |= 0x0014;
862
    s->csr[4] &= ~0x02c2;
863
    s->csr[5] &= ~0x0011;
864
    pcnet_poll_timer(s);
865
}
866

    
867
static void pcnet_rdte_poll(PCNetState *s)
868
{
869
    s->csr[28] = s->csr[29] = 0;
870
    if (s->rdra) {
871
        int bad = 0;
872
#if 1
873
        target_phys_addr_t crda = pcnet_rdra_addr(s, CSR_RCVRC(s));
874
        target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s));
875
        target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s));
876
#else
877
        target_phys_addr_t crda = s->rdra + 
878
            (CSR_RCVRL(s) - CSR_RCVRC(s)) *
879
            (BCR_SWSTYLE(s) ? 16 : 8 );
880
        int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1;
881
        target_phys_addr_t nrda = s->rdra + 
882
            (CSR_RCVRL(s) - nrdc) *
883
            (BCR_SWSTYLE(s) ? 16 : 8 );
884
        int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1;
885
        target_phys_addr_t nnrd = s->rdra + 
886
            (CSR_RCVRL(s) - nnrc) *
887
            (BCR_SWSTYLE(s) ? 16 : 8 );
888
#endif
889

    
890
        CHECK_RMD(PHYSADDR(s,crda), bad);
891
        if (!bad) {
892
            CHECK_RMD(PHYSADDR(s,nrda), bad);
893
            if (bad || (nrda == crda)) nrda = 0;
894
            CHECK_RMD(PHYSADDR(s,nnrd), bad);
895
            if (bad || (nnrd == crda)) nnrd = 0;
896

    
897
            s->csr[28] = crda & 0xffff;
898
            s->csr[29] = crda >> 16;
899
            s->csr[26] = nrda & 0xffff;
900
            s->csr[27] = nrda >> 16;
901
            s->csr[36] = nnrd & 0xffff;
902
            s->csr[37] = nnrd >> 16;
903
#ifdef PCNET_DEBUG
904
            if (bad) {
905
                printf("pcnet: BAD RMD RECORDS AFTER 0x%08x\n",
906
                       PHYSADDR(s,crda));
907
            }
908
        } else {
909
            printf("pcnet: BAD RMD RDA=0x%08x\n", PHYSADDR(s,crda));
910
#endif
911
        }
912
    }
913
    
914
    if (CSR_CRDA(s)) {
915
        struct pcnet_RMD rmd;
916
        RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
917
        CSR_CRBC(s) = rmd.rmd1.bcnt;
918
        CSR_CRST(s) = ((uint32_t *)&rmd)[1] >> 16;
919
#ifdef PCNET_DEBUG_RMD_X
920
        printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMD1=0x%08x RMD2=0x%08x\n",
921
                PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
922
                ((uint32_t *)&rmd)[1], ((uint32_t *)&rmd)[2]);
923
        PRINT_RMD(&rmd);
924
#endif
925
    } else {
926
        CSR_CRBC(s) = CSR_CRST(s) = 0;
927
    }
928
    
929
    if (CSR_NRDA(s)) {
930
        struct pcnet_RMD rmd;
931
        RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
932
        CSR_NRBC(s) = rmd.rmd1.bcnt;
933
        CSR_NRST(s) = ((uint32_t *)&rmd)[1] >> 16;
934
    } else {
935
        CSR_NRBC(s) = CSR_NRST(s) = 0;
936
    }
937

    
938
}
939

    
940
static int pcnet_tdte_poll(PCNetState *s)
941
{
942
    s->csr[34] = s->csr[35] = 0;
943
    if (s->tdra) {
944
        target_phys_addr_t cxda = s->tdra + 
945
            (CSR_XMTRL(s) - CSR_XMTRC(s)) *
946
            (BCR_SWSTYLE(s) ? 16 : 8 );
947
        int bad = 0;
948
        CHECK_TMD(PHYSADDR(s, cxda),bad);
949
        if (!bad) {
950
            if (CSR_CXDA(s) != cxda) {
951
                s->csr[60] = s->csr[34];
952
                s->csr[61] = s->csr[35];
953
                s->csr[62] = CSR_CXBC(s);
954
                s->csr[63] = CSR_CXST(s);
955
            }
956
            s->csr[34] = cxda & 0xffff;
957
            s->csr[35] = cxda >> 16;
958
#ifdef PCNET_DEBUG
959
        } else {
960
            printf("pcnet: BAD TMD XDA=0x%08x\n", PHYSADDR(s,cxda));
961
#endif
962
        }
963
    }
964

    
965
    if (CSR_CXDA(s)) {
966
        struct pcnet_TMD tmd;
967

    
968
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));                
969

    
970
        CSR_CXBC(s) = tmd.tmd1.bcnt;
971
        CSR_CXST(s) = ((uint32_t *)&tmd)[1] >> 16;
972
    } else {
973
        CSR_CXBC(s) = CSR_CXST(s) = 0;
974
    }
975
    
976
    return !!(CSR_CXST(s) & 0x8000);
977
}
978

    
979
static int pcnet_can_receive(void *opaque)
980
{
981
    PCNetState *s = opaque;
982
    if (CSR_STOP(s) || CSR_SPND(s))
983
        return 0;
984
        
985
    if (s->recv_pos > 0)
986
        return 0;
987

    
988
    return sizeof(s->buffer)-16;
989
}
990

    
991
#define MIN_BUF_SIZE 60
992

    
993
static void pcnet_receive(void *opaque, const uint8_t *buf, int size)
994
{
995
    PCNetState *s = opaque;
996
    int is_padr = 0, is_bcast = 0, is_ladr = 0;
997
    uint8_t buf1[60];
998

    
999
    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
1000
        return;
1001

    
1002
#ifdef PCNET_DEBUG
1003
    printf("pcnet_receive size=%d\n", size);
1004
#endif
1005

    
1006
    /* if too small buffer, then expand it */
1007
    if (size < MIN_BUF_SIZE) {
1008
        memcpy(buf1, buf, size);
1009
        memset(buf1 + size, 0, MIN_BUF_SIZE - size);
1010
        buf = buf1;
1011
        size = MIN_BUF_SIZE;
1012
    }
1013

    
1014
    if (CSR_PROM(s) 
1015
        || (is_padr=padr_match(s, buf, size)) 
1016
        || (is_bcast=padr_bcast(s, buf, size))
1017
        || (is_ladr=ladr_match(s, buf, size))) {
1018

    
1019
        pcnet_rdte_poll(s);
1020

    
1021
        if (!(CSR_CRST(s) & 0x8000) && s->rdra) {
1022
            struct pcnet_RMD rmd;
1023
            int rcvrc = CSR_RCVRC(s)-1,i;
1024
            target_phys_addr_t nrda;
1025
            for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {
1026
                if (rcvrc <= 1)
1027
                    rcvrc = CSR_RCVRL(s);
1028
                nrda = s->rdra +
1029
                    (CSR_RCVRL(s) - rcvrc) *
1030
                    (BCR_SWSTYLE(s) ? 16 : 8 );
1031
                RMDLOAD(&rmd, PHYSADDR(s,nrda));                  
1032
                if (rmd.rmd1.own) {                
1033
#ifdef PCNET_DEBUG_RMD
1034
                    printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n", 
1035
                                rcvrc, CSR_RCVRC(s));
1036
#endif
1037
                    CSR_RCVRC(s) = rcvrc;
1038
                    pcnet_rdte_poll(s);
1039
                    break;
1040
                }
1041
            }
1042
        }
1043

    
1044
        if (!(CSR_CRST(s) & 0x8000)) {
1045
#ifdef PCNET_DEBUG_RMD
1046
            printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));
1047
#endif
1048
            s->csr[0] |= 0x1000; /* Set MISS flag */
1049
            CSR_MISSC(s)++;
1050
        } else {
1051
            uint8_t *src = &s->buffer[8];
1052
            target_phys_addr_t crda = CSR_CRDA(s);
1053
            struct pcnet_RMD rmd;
1054
            int pktcount = 0;
1055

    
1056
            memcpy(src, buf, size);
1057
            
1058
#if 1
1059
            /* no need to compute the CRC */
1060
            src[size] = 0;
1061
            src[size + 1] = 0;
1062
            src[size + 2] = 0;
1063
            src[size + 3] = 0;
1064
            size += 4;
1065
#else
1066
            /* XXX: avoid CRC generation */
1067
            if (!CSR_ASTRP_RCV(s)) {
1068
                uint32_t fcs = ~0;
1069
                uint8_t *p = src;
1070

    
1071
                while (size < 46) {
1072
                    src[size++] = 0;
1073
                }
1074
                
1075
                while (p != &src[size]) {
1076
                    CRC(fcs, *p++);
1077
                }
1078
                ((uint32_t *)&src[size])[0] = htonl(fcs);
1079
                size += 4; /* FCS at end of packet */
1080
            } else size += 4;
1081
#endif
1082

    
1083
#ifdef PCNET_DEBUG_MATCH
1084
            PRINT_PKTHDR(buf);
1085
#endif
1086

    
1087
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1088
            /*if (!CSR_LAPPEN(s))*/
1089
                rmd.rmd1.stp = 1;
1090

    
1091
#define PCNET_RECV_STORE() do {                                 \
1092
    int count = MIN(4096 - rmd.rmd1.bcnt,size);                 \
1093
    target_phys_addr_t rbadr = PHYSADDR(s, rmd.rmd0.rbadr);     \
1094
    s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s));  \
1095
    src += count; size -= count;                                \
1096
    rmd.rmd2.mcnt = count; rmd.rmd1.own = 0;                    \
1097
    RMDSTORE(&rmd, PHYSADDR(s,crda));                           \
1098
    pktcount++;                                                 \
1099
} while (0)
1100

    
1101
            PCNET_RECV_STORE();
1102
            if ((size > 0) && CSR_NRDA(s)) {
1103
                target_phys_addr_t nrda = CSR_NRDA(s);
1104
                RMDLOAD(&rmd, PHYSADDR(s,nrda));
1105
                if (rmd.rmd1.own) {
1106
                    crda = nrda;
1107
                    PCNET_RECV_STORE();
1108
                    if ((size > 0) && (nrda=CSR_NNRD(s))) {
1109
                        RMDLOAD(&rmd, PHYSADDR(s,nrda));
1110
                        if (rmd.rmd1.own) {
1111
                            crda = nrda;
1112
                            PCNET_RECV_STORE();
1113
                        }
1114
                    }
1115
                }                
1116
            }
1117

    
1118
#undef PCNET_RECV_STORE
1119

    
1120
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1121
            if (size == 0) {
1122
                rmd.rmd1.enp = 1;
1123
                rmd.rmd1.pam = !CSR_PROM(s) && is_padr;
1124
                rmd.rmd1.lafm = !CSR_PROM(s) && is_ladr;
1125
                rmd.rmd1.bam = !CSR_PROM(s) && is_bcast;
1126
            } else {
1127
                rmd.rmd1.oflo = 1;
1128
                rmd.rmd1.buff = 1;
1129
                rmd.rmd1.err = 1;
1130
            }
1131
            RMDSTORE(&rmd, PHYSADDR(s,crda));
1132
            s->csr[0] |= 0x0400;
1133

    
1134
#ifdef PCNET_DEBUG
1135
            printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n", 
1136
                CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
1137
#endif
1138
#ifdef PCNET_DEBUG_RMD
1139
            PRINT_RMD(&rmd);
1140
#endif        
1141

    
1142
            while (pktcount--) {
1143
                if (CSR_RCVRC(s) <= 1)
1144
                    CSR_RCVRC(s) = CSR_RCVRL(s);
1145
                else
1146
                    CSR_RCVRC(s)--;            
1147
            }
1148
            
1149
            pcnet_rdte_poll(s);
1150

    
1151
        }        
1152
    }
1153

    
1154
    pcnet_poll(s);
1155
    pcnet_update_irq(s);    
1156
}
1157

    
1158
static void pcnet_transmit(PCNetState *s)
1159
{
1160
    target_phys_addr_t xmit_cxda = 0;
1161
    int count = CSR_XMTRL(s)-1;
1162
    s->xmit_pos = -1;
1163
    
1164
    if (!CSR_TXON(s)) {
1165
        s->csr[0] &= ~0x0008;
1166
        return;
1167
    }
1168

    
1169
    s->tx_busy = 1;
1170

    
1171
    txagain:
1172
    if (pcnet_tdte_poll(s)) {
1173
        struct pcnet_TMD tmd;
1174

    
1175
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));                
1176

    
1177
#ifdef PCNET_DEBUG_TMD
1178
        printf("  TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
1179
        PRINT_TMD(&tmd);
1180
#endif
1181
        if (tmd.tmd1.stp) {
1182
            s->xmit_pos = 0;                
1183
            if (!tmd.tmd1.enp) {
1184
                s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr),
1185
                                 s->buffer, 4096 - tmd.tmd1.bcnt, 
1186
                                 CSR_BSWP(s));
1187
                s->xmit_pos += 4096 - tmd.tmd1.bcnt;
1188
            } 
1189
            xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
1190
        }
1191
        if (tmd.tmd1.enp && (s->xmit_pos >= 0)) {
1192
            s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr),
1193
                             s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt, 
1194
                             CSR_BSWP(s));
1195
            s->xmit_pos += 4096 - tmd.tmd1.bcnt;
1196
#ifdef PCNET_DEBUG
1197
            printf("pcnet_transmit size=%d\n", s->xmit_pos);
1198
#endif            
1199
            if (CSR_LOOP(s))
1200
                pcnet_receive(s, s->buffer, s->xmit_pos);
1201
            else
1202
                qemu_send_packet(s->vc, s->buffer, s->xmit_pos);
1203

    
1204
            s->csr[0] &= ~0x0008;   /* clear TDMD */
1205
            s->csr[4] |= 0x0004;    /* set TXSTRT */
1206
            s->xmit_pos = -1;
1207
        }
1208

    
1209
        tmd.tmd1.own = 0;
1210
        TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1211
        if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && tmd.tmd1.ltint))
1212
            s->csr[0] |= 0x0200;    /* set TINT */
1213

    
1214
        if (CSR_XMTRC(s)<=1)
1215
            CSR_XMTRC(s) = CSR_XMTRL(s);
1216
        else
1217
            CSR_XMTRC(s)--;
1218
        if (count--)
1219
            goto txagain;
1220

    
1221
    } else 
1222
    if (s->xmit_pos >= 0) {
1223
        struct pcnet_TMD tmd;
1224
        TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));                
1225
        tmd.tmd2.buff = tmd.tmd2.uflo = tmd.tmd1.err = 1;
1226
        tmd.tmd1.own = 0;
1227
        TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda));
1228
        s->csr[0] |= 0x0200;    /* set TINT */
1229
        if (!CSR_DXSUFLO(s)) {
1230
            s->csr[0] &= ~0x0010;
1231
        } else
1232
        if (count--)
1233
          goto txagain;
1234
    }
1235

    
1236
    s->tx_busy = 0;
1237
}
1238

    
1239
static void pcnet_poll(PCNetState *s)
1240
{
1241
    if (CSR_RXON(s)) {
1242
        pcnet_rdte_poll(s);
1243
    }
1244

    
1245
    if (CSR_TDMD(s) || 
1246
        (CSR_TXON(s) && !CSR_DPOLL(s) && pcnet_tdte_poll(s)))
1247
    {
1248
        /* prevent recursion */
1249
        if (s->tx_busy)
1250
            return;
1251

    
1252
        pcnet_transmit(s);
1253
    }
1254
}
1255

    
1256
static void pcnet_poll_timer(void *opaque)
1257
{
1258
    PCNetState *s = opaque;
1259

    
1260
    qemu_del_timer(s->poll_timer);
1261

    
1262
    if (CSR_TDMD(s)) {
1263
        pcnet_transmit(s);
1264
    }
1265

    
1266
    pcnet_update_irq(s);    
1267

    
1268
    if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
1269
        uint64_t now = qemu_get_clock(vm_clock) * 33;
1270
        if (!s->timer || !now)
1271
            s->timer = now;
1272
        else {
1273
            uint64_t t = now - s->timer + CSR_POLL(s);
1274
            if (t > 0xffffLL) {
1275
                pcnet_poll(s);
1276
                CSR_POLL(s) = CSR_PINT(s);
1277
            } else
1278
                CSR_POLL(s) = t;
1279
        }
1280
        qemu_mod_timer(s->poll_timer, 
1281
            pcnet_get_next_poll_time(s,qemu_get_clock(vm_clock)));
1282
    }
1283
}
1284

    
1285

    
1286
static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value)
1287
{
1288
    uint16_t val = new_value;
1289
#ifdef PCNET_DEBUG_CSR
1290
    printf("pcnet_csr_writew rap=%d val=0x%04x\n", rap, val);
1291
#endif
1292
    switch (rap) {
1293
    case 0:
1294
        s->csr[0] &= ~(val & 0x7f00); /* Clear any interrupt flags */
1295

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

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

    
1300
        /* IFF STOP, STRT and INIT are set, clear STRT and INIT */
1301
        if ((val&7) == 7)
1302
          val &= ~3;
1303

    
1304
        if (!CSR_STOP(s) && (val & 4))
1305
            pcnet_stop(s);
1306

    
1307
        if (!CSR_INIT(s) && (val & 1))
1308
            pcnet_init(s);
1309

    
1310
        if (!CSR_STRT(s) && (val & 2))
1311
            pcnet_start(s);
1312

    
1313
        if (CSR_TDMD(s)) 
1314
            pcnet_transmit(s);
1315

    
1316
        return;
1317
    case 1:
1318
    case 2:
1319
    case 8:
1320
    case 9:
1321
    case 10:
1322
    case 11:
1323
    case 12:
1324
    case 13:
1325
    case 14:
1326
    case 15:
1327
    case 18: /* CRBAL */
1328
    case 19: /* CRBAU */
1329
    case 20: /* CXBAL */
1330
    case 21: /* CXBAU */
1331
    case 22: /* NRBAU */
1332
    case 23: /* NRBAU */
1333
    case 24:
1334
    case 25:
1335
    case 26:
1336
    case 27:
1337
    case 28:
1338
    case 29:
1339
    case 30:
1340
    case 31:
1341
    case 32:
1342
    case 33:
1343
    case 34:
1344
    case 35:
1345
    case 36:
1346
    case 37:
1347
    case 38:
1348
    case 39:
1349
    case 40: /* CRBC */
1350
    case 41:
1351
    case 42: /* CXBC */
1352
    case 43:
1353
    case 44:
1354
    case 45:
1355
    case 46: /* POLL */
1356
    case 47: /* POLLINT */
1357
    case 72:
1358
    case 74:
1359
    case 76: /* RCVRL */
1360
    case 78: /* XMTRL */
1361
    case 112:
1362
       if (CSR_STOP(s) || CSR_SPND(s))
1363
           break;
1364
       return;
1365
    case 3:
1366
        break;
1367
    case 4:
1368
        s->csr[4] &= ~(val & 0x026a); 
1369
        val &= ~0x026a; val |= s->csr[4] & 0x026a;
1370
        break;
1371
    case 5:
1372
        s->csr[5] &= ~(val & 0x0a90); 
1373
        val &= ~0x0a90; val |= s->csr[5] & 0x0a90;
1374
        break;
1375
    case 16:
1376
        pcnet_csr_writew(s,1,val);
1377
        return;
1378
    case 17:
1379
        pcnet_csr_writew(s,2,val);
1380
        return;
1381
    case 58:
1382
        pcnet_bcr_writew(s,BCR_SWS,val);
1383
        break;
1384
    default:
1385
        return;
1386
    }
1387
    s->csr[rap] = val;
1388
}
1389

    
1390
static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap)
1391
{
1392
    uint32_t val;
1393
    switch (rap) {
1394
    case 0:
1395
        pcnet_update_irq(s);
1396
        val = s->csr[0];
1397
        val |= (val & 0x7800) ? 0x8000 : 0;
1398
        break;
1399
    case 16:
1400
        return pcnet_csr_readw(s,1);
1401
    case 17:
1402
        return pcnet_csr_readw(s,2);
1403
    case 58:
1404
        return pcnet_bcr_readw(s,BCR_SWS);
1405
    case 88:
1406
        val = s->csr[89];
1407
        val <<= 16;
1408
        val |= s->csr[88];
1409
        break;
1410
    default:
1411
        val = s->csr[rap];
1412
    }
1413
#ifdef PCNET_DEBUG_CSR
1414
    printf("pcnet_csr_readw rap=%d val=0x%04x\n", rap, val);
1415
#endif
1416
    return val;
1417
}
1418

    
1419
static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val)
1420
{
1421
    rap &= 127;
1422
#ifdef PCNET_DEBUG_BCR
1423
    printf("pcnet_bcr_writew rap=%d val=0x%04x\n", rap, val);
1424
#endif
1425
    switch (rap) {
1426
    case BCR_SWS:
1427
        if (!(CSR_STOP(s) || CSR_SPND(s)))
1428
            return;
1429
        val &= ~0x0300;
1430
        switch (val & 0x00ff) {
1431
        case 0:
1432
            val |= 0x0200;
1433
            break;
1434
        case 1:
1435
            val |= 0x0100;
1436
            break;
1437
        case 2:
1438
        case 3:
1439
            val |= 0x0300;
1440
            break;
1441
        default:
1442
            printf("Bad SWSTYLE=0x%02x\n", val & 0xff);
1443
            val = 0x0200;
1444
            break;
1445
        }
1446
#ifdef PCNET_DEBUG
1447
       printf("BCR_SWS=0x%04x\n", val);
1448
#endif
1449
    case BCR_LNKST:
1450
    case BCR_LED1:
1451
    case BCR_LED2:
1452
    case BCR_LED3:
1453
    case BCR_MC:
1454
    case BCR_FDC:
1455
    case BCR_BSBC:
1456
    case BCR_EECAS:
1457
    case BCR_PLAT:
1458
        s->bcr[rap] = val;
1459
        break;
1460
    default:
1461
        break;
1462
    }
1463
}
1464

    
1465
static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap)
1466
{
1467
    uint32_t val;
1468
    rap &= 127;
1469
    switch (rap) {
1470
    case BCR_LNKST:
1471
    case BCR_LED1:
1472
    case BCR_LED2:
1473
    case BCR_LED3:
1474
        val = s->bcr[rap] & ~0x8000;
1475
        val |= (val & 0x017f & s->lnkst) ? 0x8000 : 0;
1476
        break;
1477
    default:
1478
        val = rap < 32 ? s->bcr[rap] : 0;
1479
        break;
1480
    }
1481
#ifdef PCNET_DEBUG_BCR
1482
    printf("pcnet_bcr_readw rap=%d val=0x%04x\n", rap, val);
1483
#endif
1484
    return val;
1485
}
1486

    
1487
void pcnet_h_reset(void *opaque)
1488
{
1489
    PCNetState *s = opaque;
1490
    int i;
1491
    uint16_t checksum;
1492

    
1493
    /* Initialize the PROM */
1494

    
1495
    memcpy(s->prom, s->nd->macaddr, 6);
1496
    s->prom[12] = s->prom[13] = 0x00;
1497
    s->prom[14] = s->prom[15] = 0x57;
1498

    
1499
    for (i = 0,checksum = 0; i < 16; i++)
1500
        checksum += s->prom[i];
1501
    *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);
1502

    
1503

    
1504
    s->bcr[BCR_MSRDA] = 0x0005;
1505
    s->bcr[BCR_MSWRA] = 0x0005;
1506
    s->bcr[BCR_MC   ] = 0x0002;
1507
    s->bcr[BCR_LNKST] = 0x00c0;
1508
    s->bcr[BCR_LED1 ] = 0x0084;
1509
    s->bcr[BCR_LED2 ] = 0x0088;
1510
    s->bcr[BCR_LED3 ] = 0x0090;
1511
    s->bcr[BCR_FDC  ] = 0x0000;
1512
    s->bcr[BCR_BSBC ] = 0x9001;
1513
    s->bcr[BCR_EECAS] = 0x0002;
1514
    s->bcr[BCR_SWS  ] = 0x0200;
1515
    s->bcr[BCR_PLAT ] = 0xff06;
1516

    
1517
    pcnet_s_reset(s);
1518
}
1519

    
1520
static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
1521
{
1522
    PCNetState *s = opaque;
1523
#ifdef PCNET_DEBUG
1524
    printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);
1525
#endif    
1526
    /* Check APROMWE bit to enable write access */
1527
    if (pcnet_bcr_readw(s,2) & 0x80)
1528
        s->prom[addr & 15] = val;
1529
}       
1530

    
1531
static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
1532
{
1533
    PCNetState *s = opaque;
1534
    uint32_t val = s->prom[addr &= 15];
1535
#ifdef PCNET_DEBUG
1536
    printf("pcnet_aprom_readb addr=0x%08x val=0x%02x\n", addr, val);
1537
#endif
1538
    return val;
1539
}
1540

    
1541
static void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
1542
{
1543
    PCNetState *s = opaque;
1544
    pcnet_poll_timer(s);
1545
#ifdef PCNET_DEBUG_IO
1546
    printf("pcnet_ioport_writew addr=0x%08x val=0x%04x\n", addr, val);
1547
#endif
1548
    if (!BCR_DWIO(s)) {
1549
        switch (addr & 0x0f) {
1550
        case 0x00: /* RDP */
1551
            pcnet_csr_writew(s, s->rap, val);
1552
            break;
1553
        case 0x02:
1554
            s->rap = val & 0x7f;
1555
            break;
1556
        case 0x06:
1557
            pcnet_bcr_writew(s, s->rap, val);
1558
            break;
1559
        }
1560
    }
1561
    pcnet_update_irq(s);
1562
}
1563

    
1564
static uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr)
1565
{
1566
    PCNetState *s = opaque;
1567
    uint32_t val = -1;
1568
    pcnet_poll_timer(s);
1569
    if (!BCR_DWIO(s)) {
1570
        switch (addr & 0x0f) {
1571
        case 0x00: /* RDP */
1572
            val = pcnet_csr_readw(s, s->rap);
1573
            break;
1574
        case 0x02:
1575
            val = s->rap;
1576
            break;
1577
        case 0x04:
1578
            pcnet_s_reset(s);
1579
            val = 0;
1580
            break;
1581
        case 0x06:
1582
            val = pcnet_bcr_readw(s, s->rap);
1583
            break;
1584
        }
1585
    }
1586
    pcnet_update_irq(s);
1587
#ifdef PCNET_DEBUG_IO
1588
    printf("pcnet_ioport_readw addr=0x%08x val=0x%04x\n", addr, val & 0xffff);
1589
#endif
1590
    return val;
1591
}
1592

    
1593
static void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
1594
{
1595
    PCNetState *s = opaque;
1596
    pcnet_poll_timer(s);
1597
#ifdef PCNET_DEBUG_IO
1598
    printf("pcnet_ioport_writel addr=0x%08x val=0x%08x\n", addr, val);
1599
#endif
1600
    if (BCR_DWIO(s)) {
1601
        switch (addr & 0x0f) {
1602
        case 0x00: /* RDP */
1603
            pcnet_csr_writew(s, s->rap, val & 0xffff);
1604
            break;
1605
        case 0x04:
1606
            s->rap = val & 0x7f;
1607
            break;
1608
        case 0x0c:
1609
            pcnet_bcr_writew(s, s->rap, val & 0xffff);
1610
            break;
1611
        }
1612
    } else
1613
    if ((addr & 0x0f) == 0) {
1614
        /* switch device to dword i/o mode */
1615
        pcnet_bcr_writew(s, BCR_BSBC, pcnet_bcr_readw(s, BCR_BSBC) | 0x0080);
1616
#ifdef PCNET_DEBUG_IO
1617
        printf("device switched into dword i/o mode\n");
1618
#endif        
1619
    }
1620
    pcnet_update_irq(s);
1621
}
1622

    
1623
static uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr)
1624
{
1625
    PCNetState *s = opaque;
1626
    uint32_t val = -1;
1627
    pcnet_poll_timer(s);
1628
    if (BCR_DWIO(s)) {  
1629
        switch (addr & 0x0f) {
1630
        case 0x00: /* RDP */
1631
            val = pcnet_csr_readw(s, s->rap);
1632
            break;
1633
        case 0x04:
1634
            val = s->rap;
1635
            break;
1636
        case 0x08:
1637
            pcnet_s_reset(s);
1638
            val = 0;
1639
            break;
1640
        case 0x0c:
1641
            val = pcnet_bcr_readw(s, s->rap);
1642
            break;
1643
        }
1644
    }
1645
    pcnet_update_irq(s);
1646
#ifdef PCNET_DEBUG_IO
1647
    printf("pcnet_ioport_readl addr=0x%08x val=0x%08x\n", addr, val);
1648
#endif
1649
    return val;
1650
}
1651

    
1652
static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num, 
1653
                             uint32_t addr, uint32_t size, int type)
1654
{
1655
    PCNetState *d = (PCNetState *)pci_dev;
1656

    
1657
#ifdef PCNET_DEBUG_IO
1658
    printf("pcnet_ioport_map addr=0x%04x size=0x%04x\n", addr, size);
1659
#endif
1660

    
1661
    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
1662
    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
1663
    
1664
    register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
1665
    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
1666
    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
1667
    register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
1668
}
1669

    
1670
static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
1671
{
1672
    PCNetState *d = opaque;
1673
#ifdef PCNET_DEBUG_IO
1674
    printf("pcnet_mmio_writeb addr=0x%08x val=0x%02x\n", addr, val);
1675
#endif
1676
    if (!(addr & 0x10))
1677
        pcnet_aprom_writeb(d, addr & 0x0f, val);
1678
}
1679

    
1680
static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr) 
1681
{
1682
    PCNetState *d = opaque;
1683
    uint32_t val = -1;
1684
    if (!(addr & 0x10))
1685
        val = pcnet_aprom_readb(d, addr & 0x0f);
1686
#ifdef PCNET_DEBUG_IO
1687
    printf("pcnet_mmio_readb addr=0x%08x val=0x%02x\n", addr, val & 0xff);
1688
#endif
1689
    return val;
1690
}
1691

    
1692
static void pcnet_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
1693
{
1694
    PCNetState *d = opaque;
1695
#ifdef PCNET_DEBUG_IO
1696
    printf("pcnet_mmio_writew addr=0x%08x val=0x%04x\n", addr, val);
1697
#endif
1698
    if (addr & 0x10)
1699
        pcnet_ioport_writew(d, addr & 0x0f, val);
1700
    else {
1701
        addr &= 0x0f;
1702
        pcnet_aprom_writeb(d, addr, val & 0xff);
1703
        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
1704
    }
1705
}
1706

    
1707
static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr) 
1708
{
1709
    PCNetState *d = opaque;
1710
    uint32_t val = -1;
1711
    if (addr & 0x10)
1712
        val = pcnet_ioport_readw(d, addr & 0x0f);
1713
    else {
1714
        addr &= 0x0f;
1715
        val = pcnet_aprom_readb(d, addr+1);
1716
        val <<= 8;
1717
        val |= pcnet_aprom_readb(d, addr);
1718
    }
1719
#ifdef PCNET_DEBUG_IO
1720
    printf("pcnet_mmio_readw addr=0x%08x val = 0x%04x\n", addr, val & 0xffff);
1721
#endif
1722
    return val;
1723
}
1724

    
1725
static void pcnet_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
1726
{
1727
    PCNetState *d = opaque;
1728
#ifdef PCNET_DEBUG_IO
1729
    printf("pcnet_mmio_writel addr=0x%08x val=0x%08x\n", addr, val);
1730
#endif
1731
    if (addr & 0x10)
1732
        pcnet_ioport_writel(d, addr & 0x0f, val);
1733
    else {
1734
        addr &= 0x0f;
1735
        pcnet_aprom_writeb(d, addr, val & 0xff);
1736
        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);
1737
        pcnet_aprom_writeb(d, addr+2, (val & 0xff0000) >> 16);
1738
        pcnet_aprom_writeb(d, addr+3, (val & 0xff000000) >> 24);
1739
    }
1740
}
1741

    
1742
static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr) 
1743
{
1744
    PCNetState *d = opaque;
1745
    uint32_t val;
1746
    if (addr & 0x10)
1747
        val = pcnet_ioport_readl(d, addr & 0x0f);
1748
    else {
1749
        addr &= 0x0f;
1750
        val = pcnet_aprom_readb(d, addr+3);
1751
        val <<= 8;
1752
        val |= pcnet_aprom_readb(d, addr+2);
1753
        val <<= 8;
1754
        val |= pcnet_aprom_readb(d, addr+1);
1755
        val <<= 8;
1756
        val |= pcnet_aprom_readb(d, addr);
1757
    }
1758
#ifdef PCNET_DEBUG_IO
1759
    printf("pcnet_mmio_readl addr=0x%08x val=0x%08x\n", addr, val);
1760
#endif
1761
    return val;
1762
}
1763

    
1764

    
1765
static void pcnet_save(QEMUFile *f, void *opaque)
1766
{
1767
    PCNetState *s = opaque;
1768
    unsigned int i;
1769

    
1770
    if (s->pci_dev)
1771
        pci_device_save(s->pci_dev, f);
1772

    
1773
    qemu_put_be32s(f, &s->rap);
1774
    qemu_put_be32s(f, &s->isr);
1775
    qemu_put_be32s(f, &s->lnkst);
1776
    qemu_put_be32s(f, &s->rdra);
1777
    qemu_put_be32s(f, &s->tdra);
1778
    qemu_put_buffer(f, s->prom, 16);
1779
    for (i = 0; i < 128; i++)
1780
        qemu_put_be16s(f, &s->csr[i]);
1781
    for (i = 0; i < 32; i++)
1782
        qemu_put_be16s(f, &s->bcr[i]);
1783
    qemu_put_be64s(f, &s->timer);
1784
    qemu_put_be32s(f, &s->xmit_pos);
1785
    qemu_put_be32s(f, &s->recv_pos);
1786
    qemu_put_buffer(f, s->buffer, 4096);
1787
    qemu_put_be32s(f, &s->tx_busy);
1788
    qemu_put_timer(f, s->poll_timer);
1789
}
1790

    
1791
static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
1792
{
1793
    PCNetState *s = opaque;
1794
    int i, ret;
1795

    
1796
    if (version_id != 2)
1797
        return -EINVAL;
1798

    
1799
    if (s->pci_dev) {
1800
        ret = pci_device_load(s->pci_dev, f);
1801
        if (ret < 0)
1802
            return ret;
1803
    }
1804

    
1805
    qemu_get_be32s(f, &s->rap);
1806
    qemu_get_be32s(f, &s->isr);
1807
    qemu_get_be32s(f, &s->lnkst);
1808
    qemu_get_be32s(f, &s->rdra);
1809
    qemu_get_be32s(f, &s->tdra);
1810
    qemu_get_buffer(f, s->prom, 16);
1811
    for (i = 0; i < 128; i++)
1812
        qemu_get_be16s(f, &s->csr[i]);
1813
    for (i = 0; i < 32; i++)
1814
        qemu_get_be16s(f, &s->bcr[i]);
1815
    qemu_get_be64s(f, &s->timer);
1816
    qemu_get_be32s(f, &s->xmit_pos);
1817
    qemu_get_be32s(f, &s->recv_pos);
1818
    qemu_get_buffer(f, s->buffer, 4096);
1819
    qemu_get_be32s(f, &s->tx_busy);
1820
    qemu_get_timer(f, s->poll_timer);
1821

    
1822
    return 0;
1823
}
1824

    
1825
static void pcnet_common_init(PCNetState *d, NICInfo *nd, const char *info_str)
1826
{
1827
    d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d);
1828

    
1829
    d->nd = nd;
1830

    
1831
    d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive, 
1832
                                 pcnet_can_receive, d);
1833
    
1834
    snprintf(d->vc->info_str, sizeof(d->vc->info_str),
1835
             "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
1836
             d->nd->macaddr[0],
1837
             d->nd->macaddr[1],
1838
             d->nd->macaddr[2],
1839
             d->nd->macaddr[3],
1840
             d->nd->macaddr[4],
1841
             d->nd->macaddr[5]);
1842

    
1843
    pcnet_h_reset(d);
1844
    register_savevm("pcnet", 0, 2, pcnet_save, pcnet_load, d);
1845
}
1846

    
1847
/* PCI interface */
1848

    
1849
static CPUWriteMemoryFunc *pcnet_mmio_write[] = {
1850
    (CPUWriteMemoryFunc *)&pcnet_mmio_writeb,
1851
    (CPUWriteMemoryFunc *)&pcnet_mmio_writew,
1852
    (CPUWriteMemoryFunc *)&pcnet_mmio_writel
1853
};
1854

    
1855
static CPUReadMemoryFunc *pcnet_mmio_read[] = {
1856
    (CPUReadMemoryFunc *)&pcnet_mmio_readb,
1857
    (CPUReadMemoryFunc *)&pcnet_mmio_readw,
1858
    (CPUReadMemoryFunc *)&pcnet_mmio_readl
1859
};
1860

    
1861
static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num, 
1862
                            uint32_t addr, uint32_t size, int type)
1863
{
1864
    PCNetState *d = (PCNetState *)pci_dev;
1865

    
1866
#ifdef PCNET_DEBUG_IO
1867
    printf("pcnet_ioport_map addr=0x%08x 0x%08x\n", addr, size);
1868
#endif
1869

    
1870
    cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_index);
1871
}
1872

    
1873
static void pcnet_pci_set_irq_cb(void *opaque, int isr)
1874
{
1875
    PCNetState *s = opaque;
1876

    
1877
    pci_set_irq(&s->dev, 0, isr);
1878
}
1879

    
1880
static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
1881
                                      uint8_t *buf, int len, int do_bswap)
1882
{
1883
    cpu_physical_memory_write(addr, buf, len);
1884
}
1885

    
1886
static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
1887
                                     uint8_t *buf, int len, int do_bswap)
1888
{
1889
    cpu_physical_memory_read(addr, buf, len);
1890
}
1891

    
1892
void pci_pcnet_init(PCIBus *bus, NICInfo *nd)
1893
{
1894
    PCNetState *d;
1895
    uint8_t *pci_conf;
1896

    
1897
#if 0
1898
    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n", 
1899
        sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
1900
#endif
1901

    
1902
    d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
1903
                                          -1, NULL, NULL);
1904
                                          
1905
    pci_conf = d->dev.config;
1906
    
1907
    *(uint16_t *)&pci_conf[0x00] = cpu_to_le16(0x1022);
1908
    *(uint16_t *)&pci_conf[0x02] = cpu_to_le16(0x2000);    
1909
    *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007); 
1910
    *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
1911
    pci_conf[0x08] = 0x10;
1912
    pci_conf[0x09] = 0x00;
1913
    pci_conf[0x0a] = 0x00; // ethernet network controller 
1914
    pci_conf[0x0b] = 0x02;
1915
    pci_conf[0x0e] = 0x00; // header_type
1916
    
1917
    *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
1918
    *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
1919
    
1920
    pci_conf[0x3d] = 1; // interrupt pin 0
1921
    pci_conf[0x3e] = 0x06;
1922
    pci_conf[0x3f] = 0xff;
1923

    
1924
    /* Handler for memory-mapped I/O */
1925
    d->mmio_index =
1926
      cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);
1927

    
1928
    pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE, 
1929
                           PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
1930
                           
1931
    pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE, 
1932
                           PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
1933
                           
1934
    d->set_irq_cb = pcnet_pci_set_irq_cb;
1935
    d->phys_mem_read = pci_physical_memory_read;
1936
    d->phys_mem_write = pci_physical_memory_write;
1937
    d->pci_dev = &d->dev;
1938

    
1939
    pcnet_common_init(d, nd, "pcnet");
1940
}
1941

    
1942
/* SPARC32 interface */
1943

    
1944
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
1945

    
1946
static CPUReadMemoryFunc *lance_mem_read[3] = {
1947
    (CPUReadMemoryFunc *)&pcnet_ioport_readw,
1948
    (CPUReadMemoryFunc *)&pcnet_ioport_readw,
1949
    (CPUReadMemoryFunc *)&pcnet_ioport_readw,
1950
};
1951

    
1952
static CPUWriteMemoryFunc *lance_mem_write[3] = {
1953
    (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
1954
    (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
1955
    (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
1956
};
1957

    
1958
static void pcnet_sparc_set_irq_cb(void *opaque, int isr)
1959
{
1960
    PCNetState *s = opaque;
1961

    
1962
    ledma_set_irq(s->dma_opaque, isr);
1963
}
1964

    
1965
void *lance_init(NICInfo *nd, uint32_t leaddr, void *dma_opaque)
1966
{
1967
    PCNetState *d;
1968
    int lance_io_memory;
1969

    
1970
    d = qemu_mallocz(sizeof(PCNetState));
1971
    if (!d)
1972
        return NULL;
1973

    
1974
    lance_io_memory =
1975
        cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
1976

    
1977
    d->dma_opaque = dma_opaque;
1978
    cpu_register_physical_memory(leaddr, 4, lance_io_memory);
1979

    
1980
    d->set_irq_cb = pcnet_sparc_set_irq_cb;
1981
    d->phys_mem_read = ledma_memory_read;
1982
    d->phys_mem_write = ledma_memory_write;
1983

    
1984
    pcnet_common_init(d, nd, "lance");
1985

    
1986
    return d;
1987
}
1988
#endif /* TARGET_SPARC */