Statistics
| Branch: | Revision:

root / hw / pcnet.c @ 03c18475

History | View | Annotate | Download (61.6 kB)

1
/*
2
 * QEMU AMD PC-Net II (Am79C970A) emulation
3
 * 
4
 * Copyright (c) 2004 Antony T Curtis
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
 
25
/* This software was written to be compatible with the specification:
26
 * AMD Am79C970A PCnet-PCI II Ethernet Controller Data-Sheet
27
 * AMD Publication# 19436  Rev:E  Amendment/0  Issue Date: June 2000
28
 */
29
 
30
/*
31
 * On Sparc32, this is the Lance (Am7990) part of chip STP2000 (Master I/O), also
32
 * produced as NCR89C100. See
33
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
34
 * and
35
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR92C990.txt
36
 */
37

    
38
/* 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);
75
    void (*phys_mem_write)(void *dma_opaque, target_phys_addr_t addr,
76
                          uint8_t *buf, int len);
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_BIGENDIAN(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));
265
        if (CSR_BIGENDIAN(s)) {
266
            be16_to_cpus(&xda[0]);
267
            be16_to_cpus(&xda[1]);
268
            be16_to_cpus(&xda[2]);
269
            be16_to_cpus(&xda[3]);
270
        } else {
271
            le16_to_cpus(&xda[0]);
272
            le16_to_cpus(&xda[1]);
273
            le16_to_cpus(&xda[2]);
274
            le16_to_cpus(&xda[3]);
275
        }
276

    
277
        tmd[0] = (xda[0]&0xffff) |
278
            ((xda[1]&0x00ff) << 16);
279
        tmd[1] = (xda[2]&0xffff)|
280
            ((xda[1] & 0xff00) << 16);
281
        tmd[2] =
282
            (xda[3] & 0xffff) << 16;
283
        tmd[3] = 0;
284
    } else {
285
        uint32_t xda[4];
286
        s->phys_mem_read(s->dma_opaque, addr,
287
                (void *)&xda[0], sizeof(xda));
288
        if (CSR_BIGENDIAN(s)) {
289
            be32_to_cpus(&xda[0]);
290
            be32_to_cpus(&xda[1]);
291
            be32_to_cpus(&xda[2]);
292
            be32_to_cpus(&xda[3]);
293
        } else {
294
            le32_to_cpus(&xda[0]);
295
            le32_to_cpus(&xda[1]);
296
            le32_to_cpus(&xda[2]);
297
            le32_to_cpus(&xda[3]);
298
        }
299
        if (BCR_SWSTYLE(s) != 3) {
300
            memcpy(tmd, xda, sizeof(xda));
301
        } else {
302
            tmd[0] = xda[2];
303
            tmd[1] = xda[1];
304
            tmd[2] = xda[0];
305
            tmd[3] = xda[3];
306
        }
307
    }
308
}
309

    
310
static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd1,
311
                                   target_phys_addr_t addr)
312
{
313
    const uint32_t *tmd = (const uint32_t *)tmd1;
314
    if (!BCR_SWSTYLE(s)) {
315
        uint16_t xda[4];
316
        xda[0] = tmd[0] & 0xffff;
317
        xda[1] = ((tmd[0]>>16)&0x00ff) |
318
            ((tmd[1]>>16)&0xff00);
319
        xda[2] = tmd[1] & 0xffff;
320
        xda[3] = tmd[2] >> 16;
321
        if (CSR_BIGENDIAN(s)) {
322
            cpu_to_be16s(&xda[0]);
323
            cpu_to_be16s(&xda[1]);
324
            cpu_to_be16s(&xda[2]);
325
            cpu_to_be16s(&xda[3]);
326
        } else {
327
            cpu_to_le16s(&xda[0]);
328
            cpu_to_le16s(&xda[1]);
329
            cpu_to_le16s(&xda[2]);
330
            cpu_to_le16s(&xda[3]);
331
        }
332
        s->phys_mem_write(s->dma_opaque, addr,
333
                (void *)&xda[0], sizeof(xda));
334
    } else {
335
        uint32_t xda[4];
336
        if (BCR_SWSTYLE(s) != 3) {
337
            memcpy(xda, tmd, sizeof(xda));
338
        } else {
339
            xda[0] = tmd[2];
340
            xda[1] = tmd[1];
341
            xda[2] = tmd[0];
342
            xda[3] = tmd[3];
343
        }
344
        if (CSR_BIGENDIAN(s)) {
345
            cpu_to_be32s(&xda[0]);
346
            cpu_to_be32s(&xda[1]);
347
            cpu_to_be32s(&xda[2]);
348
            cpu_to_be32s(&xda[3]);
349
        } else {
350
            cpu_to_le32s(&xda[0]);
351
            cpu_to_le32s(&xda[1]);
352
            cpu_to_le32s(&xda[2]);
353
            cpu_to_le32s(&xda[3]);
354
        }
355
        s->phys_mem_write(s->dma_opaque, addr,
356
                          (void *)&xda[0], sizeof(xda));
357
    }
358
}
359

    
360
static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd1,
361
                                  target_phys_addr_t addr)
362
{
363
    uint32_t *rmd = (uint32_t *)rmd1;
364

    
365
    if (!BCR_SWSTYLE(s)) {
366
        uint16_t rda[4];
367
        s->phys_mem_read(s->dma_opaque, addr, (void *)&rda[0], sizeof(rda));
368
        if (CSR_BIGENDIAN(s)) {
369
            be16_to_cpus(&rda[0]);
370
            be16_to_cpus(&rda[1]);
371
            be16_to_cpus(&rda[2]);
372
            be16_to_cpus(&rda[3]);
373
        } else {
374
            le16_to_cpus(&rda[0]);
375
            le16_to_cpus(&rda[1]);
376
            le16_to_cpus(&rda[2]);
377
            le16_to_cpus(&rda[3]);
378
        }
379
        rmd[0] = (rda[0]&0xffff)|
380
            ((rda[1] & 0x00ff) << 16);
381
        rmd[1] = (rda[2]&0xffff)|
382
            ((rda[1] & 0xff00) << 16);
383
        rmd[2] = rda[3] & 0xffff;
384
        rmd[3] = 0;
385
    } else {
386
        uint32_t rda[4];
387
        s->phys_mem_read(s->dma_opaque, addr, (void *)&rda[0], sizeof(rda));
388
        if (CSR_BIGENDIAN(s)) {
389
            be32_to_cpus(&rda[0]);
390
            be32_to_cpus(&rda[1]);
391
            be32_to_cpus(&rda[2]);
392
            be32_to_cpus(&rda[3]);
393
        } else {
394
            le32_to_cpus(&rda[0]);
395
            le32_to_cpus(&rda[1]);
396
            le32_to_cpus(&rda[2]);
397
            le32_to_cpus(&rda[3]);
398
        }
399
        if (BCR_SWSTYLE(s) != 3) {
400
            memcpy(rmd, rda, sizeof(rda));
401
        } else {
402
            rmd[0] = rda[2];
403
            rmd[1] = rda[1];
404
            rmd[2] = rda[0];
405
            rmd[3] = rda[3];
406
        }
407
    }
408
}
409

    
410
static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd1, 
411
                                   target_phys_addr_t addr)
412
{
413
    const uint32_t *rmd = (const uint32_t *)rmd1;
414

    
415
    if (!BCR_SWSTYLE(s)) {
416
        uint16_t rda[4];
417
        rda[0] = rmd[0] & 0xffff;
418
        rda[1] = ((rmd[0]>>16)&0xff)|
419
            ((rmd[1]>>16)&0xff00);
420
        rda[2] = rmd[1] & 0xffff;
421
        rda[3] = rmd[2] & 0xffff;
422
        if (CSR_BIGENDIAN(s)) {
423
            cpu_to_be16s(&rda[0]);
424
            cpu_to_be16s(&rda[1]);
425
            cpu_to_be16s(&rda[2]);
426
            cpu_to_be16s(&rda[3]);
427
        } else {
428
            cpu_to_le16s(&rda[0]);
429
            cpu_to_le16s(&rda[1]);
430
            cpu_to_le16s(&rda[2]);
431
            cpu_to_le16s(&rda[3]);
432
        }
433
        s->phys_mem_write(s->dma_opaque, addr,
434
                (void *)&rda[0], sizeof(rda));
435
    } else {
436
        uint32_t rda[4];
437
        if (BCR_SWSTYLE(s) != 3) {
438
            memcpy(rda, rmd, sizeof(rda));
439
        } else {
440
            rda[0] = rmd[2];
441
            rda[1] = rmd[1];
442
            rda[2] = rmd[0];
443
            rda[3] = rmd[3];
444
        }
445
        if (CSR_BIGENDIAN(s)) {
446
            cpu_to_be32s(&rda[0]);
447
            cpu_to_be32s(&rda[1]);
448
            cpu_to_be32s(&rda[2]);
449
            cpu_to_be32s(&rda[3]);
450
        } else {
451
            cpu_to_le32s(&rda[0]);
452
            cpu_to_le32s(&rda[1]);
453
            cpu_to_le32s(&rda[2]);
454
            cpu_to_le32s(&rda[3]);
455
        }
456
        s->phys_mem_write(s->dma_opaque, addr,
457
                          (void *)&rda[0], sizeof(rda));
458
    }
459
}
460

    
461

    
462
#define TMDLOAD(TMD,ADDR) pcnet_tmd_load(s,TMD,ADDR)
463

    
464
#define TMDSTORE(TMD,ADDR) pcnet_tmd_store(s,TMD,ADDR)
465

    
466
#define RMDLOAD(RMD,ADDR) pcnet_rmd_load(s,RMD,ADDR)
467

    
468
#define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR)
469

    
470
#if 1
471

    
472
#define CHECK_RMD(ADDR,RES) do {                \
473
    struct pcnet_RMD rmd;                       \
474
    RMDLOAD(&rmd,(ADDR));                       \
475
    (RES) |= (rmd.rmd1.ones != 15)              \
476
          || (rmd.rmd2.zeros != 0);             \
477
} while (0)
478

    
479
#define CHECK_TMD(ADDR,RES) do {                \
480
    struct pcnet_TMD tmd;                       \
481
    TMDLOAD(&tmd,(ADDR));                       \
482
    (RES) |= (tmd.tmd1.ones != 15);             \
483
} while (0)
484

    
485
#else
486

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

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

    
543
#endif
544

    
545
#define PRINT_PKTHDR(BUF) do {                  \
546
    struct qemu_ether_header *hdr = (void *)(BUF);   \
547
    printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, "       \
548
           "shost=%02x:%02x:%02x:%02x:%02x:%02x, "              \
549
           "type=0x%04x (bcast=%d)\n",                          \
550
           hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \
551
           hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \
552
           hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \
553
           hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \
554
           be16_to_cpu(hdr->ether_type),                                \
555
           !!ETHER_IS_MULTICAST(hdr->ether_dhost));                     \
556
} while (0)
557

    
558
#define MULTICAST_FILTER_LEN 8
559

    
560
static inline uint32_t lnc_mchash(const uint8_t *ether_addr)
561
{
562
#define LNC_POLYNOMIAL          0xEDB88320UL
563
    uint32_t crc = 0xFFFFFFFF;
564
    int idx, bit;
565
    uint8_t data;
566

    
567
    for (idx = 0; idx < 6; idx++) {
568
        for (data = *ether_addr++, bit = 0; bit < MULTICAST_FILTER_LEN; bit++) {
569
            crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LNC_POLYNOMIAL : 0);
570
            data >>= 1;
571
        }
572
    }
573
    return crc;
574
#undef LNC_POLYNOMIAL
575
}
576

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

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

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

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

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

    
698
static inline target_phys_addr_t pcnet_rdra_addr(PCNetState *s, int idx) 
699
{
700
    while (idx < 1) idx += CSR_RCVRL(s);
701
    return s->rdra + ((CSR_RCVRL(s) - idx) * (BCR_SWSTYLE(s) ? 16 : 8));
702
}
703

    
704
static inline int64_t pcnet_get_next_poll_time(PCNetState *s, int64_t current_time)
705
{
706
    int64_t next_time = current_time + 
707
        muldiv64(65536 - (CSR_SPND(s) ? 0 : CSR_POLL(s)), 
708
                 ticks_per_sec, 33000000L);
709
    if (next_time <= current_time)
710
        next_time = current_time + 1;
711
    return next_time;
712
}
713

    
714
static void pcnet_poll(PCNetState *s);
715
static void pcnet_poll_timer(void *opaque);
716

    
717
static uint32_t pcnet_csr_readw(PCNetState *s, uint32_t rap);
718
static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value);
719
static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, uint32_t val);
720
static uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
721

    
722
static void pcnet_s_reset(PCNetState *s)
723
{
724
#ifdef PCNET_DEBUG
725
    printf("pcnet_s_reset\n");
726
#endif
727

    
728
    s->lnkst = 0x40;
729
    s->rdra = 0;
730
    s->tdra = 0;
731
    s->rap = 0;
732
    
733
    s->bcr[BCR_BSBC] &= ~0x0080;
734

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

    
764
    s->tx_busy = 0;
765
}
766

    
767
static void pcnet_update_irq(PCNetState *s)
768
{
769
    int isr = 0;
770
    s->csr[0] &= ~0x0080;
771
    
772
#if 1
773
    if (((s->csr[0] & ~s->csr[3]) & 0x5f00) ||
774
        (((s->csr[4]>>1) & ~s->csr[4]) & 0x0115) ||
775
        (((s->csr[5]>>1) & s->csr[5]) & 0x0048))
776
#else
777
    if ((!(s->csr[3] & 0x4000) && !!(s->csr[0] & 0x4000)) /* BABL */ ||
778
        (!(s->csr[3] & 0x1000) && !!(s->csr[0] & 0x1000)) /* MISS */ ||
779
        (!(s->csr[3] & 0x0100) && !!(s->csr[0] & 0x0100)) /* IDON */ ||
780
        (!(s->csr[3] & 0x0200) && !!(s->csr[0] & 0x0200)) /* TINT */ ||
781
        (!(s->csr[3] & 0x0400) && !!(s->csr[0] & 0x0400)) /* RINT */ ||
782
        (!(s->csr[3] & 0x0800) && !!(s->csr[0] & 0x0800)) /* MERR */ ||
783
        (!(s->csr[4] & 0x0001) && !!(s->csr[4] & 0x0002)) /* JAB */ ||
784
        (!(s->csr[4] & 0x0004) && !!(s->csr[4] & 0x0008)) /* TXSTRT */ ||
785
        (!(s->csr[4] & 0x0010) && !!(s->csr[4] & 0x0020)) /* RCVO */ ||
786
        (!(s->csr[4] & 0x0100) && !!(s->csr[4] & 0x0200)) /* MFCO */ ||
787
        (!!(s->csr[5] & 0x0040) && !!(s->csr[5] & 0x0080)) /* EXDINT */ ||
788
        (!!(s->csr[5] & 0x0008) && !!(s->csr[5] & 0x0010)) /* MPINT */)
789
#endif
790
    {
791
       
792
        isr = CSR_INEA(s);
793
        s->csr[0] |= 0x0080;
794
    }
795
    
796
    if (!!(s->csr[4] & 0x0080) && CSR_INEA(s)) { /* UINT */
797
        s->csr[4] &= ~0x0080;
798
        s->csr[4] |= 0x0040;
799
        s->csr[0] |= 0x0080;
800
        isr = 1;
801
#ifdef PCNET_DEBUG
802
        printf("pcnet user int\n");
803
#endif
804
    }
805

    
806
#if 1
807
    if (((s->csr[5]>>1) & s->csr[5]) & 0x0500) 
808
#else
809
    if ((!!(s->csr[5] & 0x0400) && !!(s->csr[5] & 0x0800)) /* SINT */ ||
810
        (!!(s->csr[5] & 0x0100) && !!(s->csr[5] & 0x0200)) /* SLPINT */ )
811
#endif
812
    {
813
        isr = 1;
814
        s->csr[0] |= 0x0080;
815
    }
816

    
817
    if (isr != s->isr) {
818
#ifdef PCNET_DEBUG
819
        printf("pcnet: INTA=%d\n", isr);
820
#endif
821
    }
822
    s->set_irq_cb(s, isr);
823
    s->isr = isr;
824
}
825

    
826
static void pcnet_init(PCNetState *s)
827
{
828
    int rlen, tlen;
829
    uint16_t *padr, *ladrf, mode;
830
    uint32_t rdra, tdra;
831

    
832
#ifdef PCNET_DEBUG
833
    printf("pcnet_init init_addr=0x%08x\n", PHYSADDR(s,CSR_IADR(s)));
834
#endif
835
    
836
    if (BCR_SSIZE32(s)) {
837
        struct pcnet_initblk32 initblk;
838
        s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
839
                (uint8_t *)&initblk, sizeof(initblk));
840
        mode = initblk.mode;
841
        rlen = initblk.rlen >> 4;
842
        tlen = initblk.tlen >> 4;
843
        ladrf = initblk.ladrf;
844
        padr = initblk.padr;
845
        if (CSR_BIGENDIAN(s)) {
846
            rdra = be32_to_cpu(initblk.rdra);
847
            tdra = be32_to_cpu(initblk.tdra);
848
        } else {
849
            rdra = le32_to_cpu(initblk.rdra);
850
            tdra = le32_to_cpu(initblk.tdra);
851
        }
852
        s->rdra = PHYSADDR(s,initblk.rdra);
853
        s->tdra = PHYSADDR(s,initblk.tdra);
854
    } else {
855
        struct pcnet_initblk16 initblk;
856
        s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)),
857
                (uint8_t *)&initblk, sizeof(initblk));
858
        mode = initblk.mode;
859
        ladrf = initblk.ladrf;
860
        padr = initblk.padr;
861
        if (CSR_BIGENDIAN(s)) {
862
            rdra = be32_to_cpu(initblk.rdra);
863
            tdra = be32_to_cpu(initblk.tdra);
864
        } else {
865
            rdra = le32_to_cpu(initblk.rdra);
866
            tdra = le32_to_cpu(initblk.tdra);
867
        }
868
        rlen = rdra >> 29;
869
        tlen = tdra >> 29;
870
        rdra &= 0x00ffffff;
871
        tdra &= 0x00ffffff;
872
    }
873
    
874
#if defined(PCNET_DEBUG)
875
    printf("rlen=%d tlen=%d\n",
876
           rlen, tlen);
877
#endif
878
    CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512;
879
    CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512;
880
    s->csr[ 6] = (tlen << 12) | (rlen << 8);
881
    if (CSR_BIGENDIAN(s)) {
882
        s->csr[15] = be16_to_cpu(mode);
883
        s->csr[ 8] = be16_to_cpu(ladrf[0]);
884
        s->csr[ 9] = be16_to_cpu(ladrf[1]);
885
        s->csr[10] = be16_to_cpu(ladrf[2]);
886
        s->csr[11] = be16_to_cpu(ladrf[3]);
887
        s->csr[12] = be16_to_cpu(padr[0]);
888
        s->csr[13] = be16_to_cpu(padr[1]);
889
        s->csr[14] = be16_to_cpu(padr[2]);
890
    } else {
891
        s->csr[15] = le16_to_cpu(mode);
892
        s->csr[ 8] = le16_to_cpu(ladrf[0]);
893
        s->csr[ 9] = le16_to_cpu(ladrf[1]);
894
        s->csr[10] = le16_to_cpu(ladrf[2]);
895
        s->csr[11] = le16_to_cpu(ladrf[3]);
896
        s->csr[12] = le16_to_cpu(padr[0]);
897
        s->csr[13] = le16_to_cpu(padr[1]);
898
        s->csr[14] = le16_to_cpu(padr[2]);
899
    }
900
    s->rdra = PHYSADDR(s, rdra);
901
    s->tdra = PHYSADDR(s, tdra);
902

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

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

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

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

    
922
    if (!CSR_DTX(s))
923
        s->csr[0] |= 0x0010;    /* set TXON */
924
        
925
    if (!CSR_DRX(s))
926
        s->csr[0] |= 0x0020;    /* set RXON */
927

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

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

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

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

    
974
            s->csr[28] = crda & 0xffff;
975
            s->csr[29] = crda >> 16;
976
            s->csr[26] = nrda & 0xffff;
977
            s->csr[27] = nrda >> 16;
978
            s->csr[36] = nnrd & 0xffff;
979
            s->csr[37] = nnrd >> 16;
980
#ifdef PCNET_DEBUG
981
            if (bad) {
982
                printf("pcnet: BAD RMD RECORDS AFTER 0x%08x\n",
983
                       PHYSADDR(s,crda));
984
            }
985
        } else {
986
            printf("pcnet: BAD RMD RDA=0x%08x\n", PHYSADDR(s,crda));
987
#endif
988
        }
989
    }
990
    
991
    if (CSR_CRDA(s)) {
992
        struct pcnet_RMD rmd;
993
        RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s)));
994
        CSR_CRBC(s) = rmd.rmd1.bcnt;
995
        CSR_CRST(s) = ((uint32_t *)&rmd)[1] >> 16;
996
#ifdef PCNET_DEBUG_RMD_X
997
        printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMD1=0x%08x RMD2=0x%08x\n",
998
                PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s),
999
                ((uint32_t *)&rmd)[1], ((uint32_t *)&rmd)[2]);
1000
        PRINT_RMD(&rmd);
1001
#endif
1002
    } else {
1003
        CSR_CRBC(s) = CSR_CRST(s) = 0;
1004
    }
1005
    
1006
    if (CSR_NRDA(s)) {
1007
        struct pcnet_RMD rmd;
1008
        RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s)));
1009
        CSR_NRBC(s) = rmd.rmd1.bcnt;
1010
        CSR_NRST(s) = ((uint32_t *)&rmd)[1] >> 16;
1011
    } else {
1012
        CSR_NRBC(s) = CSR_NRST(s) = 0;
1013
    }
1014

    
1015
}
1016

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

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

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

    
1047
        CSR_CXBC(s) = tmd.tmd1.bcnt;
1048
        CSR_CXST(s) = ((uint32_t *)&tmd)[1] >> 16;
1049
    } else {
1050
        CSR_CXBC(s) = CSR_CXST(s) = 0;
1051
    }
1052
    
1053
    return !!(CSR_CXST(s) & 0x8000);
1054
}
1055

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

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

    
1068
#define MIN_BUF_SIZE 60
1069

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

    
1076
    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)
1077
        return;
1078

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

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

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

    
1096
        pcnet_rdte_poll(s);
1097

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

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

    
1133
            memcpy(src, buf, size);
1134
            
1135
#if 1
1136
            /* no need to compute the CRC */
1137
            src[size] = 0;
1138
            src[size + 1] = 0;
1139
            src[size + 2] = 0;
1140
            src[size + 3] = 0;
1141
            size += 4;
1142
#else
1143
            /* XXX: avoid CRC generation */
1144
            if (!CSR_ASTRP_RCV(s)) {
1145
                uint32_t fcs = ~0;
1146
                uint8_t *p = src;
1147

    
1148
                while (size < 46) {
1149
                    src[size++] = 0;
1150
                }
1151
                
1152
                while (p != &src[size]) {
1153
                    CRC(fcs, *p++);
1154
                }
1155
                ((uint32_t *)&src[size])[0] = htonl(fcs);
1156
                size += 4; /* FCS at end of packet */
1157
            } else size += 4;
1158
#endif
1159

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

    
1164
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1165
            /*if (!CSR_LAPPEN(s))*/
1166
                rmd.rmd1.stp = 1;
1167

    
1168
#define PCNET_RECV_STORE() do {                                 \
1169
    int count = MIN(4096 - rmd.rmd1.bcnt,size);                 \
1170
    target_phys_addr_t rbadr = PHYSADDR(s, rmd.rmd0.rbadr);     \
1171
    s->phys_mem_write(s->dma_opaque, rbadr, src, count);               \
1172
    src += count; size -= count;                                \
1173
    rmd.rmd2.mcnt = count; rmd.rmd1.own = 0;                    \
1174
    RMDSTORE(&rmd, PHYSADDR(s,crda));                           \
1175
    pktcount++;                                                 \
1176
} while (0)
1177

    
1178
            PCNET_RECV_STORE();
1179
            if ((size > 0) && CSR_NRDA(s)) {
1180
                target_phys_addr_t nrda = CSR_NRDA(s);
1181
                RMDLOAD(&rmd, PHYSADDR(s,nrda));
1182
                if (rmd.rmd1.own) {
1183
                    crda = nrda;
1184
                    PCNET_RECV_STORE();
1185
                    if ((size > 0) && (nrda=CSR_NNRD(s))) {
1186
                        RMDLOAD(&rmd, PHYSADDR(s,nrda));
1187
                        if (rmd.rmd1.own) {
1188
                            crda = nrda;
1189
                            PCNET_RECV_STORE();
1190
                        }
1191
                    }
1192
                }                
1193
            }
1194

    
1195
#undef PCNET_RECV_STORE
1196

    
1197
            RMDLOAD(&rmd, PHYSADDR(s,crda));
1198
            if (size == 0) {
1199
                rmd.rmd1.enp = 1;
1200
                rmd.rmd1.pam = !CSR_PROM(s) && is_padr;
1201
                rmd.rmd1.lafm = !CSR_PROM(s) && is_ladr;
1202
                rmd.rmd1.bam = !CSR_PROM(s) && is_bcast;
1203
            } else {
1204
                rmd.rmd1.oflo = 1;
1205
                rmd.rmd1.buff = 1;
1206
                rmd.rmd1.err = 1;
1207
            }
1208
            RMDSTORE(&rmd, PHYSADDR(s,crda));
1209
            s->csr[0] |= 0x0400;
1210

    
1211
#ifdef PCNET_DEBUG
1212
            printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n", 
1213
                CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);
1214
#endif
1215
#ifdef PCNET_DEBUG_RMD
1216
            PRINT_RMD(&rmd);
1217
#endif        
1218

    
1219
            while (pktcount--) {
1220
                if (CSR_RCVRC(s) <= 1)
1221
                    CSR_RCVRC(s) = CSR_RCVRL(s);
1222
                else
1223
                    CSR_RCVRC(s)--;            
1224
            }
1225
            
1226
            pcnet_rdte_poll(s);
1227

    
1228
        }        
1229
    }
1230

    
1231
    pcnet_poll(s);
1232
    pcnet_update_irq(s);    
1233
}
1234

    
1235
static void pcnet_transmit(PCNetState *s)
1236
{
1237
    target_phys_addr_t xmit_cxda = 0;
1238
    int count = CSR_XMTRL(s)-1;
1239
    s->xmit_pos = -1;
1240
    
1241
    if (!CSR_TXON(s)) {
1242
        s->csr[0] &= ~0x0008;
1243
        return;
1244
    }
1245

    
1246
    s->tx_busy = 1;
1247

    
1248
    txagain:
1249
    if (pcnet_tdte_poll(s)) {
1250
        struct pcnet_TMD tmd;
1251

    
1252
        TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s)));                
1253

    
1254
#ifdef PCNET_DEBUG_TMD
1255
        printf("  TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s)));
1256
        PRINT_TMD(&tmd);
1257
#endif
1258
        if (tmd.tmd1.stp) {
1259
            s->xmit_pos = 0;                
1260
            if (!tmd.tmd1.enp) {
1261
                s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr),
1262
                        s->buffer, 4096 - tmd.tmd1.bcnt);
1263
                s->xmit_pos += 4096 - tmd.tmd1.bcnt;
1264
            } 
1265
            xmit_cxda = PHYSADDR(s,CSR_CXDA(s));
1266
        }
1267
        if (tmd.tmd1.enp && (s->xmit_pos >= 0)) {
1268
            s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr),
1269
                    s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt);
1270
            s->xmit_pos += 4096 - tmd.tmd1.bcnt;
1271
#ifdef PCNET_DEBUG
1272
            printf("pcnet_transmit size=%d\n", s->xmit_pos);
1273
#endif            
1274
            if (CSR_LOOP(s))
1275
                pcnet_receive(s, s->buffer, s->xmit_pos);
1276
            else
1277
                qemu_send_packet(s->vc, s->buffer, s->xmit_pos);
1278

    
1279
            s->csr[0] &= ~0x0008;   /* clear TDMD */
1280
            s->csr[4] |= 0x0004;    /* set TXSTRT */
1281
            s->xmit_pos = -1;
1282
        }
1283

    
1284
        tmd.tmd1.own = 0;
1285
        TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
1286
        if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && tmd.tmd1.ltint))
1287
            s->csr[0] |= 0x0200;    /* set TINT */
1288

    
1289
        if (CSR_XMTRC(s)<=1)
1290
            CSR_XMTRC(s) = CSR_XMTRL(s);
1291
        else
1292
            CSR_XMTRC(s)--;
1293
        if (count--)
1294
            goto txagain;
1295

    
1296
    } else 
1297
    if (s->xmit_pos >= 0) {
1298
        struct pcnet_TMD tmd;
1299
        TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda));                
1300
        tmd.tmd2.buff = tmd.tmd2.uflo = tmd.tmd1.err = 1;
1301
        tmd.tmd1.own = 0;
1302
        TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda));
1303
        s->csr[0] |= 0x0200;    /* set TINT */
1304
        if (!CSR_DXSUFLO(s)) {
1305
            s->csr[0] &= ~0x0010;
1306
        } else
1307
        if (count--)
1308
          goto txagain;
1309
    }
1310

    
1311
    s->tx_busy = 0;
1312
}
1313

    
1314
static void pcnet_poll(PCNetState *s)
1315
{
1316
    if (CSR_RXON(s)) {
1317
        pcnet_rdte_poll(s);
1318
    }
1319

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

    
1327
        pcnet_transmit(s);
1328
    }
1329
}
1330

    
1331
static void pcnet_poll_timer(void *opaque)
1332
{
1333
    PCNetState *s = opaque;
1334

    
1335
    qemu_del_timer(s->poll_timer);
1336

    
1337
    if (CSR_TDMD(s)) {
1338
        pcnet_transmit(s);
1339
    }
1340

    
1341
    pcnet_update_irq(s);    
1342

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

    
1360

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

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

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

    
1375
        /* IFF STOP, STRT and INIT are set, clear STRT and INIT */
1376
        if ((val&7) == 7)
1377
          val &= ~3;
1378

    
1379
        if (!CSR_STOP(s) && (val & 4))
1380
            pcnet_stop(s);
1381

    
1382
        if (!CSR_INIT(s) && (val & 1))
1383
            pcnet_init(s);
1384

    
1385
        if (!CSR_STRT(s) && (val & 2))
1386
            pcnet_start(s);
1387

    
1388
        if (CSR_TDMD(s)) 
1389
            pcnet_transmit(s);
1390

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

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

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

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

    
1562
void pcnet_h_reset(void *opaque)
1563
{
1564
    PCNetState *s = opaque;
1565
    int i;
1566
    uint16_t checksum;
1567

    
1568
    /* Initialize the PROM */
1569

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

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

    
1578

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

    
1592
    pcnet_s_reset(s);
1593
}
1594

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

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

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

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

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

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

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

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

    
1736
    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
1737
    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
1738
    
1739
    register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
1740
    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
1741
    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
1742
    register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
1743
}
1744

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

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

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

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

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

    
1817
static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr) 
1818
{
1819
    PCNetState *d = opaque;
1820
    uint32_t val;
1821
    if (addr & 0x10)
1822
        val = pcnet_ioport_readl(d, addr & 0x0f);
1823
    else {
1824
        addr &= 0x0f;
1825
        val = pcnet_aprom_readb(d, addr+3);
1826
        val <<= 8;
1827
        val |= pcnet_aprom_readb(d, addr+2);
1828
        val <<= 8;
1829
        val |= pcnet_aprom_readb(d, addr+1);
1830
        val <<= 8;
1831
        val |= pcnet_aprom_readb(d, addr);
1832
    }
1833
#ifdef PCNET_DEBUG_IO
1834
    printf("pcnet_mmio_readl addr=0x%08x val=0x%08x\n", addr, val);
1835
#endif
1836
    return val;
1837
}
1838

    
1839

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

    
1845
    if (s->pci_dev)
1846
        pci_device_save(s->pci_dev, f);
1847

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

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

    
1871
    if (version_id != 2)
1872
        return -EINVAL;
1873

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

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

    
1897
    return 0;
1898
}
1899

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

    
1904
    d->nd = nd;
1905

    
1906
    d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive, 
1907
                                 pcnet_can_receive, d);
1908
    
1909
    snprintf(d->vc->info_str, sizeof(d->vc->info_str),
1910
             "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
1911
             d->nd->macaddr[0],
1912
             d->nd->macaddr[1],
1913
             d->nd->macaddr[2],
1914
             d->nd->macaddr[3],
1915
             d->nd->macaddr[4],
1916
             d->nd->macaddr[5]);
1917

    
1918
    pcnet_h_reset(d);
1919
    register_savevm("pcnet", 0, 2, pcnet_save, pcnet_load, d);
1920
}
1921

    
1922
/* PCI interface */
1923

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

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

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

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

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

    
1948
static void pcnet_pci_set_irq_cb(void *opaque, int isr)
1949
{
1950
    PCNetState *s = opaque;
1951

    
1952
    pci_set_irq(&s->dev, 0, isr);
1953
}
1954

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

    
1961
static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
1962
                           uint8_t *buf, int len)
1963
{
1964
    cpu_physical_memory_read(addr, buf, len);
1965
}
1966

    
1967
void pci_pcnet_init(PCIBus *bus, NICInfo *nd)
1968
{
1969
    PCNetState *d;
1970
    uint8_t *pci_conf;
1971

    
1972
#if 0
1973
    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n", 
1974
        sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));
1975
#endif
1976

    
1977
    d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),
1978
                                          -1, NULL, NULL);
1979
                                          
1980
    pci_conf = d->dev.config;
1981
    
1982
    *(uint16_t *)&pci_conf[0x00] = cpu_to_le16(0x1022);
1983
    *(uint16_t *)&pci_conf[0x02] = cpu_to_le16(0x2000);    
1984
    *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007); 
1985
    *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);
1986
    pci_conf[0x08] = 0x10;
1987
    pci_conf[0x09] = 0x00;
1988
    pci_conf[0x0a] = 0x00; // ethernet network controller 
1989
    pci_conf[0x0b] = 0x02;
1990
    pci_conf[0x0e] = 0x00; // header_type
1991
    
1992
    *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);
1993
    *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);
1994
    
1995
    pci_conf[0x3d] = 1; // interrupt pin 0
1996
    pci_conf[0x3e] = 0x06;
1997
    pci_conf[0x3f] = 0xff;
1998

    
1999
    /* Handler for memory-mapped I/O */
2000
    d->mmio_index =
2001
      cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);
2002

    
2003
    pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE, 
2004
                           PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
2005
                           
2006
    pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE, 
2007
                           PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
2008
                           
2009
    d->set_irq_cb = pcnet_pci_set_irq_cb;
2010
    d->phys_mem_read = pci_physical_memory_read;
2011
    d->phys_mem_write = pci_physical_memory_write;
2012
    d->pci_dev = &d->dev;
2013

    
2014
    pcnet_common_init(d, nd, "pcnet");
2015
}
2016

    
2017
/* SPARC32 interface */
2018

    
2019
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure
2020

    
2021
static CPUReadMemoryFunc *lance_mem_read[3] = {
2022
    (CPUReadMemoryFunc *)&pcnet_ioport_readw,
2023
    (CPUReadMemoryFunc *)&pcnet_ioport_readw,
2024
    (CPUReadMemoryFunc *)&pcnet_ioport_readw,
2025
};
2026

    
2027
static CPUWriteMemoryFunc *lance_mem_write[3] = {
2028
    (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
2029
    (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
2030
    (CPUWriteMemoryFunc *)&pcnet_ioport_writew,
2031
};
2032

    
2033
static void pcnet_sparc_set_irq_cb(void *opaque, int isr)
2034
{
2035
    PCNetState *s = opaque;
2036

    
2037
    ledma_set_irq(s->dma_opaque, isr);
2038
}
2039

    
2040
void *lance_init(NICInfo *nd, uint32_t leaddr, void *dma_opaque)
2041
{
2042
    PCNetState *d;
2043
    int lance_io_memory;
2044

    
2045
    d = qemu_mallocz(sizeof(PCNetState));
2046
    if (!d)
2047
        return NULL;
2048

    
2049
    lance_io_memory =
2050
        cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
2051

    
2052
    d->dma_opaque = dma_opaque;
2053
    cpu_register_physical_memory(leaddr, 4, lance_io_memory);
2054

    
2055
    d->set_irq_cb = pcnet_sparc_set_irq_cb;
2056
    d->phys_mem_read = ledma_memory_read;
2057
    d->phys_mem_write = ledma_memory_write;
2058

    
2059
    pcnet_common_init(d, nd, "lance");
2060

    
2061
    return d;
2062
}
2063
#endif /* TARGET_SPARC */